@flowstack-ui/brick 0.1.5 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/agents/accordion.json +89 -0
- package/dist/agents/accordion.md +50 -0
- package/dist/agents/app-bar.json +5 -0
- package/dist/agents/app-bar.md +1 -0
- package/dist/agents/appearance.json +84 -0
- package/dist/agents/appearance.md +48 -0
- package/dist/agents/badge.json +64 -0
- package/dist/agents/badge.md +41 -0
- package/dist/agents/card.json +5 -0
- package/dist/agents/card.md +1 -0
- package/dist/agents/carousel.json +131 -0
- package/dist/agents/carousel.md +64 -0
- package/dist/agents/collapsible.json +81 -0
- package/dist/agents/collapsible.md +49 -0
- package/dist/agents/container.json +10 -4
- package/dist/agents/container.md +4 -2
- package/dist/agents/divider.json +1 -1
- package/dist/agents/divider.md +1 -1
- package/dist/agents/drawer.json +11 -1
- package/dist/agents/drawer.md +3 -0
- package/dist/agents/frame.json +74 -0
- package/dist/agents/frame.md +47 -0
- package/dist/agents/grid.json +9 -0
- package/dist/agents/grid.md +2 -0
- package/dist/agents/icon.json +98 -0
- package/dist/agents/icon.md +51 -0
- package/dist/agents/image.json +18 -2
- package/dist/agents/image.md +5 -1
- package/dist/agents/interface-composition.json +143 -6
- package/dist/agents/interface-composition.md +40 -6
- package/dist/agents/layer-selection.json +13 -1
- package/dist/agents/layer-selection.md +4 -0
- package/dist/agents/list.json +80 -0
- package/dist/agents/list.md +48 -0
- package/dist/agents/manifest.json +61 -1
- package/dist/agents/scroll-area.json +8 -3
- package/dist/agents/scroll-area.md +4 -3
- package/dist/agents/section.json +65 -0
- package/dist/agents/section.md +42 -0
- package/dist/agents/stack.json +29 -5
- package/dist/agents/stack.md +14 -4
- package/dist/agents/surface.json +52 -4
- package/dist/agents/surface.md +16 -2
- package/dist/agents/tabs.json +17 -2
- package/dist/agents/tabs.md +8 -1
- package/dist/agents/text.json +14 -4
- package/dist/agents/text.md +5 -3
- package/dist/agents/z-stack.json +66 -0
- package/dist/agents/z-stack.md +41 -0
- package/dist/appearance.d.ts +2 -0
- package/dist/appearance.d.ts.map +1 -0
- package/dist/appearance.js +2 -0
- package/dist/appearance.js.map +1 -0
- package/dist/carousel.d.ts +3 -0
- package/dist/carousel.d.ts.map +1 -0
- package/dist/carousel.js +3 -0
- package/dist/carousel.js.map +1 -0
- package/dist/components/_responsive-value/ResponsiveValue.d.ts +9 -0
- package/dist/components/_responsive-value/ResponsiveValue.d.ts.map +1 -0
- package/dist/components/_responsive-value/ResponsiveValue.js +22 -0
- package/dist/components/_responsive-value/ResponsiveValue.js.map +1 -0
- package/dist/components/appearance/Appearance.d.ts +14 -0
- package/dist/components/appearance/Appearance.d.ts.map +1 -0
- package/dist/components/appearance/Appearance.js +39 -0
- package/dist/components/appearance/Appearance.js.map +1 -0
- package/dist/components/appearance/index.d.ts +2 -0
- package/dist/components/appearance/index.d.ts.map +1 -0
- package/dist/components/appearance/index.js +2 -0
- package/dist/components/appearance/index.js.map +1 -0
- package/dist/components/card/Card.d.ts +1 -0
- package/dist/components/card/Card.d.ts.map +1 -1
- package/dist/components/card/Card.js +2 -1
- package/dist/components/card/Card.js.map +1 -1
- package/dist/components/carousel/Carousel.d.ts +80 -0
- package/dist/components/carousel/Carousel.d.ts.map +1 -0
- package/dist/components/carousel/Carousel.js +90 -0
- package/dist/components/carousel/Carousel.js.map +1 -0
- package/dist/components/carousel/index.d.ts +2 -0
- package/dist/components/carousel/index.d.ts.map +1 -0
- package/dist/components/carousel/index.js +2 -0
- package/dist/components/carousel/index.js.map +1 -0
- package/dist/components/divider/Divider.js +2 -2
- package/dist/components/divider/Divider.js.map +1 -1
- package/dist/components/frame/Frame.d.ts +28 -0
- package/dist/components/frame/Frame.d.ts.map +1 -0
- package/dist/components/frame/Frame.js +84 -0
- package/dist/components/frame/Frame.js.map +1 -0
- package/dist/components/frame/index.d.ts +2 -0
- package/dist/components/frame/index.d.ts.map +1 -0
- package/dist/components/frame/index.js +2 -0
- package/dist/components/frame/index.js.map +1 -0
- package/dist/components/grid/Grid.d.ts +19 -9
- package/dist/components/grid/Grid.d.ts.map +1 -1
- package/dist/components/grid/Grid.js +26 -10
- package/dist/components/grid/Grid.js.map +1 -1
- package/dist/components/grid/index.d.ts +1 -1
- package/dist/components/grid/index.d.ts.map +1 -1
- package/dist/components/grid/index.js.map +1 -1
- package/dist/components/image/Image.d.ts +4 -0
- package/dist/components/image/Image.d.ts.map +1 -1
- package/dist/components/image/Image.js +4 -4
- package/dist/components/image/Image.js.map +1 -1
- package/dist/components/image/index.d.ts +1 -1
- package/dist/components/image/index.d.ts.map +1 -1
- package/dist/components/image/index.js +1 -1
- package/dist/components/image/index.js.map +1 -1
- package/dist/components/section/Section.d.ts +18 -0
- package/dist/components/section/Section.d.ts.map +1 -0
- package/dist/components/section/Section.js +29 -0
- package/dist/components/section/Section.js.map +1 -0
- package/dist/components/section/index.d.ts +2 -0
- package/dist/components/section/index.d.ts.map +1 -0
- package/dist/components/section/index.js +2 -0
- package/dist/components/section/index.js.map +1 -0
- package/dist/components/stack/Stack.d.ts +33 -8
- package/dist/components/stack/Stack.d.ts.map +1 -1
- package/dist/components/stack/Stack.js +71 -14
- package/dist/components/stack/Stack.js.map +1 -1
- package/dist/components/stack/index.d.ts +1 -1
- package/dist/components/stack/index.d.ts.map +1 -1
- package/dist/components/stack/index.js.map +1 -1
- package/dist/components/surface/Surface.d.ts +41 -3
- package/dist/components/surface/Surface.d.ts.map +1 -1
- package/dist/components/surface/Surface.js +79 -6
- package/dist/components/surface/Surface.js.map +1 -1
- package/dist/components/surface/index.d.ts +1 -1
- package/dist/components/surface/index.d.ts.map +1 -1
- package/dist/components/surface/index.js +1 -1
- package/dist/components/surface/index.js.map +1 -1
- package/dist/components/tabs/Tabs.d.ts +27 -6
- package/dist/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.js +10 -6
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/components/tabs/index.d.ts +1 -1
- package/dist/components/tabs/index.d.ts.map +1 -1
- package/dist/components/tabs/index.js.map +1 -1
- package/dist/components/z-stack/ZStack.d.ts +43 -0
- package/dist/components/z-stack/ZStack.d.ts.map +1 -0
- package/dist/components/z-stack/ZStack.js +70 -0
- package/dist/components/z-stack/ZStack.js.map +1 -0
- package/dist/components/z-stack/index.d.ts +2 -0
- package/dist/components/z-stack/index.d.ts.map +1 -0
- package/dist/components/z-stack/index.js +2 -0
- package/dist/components/z-stack/index.js.map +1 -0
- package/dist/frame.d.ts +2 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +2 -0
- package/dist/frame.js.map +1 -0
- package/dist/grid.d.ts +1 -1
- package/dist/grid.d.ts.map +1 -1
- package/dist/grid.js.map +1 -1
- package/dist/image.d.ts +1 -1
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +1 -1
- package/dist/image.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/section.d.ts +2 -0
- package/dist/section.d.ts.map +1 -0
- package/dist/section.js +2 -0
- package/dist/section.js.map +1 -0
- package/dist/stack.d.ts +1 -1
- package/dist/stack.d.ts.map +1 -1
- package/dist/stack.js.map +1 -1
- package/dist/styles/accordion.css +1 -1
- package/dist/styles/accordion.css.map +1 -1
- package/dist/styles/alert-dialog.css +1 -1
- package/dist/styles/alert-dialog.css.map +1 -1
- package/dist/styles/app-bar.css +1 -1
- package/dist/styles/app-bar.css.map +1 -1
- package/dist/styles/appearance.css +2 -0
- package/dist/styles/appearance.css.map +1 -0
- package/dist/styles/aspect-ratio.css +1 -1
- package/dist/styles/aspect-ratio.css.map +1 -1
- package/dist/styles/avatar.css +1 -1
- package/dist/styles/avatar.css.map +1 -1
- package/dist/styles/badge.css +1 -1
- package/dist/styles/badge.css.map +1 -1
- package/dist/styles/bottom-navigation.css +1 -1
- package/dist/styles/bottom-navigation.css.map +1 -1
- package/dist/styles/breadcrumb.css +1 -1
- package/dist/styles/breadcrumb.css.map +1 -1
- package/dist/styles/button.css +1 -1
- package/dist/styles/button.css.map +1 -1
- package/dist/styles/card.css +1 -1
- package/dist/styles/card.css.map +1 -1
- package/dist/styles/carousel.css +2 -0
- package/dist/styles/carousel.css.map +1 -0
- package/dist/styles/checkbox-group.css +1 -1
- package/dist/styles/checkbox-group.css.map +1 -1
- package/dist/styles/checkbox.css +1 -1
- package/dist/styles/checkbox.css.map +1 -1
- package/dist/styles/chip.css +1 -1
- package/dist/styles/chip.css.map +1 -1
- package/dist/styles/code-block.css +1 -1
- package/dist/styles/code-block.css.map +1 -1
- package/dist/styles/code.css +1 -1
- package/dist/styles/code.css.map +1 -1
- package/dist/styles/collapsible.css +1 -1
- package/dist/styles/collapsible.css.map +1 -1
- package/dist/styles/combobox.css +1 -1
- package/dist/styles/combobox.css.map +1 -1
- package/dist/styles/container.css +1 -1
- package/dist/styles/container.css.map +1 -1
- package/dist/styles/context-menu.css +1 -1
- package/dist/styles/context-menu.css.map +1 -1
- package/dist/styles/core.css +1 -1
- package/dist/styles/core.css.map +1 -1
- package/dist/styles/data-grid.css +1 -1
- package/dist/styles/data-grid.css.map +1 -1
- package/dist/styles/dialog.css +1 -1
- package/dist/styles/dialog.css.map +1 -1
- package/dist/styles/divider.css +1 -1
- package/dist/styles/divider.css.map +1 -1
- package/dist/styles/drawer.css +1 -1
- package/dist/styles/drawer.css.map +1 -1
- package/dist/styles/dropdown-menu.css +1 -1
- package/dist/styles/dropdown-menu.css.map +1 -1
- package/dist/styles/feed.css +1 -1
- package/dist/styles/feed.css.map +1 -1
- package/dist/styles/field.css +1 -1
- package/dist/styles/field.css.map +1 -1
- package/dist/styles/fieldset.css +1 -1
- package/dist/styles/fieldset.css.map +1 -1
- package/dist/styles/file-upload.css +1 -1
- package/dist/styles/file-upload.css.map +1 -1
- package/dist/styles/form.css +1 -1
- package/dist/styles/form.css.map +1 -1
- package/dist/styles/frame.css +2 -0
- package/dist/styles/frame.css.map +1 -0
- package/dist/styles/grid.css +1 -1
- package/dist/styles/grid.css.map +1 -1
- package/dist/styles/hide.css +1 -1
- package/dist/styles/hide.css.map +1 -1
- package/dist/styles/hover-card.css +1 -1
- package/dist/styles/hover-card.css.map +1 -1
- package/dist/styles/icon-button.css +1 -1
- package/dist/styles/icon-button.css.map +1 -1
- package/dist/styles/icon.css +1 -1
- package/dist/styles/icon.css.map +1 -1
- package/dist/styles/image.css +1 -1
- package/dist/styles/image.css.map +1 -1
- package/dist/styles/input.css +1 -1
- package/dist/styles/input.css.map +1 -1
- package/dist/styles/link.css +1 -1
- package/dist/styles/link.css.map +1 -1
- package/dist/styles/list.css +1 -1
- package/dist/styles/list.css.map +1 -1
- package/dist/styles/menubar.css +1 -1
- package/dist/styles/menubar.css.map +1 -1
- package/dist/styles/multi-select.css +1 -1
- package/dist/styles/multi-select.css.map +1 -1
- package/dist/styles/nav-list.css +1 -1
- package/dist/styles/nav-list.css.map +1 -1
- package/dist/styles/navigation-menu.css +1 -1
- package/dist/styles/navigation-menu.css.map +1 -1
- package/dist/styles/number-input.css +1 -1
- package/dist/styles/number-input.css.map +1 -1
- package/dist/styles/otp-field.css +1 -1
- package/dist/styles/otp-field.css.map +1 -1
- package/dist/styles/pagination.css +1 -1
- package/dist/styles/pagination.css.map +1 -1
- package/dist/styles/password-toggle-field.css +1 -1
- package/dist/styles/password-toggle-field.css.map +1 -1
- package/dist/styles/popover.css +1 -1
- package/dist/styles/popover.css.map +1 -1
- package/dist/styles/progress-circle.css +1 -1
- package/dist/styles/progress-circle.css.map +1 -1
- package/dist/styles/progress.css +1 -1
- package/dist/styles/progress.css.map +1 -1
- package/dist/styles/radio-group.css +1 -1
- package/dist/styles/radio-group.css.map +1 -1
- package/dist/styles/rating.css +1 -1
- package/dist/styles/rating.css.map +1 -1
- package/dist/styles/scroll-area.css +1 -1
- package/dist/styles/scroll-area.css.map +1 -1
- package/dist/styles/section.css +2 -0
- package/dist/styles/section.css.map +1 -0
- package/dist/styles/select.css +1 -1
- package/dist/styles/select.css.map +1 -1
- package/dist/styles/show.css +1 -1
- package/dist/styles/show.css.map +1 -1
- package/dist/styles/sidebar.css +1 -1
- package/dist/styles/sidebar.css.map +1 -1
- package/dist/styles/skeleton.css +1 -1
- package/dist/styles/skeleton.css.map +1 -1
- package/dist/styles/skip-link.css +1 -1
- package/dist/styles/skip-link.css.map +1 -1
- package/dist/styles/slider.css +1 -1
- package/dist/styles/slider.css.map +1 -1
- package/dist/styles/stack.css +1 -1
- package/dist/styles/stack.css.map +1 -1
- package/dist/styles/surface.css +1 -1
- package/dist/styles/surface.css.map +1 -1
- package/dist/styles/swipeable-item.css +1 -1
- package/dist/styles/swipeable-item.css.map +1 -1
- package/dist/styles/switch.css +1 -1
- package/dist/styles/switch.css.map +1 -1
- package/dist/styles/table.css +1 -1
- package/dist/styles/table.css.map +1 -1
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/tabs.css.map +1 -1
- package/dist/styles/text.css +1 -1
- package/dist/styles/text.css.map +1 -1
- package/dist/styles/textarea.css +1 -1
- package/dist/styles/textarea.css.map +1 -1
- package/dist/styles/toast.css +1 -1
- package/dist/styles/toast.css.map +1 -1
- package/dist/styles/toggle-group.css +1 -1
- package/dist/styles/toggle-group.css.map +1 -1
- package/dist/styles/toggle.css +1 -1
- package/dist/styles/toggle.css.map +1 -1
- package/dist/styles/toolbar.css +1 -1
- package/dist/styles/toolbar.css.map +1 -1
- package/dist/styles/tooltip.css +1 -1
- package/dist/styles/tooltip.css.map +1 -1
- package/dist/styles/tree-grid.css +1 -1
- package/dist/styles/tree-grid.css.map +1 -1
- package/dist/styles/tree.css +1 -1
- package/dist/styles/tree.css.map +1 -1
- package/dist/styles/visually-hidden.css +1 -1
- package/dist/styles/visually-hidden.css.map +1 -1
- package/dist/styles/z-stack.css +2 -0
- package/dist/styles/z-stack.css.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/dist/surface.d.ts +1 -1
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +1 -1
- package/dist/surface.js.map +1 -1
- package/dist/theme-contract.json +23663 -0
- package/dist/tokens.css +1 -1
- package/dist/tokens.css.map +1 -1
- package/dist/z-stack.d.ts +2 -0
- package/dist/z-stack.d.ts.map +1 -0
- package/dist/z-stack.js +2 -0
- package/dist/z-stack.js.map +1 -0
- package/docs/guides/appearance-and-tokens.md +97 -1
- package/docs/guides/theme-contract.md +72 -0
- package/package.json +29 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Carousel agent guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Present one item or campaign at a time with optional navigation, picker dots, touch scrolling, and user-controlled rotation.
|
|
6
|
+
|
|
7
|
+
## Use when
|
|
8
|
+
|
|
9
|
+
- Several peer items benefit from sharing one bounded visual region.
|
|
10
|
+
- A campaign hero needs multiple authored messages without placing them all in the initial viewport.
|
|
11
|
+
|
|
12
|
+
## Choose something else when
|
|
13
|
+
|
|
14
|
+
- Every item must be visible for comparison or comprehension. Use Grid, Stack, List, or Tabs.
|
|
15
|
+
- The content is only decorative image rotation. Use a non-interactive media treatment that respects reduced motion.
|
|
16
|
+
|
|
17
|
+
## Required composition
|
|
18
|
+
|
|
19
|
+
- Compose Root, Viewport, Track, and one Slide per unique value; add Navigation, Controls, Previous, Next, Picker, PickerItem, and RotationControl only when the product needs them.
|
|
20
|
+
- In a React Server Component, import the subpath as a module namespace with import * as Carousel from '@flowstack-ui/brick/carousel'; use the frozen Carousel runtime object only inside client components.
|
|
21
|
+
- When automatic rotation is enabled, always render RotationControl, Previous, and Next so people can stop and navigate the sequence; place RotationControl before Viewport in DOM order.
|
|
22
|
+
- Build campaign-specific slide content from Brick layout, typography, action, and media components; Carousel does not own hero messaging or proof content.
|
|
23
|
+
- When artwork, scrim, and copy form one peer campaign, compose a complete Surface with Media, Scrim, and Content inside each Slide; keep genuinely invariant evidence or navigation outside the rotating sequence.
|
|
24
|
+
- When a parent already owns a stable block size, use Root fill to propagate it through Carousel's Viewport, Track, and Slides; continue sizing authored Surface, Content, and layout components explicitly.
|
|
25
|
+
- Match Root radius to the visible containing geometry; use radius=none when an edge-to-edge square Surface owns the campaign boundary.
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
|
|
29
|
+
- **MUST:** Treat arrows and picker dots as optional authored controls; dots represent direct slide selection and are not Tabs.
|
|
30
|
+
- **MUST:** Never enable automatic rotation without a visible RotationControl and direct Previous and Next controls.
|
|
31
|
+
- **MUST:** Keep picker treatment independent from arrow visibility; use Picker variant bare for dots without a capsule and Navigation visibility interaction only when arrows remain discoverable through focus, pointer, and touch.
|
|
32
|
+
- **SHOULD:** Use a compact xs ghost RotationControl when the required stop mechanism should remain visually quiet; never remove it while automatic rotation can run.
|
|
33
|
+
- **MUST:** Preserve requested direction at loop boundaries and never clone authored slide content, IDs, controls, or form fields.
|
|
34
|
+
- **MUST:** Keep viewport motion instant until Atom exposes data-initialized; Brick's shipped Carousel CSS already enables smooth motion only after that signal.
|
|
35
|
+
- **SHOULD:** Give campaign slides stable responsive geometry so changing the active slide does not move surrounding page content.
|
|
36
|
+
- **MUST:** Treat fill as internal size propagation, not a viewport-height policy; the application or Block must establish the available parent height.
|
|
37
|
+
- **MUST:** Name the parent layout or section that establishes the definite block size before enabling fill; retain a real wrapper when that wrapper is the sizing box.
|
|
38
|
+
- **MUST:** Treat radius as Viewport and overlay-focus geometry only; it must not alter selection, scrolling, control placement, or slide anatomy.
|
|
39
|
+
- **MUST:** When controls overlay slides, reserve application-owned content safe areas so arrows, rotation controls, and picker targets never obscure authored text or actions.
|
|
40
|
+
- **SHOULD:** Prioritize only initially visible campaign media and defer non-current media when the image delivery layer supports it.
|
|
41
|
+
- **MUST:** Load styles.css or core.css plus carousel.css.
|
|
42
|
+
|
|
43
|
+
## Common mistakes
|
|
44
|
+
|
|
45
|
+
- **Avoid:** Using Tabs for picker dots or hiding the only way to stop autoplay. **Instead:** Use PickerItem buttons and render RotationControl whenever autoplay can run.
|
|
46
|
+
- **Avoid:** Putting unrelated proof rails or page sections inside every hero slide. **Instead:** Rotate only the peer campaign content and keep stable page evidence outside the Carousel.
|
|
47
|
+
- **Avoid:** Rotating campaign copy while leaving campaign-specific artwork behind as one unrelated background. **Instead:** Decide whether media is invariant or part of the campaign; when it communicates that campaign, place the complete Surface inside Slide.
|
|
48
|
+
- **Avoid:** Repeating block-size rules across Carousel Viewport, Track, and Slide. **Instead:** Establish the parent height once and opt into Root fill; size only the authored content inside each Slide separately.
|
|
49
|
+
|
|
50
|
+
## Validation checklist
|
|
51
|
+
|
|
52
|
+
- Check optional-control compositions, first and last boundaries in both directions, interaction-only arrow discovery, independent picker treatment, native horizontal touch scrolling, focus pause, hover pause, reduced motion, RTL, and screen-reader naming.
|
|
53
|
+
- Confirm inactive slides are unavailable to focus and assistive technology, the overlay-safe Viewport focus indicator remains visible above slide media, control focus rings remain complete at rounded edges, overlay controls do not cover content, complete campaign media changes with its copy, and slide changes do not cause page-level layout shift.
|
|
54
|
+
|
|
55
|
+
## Related guidance
|
|
56
|
+
|
|
57
|
+
- `button`
|
|
58
|
+
- `icon-button`
|
|
59
|
+
- `image`
|
|
60
|
+
- `surface`
|
|
61
|
+
- `stack`
|
|
62
|
+
- `grid`
|
|
63
|
+
- `text`
|
|
64
|
+
- `tabs`
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "flowstack.agent-component.v1",
|
|
3
|
+
"id": "collapsible",
|
|
4
|
+
"name": "Collapsible",
|
|
5
|
+
"package": "@flowstack-ui/brick",
|
|
6
|
+
"layer": "brick",
|
|
7
|
+
"kind": "component",
|
|
8
|
+
"purpose": "Reveal one independent in-flow region while Atom owns disclosure state, relationships, keyboard behavior, and measured mount lifecycle.",
|
|
9
|
+
"useWhen": [
|
|
10
|
+
"One control should progressively reveal one related region without creating an overlay or modal interaction."
|
|
11
|
+
],
|
|
12
|
+
"avoidWhen": [
|
|
13
|
+
{
|
|
14
|
+
"condition": "Several named peer sections form one coordinated set.",
|
|
15
|
+
"useInstead": "Accordion"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"condition": "The temporary content must layer, dismiss outside, lock scroll, or contain focus.",
|
|
19
|
+
"useInstead": "Dialog, Drawer, Popover, or Menu according to the interaction"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"composition": [
|
|
23
|
+
"Compose Root with one Trigger and one Content; put ContentInner inside Content so visible padding does not corrupt measured animation geometry.",
|
|
24
|
+
"Use Indicator inside Trigger for the canonical decorative state cue; normal Brick layout and content components belong inside ContentInner."
|
|
25
|
+
],
|
|
26
|
+
"rules": [
|
|
27
|
+
{
|
|
28
|
+
"id": "collapsible-anatomy",
|
|
29
|
+
"level": "must",
|
|
30
|
+
"statement": "Use Root, Trigger, Content, and ContentInner rather than rebuilding disclosure state, ARIA relationships, measurement, or animation lifecycle."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "collapsible-single-owner-trigger",
|
|
34
|
+
"level": "must",
|
|
35
|
+
"statement": "Let Collapsible Trigger own its finished control recipe; do not compose Button or Icon Button into Trigger because competing visual recipes would own one element."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "collapsible-content-padding",
|
|
39
|
+
"level": "must",
|
|
40
|
+
"statement": "Keep visible padding in ContentInner rather than Content so Atom can measure and animate the region accurately."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "collapsible-layout-role",
|
|
44
|
+
"level": "must",
|
|
45
|
+
"statement": "Use Collapsible for in-flow disclosure, not as a substitute for modal Drawer behavior or responsive Show/Hide policy."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "collapsible-css",
|
|
49
|
+
"level": "must",
|
|
50
|
+
"statement": "Load styles.css or core.css plus collapsible.css."
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"commonMistakes": [
|
|
54
|
+
{
|
|
55
|
+
"mistake": "Using Collapsible Trigger asChild around a finished Button or Icon Button.",
|
|
56
|
+
"correction": "Use Trigger as the only visual control owner and author its label, icon, and optional Indicator directly."
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"mistake": "Putting padding on Content or animating an application wrapper independently.",
|
|
60
|
+
"correction": "Keep Content as the measured motion boundary and put visible spacing in ContentInner."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"mistake": "Choosing Collapsible when the page must be inert behind the open panel.",
|
|
64
|
+
"correction": "Use Drawer or Dialog so Atom can own modal isolation, focus, dismissal, and scroll locking."
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"validation": [
|
|
68
|
+
"Test the accessible Trigger name, aria-expanded/aria-controls relationship, Enter and Space, controlled and uncontrolled state, disabled behavior, and focus retention.",
|
|
69
|
+
"Test open/close measurement, dynamic content, reduced motion, long labels, narrow widths, RTL, and horizontal overflow.",
|
|
70
|
+
"When adapting Collapsible inside another surface, report any Root geometry override instead of silently treating plain as a behavior-only recipe."
|
|
71
|
+
],
|
|
72
|
+
"related": [
|
|
73
|
+
"accordion",
|
|
74
|
+
"drawer",
|
|
75
|
+
"app-bar",
|
|
76
|
+
"nav-list",
|
|
77
|
+
"show",
|
|
78
|
+
"hide",
|
|
79
|
+
"stack"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Collapsible agent guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Reveal one independent in-flow region while Atom owns disclosure state, relationships, keyboard behavior, and measured mount lifecycle.
|
|
6
|
+
|
|
7
|
+
## Use when
|
|
8
|
+
|
|
9
|
+
- One control should progressively reveal one related region without creating an overlay or modal interaction.
|
|
10
|
+
|
|
11
|
+
## Choose something else when
|
|
12
|
+
|
|
13
|
+
- Several named peer sections form one coordinated set. Use Accordion.
|
|
14
|
+
- The temporary content must layer, dismiss outside, lock scroll, or contain focus. Use Dialog, Drawer, Popover, or Menu according to the interaction.
|
|
15
|
+
|
|
16
|
+
## Required composition
|
|
17
|
+
|
|
18
|
+
- Compose Root with one Trigger and one Content; put ContentInner inside Content so visible padding does not corrupt measured animation geometry.
|
|
19
|
+
- Use Indicator inside Trigger for the canonical decorative state cue; normal Brick layout and content components belong inside ContentInner.
|
|
20
|
+
|
|
21
|
+
## Rules
|
|
22
|
+
|
|
23
|
+
- **MUST:** Use Root, Trigger, Content, and ContentInner rather than rebuilding disclosure state, ARIA relationships, measurement, or animation lifecycle.
|
|
24
|
+
- **MUST:** Let Collapsible Trigger own its finished control recipe; do not compose Button or Icon Button into Trigger because competing visual recipes would own one element.
|
|
25
|
+
- **MUST:** Keep visible padding in ContentInner rather than Content so Atom can measure and animate the region accurately.
|
|
26
|
+
- **MUST:** Use Collapsible for in-flow disclosure, not as a substitute for modal Drawer behavior or responsive Show/Hide policy.
|
|
27
|
+
- **MUST:** Load styles.css or core.css plus collapsible.css.
|
|
28
|
+
|
|
29
|
+
## Common mistakes
|
|
30
|
+
|
|
31
|
+
- **Avoid:** Using Collapsible Trigger asChild around a finished Button or Icon Button. **Instead:** Use Trigger as the only visual control owner and author its label, icon, and optional Indicator directly.
|
|
32
|
+
- **Avoid:** Putting padding on Content or animating an application wrapper independently. **Instead:** Keep Content as the measured motion boundary and put visible spacing in ContentInner.
|
|
33
|
+
- **Avoid:** Choosing Collapsible when the page must be inert behind the open panel. **Instead:** Use Drawer or Dialog so Atom can own modal isolation, focus, dismissal, and scroll locking.
|
|
34
|
+
|
|
35
|
+
## Validation checklist
|
|
36
|
+
|
|
37
|
+
- Test the accessible Trigger name, aria-expanded/aria-controls relationship, Enter and Space, controlled and uncontrolled state, disabled behavior, and focus retention.
|
|
38
|
+
- Test open/close measurement, dynamic content, reduced motion, long labels, narrow widths, RTL, and horizontal overflow.
|
|
39
|
+
- When adapting Collapsible inside another surface, report any Root geometry override instead of silently treating plain as a behavior-only recipe.
|
|
40
|
+
|
|
41
|
+
## Related guidance
|
|
42
|
+
|
|
43
|
+
- `accordion`
|
|
44
|
+
- `drawer`
|
|
45
|
+
- `app-bar`
|
|
46
|
+
- `nav-list`
|
|
47
|
+
- `show`
|
|
48
|
+
- `hide`
|
|
49
|
+
- `stack`
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
"level": "must",
|
|
25
25
|
"statement": "Use Container rather than repeating application max-width, auto-margin, and gutter CSS across sections."
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
"id": "container-shared-geometry",
|
|
29
|
+
"level": "must",
|
|
30
|
+
"statement": "Give adjacent shell regions that must share alignment lines, such as an App Bar, hero content, and attached proof rail, the same Container measure and gutter recipe."
|
|
31
|
+
},
|
|
27
32
|
{
|
|
28
33
|
"id": "container-not-surface",
|
|
29
34
|
"level": "must",
|
|
@@ -37,18 +42,19 @@
|
|
|
37
42
|
],
|
|
38
43
|
"commonMistakes": [
|
|
39
44
|
{
|
|
40
|
-
"mistake": "Applying a separate max-width class to every page section or nesting Containers without a width reason.",
|
|
41
|
-
"correction": "Use one deliberate Container boundary per aligned content region."
|
|
45
|
+
"mistake": "Applying a separate max-width class to every page section, giving visually connected shell regions different measures or gutters, or nesting Containers without a width reason.",
|
|
46
|
+
"correction": "Use one deliberate Container boundary per aligned content region and repeat the same named measure and gutter where separate regions must share a grid line."
|
|
42
47
|
}
|
|
43
48
|
],
|
|
44
49
|
"validation": [
|
|
45
|
-
"Check gutters
|
|
50
|
+
"Check gutters, max width, and shared alignment lines at all adopted breakpoints, zoom levels, and RTL.",
|
|
46
51
|
"Confirm full-bleed and contained regions align intentionally and CSS is loaded."
|
|
47
52
|
],
|
|
48
53
|
"related": [
|
|
49
54
|
"stack",
|
|
50
55
|
"grid",
|
|
51
56
|
"surface",
|
|
52
|
-
"card"
|
|
57
|
+
"card",
|
|
58
|
+
"app-bar"
|
|
53
59
|
]
|
|
54
60
|
}
|
package/dist/agents/container.md
CHANGED
|
@@ -19,16 +19,17 @@ Own consistent centered content width, logical page gutters, and size variants f
|
|
|
19
19
|
## Rules
|
|
20
20
|
|
|
21
21
|
- **MUST:** Use Container rather than repeating application max-width, auto-margin, and gutter CSS across sections.
|
|
22
|
+
- **MUST:** Give adjacent shell regions that must share alignment lines, such as an App Bar, hero content, and attached proof rail, the same Container measure and gutter recipe.
|
|
22
23
|
- **MUST:** Do not use Container as a visual card or background owner.
|
|
23
24
|
- **MUST:** Load styles.css or core.css plus container.css.
|
|
24
25
|
|
|
25
26
|
## Common mistakes
|
|
26
27
|
|
|
27
|
-
- **Avoid:** Applying a separate max-width class to every page section or nesting Containers without a width reason. **Instead:** Use one deliberate Container boundary per aligned content region.
|
|
28
|
+
- **Avoid:** Applying a separate max-width class to every page section, giving visually connected shell regions different measures or gutters, or nesting Containers without a width reason. **Instead:** Use one deliberate Container boundary per aligned content region and repeat the same named measure and gutter where separate regions must share a grid line.
|
|
28
29
|
|
|
29
30
|
## Validation checklist
|
|
30
31
|
|
|
31
|
-
- Check gutters
|
|
32
|
+
- Check gutters, max width, and shared alignment lines at all adopted breakpoints, zoom levels, and RTL.
|
|
32
33
|
- Confirm full-bleed and contained regions align intentionally and CSS is loaded.
|
|
33
34
|
|
|
34
35
|
## Related guidance
|
|
@@ -37,3 +38,4 @@ Own consistent centered content width, logical page gutters, and size variants f
|
|
|
37
38
|
- `grid`
|
|
38
39
|
- `surface`
|
|
39
40
|
- `card`
|
|
41
|
+
- `app-bar`
|
package/dist/agents/divider.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
}
|
|
17
17
|
],
|
|
18
18
|
"composition": [
|
|
19
|
-
"Use Divider
|
|
19
|
+
"Use Divider inside the layout owner shared by the adjacent complete groups and choose decorative=false only when the separation has meaning."
|
|
20
20
|
],
|
|
21
21
|
"rules": [
|
|
22
22
|
{
|
package/dist/agents/divider.md
CHANGED
|
@@ -14,7 +14,7 @@ Render a finished decorative or semantic content boundary with horizontal or ver
|
|
|
14
14
|
|
|
15
15
|
## Required composition
|
|
16
16
|
|
|
17
|
-
- Use Divider
|
|
17
|
+
- Use Divider inside the layout owner shared by the adjacent complete groups and choose decorative=false only when the separation has meaning.
|
|
18
18
|
|
|
19
19
|
## Rules
|
|
20
20
|
|
package/dist/agents/drawer.json
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
}
|
|
17
17
|
],
|
|
18
18
|
"composition": [
|
|
19
|
-
"Compose Trigger and Portal with Overlay and Content; put a header containing Title, Description when useful, and Close inside Content, then use Stack/NavList for its body."
|
|
19
|
+
"Compose Trigger and Portal with Overlay and Content; put a header containing Title, Description when useful, and Close inside Content, then use Stack/NavList for its body.",
|
|
20
|
+
"Title is a native heading rather than a polymorphic layout host. Use its as prop to choose the heading level; do not pass a multi-element brand or layout through asChild. When the surface intentionally has no visible heading, give Content an explicit accessible name such as aria-label=\"Mobile navigation\"."
|
|
20
21
|
],
|
|
21
22
|
"rules": [
|
|
22
23
|
{
|
|
@@ -24,6 +25,11 @@
|
|
|
24
25
|
"level": "must",
|
|
25
26
|
"statement": "Use Drawer parts rather than hand-building overlay, focus trap, Escape, outside interaction, or portal behavior."
|
|
26
27
|
},
|
|
28
|
+
{
|
|
29
|
+
"id": "drawer-accessible-name",
|
|
30
|
+
"level": "must",
|
|
31
|
+
"statement": "Give Content an accessible name with a concise Title or, when no visible heading is appropriate, an explicit aria-label or aria-labelledby on Content."
|
|
32
|
+
},
|
|
27
33
|
{
|
|
28
34
|
"id": "drawer-responsive",
|
|
29
35
|
"level": "must",
|
|
@@ -58,6 +64,10 @@
|
|
|
58
64
|
{
|
|
59
65
|
"mistake": "Adding use client to an entire Next page only to dereference the legacy Drawer runtime object.",
|
|
60
66
|
"correction": "Use the RSC-safe module-namespace subpath so only Drawer remains client-owned."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"mistake": "Using asChild on Title or treating a brand lockup as a heading.",
|
|
70
|
+
"correction": "Keep branding in the visual header and name Content explicitly when there is no concise visible title."
|
|
61
71
|
}
|
|
62
72
|
],
|
|
63
73
|
"validation": [
|
package/dist/agents/drawer.md
CHANGED
|
@@ -15,10 +15,12 @@ Present a finished modal side sheet while Atom owns focus, dismissal, portal, sc
|
|
|
15
15
|
## Required composition
|
|
16
16
|
|
|
17
17
|
- Compose Trigger and Portal with Overlay and Content; put a header containing Title, Description when useful, and Close inside Content, then use Stack/NavList for its body.
|
|
18
|
+
- Title is a native heading rather than a polymorphic layout host. Use its as prop to choose the heading level; do not pass a multi-element brand or layout through asChild. When the surface intentionally has no visible heading, give Content an explicit accessible name such as aria-label="Mobile navigation".
|
|
18
19
|
|
|
19
20
|
## Rules
|
|
20
21
|
|
|
21
22
|
- **MUST:** Use Drawer parts rather than hand-building overlay, focus trap, Escape, outside interaction, or portal behavior.
|
|
23
|
+
- **MUST:** Give Content an accessible name with a concise Title or, when no visible heading is appropriate, an explicit aria-label or aria-labelledby on Content.
|
|
22
24
|
- **MUST:** Choose size and placement from content needs: use xl when content may need the viewport but should shrink when short, and full only when the surface must always fill it.
|
|
23
25
|
- **MUST:** Let top and bottom Drawers grow naturally to their selected size cap; keep long overflow in Drawer.Body instead of forcing a fixed application height.
|
|
24
26
|
- **MUST:** Use Footer justify for simple action distribution, a Brick layout component inside Footer for complex grouping, and Button fullWidth only when the action itself should fill the row.
|
|
@@ -29,6 +31,7 @@ Present a finished modal side sheet while Atom owns focus, dismissal, portal, sc
|
|
|
29
31
|
|
|
30
32
|
- **Avoid:** Building a mobile menu as an absolutely positioned div or placing Close outside the labeled content hierarchy. **Instead:** Use Drawer anatomy and compose the menu content with Brick navigation and layout components.
|
|
31
33
|
- **Avoid:** Adding use client to an entire Next page only to dereference the legacy Drawer runtime object. **Instead:** Use the RSC-safe module-namespace subpath so only Drawer remains client-owned.
|
|
34
|
+
- **Avoid:** Using asChild on Title or treating a brand lockup as a heading. **Instead:** Keep branding in the visual header and name Content explicitly when there is no concise visible title.
|
|
32
35
|
|
|
33
36
|
## Validation checklist
|
|
34
37
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "flowstack.agent-component.v1",
|
|
3
|
+
"id": "frame",
|
|
4
|
+
"name": "Frame",
|
|
5
|
+
"package": "@flowstack-ui/brick",
|
|
6
|
+
"layer": "brick",
|
|
7
|
+
"kind": "component",
|
|
8
|
+
"purpose": "Own responsive logical size constraints for one local element without taking over layout, paint, spacing, or overflow.",
|
|
9
|
+
"useWhen": [
|
|
10
|
+
"A rail, copy region, media canvas, or scroll boundary needs an explicit inline or block size constraint."
|
|
11
|
+
],
|
|
12
|
+
"avoidWhen": [
|
|
13
|
+
{
|
|
14
|
+
"condition": "The need is shared page measure, child arrangement, paint, aspect ratio, or scrolling.",
|
|
15
|
+
"useInstead": "Container, Stack/Grid, Surface, AspectRatio, or ScrollArea"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"composition": [
|
|
19
|
+
"Use Frame inside a layout Item, or let Stack.Item/Grid.Item compose asChild around Frame when one host must own both parent participation and internal constraints.",
|
|
20
|
+
"For bounded long content, put ScrollArea inside a maxBlockSize Frame; Frame constrains and ScrollArea scrolls."
|
|
21
|
+
],
|
|
22
|
+
"rules": [
|
|
23
|
+
{
|
|
24
|
+
"id": "frame-constraint-owner",
|
|
25
|
+
"level": "must",
|
|
26
|
+
"statement": "Use Frame only for inlineSize, minInlineSize, maxInlineSize, blockSize, minBlockSize, or maxBlockSize."
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "frame-logical",
|
|
30
|
+
"level": "must",
|
|
31
|
+
"statement": "Prefer logical size constraints and responsive values rather than physical width/height application classes."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "frame-parent-participation",
|
|
35
|
+
"level": "must",
|
|
36
|
+
"statement": "Keep flex/grid participation on Stack.Item or Grid.Item; Frame owns the constrained element's internal geometry."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "frame-nesting",
|
|
40
|
+
"level": "must",
|
|
41
|
+
"statement": "Use nested Frames when separate ancestors need separate constraints; each Frame keeps its base and responsive values locally scoped."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "frame-overflow",
|
|
45
|
+
"level": "must",
|
|
46
|
+
"statement": "Do not treat maxBlockSize as scrolling; compose ScrollArea when overflow must remain reachable."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "frame-css",
|
|
50
|
+
"level": "must",
|
|
51
|
+
"statement": "Load styles.css or core.css plus frame.css."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"commonMistakes": [
|
|
55
|
+
{
|
|
56
|
+
"mistake": "Turning Frame into a universal Box with paint, spacing, position, overflow, and typography props.",
|
|
57
|
+
"correction": "Keep Frame to six logical constraints and compose the existing Brick owner for every other responsibility."
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"validation": [
|
|
61
|
+
"Check responsive carry-forward, zoom/reflow, long content, RTL, vertical writing, and focus visibility.",
|
|
62
|
+
"Confirm every constrained node has one clear job and that ScrollArea owns any required overflow."
|
|
63
|
+
],
|
|
64
|
+
"related": [
|
|
65
|
+
"stack",
|
|
66
|
+
"grid",
|
|
67
|
+
"container",
|
|
68
|
+
"section",
|
|
69
|
+
"surface",
|
|
70
|
+
"aspect-ratio",
|
|
71
|
+
"scroll-area",
|
|
72
|
+
"interface-composition"
|
|
73
|
+
]
|
|
74
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Frame agent guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Own responsive logical size constraints for one local element without taking over layout, paint, spacing, or overflow.
|
|
6
|
+
|
|
7
|
+
## Use when
|
|
8
|
+
|
|
9
|
+
- A rail, copy region, media canvas, or scroll boundary needs an explicit inline or block size constraint.
|
|
10
|
+
|
|
11
|
+
## Choose something else when
|
|
12
|
+
|
|
13
|
+
- The need is shared page measure, child arrangement, paint, aspect ratio, or scrolling. Use Container, Stack/Grid, Surface, AspectRatio, or ScrollArea.
|
|
14
|
+
|
|
15
|
+
## Required composition
|
|
16
|
+
|
|
17
|
+
- Use Frame inside a layout Item, or let Stack.Item/Grid.Item compose asChild around Frame when one host must own both parent participation and internal constraints.
|
|
18
|
+
- For bounded long content, put ScrollArea inside a maxBlockSize Frame; Frame constrains and ScrollArea scrolls.
|
|
19
|
+
|
|
20
|
+
## Rules
|
|
21
|
+
|
|
22
|
+
- **MUST:** Use Frame only for inlineSize, minInlineSize, maxInlineSize, blockSize, minBlockSize, or maxBlockSize.
|
|
23
|
+
- **MUST:** Prefer logical size constraints and responsive values rather than physical width/height application classes.
|
|
24
|
+
- **MUST:** Keep flex/grid participation on Stack.Item or Grid.Item; Frame owns the constrained element's internal geometry.
|
|
25
|
+
- **MUST:** Use nested Frames when separate ancestors need separate constraints; each Frame keeps its base and responsive values locally scoped.
|
|
26
|
+
- **MUST:** Do not treat maxBlockSize as scrolling; compose ScrollArea when overflow must remain reachable.
|
|
27
|
+
- **MUST:** Load styles.css or core.css plus frame.css.
|
|
28
|
+
|
|
29
|
+
## Common mistakes
|
|
30
|
+
|
|
31
|
+
- **Avoid:** Turning Frame into a universal Box with paint, spacing, position, overflow, and typography props. **Instead:** Keep Frame to six logical constraints and compose the existing Brick owner for every other responsibility.
|
|
32
|
+
|
|
33
|
+
## Validation checklist
|
|
34
|
+
|
|
35
|
+
- Check responsive carry-forward, zoom/reflow, long content, RTL, vertical writing, and focus visibility.
|
|
36
|
+
- Confirm every constrained node has one clear job and that ScrollArea owns any required overflow.
|
|
37
|
+
|
|
38
|
+
## Related guidance
|
|
39
|
+
|
|
40
|
+
- `stack`
|
|
41
|
+
- `grid`
|
|
42
|
+
- `container`
|
|
43
|
+
- `section`
|
|
44
|
+
- `surface`
|
|
45
|
+
- `aspect-ratio`
|
|
46
|
+
- `scroll-area`
|
|
47
|
+
- `interface-composition`
|
package/dist/agents/grid.json
CHANGED
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
"level": "must",
|
|
25
25
|
"statement": "Keep DOM order meaningful; visual placement must not create a confusing keyboard or reading sequence."
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
"id": "grid-responsive-relationships",
|
|
29
|
+
"level": "must",
|
|
30
|
+
"statement": "Use responsive columns, gaps, unanchored spans, and alignment when the same authored Grid changes at Brick breakpoints; keep explicit line starts and ends static."
|
|
31
|
+
},
|
|
27
32
|
{
|
|
28
33
|
"id": "grid-item-as-child",
|
|
29
34
|
"level": "must",
|
|
@@ -40,6 +45,10 @@
|
|
|
40
45
|
"mistake": "Keeping too many columns until cards become unreadably narrow.",
|
|
41
46
|
"correction": "Reduce columns at the content's real minimum width, not at a device-name breakpoint."
|
|
42
47
|
},
|
|
48
|
+
{
|
|
49
|
+
"mistake": "Combining a responsive Item span with explicit line placement.",
|
|
50
|
+
"correction": "Let the responsive item auto-place, or keep one deliberate static line placement."
|
|
51
|
+
},
|
|
43
52
|
{
|
|
44
53
|
"mistake": "Adding a Grid.Item wrapper and height CSS around an element that should itself stretch as the grid item.",
|
|
45
54
|
"correction": "Compose that one element with Grid.Item asChild."
|
package/dist/agents/grid.md
CHANGED
|
@@ -19,12 +19,14 @@ Arrange content on tokenized two-dimensional tracks with public column, row, gap
|
|
|
19
19
|
## Rules
|
|
20
20
|
|
|
21
21
|
- **MUST:** Keep DOM order meaningful; visual placement must not create a confusing keyboard or reading sequence.
|
|
22
|
+
- **MUST:** Use responsive columns, gaps, unanchored spans, and alignment when the same authored Grid changes at Brick breakpoints; keep explicit line starts and ends static.
|
|
22
23
|
- **MUST:** Use Grid.Item asChild when an existing link, Surface, or component should itself receive placement; provide exactly one element and preserve its native semantics.
|
|
23
24
|
- **MUST:** Load styles.css or core.css plus grid.css.
|
|
24
25
|
|
|
25
26
|
## Common mistakes
|
|
26
27
|
|
|
27
28
|
- **Avoid:** Keeping too many columns until cards become unreadably narrow. **Instead:** Reduce columns at the content's real minimum width, not at a device-name breakpoint.
|
|
29
|
+
- **Avoid:** Combining a responsive Item span with explicit line placement. **Instead:** Let the responsive item auto-place, or keep one deliberate static line placement.
|
|
28
30
|
- **Avoid:** Adding a Grid.Item wrapper and height CSS around an element that should itself stretch as the grid item. **Instead:** Compose that one element with Grid.Item asChild.
|
|
29
31
|
|
|
30
32
|
## Validation checklist
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "flowstack.agent-component.v1",
|
|
3
|
+
"id": "icon",
|
|
4
|
+
"name": "Icon",
|
|
5
|
+
"package": "@flowstack-ui/brick",
|
|
6
|
+
"layer": "brick",
|
|
7
|
+
"kind": "component",
|
|
8
|
+
"purpose": "Normalize one consumer-authored SVG with Brick sizing, semantic foreground, alignment, direction, and decorative-or-informative accessibility semantics.",
|
|
9
|
+
"useWhen": [
|
|
10
|
+
"An authored SVG needs Brick size, currentColor-based tone, alignment, or opt-in directional RTL mirroring."
|
|
11
|
+
],
|
|
12
|
+
"avoidWhen": [
|
|
13
|
+
{
|
|
14
|
+
"condition": "The graphic performs an action or needs its own touch target.",
|
|
15
|
+
"useInstead": "Button, IconButton, Toggle, or the owning interactive component"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"condition": "The content is a photo, raster asset, responsive media object, fallback, or loading state.",
|
|
19
|
+
"useInstead": "Image"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"condition": "The graphic is a logo, illustration, chart, or multiregion visual with independent semantics.",
|
|
23
|
+
"useInstead": "an application-owned SVG or media composition with explicit semantics"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"composition": [
|
|
27
|
+
"Pass exactly one consumer-authored SVG element; prefer the default span wrapper and use asChild only when the direct root must remain that SVG.",
|
|
28
|
+
"When visible nearby text already provides the meaning, keep Icon decorative; when a standalone icon conveys information, provide label or aria-labelledby.",
|
|
29
|
+
"Inside an icon-only control, label the control and leave its nested Icon decorative."
|
|
30
|
+
],
|
|
31
|
+
"rules": [
|
|
32
|
+
{
|
|
33
|
+
"id": "icon-not-control",
|
|
34
|
+
"level": "must",
|
|
35
|
+
"statement": "Use Icon only for visual content; never use it as an interactive host or touch target."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "icon-accessibility-mode",
|
|
39
|
+
"level": "must",
|
|
40
|
+
"statement": "Keep the decorative default when meaning is redundant, or provide exactly one nonempty label or aria-labelledby reference when the standalone graphic is informative."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "icon-control-name",
|
|
44
|
+
"level": "must",
|
|
45
|
+
"statement": "Give an icon-only Button, IconButton, Toggle, or other control its accessible name on the control, not on its nested Icon."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "icon-current-color",
|
|
49
|
+
"level": "should",
|
|
50
|
+
"statement": "Use currentColor for single-color SVG fills or strokes so Brick tone and inherited control state can apply."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "icon-directional",
|
|
54
|
+
"level": "must",
|
|
55
|
+
"statement": "Enable directional only for glyphs whose meaning reverses in RTL, such as arrows and forward/back controls."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "icon-as-child",
|
|
59
|
+
"level": "must",
|
|
60
|
+
"statement": "Use asChild only with one direct non-interactive SVG; never compose Icon onto a button, anchor, input, or other interactive host."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "icon-layout",
|
|
64
|
+
"level": "must",
|
|
65
|
+
"statement": "Use Brick Stack, layout components, or an owning component icon slot for sibling alignment instead of wrapper spans or application offsets."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "icon-css",
|
|
69
|
+
"level": "must",
|
|
70
|
+
"statement": "Load styles.css or core.css plus icon.css."
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"commonMistakes": [
|
|
74
|
+
{
|
|
75
|
+
"mistake": "Using a raw SVG with ad hoc width, color, alignment, or ARIA inside ordinary Brick composition.",
|
|
76
|
+
"correction": "Wrap the authored SVG in Icon, choose the semantic size/tone recipe, and let the owning Stack or control align it."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"mistake": "Giving both the control and its nested Icon the same accessible label.",
|
|
80
|
+
"correction": "Label the control and keep the nested Icon decorative to prevent duplicate announcements."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"mistake": "Using directional on logos, status symbols, checks, clocks, or other glyphs that do not reverse meaning in RTL.",
|
|
84
|
+
"correction": "Leave directional false unless the glyph itself communicates direction."
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"validation": [
|
|
88
|
+
"Check decorative and informative accessibility trees, icon-only control naming, all sizes and tones, currentColor adoption, flex shrinking, and RTL directional mirroring.",
|
|
89
|
+
"Confirm asChild targets only one SVG and that CSS is present."
|
|
90
|
+
],
|
|
91
|
+
"related": [
|
|
92
|
+
"icon-button",
|
|
93
|
+
"image",
|
|
94
|
+
"button",
|
|
95
|
+
"stack",
|
|
96
|
+
"text"
|
|
97
|
+
]
|
|
98
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Icon agent guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Normalize one consumer-authored SVG with Brick sizing, semantic foreground, alignment, direction, and decorative-or-informative accessibility semantics.
|
|
6
|
+
|
|
7
|
+
## Use when
|
|
8
|
+
|
|
9
|
+
- An authored SVG needs Brick size, currentColor-based tone, alignment, or opt-in directional RTL mirroring.
|
|
10
|
+
|
|
11
|
+
## Choose something else when
|
|
12
|
+
|
|
13
|
+
- The graphic performs an action or needs its own touch target. Use Button, IconButton, Toggle, or the owning interactive component.
|
|
14
|
+
- The content is a photo, raster asset, responsive media object, fallback, or loading state. Use Image.
|
|
15
|
+
- The graphic is a logo, illustration, chart, or multiregion visual with independent semantics. Use an application-owned SVG or media composition with explicit semantics.
|
|
16
|
+
|
|
17
|
+
## Required composition
|
|
18
|
+
|
|
19
|
+
- Pass exactly one consumer-authored SVG element; prefer the default span wrapper and use asChild only when the direct root must remain that SVG.
|
|
20
|
+
- When visible nearby text already provides the meaning, keep Icon decorative; when a standalone icon conveys information, provide label or aria-labelledby.
|
|
21
|
+
- Inside an icon-only control, label the control and leave its nested Icon decorative.
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
- **MUST:** Use Icon only for visual content; never use it as an interactive host or touch target.
|
|
26
|
+
- **MUST:** Keep the decorative default when meaning is redundant, or provide exactly one nonempty label or aria-labelledby reference when the standalone graphic is informative.
|
|
27
|
+
- **MUST:** Give an icon-only Button, IconButton, Toggle, or other control its accessible name on the control, not on its nested Icon.
|
|
28
|
+
- **SHOULD:** Use currentColor for single-color SVG fills or strokes so Brick tone and inherited control state can apply.
|
|
29
|
+
- **MUST:** Enable directional only for glyphs whose meaning reverses in RTL, such as arrows and forward/back controls.
|
|
30
|
+
- **MUST:** Use asChild only with one direct non-interactive SVG; never compose Icon onto a button, anchor, input, or other interactive host.
|
|
31
|
+
- **MUST:** Use Brick Stack, layout components, or an owning component icon slot for sibling alignment instead of wrapper spans or application offsets.
|
|
32
|
+
- **MUST:** Load styles.css or core.css plus icon.css.
|
|
33
|
+
|
|
34
|
+
## Common mistakes
|
|
35
|
+
|
|
36
|
+
- **Avoid:** Using a raw SVG with ad hoc width, color, alignment, or ARIA inside ordinary Brick composition. **Instead:** Wrap the authored SVG in Icon, choose the semantic size/tone recipe, and let the owning Stack or control align it.
|
|
37
|
+
- **Avoid:** Giving both the control and its nested Icon the same accessible label. **Instead:** Label the control and keep the nested Icon decorative to prevent duplicate announcements.
|
|
38
|
+
- **Avoid:** Using directional on logos, status symbols, checks, clocks, or other glyphs that do not reverse meaning in RTL. **Instead:** Leave directional false unless the glyph itself communicates direction.
|
|
39
|
+
|
|
40
|
+
## Validation checklist
|
|
41
|
+
|
|
42
|
+
- Check decorative and informative accessibility trees, icon-only control naming, all sizes and tones, currentColor adoption, flex shrinking, and RTL directional mirroring.
|
|
43
|
+
- Confirm asChild targets only one SVG and that CSS is present.
|
|
44
|
+
|
|
45
|
+
## Related guidance
|
|
46
|
+
|
|
47
|
+
- `icon-button`
|
|
48
|
+
- `image`
|
|
49
|
+
- `button`
|
|
50
|
+
- `stack`
|
|
51
|
+
- `text`
|