hazo_ui 2.11.0 → 2.17.0
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/CHANGE_LOG.md +228 -0
- package/README.md +491 -0
- package/dist/index.cjs +2959 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +557 -1
- package/dist/index.d.ts +557 -1
- package/dist/index.js +2904 -459
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -0
- package/package.json +1 -1
package/CHANGE_LOG.md
CHANGED
|
@@ -5,6 +5,234 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.17.0] - 2026-05-17
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`hazo_ui_charts` — new chart-primitives sub-section.** Six components
|
|
12
|
+
for the Site Ops Dashboard project, ported from its mockup HTML so the
|
|
13
|
+
app doesn't need a third-party chart lib:
|
|
14
|
+
- `Sparkline` — axisless trend line for KPI cards (12% area fill,
|
|
15
|
+
single endpoint dot, no hover — by design per PRD §6b).
|
|
16
|
+
- `InverseSparkline` — same shape but Y-axis inverted (lower = better)
|
|
17
|
+
for GSC position trends. 62×18 default, used inline in scrollable
|
|
18
|
+
query lists.
|
|
19
|
+
- `LineChart` — full anatomy (3 dashed gridlines, Y ticks max/mid/min,
|
|
20
|
+
X labels start/mid/end, marker dot + dashed guide-line to Y-axis +
|
|
21
|
+
above-left value label). Optional hover tooltip surfaces a cursor +
|
|
22
|
+
bubble at the nearest data index.
|
|
23
|
+
- `MultiLineChart` — shared Y-axis, per-series endpoint marker, no
|
|
24
|
+
area fill (avoids color collisions). Hover bubble shows all series
|
|
25
|
+
stacked. Optional legend below the SVG.
|
|
26
|
+
- `StackedBars` — generic stacked-bar over time. One bar per X
|
|
27
|
+
position; each bar split into top-to-bottom colored bands. Used by
|
|
28
|
+
the GSC position-bucket distribution view.
|
|
29
|
+
- `DateRangeSelector` — segmented control (`value` + `onChange`).
|
|
30
|
+
Framework-agnostic: no `next/navigation` import; consumer wires the
|
|
31
|
+
state. Active pill tints with `--primary`.
|
|
32
|
+
- Pure helpers: `format_num` (compact `1.2k` / `1.3M`),
|
|
33
|
+
`pick_x_label_indices`.
|
|
34
|
+
- Shared types: `ChartDataPoint`, `ChartDataSeries`, `MultiSeries`,
|
|
35
|
+
`StackedBar`, `DateRangeOption`.
|
|
36
|
+
- Dev-app demo at `/charts` with six sections (one per primitive)
|
|
37
|
+
covering rising / falling / flat / with-nulls / all-zeros /
|
|
38
|
+
single-point data shapes.
|
|
39
|
+
|
|
40
|
+
### Notes
|
|
41
|
+
- Hover coordinate mapping uses `getBoundingClientRect()` to translate
|
|
42
|
+
client X → viewBox X. Assumes the SVG renders at `width: 100%` (the
|
|
43
|
+
default we ship). Documented in `src/components/hazo_ui_charts/AGENTS.md`.
|
|
44
|
+
- Axis label color and gridline color are pinned hex (`#8b949e`,
|
|
45
|
+
`#2a3441`) chosen for the Site Ops dark theme. Theming via CSS
|
|
46
|
+
variables is a follow-up if a second consumer needs it.
|
|
47
|
+
- All chart components ship as Client Components by default — the
|
|
48
|
+
library bundle is `"use client"`-stamped at build time, same as the
|
|
49
|
+
rest of hazo_ui. The pure-SVG primitives don't *require* JS to
|
|
50
|
+
render, but they don't get RSC-rendered either.
|
|
51
|
+
|
|
52
|
+
### API
|
|
53
|
+
- No changes to existing components; this is purely additive.
|
|
54
|
+
|
|
55
|
+
## [2.16.0] - 2026-05-17
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- **Restyled `HazoUiMultiSortDialog` and `HazoUiMultiFilterDialog`** for a
|
|
59
|
+
modern, Linear/Notion-style appearance:
|
|
60
|
+
- Tighter dialog chrome: bordered header, padded body, bordered footer
|
|
61
|
+
bar with subtle muted background — replaces the flat, dated look.
|
|
62
|
+
- **Sort dialog**: each row now shows a numbered priority badge, a
|
|
63
|
+
segmented Asc/Desc pill (replaces the ambiguous switch), and a muted
|
|
64
|
+
delete affordance that reddens on hover.
|
|
65
|
+
- **Filter dialog**: rows have compact mathematical operator symbols
|
|
66
|
+
(`=`, `≠`, `>`, `<`, `≥`, `≤`) in a narrow select; inputs are 32px
|
|
67
|
+
tall for a denser layout; rows match the sort dialog visually.
|
|
68
|
+
- **Footer hierarchy fixed**: `Clear all` is a low-emphasis ghost
|
|
69
|
+
button on the left; `Cancel` (outline) and `Apply` (primary) are
|
|
70
|
+
grouped on the right — `Apply` is the rightmost / final action.
|
|
71
|
+
- Trigger buttons now show an active-count badge next to the icon.
|
|
72
|
+
- Empty state uses a dashed-border placeholder card; the "Add field"
|
|
73
|
+
affordance matches and disables itself when all fields are added.
|
|
74
|
+
- **Dialog animation**: removed `slide-in-from-left-1/2` /
|
|
75
|
+
`slide-out-to-left-1/2` classes from `DialogContent`. Modals now
|
|
76
|
+
fade + zoom in place from center — no more horizontal "drift" that
|
|
77
|
+
caught the dialog mid-animation looking off-screen.
|
|
78
|
+
|
|
79
|
+
### API
|
|
80
|
+
- All component props (including the color-override props on both
|
|
81
|
+
dialogs) are unchanged; this is a visual refresh, not a contract
|
|
82
|
+
change. Existing consumers do not need to update call sites.
|
|
83
|
+
|
|
84
|
+
## [2.15.1] - 2026-05-17
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
- **SSR/CSR hydration mismatch in HazoUiTable number/currency/percent
|
|
88
|
+
formatters.** `Intl.NumberFormat(undefined, …)` resolved to the
|
|
89
|
+
runtime's host locale, which differs between Node (server) and the
|
|
90
|
+
browser (client) — e.g. server `$4,812,500.00` vs. client
|
|
91
|
+
`US$4,812,500.00` when the browser default is `en-GB`. The library
|
|
92
|
+
now pins to `"en-US"` so both environments produce the same string.
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
- New `locale?: string` on `TableColumn` (BCP-47 tag, e.g. `"de-DE"`,
|
|
96
|
+
`"ja-JP"`) — opt-out for the new pinned default. Applies to `number`,
|
|
97
|
+
`currency`, and `percent` formatters. Date formatting was unaffected
|
|
98
|
+
and is unchanged (it uses `date-fns`, not `Intl`).
|
|
99
|
+
|
|
100
|
+
## [2.15.0] - 2026-05-17
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
- **Shift-click multi-sort on `HazoUiTable` headers.** Plain header
|
|
104
|
+
click still cycles asc → desc → none (single column). Shift-click
|
|
105
|
+
a header to append it as a secondary sort, cycling that column
|
|
106
|
+
asc → desc → removed without collapsing prior columns. Discoverable
|
|
107
|
+
via a `title=` tooltip on the sort button. `useTableState.cycleHeaderSort`
|
|
108
|
+
gains an `append?: boolean` parameter; new `cycleAppendColumn` helper
|
|
109
|
+
alongside the existing `cycleSingleColumn`.
|
|
110
|
+
- **Column-level `currency` override on `TableColumn`.** When `formatter`
|
|
111
|
+
is `"currency"`, the formatter reads `column.currency` (any ISO-4217
|
|
112
|
+
code, e.g. `"EUR"`, `"GBP"`) instead of the previously hard-coded
|
|
113
|
+
`"USD"`. Defaults to `"USD"` when omitted — fully backwards-compatible.
|
|
114
|
+
- **Structured `onLoad` error UX.** `HazoUiTableProps` gains
|
|
115
|
+
`error?: React.ReactNode | ((err: unknown) => React.ReactNode)`.
|
|
116
|
+
`useTableState` exposes `serverError` (always `null` outside server
|
|
117
|
+
mode). On `onLoad` rejection, the table renders the consumer's
|
|
118
|
+
`error` prop in place of rows; if none is provided, a default
|
|
119
|
+
`EmptyState` shows the thrown message. `console.warn` continues to
|
|
120
|
+
log every rejection. Branch added to both the desktop `TableBody`
|
|
121
|
+
and the mobile card view.
|
|
122
|
+
- Dev-app `/table` §9 demos the error state with a rejecting loader.
|
|
123
|
+
§2 copy mentions the new shift-click gesture.
|
|
124
|
+
|
|
125
|
+
### Internal
|
|
126
|
+
- Renamed `use_table_state` → `useTableState` (function only — the
|
|
127
|
+
filename stays `use_table_state.ts`). Aligns with the package's
|
|
128
|
+
other hooks (`useMediaQuery`, `useLoadingState`, `useErrorDisplay`)
|
|
129
|
+
and unblocks the `react-hooks/rules-of-hooks` lint rule.
|
|
130
|
+
- New ESLint v9 flat config (`eslint.config.js`) so `npm run lint`
|
|
131
|
+
works again. Scoped to `src/**/*.{ts,tsx}` with
|
|
132
|
+
`@typescript-eslint` and `react-hooks` rules.
|
|
133
|
+
|
|
134
|
+
### Notes
|
|
135
|
+
- The 200 ms search debounce default is unchanged — the spec §10
|
|
136
|
+
follow-up about tuning needs empirical data from the sister app.
|
|
137
|
+
Consumers can already override per-table via `searchDebounceMs`.
|
|
138
|
+
|
|
139
|
+
## [2.14.0] - 2026-05-17
|
|
140
|
+
|
|
141
|
+
### Added
|
|
142
|
+
- **`Table` shadcn primitive family.** Eight components (`Table`,
|
|
143
|
+
`TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`,
|
|
144
|
+
`TableCell`, `TableCaption`) re-exported under bare shadcn names.
|
|
145
|
+
Matches the canonical shadcn shape — drop-in for consumers that want
|
|
146
|
+
raw markup.
|
|
147
|
+
- **`HazoUiTable` composite.** Column-config-driven data table that
|
|
148
|
+
composes the primitive with an in-memory filter/sort/paginate
|
|
149
|
+
pipeline:
|
|
150
|
+
- `TableColumn` is the single source of truth for display, sort,
|
|
151
|
+
filter, and search metadata.
|
|
152
|
+
- Sortable headers cycle asc → desc → none and replace any
|
|
153
|
+
multi-column sort with single-column on click. Multi-column sort
|
|
154
|
+
via the optional `HazoUiMultiSortDialog` integration; indicators
|
|
155
|
+
show order numbers.
|
|
156
|
+
- Optional toolbar with debounced free-text search (200 ms),
|
|
157
|
+
`HazoUiMultiFilterDialog`, and `HazoUiMultiSortDialog`. Available
|
|
158
|
+
fields are derived from columns — declared once.
|
|
159
|
+
- Loading state via `SkeletonBar`; empty / no-results via
|
|
160
|
+
`EmptyState`.
|
|
161
|
+
- Optional pagination footer with "Showing X–Y of Z" + Prev/Next.
|
|
162
|
+
- Optional row click with full mouse + keyboard support (Enter,
|
|
163
|
+
Space) when `onRowClick` is set.
|
|
164
|
+
- Mobile card-per-row fallback below a configurable breakpoint
|
|
165
|
+
(default 768 px). Opt out with `mobileCardFallback={false}`.
|
|
166
|
+
- Optional `onLoad({ page, sort, filter })` for server-side data;
|
|
167
|
+
latest-request-wins.
|
|
168
|
+
- Dev-app `/table` route with eight demo sections covering every
|
|
169
|
+
acceptance scenario.
|
|
170
|
+
|
|
171
|
+
### Dependencies
|
|
172
|
+
- No new dependencies. Composes existing `Skeleton`, `EmptyState`,
|
|
173
|
+
`Card`, `Input`, `Button`, `HazoUiMultiSortDialog`,
|
|
174
|
+
`HazoUiMultiFilterDialog`, `useMediaQuery` from this package, plus
|
|
175
|
+
`date-fns` and `lucide-react` (already deps).
|
|
176
|
+
|
|
177
|
+
## [2.13.1] - 2026-05-16
|
|
178
|
+
|
|
179
|
+
### Changed
|
|
180
|
+
- **`KanbanEditor` is now built on `HazoUiDialog`** (was raw shadcn `Dialog` primitives). Picks up the standardized header (with `title` + `description` so Radix's missing-`Description` warning is gone naturally), the standardized Save/Cancel footer with built-in `actionButtonLoading` spinner + `actionButtonDisabled`, and a priority-tinted full-width header bar via `headerBar` + `headerBarColor` — reads `hsl(var(--hazo-kanban-priority-{p0..p3}))` for visual continuity with the card left borders. The Save button gets a `Check` icon for clarity.
|
|
181
|
+
- Auto-detect default editor now appends a **Status** select at the end (sourced from the kanban's `columns`), so users can move the card between columns from the editor out of the box without configuring `editorFields`.
|
|
182
|
+
- Field labels rendered slightly smaller and muted (`text-xs font-medium text-muted-foreground`) for a more compact SaaS density.
|
|
183
|
+
|
|
184
|
+
### Added
|
|
185
|
+
- New `'status'` value on `KanbanEditorFieldType`. Renders a `Select` pre-populated from the kanban's `columns` prop (label = `column.title`, value = `column.key`). Bound to `columnKey` by convention; saving with a different status moves the card to a new column through the consumer's `onCardSave` handler — same code path as `onMove`.
|
|
186
|
+
- Dev-app §7 editor declares `{ key: 'columnKey', type: 'status', label: 'Status' }` so the demo exercises the new field type.
|
|
187
|
+
|
|
188
|
+
### Removed
|
|
189
|
+
- The explicit `aria-describedby={undefined}` workaround on `DialogContent` from v2.13.0 — `HazoUiDialog` exposes a proper `description` prop that satisfies Radix without the escape hatch.
|
|
190
|
+
|
|
191
|
+
## [2.13.0] - 2026-05-16
|
|
192
|
+
|
|
193
|
+
### Changed (breaking, but pre-publish)
|
|
194
|
+
- **Renamed `HazoUiBoard` family to `HazoUiKanban`.** v2.12.0 was committed to git but never `npm publish`'d, so this is a hard rename with no deprecation shim. Affected exports: `HazoUiBoard` → `HazoUiKanban`, `HazoUiBoardFilter` → `HazoUiKanbanFilter`, `applyBoardFilter` → `applyKanbanFilter`, plus the corresponding type aliases (`BoardItem` → `KanbanItem`, etc.). CSS class prefixes `cls_hazo_board_*` → `cls_hazo_kanban_*`; CSS variables `--hazo-board-*` → `--hazo-kanban-*`. Dev-app route `/board` → `/kanban`.
|
|
195
|
+
|
|
196
|
+
### Added
|
|
197
|
+
- **Out-of-the-box card editor.** Each card now carries a pencil icon (top-right, opacity-0 idle, opacity-100 on hover/focus). Clicking opens a `HazoUiDialog`-shell editor. Three rendering modes:
|
|
198
|
+
1. `renderCardEditor` render-prop — full control over the body.
|
|
199
|
+
2. `editorFields` declarative config — library renders one row per field declaration. Six built-in types: `text`, `textarea`, `select`, `number`, `checkbox`, `priority`. Required-field gating disables Save when text/textarea/number fields are empty.
|
|
200
|
+
3. Neither — library auto-detects string-typed fields on the item (skipping `id`, `columnKey`, `priority`).
|
|
201
|
+
- **Async save lifecycle.** `onCardSave` returns `void | Promise<void>`. A returned Promise gates dialog close and shows a "Saving…" spinner; a rejected Promise keeps the dialog open with `ctx.error` populated. Consumer is responsible for updating `items` on success (symmetric with `onMove`).
|
|
202
|
+
- Seven new props on `HazoUiKanbanProps<T>`: `editorFields`, `editorPriorities`, `editorTitle`, `renderCardEditor`, `hideEditorFooter`, `onCardSave`, `disableEdit`.
|
|
203
|
+
- Four new public types: `KanbanEditorField`, `KanbanEditorFieldType`, `KanbanEditorCtx<T>`, `KanbanSaveEvent<T>`.
|
|
204
|
+
- Dev-app demo at `/kanban` extended with three new sections (§6 default editor, §7 declarative editor, §8 renderCardEditor override).
|
|
205
|
+
|
|
206
|
+
### Fixed
|
|
207
|
+
- Suppressed Radix `DialogContent` missing-`Description` warning in `KanbanEditor` by setting `aria-describedby={undefined}` explicitly. Caught during the v2.13.0 smoke test — every editor open emitted a console warning under React strict mode.
|
|
208
|
+
|
|
209
|
+
### Notes
|
|
210
|
+
- No new CSS variables — the editor uses existing shadcn Dialog tokens and input/select/checkbox/textarea/button variables.
|
|
211
|
+
- The pencil icon is hidden when `disableEdit={true}` OR `onCardSave` is not provided (no point letting the user edit if nothing happens on save).
|
|
212
|
+
- The pencil's `pointerdown`/`mousedown`/`keydown` events stop propagation so dnd-kit's PointerSensor doesn't interpret the click as the start of a drag.
|
|
213
|
+
- One shared `<KanbanEditor>` instance mounts at the orchestrator level, not one Dialog per card.
|
|
214
|
+
- No `SETUP_CHECKLIST.md` changes (no new setup steps for consumers).
|
|
215
|
+
|
|
216
|
+
## [2.12.0] - 2026-05-16
|
|
217
|
+
|
|
218
|
+
### Added
|
|
219
|
+
- **`HazoUiBoard`** — drag-drop kanban board primitive with mobile tab-strip / desktop column-grid layout switch via pure CSS. Wraps `@dnd-kit/*` internally; consumers see only the `HazoUi*` API. Optimistic-overlay state model: `items` is consumer-controlled; failed moves snap back via `handle.revert()` carried on the `BoardMoveEvent`.
|
|
220
|
+
- **`HazoUiBoardFilter`** — controlled-or-uncontrolled filter bar with free-text search, multi-select category chips (`ToggleGroup type="multiple"`), and single-select priority chips. Decoupled from `HazoUiBoard` — consumer applies the filter to `items` before passing in.
|
|
221
|
+
- **`applyBoardFilter`** — pure helper that filters `items` by search / categories / priority. Convenience export; consumers can swap in their own filter function.
|
|
222
|
+
- Keyboard navigation per `@dnd-kit/accessibility` patterns (Tab focus → Space pick up → Arrow keys → Space drop → Esc cancel).
|
|
223
|
+
- Custom screen-reader announcements that name the action and column; override-able via the `announcements` prop.
|
|
224
|
+
- New CSS custom properties in both `src/styles/globals.css` (dev-app input) and `src/styles/hazo-ui.css` (shipped to `dist/styles.css`): `--hazo-board-priority-p0..p3` (HSL channels), `--hazo-board-card-bg`, `--hazo-board-card-border`, `--hazo-board-column-gap`. Apps can re-theme by overriding any variable in their cascade.
|
|
225
|
+
- Dev-app demo at `dev-app/app/board/page.tsx` (route `/board`) with 5 sections: default kanban, controlled filter, uncontrolled filter, keyboard-only walkthrough, and optimistic-update + revert.
|
|
226
|
+
|
|
227
|
+
### Fixed (during the v2.12.0 cycle)
|
|
228
|
+
- **dev-app `next build` failure on pre-existing UI components.** `dev-app/package.json` pinned `@types/react` to `18.3.28` (workspace-root version) so type-check no longer fails in `src/components/ui/button-group.tsx` and `toggle-group.tsx` with "Type 'bigint' is not assignable to type 'ReactNode'". Pre-existing infrastructure issue surfaced during board demo wiring.
|
|
229
|
+
|
|
230
|
+
### Notes
|
|
231
|
+
- Sub-components `BoardColumn` and `BoardCard` are intentionally internal — the data-driven `HazoUiBoard` API (`columns`, `items`, `renderCard`) is the only entry point.
|
|
232
|
+
- `HazoUiBoard` passes a `React.useId()`-derived value as `DndContext`'s `id` prop so multiple boards on one page produce stable, SSR-deterministic `aria-describedby` IDs (no hydration warnings).
|
|
233
|
+
- No new dependencies (`@dnd-kit/*` was already in `dependencies` from prior versions).
|
|
234
|
+
- No `SETUP_CHECKLIST.md` changes (no new setup steps for consumers).
|
|
235
|
+
|
|
8
236
|
## [2.11.0] - 2026-05-16
|
|
9
237
|
|
|
10
238
|
### Fixed
|