hazo_ui 6.0.0 → 6.3.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/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import * as React27 from 'react';
5
- import React27__default, { lazy, useRef, useState, useCallback, useEffect, useMemo, Fragment, Suspense } from 'react';
5
+ import React27__default, { lazy, useRef, useState, useCallback, useEffect, useMemo, Fragment, Suspense, useSyncExternalStore } from 'react';
6
6
  import { generateRequestId } from 'hazo_core';
7
7
  import { withContext, setBrowserCorrelationId } from 'hazo_core/client';
8
8
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
@@ -8749,6 +8749,23 @@ function errorToast({ title, description, duration = 5e3, action }) {
8749
8749
  action: action ? { label: action.label, onClick: action.onClick } : void 0
8750
8750
  });
8751
8751
  }
8752
+ function permissionToast({
8753
+ missingPermissions,
8754
+ descriptions,
8755
+ action,
8756
+ duration = 5e3
8757
+ }) {
8758
+ const description = missingPermissions.length === 0 ? "You do not have permission to perform this action." : `Missing: ${missingPermissions.map((key) => {
8759
+ const label = descriptions?.[key];
8760
+ return label ? `\`${key}\` \u2014 ${label}` : `\`${key}\``;
8761
+ }).join("; ")}`;
8762
+ return errorToast({
8763
+ title: "Permission required",
8764
+ description,
8765
+ action,
8766
+ duration
8767
+ });
8768
+ }
8752
8769
  function useLoadingState(initial = false) {
8753
8770
  const [isLoading, setLoading] = useState(initial);
8754
8771
  const withLoading = useCallback(async (fn) => {
@@ -11857,6 +11874,253 @@ function AppFooter({ variant, footer, identity, className }) {
11857
11874
  );
11858
11875
  }
11859
11876
 
11860
- export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppFooter, AppHeader, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, CanvasTextToolbar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiIcon, HazoUiIconPicker, HazoUiImageCropper, HazoUiImageCropperDialog, HazoUiKanban, HazoUiKanbanFilter, HazoUiMemoryDropdown, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputAffix, InverseSparkline, Label3 as Label, LoadingTimeout, Logo, MarkdownEditor, NotificationCountBadge, NotificationItem, NotificationPanel, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Slider, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, isLucideValue, median, parse_commands_from_text, pick_x_label_indices, reset_hazo_ui_config, resolve_animation_classes, safeHref, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, upsertEntry as upsertMemoryEntry, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useMediaQuery, useSessionStorage, useViewport, useWakeLock, use_fullscreen, use_wake_lock };
11877
+ // src/lib/remembered_state.ts
11878
+ function readRememberedState(key) {
11879
+ if (typeof window === "undefined") return null;
11880
+ try {
11881
+ const raw = window.localStorage.getItem(key);
11882
+ return raw ? JSON.parse(raw) : null;
11883
+ } catch {
11884
+ return null;
11885
+ }
11886
+ }
11887
+ function writeRememberedState(key, snapshot) {
11888
+ if (typeof window === "undefined") return;
11889
+ try {
11890
+ window.localStorage.setItem(key, JSON.stringify(snapshot));
11891
+ } catch {
11892
+ }
11893
+ }
11894
+ function hasUrlParam(search, paramName) {
11895
+ try {
11896
+ return new URLSearchParams(search).has(paramName);
11897
+ } catch {
11898
+ return false;
11899
+ }
11900
+ }
11901
+
11902
+ // src/hooks/use_remembered_state.ts
11903
+ function useRememberedState({
11904
+ key,
11905
+ snapshot,
11906
+ restore,
11907
+ enabled = true,
11908
+ debounceMs = 600,
11909
+ skipWhenUrlParam
11910
+ }) {
11911
+ const restoreRef = useRef(restore);
11912
+ useEffect(() => {
11913
+ restoreRef.current = restore;
11914
+ });
11915
+ const didRestore = useRef(false);
11916
+ useEffect(() => {
11917
+ if (didRestore.current) return;
11918
+ didRestore.current = true;
11919
+ if (!enabled) return;
11920
+ if (typeof window === "undefined") return;
11921
+ if (skipWhenUrlParam && hasUrlParam(window.location.search, skipWhenUrlParam)) return;
11922
+ const remembered = readRememberedState(key);
11923
+ if (remembered === null) return;
11924
+ try {
11925
+ restoreRef.current(remembered);
11926
+ } catch {
11927
+ }
11928
+ }, [key, enabled, skipWhenUrlParam]);
11929
+ const snapshotJson = JSON.stringify(snapshot);
11930
+ const writeTimer = useRef(null);
11931
+ useEffect(() => {
11932
+ if (!enabled) return;
11933
+ if (writeTimer.current) clearTimeout(writeTimer.current);
11934
+ writeTimer.current = setTimeout(() => {
11935
+ writeRememberedState(key, snapshot);
11936
+ }, debounceMs);
11937
+ return () => {
11938
+ if (writeTimer.current) clearTimeout(writeTimer.current);
11939
+ };
11940
+ }, [key, snapshotJson, enabled, debounceMs]);
11941
+ }
11942
+ var COARSE_QUERY = "(pointer: coarse)";
11943
+ function subscribe_coarse(notify) {
11944
+ if (typeof window === "undefined") return () => {
11945
+ };
11946
+ const mql = window.matchMedia(COARSE_QUERY);
11947
+ mql.addEventListener("change", notify);
11948
+ return () => mql.removeEventListener("change", notify);
11949
+ }
11950
+ function get_coarse_snapshot() {
11951
+ return window.matchMedia(COARSE_QUERY).matches;
11952
+ }
11953
+ function get_coarse_server_snapshot() {
11954
+ return false;
11955
+ }
11956
+ function useLongPress({
11957
+ onLongPress,
11958
+ delayMs = 500,
11959
+ moveThresholdPx = 8,
11960
+ hapticMs = 10
11961
+ }) {
11962
+ const isCoarse = useSyncExternalStore(
11963
+ subscribe_coarse,
11964
+ get_coarse_snapshot,
11965
+ get_coarse_server_snapshot
11966
+ );
11967
+ const timerRef = useRef(null);
11968
+ const originRef = useRef(null);
11969
+ const firedRef = useRef(false);
11970
+ const eventRef = useRef(null);
11971
+ const cancel = useCallback(() => {
11972
+ if (timerRef.current !== null) {
11973
+ clearTimeout(timerRef.current);
11974
+ timerRef.current = null;
11975
+ }
11976
+ originRef.current = null;
11977
+ eventRef.current = null;
11978
+ }, []);
11979
+ useEffect(() => () => cancel(), [cancel]);
11980
+ const noop = useCallback(() => {
11981
+ }, []);
11982
+ const handlePointerDown = useCallback(
11983
+ (e) => {
11984
+ if (originRef.current && originRef.current.pointerId !== e.pointerId) {
11985
+ cancel();
11986
+ return;
11987
+ }
11988
+ firedRef.current = false;
11989
+ originRef.current = { x: e.clientX, y: e.clientY, pointerId: e.pointerId };
11990
+ eventRef.current = e;
11991
+ timerRef.current = setTimeout(() => {
11992
+ timerRef.current = null;
11993
+ firedRef.current = true;
11994
+ if (hapticMs > 0 && typeof navigator !== "undefined" && "vibrate" in navigator) {
11995
+ try {
11996
+ navigator.vibrate?.(hapticMs);
11997
+ } catch {
11998
+ }
11999
+ }
12000
+ const evt = eventRef.current;
12001
+ if (evt) onLongPress(evt);
12002
+ }, delayMs);
12003
+ },
12004
+ [delayMs, hapticMs, cancel, onLongPress]
12005
+ );
12006
+ const handlePointerMove = useCallback(
12007
+ (e) => {
12008
+ if (!originRef.current) return;
12009
+ const dx = e.clientX - originRef.current.x;
12010
+ const dy = e.clientY - originRef.current.y;
12011
+ if (Math.hypot(dx, dy) > moveThresholdPx) cancel();
12012
+ },
12013
+ [moveThresholdPx, cancel]
12014
+ );
12015
+ const handlePointerUpOrCancel = useCallback(() => {
12016
+ cancel();
12017
+ }, [cancel]);
12018
+ const handleClick = useCallback((e) => {
12019
+ if (firedRef.current) {
12020
+ e.preventDefault();
12021
+ e.stopPropagation();
12022
+ firedRef.current = false;
12023
+ }
12024
+ }, []);
12025
+ if (!isCoarse) {
12026
+ return {
12027
+ onPointerDown: noop,
12028
+ onPointerMove: noop,
12029
+ onPointerUp: noop,
12030
+ onPointerCancel: noop,
12031
+ onClick: noop
12032
+ };
12033
+ }
12034
+ return {
12035
+ onPointerDown: handlePointerDown,
12036
+ onPointerMove: handlePointerMove,
12037
+ onPointerUp: handlePointerUpOrCancel,
12038
+ onPointerCancel: handlePointerUpOrCancel,
12039
+ onClick: handleClick
12040
+ };
12041
+ }
12042
+
12043
+ // src/lib/announce.ts
12044
+ var DEFAULT_ANNOUNCE_EVENT = "hazo_ui:announce";
12045
+ function announce(message, priority = "polite", options) {
12046
+ if (typeof window === "undefined") return;
12047
+ const trimmed = message.trim();
12048
+ if (!trimmed) return;
12049
+ const eventName = options?.eventName ?? DEFAULT_ANNOUNCE_EVENT;
12050
+ window.dispatchEvent(
12051
+ new CustomEvent(eventName, {
12052
+ detail: { message: trimmed, priority }
12053
+ })
12054
+ );
12055
+ }
12056
+ function LiveRegion({
12057
+ eventName = DEFAULT_ANNOUNCE_EVENT,
12058
+ className = "sr-only",
12059
+ clearAfterMs = 6e3
12060
+ }) {
12061
+ const [polite, set_polite] = useState("");
12062
+ const [assertive, set_assertive] = useState("");
12063
+ const polite_timer = useRef(null);
12064
+ const assertive_timer = useRef(null);
12065
+ useEffect(() => {
12066
+ const handler = (e) => {
12067
+ const detail = e.detail;
12068
+ if (!detail?.message) return;
12069
+ if (detail.priority === "assertive") {
12070
+ if (assertive_timer.current) clearTimeout(assertive_timer.current);
12071
+ set_assertive((prev) => prev === detail.message ? `${detail.message} ` : detail.message);
12072
+ assertive_timer.current = setTimeout(() => set_assertive(""), clearAfterMs);
12073
+ } else {
12074
+ if (polite_timer.current) clearTimeout(polite_timer.current);
12075
+ set_polite((prev) => prev === detail.message ? `${detail.message} ` : detail.message);
12076
+ polite_timer.current = setTimeout(() => set_polite(""), clearAfterMs);
12077
+ }
12078
+ };
12079
+ window.addEventListener(eventName, handler);
12080
+ return () => {
12081
+ window.removeEventListener(eventName, handler);
12082
+ if (polite_timer.current) clearTimeout(polite_timer.current);
12083
+ if (assertive_timer.current) clearTimeout(assertive_timer.current);
12084
+ };
12085
+ }, [eventName, clearAfterMs]);
12086
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
12087
+ /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", className, children: polite }),
12088
+ /* @__PURE__ */ jsx("div", { role: "alert", "aria-live": "assertive", "aria-atomic": "true", className, children: assertive })
12089
+ ] });
12090
+ }
12091
+
12092
+ // src/lib/scroll_restore.ts
12093
+ var DEFAULT_SCROLL_RESTORE_PREFIX = "hazo_ui:scrollPos";
12094
+ function buildScrollRestoreKey(prefix, treeId, viewName) {
12095
+ return `${prefix}.${treeId}.${viewName}`;
12096
+ }
12097
+ function saveScrollPos(key, scrollY) {
12098
+ if (typeof window === "undefined") return;
12099
+ try {
12100
+ window.localStorage.setItem(key, String(Math.round(scrollY)));
12101
+ } catch {
12102
+ }
12103
+ }
12104
+ function loadScrollPos(key) {
12105
+ if (typeof window === "undefined") return null;
12106
+ try {
12107
+ const raw = window.localStorage.getItem(key);
12108
+ if (!raw) return null;
12109
+ const n = Number.parseInt(raw, 10);
12110
+ return Number.isFinite(n) ? n : null;
12111
+ } catch {
12112
+ return null;
12113
+ }
12114
+ }
12115
+
12116
+ // src/hooks/use_scroll_restore.ts
12117
+ function useScrollRestore(treeId, viewName, options) {
12118
+ const key = buildScrollRestoreKey(options?.prefix ?? DEFAULT_SCROLL_RESTORE_PREFIX, treeId, viewName);
12119
+ const save = useCallback((scrollY) => saveScrollPos(key, scrollY), [key]);
12120
+ const load = useCallback(() => loadScrollPos(key), [key]);
12121
+ return { save, load };
12122
+ }
12123
+
12124
+ export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppFooter, AppHeader, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, CanvasTextToolbar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DEFAULT_ANNOUNCE_EVENT, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiIcon, HazoUiIconPicker, HazoUiImageCropper, HazoUiImageCropperDialog, HazoUiKanban, HazoUiKanbanFilter, HazoUiMemoryDropdown, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputAffix, InverseSparkline, Label3 as Label, LiveRegion, LoadingTimeout, Logo, MarkdownEditor, NotificationCountBadge, NotificationItem, NotificationPanel, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Slider, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, announce, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, hasUrlParam, isLucideValue, median, parse_commands_from_text, permissionToast, pick_x_label_indices, readRememberedState, reset_hazo_ui_config, resolve_animation_classes, safeHref, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, upsertEntry as upsertMemoryEntry, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useLongPress, useMediaQuery, useRememberedState, useScrollRestore, useSessionStorage, useViewport, useWakeLock, use_fullscreen, use_wake_lock, writeRememberedState };
11861
12125
  //# sourceMappingURL=index.js.map
11862
12126
  //# sourceMappingURL=index.js.map