@dezkareid/components 1.0.0 → 1.0.2

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 (61) hide show
  1. package/dist/components.min.css +1 -1
  2. package/dist/css/tag.module.css.js +1 -1
  3. package/dist/css/theme-toggle.module.css.js +1 -1
  4. package/dist/react/Button/index.d.ts +3 -3
  5. package/dist/react/Button/index.d.ts.map +1 -1
  6. package/dist/react/Button/index.js +1 -1
  7. package/dist/react/Button/index.js.map +1 -1
  8. package/dist/react/Card/index.d.ts +3 -3
  9. package/dist/react/Card/index.d.ts.map +1 -1
  10. package/dist/react/Card/index.js.map +1 -1
  11. package/dist/react/Tag/index.d.ts +3 -3
  12. package/dist/react/Tag/index.d.ts.map +1 -1
  13. package/dist/react/Tag/index.js.map +1 -1
  14. package/dist/react/ThemeToggle/index.d.ts.map +1 -1
  15. package/dist/react/ThemeToggle/index.js +6 -2
  16. package/dist/react/ThemeToggle/index.js.map +1 -1
  17. package/dist/shared/js/theme.js +4 -4
  18. package/dist/shared/js/theme.js.map +1 -1
  19. package/dist/shared/types/button.d.ts +1 -1
  20. package/dist/shared/types/button.d.ts.map +1 -1
  21. package/dist/shared/types/card.d.ts +2 -1
  22. package/dist/shared/types/card.d.ts.map +1 -1
  23. package/dist/shared/types/tag.d.ts +2 -2
  24. package/dist/shared/types/tag.d.ts.map +1 -1
  25. package/dist/shared/types/theme-toggle.d.ts +1 -2
  26. package/dist/shared/types/theme-toggle.d.ts.map +1 -1
  27. package/package.json +18 -5
  28. package/src/astro/Button/index.astro +1 -1
  29. package/src/astro/ThemeToggle/index.astro +49 -11
  30. package/src/css/button.module.css +49 -14
  31. package/src/css/card.module.css +3 -1
  32. package/src/css/tag.module.css +21 -7
  33. package/src/css/theme-toggle.module.css +26 -0
  34. package/src/react/Button/index.test.tsx +17 -7
  35. package/src/react/Button/index.tsx +4 -3
  36. package/src/react/Card/index.test.tsx +13 -3
  37. package/src/react/Card/index.tsx +3 -3
  38. package/src/react/Tag/index.test.tsx +10 -0
  39. package/src/react/Tag/index.tsx +3 -3
  40. package/src/react/ThemeToggle/index.test.tsx +25 -2
  41. package/src/react/ThemeToggle/index.tsx +57 -9
  42. package/src/shared/js/theme.ts +4 -4
  43. package/src/shared/types/button.ts +1 -1
  44. package/src/shared/types/card.ts +2 -1
  45. package/src/shared/types/tag.ts +2 -2
  46. package/src/shared/types/theme-toggle.ts +1 -3
  47. package/src/vue/Button/index.vue +1 -1
  48. package/src/vue/ThemeToggle/index.vue +52 -9
  49. package/.releaserc +0 -18
  50. package/.turbo/turbo-build.log +0 -7
  51. package/.turbo/turbo-test.log +0 -17
  52. package/AGENTS.md +0 -174
  53. package/CHANGELOG.md +0 -12
  54. package/done/2026-03-03-design-system-components/osddt.plan.md +0 -233
  55. package/done/2026-03-03-design-system-components/osddt.spec.md +0 -90
  56. package/done/2026-03-03-design-system-components/osddt.tasks.md +0 -100
  57. package/rollup.config.mjs +0 -32
  58. package/setupTests.ts +0 -1
  59. package/tsconfig.json +0 -19
  60. package/vite.config.build.ts +0 -34
  61. package/vitest.config.ts +0 -12
