hazo_ui 3.5.0 → 4.2.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 +56 -0
- package/README.md +111 -0
- package/SETUP_CHECKLIST.md +8 -1
- package/dist/index.cjs +285 -604
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -63
- package/dist/index.d.ts +92 -63
- package/dist/index.js +279 -602
- package/dist/index.js.map +1 -1
- package/package.json +5 -8
package/CHANGE_LOG.md
CHANGED
|
@@ -5,6 +5,62 @@ 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
|
+
## v4.2.0 (2026-06-14)
|
|
9
|
+
|
|
10
|
+
### New
|
|
11
|
+
- `HazoUiImageCropper` — round profile-photo cropper built on `react-easy-crop`.
|
|
12
|
+
Pan and zoom a source image inside a 320 px stage; uses `forwardRef` to expose a
|
|
13
|
+
`getCroppedBlob()` imperative handle so parent components (e.g. a dialog confirm
|
|
14
|
+
button) can request the WebP blob on demand. Zoom control uses the existing
|
|
15
|
+
`Slider` primitive. All user-facing strings are props with English defaults.
|
|
16
|
+
- `HazoUiImageCropperDialog` — dialog wrapper (built on `HazoUiDialog`) that manages
|
|
17
|
+
the File → object URL lifecycle, triggers `getCroppedBlob()` on Confirm, shows a
|
|
18
|
+
loading spinner while the blob is produced, and closes automatically after
|
|
19
|
+
`onConfirm` resolves. Label props (`title`, `confirmLabel`, `cancelLabel`,
|
|
20
|
+
`zoomLabel`) accept translated strings so no next-intl dependency is needed.
|
|
21
|
+
|
|
22
|
+
### Dependencies
|
|
23
|
+
- **`react-easy-crop` (^6.0.2) added to `dependencies`.**
|
|
24
|
+
|
|
25
|
+
## v4.1.1 (2026-06-14)
|
|
26
|
+
|
|
27
|
+
### New
|
|
28
|
+
- `Slider` — Radix-backed (`@radix-ui/react-slider`) range slider primitive following the shadcn pattern; styled via theme tokens (`bg-primary`/`bg-secondary`) so consumers re-skin via CSS variables. Closes FR-003.
|
|
29
|
+
- `InputAffix` — input with optional `prefix`/`suffix` slots (e.g. a `$` affix) sharing the `Input` primitive's border/height styling; numeric-friendly. Closes FR-004.
|
|
30
|
+
- **ETA Progress Bar** — determinate progress with rolling-window time estimation:
|
|
31
|
+
- `HazoUiProgressBar` — controlled determinate bar driven by a `0..1` `value` prop.
|
|
32
|
+
- `useEtaProgress` — driver hook (`{ value, start, unitDone, finish }`) that estimates remaining time from a rolling window of past run durations.
|
|
33
|
+
- `HazoUiEtaProgress` — storage-backed self-estimating bar that persists its duration window via **`hazo_state`**.
|
|
34
|
+
- Pure estimation helpers `median`, `computeEta`, `easeToward` are exported for direct use/testing.
|
|
35
|
+
|
|
36
|
+
### Dependencies
|
|
37
|
+
- **`hazo_state` (^0.1.0) is now a required peer dependency.** The `hazo_ui` barrel statically imports `hazo_state/client` (for `HazoUiEtaProgress`), so consumers must install `hazo_state` alongside `hazo_ui`. (It was briefly declared optional, which was incorrect — the import is unconditional.)
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- test-app: `hazo_state` webpack alias now uses an exact (`$`) match so subpath imports (`hazo_state/client`) resolve instead of being rewritten into the bare-package path.
|
|
41
|
+
- test-app autotest: `Slider` / `InputAffix` export-contract scenarios now accept `forwardRef`/`memo` components (which are objects, not functions); added `eta_progress_estimation` (pure-helper behaviour) and `eta_progress_ui` (progress-bar export contract) scenarios.
|
|
42
|
+
|
|
43
|
+
## v4.0.0 (2026-06-13)
|
|
44
|
+
|
|
45
|
+
### BREAKING
|
|
46
|
+
|
|
47
|
+
- **`LineChart` and `MultiLineChart` removed.** These components (along with their prop types
|
|
48
|
+
`LineChartProps`, `MultiLineChartProps`, and the `MultiSeries` type) have been extracted from
|
|
49
|
+
`hazo_ui` and re-implemented in `hazo_dataviz` on recharts with the same prop API. Consumers
|
|
50
|
+
must update their imports:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// Before (hazo_ui ≤ 3.x)
|
|
54
|
+
import { LineChart, MultiLineChart, type MultiSeries } from "hazo_ui";
|
|
55
|
+
|
|
56
|
+
// After (hazo_ui 4.x)
|
|
57
|
+
import { LineChart, MultiLineChart, type MultiSeries } from "hazo_dataviz/client";
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
All other chart primitives are **unchanged**: `Sparkline`, `InverseSparkline`, `StackedBars`,
|
|
61
|
+
`DateRangeSelector`, and `FunnelChart` remain in `hazo_ui` along with their shared types
|
|
62
|
+
(`ChartDataPoint`, `ChartDataSeries`, `StackedBar`, `DateRangeOption`, `FunnelStep`).
|
|
63
|
+
|
|
8
64
|
## v3.5.0 (2026-06-12)
|
|
9
65
|
|
|
10
66
|
### New
|
package/README.md
CHANGED
|
@@ -204,6 +204,8 @@ The following components support both global config and prop-level color overrid
|
|
|
204
204
|
|
|
205
205
|
- **[HazoUiConfirmDialog](#hazouiconfirmdialog)** - A compact, opinionated confirmation dialog with accent top border, variant system (destructive, warning, info, success), async loading support, and configurable buttons. Perfect for delete confirmations, unsaved changes warnings, and simple acknowledgments.
|
|
206
206
|
|
|
207
|
+
- **[HazoUiImageCropper / HazoUiImageCropperDialog](#hazouiimagecropper--hazouiimagecropperdialog)** (v4.2.0) - Round profile-photo cropper with pan/zoom built on `react-easy-crop`. Outputs a 512×512 WebP Blob. The standalone `HazoUiImageCropper` exposes a `getCroppedBlob()` imperative handle; `HazoUiImageCropperDialog` wraps it in a dialog with a managed object-URL lifecycle and loading state.
|
|
208
|
+
|
|
207
209
|
- **[HazoUiTable](#hazouitable--column-config-driven-data-table-v2140)** - A column-config-driven data table built on a shadcn `Table` primitive family. Sortable headers, debounced search, multi-column filter / sort dialogs, pagination, row click (mouse + keyboard), loading / empty / no-results states, and a card-per-row mobile fallback. Optional server-side `onLoad`.
|
|
208
210
|
|
|
209
211
|
- **[Drawer](#drawer)** - A `vaul`-backed bottom sheet primitive for mobile UIs. Pair with `useMediaQuery` to swap between `Dialog` and `Drawer` based on viewport width.
|
|
@@ -224,6 +226,20 @@ Lightweight, opinionated components for the four ubiquitous async states: **load
|
|
|
224
226
|
- **[useLoadingState](#useloadingstate)** hook - `{ isLoading, setLoading, withLoading }` with an async wrapper.
|
|
225
227
|
- **[useErrorDisplay](#useerrordisplay)** hook - Passive `{ error, setError, clearError }` that coerces `Error` instances to strings.
|
|
226
228
|
|
|
229
|
+
### Form & Feedback Primitives (v4.1)
|
|
230
|
+
|
|
231
|
+
- **Slider** - Radix-backed (`@radix-ui/react-slider`) range slider following the shadcn pattern. Styled via theme tokens (`bg-primary` / `bg-secondary`) so consumers re-skin through CSS variables.
|
|
232
|
+
- **InputAffix** - Input with optional `prefix` / `suffix` slots (e.g. a `$` affix) sharing the base `Input` primitive's border/height styling; numeric-friendly.
|
|
233
|
+
- **ETA Progress Bar** - Determinate progress with rolling-window time estimation:
|
|
234
|
+
- `HazoUiProgressBar` - controlled determinate bar driven by a `0..1` `value` prop.
|
|
235
|
+
- `useEtaProgress` - driver hook returning `{ value, start, unitDone, finish }` that estimates remaining time from past run durations.
|
|
236
|
+
- `HazoUiEtaProgress` - storage-backed self-estimating bar that persists its duration window via `hazo_state` (a **required** peer dependency of hazo_ui — see Setup).
|
|
237
|
+
- Pure helpers `median`, `computeEta`, `easeToward` are exported for direct use/testing.
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { Slider, InputAffix, HazoUiProgressBar, HazoUiEtaProgress, useEtaProgress } from 'hazo_ui';
|
|
241
|
+
```
|
|
242
|
+
|
|
227
243
|
### shadcn/ui Primitive Re-exports
|
|
228
244
|
|
|
229
245
|
All shadcn/ui base components are re-exported from hazo_ui, so sibling hazo_* packages (and consumers) can import UI primitives from a single source without installing shadcn/ui separately:
|
|
@@ -2110,6 +2126,101 @@ Use the `loading` prop to override this behavior with external control.
|
|
|
2110
2126
|
|
|
2111
2127
|
---
|
|
2112
2128
|
|
|
2129
|
+
## HazoUiImageCropper / HazoUiImageCropperDialog
|
|
2130
|
+
|
|
2131
|
+
Round profile-photo cropper (v4.2.0). Pan and zoom a source image inside a circular
|
|
2132
|
+
stage; outputs a square WebP `Blob` at a configurable resolution (default 512×512).
|
|
2133
|
+
|
|
2134
|
+
### Basic usage — standalone cropper with imperative handle
|
|
2135
|
+
|
|
2136
|
+
```tsx
|
|
2137
|
+
import { useRef } from 'react';
|
|
2138
|
+
import { HazoUiImageCropper, type HazoUiImageCropperHandle } from 'hazo_ui';
|
|
2139
|
+
|
|
2140
|
+
function MyPage() {
|
|
2141
|
+
const cropperRef = useRef<HazoUiImageCropperHandle>(null);
|
|
2142
|
+
|
|
2143
|
+
const handleSave = async () => {
|
|
2144
|
+
const blob = await cropperRef.current!.getCroppedBlob();
|
|
2145
|
+
// Upload blob, create preview, etc.
|
|
2146
|
+
};
|
|
2147
|
+
|
|
2148
|
+
return (
|
|
2149
|
+
<>
|
|
2150
|
+
<HazoUiImageCropper ref={cropperRef} imageSrc={objectUrl} />
|
|
2151
|
+
<button onClick={handleSave}>Save</button>
|
|
2152
|
+
</>
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
```
|
|
2156
|
+
|
|
2157
|
+
### Basic usage — dialog wrapper
|
|
2158
|
+
|
|
2159
|
+
```tsx
|
|
2160
|
+
import { useState } from 'react';
|
|
2161
|
+
import { HazoUiImageCropperDialog } from 'hazo_ui';
|
|
2162
|
+
|
|
2163
|
+
function ProfileEditor() {
|
|
2164
|
+
const [file, setFile] = useState<File | null>(null);
|
|
2165
|
+
const [open, setOpen] = useState(false);
|
|
2166
|
+
|
|
2167
|
+
return (
|
|
2168
|
+
<>
|
|
2169
|
+
<input type="file" accept="image/*"
|
|
2170
|
+
onChange={e => { setFile(e.target.files![0]); setOpen(true); }} />
|
|
2171
|
+
|
|
2172
|
+
<HazoUiImageCropperDialog
|
|
2173
|
+
open={open}
|
|
2174
|
+
onOpenChange={setOpen}
|
|
2175
|
+
file={file}
|
|
2176
|
+
onConfirm={async (blob) => {
|
|
2177
|
+
await uploadAvatar(blob);
|
|
2178
|
+
}}
|
|
2179
|
+
title="Crop photo"
|
|
2180
|
+
confirmLabel="Save"
|
|
2181
|
+
cancelLabel="Cancel"
|
|
2182
|
+
zoomLabel="Zoom"
|
|
2183
|
+
/>
|
|
2184
|
+
</>
|
|
2185
|
+
);
|
|
2186
|
+
}
|
|
2187
|
+
```
|
|
2188
|
+
|
|
2189
|
+
### HazoUiImageCropper Props
|
|
2190
|
+
|
|
2191
|
+
| Prop | Type | Default | Description |
|
|
2192
|
+
|------|------|---------|-------------|
|
|
2193
|
+
| `imageSrc` | `string` | — | **Required.** Source image URL or object URL |
|
|
2194
|
+
| `onCropped` | `(blob: Blob) => void \| Promise<void>` | — | Optional convenience callback when blob is produced |
|
|
2195
|
+
| `outputSize` | `number` | `512` | Output canvas dimensions in pixels (square) |
|
|
2196
|
+
| `quality` | `number` | `0.9` | WebP quality (0–1) |
|
|
2197
|
+
| `zoomLabel` | `string` | `"Zoom"` | Zoom slider label (pass a translated string) |
|
|
2198
|
+
| `className` | `string` | — | Additional className for the root element |
|
|
2199
|
+
|
|
2200
|
+
The component accepts a `ref` of type `HazoUiImageCropperHandle` exposing:
|
|
2201
|
+
|
|
2202
|
+
| Method | Returns | Description |
|
|
2203
|
+
|--------|---------|-------------|
|
|
2204
|
+
| `getCroppedBlob()` | `Promise<Blob>` | Produces a WebP blob from the current crop area |
|
|
2205
|
+
|
|
2206
|
+
### HazoUiImageCropperDialog Props
|
|
2207
|
+
|
|
2208
|
+
| Prop | Type | Default | Description |
|
|
2209
|
+
|------|------|---------|-------------|
|
|
2210
|
+
| `open` | `boolean` | — | **Required.** Controls dialog visibility |
|
|
2211
|
+
| `onOpenChange` | `(open: boolean) => void` | — | **Required.** Called when dialog open state changes |
|
|
2212
|
+
| `file` | `File \| null` | — | **Required.** The image file to crop |
|
|
2213
|
+
| `onConfirm` | `(blob: Blob) => void \| Promise<void>` | — | **Required.** Called with the cropped blob on Save |
|
|
2214
|
+
| `onCancel` | `() => void` | — | Called when the user cancels |
|
|
2215
|
+
| `title` | `string` | `"Crop photo"` | Dialog title |
|
|
2216
|
+
| `confirmLabel` | `string` | `"Save"` | Confirm button text |
|
|
2217
|
+
| `cancelLabel` | `string` | `"Cancel"` | Cancel button text |
|
|
2218
|
+
| `zoomLabel` | `string` | `"Zoom"` | Zoom slider label |
|
|
2219
|
+
| `outputSize` | `number` | `512` | Output size in pixels |
|
|
2220
|
+
| `quality` | `number` | `0.9` | WebP quality (0–1) |
|
|
2221
|
+
|
|
2222
|
+
---
|
|
2223
|
+
|
|
2113
2224
|
## HazoUiDialog
|
|
2114
2225
|
|
|
2115
2226
|
A flexible, standardized dialog component with customizable animations, sizes, and theming. Built on Radix UI Dialog primitives with a consistent header/body/footer layout.
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -98,11 +98,13 @@ The following peer dependencies are required:
|
|
|
98
98
|
|
|
99
99
|
- [ ] React (^18.0.0 or ^19.0.0)
|
|
100
100
|
- [ ] React DOM (^18.0.0 or ^19.0.0)
|
|
101
|
+
- [ ] hazo_core (^1.2.0)
|
|
102
|
+
- [ ] hazo_state (^0.1.0) — the `hazo_ui` barrel statically imports `hazo_state/client` (for `HazoUiEtaProgress`), so this is **required** even if you don't use the ETA progress bar.
|
|
101
103
|
|
|
102
104
|
If not already installed:
|
|
103
105
|
|
|
104
106
|
```bash
|
|
105
|
-
npm install react react-dom
|
|
107
|
+
npm install react react-dom hazo_core hazo_state
|
|
106
108
|
```
|
|
107
109
|
|
|
108
110
|
### 3. Install Required Dependencies
|
|
@@ -137,6 +139,11 @@ npm install @radix-ui/react-dialog @radix-ui/react-popover @radix-ui/react-selec
|
|
|
137
139
|
- **useLoadingState, useErrorDisplay** hooks: No additional dependencies
|
|
138
140
|
- **Celebration (v2.18.0)**:
|
|
139
141
|
- **CelebrationProvider, celebrate, CELEBRATION_GRADIENT**: No additional peer deps — `canvas-confetti` and `html-to-image` are bundled direct dependencies
|
|
142
|
+
- **Form & Feedback primitives (v4.1)**:
|
|
143
|
+
- **Slider**: `@radix-ui/react-slider`
|
|
144
|
+
- **InputAffix**: No additional dependencies (uses the base shadcn/ui `Input` component)
|
|
145
|
+
- **HazoUiProgressBar, useEtaProgress, median, computeEta, easeToward**: No additional dependencies
|
|
146
|
+
- **HazoUiEtaProgress**: `hazo_state` (^0.1.0) — a **required** peer dep of hazo_ui (the barrel imports it unconditionally), so it is always installed regardless of which components you use.
|
|
140
147
|
|
|
141
148
|
### 4. Configure Tailwind CSS
|
|
142
149
|
|