braid-design-system 34.8.2 → 34.9.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 +50 -0
- package/dist/color-mode/query-param.d.cts +1 -1
- package/dist/color-mode/query-param.d.mts +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +3 -2
- package/dist/lib/components/Avatar/Avatar.cjs +213 -0
- package/dist/lib/components/Avatar/Avatar.css.cjs +31 -0
- package/dist/lib/components/Avatar/Avatar.css.d.cts +4 -0
- package/dist/lib/components/Avatar/Avatar.css.d.mts +4 -0
- package/dist/lib/components/Avatar/Avatar.css.mjs +29 -0
- package/dist/lib/components/Avatar/Avatar.d.cts +21 -0
- package/dist/lib/components/Avatar/Avatar.d.mts +21 -0
- package/dist/lib/components/Avatar/Avatar.mjs +211 -0
- package/dist/lib/components/Avatar/Avatar.playroom.cjs +14 -0
- package/dist/lib/components/Avatar/Avatar.playroom.d.cts +8 -0
- package/dist/lib/components/Avatar/Avatar.playroom.d.mts +8 -0
- package/dist/lib/components/Avatar/Avatar.playroom.mjs +14 -0
- package/dist/lib/components/Drawer/Drawer.cjs +26 -0
- package/dist/lib/components/Drawer/Drawer.d.cts +15 -4
- package/dist/lib/components/Drawer/Drawer.d.mts +15 -4
- package/dist/lib/components/Drawer/Drawer.mjs +25 -0
- package/dist/lib/components/Heading/Heading.cjs +2 -1
- package/dist/lib/components/Heading/Heading.mjs +3 -2
- package/dist/lib/components/List/List.cjs +16 -16
- package/dist/lib/components/List/List.mjs +16 -16
- package/dist/lib/components/Rating/Rating.cjs +48 -20
- package/dist/lib/components/Rating/Rating.css.cjs +34 -0
- package/dist/lib/components/Rating/Rating.css.mjs +31 -1
- package/dist/lib/components/Rating/Rating.d.cts +11 -2
- package/dist/lib/components/Rating/Rating.d.mts +11 -2
- package/dist/lib/components/Rating/Rating.mjs +50 -22
- package/dist/lib/components/Text/Text.cjs +2 -1
- package/dist/lib/components/Text/Text.mjs +2 -1
- package/dist/lib/components/index.d.cts +2 -1
- package/dist/lib/components/index.d.mts +2 -1
- package/dist/lib/components/private/InlineField/StyledInput.cjs +3 -4
- package/dist/lib/components/private/InlineField/StyledInput.mjs +3 -4
- package/dist/lib/components/private/Modal/Modal.cjs +6 -2
- package/dist/lib/components/private/Modal/Modal.mjs +6 -2
- package/dist/lib/components/private/Modal/ModalContent.cjs +104 -71
- package/dist/lib/components/private/Modal/ModalContent.mjs +104 -71
- package/dist/lib/components/private/Skeleton/Skeleton.cjs +14 -0
- package/dist/lib/components/private/Skeleton/Skeleton.css.cjs +25 -0
- package/dist/lib/components/private/Skeleton/Skeleton.css.mjs +25 -0
- package/dist/lib/components/private/Skeleton/Skeleton.mjs +14 -0
- package/dist/lib/css/atoms/sprinkles.css.d.cts +1 -1
- package/dist/lib/css/atoms/sprinkles.css.d.mts +1 -1
- package/dist/lib/css/typography.css.cjs +12 -0
- package/dist/lib/css/typography.css.mjs +12 -2
- package/dist/lib/playroom/components.cjs +2 -0
- package/dist/lib/playroom/components.d.cts +2 -1
- package/dist/lib/playroom/components.d.mts +2 -1
- package/dist/lib/playroom/components.mjs +2 -1
- package/dist/lib/playroom/snippets/Avatar.cjs +41 -0
- package/dist/lib/playroom/snippets/Avatar.mjs +41 -0
- package/dist/lib/playroom/snippets/CardList.cjs +1 -1
- package/dist/lib/playroom/snippets/CardList.mjs +1 -1
- package/dist/lib/playroom/snippets.cjs +2 -10
- package/dist/lib/playroom/snippets.mjs +94 -102
- package/dist/lib/themes/docs/tokens.cjs +4 -4
- package/dist/lib/themes/docs/tokens.mjs +4 -4
- package/dist/lib/themes/wireframe/tokens.cjs +1 -1
- package/dist/lib/themes/wireframe/tokens.mjs +1 -1
- package/dist/node_modules/.pnpm/{@capsizecss_metrics@4.2.0 → @capsizecss_metrics@4.3.0}/node_modules/@capsizecss/metrics/entireMetricsCollection/appleSystem/index.cjs +1 -1
- package/dist/node_modules/.pnpm/{@capsizecss_metrics@4.2.0 → @capsizecss_metrics@4.3.0}/node_modules/@capsizecss/metrics/entireMetricsCollection/appleSystem/index.mjs +1 -1
- package/dist/node_modules/.pnpm/{@capsizecss_metrics@4.2.0 → @capsizecss_metrics@4.3.0}/node_modules/@capsizecss/metrics/entireMetricsCollection/courierNew/index.cjs +1 -1
- package/dist/node_modules/.pnpm/{@capsizecss_metrics@4.2.0 → @capsizecss_metrics@4.3.0}/node_modules/@capsizecss/metrics/entireMetricsCollection/courierNew/index.mjs +1 -1
- package/dist/playroom/components.cjs +2 -0
- package/dist/playroom/components.d.cts +2 -1
- package/dist/playroom/components.d.mts +2 -1
- package/dist/playroom/components.mjs +2 -1
- package/package.json +3 -3
- package/dist/lib/playroom/snippets/DividedList.cjs +0 -8
- package/dist/lib/playroom/snippets/DividedList.mjs +0 -8
- package/dist/lib/playroom/snippets/Form.cjs +0 -12
- package/dist/lib/playroom/snippets/Form.mjs +0 -12
- package/dist/lib/playroom/snippets/SteppedSection.cjs +0 -8
- package/dist/lib/playroom/snippets/SteppedSection.mjs +0 -8
- package/dist/lib/playroom/snippets/TabbedSection.cjs +0 -8
- package/dist/lib/playroom/snippets/TabbedSection.mjs +0 -8
- package/dist/lib/playroom/snippets/TableSection.cjs +0 -8
- package/dist/lib/playroom/snippets/TableSection.mjs +0 -8
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { palette } from "../../color/palette.mjs";
|
|
2
|
+
import buildDataAttributes_default from "../private/buildDataAttributes.mjs";
|
|
3
|
+
import { Box } from "../Box/Box.mjs";
|
|
4
|
+
import { Text } from "../Text/Text.mjs";
|
|
5
|
+
import { IconImageBroken } from "../icons/IconImageBroken/IconImageBroken.mjs";
|
|
6
|
+
import { IconProfile } from "../icons/IconProfile/IconProfile.mjs";
|
|
7
|
+
import { virtualTouchable } from "../private/touchable/virtualTouchable.css.mjs";
|
|
8
|
+
import { Heading } from "../Heading/Heading.mjs";
|
|
9
|
+
import { Skeleton } from "../private/Skeleton/Skeleton.mjs";
|
|
10
|
+
import { image, keyline, size } from "./Avatar.css.mjs";
|
|
11
|
+
import assert from "assert";
|
|
12
|
+
import { forwardRef, isValidElement, useLayoutEffect, useRef, useState } from "react";
|
|
13
|
+
import { jsx } from "react/jsx-runtime";
|
|
14
|
+
//#region src/lib/components/Avatar/Avatar.tsx
|
|
15
|
+
const backgroundColours = [
|
|
16
|
+
{
|
|
17
|
+
value: palette.seekPink[200],
|
|
18
|
+
type: "customLight"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
value: palette.seekBlueLight[200],
|
|
22
|
+
type: "customLight"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
value: palette.orange[200],
|
|
26
|
+
type: "customLight"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: palette.red[200],
|
|
30
|
+
type: "customLight"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
value: palette.purple[200],
|
|
34
|
+
type: "customLight"
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
const isNonSvgDataUri = (src) => /^data:/i.test(src) && !/^data:image\/svg/i.test(src);
|
|
38
|
+
const isEmptyDecodedImage = (img) => img.naturalWidth === 0 && img.naturalHeight === 0;
|
|
39
|
+
const rasterDataUriFailedToDecode = (img) => img.complete && isEmptyDecodedImage(img) && isNonSvgDataUri(img.src);
|
|
40
|
+
const avatarSizeToBorderRadius = {
|
|
41
|
+
xxlarge: "large",
|
|
42
|
+
xlarge: "large",
|
|
43
|
+
large: "standard",
|
|
44
|
+
standard: "standard",
|
|
45
|
+
small: "standard",
|
|
46
|
+
xsmall: "small"
|
|
47
|
+
};
|
|
48
|
+
const avatarSizeToTextSize = {
|
|
49
|
+
xxlarge: "large",
|
|
50
|
+
xlarge: "large",
|
|
51
|
+
large: "large",
|
|
52
|
+
standard: "standard",
|
|
53
|
+
small: "small",
|
|
54
|
+
xsmall: "xsmall"
|
|
55
|
+
};
|
|
56
|
+
const AvatarTextContent = ({ size, children }) => {
|
|
57
|
+
if (size !== "xxlarge") return /* @__PURE__ */ jsx(Text, {
|
|
58
|
+
weight: "strong",
|
|
59
|
+
size: avatarSizeToTextSize[size],
|
|
60
|
+
baseline: false,
|
|
61
|
+
children
|
|
62
|
+
});
|
|
63
|
+
return /* @__PURE__ */ jsx(Heading, {
|
|
64
|
+
level: "3",
|
|
65
|
+
component: "span",
|
|
66
|
+
children
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const letterRegex = /^\p{L}/u;
|
|
70
|
+
const getInitials = (fullName) => {
|
|
71
|
+
for (const character of fullName) if (letterRegex.test(character)) return character.toLocaleUpperCase();
|
|
72
|
+
return null;
|
|
73
|
+
};
|
|
74
|
+
const backgroundColourForName = (name) => {
|
|
75
|
+
let hash = 0;
|
|
76
|
+
for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
77
|
+
return backgroundColours[Math.abs(hash) % backgroundColours.length];
|
|
78
|
+
};
|
|
79
|
+
const assertIconHasNoSize = (icon) => {
|
|
80
|
+
assert(isValidElement(icon) && icon.props.size === void 0, "Icons cannot set the 'size' prop when passed to an Avatar component");
|
|
81
|
+
};
|
|
82
|
+
const isAvatarSize = (value) => value in size;
|
|
83
|
+
const resolveAvatarSize = (size) => isAvatarSize(size) ? size : "standard";
|
|
84
|
+
const Avatar = forwardRef(({ name = "", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, size: sizeProp = "standard", loading = false, imageUrl, icon, onClick, tabIndex, data, ...restProps }, ref) => {
|
|
85
|
+
const size$1 = resolveAvatarSize(sizeProp);
|
|
86
|
+
const focusable = tabIndex != null;
|
|
87
|
+
assert(!onClick || Boolean(ariaLabel), "Avatar with onClick requires aria-label so the button has an accessible name.");
|
|
88
|
+
assert(!focusable || Boolean(ariaLabel), "Avatar with tabIndex requires aria-label so the focusable avatar has an accessible name.");
|
|
89
|
+
if (icon) assertIconHasNoSize(icon);
|
|
90
|
+
const [imageError, setImageError] = useState(false);
|
|
91
|
+
const [imageLoaded, setImageLoaded] = useState(false);
|
|
92
|
+
const [imageSource, setImageSource] = useState(imageUrl);
|
|
93
|
+
const [loadingSource, setLoadingSource] = useState(loading);
|
|
94
|
+
const imageRef = useRef(null);
|
|
95
|
+
if (imageUrl !== imageSource || loading !== loadingSource) {
|
|
96
|
+
setImageSource(imageUrl);
|
|
97
|
+
setLoadingSource(loading);
|
|
98
|
+
setImageError(false);
|
|
99
|
+
setImageLoaded(false);
|
|
100
|
+
}
|
|
101
|
+
useLayoutEffect(() => {
|
|
102
|
+
setImageError(false);
|
|
103
|
+
const img = imageRef.current;
|
|
104
|
+
if (img && rasterDataUriFailedToDecode(img)) {
|
|
105
|
+
setImageError(true);
|
|
106
|
+
setImageLoaded(false);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setImageLoaded(Boolean(img?.complete));
|
|
110
|
+
if (!img || typeof img.decode !== "function" || !/^data:/i.test(img.src) || /^data:image\/svg/i.test(img.src)) return;
|
|
111
|
+
let cancelled = false;
|
|
112
|
+
img.decode().then(() => {
|
|
113
|
+
if (cancelled) return;
|
|
114
|
+
if (rasterDataUriFailedToDecode(img)) setImageError(true);
|
|
115
|
+
}, () => {
|
|
116
|
+
if (!cancelled) setImageError(true);
|
|
117
|
+
});
|
|
118
|
+
return () => {
|
|
119
|
+
cancelled = true;
|
|
120
|
+
};
|
|
121
|
+
}, [imageUrl, loading]);
|
|
122
|
+
const labelled = Boolean(ariaLabel);
|
|
123
|
+
const clickable = Boolean(onClick);
|
|
124
|
+
const borderRadius = avatarSizeToBorderRadius[size$1];
|
|
125
|
+
let a11yProps;
|
|
126
|
+
if (clickable) a11yProps = {
|
|
127
|
+
component: "button",
|
|
128
|
+
type: "button",
|
|
129
|
+
onClick,
|
|
130
|
+
"aria-label": ariaLabel
|
|
131
|
+
};
|
|
132
|
+
else if (labelled) a11yProps = {
|
|
133
|
+
role: "img",
|
|
134
|
+
"aria-label": ariaLabel
|
|
135
|
+
};
|
|
136
|
+
else if (!focusable) a11yProps = { "aria-hidden": true };
|
|
137
|
+
else a11yProps = {};
|
|
138
|
+
let content;
|
|
139
|
+
let colour = null;
|
|
140
|
+
if (loading) content = /* @__PURE__ */ jsx(Skeleton, {});
|
|
141
|
+
else if (imageUrl && imageError) content = /* @__PURE__ */ jsx(AvatarTextContent, {
|
|
142
|
+
size: size$1,
|
|
143
|
+
children: /* @__PURE__ */ jsx(IconImageBroken, {})
|
|
144
|
+
});
|
|
145
|
+
else if (imageUrl) content = /* @__PURE__ */ jsx(Box, {
|
|
146
|
+
component: "img",
|
|
147
|
+
ref: imageRef,
|
|
148
|
+
src: imageUrl,
|
|
149
|
+
alt: "",
|
|
150
|
+
"aria-hidden": true,
|
|
151
|
+
width: "full",
|
|
152
|
+
height: "full",
|
|
153
|
+
className: image,
|
|
154
|
+
opacity: imageLoaded ? void 0 : 0,
|
|
155
|
+
onError: () => setImageError(true),
|
|
156
|
+
onLoad: () => {
|
|
157
|
+
const img = imageRef.current;
|
|
158
|
+
if (img && isEmptyDecodedImage(img) && isNonSvgDataUri(img.src)) {
|
|
159
|
+
setImageError(true);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
setImageLoaded(true);
|
|
163
|
+
}
|
|
164
|
+
}, imageUrl);
|
|
165
|
+
else {
|
|
166
|
+
const resolvedInitials = getInitials(name);
|
|
167
|
+
const showCustomIcon = resolvedInitials === null && Boolean(icon);
|
|
168
|
+
let textContent = resolvedInitials;
|
|
169
|
+
if (showCustomIcon) textContent = icon;
|
|
170
|
+
else if (resolvedInitials === null) textContent = /* @__PURE__ */ jsx(IconProfile, {});
|
|
171
|
+
colour = resolvedInitials && !showCustomIcon ? backgroundColourForName(name) : null;
|
|
172
|
+
content = /* @__PURE__ */ jsx(AvatarTextContent, {
|
|
173
|
+
size: size$1,
|
|
174
|
+
children: textContent
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
178
|
+
ref,
|
|
179
|
+
tabIndex,
|
|
180
|
+
"aria-describedby": ariaDescribedBy,
|
|
181
|
+
position: "relative",
|
|
182
|
+
cursor: clickable ? "pointer" : void 0,
|
|
183
|
+
borderRadius,
|
|
184
|
+
background: colour?.type ?? "neutralLight",
|
|
185
|
+
outline: !clickable && focusable ? "focus" : void 0,
|
|
186
|
+
className: {
|
|
187
|
+
[size[size$1]]: true,
|
|
188
|
+
[keyline]: true,
|
|
189
|
+
[virtualTouchable]: clickable && (size$1 === "xsmall" || size$1 === "small")
|
|
190
|
+
},
|
|
191
|
+
style: colour ? { background: colour.value } : void 0,
|
|
192
|
+
...a11yProps,
|
|
193
|
+
...buildDataAttributes_default({
|
|
194
|
+
data,
|
|
195
|
+
validateRestProps: restProps
|
|
196
|
+
}),
|
|
197
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
198
|
+
display: "flex",
|
|
199
|
+
alignItems: "center",
|
|
200
|
+
justifyContent: "center",
|
|
201
|
+
width: "full",
|
|
202
|
+
height: "full",
|
|
203
|
+
overflow: "hidden",
|
|
204
|
+
borderRadius,
|
|
205
|
+
children: content
|
|
206
|
+
})
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
Avatar.displayName = "Avatar";
|
|
210
|
+
//#endregion
|
|
211
|
+
export { Avatar };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const require_Avatar_css = require("./Avatar.css.cjs");
|
|
2
|
+
const require_Avatar = require("./Avatar.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/lib/components/Avatar/Avatar.playroom.tsx
|
|
6
|
+
const Avatar = (0, react.forwardRef)(({ size: size$1, icon, ...restProps }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Avatar.Avatar, {
|
|
7
|
+
ref,
|
|
8
|
+
...restProps,
|
|
9
|
+
size: size$1 && size$1 in require_Avatar_css.size ? size$1 : void 0,
|
|
10
|
+
icon: typeof icon === "boolean" ? void 0 : icon
|
|
11
|
+
}));
|
|
12
|
+
Avatar.displayName = "Avatar";
|
|
13
|
+
//#endregion
|
|
14
|
+
exports.Avatar = Avatar;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AvatarProps } from "./Avatar.cjs";
|
|
2
|
+
//#region src/lib/components/Avatar/Avatar.playroom.d.ts
|
|
3
|
+
declare const Avatar: import("react").ForwardRefExoticComponent<Omit<AvatarProps, "size" | "icon"> & {
|
|
4
|
+
size?: string;
|
|
5
|
+
icon?: AvatarProps["icon"] | boolean;
|
|
6
|
+
} & import("react").RefAttributes<HTMLElement>>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { Avatar };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AvatarProps } from "./Avatar.mjs";
|
|
2
|
+
//#region src/lib/components/Avatar/Avatar.playroom.d.ts
|
|
3
|
+
declare const Avatar: import("react").ForwardRefExoticComponent<Omit<AvatarProps, "size" | "icon"> & {
|
|
4
|
+
size?: string;
|
|
5
|
+
icon?: AvatarProps["icon"] | boolean;
|
|
6
|
+
} & import("react").RefAttributes<HTMLElement>>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { Avatar };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { size } from "./Avatar.css.mjs";
|
|
2
|
+
import { Avatar as Avatar$1 } from "./Avatar.mjs";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/lib/components/Avatar/Avatar.playroom.tsx
|
|
6
|
+
const Avatar = forwardRef(({ size: size$1, icon, ...restProps }, ref) => /* @__PURE__ */ jsx(Avatar$1, {
|
|
7
|
+
ref,
|
|
8
|
+
...restProps,
|
|
9
|
+
size: size$1 && size$1 in size ? size$1 : void 0,
|
|
10
|
+
icon: typeof icon === "boolean" ? void 0 : icon
|
|
11
|
+
}));
|
|
12
|
+
Avatar.displayName = "Avatar";
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Avatar };
|
|
@@ -2,6 +2,8 @@ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
|
2
2
|
const require_Modal = require("../private/Modal/Modal.cjs");
|
|
3
3
|
let assert = require("assert");
|
|
4
4
|
assert = require_runtime.__toESM(assert, 1);
|
|
5
|
+
let dedent = require("dedent");
|
|
6
|
+
dedent = require_runtime.__toESM(dedent, 1);
|
|
5
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
8
|
//#region src/lib/components/Drawer/Drawer.tsx
|
|
7
9
|
const validWidths = [
|
|
@@ -16,9 +18,33 @@ const modalStyle = {
|
|
|
16
18
|
headingLevel: "2",
|
|
17
19
|
illustration: void 0
|
|
18
20
|
};
|
|
21
|
+
const assertAccessibleName = ({ title, description, "aria-label": ariaLabel, "aria-description": ariaDescription }) => {
|
|
22
|
+
const docsMessage = "See the Drawer documentation for more information: https://seek-oss.github.io/braid-design-system/components/Drawer#title-and-description";
|
|
23
|
+
(0, assert.default)(typeof title === "string" !== (typeof ariaLabel === "string"), dedent.default`
|
|
24
|
+
Drawer requires either a title or an aria-label.
|
|
25
|
+
|
|
26
|
+
${docsMessage}
|
|
27
|
+
`);
|
|
28
|
+
(0, assert.default)(typeof ariaLabel !== "string" || ariaLabel.trim() !== "", dedent.default`
|
|
29
|
+
Drawer aria-label must not be empty.
|
|
30
|
+
|
|
31
|
+
${docsMessage}
|
|
32
|
+
`);
|
|
33
|
+
(0, assert.default)(description === void 0 || typeof title === "string", dedent.default`
|
|
34
|
+
Drawer description can only be used with a title.
|
|
35
|
+
|
|
36
|
+
${docsMessage}
|
|
37
|
+
`);
|
|
38
|
+
(0, assert.default)(ariaDescription === void 0 || typeof ariaLabel === "string", dedent.default`
|
|
39
|
+
Drawer aria-description can only be used with an aria-label.
|
|
40
|
+
|
|
41
|
+
${docsMessage}
|
|
42
|
+
`);
|
|
43
|
+
};
|
|
19
44
|
const Drawer = ({ width = defaultWidth, position = defaultPosition, footer, ...restProps }) => {
|
|
20
45
|
(0, assert.default)(validWidths.indexOf(width) >= 0, `Invalid width: ${width}`);
|
|
21
46
|
(0, assert.default)(validPositions.indexOf(position) >= 0, `Invalid position: ${position}`);
|
|
47
|
+
assertAccessibleName(restProps);
|
|
22
48
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Modal.Modal, {
|
|
23
49
|
width,
|
|
24
50
|
position,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ModalContentProps } from "../private/Modal/ModalContent.cjs";
|
|
2
2
|
import { ModalProps } from "../private/Modal/Modal.cjs";
|
|
3
|
-
import { FC } from "react";
|
|
4
3
|
//#region src/lib/components/Drawer/Drawer.d.ts
|
|
5
4
|
declare const validWidths: readonly ["small", "medium", "large"];
|
|
6
5
|
declare const validPositions: readonly ["left", "right"];
|
|
@@ -8,11 +7,23 @@ declare const modalStyle: {
|
|
|
8
7
|
readonly headingLevel: "2";
|
|
9
8
|
readonly illustration: undefined;
|
|
10
9
|
};
|
|
11
|
-
|
|
10
|
+
type DrawerHeaderProps = {
|
|
11
|
+
title: string;
|
|
12
|
+
description?: ModalContentProps['description'];
|
|
13
|
+
'aria-label'?: never;
|
|
14
|
+
'aria-description'?: never;
|
|
15
|
+
} | {
|
|
16
|
+
title?: never;
|
|
17
|
+
description?: never;
|
|
18
|
+
'aria-label': string;
|
|
19
|
+
'aria-description'?: string;
|
|
20
|
+
};
|
|
21
|
+
type DrawerModalOmittedKeys = keyof typeof modalStyle | 'width' | 'position' | 'coverImage' | 'title' | 'description' | 'aria-label' | 'aria-description';
|
|
22
|
+
type DrawerProps = Omit<ModalProps, DrawerModalOmittedKeys> & DrawerHeaderProps & {
|
|
12
23
|
width?: (typeof validWidths)[number];
|
|
13
24
|
position?: (typeof validPositions)[number];
|
|
14
25
|
footer?: ModalContentProps['footer'];
|
|
15
|
-
}
|
|
16
|
-
declare const Drawer:
|
|
26
|
+
};
|
|
27
|
+
declare const Drawer: ({ width, position, footer, ...restProps }: DrawerProps) => import("react").JSX.Element;
|
|
17
28
|
//#endregion
|
|
18
29
|
export { Drawer, DrawerProps };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ModalContentProps } from "../private/Modal/ModalContent.mjs";
|
|
2
2
|
import { ModalProps } from "../private/Modal/Modal.mjs";
|
|
3
|
-
import { FC } from "react";
|
|
4
3
|
//#region src/lib/components/Drawer/Drawer.d.ts
|
|
5
4
|
declare const validWidths: readonly ["small", "medium", "large"];
|
|
6
5
|
declare const validPositions: readonly ["left", "right"];
|
|
@@ -8,11 +7,23 @@ declare const modalStyle: {
|
|
|
8
7
|
readonly headingLevel: "2";
|
|
9
8
|
readonly illustration: undefined;
|
|
10
9
|
};
|
|
11
|
-
|
|
10
|
+
type DrawerHeaderProps = {
|
|
11
|
+
title: string;
|
|
12
|
+
description?: ModalContentProps['description'];
|
|
13
|
+
'aria-label'?: never;
|
|
14
|
+
'aria-description'?: never;
|
|
15
|
+
} | {
|
|
16
|
+
title?: never;
|
|
17
|
+
description?: never;
|
|
18
|
+
'aria-label': string;
|
|
19
|
+
'aria-description'?: string;
|
|
20
|
+
};
|
|
21
|
+
type DrawerModalOmittedKeys = keyof typeof modalStyle | 'width' | 'position' | 'coverImage' | 'title' | 'description' | 'aria-label' | 'aria-description';
|
|
22
|
+
type DrawerProps = Omit<ModalProps, DrawerModalOmittedKeys> & DrawerHeaderProps & {
|
|
12
23
|
width?: (typeof validWidths)[number];
|
|
13
24
|
position?: (typeof validPositions)[number];
|
|
14
25
|
footer?: ModalContentProps['footer'];
|
|
15
|
-
}
|
|
16
|
-
declare const Drawer:
|
|
26
|
+
};
|
|
27
|
+
declare const Drawer: ({ width, position, footer, ...restProps }: DrawerProps) => import("react").JSX.Element;
|
|
17
28
|
//#endregion
|
|
18
29
|
export { Drawer, DrawerProps };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AllowCloseContext, Modal } from "../private/Modal/Modal.mjs";
|
|
2
2
|
import assert from "assert";
|
|
3
|
+
import dedent from "dedent";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
//#region src/lib/components/Drawer/Drawer.tsx
|
|
5
6
|
const validWidths = [
|
|
@@ -14,9 +15,33 @@ const modalStyle = {
|
|
|
14
15
|
headingLevel: "2",
|
|
15
16
|
illustration: void 0
|
|
16
17
|
};
|
|
18
|
+
const assertAccessibleName = ({ title, description, "aria-label": ariaLabel, "aria-description": ariaDescription }) => {
|
|
19
|
+
const docsMessage = "See the Drawer documentation for more information: https://seek-oss.github.io/braid-design-system/components/Drawer#title-and-description";
|
|
20
|
+
assert(typeof title === "string" !== (typeof ariaLabel === "string"), dedent`
|
|
21
|
+
Drawer requires either a title or an aria-label.
|
|
22
|
+
|
|
23
|
+
${docsMessage}
|
|
24
|
+
`);
|
|
25
|
+
assert(typeof ariaLabel !== "string" || ariaLabel.trim() !== "", dedent`
|
|
26
|
+
Drawer aria-label must not be empty.
|
|
27
|
+
|
|
28
|
+
${docsMessage}
|
|
29
|
+
`);
|
|
30
|
+
assert(description === void 0 || typeof title === "string", dedent`
|
|
31
|
+
Drawer description can only be used with a title.
|
|
32
|
+
|
|
33
|
+
${docsMessage}
|
|
34
|
+
`);
|
|
35
|
+
assert(ariaDescription === void 0 || typeof ariaLabel === "string", dedent`
|
|
36
|
+
Drawer aria-description can only be used with an aria-label.
|
|
37
|
+
|
|
38
|
+
${docsMessage}
|
|
39
|
+
`);
|
|
40
|
+
};
|
|
17
41
|
const Drawer = ({ width = defaultWidth, position = defaultPosition, footer, ...restProps }) => {
|
|
18
42
|
assert(validWidths.indexOf(width) >= 0, `Invalid width: ${width}`);
|
|
19
43
|
assert(validPositions.indexOf(position) >= 0, `Invalid position: ${position}`);
|
|
44
|
+
assertAccessibleName(restProps);
|
|
20
45
|
return /* @__PURE__ */ jsx(Modal, {
|
|
21
46
|
width,
|
|
22
47
|
position,
|
|
@@ -18,7 +18,8 @@ const Heading = ({ level, weight, component, ...typographyProps }) => /* @__PURE
|
|
|
18
18
|
require_typography_css.fontFamily,
|
|
19
19
|
require_typography_css.headingWeight[weight || "regular"],
|
|
20
20
|
require_typography_css.heading[level],
|
|
21
|
-
require_typography_css.tone.neutral
|
|
21
|
+
require_typography_css.tone.neutral,
|
|
22
|
+
require_typography_css.headingSubSupScript
|
|
22
23
|
]
|
|
23
24
|
})
|
|
24
25
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fontFamily, heading, headingWeight, tone } from "../../css/typography.css.mjs";
|
|
1
|
+
import { fontFamily, heading, headingSubSupScript, headingWeight, tone } from "../../css/typography.css.mjs";
|
|
2
2
|
import { Typography } from "../private/Typography/Typography.mjs";
|
|
3
3
|
import HeadingContext_default from "./HeadingContext.mjs";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -18,7 +18,8 @@ const Heading = ({ level, weight, component, ...typographyProps }) => /* @__PURE
|
|
|
18
18
|
fontFamily,
|
|
19
19
|
headingWeight[weight || "regular"],
|
|
20
20
|
heading[level],
|
|
21
|
-
tone.neutral
|
|
21
|
+
tone.neutral,
|
|
22
|
+
headingSubSupScript
|
|
22
23
|
]
|
|
23
24
|
})
|
|
24
25
|
});
|
|
@@ -68,6 +68,21 @@ const List = ({ children, size: sizeProp, tone: toneProp, space: spaceProp, type
|
|
|
68
68
|
data,
|
|
69
69
|
children: react.Children.map(listItems, (listItem, index) => {
|
|
70
70
|
const resolvedIndex = index + (start - 1);
|
|
71
|
+
let indicator;
|
|
72
|
+
if (type === "number") indicator = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, {
|
|
73
|
+
length: lastNumberLength,
|
|
74
|
+
children: resolvedIndex + 1
|
|
75
|
+
});
|
|
76
|
+
else if (type === "alpha") indicator = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, { children: numberToAlpha(resolvedIndex + 1) });
|
|
77
|
+
else if (type === "roman") indicator = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, {
|
|
78
|
+
length: 2,
|
|
79
|
+
children: numberToRomanNumerals(resolvedIndex + 1)
|
|
80
|
+
});
|
|
81
|
+
else if (type === "icon" && "icon" in restProps) indicator = restProps.icon;
|
|
82
|
+
else indicator = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
83
|
+
borderRadius: "full",
|
|
84
|
+
className: [require_List_css.currentColor, require_List_css.size[size$1]]
|
|
85
|
+
});
|
|
71
86
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Box.Box, {
|
|
72
87
|
component: "li",
|
|
73
88
|
display: "flex",
|
|
@@ -81,22 +96,7 @@ const List = ({ children, size: sizeProp, tone: toneProp, space: spaceProp, type
|
|
|
81
96
|
className: require_lineHeightContainer_css.lineHeightContainer[size$1],
|
|
82
97
|
userSelect: "none",
|
|
83
98
|
"aria-hidden": true,
|
|
84
|
-
children:
|
|
85
|
-
if (type === "number") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, {
|
|
86
|
-
length: lastNumberLength,
|
|
87
|
-
children: resolvedIndex + 1
|
|
88
|
-
});
|
|
89
|
-
if (type === "alpha") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, { children: numberToAlpha(resolvedIndex + 1) });
|
|
90
|
-
if (type === "roman") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CharacterBullet, {
|
|
91
|
-
length: 2,
|
|
92
|
-
children: numberToRomanNumerals(resolvedIndex + 1)
|
|
93
|
-
});
|
|
94
|
-
if (type === "icon" && "icon" in restProps) return restProps.icon;
|
|
95
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
96
|
-
borderRadius: "full",
|
|
97
|
-
className: [require_List_css.currentColor, require_List_css.size[size$1]]
|
|
98
|
-
});
|
|
99
|
-
})()
|
|
99
|
+
children: indicator
|
|
100
100
|
})
|
|
101
101
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
102
102
|
minWidth: 0,
|
|
@@ -68,6 +68,21 @@ const List = ({ children, size: sizeProp, tone: toneProp, space: spaceProp, type
|
|
|
68
68
|
data,
|
|
69
69
|
children: Children.map(listItems, (listItem, index) => {
|
|
70
70
|
const resolvedIndex = index + (start - 1);
|
|
71
|
+
let indicator;
|
|
72
|
+
if (type === "number") indicator = /* @__PURE__ */ jsx(CharacterBullet, {
|
|
73
|
+
length: lastNumberLength,
|
|
74
|
+
children: resolvedIndex + 1
|
|
75
|
+
});
|
|
76
|
+
else if (type === "alpha") indicator = /* @__PURE__ */ jsx(CharacterBullet, { children: numberToAlpha(resolvedIndex + 1) });
|
|
77
|
+
else if (type === "roman") indicator = /* @__PURE__ */ jsx(CharacterBullet, {
|
|
78
|
+
length: 2,
|
|
79
|
+
children: numberToRomanNumerals(resolvedIndex + 1)
|
|
80
|
+
});
|
|
81
|
+
else if (type === "icon" && "icon" in restProps) indicator = restProps.icon;
|
|
82
|
+
else indicator = /* @__PURE__ */ jsx(Box, {
|
|
83
|
+
borderRadius: "full",
|
|
84
|
+
className: [currentColor, size[size$1]]
|
|
85
|
+
});
|
|
71
86
|
return /* @__PURE__ */ jsxs(Box, {
|
|
72
87
|
component: "li",
|
|
73
88
|
display: "flex",
|
|
@@ -81,22 +96,7 @@ const List = ({ children, size: sizeProp, tone: toneProp, space: spaceProp, type
|
|
|
81
96
|
className: lineHeightContainer[size$1],
|
|
82
97
|
userSelect: "none",
|
|
83
98
|
"aria-hidden": true,
|
|
84
|
-
children:
|
|
85
|
-
if (type === "number") return /* @__PURE__ */ jsx(CharacterBullet, {
|
|
86
|
-
length: lastNumberLength,
|
|
87
|
-
children: resolvedIndex + 1
|
|
88
|
-
});
|
|
89
|
-
if (type === "alpha") return /* @__PURE__ */ jsx(CharacterBullet, { children: numberToAlpha(resolvedIndex + 1) });
|
|
90
|
-
if (type === "roman") return /* @__PURE__ */ jsx(CharacterBullet, {
|
|
91
|
-
length: 2,
|
|
92
|
-
children: numberToRomanNumerals(resolvedIndex + 1)
|
|
93
|
-
});
|
|
94
|
-
if (type === "icon" && "icon" in restProps) return restProps.icon;
|
|
95
|
-
return /* @__PURE__ */ jsx(Box, {
|
|
96
|
-
borderRadius: "full",
|
|
97
|
-
className: [currentColor, size[size$1]]
|
|
98
|
-
});
|
|
99
|
-
})()
|
|
99
|
+
children: indicator
|
|
100
100
|
})
|
|
101
101
|
}), /* @__PURE__ */ jsx(Box, {
|
|
102
102
|
minWidth: 0,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
const require_Box = require("../Box/Box.cjs");
|
|
3
|
-
require("../private/iconSlotSpace.cjs");
|
|
3
|
+
const require_iconSlotSpace = require("../private/iconSlotSpace.cjs");
|
|
4
4
|
const require_Text = require("../Text/Text.cjs");
|
|
5
5
|
const require_IconContainer = require("../icons/IconContainer.cjs");
|
|
6
|
+
const require_TextLink = require("../TextLink/TextLink.cjs");
|
|
6
7
|
const require_IconRatingEmptySvg = require("../icons/IconRating/IconRatingEmptySvg.cjs");
|
|
7
8
|
const require_IconRatingFullSvg = require("../icons/IconRating/IconRatingFullSvg.cjs");
|
|
8
9
|
const require_IconRatingHalfSvg = require("../icons/IconRating/IconRatingHalfSvg.cjs");
|
|
@@ -27,8 +28,10 @@ const RatingStar = ({ percent, ...restProps }) => {
|
|
|
27
28
|
});
|
|
28
29
|
};
|
|
29
30
|
const ratingArr = [...Array(5)];
|
|
30
|
-
const Rating = ({ rating, size = "standard", weight, variant = "full", tone = "brandAccent", "aria-label": ariaLabel, data }) => {
|
|
31
|
+
const Rating = ({ rating, size = "standard", weight, variant = "full", tone = "brandAccent", "aria-label": ariaLabel, data, reviewText, reviewLink, onClick }) => {
|
|
31
32
|
(0, assert.default)(!rating || rating >= 0 && rating <= 5, "Rating must be between 0 and 5");
|
|
33
|
+
(0, assert.default)(!reviewLink || typeof reviewText === "string", "reviewText must be set when reviewLink is provided");
|
|
34
|
+
(0, assert.default)(!onClick || reviewLink, "reviewLink must be set when onClick is provided");
|
|
32
35
|
if (process.env.NODE_ENV !== "production") {
|
|
33
36
|
if (typeof weight !== "undefined" && variant === "starsOnly") console.warn(dedent.default`
|
|
34
37
|
The "weight" prop is not valid with the "starsOnly" variant as there is no visible text. Either remove the \`weight\` prop or choose an alternative \`variant\`.
|
|
@@ -38,28 +41,53 @@ const Rating = ({ rating, size = "standard", weight, variant = "full", tone = "b
|
|
|
38
41
|
/>
|
|
39
42
|
`, "color: red", "color: inherit");
|
|
40
43
|
}
|
|
41
|
-
|
|
44
|
+
const stars = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
45
|
+
component: "span",
|
|
46
|
+
className: require_Rating_css.inlineFlex,
|
|
47
|
+
role: "img",
|
|
48
|
+
"aria-label": ariaLabel || `${rating.toFixed(1)} out of ${ratingArr.length}`,
|
|
49
|
+
children: variant === "minimal" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RatingStar, {
|
|
50
|
+
percent: 100,
|
|
51
|
+
tone: tone === "neutral" ? "neutral" : "brandAccent"
|
|
52
|
+
}) : ratingArr.map((_, position) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RatingStar, {
|
|
53
|
+
percent: getPercent(rating, position),
|
|
54
|
+
tone: tone === "neutral" ? "neutral" : "brandAccent"
|
|
55
|
+
}, position))
|
|
56
|
+
});
|
|
57
|
+
const ratingText = variant !== "starsOnly" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
58
|
+
component: "span",
|
|
59
|
+
paddingLeft: require_iconSlotSpace.iconSlotSpace,
|
|
60
|
+
"aria-hidden": true,
|
|
61
|
+
children: rating.toFixed(1)
|
|
62
|
+
}) : null;
|
|
63
|
+
let reviewContent = null;
|
|
64
|
+
if (reviewText) reviewContent = reviewLink ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_TextLink.TextLink, {
|
|
65
|
+
href: reviewLink,
|
|
66
|
+
weight: "weak",
|
|
67
|
+
onClick,
|
|
68
|
+
children: reviewText
|
|
69
|
+
}) : reviewText;
|
|
70
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Text.Text, {
|
|
42
71
|
size,
|
|
43
72
|
data,
|
|
44
73
|
weight,
|
|
45
|
-
children:
|
|
46
|
-
component: "span",
|
|
47
|
-
className: require_Rating_css.inlineFlex,
|
|
48
|
-
role: "img",
|
|
49
|
-
"aria-label": ariaLabel || `${rating.toFixed(1)} out of ${ratingArr.length}`,
|
|
50
|
-
children: variant === "minimal" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RatingStar, {
|
|
51
|
-
percent: 100,
|
|
52
|
-
tone: tone === "neutral" ? "neutral" : "brandAccent"
|
|
53
|
-
}) : ratingArr.map((_, position) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RatingStar, {
|
|
54
|
-
percent: getPercent(rating, position),
|
|
55
|
-
tone: tone === "neutral" ? "neutral" : "brandAccent"
|
|
56
|
-
}, position))
|
|
57
|
-
}), variant !== "starsOnly" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
74
|
+
children: reviewContent ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
58
75
|
component: "span",
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
76
|
+
className: require_Rating_css.clip,
|
|
77
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Box.Box, {
|
|
78
|
+
component: "span",
|
|
79
|
+
className: require_Rating_css.row,
|
|
80
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Box.Box, {
|
|
81
|
+
component: "span",
|
|
82
|
+
className: require_Rating_css.group,
|
|
83
|
+
children: [stars, ratingText]
|
|
84
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
85
|
+
component: "span",
|
|
86
|
+
className: require_Rating_css.reviews,
|
|
87
|
+
children: reviewContent
|
|
88
|
+
})]
|
|
89
|
+
})
|
|
90
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [stars, ratingText] })
|
|
63
91
|
});
|
|
64
92
|
};
|
|
65
93
|
//#endregion
|