braid-design-system 34.1.0 → 34.2.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 +58 -0
- package/dist/color-mode/query-param.d.cts +1 -1
- package/dist/color-mode/query-param.d.mts +1 -1
- package/dist/css.cjs +3 -2
- package/dist/css.d.cts +4 -0
- package/dist/css.d.mts +4 -0
- package/dist/css.mjs +3 -2
- package/dist/lib/components/Badge/Badge.cjs +3 -1
- package/dist/lib/components/Badge/Badge.d.cts +2 -0
- package/dist/lib/components/Badge/Badge.d.mts +2 -0
- package/dist/lib/components/Badge/Badge.mjs +3 -1
- package/dist/lib/components/Drawer/Drawer.d.cts +1 -1
- package/dist/lib/components/Drawer/Drawer.d.mts +1 -1
- package/dist/lib/components/MenuRenderer/MenuRenderer.cjs +1 -1
- package/dist/lib/components/MenuRenderer/MenuRenderer.mjs +1 -1
- package/dist/lib/components/private/Modal/Modal.css.cjs +20 -3
- package/dist/lib/components/private/Modal/Modal.css.mjs +18 -5
- package/dist/lib/components/private/Modal/ModalContent.cjs +131 -67
- package/dist/lib/components/private/Modal/ModalContent.d.cts +9 -3
- package/dist/lib/components/private/Modal/ModalContent.d.mts +9 -3
- package/dist/lib/components/private/Modal/ModalContent.mjs +134 -70
- package/dist/lib/components/private/ScrollContainer/ScrollContainer.cjs +25 -6
- package/dist/lib/components/private/ScrollContainer/ScrollContainer.css.cjs +14 -6
- package/dist/lib/components/private/ScrollContainer/ScrollContainer.css.mjs +15 -7
- package/dist/lib/components/private/ScrollContainer/ScrollContainer.mjs +25 -6
- package/dist/lib/components/private/scrollbars.css.cjs +27 -0
- package/dist/lib/components/private/scrollbars.css.mjs +26 -0
- package/dist/lib/playroom/snippets/BrandedContainer.cjs +16 -0
- package/dist/lib/playroom/snippets/BrandedContainer.mjs +15 -0
- package/dist/lib/playroom/snippets/CardList.cjs +10 -0
- package/dist/lib/playroom/snippets/CardList.mjs +9 -0
- package/dist/lib/playroom/snippets/CompactPage.cjs +10 -0
- package/dist/lib/playroom/snippets/CompactPage.mjs +9 -0
- package/dist/lib/playroom/snippets/DividedList.cjs +10 -0
- package/dist/lib/playroom/snippets/DividedList.mjs +9 -0
- package/dist/lib/playroom/snippets/Form.cjs +14 -0
- package/dist/lib/playroom/snippets/Form.mjs +13 -0
- package/dist/lib/playroom/snippets/SpaciousPage.cjs +10 -0
- package/dist/lib/playroom/snippets/SpaciousPage.mjs +9 -0
- package/dist/lib/playroom/snippets/StandardPage.cjs +10 -0
- package/dist/lib/playroom/snippets/StandardPage.mjs +9 -0
- package/dist/lib/playroom/snippets/StandardSection.cjs +10 -0
- package/dist/lib/playroom/snippets/StandardSection.mjs +9 -0
- package/dist/lib/playroom/snippets/SteppedSection.cjs +10 -0
- package/dist/lib/playroom/snippets/SteppedSection.mjs +9 -0
- package/dist/lib/playroom/snippets/TabbedSection.cjs +10 -0
- package/dist/lib/playroom/snippets/TabbedSection.mjs +9 -0
- package/dist/lib/playroom/snippets/TableSection.cjs +10 -0
- package/dist/lib/playroom/snippets/TableSection.mjs +9 -0
- package/dist/lib/playroom/snippets.cjs +22 -4
- package/dist/lib/playroom/snippets.mjs +108 -90
- package/dist/lib/themes/baseTokens/nvl.cjs +1 -1
- package/dist/lib/themes/baseTokens/nvl.mjs +1 -1
- package/package.json +3 -4
- package/dist/lib/playroom/snippets/layouts.cjs +0 -22
- package/dist/lib/playroom/snippets/layouts.mjs +0 -21
- package/dist/lib/playroom/snippets/sections.cjs +0 -59
- package/dist/lib/playroom/snippets/sections.mjs +0 -58
|
@@ -4,7 +4,7 @@ import { BoxProps } from "../../Box/Box.cjs";
|
|
|
4
4
|
import { ReactNode, Ref } from "react";
|
|
5
5
|
|
|
6
6
|
//#region src/lib/components/private/Modal/ModalContent.d.ts
|
|
7
|
-
|
|
7
|
+
type ModalContentCommonProps = {
|
|
8
8
|
id?: string;
|
|
9
9
|
title: string;
|
|
10
10
|
children: ReactNode;
|
|
@@ -12,13 +12,19 @@ interface ModalContentProps {
|
|
|
12
12
|
closeLabel?: string;
|
|
13
13
|
width: BoxProps['maxWidth'] | 'content';
|
|
14
14
|
description?: ReactNodeNoStrings;
|
|
15
|
-
illustration?: ReactNodeNoStrings;
|
|
16
15
|
position: 'center' | 'right' | 'left';
|
|
17
16
|
headingLevel: '2' | '3';
|
|
18
17
|
scrollLock?: boolean;
|
|
19
18
|
headingRef?: Ref<HTMLElement>;
|
|
20
19
|
modalRef?: Ref<HTMLElement>;
|
|
21
20
|
data?: DataAttributeMap;
|
|
22
|
-
}
|
|
21
|
+
};
|
|
22
|
+
type ModalContentProps = ModalContentCommonProps & ({
|
|
23
|
+
coverImage?: never;
|
|
24
|
+
illustration?: ReactNodeNoStrings;
|
|
25
|
+
} | {
|
|
26
|
+
coverImage?: string;
|
|
27
|
+
illustration?: never;
|
|
28
|
+
});
|
|
23
29
|
//#endregion
|
|
24
30
|
export { ModalContentProps };
|
|
@@ -3,7 +3,7 @@ import { DataAttributeMap } from "../buildDataAttributes.mjs";
|
|
|
3
3
|
import { BoxProps } from "../../Box/Box.mjs";
|
|
4
4
|
import { ReactNode, Ref } from "react";
|
|
5
5
|
//#region src/lib/components/private/Modal/ModalContent.d.ts
|
|
6
|
-
|
|
6
|
+
type ModalContentCommonProps = {
|
|
7
7
|
id?: string;
|
|
8
8
|
title: string;
|
|
9
9
|
children: ReactNode;
|
|
@@ -11,13 +11,19 @@ interface ModalContentProps {
|
|
|
11
11
|
closeLabel?: string;
|
|
12
12
|
width: BoxProps['maxWidth'] | 'content';
|
|
13
13
|
description?: ReactNodeNoStrings;
|
|
14
|
-
illustration?: ReactNodeNoStrings;
|
|
15
14
|
position: 'center' | 'right' | 'left';
|
|
16
15
|
headingLevel: '2' | '3';
|
|
17
16
|
scrollLock?: boolean;
|
|
18
17
|
headingRef?: Ref<HTMLElement>;
|
|
19
18
|
modalRef?: Ref<HTMLElement>;
|
|
20
19
|
data?: DataAttributeMap;
|
|
21
|
-
}
|
|
20
|
+
};
|
|
21
|
+
type ModalContentProps = ModalContentCommonProps & ({
|
|
22
|
+
coverImage?: never;
|
|
23
|
+
illustration?: ReactNodeNoStrings;
|
|
24
|
+
} | {
|
|
25
|
+
coverImage?: string;
|
|
26
|
+
illustration?: never;
|
|
27
|
+
});
|
|
22
28
|
//#endregion
|
|
23
29
|
export { ModalContentProps };
|
|
@@ -3,14 +3,18 @@ import { Box } from "../../Box/Box.mjs";
|
|
|
3
3
|
import { Stack } from "../../Stack/Stack.mjs";
|
|
4
4
|
import { useFallbackId } from "../../../hooks/useFallbackId.mjs";
|
|
5
5
|
import { IconClear } from "../../icons/IconClear/IconClear.mjs";
|
|
6
|
+
import { Column } from "../../Column/Column.mjs";
|
|
7
|
+
import { Columns } from "../../Columns/Columns.mjs";
|
|
6
8
|
import { Bleed } from "../../Bleed/Bleed.mjs";
|
|
7
9
|
import { ButtonIcon } from "../../ButtonIcon/ButtonIcon.mjs";
|
|
8
10
|
import { normalizeKey } from "../normalizeKey.mjs";
|
|
9
11
|
import { Heading } from "../../Heading/Heading.mjs";
|
|
10
12
|
import { pageBlockGutters } from "../../PageBlock/pageBlockGutters.mjs";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
13
|
+
import { ScrollContainer } from "../ScrollContainer/ScrollContainer.mjs";
|
|
14
|
+
import { closeIconOffset, coverImage, coverImageHeightLimit, coverImageVar, headingRoot, hideOverflowAboveMobile, maxSize, pointerEventsAll } from "./Modal.css.mjs";
|
|
15
|
+
import { forwardRef, useId, useRef } from "react";
|
|
16
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
17
|
+
import { assignInlineVars } from "@vanilla-extract/dynamic";
|
|
14
18
|
import { RemoveScroll } from "react-remove-scroll";
|
|
15
19
|
|
|
16
20
|
//#region src/lib/components/private/Modal/ModalContent.tsx
|
|
@@ -18,48 +22,130 @@ const modalPadding = {
|
|
|
18
22
|
mobile: "gutter",
|
|
19
23
|
tablet: "large"
|
|
20
24
|
};
|
|
21
|
-
const ModalContentHeader = forwardRef(({ title, headingLevel, description, descriptionId,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const ModalContentHeader = forwardRef(({ title, headingLevel, description, descriptionId, illustration, reserveCloseArea }, ref) => {
|
|
26
|
+
const header = /* @__PURE__ */ jsxs(Stack, {
|
|
27
|
+
space: headingLevel === "2" ? {
|
|
28
|
+
mobile: "small",
|
|
29
|
+
tablet: "medium"
|
|
30
|
+
} : "small",
|
|
31
|
+
children: [/* @__PURE__ */ jsx(Heading, {
|
|
32
|
+
level: headingLevel,
|
|
33
|
+
align: illustration ? "center" : void 0,
|
|
34
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
35
|
+
ref,
|
|
36
|
+
tabIndex: -1,
|
|
37
|
+
component: "span",
|
|
38
|
+
position: "relative",
|
|
39
|
+
outline: "focus",
|
|
40
|
+
borderRadius: "small",
|
|
41
|
+
className: headingRoot,
|
|
42
|
+
children: title
|
|
43
|
+
})
|
|
44
|
+
}), description ? /* @__PURE__ */ jsx(Box, {
|
|
45
|
+
id: descriptionId,
|
|
46
|
+
children: description
|
|
47
|
+
}) : null]
|
|
48
|
+
});
|
|
49
|
+
const resolvedLayout = illustration ? /* @__PURE__ */ jsxs(Stack, {
|
|
50
|
+
space: "medium",
|
|
51
|
+
align: "center",
|
|
52
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
53
|
+
paddingX: "gutter",
|
|
54
|
+
children: illustration
|
|
55
|
+
}), header]
|
|
56
|
+
}) : header;
|
|
57
|
+
return reserveCloseArea && !illustration ? /* @__PURE__ */ jsxs(Box, {
|
|
58
|
+
display: "flex",
|
|
59
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
60
|
+
width: "full",
|
|
61
|
+
minWidth: 0,
|
|
62
|
+
children: resolvedLayout
|
|
63
|
+
}), /* @__PURE__ */ jsx(Box, {
|
|
64
|
+
width: "touchable",
|
|
65
|
+
flexShrink: 0,
|
|
66
|
+
flexGrow: 0
|
|
67
|
+
})]
|
|
68
|
+
}) : resolvedLayout;
|
|
69
|
+
});
|
|
70
|
+
const ModalContentScrollLayout = ({ children, applyCoverImageHeightLimit, contentStartRef, coverImageEnabled, applyPageBlockGutters, applyFullHeight }) => /* @__PURE__ */ jsxs(ScrollContainer, {
|
|
71
|
+
direction: "vertical",
|
|
72
|
+
children: [coverImageEnabled && /* @__PURE__ */ jsx("span", { ref: contentStartRef }), /* @__PURE__ */ jsx(Box, {
|
|
73
|
+
className: applyCoverImageHeightLimit ? coverImageHeightLimit : void 0,
|
|
74
|
+
height: applyFullHeight ? "full" : void 0,
|
|
29
75
|
children: /* @__PURE__ */ jsx(Box, {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
76
|
+
display: "flex",
|
|
77
|
+
gap: "large",
|
|
78
|
+
flexDirection: "column",
|
|
79
|
+
height: applyFullHeight ? "full" : void 0,
|
|
80
|
+
paddingY: modalPadding,
|
|
81
|
+
paddingX: applyPageBlockGutters ? pageBlockGutters : modalPadding,
|
|
82
|
+
children
|
|
83
|
+
})
|
|
84
|
+
})]
|
|
85
|
+
});
|
|
86
|
+
const ModalCoverImageLayout = ({ width, image, children }) => {
|
|
87
|
+
const forceStack = width === "xsmall";
|
|
88
|
+
const coverImage$1 = /* @__PURE__ */ jsx(Box, {
|
|
89
|
+
position: "relative",
|
|
90
|
+
height: "full",
|
|
91
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
92
|
+
position: { tablet: forceStack ? void 0 : "absolute" },
|
|
93
|
+
inset: 0,
|
|
94
|
+
className: coverImage,
|
|
95
|
+
width: "full",
|
|
96
|
+
height: "full",
|
|
97
|
+
style: assignInlineVars({ [coverImageVar]: `url(${image})` })
|
|
38
98
|
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
|
|
99
|
+
});
|
|
100
|
+
return forceStack ? /* @__PURE__ */ jsxs(Stack, {
|
|
101
|
+
space: "none",
|
|
102
|
+
children: [coverImage$1, /* @__PURE__ */ jsx(Fragment$1, { children })]
|
|
103
|
+
}) : /* @__PURE__ */ jsxs(Columns, {
|
|
104
|
+
space: "none",
|
|
105
|
+
collapseBelow: "tablet",
|
|
106
|
+
reverse: true,
|
|
107
|
+
children: [/* @__PURE__ */ jsx(Column, { children: coverImage$1 }), /* @__PURE__ */ jsx(Column, { children })]
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
const ModalContent = ({ id, children, description, onClose, width, closeLabel = "Close", illustration, coverImage, title, headingRef: headingRefProp, modalRef: modalRefProp, scrollLock = true, position, headingLevel, data, ...restProps }) => {
|
|
45
111
|
const resolvedId = useFallbackId(id);
|
|
46
112
|
const descriptionId = useId();
|
|
47
113
|
const defaultModalRef = useRef(null);
|
|
48
114
|
const modalRef = modalRefProp || defaultModalRef;
|
|
49
115
|
const defaultHeadingRef = useRef(null);
|
|
50
116
|
const headingRef = headingRefProp || defaultHeadingRef;
|
|
117
|
+
const contentStartRef = useRef(null);
|
|
51
118
|
const handleEscape = (event) => {
|
|
52
119
|
if (normalizeKey(event) === "Escape") {
|
|
53
120
|
event.stopPropagation();
|
|
54
121
|
onClose();
|
|
55
122
|
}
|
|
56
123
|
};
|
|
124
|
+
const isDrawer = position === "left" || position === "right";
|
|
125
|
+
const coverImageEnabled = Boolean(coverImage) && !isDrawer;
|
|
126
|
+
const allowColumnLayout = coverImageEnabled && width !== "xsmall";
|
|
57
127
|
const justifyContent = {
|
|
58
128
|
left: "flexStart",
|
|
59
129
|
center: "center",
|
|
60
130
|
right: "flexEnd"
|
|
61
131
|
}[position];
|
|
62
|
-
const modalRadius =
|
|
132
|
+
const modalRadius = !isDrawer ? "xlarge" : void 0;
|
|
133
|
+
const modalLayout = /* @__PURE__ */ jsxs(ModalContentScrollLayout, {
|
|
134
|
+
applyCoverImageHeightLimit: allowColumnLayout,
|
|
135
|
+
applyPageBlockGutters: isDrawer,
|
|
136
|
+
applyFullHeight: isDrawer,
|
|
137
|
+
contentStartRef,
|
|
138
|
+
coverImageEnabled,
|
|
139
|
+
children: [/* @__PURE__ */ jsx(ModalContentHeader, {
|
|
140
|
+
title,
|
|
141
|
+
headingLevel,
|
|
142
|
+
description,
|
|
143
|
+
descriptionId,
|
|
144
|
+
illustration: illustration && !coverImageEnabled ? illustration : void 0,
|
|
145
|
+
ref: headingRef,
|
|
146
|
+
reserveCloseArea: true
|
|
147
|
+
}), children]
|
|
148
|
+
});
|
|
63
149
|
return /* @__PURE__ */ jsx(Box, {
|
|
64
150
|
role: "dialog",
|
|
65
151
|
"aria-label": title,
|
|
@@ -69,7 +155,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
69
155
|
onKeyDown: handleEscape,
|
|
70
156
|
position: "relative",
|
|
71
157
|
width: "full",
|
|
72
|
-
height: "full",
|
|
158
|
+
height: isDrawer ? "full" : void 0,
|
|
73
159
|
display: "flex",
|
|
74
160
|
alignItems: "center",
|
|
75
161
|
textAlign: "left",
|
|
@@ -80,8 +166,8 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
80
166
|
display: "flex",
|
|
81
167
|
alignItems: "center",
|
|
82
168
|
justifyContent,
|
|
83
|
-
height:
|
|
84
|
-
overflow:
|
|
169
|
+
height: isDrawer ? "full" : void 0,
|
|
170
|
+
overflow: "hidden",
|
|
85
171
|
boxShadow: "large",
|
|
86
172
|
borderRadius: modalRadius,
|
|
87
173
|
width: width !== "content" ? "full" : void 0,
|
|
@@ -90,7 +176,7 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
90
176
|
noRelative: true,
|
|
91
177
|
forwardProps: true,
|
|
92
178
|
enabled: scrollLock,
|
|
93
|
-
children: /* @__PURE__ */
|
|
179
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
94
180
|
display: "flex",
|
|
95
181
|
gap: "large",
|
|
96
182
|
flexDirection: "column",
|
|
@@ -99,47 +185,25 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
99
185
|
overflow: "auto",
|
|
100
186
|
position: "relative",
|
|
101
187
|
width: width !== "content" ? "full" : void 0,
|
|
102
|
-
height:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
188
|
+
height: isDrawer ? "full" : void 0,
|
|
189
|
+
className: {
|
|
190
|
+
[pointerEventsAll]: true,
|
|
191
|
+
[maxSize[position]]: !isDrawer,
|
|
192
|
+
[hideOverflowAboveMobile]: allowColumnLayout
|
|
193
|
+
},
|
|
106
194
|
...buildDataAttributes_default({
|
|
107
195
|
data,
|
|
108
196
|
validateRestProps: restProps
|
|
109
197
|
}),
|
|
110
|
-
children:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
children:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
description,
|
|
120
|
-
descriptionId,
|
|
121
|
-
center: Boolean(illustration),
|
|
122
|
-
ref: headingRef
|
|
123
|
-
})]
|
|
124
|
-
}) : /* @__PURE__ */ jsxs(Box, {
|
|
125
|
-
display: "flex",
|
|
126
|
-
children: [/* @__PURE__ */ jsx(Box, {
|
|
127
|
-
width: "full",
|
|
128
|
-
minWidth: 0,
|
|
129
|
-
children: /* @__PURE__ */ jsx(ModalContentHeader, {
|
|
130
|
-
title,
|
|
131
|
-
headingLevel,
|
|
132
|
-
description,
|
|
133
|
-
descriptionId,
|
|
134
|
-
center: Boolean(illustration),
|
|
135
|
-
ref: headingRef
|
|
136
|
-
})
|
|
137
|
-
}), /* @__PURE__ */ jsx(Box, {
|
|
138
|
-
width: "touchable",
|
|
139
|
-
flexShrink: 0,
|
|
140
|
-
flexGrow: 0
|
|
141
|
-
})]
|
|
142
|
-
}), /* @__PURE__ */ jsx(Fragment, { children })]
|
|
198
|
+
children: /* @__PURE__ */ jsx(ScrollContainer, {
|
|
199
|
+
direction: "vertical",
|
|
200
|
+
startRef: contentStartRef,
|
|
201
|
+
children: coverImageEnabled && coverImage ? /* @__PURE__ */ jsx(ModalCoverImageLayout, {
|
|
202
|
+
width,
|
|
203
|
+
image: coverImage,
|
|
204
|
+
children: modalLayout
|
|
205
|
+
}) : modalLayout
|
|
206
|
+
})
|
|
143
207
|
})
|
|
144
208
|
}), /* @__PURE__ */ jsx(Box, {
|
|
145
209
|
position: "absolute",
|
|
@@ -150,10 +214,11 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
150
214
|
display: "flex",
|
|
151
215
|
justifyContent: "flexEnd",
|
|
152
216
|
paddingTop: modalPadding,
|
|
153
|
-
paddingRight:
|
|
154
|
-
className:
|
|
217
|
+
paddingRight: isDrawer ? pageBlockGutters : modalPadding,
|
|
218
|
+
className: !isDrawer && maxSize[position],
|
|
155
219
|
children: /* @__PURE__ */ jsx(Bleed, {
|
|
156
220
|
space: "xsmall",
|
|
221
|
+
horizontal: "xxsmall",
|
|
157
222
|
children: /* @__PURE__ */ jsx(Box, {
|
|
158
223
|
position: "relative",
|
|
159
224
|
background: "surface",
|
|
@@ -164,7 +229,6 @@ const ModalContent = ({ id, children, description, onClose, width, closeLabel =
|
|
|
164
229
|
label: closeLabel,
|
|
165
230
|
icon: /* @__PURE__ */ jsx(IconClear, { tone: "secondary" }),
|
|
166
231
|
variant: "transparent",
|
|
167
|
-
size: "large",
|
|
168
232
|
onClick: onClose
|
|
169
233
|
})
|
|
170
234
|
})
|
|
@@ -3,36 +3,55 @@ const require_buildDataAttributes = require('../buildDataAttributes.cjs');
|
|
|
3
3
|
const require_Box = require('../../Box/Box.cjs');
|
|
4
4
|
const require_useIsomorphicLayoutEffect = require('../../../hooks/useIsomorphicLayoutEffect.cjs');
|
|
5
5
|
const require_ScrollContainer_css = require('./ScrollContainer.css.cjs');
|
|
6
|
+
const require_scrollbars_css = require('../scrollbars.css.cjs');
|
|
6
7
|
let react = require("react");
|
|
7
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
9
|
let throttle_debounce = require("throttle-debounce");
|
|
9
10
|
|
|
10
11
|
//#region src/lib/components/private/ScrollContainer/ScrollContainer.tsx
|
|
11
12
|
const scrollOffset = 2;
|
|
12
|
-
const maskOverflow = (element, direction) => setTimeout(() => {
|
|
13
|
+
const maskOverflow = ({ element, direction, gateStart }) => setTimeout(() => {
|
|
13
14
|
const atTop = element.scrollTop <= 0;
|
|
14
15
|
const atBottom = element.scrollHeight - element.offsetHeight - element.scrollTop < scrollOffset;
|
|
15
16
|
const atLeft = element.scrollLeft <= 0;
|
|
16
17
|
const atRight = element.scrollWidth - element.offsetWidth - element.scrollLeft < scrollOffset;
|
|
17
18
|
if (direction === "vertical" || direction === "all") {
|
|
18
|
-
element.classList[atTop ? "remove" : "add"](require_ScrollContainer_css.maskTop);
|
|
19
|
+
element.classList[atTop || gateStart ? "remove" : "add"](require_ScrollContainer_css.maskTop);
|
|
19
20
|
element.classList[atBottom ? "remove" : "add"](require_ScrollContainer_css.maskBottom);
|
|
20
21
|
}
|
|
21
22
|
if (direction === "horizontal" || direction === "all") {
|
|
22
|
-
element.classList[atLeft ? "remove" : "add"](require_ScrollContainer_css.maskLeft);
|
|
23
|
+
element.classList[atLeft || gateStart ? "remove" : "add"](require_ScrollContainer_css.maskLeft);
|
|
23
24
|
element.classList[atRight ? "remove" : "add"](require_ScrollContainer_css.maskRight);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
|
-
const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fadeSize: fadeSize$1 = "medium", hideScrollbar: hideScrollbar$1 = false, data, ...restProps }) => {
|
|
27
|
+
const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fadeSize: fadeSize$1 = "medium", hideScrollbar: hideScrollbar$1 = false, startRef, data, ...restProps }) => {
|
|
27
28
|
const containerRef = (0, react.useRef)(null);
|
|
29
|
+
const gateStartRef = (0, react.useRef)(Boolean(startRef?.current));
|
|
28
30
|
const updateMask = (0, throttle_debounce.throttle)(100, (0, react.useCallback)(() => {
|
|
29
|
-
if (containerRef.current) maskOverflow(
|
|
31
|
+
if (containerRef.current) maskOverflow({
|
|
32
|
+
element: containerRef.current,
|
|
33
|
+
direction: direction$1,
|
|
34
|
+
gateStart: gateStartRef.current
|
|
35
|
+
});
|
|
30
36
|
}, [containerRef, direction$1]));
|
|
31
37
|
require_useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
32
38
|
if (containerRef.current) updateMask();
|
|
33
39
|
window.addEventListener("resize", updateMask);
|
|
34
40
|
return () => window.removeEventListener("resize", updateMask);
|
|
35
41
|
}, [updateMask]);
|
|
42
|
+
require_useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
43
|
+
if (!startRef?.current || !containerRef.current) return;
|
|
44
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
45
|
+
if (!entry.rootBounds) return;
|
|
46
|
+
gateStartRef.current = !(direction$1 === "horizontal" || direction$1 === "all" ? entry.boundingClientRect.left < entry.rootBounds.left : entry.boundingClientRect.top < entry.rootBounds.top);
|
|
47
|
+
updateMask();
|
|
48
|
+
}, {
|
|
49
|
+
root: containerRef.current,
|
|
50
|
+
threshold: [0, 1]
|
|
51
|
+
});
|
|
52
|
+
observer.observe(startRef.current);
|
|
53
|
+
return () => observer.disconnect();
|
|
54
|
+
}, [startRef, updateMask]);
|
|
36
55
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
|
|
37
56
|
ref: containerRef,
|
|
38
57
|
onScroll: updateMask,
|
|
@@ -41,7 +60,7 @@ const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fade
|
|
|
41
60
|
className: [
|
|
42
61
|
require_ScrollContainer_css.container,
|
|
43
62
|
require_ScrollContainer_css.mask,
|
|
44
|
-
hideScrollbar$1 ? require_ScrollContainer_css.hideScrollbar :
|
|
63
|
+
hideScrollbar$1 ? require_ScrollContainer_css.hideScrollbar : require_scrollbars_css.scrollbars,
|
|
45
64
|
require_ScrollContainer_css.fadeSize[fadeSize$1],
|
|
46
65
|
require_ScrollContainer_css.direction[direction$1]
|
|
47
66
|
],
|
|
@@ -39,12 +39,20 @@ const left = (0, _vanilla_extract_css.createVar)("left");
|
|
|
39
39
|
const right = (0, _vanilla_extract_css.createVar)("right");
|
|
40
40
|
const top = (0, _vanilla_extract_css.createVar)("top");
|
|
41
41
|
const bottom = (0, _vanilla_extract_css.createVar)("bottom");
|
|
42
|
-
const mask = (0, _vanilla_extract_css.style)({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
]
|
|
42
|
+
const mask = (0, _vanilla_extract_css.style)({
|
|
43
|
+
vars: {
|
|
44
|
+
[left]: "0",
|
|
45
|
+
[right]: "0",
|
|
46
|
+
[top]: "0",
|
|
47
|
+
[bottom]: "0"
|
|
48
|
+
},
|
|
49
|
+
maskImage: [
|
|
50
|
+
`linear-gradient(to bottom, transparent 0, black ${top})`,
|
|
51
|
+
`linear-gradient(to right, transparent 0, black ${left})`,
|
|
52
|
+
`linear-gradient(to left, transparent 0, black ${right})`,
|
|
53
|
+
`linear-gradient(to top, transparent 0, black ${bottom})`
|
|
54
|
+
].join(",")
|
|
55
|
+
}, "mask");
|
|
48
56
|
const maskLeft = (0, _vanilla_extract_css.style)({ vars: { [left]: scrollOverlaySize } }, "maskLeft");
|
|
49
57
|
const maskRight = (0, _vanilla_extract_css.style)({ vars: { [right]: scrollOverlaySize } }, "maskRight");
|
|
50
58
|
const maskTop = (0, _vanilla_extract_css.style)({ vars: { [top]: scrollOverlaySize } }, "maskTop");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
|
|
2
|
-
import { createVar,
|
|
2
|
+
import { createVar, style, styleVariants } from "@vanilla-extract/css";
|
|
3
3
|
|
|
4
4
|
//#region src/lib/components/private/ScrollContainer/ScrollContainer.css.ts
|
|
5
5
|
setFileScope("src/lib/components/private/ScrollContainer/ScrollContainer.css.ts", "braid-design-system");
|
|
@@ -38,12 +38,20 @@ const left = createVar("left");
|
|
|
38
38
|
const right = createVar("right");
|
|
39
39
|
const top = createVar("top");
|
|
40
40
|
const bottom = createVar("bottom");
|
|
41
|
-
const mask = style({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
]
|
|
41
|
+
const mask = style({
|
|
42
|
+
vars: {
|
|
43
|
+
[left]: "0",
|
|
44
|
+
[right]: "0",
|
|
45
|
+
[top]: "0",
|
|
46
|
+
[bottom]: "0"
|
|
47
|
+
},
|
|
48
|
+
maskImage: [
|
|
49
|
+
`linear-gradient(to bottom, transparent 0, black ${top})`,
|
|
50
|
+
`linear-gradient(to right, transparent 0, black ${left})`,
|
|
51
|
+
`linear-gradient(to left, transparent 0, black ${right})`,
|
|
52
|
+
`linear-gradient(to top, transparent 0, black ${bottom})`
|
|
53
|
+
].join(",")
|
|
54
|
+
}, "mask");
|
|
47
55
|
const maskLeft = style({ vars: { [left]: scrollOverlaySize } }, "maskLeft");
|
|
48
56
|
const maskRight = style({ vars: { [right]: scrollOverlaySize } }, "maskRight");
|
|
49
57
|
const maskTop = style({ vars: { [top]: scrollOverlaySize } }, "maskTop");
|
|
@@ -2,36 +2,55 @@ import buildDataAttributes_default from "../buildDataAttributes.mjs";
|
|
|
2
2
|
import { Box } from "../../Box/Box.mjs";
|
|
3
3
|
import { useIsomorphicLayoutEffect } from "../../../hooks/useIsomorphicLayoutEffect.mjs";
|
|
4
4
|
import { container, direction, fadeSize, hideScrollbar, mask, maskBottom, maskLeft, maskRight, maskTop } from "./ScrollContainer.css.mjs";
|
|
5
|
+
import { scrollbars } from "../scrollbars.css.mjs";
|
|
5
6
|
import { useCallback, useRef } from "react";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
7
8
|
import { throttle } from "throttle-debounce";
|
|
8
9
|
|
|
9
10
|
//#region src/lib/components/private/ScrollContainer/ScrollContainer.tsx
|
|
10
11
|
const scrollOffset = 2;
|
|
11
|
-
const maskOverflow = (element, direction) => setTimeout(() => {
|
|
12
|
+
const maskOverflow = ({ element, direction, gateStart }) => setTimeout(() => {
|
|
12
13
|
const atTop = element.scrollTop <= 0;
|
|
13
14
|
const atBottom = element.scrollHeight - element.offsetHeight - element.scrollTop < scrollOffset;
|
|
14
15
|
const atLeft = element.scrollLeft <= 0;
|
|
15
16
|
const atRight = element.scrollWidth - element.offsetWidth - element.scrollLeft < scrollOffset;
|
|
16
17
|
if (direction === "vertical" || direction === "all") {
|
|
17
|
-
element.classList[atTop ? "remove" : "add"](maskTop);
|
|
18
|
+
element.classList[atTop || gateStart ? "remove" : "add"](maskTop);
|
|
18
19
|
element.classList[atBottom ? "remove" : "add"](maskBottom);
|
|
19
20
|
}
|
|
20
21
|
if (direction === "horizontal" || direction === "all") {
|
|
21
|
-
element.classList[atLeft ? "remove" : "add"](maskLeft);
|
|
22
|
+
element.classList[atLeft || gateStart ? "remove" : "add"](maskLeft);
|
|
22
23
|
element.classList[atRight ? "remove" : "add"](maskRight);
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
|
-
const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fadeSize: fadeSize$1 = "medium", hideScrollbar: hideScrollbar$1 = false, data, ...restProps }) => {
|
|
26
|
+
const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fadeSize: fadeSize$1 = "medium", hideScrollbar: hideScrollbar$1 = false, startRef, data, ...restProps }) => {
|
|
26
27
|
const containerRef = useRef(null);
|
|
28
|
+
const gateStartRef = useRef(Boolean(startRef?.current));
|
|
27
29
|
const updateMask = throttle(100, useCallback(() => {
|
|
28
|
-
if (containerRef.current) maskOverflow(
|
|
30
|
+
if (containerRef.current) maskOverflow({
|
|
31
|
+
element: containerRef.current,
|
|
32
|
+
direction: direction$1,
|
|
33
|
+
gateStart: gateStartRef.current
|
|
34
|
+
});
|
|
29
35
|
}, [containerRef, direction$1]));
|
|
30
36
|
useIsomorphicLayoutEffect(() => {
|
|
31
37
|
if (containerRef.current) updateMask();
|
|
32
38
|
window.addEventListener("resize", updateMask);
|
|
33
39
|
return () => window.removeEventListener("resize", updateMask);
|
|
34
40
|
}, [updateMask]);
|
|
41
|
+
useIsomorphicLayoutEffect(() => {
|
|
42
|
+
if (!startRef?.current || !containerRef.current) return;
|
|
43
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
44
|
+
if (!entry.rootBounds) return;
|
|
45
|
+
gateStartRef.current = !(direction$1 === "horizontal" || direction$1 === "all" ? entry.boundingClientRect.left < entry.rootBounds.left : entry.boundingClientRect.top < entry.rootBounds.top);
|
|
46
|
+
updateMask();
|
|
47
|
+
}, {
|
|
48
|
+
root: containerRef.current,
|
|
49
|
+
threshold: [0, 1]
|
|
50
|
+
});
|
|
51
|
+
observer.observe(startRef.current);
|
|
52
|
+
return () => observer.disconnect();
|
|
53
|
+
}, [startRef, updateMask]);
|
|
35
54
|
return /* @__PURE__ */ jsx(Box, {
|
|
36
55
|
ref: containerRef,
|
|
37
56
|
onScroll: updateMask,
|
|
@@ -40,7 +59,7 @@ const ScrollContainer = ({ children, direction: direction$1 = "horizontal", fade
|
|
|
40
59
|
className: [
|
|
41
60
|
container,
|
|
42
61
|
mask,
|
|
43
|
-
hideScrollbar$1 ? hideScrollbar :
|
|
62
|
+
hideScrollbar$1 ? hideScrollbar : scrollbars,
|
|
44
63
|
fadeSize[fadeSize$1],
|
|
45
64
|
direction[direction$1]
|
|
46
65
|
],
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_colorModeStyle = require('../../css/colorModeStyle.cjs');
|
|
3
|
+
let _vanilla_extract_css_fileScope = require("@vanilla-extract/css/fileScope");
|
|
4
|
+
let _vanilla_extract_css = require("@vanilla-extract/css");
|
|
5
|
+
|
|
6
|
+
//#region src/lib/components/private/scrollbars.css.ts
|
|
7
|
+
(0, _vanilla_extract_css_fileScope.setFileScope)("src/lib/components/private/scrollbars.css.ts", "braid-design-system");
|
|
8
|
+
const thumbColor = (0, _vanilla_extract_css.createVar)("thumbColor");
|
|
9
|
+
const trackColor = "transparent";
|
|
10
|
+
const scrollbars = (0, _vanilla_extract_css.style)([require_colorModeStyle.colorModeStyle({
|
|
11
|
+
lightMode: { vars: { [thumbColor]: "rgba(0 0 0 / 0.4)" } },
|
|
12
|
+
darkMode: { vars: { [thumbColor]: "rgba(255 255 255 / 0.4)" } }
|
|
13
|
+
}), {
|
|
14
|
+
scrollbarColor: `${thumbColor} ${trackColor}`,
|
|
15
|
+
"@supports": { "not (scrollbar-color: auto)": { selectors: {
|
|
16
|
+
"&::-webkit-scrollbar": {
|
|
17
|
+
background: trackColor,
|
|
18
|
+
width: 8,
|
|
19
|
+
height: 8
|
|
20
|
+
},
|
|
21
|
+
"&::-webkit-scrollbar-thumb": { background: thumbColor }
|
|
22
|
+
} } }
|
|
23
|
+
}], "scrollbars");
|
|
24
|
+
(0, _vanilla_extract_css_fileScope.endFileScope)();
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
exports.scrollbars = scrollbars;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { colorModeStyle } from "../../css/colorModeStyle.mjs";
|
|
2
|
+
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
|
|
3
|
+
import { createVar, style } from "@vanilla-extract/css";
|
|
4
|
+
|
|
5
|
+
//#region src/lib/components/private/scrollbars.css.ts
|
|
6
|
+
setFileScope("src/lib/components/private/scrollbars.css.ts", "braid-design-system");
|
|
7
|
+
const thumbColor = createVar("thumbColor");
|
|
8
|
+
const trackColor = "transparent";
|
|
9
|
+
const scrollbars = style([colorModeStyle({
|
|
10
|
+
lightMode: { vars: { [thumbColor]: "rgba(0 0 0 / 0.4)" } },
|
|
11
|
+
darkMode: { vars: { [thumbColor]: "rgba(255 255 255 / 0.4)" } }
|
|
12
|
+
}), {
|
|
13
|
+
scrollbarColor: `${thumbColor} ${trackColor}`,
|
|
14
|
+
"@supports": { "not (scrollbar-color: auto)": { selectors: {
|
|
15
|
+
"&::-webkit-scrollbar": {
|
|
16
|
+
background: trackColor,
|
|
17
|
+
width: 8,
|
|
18
|
+
height: 8
|
|
19
|
+
},
|
|
20
|
+
"&::-webkit-scrollbar-thumb": { background: thumbColor }
|
|
21
|
+
} } }
|
|
22
|
+
}], "scrollbars");
|
|
23
|
+
endFileScope();
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { scrollbars };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/lib/playroom/snippets/BrandedContainer.ts
|
|
3
|
+
const snippets = [{
|
|
4
|
+
group: "Sections",
|
|
5
|
+
name: "Branded container",
|
|
6
|
+
description: "Full bleed",
|
|
7
|
+
code: "<Box background=\"brand\" paddingY=\"xlarge\">\n <PageBlock width=\"medium\">\n <Stack space=\"large\">\n <Heading level=\"2\">Heading</Heading>\n\n <Text>\n Combines a <Strong>Heading level 2</Strong> with a{\" \"}\n <Strong>large Stack</Strong> spacing content groups within the section.\n <br />\n Uses a <Strong>PageBlock</Strong> inside the section to maintain screen\n gutters on small screens.\n </Text>\n\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. In convallis\n cursus quam nec volutpat. In hac habitasse platea dictumst. Praesent\n egestas erat id mollis imperdiet. Vestibulum non commodo nisi, sed\n tempus magna. Duis a malesuada diam.\n </Text>\n </Stack>\n </PageBlock>\n</Box>"
|
|
8
|
+
}, {
|
|
9
|
+
group: "Sections",
|
|
10
|
+
name: "Branded container",
|
|
11
|
+
description: "Rounded from desktop (full bleed below)",
|
|
12
|
+
code: "<Box paddingX={{ desktop: \"gutter\" }}>\n <ContentBlock width=\"large\">\n <Box\n background=\"brand\"\n paddingY=\"xlarge\"\n borderRadius={{ desktop: \"xlarge\" }}\n >\n <PageBlock width=\"medium\">\n <Stack space=\"large\">\n <Heading level=\"2\">Heading</Heading>\n\n <Text>\n Combines a <Strong>Heading level 2</Strong> with a{\" \"}\n <Strong>large Stack</Strong> spacing content groups within the\n section.\n <br />\n Uses a <Strong>PageBlock</Strong> inside the section to maintain\n screen gutters on small screens.\n </Text>\n\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. In\n convallis cursus quam nec volutpat. In hac habitasse platea\n dictumst. Praesent egestas erat id mollis imperdiet. Vestibulum non\n commodo nisi, sed tempus magna. Duis a malesuada diam.\n </Text>\n </Stack>\n </PageBlock>\n </Box>\n </ContentBlock>\n</Box>"
|
|
13
|
+
}];
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.snippets = snippets;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/lib/playroom/snippets/BrandedContainer.ts
|
|
2
|
+
const snippets = [{
|
|
3
|
+
group: "Sections",
|
|
4
|
+
name: "Branded container",
|
|
5
|
+
description: "Full bleed",
|
|
6
|
+
code: "<Box background=\"brand\" paddingY=\"xlarge\">\n <PageBlock width=\"medium\">\n <Stack space=\"large\">\n <Heading level=\"2\">Heading</Heading>\n\n <Text>\n Combines a <Strong>Heading level 2</Strong> with a{\" \"}\n <Strong>large Stack</Strong> spacing content groups within the section.\n <br />\n Uses a <Strong>PageBlock</Strong> inside the section to maintain screen\n gutters on small screens.\n </Text>\n\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. In convallis\n cursus quam nec volutpat. In hac habitasse platea dictumst. Praesent\n egestas erat id mollis imperdiet. Vestibulum non commodo nisi, sed\n tempus magna. Duis a malesuada diam.\n </Text>\n </Stack>\n </PageBlock>\n</Box>"
|
|
7
|
+
}, {
|
|
8
|
+
group: "Sections",
|
|
9
|
+
name: "Branded container",
|
|
10
|
+
description: "Rounded from desktop (full bleed below)",
|
|
11
|
+
code: "<Box paddingX={{ desktop: \"gutter\" }}>\n <ContentBlock width=\"large\">\n <Box\n background=\"brand\"\n paddingY=\"xlarge\"\n borderRadius={{ desktop: \"xlarge\" }}\n >\n <PageBlock width=\"medium\">\n <Stack space=\"large\">\n <Heading level=\"2\">Heading</Heading>\n\n <Text>\n Combines a <Strong>Heading level 2</Strong> with a{\" \"}\n <Strong>large Stack</Strong> spacing content groups within the\n section.\n <br />\n Uses a <Strong>PageBlock</Strong> inside the section to maintain\n screen gutters on small screens.\n </Text>\n\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. In\n convallis cursus quam nec volutpat. In hac habitasse platea\n dictumst. Praesent egestas erat id mollis imperdiet. Vestibulum non\n commodo nisi, sed tempus magna. Duis a malesuada diam.\n </Text>\n </Stack>\n </PageBlock>\n </Box>\n </ContentBlock>\n</Box>"
|
|
12
|
+
}];
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { snippets };
|