@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.
- package/AGENTS.md +72 -0
- package/README.md +396 -0
- package/dist/index.cjs +2273 -0
- package/dist/index.css +2543 -0
- package/dist/index.d.cts +453 -0
- package/dist/index.d.ts +453 -0
- package/dist/index.js +2221 -0
- package/package.json +143 -0
- package/src/components/interaction/Button/Button.module.css +136 -0
- package/src/components/interaction/Button/Button.spec.tsx +50 -0
- package/src/components/interaction/Button/Button.stories.tsx +43 -0
- package/src/components/interaction/Button/Button.tsx +68 -0
- package/src/components/interaction/Button/index.ts +1 -0
- package/src/components/interaction/Command/Command.module.css +128 -0
- package/src/components/interaction/Command/Command.spec.tsx +60 -0
- package/src/components/interaction/Command/Command.stories.tsx +35 -0
- package/src/components/interaction/Command/Command.tsx +161 -0
- package/src/components/interaction/Command/index.ts +2 -0
- package/src/components/interaction/Dialog/Dialog.module.css +39 -0
- package/src/components/interaction/Dialog/Dialog.spec.tsx +43 -0
- package/src/components/interaction/Dialog/Dialog.stories.tsx +36 -0
- package/src/components/interaction/Dialog/Dialog.tsx +42 -0
- package/src/components/interaction/Dialog/index.ts +1 -0
- package/src/components/interaction/Drawer/Drawer.module.css +98 -0
- package/src/components/interaction/Drawer/Drawer.spec.tsx +43 -0
- package/src/components/interaction/Drawer/Drawer.stories.tsx +46 -0
- package/src/components/interaction/Drawer/Drawer.tsx +71 -0
- package/src/components/interaction/Drawer/index.ts +1 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +68 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +74 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +68 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +137 -0
- package/src/components/interaction/DropdownMenu/index.ts +1 -0
- package/src/components/interaction/Popover/Popover.module.css +39 -0
- package/src/components/interaction/Popover/Popover.spec.tsx +72 -0
- package/src/components/interaction/Popover/Popover.stories.tsx +47 -0
- package/src/components/interaction/Popover/Popover.tsx +78 -0
- package/src/components/interaction/Popover/index.ts +1 -0
- package/src/components/interaction/Rating/Rating.module.css +16 -0
- package/src/components/interaction/Rating/Rating.spec.tsx +30 -0
- package/src/components/interaction/Rating/Rating.stories.tsx +29 -0
- package/src/components/interaction/Rating/Rating.tsx +30 -0
- package/src/components/interaction/Rating/index.ts +1 -0
- package/src/components/interaction/Toast/Toast.module.css +48 -0
- package/src/components/interaction/Toast/Toast.spec.tsx +41 -0
- package/src/components/interaction/Toast/Toast.stories.tsx +57 -0
- package/src/components/interaction/Toast/Toast.tsx +64 -0
- package/src/components/interaction/Toast/index.ts +1 -0
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +61 -0
- package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +39 -0
- package/src/components/interaction/form/Checkbox/Checkbox.stories.tsx +17 -0
- package/src/components/interaction/form/Checkbox/Checkbox.tsx +39 -0
- package/src/components/interaction/form/Checkbox/index.ts +1 -0
- package/src/components/interaction/form/Combobox/Combobox.module.css +104 -0
- package/src/components/interaction/form/Combobox/Combobox.spec.tsx +81 -0
- package/src/components/interaction/form/Combobox/Combobox.stories.tsx +25 -0
- package/src/components/interaction/form/Combobox/Combobox.tsx +182 -0
- package/src/components/interaction/form/Combobox/index.ts +1 -0
- package/src/components/interaction/form/FileInput/FileInput.module.css +79 -0
- package/src/components/interaction/form/FileInput/FileInput.spec.tsx +53 -0
- package/src/components/interaction/form/FileInput/FileInput.stories.tsx +17 -0
- package/src/components/interaction/form/FileInput/FileInput.tsx +99 -0
- package/src/components/interaction/form/FileInput/index.ts +1 -0
- package/src/components/interaction/form/FormInput/FormInput.module.css +37 -0
- package/src/components/interaction/form/FormInput/FormInput.spec.tsx +43 -0
- package/src/components/interaction/form/FormInput/FormInput.stories.tsx +17 -0
- package/src/components/interaction/form/FormInput/FormInput.tsx +47 -0
- package/src/components/interaction/form/FormInput/index.ts +1 -0
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +78 -0
- package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +49 -0
- package/src/components/interaction/form/NumberInput/NumberInput.stories.tsx +17 -0
- package/src/components/interaction/form/NumberInput/NumberInput.tsx +106 -0
- package/src/components/interaction/form/NumberInput/index.ts +1 -0
- package/src/components/interaction/form/Radio/Radio.module.css +62 -0
- package/src/components/interaction/form/Radio/Radio.spec.tsx +38 -0
- package/src/components/interaction/form/Radio/Radio.stories.tsx +26 -0
- package/src/components/interaction/form/Radio/Radio.tsx +39 -0
- package/src/components/interaction/form/Radio/index.ts +1 -0
- package/src/components/interaction/form/Select/Select.module.css +64 -0
- package/src/components/interaction/form/Select/Select.spec.tsx +61 -0
- package/src/components/interaction/form/Select/Select.stories.tsx +24 -0
- package/src/components/interaction/form/Select/Select.tsx +72 -0
- package/src/components/interaction/form/Select/index.ts +1 -0
- package/src/components/interaction/form/Slider/Slider.module.css +99 -0
- package/src/components/interaction/form/Slider/Slider.spec.tsx +53 -0
- package/src/components/interaction/form/Slider/Slider.stories.tsx +18 -0
- package/src/components/interaction/form/Slider/Slider.tsx +71 -0
- package/src/components/interaction/form/Slider/index.ts +1 -0
- package/src/components/interaction/form/Switch/Switch.module.css +114 -0
- package/src/components/interaction/form/Switch/Switch.spec.tsx +48 -0
- package/src/components/interaction/form/Switch/Switch.stories.tsx +31 -0
- package/src/components/interaction/form/Switch/Switch.tsx +54 -0
- package/src/components/interaction/form/Switch/index.ts +1 -0
- package/src/components/interaction/form/Textarea/Textarea.module.css +44 -0
- package/src/components/interaction/form/Textarea/Textarea.spec.tsx +53 -0
- package/src/components/interaction/form/Textarea/Textarea.stories.tsx +18 -0
- package/src/components/interaction/form/Textarea/Textarea.tsx +44 -0
- package/src/components/interaction/form/Textarea/index.ts +1 -0
- package/src/components/interaction/form/atoms/InputContainer.module.css +9 -0
- package/src/components/interaction/form/atoms/InputContainer.tsx +9 -0
- package/src/components/interaction/form/atoms/Label.module.css +10 -0
- package/src/components/interaction/form/atoms/Label.tsx +15 -0
- package/src/components/interaction/form/atoms/Message.module.css +11 -0
- package/src/components/interaction/form/atoms/Message.tsx +17 -0
- package/src/components/layout/ButtonGroup/ButtonGroup.module.css +59 -0
- package/src/components/layout/ButtonGroup/ButtonGroup.spec.tsx +20 -0
- package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +28 -0
- package/src/components/layout/ButtonGroup/ButtonGroup.tsx +17 -0
- package/src/components/layout/ButtonGroup/index.ts +1 -0
- package/src/components/layout/Card/Card.module.css +72 -0
- package/src/components/layout/Card/Card.spec.tsx +33 -0
- package/src/components/layout/Card/Card.stories.tsx +32 -0
- package/src/components/layout/Card/Card.tsx +45 -0
- package/src/components/layout/Card/index.ts +1 -0
- package/src/components/layout/IconWrapper/IconWrapper.module.css +24 -0
- package/src/components/layout/IconWrapper/IconWrapper.spec.tsx +19 -0
- package/src/components/layout/IconWrapper/IconWrapper.stories.tsx +22 -0
- package/src/components/layout/IconWrapper/IconWrapper.tsx +14 -0
- package/src/components/layout/IconWrapper/index.ts +1 -0
- package/src/components/layout/SectionHeader/SectionHeader.module.css +75 -0
- package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +31 -0
- package/src/components/layout/SectionHeader/SectionHeader.stories.tsx +21 -0
- package/src/components/layout/SectionHeader/SectionHeader.tsx +32 -0
- package/src/components/layout/SectionHeader/index.ts +1 -0
- package/src/components/ui/Accordion/Accordion.module.css +87 -0
- package/src/components/ui/Accordion/Accordion.spec.tsx +78 -0
- package/src/components/ui/Accordion/Accordion.stories.tsx +34 -0
- package/src/components/ui/Accordion/Accordion.tsx +82 -0
- package/src/components/ui/Accordion/index.ts +1 -0
- package/src/components/ui/Alert/Alert.module.css +91 -0
- package/src/components/ui/Alert/Alert.spec.tsx +63 -0
- package/src/components/ui/Alert/Alert.stories.tsx +53 -0
- package/src/components/ui/Alert/Alert.tsx +54 -0
- package/src/components/ui/Alert/index.ts +1 -0
- package/src/components/ui/Avatar/Avatar.module.css +42 -0
- package/src/components/ui/Avatar/Avatar.spec.tsx +49 -0
- package/src/components/ui/Avatar/Avatar.stories.tsx +44 -0
- package/src/components/ui/Avatar/Avatar.tsx +45 -0
- package/src/components/ui/Avatar/index.ts +1 -0
- package/src/components/ui/Badge/Badge.module.css +46 -0
- package/src/components/ui/Badge/Badge.spec.tsx +19 -0
- package/src/components/ui/Badge/Badge.stories.tsx +29 -0
- package/src/components/ui/Badge/Badge.tsx +13 -0
- package/src/components/ui/Badge/index.ts +1 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.module.css +50 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.spec.tsx +44 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.stories.tsx +48 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.tsx +41 -0
- package/src/components/ui/Breadcrumb/index.ts +1 -0
- package/src/components/ui/Calendar/Calendar.module.css +120 -0
- package/src/components/ui/Calendar/Calendar.spec.tsx +64 -0
- package/src/components/ui/Calendar/Calendar.stories.tsx +59 -0
- package/src/components/ui/Calendar/Calendar.tsx +184 -0
- package/src/components/ui/Calendar/index.ts +1 -0
- package/src/components/ui/Carousel/Carousel.module.css +66 -0
- package/src/components/ui/Carousel/Carousel.spec.tsx +29 -0
- package/src/components/ui/Carousel/Carousel.stories.tsx +30 -0
- package/src/components/ui/Carousel/Carousel.tsx +64 -0
- package/src/components/ui/Carousel/index.ts +1 -0
- package/src/components/ui/DescriptionList/DescriptionList.module.css +43 -0
- package/src/components/ui/DescriptionList/DescriptionList.spec.tsx +31 -0
- package/src/components/ui/DescriptionList/DescriptionList.stories.tsx +21 -0
- package/src/components/ui/DescriptionList/DescriptionList.tsx +30 -0
- package/src/components/ui/DescriptionList/index.ts +1 -0
- package/src/components/ui/Link/Link.module.css +64 -0
- package/src/components/ui/Link/Link.spec.tsx +43 -0
- package/src/components/ui/Link/Link.stories.tsx +55 -0
- package/src/components/ui/Link/Link.tsx +42 -0
- package/src/components/ui/Link/index.ts +1 -0
- package/src/components/ui/Loading/Loading.module.css +33 -0
- package/src/components/ui/Loading/Loading.spec.tsx +19 -0
- package/src/components/ui/Loading/Loading.stories.tsx +27 -0
- package/src/components/ui/Loading/Loading.tsx +15 -0
- package/src/components/ui/Loading/index.ts +1 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +79 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +42 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.stories.tsx +30 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.tsx +45 -0
- package/src/components/ui/NotificationBanner/index.ts +1 -0
- package/src/components/ui/Pagination/Pagination.module.css +78 -0
- package/src/components/ui/Pagination/Pagination.spec.tsx +67 -0
- package/src/components/ui/Pagination/Pagination.stories.tsx +40 -0
- package/src/components/ui/Pagination/Pagination.tsx +87 -0
- package/src/components/ui/Pagination/index.ts +1 -0
- package/src/components/ui/Progress/Progress.module.css +51 -0
- package/src/components/ui/Progress/Progress.spec.tsx +55 -0
- package/src/components/ui/Progress/Progress.stories.tsx +30 -0
- package/src/components/ui/Progress/Progress.tsx +43 -0
- package/src/components/ui/Progress/index.ts +1 -0
- package/src/components/ui/ProgressCircle/ProgressCircle.module.css +40 -0
- package/src/components/ui/ProgressCircle/ProgressCircle.spec.tsx +34 -0
- package/src/components/ui/ProgressCircle/ProgressCircle.stories.tsx +18 -0
- package/src/components/ui/ProgressCircle/ProgressCircle.tsx +75 -0
- package/src/components/ui/ProgressCircle/index.ts +1 -0
- package/src/components/ui/Separator/Separator.module.css +23 -0
- package/src/components/ui/Separator/Separator.spec.tsx +30 -0
- package/src/components/ui/Separator/Separator.stories.tsx +40 -0
- package/src/components/ui/Separator/Separator.tsx +21 -0
- package/src/components/ui/Separator/index.ts +1 -0
- package/src/components/ui/Skeleton/Skeleton.module.css +24 -0
- package/src/components/ui/Skeleton/Skeleton.spec.tsx +19 -0
- package/src/components/ui/Skeleton/Skeleton.stories.tsx +25 -0
- package/src/components/ui/Skeleton/Skeleton.tsx +12 -0
- package/src/components/ui/Skeleton/index.ts +1 -0
- package/src/components/ui/SkipLink/SkipLink.module.css +30 -0
- package/src/components/ui/SkipLink/SkipLink.spec.tsx +24 -0
- package/src/components/ui/SkipLink/SkipLink.stories.tsx +24 -0
- package/src/components/ui/SkipLink/SkipLink.tsx +14 -0
- package/src/components/ui/SkipLink/index.ts +1 -0
- package/src/components/ui/Table/Table.module.css +111 -0
- package/src/components/ui/Table/Table.spec.tsx +69 -0
- package/src/components/ui/Table/Table.stories.tsx +53 -0
- package/src/components/ui/Table/Table.tsx +98 -0
- package/src/components/ui/Table/index.ts +1 -0
- package/src/components/ui/Tabs/Tabs.module.css +61 -0
- package/src/components/ui/Tabs/Tabs.spec.tsx +91 -0
- package/src/components/ui/Tabs/Tabs.stories.tsx +59 -0
- package/src/components/ui/Tabs/Tabs.tsx +100 -0
- package/src/components/ui/Tabs/index.ts +1 -0
- package/src/components/ui/Tooltip/Tooltip.module.css +69 -0
- package/src/components/ui/Tooltip/Tooltip.spec.tsx +46 -0
- package/src/components/ui/Tooltip/Tooltip.stories.tsx +69 -0
- package/src/components/ui/Tooltip/Tooltip.tsx +38 -0
- package/src/components/ui/Tooltip/index.ts +1 -0
- package/src/components/ui/Typography/Typography.module.css +41 -0
- package/src/components/ui/Typography/Typography.spec.tsx +39 -0
- package/src/components/ui/Typography/Typography.stories.tsx +31 -0
- package/src/components/ui/Typography/Typography.tsx +28 -0
- package/src/components/ui/Typography/index.ts +1 -0
- package/src/css/index.css +55 -0
- package/src/index.ts +54 -0
- package/src/test/setup.ts +1 -0
- 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.
|