@boostdev/design-system-components 0.1.1

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.
Files changed (233) hide show
  1. package/AGENTS.md +72 -0
  2. package/README.md +396 -0
  3. package/dist/index.cjs +2273 -0
  4. package/dist/index.css +2543 -0
  5. package/dist/index.d.cts +453 -0
  6. package/dist/index.d.ts +453 -0
  7. package/dist/index.js +2221 -0
  8. package/package.json +143 -0
  9. package/src/components/interaction/Button/Button.module.css +136 -0
  10. package/src/components/interaction/Button/Button.spec.tsx +50 -0
  11. package/src/components/interaction/Button/Button.stories.tsx +43 -0
  12. package/src/components/interaction/Button/Button.tsx +68 -0
  13. package/src/components/interaction/Button/index.ts +1 -0
  14. package/src/components/interaction/Command/Command.module.css +128 -0
  15. package/src/components/interaction/Command/Command.spec.tsx +60 -0
  16. package/src/components/interaction/Command/Command.stories.tsx +35 -0
  17. package/src/components/interaction/Command/Command.tsx +161 -0
  18. package/src/components/interaction/Command/index.ts +2 -0
  19. package/src/components/interaction/Dialog/Dialog.module.css +39 -0
  20. package/src/components/interaction/Dialog/Dialog.spec.tsx +43 -0
  21. package/src/components/interaction/Dialog/Dialog.stories.tsx +36 -0
  22. package/src/components/interaction/Dialog/Dialog.tsx +42 -0
  23. package/src/components/interaction/Dialog/index.ts +1 -0
  24. package/src/components/interaction/Drawer/Drawer.module.css +98 -0
  25. package/src/components/interaction/Drawer/Drawer.spec.tsx +43 -0
  26. package/src/components/interaction/Drawer/Drawer.stories.tsx +46 -0
  27. package/src/components/interaction/Drawer/Drawer.tsx +71 -0
  28. package/src/components/interaction/Drawer/index.ts +1 -0
  29. package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +68 -0
  30. package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +74 -0
  31. package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +68 -0
  32. package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +137 -0
  33. package/src/components/interaction/DropdownMenu/index.ts +1 -0
  34. package/src/components/interaction/Popover/Popover.module.css +39 -0
  35. package/src/components/interaction/Popover/Popover.spec.tsx +72 -0
  36. package/src/components/interaction/Popover/Popover.stories.tsx +47 -0
  37. package/src/components/interaction/Popover/Popover.tsx +78 -0
  38. package/src/components/interaction/Popover/index.ts +1 -0
  39. package/src/components/interaction/Rating/Rating.module.css +16 -0
  40. package/src/components/interaction/Rating/Rating.spec.tsx +30 -0
  41. package/src/components/interaction/Rating/Rating.stories.tsx +29 -0
  42. package/src/components/interaction/Rating/Rating.tsx +30 -0
  43. package/src/components/interaction/Rating/index.ts +1 -0
  44. package/src/components/interaction/Toast/Toast.module.css +48 -0
  45. package/src/components/interaction/Toast/Toast.spec.tsx +41 -0
  46. package/src/components/interaction/Toast/Toast.stories.tsx +57 -0
  47. package/src/components/interaction/Toast/Toast.tsx +64 -0
  48. package/src/components/interaction/Toast/index.ts +1 -0
  49. package/src/components/interaction/form/Checkbox/Checkbox.module.css +61 -0
  50. package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +39 -0
  51. package/src/components/interaction/form/Checkbox/Checkbox.stories.tsx +17 -0
  52. package/src/components/interaction/form/Checkbox/Checkbox.tsx +39 -0
  53. package/src/components/interaction/form/Checkbox/index.ts +1 -0
  54. package/src/components/interaction/form/Combobox/Combobox.module.css +104 -0
  55. package/src/components/interaction/form/Combobox/Combobox.spec.tsx +81 -0
  56. package/src/components/interaction/form/Combobox/Combobox.stories.tsx +25 -0
  57. package/src/components/interaction/form/Combobox/Combobox.tsx +182 -0
  58. package/src/components/interaction/form/Combobox/index.ts +1 -0
  59. package/src/components/interaction/form/FileInput/FileInput.module.css +79 -0
  60. package/src/components/interaction/form/FileInput/FileInput.spec.tsx +53 -0
  61. package/src/components/interaction/form/FileInput/FileInput.stories.tsx +17 -0
  62. package/src/components/interaction/form/FileInput/FileInput.tsx +99 -0
  63. package/src/components/interaction/form/FileInput/index.ts +1 -0
  64. package/src/components/interaction/form/FormInput/FormInput.module.css +37 -0
  65. package/src/components/interaction/form/FormInput/FormInput.spec.tsx +43 -0
  66. package/src/components/interaction/form/FormInput/FormInput.stories.tsx +17 -0
  67. package/src/components/interaction/form/FormInput/FormInput.tsx +47 -0
  68. package/src/components/interaction/form/FormInput/index.ts +1 -0
  69. package/src/components/interaction/form/NumberInput/NumberInput.module.css +78 -0
  70. package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +49 -0
  71. package/src/components/interaction/form/NumberInput/NumberInput.stories.tsx +17 -0
  72. package/src/components/interaction/form/NumberInput/NumberInput.tsx +106 -0
  73. package/src/components/interaction/form/NumberInput/index.ts +1 -0
  74. package/src/components/interaction/form/Radio/Radio.module.css +62 -0
  75. package/src/components/interaction/form/Radio/Radio.spec.tsx +38 -0
  76. package/src/components/interaction/form/Radio/Radio.stories.tsx +26 -0
  77. package/src/components/interaction/form/Radio/Radio.tsx +39 -0
  78. package/src/components/interaction/form/Radio/index.ts +1 -0
  79. package/src/components/interaction/form/Select/Select.module.css +64 -0
  80. package/src/components/interaction/form/Select/Select.spec.tsx +61 -0
  81. package/src/components/interaction/form/Select/Select.stories.tsx +24 -0
  82. package/src/components/interaction/form/Select/Select.tsx +72 -0
  83. package/src/components/interaction/form/Select/index.ts +1 -0
  84. package/src/components/interaction/form/Slider/Slider.module.css +99 -0
  85. package/src/components/interaction/form/Slider/Slider.spec.tsx +53 -0
  86. package/src/components/interaction/form/Slider/Slider.stories.tsx +18 -0
  87. package/src/components/interaction/form/Slider/Slider.tsx +71 -0
  88. package/src/components/interaction/form/Slider/index.ts +1 -0
  89. package/src/components/interaction/form/Switch/Switch.module.css +114 -0
  90. package/src/components/interaction/form/Switch/Switch.spec.tsx +48 -0
  91. package/src/components/interaction/form/Switch/Switch.stories.tsx +31 -0
  92. package/src/components/interaction/form/Switch/Switch.tsx +54 -0
  93. package/src/components/interaction/form/Switch/index.ts +1 -0
  94. package/src/components/interaction/form/Textarea/Textarea.module.css +44 -0
  95. package/src/components/interaction/form/Textarea/Textarea.spec.tsx +53 -0
  96. package/src/components/interaction/form/Textarea/Textarea.stories.tsx +18 -0
  97. package/src/components/interaction/form/Textarea/Textarea.tsx +44 -0
  98. package/src/components/interaction/form/Textarea/index.ts +1 -0
  99. package/src/components/interaction/form/atoms/InputContainer.module.css +9 -0
  100. package/src/components/interaction/form/atoms/InputContainer.tsx +9 -0
  101. package/src/components/interaction/form/atoms/Label.module.css +10 -0
  102. package/src/components/interaction/form/atoms/Label.tsx +15 -0
  103. package/src/components/interaction/form/atoms/Message.module.css +11 -0
  104. package/src/components/interaction/form/atoms/Message.tsx +17 -0
  105. package/src/components/layout/ButtonGroup/ButtonGroup.module.css +59 -0
  106. package/src/components/layout/ButtonGroup/ButtonGroup.spec.tsx +20 -0
  107. package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +28 -0
  108. package/src/components/layout/ButtonGroup/ButtonGroup.tsx +17 -0
  109. package/src/components/layout/ButtonGroup/index.ts +1 -0
  110. package/src/components/layout/Card/Card.module.css +72 -0
  111. package/src/components/layout/Card/Card.spec.tsx +33 -0
  112. package/src/components/layout/Card/Card.stories.tsx +32 -0
  113. package/src/components/layout/Card/Card.tsx +45 -0
  114. package/src/components/layout/Card/index.ts +1 -0
  115. package/src/components/layout/IconWrapper/IconWrapper.module.css +24 -0
  116. package/src/components/layout/IconWrapper/IconWrapper.spec.tsx +19 -0
  117. package/src/components/layout/IconWrapper/IconWrapper.stories.tsx +22 -0
  118. package/src/components/layout/IconWrapper/IconWrapper.tsx +14 -0
  119. package/src/components/layout/IconWrapper/index.ts +1 -0
  120. package/src/components/layout/SectionHeader/SectionHeader.module.css +75 -0
  121. package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +31 -0
  122. package/src/components/layout/SectionHeader/SectionHeader.stories.tsx +21 -0
  123. package/src/components/layout/SectionHeader/SectionHeader.tsx +32 -0
  124. package/src/components/layout/SectionHeader/index.ts +1 -0
  125. package/src/components/ui/Accordion/Accordion.module.css +87 -0
  126. package/src/components/ui/Accordion/Accordion.spec.tsx +78 -0
  127. package/src/components/ui/Accordion/Accordion.stories.tsx +34 -0
  128. package/src/components/ui/Accordion/Accordion.tsx +82 -0
  129. package/src/components/ui/Accordion/index.ts +1 -0
  130. package/src/components/ui/Alert/Alert.module.css +91 -0
  131. package/src/components/ui/Alert/Alert.spec.tsx +63 -0
  132. package/src/components/ui/Alert/Alert.stories.tsx +53 -0
  133. package/src/components/ui/Alert/Alert.tsx +54 -0
  134. package/src/components/ui/Alert/index.ts +1 -0
  135. package/src/components/ui/Avatar/Avatar.module.css +42 -0
  136. package/src/components/ui/Avatar/Avatar.spec.tsx +49 -0
  137. package/src/components/ui/Avatar/Avatar.stories.tsx +44 -0
  138. package/src/components/ui/Avatar/Avatar.tsx +45 -0
  139. package/src/components/ui/Avatar/index.ts +1 -0
  140. package/src/components/ui/Badge/Badge.module.css +46 -0
  141. package/src/components/ui/Badge/Badge.spec.tsx +19 -0
  142. package/src/components/ui/Badge/Badge.stories.tsx +29 -0
  143. package/src/components/ui/Badge/Badge.tsx +13 -0
  144. package/src/components/ui/Badge/index.ts +1 -0
  145. package/src/components/ui/Breadcrumb/Breadcrumb.module.css +50 -0
  146. package/src/components/ui/Breadcrumb/Breadcrumb.spec.tsx +44 -0
  147. package/src/components/ui/Breadcrumb/Breadcrumb.stories.tsx +48 -0
  148. package/src/components/ui/Breadcrumb/Breadcrumb.tsx +41 -0
  149. package/src/components/ui/Breadcrumb/index.ts +1 -0
  150. package/src/components/ui/Calendar/Calendar.module.css +120 -0
  151. package/src/components/ui/Calendar/Calendar.spec.tsx +64 -0
  152. package/src/components/ui/Calendar/Calendar.stories.tsx +59 -0
  153. package/src/components/ui/Calendar/Calendar.tsx +184 -0
  154. package/src/components/ui/Calendar/index.ts +1 -0
  155. package/src/components/ui/Carousel/Carousel.module.css +66 -0
  156. package/src/components/ui/Carousel/Carousel.spec.tsx +29 -0
  157. package/src/components/ui/Carousel/Carousel.stories.tsx +30 -0
  158. package/src/components/ui/Carousel/Carousel.tsx +64 -0
  159. package/src/components/ui/Carousel/index.ts +1 -0
  160. package/src/components/ui/DescriptionList/DescriptionList.module.css +43 -0
  161. package/src/components/ui/DescriptionList/DescriptionList.spec.tsx +31 -0
  162. package/src/components/ui/DescriptionList/DescriptionList.stories.tsx +21 -0
  163. package/src/components/ui/DescriptionList/DescriptionList.tsx +30 -0
  164. package/src/components/ui/DescriptionList/index.ts +1 -0
  165. package/src/components/ui/Link/Link.module.css +64 -0
  166. package/src/components/ui/Link/Link.spec.tsx +43 -0
  167. package/src/components/ui/Link/Link.stories.tsx +55 -0
  168. package/src/components/ui/Link/Link.tsx +42 -0
  169. package/src/components/ui/Link/index.ts +1 -0
  170. package/src/components/ui/Loading/Loading.module.css +33 -0
  171. package/src/components/ui/Loading/Loading.spec.tsx +19 -0
  172. package/src/components/ui/Loading/Loading.stories.tsx +27 -0
  173. package/src/components/ui/Loading/Loading.tsx +15 -0
  174. package/src/components/ui/Loading/index.ts +1 -0
  175. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +79 -0
  176. package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +42 -0
  177. package/src/components/ui/NotificationBanner/NotificationBanner.stories.tsx +30 -0
  178. package/src/components/ui/NotificationBanner/NotificationBanner.tsx +45 -0
  179. package/src/components/ui/NotificationBanner/index.ts +1 -0
  180. package/src/components/ui/Pagination/Pagination.module.css +78 -0
  181. package/src/components/ui/Pagination/Pagination.spec.tsx +67 -0
  182. package/src/components/ui/Pagination/Pagination.stories.tsx +40 -0
  183. package/src/components/ui/Pagination/Pagination.tsx +87 -0
  184. package/src/components/ui/Pagination/index.ts +1 -0
  185. package/src/components/ui/Progress/Progress.module.css +51 -0
  186. package/src/components/ui/Progress/Progress.spec.tsx +55 -0
  187. package/src/components/ui/Progress/Progress.stories.tsx +30 -0
  188. package/src/components/ui/Progress/Progress.tsx +43 -0
  189. package/src/components/ui/Progress/index.ts +1 -0
  190. package/src/components/ui/ProgressCircle/ProgressCircle.module.css +40 -0
  191. package/src/components/ui/ProgressCircle/ProgressCircle.spec.tsx +34 -0
  192. package/src/components/ui/ProgressCircle/ProgressCircle.stories.tsx +18 -0
  193. package/src/components/ui/ProgressCircle/ProgressCircle.tsx +75 -0
  194. package/src/components/ui/ProgressCircle/index.ts +1 -0
  195. package/src/components/ui/Separator/Separator.module.css +23 -0
  196. package/src/components/ui/Separator/Separator.spec.tsx +30 -0
  197. package/src/components/ui/Separator/Separator.stories.tsx +40 -0
  198. package/src/components/ui/Separator/Separator.tsx +21 -0
  199. package/src/components/ui/Separator/index.ts +1 -0
  200. package/src/components/ui/Skeleton/Skeleton.module.css +24 -0
  201. package/src/components/ui/Skeleton/Skeleton.spec.tsx +19 -0
  202. package/src/components/ui/Skeleton/Skeleton.stories.tsx +25 -0
  203. package/src/components/ui/Skeleton/Skeleton.tsx +12 -0
  204. package/src/components/ui/Skeleton/index.ts +1 -0
  205. package/src/components/ui/SkipLink/SkipLink.module.css +30 -0
  206. package/src/components/ui/SkipLink/SkipLink.spec.tsx +24 -0
  207. package/src/components/ui/SkipLink/SkipLink.stories.tsx +24 -0
  208. package/src/components/ui/SkipLink/SkipLink.tsx +14 -0
  209. package/src/components/ui/SkipLink/index.ts +1 -0
  210. package/src/components/ui/Table/Table.module.css +111 -0
  211. package/src/components/ui/Table/Table.spec.tsx +69 -0
  212. package/src/components/ui/Table/Table.stories.tsx +53 -0
  213. package/src/components/ui/Table/Table.tsx +98 -0
  214. package/src/components/ui/Table/index.ts +1 -0
  215. package/src/components/ui/Tabs/Tabs.module.css +61 -0
  216. package/src/components/ui/Tabs/Tabs.spec.tsx +91 -0
  217. package/src/components/ui/Tabs/Tabs.stories.tsx +59 -0
  218. package/src/components/ui/Tabs/Tabs.tsx +100 -0
  219. package/src/components/ui/Tabs/index.ts +1 -0
  220. package/src/components/ui/Tooltip/Tooltip.module.css +69 -0
  221. package/src/components/ui/Tooltip/Tooltip.spec.tsx +46 -0
  222. package/src/components/ui/Tooltip/Tooltip.stories.tsx +69 -0
  223. package/src/components/ui/Tooltip/Tooltip.tsx +38 -0
  224. package/src/components/ui/Tooltip/index.ts +1 -0
  225. package/src/components/ui/Typography/Typography.module.css +41 -0
  226. package/src/components/ui/Typography/Typography.spec.tsx +39 -0
  227. package/src/components/ui/Typography/Typography.stories.tsx +31 -0
  228. package/src/components/ui/Typography/Typography.tsx +28 -0
  229. package/src/components/ui/Typography/index.ts +1 -0
  230. package/src/css/index.css +55 -0
  231. package/src/index.ts +54 -0
  232. package/src/test/setup.ts +1 -0
  233. package/src/typings.d.ts +4 -0
