@salt-ds/core 1.53.0 → 1.54.1
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 +42 -0
- package/css/salt-core.css +47 -45
- package/dist-cjs/avatar/Avatar.css.js +1 -1
- package/dist-cjs/badge/Badge.css.js +1 -1
- package/dist-cjs/collapsible/CollapsibleTrigger.js +3 -2
- package/dist-cjs/collapsible/CollapsibleTrigger.js.map +1 -1
- package/dist-cjs/combo-box/ComboBox.js +2 -1
- package/dist-cjs/combo-box/ComboBox.js.map +1 -1
- package/dist-cjs/index.js +2 -0
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/list-control/ListControlState.js +108 -87
- package/dist-cjs/list-control/ListControlState.js.map +1 -1
- package/dist-cjs/menu/MenuBase.js +5 -2
- package/dist-cjs/menu/MenuBase.js.map +1 -1
- package/dist-cjs/menu/MenuContext.js +3 -1
- package/dist-cjs/menu/MenuContext.js.map +1 -1
- package/dist-cjs/menu/MenuItem.js +5 -0
- package/dist-cjs/menu/MenuItem.js.map +1 -1
- package/dist-cjs/menu/MenuTrigger.js +3 -2
- package/dist-cjs/menu/MenuTrigger.js.map +1 -1
- package/dist-cjs/multiline-input/MultilineInput.js +2 -1
- package/dist-cjs/multiline-input/MultilineInput.js.map +1 -1
- package/dist-cjs/number-input/NumberInput.js +7 -7
- package/dist-cjs/number-input/NumberInput.js.map +1 -1
- package/dist-cjs/number-input/internal/useLongPressPointerAction.js +63 -0
- package/dist-cjs/number-input/internal/useLongPressPointerAction.js.map +1 -0
- package/dist-cjs/overlay/OverlayTrigger.js +2 -2
- package/dist-cjs/overlay/OverlayTrigger.js.map +1 -1
- package/dist-cjs/pill/Pill.js +72 -9
- package/dist-cjs/pill/Pill.js.map +1 -1
- package/dist-cjs/pill/PillCheckIcon.css.js +6 -0
- package/dist-cjs/pill/PillCheckIcon.css.js.map +1 -0
- package/dist-cjs/pill/PillCheckIcon.js +48 -0
- package/dist-cjs/pill/PillCheckIcon.js.map +1 -0
- package/dist-cjs/pill/PillGroup.css.js +6 -0
- package/dist-cjs/pill/PillGroup.css.js.map +1 -0
- package/dist-cjs/pill/PillGroup.js +83 -0
- package/dist-cjs/pill/PillGroup.js.map +1 -0
- package/dist-cjs/pill/PillGroupContext.js +27 -0
- package/dist-cjs/pill/PillGroupContext.js.map +1 -0
- package/dist-cjs/pill-input/PillInput.js +1 -0
- package/dist-cjs/pill-input/PillInput.js.map +1 -1
- package/dist-cjs/salt-provider/ProviderContext.js +11 -0
- package/dist-cjs/salt-provider/ProviderContext.js.map +1 -0
- package/dist-cjs/salt-provider/SaltProvider.js +24 -132
- package/dist-cjs/salt-provider/SaltProvider.js.map +1 -1
- package/dist-cjs/salt-provider/ThemeApplicator.js +115 -0
- package/dist-cjs/salt-provider/ThemeApplicator.js.map +1 -0
- package/dist-cjs/slider/internal/useRangeSliderThumb.js +14 -5
- package/dist-cjs/slider/internal/useRangeSliderThumb.js.map +1 -1
- package/dist-cjs/slider/internal/useSliderThumb.js +14 -5
- package/dist-cjs/slider/internal/useSliderThumb.js.map +1 -1
- package/dist-cjs/tag/Tag.css.js +1 -1
- package/dist-cjs/toggle-button/ToggleButton.css.js +1 -1
- package/dist-es/avatar/Avatar.css.js +1 -1
- package/dist-es/badge/Badge.css.js +1 -1
- package/dist-es/collapsible/CollapsibleTrigger.js +3 -2
- package/dist-es/collapsible/CollapsibleTrigger.js.map +1 -1
- package/dist-es/combo-box/ComboBox.js +3 -2
- package/dist-es/combo-box/ComboBox.js.map +1 -1
- package/dist-es/index.js +1 -0
- package/dist-es/index.js.map +1 -1
- package/dist-es/list-control/ListControlState.js +108 -87
- package/dist-es/list-control/ListControlState.js.map +1 -1
- package/dist-es/menu/MenuBase.js +5 -2
- package/dist-es/menu/MenuBase.js.map +1 -1
- package/dist-es/menu/MenuContext.js +3 -1
- package/dist-es/menu/MenuContext.js.map +1 -1
- package/dist-es/menu/MenuItem.js +6 -1
- package/dist-es/menu/MenuItem.js.map +1 -1
- package/dist-es/menu/MenuTrigger.js +3 -2
- package/dist-es/menu/MenuTrigger.js.map +1 -1
- package/dist-es/multiline-input/MultilineInput.js +3 -2
- package/dist-es/multiline-input/MultilineInput.js.map +1 -1
- package/dist-es/number-input/NumberInput.js +7 -7
- package/dist-es/number-input/NumberInput.js.map +1 -1
- package/dist-es/number-input/internal/useLongPressPointerAction.js +61 -0
- package/dist-es/number-input/internal/useLongPressPointerAction.js.map +1 -0
- package/dist-es/overlay/OverlayTrigger.js +2 -2
- package/dist-es/overlay/OverlayTrigger.js.map +1 -1
- package/dist-es/pill/Pill.js +74 -11
- package/dist-es/pill/Pill.js.map +1 -1
- package/dist-es/pill/PillCheckIcon.css.js +4 -0
- package/dist-es/pill/PillCheckIcon.css.js.map +1 -0
- package/dist-es/pill/PillCheckIcon.js +46 -0
- package/dist-es/pill/PillCheckIcon.js.map +1 -0
- package/dist-es/pill/PillGroup.css.js +4 -0
- package/dist-es/pill/PillGroup.css.js.map +1 -0
- package/dist-es/pill/PillGroup.js +81 -0
- package/dist-es/pill/PillGroup.js.map +1 -0
- package/dist-es/pill/PillGroupContext.js +24 -0
- package/dist-es/pill/PillGroupContext.js.map +1 -0
- package/dist-es/pill-input/PillInput.js +1 -0
- package/dist-es/pill-input/PillInput.js.map +1 -1
- package/dist-es/salt-provider/ProviderContext.js +9 -0
- package/dist-es/salt-provider/ProviderContext.js.map +1 -0
- package/dist-es/salt-provider/SaltProvider.js +25 -133
- package/dist-es/salt-provider/SaltProvider.js.map +1 -1
- package/dist-es/salt-provider/ThemeApplicator.js +113 -0
- package/dist-es/salt-provider/ThemeApplicator.js.map +1 -0
- package/dist-es/slider/internal/useRangeSliderThumb.js +14 -5
- package/dist-es/slider/internal/useRangeSliderThumb.js.map +1 -1
- package/dist-es/slider/internal/useSliderThumb.js +14 -5
- package/dist-es/slider/internal/useSliderThumb.js.map +1 -1
- package/dist-es/tag/Tag.css.js +1 -1
- package/dist-es/toggle-button/ToggleButton.css.js +1 -1
- package/dist-types/menu/MenuContext.d.ts +2 -0
- package/dist-types/number-input/internal/useLongPressPointerAction.d.ts +2 -0
- package/dist-types/pill/Pill.d.ts +1 -0
- package/dist-types/pill/PillCheckIcon.d.ts +7 -0
- package/dist-types/pill/PillGroup.d.ts +34 -0
- package/dist-types/pill/PillGroupContext.d.ts +9 -0
- package/dist-types/pill/index.d.ts +1 -0
- package/dist-types/salt-provider/ProviderContext.d.ts +5 -0
- package/dist-types/salt-provider/SaltProvider.d.ts +5 -56
- package/dist-types/salt-provider/ThemeApplicator.d.ts +56 -0
- package/package.json +2 -2
- package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js +0 -50
- package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-es/number-input/internal/useActivateWhileMouseDown.js +0 -48
- package/dist-es/number-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-types/number-input/internal/useActivateWhileMouseDown.d.ts +0 -5
|
@@ -9,9 +9,10 @@ require('../aria-announcer/AriaAnnouncerContext.js');
|
|
|
9
9
|
var AriaAnnouncerProvider = require('../aria-announcer/AriaAnnouncerProvider.js');
|
|
10
10
|
var BreakpointProvider = require('../breakpoints/BreakpointProvider.js');
|
|
11
11
|
var Breakpoints = require('../breakpoints/Breakpoints.js');
|
|
12
|
-
var useIsomorphicLayoutEffect = require('../utils/useIsomorphicLayoutEffect.js');
|
|
13
12
|
var ViewportProvider = require('../viewport/ViewportProvider.js');
|
|
13
|
+
var ProviderContext = require('./ProviderContext.js');
|
|
14
14
|
var SaltProvider$1 = require('./SaltProvider.css.js');
|
|
15
|
+
var ThemeApplicator = require('./ThemeApplicator.js');
|
|
15
16
|
|
|
16
17
|
const DEFAULT_DENSITY = "medium";
|
|
17
18
|
const DEFAULT_THEME_NAME = "salt-theme";
|
|
@@ -36,70 +37,6 @@ const ThemeContext = React.createContext({
|
|
|
36
37
|
UNSTABLE_actionFont: DEFAULT_ACTION_FONT
|
|
37
38
|
});
|
|
38
39
|
const BreakpointContext = React.createContext(Breakpoints.DEFAULT_BREAKPOINTS);
|
|
39
|
-
const getThemeNames = (themeName, themeNext) => {
|
|
40
|
-
if (themeNext) {
|
|
41
|
-
return themeName === DEFAULT_THEME_NAME ? clsx.clsx(DEFAULT_THEME_NAME, DEFAULT_THEME_NAME_NEXT) : clsx.clsx(DEFAULT_THEME_NAME, DEFAULT_THEME_NAME_NEXT, themeName);
|
|
42
|
-
}
|
|
43
|
-
return themeName === DEFAULT_THEME_NAME ? themeName : clsx.clsx(DEFAULT_THEME_NAME, themeName);
|
|
44
|
-
};
|
|
45
|
-
const createThemedChildren = ({
|
|
46
|
-
children,
|
|
47
|
-
themeName,
|
|
48
|
-
density,
|
|
49
|
-
mode,
|
|
50
|
-
applyClassesTo,
|
|
51
|
-
themeNext,
|
|
52
|
-
corner,
|
|
53
|
-
headingFont,
|
|
54
|
-
accent,
|
|
55
|
-
actionFont
|
|
56
|
-
}) => {
|
|
57
|
-
var _a;
|
|
58
|
-
const themeNamesString = getThemeNames(themeName, themeNext);
|
|
59
|
-
const themeNextProps = {
|
|
60
|
-
"data-corner": corner,
|
|
61
|
-
"data-heading-font": headingFont,
|
|
62
|
-
"data-accent": accent,
|
|
63
|
-
"data-action-font": actionFont
|
|
64
|
-
};
|
|
65
|
-
if (applyClassesTo === "root") {
|
|
66
|
-
return children;
|
|
67
|
-
}
|
|
68
|
-
if (applyClassesTo === "child") {
|
|
69
|
-
if (React.isValidElement(children)) {
|
|
70
|
-
return React.cloneElement(children, {
|
|
71
|
-
className: clsx.clsx(
|
|
72
|
-
(_a = children.props) == null ? void 0 : _a.className,
|
|
73
|
-
themeNamesString,
|
|
74
|
-
`salt-density-${density}`
|
|
75
|
-
),
|
|
76
|
-
// @ts-expect-error
|
|
77
|
-
"data-mode": mode,
|
|
78
|
-
...themeNext ? themeNextProps : {}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
console.warn(
|
|
82
|
-
`
|
|
83
|
-
SaltProvider can only apply CSS classes for theming to a single nested child element of the SaltProvider.
|
|
84
|
-
Either wrap elements with a single container or consider removing the applyClassesToChild prop, in which case a
|
|
85
|
-
div element will wrap your child elements`
|
|
86
|
-
);
|
|
87
|
-
return children;
|
|
88
|
-
}
|
|
89
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
90
|
-
"div",
|
|
91
|
-
{
|
|
92
|
-
className: clsx.clsx(
|
|
93
|
-
"salt-provider",
|
|
94
|
-
themeNamesString,
|
|
95
|
-
`salt-density-${density}`
|
|
96
|
-
),
|
|
97
|
-
"data-mode": mode,
|
|
98
|
-
...themeNext ? themeNextProps : {},
|
|
99
|
-
children
|
|
100
|
-
}
|
|
101
|
-
);
|
|
102
|
-
};
|
|
103
40
|
function InternalSaltProvider({
|
|
104
41
|
applyClassesTo: applyClassesToProp,
|
|
105
42
|
children,
|
|
@@ -113,26 +50,26 @@ function InternalSaltProvider({
|
|
|
113
50
|
accent: accentProp,
|
|
114
51
|
actionFont: actionFontProp
|
|
115
52
|
}) {
|
|
53
|
+
const prevProvider = React.useContext(ProviderContext.ProviderContext);
|
|
116
54
|
const inheritedDensity = React.useContext(DensityContext);
|
|
117
55
|
const {
|
|
118
56
|
theme: inheritedTheme,
|
|
119
57
|
mode: inheritedMode,
|
|
120
|
-
window: inheritedWindow,
|
|
121
58
|
corner: inheritedCorner,
|
|
122
59
|
headingFont: inheritedHeadingFont,
|
|
123
60
|
accent: inheritedAccent,
|
|
124
61
|
actionFont: inheritedActionFont
|
|
125
62
|
} = React.useContext(ThemeContext);
|
|
126
|
-
const isRootProvider =
|
|
63
|
+
const isRootProvider = prevProvider === null;
|
|
127
64
|
const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;
|
|
128
|
-
const
|
|
65
|
+
const inheritedThemeName = inheritedTheme === "" ? DEFAULT_THEME_NAME : inheritedTheme;
|
|
66
|
+
const themeName = themeProp ?? inheritedThemeName;
|
|
129
67
|
const mode = modeProp ?? inheritedMode;
|
|
130
68
|
const breakpoints = breakpointsProp ?? Breakpoints.DEFAULT_BREAKPOINTS;
|
|
131
69
|
const corner = cornerProp ?? inheritedCorner ?? DEFAULT_CORNER;
|
|
132
70
|
const headingFont = headingFontProp ?? inheritedHeadingFont ?? DEFAULT_HEADING_FONT;
|
|
133
71
|
const accent = accentProp ?? inheritedAccent ?? DEFAULT_ACCENT;
|
|
134
72
|
const actionFont = actionFontProp ?? inheritedActionFont ?? DEFAULT_ACTION_FONT;
|
|
135
|
-
const applyClassesTo = applyClassesToProp ?? (isRootProvider ? "root" : "scope");
|
|
136
73
|
const targetWindow = window.useWindow();
|
|
137
74
|
styles.useComponentCssInjection({
|
|
138
75
|
testId: "salt-provider",
|
|
@@ -166,70 +103,25 @@ function InternalSaltProvider({
|
|
|
166
103
|
actionFont
|
|
167
104
|
]
|
|
168
105
|
);
|
|
169
|
-
const themedChildren = createThemedChildren({
|
|
170
|
-
children,
|
|
171
|
-
themeName,
|
|
172
|
-
density,
|
|
173
|
-
mode,
|
|
174
|
-
applyClassesTo,
|
|
175
|
-
themeNext,
|
|
176
|
-
corner,
|
|
177
|
-
headingFont,
|
|
178
|
-
accent,
|
|
179
|
-
actionFont
|
|
180
|
-
});
|
|
181
|
-
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
182
|
-
const themeNamesString = getThemeNames(themeName, themeNext);
|
|
183
|
-
const themeNames = themeNamesString.split(" ");
|
|
184
|
-
if (applyClassesTo === "root" && targetWindow) {
|
|
185
|
-
if (inheritedWindow !== targetWindow) {
|
|
186
|
-
targetWindow.document.documentElement.classList.add(
|
|
187
|
-
...themeNames,
|
|
188
|
-
`salt-density-${density}`
|
|
189
|
-
);
|
|
190
|
-
targetWindow.document.documentElement.dataset.mode = mode;
|
|
191
|
-
if (themeNext) {
|
|
192
|
-
targetWindow.document.documentElement.dataset.corner = corner;
|
|
193
|
-
targetWindow.document.documentElement.dataset.headingFont = headingFont;
|
|
194
|
-
targetWindow.document.documentElement.dataset.accent = accent;
|
|
195
|
-
targetWindow.document.documentElement.dataset.actionFont = actionFont;
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
console.warn(
|
|
199
|
-
"SaltProvider can only apply CSS classes to the root if it is the root level SaltProvider."
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return () => {
|
|
204
|
-
if (applyClassesTo === "root" && targetWindow) {
|
|
205
|
-
targetWindow.document.documentElement.classList.remove(
|
|
206
|
-
...themeNames,
|
|
207
|
-
`salt-density-${density}`
|
|
208
|
-
);
|
|
209
|
-
targetWindow.document.documentElement.dataset.mode = void 0;
|
|
210
|
-
if (themeNext) {
|
|
211
|
-
delete targetWindow.document.documentElement.dataset.corner;
|
|
212
|
-
delete targetWindow.document.documentElement.dataset.headingFont;
|
|
213
|
-
delete targetWindow.document.documentElement.dataset.accent;
|
|
214
|
-
delete targetWindow.document.documentElement.dataset.actionFont;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
}, [
|
|
219
|
-
applyClassesTo,
|
|
220
|
-
density,
|
|
221
|
-
mode,
|
|
222
|
-
themeName,
|
|
223
|
-
targetWindow,
|
|
224
|
-
inheritedWindow,
|
|
225
|
-
themeNext,
|
|
226
|
-
corner,
|
|
227
|
-
headingFont,
|
|
228
|
-
accent,
|
|
229
|
-
actionFont
|
|
230
|
-
]);
|
|
231
106
|
const matchedBreakpoints = BreakpointProvider.useMatchedBreakpoints(breakpoints);
|
|
232
|
-
const saltProvider = /* @__PURE__ */ jsxRuntime.jsx(DensityContext.Provider, { value: density, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: themeContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(BreakpointProvider.BreakpointProvider, { matchedBreakpoints, children: /* @__PURE__ */ jsxRuntime.jsx(BreakpointContext.Provider, { value: breakpoints, children: /* @__PURE__ */ jsxRuntime.jsx(ViewportProvider.ViewportProvider, { children:
|
|
107
|
+
const saltProvider = /* @__PURE__ */ jsxRuntime.jsx(ProviderContext.ProviderContext.Provider, { value: { targetWindow }, children: /* @__PURE__ */ jsxRuntime.jsx(DensityContext.Provider, { value: density, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: themeContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(BreakpointProvider.BreakpointProvider, { matchedBreakpoints, children: /* @__PURE__ */ jsxRuntime.jsx(BreakpointContext.Provider, { value: breakpoints, children: /* @__PURE__ */ jsxRuntime.jsx(ViewportProvider.ViewportProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
108
|
+
ThemeApplicator.ThemeApplicator,
|
|
109
|
+
{
|
|
110
|
+
applyClassesTo: applyClassesToProp ?? (isRootProvider ? "root" : "scope"),
|
|
111
|
+
density,
|
|
112
|
+
theme: clsx.clsx(
|
|
113
|
+
DEFAULT_THEME_NAME,
|
|
114
|
+
{ [DEFAULT_THEME_NAME_NEXT]: themeNext },
|
|
115
|
+
themeProp
|
|
116
|
+
),
|
|
117
|
+
mode,
|
|
118
|
+
accent: themeNext ? accent : void 0,
|
|
119
|
+
actionFont: themeNext ? actionFont : void 0,
|
|
120
|
+
headingFont: themeNext ? headingFont : void 0,
|
|
121
|
+
corner: themeNext ? corner : void 0,
|
|
122
|
+
children
|
|
123
|
+
}
|
|
124
|
+
) }) }) }) }) }) });
|
|
233
125
|
if (isRootProvider) {
|
|
234
126
|
return /* @__PURE__ */ jsxRuntime.jsx(AriaAnnouncerProvider.AriaAnnouncerProvider, { children: saltProvider });
|
|
235
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaltProvider.js","sources":["../src/salt-provider/SaltProvider.tsx"],"sourcesContent":["import {\n StyleInjectionProvider,\n useComponentCssInjection,\n} from \"@salt-ds/styles\";\nimport { useWindow, type WindowContextType } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n cloneElement,\n createContext,\n type HTMLAttributes,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useContext,\n useMemo,\n} from \"react\";\nimport { AriaAnnouncerProvider } from \"../aria-announcer\";\nimport {\n BreakpointProvider,\n type Breakpoints,\n DEFAULT_BREAKPOINTS,\n useMatchedBreakpoints,\n} from \"../breakpoints\";\nimport type {\n Accent,\n ActionFont,\n Corner,\n Density,\n HeadingFont,\n Mode,\n ThemeName,\n} from \"../theme\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\nimport { ViewportProvider } from \"../viewport\";\nimport saltProviderCss from \"./SaltProvider.css\";\n\nexport const DEFAULT_DENSITY = \"medium\";\n\nconst DEFAULT_THEME_NAME = \"salt-theme\";\nconst DEFAULT_THEME_NAME_NEXT = \"salt-theme-next\";\n\nconst DEFAULT_MODE = \"light\";\nconst DEFAULT_CORNER: Corner = \"sharp\";\nconst DEFAULT_HEADING_FONT: HeadingFont = \"Open Sans\";\nconst DEFAULT_ACCENT: Accent = \"blue\";\nconst DEFAULT_ACTION_FONT: ActionFont = \"Open Sans\";\nexport interface ThemeContextProps {\n theme: ThemeName;\n mode: Mode;\n window?: WindowContextType;\n /** Only available when using SaltProviderNext. */\n themeNext: boolean;\n corner: Corner;\n /** @deprecated use `corner`*/\n UNSTABLE_corner: Corner;\n headingFont: HeadingFont;\n /** @deprecated use `headingFont` */\n UNSTABLE_headingFont: HeadingFont;\n accent: Accent;\n /** @deprecated use `accent` */\n UNSTABLE_accent: Accent;\n actionFont: ActionFont;\n /** @deprecated use `actionFont` */\n UNSTABLE_actionFont: ActionFont;\n}\n\nexport const DensityContext = createContext<Density>(DEFAULT_DENSITY);\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n theme: \"\",\n mode: DEFAULT_MODE,\n themeNext: false,\n corner: DEFAULT_CORNER,\n UNSTABLE_corner: DEFAULT_CORNER,\n headingFont: DEFAULT_HEADING_FONT,\n UNSTABLE_headingFont: DEFAULT_HEADING_FONT,\n accent: DEFAULT_ACCENT,\n UNSTABLE_accent: DEFAULT_ACCENT,\n actionFont: DEFAULT_ACTION_FONT,\n UNSTABLE_actionFont: DEFAULT_ACTION_FONT,\n});\n\nexport const BreakpointContext =\n createContext<Breakpoints>(DEFAULT_BREAKPOINTS);\n\n/**\n * We're relying `DEFAULT_THEME_NAME` to determine whether the provider is a root.\n */\nconst getThemeNames = (\n themeName: ThemeName,\n themeNext?: boolean,\n): ThemeName => {\n if (themeNext) {\n return themeName === DEFAULT_THEME_NAME\n ? clsx(DEFAULT_THEME_NAME, DEFAULT_THEME_NAME_NEXT)\n : clsx(DEFAULT_THEME_NAME, DEFAULT_THEME_NAME_NEXT, themeName);\n }\n return themeName === DEFAULT_THEME_NAME\n ? themeName\n : clsx(DEFAULT_THEME_NAME, themeName);\n};\n\ninterface ThemeNextProps {\n themeNext?: boolean;\n}\n\nconst createThemedChildren = ({\n children,\n themeName,\n density,\n mode,\n applyClassesTo,\n themeNext,\n corner,\n headingFont,\n accent,\n actionFont,\n}: {\n children: ReactNode;\n themeName: ThemeName;\n density: Density;\n mode: Mode;\n applyClassesTo?: TargetElement;\n} & ThemeNextProps &\n SaltProviderNextAdditionalProps) => {\n const themeNamesString = getThemeNames(themeName, themeNext);\n const themeNextProps = {\n \"data-corner\": corner,\n \"data-heading-font\": headingFont,\n \"data-accent\": accent,\n \"data-action-font\": actionFont,\n };\n if (applyClassesTo === \"root\") {\n return children;\n }\n if (applyClassesTo === \"child\") {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: clsx(\n children.props?.className,\n themeNamesString,\n `salt-density-${density}`,\n ),\n // @ts-expect-error\n \"data-mode\": mode,\n ...(themeNext ? themeNextProps : {}),\n });\n }\n console.warn(\n `\\nSaltProvider can only apply CSS classes for theming to a single nested child element of the SaltProvider.\n Either wrap elements with a single container or consider removing the applyClassesToChild prop, in which case a\n div element will wrap your child elements`,\n );\n return children;\n }\n return (\n <div\n className={clsx(\n \"salt-provider\",\n themeNamesString,\n `salt-density-${density}`,\n )}\n data-mode={mode}\n {...(themeNext ? themeNextProps : {})}\n >\n {children}\n </div>\n );\n};\n\ntype TargetElement = \"root\" | \"scope\" | \"child\";\n\ninterface SaltProviderBaseProps {\n /**\n * Either \"root\", \"scope\" or \"child\".\n * Specifies the location of salt theme class and attributes should be applied to.\n *\n * Defaults to \"root\" for a root provider, otherwise \"scope\".\n */\n applyClassesTo?: TargetElement;\n /**\n * Either \"high\", \"medium\", \"low\" or \"touch\".\n * Determines the amount of content that can fit on a screen based on the size and spacing of components.\n * Refer to [density](https://www.saltdesignsystem.com/salt/foundations/density) doc for more detail.\n *\n * @default \"medium\"\n */\n density?: Density;\n /**\n * A string. Specifies custom theme name(s) you want to apply, similar to `className`.\n */\n theme?: ThemeName;\n /**\n * Either \"light\" or \"dark\". Enable the color palette to change from light to dark.\n * Refer to [modes](https://www.saltdesignsystem.com/salt/foundations/modes) doc for more detail.\n *\n * @default \"light\"\n */\n mode?: Mode;\n /**\n * Shape of `{ xs: number; sm: number; md: number; lg: number; xl: number; }`.\n * Determines breakpoints used in responsive calculation for layout components.\n */\n breakpoints?: Breakpoints;\n /**\n * A boolean. Enables dynamic style injection for each component.\n *\n * If `false`, you'll need to include component CSS yourself.\n *\n * @default true\n */\n enableStyleInjection?: boolean;\n}\n\ninterface SaltProviderThatAppliesClassesToChild extends SaltProviderBaseProps {\n children: ReactElement;\n applyClassesTo: \"child\";\n}\n\ninterface SaltProviderThatInjectsThemeElement extends SaltProviderBaseProps {\n children: ReactNode;\n}\n\ninterface SaltProviderThatClassesToRoot\n extends SaltProviderThatInjectsThemeElement {\n applyClassesTo: \"root\";\n}\n\ntype SaltProviderProps =\n | SaltProviderThatAppliesClassesToChild\n | SaltProviderThatInjectsThemeElement\n | SaltProviderThatClassesToRoot;\n\nfunction InternalSaltProvider({\n applyClassesTo: applyClassesToProp,\n children,\n density: densityProp,\n theme: themeProp,\n mode: modeProp,\n breakpoints: breakpointsProp,\n themeNext,\n corner: cornerProp,\n headingFont: headingFontProp,\n accent: accentProp,\n actionFont: actionFontProp,\n}: Omit<\n SaltProviderProps & ThemeNextProps & SaltProviderNextProps,\n \"enableStyleInjection\"\n>) {\n const inheritedDensity = useContext(DensityContext);\n const {\n theme: inheritedTheme,\n mode: inheritedMode,\n window: inheritedWindow,\n corner: inheritedCorner,\n headingFont: inheritedHeadingFont,\n accent: inheritedAccent,\n actionFont: inheritedActionFont,\n } = useContext(ThemeContext);\n\n const isRootProvider = inheritedTheme === undefined || inheritedTheme === \"\";\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const themeName =\n themeProp ?? (inheritedTheme === \"\" ? DEFAULT_THEME_NAME : inheritedTheme);\n const mode = modeProp ?? inheritedMode;\n const breakpoints = breakpointsProp ?? DEFAULT_BREAKPOINTS;\n const corner = cornerProp ?? inheritedCorner ?? DEFAULT_CORNER;\n const headingFont =\n headingFontProp ?? inheritedHeadingFont ?? DEFAULT_HEADING_FONT;\n const accent = accentProp ?? inheritedAccent ?? DEFAULT_ACCENT;\n const actionFont =\n actionFontProp ?? inheritedActionFont ?? DEFAULT_ACTION_FONT;\n\n const applyClassesTo =\n applyClassesToProp ?? (isRootProvider ? \"root\" : \"scope\");\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-provider\",\n css: saltProviderCss,\n window: targetWindow,\n });\n\n const themeContextValue = useMemo(\n () => ({\n theme: themeName,\n mode,\n window: targetWindow,\n themeNext: Boolean(themeNext),\n corner: corner,\n headingFont: headingFont,\n accent: accent,\n actionFont: actionFont,\n // Backward compatibility\n UNSTABLE_corner: corner,\n UNSTABLE_headingFont: headingFont,\n UNSTABLE_accent: accent,\n UNSTABLE_actionFont: actionFont,\n }),\n [\n themeName,\n mode,\n targetWindow,\n themeNext,\n corner,\n headingFont,\n accent,\n actionFont,\n ],\n );\n\n const themedChildren = createThemedChildren({\n children,\n themeName,\n density,\n mode,\n applyClassesTo,\n themeNext,\n corner: corner,\n headingFont,\n accent,\n actionFont,\n });\n\n useIsomorphicLayoutEffect(() => {\n const themeNamesString = getThemeNames(themeName, themeNext);\n const themeNames = themeNamesString.split(\" \");\n\n if (applyClassesTo === \"root\" && targetWindow) {\n if (inheritedWindow !== targetWindow) {\n // add the styles we want to apply\n targetWindow.document.documentElement.classList.add(\n ...themeNames,\n `salt-density-${density}`,\n );\n targetWindow.document.documentElement.dataset.mode = mode;\n if (themeNext) {\n targetWindow.document.documentElement.dataset.corner = corner;\n targetWindow.document.documentElement.dataset.headingFont =\n headingFont;\n targetWindow.document.documentElement.dataset.accent = accent;\n targetWindow.document.documentElement.dataset.actionFont = actionFont;\n }\n } else {\n console.warn(\n \"SaltProvider can only apply CSS classes to the root if it is the root level SaltProvider.\",\n );\n }\n }\n return () => {\n if (applyClassesTo === \"root\" && targetWindow) {\n // When unmounting/remounting, remove the applied styles from the root\n targetWindow.document.documentElement.classList.remove(\n ...themeNames,\n `salt-density-${density}`,\n );\n targetWindow.document.documentElement.dataset.mode = undefined;\n if (themeNext) {\n delete targetWindow.document.documentElement.dataset.corner;\n delete targetWindow.document.documentElement.dataset.headingFont;\n delete targetWindow.document.documentElement.dataset.accent;\n delete targetWindow.document.documentElement.dataset.actionFont;\n }\n }\n };\n }, [\n applyClassesTo,\n density,\n mode,\n themeName,\n targetWindow,\n inheritedWindow,\n themeNext,\n corner,\n headingFont,\n accent,\n actionFont,\n ]);\n\n const matchedBreakpoints = useMatchedBreakpoints(breakpoints);\n\n const saltProvider = (\n <DensityContext.Provider value={density}>\n <ThemeContext.Provider value={themeContextValue}>\n <BreakpointProvider matchedBreakpoints={matchedBreakpoints}>\n <BreakpointContext.Provider value={breakpoints}>\n <ViewportProvider>{themedChildren}</ViewportProvider>\n </BreakpointContext.Provider>\n </BreakpointProvider>\n </ThemeContext.Provider>\n </DensityContext.Provider>\n );\n\n if (isRootProvider) {\n return <AriaAnnouncerProvider>{saltProvider}</AriaAnnouncerProvider>;\n }\n return saltProvider;\n}\n\nexport function SaltProvider({\n enableStyleInjection,\n ...restProps\n}: SaltProviderProps) {\n return (\n <StyleInjectionProvider value={enableStyleInjection}>\n <InternalSaltProvider {...restProps} />\n </StyleInjectionProvider>\n );\n}\n\ninterface SaltProviderNextAdditionalProps {\n /**\n * Either \"sharp\" or \"rounded\".\n * Determines selected components corner radius.\n * @default \"sharp\"\n */\n corner?: Corner;\n /**\n * Either \"Open Sans\" or \"Amplitude\".\n * Determines font family of display and heading text.\n * @default \"Open Sans\"\n */\n headingFont?: HeadingFont;\n /**\n * Either \"blue\" or \"teal\".\n * Determines accent color used across components, e.g. Accent Button, List, Calendar.\n * @default \"blue\"\n */\n accent?: Accent;\n /**\n * Either \"Open Sans\" or \"Amplitude\".\n * Determines font family of action components, mostly Buttons.\n * @default \"Open Sans\"\n */\n actionFont?: ActionFont;\n}\n\nexport type SaltProviderNextProps = SaltProviderProps &\n SaltProviderNextAdditionalProps;\n/** @deprecated use `SaltProviderNextProps` */\nexport type UNSTABLE_SaltProviderNextProps = SaltProviderNextProps;\n\nexport function SaltProviderNext({\n enableStyleInjection,\n ...restProps\n}: SaltProviderNextProps) {\n return (\n <StyleInjectionProvider value={enableStyleInjection}>\n {/* Leveraging InternalSaltProvider being not exported, so we can pass more props than previously supported */}\n <InternalSaltProvider {...restProps} themeNext={true} />\n </StyleInjectionProvider>\n );\n}\n/** @deprecated use `SaltProviderNext` */\nexport const UNSTABLE_SaltProviderNext = SaltProviderNext;\n\nexport const useTheme = (): ThemeContextProps => {\n const { window: _window, ...contextWithoutWindow } = useContext(ThemeContext);\n\n return contextWithoutWindow;\n};\n\n/**\n * `useDensity` merges density value from `DensityContext` with the one from component's props.\n */\nexport function useDensity(density?: Density): Density {\n const densityFromContext = useContext(DensityContext);\n return density ?? densityFromContext ?? DEFAULT_DENSITY;\n}\n\nexport const useBreakpoints = (): Breakpoints => {\n return useContext(BreakpointContext);\n};\n"],"names":["createContext","DEFAULT_BREAKPOINTS","clsx","isValidElement","cloneElement","jsx","useContext","useWindow","useComponentCssInjection","saltProviderCss","useMemo","useIsomorphicLayoutEffect","useMatchedBreakpoints","BreakpointProvider","ViewportProvider","AriaAnnouncerProvider","StyleInjectionProvider"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SaltProvider.js","sources":["../src/salt-provider/SaltProvider.tsx"],"sourcesContent":["import {\n StyleInjectionProvider,\n useComponentCssInjection,\n} from \"@salt-ds/styles\";\nimport { useWindow, type WindowContextType } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n createContext,\n type ReactElement,\n type ReactNode,\n useContext,\n useMemo,\n} from \"react\";\nimport { AriaAnnouncerProvider } from \"../aria-announcer\";\nimport {\n BreakpointProvider,\n type Breakpoints,\n DEFAULT_BREAKPOINTS,\n useMatchedBreakpoints,\n} from \"../breakpoints\";\nimport type {\n Accent,\n ActionFont,\n Corner,\n Density,\n HeadingFont,\n Mode,\n ThemeName,\n} from \"../theme\";\nimport { ViewportProvider } from \"../viewport\";\nimport { ProviderContext } from \"./ProviderContext\";\nimport saltProviderCss from \"./SaltProvider.css\";\nimport { ThemeApplicator, type ThemeApplicatorProps } from \"./ThemeApplicator\";\n\nexport const DEFAULT_DENSITY = \"medium\";\n\nconst DEFAULT_THEME_NAME = \"salt-theme\";\nconst DEFAULT_THEME_NAME_NEXT = \"salt-theme-next\";\n\nconst DEFAULT_MODE = \"light\";\nconst DEFAULT_CORNER: Corner = \"sharp\";\nconst DEFAULT_HEADING_FONT: HeadingFont = \"Open Sans\";\nconst DEFAULT_ACCENT: Accent = \"blue\";\nconst DEFAULT_ACTION_FONT: ActionFont = \"Open Sans\";\nexport interface ThemeContextProps {\n theme: ThemeName;\n mode: Mode;\n window?: WindowContextType;\n /** Only available when using SaltProviderNext. */\n themeNext: boolean;\n corner: Corner;\n /** @deprecated use `corner`*/\n UNSTABLE_corner: Corner;\n headingFont: HeadingFont;\n /** @deprecated use `headingFont` */\n UNSTABLE_headingFont: HeadingFont;\n accent: Accent;\n /** @deprecated use `accent` */\n UNSTABLE_accent: Accent;\n actionFont: ActionFont;\n /** @deprecated use `actionFont` */\n UNSTABLE_actionFont: ActionFont;\n}\n\nexport const DensityContext = createContext<Density>(DEFAULT_DENSITY);\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n theme: \"\",\n mode: DEFAULT_MODE,\n themeNext: false,\n corner: DEFAULT_CORNER,\n UNSTABLE_corner: DEFAULT_CORNER,\n headingFont: DEFAULT_HEADING_FONT,\n UNSTABLE_headingFont: DEFAULT_HEADING_FONT,\n accent: DEFAULT_ACCENT,\n UNSTABLE_accent: DEFAULT_ACCENT,\n actionFont: DEFAULT_ACTION_FONT,\n UNSTABLE_actionFont: DEFAULT_ACTION_FONT,\n});\n\nexport const BreakpointContext =\n createContext<Breakpoints>(DEFAULT_BREAKPOINTS);\n\ntype ThemeNextOnlyAttributes =\n | \"accent\"\n | \"corner\"\n | \"actionFont\"\n | \"headingFont\";\n\ninterface SaltProviderBaseProps\n extends Partial<\n Omit<ThemeApplicatorProps, \"children\" | ThemeNextOnlyAttributes>\n > {\n /**\n * Shape of `{ xs: number; sm: number; md: number; lg: number; xl: number; }`.\n * Determines breakpoints used in responsive calculation for layout components.\n */\n breakpoints?: Breakpoints;\n /**\n * A boolean. Enables dynamic style injection for each component.\n *\n * If `false`, you'll need to include component CSS yourself.\n *\n * @default true\n */\n enableStyleInjection?: boolean;\n}\n\ninterface SaltProviderThatAppliesClassesToChild extends SaltProviderBaseProps {\n children: ReactElement;\n applyClassesTo: \"child\";\n}\n\ninterface SaltProviderThatInjectsThemeElement extends SaltProviderBaseProps {\n children: ReactNode;\n}\n\ninterface SaltProviderThatClassesToRoot\n extends SaltProviderThatInjectsThemeElement {\n applyClassesTo: \"root\";\n}\n\ntype SaltProviderProps =\n | SaltProviderThatAppliesClassesToChild\n | SaltProviderThatInjectsThemeElement\n | SaltProviderThatClassesToRoot;\n\nfunction InternalSaltProvider({\n applyClassesTo: applyClassesToProp,\n children,\n density: densityProp,\n theme: themeProp,\n mode: modeProp,\n breakpoints: breakpointsProp,\n themeNext,\n corner: cornerProp,\n headingFont: headingFontProp,\n accent: accentProp,\n actionFont: actionFontProp,\n}: Omit<\n SaltProviderProps & {\n themeNext?: boolean;\n } & SaltProviderNextProps,\n \"enableStyleInjection\"\n>) {\n const prevProvider = useContext(ProviderContext);\n const inheritedDensity = useContext(DensityContext);\n const {\n theme: inheritedTheme,\n mode: inheritedMode,\n corner: inheritedCorner,\n headingFont: inheritedHeadingFont,\n accent: inheritedAccent,\n actionFont: inheritedActionFont,\n } = useContext(ThemeContext);\n\n const isRootProvider = prevProvider === null;\n\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const inheritedThemeName =\n inheritedTheme === \"\" ? DEFAULT_THEME_NAME : inheritedTheme;\n const themeName = themeProp ?? inheritedThemeName;\n const mode = modeProp ?? inheritedMode;\n const breakpoints = breakpointsProp ?? DEFAULT_BREAKPOINTS;\n\n const corner = cornerProp ?? inheritedCorner ?? DEFAULT_CORNER;\n const headingFont =\n headingFontProp ?? inheritedHeadingFont ?? DEFAULT_HEADING_FONT;\n const accent = accentProp ?? inheritedAccent ?? DEFAULT_ACCENT;\n const actionFont =\n actionFontProp ?? inheritedActionFont ?? DEFAULT_ACTION_FONT;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-provider\",\n css: saltProviderCss,\n window: targetWindow,\n });\n\n const themeContextValue = useMemo(\n () => ({\n theme: themeName,\n mode,\n window: targetWindow,\n themeNext: Boolean(themeNext),\n corner: corner,\n headingFont: headingFont,\n accent: accent,\n actionFont: actionFont,\n // Backward compatibility\n UNSTABLE_corner: corner,\n UNSTABLE_headingFont: headingFont,\n UNSTABLE_accent: accent,\n UNSTABLE_actionFont: actionFont,\n }),\n [\n themeName,\n mode,\n targetWindow,\n themeNext,\n corner,\n headingFont,\n accent,\n actionFont,\n ],\n );\n\n const matchedBreakpoints = useMatchedBreakpoints(breakpoints);\n\n const saltProvider = (\n <ProviderContext.Provider value={{ targetWindow }}>\n <DensityContext.Provider value={density}>\n <ThemeContext.Provider value={themeContextValue}>\n <BreakpointProvider matchedBreakpoints={matchedBreakpoints}>\n <BreakpointContext.Provider value={breakpoints}>\n <ViewportProvider>\n <ThemeApplicator\n applyClassesTo={\n applyClassesToProp ?? (isRootProvider ? \"root\" : \"scope\")\n }\n density={density}\n theme={clsx(\n DEFAULT_THEME_NAME,\n { [DEFAULT_THEME_NAME_NEXT]: themeNext },\n themeProp,\n )}\n mode={mode}\n accent={themeNext ? accent : undefined}\n actionFont={themeNext ? actionFont : undefined}\n headingFont={themeNext ? headingFont : undefined}\n corner={themeNext ? corner : undefined}\n >\n {children}\n </ThemeApplicator>\n </ViewportProvider>\n </BreakpointContext.Provider>\n </BreakpointProvider>\n </ThemeContext.Provider>\n </DensityContext.Provider>\n </ProviderContext.Provider>\n );\n\n if (isRootProvider) {\n return <AriaAnnouncerProvider>{saltProvider}</AriaAnnouncerProvider>;\n }\n return saltProvider;\n}\n\nexport function SaltProvider({\n enableStyleInjection,\n ...restProps\n}: SaltProviderProps) {\n return (\n <StyleInjectionProvider value={enableStyleInjection}>\n <InternalSaltProvider {...restProps} />\n </StyleInjectionProvider>\n );\n}\n\nexport type SaltProviderNextProps = SaltProviderProps &\n Pick<ThemeApplicatorProps, ThemeNextOnlyAttributes>;\nexport function SaltProviderNext({\n enableStyleInjection,\n ...restProps\n}: SaltProviderNextProps) {\n return (\n <StyleInjectionProvider value={enableStyleInjection}>\n {/* Leveraging InternalSaltProvider being not exported, so we can pass more props than previously supported */}\n <InternalSaltProvider {...restProps} themeNext={true} />\n </StyleInjectionProvider>\n );\n}\n\n/** @deprecated use `SaltProviderNextProps` */\nexport type UNSTABLE_SaltProviderNextProps = SaltProviderNextProps;\n\n/** @deprecated use `SaltProviderNext` */\nexport const UNSTABLE_SaltProviderNext = SaltProviderNext;\n\nexport const useTheme = (): ThemeContextProps => {\n const { window: _window, ...contextWithoutWindow } = useContext(ThemeContext);\n\n return contextWithoutWindow;\n};\n\n/**\n * `useDensity` merges density value from `DensityContext` with the one from component's props.\n */\nexport function useDensity(density?: Density): Density {\n const densityFromContext = useContext(DensityContext);\n return density ?? densityFromContext ?? DEFAULT_DENSITY;\n}\n\nexport const useBreakpoints = (): Breakpoints => {\n return useContext(BreakpointContext);\n};\n"],"names":["createContext","DEFAULT_BREAKPOINTS","useContext","ProviderContext","useWindow","useComponentCssInjection","saltProviderCss","useMemo","useMatchedBreakpoints","jsx","BreakpointProvider","ViewportProvider","ThemeApplicator","clsx","AriaAnnouncerProvider","StyleInjectionProvider"],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var window = require('@salt-ds/window');
|
|
5
|
+
var clsx = require('clsx');
|
|
6
|
+
var React = require('react');
|
|
7
|
+
var useId = require('../utils/useId.js');
|
|
8
|
+
var useIsomorphicLayoutEffect = require('../utils/useIsomorphicLayoutEffect.js');
|
|
9
|
+
|
|
10
|
+
const providerSymbol = Symbol.for("salt-provider");
|
|
11
|
+
function ThemeApplicator({
|
|
12
|
+
applyClassesTo,
|
|
13
|
+
children,
|
|
14
|
+
density,
|
|
15
|
+
mode,
|
|
16
|
+
theme,
|
|
17
|
+
corner,
|
|
18
|
+
headingFont,
|
|
19
|
+
accent,
|
|
20
|
+
actionFont
|
|
21
|
+
}) {
|
|
22
|
+
var _a;
|
|
23
|
+
const targetWindow = window.useWindow();
|
|
24
|
+
const providerId = useId.useId();
|
|
25
|
+
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
26
|
+
if (applyClassesTo !== "root" || !targetWindow || !providerId) return;
|
|
27
|
+
const targetDocument = targetWindow.document;
|
|
28
|
+
if (!targetDocument[providerSymbol]) {
|
|
29
|
+
targetDocument[providerSymbol] = providerId;
|
|
30
|
+
}
|
|
31
|
+
if (providerId !== targetDocument[providerSymbol]) {
|
|
32
|
+
console.warn(
|
|
33
|
+
"Multiple providers targeting the same window. There can be only one level root level SaltProvider per window."
|
|
34
|
+
);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const themeNames = theme.split(" ");
|
|
38
|
+
targetDocument.documentElement.classList.add(
|
|
39
|
+
...themeNames,
|
|
40
|
+
`salt-density-${density}`
|
|
41
|
+
);
|
|
42
|
+
targetDocument.documentElement.dataset.mode = mode;
|
|
43
|
+
if (corner) targetDocument.documentElement.dataset.corner = corner;
|
|
44
|
+
if (headingFont)
|
|
45
|
+
targetDocument.documentElement.dataset.headingFont = headingFont;
|
|
46
|
+
if (accent) targetDocument.documentElement.dataset.accent = accent;
|
|
47
|
+
if (actionFont)
|
|
48
|
+
targetDocument.documentElement.dataset.actionFont = actionFont;
|
|
49
|
+
return () => {
|
|
50
|
+
delete targetDocument[providerSymbol];
|
|
51
|
+
targetDocument.documentElement.classList.remove(
|
|
52
|
+
...themeNames,
|
|
53
|
+
`salt-density-${density}`
|
|
54
|
+
);
|
|
55
|
+
targetDocument.documentElement.dataset.mode = void 0;
|
|
56
|
+
delete targetDocument.documentElement.dataset.corner;
|
|
57
|
+
delete targetDocument.documentElement.dataset.headingFont;
|
|
58
|
+
delete targetDocument.documentElement.dataset.accent;
|
|
59
|
+
delete targetDocument.documentElement.dataset.actionFont;
|
|
60
|
+
};
|
|
61
|
+
}, [
|
|
62
|
+
providerId,
|
|
63
|
+
applyClassesTo,
|
|
64
|
+
density,
|
|
65
|
+
mode,
|
|
66
|
+
theme,
|
|
67
|
+
targetWindow,
|
|
68
|
+
corner,
|
|
69
|
+
headingFont,
|
|
70
|
+
accent,
|
|
71
|
+
actionFont
|
|
72
|
+
]);
|
|
73
|
+
const themeNextProps = {
|
|
74
|
+
"data-corner": corner,
|
|
75
|
+
"data-heading-font": headingFont,
|
|
76
|
+
"data-accent": accent,
|
|
77
|
+
"data-action-font": actionFont
|
|
78
|
+
};
|
|
79
|
+
if (applyClassesTo === "child") {
|
|
80
|
+
if (React.isValidElement(children)) {
|
|
81
|
+
return React.cloneElement(children, {
|
|
82
|
+
className: clsx.clsx(
|
|
83
|
+
(_a = children.props) == null ? void 0 : _a.className,
|
|
84
|
+
theme,
|
|
85
|
+
`salt-density-${density}`
|
|
86
|
+
),
|
|
87
|
+
// @ts-expect-error
|
|
88
|
+
"data-mode": mode,
|
|
89
|
+
...themeNextProps
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
console.warn(
|
|
93
|
+
`
|
|
94
|
+
SaltProvider can only apply CSS classes for theming to a single nested child element of the SaltProvider.
|
|
95
|
+
Either wrap elements with a single container or consider removing the applyClassesToChild prop, in which case a
|
|
96
|
+
div element will wrap your child elements`
|
|
97
|
+
);
|
|
98
|
+
return children;
|
|
99
|
+
}
|
|
100
|
+
if (applyClassesTo === "scope") {
|
|
101
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
"div",
|
|
103
|
+
{
|
|
104
|
+
className: clsx.clsx("salt-provider", theme, `salt-density-${density}`),
|
|
105
|
+
"data-mode": mode,
|
|
106
|
+
...themeNextProps,
|
|
107
|
+
children
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return children;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
exports.ThemeApplicator = ThemeApplicator;
|
|
115
|
+
//# sourceMappingURL=ThemeApplicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeApplicator.js","sources":["../src/salt-provider/ThemeApplicator.tsx"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n type ReactNode,\n} from \"react\";\nimport type {\n Accent,\n ActionFont,\n Corner,\n Density,\n HeadingFont,\n Mode,\n ThemeName,\n} from \"../theme/index\";\nimport { useId } from \"../utils/useId\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\n\nexport interface ThemeApplicatorProps {\n /**\n * Either \"root\", \"scope\" or \"child\".\n * Specifies the location of salt theme class and attributes should be applied to.\n *\n * Defaults to \"root\" for a root provider, otherwise \"scope\".\n */\n applyClassesTo: \"root\" | \"scope\" | \"child\";\n /**\n * Either \"high\", \"medium\", \"low\" or \"touch\".\n * Determines the amount of content that can fit on a screen based on the size and spacing of components.\n * Refer to [density](https://www.saltdesignsystem.com/salt/foundations/density) doc for more detail.\n *\n * @default \"medium\"\n */\n density: Density;\n /**\n * A string. Specifies custom theme name(s) you want to apply, similar to `className`.\n */\n theme: ThemeName;\n /**\n * Either \"light\" or \"dark\". Enable the color palette to change from light to dark.\n * Refer to [modes](https://www.saltdesignsystem.com/salt/foundations/modes) doc for more detail.\n *\n * @default \"light\"\n */\n mode: Mode;\n /**\n * Either \"sharp\" or \"rounded\".\n * Determines selected components corner radius.\n * @default \"sharp\"\n */\n corner?: Corner;\n /**\n * Either \"Open Sans\" or \"Amplitude\".\n * Determines font family of display and heading text.\n * @default \"Open Sans\"\n */\n headingFont?: HeadingFont;\n /**\n * Either \"blue\" or \"teal\".\n * Determines accent color used across components, e.g. Accent Button, List, Calendar.\n * @default \"blue\"\n */\n accent?: Accent;\n /**\n * Either \"Open Sans\" or \"Amplitude\".\n * Determines font family of action components, mostly Buttons.\n * @default \"Open Sans\"\n */\n actionFont?: ActionFont;\n children?: ReactNode;\n}\n\nconst providerSymbol = Symbol.for(\"salt-provider\");\n\nexport function ThemeApplicator({\n applyClassesTo,\n children,\n density,\n mode,\n theme,\n corner,\n headingFont,\n accent,\n actionFont,\n}: ThemeApplicatorProps) {\n const targetWindow = useWindow();\n\n const providerId = useId();\n\n useIsomorphicLayoutEffect(() => {\n if (applyClassesTo !== \"root\" || !targetWindow || !providerId) return;\n\n const targetDocument: Document & { [providerSymbol]?: string } =\n targetWindow.document;\n\n // Claim the document if no other provider has already. The symbol is used so the lock isn't enumerable and guarantees it won't clash with anything else.\n if (!targetDocument[providerSymbol]) {\n targetDocument[providerSymbol] = providerId;\n }\n\n if (providerId !== targetDocument[providerSymbol]) {\n console.warn(\n \"Multiple providers targeting the same window. There can be only one level root level SaltProvider per window.\",\n );\n return;\n }\n\n const themeNames = theme.split(\" \");\n\n // add the styles we want to apply\n targetDocument.documentElement.classList.add(\n ...themeNames,\n `salt-density-${density}`,\n );\n targetDocument.documentElement.dataset.mode = mode;\n\n // Theme Next\n if (corner) targetDocument.documentElement.dataset.corner = corner;\n if (headingFont)\n targetDocument.documentElement.dataset.headingFont = headingFont;\n if (accent) targetDocument.documentElement.dataset.accent = accent;\n if (actionFont)\n targetDocument.documentElement.dataset.actionFont = actionFont;\n\n return () => {\n // Delete lock\n delete targetDocument[providerSymbol];\n\n // When unmounting/remounting, remove the applied styles from the root\n targetDocument.documentElement.classList.remove(\n ...themeNames,\n `salt-density-${density}`,\n );\n targetDocument.documentElement.dataset.mode = undefined;\n\n // Theme Next\n delete targetDocument.documentElement.dataset.corner;\n delete targetDocument.documentElement.dataset.headingFont;\n delete targetDocument.documentElement.dataset.accent;\n delete targetDocument.documentElement.dataset.actionFont;\n };\n }, [\n providerId,\n applyClassesTo,\n density,\n mode,\n theme,\n targetWindow,\n corner,\n headingFont,\n accent,\n actionFont,\n ]);\n\n const themeNextProps = {\n \"data-corner\": corner,\n \"data-heading-font\": headingFont,\n \"data-accent\": accent,\n \"data-action-font\": actionFont,\n };\n\n if (applyClassesTo === \"child\") {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: clsx(\n children.props?.className,\n theme,\n `salt-density-${density}`,\n ),\n // @ts-expect-error\n \"data-mode\": mode,\n ...themeNextProps,\n });\n }\n console.warn(\n `\\nSaltProvider can only apply CSS classes for theming to a single nested child element of the SaltProvider.\n Either wrap elements with a single container or consider removing the applyClassesToChild prop, in which case a\n div element will wrap your child elements`,\n );\n return children;\n }\n\n if (applyClassesTo === \"scope\") {\n return (\n <div\n className={clsx(\"salt-provider\", theme, `salt-density-${density}`)}\n data-mode={mode}\n {...themeNextProps}\n >\n {children}\n </div>\n );\n }\n\n return children;\n}\n"],"names":["useWindow","useId","useIsomorphicLayoutEffect","isValidElement","cloneElement","clsx","jsx"],"mappings":"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"}
|
|
@@ -78,7 +78,7 @@ const useRangeSliderThumb = ({
|
|
|
78
78
|
onChange
|
|
79
79
|
]
|
|
80
80
|
);
|
|
81
|
-
const
|
|
81
|
+
const handleDragEnd = React.useCallback(
|
|
82
82
|
(event) => {
|
|
83
83
|
setIsDragging(false);
|
|
84
84
|
setIsFocusVisible(false);
|
|
@@ -89,16 +89,25 @@ const useRangeSliderThumb = ({
|
|
|
89
89
|
React.useEffect(() => {
|
|
90
90
|
if (isDragging) {
|
|
91
91
|
targetWindow == null ? void 0 : targetWindow.addEventListener("pointermove", handlePointerMove);
|
|
92
|
-
targetWindow == null ? void 0 : targetWindow.addEventListener("pointerup",
|
|
92
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("pointerup", handleDragEnd);
|
|
93
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("pointercancel", handleDragEnd);
|
|
94
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("blur", handleDragEnd);
|
|
95
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("contextmenu", handleDragEnd);
|
|
93
96
|
} else {
|
|
94
97
|
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointermove", handlePointerMove);
|
|
95
|
-
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup",
|
|
98
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup", handleDragEnd);
|
|
99
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointercancel", handleDragEnd);
|
|
100
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("blur", handleDragEnd);
|
|
101
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("contextmenu", handleDragEnd);
|
|
96
102
|
}
|
|
97
103
|
return () => {
|
|
98
104
|
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointermove", handlePointerMove);
|
|
99
|
-
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup",
|
|
105
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup", handleDragEnd);
|
|
106
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointercancel", handleDragEnd);
|
|
107
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("blur", handleDragEnd);
|
|
108
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("contextmenu", handleDragEnd);
|
|
100
109
|
};
|
|
101
|
-
}, [
|
|
110
|
+
}, [isDragging, targetWindow, handlePointerMove, handleDragEnd]);
|
|
102
111
|
const handlePointerDownOnThumb = React.useCallback(
|
|
103
112
|
(event, thumbIndex) => {
|
|
104
113
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRangeSliderThumb.js","sources":["../src/slider/internal/useRangeSliderThumb.ts"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport {\n type ChangeEvent,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { SliderProps } from \"../Slider\";\nimport { getClickedPosition, getKeyboardValue } from \"./utils\";\n\ntype UseRangeSliderThumbProps = Pick<SliderProps, \"min\" | \"max\" | \"step\"> & {\n decimalPlaces: number;\n handleInputChange: (\n event: ChangeEvent<HTMLInputElement>,\n thumbIndex: number,\n ) => void;\n inputRefs: RefObject<HTMLInputElement>[];\n marks?: { label: string; value: number }[];\n onChange?: (event: Event, value: [number, number]) => void;\n onChangeEnd?: (event: Event, value: [number, number]) => void;\n restrictToMarks?: boolean;\n setValue: Dispatch<SetStateAction<[number, number]>>;\n stepMultiplier: number;\n value: [number, number];\n};\n\nexport const useRangeSliderThumb = ({\n decimalPlaces,\n handleInputChange,\n inputRefs,\n marks,\n min = 0,\n max = 10,\n step = 1,\n onChange,\n onChangeEnd,\n restrictToMarks,\n setValue,\n stepMultiplier,\n value,\n}: UseRangeSliderThumbProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const [isFocusVisible, setIsFocusVisible] = useState(false);\n const [thumbIndexState, setIsThumbIndex] = useState<number>(0);\n const lastValueRef = useRef<[number, number]>(value);\n const sliderRef = useRef<HTMLDivElement>(null);\n const targetWindow = useWindow();\n\n const preventThumbOverlap = useCallback(\n (currentValue: number, value: [number, number], thumbIndex: number) => {\n const values = [...value] as [number, number];\n if (thumbIndex === 0 && currentValue >= values[1]) {\n values[0] = values[1];\n } else if (thumbIndex === 1 && currentValue <= values[0]) {\n values[1] = values[0];\n } else {\n values[thumbIndex] = currentValue;\n }\n return values;\n },\n [],\n );\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n if (!sliderRef.current) return;\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined) return;\n const newValues = preventThumbOverlap(\n newValue,\n value as [number, number],\n thumbIndexState,\n );\n\n if (\n newValues[0] !== lastValueRef.current[0] ||\n newValues[1] !== lastValueRef.current[1]\n ) {\n lastValueRef.current = newValues;\n setValue(newValues);\n onChange?.(event, newValues);\n }\n },\n [\n decimalPlaces,\n marks,\n max,\n min,\n step,\n preventThumbOverlap,\n restrictToMarks,\n value,\n thumbIndexState,\n setValue,\n onChange,\n ],\n );\n\n const handlePointerUp = useCallback(\n (event: PointerEvent) => {\n setIsDragging(false);\n setIsFocusVisible(false);\n onChangeEnd?.(event, lastValueRef.current);\n },\n [onChangeEnd],\n );\n\n useEffect(() => {\n if (isDragging) {\n targetWindow?.addEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.addEventListener(\"pointerup\", handlePointerUp);\n } else {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handlePointerUp);\n }\n return () => {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [handlePointerMove, handlePointerUp, isDragging, targetWindow]);\n\n const handlePointerDownOnThumb = useCallback(\n (event: React.PointerEvent<HTMLDivElement>, thumbIndex: number) => {\n event.preventDefault();\n // To prevent the pointerdown event from bubbling up to the slider track\n // and triggering its pointerdown event\n event.stopPropagation();\n\n inputRefs[thumbIndex].current?.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n if (thumbIndex !== undefined) {\n setIsThumbIndex(thumbIndex);\n }\n },\n [inputRefs],\n );\n\n const handlePointerDownOnTrack = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n setIsDragging(true);\n\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n let closestThumbIndex = 0;\n\n if (newValue === undefined) return;\n const newValues = [...value] as [number, number];\n // Find nearest thumb\n const distanceToThumb0 = Math.abs(newValue - newValues[0]);\n const distanceToThumb1 = Math.abs(newValue - newValues[1]);\n if (distanceToThumb0 > distanceToThumb1) {\n // Move the second thumb\n newValues[1] = newValue;\n closestThumbIndex = 1;\n } else if (distanceToThumb0 < distanceToThumb1) {\n // Move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n } else {\n // If distances are equal, determine based on the click position\n if (newValue < newValues[0]) {\n // Clicked position is before both thumbs, move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n } else if (newValue > newValues[1]) {\n // Clicked position is after both thumbs, move the second thumb\n newValues[1] = newValue;\n closestThumbIndex = 1;\n } else {\n // Clicked position is between the thumbs, move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n }\n }\n setIsThumbIndex(closestThumbIndex);\n inputRefs[closestThumbIndex].current?.focus();\n setIsFocusVisible(false);\n\n if (\n newValues[0] !== lastValueRef.current[0] ||\n newValues[1] !== lastValueRef.current[1]\n ) {\n lastValueRef.current = newValues;\n setValue(newValues);\n onChange?.(event.nativeEvent, newValues);\n }\n },\n [\n decimalPlaces,\n marks,\n value,\n max,\n min,\n inputRefs,\n onChange,\n restrictToMarks,\n setValue,\n step,\n ],\n );\n\n const handleKeydownOnThumb = useCallback(\n (event: React.KeyboardEvent, thumbIndex: number) => {\n const newValue = getKeyboardValue(\n event,\n value[thumbIndex],\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n );\n if (\n newValue === undefined ||\n newValue === lastValueRef.current[thumbIndex]\n ) {\n return;\n }\n setIsFocusVisible(true);\n lastValueRef.current[thumbIndex] = newValue;\n handleInputChange(\n {\n target: { value: newValue.toString() },\n } as ChangeEvent<HTMLInputElement>,\n thumbIndex,\n );\n },\n [\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n handleInputChange,\n ],\n );\n\n const handleFocus = (thumbIndex: number) => {\n setIsThumbIndex(thumbIndex);\n setIsFocusVisible(true);\n };\n\n const handleBlur = (thumbIndex: number) => {\n setIsThumbIndex(thumbIndex);\n setIsFocusVisible(false);\n };\n\n return {\n handleBlur,\n handleFocus,\n handleKeydownOnThumb,\n handlePointerDownOnThumb,\n handlePointerDownOnTrack,\n isDragging,\n isFocusVisible,\n preventThumbOverlap,\n sliderRef,\n thumbIndexState,\n };\n};\n"],"names":["useState","useRef","useWindow","useCallback","value","getClickedPosition","useEffect","getKeyboardValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useRangeSliderThumb.js","sources":["../src/slider/internal/useRangeSliderThumb.ts"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport {\n type ChangeEvent,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { SliderProps } from \"../Slider\";\nimport { getClickedPosition, getKeyboardValue } from \"./utils\";\n\ntype UseRangeSliderThumbProps = Pick<SliderProps, \"min\" | \"max\" | \"step\"> & {\n decimalPlaces: number;\n handleInputChange: (\n event: ChangeEvent<HTMLInputElement>,\n thumbIndex: number,\n ) => void;\n inputRefs: RefObject<HTMLInputElement>[];\n marks?: { label: string; value: number }[];\n onChange?: (event: Event, value: [number, number]) => void;\n onChangeEnd?: (event: Event, value: [number, number]) => void;\n restrictToMarks?: boolean;\n setValue: Dispatch<SetStateAction<[number, number]>>;\n stepMultiplier: number;\n value: [number, number];\n};\n\nexport const useRangeSliderThumb = ({\n decimalPlaces,\n handleInputChange,\n inputRefs,\n marks,\n min = 0,\n max = 10,\n step = 1,\n onChange,\n onChangeEnd,\n restrictToMarks,\n setValue,\n stepMultiplier,\n value,\n}: UseRangeSliderThumbProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const [isFocusVisible, setIsFocusVisible] = useState(false);\n const [thumbIndexState, setIsThumbIndex] = useState<number>(0);\n const lastValueRef = useRef<[number, number]>(value);\n const sliderRef = useRef<HTMLDivElement>(null);\n const targetWindow = useWindow();\n\n const preventThumbOverlap = useCallback(\n (currentValue: number, value: [number, number], thumbIndex: number) => {\n const values = [...value] as [number, number];\n if (thumbIndex === 0 && currentValue >= values[1]) {\n values[0] = values[1];\n } else if (thumbIndex === 1 && currentValue <= values[0]) {\n values[1] = values[0];\n } else {\n values[thumbIndex] = currentValue;\n }\n return values;\n },\n [],\n );\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n if (!sliderRef.current) return;\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined) return;\n const newValues = preventThumbOverlap(\n newValue,\n value as [number, number],\n thumbIndexState,\n );\n\n if (\n newValues[0] !== lastValueRef.current[0] ||\n newValues[1] !== lastValueRef.current[1]\n ) {\n lastValueRef.current = newValues;\n setValue(newValues);\n onChange?.(event, newValues);\n }\n },\n [\n decimalPlaces,\n marks,\n max,\n min,\n step,\n preventThumbOverlap,\n restrictToMarks,\n value,\n thumbIndexState,\n setValue,\n onChange,\n ],\n );\n\n const handleDragEnd = useCallback(\n (event: Event) => {\n setIsDragging(false);\n setIsFocusVisible(false);\n onChangeEnd?.(event, lastValueRef.current);\n },\n [onChangeEnd],\n );\n\n useEffect(() => {\n if (isDragging) {\n targetWindow?.addEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.addEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.addEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.addEventListener(\"blur\", handleDragEnd);\n targetWindow?.addEventListener(\"contextmenu\", handleDragEnd);\n } else {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.removeEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.removeEventListener(\"blur\", handleDragEnd);\n targetWindow?.removeEventListener(\"contextmenu\", handleDragEnd);\n }\n return () => {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.removeEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.removeEventListener(\"blur\", handleDragEnd);\n targetWindow?.removeEventListener(\"contextmenu\", handleDragEnd);\n };\n }, [isDragging, targetWindow, handlePointerMove, handleDragEnd]);\n\n const handlePointerDownOnThumb = useCallback(\n (event: React.PointerEvent<HTMLDivElement>, thumbIndex: number) => {\n event.preventDefault();\n // To prevent the pointerdown event from bubbling up to the slider track\n // and triggering its pointerdown event\n event.stopPropagation();\n\n inputRefs[thumbIndex].current?.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n if (thumbIndex !== undefined) {\n setIsThumbIndex(thumbIndex);\n }\n },\n [inputRefs],\n );\n\n const handlePointerDownOnTrack = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n setIsDragging(true);\n\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n let closestThumbIndex = 0;\n\n if (newValue === undefined) return;\n const newValues = [...value] as [number, number];\n // Find nearest thumb\n const distanceToThumb0 = Math.abs(newValue - newValues[0]);\n const distanceToThumb1 = Math.abs(newValue - newValues[1]);\n if (distanceToThumb0 > distanceToThumb1) {\n // Move the second thumb\n newValues[1] = newValue;\n closestThumbIndex = 1;\n } else if (distanceToThumb0 < distanceToThumb1) {\n // Move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n } else {\n // If distances are equal, determine based on the click position\n if (newValue < newValues[0]) {\n // Clicked position is before both thumbs, move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n } else if (newValue > newValues[1]) {\n // Clicked position is after both thumbs, move the second thumb\n newValues[1] = newValue;\n closestThumbIndex = 1;\n } else {\n // Clicked position is between the thumbs, move the first thumb\n newValues[0] = newValue;\n closestThumbIndex = 0;\n }\n }\n setIsThumbIndex(closestThumbIndex);\n inputRefs[closestThumbIndex].current?.focus();\n setIsFocusVisible(false);\n\n if (\n newValues[0] !== lastValueRef.current[0] ||\n newValues[1] !== lastValueRef.current[1]\n ) {\n lastValueRef.current = newValues;\n setValue(newValues);\n onChange?.(event.nativeEvent, newValues);\n }\n },\n [\n decimalPlaces,\n marks,\n value,\n max,\n min,\n inputRefs,\n onChange,\n restrictToMarks,\n setValue,\n step,\n ],\n );\n\n const handleKeydownOnThumb = useCallback(\n (event: React.KeyboardEvent, thumbIndex: number) => {\n const newValue = getKeyboardValue(\n event,\n value[thumbIndex],\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n );\n if (\n newValue === undefined ||\n newValue === lastValueRef.current[thumbIndex]\n ) {\n return;\n }\n setIsFocusVisible(true);\n lastValueRef.current[thumbIndex] = newValue;\n handleInputChange(\n {\n target: { value: newValue.toString() },\n } as ChangeEvent<HTMLInputElement>,\n thumbIndex,\n );\n },\n [\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n handleInputChange,\n ],\n );\n\n const handleFocus = (thumbIndex: number) => {\n setIsThumbIndex(thumbIndex);\n setIsFocusVisible(true);\n };\n\n const handleBlur = (thumbIndex: number) => {\n setIsThumbIndex(thumbIndex);\n setIsFocusVisible(false);\n };\n\n return {\n handleBlur,\n handleFocus,\n handleKeydownOnThumb,\n handlePointerDownOnThumb,\n handlePointerDownOnTrack,\n isDragging,\n isFocusVisible,\n preventThumbOverlap,\n sliderRef,\n thumbIndexState,\n };\n};\n"],"names":["useState","useRef","useWindow","useCallback","value","getClickedPosition","useEffect","getKeyboardValue"],"mappings":"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"}
|
|
@@ -46,7 +46,7 @@ const useSliderThumb = ({
|
|
|
46
46
|
},
|
|
47
47
|
[decimalPlaces, marks, max, min, onChange, setValue, restrictToMarks, step]
|
|
48
48
|
);
|
|
49
|
-
const
|
|
49
|
+
const handleDragEnd = React.useCallback(
|
|
50
50
|
(event) => {
|
|
51
51
|
setIsDragging(false);
|
|
52
52
|
setIsFocusVisible(false);
|
|
@@ -57,16 +57,25 @@ const useSliderThumb = ({
|
|
|
57
57
|
React.useEffect(() => {
|
|
58
58
|
if (isDragging) {
|
|
59
59
|
targetWindow == null ? void 0 : targetWindow.addEventListener("pointermove", handlePointerMove);
|
|
60
|
-
targetWindow == null ? void 0 : targetWindow.addEventListener("pointerup",
|
|
60
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("pointerup", handleDragEnd);
|
|
61
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("pointercancel", handleDragEnd);
|
|
62
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("blur", handleDragEnd);
|
|
63
|
+
targetWindow == null ? void 0 : targetWindow.addEventListener("contextmenu", handleDragEnd);
|
|
61
64
|
} else {
|
|
62
65
|
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointermove", handlePointerMove);
|
|
63
|
-
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup",
|
|
66
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup", handleDragEnd);
|
|
67
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointercancel", handleDragEnd);
|
|
68
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("blur", handleDragEnd);
|
|
69
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("contextmenu", handleDragEnd);
|
|
64
70
|
}
|
|
65
71
|
return () => {
|
|
66
72
|
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointermove", handlePointerMove);
|
|
67
|
-
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup",
|
|
73
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointerup", handleDragEnd);
|
|
74
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("pointercancel", handleDragEnd);
|
|
75
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("blur", handleDragEnd);
|
|
76
|
+
targetWindow == null ? void 0 : targetWindow.removeEventListener("contextmenu", handleDragEnd);
|
|
68
77
|
};
|
|
69
|
-
}, [
|
|
78
|
+
}, [isDragging, targetWindow, handlePointerMove, handleDragEnd]);
|
|
70
79
|
const handlePointerDownOnThumb = React.useCallback(
|
|
71
80
|
(event) => {
|
|
72
81
|
event.preventDefault();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSliderThumb.js","sources":["../src/slider/internal/useSliderThumb.ts"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport {\n type ChangeEvent,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { SliderProps } from \"../Slider\";\nimport { getClickedPosition, getKeyboardValue } from \"./utils\";\n\ntype UseSliderThumbProps = Pick<SliderProps, \"min\" | \"max\" | \"step\"> & {\n decimalPlaces: number;\n handleInputChange: (event: ChangeEvent<HTMLInputElement>) => void;\n inputRef: RefObject<HTMLInputElement>;\n marks?: { label: string; value: number }[];\n onChange?: (event: Event, value: number) => void;\n onChangeEnd?: (event: Event, value: number) => void;\n restrictToMarks?: boolean;\n setValue: Dispatch<SetStateAction<number>>;\n stepMultiplier: number;\n value: number;\n};\n\nexport const useSliderThumb = ({\n decimalPlaces,\n handleInputChange,\n inputRef,\n marks,\n min = 0,\n max = 10,\n step = 1,\n onChange,\n onChangeEnd,\n restrictToMarks,\n setValue,\n stepMultiplier,\n value,\n}: UseSliderThumbProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const [isFocusVisible, setIsFocusVisible] = useState(false);\n const lastValueRef = useRef<number>(value);\n const sliderRef = useRef<HTMLDivElement>(null);\n const targetWindow = useWindow();\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n if (!sliderRef.current) return;\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n lastValueRef.current = newValue;\n setValue(newValue);\n onChange?.(event, newValue);\n },\n [decimalPlaces, marks, max, min, onChange, setValue, restrictToMarks, step],\n );\n\n const handlePointerUp = useCallback(\n (event: PointerEvent) => {\n setIsDragging(false);\n setIsFocusVisible(false);\n onChangeEnd?.(event, lastValueRef.current);\n },\n [onChangeEnd],\n );\n\n useEffect(() => {\n if (isDragging) {\n targetWindow?.addEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.addEventListener(\"pointerup\", handlePointerUp);\n } else {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handlePointerUp);\n }\n return () => {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [handlePointerMove, handlePointerUp, isDragging, targetWindow]);\n\n const handlePointerDownOnThumb = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n // To prevent the pointerdown event from bubbling up to the slider track\n // and triggering its pointerdown event\n event.stopPropagation();\n if (inputRef.current) inputRef.current.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n },\n [inputRef],\n );\n\n const handlePointerDownOnTrack = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n if (inputRef.current) inputRef.current.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n lastValueRef.current = newValue;\n setValue(newValue);\n onChange?.(event.nativeEvent, newValue);\n },\n [\n decimalPlaces,\n inputRef,\n marks,\n max,\n min,\n onChange,\n restrictToMarks,\n setValue,\n step,\n ],\n );\n\n const handleKeydownOnThumb = useCallback(\n (event: React.KeyboardEvent) => {\n const newValue = getKeyboardValue(\n event,\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n setIsFocusVisible(true);\n lastValueRef.current = newValue;\n handleInputChange({\n target: { value: newValue.toString() },\n } as ChangeEvent<HTMLInputElement>);\n },\n [\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n handleInputChange,\n ],\n );\n\n const handleFocus = () => setIsFocusVisible(true);\n\n const handleBlur = () => setIsFocusVisible(false);\n\n return {\n handleBlur,\n handleFocus,\n handleKeydownOnThumb,\n handlePointerDownOnThumb,\n handlePointerDownOnTrack,\n isDragging,\n isFocusVisible,\n sliderRef,\n };\n};\n"],"names":["useState","useRef","useWindow","useCallback","getClickedPosition","useEffect","getKeyboardValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useSliderThumb.js","sources":["../src/slider/internal/useSliderThumb.ts"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport {\n type ChangeEvent,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { SliderProps } from \"../Slider\";\nimport { getClickedPosition, getKeyboardValue } from \"./utils\";\n\ntype UseSliderThumbProps = Pick<SliderProps, \"min\" | \"max\" | \"step\"> & {\n decimalPlaces: number;\n handleInputChange: (event: ChangeEvent<HTMLInputElement>) => void;\n inputRef: RefObject<HTMLInputElement>;\n marks?: { label: string; value: number }[];\n onChange?: (event: Event, value: number) => void;\n onChangeEnd?: (event: Event, value: number) => void;\n restrictToMarks?: boolean;\n setValue: Dispatch<SetStateAction<number>>;\n stepMultiplier: number;\n value: number;\n};\n\nexport const useSliderThumb = ({\n decimalPlaces,\n handleInputChange,\n inputRef,\n marks,\n min = 0,\n max = 10,\n step = 1,\n onChange,\n onChangeEnd,\n restrictToMarks,\n setValue,\n stepMultiplier,\n value,\n}: UseSliderThumbProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const [isFocusVisible, setIsFocusVisible] = useState(false);\n const lastValueRef = useRef<number>(value);\n const sliderRef = useRef<HTMLDivElement>(null);\n const targetWindow = useWindow();\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n if (!sliderRef.current) return;\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n lastValueRef.current = newValue;\n setValue(newValue);\n onChange?.(event, newValue);\n },\n [decimalPlaces, marks, max, min, onChange, setValue, restrictToMarks, step],\n );\n\n const handleDragEnd = useCallback(\n (event: Event) => {\n setIsDragging(false);\n setIsFocusVisible(false);\n onChangeEnd?.(event, lastValueRef.current);\n },\n [onChangeEnd],\n );\n\n useEffect(() => {\n if (isDragging) {\n targetWindow?.addEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.addEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.addEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.addEventListener(\"blur\", handleDragEnd);\n targetWindow?.addEventListener(\"contextmenu\", handleDragEnd);\n } else {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.removeEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.removeEventListener(\"blur\", handleDragEnd);\n targetWindow?.removeEventListener(\"contextmenu\", handleDragEnd);\n }\n\n return () => {\n targetWindow?.removeEventListener(\"pointermove\", handlePointerMove);\n targetWindow?.removeEventListener(\"pointerup\", handleDragEnd);\n targetWindow?.removeEventListener(\"pointercancel\", handleDragEnd);\n targetWindow?.removeEventListener(\"blur\", handleDragEnd);\n targetWindow?.removeEventListener(\"contextmenu\", handleDragEnd);\n };\n }, [isDragging, targetWindow, handlePointerMove, handleDragEnd]);\n\n const handlePointerDownOnThumb = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (inputRef.current) inputRef.current.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n },\n [inputRef],\n );\n\n const handlePointerDownOnTrack = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n if (inputRef.current) inputRef.current.focus();\n setIsDragging(true);\n setIsFocusVisible(false);\n const newValue = getClickedPosition(\n sliderRef,\n event.clientX,\n max,\n min,\n step,\n decimalPlaces,\n marks,\n restrictToMarks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n lastValueRef.current = newValue;\n setValue(newValue);\n onChange?.(event.nativeEvent, newValue);\n },\n [\n decimalPlaces,\n inputRef,\n marks,\n max,\n min,\n onChange,\n restrictToMarks,\n setValue,\n step,\n ],\n );\n\n const handleKeydownOnThumb = useCallback(\n (event: React.KeyboardEvent) => {\n const newValue = getKeyboardValue(\n event,\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n );\n if (newValue === undefined || lastValueRef.current === newValue) {\n return;\n }\n setIsFocusVisible(true);\n lastValueRef.current = newValue;\n handleInputChange({\n target: { value: newValue.toString() },\n } as ChangeEvent<HTMLInputElement>);\n },\n [\n value,\n step,\n stepMultiplier,\n max,\n min,\n restrictToMarks,\n marks,\n handleInputChange,\n ],\n );\n\n const handleFocus = () => setIsFocusVisible(true);\n const handleBlur = () => setIsFocusVisible(false);\n\n return {\n handleBlur,\n handleFocus,\n handleKeydownOnThumb,\n handlePointerDownOnThumb,\n handlePointerDownOnTrack,\n isDragging,\n isFocusVisible,\n sliderRef,\n };\n};\n"],"names":["useState","useRef","useWindow","useCallback","getClickedPosition","useEffect","getKeyboardValue"],"mappings":"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"}
|