package/AGENTS.md DELETED
@@ -1,174 +0,0 @@
1
- # @dezkareid/components
2
-
3
- A package to export UI components in formats like React, Astro, Vue, etc.
4
-
5
- ## Overview
6
-
7
- Always use Context7 MCP when I need external library/API documentation, code generation, setup or configuration steps without me having to explicitly ask.
8
-
9
- The following paths are the entry points to the different packages:
10
-
11
- - `src/react/`: React components (entry: `src/react/index.ts`)
12
- - `src/astro/`: Astro components (entry: `src/astro/index.ts`)
13
- - `src/vue/`: Vue components (entry: `src/vue/index.ts`)
14
- - `src/css/`: Shared CSS Modules (one file per component, `src/css/index.ts` imports all for the CSS bundle)
15
- - `src/shared/js/`: Framework-agnostic JS utilities
16
- - `src/shared/types/`: Shared TypeScript interfaces for all components
17
-
18
- ## Package Exports
19
-
20
- | Export | Points to | Compiled? |
21
- |---|---|---|
22
- | `@dezkareid/components/react` | `dist/react.js` | Yes — pre-compiled ES module via Rollup + `@rollup/plugin-typescript` |
23
- | `@dezkareid/components/astro` | `src/astro/index.ts` | No — compiled by the consuming Astro app |
24
- | `@dezkareid/components/vue` | `src/vue/index.ts` | No — compiled by the consuming Vite/Vue app |
25
- | `@dezkareid/components/css` | `dist/components.min.css` | Yes — CSS Modules processed and extracted via `rollup-plugin-postcss` |
26
-
27
- ### Why Astro and Vue are not pre-compiled
28
-
29
- - **Astro** `.astro` files require Astro's own compiler — they cannot be pre-compiled to generic JS
30
- - **Vue** SFCs are best compiled by the consumer's Vite for correct SSR and template optimisation
31
-
32
- ## Build
33
-
34
- The build uses **Rollup** (`rollup.config.mjs`) — not Vite — because `rollup-plugin-postcss` handles CSS Modules extraction correctly in Rollup without conflicts.
35
-
36
- The build produces:
37
- - `dist/react.js` — ES module barrel entry
38
- - `dist/react/**/*.js` — individual component chunks (tree-shakeable via `preserveModules`)
39
- - `dist/react/**/*.d.ts` — TypeScript declarations
40
- - `dist/components.min.css` — all CSS Modules processed, scoped, and bundled into one file
41
-
42
- Key plugins:
43
- - `rollup-plugin-postcss` with `autoModules: true, extract: 'components.min.css', minimize: true` — processes CSS Modules and extracts to a single file
44
- - `@rollup/plugin-typescript` with `declaration: true` — compiles TSX and emits `.d.ts` files
45
- - `@rollup/plugin-node-resolve` — resolves node_modules
46
-
47
- ### CSS Modules in the build
48
-
49
- CSS class names are scoped (hashed) by `postcss-modules`. The JS proxy files (e.g. `dist/css/button.module.css.js`) export the class name map so React components can reference the correct hashed names. The `dist/components.min.css` file contains the matching scoped styles.
50
-
51
- Consumers **must** import `@dezkareid/components/css` once at their app root — styles are not auto-injected into JS.
52
-
53
- ## Development
54
-
55
- Each component lives in its own folder within each framework directory, e.g. `src/react/Button/index.tsx`.
56
-
57
- A component set should include:
58
-
59
- - `src/shared/types/<component>.ts` — shared TypeScript props interface
60
- - `src/css/<component>.module.css` — BEM + OOCSS styles using design tokens only
61
- - `src/react/<Component>/index.tsx` — React implementation
62
- - `src/react/<Component>/index.test.tsx` — Vitest + RTL tests (React only)
63
- - `src/astro/<Component>/index.astro` — Astro implementation
64
- - `src/vue/<Component>/index.vue` — Vue SFC implementation
65
-
66
- ### CSS conventions
67
-
68
- - Use **BEM** for class naming: `.block`, `.block--modifier`, `.block__element`
69
- - Use **OOCSS** to separate structure (layout/sizing/spacing) from skin (colour/border/shadow)
70
- - All values must use CSS custom properties from `@dezkareid/design-tokens` — never hardcode hex, rgb, or px values
71
- - Use semantic tokens (`--color-primary`, `--color-text-primary`, etc.) for automatic light/dark support
72
- - When a needed token doesn't exist, use the closest base token and add a `TODO: Propose --token-name` comment
73
-
74
- ### Available components
75
-
76
- #### Button
77
-
78
- File: `src/react/Button/index.tsx` | `src/astro/Button/index.astro` | `src/vue/Button/index.vue`
79
- Types: `src/shared/types/button.ts` | CSS: `src/css/button.module.css`
80
-
81
- Props:
82
- - `variant?: 'primary' | 'secondary'` — default `'primary'`
83
- - `size?: 'sm' | 'md' | 'lg'` — default `'md'`
84
- - `disabled?: boolean` — default `false`
85
- - Forwards all native `<button>` HTML attributes
86
-
87
- BEM classes: `.button`, `.button--primary`, `.button--secondary`, `.button--sm`, `.button--md`, `.button--lg`, `.button--disabled`
88
-
89
- #### Tag
90
-
91
- File: `src/react/Tag/index.tsx` | `src/astro/Tag/index.astro` | `src/vue/Tag/index.vue`
92
- Types: `src/shared/types/tag.ts` | CSS: `src/css/tag.module.css`
93
-
94
- Props:
95
- - `variant?: 'default' | 'success' | 'danger'` — default `'default'`
96
- - Accepts arbitrary `children`/slot content (not limited to plain text)
97
-
98
- BEM classes: `.tag`, `.tag--default`, `.tag--success`, `.tag--danger`
99
-
100
- #### Card
101
-
102
- File: `src/react/Card/index.tsx` | `src/astro/Card/index.astro` | `src/vue/Card/index.vue`
103
- Types: `src/shared/types/card.ts` | CSS: `src/css/card.module.css`
104
-
105
- Props:
106
- - `elevation?: 'flat' | 'raised'` — default `'raised'`
107
- - Accepts arbitrary `children`/slot content
108
-
109
- BEM classes: `.card`, `.card--raised`, `.card--flat`
110
-
111
- Note: `--shadow-raised` token is proposed but not yet in `@dezkareid/design-tokens`; currently uses a raw `box-shadow` value.
112
-
113
- #### ThemeToggle
114
-
115
- File: `src/react/ThemeToggle/index.tsx` | `src/astro/ThemeToggle/index.astro` | `src/vue/ThemeToggle/index.vue`
116
- Types: `src/shared/types/theme-toggle.ts` | CSS: `src/css/theme-toggle.module.css`
117
- Shared logic: `src/shared/js/theme.ts`
118
-
119
- Props: none (self-contained stateful component)
120
-
121
- Behaviour:
122
- - On mount: reads `localStorage.getItem('color-scheme')`; falls back to `window.matchMedia('(prefers-color-scheme: dark)')`
123
- - On toggle: flips theme, calls `applyTheme()` (sets `color-scheme` on `<html>`), calls `persistTheme()` (writes to `localStorage`)
124
- - Astro version includes an inline `<script is:inline>` for FOUC prevention
125
- - All `window`/`localStorage` access is SSR-safe (`typeof window !== 'undefined'` guards in `theme.ts`)
126
-
127
- BEM classes: `.theme-toggle`, `.theme-toggle--dark`
128
-
129
- And offer support for the next characteristics:
130
-
131
- - Multi-theme support
132
- - Mobile first
133
- - Accessibility support
134
- - Performance focused
135
-
136
- To choose colors use the `design-tokens` skill (already have multi-theme support). When you need to use a color not defined in the design tokens you can propose a new color to be added to the design tokens using a commentary in the code.
137
-
138
- ## Critical Dependency Versions
139
-
140
- The following versions are established across the project's packages and should be respected when adding new dependencies or troubleshooting.
141
-
142
- ### Core Languages & Runtimes
143
- - **TypeScript**: `5.9.3`
144
-
145
- ### Build & Bundling Tools
146
- - **Rollup**: `4.56.0`
147
- - **Vite**: `7.3.1` (via `@vitejs/plugin-react`)
148
- - **@vitejs/plugin-react**: `5.1.4`
149
-
150
- ### Testing Frameworks
151
- - **Vitest**: `4.0.18`
152
- - **React Testing Library**: `16.3.2`
153
- - **jsdom**: `27.4.0`
154
-
155
- ### Linting & Formatting
156
- - **ESLint**: `9.39.2`
157
- - **Prettier**: `3.8.1`
158
-
159
- ### Type Definitions
160
- - **@types/node**: `25.0.10`
161
- - **@types/react**: `19.2.9`
162
- - **@types/fs-extra**: `11.0.4`
163
- - **@types/jest**: `30.0.0`
164
-
165
- ### Key Libraries
166
- - **React**: `19.2.4` (Peer dependency: `^18.0.0 || ^19.0.0`)
167
- - **React DOM**: `19.2.4`
168
-
169
- ## Documentation
170
-
171
- - `README.md`: The source to use the package.
172
- - `AGENTS.md`: The source to understand the package for ai-assisted tools.
173
-
174
- When a component is created or modified, consider update those files with the new information.
package/CHANGELOG.md DELETED
@@ -1,12 +0,0 @@
1
- # @dezkareid/components-v1.0.0 (2026-03-04)
2
-
3
-
4
- ### Bug Fixes
5
-
6
- * set right build scripts ([5418aa9](https://github.com/dezkareid/dezkareid/commit/5418aa97e19e1e0f52a25db21c509433dd16e452))
7
-
8
-
9
- ### Features
10
-
11
- * **components:** add tag, theme toggle, card and button ([036cf28](https://github.com/dezkareid/dezkareid/commit/036cf288de3958d0726f4c224190dd58cf3ba5c7))
12
- * release components ([93e8372](https://github.com/dezkareid/dezkareid/commit/93e8372146e1549f8d58d7883254cebdff716bbf))
@@ -1,233 +0,0 @@
1
- # Implementation Plan: Design System Components
2
-
3
- ## Architecture Overview
4
-
5
- ### Directory Structure
6
-
7
- Framework-specific components are grouped by framework. CSS and shared logic live in a top-level `shared/` folder, keeping styling and utilities decoupled from any framework.
8
-
9
- ```
10
- src/
11
- css/
12
- button.module.css # Button BEM + OOCSS classes
13
- tag.module.css # Tag BEM + OOCSS classes
14
- card.module.css # Card BEM + OOCSS classes
15
- theme-toggle.module.css # ThemeToggle BEM + OOCSS classes
16
- shared/
17
- js/
18
- theme.ts # ThemeToggle logic (read/write localStorage, apply color-scheme)
19
- types/
20
- button.ts # ButtonProps interface
21
- tag.ts # TagProps interface
22
- card.ts # CardProps interface
23
- theme-toggle.ts # ThemeToggleProps interface
24
- react/
25
- Button/
26
- index.tsx
27
- index.test.tsx
28
- Tag/
29
- index.tsx
30
- index.test.tsx
31
- Card/
32
- index.tsx
33
- index.test.tsx
34
- ThemeToggle/
35
- index.tsx
36
- index.test.tsx
37
- index.ts # Barrel: exports all React components
38
- astro/
39
- Button/
40
- index.astro
41
- Tag/
42
- index.astro
43
- Card/
44
- index.astro
45
- ThemeToggle/
46
- index.astro
47
- index.ts # Barrel: exports all Astro components
48
- vue/
49
- Button/
50
- index.vue
51
- Tag/
52
- index.vue
53
- Card/
54
- index.vue
55
- ThemeToggle/
56
- index.vue
57
- index.ts # Barrel: exports all Vue components
58
- ```
59
-
60
- ### Styling Strategy
61
-
62
- - **CSS Modules** for component-scoped styles, located in `src/css/`.
63
- - **BEM** for class naming within each module: block (`button`), element (`button__label`), modifier (`button--primary`, `button--sm`, `button--disabled`).
64
- - **OOCSS** to separate structural responsibility from skin responsibility:
65
- - *Structure classes* define layout, sizing, spacing, and display behaviour (e.g. `.button`, `.card`).
66
- - *Skin classes* define colour, border, shadow, and typography (e.g. `.button--primary`, `.tag--success`, `.card--raised`).
67
- - Framework files compose both structure and skin classes together.
68
- - All colour, spacing, and font values use CSS custom properties from `@dezkareid/design-tokens`.
69
- - Semantic tokens (`--color-background-primary`, `--color-text-primary`, etc.) are used exclusively — no raw hex/px values.
70
-
71
- ### Theming
72
-
73
- - The `color-scheme` attribute on `<html>` drives light/dark switching.
74
- - `ThemeToggle` is the only component that reads/writes theme state. All other components are passive consumers of semantic tokens.
75
- - `ThemeToggle` uses `localStorage` (key: `color-scheme`) for persistence and falls back to `prefers-color-scheme`.
76
-
77
- ### TypeScript
78
-
79
- - Shared prop interfaces/types are defined in `src/shared/types/<component>.ts` and imported by all three framework implementations.
80
- - Strict typing; no `any`.
81
-
82
- ### Testing
83
-
84
- - React implementations only (as per spec).
85
- - Vitest + React Testing Library.
86
- - Tests cover: rendering variants, disabled states, slot/children content, ThemeToggle localStorage and OS-preference behaviour.
87
-
88
- ### Entry Points
89
-
90
- The package will expose three sub-path exports:
91
- - `@dezkareid/components/react` → all React components
92
- - `@dezkareid/components/astro` → all Astro components
93
- - `@dezkareid/components/vue` → all Vue components
94
-
95
- `package.json` `exports` field will be configured accordingly.
96
-
97
- ---
98
-
99
- ## Implementation Phases
100
-
101
- ### Phase 1 — Package Setup
102
-
103
- **Goal**: Establish the build infrastructure, folder layout, and entry points before writing any component code.
104
-
105
- - Configure `package.json` with `exports` for `react/`, `astro/`, and `vue/` sub-paths.
106
- - Create the full directory skeleton: `src/css/`, `src/shared/js/`, `src/shared/types/`, `src/react/`, `src/astro/`, `src/vue/`.
107
- - Create barrel `index.ts` files for each framework entry point (`src/react/index.ts`, `src/astro/index.ts`, `src/vue/index.ts`).
108
- - Verify that `@dezkareid/design-tokens` is available as a dependency and that its CSS token file can be imported from `src/css/`.
109
- - Set up Vitest config (if not present) targeting `src/react/**/*.test.tsx`.
110
-
111
- ### Phase 2 — Button Component
112
-
113
- **Goal**: Implement the Button component across all three frameworks with full variant, size, and disabled support.
114
-
115
- - Define `ButtonProps` in `src/shared/types/button.ts`: `variant: 'primary' | 'secondary'`, `size: 'sm' | 'md' | 'lg'`, `disabled?: boolean`, `children/slot`.
116
- - Write `src/css/button.module.css` using BEM + OOCSS:
117
- - **Structure**: `.button` — `display: inline-flex`, `align-items: center`, `cursor: pointer`, `border: none`, `border-radius`.
118
- - **Structure modifiers** (size): `.button--sm`, `.button--md`, `.button--lg` — vary `padding` and `font-size` via spacing/font tokens.
119
- - **Skin modifiers** (variant): `.button--primary` — `background-color: var(--color-primary)`, `color: var(--color-text-inverse)`; `.button--secondary` — `background-color: transparent`, `border: 1px solid var(--color-primary)`, `color: var(--color-primary)`.
120
- - **State modifier**: `.button--disabled` — reduced opacity, `cursor: not-allowed`, `pointer-events: none`.
121
- - Implement `src/react/Button/index.tsx` — renders `<button>`, composes BEM classes from CSS module, passes through native button props.
122
- - Implement `src/astro/Button/index.astro`.
123
- - Implement `src/vue/Button/index.vue`.
124
- - Write `src/react/Button/index.test.tsx`: renders each variant, renders each size, disabled prevents click, accessible role.
125
-
126
- ### Phase 3 — Tag Component
127
-
128
- **Goal**: Implement the Tag component across all three frameworks with semantic colour variants and children support.
129
-
130
- - Define `TagProps` in `src/shared/types/tag.ts`: `variant: 'default' | 'success' | 'danger'`, `children/slot`.
131
- - Write `src/css/tag.module.css` using BEM + OOCSS:
132
- - **Structure**: `.tag` — `display: inline-flex`, `align-items: center`, `border-radius`, `padding: var(--spacing-4) var(--spacing-8)`, `font-size: var(--font-size-100)`.
133
- - **Skin modifiers** (variant): `.tag--default` — `background-color: var(--color-background-secondary)`, `color: var(--color-text-primary)`; `.tag--success` — `background-color: var(--color-success)`, `color: var(--color-text-inverse)`; `.tag--danger` — `background-color: var(--color-base-red-500)`, `color: var(--color-text-inverse)`. *(Note: propose `--color-danger` semantic token for the design-tokens package.)*
134
- - Implement `src/react/Tag/index.tsx` — renders a `<span>`, composes BEM classes, accepts `children`.
135
- - Implement `src/astro/Tag/index.astro`.
136
- - Implement `src/vue/Tag/index.vue`.
137
- - Write `src/react/Tag/index.test.tsx`: renders each variant, renders slot/children content.
138
-
139
- ### Phase 4 — Card Component
140
-
141
- **Goal**: Implement the Card component across all three frameworks with flat and raised elevation.
142
-
143
- - Define `CardProps` in `src/shared/types/card.ts`: `elevation?: 'flat' | 'raised'` (default: `'raised'`), `children/slot`.
144
- - Write `src/css/card.module.css` using BEM + OOCSS:
145
- - **Structure**: `.card` — `display: block`, `border-radius`, `padding: var(--spacing-24)`, `width: 100%`.
146
- - **Skin** (base): `.card` — `background-color: var(--color-background-secondary)`, `color: var(--color-text-primary)`.
147
- - **Skin modifiers** (elevation): `.card--raised` — `box-shadow: 0 2px 8px rgba(0,0,0,0.12)` *(propose `--shadow-raised` token)*; `.card--flat` — no shadow.
148
- - Implement `src/react/Card/index.tsx` — renders a `<div>`, composes BEM classes, accepts `children`.
149
- - Implement `src/astro/Card/index.astro`.
150
- - Implement `src/vue/Card/index.vue`.
151
- - Write `src/react/Card/index.test.tsx`: renders children, applies correct elevation class.
152
-
153
- ### Phase 5 — ThemeToggle Component
154
-
155
- **Goal**: Implement the ThemeToggle component across all three frameworks with localStorage persistence and OS preference fallback.
156
-
157
- - Define `ThemeToggleProps` in `src/shared/types/theme-toggle.ts`: no required props (self-contained stateful component).
158
- - Extract shared theme logic to `src/shared/js/theme.ts`:
159
- - `getInitialTheme(): 'light' | 'dark'` — reads `localStorage.getItem('color-scheme')`; falls back to `window.matchMedia('(prefers-color-scheme: dark)').matches`.
160
- - `applyTheme(theme: 'light' | 'dark'): void` — sets `document.documentElement.setAttribute('color-scheme', theme)`.
161
- - `persistTheme(theme: 'light' | 'dark'): void` — writes to `localStorage`.
162
- - All functions guard against `typeof window === 'undefined'` for SSR safety.
163
- - Write `src/css/theme-toggle.module.css` using BEM + OOCSS:
164
- - **Structure**: `.theme-toggle` — `display: inline-flex`, `align-items: center`, `cursor: pointer`, `padding`, `border: none`.
165
- - **Skin**: `.theme-toggle` — `background-color: transparent`, `color: var(--color-text-primary)`.
166
- - **State modifier**: `.theme-toggle--dark` — visual indicator for dark mode active state.
167
- - Implement `src/react/ThemeToggle/index.tsx` — uses `useState` + `useEffect`, calls `src/shared/js/theme.ts` utilities.
168
- - Implement `src/astro/ThemeToggle/index.astro` — static markup + inline `<script>` that imports and calls `src/shared/js/theme.ts`.
169
- - Implement `src/vue/ThemeToggle/index.vue` — uses `ref` + `onMounted`, calls shared utilities.
170
- - Write `src/react/ThemeToggle/index.test.tsx`: initialises from `localStorage`, initialises from `prefers-color-scheme` when no stored value, toggles on click, persists to `localStorage`.
171
-
172
- ### Phase 6 — Exports & Package Configuration
173
-
174
- **Goal**: Wire all components into the entry points and validate the exports map.
175
-
176
- - Update `src/react/index.ts` to re-export `Button`, `Tag`, `Card`, `ThemeToggle` from their respective sub-folders.
177
- - Update `src/astro/index.ts` to re-export Astro components.
178
- - Update `src/vue/index.ts` to re-export Vue components.
179
- - Update `package.json` `exports`:
180
- ```json
181
- {
182
- "./react": "./src/react/index.ts",
183
- "./astro": "./src/astro/index.ts",
184
- "./vue": "./src/vue/index.ts"
185
- }
186
- ```
187
- - Verify build compiles without errors.
188
-
189
- ### Phase 7 — Documentation
190
-
191
- **Goal**: Update `README.md` and `AGENTS.md` to reflect the new components.
192
-
193
- - Add installation note for `@dezkareid/design-tokens` CSS requirement.
194
- - Add usage examples for each component in each framework format.
195
- - Update `AGENTS.md` with component API summaries.
196
-
197
- ---
198
-
199
- ## Technical Dependencies
200
-
201
- | Dependency | Purpose | Already Present? |
202
- |---|---|---|
203
- | `@dezkareid/design-tokens` | CSS token variables | To verify |
204
- | `react` / `react-dom` | React runtime | Peer dep |
205
- | `vue` | Vue runtime | To add as peer dep |
206
- | `astro` | Astro runtime | To add as peer dep |
207
- | `vitest` | Test runner | To configure |
208
- | `@testing-library/react` | React test utilities | To configure |
209
- | `jsdom` | DOM environment for tests | To configure |
210
- | `typescript` | Type checking | To configure |
211
-
212
- ---
213
-
214
- ## Risks & Mitigations
215
-
216
- | Risk | Mitigation |
217
- |---|---|
218
- | Missing semantic tokens (e.g. `--color-danger`, `--shadow-raised`) | Use base tokens as fallback; add inline comments proposing new tokens to the design-tokens package |
219
- | CSS Modules not supported in Astro/Vue by default | Astro natively supports CSS Modules; Vue supports them via `<style module>` — both are straightforward |
220
- | `localStorage` access in SSR/Astro contexts | Wrap all `localStorage` access in `typeof window !== 'undefined'` guards; use `is:inline` or `client:load` in Astro |
221
- | ThemeToggle hydration flash (FOUC) | Emit an inline `<script>` that applies the theme before first paint (Astro strategy); React version uses `useEffect` which may flash — document as a known limitation |
222
- | Vue not yet configured as a peer dependency | Add `vue` peer dep to `package.json` in Phase 1 |
223
-
224
- ---
225
-
226
- ## Out of Scope
227
-
228
- - Icon library (no icon assets bundled with components).
229
- - Animation/transition system.
230
- - Loading state or icon-only Button variant.
231
- - Storybook or visual regression tooling.
232
- - SSR-optimised theme detection beyond the `<script>` injection approach.
233
- - Astro and Vue unit tests (React tests only, per spec).
@@ -1,90 +0,0 @@
1
- # Feature Specification: Design System Components
2
-
3
- ## Overview
4
-
5
- Add four foundational UI components — **Button**, **Tag**, **Card**, and **ThemeToggle** — to the `@dezkareid/components` package. These components form the core building blocks of the personal design system, enabling consistent, accessible, and theme-aware UI across all surfaces that consume the package (React, Astro, Vue).
6
-
7
- Each component must ship in all three framework formats (React, Astro, Vue), use design tokens for all visual properties, and support light/dark theming automatically.
8
-
9
- ---
10
-
11
- ## Requirements
12
-
13
- ### Button
14
-
15
- - Renders a clickable element that triggers an action.
16
- - Supports at least two visual variants: **primary** (filled) and **secondary** (outlined).
17
- - Supports a **disabled** state that prevents interaction and communicates non-interactivity visually.
18
- - Accepts a label via slot/children.
19
- - Must be keyboard-accessible and announce its role to assistive technologies.
20
-
21
- ### Tag
22
-
23
- - Renders a small inline label used to categorise or annotate content.
24
- - Supports at least three semantic colour variants: **default**, **success**, and **danger**.
25
- - Is non-interactive (display only).
26
- - Text content is passed via slot/children.
27
- - Must be readable by assistive technologies (appropriate role/label).
28
-
29
- ### Card
30
-
31
- - Renders a contained surface that groups related content.
32
- - Accepts arbitrary content via slot/children (title, body, actions).
33
- - Provides consistent internal spacing and a distinct background relative to the page.
34
- - Must be usable as a layout container with no fixed height.
35
-
36
- ### ThemeToggle
37
-
38
- - Renders a toggle control that switches the active colour scheme between light and dark.
39
- - The current theme state is reflected visually (icon or label change).
40
- - Toggling persists the preference to `localStorage` under the key `color-scheme`.
41
- - On initial load, reads `localStorage` first; falls back to the OS `prefers-color-scheme` preference.
42
- - Theme is applied by setting `color-scheme` on the `<html>` element (`light` or `dark`).
43
- - Must be keyboard-accessible and communicate its current state to assistive technologies.
44
-
45
- ---
46
-
47
- ## Scope
48
-
49
- ### In scope
50
-
51
- - React, Astro, and Vue implementations for all four components.
52
- - Design-token-driven styling (no hardcoded colour or spacing values).
53
- - Automatic light/dark theme support via CSS semantic tokens.
54
- - Accessible markup (keyboard navigation, ARIA roles/attributes where needed).
55
- - Mobile-first responsive behaviour.
56
- - Unit/integration tests for the React implementations.
57
- - TypeScript prop types/interfaces for all components.
58
- - Updated `README.md` and `AGENTS.md` with usage examples for each component.
59
-
60
- ### Out of scope
61
-
62
- - Icon library integration (icons may be addressed as a follow-up).
63
- - Animation or transition systems.
64
- - Complex compound variants (e.g. icon-only Button, loading state).
65
- - Storybook or visual regression tooling.
66
- - Server-side rendering (SSR) specific configuration.
67
-
68
- ---
69
-
70
- ## Acceptance Criteria
71
-
72
- 1. **Button** renders correctly in primary and secondary variants and is disabled when `disabled` is set.
73
- 2. **Tag** renders in default, success, and danger variants using the correct semantic colour tokens.
74
- 3. **Card** renders its children inside a visually distinct surface with consistent spacing.
75
- 4. **ThemeToggle** switches the `color-scheme` attribute on `<html>` and persists the value to `localStorage`.
76
- 5. **ThemeToggle** reads `localStorage` on mount and applies the stored value; if absent, applies the OS preference.
77
- 6. All components pass accessibility checks (keyboard focus, ARIA) without errors.
78
- 7. All components render correctly in both light and dark modes using semantic tokens only.
79
- 8. React implementations have passing unit tests.
80
- 9. Each component is exported from the appropriate entry point (`react/`, `astro/`, `vue/`).
81
- 10. `README.md` includes import and usage examples for all four components.
82
-
83
- ---
84
-
85
- ## Decisions
86
-
87
- 1. **Button sizes**: Button will support three size variants — small, medium, and large — via a `size` prop.
88
- 2. **Tag dismissibility**: Tag remains display-only with no close action. It must accept arbitrary content via slot/children (not just a plain text string).
89
- 3. **Card elevation**: Card will support two elevation levels — **flat** (no shadow) and **raised** (with shadow) — via an `elevation` prop.
90
- 4. **ThemeToggle framework scope**: ThemeToggle will ship in all three framework formats (React, Astro, Vue), consistent with the other components.
@@ -1,100 +0,0 @@
1
- # Task List: Design System Components
2
-
3
- ---
4
-
5
- ## Phase 1 — Package Setup
6
-
7
- > All Phase 2–7 tasks depend on Phase 1 being complete.
8
-
9
- - [x] [S] Configure `package.json`: add `exports` map for `./react`, `./astro`, `./vue` sub-paths, and add `vue` + `astro` as peer dependencies
10
- - [x] [S] Create directory skeleton: `src/css/`, `src/shared/js/`, `src/shared/types/`, `src/react/`, `src/astro/`, `src/vue/`
11
- - [x] [S] Create empty barrel files: `src/react/index.ts`, `src/astro/index.ts`, `src/vue/index.ts`
12
- - [x] [S] Verify `@dezkareid/design-tokens` is installed and its CSS token file is importable; add as dependency if missing
13
- - [x] [M] Set up Vitest config targeting `src/react/**/*.test.tsx` with jsdom environment and React Testing Library
14
-
15
- **Definition of Done**: `package.json` has correct exports and peer deps; all directories exist; Vitest runs (no tests yet, zero failures).
16
-
17
- ---
18
-
19
- ## Phase 2 — Button Component
20
-
21
- > Depends on: Phase 1
22
-
23
- - [x] [S] Define `ButtonProps` interface in `src/shared/types/button.ts` (`variant`, `size`, `disabled`, `children`)
24
- - [x] [M] Write `src/css/button.module.css` — structure (`.button`, size modifiers `.button--sm/md/lg`) and skin (variant modifiers `.button--primary/secondary`, state modifier `.button--disabled`) using BEM + OOCSS
25
- - [x] [M] Implement `src/react/Button/index.tsx` — composes BEM classes, forwards native button props
26
- - [x] [M] Write `src/react/Button/index.test.tsx` — renders primary/secondary variants, renders sm/md/lg sizes, disabled prevents click, has accessible button role
27
- - [x] [M] Implement `src/astro/Button/index.astro`
28
- - [x] [M] Implement `src/vue/Button/index.vue`
29
-
30
- **Definition of Done**: Button renders all variants and sizes in all three frameworks; React tests pass; no hardcoded colour or spacing values.
31
-
32
- ---
33
-
34
- ## Phase 3 — Tag Component
35
-
36
- > Depends on: Phase 1
37
-
38
- - [x] [S] Define `TagProps` interface in `src/shared/types/tag.ts` (`variant`, `children`)
39
- - [x] [M] Write `src/css/tag.module.css` — structure (`.tag`) and skin (variant modifiers `.tag--default/success/danger`) using BEM + OOCSS; add comment proposing `--color-danger` semantic token
40
- - [x] [M] Implement `src/react/Tag/index.tsx` — renders `<span>`, accepts `children`, composes BEM classes
41
- - [x] [M] Write `src/react/Tag/index.test.tsx` — renders default/success/danger variants, renders arbitrary children content
42
- - [x] [M] Implement `src/astro/Tag/index.astro`
43
- - [x] [M] Implement `src/vue/Tag/index.vue`
44
-
45
- **Definition of Done**: Tag renders all variants with correct colours in all three frameworks; accepts arbitrary slot/children; React tests pass.
46
-
47
- ---
48
-
49
- ## Phase 4 — Card Component
50
-
51
- > Depends on: Phase 1
52
-
53
- - [x] [S] Define `CardProps` interface in `src/shared/types/card.ts` (`elevation`, `children`; default elevation `'raised'`)
54
- - [x] [M] Write `src/css/card.module.css` — structure (`.card`) and skin (base skin on `.card`, elevation modifiers `.card--raised/flat`) using BEM + OOCSS; add comment proposing `--shadow-raised` token
55
- - [x] [M] Implement `src/react/Card/index.tsx` — renders `<div>`, accepts `children`, composes BEM classes
56
- - [x] [M] Write `src/react/Card/index.test.tsx` — renders children, applies `card--raised` by default, applies `card--flat` when set
57
- - [x] [M] Implement `src/astro/Card/index.astro`
58
- - [x] [M] Implement `src/vue/Card/index.vue`
59
-
60
- **Definition of Done**: Card renders children inside a themed surface with correct elevation in all three frameworks; React tests pass.
61
-
62
- ---
63
-
64
- ## Phase 5 — ThemeToggle Component
65
-
66
- > Depends on: Phase 1
67
-
68
- - [x] [S] Define `ThemeToggleProps` interface in `src/shared/types/theme-toggle.ts` (no required props)
69
- - [x] [M] Implement shared theme utilities in `src/shared/js/theme.ts`: `getInitialTheme()`, `applyTheme()`, `persistTheme()` — all SSR-safe with `typeof window` guards
70
- - [x] [M] Write `src/css/theme-toggle.module.css` — structure (`.theme-toggle`) and skin + state modifier (`.theme-toggle--dark`) using BEM + OOCSS
71
- - [x] [M] Implement `src/react/ThemeToggle/index.tsx` — uses `useState` + `useEffect`, calls shared theme utilities
72
- - [x] [L] Write `src/react/ThemeToggle/index.test.tsx` — initialises from `localStorage`, falls back to `prefers-color-scheme`, toggles on click, persists to `localStorage`
73
- - [x] [M] Implement `src/astro/ThemeToggle/index.astro` — static markup + inline `<script>` calling shared utilities
74
- - [x] [M] Implement `src/vue/ThemeToggle/index.vue` — uses `ref` + `onMounted`, calls shared utilities
75
-
76
- **Definition of Done**: ThemeToggle reads, applies, and persists theme in all three frameworks; React tests pass; no FOUC in Astro (inline script runs before paint).
77
-
78
- ---
79
-
80
- ## Phase 6 — Exports & Package Configuration
81
-
82
- > Depends on: Phases 2–5
83
-
84
- - [x] [S] Update `src/react/index.ts` to re-export `Button`, `Tag`, `Card`, `ThemeToggle`
85
- - [x] [S] Update `src/astro/index.ts` to re-export all Astro components
86
- - [x] [S] Update `src/vue/index.ts` to re-export all Vue components
87
- - [x] [S] Verify `package.json` `exports` paths resolve correctly (smoke check imports)
88
-
89
- **Definition of Done**: All components importable from `@dezkareid/components/react`, `/astro`, and `/vue`; no TypeScript errors.
90
-
91
- ---
92
-
93
- ## Phase 7 — Documentation
94
-
95
- > Depends on: Phase 6
96
-
97
- - [x] [M] Update `README.md`: add `@dezkareid/design-tokens` CSS import requirement, add usage examples for Button, Tag, Card, ThemeToggle in all three framework formats
98
- - [x] [M] Update `AGENTS.md`: add component API summaries (props, variants, slot/children behaviour) for all four components
99
-
100
- **Definition of Done**: README covers install, token CSS import, and usage for all components; AGENTS.md describes all component APIs for AI tooling.
package/rollup.config.mjs DELETED
@@ -1,32 +0,0 @@
1
- import typescript from '@rollup/plugin-typescript';
2
- import resolve from '@rollup/plugin-node-resolve';
3
- import commonjs from '@rollup/plugin-commonjs';
4
- import postcss from 'rollup-plugin-postcss';
5
-
6
- export default {
7
- input: 'src/react/index.ts',
8
- external: ['react', 'react/jsx-runtime'],
9
- plugins: [
10
- resolve({ extensions: ['.ts', '.tsx'] }),
11
- commonjs(),
12
- postcss({
13
- autoModules: true,
14
- extract: 'components.min.css',
15
- minimize: true,
16
- }),
17
- typescript({
18
- tsconfig: './tsconfig.json',
19
- declaration: true,
20
- declarationDir: 'dist',
21
- exclude: ['**/*.test.tsx', '**/*.test.ts', 'setupTests.ts'],
22
- }),
23
- ],
24
- output: {
25
- dir: 'dist',
26
- format: 'es',
27
- preserveModules: true,
28
- preserveModulesRoot: 'src',
29
- entryFileNames: '[name].js',
30
- sourcemap: true,
31
- },
32
- };
package/setupTests.ts DELETED
@@ -1 +0,0 @@
1
- import '@testing-library/jest-dom';
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
5
- "module": "ESNext",
6
- "moduleResolution": "bundler",
7
- "jsx": "react-jsx",
8
- "strict": true,
9
- "declaration": true,
10
- "declarationMap": true,
11
- "sourceMap": true,
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "resolveJsonModule": true,
15
- "types": ["vitest/globals", "@testing-library/jest-dom"],
16
- "outDir": "dist"
17
- },
18
- "include": ["src", "setupTests.ts"]
19
- }