package/AGENTS.md ADDED
@@ -0,0 +1,72 @@
1
+ # @boostdev/components - Agent Guide
2
+
3
+ ## What this package provides
4
+
5
+ A framework-agnostic React component library built on top of `@boostdev/design-system-foundation`.
6
+ All components use CSS Modules and consume design tokens from `@boostdev/design-system-foundation`.
7
+ Zero extra runtime — bring your own CSS reset and token layer.
8
+
9
+ ## Prerequisites
10
+
11
+ Consumers must load the design system CSS before using these components:
12
+ ```css
13
+ @import '@boostdev/design-system-foundation/css';
14
+ ```
15
+ Or individual token layers. All component styles live inside `@layer component`.
16
+
17
+ ## Component categories
18
+
19
+ - **ui/**: Pure display — Badge, Typography, Loading, Skeleton
20
+ - **interaction/**: Interactive — Button, Dialog, Toast (with Provider + hook), Rating
21
+ - **interaction/form/**: Form fields — FormInput, Checkbox, Radio (+ atom primitives Label, Message, InputContainer)
22
+ - **layout/**: Layout helpers — ButtonGroup, Card, SectionHeader, IconWrapper
23
+
24
+ ## Styling conventions
25
+
26
+ - CSS Modules (`.module.css`) for all components — styles are scoped, no global leakage
27
+ - All rules placed inside `@layer component` to sit above token layers in the cascade
28
+ - Variant classes follow the pattern `--{variant}` or `--{group}_{variant}` matching the source
29
+ - Component-level CSS custom properties (e.g. `--button_bg`) can be overridden from a parent
30
+ - Never hardcode colours, spacing, or typography values — always use design tokens
31
+
32
+ ## Token usage rules (from @boostdev/design-system-foundation)
33
+
34
+ - Colour surfaces always pair with their `on-` content token
35
+ - Space: use named scale tokens (`--space_xs`, `--space_m`, etc.), never raw px/rem
36
+ - Shadow: use elevation scale (`--shadow_s` … `--shadow_2xl`)
37
+ - Z-index: use named role tokens, never raw integers
38
+
39
+ ## Import paths
40
+
41
+ ```ts
42
+ // Named exports from the main barrel
43
+ import { Button, Badge, Typography } from '@boostdev/components';
44
+
45
+ // CSS (import once, at the app root)
46
+ import '@boostdev/components/css';
47
+ ```
48
+
49
+ ## Accessibility requirements (WCAG 2.1 AA)
50
+
51
+ Every component must meet WCAG 2.1 Level AA:
52
+
53
+ - **Semantic HTML** — use the correct element (`<button>`, `<a>`, `<nav>`, `<dialog>`, etc.)
54
+ - **Keyboard navigable** — all interactive elements reachable and operable via keyboard
55
+ - **Focus visible** — visible focus indicator on every interactive element (WCAG 2.4.7)
56
+ - **ARIA** — add `aria-label` / `aria-labelledby` / `role` where native semantics are insufficient; no redundant ARIA
57
+ - **Colour contrast** — minimum 4.5:1 for text, 3:1 for large text and UI components (WCAG 1.4.3 / 1.4.11)
58
+ - **Touch targets** — minimum 44×44px interactive area (WCAG 2.5.5)
59
+ - **State communication** — disabled, loading, error, and expanded states communicated via ARIA attributes
60
+ - **No motion harm** — respect `prefers-reduced-motion` for animations/transitions
61
+
62
+ References: https://developer.mozilla.org/en-US/docs/Web/Accessibility | https://www.w3.org/WAI/WCAG21/quickref/
63
+
64
+ ## Adding new components
65
+
66
+ 1. Create `src/components/{category}/{ComponentName}/`
67
+ 2. Add `ComponentName.tsx`, `ComponentName.module.css`, `index.ts`
68
+ 3. Wrap all CSS rules in `@layer component { ... }`
69
+ 4. Use only design token custom properties for colours, spacing, typography
70
+ 5. Re-export from the category barrel and from `src/index.ts`
71
+ 6. Meet all accessibility requirements listed above
72
+ 7. After changes: `pnpm build`, `pnpm typecheck`, `pnpm lint`, `pnpm lint:css`
package/README.md ADDED
@@ -0,0 +1,396 @@
1
+ # @boostdev/components
2
+
3
+ Accessible, token-driven React components built on [`@boostdev/design-system-foundation`](https://www.npmjs.com/package/@boostdev/design-system-foundation).
4
+ Zero extra runtime — bring your own CSS reset and token layer, then import the components.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ pnpm add @boostdev/components @boostdev/design-system-foundation
10
+ npm install @boostdev/components @boostdev/design-system-foundation
11
+ yarn add @boostdev/components @boostdev/design-system-foundation
12
+ ```
13
+
14
+ `@boostdev/design-system-foundation` is a required peer dependency. The components rely on its
15
+ CSS custom properties for all colour, spacing, and typography values.
16
+
17
+ ## Setup
18
+
19
+ Import the design system tokens and the component styles once at your app root:
20
+
21
+ ```css
22
+ /* app.css */
23
+ @import "@boostdev/design-system-foundation/css";
24
+ @import "@boostdev/components/css";
25
+ ```
26
+
27
+ Or with a JS bundler (Vite, Next.js, etc.):
28
+
29
+ ```ts
30
+ // main.ts / layout.tsx
31
+ import '@boostdev/design-system-foundation/css';
32
+ import '@boostdev/components/css';
33
+ ```
34
+
35
+ All component styles live inside `@layer component`, which sits above the token layers in the
36
+ cascade. You can override any component from outside without specificity fights.
37
+
38
+ ---
39
+
40
+ ## Usage
41
+
42
+ ### UI components
43
+
44
+ #### Badge
45
+
46
+ ```tsx
47
+ import { Badge } from '@boostdev/components';
48
+
49
+ <Badge>New</Badge>
50
+ <Badge variant="success">Active</Badge>
51
+ <Badge variant="error">Failed</Badge>
52
+ <Badge variant="warning">Pending</Badge>
53
+ <Badge variant="secondary">Draft</Badge>
54
+ ```
55
+
56
+ Variants: `primary` (default) · `secondary` · `success` · `error` · `warning`
57
+
58
+ ---
59
+
60
+ #### Typography
61
+
62
+ ```tsx
63
+ import { Typography } from '@boostdev/components';
64
+
65
+ <Typography variant="h1">Page title</Typography>
66
+ <Typography variant="h2">Section title</Typography>
67
+ <Typography variant="body">Paragraph text</Typography>
68
+ <Typography variant="body_s">Small print</Typography>
69
+ ```
70
+
71
+ Pass `component` to override the rendered element without changing the visual style:
72
+
73
+ ```tsx
74
+ <Typography variant="h2" component="h3">Visually h2, semantically h3</Typography>
75
+ ```
76
+
77
+ Variants: `h1` · `h2` · `h3` · `body` (default) · `body_s`
78
+
79
+ ---
80
+
81
+ #### Loading
82
+
83
+ ```tsx
84
+ import { Loading } from '@boostdev/components';
85
+
86
+ <Loading />
87
+ <Loading size="small" />
88
+ <Loading size="large" />
89
+ ```
90
+
91
+ Sizes: `small` · `medium` (default) · `large`
92
+
93
+ ---
94
+
95
+ #### Skeleton
96
+
97
+ ```tsx
98
+ import { Skeleton } from '@boostdev/components';
99
+
100
+ <Skeleton className="w-48 h-4" />
101
+ ```
102
+
103
+ Renders an `aria-hidden` shimmer block. Size it with a `className` or inline style.
104
+
105
+ ---
106
+
107
+ ### Interaction components
108
+
109
+ #### Button
110
+
111
+ ```tsx
112
+ import { Button } from '@boostdev/components';
113
+
114
+ <Button>Click me</Button>
115
+ <Button variant="secondary">Cancel</Button>
116
+ <Button size="small">Small</Button>
117
+ <Button href="/dashboard">Link button</Button>
118
+ <Button iconStart={<Icon />} aria-label="Delete" />
119
+ <Button hasPulse>Call to action</Button>
120
+ ```
121
+
122
+ | Prop | Type | Default |
123
+ |---|---|---|
124
+ | `variant` | `'primary' \| 'secondary'` | `'primary'` |
125
+ | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
126
+ | `href` | `string` | — renders an `<a>` |
127
+ | `iconStart` | `ReactNode` | — |
128
+ | `iconEnd` | `ReactNode` | — |
129
+ | `hasPulse` | `boolean` | `false` |
130
+ | `disabled` | `boolean` | `false` |
131
+
132
+ ---
133
+
134
+ #### Dialog
135
+
136
+ ```tsx
137
+ import { Dialog } from '@boostdev/components';
138
+
139
+ <Dialog isVisible={open} handleClose={() => setOpen(false)}>
140
+ <h2>Confirm</h2>
141
+ <p>Are you sure?</p>
142
+ </Dialog>
143
+ ```
144
+
145
+ Renders a native `<dialog>` element. `isVisible` controls open/close; `handleClose` is called
146
+ when the close button is pressed.
147
+
148
+ ---
149
+
150
+ #### Rating
151
+
152
+ ```tsx
153
+ import { Rating } from '@boostdev/components';
154
+
155
+ <Rating value={3} />
156
+ <Rating value={4} max={10} />
157
+ ```
158
+
159
+ `max` defaults to `5`. Stars are rendered as SVG icons; unfilled stars use the current
160
+ background colour.
161
+
162
+ ---
163
+
164
+ #### Toast
165
+
166
+ ```tsx
167
+ import { ToastProvider, useToast } from '@boostdev/components';
168
+
169
+ // Wrap your app (or layout) once:
170
+ <ToastProvider>
171
+ <App />
172
+ </ToastProvider>
173
+
174
+ // Inside any component:
175
+ function SaveButton() {
176
+ const { showToast } = useToast();
177
+ return (
178
+ <button onClick={() => showToast('Saved!', 'success')}>
179
+ Save
180
+ </button>
181
+ );
182
+ }
183
+ ```
184
+
185
+ `showToast(message, variant)` — variant: `'success'` · `'error'` · `'info'`
186
+
187
+ Toasts auto-dismiss after 5 seconds.
188
+
189
+ ---
190
+
191
+ ### Form components
192
+
193
+ All form components accept standard HTML input attributes via spread in addition to their own props.
194
+
195
+ #### FormInput
196
+
197
+ ```tsx
198
+ import { FormInput } from '@boostdev/components';
199
+
200
+ <FormInput
201
+ label="Email"
202
+ name="email"
203
+ type="email"
204
+ hint="We'll never share your email"
205
+ error={errors.email}
206
+ />
207
+ ```
208
+
209
+ #### Checkbox
210
+
211
+ ```tsx
212
+ import { Checkbox } from '@boostdev/components';
213
+
214
+ <Checkbox
215
+ label="I agree to the terms"
216
+ name="agree"
217
+ error={errors.agree}
218
+ />
219
+ ```
220
+
221
+ #### Radio
222
+
223
+ ```tsx
224
+ import { Radio } from '@boostdev/components';
225
+
226
+ <Radio label="Option A" name="choice" value="a" />
227
+ <Radio label="Option B" name="choice" value="b" />
228
+ ```
229
+
230
+ ---
231
+
232
+ ### Layout components
233
+
234
+ #### ButtonGroup
235
+
236
+ ```tsx
237
+ import { ButtonGroup, Button } from '@boostdev/components';
238
+
239
+ <ButtonGroup variant="flow">
240
+ <Button>Back</Button>
241
+ <Button>Next</Button>
242
+ </ButtonGroup>
243
+ ```
244
+
245
+ Variants: `flow` · `card` · `modal` · `content`
246
+
247
+ ---
248
+
249
+ #### Card
250
+
251
+ ```tsx
252
+ import { Card } from '@boostdev/components';
253
+
254
+ <Card>Basic card</Card>
255
+ <Card variant="elevated" padding="large">Elevated</Card>
256
+ <Card variant="outlined" textAlign="center">Outlined</Card>
257
+ <Card onClick={() => navigate('/detail')}>Clickable card</Card>
258
+ ```
259
+
260
+ | Prop | Type | Default |
261
+ |---|---|---|
262
+ | `variant` | `'default' \| 'elevated' \| 'outlined'` | `'default'` |
263
+ | `padding` | `'none' \| 'small' \| 'medium' \| 'large'` | `'medium'` |
264
+ | `textAlign` | `'start' \| 'center' \| 'end'` | `'start'` |
265
+ | `onClick` | `() => void` | — renders a `<button>` |
266
+
267
+ ---
268
+
269
+ #### SectionHeader
270
+
271
+ ```tsx
272
+ import { SectionHeader } from '@boostdev/components';
273
+
274
+ <SectionHeader title="Our services" />
275
+ <SectionHeader
276
+ title="Welcome"
277
+ subtitle="Everything you need in one place"
278
+ size="large"
279
+ alignment="center"
280
+ />
281
+ ```
282
+
283
+ | Prop | Type | Default |
284
+ |---|---|---|
285
+ | `title` | `string` | required |
286
+ | `subtitle` | `string` | — |
287
+ | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
288
+ | `alignment` | `'start' \| 'center' \| 'end'` | `'start'` |
289
+
290
+ ---
291
+
292
+ #### IconWrapper
293
+
294
+ ```tsx
295
+ import { IconWrapper } from '@boostdev/components';
296
+
297
+ <IconWrapper>
298
+ <svg>...</svg>
299
+ </IconWrapper>
300
+ ```
301
+
302
+ Renders a circular container sized to its own `font-size`. Override the background colour via the
303
+ `--icon-wrapper-color` CSS custom property.
304
+
305
+ ---
306
+
307
+ ### Utilities
308
+
309
+ #### cn
310
+
311
+ Composes class name strings, filtering out falsy values:
312
+
313
+ ```ts
314
+ import { cn } from '@boostdev/components';
315
+
316
+ cn('card', isActive && 'card--active', [extraClass])
317
+ // → "card card--active extraClass"
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Overriding component styles
323
+
324
+ Every component exposes CSS custom properties as a styling API. Set them on a parent or via
325
+ `style` to adjust the component without writing extra CSS:
326
+
327
+ ```css
328
+ /* Override the button background for a specific context */
329
+ .hero .button {
330
+ --button_bg: var(--color_brand);
331
+ --button_text: var(--color_on-brand);
332
+ }
333
+ ```
334
+
335
+ All component styles sit in `@layer component`. You can also write rules in a higher layer:
336
+
337
+ ```css
338
+ @layer my-overrides {
339
+ .my-button {
340
+ border-radius: 0;
341
+ }
342
+ }
343
+ ```
344
+
345
+ ---
346
+
347
+ ## Theming
348
+
349
+ Components inherit from `@boostdev/design-system-foundation` tokens. Override semantic tokens to
350
+ retheme all components at once:
351
+
352
+ ```css
353
+ /* tokens.config.css — import after the design system CSS */
354
+ @layer tokens.override {
355
+ :root {
356
+ --color_cta: var(--BASE__color--orange);
357
+ --color_on-cta: var(--BASE__color--white);
358
+ --color_interactive: var(--BASE__color--orange);
359
+ }
360
+ }
361
+ ```
362
+
363
+ Dark mode is handled automatically via `[data-theme="dark"]` or `prefers-color-scheme`.
364
+
365
+ ---
366
+
367
+ ## Development
368
+
369
+ ```bash
370
+ pnpm build # compile to dist/
371
+ pnpm typecheck # TypeScript check (library code only)
372
+ pnpm lint # ESLint
373
+ pnpm lint:css # Stylelint
374
+ pnpm test # Vitest — 71 tests
375
+ pnpm storybook # Storybook dev server on port 6006
376
+ ```
377
+
378
+ ### Adding a new component
379
+
380
+ 1. Create `src/components/{category}/{Name}/`
381
+ 2. Add `Name.tsx`, `Name.module.css`, `index.ts`
382
+ 3. Wrap all CSS in `@layer component { ... }`
383
+ 4. Use only design token custom properties — no hard-coded colours, spacing, or font sizes
384
+ 5. Re-export from `src/index.ts`
385
+ 6. Run `pnpm build && pnpm typecheck && pnpm lint && pnpm lint:css && pnpm test`
386
+
387
+ ---
388
+
389
+ ## Publishing a new version
390
+
391
+ ```bash
392
+ npm version patch # or minor / major
393
+ git push --follow-tags
394
+ ```
395
+
396
+ GitLab CI will build and publish to npm automatically on version tags.