@hjmds/react 0.8.2
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/README.md +146 -0
- package/dist/actions.d.ts +61 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +54 -0
- package/dist/actions.js.map +1 -0
- package/dist/advanced-display.d.ts +133 -0
- package/dist/advanced-display.d.ts.map +1 -0
- package/dist/advanced-display.js +201 -0
- package/dist/advanced-display.js.map +1 -0
- package/dist/advanced-forms.d.ts +116 -0
- package/dist/advanced-forms.d.ts.map +1 -0
- package/dist/advanced-forms.js +234 -0
- package/dist/advanced-forms.js.map +1 -0
- package/dist/advanced-navigation.d.ts +24 -0
- package/dist/advanced-navigation.d.ts.map +1 -0
- package/dist/advanced-navigation.js +25 -0
- package/dist/advanced-navigation.js.map +1 -0
- package/dist/bottom-navigation.d.ts +37 -0
- package/dist/bottom-navigation.d.ts.map +1 -0
- package/dist/bottom-navigation.js +132 -0
- package/dist/bottom-navigation.js.map +1 -0
- package/dist/date-picker.d.ts +24 -0
- package/dist/date-picker.d.ts.map +1 -0
- package/dist/date-picker.js +81 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/display-public.d.ts +5 -0
- package/dist/display-public.d.ts.map +1 -0
- package/dist/display-public.js +5 -0
- package/dist/display-public.js.map +1 -0
- package/dist/display.d.ts +77 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +51 -0
- package/dist/display.js.map +1 -0
- package/dist/evidence.d.ts +940 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +98 -0
- package/dist/evidence.js.map +1 -0
- package/dist/feedback.d.ts +89 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +41 -0
- package/dist/feedback.js.map +1 -0
- package/dist/file-picker.d.ts +30 -0
- package/dist/file-picker.d.ts.map +1 -0
- package/dist/file-picker.js +40 -0
- package/dist/file-picker.js.map +1 -0
- package/dist/forms-public.d.ts +8 -0
- package/dist/forms-public.d.ts.map +1 -0
- package/dist/forms-public.js +8 -0
- package/dist/forms-public.js.map +1 -0
- package/dist/forms.d.ts +160 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +178 -0
- package/dist/forms.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +17 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +68 -0
- package/dist/internal.js.map +1 -0
- package/dist/layout.d.ts +134 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +167 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation-public.d.ts +6 -0
- package/dist/navigation-public.d.ts.map +1 -0
- package/dist/navigation-public.js +6 -0
- package/dist/navigation-public.js.map +1 -0
- package/dist/navigation.d.ts +65 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +196 -0
- package/dist/navigation.js.map +1 -0
- package/dist/number-field.d.ts +55 -0
- package/dist/number-field.d.ts.map +1 -0
- package/dist/number-field.js +107 -0
- package/dist/number-field.js.map +1 -0
- package/dist/otp-field.d.ts +2 -0
- package/dist/otp-field.d.ts.map +1 -0
- package/dist/otp-field.js +2 -0
- package/dist/otp-field.js.map +1 -0
- package/dist/overlays.d.ts +192 -0
- package/dist/overlays.d.ts.map +1 -0
- package/dist/overlays.js +949 -0
- package/dist/overlays.js.map +1 -0
- package/dist/password-field.d.ts +2 -0
- package/dist/password-field.d.ts.map +1 -0
- package/dist/password-field.js +2 -0
- package/dist/password-field.js.map +1 -0
- package/dist/portal.d.ts +32 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +264 -0
- package/dist/portal.js.map +1 -0
- package/dist/provider.d.ts +38 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +87 -0
- package/dist/provider.js.map +1 -0
- package/dist/select.d.ts +72 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +353 -0
- package/dist/select.js.map +1 -0
- package/dist/selection.d.ts +160 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +225 -0
- package/dist/selection.js.map +1 -0
- package/dist/slider.d.ts +35 -0
- package/dist/slider.d.ts.map +1 -0
- package/dist/slider.js +150 -0
- package/dist/slider.js.map +1 -0
- package/dist/steps.d.ts +29 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +10 -0
- package/dist/steps.js.map +1 -0
- package/dist/styles.css +1349 -0
- package/dist/supplemental-display.d.ts +59 -0
- package/dist/supplemental-display.d.ts.map +1 -0
- package/dist/supplemental-display.js +136 -0
- package/dist/supplemental-display.js.map +1 -0
- package/dist/supplemental-navigation.d.ts +28 -0
- package/dist/supplemental-navigation.d.ts.map +1 -0
- package/dist/supplemental-navigation.js +106 -0
- package/dist/supplemental-navigation.js.map +1 -0
- package/dist/theme.d.ts +5 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +55 -0
- package/dist/theme.js.map +1 -0
- package/dist/toast.d.ts +41 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +250 -0
- package/dist/toast.js.map +1 -0
- package/dist/upload-item.d.ts +18 -0
- package/dist/upload-item.d.ts.map +1 -0
- package/dist/upload-item.js +19 -0
- package/dist/upload-item.js.map +1 -0
- package/package.json +151 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type IconDescriptor } from "@hjmds/design-contracts/components/icon";
|
|
2
|
+
import { type ImageDescriptor, type ImageLoadStatus } from "@hjmds/design-contracts/components/image";
|
|
3
|
+
import { type CounterBadgeSize, type CounterBadgeTone, type CounterBadgeVariant } from "@hjmds/design-contracts/recipes";
|
|
4
|
+
import { type CSSProperties, type HTMLAttributes, type ImgHTMLAttributes, type ReactElement, type ReactEventHandler, type ReactNode, type Ref, type SVGAttributes } from "react";
|
|
5
|
+
export type IconProps = Omit<SVGAttributes<SVGSVGElement>, "children" | "color"> & IconDescriptor;
|
|
6
|
+
export declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
7
|
+
type ImageElementProps = Omit<ImgHTMLAttributes<HTMLImageElement>, "alt" | "aria-hidden" | "aria-label" | "children" | "className" | "height" | "onError" | "onLoad" | "role" | "src" | "style" | "width">;
|
|
8
|
+
/** Canonical props handed to a framework adapter such as `next/image`. */
|
|
9
|
+
export type ImageAdapterProps = ImageElementProps & Readonly<{
|
|
10
|
+
src: string;
|
|
11
|
+
alt: string;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
className?: string;
|
|
15
|
+
style: CSSProperties;
|
|
16
|
+
"aria-hidden"?: true;
|
|
17
|
+
onLoad: ReactEventHandler<HTMLImageElement>;
|
|
18
|
+
onError: ReactEventHandler<HTMLImageElement>;
|
|
19
|
+
ref?: Ref<HTMLImageElement>;
|
|
20
|
+
}>;
|
|
21
|
+
type ImageRootProps = Omit<HTMLAttributes<HTMLSpanElement>, "aria-hidden" | "aria-label" | "aria-labelledby" | "children" | "onError" | "onLoad" | "role">;
|
|
22
|
+
export type ImageProps = ImageRootProps & ImageDescriptor & Readonly<{
|
|
23
|
+
/** Additional native `<img>` props shared with the framework adapter. */
|
|
24
|
+
imageProps?: ImageElementProps & Readonly<{
|
|
25
|
+
className?: string;
|
|
26
|
+
style?: CSSProperties;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Receives the complete accessible image contract. The adapter must pass
|
|
30
|
+
* these props to its underlying image element so HJM can observe failure.
|
|
31
|
+
*/
|
|
32
|
+
renderImage?: (props: ImageAdapterProps) => ReactElement;
|
|
33
|
+
/** Visual content only; HJM keeps the fallback's accessible name. */
|
|
34
|
+
fallback?: ReactNode;
|
|
35
|
+
imageRef?: Ref<HTMLImageElement>;
|
|
36
|
+
onLoad?: ReactEventHandler<HTMLImageElement>;
|
|
37
|
+
onError?: ReactEventHandler<HTMLImageElement>;
|
|
38
|
+
onLoadStatusChange?: (status: Extract<ImageLoadStatus, "loaded" | "error">) => void;
|
|
39
|
+
}>;
|
|
40
|
+
/** Intrinsic-size image with canonical alt semantics and an accessible fallback. */
|
|
41
|
+
export declare const Image: import("react").ForwardRefExoticComponent<ImageProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
42
|
+
export type CounterBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & Readonly<{
|
|
43
|
+
count: number;
|
|
44
|
+
max?: number;
|
|
45
|
+
tone?: CounterBadgeTone;
|
|
46
|
+
size?: CounterBadgeSize;
|
|
47
|
+
variant?: CounterBadgeVariant;
|
|
48
|
+
accessibilityLabel?: string;
|
|
49
|
+
}>;
|
|
50
|
+
export declare const CounterBadge: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLSpanElement>, "children"> & Readonly<{
|
|
51
|
+
count: number;
|
|
52
|
+
max?: number;
|
|
53
|
+
tone?: CounterBadgeTone;
|
|
54
|
+
size?: CounterBadgeSize;
|
|
55
|
+
variant?: CounterBadgeVariant;
|
|
56
|
+
accessibilityLabel?: string;
|
|
57
|
+
}> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=supplemental-display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supplemental-display.d.ts","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getIconTransform, resolveIconDescriptor, } from "@hjmds/design-contracts/components/icon";
|
|
3
|
+
import { imageRecipe, resolveImageAspectRatio, resolveImageDescriptor, resolveImageFallbackAccessibilityLabel, } from "@hjmds/design-contracts/components/image";
|
|
4
|
+
import { counterBadgeRecipe, formatCounterBadgeCount, iconRecipe, } from "@hjmds/design-contracts/recipes";
|
|
5
|
+
import { forwardRef, useState, } from "react";
|
|
6
|
+
import { classNames } from "./internal.js";
|
|
7
|
+
import { useOptionalHjmTheme } from "./provider.js";
|
|
8
|
+
/** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */
|
|
9
|
+
const iconPaths = {
|
|
10
|
+
add: "M12 5v14M5 12h14",
|
|
11
|
+
ai: "M12 2l1.2 4.1L17 8l-3.8 1.9L12 14l-1.2-4.1L7 8l3.8-1.9L12 2ZM19 14l.7 2.3L22 17.5l-2.3 1.2L19 21l-.7-2.3-2.3-1.2 2.3-1.2L19 14Z",
|
|
12
|
+
alert: "M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01",
|
|
13
|
+
back: "M15 18 9 12l6-6M9 12h10",
|
|
14
|
+
calendar: "M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm2-2v4m10-4v4M3 9h18",
|
|
15
|
+
check: "m5 12 4 4L19 6",
|
|
16
|
+
chevronDown: "m6 9 6 6 6-6",
|
|
17
|
+
chevronEnd: "m9 6 6 6-6 6",
|
|
18
|
+
chevronStart: "m15 6-6 6 6 6",
|
|
19
|
+
chevronUp: "m6 15 6-6 6 6",
|
|
20
|
+
close: "M6 6l12 12M18 6 6 18",
|
|
21
|
+
compare: "M8 7h11m0 0-3-3m3 3-3 3M16 17H5m0 0 3-3m-3 3 3 3",
|
|
22
|
+
copy: "M8 8h11a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2V8Zm8 0V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3",
|
|
23
|
+
delete: "M4 7h16M9 7V4h6v3m3 0-1 14H7L6 7m4 4v6m4-6v6",
|
|
24
|
+
download: "M12 3v12m0 0 5-5m-5 5-5-5M4 19v2h16v-2",
|
|
25
|
+
edit: "m4 16-1 5 5-1L19 9l-4-4L4 16Zm9-9 4 4",
|
|
26
|
+
error: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-14v5m0 3h.01",
|
|
27
|
+
favorite: "M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1.1-1.1a5.5 5.5 0 0 0-7.8 7.8L12 21l8.8-8.6a5.5 5.5 0 0 0 0-7.8Z",
|
|
28
|
+
filter: "M3 5h18l-7 8v6l-4 2v-8L3 5Z",
|
|
29
|
+
forward: "m9 6 6 6-6 6m6-6H5",
|
|
30
|
+
help: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-3-13a3 3 0 1 1 4.7 2.5c-1 .7-1.7 1.2-1.7 2.5m0 3h.01",
|
|
31
|
+
home: "m3 11 9-8 9 8v10h-6v-6H9v6H3V11Z",
|
|
32
|
+
info: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-11v6m0-10h.01",
|
|
33
|
+
lock: "M6 10h12v11H6V10Zm3 0V7a3 3 0 0 1 6 0v3",
|
|
34
|
+
menu: "M4 6h16M4 12h16M4 18h16",
|
|
35
|
+
more: "M5 12h.01M12 12h.01M19 12h.01",
|
|
36
|
+
notifications: "M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9Zm-8 12h4",
|
|
37
|
+
pause: "M8 5v14m8-14v14",
|
|
38
|
+
play: "m8 5 11 7-11 7V5Z",
|
|
39
|
+
refresh: "M20 7v5h-5M4 17v-5h5m10.5-3A8 8 0 0 0 6 6l-2 2m.5 7A8 8 0 0 0 18 18l2-2",
|
|
40
|
+
search: "m21 21-4.4-4.4M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z",
|
|
41
|
+
settings: "M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-3.5 2-1.5-2-3.5-2.4 1a8 8 0 0 0-2-1.2L14.7 4h-4l-.4 2.8A8 8 0 0 0 8 8L5.6 7l-2 3.5 2 1.5a8 8 0 0 0 0 2l-2 1.5 2 3.5L8 18a8 8 0 0 0 2.3 1.2l.4 2.8h4l.3-2.8A8 8 0 0 0 17 18l2.4 1 2-3.5-2-1.5a8 8 0 0 0 0-2Z",
|
|
42
|
+
share: "M18 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM6 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm12 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM8.6 16.5l6.8 4M15.4 6.5l-6.8 4",
|
|
43
|
+
success: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-5-10 3 3 7-7",
|
|
44
|
+
trendDown: "M3 7l7 7 4-4 7 7m0 0v-6m0 6h-6",
|
|
45
|
+
trendFlat: "M4 12h16m0 0-4-4m4 4-4 4",
|
|
46
|
+
trendUp: "M3 17l7-7 4 4 7-7m0 0v6m0-6h-6",
|
|
47
|
+
upload: "M12 21V9m0 0-5 5m5-5 5 5M4 5V3h16v2",
|
|
48
|
+
user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-8 9a8 8 0 0 1 16 0",
|
|
49
|
+
users: "M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-7 10a7 7 0 0 1 14 0m1-16a4 4 0 0 1 0 7m0 3a6 6 0 0 1 5 6",
|
|
50
|
+
visibility: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
|
|
51
|
+
visibilityOff: "m3 3 18 18M10.6 5.2A9 9 0 0 1 12 5c6 0 10 7 10 7a17 17 0 0 1-2.1 3M6.6 6.6C3.8 8.5 2 12 2 12s4 7 10 7a9 9 0 0 0 3.4-.7M9.9 9.9a3 3 0 0 0 4.2 4.2",
|
|
52
|
+
warning: "M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01",
|
|
53
|
+
};
|
|
54
|
+
export const Icon = forwardRef(function Icon({ name, size, tone, weight, directionality, decorative, accessibilityLabel, className, style, ...props }, ref) {
|
|
55
|
+
const descriptor = resolveIconDescriptor({
|
|
56
|
+
name,
|
|
57
|
+
...(size === undefined ? {} : { size }),
|
|
58
|
+
...(tone === undefined ? {} : { tone }),
|
|
59
|
+
...(weight === undefined ? {} : { weight }),
|
|
60
|
+
...(directionality === undefined ? {} : { directionality }),
|
|
61
|
+
...(decorative === undefined ? {} : { decorative }),
|
|
62
|
+
...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),
|
|
63
|
+
});
|
|
64
|
+
const theme = useOptionalHjmTheme();
|
|
65
|
+
const transform = getIconTransform(descriptor.directionality, theme?.environment.direction ?? "ltr");
|
|
66
|
+
const dimension = iconRecipe.sizes[descriptor.size];
|
|
67
|
+
return (_jsx("svg", { ...props, ref: ref, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: classNames("hjm-icon", className), "data-name": descriptor.name, "data-size": descriptor.size, "data-tone": descriptor.tone, "data-weight": descriptor.weight, "data-transform": transform, width: dimension, height: dimension, stroke: "currentColor", strokeWidth: iconRecipe.weights[descriptor.weight], strokeLinecap: "round", strokeLinejoin: "round", role: descriptor.decorative ? undefined : "img", "aria-hidden": descriptor.decorative || undefined, "aria-label": descriptor.decorative ? undefined : descriptor.accessibilityLabel, focusable: "false", style: style, children: _jsx("path", { d: iconPaths[descriptor.name] }) }));
|
|
68
|
+
});
|
|
69
|
+
/** Intrinsic-size image with canonical alt semantics and an accessible fallback. */
|
|
70
|
+
export const Image = forwardRef(function Image({ src, width, height, fit, decorative, accessibilityLabel, imageProps, renderImage, fallback, imageRef, onLoad, onError, onLoadStatusChange, className, style, ...props }, ref) {
|
|
71
|
+
const descriptor = resolveImageDescriptor({
|
|
72
|
+
src,
|
|
73
|
+
width,
|
|
74
|
+
height,
|
|
75
|
+
...(fit === undefined ? {} : { fit }),
|
|
76
|
+
...(decorative === undefined ? {} : { decorative }),
|
|
77
|
+
...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),
|
|
78
|
+
});
|
|
79
|
+
const [state, setState] = useState({
|
|
80
|
+
src: descriptor.src,
|
|
81
|
+
status: "loading",
|
|
82
|
+
});
|
|
83
|
+
const status = state.src === descriptor.src ? state.status : "loading";
|
|
84
|
+
const { className: imageClassName, style: imageStyle, ...restImageProps } = imageProps ?? {};
|
|
85
|
+
const handleLoad = (event) => {
|
|
86
|
+
setState({ src: descriptor.src, status: "loaded" });
|
|
87
|
+
onLoadStatusChange?.("loaded");
|
|
88
|
+
onLoad?.(event);
|
|
89
|
+
};
|
|
90
|
+
const handleError = (event) => {
|
|
91
|
+
setState({ src: descriptor.src, status: "error" });
|
|
92
|
+
onLoadStatusChange?.("error");
|
|
93
|
+
onError?.(event);
|
|
94
|
+
};
|
|
95
|
+
const adapterProps = {
|
|
96
|
+
...restImageProps,
|
|
97
|
+
src: descriptor.src,
|
|
98
|
+
alt: descriptor.decorative ? "" : descriptor.accessibilityLabel,
|
|
99
|
+
width: descriptor.width,
|
|
100
|
+
height: descriptor.height,
|
|
101
|
+
className: classNames("hjm-image__asset", imageClassName) ??
|
|
102
|
+
"hjm-image__asset",
|
|
103
|
+
style: { ...imageStyle, objectFit: descriptor.fit },
|
|
104
|
+
...(descriptor.decorative ? { "aria-hidden": true } : {}),
|
|
105
|
+
onLoad: handleLoad,
|
|
106
|
+
onError: handleError,
|
|
107
|
+
...(imageRef === undefined ? {} : { ref: imageRef }),
|
|
108
|
+
};
|
|
109
|
+
let visual;
|
|
110
|
+
if (status === "error") {
|
|
111
|
+
const fallbackLabel = resolveImageFallbackAccessibilityLabel(descriptor);
|
|
112
|
+
visual = (_jsx("span", { className: "hjm-image__fallback", role: descriptor.decorative ? undefined : "img", "aria-label": fallbackLabel, "aria-hidden": descriptor.decorative || undefined, children: _jsx("span", { className: "hjm-image__fallback-icon", "aria-hidden": "true", children: fallback ?? (_jsx(Icon, { name: imageRecipe.fallback.icon.name, tone: imageRecipe.fallback.icon.tone, decorative: true })) }) }));
|
|
113
|
+
}
|
|
114
|
+
else if (renderImage === undefined) {
|
|
115
|
+
const { ref: assetRef, ...nativeImageProps } = adapterProps;
|
|
116
|
+
visual = _jsx("img", { ...nativeImageProps, ref: assetRef });
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
visual = renderImage(adapterProps);
|
|
120
|
+
}
|
|
121
|
+
return (_jsx("span", { ...props, ref: ref, className: classNames("hjm-image", className), "data-fit": descriptor.fit, "data-status": status, style: {
|
|
122
|
+
inlineSize: descriptor.width,
|
|
123
|
+
...style,
|
|
124
|
+
aspectRatio: resolveImageAspectRatio(descriptor.width, descriptor.height),
|
|
125
|
+
}, children: visual }));
|
|
126
|
+
});
|
|
127
|
+
export const CounterBadge = forwardRef(function CounterBadge({ count, max = counterBadgeRecipe.defaults.max, tone = counterBadgeRecipe.defaults.tone, size = counterBadgeRecipe.defaults.size, variant = counterBadgeRecipe.defaults.variant, accessibilityLabel, className, ...props }, ref) {
|
|
128
|
+
const label = formatCounterBadgeCount(count, max);
|
|
129
|
+
if (accessibilityLabel !== undefined && accessibilityLabel.trim().length === 0) {
|
|
130
|
+
throw new TypeError("CounterBadge accessibilityLabel must not be empty");
|
|
131
|
+
}
|
|
132
|
+
if (label === null)
|
|
133
|
+
return null;
|
|
134
|
+
return (_jsx("span", { ...props, ref: ref, className: classNames("hjm-counter-badge", className), "data-tone": tone, "data-size": size, "data-variant": variant, "aria-hidden": accessibilityLabel === undefined || undefined, "aria-label": accessibilityLabel, children: label }));
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=supplemental-display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supplemental-display.js","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getIconTransform,\n resolveIconDescriptor,\n type IconDescriptor,\n type SemanticIconName,\n} from \"@hjmds/design-contracts/components/icon\";\nimport {\n imageRecipe,\n resolveImageAspectRatio,\n resolveImageDescriptor,\n resolveImageFallbackAccessibilityLabel,\n type ImageDescriptor,\n type ImageLoadStatus,\n} from \"@hjmds/design-contracts/components/image\";\nimport {\n counterBadgeRecipe,\n formatCounterBadgeCount,\n iconRecipe,\n type CounterBadgeSize,\n type CounterBadgeTone,\n type CounterBadgeVariant,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ImgHTMLAttributes,\n type ReactElement,\n type ReactEventHandler,\n type ReactNode,\n type Ref,\n type SVGAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\n/** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */\nconst iconPaths = {\n add: \"M12 5v14M5 12h14\",\n ai: \"M12 2l1.2 4.1L17 8l-3.8 1.9L12 14l-1.2-4.1L7 8l3.8-1.9L12 2ZM19 14l.7 2.3L22 17.5l-2.3 1.2L19 21l-.7-2.3-2.3-1.2 2.3-1.2L19 14Z\",\n alert: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n back: \"M15 18 9 12l6-6M9 12h10\",\n calendar: \"M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm2-2v4m10-4v4M3 9h18\",\n check: \"m5 12 4 4L19 6\",\n chevronDown: \"m6 9 6 6 6-6\",\n chevronEnd: \"m9 6 6 6-6 6\",\n chevronStart: \"m15 6-6 6 6 6\",\n chevronUp: \"m6 15 6-6 6 6\",\n close: \"M6 6l12 12M18 6 6 18\",\n compare: \"M8 7h11m0 0-3-3m3 3-3 3M16 17H5m0 0 3-3m-3 3 3 3\",\n copy: \"M8 8h11a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2V8Zm8 0V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3\",\n delete: \"M4 7h16M9 7V4h6v3m3 0-1 14H7L6 7m4 4v6m4-6v6\",\n download: \"M12 3v12m0 0 5-5m-5 5-5-5M4 19v2h16v-2\",\n edit: \"m4 16-1 5 5-1L19 9l-4-4L4 16Zm9-9 4 4\",\n error: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-14v5m0 3h.01\",\n favorite: \"M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1.1-1.1a5.5 5.5 0 0 0-7.8 7.8L12 21l8.8-8.6a5.5 5.5 0 0 0 0-7.8Z\",\n filter: \"M3 5h18l-7 8v6l-4 2v-8L3 5Z\",\n forward: \"m9 6 6 6-6 6m6-6H5\",\n help: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-3-13a3 3 0 1 1 4.7 2.5c-1 .7-1.7 1.2-1.7 2.5m0 3h.01\",\n home: \"m3 11 9-8 9 8v10h-6v-6H9v6H3V11Z\",\n info: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-11v6m0-10h.01\",\n lock: \"M6 10h12v11H6V10Zm3 0V7a3 3 0 0 1 6 0v3\",\n menu: \"M4 6h16M4 12h16M4 18h16\",\n more: \"M5 12h.01M12 12h.01M19 12h.01\",\n notifications: \"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9Zm-8 12h4\",\n pause: \"M8 5v14m8-14v14\",\n play: \"m8 5 11 7-11 7V5Z\",\n refresh: \"M20 7v5h-5M4 17v-5h5m10.5-3A8 8 0 0 0 6 6l-2 2m.5 7A8 8 0 0 0 18 18l2-2\",\n search: \"m21 21-4.4-4.4M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z\",\n settings: \"M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-3.5 2-1.5-2-3.5-2.4 1a8 8 0 0 0-2-1.2L14.7 4h-4l-.4 2.8A8 8 0 0 0 8 8L5.6 7l-2 3.5 2 1.5a8 8 0 0 0 0 2l-2 1.5 2 3.5L8 18a8 8 0 0 0 2.3 1.2l.4 2.8h4l.3-2.8A8 8 0 0 0 17 18l2.4 1 2-3.5-2-1.5a8 8 0 0 0 0-2Z\",\n share: \"M18 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM6 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm12 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM8.6 16.5l6.8 4M15.4 6.5l-6.8 4\",\n success: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-5-10 3 3 7-7\",\n trendDown: \"M3 7l7 7 4-4 7 7m0 0v-6m0 6h-6\",\n trendFlat: \"M4 12h16m0 0-4-4m4 4-4 4\",\n trendUp: \"M3 17l7-7 4 4 7-7m0 0v6m0-6h-6\",\n upload: \"M12 21V9m0 0-5 5m5-5 5 5M4 5V3h16v2\",\n user: \"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-8 9a8 8 0 0 1 16 0\",\n users: \"M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-7 10a7 7 0 0 1 14 0m1-16a4 4 0 0 1 0 7m0 3a6 6 0 0 1 5 6\",\n visibility: \"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z\",\n visibilityOff: \"m3 3 18 18M10.6 5.2A9 9 0 0 1 12 5c6 0 10 7 10 7a17 17 0 0 1-2.1 3M6.6 6.6C3.8 8.5 2 12 2 12s4 7 10 7a9 9 0 0 0 3.4-.7M9.9 9.9a3 3 0 0 0 4.2 4.2\",\n warning: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n} as const satisfies Record<SemanticIconName, string>;\n\nexport type IconProps = Omit<\n SVGAttributes<SVGSVGElement>,\n \"children\" | \"color\"\n> & IconDescriptor;\n\nexport const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(\n {\n name,\n size,\n tone,\n weight,\n directionality,\n decorative,\n accessibilityLabel,\n className,\n style,\n ...props\n },\n ref,\n) {\n const descriptor = resolveIconDescriptor({\n name,\n ...(size === undefined ? {} : { size }),\n ...(tone === undefined ? {} : { tone }),\n ...(weight === undefined ? {} : { weight }),\n ...(directionality === undefined ? {} : { directionality }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as IconDescriptor);\n const theme = useOptionalHjmTheme();\n const transform = getIconTransform(\n descriptor.directionality,\n theme?.environment.direction ?? \"ltr\",\n );\n const dimension = iconRecipe.sizes[descriptor.size];\n return (\n <svg\n {...props}\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={classNames(\"hjm-icon\", className)}\n data-name={descriptor.name}\n data-size={descriptor.size}\n data-tone={descriptor.tone}\n data-weight={descriptor.weight}\n data-transform={transform}\n width={dimension}\n height={dimension}\n stroke=\"currentColor\"\n strokeWidth={iconRecipe.weights[descriptor.weight]}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-hidden={descriptor.decorative || undefined}\n aria-label={descriptor.decorative ? undefined : descriptor.accessibilityLabel}\n focusable=\"false\"\n style={style}\n >\n <path d={iconPaths[descriptor.name]} />\n </svg>\n );\n});\n\ntype ImageElementProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n | \"alt\"\n | \"aria-hidden\"\n | \"aria-label\"\n | \"children\"\n | \"className\"\n | \"height\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n | \"src\"\n | \"style\"\n | \"width\"\n>;\n\n/** Canonical props handed to a framework adapter such as `next/image`. */\nexport type ImageAdapterProps = ImageElementProps &\n Readonly<{\n src: string;\n alt: string;\n width: number;\n height: number;\n className?: string;\n style: CSSProperties;\n \"aria-hidden\"?: true;\n onLoad: ReactEventHandler<HTMLImageElement>;\n onError: ReactEventHandler<HTMLImageElement>;\n ref?: Ref<HTMLImageElement>;\n }>;\n\ntype ImageRootProps = Omit<\n HTMLAttributes<HTMLSpanElement>,\n | \"aria-hidden\"\n | \"aria-label\"\n | \"aria-labelledby\"\n | \"children\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n>;\n\nexport type ImageProps = ImageRootProps &\n ImageDescriptor &\n Readonly<{\n /** Additional native `<img>` props shared with the framework adapter. */\n imageProps?: ImageElementProps &\n Readonly<{ className?: string; style?: CSSProperties }>;\n /**\n * Receives the complete accessible image contract. The adapter must pass\n * these props to its underlying image element so HJM can observe failure.\n */\n renderImage?: (props: ImageAdapterProps) => ReactElement;\n /** Visual content only; HJM keeps the fallback's accessible name. */\n fallback?: ReactNode;\n imageRef?: Ref<HTMLImageElement>;\n onLoad?: ReactEventHandler<HTMLImageElement>;\n onError?: ReactEventHandler<HTMLImageElement>;\n onLoadStatusChange?: (status: Extract<ImageLoadStatus, \"loaded\" | \"error\">) => void;\n }>;\n\ntype ImageState = Readonly<{\n src: string;\n status: Extract<ImageLoadStatus, \"loading\" | \"loaded\" | \"error\">;\n}>;\n\n/** Intrinsic-size image with canonical alt semantics and an accessible fallback. */\nexport const Image = forwardRef<HTMLSpanElement, ImageProps>(function Image(\n {\n src,\n width,\n height,\n fit,\n decorative,\n accessibilityLabel,\n imageProps,\n renderImage,\n fallback,\n imageRef,\n onLoad,\n onError,\n onLoadStatusChange,\n className,\n style,\n ...props\n },\n ref,\n) {\n const descriptor = resolveImageDescriptor({\n src,\n width,\n height,\n ...(fit === undefined ? {} : { fit }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as ImageDescriptor);\n const [state, setState] = useState<ImageState>({\n src: descriptor.src,\n status: \"loading\",\n });\n const status = state.src === descriptor.src ? state.status : \"loading\";\n const {\n className: imageClassName,\n style: imageStyle,\n ...restImageProps\n } = imageProps ?? {};\n\n const handleLoad: ReactEventHandler<HTMLImageElement> = (event) => {\n setState({ src: descriptor.src, status: \"loaded\" });\n onLoadStatusChange?.(\"loaded\");\n onLoad?.(event);\n };\n const handleError: ReactEventHandler<HTMLImageElement> = (event) => {\n setState({ src: descriptor.src, status: \"error\" });\n onLoadStatusChange?.(\"error\");\n onError?.(event);\n };\n const adapterProps: ImageAdapterProps = {\n ...restImageProps,\n src: descriptor.src,\n alt: descriptor.decorative ? \"\" : descriptor.accessibilityLabel,\n width: descriptor.width,\n height: descriptor.height,\n className: classNames(\"hjm-image__asset\", imageClassName) ??\n \"hjm-image__asset\",\n style: { ...imageStyle, objectFit: descriptor.fit },\n ...(descriptor.decorative ? { \"aria-hidden\": true } : {}),\n onLoad: handleLoad,\n onError: handleError,\n ...(imageRef === undefined ? {} : { ref: imageRef }),\n };\n\n let visual: ReactNode;\n if (status === \"error\") {\n const fallbackLabel = resolveImageFallbackAccessibilityLabel(descriptor);\n visual = (\n <span\n className=\"hjm-image__fallback\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-label={fallbackLabel}\n aria-hidden={descriptor.decorative || undefined}\n >\n <span className=\"hjm-image__fallback-icon\" aria-hidden=\"true\">\n {fallback ?? (\n <Icon\n name={imageRecipe.fallback.icon.name}\n tone={imageRecipe.fallback.icon.tone}\n decorative\n />\n )}\n </span>\n </span>\n );\n } else if (renderImage === undefined) {\n const { ref: assetRef, ...nativeImageProps } = adapterProps;\n visual = <img {...nativeImageProps} ref={assetRef} />;\n } else {\n visual = renderImage(adapterProps);\n }\n\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-image\", className)}\n data-fit={descriptor.fit}\n data-status={status}\n style={{\n inlineSize: descriptor.width,\n ...style,\n aspectRatio: resolveImageAspectRatio(\n descriptor.width,\n descriptor.height,\n ),\n }}\n >\n {visual}\n </span>\n );\n});\n\nexport type CounterBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n count: number;\n max?: number;\n tone?: CounterBadgeTone;\n size?: CounterBadgeSize;\n variant?: CounterBadgeVariant;\n accessibilityLabel?: string;\n }>;\n\nexport const CounterBadge = forwardRef<HTMLSpanElement, CounterBadgeProps>(\n function CounterBadge(\n {\n count,\n max = counterBadgeRecipe.defaults.max,\n tone = counterBadgeRecipe.defaults.tone,\n size = counterBadgeRecipe.defaults.size,\n variant = counterBadgeRecipe.defaults.variant,\n accessibilityLabel,\n className,\n ...props\n },\n ref,\n ) {\n const label = formatCounterBadgeCount(count, max);\n if (accessibilityLabel !== undefined && accessibilityLabel.trim().length === 0) {\n throw new TypeError(\"CounterBadge accessibilityLabel must not be empty\");\n }\n if (label === null) return null;\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-counter-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n aria-hidden={accessibilityLabel === undefined || undefined}\n aria-label={accessibilityLabel}\n >\n {label}\n </span>\n );\n },\n);\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type LoadMoreDescriptor, type LoadMoreMode, type LoadMoreRequestHandler, type LoadMoreRequestOutcome, type LoadMoreRequestReason } from "@hjmds/design-contracts/components/load-more";
|
|
2
|
+
import { type LoadMoreDensity } from "@hjmds/design-contracts/recipes";
|
|
3
|
+
import { type HTMLAttributes } from "react";
|
|
4
|
+
export type LoadMoreProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
|
|
5
|
+
descriptor: LoadMoreDescriptor;
|
|
6
|
+
mode?: LoadMoreMode;
|
|
7
|
+
density?: LoadMoreDensity;
|
|
8
|
+
onLoadMore: LoadMoreRequestHandler;
|
|
9
|
+
onRequestOutcome?: (outcome: LoadMoreRequestOutcome, reason: LoadMoreRequestReason) => void;
|
|
10
|
+
onRequestError?: (error: unknown, reason: LoadMoreRequestReason) => void;
|
|
11
|
+
intersectionRoot?: Element | Document | null;
|
|
12
|
+
rootMargin?: string;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* A collection footer that keeps product data controlled while the shared
|
|
16
|
+
* controller prevents overlapping cursor requests.
|
|
17
|
+
*/
|
|
18
|
+
export declare const LoadMore: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
|
|
19
|
+
descriptor: LoadMoreDescriptor;
|
|
20
|
+
mode?: LoadMoreMode;
|
|
21
|
+
density?: LoadMoreDensity;
|
|
22
|
+
onLoadMore: LoadMoreRequestHandler;
|
|
23
|
+
onRequestOutcome?: (outcome: LoadMoreRequestOutcome, reason: LoadMoreRequestReason) => void;
|
|
24
|
+
onRequestError?: (error: unknown, reason: LoadMoreRequestReason) => void;
|
|
25
|
+
intersectionRoot?: Element | Document | null;
|
|
26
|
+
rootMargin?: string;
|
|
27
|
+
}> & import("react").RefAttributes<HTMLDivElement>>;
|
|
28
|
+
//# sourceMappingURL=supplemental-navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supplemental-navigation.d.ts","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AA+Bf,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAC1E,QAAQ,CAAC;IACP,UAAU,EAAE,kBAAkB,CAAC;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,sBAAsB,CAAC;IACnC,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACzE,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,QAAQ;gBAjBL,kBAAkB;WACvB,YAAY;cACT,eAAe;gBACb,sBAAsB;uBACf,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI;qBACQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI;uBACrD,OAAO,GAAG,QAAQ,GAAG,IAAI;iBAC/B,MAAM;mDA+ItB,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createLoadMoreController, validateLoadMoreDescriptor, } from "@hjmds/design-contracts/components/load-more";
|
|
3
|
+
import { loadMoreRecipe, } from "@hjmds/design-contracts/recipes";
|
|
4
|
+
import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
5
|
+
import { classNames } from "./internal.js";
|
|
6
|
+
function createLoadMoreControllerFacade() {
|
|
7
|
+
const detachedSnapshot = {
|
|
8
|
+
mode: "automatic",
|
|
9
|
+
inFlightRequestKey: null,
|
|
10
|
+
disposed: true,
|
|
11
|
+
};
|
|
12
|
+
let active = null;
|
|
13
|
+
return {
|
|
14
|
+
facade: {
|
|
15
|
+
getSnapshot: () => active?.getSnapshot() ?? detachedSnapshot,
|
|
16
|
+
request: (state, reason) => {
|
|
17
|
+
if (!active)
|
|
18
|
+
throw new Error("Cannot use a detached LoadMore controller");
|
|
19
|
+
return active.request(state, reason);
|
|
20
|
+
},
|
|
21
|
+
dispose: () => active?.dispose() ?? false,
|
|
22
|
+
},
|
|
23
|
+
attach(controller) {
|
|
24
|
+
active = controller;
|
|
25
|
+
return () => {
|
|
26
|
+
if (active === controller)
|
|
27
|
+
active = null;
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A collection footer that keeps product data controlled while the shared
|
|
34
|
+
* controller prevents overlapping cursor requests.
|
|
35
|
+
*/
|
|
36
|
+
export const LoadMore = forwardRef(function LoadMore({ descriptor, mode = loadMoreRecipe.defaults.mode, density = loadMoreRecipe.defaults.density, onLoadMore, onRequestOutcome, onRequestError, intersectionRoot = null, rootMargin = "200px 0px", className, ...props }, ref) {
|
|
37
|
+
validateLoadMoreDescriptor(descriptor);
|
|
38
|
+
const onLoadMoreRef = useRef(onLoadMore);
|
|
39
|
+
onLoadMoreRef.current = onLoadMore;
|
|
40
|
+
const [controllerFacade] = useState(createLoadMoreControllerFacade);
|
|
41
|
+
const controller = controllerFacade.facade;
|
|
42
|
+
const sentinelRef = useRef(null);
|
|
43
|
+
const currentRequestIdentityRef = useRef(null);
|
|
44
|
+
const completedRequestIdentityRef = useRef(null);
|
|
45
|
+
const currentRequestIdentity = descriptor.state.status === "ready" || descriptor.state.status === "error"
|
|
46
|
+
? `${descriptor.state.status}:${descriptor.state.requestKey}`
|
|
47
|
+
: null;
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
currentRequestIdentityRef.current = currentRequestIdentity;
|
|
50
|
+
}, [currentRequestIdentity]);
|
|
51
|
+
const request = useCallback(async (state, reason) => {
|
|
52
|
+
if (state.status === "loading" || state.status === "complete")
|
|
53
|
+
return;
|
|
54
|
+
const requestIdentity = `${state.status}:${state.requestKey}`;
|
|
55
|
+
// IntersectionObserver may deliver an already queued callback after
|
|
56
|
+
// disconnect. Only events for the currently committed descriptor may
|
|
57
|
+
// enter the shared request controller.
|
|
58
|
+
if (currentRequestIdentityRef.current !== requestIdentity)
|
|
59
|
+
return;
|
|
60
|
+
// Once a request settles successfully, retire that exact state/key
|
|
61
|
+
// until the product commits a new cursor or a retryable error state.
|
|
62
|
+
if (completedRequestIdentityRef.current === requestIdentity)
|
|
63
|
+
return;
|
|
64
|
+
try {
|
|
65
|
+
const outcome = await controller.request(state, reason);
|
|
66
|
+
if (outcome === "started") {
|
|
67
|
+
completedRequestIdentityRef.current = requestIdentity;
|
|
68
|
+
}
|
|
69
|
+
onRequestOutcome?.(outcome, reason);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
onRequestError?.(error, reason);
|
|
73
|
+
}
|
|
74
|
+
}, [controller, onRequestError, onRequestOutcome]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const attached = createLoadMoreController({
|
|
77
|
+
mode,
|
|
78
|
+
onLoadMore: (nextRequest) => onLoadMoreRef.current(nextRequest),
|
|
79
|
+
});
|
|
80
|
+
const detach = controllerFacade.attach(attached);
|
|
81
|
+
return () => {
|
|
82
|
+
detach();
|
|
83
|
+
attached.dispose();
|
|
84
|
+
};
|
|
85
|
+
}, [controllerFacade, mode]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (mode !== "automatic" ||
|
|
88
|
+
descriptor.state.status !== "ready" ||
|
|
89
|
+
typeof IntersectionObserver === "undefined") {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const sentinel = sentinelRef.current;
|
|
93
|
+
if (!sentinel)
|
|
94
|
+
return;
|
|
95
|
+
const observer = new IntersectionObserver((entries) => {
|
|
96
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
97
|
+
void request(descriptor.state, "viewport");
|
|
98
|
+
}
|
|
99
|
+
}, { root: intersectionRoot, rootMargin });
|
|
100
|
+
observer.observe(sentinel);
|
|
101
|
+
return () => observer.disconnect();
|
|
102
|
+
}, [descriptor.state, intersectionRoot, mode, request, rootMargin]);
|
|
103
|
+
const { state, labels } = descriptor;
|
|
104
|
+
return (_jsxs("div", { ...props, ref: ref, className: classNames("hjm-load-more", className), "data-mode": mode, "data-density": density, "data-state": state.status, "aria-busy": state.status === "loading" || undefined, children: [_jsx("span", { ref: sentinelRef, className: "hjm-load-more__sentinel", "aria-hidden": "true" }), state.status === "ready" ? (_jsx("button", { type: "button", className: "hjm-load-more__trigger", onClick: () => void request(state, "manual"), children: labels.loadMore })) : state.status === "loading" ? (_jsxs("div", { className: "hjm-load-more__status", role: "status", children: [_jsx("span", { className: "hjm-load-more__spinner", "aria-hidden": "true" }), labels.loading] })) : state.status === "error" ? (_jsxs("div", { className: "hjm-load-more__error", children: [_jsx("span", { role: "alert", children: state.message }), _jsx("button", { type: "button", className: "hjm-load-more__trigger", onClick: () => void request(state, "retry"), children: labels.retry })] })) : (_jsx("div", { className: "hjm-load-more__end", children: labels.complete }))] }));
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=supplemental-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supplemental-navigation.js","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createLoadMoreController,\n validateLoadMoreDescriptor,\n type LoadMoreController,\n type LoadMoreControllerSnapshot,\n type LoadMoreDescriptor,\n type LoadMoreMode,\n type LoadMoreRequestHandler,\n type LoadMoreRequestOutcome,\n type LoadMoreRequestReason,\n} from \"@hjmds/design-contracts/components/load-more\";\nimport {\n loadMoreRecipe,\n type LoadMoreDensity,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type HTMLAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\n\nfunction createLoadMoreControllerFacade(): Readonly<{\n facade: LoadMoreController;\n attach(controller: LoadMoreController): () => void;\n}> {\n const detachedSnapshot: LoadMoreControllerSnapshot = {\n mode: \"automatic\",\n inFlightRequestKey: null,\n disposed: true,\n };\n let active: LoadMoreController | null = null;\n return {\n facade: {\n getSnapshot: () => active?.getSnapshot() ?? detachedSnapshot,\n request: (state, reason) => {\n if (!active) throw new Error(\"Cannot use a detached LoadMore controller\");\n return active.request(state, reason);\n },\n dispose: () => active?.dispose() ?? false,\n },\n attach(controller) {\n active = controller;\n return () => {\n if (active === controller) active = null;\n };\n },\n };\n}\n\nexport type LoadMoreProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n descriptor: LoadMoreDescriptor;\n mode?: LoadMoreMode;\n density?: LoadMoreDensity;\n onLoadMore: LoadMoreRequestHandler;\n onRequestOutcome?: (\n outcome: LoadMoreRequestOutcome,\n reason: LoadMoreRequestReason,\n ) => void;\n onRequestError?: (error: unknown, reason: LoadMoreRequestReason) => void;\n intersectionRoot?: Element | Document | null;\n rootMargin?: string;\n }>;\n\n/**\n * A collection footer that keeps product data controlled while the shared\n * controller prevents overlapping cursor requests.\n */\nexport const LoadMore = forwardRef<HTMLDivElement, LoadMoreProps>(\n function LoadMore(\n {\n descriptor,\n mode = loadMoreRecipe.defaults.mode,\n density = loadMoreRecipe.defaults.density,\n onLoadMore,\n onRequestOutcome,\n onRequestError,\n intersectionRoot = null,\n rootMargin = \"200px 0px\",\n className,\n ...props\n },\n ref,\n ) {\n validateLoadMoreDescriptor(descriptor);\n const onLoadMoreRef = useRef(onLoadMore);\n onLoadMoreRef.current = onLoadMore;\n const [controllerFacade] = useState(createLoadMoreControllerFacade);\n const controller = controllerFacade.facade;\n const sentinelRef = useRef<HTMLSpanElement>(null);\n const currentRequestIdentityRef = useRef<string | null>(null);\n const completedRequestIdentityRef = useRef<string | null>(null);\n const currentRequestIdentity =\n descriptor.state.status === \"ready\" || descriptor.state.status === \"error\"\n ? `${descriptor.state.status}:${descriptor.state.requestKey}`\n : null;\n\n useLayoutEffect(() => {\n currentRequestIdentityRef.current = currentRequestIdentity;\n }, [currentRequestIdentity]);\n\n const request = useCallback(\n async (\n state: LoadMoreDescriptor[\"state\"],\n reason: LoadMoreRequestReason,\n ) => {\n if (state.status === \"loading\" || state.status === \"complete\") return;\n const requestIdentity = `${state.status}:${state.requestKey}`;\n // IntersectionObserver may deliver an already queued callback after\n // disconnect. Only events for the currently committed descriptor may\n // enter the shared request controller.\n if (currentRequestIdentityRef.current !== requestIdentity) return;\n // Once a request settles successfully, retire that exact state/key\n // until the product commits a new cursor or a retryable error state.\n if (completedRequestIdentityRef.current === requestIdentity) return;\n try {\n const outcome = await controller.request(state, reason);\n if (outcome === \"started\") {\n completedRequestIdentityRef.current = requestIdentity;\n }\n onRequestOutcome?.(outcome, reason);\n } catch (error) {\n onRequestError?.(error, reason);\n }\n },\n [controller, onRequestError, onRequestOutcome],\n );\n\n useEffect(() => {\n const attached = createLoadMoreController({\n mode,\n onLoadMore: (nextRequest) => onLoadMoreRef.current(nextRequest),\n });\n const detach = controllerFacade.attach(attached);\n return () => {\n detach();\n attached.dispose();\n };\n }, [controllerFacade, mode]);\n\n useEffect(() => {\n if (\n mode !== \"automatic\" ||\n descriptor.state.status !== \"ready\" ||\n typeof IntersectionObserver === \"undefined\"\n ) {\n return;\n }\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n void request(descriptor.state, \"viewport\");\n }\n },\n { root: intersectionRoot, rootMargin },\n );\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [descriptor.state, intersectionRoot, mode, request, rootMargin]);\n\n const { state, labels } = descriptor;\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-load-more\", className)}\n data-mode={mode}\n data-density={density}\n data-state={state.status}\n aria-busy={state.status === \"loading\" || undefined}\n >\n <span ref={sentinelRef} className=\"hjm-load-more__sentinel\" aria-hidden=\"true\" />\n {state.status === \"ready\" ? (\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"manual\")}\n >\n {labels.loadMore}\n </button>\n ) : state.status === \"loading\" ? (\n <div className=\"hjm-load-more__status\" role=\"status\">\n <span className=\"hjm-load-more__spinner\" aria-hidden=\"true\" />\n {labels.loading}\n </div>\n ) : state.status === \"error\" ? (\n <div className=\"hjm-load-more__error\">\n <span role=\"alert\">{state.message}</span>\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"retry\")}\n >\n {labels.retry}\n </button>\n </div>\n ) : (\n <div className=\"hjm-load-more__end\">{labels.complete}</div>\n )}\n </div>\n );\n },\n);\n"]}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DesignSystemProviderValue } from "@hjmds/design-contracts/components/design-system-provider";
|
|
2
|
+
import type { CSSProperties } from "react";
|
|
3
|
+
export type HjmThemeStyle = CSSProperties & Record<`--hjm-${string}`, string | number>;
|
|
4
|
+
export declare function createHjmThemeStyle(value: DesignSystemProviderValue): HjmThemeStyle;
|
|
5
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2DAA2D,CAAC;AAC3G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAU7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CAiDf"}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { control, fontFamily, fontWeight, motion, radius, spacing, typography, } from "@hjmds/design-contracts/foundations";
|
|
2
|
+
function kebab(value) {
|
|
3
|
+
return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
4
|
+
}
|
|
5
|
+
function rem(value) {
|
|
6
|
+
return `${Number((value / 16).toFixed(5))}rem`;
|
|
7
|
+
}
|
|
8
|
+
export function createHjmThemeStyle(value) {
|
|
9
|
+
const { environment, palette } = value;
|
|
10
|
+
const style = {
|
|
11
|
+
"--hjm-text-scale": environment.textScale,
|
|
12
|
+
"--hjm-motion-scale": environment.reducedMotion ? 0 : 1,
|
|
13
|
+
colorScheme: environment.theme,
|
|
14
|
+
backgroundColor: palette.theme.bg,
|
|
15
|
+
color: palette.theme.text,
|
|
16
|
+
};
|
|
17
|
+
for (const [name, color] of Object.entries(palette.theme)) {
|
|
18
|
+
style[`--hjm-color-${kebab(name)}`] = color;
|
|
19
|
+
}
|
|
20
|
+
for (const [name, color] of Object.entries(palette.statusAccents)) {
|
|
21
|
+
style[`--hjm-accent-${kebab(name)}`] = color;
|
|
22
|
+
}
|
|
23
|
+
for (const [name, color] of Object.entries(palette.statusAccentFills)) {
|
|
24
|
+
style[`--hjm-accent-fill-${kebab(name)}`] = color;
|
|
25
|
+
}
|
|
26
|
+
for (const [name, value] of Object.entries(spacing)) {
|
|
27
|
+
style[`--hjm-space-${kebab(name)}`] = `${value}px`;
|
|
28
|
+
}
|
|
29
|
+
for (const [name, value] of Object.entries(radius)) {
|
|
30
|
+
style[`--hjm-radius-${kebab(name)}`] = `${value}px`;
|
|
31
|
+
}
|
|
32
|
+
for (const [name, value] of Object.entries(typography)) {
|
|
33
|
+
style[`--hjm-type-${kebab(name)}-size`] =
|
|
34
|
+
`calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;
|
|
35
|
+
style[`--hjm-type-${kebab(name)}-line-height`] =
|
|
36
|
+
`calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;
|
|
37
|
+
style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;
|
|
38
|
+
}
|
|
39
|
+
for (const [name, value] of Object.entries(fontWeight)) {
|
|
40
|
+
style[`--hjm-font-weight-${kebab(name)}`] = value;
|
|
41
|
+
}
|
|
42
|
+
for (const [name, value] of Object.entries(motion)) {
|
|
43
|
+
style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion
|
|
44
|
+
? "0ms"
|
|
45
|
+
: `${value}ms`;
|
|
46
|
+
}
|
|
47
|
+
style["--hjm-font-family-ui"] = fontFamily.ui.join(", ");
|
|
48
|
+
style["--hjm-control-min-touch-target"] = `${control.minTouchTarget}px`;
|
|
49
|
+
style["--hjm-control-field-height"] = `${control.fieldHeight}px`;
|
|
50
|
+
for (const [name, value] of Object.entries(control.buttonHeight)) {
|
|
51
|
+
style[`--hjm-control-button-${kebab(name)}`] = `${value}px`;
|
|
52
|
+
}
|
|
53
|
+
return style;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n control,\n fontFamily,\n fontWeight,\n motion,\n radius,\n spacing,\n typography,\n} from \"@hjmds/design-contracts/foundations\";\nimport type { DesignSystemProviderValue } from \"@hjmds/design-contracts/components/design-system-provider\";\nimport type { CSSProperties } from \"react\";\n\nexport type HjmThemeStyle = CSSProperties &\n Record<`--hjm-${string}`, string | number>;\n\nfunction kebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\nfunction rem(value: number): string {\n return `${Number((value / 16).toFixed(5))}rem`;\n}\n\nexport function createHjmThemeStyle(\n value: DesignSystemProviderValue,\n): HjmThemeStyle {\n const { environment, palette } = value;\n const style: HjmThemeStyle = {\n \"--hjm-text-scale\": environment.textScale,\n \"--hjm-motion-scale\": environment.reducedMotion ? 0 : 1,\n colorScheme: environment.theme,\n backgroundColor: palette.theme.bg,\n color: palette.theme.text,\n };\n\n for (const [name, color] of Object.entries(palette.theme)) {\n style[`--hjm-color-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccents)) {\n style[`--hjm-accent-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccentFills)) {\n style[`--hjm-accent-fill-${kebab(name)}`] = color;\n }\n for (const [name, value] of Object.entries(spacing)) {\n style[`--hjm-space-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(radius)) {\n style[`--hjm-radius-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(typography)) {\n style[`--hjm-type-${kebab(name)}-size`] =\n `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-line-height`] =\n `calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;\n }\n for (const [name, value] of Object.entries(fontWeight)) {\n style[`--hjm-font-weight-${kebab(name)}`] = value;\n }\n for (const [name, value] of Object.entries(motion)) {\n style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion\n ? \"0ms\"\n : `${value}ms`;\n }\n\n style[\"--hjm-font-family-ui\"] = fontFamily.ui.join(\", \");\n style[\"--hjm-control-min-touch-target\"] = `${control.minTouchTarget}px`;\n style[\"--hjm-control-field-height\"] = `${control.fieldHeight}px`;\n for (const [name, value] of Object.entries(control.buttonHeight)) {\n style[`--hjm-control-button-${kebab(name)}`] = `${value}px`;\n }\n\n return style;\n}\n"]}
|
package/dist/toast.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ToastDescriptor, type ToastDismissReason, type ToastDuplicatePolicy, type ToastId, type ToastOverflowPolicy, type ToastPublishOptions, type ToastPublishResult, type ToastStore, type ToastTimerUpdatePolicy } from "@hjmds/design-contracts/components/toast";
|
|
2
|
+
import { type ToastPlacement } from "@hjmds/design-contracts/recipes";
|
|
3
|
+
import { type HTMLAttributes, type ReactNode } from "react";
|
|
4
|
+
export type ToastProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> & Readonly<{
|
|
5
|
+
descriptor: ToastDescriptor;
|
|
6
|
+
onDismissRequest: (reason: ToastDismissReason) => void;
|
|
7
|
+
}>;
|
|
8
|
+
/** Controlled single-toast renderer; ToastProvider supplies the full FIFO lifecycle. */
|
|
9
|
+
export declare const Toast: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> & Readonly<{
|
|
10
|
+
descriptor: ToastDescriptor;
|
|
11
|
+
onDismissRequest: (reason: ToastDismissReason) => void;
|
|
12
|
+
}> & import("react").RefAttributes<HTMLDivElement>>;
|
|
13
|
+
export type ToastApi = Readonly<{
|
|
14
|
+
publish(descriptor: ToastDescriptor, options?: ToastPublishOptions): ToastPublishResult;
|
|
15
|
+
dismiss(id: ToastId, reason: ToastDismissReason): boolean;
|
|
16
|
+
close(id: ToastId): boolean;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function useToast(): ToastApi;
|
|
19
|
+
export type ToastProviderProps = Readonly<{
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
label: string;
|
|
22
|
+
placement?: ToastPlacement;
|
|
23
|
+
store?: ToastStore;
|
|
24
|
+
initialToasts?: readonly ToastDescriptor[];
|
|
25
|
+
maxVisible?: number;
|
|
26
|
+
maxQueued?: number;
|
|
27
|
+
duplicatePolicy?: ToastDuplicatePolicy;
|
|
28
|
+
timerUpdatePolicy?: ToastTimerUpdatePolicy;
|
|
29
|
+
overflowPolicy?: ToastOverflowPolicy;
|
|
30
|
+
portalContainer?: HTMLElement;
|
|
31
|
+
/** Captured per publication so already-visible localized copy keeps its language. */
|
|
32
|
+
locale?: string;
|
|
33
|
+
/** Extra space above a fixed product dock, in pixels or any CSS length. */
|
|
34
|
+
bottomOffset?: number | string;
|
|
35
|
+
/** Optional discoverable keyboard shortcut, for example `F8`. */
|
|
36
|
+
hotkey?: string;
|
|
37
|
+
/** Screen-reader help associated with the viewport when `hotkey` is supplied. */
|
|
38
|
+
hotkeyHelp?: string;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function ToastProvider({ children, label, placement, store, initialToasts, maxVisible, maxQueued, duplicatePolicy, timerUpdatePolicy, overflowPolicy, portalContainer, locale, bottomOffset, hotkey, hotkeyHelp, }: ToastProviderProps): import("react").JSX.Element;
|
|
41
|
+
//# sourceMappingURL=toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../src/toast.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,OAAO,EACZ,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC5B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAYL,KAAK,cAAc,EAEnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA6Gf,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GACjF,QAAQ,CAAC;IACP,UAAU,EAAE,eAAe,CAAC;IAC5B,gBAAgB,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxD,CAAC,CAAC;AAEL,wFAAwF;AACxF,eAAO,MAAM,KAAK;gBALF,eAAe;sBACT,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI;mDA6BxD,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,kBAAkB,CAAC;IACxF,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAC1D,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B,CAAC,CAAC;AAIH,wBAAgB,QAAQ,IAAI,QAAQ,CAInC;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,aAAa,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAC3C,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAqDH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,EACL,SAA0C,EAC1C,KAAK,EACL,aAAkB,EAClB,UAAU,EACV,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,MAAM,EACN,YAAgB,EAChB,MAAM,EACN,UAAU,GACX,EAAE,kBAAkB,+BA4NpB"}
|