@@ -28,7 +28,8 @@ packages/{framework}/src/components/{component-name}/
2828
2929## Creating New Examples
3030
31- ** IMPORTANT: When adding examples, ALL steps below must be completed. Missing any step means the example is incomplete.**
31+ ** IMPORTANT: When adding examples, ALL steps below must be completed. Missing any step means the example is
32+ incomplete.**
3233
3334When creating a new example for a component, you ** MUST** update the following files:
3435
@@ -41,33 +42,41 @@ When creating a new example for a component, you **MUST** update the following f
41422 . ** Update Storybook stories for all frameworks** (REQUIRED - examples won't appear without this):
4243 - ` packages/react/src/components/{component}/{component}.stories.tsx ` - Add export in alphabetical order
4344 - ` packages/solid/src/components/{component}/{component}.stories.tsx ` - Add export in alphabetical order
44- - ` packages/vue/src/components/{component}/{component}.stories.vue ` - Add import and ` <Variant> ` in alphabetical order
45- - ` packages/svelte/src/lib/components/{component}/{component}.stories.ts ` - Add import and export in alphabetical order
45+ - ` packages/vue/src/components/{component}/{component}.stories.vue ` - Add import and ` <Variant> ` in alphabetical
46+ order
47+ - ` packages/svelte/src/lib/components/{component}/{component}.stories.ts ` - Add import and export in alphabetical
48+ order
4649
47503 . ** Update component documentation** (if applicable):
4851 - ` website/src/content/pages/components/{component}.mdx ` - Add ` <Example id="{example-name}" /> ` with description
4952
50- ** Note** : Steps 1 and 2 are MANDATORY. Without updating the stories files, the examples will not be visible in Storybook.
53+ ** Note** : Steps 1 and 2 are MANDATORY. Without updating the stories files, the examples will not be visible in
54+ Storybook.
5155
5256### Example Workflow
5357
5458For a new "links" example on the Menu component:
5559
56601 . Create example files in all four frameworks
57612 . Update stories:
62+
5863 ``` tsx
5964 // React/Solid: Add to exports
6065 export { Links } from ' ./examples/links'
6166
6267 // Vue: Add to imports and template
6368 import Links from ' ./examples/links.vue'
64- <Variant title = " Links" ><Links /></Variant >
69+ ;< Variant title = " Links" >
70+ <Links />
71+ < / Variant >
6572
6673 // Svelte: Add import and export
6774 import LinksExample from ' ./examples/links.svelte'
6875 export const Links = { render : () => ({ Component: LinksExample }) }
6976 ```
77+
70783 . Update MDX documentation:
79+
7180 ``` mdx
7281 ### Menu with links
7382
@@ -206,13 +215,15 @@ Every component should include these example patterns where applicable:
206215
207216## Root Provider Pattern (Critical)
208217
209- ** The ` root-provider ` example is essential for most components** as it demonstrates external state management using component hooks.
218+ ** The ` root-provider ` example is essential for most components** as it demonstrates external state management using
219+ component hooks.
210220
211221### Two Approaches: Choose One
212222
213223There are two ways to use components - pick one approach, never mix them:
214224
215225** Approach 1: Component.Root (Declarative)**
226+
216227- Pass props directly to ` Component.Root `
217228- Component manages its own internal state
218229- Limited access to state and methods
@@ -226,6 +237,7 @@ There are two ways to use components - pick one approach, never mix them:
226237```
227238
228239** Approach 2: useComponent + RootProvider (Programmatic)**
240+
229241- Call ` useComponent(props) ` to get the component API/store
230242- Pass the store to ` Component.RootProvider `
231243- Full access to state properties and methods (` .setOpen() ` , ` .open ` , etc.)
@@ -245,16 +257,20 @@ return (
245257```
246258
247259** ❌ NEVER mix both approaches:**
260+
248261``` tsx
249262// ❌ WRONG - Don't use Root inside RootProvider
250263<Dialog.RootProvider value = { dialog } >
251- <Dialog.Root > { /* This is incorrect! */ }
264+ <Dialog.Root >
265+ { ' ' }
266+ { /* This is incorrect! */ }
252267 <Dialog.Content />
253268 </Dialog.Root >
254269</Dialog.RootProvider >
255270```
256271
257- The benefit of ` useComponent + RootProvider ` is direct access to the component's state and methods, enabling programmatic control from anywhere in your component.
272+ The benefit of ` useComponent + RootProvider ` is direct access to the component's state and methods, enabling
273+ programmatic control from anywhere in your component.
258274
259275### React Pattern
260276
@@ -297,9 +313,7 @@ export const Example = () => {
297313 return (
298314 <Dialog.RootProvider value = { dialog } >
299315 <Dialog.Trigger >Open</Dialog.Trigger >
300- <Dialog.Content >
301- { /* Content */ }
302- </Dialog.Content >
316+ <Dialog.Content >{ /* Content */ } </Dialog.Content >
303317 </Dialog.RootProvider >
304318 )
305319}
@@ -342,9 +356,7 @@ export const Example = () => {
342356 return (
343357 <Dialog.RootProvider value = { dialog } >
344358 <Dialog.Trigger >Open</Dialog.Trigger >
345- <Dialog.Content >
346- { /* Content */ }
347- </Dialog.Content >
359+ <Dialog.Content >{ /* Content */ } </Dialog.Content >
348360 </Dialog.RootProvider >
349361 )
350362}
@@ -584,15 +596,15 @@ import { Teleport } from 'vue'
584596``` ts
585597// React/Svelte Portal Props
586598interface PortalProps {
587- disabled? : boolean // Renders inline when true
588- container? : HTMLElement // Custom mount point
589- children: ReactNode // Content to portal
599+ disabled? : boolean // Renders inline when true
600+ container? : HTMLElement // Custom mount point
601+ children: ReactNode // Content to portal
590602}
591603
592604// Vue Teleport Props
593605interface TeleportProps {
594- to: string | Element // Target selector or element
595- disabled? : boolean // Renders inline when true
606+ to: string | Element // Target selector or element
607+ disabled? : boolean // Renders inline when true
596608}
597609```
598610
@@ -608,6 +620,7 @@ interface TeleportProps {
608620### Accessibility Testing
609621
610622** vitest-axe Integration:**
623+
611624``` ts
612625import { axe } from ' vitest-axe'
613626import { render } from ' @testing-library/react' // or framework equivalent
@@ -620,6 +633,7 @@ test('should not have accessibility violations', async () => {
620633```
621634
622635** Keyboard Navigation Testing:**
636+
623637``` ts
624638import { fireEvent } from ' @testing-library/react'
625639
@@ -641,6 +655,7 @@ test('should handle keyboard navigation', async () => {
641655```
642656
643657** ARIA Attributes Testing:**
658+
644659``` ts
645660test (' should have correct ARIA attributes' , () => {
646661 render (<Component expanded ={true} />)
@@ -654,29 +669,34 @@ test('should have correct ARIA attributes', () => {
654669### Cross-Framework Testing Patterns
655670
656671** React Testing:**
672+
657673``` ts
658674import { render , screen } from ' @testing-library/react'
659675import userEvent from ' @testing-library/user-event'
660676```
661677
662678** Solid Testing:**
679+
663680``` ts
664681import { render , screen } from ' @solidjs/testing-library'
665682```
666683
667684** Vue Testing:**
685+
668686``` ts
669687import { render , screen } from ' @testing-library/vue'
670688```
671689
672690** Svelte Testing:**
691+
673692``` ts
674693import { render , screen } from ' @testing-library/svelte'
675694```
676695
677696### Component State Testing
678697
679698** Controlled vs Uncontrolled:**
699+
680700``` ts
681701test (' controlled component' , () => {
682702 const onValueChange = vi .fn ()
@@ -699,6 +719,7 @@ test('uncontrolled component', () => {
699719### Screen Reader Compatibility
700720
701721** Announcement Testing:**
722+
702723``` ts
703724test (' should announce state changes' , async () => {
704725 render (<Component />)
@@ -714,6 +735,7 @@ test('should announce state changes', async () => {
714735```
715736
716737** Focus Management:**
738+
717739``` ts
718740test (' should manage focus correctly' , () => {
719741 render (<Dialog />)
@@ -749,4 +771,9 @@ test('should manage focus correctly', () => {
749771- Minimize re-renders with proper memoization
750772- Use lazy mounting for heavy components (` lazy-mount.tsx ` )
751773- Implement proper cleanup in unmount handlers
752- - Follow framework-specific performance patterns
774+ - Follow framework-specific performance patterns
775+
776+ ### When to Use Each Approach
777+
778+ - ** Use ` Component.Context ` ** : When you need to access the API for composition within the component tree
779+ - ** Use ` useComponent + RootProvider ` ** : When you need external control and state management outside the component
0 commit comments