@doneisbetter/gds-core 3.0.0 → 3.0.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/dist/{chunk-NBCULITN.mjs → chunk-6FX7WZZO.mjs} +856 -155
- package/dist/{chunk-P7ICTEEB.mjs → chunk-YP7RL2MC.mjs} +784 -364
- package/dist/client.d.mts +259 -8
- package/dist/client.d.ts +259 -8
- package/dist/client.js +1720 -562
- package/dist/client.mjs +74 -4
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1720 -562
- package/dist/index.mjs +74 -4
- package/dist/{server-woziKWie.d.mts → server-DCXU_K9q.d.mts} +144 -4
- package/dist/{server-woziKWie.d.ts → server-DCXU_K9q.d.ts} +144 -4
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +831 -395
- package/dist/server.mjs +29 -1
- package/package.json +2 -2
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
FormField,
|
|
4
4
|
GdsIcons,
|
|
5
5
|
ListingCard,
|
|
6
|
+
NotificationCenterView,
|
|
6
7
|
ReferenceSection,
|
|
7
8
|
StateBlock,
|
|
8
9
|
getSemanticActionLabel,
|
|
9
10
|
resolveSemanticActionConfig
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YP7RL2MC.mjs";
|
|
11
12
|
|
|
12
13
|
// src/SemanticButton.tsx
|
|
13
14
|
import { useEffect, useState } from "react";
|
|
@@ -96,12 +97,14 @@ function ConfirmDialog({
|
|
|
96
97
|
import { ActionIcon, useMantineColorScheme, useComputedColorScheme } from "@mantine/core";
|
|
97
98
|
import { useGdsTranslation as useGdsTranslation2 } from "@doneisbetter/gds-theme";
|
|
98
99
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
99
|
-
function ThemeToggle({ size = "md" }) {
|
|
100
|
+
function ThemeToggle({ size = "md", onColorSchemeChange }) {
|
|
100
101
|
const { setColorScheme } = useMantineColorScheme();
|
|
101
102
|
const computedColorScheme = useComputedColorScheme("light", { getInitialValueInEffect: true });
|
|
102
103
|
const { t } = useGdsTranslation2();
|
|
103
104
|
const toggleColorScheme = () => {
|
|
104
|
-
|
|
105
|
+
const nextScheme = computedColorScheme === "dark" ? "light" : "dark";
|
|
106
|
+
setColorScheme(nextScheme);
|
|
107
|
+
onColorSchemeChange?.(nextScheme);
|
|
105
108
|
};
|
|
106
109
|
const isDark = computedColorScheme === "dark";
|
|
107
110
|
return /* @__PURE__ */ jsx3(
|
|
@@ -117,7 +120,7 @@ function ThemeToggle({ size = "md" }) {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
// src/ReferenceThemeExplorer.tsx
|
|
120
|
-
import { useMemo, useState as useState2 } from "react";
|
|
123
|
+
import { useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
121
124
|
import {
|
|
122
125
|
Badge,
|
|
123
126
|
Button as Button2,
|
|
@@ -134,61 +137,32 @@ import {
|
|
|
134
137
|
} from "@mantine/core";
|
|
135
138
|
import {
|
|
136
139
|
GdsProvider,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
gdsTheme
|
|
140
|
+
applyGdsFontLane,
|
|
141
|
+
getGdsFontLanes,
|
|
142
|
+
getGdsThemePresets,
|
|
143
|
+
resolveGdsThemePreset
|
|
142
144
|
} from "@doneisbetter/gds-theme";
|
|
143
145
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
144
146
|
function resolvePreviewColorScheme(presetId, requestedScheme) {
|
|
145
|
-
if (presetId === "dark-public") {
|
|
147
|
+
if (presetId === "dark-public" || presetId === "neon-night") {
|
|
146
148
|
return "dark";
|
|
147
149
|
}
|
|
148
150
|
return requestedScheme;
|
|
149
151
|
}
|
|
150
|
-
var
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
supportedUse: "Products with a deliberate dark visual baseline, low-light UX, or premium media-first surfaces.",
|
|
165
|
-
avoidFor: "Avoid when mixed mode and editorial readability are core requirements."
|
|
166
|
-
},
|
|
167
|
-
"flat-surface": {
|
|
168
|
-
label: "Flat surface theme",
|
|
169
|
-
bestFor: "Operational products that prefer quieter elevation and flatter surface contrast.",
|
|
170
|
-
summary: "Removes some visual weight without creating a second token authority.",
|
|
171
|
-
themeKey: "gdsFlatSurfaceTheme",
|
|
172
|
-
supportedUse: "Dashboards, admin surfaces, and dense content where elevation becomes distracting.",
|
|
173
|
-
avoidFor: "Avoid for brand-first storytelling or high-expressiveness hero-first pages."
|
|
174
|
-
},
|
|
175
|
-
editorial: {
|
|
176
|
-
label: "Editorial serif theme",
|
|
177
|
-
bestFor: "Documentation, editorial, and content-led experiences.",
|
|
178
|
-
summary: "Adds a more expressive public reading tone while staying inside GDS contracts.",
|
|
179
|
-
themeKey: "gdsEditorialPublicTheme",
|
|
180
|
-
supportedUse: "Guides, docs, and catalog content where reading comfort matters more than impact.",
|
|
181
|
-
avoidFor: "Avoid for dense transactional or data-first workflows with strict minimal contrast."
|
|
182
|
-
},
|
|
183
|
-
brand: {
|
|
184
|
-
label: "Brand theme generator",
|
|
185
|
-
bestFor: "Consumer teams that need controlled brand expression without forking the system.",
|
|
186
|
-
summary: "Composes the shipped helpers into a governed product-authored theme lane.",
|
|
187
|
-
themeKey: "createPublicBrandTheme(...)",
|
|
188
|
-
supportedUse: "Whitelisted public branding programs with narrow product-authored intent and policy guardrails.",
|
|
189
|
-
avoidFor: "Avoid for local style experiments or temporary visual fixes without compliance approval."
|
|
190
|
-
}
|
|
191
|
-
};
|
|
152
|
+
var presetCatalog = getGdsThemePresets();
|
|
153
|
+
var themePresetCatalog = Object.fromEntries(
|
|
154
|
+
presetCatalog.map((preset) => [
|
|
155
|
+
preset.id,
|
|
156
|
+
{
|
|
157
|
+
label: preset.label,
|
|
158
|
+
bestFor: `Apps aligned with ${preset.label.toLowerCase()}.`,
|
|
159
|
+
summary: preset.description,
|
|
160
|
+
themeKey: preset.runtimeLane,
|
|
161
|
+
supportedUse: `General product adoption with ${preset.label}.`,
|
|
162
|
+
avoidFor: "Avoid creating a local non-canonical theme authority."
|
|
163
|
+
}
|
|
164
|
+
])
|
|
165
|
+
);
|
|
192
166
|
var colorSchemeProof = [
|
|
193
167
|
{
|
|
194
168
|
id: "light",
|
|
@@ -269,40 +243,50 @@ function ThemePreviewSurface({
|
|
|
269
243
|
] })
|
|
270
244
|
] }) });
|
|
271
245
|
}
|
|
272
|
-
function ReferenceThemeExplorer(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const [
|
|
277
|
-
const [
|
|
246
|
+
function ReferenceThemeExplorer({
|
|
247
|
+
initialSelection,
|
|
248
|
+
onSelectionChange
|
|
249
|
+
}) {
|
|
250
|
+
const [preset, setPreset] = useState2(initialSelection?.preset ?? "default");
|
|
251
|
+
const [colorScheme, setColorScheme] = useState2(initialSelection?.colorScheme ?? "light");
|
|
252
|
+
const [brandPrimary, setBrandPrimary] = useState2(initialSelection?.brandPrimary ?? "blue");
|
|
253
|
+
const [brandFlatSurfaces, setBrandFlatSurfaces] = useState2(initialSelection?.brandFlatSurfaces ?? true);
|
|
254
|
+
const [brandEditorialSerif, setBrandEditorialSerif] = useState2(initialSelection?.brandEditorialSerif ?? false);
|
|
255
|
+
const [fontLane, setFontLane] = useState2(initialSelection?.fontLane ?? "inter");
|
|
278
256
|
const [comparisonEnabled, setComparisonEnabled] = useState2(false);
|
|
279
257
|
const [comparisonPreset, setComparisonPreset] = useState2("editorial");
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
case "editorial":
|
|
287
|
-
return gdsEditorialPublicTheme;
|
|
288
|
-
case "brand":
|
|
289
|
-
return createPublicBrandTheme({
|
|
290
|
-
flatSurfaces: brandFlatSurfaces,
|
|
291
|
-
editorialSerif: brandEditorialSerif,
|
|
292
|
-
overrides: { primaryColor: brandPrimary }
|
|
293
|
-
});
|
|
294
|
-
default:
|
|
295
|
-
return gdsTheme;
|
|
296
|
-
}
|
|
297
|
-
};
|
|
258
|
+
const availableComparisonPresets = presetCatalog.filter((item) => item.id !== preset).map((item) => item.id);
|
|
259
|
+
const resolveTheme = (presetId) => applyGdsFontLane(resolveGdsThemePreset(presetId, {
|
|
260
|
+
brandPrimary,
|
|
261
|
+
brandFlatSurfaces,
|
|
262
|
+
brandEditorialSerif
|
|
263
|
+
}), fontLane);
|
|
298
264
|
const selectionSummary = themePresetCatalog[preset];
|
|
299
265
|
const comparisonSummary = themePresetCatalog[comparisonPreset];
|
|
300
|
-
const selectedTheme = useMemo(() => resolveTheme(preset), [preset, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
|
|
301
|
-
const comparedTheme = useMemo(() => resolveTheme(comparisonPreset), [comparisonPreset, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
|
|
266
|
+
const selectedTheme = useMemo(() => resolveTheme(preset), [preset, brandPrimary, brandFlatSurfaces, brandEditorialSerif, fontLane]);
|
|
267
|
+
const comparedTheme = useMemo(() => resolveTheme(comparisonPreset), [comparisonPreset, brandPrimary, brandFlatSurfaces, brandEditorialSerif, fontLane]);
|
|
302
268
|
const effectiveColorScheme = resolvePreviewColorScheme(preset, colorScheme);
|
|
303
269
|
const effectiveComparisonScheme = resolvePreviewColorScheme(comparisonPreset, colorScheme);
|
|
304
|
-
const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}`;
|
|
305
|
-
const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}`;
|
|
270
|
+
const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
|
|
271
|
+
const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
|
|
272
|
+
useEffect2(() => {
|
|
273
|
+
onSelectionChange?.({
|
|
274
|
+
preset,
|
|
275
|
+
colorScheme: effectiveColorScheme,
|
|
276
|
+
theme: selectedTheme,
|
|
277
|
+
fontLane,
|
|
278
|
+
runtimeKey: previewKey,
|
|
279
|
+
brandPrimary,
|
|
280
|
+
brandFlatSurfaces,
|
|
281
|
+
brandEditorialSerif
|
|
282
|
+
});
|
|
283
|
+
}, [onSelectionChange, preset, effectiveColorScheme, selectedTheme, fontLane, previewKey, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
|
|
284
|
+
useEffect2(() => {
|
|
285
|
+
if (comparisonPreset !== preset) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
setComparisonPreset(availableComparisonPresets[0] ?? "editorial");
|
|
289
|
+
}, [comparisonPreset, preset, availableComparisonPresets]);
|
|
306
290
|
const reset = () => {
|
|
307
291
|
setPreset("default");
|
|
308
292
|
setColorScheme("light");
|
|
@@ -311,6 +295,7 @@ function ReferenceThemeExplorer() {
|
|
|
311
295
|
setBrandEditorialSerif(false);
|
|
312
296
|
setComparisonEnabled(false);
|
|
313
297
|
setComparisonPreset("editorial");
|
|
298
|
+
setFontLane("inter");
|
|
314
299
|
};
|
|
315
300
|
return /* @__PURE__ */ jsxs2(Stack, { gap: "xl", children: [
|
|
316
301
|
/* @__PURE__ */ jsx4(
|
|
@@ -343,8 +328,17 @@ function ReferenceThemeExplorer() {
|
|
|
343
328
|
]
|
|
344
329
|
}
|
|
345
330
|
) }),
|
|
331
|
+
/* @__PURE__ */ jsx4(FormField, { label: "Webfont lane", children: /* @__PURE__ */ jsx4(
|
|
332
|
+
NativeSelect,
|
|
333
|
+
{
|
|
334
|
+
"aria-label": "Webfont lane",
|
|
335
|
+
value: fontLane,
|
|
336
|
+
onChange: (event) => setFontLane(event.currentTarget.value || "inter"),
|
|
337
|
+
data: getGdsFontLanes().map((lane) => ({ value: lane.id, label: lane.label }))
|
|
338
|
+
}
|
|
339
|
+
) }),
|
|
346
340
|
/* @__PURE__ */ jsx4(Button2, { variant: "default", size: "sm", onClick: reset, children: "Reset theme lab" }),
|
|
347
|
-
/* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: "
|
|
341
|
+
/* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: "Theme changes apply to the official site shell so visitors can validate real whole-page runtime behavior." })
|
|
348
342
|
] }) }),
|
|
349
343
|
/* @__PURE__ */ jsx4(Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ jsxs2(Stack, { gap: "md", children: [
|
|
350
344
|
/* @__PURE__ */ jsx4(Title, { order: 4, children: "Brand builder options" }),
|
|
@@ -398,7 +392,7 @@ function ReferenceThemeExplorer() {
|
|
|
398
392
|
" ",
|
|
399
393
|
colorScheme
|
|
400
394
|
] }),
|
|
401
|
-
preset === "dark-public" && colorScheme !== effectiveColorScheme ? /* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: "
|
|
395
|
+
(preset === "dark-public" || preset === "neon-night") && colorScheme !== effectiveColorScheme ? /* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: "This dark-forward preset always renders in dark mode inside the live preview." }) : null
|
|
402
396
|
] }),
|
|
403
397
|
/* @__PURE__ */ jsx4(
|
|
404
398
|
Checkbox,
|
|
@@ -416,7 +410,7 @@ function ReferenceThemeExplorer() {
|
|
|
416
410
|
value: comparisonPreset,
|
|
417
411
|
onChange: (event) => setComparisonPreset(event.currentTarget.value || "editorial"),
|
|
418
412
|
disabled: !comparisonEnabled,
|
|
419
|
-
data:
|
|
413
|
+
data: availableComparisonPresets.map((value) => ({ value, label: themePresetCatalog[value].label }))
|
|
420
414
|
}
|
|
421
415
|
) })
|
|
422
416
|
] }) })
|
|
@@ -564,10 +558,118 @@ function GameBoardTile({
|
|
|
564
558
|
) });
|
|
565
559
|
}
|
|
566
560
|
|
|
561
|
+
// src/ListingState.client.tsx
|
|
562
|
+
import { createContext, useContext, useMemo as useMemo2, useReducer } from "react";
|
|
563
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
564
|
+
function createInitialState(config = {}) {
|
|
565
|
+
return {
|
|
566
|
+
search: "",
|
|
567
|
+
sort: config.defaultSort ?? "newest",
|
|
568
|
+
filters: [],
|
|
569
|
+
page: 1,
|
|
570
|
+
pageSize: config.defaultPageSize ?? 25,
|
|
571
|
+
selection: []
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function listingQueryReducer(state, action) {
|
|
575
|
+
if (action.type === "set-search") {
|
|
576
|
+
return { ...state, search: action.value, page: 1, selection: [] };
|
|
577
|
+
}
|
|
578
|
+
if (action.type === "set-sort") {
|
|
579
|
+
return { ...state, sort: action.value, page: 1, selection: [] };
|
|
580
|
+
}
|
|
581
|
+
if (action.type === "toggle-filter") {
|
|
582
|
+
const exists = state.filters.includes(action.value);
|
|
583
|
+
return {
|
|
584
|
+
...state,
|
|
585
|
+
filters: exists ? state.filters.filter((item) => item !== action.value) : [...state.filters, action.value],
|
|
586
|
+
page: 1,
|
|
587
|
+
selection: []
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
if (action.type === "clear-filters") {
|
|
591
|
+
return { ...state, filters: [], page: 1, selection: [] };
|
|
592
|
+
}
|
|
593
|
+
if (action.type === "set-page") {
|
|
594
|
+
return { ...state, page: Math.max(1, Math.floor(action.value)) };
|
|
595
|
+
}
|
|
596
|
+
if (action.type === "set-page-size") {
|
|
597
|
+
const nextPageSize = Math.max(1, Math.floor(action.value));
|
|
598
|
+
return { ...state, pageSize: nextPageSize, page: 1, selection: [] };
|
|
599
|
+
}
|
|
600
|
+
if (action.type === "toggle-selection") {
|
|
601
|
+
const exists = state.selection.includes(action.value);
|
|
602
|
+
return {
|
|
603
|
+
...state,
|
|
604
|
+
selection: exists ? state.selection.filter((item) => item !== action.value) : [...state.selection, action.value]
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
if (action.type === "clear-selection") {
|
|
608
|
+
return { ...state, selection: [] };
|
|
609
|
+
}
|
|
610
|
+
return createInitialState({ defaultSort: state.sort, defaultPageSize: state.pageSize });
|
|
611
|
+
}
|
|
612
|
+
var ListingStateContext = createContext(null);
|
|
613
|
+
function ListingProvider({
|
|
614
|
+
children,
|
|
615
|
+
config
|
|
616
|
+
}) {
|
|
617
|
+
const [state, dispatch] = useReducer(listingQueryReducer, config, createInitialState);
|
|
618
|
+
const value = useMemo2(() => ({ state, dispatch }), [state]);
|
|
619
|
+
return /* @__PURE__ */ jsx6(ListingStateContext.Provider, { value, children });
|
|
620
|
+
}
|
|
621
|
+
function useListingState() {
|
|
622
|
+
const context = useContext(ListingStateContext);
|
|
623
|
+
if (!context) {
|
|
624
|
+
throw new Error("useListingState must be used within ListingProvider.");
|
|
625
|
+
}
|
|
626
|
+
return context;
|
|
627
|
+
}
|
|
628
|
+
|
|
567
629
|
// src/DiscoveryShell.tsx
|
|
630
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
568
631
|
import { AppShell as MantineAppShell, Box, Burger, Group as Group3, ScrollArea } from "@mantine/core";
|
|
569
|
-
import {
|
|
570
|
-
import { jsx as
|
|
632
|
+
import { useMediaQuery as useMediaQuery2 } from "@mantine/hooks";
|
|
633
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
634
|
+
function useDiscoveryShellState({
|
|
635
|
+
defaultSidebarOpen = false,
|
|
636
|
+
sidebarStorageKey,
|
|
637
|
+
onSidebarOpenedChange
|
|
638
|
+
} = {}) {
|
|
639
|
+
const [opened, setOpenedState] = useState3(defaultSidebarOpen);
|
|
640
|
+
useEffect3(() => {
|
|
641
|
+
if (!sidebarStorageKey || typeof window === "undefined") {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
const stored = window.localStorage.getItem(sidebarStorageKey);
|
|
645
|
+
if (stored === "open") {
|
|
646
|
+
setOpenedState(true);
|
|
647
|
+
}
|
|
648
|
+
if (stored === "closed") {
|
|
649
|
+
setOpenedState(false);
|
|
650
|
+
}
|
|
651
|
+
}, [sidebarStorageKey]);
|
|
652
|
+
const persistAndNotify = (next) => {
|
|
653
|
+
if (sidebarStorageKey && typeof window !== "undefined") {
|
|
654
|
+
window.localStorage.setItem(sidebarStorageKey, next ? "open" : "closed");
|
|
655
|
+
}
|
|
656
|
+
onSidebarOpenedChange?.(next);
|
|
657
|
+
};
|
|
658
|
+
const setOpened = (next) => {
|
|
659
|
+
setOpenedState(next);
|
|
660
|
+
persistAndNotify(next);
|
|
661
|
+
};
|
|
662
|
+
const open = () => setOpened(true);
|
|
663
|
+
const close = () => setOpened(false);
|
|
664
|
+
const toggle = () => {
|
|
665
|
+
setOpenedState((current) => {
|
|
666
|
+
const next = !current;
|
|
667
|
+
persistAndNotify(next);
|
|
668
|
+
return next;
|
|
669
|
+
});
|
|
670
|
+
};
|
|
671
|
+
return { opened, open, close, toggle, setOpened };
|
|
672
|
+
}
|
|
571
673
|
function DiscoveryShell({
|
|
572
674
|
header,
|
|
573
675
|
sidebar,
|
|
@@ -575,13 +677,29 @@ function DiscoveryShell({
|
|
|
575
677
|
children,
|
|
576
678
|
mobileNavigationLabel = "Toggle navigation",
|
|
577
679
|
defaultSidebarOpen = false,
|
|
680
|
+
sidebarStorageKey,
|
|
681
|
+
sidebarOpened,
|
|
682
|
+
onSidebarOpenedChange,
|
|
578
683
|
stickySidebar = true,
|
|
684
|
+
desktopCollapsible = false,
|
|
685
|
+
desktopNavigationLabel = "Toggle sidebar",
|
|
579
686
|
sidebarWidth = 280,
|
|
580
687
|
headerHeight = 60,
|
|
581
688
|
shellPadding = "md",
|
|
582
689
|
collapseBreakpoint = "sm"
|
|
583
690
|
}) {
|
|
584
|
-
const
|
|
691
|
+
const breakpointByAlias = {
|
|
692
|
+
xs: "36em",
|
|
693
|
+
sm: "48em",
|
|
694
|
+
md: "62em",
|
|
695
|
+
lg: "75em",
|
|
696
|
+
xl: "88em"
|
|
697
|
+
};
|
|
698
|
+
const isMobile = useMediaQuery2(`(max-width: ${breakpointByAlias[collapseBreakpoint]})`);
|
|
699
|
+
const shellState = useDiscoveryShellState({ defaultSidebarOpen, sidebarStorageKey, onSidebarOpenedChange });
|
|
700
|
+
const opened = sidebarOpened ?? shellState.opened;
|
|
701
|
+
const close = onSidebarOpenedChange ? () => onSidebarOpenedChange(false) : shellState.close;
|
|
702
|
+
const toggle = onSidebarOpenedChange ? () => onSidebarOpenedChange(!opened) : shellState.toggle;
|
|
585
703
|
return /* @__PURE__ */ jsxs3(
|
|
586
704
|
MantineAppShell,
|
|
587
705
|
{
|
|
@@ -590,12 +708,15 @@ function DiscoveryShell({
|
|
|
590
708
|
navbar: {
|
|
591
709
|
width: sidebarWidth,
|
|
592
710
|
breakpoint: collapseBreakpoint,
|
|
593
|
-
collapsed: {
|
|
711
|
+
collapsed: {
|
|
712
|
+
mobile: !opened,
|
|
713
|
+
desktop: desktopCollapsible ? !opened : false
|
|
714
|
+
}
|
|
594
715
|
},
|
|
595
716
|
padding: shellPadding,
|
|
596
717
|
children: [
|
|
597
|
-
/* @__PURE__ */
|
|
598
|
-
/* @__PURE__ */
|
|
718
|
+
/* @__PURE__ */ jsx7(MantineAppShell.Header, { children: /* @__PURE__ */ jsxs3(Group3, { h: "100%", px: "md", gap: "sm", wrap: "nowrap", children: [
|
|
719
|
+
/* @__PURE__ */ jsx7(
|
|
599
720
|
Burger,
|
|
600
721
|
{
|
|
601
722
|
opened,
|
|
@@ -605,9 +726,19 @@ function DiscoveryShell({
|
|
|
605
726
|
"aria-label": mobileNavigationLabel
|
|
606
727
|
}
|
|
607
728
|
),
|
|
608
|
-
/* @__PURE__ */
|
|
729
|
+
desktopCollapsible ? /* @__PURE__ */ jsx7(
|
|
730
|
+
Burger,
|
|
731
|
+
{
|
|
732
|
+
opened,
|
|
733
|
+
onClick: toggle,
|
|
734
|
+
visibleFrom: collapseBreakpoint,
|
|
735
|
+
size: "sm",
|
|
736
|
+
"aria-label": desktopNavigationLabel
|
|
737
|
+
}
|
|
738
|
+
) : null,
|
|
739
|
+
/* @__PURE__ */ jsx7(Box, { style: { flex: 1, minWidth: 0 }, children: header })
|
|
609
740
|
] }) }),
|
|
610
|
-
/* @__PURE__ */
|
|
741
|
+
/* @__PURE__ */ jsx7(MantineAppShell.Navbar, { p: "md", "data-sticky-sidebar": stickySidebar || void 0, children: /* @__PURE__ */ jsx7(ScrollArea, { h: "100%", type: "auto", children: /* @__PURE__ */ jsx7(
|
|
611
742
|
Box,
|
|
612
743
|
{
|
|
613
744
|
h: "100%",
|
|
@@ -618,27 +749,37 @@ function DiscoveryShell({
|
|
|
618
749
|
children: sidebar
|
|
619
750
|
}
|
|
620
751
|
) }) }),
|
|
621
|
-
footer ? /* @__PURE__ */
|
|
622
|
-
/* @__PURE__ */
|
|
752
|
+
footer ? /* @__PURE__ */ jsx7(MantineAppShell.Footer, { children: /* @__PURE__ */ jsx7(Group3, { h: "100%", px: "md", justify: "space-around", wrap: "nowrap", children: footer }) }) : null,
|
|
753
|
+
/* @__PURE__ */ jsx7(
|
|
754
|
+
MantineAppShell.Main,
|
|
755
|
+
{
|
|
756
|
+
onClick: () => {
|
|
757
|
+
if (isMobile) {
|
|
758
|
+
close();
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
children
|
|
762
|
+
}
|
|
763
|
+
)
|
|
623
764
|
]
|
|
624
765
|
}
|
|
625
766
|
);
|
|
626
767
|
}
|
|
627
768
|
|
|
628
769
|
// src/DocsShell.tsx
|
|
629
|
-
import { useState as
|
|
770
|
+
import { useState as useState4 } from "react";
|
|
630
771
|
import { Box as Box2, Burger as Burger2, Container, Divider, Group as Group4, Stack as Stack2, Text as Text4, Transition } from "@mantine/core";
|
|
631
|
-
import { Fragment, jsx as
|
|
772
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
632
773
|
function DocsShellSidebar({ primaryNavigation, secondaryNavigation }) {
|
|
633
774
|
return /* @__PURE__ */ jsxs4(Stack2, { gap: "md", h: "100%", children: [
|
|
634
775
|
primaryNavigation ? /* @__PURE__ */ jsxs4(Stack2, { gap: "xs", children: [
|
|
635
|
-
/* @__PURE__ */
|
|
776
|
+
/* @__PURE__ */ jsx8(Text4, { size: "xs", fw: 700, c: "dimmed", children: "Primary" }),
|
|
636
777
|
primaryNavigation
|
|
637
778
|
] }) : null,
|
|
638
779
|
secondaryNavigation ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
639
|
-
/* @__PURE__ */
|
|
780
|
+
/* @__PURE__ */ jsx8(Divider, {}),
|
|
640
781
|
/* @__PURE__ */ jsxs4(Stack2, { gap: "xs", children: [
|
|
641
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ jsx8(Text4, { size: "xs", fw: 700, c: "dimmed", children: "More" }),
|
|
642
783
|
secondaryNavigation
|
|
643
784
|
] })
|
|
644
785
|
] }) : null
|
|
@@ -662,14 +803,14 @@ function DocsShell({
|
|
|
662
803
|
children,
|
|
663
804
|
contentWidth = "full"
|
|
664
805
|
}) {
|
|
665
|
-
const [mobileNavOpen, setMobileNavOpen] =
|
|
666
|
-
return /* @__PURE__ */
|
|
806
|
+
const [mobileNavOpen, setMobileNavOpen] = useState4(false);
|
|
807
|
+
return /* @__PURE__ */ jsx8(
|
|
667
808
|
DiscoveryShell,
|
|
668
809
|
{
|
|
669
810
|
header: /* @__PURE__ */ jsxs4(Group4, { h: "100%", justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
|
|
670
811
|
/* @__PURE__ */ jsxs4(Group4, { gap: "sm", align: "center", wrap: "nowrap", style: { minWidth: 0 }, children: [
|
|
671
812
|
mobileNavigationMode === "inline-collapse" && mobileNavigation ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
672
|
-
/* @__PURE__ */
|
|
813
|
+
/* @__PURE__ */ jsx8(
|
|
673
814
|
Burger2,
|
|
674
815
|
{
|
|
675
816
|
opened: mobileNavOpen,
|
|
@@ -679,14 +820,14 @@ function DocsShell({
|
|
|
679
820
|
"aria-label": "Toggle docs navigation"
|
|
680
821
|
}
|
|
681
822
|
),
|
|
682
|
-
/* @__PURE__ */
|
|
823
|
+
/* @__PURE__ */ jsx8(Transition, { mounted: mobileNavOpen, transition: "pop", duration: 120, children: (styles) => /* @__PURE__ */ jsx8(Box2, { style: styles, children: /* @__PURE__ */ jsx8(Box2, { mt: "xs", p: "sm", style: { borderRadius: 8, border: "1px solid var(--mantine-color-default-border)" }, children: mobileNavigation }) }) })
|
|
683
824
|
] }) : null,
|
|
684
|
-
/* @__PURE__ */
|
|
685
|
-
headerContext ? /* @__PURE__ */
|
|
825
|
+
/* @__PURE__ */ jsx8(Box2, { style: { minWidth: 0 }, children: brand }),
|
|
826
|
+
headerContext ? /* @__PURE__ */ jsx8(Text4, { size: "sm", c: "dimmed", lineClamp: 1, children: headerContext }) : null
|
|
686
827
|
] }),
|
|
687
|
-
/* @__PURE__ */
|
|
828
|
+
/* @__PURE__ */ jsx8(Group4, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: actions })
|
|
688
829
|
] }),
|
|
689
|
-
sidebar: /* @__PURE__ */
|
|
830
|
+
sidebar: /* @__PURE__ */ jsx8(
|
|
690
831
|
DocsShellSidebar,
|
|
691
832
|
{
|
|
692
833
|
primaryNavigation,
|
|
@@ -696,7 +837,7 @@ function DocsShell({
|
|
|
696
837
|
footer,
|
|
697
838
|
mobileNavigationLabel: "Open docs navigation",
|
|
698
839
|
headerHeight: 72,
|
|
699
|
-
children: /* @__PURE__ */
|
|
840
|
+
children: /* @__PURE__ */ jsx8(Container, { size: resolveContentContainerSize(contentWidth), px: "md", py: "lg", w: "100%", children })
|
|
700
841
|
}
|
|
701
842
|
);
|
|
702
843
|
}
|
|
@@ -705,14 +846,14 @@ function DocsShell({
|
|
|
705
846
|
import { forwardRef } from "react";
|
|
706
847
|
import { Box as Box3, NavLink, Stack as Stack3, Text as Text5, createPolymorphicComponent } from "@mantine/core";
|
|
707
848
|
import { useGdsTranslation as useGdsTranslation3 } from "@doneisbetter/gds-theme";
|
|
708
|
-
import { jsx as
|
|
849
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
709
850
|
function SidebarNav({ children, ariaLabel = "Primary navigation", gap = "md" }) {
|
|
710
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsx9(Stack3, { component: "nav", "aria-label": ariaLabel, gap, h: "100%", children });
|
|
711
852
|
}
|
|
712
853
|
function SidebarNavSection({ label, children, pushToBottom = false }) {
|
|
713
854
|
return /* @__PURE__ */ jsxs5(Stack3, { gap: "xs", mt: pushToBottom ? "auto" : void 0, children: [
|
|
714
|
-
label ? /* @__PURE__ */
|
|
715
|
-
/* @__PURE__ */
|
|
855
|
+
label ? /* @__PURE__ */ jsx9(Text5, { size: "xs", fw: 700, c: "dimmed", children: label }) : null,
|
|
856
|
+
/* @__PURE__ */ jsx9(Stack3, { gap: 4, children })
|
|
716
857
|
] });
|
|
717
858
|
}
|
|
718
859
|
var _SidebarNavItem = forwardRef(
|
|
@@ -731,14 +872,14 @@ var _SidebarNavItem = forwardRef(
|
|
|
731
872
|
const config = action ? resolveSemanticActionConfig(action, vocabularyPacks) : null;
|
|
732
873
|
const Icon = config?.icon;
|
|
733
874
|
const resolvedLabel = label ?? (action ? getSemanticActionLabel(action, t, vocabularyPacks) : void 0);
|
|
734
|
-
return /* @__PURE__ */
|
|
875
|
+
return /* @__PURE__ */ jsx9(
|
|
735
876
|
NavLink,
|
|
736
877
|
{
|
|
737
878
|
ref,
|
|
738
879
|
label: resolvedLabel,
|
|
739
880
|
description,
|
|
740
|
-
leftSection: icon ?? (Icon ? /* @__PURE__ */
|
|
741
|
-
rightSection: badge ? /* @__PURE__ */
|
|
881
|
+
leftSection: icon ?? (Icon ? /* @__PURE__ */ jsx9(Icon, { size: "1rem", stroke: 1.5 }) : void 0),
|
|
882
|
+
rightSection: badge ? /* @__PURE__ */ jsx9(Box3, { children: badge }) : props.rightSection,
|
|
742
883
|
"aria-label": ariaLabel ?? (typeof resolvedLabel === "string" ? resolvedLabel : void 0),
|
|
743
884
|
"aria-current": props.active ? "page" : ariaCurrent,
|
|
744
885
|
...props
|
|
@@ -749,11 +890,11 @@ var _SidebarNavItem = forwardRef(
|
|
|
749
890
|
var SidebarNavItem = createPolymorphicComponent(_SidebarNavItem);
|
|
750
891
|
|
|
751
892
|
// src/DocsCodeBlock.tsx
|
|
752
|
-
import { useState as
|
|
893
|
+
import { useState as useState5 } from "react";
|
|
753
894
|
import { ActionIcon as ActionIcon2, Code as Code2, Group as Group5, Paper as Paper3, Stack as Stack4, Text as Text6 } from "@mantine/core";
|
|
754
|
-
import { jsx as
|
|
895
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
755
896
|
function DocsCodeBlock({ code, language, title, withCopy = true }) {
|
|
756
|
-
const [copied, setCopied] =
|
|
897
|
+
const [copied, setCopied] = useState5(false);
|
|
757
898
|
const handleCopy = async () => {
|
|
758
899
|
if (!navigator?.clipboard) {
|
|
759
900
|
return;
|
|
@@ -762,13 +903,13 @@ function DocsCodeBlock({ code, language, title, withCopy = true }) {
|
|
|
762
903
|
setCopied(true);
|
|
763
904
|
window.setTimeout(() => setCopied(false), 1200);
|
|
764
905
|
};
|
|
765
|
-
return /* @__PURE__ */
|
|
906
|
+
return /* @__PURE__ */ jsx10(Paper3, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ jsxs6(Stack4, { gap: "sm", children: [
|
|
766
907
|
title || withCopy ? /* @__PURE__ */ jsxs6(Group5, { justify: "space-between", align: "center", children: [
|
|
767
908
|
/* @__PURE__ */ jsxs6(Stack4, { gap: 0, children: [
|
|
768
|
-
title ? /* @__PURE__ */
|
|
769
|
-
language ? /* @__PURE__ */
|
|
909
|
+
title ? /* @__PURE__ */ jsx10(Text6, { fw: 600, children: title }) : null,
|
|
910
|
+
language ? /* @__PURE__ */ jsx10(Text6, { size: "xs", c: "dimmed", children: language }) : null
|
|
770
911
|
] }),
|
|
771
|
-
withCopy ? /* @__PURE__ */
|
|
912
|
+
withCopy ? /* @__PURE__ */ jsx10(
|
|
772
913
|
ActionIcon2,
|
|
773
914
|
{
|
|
774
915
|
variant: "subtle",
|
|
@@ -776,18 +917,18 @@ function DocsCodeBlock({ code, language, title, withCopy = true }) {
|
|
|
776
917
|
onClick: () => {
|
|
777
918
|
void handleCopy();
|
|
778
919
|
},
|
|
779
|
-
children: /* @__PURE__ */
|
|
920
|
+
children: /* @__PURE__ */ jsx10(GdsIcons.Copy, { size: "1rem" })
|
|
780
921
|
}
|
|
781
922
|
) : null
|
|
782
923
|
] }) : null,
|
|
783
|
-
/* @__PURE__ */
|
|
924
|
+
/* @__PURE__ */ jsx10(Code2, { block: true, children: code })
|
|
784
925
|
] }) });
|
|
785
926
|
}
|
|
786
927
|
|
|
787
928
|
// src/ShareButtonGroup.tsx
|
|
788
|
-
import { useState as
|
|
929
|
+
import { useState as useState6 } from "react";
|
|
789
930
|
import { ActionIcon as ActionIcon3, Button as Button3, Group as Group6, Stack as Stack5, Text as Text7 } from "@mantine/core";
|
|
790
|
-
import { jsx as
|
|
931
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
791
932
|
var channelLabels = {
|
|
792
933
|
native: "Share",
|
|
793
934
|
copy: "Copy link",
|
|
@@ -822,9 +963,9 @@ function ShareAction({
|
|
|
822
963
|
const label = channelLabels[channel];
|
|
823
964
|
const Icon = channel === "copy" ? GdsIcons.Copy : channel === "mail" ? GdsIcons.Mail : channel === "message" ? GdsIcons.Message : GdsIcons.Refer;
|
|
824
965
|
if (compact) {
|
|
825
|
-
return href ? /* @__PURE__ */
|
|
966
|
+
return href ? /* @__PURE__ */ jsx11(ActionIcon3, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "subtle", size: "lg", "aria-label": label, children: /* @__PURE__ */ jsx11(Icon, { size: "1rem", stroke: 1.75 }) }) : /* @__PURE__ */ jsx11(ActionIcon3, { variant: "subtle", size: "lg", "aria-label": label, onClick, children: /* @__PURE__ */ jsx11(Icon, { size: "1rem", stroke: 1.75 }) });
|
|
826
967
|
}
|
|
827
|
-
return href ? /* @__PURE__ */
|
|
968
|
+
return href ? /* @__PURE__ */ jsx11(Button3, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "default", leftSection: /* @__PURE__ */ jsx11(Icon, { size: "1rem", stroke: 1.75 }), children: label }) : /* @__PURE__ */ jsx11(Button3, { variant: "default", leftSection: /* @__PURE__ */ jsx11(Icon, { size: "1rem", stroke: 1.75 }), onClick, children: label });
|
|
828
969
|
}
|
|
829
970
|
function ShareButtonGroup({
|
|
830
971
|
url,
|
|
@@ -835,8 +976,8 @@ function ShareButtonGroup({
|
|
|
835
976
|
label = "Share this",
|
|
836
977
|
description
|
|
837
978
|
}) {
|
|
838
|
-
const [copied, setCopied] =
|
|
839
|
-
const [shared, setShared] =
|
|
979
|
+
const [copied, setCopied] = useState6(false);
|
|
980
|
+
const [shared, setShared] = useState6(false);
|
|
840
981
|
const hrefs = encodeShare(url, title, text);
|
|
841
982
|
async function handleCopy() {
|
|
842
983
|
await navigator.clipboard?.writeText?.(url);
|
|
@@ -854,27 +995,27 @@ function ShareButtonGroup({
|
|
|
854
995
|
}
|
|
855
996
|
return /* @__PURE__ */ jsxs7(Stack5, { gap: "sm", children: [
|
|
856
997
|
/* @__PURE__ */ jsxs7(Stack5, { gap: 2, children: [
|
|
857
|
-
/* @__PURE__ */
|
|
858
|
-
description ? /* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsx11(Text7, { fw: 600, children: label }),
|
|
999
|
+
description ? /* @__PURE__ */ jsx11(Text7, { size: "sm", c: "dimmed", children: description }) : null
|
|
859
1000
|
] }),
|
|
860
|
-
/* @__PURE__ */
|
|
1001
|
+
/* @__PURE__ */ jsx11(Group6, { gap: "sm", wrap: "wrap", children: channels.map((channel) => {
|
|
861
1002
|
if (channel === "copy") {
|
|
862
|
-
return /* @__PURE__ */
|
|
1003
|
+
return /* @__PURE__ */ jsx11(ShareAction, { channel, compact, onClick: () => void handleCopy() }, channel);
|
|
863
1004
|
}
|
|
864
1005
|
if (channel === "native") {
|
|
865
|
-
return /* @__PURE__ */
|
|
1006
|
+
return /* @__PURE__ */ jsx11(ShareAction, { channel, compact, onClick: () => void handleNativeShare() }, channel);
|
|
866
1007
|
}
|
|
867
|
-
return /* @__PURE__ */
|
|
1008
|
+
return /* @__PURE__ */ jsx11(ShareAction, { channel, compact, href: hrefs[channel] }, channel);
|
|
868
1009
|
}) }),
|
|
869
|
-
copied ? /* @__PURE__ */
|
|
870
|
-
shared ? /* @__PURE__ */
|
|
1010
|
+
copied ? /* @__PURE__ */ jsx11(Text7, { size: "sm", c: "teal", children: "Link copied." }) : null,
|
|
1011
|
+
shared ? /* @__PURE__ */ jsx11(Text7, { size: "sm", c: "teal", children: "Share sheet opened." }) : null
|
|
871
1012
|
] });
|
|
872
1013
|
}
|
|
873
1014
|
|
|
874
1015
|
// src/UploadDropzone.tsx
|
|
875
|
-
import { useRef, useState as
|
|
1016
|
+
import { useRef, useState as useState7 } from "react";
|
|
876
1017
|
import { Badge as Badge2, Box as Box4, Button as Button4, Group as Group7, Stack as Stack6, Text as Text8 } from "@mantine/core";
|
|
877
|
-
import { jsx as
|
|
1018
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
878
1019
|
function UploadDropzone({
|
|
879
1020
|
title,
|
|
880
1021
|
description,
|
|
@@ -894,7 +1035,7 @@ function UploadDropzone({
|
|
|
894
1035
|
readonly = false
|
|
895
1036
|
}) {
|
|
896
1037
|
const inputRef = useRef(null);
|
|
897
|
-
const [dragging, setDragging] =
|
|
1038
|
+
const [dragging, setDragging] = useState7(false);
|
|
898
1039
|
const UploadIcon = GdsIcons.Upload;
|
|
899
1040
|
const effectiveState = readonly ? "readonly" : dragging ? "drag-active" : state;
|
|
900
1041
|
const isDisabled = readonly || effectiveState === "upload-pending";
|
|
@@ -929,7 +1070,7 @@ function UploadDropzone({
|
|
|
929
1070
|
},
|
|
930
1071
|
"aria-invalid": isError || void 0,
|
|
931
1072
|
children: [
|
|
932
|
-
/* @__PURE__ */
|
|
1073
|
+
/* @__PURE__ */ jsx12(
|
|
933
1074
|
"input",
|
|
934
1075
|
{
|
|
935
1076
|
ref: inputRef,
|
|
@@ -942,22 +1083,22 @@ function UploadDropzone({
|
|
|
942
1083
|
}
|
|
943
1084
|
),
|
|
944
1085
|
/* @__PURE__ */ jsxs8(Stack6, { align: mode === "inline" ? "flex-start" : "center", ta: mode === "inline" ? "left" : "center", gap: "sm", children: [
|
|
945
|
-
/* @__PURE__ */
|
|
946
|
-
/* @__PURE__ */
|
|
947
|
-
/* @__PURE__ */
|
|
948
|
-
description ? /* @__PURE__ */
|
|
1086
|
+
/* @__PURE__ */ jsx12(UploadIcon, { size: "1.5rem" }),
|
|
1087
|
+
/* @__PURE__ */ jsx12(Badge2, { variant: "light", color: isError ? "red" : effectiveState === "selected" ? "blue" : effectiveState === "upload-pending" ? "violet" : "gray", children: effectiveState.replace("-", " ") }),
|
|
1088
|
+
/* @__PURE__ */ jsx12(Text8, { fw: 600, children: title }),
|
|
1089
|
+
description ? /* @__PURE__ */ jsx12(Text8, { size: "sm", c: "dimmed", children: description }) : null,
|
|
949
1090
|
acceptedTypesLabel || maxSizeLabel ? /* @__PURE__ */ jsxs8(Group7, { gap: "xs", justify: mode === "inline" ? "flex-start" : "center", children: [
|
|
950
|
-
acceptedTypesLabel ? /* @__PURE__ */
|
|
951
|
-
maxSizeLabel ? /* @__PURE__ */
|
|
1091
|
+
acceptedTypesLabel ? /* @__PURE__ */ jsx12(Badge2, { variant: "outline", color: "gray", children: acceptedTypesLabel }) : null,
|
|
1092
|
+
maxSizeLabel ? /* @__PURE__ */ jsx12(Badge2, { variant: "outline", color: "gray", children: maxSizeLabel }) : null
|
|
952
1093
|
] }) : null,
|
|
953
1094
|
selectedFiles.length ? /* @__PURE__ */ jsxs8(Text8, { size: "sm", children: [
|
|
954
1095
|
"Selected: ",
|
|
955
1096
|
selectedFiles.join(", ")
|
|
956
1097
|
] }) : null,
|
|
957
|
-
policyText ? /* @__PURE__ */
|
|
958
|
-
error ? /* @__PURE__ */
|
|
1098
|
+
policyText ? /* @__PURE__ */ jsx12(Text8, { size: "sm", c: isError ? "red.7" : "dimmed", children: policyText }) : null,
|
|
1099
|
+
error ? /* @__PURE__ */ jsx12(Text8, { size: "sm", c: "red.7", role: "alert", children: error }) : null,
|
|
959
1100
|
/* @__PURE__ */ jsxs8(Group7, { children: [
|
|
960
|
-
/* @__PURE__ */
|
|
1101
|
+
/* @__PURE__ */ jsx12(Button4, { variant: "light", onClick: () => inputRef.current?.click(), disabled: isDisabled, children: actionLabel }),
|
|
961
1102
|
retryAction,
|
|
962
1103
|
removeAction
|
|
963
1104
|
] })
|
|
@@ -970,7 +1111,7 @@ function UploadDropzone({
|
|
|
970
1111
|
// src/AccessRecoveryPanel.tsx
|
|
971
1112
|
import { Group as Group8 } from "@mantine/core";
|
|
972
1113
|
import { useGdsTranslation as useGdsTranslation4 } from "@doneisbetter/gds-theme";
|
|
973
|
-
import { jsx as
|
|
1114
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
974
1115
|
var stateBlockVariantByState = {
|
|
975
1116
|
unauthenticated: "permission",
|
|
976
1117
|
"expired-session": "info",
|
|
@@ -1050,7 +1191,7 @@ function ActionGroup({
|
|
|
1050
1191
|
if (actions.length === 0) {
|
|
1051
1192
|
return null;
|
|
1052
1193
|
}
|
|
1053
|
-
return /* @__PURE__ */
|
|
1194
|
+
return /* @__PURE__ */ jsx13(Group8, { gap: "sm", justify: "center", wrap: "wrap", children: actions.map((actionConfig, index) => /* @__PURE__ */ jsx13(
|
|
1054
1195
|
SemanticButton,
|
|
1055
1196
|
{
|
|
1056
1197
|
action: actionConfig.action,
|
|
@@ -1084,14 +1225,14 @@ function AccessRecoveryPanel({
|
|
|
1084
1225
|
onBack,
|
|
1085
1226
|
supportAction
|
|
1086
1227
|
});
|
|
1087
|
-
return /* @__PURE__ */
|
|
1228
|
+
return /* @__PURE__ */ jsx13(
|
|
1088
1229
|
StateBlock,
|
|
1089
1230
|
{
|
|
1090
1231
|
variant: stateBlockVariantByState[state],
|
|
1091
1232
|
compact,
|
|
1092
1233
|
title: title ?? t(`gds.accessRecovery.${state}.title`, defaultCopy.title),
|
|
1093
1234
|
description: description ?? t(`gds.accessRecovery.${state}.description`, defaultCopy.description),
|
|
1094
|
-
action: /* @__PURE__ */
|
|
1235
|
+
action: /* @__PURE__ */ jsx13(
|
|
1095
1236
|
ActionGroup,
|
|
1096
1237
|
{
|
|
1097
1238
|
primaryAction: primaryAction ?? defaults.primary,
|
|
@@ -1103,12 +1244,555 @@ function AccessRecoveryPanel({
|
|
|
1103
1244
|
);
|
|
1104
1245
|
}
|
|
1105
1246
|
|
|
1247
|
+
// src/GdsForm.client.tsx
|
|
1248
|
+
import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3, useReducer as useReducer2 } from "react";
|
|
1249
|
+
import { Alert, Anchor, Stack as Stack7, Text as Text9 } from "@mantine/core";
|
|
1250
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1251
|
+
function createFieldState(value) {
|
|
1252
|
+
return { value, touched: false, dirty: false };
|
|
1253
|
+
}
|
|
1254
|
+
function createSnapshot(values) {
|
|
1255
|
+
const fields = Object.entries(values).reduce((acc, [field, value]) => {
|
|
1256
|
+
acc[field] = createFieldState(value);
|
|
1257
|
+
return acc;
|
|
1258
|
+
}, {});
|
|
1259
|
+
return { fields, issues: [], submitState: "idle" };
|
|
1260
|
+
}
|
|
1261
|
+
function gdsFormReducer(state, action) {
|
|
1262
|
+
switch (action.type) {
|
|
1263
|
+
case "set-field": {
|
|
1264
|
+
const current = state.fields[action.field] ?? createFieldState("");
|
|
1265
|
+
return {
|
|
1266
|
+
...state,
|
|
1267
|
+
fields: {
|
|
1268
|
+
...state.fields,
|
|
1269
|
+
[action.field]: {
|
|
1270
|
+
value: action.value,
|
|
1271
|
+
touched: current.touched,
|
|
1272
|
+
dirty: true
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
case "touch-field": {
|
|
1278
|
+
const current = state.fields[action.field] ?? createFieldState("");
|
|
1279
|
+
return {
|
|
1280
|
+
...state,
|
|
1281
|
+
fields: {
|
|
1282
|
+
...state.fields,
|
|
1283
|
+
[action.field]: { ...current, touched: true }
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
case "set-issues":
|
|
1288
|
+
return { ...state, issues: [...action.issues] };
|
|
1289
|
+
case "set-submit-state":
|
|
1290
|
+
return { ...state, submitState: action.submitState, submitError: action.submitError };
|
|
1291
|
+
case "reset":
|
|
1292
|
+
return createSnapshot(action.values ?? {});
|
|
1293
|
+
default:
|
|
1294
|
+
return state;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
function sortIssues(issues) {
|
|
1298
|
+
const weight = { blocking: 0, warning: 1, info: 2 };
|
|
1299
|
+
return [...issues].sort((a, b) => weight[a.severity] - weight[b.severity]);
|
|
1300
|
+
}
|
|
1301
|
+
function useGdsForm({
|
|
1302
|
+
initialValues,
|
|
1303
|
+
validate,
|
|
1304
|
+
validateAsync,
|
|
1305
|
+
onSubmit
|
|
1306
|
+
}) {
|
|
1307
|
+
const [snapshot, dispatch] = useReducer2(gdsFormReducer, initialValues, createSnapshot);
|
|
1308
|
+
const submit = async () => {
|
|
1309
|
+
dispatch({ type: "set-submit-state", submitState: "validating" });
|
|
1310
|
+
const syncIssues = sortIssues(validate ? validate(snapshot) : []);
|
|
1311
|
+
let mergedIssues = syncIssues;
|
|
1312
|
+
if (syncIssues.filter((issue) => issue.severity === "blocking").length === 0 && validateAsync) {
|
|
1313
|
+
const asyncIssues = sortIssues(await validateAsync(snapshot));
|
|
1314
|
+
mergedIssues = sortIssues([...syncIssues, ...asyncIssues]);
|
|
1315
|
+
}
|
|
1316
|
+
dispatch({ type: "set-issues", issues: mergedIssues });
|
|
1317
|
+
if (mergedIssues.some((issue) => issue.severity === "blocking")) {
|
|
1318
|
+
dispatch({ type: "set-submit-state", submitState: "error", submitError: "Please resolve blocking validation issues." });
|
|
1319
|
+
return false;
|
|
1320
|
+
}
|
|
1321
|
+
dispatch({ type: "set-submit-state", submitState: "submitting" });
|
|
1322
|
+
try {
|
|
1323
|
+
await onSubmit(
|
|
1324
|
+
Object.entries(snapshot.fields).reduce((acc, [field, state]) => {
|
|
1325
|
+
acc[field] = state.value;
|
|
1326
|
+
return acc;
|
|
1327
|
+
}, {})
|
|
1328
|
+
);
|
|
1329
|
+
dispatch({ type: "set-submit-state", submitState: "success" });
|
|
1330
|
+
return true;
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
dispatch({
|
|
1333
|
+
type: "set-submit-state",
|
|
1334
|
+
submitState: "error",
|
|
1335
|
+
submitError: error instanceof Error ? error.message : "Submission failed."
|
|
1336
|
+
});
|
|
1337
|
+
return false;
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
return useMemo3(
|
|
1341
|
+
() => ({
|
|
1342
|
+
snapshot,
|
|
1343
|
+
setFieldValue: (field, value) => dispatch({ type: "set-field", field, value }),
|
|
1344
|
+
touchField: (field) => dispatch({ type: "touch-field", field }),
|
|
1345
|
+
submit,
|
|
1346
|
+
retrySubmit: submit
|
|
1347
|
+
}),
|
|
1348
|
+
[snapshot]
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
var GdsFormContext = createContext2(null);
|
|
1352
|
+
function GdsFormProvider({ snapshot, children }) {
|
|
1353
|
+
return /* @__PURE__ */ jsx14(GdsFormContext.Provider, { value: { snapshot }, children });
|
|
1354
|
+
}
|
|
1355
|
+
function useGdsFormSnapshot() {
|
|
1356
|
+
const context = useContext2(GdsFormContext);
|
|
1357
|
+
if (!context) {
|
|
1358
|
+
throw new Error("useGdsFormSnapshot must be used within GdsFormProvider.");
|
|
1359
|
+
}
|
|
1360
|
+
return context.snapshot;
|
|
1361
|
+
}
|
|
1362
|
+
function FormErrorSummary({ title = "Please review the following issues." }) {
|
|
1363
|
+
const snapshot = useGdsFormSnapshot();
|
|
1364
|
+
const blocking = snapshot.issues.filter((issue) => issue.severity === "blocking");
|
|
1365
|
+
if (blocking.length === 0) {
|
|
1366
|
+
return null;
|
|
1367
|
+
}
|
|
1368
|
+
return /* @__PURE__ */ jsx14(Alert, { color: "red", title, children: /* @__PURE__ */ jsx14(Stack7, { gap: 4, children: blocking.map((issue) => /* @__PURE__ */ jsx14(Anchor, { href: `#${issue.field}`, children: issue.message }, `${issue.field}-${issue.message}`)) }) });
|
|
1369
|
+
}
|
|
1370
|
+
function ValidatedFieldMessage({ field }) {
|
|
1371
|
+
const snapshot = useGdsFormSnapshot();
|
|
1372
|
+
const issue = snapshot.issues.find((item) => item.field === field && item.severity === "blocking");
|
|
1373
|
+
if (!issue) {
|
|
1374
|
+
return null;
|
|
1375
|
+
}
|
|
1376
|
+
return /* @__PURE__ */ jsx14(Text9, { size: "xs", c: "red.7", id: `${field}-error`, children: issue.message });
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// src/AdvancedDataTable.client.tsx
|
|
1380
|
+
import { useMemo as useMemo4, useState as useState8 } from "react";
|
|
1381
|
+
import { Checkbox as Checkbox2, Group as Group9, ScrollArea as ScrollArea2, SegmentedControl, Stack as Stack8, Table, Text as Text10 } from "@mantine/core";
|
|
1382
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1383
|
+
function compareValues(a, b) {
|
|
1384
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
1385
|
+
return a - b;
|
|
1386
|
+
}
|
|
1387
|
+
return String(a).localeCompare(String(b), void 0, { numeric: true, sensitivity: "base" });
|
|
1388
|
+
}
|
|
1389
|
+
function AdvancedDataTable({
|
|
1390
|
+
rows,
|
|
1391
|
+
columns,
|
|
1392
|
+
rowId,
|
|
1393
|
+
loading = false,
|
|
1394
|
+
error = null,
|
|
1395
|
+
density: densityProp,
|
|
1396
|
+
stickyHeader = true,
|
|
1397
|
+
stickyHeaderOffset = 0,
|
|
1398
|
+
selectedRowIds,
|
|
1399
|
+
onSelectedRowIdsChange,
|
|
1400
|
+
sortBy: sortByProp,
|
|
1401
|
+
sortDirection: sortDirectionProp,
|
|
1402
|
+
onSortChange,
|
|
1403
|
+
responsiveFallback = "stacked-cards"
|
|
1404
|
+
}) {
|
|
1405
|
+
const [densityState, setDensityState] = useState8(densityProp ?? "comfortable");
|
|
1406
|
+
const [sortState, setSortState] = useState8({ key: sortByProp ?? null, direction: sortDirectionProp ?? "asc" });
|
|
1407
|
+
const [selectionState, setSelectionState] = useState8([]);
|
|
1408
|
+
const density = densityProp ?? densityState;
|
|
1409
|
+
const sortBy = sortByProp ?? sortState.key;
|
|
1410
|
+
const sortDirection = sortDirectionProp ?? sortState.direction;
|
|
1411
|
+
const selection = selectedRowIds ?? selectionState;
|
|
1412
|
+
const sortedRows = useMemo4(() => {
|
|
1413
|
+
if (!sortBy) {
|
|
1414
|
+
return rows;
|
|
1415
|
+
}
|
|
1416
|
+
const column = columns.find((item) => item.key === sortBy);
|
|
1417
|
+
if (!column) {
|
|
1418
|
+
return rows;
|
|
1419
|
+
}
|
|
1420
|
+
const next = [...rows].sort((left, right) => {
|
|
1421
|
+
const leftValue = column.sortAccessor ? column.sortAccessor(left) : String(left[column.key] ?? "");
|
|
1422
|
+
const rightValue = column.sortAccessor ? column.sortAccessor(right) : String(right[column.key] ?? "");
|
|
1423
|
+
const result = compareValues(leftValue, rightValue);
|
|
1424
|
+
return sortDirection === "asc" ? result : -result;
|
|
1425
|
+
});
|
|
1426
|
+
return next;
|
|
1427
|
+
}, [rows, columns, sortBy, sortDirection]);
|
|
1428
|
+
const allIds = useMemo4(() => sortedRows.map((row, index) => rowId(row, index)), [sortedRows, rowId]);
|
|
1429
|
+
const allSelected = allIds.length > 0 && allIds.every((id) => selection.includes(id));
|
|
1430
|
+
if (error) {
|
|
1431
|
+
return /* @__PURE__ */ jsx15(StateBlock, { variant: "error", title: "Unable to load table", description: error, compact: true });
|
|
1432
|
+
}
|
|
1433
|
+
if (loading) {
|
|
1434
|
+
return /* @__PURE__ */ jsx15(StateBlock, { variant: "loading", title: "Loading table", description: "Preparing enterprise data grid.", compact: true });
|
|
1435
|
+
}
|
|
1436
|
+
if (!rows.length) {
|
|
1437
|
+
return /* @__PURE__ */ jsx15(
|
|
1438
|
+
StateBlock,
|
|
1439
|
+
{
|
|
1440
|
+
variant: "empty",
|
|
1441
|
+
title: "No rows available",
|
|
1442
|
+
description: "Adjust filters or broaden scope to populate this table.",
|
|
1443
|
+
compact: true
|
|
1444
|
+
}
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
const horizontalSpacing = density === "compact" ? "xs" : "md";
|
|
1448
|
+
const verticalSpacing = density === "compact" ? 6 : 10;
|
|
1449
|
+
return /* @__PURE__ */ jsxs9(Stack8, { gap: "sm", children: [
|
|
1450
|
+
/* @__PURE__ */ jsxs9(Group9, { justify: "space-between", align: "center", children: [
|
|
1451
|
+
/* @__PURE__ */ jsxs9(Text10, { size: "sm", fw: 600, children: [
|
|
1452
|
+
rows.length,
|
|
1453
|
+
" rows"
|
|
1454
|
+
] }),
|
|
1455
|
+
/* @__PURE__ */ jsx15(
|
|
1456
|
+
SegmentedControl,
|
|
1457
|
+
{
|
|
1458
|
+
size: "xs",
|
|
1459
|
+
value: density,
|
|
1460
|
+
onChange: (value) => setDensityState(value),
|
|
1461
|
+
data: [
|
|
1462
|
+
{ label: "Compact", value: "compact" },
|
|
1463
|
+
{ label: "Comfortable", value: "comfortable" }
|
|
1464
|
+
]
|
|
1465
|
+
}
|
|
1466
|
+
)
|
|
1467
|
+
] }),
|
|
1468
|
+
/* @__PURE__ */ jsx15(ScrollArea2, { children: /* @__PURE__ */ jsxs9(
|
|
1469
|
+
Table,
|
|
1470
|
+
{
|
|
1471
|
+
stickyHeader,
|
|
1472
|
+
stickyHeaderOffset,
|
|
1473
|
+
withTableBorder: true,
|
|
1474
|
+
highlightOnHover: true,
|
|
1475
|
+
striped: true,
|
|
1476
|
+
horizontalSpacing,
|
|
1477
|
+
verticalSpacing,
|
|
1478
|
+
children: [
|
|
1479
|
+
/* @__PURE__ */ jsx15(Table.Thead, { children: /* @__PURE__ */ jsxs9(Table.Tr, { children: [
|
|
1480
|
+
/* @__PURE__ */ jsx15(Table.Th, { children: /* @__PURE__ */ jsx15(
|
|
1481
|
+
Checkbox2,
|
|
1482
|
+
{
|
|
1483
|
+
"aria-label": "Select all rows",
|
|
1484
|
+
checked: allSelected,
|
|
1485
|
+
indeterminate: !allSelected && selection.length > 0,
|
|
1486
|
+
onChange: (event) => {
|
|
1487
|
+
const next = event.currentTarget.checked ? allIds : [];
|
|
1488
|
+
if (onSelectedRowIdsChange) {
|
|
1489
|
+
onSelectedRowIdsChange(next);
|
|
1490
|
+
} else {
|
|
1491
|
+
setSelectionState(next);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
) }),
|
|
1496
|
+
columns.map((column) => /* @__PURE__ */ jsx15(Table.Th, { style: column.width ? { width: column.width } : void 0, children: column.sortable ? /* @__PURE__ */ jsx15(
|
|
1497
|
+
"button",
|
|
1498
|
+
{
|
|
1499
|
+
type: "button",
|
|
1500
|
+
"aria-label": `Sort by ${column.label}`,
|
|
1501
|
+
onClick: () => {
|
|
1502
|
+
const nextDirection = sortBy === column.key && sortDirection === "asc" ? "desc" : "asc";
|
|
1503
|
+
if (onSortChange) {
|
|
1504
|
+
onSortChange(column.key, nextDirection);
|
|
1505
|
+
} else {
|
|
1506
|
+
setSortState({ key: column.key, direction: nextDirection });
|
|
1507
|
+
}
|
|
1508
|
+
},
|
|
1509
|
+
children: column.label
|
|
1510
|
+
}
|
|
1511
|
+
) : column.label }, column.key))
|
|
1512
|
+
] }) }),
|
|
1513
|
+
/* @__PURE__ */ jsx15(Table.Tbody, { children: sortedRows.map((row, index) => {
|
|
1514
|
+
const id = rowId(row, index);
|
|
1515
|
+
const checked = selection.includes(id);
|
|
1516
|
+
return /* @__PURE__ */ jsxs9(Table.Tr, { children: [
|
|
1517
|
+
/* @__PURE__ */ jsx15(Table.Td, { children: /* @__PURE__ */ jsx15(
|
|
1518
|
+
Checkbox2,
|
|
1519
|
+
{
|
|
1520
|
+
"aria-label": `Select row ${id}`,
|
|
1521
|
+
checked,
|
|
1522
|
+
onChange: () => {
|
|
1523
|
+
const next = checked ? selection.filter((item) => item !== id) : [...selection, id];
|
|
1524
|
+
if (onSelectedRowIdsChange) {
|
|
1525
|
+
onSelectedRowIdsChange(next);
|
|
1526
|
+
} else {
|
|
1527
|
+
setSelectionState(next);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
) }),
|
|
1532
|
+
columns.map((column) => /* @__PURE__ */ jsx15(Table.Td, { children: column.render ? column.render(row) : String(row[column.key] ?? "") }, column.key))
|
|
1533
|
+
] }, id);
|
|
1534
|
+
}) })
|
|
1535
|
+
]
|
|
1536
|
+
}
|
|
1537
|
+
) }),
|
|
1538
|
+
responsiveFallback === "stacked-cards" ? /* @__PURE__ */ jsx15(Stack8, { gap: "xs", children: sortedRows.slice(0, 3).map((row, index) => {
|
|
1539
|
+
const id = rowId(row, index);
|
|
1540
|
+
return /* @__PURE__ */ jsx15(
|
|
1541
|
+
StateBlock,
|
|
1542
|
+
{
|
|
1543
|
+
variant: "info",
|
|
1544
|
+
compact: true,
|
|
1545
|
+
title: String(row[columns[0]?.key] ?? id),
|
|
1546
|
+
description: columns.slice(1, 3).map((column) => `${column.label}: ${String(row[column.key] ?? "")}`).join(" | ")
|
|
1547
|
+
},
|
|
1548
|
+
`card-${id}`
|
|
1549
|
+
);
|
|
1550
|
+
}) }) : null
|
|
1551
|
+
] });
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// src/OverlayManager.client.tsx
|
|
1555
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo5, useState as useState9 } from "react";
|
|
1556
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1557
|
+
var OverlayManagerContext = createContext3(null);
|
|
1558
|
+
function OverlayManagerProvider({ children }) {
|
|
1559
|
+
const [stack, setStack] = useState9([]);
|
|
1560
|
+
const value = useMemo5(() => ({
|
|
1561
|
+
stack,
|
|
1562
|
+
registerOverlay: (overlay) => {
|
|
1563
|
+
setStack((current) => {
|
|
1564
|
+
const without = current.filter((item) => item.id !== overlay.id);
|
|
1565
|
+
return [...without, overlay];
|
|
1566
|
+
});
|
|
1567
|
+
},
|
|
1568
|
+
unregisterOverlay: (id) => {
|
|
1569
|
+
setStack((current) => current.filter((item) => item.id !== id));
|
|
1570
|
+
},
|
|
1571
|
+
isTopMost: (id) => stack.length > 0 && stack[stack.length - 1]?.id === id,
|
|
1572
|
+
requestClose: (id, reason) => {
|
|
1573
|
+
if (stack.length === 0 || stack[stack.length - 1]?.id !== id) {
|
|
1574
|
+
return null;
|
|
1575
|
+
}
|
|
1576
|
+
return reason;
|
|
1577
|
+
}
|
|
1578
|
+
}), [stack]);
|
|
1579
|
+
return /* @__PURE__ */ jsx16(OverlayManagerContext.Provider, { value, children });
|
|
1580
|
+
}
|
|
1581
|
+
function useOverlayManager() {
|
|
1582
|
+
const context = useContext3(OverlayManagerContext);
|
|
1583
|
+
if (!context) {
|
|
1584
|
+
throw new Error("useOverlayManager must be used within OverlayManagerProvider.");
|
|
1585
|
+
}
|
|
1586
|
+
return context;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
// src/CommandPalette.client.tsx
|
|
1590
|
+
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect4, useMemo as useMemo6, useState as useState10 } from "react";
|
|
1591
|
+
import { ActionIcon as ActionIcon4, Group as Group10, Modal as Modal2, Stack as Stack9, Text as Text11, TextInput as TextInput2 } from "@mantine/core";
|
|
1592
|
+
import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1593
|
+
var CommandPaletteContext = createContext4(null);
|
|
1594
|
+
function normalize(text) {
|
|
1595
|
+
return text.trim().toLowerCase();
|
|
1596
|
+
}
|
|
1597
|
+
function scoreCommand(command, query, recentUse) {
|
|
1598
|
+
const q = normalize(query);
|
|
1599
|
+
if (!q) {
|
|
1600
|
+
return 0;
|
|
1601
|
+
}
|
|
1602
|
+
const label = normalize(command.label);
|
|
1603
|
+
const keywords = command.keywords?.map(normalize) ?? [];
|
|
1604
|
+
const prefix = label.startsWith(q) ? 1 : 0;
|
|
1605
|
+
const keyword = keywords.some((item) => item.includes(q)) ? 1 : 0;
|
|
1606
|
+
const recent = recentUse[command.id] ? 1 : 0;
|
|
1607
|
+
return 0.6 * prefix + 0.3 * keyword + 0.1 * recent;
|
|
1608
|
+
}
|
|
1609
|
+
function CommandRegistryProvider({ children }) {
|
|
1610
|
+
const [commands, setCommands] = useState10([]);
|
|
1611
|
+
const [opened, setOpened] = useState10(false);
|
|
1612
|
+
const value = useMemo6(() => ({
|
|
1613
|
+
commands,
|
|
1614
|
+
registerCommands: (next) => setCommands(next),
|
|
1615
|
+
open: () => setOpened(true),
|
|
1616
|
+
close: () => setOpened(false)
|
|
1617
|
+
}), [commands]);
|
|
1618
|
+
return /* @__PURE__ */ jsxs10(CommandPaletteContext.Provider, { value, children: [
|
|
1619
|
+
children,
|
|
1620
|
+
/* @__PURE__ */ jsx17(CommandPalette, { opened, onClose: () => setOpened(false) })
|
|
1621
|
+
] });
|
|
1622
|
+
}
|
|
1623
|
+
function useCommandLauncher() {
|
|
1624
|
+
const context = useContext4(CommandPaletteContext);
|
|
1625
|
+
if (!context) {
|
|
1626
|
+
throw new Error("useCommandLauncher must be used within CommandRegistryProvider.");
|
|
1627
|
+
}
|
|
1628
|
+
return {
|
|
1629
|
+
open: context.open,
|
|
1630
|
+
close: context.close,
|
|
1631
|
+
registerCommands: context.registerCommands
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
function CommandPalette({ opened, onClose }) {
|
|
1635
|
+
const contextValue = useContext4(CommandPaletteContext);
|
|
1636
|
+
if (!contextValue) {
|
|
1637
|
+
throw new Error("CommandPalette must be used within CommandRegistryProvider.");
|
|
1638
|
+
}
|
|
1639
|
+
const registry = contextValue;
|
|
1640
|
+
const [query, setQuery] = useState10("");
|
|
1641
|
+
const [recentUse, setRecentUse] = useState10({});
|
|
1642
|
+
const enabledCommands = registry.commands.filter((command) => command.enabledWhen ? command.enabledWhen() : true);
|
|
1643
|
+
const filteredCommands = [...enabledCommands].map((command) => ({ command, score: scoreCommand(command, query, recentUse) })).filter(({ command, score }) => normalize(query) === "" || score > 0 || normalize(command.label).includes(normalize(query))).sort((a, b) => b.score - a.score).map((item) => item.command);
|
|
1644
|
+
useEffect4(() => {
|
|
1645
|
+
function onKeyDown(event) {
|
|
1646
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
|
1647
|
+
event.preventDefault();
|
|
1648
|
+
registry.open();
|
|
1649
|
+
}
|
|
1650
|
+
if (event.key === "Escape" && opened) {
|
|
1651
|
+
onClose();
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1655
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1656
|
+
}, [registry, opened, onClose]);
|
|
1657
|
+
return /* @__PURE__ */ jsx17(Modal2, { opened, onClose, title: "Quick actions", centered: true, children: /* @__PURE__ */ jsxs10(Stack9, { gap: "sm", children: [
|
|
1658
|
+
/* @__PURE__ */ jsx17(
|
|
1659
|
+
TextInput2,
|
|
1660
|
+
{
|
|
1661
|
+
"aria-label": "Command search",
|
|
1662
|
+
placeholder: "Search commands",
|
|
1663
|
+
value: query,
|
|
1664
|
+
onChange: (event) => setQuery(event.currentTarget.value)
|
|
1665
|
+
}
|
|
1666
|
+
),
|
|
1667
|
+
filteredCommands.length === 0 ? /* @__PURE__ */ jsx17(Text11, { size: "sm", c: "dimmed", children: "No matching commands." }) : filteredCommands.map((command) => /* @__PURE__ */ jsxs10(Group10, { justify: "space-between", wrap: "nowrap", children: [
|
|
1668
|
+
/* @__PURE__ */ jsx17(
|
|
1669
|
+
"button",
|
|
1670
|
+
{
|
|
1671
|
+
type: "button",
|
|
1672
|
+
onClick: async () => {
|
|
1673
|
+
await command.run();
|
|
1674
|
+
setRecentUse((current) => ({ ...current, [command.id]: Date.now() }));
|
|
1675
|
+
onClose();
|
|
1676
|
+
},
|
|
1677
|
+
"aria-label": command.label,
|
|
1678
|
+
children: command.label
|
|
1679
|
+
}
|
|
1680
|
+
),
|
|
1681
|
+
command.shortcut ? /* @__PURE__ */ jsx17(Text11, { size: "xs", c: "dimmed", children: command.shortcut }) : null
|
|
1682
|
+
] }, command.id)),
|
|
1683
|
+
/* @__PURE__ */ jsx17(Group10, { justify: "flex-end", children: /* @__PURE__ */ jsx17(ActionIcon4, { variant: "subtle", "aria-label": "Close command palette", onClick: onClose, children: /* @__PURE__ */ jsx17(GdsIcons.Close, { size: "1rem" }) }) })
|
|
1684
|
+
] }) });
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
// src/Notifications.client.tsx
|
|
1688
|
+
import { createContext as createContext5, useContext as useContext5, useMemo as useMemo7, useState as useState11 } from "react";
|
|
1689
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1690
|
+
var GdsNotificationContext = createContext5(null);
|
|
1691
|
+
function GdsNotificationProvider({ children }) {
|
|
1692
|
+
const [notifications, setNotifications] = useState11([]);
|
|
1693
|
+
const value = useMemo7(() => ({
|
|
1694
|
+
notifications,
|
|
1695
|
+
notify: (message) => {
|
|
1696
|
+
setNotifications((current) => {
|
|
1697
|
+
const rest = current.filter((item) => item.id !== message.id);
|
|
1698
|
+
return [...rest, message];
|
|
1699
|
+
});
|
|
1700
|
+
if (typeof message.autoCloseMs === "number" && message.autoCloseMs > 0) {
|
|
1701
|
+
window.setTimeout(() => {
|
|
1702
|
+
setNotifications((current) => current.filter((item) => item.id !== message.id));
|
|
1703
|
+
}, message.autoCloseMs);
|
|
1704
|
+
}
|
|
1705
|
+
},
|
|
1706
|
+
dismiss: (id) => {
|
|
1707
|
+
setNotifications((current) => current.filter((item) => item.id !== id));
|
|
1708
|
+
},
|
|
1709
|
+
clear: () => {
|
|
1710
|
+
setNotifications([]);
|
|
1711
|
+
}
|
|
1712
|
+
}), [notifications]);
|
|
1713
|
+
return /* @__PURE__ */ jsx18(GdsNotificationContext.Provider, { value, children });
|
|
1714
|
+
}
|
|
1715
|
+
function useGdsNotifications() {
|
|
1716
|
+
const context = useContext5(GdsNotificationContext);
|
|
1717
|
+
if (!context) {
|
|
1718
|
+
throw new Error("useGdsNotifications must be used within GdsNotificationProvider.");
|
|
1719
|
+
}
|
|
1720
|
+
return context;
|
|
1721
|
+
}
|
|
1722
|
+
function NotificationCenter({
|
|
1723
|
+
title = "Notifications",
|
|
1724
|
+
emptyMessage = "No active notifications."
|
|
1725
|
+
}) {
|
|
1726
|
+
const { notifications, dismiss, clear } = useGdsNotifications();
|
|
1727
|
+
return /* @__PURE__ */ jsx18(
|
|
1728
|
+
NotificationCenterView,
|
|
1729
|
+
{
|
|
1730
|
+
title,
|
|
1731
|
+
emptyMessage,
|
|
1732
|
+
notifications,
|
|
1733
|
+
onDismiss: dismiss,
|
|
1734
|
+
onClear: clear
|
|
1735
|
+
}
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
// src/Telemetry.client.tsx
|
|
1740
|
+
import { createContext as createContext6, useContext as useContext6, useMemo as useMemo8 } from "react";
|
|
1741
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1742
|
+
var GdsTelemetryContext = createContext6(null);
|
|
1743
|
+
function hashToUnit(value) {
|
|
1744
|
+
let hash = 0;
|
|
1745
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1746
|
+
hash = (hash << 5) - hash + value.charCodeAt(index);
|
|
1747
|
+
hash |= 0;
|
|
1748
|
+
}
|
|
1749
|
+
return Math.abs(hash % 1e3) / 1e3;
|
|
1750
|
+
}
|
|
1751
|
+
function redactContext(context) {
|
|
1752
|
+
if (!context) {
|
|
1753
|
+
return context;
|
|
1754
|
+
}
|
|
1755
|
+
return Object.entries(context).reduce((acc, [key, value]) => {
|
|
1756
|
+
if (key.toLowerCase().includes("email") || key.toLowerCase().includes("name") || key.toLowerCase().includes("phone")) {
|
|
1757
|
+
return acc;
|
|
1758
|
+
}
|
|
1759
|
+
acc[key] = value;
|
|
1760
|
+
return acc;
|
|
1761
|
+
}, {});
|
|
1762
|
+
}
|
|
1763
|
+
function GdsTelemetryProvider({ children, sink, sampleRate = 1 }) {
|
|
1764
|
+
const value = useMemo8(() => ({
|
|
1765
|
+
emit: (event) => {
|
|
1766
|
+
if (hashToUnit(event.correlationId) > sampleRate) {
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
sink?.({
|
|
1770
|
+
...event,
|
|
1771
|
+
context: redactContext(event.context),
|
|
1772
|
+
ts: Date.now()
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
}), [sampleRate, sink]);
|
|
1776
|
+
return /* @__PURE__ */ jsx19(GdsTelemetryContext.Provider, { value, children });
|
|
1777
|
+
}
|
|
1778
|
+
function useGdsTelemetry() {
|
|
1779
|
+
const context = useContext6(GdsTelemetryContext);
|
|
1780
|
+
if (!context) {
|
|
1781
|
+
throw new Error("useGdsTelemetry must be used within GdsTelemetryProvider.");
|
|
1782
|
+
}
|
|
1783
|
+
return context;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1106
1786
|
export {
|
|
1107
1787
|
SemanticButton,
|
|
1108
1788
|
ConfirmDialog,
|
|
1109
1789
|
ThemeToggle,
|
|
1110
1790
|
ReferenceThemeExplorer,
|
|
1111
1791
|
GameBoardTile,
|
|
1792
|
+
listingQueryReducer,
|
|
1793
|
+
ListingProvider,
|
|
1794
|
+
useListingState,
|
|
1795
|
+
useDiscoveryShellState,
|
|
1112
1796
|
DiscoveryShell,
|
|
1113
1797
|
DocsShell,
|
|
1114
1798
|
SidebarNav,
|
|
@@ -1117,5 +1801,22 @@ export {
|
|
|
1117
1801
|
DocsCodeBlock,
|
|
1118
1802
|
ShareButtonGroup,
|
|
1119
1803
|
UploadDropzone,
|
|
1120
|
-
AccessRecoveryPanel
|
|
1804
|
+
AccessRecoveryPanel,
|
|
1805
|
+
gdsFormReducer,
|
|
1806
|
+
useGdsForm,
|
|
1807
|
+
GdsFormProvider,
|
|
1808
|
+
useGdsFormSnapshot,
|
|
1809
|
+
FormErrorSummary,
|
|
1810
|
+
ValidatedFieldMessage,
|
|
1811
|
+
AdvancedDataTable,
|
|
1812
|
+
OverlayManagerProvider,
|
|
1813
|
+
useOverlayManager,
|
|
1814
|
+
CommandRegistryProvider,
|
|
1815
|
+
useCommandLauncher,
|
|
1816
|
+
CommandPalette,
|
|
1817
|
+
GdsNotificationProvider,
|
|
1818
|
+
useGdsNotifications,
|
|
1819
|
+
NotificationCenter,
|
|
1820
|
+
GdsTelemetryProvider,
|
|
1821
|
+
useGdsTelemetry
|
|
1121
1822
|
};
|