hazo_ui 6.13.1 → 6.15.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 +63 -0
- package/dist/index.cjs +27 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +27 -18
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGE_LOG.md
CHANGED
|
@@ -5,6 +5,69 @@ 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
|
+
## v6.15.0 (2026-10-13)
|
|
9
|
+
|
|
10
|
+
### Added — `useHazoEvent` hook
|
|
11
|
+
|
|
12
|
+
- `useHazoEvent(pkg, event, handler)` subscribes to the `hazo:<pkg>:<event>`
|
|
13
|
+
`CustomEvent` dispatched via hazo_core's `dispatchHazoEvent` (requires
|
|
14
|
+
`hazo_core ^2.5.0`). Stable-ref `useEffect` listener (re-subscribing a new
|
|
15
|
+
`handler` on every render never adds a duplicate listener), cleans up on
|
|
16
|
+
unmount. The subscribe-side counterpart of the `hazo:<pkg>:<event>`
|
|
17
|
+
convention — lets a host app react to a hazo_* package's internal state
|
|
18
|
+
change with zero coupling. First consumer: Kinstripe's admin feedback
|
|
19
|
+
badges reacting to hazo_feedback's `status-changed` event.
|
|
20
|
+
|
|
21
|
+
## v6.14.1 (2026-10-13)
|
|
22
|
+
|
|
23
|
+
### Fixed — `useFullscreen` silently did nothing when the native API rejected the request
|
|
24
|
+
|
|
25
|
+
- `enter()` only fell back to CSS-driven pseudo-fullscreen when
|
|
26
|
+
`requestFullscreen` was entirely absent (iOS Safari). When the API exists
|
|
27
|
+
but the browser *rejects* the call — most commonly a cross-origin iframe
|
|
28
|
+
embed missing `allow="fullscreen"` (`SecurityError`) — the rejection was
|
|
29
|
+
silently swallowed with no fallback, so the fullscreen button appeared to
|
|
30
|
+
do nothing.
|
|
31
|
+
- `exit()` and `toggle()` had matching bugs once pseudo-fullscreen could be
|
|
32
|
+
reached this way: both branched on `document.fullscreenElement` (always
|
|
33
|
+
`null` in pseudo-fullscreen), so `exit()` could never clear the state and
|
|
34
|
+
`toggle()` would call `enter()` again instead of exiting. Both now branch
|
|
35
|
+
on the hook's own tracked `isFullscreen` state instead.
|
|
36
|
+
|
|
37
|
+
## v6.14.0 (2026-10-04)
|
|
38
|
+
|
|
39
|
+
### Added — German (`de`) catalog and LocalePicker demo
|
|
40
|
+
|
|
41
|
+
- New `src/locales/de.json`: German translation of all 219 keys in `en.json`
|
|
42
|
+
(flat dotted keys, identical key set, every `{{placeholder}}` preserved
|
|
43
|
+
verbatim). Consumers register it through hazo_i18n alongside `en`; the package
|
|
44
|
+
does not bundle non-English catalogs into `dist/`.
|
|
45
|
+
- The German catalog was produced with the hazo_i18n pipeline, not by hand:
|
|
46
|
+
`translateMessages()` (export, then Gemini via `hazo_llm_api` per chunk, then
|
|
47
|
+
`importMessages()` with ICU/HTML/expansion validation). 9 chunks, 0 failed,
|
|
48
|
+
0 rejected. 14 non-blocking length-expansion warnings on very short strings
|
|
49
|
+
(e.g. `Save` to `Speichern`) were accepted; no translation was changed by hand.
|
|
50
|
+
- Rationale: German is the first non-English catalog for hazo_ui, and it exercises
|
|
51
|
+
the hazo_i18n export/LLM/import round trip on a real package catalog.
|
|
52
|
+
- Test-app: new `/locale-picker` page demoing `LocalePicker` (dropdown, compact and
|
|
53
|
+
inline variants; native, native+code and code display; flags) with real locale
|
|
54
|
+
alternates. Alternates point at a new `/set-locale` route that sets the
|
|
55
|
+
`NEXT_LOCALE` cookie and redirects back.
|
|
56
|
+
- Test-app `i18n_runtime.ts` now registers the hazo_ui `en` and `de` catalogs under
|
|
57
|
+
the `hazo_ui` namespace, so hazo_ui components switch language in the test-app
|
|
58
|
+
through `HazoUiI18nProvider`. Previously they stayed English.
|
|
59
|
+
|
|
60
|
+
### Fixed — dialog re-render loop on open
|
|
61
|
+
|
|
62
|
+
- `HazoUiMultiFilterDialog` and `HazoUiMultiSortDialog` defaulted `initialFilters` /
|
|
63
|
+
`initialSortFields` to a fresh `[]` each render. Their open-time sync effect depends
|
|
64
|
+
on that prop, so every render reset state to a new array and looped until React
|
|
65
|
+
threw `RangeError: Invalid array length`. Defaults now reference a module-level
|
|
66
|
+
empty constant.
|
|
67
|
+
- `filter_dialog_i18n.test.tsx`: the "explicit title wins" assertion queried
|
|
68
|
+
`getByText("Filter")`, which matched the still-mounted trigger button; it now asserts
|
|
69
|
+
no heading named "Filter".
|
|
70
|
+
|
|
8
71
|
## v6.13.1 (2026-10-03)
|
|
9
72
|
|
|
10
73
|
### Fixed — remaining hardcoded English strings now go through i18n
|
package/dist/index.cjs
CHANGED
|
@@ -1145,10 +1145,11 @@ function FilterFieldItem({
|
|
|
1145
1145
|
] })
|
|
1146
1146
|
] });
|
|
1147
1147
|
}
|
|
1148
|
+
var NO_INITIAL_FILTERS = [];
|
|
1148
1149
|
function HazoUiMultiFilterDialog({
|
|
1149
1150
|
availableFields,
|
|
1150
1151
|
onFilterChange,
|
|
1151
|
-
initialFilters =
|
|
1152
|
+
initialFilters = NO_INITIAL_FILTERS,
|
|
1152
1153
|
title: titleProp,
|
|
1153
1154
|
description: descriptionProp,
|
|
1154
1155
|
headerBackgroundColor,
|
|
@@ -1513,10 +1514,11 @@ function SortableSortFieldItem({
|
|
|
1513
1514
|
}
|
|
1514
1515
|
);
|
|
1515
1516
|
}
|
|
1517
|
+
var NO_INITIAL_SORT_FIELDS = [];
|
|
1516
1518
|
function HazoUiMultiSortDialog({
|
|
1517
1519
|
availableFields,
|
|
1518
1520
|
onSortChange,
|
|
1519
|
-
initialSortFields =
|
|
1521
|
+
initialSortFields = NO_INITIAL_SORT_FIELDS,
|
|
1520
1522
|
title: titleProp,
|
|
1521
1523
|
description: descriptionProp,
|
|
1522
1524
|
headerBackgroundColor,
|
|
@@ -9369,32 +9371,27 @@ function useFullscreen(elementRef) {
|
|
|
9369
9371
|
try {
|
|
9370
9372
|
await get_target().requestFullscreen();
|
|
9371
9373
|
} catch {
|
|
9374
|
+
set_is_fullscreen(true);
|
|
9372
9375
|
}
|
|
9373
9376
|
}, [supported, get_target]);
|
|
9374
9377
|
const exit = React27.useCallback(async () => {
|
|
9375
9378
|
if (typeof document === "undefined") return;
|
|
9376
|
-
if (
|
|
9377
|
-
|
|
9379
|
+
if (document.fullscreenElement) {
|
|
9380
|
+
try {
|
|
9381
|
+
await document.exitFullscreen();
|
|
9382
|
+
} catch {
|
|
9383
|
+
}
|
|
9378
9384
|
return;
|
|
9379
9385
|
}
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
await document.exitFullscreen();
|
|
9383
|
-
} catch {
|
|
9384
|
-
}
|
|
9385
|
-
}, [supported]);
|
|
9386
|
+
set_is_fullscreen(false);
|
|
9387
|
+
}, []);
|
|
9386
9388
|
const toggle = React27.useCallback(async () => {
|
|
9387
|
-
if (
|
|
9388
|
-
if (is_fullscreen) await exit();
|
|
9389
|
-
else await enter();
|
|
9390
|
-
return;
|
|
9391
|
-
}
|
|
9392
|
-
if (document.fullscreenElement) {
|
|
9389
|
+
if (is_fullscreen) {
|
|
9393
9390
|
await exit();
|
|
9394
9391
|
} else {
|
|
9395
9392
|
await enter();
|
|
9396
9393
|
}
|
|
9397
|
-
}, [
|
|
9394
|
+
}, [is_fullscreen, enter, exit]);
|
|
9398
9395
|
return { isFullscreen: is_fullscreen, enter, exit, toggle };
|
|
9399
9396
|
}
|
|
9400
9397
|
function use_wake_lock(active) {
|
|
@@ -13187,6 +13184,18 @@ function LocalePicker({
|
|
|
13187
13184
|
] });
|
|
13188
13185
|
}
|
|
13189
13186
|
LocalePicker.displayName = "LocalePicker";
|
|
13187
|
+
function useHazoEvent(pkg, event, handler) {
|
|
13188
|
+
const handler_ref = React27.useRef(handler);
|
|
13189
|
+
handler_ref.current = handler;
|
|
13190
|
+
React27.useEffect(() => {
|
|
13191
|
+
const event_name = `hazo:${pkg}:${event}`;
|
|
13192
|
+
const listener = (e) => {
|
|
13193
|
+
handler_ref.current(e.detail);
|
|
13194
|
+
};
|
|
13195
|
+
window.addEventListener(event_name, listener);
|
|
13196
|
+
return () => window.removeEventListener(event_name, listener);
|
|
13197
|
+
}, [pkg, event]);
|
|
13198
|
+
}
|
|
13190
13199
|
|
|
13191
13200
|
Object.defineProperty(exports, "rawToast", {
|
|
13192
13201
|
enumerable: true,
|
|
@@ -13425,6 +13434,7 @@ exports.useDebounce = useDebounce;
|
|
|
13425
13434
|
exports.useErrorDisplay = useErrorDisplay;
|
|
13426
13435
|
exports.useEtaProgress = useEtaProgress;
|
|
13427
13436
|
exports.useFullscreen = useFullscreen;
|
|
13437
|
+
exports.useHazoEvent = useHazoEvent;
|
|
13428
13438
|
exports.useHazoUiT = useHazoUiT;
|
|
13429
13439
|
exports.useIsMobile = useIsMobile;
|
|
13430
13440
|
exports.useLoadingState = useLoadingState;
|