braid-design-system 34.9.0 → 34.10.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/CHANGELOG.md +62 -0
- package/dist/color-mode/query-param.d.cts +1 -1
- package/dist/color-mode/query-param.d.mts +1 -1
- package/dist/lib/components/Accordion/Accordion.cjs +61 -13
- package/dist/lib/components/Accordion/Accordion.d.cts +56 -2
- package/dist/lib/components/Accordion/Accordion.d.mts +56 -2
- package/dist/lib/components/Accordion/Accordion.mjs +62 -14
- package/dist/lib/components/Accordion/AccordionContext.d.cts +7 -0
- package/dist/lib/components/Accordion/AccordionContext.d.mts +7 -0
- package/dist/lib/components/Accordion/AccordionItem.cjs +86 -12
- package/dist/lib/components/Accordion/AccordionItem.css.cjs +15 -0
- package/dist/lib/components/Accordion/AccordionItem.css.mjs +13 -1
- package/dist/lib/components/Accordion/AccordionItem.d.cts +5 -0
- package/dist/lib/components/Accordion/AccordionItem.d.mts +5 -0
- package/dist/lib/components/Accordion/AccordionItem.mjs +88 -14
- package/dist/lib/components/Accordion/AccordionItem.playroom.cjs +6 -2
- package/dist/lib/components/Accordion/AccordionItem.playroom.d.cts +1 -1
- package/dist/lib/components/Accordion/AccordionItem.playroom.d.mts +1 -1
- package/dist/lib/components/Accordion/AccordionItem.playroom.mjs +6 -2
- package/dist/lib/components/Avatar/Avatar.cjs +1 -1
- package/dist/lib/components/Avatar/Avatar.css.cjs +2 -1
- package/dist/lib/components/Avatar/Avatar.css.mjs +2 -1
- package/dist/lib/components/Avatar/Avatar.mjs +1 -1
- package/dist/lib/components/BraidPortal/BraidPortal.cjs +0 -1
- package/dist/lib/components/BraidPortal/BraidPortal.mjs +0 -1
- package/dist/lib/components/BraidProvider/BraidProvider.cjs +0 -1
- package/dist/lib/components/BraidProvider/BraidProvider.mjs +0 -1
- package/dist/lib/components/BraidProvider/VanillaThemeContainer.cjs +2 -2
- package/dist/lib/components/BraidProvider/VanillaThemeContainer.mjs +2 -2
- package/dist/lib/components/Drawer/Drawer.cjs +5 -0
- package/dist/lib/components/Drawer/Drawer.mjs +5 -0
- package/dist/lib/components/private/Modal/Modal.cjs +0 -10
- package/dist/lib/components/private/Modal/Modal.mjs +0 -10
- package/dist/lib/components/private/Modal/ModalContent.cjs +9 -4
- package/dist/lib/components/private/Modal/ModalContent.mjs +9 -4
- package/dist/lib/components/useToast/Toast.cjs +8 -3
- package/dist/lib/components/useToast/Toast.mjs +8 -3
- package/dist/lib/components/useToast/ToastTypes.d.cts +3 -1
- package/dist/lib/components/useToast/ToastTypes.d.mts +3 -1
- package/dist/lib/components/useToast/useFlipList.cjs +3 -3
- package/dist/lib/components/useToast/useFlipList.mjs +3 -3
- package/dist/lib/components/useToast/useTimeout.cjs +1 -1
- package/dist/lib/components/useToast/useTimeout.mjs +1 -1
- package/dist/lib/playroom/snippets/Accordion.cjs +8 -12
- package/dist/lib/playroom/snippets/Accordion.mjs +8 -12
- package/dist/lib/playroom/snippets/BulkActions.cjs +8 -0
- package/dist/lib/playroom/snippets/BulkActions.mjs +8 -0
- package/dist/lib/playroom/snippets/DividedLists.cjs +8 -0
- package/dist/lib/playroom/snippets/DividedLists.mjs +8 -0
- package/dist/lib/playroom/snippets/EmptyState.cjs +12 -0
- package/dist/lib/playroom/snippets/EmptyState.mjs +12 -0
- package/dist/lib/playroom/snippets/ErrorState.cjs +12 -0
- package/dist/lib/playroom/snippets/ErrorState.mjs +12 -0
- package/dist/lib/playroom/snippets/Forms.cjs +12 -0
- package/dist/lib/playroom/snippets/Forms.mjs +12 -0
- package/dist/lib/playroom/snippets/Nudge.cjs +20 -0
- package/dist/lib/playroom/snippets/Nudge.mjs +20 -0
- package/dist/lib/playroom/snippets/ServiceOutageBanner.cjs +12 -0
- package/dist/lib/playroom/snippets/ServiceOutageBanner.mjs +12 -0
- package/dist/lib/playroom/snippets/SkeletonLoader.cjs +8 -0
- package/dist/lib/playroom/snippets/SkeletonLoader.mjs +8 -0
- package/dist/lib/playroom/snippets/SocialShare.cjs +8 -0
- package/dist/lib/playroom/snippets/SocialShare.mjs +8 -0
- package/dist/lib/playroom/snippets.cjs +20 -1
- package/dist/lib/playroom/snippets.mjs +116 -97
- package/dist/playroom/FrameComponent.mjs +1 -2
- package/dist/playroom/components.d.cts +5 -0
- package/dist/playroom/components.d.mts +5 -0
- package/dist/playroom/scope.mjs +1 -2
- package/dist/playroom/snippets.mjs +1 -2
- package/dist/test.mjs +1 -2
- package/dist/themes/docs.mjs +1 -2
- package/dist/themes/seekBusiness.mjs +1 -2
- package/dist/themes/seekJobs.mjs +1 -2
- package/dist/themes/wireframe.mjs +1 -2
- package/package.json +4 -3
|
@@ -14,6 +14,11 @@ interface AccordionItemBaseProps {
|
|
|
14
14
|
icon?: TextProps['icon'];
|
|
15
15
|
data?: DataAttributeMap;
|
|
16
16
|
badge?: ReactElement<BadgeProps> | null;
|
|
17
|
+
/**
|
|
18
|
+
* Key used when Accordion owns the open items.
|
|
19
|
+
* Required when `multiple` is `false`, or when `value`, `defaultValue`, or `onChange` is set on Accordion.
|
|
20
|
+
*/
|
|
21
|
+
value?: string;
|
|
17
22
|
}
|
|
18
23
|
type AccordionItemProps = AccordionItemBaseProps & UseDisclosureProps;
|
|
19
24
|
type AccordionItemStateProps = DisclosureStateProps;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import buildDataAttributes_default from "../private/buildDataAttributes.mjs";
|
|
2
2
|
import { Box } from "../Box/Box.mjs";
|
|
3
|
-
import { Stack } from "../Stack/Stack.mjs";
|
|
4
3
|
import { AccordionContext, validTones } from "./AccordionContext.mjs";
|
|
5
4
|
import "./Accordion.mjs";
|
|
5
|
+
import { useFallbackId } from "../../hooks/useFallbackId.mjs";
|
|
6
6
|
import { useDisclosure } from "../Disclosure/useDisclosure.mjs";
|
|
7
7
|
import { Spread } from "../Spread/Spread.mjs";
|
|
8
8
|
import { Text } from "../Text/Text.mjs";
|
|
9
9
|
import { IconChevron } from "../icons/IconChevron/IconChevron.mjs";
|
|
10
10
|
import { badgeSlotSpace } from "../private/badgeSlotSpace.mjs";
|
|
11
|
-
import { button, focusRing } from "./AccordionItem.css.mjs";
|
|
11
|
+
import { button, content, contentClosed, contentOpen, focusRing } from "./AccordionItem.css.mjs";
|
|
12
12
|
import assert from "assert";
|
|
13
|
-
import { cloneElement, useContext } from "react";
|
|
13
|
+
import { cloneElement, useCallback, useContext, useLayoutEffect, useRef, useState } from "react";
|
|
14
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
//#region src/lib/components/Accordion/AccordionItem.tsx
|
|
16
16
|
const itemSpaceForSize = {
|
|
@@ -19,12 +19,21 @@ const itemSpaceForSize = {
|
|
|
19
19
|
standard: "medium",
|
|
20
20
|
large: "medium"
|
|
21
21
|
};
|
|
22
|
-
const
|
|
22
|
+
const minDurationMs = 200;
|
|
23
|
+
const maxDurationMs = 500;
|
|
24
|
+
const pixelsPerSecond = 320;
|
|
25
|
+
const durationMsForHeight = (height) => Math.round(Math.min(maxDurationMs, Math.max(minDurationMs, height / pixelsPerSecond * 1e3)));
|
|
26
|
+
const prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
27
|
+
const isHeightTransition = (event) => event.propertyName === "height" && event.target === event.currentTarget;
|
|
28
|
+
const AccordionItem = ({ id, value, label, children, badge, size: sizeProp, tone: toneProp, weight: weightProp, icon, data, expanded: expandedProp, onToggle, ...restProps }) => {
|
|
23
29
|
const accordionContext = useContext(AccordionContext);
|
|
30
|
+
const managed = Boolean(accordionContext?.managed);
|
|
24
31
|
assert(!(accordionContext && sizeProp), "Size cannot be set on AccordionItem when inside Accordion. Size should be set on Accordion instead.");
|
|
25
32
|
assert(!(accordionContext && toneProp), "Tone cannot be set on AccordionItem when inside Accordion. Tone should be set on Accordion instead.");
|
|
26
33
|
assert(!(accordionContext && weightProp), "Weight cannot be set on AccordionItem when inside Accordion. Weight should be set on Accordion instead.");
|
|
27
|
-
assert(toneProp === void 0 || validTones.includes(toneProp), `The 'tone' prop should be one of the following: ${validTones.map((
|
|
34
|
+
assert(toneProp === void 0 || validTones.includes(toneProp), `The 'tone' prop should be one of the following: ${validTones.map((tone) => `"${tone}"`).join(", ")}`);
|
|
35
|
+
assert(!managed || typeof value === "string" && value.length > 0, "AccordionItem 'value' must be a non-empty string when Accordion controls which items are open.");
|
|
36
|
+
assert(!(managed && expandedProp !== void 0), "expanded cannot be set on AccordionItem when Accordion controls which items are open. Use 'value' and 'onChange' on Accordion.");
|
|
28
37
|
assert(!badge || badge.type.__isBadge__, `AccordionItem badge prop can only be an instance of Badge. e.g. <AccordionItem badge={<Badge>New</Badge>}>`);
|
|
29
38
|
assert(!badge || badge.props.bleedY === void 0, "Badge elements cannot set the 'bleedY' prop when passed to an AccordionItem component");
|
|
30
39
|
assert(!icon || icon.props.size === void 0 && icon.props.tone === void 0, "Icons cannot set the 'size' or 'tone' prop when passed to an AccordionItem component");
|
|
@@ -32,14 +41,64 @@ const AccordionItem = ({ id, label, children, badge, size: sizeProp, tone: toneP
|
|
|
32
41
|
const tone = accordionContext?.tone ?? toneProp ?? "neutral";
|
|
33
42
|
const weight = accordionContext?.weight ?? weightProp ?? "medium";
|
|
34
43
|
const itemSpace = itemSpaceForSize[size] ?? "none";
|
|
44
|
+
const contentRef = useRef(null);
|
|
45
|
+
const contentSizeRef = useRef(null);
|
|
35
46
|
assert(typeof label === "undefined" || typeof label === "string", "Label must be a string");
|
|
47
|
+
const resolvedId = useFallbackId(id);
|
|
48
|
+
let disclosureState = { onToggle };
|
|
49
|
+
if (managed && accordionContext && value) disclosureState = {
|
|
50
|
+
expanded: accordionContext.openValues.includes(value),
|
|
51
|
+
onToggle: (nextExpanded) => {
|
|
52
|
+
accordionContext.toggleValue(value);
|
|
53
|
+
onToggle?.(nextExpanded);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
else if (expandedProp !== void 0) disclosureState = {
|
|
57
|
+
expanded: expandedProp,
|
|
58
|
+
onToggle
|
|
59
|
+
};
|
|
36
60
|
const { expanded, buttonProps, contentProps } = useDisclosure({
|
|
37
|
-
id,
|
|
38
|
-
...
|
|
39
|
-
onToggle: restProps.onToggle,
|
|
40
|
-
expanded: restProps.expanded
|
|
41
|
-
} : { onToggle: restProps.onToggle }
|
|
61
|
+
id: resolvedId,
|
|
62
|
+
...disclosureState
|
|
42
63
|
});
|
|
64
|
+
const [trackedExpanded, setTrackedExpanded] = useState(expanded);
|
|
65
|
+
const [animatedHeight, setAnimatedHeight] = useState(null);
|
|
66
|
+
const [animationDurationMs, setAnimationDurationMs] = useState(minDurationMs);
|
|
67
|
+
const isAnimating = animatedHeight !== null;
|
|
68
|
+
if (expanded !== trackedExpanded) {
|
|
69
|
+
setTrackedExpanded(expanded);
|
|
70
|
+
if (prefersReducedMotion()) setAnimatedHeight(null);
|
|
71
|
+
else {
|
|
72
|
+
const height = contentSizeRef.current?.scrollHeight ?? 0;
|
|
73
|
+
setAnimatedHeight(height);
|
|
74
|
+
setAnimationDurationMs(durationMsForHeight(height));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const finishAnimation = useCallback(() => {
|
|
78
|
+
setAnimatedHeight(null);
|
|
79
|
+
}, []);
|
|
80
|
+
const finishHeightTransition = useCallback((event) => {
|
|
81
|
+
if (isHeightTransition(event)) finishAnimation();
|
|
82
|
+
}, [finishAnimation]);
|
|
83
|
+
useLayoutEffect(() => {
|
|
84
|
+
contentRef.current?.toggleAttribute("inert", !expanded);
|
|
85
|
+
}, [expanded]);
|
|
86
|
+
useLayoutEffect(() => {
|
|
87
|
+
if (!isAnimating) return;
|
|
88
|
+
if (!expanded) {
|
|
89
|
+
contentRef.current?.getBoundingClientRect();
|
|
90
|
+
setAnimatedHeight(0);
|
|
91
|
+
}
|
|
92
|
+
const timeoutId = window.setTimeout(finishAnimation, animationDurationMs + 50);
|
|
93
|
+
return () => {
|
|
94
|
+
window.clearTimeout(timeoutId);
|
|
95
|
+
};
|
|
96
|
+
}, [
|
|
97
|
+
animationDurationMs,
|
|
98
|
+
expanded,
|
|
99
|
+
finishAnimation,
|
|
100
|
+
isAnimating
|
|
101
|
+
]);
|
|
43
102
|
if (process.env.NODE_ENV !== "production")
|
|
44
103
|
/**
|
|
45
104
|
* Validate that consumers are not passing `data-*`props,
|
|
@@ -49,8 +108,7 @@ const AccordionItem = ({ id, label, children, badge, size: sizeProp, tone: toneP
|
|
|
49
108
|
data,
|
|
50
109
|
validateRestProps: restProps
|
|
51
110
|
});
|
|
52
|
-
return /* @__PURE__ */ jsxs(
|
|
53
|
-
space: itemSpace,
|
|
111
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
54
112
|
data,
|
|
55
113
|
children: [/* @__PURE__ */ jsx(Box, {
|
|
56
114
|
position: "relative",
|
|
@@ -89,9 +147,25 @@ const AccordionItem = ({ id, label, children, badge, size: sizeProp, tone: toneP
|
|
|
89
147
|
})
|
|
90
148
|
})
|
|
91
149
|
}), /* @__PURE__ */ jsx(Box, {
|
|
92
|
-
|
|
150
|
+
className: {
|
|
151
|
+
[content]: true,
|
|
152
|
+
[contentOpen]: expanded && !isAnimating,
|
|
153
|
+
[contentClosed]: !expanded && !isAnimating
|
|
154
|
+
},
|
|
155
|
+
style: isAnimating ? {
|
|
156
|
+
height: animatedHeight,
|
|
157
|
+
transitionDuration: `${animationDurationMs}ms`
|
|
158
|
+
} : void 0,
|
|
159
|
+
onTransitionEnd: finishHeightTransition,
|
|
160
|
+
onTransitionCancel: finishHeightTransition,
|
|
161
|
+
"aria-hidden": expanded ? void 0 : true,
|
|
162
|
+
ref: contentRef,
|
|
93
163
|
...contentProps,
|
|
94
|
-
children
|
|
164
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
165
|
+
ref: contentSizeRef,
|
|
166
|
+
paddingTop: itemSpace,
|
|
167
|
+
children
|
|
168
|
+
})
|
|
95
169
|
})]
|
|
96
170
|
});
|
|
97
171
|
};
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
const require_AccordionContext = require("./AccordionContext.cjs");
|
|
1
2
|
const require_AccordionItem = require("./AccordionItem.cjs");
|
|
2
3
|
const require_playroomState = require("../../playroom/playroomState.cjs");
|
|
4
|
+
let react = require("react");
|
|
3
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
6
|
//#region src/lib/components/Accordion/AccordionItem.playroom.tsx
|
|
5
|
-
const AccordionItem = ({ label, stateName, expanded, onToggle, size, tone, weight, badge, icon, ...restProps }) => {
|
|
7
|
+
const AccordionItem = ({ label, stateName, expanded, onToggle, size, tone, weight, badge, icon, value, ...restProps }) => {
|
|
8
|
+
const managed = Boolean((0, react.useContext)(require_AccordionContext.AccordionContext)?.managed);
|
|
6
9
|
const [state, handleChange] = require_playroomState.useFallbackState(stateName, expanded, onToggle, false);
|
|
7
10
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AccordionItem.AccordionItem, {
|
|
8
|
-
|
|
11
|
+
value: typeof value === "string" ? value : void 0,
|
|
9
12
|
onToggle: handleChange,
|
|
13
|
+
expanded: managed ? void 0 : state,
|
|
10
14
|
label: typeof label !== "boolean" ? label : "",
|
|
11
15
|
size: typeof size === "boolean" ? void 0 : size,
|
|
12
16
|
tone: typeof tone === "boolean" ? void 0 : tone,
|
|
@@ -3,7 +3,7 @@ import { StateProp } from "../../playroom/playroomState.cjs";
|
|
|
3
3
|
import { FC } from "react";
|
|
4
4
|
//#region src/lib/components/Accordion/AccordionItem.playroom.d.ts
|
|
5
5
|
type OptionalProps = 'id';
|
|
6
|
-
type PlayroomAccordionItemProps = StateProp & AccordionItemBaseProps & AccordionItemStateProps & Partial<Pick<AccordionItemProps, OptionalProps>>;
|
|
6
|
+
type PlayroomAccordionItemProps = StateProp & AccordionItemBaseProps & AccordionItemStateProps & Partial<Pick<AccordionItemProps, OptionalProps | 'value'>>;
|
|
7
7
|
declare const AccordionItem: FC<PlayroomAccordionItemProps>;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { AccordionItem };
|
|
@@ -3,7 +3,7 @@ import { StateProp } from "../../playroom/playroomState.mjs";
|
|
|
3
3
|
import { FC } from "react";
|
|
4
4
|
//#region src/lib/components/Accordion/AccordionItem.playroom.d.ts
|
|
5
5
|
type OptionalProps = 'id';
|
|
6
|
-
type PlayroomAccordionItemProps = StateProp & AccordionItemBaseProps & AccordionItemStateProps & Partial<Pick<AccordionItemProps, OptionalProps>>;
|
|
6
|
+
type PlayroomAccordionItemProps = StateProp & AccordionItemBaseProps & AccordionItemStateProps & Partial<Pick<AccordionItemProps, OptionalProps | 'value'>>;
|
|
7
7
|
declare const AccordionItem: FC<PlayroomAccordionItemProps>;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { AccordionItem };
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { AccordionContext } from "./AccordionContext.mjs";
|
|
1
2
|
import { AccordionItem as AccordionItem$1 } from "./AccordionItem.mjs";
|
|
2
3
|
import { useFallbackState } from "../../playroom/playroomState.mjs";
|
|
4
|
+
import { useContext } from "react";
|
|
3
5
|
import { jsx } from "react/jsx-runtime";
|
|
4
6
|
//#region src/lib/components/Accordion/AccordionItem.playroom.tsx
|
|
5
|
-
const AccordionItem = ({ label, stateName, expanded, onToggle, size, tone, weight, badge, icon, ...restProps }) => {
|
|
7
|
+
const AccordionItem = ({ label, stateName, expanded, onToggle, size, tone, weight, badge, icon, value, ...restProps }) => {
|
|
8
|
+
const managed = Boolean(useContext(AccordionContext)?.managed);
|
|
6
9
|
const [state, handleChange] = useFallbackState(stateName, expanded, onToggle, false);
|
|
7
10
|
return /* @__PURE__ */ jsx(AccordionItem$1, {
|
|
8
|
-
|
|
11
|
+
value: typeof value === "string" ? value : void 0,
|
|
9
12
|
onToggle: handleChange,
|
|
13
|
+
expanded: managed ? void 0 : state,
|
|
10
14
|
label: typeof label !== "boolean" ? label : "",
|
|
11
15
|
size: typeof size === "boolean" ? void 0 : size,
|
|
12
16
|
tone: typeof tone === "boolean" ? void 0 : tone,
|
|
@@ -187,7 +187,6 @@ const Avatar = (0, react.forwardRef)(({ name = "", "aria-label": ariaLabel, "ari
|
|
|
187
187
|
outline: !clickable && focusable ? "focus" : void 0,
|
|
188
188
|
className: {
|
|
189
189
|
[require_Avatar_css.size[size$1]]: true,
|
|
190
|
-
[require_Avatar_css.keyline]: true,
|
|
191
190
|
[require_virtualTouchable_css.virtualTouchable]: clickable && (size$1 === "xsmall" || size$1 === "small")
|
|
192
191
|
},
|
|
193
192
|
style: colour ? { background: colour.value } : void 0,
|
|
@@ -204,6 +203,7 @@ const Avatar = (0, react.forwardRef)(({ name = "", "aria-label": ariaLabel, "ari
|
|
|
204
203
|
height: "full",
|
|
205
204
|
overflow: "hidden",
|
|
206
205
|
borderRadius,
|
|
206
|
+
className: require_Avatar_css.keyline,
|
|
207
207
|
children: content
|
|
208
208
|
})
|
|
209
209
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const require_px = require("../../utils/px.cjs");
|
|
1
2
|
const require_vars_css = require("../../themes/vars.css.cjs");
|
|
2
3
|
let _vanilla_extract_css_fileScope = require("@vanilla-extract/css/fileScope");
|
|
3
4
|
let _vanilla_extract_css = require("@vanilla-extract/css");
|
|
@@ -12,7 +13,7 @@ const size = (0, _vanilla_extract_css.styleVariants)({
|
|
|
12
13
|
xxlarge: 96
|
|
13
14
|
}, (pixels) => ({
|
|
14
15
|
height: pixels,
|
|
15
|
-
width: pixels
|
|
16
|
+
width: `${require_px.px(pixels)} !important`
|
|
16
17
|
}), "size");
|
|
17
18
|
const keyline = (0, _vanilla_extract_css.style)({
|
|
18
19
|
borderWidth: require_vars_css.vars.borderWidth.standard,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { px } from "../../utils/px.mjs";
|
|
1
2
|
import { vars } from "../../themes/vars.css.mjs";
|
|
2
3
|
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
|
|
3
4
|
import { style, styleVariants } from "@vanilla-extract/css";
|
|
@@ -12,7 +13,7 @@ const size = styleVariants({
|
|
|
12
13
|
xxlarge: 96
|
|
13
14
|
}, (pixels) => ({
|
|
14
15
|
height: pixels,
|
|
15
|
-
width: pixels
|
|
16
|
+
width: `${px(pixels)} !important`
|
|
16
17
|
}), "size");
|
|
17
18
|
const keyline = style({
|
|
18
19
|
borderWidth: vars.borderWidth.standard,
|
|
@@ -185,7 +185,6 @@ const Avatar = forwardRef(({ name = "", "aria-label": ariaLabel, "aria-described
|
|
|
185
185
|
outline: !clickable && focusable ? "focus" : void 0,
|
|
186
186
|
className: {
|
|
187
187
|
[size[size$1]]: true,
|
|
188
|
-
[keyline]: true,
|
|
189
188
|
[virtualTouchable]: clickable && (size$1 === "xsmall" || size$1 === "small")
|
|
190
189
|
},
|
|
191
190
|
style: colour ? { background: colour.value } : void 0,
|
|
@@ -202,6 +201,7 @@ const Avatar = forwardRef(({ name = "", "aria-label": ariaLabel, "aria-described
|
|
|
202
201
|
height: "full",
|
|
203
202
|
overflow: "hidden",
|
|
204
203
|
borderRadius,
|
|
204
|
+
className: keyline,
|
|
205
205
|
children: content
|
|
206
206
|
})
|
|
207
207
|
});
|
|
@@ -10,7 +10,6 @@ const BraidPortal = ({ children, container }) => {
|
|
|
10
10
|
value: null,
|
|
11
11
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_VanillaThemeContainer.VanillaThemeContainer, {
|
|
12
12
|
theme: vanillaTheme,
|
|
13
|
-
setDefaultTextTones: true,
|
|
14
13
|
children
|
|
15
14
|
})
|
|
16
15
|
}), container ?? document.body);
|
|
@@ -46,7 +46,6 @@ const BraidProvider = ({ theme, styleBody = true, linkComponent, children }) =>
|
|
|
46
46
|
`
|
|
47
47
|
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_VanillaThemeContainer.VanillaThemeContainer, {
|
|
48
48
|
theme: theme.vanillaTheme,
|
|
49
|
-
setDefaultTextTones: !alreadyInBraidProvider,
|
|
50
49
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkComponentContext.Provider, {
|
|
51
50
|
value: linkComponent || linkComponentFromContext,
|
|
52
51
|
children: alreadyInBraidProvider || inTestProvider ? children : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_BreakpointContext.BreakpointProvider, { children })
|
|
@@ -43,7 +43,6 @@ const BraidProvider = ({ theme, styleBody = true, linkComponent, children }) =>
|
|
|
43
43
|
`
|
|
44
44
|
}) : null, /* @__PURE__ */ jsx(VanillaThemeContainer, {
|
|
45
45
|
theme: theme.vanillaTheme,
|
|
46
|
-
setDefaultTextTones: !alreadyInBraidProvider,
|
|
47
46
|
children: /* @__PURE__ */ jsx(LinkComponentContext.Provider, {
|
|
48
47
|
value: linkComponent || linkComponentFromContext,
|
|
49
48
|
children: alreadyInBraidProvider || inTestProvider ? children : /* @__PURE__ */ jsx(BreakpointProvider, { children })
|
|
@@ -2,8 +2,8 @@ const require_typography_css = require("../../css/typography.css.cjs");
|
|
|
2
2
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
3
|
//#region src/lib/components/BraidProvider/VanillaThemeContainer.tsx
|
|
4
4
|
const textTones = [require_typography_css.lightModeTone.light, require_typography_css.darkModeTone.dark].join(" ");
|
|
5
|
-
const VanillaThemeContainer = ({ children, theme
|
|
6
|
-
className: `${theme}
|
|
5
|
+
const VanillaThemeContainer = ({ children, theme }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6
|
+
className: `${theme} ${textTones}`,
|
|
7
7
|
children
|
|
8
8
|
});
|
|
9
9
|
//#endregion
|
|
@@ -2,8 +2,8 @@ import { darkModeTone, lightModeTone } from "../../css/typography.css.mjs";
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
//#region src/lib/components/BraidProvider/VanillaThemeContainer.tsx
|
|
4
4
|
const textTones = [lightModeTone.light, darkModeTone.dark].join(" ");
|
|
5
|
-
const VanillaThemeContainer = ({ children, theme
|
|
6
|
-
className: `${theme}
|
|
5
|
+
const VanillaThemeContainer = ({ children, theme }) => /* @__PURE__ */ jsx("div", {
|
|
6
|
+
className: `${theme} ${textTones}`,
|
|
7
7
|
children
|
|
8
8
|
});
|
|
9
9
|
//#endregion
|
|
@@ -23,6 +23,11 @@ const assertAccessibleName = ({ title, description, "aria-label": ariaLabel, "ar
|
|
|
23
23
|
(0, assert.default)(typeof title === "string" !== (typeof ariaLabel === "string"), dedent.default`
|
|
24
24
|
Drawer requires either a title or an aria-label.
|
|
25
25
|
|
|
26
|
+
${docsMessage}
|
|
27
|
+
`);
|
|
28
|
+
(0, assert.default)(typeof title !== "string" || title.trim() !== "", dedent.default`
|
|
29
|
+
Drawer title must not be empty.
|
|
30
|
+
|
|
26
31
|
${docsMessage}
|
|
27
32
|
`);
|
|
28
33
|
(0, assert.default)(typeof ariaLabel !== "string" || ariaLabel.trim() !== "", dedent.default`
|
|
@@ -20,6 +20,11 @@ const assertAccessibleName = ({ title, description, "aria-label": ariaLabel, "ar
|
|
|
20
20
|
assert(typeof title === "string" !== (typeof ariaLabel === "string"), dedent`
|
|
21
21
|
Drawer requires either a title or an aria-label.
|
|
22
22
|
|
|
23
|
+
${docsMessage}
|
|
24
|
+
`);
|
|
25
|
+
assert(typeof title !== "string" || title.trim() !== "", dedent`
|
|
26
|
+
Drawer title must not be empty.
|
|
27
|
+
|
|
23
28
|
${docsMessage}
|
|
24
29
|
`);
|
|
25
30
|
assert(typeof ariaLabel !== "string" || ariaLabel.trim() !== "", dedent`
|
|
@@ -64,7 +64,6 @@ const reducer = (prevState, action) => {
|
|
|
64
64
|
};
|
|
65
65
|
const ANIMATION_DURATION = 300;
|
|
66
66
|
const Modal = ({ id, open, children, description, onClose, width, closeLabel, illustration, title, "aria-label": ariaLabel, "aria-description": ariaDescription, headingLevel, position, ...restProps }) => {
|
|
67
|
-
const [trapActive, setTrapActive] = (0, react.useState)(true);
|
|
68
67
|
const [state, dispatch] = (0, react.useReducer)(reducer, INITIAL);
|
|
69
68
|
const allowClose = (0, react.useContext)(AllowCloseContext);
|
|
70
69
|
const shouldFocus = typeof document !== "undefined" && typeof document.hasFocus === "function" && document.hasFocus();
|
|
@@ -100,17 +99,8 @@ const Modal = ({ id, open, children, description, onClose, width, closeLabel, il
|
|
|
100
99
|
(0, react.useEffect)(() => {
|
|
101
100
|
if (typeof onClose === "function") closeHandlerRef.current = onClose;
|
|
102
101
|
}, [onClose]);
|
|
103
|
-
(0, react.useEffect)(() => {
|
|
104
|
-
const event = trapActive ? "blur" : "focus";
|
|
105
|
-
const handleEvent = () => setTrapActive(!trapActive);
|
|
106
|
-
window.addEventListener(event, handleEvent);
|
|
107
|
-
return () => {
|
|
108
|
-
window.removeEventListener(event, handleEvent);
|
|
109
|
-
};
|
|
110
|
-
}, [trapActive]);
|
|
111
102
|
return state === OPENING || state === OPEN || state === CLOSING ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModalPortal, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(FocusLock, {
|
|
112
103
|
className: require_Modal_css.resetStackingContext,
|
|
113
|
-
disabled: !trapActive,
|
|
114
104
|
autoFocus: false,
|
|
115
105
|
onActivation: () => {
|
|
116
106
|
if (state === OPEN) return;
|
|
@@ -62,7 +62,6 @@ const reducer = (prevState, action) => {
|
|
|
62
62
|
};
|
|
63
63
|
const ANIMATION_DURATION = 300;
|
|
64
64
|
const Modal = ({ id, open, children, description, onClose, width, closeLabel, illustration, title, "aria-label": ariaLabel, "aria-description": ariaDescription, headingLevel, position, ...restProps }) => {
|
|
65
|
-
const [trapActive, setTrapActive] = useState(true);
|
|
66
65
|
const [state, dispatch] = useReducer(reducer, INITIAL);
|
|
67
66
|
const allowClose = useContext(AllowCloseContext);
|
|
68
67
|
const shouldFocus = typeof document !== "undefined" && typeof document.hasFocus === "function" && document.hasFocus();
|
|
@@ -98,17 +97,8 @@ const Modal = ({ id, open, children, description, onClose, width, closeLabel, il
|
|
|
98
97
|
useEffect(() => {
|
|
99
98
|
if (typeof onClose === "function") closeHandlerRef.current = onClose;
|
|
100
99
|
}, [onClose]);
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
const event = trapActive ? "blur" : "focus";
|
|
103
|
-
const handleEvent = () => setTrapActive(!trapActive);
|
|
104
|
-
window.addEventListener(event, handleEvent);
|
|
105
|
-
return () => {
|
|
106
|
-
window.removeEventListener(event, handleEvent);
|
|
107
|
-
};
|
|
108
|
-
}, [trapActive]);
|
|
109
100
|
return state === OPENING || state === OPEN || state === CLOSING ? /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsxs(FocusLock, {
|
|
110
101
|
className: resetStackingContext,
|
|
111
|
-
disabled: !trapActive,
|
|
112
102
|
autoFocus: false,
|
|
113
103
|
onActivation: () => {
|
|
114
104
|
if (state === OPEN) return;
|
|
@@ -158,6 +158,11 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
158
158
|
right: "flexEnd"
|
|
159
159
|
}[position];
|
|
160
160
|
const modalRadius = !isDrawer ? "xlarge" : void 0;
|
|
161
|
+
/**
|
|
162
|
+
* Only Drawer supports omitting the title, in which case there is no header
|
|
163
|
+
* to hold the content clear of the close button.
|
|
164
|
+
*/
|
|
165
|
+
const untitledDrawer = isDrawer && !title;
|
|
161
166
|
const modalLayout = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ModalContentScrollLayout, {
|
|
162
167
|
applyPageBlockGutters: isDrawer,
|
|
163
168
|
applyFullHeight: isDrawer || allowColumnLayout && Boolean(footer) && !isMobile,
|
|
@@ -165,7 +170,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
165
170
|
coverImageEnabled,
|
|
166
171
|
hasFooter: Boolean(footer),
|
|
167
172
|
children: [
|
|
168
|
-
|
|
173
|
+
!untitledDrawer ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModalContentHeader, {
|
|
169
174
|
title,
|
|
170
175
|
headingLevel,
|
|
171
176
|
description,
|
|
@@ -174,7 +179,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
174
179
|
ref: headingRef,
|
|
175
180
|
reserveCloseArea: true
|
|
176
181
|
}) : null,
|
|
177
|
-
|
|
182
|
+
untitledDrawer ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
178
183
|
require_Bleed.Bleed,
|
|
179
184
|
/**
|
|
180
185
|
* Matches close button size so content starts below it. `bottom`
|
|
@@ -203,9 +208,9 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
203
208
|
ref: dialogRef,
|
|
204
209
|
role: "dialog",
|
|
205
210
|
"aria-label": ariaLabel || title,
|
|
206
|
-
"aria-describedby":
|
|
211
|
+
"aria-describedby": !untitledDrawer && description || ariaDescription ? descriptionId : void 0,
|
|
207
212
|
"aria-modal": "true",
|
|
208
|
-
tabIndex:
|
|
213
|
+
tabIndex: untitledDrawer ? -1 : void 0,
|
|
209
214
|
id: resolvedId,
|
|
210
215
|
onKeyDown: handleEscape,
|
|
211
216
|
position: "relative",
|
|
@@ -158,6 +158,11 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
158
158
|
right: "flexEnd"
|
|
159
159
|
}[position];
|
|
160
160
|
const modalRadius = !isDrawer ? "xlarge" : void 0;
|
|
161
|
+
/**
|
|
162
|
+
* Only Drawer supports omitting the title, in which case there is no header
|
|
163
|
+
* to hold the content clear of the close button.
|
|
164
|
+
*/
|
|
165
|
+
const untitledDrawer = isDrawer && !title;
|
|
161
166
|
const modalLayout = /* @__PURE__ */ jsxs(ModalContentScrollLayout, {
|
|
162
167
|
applyPageBlockGutters: isDrawer,
|
|
163
168
|
applyFullHeight: isDrawer || allowColumnLayout && Boolean(footer) && !isMobile,
|
|
@@ -165,7 +170,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
165
170
|
coverImageEnabled,
|
|
166
171
|
hasFooter: Boolean(footer),
|
|
167
172
|
children: [
|
|
168
|
-
|
|
173
|
+
!untitledDrawer ? /* @__PURE__ */ jsx(ModalContentHeader, {
|
|
169
174
|
title,
|
|
170
175
|
headingLevel,
|
|
171
176
|
description,
|
|
@@ -174,7 +179,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
174
179
|
ref: headingRef,
|
|
175
180
|
reserveCloseArea: true
|
|
176
181
|
}) : null,
|
|
177
|
-
|
|
182
|
+
untitledDrawer ? /* @__PURE__ */ jsx(
|
|
178
183
|
Bleed,
|
|
179
184
|
/**
|
|
180
185
|
* Matches close button size so content starts below it. `bottom`
|
|
@@ -203,9 +208,9 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
203
208
|
ref: dialogRef,
|
|
204
209
|
role: "dialog",
|
|
205
210
|
"aria-label": ariaLabel || title,
|
|
206
|
-
"aria-describedby":
|
|
211
|
+
"aria-describedby": !untitledDrawer && description || ariaDescription ? descriptionId : void 0,
|
|
207
212
|
"aria-modal": "true",
|
|
208
|
-
tabIndex:
|
|
213
|
+
tabIndex: untitledDrawer ? -1 : void 0,
|
|
209
214
|
id: resolvedId,
|
|
210
215
|
onKeyDown: handleEscape,
|
|
211
216
|
position: "relative",
|
|
@@ -25,7 +25,11 @@ const toneToIcon = {
|
|
|
25
25
|
critical: require_IconCritical.IconCritical,
|
|
26
26
|
positive: require_IconPositive.IconPositive
|
|
27
27
|
};
|
|
28
|
-
const toastDuration =
|
|
28
|
+
const toastDuration = {
|
|
29
|
+
short: 6e3,
|
|
30
|
+
standard: 1e4,
|
|
31
|
+
indefinite: null
|
|
32
|
+
};
|
|
29
33
|
const borderRadius = "large";
|
|
30
34
|
const Action = ({ label, onClick, removeToast }) => {
|
|
31
35
|
const handleClick = (0, react.useCallback)((event) => {
|
|
@@ -54,14 +58,15 @@ const ToastIcon = ({ tone, icon }) => {
|
|
|
54
58
|
if (icon) return (0, react.cloneElement)(icon, { tone });
|
|
55
59
|
return null;
|
|
56
60
|
};
|
|
57
|
-
const Toast = (0, react.forwardRef)(({ toastKey, dedupeKey, message, description, tone, icon, onClose, closeLabel = "Close", action, shouldRemove, data, expanded = true, ...restProps }, ref) => {
|
|
61
|
+
const Toast = (0, react.forwardRef)(({ toastKey, dedupeKey, message, duration = "standard", description, tone, icon, onClose, closeLabel = "Close", action, shouldRemove, data, expanded = true, ...restProps }, ref) => {
|
|
58
62
|
const remove = (0, react.useCallback)(() => onClose(dedupeKey, toastKey), [
|
|
59
63
|
onClose,
|
|
60
64
|
dedupeKey,
|
|
61
65
|
toastKey
|
|
62
66
|
]);
|
|
67
|
+
const resolvedDuration = toastDuration[duration];
|
|
63
68
|
const { stopTimeout, startTimeout } = require_useTimeout.useTimeout({
|
|
64
|
-
duration:
|
|
69
|
+
duration: resolvedDuration,
|
|
65
70
|
onTimeout: remove
|
|
66
71
|
});
|
|
67
72
|
(0, react.useEffect)(() => {
|
|
@@ -23,7 +23,11 @@ const toneToIcon = {
|
|
|
23
23
|
critical: IconCritical,
|
|
24
24
|
positive: IconPositive
|
|
25
25
|
};
|
|
26
|
-
const toastDuration =
|
|
26
|
+
const toastDuration = {
|
|
27
|
+
short: 6e3,
|
|
28
|
+
standard: 1e4,
|
|
29
|
+
indefinite: null
|
|
30
|
+
};
|
|
27
31
|
const borderRadius = "large";
|
|
28
32
|
const Action = ({ label, onClick, removeToast }) => {
|
|
29
33
|
const handleClick = useCallback((event) => {
|
|
@@ -52,14 +56,15 @@ const ToastIcon = ({ tone, icon }) => {
|
|
|
52
56
|
if (icon) return cloneElement(icon, { tone });
|
|
53
57
|
return null;
|
|
54
58
|
};
|
|
55
|
-
const Toast = forwardRef(({ toastKey, dedupeKey, message, description, tone, icon, onClose, closeLabel = "Close", action, shouldRemove, data, expanded = true, ...restProps }, ref) => {
|
|
59
|
+
const Toast = forwardRef(({ toastKey, dedupeKey, message, duration = "standard", description, tone, icon, onClose, closeLabel = "Close", action, shouldRemove, data, expanded = true, ...restProps }, ref) => {
|
|
56
60
|
const remove = useCallback(() => onClose(dedupeKey, toastKey), [
|
|
57
61
|
onClose,
|
|
58
62
|
dedupeKey,
|
|
59
63
|
toastKey
|
|
60
64
|
]);
|
|
65
|
+
const resolvedDuration = toastDuration[duration];
|
|
61
66
|
const { stopTimeout, startTimeout } = useTimeout({
|
|
62
|
-
duration:
|
|
67
|
+
duration: resolvedDuration,
|
|
63
68
|
onTimeout: remove
|
|
64
69
|
});
|
|
65
70
|
useEffect(() => {
|
|
@@ -6,6 +6,7 @@ interface ToastAction {
|
|
|
6
6
|
label: string;
|
|
7
7
|
onClick: () => void;
|
|
8
8
|
}
|
|
9
|
+
type ToastDuration = 'short' | 'standard' | 'indefinite';
|
|
9
10
|
type Toast = {
|
|
10
11
|
key?: string;
|
|
11
12
|
message: string;
|
|
@@ -13,6 +14,7 @@ type Toast = {
|
|
|
13
14
|
action?: ToastAction;
|
|
14
15
|
closeLabel?: string;
|
|
15
16
|
data?: DataAttributeMap;
|
|
17
|
+
duration?: ToastDuration;
|
|
16
18
|
} & ({
|
|
17
19
|
tone: 'positive' | 'critical';
|
|
18
20
|
} | {
|
|
@@ -20,4 +22,4 @@ type Toast = {
|
|
|
20
22
|
icon?: ReactElement<UseIconProps>;
|
|
21
23
|
});
|
|
22
24
|
//#endregion
|
|
23
|
-
export { Toast, ToastAction };
|
|
25
|
+
export { Toast, ToastAction, ToastDuration };
|
|
@@ -6,6 +6,7 @@ interface ToastAction {
|
|
|
6
6
|
label: string;
|
|
7
7
|
onClick: () => void;
|
|
8
8
|
}
|
|
9
|
+
type ToastDuration = 'short' | 'standard' | 'indefinite';
|
|
9
10
|
type Toast = {
|
|
10
11
|
key?: string;
|
|
11
12
|
message: string;
|
|
@@ -13,6 +14,7 @@ type Toast = {
|
|
|
13
14
|
action?: ToastAction;
|
|
14
15
|
closeLabel?: string;
|
|
15
16
|
data?: DataAttributeMap;
|
|
17
|
+
duration?: ToastDuration;
|
|
16
18
|
} & ({
|
|
17
19
|
tone: 'positive' | 'critical';
|
|
18
20
|
} | {
|
|
@@ -20,4 +22,4 @@ type Toast = {
|
|
|
20
22
|
icon?: ReactElement<UseIconProps>;
|
|
21
23
|
});
|
|
22
24
|
//#endregion
|
|
23
|
-
export { Toast, ToastAction };
|
|
25
|
+
export { Toast, ToastAction, ToastDuration };
|
|
@@ -154,11 +154,11 @@ const useFlipList = (expanded) => {
|
|
|
154
154
|
property: "transform",
|
|
155
155
|
from: transform
|
|
156
156
|
},
|
|
157
|
-
{
|
|
157
|
+
...element.classList.contains(require_Toast_css.collapsed) ? [{
|
|
158
158
|
property: "className",
|
|
159
|
-
from:
|
|
159
|
+
from: require_Toast_css.collapsed,
|
|
160
160
|
to: void 0
|
|
161
|
-
}
|
|
161
|
+
}] : []
|
|
162
162
|
]
|
|
163
163
|
});
|
|
164
164
|
}
|