docs: adicionar plano do notebook story
This commit is contained in:
1 parent
b4a2b81d55
commit
d768dfa791
1 file changed
+18
-13
@@ -42,7 +42,7 @@
|
||||
- Test: `app/components/story/NotebookStory.test.tsx` — modo reduzido, elegibilidade 3D e integração de tabs.
|
||||
- Modify: `app/components/cinematic/CinematicHome.tsx` — usar `NotebookStory` e remover `PrintReel`/`ScrollStory`.
|
||||
- Modify: `app/globals.css` — somente tokens/classes novas do notebook, sem tocar no `globals.css` raiz do usuário.
|
||||
- Delete after migration: `app/components/story/PrintReel.tsx`, `app/components/story/ScrollStory.tsx`, `app/components/story/StoryStage3D.tsx`, `app/components/story/phoneScreenTexture.ts` e testes órfãos.
|
||||
- Delete after migration: `app/components/story/PrintReel.tsx`, `app/components/story/ScrollStory.tsx`, `app/components/story/StoryStage3D.tsx`, `app/components/story/phoneScreenTexture.ts`, seus testes órfãos e `public/models/phone-quaternius.glb`.
|
||||
|
||||
---
|
||||
|
||||
@@ -69,7 +69,7 @@ Invoke-WebRequest `
|
||||
|
||||
- [ ] **Step 2: Inspect the GLB node and material names before code**
|
||||
|
||||
Read the GLB header and JSON chunk with a one-off Node script. Record the actual node names, parent relationships, bounding boxes and material names in the implementation notes. The script must fail if there is no separate lid-like node.
|
||||
Read the GLB header and JSON chunk with a one-off Node script. Record the actual validated mapping (`Laptop_Base`, `Laptop_Lid`), parent relationships, bounding boxes and material names in `NotebookStage3D.tsx` and `CREDITS.md`. The script must fail if there is no separate lid-like node.
|
||||
|
||||
```js
|
||||
const fs = require('node:fs');
|
||||
@@ -172,7 +172,7 @@ const projectsFixture = [
|
||||
},
|
||||
{
|
||||
id: "sc-plus",
|
||||
title: "SCPLUS",
|
||||
title: "SC Plus Aquicultura",
|
||||
subtitle: "Landing Page Institucional",
|
||||
demoUrl: "https://scplus.evandro.dev.br",
|
||||
technologies: ["Next.js", "React"],
|
||||
@@ -344,14 +344,14 @@ export default function NotebookBrowser(props: NotebookBrowserProps): JSX.Elemen
|
||||
|
||||
- [ ] **Step 1: Write failing semantic and interaction tests**
|
||||
|
||||
Test observable behavior, not implementation details:
|
||||
Test observable behavior, not implementation details. Import `userEvent` in the test file before using `userEvent.setup()`:
|
||||
|
||||
```tsx
|
||||
it('renders the active project as an accessible tabpanel', () => {
|
||||
render(<NotebookBrowser {...props} activeIndex={1} />);
|
||||
expect(screen.getByRole('tablist', { name: /projetos em produção/i })).toBeInTheDocument();
|
||||
expect(screen.getAllByRole('tab')[1]).toHaveAttribute('aria-selected', 'true');
|
||||
expect(screen.getByRole('tabpanel')).toHaveAccessibleName(/SCPLUS/i);
|
||||
expect(screen.getByRole('tabpanel')).toHaveAccessibleName(/SC Plus Aquicultura/i);
|
||||
});
|
||||
|
||||
it('moves between tabs with arrow keys and Home/End', async () => {
|
||||
@@ -510,21 +510,26 @@ export default function NotebookStage3D(props: NotebookStage3DProps): JSX.Elemen
|
||||
|
||||
- [ ] **Step 1: Write failing stage boundary tests**
|
||||
|
||||
Mock only the R3F/Drei renderer boundary; assert the observable fallback contract. The test mock must expose the hook used by production:
|
||||
Mock only the R3F/Drei renderer boundary; assert the observable fallback contract. Keep the `useGLTF` mock persistent for the failure case because React error boundaries may retry rendering:
|
||||
|
||||
```tsx
|
||||
jest.mock("@react-three/drei", () => ({
|
||||
...jest.requireActual("@react-three/drei"),
|
||||
Html: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
useGLTF: jest.fn(() => ({ scene: new THREE.Group() })),
|
||||
}));
|
||||
|
||||
const mockedUseGLTF = jest.mocked(useGLTF);
|
||||
|
||||
function mockUseGLTFFailure() {
|
||||
mockedUseGLTF.mockImplementationOnce(() => {
|
||||
beforeEach(() => {
|
||||
mockedUseGLTF.mockImplementation(() => ({ scene: new THREE.Group() }));
|
||||
});
|
||||
|
||||
it("returns usable content when GLB loading fails", () => {
|
||||
mockedUseGLTF.mockImplementation(() => {
|
||||
throw new Error("GLB failed");
|
||||
});
|
||||
}
|
||||
// render and assert the DOM fallback, not the Canvas internals
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run stage tests and verify the expected red failure**
|
||||
@@ -536,10 +541,8 @@ pnpm exec jest app/components/story/NotebookStage3D.test.tsx --runInBand
|
||||
- [ ] **Step 3: Implement the GLB rig**
|
||||
|
||||
Implementation requirements:
|
||||
|
||||
- `useGLTF('/models/laptop-kenney.glb')` only; no remote URL.
|
||||
- Clone the scene and apply materials from the notebook color map.
|
||||
- Resolve the validated base/lid/screen/keyboard nodes from Task 1.
|
||||
- Clone the scene, resolve the validated `Laptop_Base` and `Laptop_Lid` nodes, and apply materials from the notebook color map.
|
||||
- Attach the browser surface to a calibrated screen anchor on the lid using Drei `Html transform`.
|
||||
- Apply `getNotebookFrame(progress.current, projects.length)` to lid angle, screen opacity, device opacity and cursor props.
|
||||
- Keep base stable; only lid articulates.
|
||||
@@ -584,6 +587,8 @@ export type NotebookStoryProps = {
|
||||
projects: PortfolioProject[];
|
||||
};
|
||||
|
||||
export function canUseNotebook3D(view: Pick<Window, "innerWidth" | "matchMedia">): boolean;
|
||||
export function getNotebookSeekProgress(index: number, tabCount: number): number;
|
||||
export default function NotebookStory(props: NotebookStoryProps): JSX.Element;
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user