@neuravision/construct 2.0.2 → 2.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/CHANGELOG.md +272 -0
- package/README.md +148 -152
- package/behaviors/combobox.js +447 -0
- package/behaviors/drawer.js +18 -0
- package/behaviors/dropdown.js +296 -0
- package/behaviors/index.d.ts +333 -0
- package/behaviors/index.js +9 -0
- package/behaviors/internal/dialog-controller.js +351 -0
- package/behaviors/internal/dom.js +377 -0
- package/behaviors/internal/overlay.js +241 -0
- package/behaviors/internal/popup-layer.js +188 -0
- package/behaviors/modal.js +17 -0
- package/behaviors/popover.js +269 -0
- package/behaviors/select-menu.js +326 -0
- package/behaviors/tabs.js +230 -0
- package/behaviors/toggle-group.js +234 -0
- package/behaviors/tooltip.js +233 -0
- package/components/README.md +279 -83
- package/components/_shared.css +11 -10
- package/components/_shell-shared.css +20 -4
- package/components/app-shell-v2.css +21 -14
- package/components/app-shell.css +23 -14
- package/components/badge.css +15 -0
- package/components/button.css +103 -15
- package/components/card.css +53 -8
- package/components/checkbox.css +3 -2
- package/components/chip.css +1 -1
- package/components/datepicker.css +3 -1
- package/components/datum.css +204 -0
- package/components/index.css +5 -0
- package/components/meter.css +182 -0
- package/components/navbar.css +88 -3
- package/components/slider.css +2 -1
- package/components/status.css +107 -0
- package/components/switch.css +4 -3
- package/components/tooltip.css +4 -0
- package/docs/architecture.md +79 -0
- package/docs/behaviors.md +101 -0
- package/docs/fonts.md +70 -0
- package/docs/governance.md +85 -0
- package/docs/guidelines.md +42 -23
- package/examples/react/README.md +20 -0
- package/examples/react/SettingsModal.jsx +66 -0
- package/examples/react/construct.css +5 -0
- package/fonts.css +10 -0
- package/foundations.css +8 -1
- package/package.json +72 -21
- package/schemas/components.schema.json +107 -0
- package/schemas/examples/theme.example.json +27 -0
- package/schemas/primitives.schema.json +135 -0
- package/schemas/semantic.schema.json +223 -0
- package/schemas/theme.schema.json +63 -0
- package/scripts/build-tokens.mjs +1417 -0
- package/scripts/construct-theme.mjs +43 -0
- package/scripts/validate-tokens.mjs +25 -0
- package/standalone/accordion.css +3 -0
- package/standalone/alert.css +3 -0
- package/standalone/app-shell-v2.css +4 -0
- package/standalone/app-shell.css +4 -0
- package/standalone/avatar.css +3 -0
- package/standalone/badge.css +3 -0
- package/standalone/banner.css +3 -0
- package/standalone/breadcrumbs.css +3 -0
- package/standalone/button.css +3 -0
- package/standalone/card.css +3 -0
- package/standalone/chart.css +3 -0
- package/standalone/checkbox.css +3 -0
- package/standalone/chip.css +3 -0
- package/standalone/combobox.css +3 -0
- package/standalone/core.css +4 -0
- package/standalone/data-table.css +3 -0
- package/standalone/datepicker.css +3 -0
- package/standalone/datum.css +3 -0
- package/standalone/divider.css +3 -0
- package/standalone/drawer.css +3 -0
- package/standalone/dropdown.css +3 -0
- package/standalone/empty-state.css +3 -0
- package/standalone/field.css +3 -0
- package/standalone/file-upload.css +3 -0
- package/standalone/icon.css +3 -0
- package/standalone/input.css +3 -0
- package/standalone/list.css +3 -0
- package/standalone/meter.css +3 -0
- package/standalone/modal.css +3 -0
- package/standalone/navbar.css +3 -0
- package/standalone/pagination.css +3 -0
- package/standalone/popover.css +3 -0
- package/standalone/progress-bar.css +3 -0
- package/standalone/select-menu.css +3 -0
- package/standalone/select.css +3 -0
- package/standalone/sidebar.css +3 -0
- package/standalone/skeleton.css +3 -0
- package/standalone/skip-link.css +3 -0
- package/standalone/slider.css +3 -0
- package/standalone/spinner.css +3 -0
- package/standalone/status.css +3 -0
- package/standalone/switch.css +3 -0
- package/standalone/table.css +3 -0
- package/standalone/tabs.css +3 -0
- package/standalone/textarea.css +3 -0
- package/standalone/toast.css +3 -0
- package/standalone/toggle-group.css +3 -0
- package/standalone/toolbar.css +3 -0
- package/standalone/tooltip.css +3 -0
- package/standalone/tree.css +3 -0
- package/tokens/README.md +130 -126
- package/tokens/components.json +54 -0
- package/tokens/primitives.json +268 -0
- package/tokens/semantic.dark.json +93 -0
- package/tokens/semantic.high-contrast.json +93 -0
- package/tokens/semantic.light.json +178 -0
- package/tokens/tokens.css +532 -28
- package/tokens/tokens.js +335 -25
- package/tokens/tokens.json +764 -21
- package/tokens/tokens.ts +335 -25
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@neuravision/construct` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.1.1] - 2026-07-16
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
## [2.1.0] - 2026-07-15
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- A validated three-layer token contract (primitive → semantic → component) with 40 component tokens, published JSON Schemas, typed JS/TS exports, and complete nested theme scopes.
|
|
17
|
+
- The `construct-theme` CLI for external theme inputs, including unknown-path, reference, shape, selector, and contrast validation. Built-in themes now verify 57 contrast pairs each.
|
|
18
|
+
- Optional, dependency-free, typed headless controllers for modal, drawer, tabs, toggle group, dropdown, select menu, combobox, tooltip, and popover.
|
|
19
|
+
- Generic live/connection status, metric, and segmented meter contracts; loading-button behavior; a compact responsive navbar; and shared App Shell sizing/motion hooks.
|
|
20
|
+
- Generated standalone package entry points for all 49 component styles plus a public component core entry.
|
|
21
|
+
- Automated CSS-variable closure, package-export, version, token negative-case, real coarse-pointer, and forced-colors contracts.
|
|
22
|
+
- Architecture, behavior, font/self-hosting, governance/Definition-of-Done documentation and a React lifecycle example.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `foundations.css` is network-free. Hosted Lato and JetBrains Mono loading moved to the explicit opt-in `fonts.css` entry.
|
|
27
|
+
- Explicit light, dark, high-contrast, and custom theme scopes emit complete semantic and component contracts, making arbitrary nested container themes deterministic.
|
|
28
|
+
- Light accent interaction colors, light solid success/warning colors, dark muted text, and high-contrast active accent were adjusted to satisfy the expanded contrast matrix.
|
|
29
|
+
- App Shell V2 is the recommended shell; V1 remains supported through compatibility aliases instead of a divergent public token vocabulary.
|
|
30
|
+
- The verified development baseline is Node.js 22.12+ (or 24+) with Storybook 10.5, Vitest 4.1, and Playwright 1.61; the unused coverage package and vulnerable legacy test-tool chain were removed, and CI/publish preflights now reject high or critical dependency advisories.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Added the missing `--font-size-2xs`, `--color-bg-subtle`, and `--color-border-muted` contracts and removed the Datepicker's undeclared global pseudo-token.
|
|
35
|
+
- Prevented light component aliases and inherited semantic values from leaking into nested dark, high-contrast, light, or custom theme containers.
|
|
36
|
+
- Expanded the small Switch coarse-pointer hit area on both axes and enforced the 44×44 Construct target policy for default/small actions and compact controls.
|
|
37
|
+
- Preserved meaningful borders, state indicators, and focus visibility in forced-colors mode.
|
|
38
|
+
- Raised the default light/dark boundary colors and added compiler gates for control borders against canvas, surface, elevated, and control backgrounds.
|
|
39
|
+
- Rejected negative component dimensions, radii, font metrics, and shadow blur radii while preserving valid negative letter spacing, shadow offsets, and spread values.
|
|
40
|
+
- Preserved the existing `_keyframes.css`, `_shared.css`, and `_shell-shared.css` package subpaths while public component imports move to generated standalone adapters.
|
|
41
|
+
|
|
42
|
+
### Accessibility
|
|
43
|
+
|
|
44
|
+
- Composite-widget behavior now has tested keyboard, focus, dismissal, typeahead, nested-overlay, cleanup, and ARIA synchronization contracts instead of relying on CSS documentation alone.
|
|
45
|
+
- Status meaning is conveyed with visible text plus a non-text indicator; semantic state color is no longer used as small text on an unrelated surface.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## [2.0.4] - 2026-06-28
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **Datum grammar — the signature, now spoken by components.** The orange "datum"
|
|
53
|
+
(Construct's reference line for focus / active / current state) was promoted from focus
|
|
54
|
+
rings and bespoke docs CSS into reusable, opt-in component vocabulary in a new
|
|
55
|
+
`components/datum.css`:
|
|
56
|
+
- `.ct-eyebrow` — a mono kicker with a leading datum tick, for labelling sections.
|
|
57
|
+
- `.ct-datum-scale` — a measured reference line (a ruler with minor/major ticks and an
|
|
58
|
+
orange "origin" segment) for section headers.
|
|
59
|
+
- `.ct-specs` / `.ct-spec` (+ `.ct-spec--origin`) — an engineering datasheet for key figures.
|
|
60
|
+
- Card modifiers in `card.css`: `.ct-card--datum` (a corner registration mark) and an
|
|
61
|
+
active state (`.ct-card--active` / `[data-state="active"]`) that carries the same orange
|
|
62
|
+
leading edge as `.ct-list__item` and `.ct-sidebar`, so every active surface reads as one system.
|
|
63
|
+
|
|
64
|
+
### Accessibility
|
|
65
|
+
|
|
66
|
+
- Eyebrow and spec labels use `--color-text-secondary` (≥7:1 on every surface across light,
|
|
67
|
+
dark and high-contrast); orange is reserved for non-text edges/ticks (`--color-brand-accent`,
|
|
68
|
+
≥3:1 as a graphic object). Default cards and existing `aria-selected` card behaviour are unchanged.
|
|
69
|
+
|
|
70
|
+
## [2.0.3] - 2026-06-28
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- **Lato typeface was declared but never loaded.** The 2.0.2 switch updated the font-family
|
|
75
|
+
tokens to Lato but left the Google Fonts `@import` in `foundations.css` pointing at Manrope,
|
|
76
|
+
so consumers loaded Manrope (unused) while Lato fell back to a system sans-serif. The
|
|
77
|
+
`@import` now loads `Lato:wght@400;700;900` (JetBrains Mono unchanged). Documentation
|
|
78
|
+
(`DesignTokens`, `Accessibility`, `Introduction`) updated from Manrope to Lato.
|
|
79
|
+
|
|
80
|
+
### Notes
|
|
81
|
+
|
|
82
|
+
- Lato ships only in 400/700/900 — it has no 500/600/800. The `medium` (500) and `semibold`
|
|
83
|
+
(600) weight tokens therefore resolve to the nearest available face (400 and 700), and
|
|
84
|
+
`extrabold` (800) to 900. This is inherent to Lato; `font-synthesis: none` keeps these as
|
|
85
|
+
real faces (no faux weights).
|
|
86
|
+
|
|
87
|
+
## [2.0.2] - 2026-06-28
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- Switch primary typeface from Manrope to Lato (400/700/900)
|
|
92
|
+
|
|
93
|
+
## [2.0.1] - 2026-06-27
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- **Navbar height token.** The navbar referenced a non-existent `--control-height-xl` primitive (the control-height scale ends at `lg`), so the navbar fell back to an undefined height. Introduced a dedicated `layout.navbar.height` primitive (`--navbar-height`, 56px) and pointed `.ct-navbar` at it. The control-height scale stays reserved for form controls.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## [2.0.0] - 2026-06-27
|
|
101
|
+
|
|
102
|
+
A new visual identity — *"engineered for everyone."* Construct moves from a generic tech-blue/slate look to a distinctive system: warm concrete neutrals, an ink-steel primary, and a safety-orange accent that acts as a single recurring **"datum"** marking what is focused / active / selected / current. Verified WCAG AA across light, dark, and high-contrast themes.
|
|
103
|
+
|
|
104
|
+
**BREAKING CHANGES:**
|
|
105
|
+
|
|
106
|
+
- **Neutral primitive ramp renamed `slate` → `stone`.** Consumers referencing `color.slate.*` or `--color-slate-*` must migrate to `stone.*`. The neutral palette is now warm concrete/graphite instead of cool blue-grey.
|
|
107
|
+
- **Default typefaces changed** from Sora + Source Sans 3 to **Manrope** (display + body). The Google Fonts import in `foundations.css` was updated accordingly; self-hosting consumers must update their font files.
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
|
|
111
|
+
- **The "datum" signature** — the orange accent now marks focus rings, active tab underlines, checked selection controls, slider fills, selected chips, the current pagination page, and active navigation (leading edge) across all components.
|
|
112
|
+
- New semantic tokens: `color.brand.onAccent`, `color.text.onPrimary`, `color.state.onSolid` (theme-aware foregrounds for solid fills), and the `font.weight.extrabold` (800) display weight.
|
|
113
|
+
- New `orange` primitive ramp (structural safety orange).
|
|
114
|
+
|
|
115
|
+
### Changed
|
|
116
|
+
|
|
117
|
+
- State ramps retuned to widen hue separation from the brand orange: `ocean` → blueprint blue (info), `amber` → gold (warning), `red` → crimson (danger).
|
|
118
|
+
- Shadows warmed (warm-ink instead of cool blue); display headings now use weight 800.
|
|
119
|
+
- Solid chips and solid banners now use a theme-aware foreground (`state.onSolid`) so their labels meet AA contrast in dark and high-contrast themes.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## [1.4.0] - 2026-06-27
|
|
123
|
+
|
|
124
|
+
### Added
|
|
125
|
+
|
|
126
|
+
- **Tooling — design-sync for [claude.ai/design](https://claude.ai/design):** Construct can now be synced to a Claude Design project so Claude's design agent builds with the real Construct components. Because Construct is a pure CSS/token system, an off-script generator (`.design-sync/build.mjs`) flattens the authored CSS into one bundle and builds one preview card per component from the true Storybook-rendered HTML, plus per-component usage docs and a class-vocabulary README header. Sync state lives under `.design-sync/`; no change to the published package surface.
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
## [1.3.1] - 2026-06-17
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- **a11y / focus:** Raised the `--color-focus-ring` contrast so the focus indicator meets the WCAG 2.2 ≥ 3:1 non-text-contrast minimum against the canvas and surface backgrounds. The `light` ring (`teal.400`, 2.59:1 on canvas) → `teal.600` (5.09:1) and the `high-contrast` ring (`amber.400`, 2.07:1) → `amber.700` (6.68:1); the `dark` ring already passed and is unchanged. Affects every component that uses the shared focus token (24 files).
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## [1.3.0] - 2026-06-17
|
|
137
|
+
|
|
138
|
+
### Added
|
|
139
|
+
|
|
140
|
+
- Chart styling skin (`ct-chart`) — a framework-agnostic theme layer for SVG data-visualisation primitives (line/area, bar, donut, sparkline, gauge). Provides series colour mapping (`.ct-chart__series--{1..8}` via `currentColor`), grid/axis, legend, donut/gauge text, and a visually-hidden **accessible data-table fallback** (`.ct-chart__table`, revealed with `.ct-chart--show-table`). Geometry is supplied by the consuming layer; this file only themes the result. `prefers-reduced-motion` and `forced-colors` supported.
|
|
141
|
+
- New categorical chart palette tokens `--color-chart-series-{1..8}`, defined for `light`, `dark`, and `high-contrast` themes. Every series colour meets the WCAG 1.4.11 non-text contrast minimum (≥ 3:1) against both the canvas and surface backgrounds.
|
|
142
|
+
- Storybook coverage for `ct-chart` (`Chart.stories.js`): line/area, bar, donut, gauge, sparkline, empty state, the interactive data-table toggle (documenting the `aria-expanded`/`aria-controls` contract), and an optional keyboard-focusable-marks example. All stories pass the a11y addon in `error` mode.
|
|
143
|
+
|
|
144
|
+
### Fixed
|
|
145
|
+
|
|
146
|
+
- `ct-chart`: interactive marks (`.ct-chart__bar`, `.ct-chart__slice`, `.ct-chart__dot`) now have `:focus-visible` parity with their `:hover` affordance, so consumer-focusable data points show a visible focus ring.
|
|
147
|
+
- `ct-chart`: hoisted `--ct-chart-gauge-width` into the `.ct-chart` config block (was an inline `var()` fallback duplicated across two rules), making it discoverable and overridable like the other `--ct-chart-*` properties.
|
|
148
|
+
- `ct-chart`: consistent `forced-colors` behaviour — data marks (line, area, dots, bars, slices, legend marker, gauge) now uniformly preserve their series/state colour via `forced-color-adjust: none`, so a coloured legend no longer describes monochrome lines in Windows High Contrast. Grid and axes still follow the user's forced palette, and the data-table fallback remains the fully compliant path.
|
|
149
|
+
|
|
150
|
+
## [1.2.0] - 2026-05-07
|
|
151
|
+
|
|
152
|
+
### Added
|
|
153
|
+
|
|
154
|
+
- Tree component (`ct-tree`) implementing the WAI-ARIA Tree View pattern: n-level nesting, roving tabindex, full keyboard navigation (↑/↓/→/←/Home/End/`*`/type-ahead), single & multi selection, async loading state (`aria-busy`), and an orphan-node modifier (`.ct-tree__node--orphan`) for hierarchies with missing parents. Modifiers: `--guides`, `--dense`, `--bordered`. Forced-colors and `prefers-reduced-motion` supported. (#86)
|
|
155
|
+
|
|
156
|
+
## [1.1.6] - 2026-04-09
|
|
157
|
+
|
|
158
|
+
### Changed
|
|
159
|
+
|
|
160
|
+
### Added
|
|
161
|
+
|
|
162
|
+
- Avatar seeded color palette: `.ct-avatar[data-seed-color="N"]` (N = 1–8) selects a deterministic background/foreground pair from the palette, letting consumers give each user a stable color. Avatars without the attribute keep the existing default — fully backwards compatible. (#85)
|
|
163
|
+
- New semantic tokens `--color-avatar-seed-{1..8}-{bg,fg}` and component-level `--ct-avatar-seed-{1..8}-{bg,fg}` aliases, defined for `light`, `dark`, and `high-contrast` themes. Every pair meets WCAG AA (≥ 4.5:1, lowest measured 6.48:1).
|
|
164
|
+
- New color primitives `purple` and `pink` (50–900 scales) feeding the seed palette.
|
|
165
|
+
- Storybook story `Data Display/Avatar/Seeded Colors` showcasing the palette and confirming the unseeded fallback.
|
|
166
|
+
|
|
167
|
+
## [1.1.5] - 2026-04-03
|
|
168
|
+
|
|
169
|
+
### Changed
|
|
170
|
+
|
|
171
|
+
## [1.1.4] - 2026-03-27
|
|
172
|
+
|
|
173
|
+
### Changed
|
|
174
|
+
|
|
175
|
+
## [1.1.3] - 2026-03-27
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
|
|
179
|
+
## [1.1.2] - 2026-03-21
|
|
180
|
+
|
|
181
|
+
### Changed
|
|
182
|
+
|
|
183
|
+
## [1.1.1] - 2026-03-21
|
|
184
|
+
|
|
185
|
+
### Changed
|
|
186
|
+
|
|
187
|
+
## [1.1.0] - 2026-03-21
|
|
188
|
+
|
|
189
|
+
### Added
|
|
190
|
+
|
|
191
|
+
-
|
|
192
|
+
|
|
193
|
+
## [0.2.0] - 2026-03-12
|
|
194
|
+
|
|
195
|
+
### Added
|
|
196
|
+
|
|
197
|
+
- Toolbar component (`ct-toolbar`) with brand, navigation, and action slots
|
|
198
|
+
- Sidebar component (`ct-sidebar`) with side, over, and push modes
|
|
199
|
+
- Progress bar component (`ct-progress-bar`) with determinate, indeterminate, and size/variant modifiers
|
|
200
|
+
- Toggle group component (`ct-toggle-group`) with single/multiple selection and size variants
|
|
201
|
+
- Nav list component (`ct-nav-list`, `ct-nav-item`) for sidebar navigation
|
|
202
|
+
- Icon component (`ct-icon`) with sm, md, lg, xl sizes
|
|
203
|
+
- `prefers-reduced-motion` support in components layer for self-contained usage
|
|
204
|
+
- Explicit `:focus-visible` styles for all interactive components (button, form controls, checkbox, radio, switch, tabs, dropdown items, pagination, datepicker, table sort, nav items, toolbar links)
|
|
205
|
+
|
|
206
|
+
### Fixed
|
|
207
|
+
|
|
208
|
+
- Inconsistent focus indicators across components (standardized to `outline: 2px solid` with appropriate offsets)
|
|
209
|
+
- Missing focus styles on `.ct-button`, `.ct-check__input`, `.ct-radio__input`, `.ct-switch__input`, `.ct-tabs__trigger`
|
|
210
|
+
- Form controls now show both border-color change and outline ring on focus for WCAG 2.1 AA compliance
|
|
211
|
+
|
|
212
|
+
## [0.1.1] - 2026-03-12
|
|
213
|
+
|
|
214
|
+
### Changed
|
|
215
|
+
|
|
216
|
+
- Updated `.gitignore` to exclude internal documentation and mock data
|
|
217
|
+
- Project configuration and metadata cleanup
|
|
218
|
+
|
|
219
|
+
## [0.1.0] - 2026-01-31
|
|
220
|
+
|
|
221
|
+
### Added
|
|
222
|
+
|
|
223
|
+
- Initial release of the Construct Design System
|
|
224
|
+
- Two-tier token pipeline (primitives + semantic) with CSS, JSON, and TypeScript outputs
|
|
225
|
+
- Three theme modes: light (default), dark, high-contrast
|
|
226
|
+
- System preference fallback via `prefers-color-scheme` and `prefers-contrast`
|
|
227
|
+
- Foundation styles: CSS reset, typography scale, layout utilities
|
|
228
|
+
- Component library with `ct-` prefix and BEM naming:
|
|
229
|
+
- Button (primary, secondary, outline, ghost, accent, danger, link variants; sm/md/lg sizes)
|
|
230
|
+
- Form controls: input, select, textarea with field wrapper, hints, and error states
|
|
231
|
+
- Selection controls: checkbox, radio, switch
|
|
232
|
+
- Card with header, body, footer, and interactive variant
|
|
233
|
+
- Table with striped, compact, sortable, and numeric cell variants
|
|
234
|
+
- Data table with header, toolbar, filters, search, pagination, and footer
|
|
235
|
+
- Modal and confirmation dialog
|
|
236
|
+
- Toast notifications with info, success, warning, danger variants
|
|
237
|
+
- Tooltip with top, bottom, left, right positioning
|
|
238
|
+
- Tabs with trigger and panel
|
|
239
|
+
- Dropdown menu with items, labels, separators
|
|
240
|
+
- Pagination with navigation links
|
|
241
|
+
- Breadcrumbs
|
|
242
|
+
- Datepicker with calendar grid
|
|
243
|
+
- Badge and chip with variant and interactive modifiers
|
|
244
|
+
- File upload with drag-and-drop dropzone and file list
|
|
245
|
+
- Spinner, skeleton loader, and loading overlay
|
|
246
|
+
- Accessibility: ARIA attribute-driven states, semantic HTML patterns
|
|
247
|
+
- Storybook with HTML Vite, a11y addon (error-level), theme switching, autodocs
|
|
248
|
+
- Story-driven testing via Vitest + Playwright
|
|
249
|
+
- GitHub Actions workflow for Storybook deployment to GitHub Pages
|
|
250
|
+
- Token build script with `--check` mode for CI validation
|
|
251
|
+
|
|
252
|
+
[2.1.1]: https://github.com/Samyssmile/construct/compare/v2.1.0...v2.1.1
|
|
253
|
+
[2.1.0]: https://github.com/Samyssmile/construct/compare/v2.0.4...v2.1.0
|
|
254
|
+
[2.0.4]: https://github.com/Samyssmile/construct/compare/v2.0.3...v2.0.4
|
|
255
|
+
[2.0.3]: https://github.com/Samyssmile/construct/compare/v2.0.2...v2.0.3
|
|
256
|
+
[2.0.2]: https://github.com/Samyssmile/construct/compare/v2.0.1...v2.0.2
|
|
257
|
+
[2.0.1]: https://github.com/Samyssmile/construct/compare/v2.0.0...v2.0.1
|
|
258
|
+
[2.0.0]: https://github.com/Samyssmile/construct/compare/v1.4.0...v2.0.0
|
|
259
|
+
[1.4.0]: https://github.com/Samyssmile/construct/compare/v1.3.1...v1.4.0
|
|
260
|
+
[1.3.1]: https://github.com/Samyssmile/construct/compare/v1.3.0...v1.3.1
|
|
261
|
+
[1.3.0]: https://github.com/Samyssmile/construct/compare/v1.2.0...v1.3.0
|
|
262
|
+
[1.2.0]: https://github.com/Samyssmile/construct/compare/v1.1.6...v1.2.0
|
|
263
|
+
[1.1.6]: https://github.com/Samyssmile/construct/compare/v1.1.5...v1.1.6
|
|
264
|
+
[1.1.5]: https://github.com/Samyssmile/construct/compare/v1.1.4...v1.1.5
|
|
265
|
+
[1.1.4]: https://github.com/Samyssmile/construct/compare/v1.1.3...v1.1.4
|
|
266
|
+
[1.1.3]: https://github.com/Samyssmile/construct/compare/v1.1.2...v1.1.3
|
|
267
|
+
[1.1.2]: https://github.com/Samyssmile/construct/compare/v1.1.1...v1.1.2
|
|
268
|
+
[1.1.1]: https://github.com/Samyssmile/construct/compare/v1.1.0...v1.1.1
|
|
269
|
+
[1.1.0]: https://github.com/Samyssmile/construct/compare/v1.0.0...v1.1.0
|
|
270
|
+
[0.2.0]: https://github.com/Samyssmile/construct/compare/v0.1.1...v0.2.0
|
|
271
|
+
[0.1.1]: https://github.com/Samyssmile/construct/compare/v0.1.0...v0.1.1
|
|
272
|
+
[0.1.0]: https://github.com/Samyssmile/construct/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -1,230 +1,226 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://samyssmile.github.io/construct/)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Construct
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**A token-based, framework-agnostic design system for accessible, modern web UI.**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- **TypeScript Support** - Full type definitions for tokens
|
|
9
|
+
[](https://www.npmjs.com/package/@neuravision/construct)
|
|
10
|
+
[](https://www.npmjs.com/package/@neuravision/construct)
|
|
11
|
+
[](https://samyssmile.github.io/construct/)
|
|
12
|
+
[](https://github.com/Samyssmile/construct/actions/workflows/deploy-storybook.yml)
|
|
13
|
+
[](docs/guidelines.md)
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
[](CONTRIBUTING.md)
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
[**Live Storybook**](https://samyssmile.github.io/construct/) · [Components](#-components) · [Design Tokens](#-design-tokens) · [Accessibility](#-accessibility) · [Contributing](CONTRIBUTING.md)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Why Construct?
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
Construct is a **single source of design truth** that ships portable CSS, validated design tokens, and opt-in headless behaviors — without framework lock-in. Style values live once as JSON tokens and compile to CSS custom properties, JSON, and typed TypeScript exports. Components use `ct-` classes and ARIA/data state, so they work anywhere that renders DOM.
|
|
26
|
+
|
|
27
|
+
- 🎯 **Three token layers** — primitive, semantic, and component contracts with schema and contrast validation
|
|
28
|
+
- 🧩 **Framework-agnostic** — 49 standalone component style entries and a full CSS bundle
|
|
29
|
+
- ♿ **Accessibility first** — WCAG 2.2 AA targets, tested ARIA/keyboard controllers, focus and forced-colors contracts
|
|
30
|
+
- ⚙️ **Optional behavior** — nine typed, dependency-free ESM controllers; importing CSS never starts JavaScript
|
|
31
|
+
- 🎨 **Three themes** — `light`, `dark`, `high-contrast`, with system-preference fallback
|
|
32
|
+
- 📐 **The "datum" grammar** — a signature orange reference line for focus / active / current state
|
|
33
|
+
- 🛠️ **Typed tokens** — autocomplete-friendly TypeScript exports
|
|
34
|
+
- 📖 **Interactive docs** — every component documented & a11y-tested in [Storybook](https://samyssmile.github.io/construct/)
|
|
35
|
+
|
|
36
|
+
## 📦 Installation
|
|
21
37
|
|
|
22
38
|
```bash
|
|
23
39
|
npm install @neuravision/construct
|
|
24
40
|
```
|
|
25
41
|
|
|
26
|
-
|
|
42
|
+
Using Angular? Reach for the official wrapper [**@neuravision/ng-construct**](https://github.com/Samyssmile/ng-construct) — typed, signal-based components built on top of these styles.
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
## 🚀 Quick Start
|
|
45
|
+
|
|
46
|
+
Import the foundation styles and the component bundle once (e.g. in your global stylesheet):
|
|
29
47
|
|
|
30
48
|
```css
|
|
31
49
|
@import "@neuravision/construct/foundations.css";
|
|
32
50
|
@import "@neuravision/construct/components/components.css";
|
|
33
51
|
```
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
Then use the classes in your markup:
|
|
36
54
|
|
|
37
55
|
```html
|
|
38
|
-
<button class="ct-button">Primary
|
|
39
|
-
<button class="ct-button ct-button--secondary">Secondary</button>
|
|
56
|
+
<button class="ct-button" type="button">Primary</button>
|
|
57
|
+
<button class="ct-button ct-button--secondary" type="button">Secondary</button>
|
|
58
|
+
|
|
59
|
+
<div class="ct-field">
|
|
60
|
+
<label class="ct-field__label" for="email">Email</label>
|
|
61
|
+
<input class="ct-input" id="email" type="email" placeholder="name@company.com" />
|
|
62
|
+
</div>
|
|
40
63
|
```
|
|
41
64
|
|
|
42
|
-
Or
|
|
65
|
+
Or build custom UI directly on the tokens:
|
|
43
66
|
|
|
44
67
|
```css
|
|
45
|
-
.custom-
|
|
46
|
-
background: var(--color-
|
|
68
|
+
.custom-card {
|
|
69
|
+
background: var(--color-bg-surface);
|
|
70
|
+
color: var(--color-text-primary);
|
|
47
71
|
padding: var(--space-4);
|
|
48
72
|
border-radius: var(--radius-control);
|
|
49
73
|
}
|
|
50
74
|
```
|
|
51
75
|
|
|
52
|
-
|
|
76
|
+
> 💡 Need a smaller bundle? Import a generated standalone style entry such as
|
|
77
|
+
> `@import "@neuravision/construct/components/button.css";`. Related public patterns can share an
|
|
78
|
+
> entry: Radio is included in `checkbox.css`, and Metric is included in `datum.css`.
|
|
53
79
|
|
|
54
|
-
|
|
80
|
+
Composite widgets can use the optional behavior entry instead of reimplementing keyboard and focus state machines:
|
|
55
81
|
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
...
|
|
59
|
-
</html>
|
|
82
|
+
```js
|
|
83
|
+
import { createModalController } from '@neuravision/construct/behaviors';
|
|
60
84
|
```
|
|
61
85
|
|
|
62
|
-
|
|
63
|
-
- `light` (default)
|
|
64
|
-
- `dark`
|
|
65
|
-
- `high-contrast`
|
|
86
|
+
Foundations make no network request. Import `@neuravision/construct/fonts.css` before foundations only when the product explicitly accepts the hosted-font privacy and CSP tradeoff; self-hosting is documented in [docs/fonts.md](docs/fonts.md).
|
|
66
87
|
|
|
67
|
-
|
|
68
|
-
- `prefers-color-scheme: dark` → dark theme
|
|
69
|
-
- `prefers-contrast: more` → high-contrast theme
|
|
88
|
+
## 🎨 Theming
|
|
70
89
|
|
|
71
|
-
|
|
90
|
+
Set `data-theme` on the root element (or any container) to switch modes:
|
|
72
91
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
├── tokens/ # Design tokens (JSON, CSS, JS, TS)
|
|
76
|
-
│ ├── primitives.json # Base values (colors, sizes)
|
|
77
|
-
│ ├── semantic.light.json # Semantic mappings
|
|
78
|
-
│ ├── semantic.dark.json # Dark theme overrides
|
|
79
|
-
│ ├── semantic.high-contrast.json # High-contrast theme overrides
|
|
80
|
-
│ ├── tokens.css # CSS Custom Properties
|
|
81
|
-
│ ├── tokens.json # Resolved JSON output
|
|
82
|
-
│ ├── tokens.js # JavaScript exports
|
|
83
|
-
│ └── tokens.ts # TypeScript exports
|
|
84
|
-
├── components/ # Framework-agnostic styles
|
|
85
|
-
│ ├── components.css # All component styles
|
|
86
|
-
│ └── README.md # Component documentation
|
|
87
|
-
├── foundations.css # Reset, typography, layout utilities
|
|
88
|
-
└── docs/ # Guidelines & best practices
|
|
89
|
-
└── guidelines.md
|
|
92
|
+
```html
|
|
93
|
+
<html data-theme="dark"> … </html>
|
|
90
94
|
```
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
| Value | Description |
|
|
97
|
+
|-------|-------------|
|
|
98
|
+
| `light` | Default theme |
|
|
99
|
+
| `dark` | Dark theme |
|
|
100
|
+
| `high-contrast` | Maximum-contrast theme |
|
|
93
101
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
### Primitives
|
|
97
|
-
Raw design values (colors, spacing, typography)
|
|
98
|
-
|
|
99
|
-
```json
|
|
100
|
-
{
|
|
101
|
-
"color": {
|
|
102
|
-
"stone": {
|
|
103
|
-
"950": "#16130F"
|
|
104
|
-
},
|
|
105
|
-
"orange": {
|
|
106
|
-
"500": "#F4581C"
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
"space": {
|
|
110
|
-
"4": 8
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
```
|
|
102
|
+
With **no** `data-theme` set, Construct respects system preferences automatically:
|
|
103
|
+
`prefers-color-scheme: dark` → dark, `prefers-contrast: more` → high-contrast.
|
|
114
104
|
|
|
115
|
-
|
|
116
|
-
Contextual aliases that reference primitives
|
|
105
|
+
Validated product themes can extend a built-in theme without copying generated CSS:
|
|
117
106
|
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
"color": {
|
|
121
|
-
"brand": {
|
|
122
|
-
"primary": "{color.stone.950}"
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
107
|
+
```bash
|
|
108
|
+
npx construct-theme --theme ./brand.theme.json --out-dir ./src/generated/construct
|
|
126
109
|
```
|
|
127
110
|
|
|
128
|
-
|
|
111
|
+
Load the generated token stylesheet after all Construct style entries, because foundations and component entries include the built-in token sheet themselves:
|
|
129
112
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
npm run build
|
|
113
|
+
```css
|
|
114
|
+
@import '@neuravision/construct/foundations.css';
|
|
115
|
+
@import '@neuravision/construct/components/components.css';
|
|
116
|
+
@import './generated/construct/tokens.css';
|
|
137
117
|
```
|
|
138
118
|
|
|
119
|
+
Application-specific overrides may follow it. Keeping the generated theme last among Construct imports ensures its root and scoped values win deterministically.
|
|
120
|
+
|
|
139
121
|
## 🧩 Components
|
|
140
122
|
|
|
141
|
-
|
|
142
|
-
- Button (6 variants, 3 sizes)
|
|
143
|
-
- Input (text, email, password, search)
|
|
144
|
-
- Select (native dropdown)
|
|
145
|
-
- Textarea
|
|
146
|
-
- Checkbox
|
|
147
|
-
- Radio
|
|
148
|
-
- Switch
|
|
149
|
-
|
|
150
|
-
### Complex Components
|
|
151
|
-
- Card
|
|
152
|
-
- Table / Data Table
|
|
153
|
-
- Modal
|
|
154
|
-
- Toast (notifications)
|
|
155
|
-
- Tabs
|
|
156
|
-
- Dropdown
|
|
157
|
-
- Pagination
|
|
158
|
-
- Breadcrumbs
|
|
159
|
-
- Datepicker
|
|
160
|
-
|
|
161
|
-
[View all components in Storybook](https://samyssmile.github.io/construct/)
|
|
123
|
+
49 standalone component style entries, documented and accessibility-tested in [Storybook](https://samyssmile.github.io/construct/).
|
|
162
124
|
|
|
163
|
-
|
|
125
|
+
| Category | Components |
|
|
126
|
+
|----------|-----------|
|
|
127
|
+
| **Actions** | Button · Toggle Group · Toolbar |
|
|
128
|
+
| **Forms & Inputs** | Field · Input · Textarea · Select · Select Menu · Checkbox · Radio · Switch · Slider · Combobox · Chip · File Upload · Datepicker |
|
|
129
|
+
| **Data Display** | Table · Data Table · List · Tree · Avatar · Badge · Icon · Tooltip · Chart · Metric · Meter |
|
|
130
|
+
| **Feedback** | Alert · Banner · Toast · Spinner · Skeleton · Progress Bar · Status · Empty State |
|
|
131
|
+
| **Navigation** | Navbar · Breadcrumbs · Tabs · Pagination · Sidebar · Skip Link |
|
|
132
|
+
| **Overlays** | Modal · Drawer · Popover · Dropdown |
|
|
133
|
+
| **Layout** | Card · Divider · Accordion · App Shell (V1 compatibility + V2 recommended) |
|
|
164
134
|
|
|
165
|
-
|
|
135
|
+
→ [**Explore every component in the live Storybook**](https://samyssmile.github.io/construct/)
|
|
166
136
|
|
|
167
|
-
|
|
168
|
-
- ✅ ARIA attributes where needed
|
|
169
|
-
- ✅ Full keyboard navigation
|
|
170
|
-
- ✅ Focus management
|
|
171
|
-
- ✅ WCAG 2.1 AA contrast standards
|
|
172
|
-
- ✅ Screen reader support
|
|
173
|
-
- ✅ Respects `prefers-reduced-motion`
|
|
174
|
-
- ✅ Live regions for dynamic content
|
|
137
|
+
## 🎨 Design Tokens
|
|
175
138
|
|
|
176
|
-
|
|
139
|
+
Construct uses a **three-layer token system**: raw *primitives*, theme-aware *semantic* aliases, and stable *component* decisions.
|
|
177
140
|
|
|
178
|
-
|
|
141
|
+
```jsonc
|
|
142
|
+
// primitives — raw values
|
|
143
|
+
{ "color": { "orange": { "500": "#F4581C" }, "stone": { "950": "#16130F" } }, "space": { "4": 8 } }
|
|
179
144
|
|
|
180
|
-
|
|
145
|
+
// semantic — contextual aliases that reference primitives
|
|
146
|
+
{ "color": { "brand": { "primary": "{color.stone.950}", "accent": "{color.orange.500}" } } }
|
|
181
147
|
|
|
182
|
-
|
|
183
|
-
|
|
148
|
+
// component — reusable component decisions
|
|
149
|
+
{ "button": { "height": "{size.controlHeight.md}", "radius": "{radius.control}" } }
|
|
184
150
|
```
|
|
185
151
|
|
|
186
|
-
|
|
152
|
+
The build pipeline (`npm run build`) compiles `tokens/*.json` into:
|
|
187
153
|
|
|
188
|
-
|
|
154
|
+
- **`tokens.css`** — CSS custom properties (`--color-brand-accent`)
|
|
155
|
+
- **`tokens.json`** — resolved values for tooling
|
|
156
|
+
- **`tokens.ts` / `tokens.js`** — typed exports
|
|
189
157
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
158
|
+
> ⚠️ Never hand-edit generated files (`tokens/tokens.*`). Edit the source JSON and run `npm run build`.
|
|
159
|
+
|
|
160
|
+
## ♿ Accessibility
|
|
193
161
|
|
|
194
|
-
|
|
162
|
+
Accessibility is a first-class requirement, not an afterthought:
|
|
163
|
+
|
|
164
|
+
- ✅ Semantic HTML and explicit ARIA/data-state markup contracts
|
|
165
|
+
- ✅ Optional tested keyboard behavior (roving tabindex, focus traps, arrows, typeahead, focus return)
|
|
166
|
+
- ✅ Visible focus indicators (the orange "datum")
|
|
167
|
+
- ✅ Automated WCAG contrast pairs across built-in and custom themes
|
|
168
|
+
- ✅ Screen-reader semantics and documented live-region patterns for dynamic content
|
|
169
|
+
- ✅ Respects `prefers-reduced-motion`
|
|
170
|
+
|
|
171
|
+
The Storybook a11y addon is configured to **fail the build on violations**. See [docs/guidelines.md](docs/guidelines.md) for the detailed patterns.
|
|
172
|
+
|
|
173
|
+
## 🧰 Tech & Tooling
|
|
174
|
+
|
|
175
|
+
| | |
|
|
176
|
+
|---|---|
|
|
177
|
+
| **Distribution** | Plain CSS + design tokens + optional dependency-free ESM behaviors |
|
|
178
|
+
| **Docs & tests** | Storybook 10 · Vitest 4 · Playwright (story-driven) |
|
|
179
|
+
| **a11y testing** | `@storybook/addon-a11y` (fails on violations) |
|
|
180
|
+
| **Token build** | Custom pipeline (`scripts/build-tokens.mjs`) |
|
|
181
|
+
|
|
182
|
+
## 🛠️ Local Development
|
|
195
183
|
|
|
196
184
|
```bash
|
|
197
|
-
npm
|
|
185
|
+
npm install # install dependencies
|
|
186
|
+
npm run storybook # dev server → http://localhost:6006
|
|
187
|
+
npm run audit # reject high/critical dependency advisories
|
|
188
|
+
npm run build # build token and standalone CSS outputs
|
|
189
|
+
npm run check # verify generated, schema, contrast, CSS, export & version contracts
|
|
190
|
+
npm test # run behavior, Storybook, touch & forced-colors browser tests
|
|
198
191
|
```
|
|
199
192
|
|
|
200
193
|
## 🎯 Framework Support
|
|
201
194
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- Svelte (Svelte 4+)
|
|
195
|
+
| Framework | Status |
|
|
196
|
+
|-----------|--------|
|
|
197
|
+
| **Vanilla HTML / CSS** | ✅ Available — use the `ct-` classes directly |
|
|
198
|
+
| **Angular** | ✅ Available — [`@neuravision/ng-construct`](https://github.com/Samyssmile/ng-construct) |
|
|
199
|
+
| **React** | ✅ CSS + headless controllers; [lifecycle example](examples/react/README.md) |
|
|
200
|
+
| **Svelte** | ✅ CSS + headless controllers |
|
|
209
201
|
|
|
210
202
|
## 📖 Documentation
|
|
211
203
|
|
|
212
|
-
- [Design Guidelines](docs/guidelines.md)
|
|
213
|
-
- [Component Usage](components/README.md)
|
|
214
|
-
- [Token
|
|
204
|
+
- [Design Guidelines](docs/guidelines.md) — do's, don'ts & accessibility patterns
|
|
205
|
+
- [Component Usage](components/README.md) — HTML patterns and examples
|
|
206
|
+
- [Token Reference](tokens/README.md) — token structure & naming
|
|
207
|
+
- [Architecture](docs/architecture.md) — package layers and ownership boundaries
|
|
208
|
+
- [Headless Behaviors](docs/behaviors.md) — typed controllers and lifecycle
|
|
209
|
+
- [Fonts](docs/fonts.md) — network-free defaults, hosted opt-in, self-hosting
|
|
210
|
+
- [Governance](docs/governance.md) — Definition of Done and release gates
|
|
211
|
+
- [Changelog](CHANGELOG.md) — release history
|
|
215
212
|
|
|
216
213
|
## 🤝 Contributing
|
|
217
214
|
|
|
218
|
-
Contributions are welcome! Please read
|
|
215
|
+
Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) and our
|
|
216
|
+
[Code of Conduct](CODE_OF_CONDUCT.md) before opening a PR. Found a security issue? See [SECURITY.md](SECURITY.md).
|
|
219
217
|
|
|
220
218
|
## 📄 License
|
|
221
219
|
|
|
222
|
-
MIT
|
|
223
|
-
|
|
224
|
-
## 🙏 Credits
|
|
225
|
-
|
|
226
|
-
Built with accessibility and modern design principles in mind.
|
|
220
|
+
[MIT](LICENSE) © Construct contributors
|
|
227
221
|
|
|
228
222
|
---
|
|
229
223
|
|
|
230
|
-
|
|
224
|
+
<div align="center">
|
|
225
|
+
<sub>Built with accessibility and modern design principles in mind · <a href="https://samyssmile.github.io/construct/">Live Storybook</a></sub>
|
|
226
|
+
</div>
|