@nswds/app 1.103.0 → 1.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/globals.css +257 -0
- package/dist/index.cjs +1775 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +1773 -162
- package/dist/index.js.map +1 -1
- package/dist/styles.css +257 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,8 +40,8 @@ var LabelPrimitive = require('@radix-ui/react-label');
|
|
|
40
40
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
41
41
|
var TabsPrimitives = require('@radix-ui/react-tabs');
|
|
42
42
|
var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
|
|
43
|
+
var SheetPrimitive = require('@radix-ui/react-dialog');
|
|
43
44
|
var cmdk = require('cmdk');
|
|
44
|
-
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
45
45
|
var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
|
|
46
46
|
var reactTable = require('@tanstack/react-table');
|
|
47
47
|
var SeparatorPrimitive = require('@radix-ui/react-separator');
|
|
@@ -110,7 +110,7 @@ var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
|
110
110
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
111
111
|
var TabsPrimitives__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitives);
|
|
112
112
|
var CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespace(CollapsiblePrimitive);
|
|
113
|
-
var
|
|
113
|
+
var SheetPrimitive__namespace = /*#__PURE__*/_interopNamespace(SheetPrimitive);
|
|
114
114
|
var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
|
|
115
115
|
var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
|
|
116
116
|
var ToggleGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToggleGroupPrimitive);
|
|
@@ -16914,18 +16914,35 @@ function ColorPairingToolV2Content({ visibleFormats }) {
|
|
|
16914
16914
|
initialState.selectedBackgroundToken
|
|
16915
16915
|
);
|
|
16916
16916
|
const [selectedPairId, setSelectedPairId] = React5.useState(initialState.selectedPairId);
|
|
16917
|
-
const themeFamilies = getPairingFamilies(themeCategory);
|
|
16918
|
-
const context =
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16917
|
+
const themeFamilies = React5.useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
|
|
16918
|
+
const context = React5.useMemo(
|
|
16919
|
+
() => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
|
|
16920
|
+
[themeCategory, primaryFamilyKey, accentFamilyKey]
|
|
16921
|
+
);
|
|
16922
|
+
const selectableFamilies = React5.useMemo(
|
|
16923
|
+
() => themeFamilies.filter((family) => family.key !== context.grey.key),
|
|
16924
|
+
[themeFamilies, context.grey.key]
|
|
16925
|
+
);
|
|
16926
|
+
const selectableAccentFamilies = React5.useMemo(
|
|
16927
|
+
() => selectableFamilies.filter((family) => family.key !== context.primary.key),
|
|
16928
|
+
[selectableFamilies, context.primary.key]
|
|
16929
|
+
);
|
|
16930
|
+
const selectedBackground = React5.useMemo(
|
|
16931
|
+
() => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
|
|
16932
|
+
[context.backgrounds, selectedBackgroundToken]
|
|
16933
|
+
);
|
|
16934
|
+
const selectedBackgroundPairs = React5.useMemo(
|
|
16935
|
+
() => selectedBackground ? context.pairsByBackground[selectedBackground.token] ?? [] : [],
|
|
16936
|
+
[context.pairsByBackground, selectedBackground]
|
|
16937
|
+
);
|
|
16938
|
+
const selectedPair = React5.useMemo(
|
|
16939
|
+
() => getPreferredPairForBackground2(selectedBackgroundPairs, selectedPairId),
|
|
16940
|
+
[selectedBackgroundPairs, selectedPairId]
|
|
16941
|
+
);
|
|
16926
16942
|
const detailForeground = selectedPair?.foreground ?? null;
|
|
16927
|
-
const familySummary =
|
|
16928
|
-
" + "
|
|
16943
|
+
const familySummary = React5.useMemo(
|
|
16944
|
+
() => [context.primary.label, context.accent.label, context.grey.label].join(" + "),
|
|
16945
|
+
[context.primary.label, context.accent.label, context.grey.label]
|
|
16929
16946
|
);
|
|
16930
16947
|
const updateUrlParams = (nextThemeCategory, nextPrimaryKey, nextAccentKey, nextSelectedBackgroundToken, nextSelectedPairId) => {
|
|
16931
16948
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -17228,6 +17245,1723 @@ function ColorPairingToolV2({
|
|
|
17228
17245
|
const normalizedVisibleFormats = [...new Set(visibleFormats)];
|
|
17229
17246
|
return /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolV2Loading, {}), children: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolV2Content, { visibleFormats: normalizedVisibleFormats }) });
|
|
17230
17247
|
}
|
|
17248
|
+
function Sheet({ ...props }) {
|
|
17249
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Root, { "data-slot": "sheet", ...props });
|
|
17250
|
+
}
|
|
17251
|
+
function SheetTrigger({ ...props }) {
|
|
17252
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Trigger, { "data-slot": "sheet-trigger", ...props });
|
|
17253
|
+
}
|
|
17254
|
+
function SheetClose({ ...props }) {
|
|
17255
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Close, { "data-slot": "sheet-close", ...props });
|
|
17256
|
+
}
|
|
17257
|
+
function SheetPortal({ ...props }) {
|
|
17258
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Portal, { "data-slot": "sheet-portal", ...props });
|
|
17259
|
+
}
|
|
17260
|
+
function SheetOverlay({
|
|
17261
|
+
className,
|
|
17262
|
+
...props
|
|
17263
|
+
}) {
|
|
17264
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17265
|
+
SheetPrimitive__namespace.Overlay,
|
|
17266
|
+
{
|
|
17267
|
+
"data-slot": "sheet-overlay",
|
|
17268
|
+
className: cn(
|
|
17269
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
17270
|
+
className
|
|
17271
|
+
),
|
|
17272
|
+
...props
|
|
17273
|
+
}
|
|
17274
|
+
);
|
|
17275
|
+
}
|
|
17276
|
+
function SheetContent({
|
|
17277
|
+
className,
|
|
17278
|
+
children,
|
|
17279
|
+
side = "right",
|
|
17280
|
+
showClose = true,
|
|
17281
|
+
...props
|
|
17282
|
+
}) {
|
|
17283
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(SheetPortal, { children: [
|
|
17284
|
+
/* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, {}),
|
|
17285
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17286
|
+
SheetPrimitive__namespace.Content,
|
|
17287
|
+
{
|
|
17288
|
+
"data-slot": "sheet-content",
|
|
17289
|
+
className: cn(
|
|
17290
|
+
"fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=closed]:animate-out data-[state=open]:duration-500 data-[state=open]:animate-in",
|
|
17291
|
+
side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
|
17292
|
+
side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
|
17293
|
+
side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
|
17294
|
+
side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
|
17295
|
+
className
|
|
17296
|
+
),
|
|
17297
|
+
...props,
|
|
17298
|
+
children: [
|
|
17299
|
+
children,
|
|
17300
|
+
showClose && /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Close, { "data-slot": "sheet-close", className: "absolute top-4 right-4", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon", children: [
|
|
17301
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
|
|
17302
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
17303
|
+
] }) })
|
|
17304
|
+
]
|
|
17305
|
+
}
|
|
17306
|
+
)
|
|
17307
|
+
] });
|
|
17308
|
+
}
|
|
17309
|
+
function SheetHeader({ className, ...props }) {
|
|
17310
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17311
|
+
"div",
|
|
17312
|
+
{
|
|
17313
|
+
"data-slot": "sheet-header",
|
|
17314
|
+
className: cn("flex flex-col gap-1.5 p-4", className),
|
|
17315
|
+
...props
|
|
17316
|
+
}
|
|
17317
|
+
);
|
|
17318
|
+
}
|
|
17319
|
+
function SheetFooter({ className, ...props }) {
|
|
17320
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17321
|
+
"div",
|
|
17322
|
+
{
|
|
17323
|
+
"data-slot": "sheet-footer",
|
|
17324
|
+
className: cn("mt-auto flex flex-col gap-2 p-4", className),
|
|
17325
|
+
...props
|
|
17326
|
+
}
|
|
17327
|
+
);
|
|
17328
|
+
}
|
|
17329
|
+
function SheetTitle({ className, ...props }) {
|
|
17330
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17331
|
+
SheetPrimitive__namespace.Title,
|
|
17332
|
+
{
|
|
17333
|
+
"data-slot": "sheet-title",
|
|
17334
|
+
className: cn("font-semibold text-foreground", className),
|
|
17335
|
+
...props
|
|
17336
|
+
}
|
|
17337
|
+
);
|
|
17338
|
+
}
|
|
17339
|
+
function SheetDescription({
|
|
17340
|
+
className,
|
|
17341
|
+
...props
|
|
17342
|
+
}) {
|
|
17343
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17344
|
+
SheetPrimitive__namespace.Description,
|
|
17345
|
+
{
|
|
17346
|
+
"data-slot": "sheet-description",
|
|
17347
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
17348
|
+
...props
|
|
17349
|
+
}
|
|
17350
|
+
);
|
|
17351
|
+
}
|
|
17352
|
+
function useSelectorHeight(selector = "header") {
|
|
17353
|
+
const [height, setHeight] = React5.useState(0);
|
|
17354
|
+
const elementRef = React5.useRef(null);
|
|
17355
|
+
const resizeObserverRef = React5.useRef(null);
|
|
17356
|
+
React5.useEffect(() => {
|
|
17357
|
+
const element = document.querySelector(selector);
|
|
17358
|
+
if (!element) return;
|
|
17359
|
+
elementRef.current = element;
|
|
17360
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
17361
|
+
const entry = entries[0];
|
|
17362
|
+
const target = entry?.target ?? elementRef.current;
|
|
17363
|
+
if (!target) return;
|
|
17364
|
+
setHeight(target.offsetHeight);
|
|
17365
|
+
});
|
|
17366
|
+
resizeObserverRef.current = resizeObserver;
|
|
17367
|
+
resizeObserver.observe(element);
|
|
17368
|
+
return () => {
|
|
17369
|
+
resizeObserverRef.current?.disconnect();
|
|
17370
|
+
};
|
|
17371
|
+
}, [selector]);
|
|
17372
|
+
return height;
|
|
17373
|
+
}
|
|
17374
|
+
|
|
17375
|
+
// src/hooks/useStickyOffset.ts
|
|
17376
|
+
function useStickyOffset(extraPadding = 0) {
|
|
17377
|
+
const headerHeight = useSelectorHeight("#nsw-header");
|
|
17378
|
+
const navigationHeight = useSelectorHeight("#nsw-main-navigation");
|
|
17379
|
+
return React5.useMemo(() => {
|
|
17380
|
+
const total = headerHeight + navigationHeight + extraPadding;
|
|
17381
|
+
return total > 0 ? total : 0;
|
|
17382
|
+
}, [extraPadding, headerHeight, navigationHeight]);
|
|
17383
|
+
}
|
|
17384
|
+
var PREFERRED_BACKGROUND_TONES3 = [400, 600, 200, 800, 100, 50];
|
|
17385
|
+
var DEFAULT_VISIBLE_FORMATS3 = ["hex", "rgb", "hsl", "oklch"];
|
|
17386
|
+
var DEFAULT_INITIAL_BACKGROUND_TOKEN3 = "nsw-blue-800";
|
|
17387
|
+
var DEFAULT_INITIAL_PAIR_ID3 = "nsw-blue-800:nsw-blue-200";
|
|
17388
|
+
var COLOR_PAIRING_TOOL_V3_PATH = "/core/colour/colour-pairing-tool-3";
|
|
17389
|
+
var AAA_NORMAL_TEXT_THRESHOLD2 = "7.0:1 for text below the WCAG large-text threshold. Sentence-case body copy should generally stay at 16px+ unless it is microcopy.";
|
|
17390
|
+
var AAA_LARGE_TEXT_THRESHOLD2 = "4.5:1 for WCAG large text: 24px+, or 18.5px+ bold";
|
|
17391
|
+
var MOBILE_RESULT_SCROLL_QUERY = "(max-width: 1023px)";
|
|
17392
|
+
var PERSISTENT_DRAWER_MIN_WIDTH_QUERY = "(min-width: 1280px)";
|
|
17393
|
+
var COLOR_PAIRING_TOOL_DRAWER_STEPS = [
|
|
17394
|
+
{
|
|
17395
|
+
id: "colours",
|
|
17396
|
+
title: "Choose colours",
|
|
17397
|
+
eyebrow: "Step 1 of 3",
|
|
17398
|
+
description: "Select the palette, primary family, and accent family."
|
|
17399
|
+
},
|
|
17400
|
+
{
|
|
17401
|
+
id: "backgrounds",
|
|
17402
|
+
title: "Choose background",
|
|
17403
|
+
eyebrow: "Step 2 of 3",
|
|
17404
|
+
description: "Pick the background tone that you want to pair."
|
|
17405
|
+
},
|
|
17406
|
+
{
|
|
17407
|
+
id: "combinations",
|
|
17408
|
+
title: "Choose recommended combinations",
|
|
17409
|
+
eyebrow: "Step 3 of 3",
|
|
17410
|
+
description: "Select the foreground pairing that should drive the example."
|
|
17411
|
+
}
|
|
17412
|
+
];
|
|
17413
|
+
var COLOR_PAIRING_TOOL_V3_ANALYTICS_EVENT = "nsw-colour-pairing-tool-v3";
|
|
17414
|
+
function getToneFromToken3(token) {
|
|
17415
|
+
if (!token) return null;
|
|
17416
|
+
const match = token.match(/-(\d+)$/);
|
|
17417
|
+
return match ? Number.parseInt(match[1], 10) : null;
|
|
17418
|
+
}
|
|
17419
|
+
function getFamilySwatchColor3(family, preferredTone = 600) {
|
|
17420
|
+
const exactMatch = family.colors.find((color2) => color2.tone === preferredTone);
|
|
17421
|
+
if (exactMatch) {
|
|
17422
|
+
return exactMatch.hex;
|
|
17423
|
+
}
|
|
17424
|
+
const closestMatch = [...family.colors].sort(
|
|
17425
|
+
(left, right) => Math.abs(left.tone - preferredTone) - Math.abs(right.tone - preferredTone)
|
|
17426
|
+
)[0];
|
|
17427
|
+
return closestMatch?.hex ?? "transparent";
|
|
17428
|
+
}
|
|
17429
|
+
function getFamilySelectorLabel3(family, themeCategory, selectionRole) {
|
|
17430
|
+
if (themeCategory !== "aboriginal") {
|
|
17431
|
+
return family.label;
|
|
17432
|
+
}
|
|
17433
|
+
const preferredTone = selectionRole === "primary colour" ? 800 : 600;
|
|
17434
|
+
return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
|
|
17435
|
+
}
|
|
17436
|
+
function getPairingColorDisplayName3(color2) {
|
|
17437
|
+
return color2.name ?? `${color2.familyLabel} ${color2.tone}`;
|
|
17438
|
+
}
|
|
17439
|
+
function isWhiteForegroundPair3(pair) {
|
|
17440
|
+
return pair.foreground.token === "white";
|
|
17441
|
+
}
|
|
17442
|
+
function isLargeTextOnlyPair(pair) {
|
|
17443
|
+
return pair.passes.aaaLarge && !pair.passes.aaaText;
|
|
17444
|
+
}
|
|
17445
|
+
function getWhiteForegroundGuidance3(pair) {
|
|
17446
|
+
if (pair.passes.aaaText) {
|
|
17447
|
+
return "White is approved for headings, body copy, and calls to action on this background.";
|
|
17448
|
+
}
|
|
17449
|
+
if (pair.passes.aaaLarge) {
|
|
17450
|
+
return "Use white only for WCAG large text on this background, such as headings at 24px+ or bold text at 18.5px+. Keep sentence-case body copy at 16px+ and use a darker recommended foreground instead.";
|
|
17451
|
+
}
|
|
17452
|
+
return "Do not use white on this background. Choose one of the recommended foregrounds below instead.";
|
|
17453
|
+
}
|
|
17454
|
+
function getPreviewGuidance3(pair, isRecommended) {
|
|
17455
|
+
if (!isWhiteForegroundPair3(pair)) {
|
|
17456
|
+
return "Use only AAA-recommended combinations across your selected primary, accent, and grey families.";
|
|
17457
|
+
}
|
|
17458
|
+
if (isRecommended) {
|
|
17459
|
+
return "Use white text on dark colour only when it meets AAA for headings, body copy, and calls to action.";
|
|
17460
|
+
}
|
|
17461
|
+
return getWhiteForegroundGuidance3(pair);
|
|
17462
|
+
}
|
|
17463
|
+
function getPreferredPairForBackground3(pairs, preferredPairId) {
|
|
17464
|
+
if (preferredPairId) {
|
|
17465
|
+
const preferredPair = pairs.find((pair) => pair.id === preferredPairId);
|
|
17466
|
+
if (preferredPair) {
|
|
17467
|
+
return preferredPair;
|
|
17468
|
+
}
|
|
17469
|
+
}
|
|
17470
|
+
return pairs.find((pair) => !isWhiteForegroundPair3(pair)) ?? pairs[0] ?? null;
|
|
17471
|
+
}
|
|
17472
|
+
function getDefaultBackgroundToken3(context) {
|
|
17473
|
+
for (const tone of PREFERRED_BACKGROUND_TONES3) {
|
|
17474
|
+
for (const group of context.backgroundGroups) {
|
|
17475
|
+
const match = group.backgrounds.find(
|
|
17476
|
+
(background) => background.tone === tone && (context.pairsByBackground[background.token]?.length ?? 0) > 0
|
|
17477
|
+
);
|
|
17478
|
+
if (match) {
|
|
17479
|
+
return match.token;
|
|
17480
|
+
}
|
|
17481
|
+
}
|
|
17482
|
+
}
|
|
17483
|
+
for (const tone of PREFERRED_BACKGROUND_TONES3) {
|
|
17484
|
+
for (const group of context.backgroundGroups) {
|
|
17485
|
+
const match = group.backgrounds.find((background) => background.tone === tone);
|
|
17486
|
+
if (match) {
|
|
17487
|
+
return match.token;
|
|
17488
|
+
}
|
|
17489
|
+
}
|
|
17490
|
+
}
|
|
17491
|
+
return context.backgrounds[0]?.token ?? "";
|
|
17492
|
+
}
|
|
17493
|
+
function resolveBackgroundToken3(context, preferredToken, preferredTone) {
|
|
17494
|
+
if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
|
|
17495
|
+
return preferredToken;
|
|
17496
|
+
}
|
|
17497
|
+
if (preferredTone !== null && preferredTone !== void 0) {
|
|
17498
|
+
for (const group of context.backgroundGroups) {
|
|
17499
|
+
const match = group.backgrounds.find((background) => background.tone === preferredTone);
|
|
17500
|
+
if (match) {
|
|
17501
|
+
return match.token;
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
}
|
|
17505
|
+
return getDefaultBackgroundToken3(context);
|
|
17506
|
+
}
|
|
17507
|
+
function getInitialPairingState3(searchParams) {
|
|
17508
|
+
const paletteParam = searchParams.get("palette");
|
|
17509
|
+
const primaryParam = searchParams.get("primary");
|
|
17510
|
+
const accentParam = searchParams.get("accent");
|
|
17511
|
+
const pairParam = searchParams.get("pair");
|
|
17512
|
+
const backgroundParam = searchParams.get("background");
|
|
17513
|
+
const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
|
|
17514
|
+
const context = getPairingContext(themeCategory, primaryParam, accentParam);
|
|
17515
|
+
const shouldUseDefaultBrandExample = !backgroundParam && !pairParam && themeCategory === "brand" && context.primary.key === "blue" && context.accent.key === "red";
|
|
17516
|
+
const defaultBackgroundToken = shouldUseDefaultBrandExample ? context.backgrounds.some(
|
|
17517
|
+
(background) => background.token === DEFAULT_INITIAL_BACKGROUND_TOKEN3
|
|
17518
|
+
) ? DEFAULT_INITIAL_BACKGROUND_TOKEN3 : null : null;
|
|
17519
|
+
const defaultPairId = shouldUseDefaultBrandExample && defaultBackgroundToken && context.pairsByBackground[defaultBackgroundToken]?.some(
|
|
17520
|
+
(pair) => pair.id === DEFAULT_INITIAL_PAIR_ID3
|
|
17521
|
+
) ? DEFAULT_INITIAL_PAIR_ID3 : null;
|
|
17522
|
+
const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
|
|
17523
|
+
const selectedBackgroundToken = resolveBackgroundToken3(
|
|
17524
|
+
context,
|
|
17525
|
+
backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
|
|
17526
|
+
getToneFromToken3(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
|
|
17527
|
+
);
|
|
17528
|
+
const selectedPairId = getPreferredPairForBackground3(
|
|
17529
|
+
context.pairsByBackground[selectedBackgroundToken] ?? [],
|
|
17530
|
+
pairParam ?? defaultPairId
|
|
17531
|
+
)?.id ?? "";
|
|
17532
|
+
return {
|
|
17533
|
+
accentKey: context.accent.key,
|
|
17534
|
+
primaryKey: context.primary.key,
|
|
17535
|
+
selectedBackgroundToken,
|
|
17536
|
+
selectedPairId,
|
|
17537
|
+
themeCategory
|
|
17538
|
+
};
|
|
17539
|
+
}
|
|
17540
|
+
function getReadableTextColor2(tone) {
|
|
17541
|
+
return tone >= 600 ? "#ffffff" : "#002664";
|
|
17542
|
+
}
|
|
17543
|
+
function getBackgroundOptionName(background) {
|
|
17544
|
+
return background.name ?? `${background.familyLabel} ${background.tone}`;
|
|
17545
|
+
}
|
|
17546
|
+
function getResultExplanation(pair, bestPair) {
|
|
17547
|
+
if (!pair) {
|
|
17548
|
+
return "No AAA-compliant foreground options available for this selection.";
|
|
17549
|
+
}
|
|
17550
|
+
if (pair.id === bestPair?.id) {
|
|
17551
|
+
return "Meets AAA for normal and large text. This is the NSW-recommended starting point for this background.";
|
|
17552
|
+
}
|
|
17553
|
+
if (isWhiteForegroundPair3(pair) && isLargeTextOnlyPair(pair)) {
|
|
17554
|
+
return "White meets AAA for large text on this background only. Use a darker foreground for standard body copy and smaller interface text.";
|
|
17555
|
+
}
|
|
17556
|
+
if (isWhiteForegroundPair3(pair) && !pair.passes.aaaLarge) {
|
|
17557
|
+
return "White does not meet AAA for normal or large text on this background. Use another approved background or a darker foreground where one is available.";
|
|
17558
|
+
}
|
|
17559
|
+
return "Meets AAA for normal and large text. This is a valid alternative, while the recommended pairing remains the clearest default.";
|
|
17560
|
+
}
|
|
17561
|
+
function getBestRecommendationReason(pair, context) {
|
|
17562
|
+
if (isWhiteForegroundPair3(pair)) {
|
|
17563
|
+
return "Recommended because this background is dark enough to support white text at AAA contrast.";
|
|
17564
|
+
}
|
|
17565
|
+
if (pair.foreground.familyKey === pair.background.familyKey) {
|
|
17566
|
+
return "Recommended because it stays within the same colour family while keeping clear AAA contrast.";
|
|
17567
|
+
}
|
|
17568
|
+
if (pair.foreground.familyKey === context.grey.key) {
|
|
17569
|
+
return "Recommended because grey provides a strong neutral contrast without competing with the background.";
|
|
17570
|
+
}
|
|
17571
|
+
if (pair.foreground.familyKey === context.accent.key) {
|
|
17572
|
+
return "Recommended because the selected accent family adds emphasis while preserving AAA contrast.";
|
|
17573
|
+
}
|
|
17574
|
+
if (pair.foreground.familyKey === context.primary.key) {
|
|
17575
|
+
return "Recommended because the selected primary family gives the clearest AAA-compliant contrast for this background.";
|
|
17576
|
+
}
|
|
17577
|
+
return "Recommended because it is the clearest NSW-approved AAA pairing for this background.";
|
|
17578
|
+
}
|
|
17579
|
+
function getRecommendationCategory(pair, bestPair, context) {
|
|
17580
|
+
if (pair.id === bestPair?.id) return "best";
|
|
17581
|
+
if (isWhiteForegroundPair3(pair)) return "white";
|
|
17582
|
+
if (pair.foreground.familyKey === pair.background.familyKey) return "same-family";
|
|
17583
|
+
if (pair.foreground.familyKey === context.accent.key) return "accent-family";
|
|
17584
|
+
if (pair.foreground.familyKey === context.grey.key) return "grey-option";
|
|
17585
|
+
if (pair.foreground.familyKey === context.primary.key) return "primary-family";
|
|
17586
|
+
return "approved";
|
|
17587
|
+
}
|
|
17588
|
+
function getRecommendationCategoryLabel(category) {
|
|
17589
|
+
switch (category) {
|
|
17590
|
+
case "best":
|
|
17591
|
+
return "Best recommended";
|
|
17592
|
+
case "same-family":
|
|
17593
|
+
return "Same family";
|
|
17594
|
+
case "accent-family":
|
|
17595
|
+
return "Accent family";
|
|
17596
|
+
case "grey-option":
|
|
17597
|
+
return "Grey option";
|
|
17598
|
+
case "primary-family":
|
|
17599
|
+
return "Primary family";
|
|
17600
|
+
case "white":
|
|
17601
|
+
return "White";
|
|
17602
|
+
default:
|
|
17603
|
+
return "Approved option";
|
|
17604
|
+
}
|
|
17605
|
+
}
|
|
17606
|
+
function getRecommendationSortRank(category) {
|
|
17607
|
+
switch (category) {
|
|
17608
|
+
case "best":
|
|
17609
|
+
return 0;
|
|
17610
|
+
case "same-family":
|
|
17611
|
+
return 1;
|
|
17612
|
+
case "accent-family":
|
|
17613
|
+
return 2;
|
|
17614
|
+
case "grey-option":
|
|
17615
|
+
return 3;
|
|
17616
|
+
case "white":
|
|
17617
|
+
return 4;
|
|
17618
|
+
case "primary-family":
|
|
17619
|
+
return 5;
|
|
17620
|
+
default:
|
|
17621
|
+
return 6;
|
|
17622
|
+
}
|
|
17623
|
+
}
|
|
17624
|
+
function getAvailabilityMeta(isSelected, hasPairs) {
|
|
17625
|
+
if (isSelected && hasPairs) {
|
|
17626
|
+
return {
|
|
17627
|
+
description: "Selected background with AAA foreground options.",
|
|
17628
|
+
icon: Icons.check_circle,
|
|
17629
|
+
label: "Selected",
|
|
17630
|
+
tone: "selected"
|
|
17631
|
+
};
|
|
17632
|
+
}
|
|
17633
|
+
if (isSelected) {
|
|
17634
|
+
return {
|
|
17635
|
+
description: "Selected background with no AAA foreground options.",
|
|
17636
|
+
icon: Icons.warning,
|
|
17637
|
+
label: "Selected, no AAA",
|
|
17638
|
+
tone: "unavailable"
|
|
17639
|
+
};
|
|
17640
|
+
}
|
|
17641
|
+
if (hasPairs) {
|
|
17642
|
+
return {
|
|
17643
|
+
description: "AAA foreground options available.",
|
|
17644
|
+
icon: Icons.radio_button_checked,
|
|
17645
|
+
label: "Available",
|
|
17646
|
+
tone: "available"
|
|
17647
|
+
};
|
|
17648
|
+
}
|
|
17649
|
+
return {
|
|
17650
|
+
description: "No AAA foreground available.",
|
|
17651
|
+
icon: Icons.close,
|
|
17652
|
+
label: "No AAA",
|
|
17653
|
+
tone: "unavailable"
|
|
17654
|
+
};
|
|
17655
|
+
}
|
|
17656
|
+
function getPairingCopyText(pair) {
|
|
17657
|
+
return [
|
|
17658
|
+
`Background: ${pair.background.token} (${pair.background.hex})`,
|
|
17659
|
+
`Foreground: ${pair.foreground.token} (${pair.foreground.hex})`,
|
|
17660
|
+
`Contrast ratio: ${pair.contrastRatio.toFixed(2)}:1`,
|
|
17661
|
+
"Accessibility: Meets AAA for normal and large text"
|
|
17662
|
+
].join("\n");
|
|
17663
|
+
}
|
|
17664
|
+
function getLiveAnnouncement(pair, background) {
|
|
17665
|
+
if (!background) {
|
|
17666
|
+
return "No approved background tones available.";
|
|
17667
|
+
}
|
|
17668
|
+
if (!pair) {
|
|
17669
|
+
return `${background.token} selected. No AAA-compliant foreground options available for this selection.`;
|
|
17670
|
+
}
|
|
17671
|
+
if (isWhiteForegroundPair3(pair) && isLargeTextOnlyPair(pair)) {
|
|
17672
|
+
return `${background.token} with white. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Meets AAA for large text only.`;
|
|
17673
|
+
}
|
|
17674
|
+
if (isWhiteForegroundPair3(pair) && !pair.passes.aaaLarge) {
|
|
17675
|
+
return `${background.token} with white. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Fails AAA for normal and large text.`;
|
|
17676
|
+
}
|
|
17677
|
+
return `${background.token} with ${pair.foreground.token}. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Meets AAA for normal and large text.`;
|
|
17678
|
+
}
|
|
17679
|
+
function formatValueRows(color2, visibleFormats) {
|
|
17680
|
+
const hasDisplayTone = color2.token !== "white";
|
|
17681
|
+
return [
|
|
17682
|
+
{ key: "token", label: "Token", value: color2.token, copyable: true },
|
|
17683
|
+
{
|
|
17684
|
+
key: "tone",
|
|
17685
|
+
label: "Tone",
|
|
17686
|
+
value: hasDisplayTone ? String(color2.tone) : "Not applicable",
|
|
17687
|
+
copyable: hasDisplayTone
|
|
17688
|
+
},
|
|
17689
|
+
...visibleFormats.map((format) => ({
|
|
17690
|
+
key: format,
|
|
17691
|
+
label: format.toUpperCase(),
|
|
17692
|
+
value: color2[format],
|
|
17693
|
+
copyable: true
|
|
17694
|
+
}))
|
|
17695
|
+
];
|
|
17696
|
+
}
|
|
17697
|
+
function SelectorButton({
|
|
17698
|
+
description,
|
|
17699
|
+
isSelected,
|
|
17700
|
+
label,
|
|
17701
|
+
onClick,
|
|
17702
|
+
swatch
|
|
17703
|
+
}) {
|
|
17704
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17705
|
+
"button",
|
|
17706
|
+
{
|
|
17707
|
+
type: "button",
|
|
17708
|
+
"aria-pressed": isSelected,
|
|
17709
|
+
onClick,
|
|
17710
|
+
className: cn(
|
|
17711
|
+
"w-full rounded-sm border px-3 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
|
|
17712
|
+
isSelected ? "border-primary-800 bg-primary-50" : "border-grey-300 bg-white hover:border-primary-500 hover:bg-grey-50"
|
|
17713
|
+
),
|
|
17714
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
17715
|
+
swatch ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
17716
|
+
"span",
|
|
17717
|
+
{
|
|
17718
|
+
"aria-hidden": "true",
|
|
17719
|
+
className: "mt-0.5 size-4 shrink-0 rounded-full border border-black/10",
|
|
17720
|
+
style: { backgroundColor: swatch }
|
|
17721
|
+
}
|
|
17722
|
+
) : null,
|
|
17723
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
17724
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-foreground", children: label }),
|
|
17725
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs/5 text-muted-foreground", children: description }) : null
|
|
17726
|
+
] })
|
|
17727
|
+
] })
|
|
17728
|
+
}
|
|
17729
|
+
);
|
|
17730
|
+
}
|
|
17731
|
+
function BackgroundSwatchButton({
|
|
17732
|
+
background,
|
|
17733
|
+
hasPairs,
|
|
17734
|
+
isSelected,
|
|
17735
|
+
onClick
|
|
17736
|
+
}) {
|
|
17737
|
+
const status = getAvailabilityMeta(isSelected, hasPairs);
|
|
17738
|
+
const StatusIcon = status.icon;
|
|
17739
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17740
|
+
"button",
|
|
17741
|
+
{
|
|
17742
|
+
type: "button",
|
|
17743
|
+
"aria-pressed": isSelected,
|
|
17744
|
+
"aria-label": `Select ${background.token} background. ${status.description}`,
|
|
17745
|
+
onClick,
|
|
17746
|
+
className: cn(
|
|
17747
|
+
"w-full rounded-sm border bg-white p-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
|
|
17748
|
+
isSelected ? "border-primary-800 bg-primary-50" : hasPairs ? "border-grey-300 hover:border-primary-500 hover:bg-grey-50" : "border-grey-300 hover:border-grey-500"
|
|
17749
|
+
),
|
|
17750
|
+
children: [
|
|
17751
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
17752
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
17753
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-foreground", children: getBackgroundOptionName(background) }),
|
|
17754
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-muted-foreground", children: background.token })
|
|
17755
|
+
] }),
|
|
17756
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17757
|
+
"span",
|
|
17758
|
+
{
|
|
17759
|
+
className: cn(
|
|
17760
|
+
"inline-flex items-center gap-1 rounded-sm border px-2 py-1 text-[0.68rem] font-semibold uppercase",
|
|
17761
|
+
status.tone === "selected" && "border-primary-800 bg-primary-800 text-white dark:border-primary-500 dark:bg-primary-500",
|
|
17762
|
+
status.tone === "available" && "border-grey-300 bg-grey-50 text-foreground",
|
|
17763
|
+
status.tone === "unavailable" && "border-danger-300 bg-danger-50 text-danger-900 dark:border-danger-800 dark:bg-danger-950/20 dark:text-danger-200"
|
|
17764
|
+
),
|
|
17765
|
+
children: [
|
|
17766
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { "data-slot": "icon", className: "size-4" }),
|
|
17767
|
+
status.label
|
|
17768
|
+
]
|
|
17769
|
+
}
|
|
17770
|
+
)
|
|
17771
|
+
] }),
|
|
17772
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 overflow-hidden rounded-[2px] border border-black/10", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-14 w-full", style: { backgroundColor: background.hex } }) }),
|
|
17773
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-xs/5 text-muted-foreground", children: status.description })
|
|
17774
|
+
]
|
|
17775
|
+
}
|
|
17776
|
+
);
|
|
17777
|
+
}
|
|
17778
|
+
function ResultSummaryTile({
|
|
17779
|
+
children,
|
|
17780
|
+
className,
|
|
17781
|
+
label
|
|
17782
|
+
}) {
|
|
17783
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("rounded-sm border border-grey-200 bg-white px-4 py-4 sm:px-5", className), children: [
|
|
17784
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-grey-700", children: label }),
|
|
17785
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children })
|
|
17786
|
+
] });
|
|
17787
|
+
}
|
|
17788
|
+
function AccessibilityCheckTile({
|
|
17789
|
+
className,
|
|
17790
|
+
label,
|
|
17791
|
+
passes,
|
|
17792
|
+
threshold
|
|
17793
|
+
}) {
|
|
17794
|
+
const status = passes === null ? "unavailable" : passes ? "pass" : "fail";
|
|
17795
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17796
|
+
"div",
|
|
17797
|
+
{
|
|
17798
|
+
className: cn(
|
|
17799
|
+
"rounded-sm border px-4 py-4 sm:px-5",
|
|
17800
|
+
className,
|
|
17801
|
+
status === "pass" && "border-success-200 bg-success-50",
|
|
17802
|
+
status === "fail" && "border-danger-200 bg-danger-50",
|
|
17803
|
+
status === "unavailable" && "border-grey-200 bg-white"
|
|
17804
|
+
),
|
|
17805
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4", children: [
|
|
17806
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
17807
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-foreground", children: label }),
|
|
17808
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm/6 text-muted-foreground", children: status === "unavailable" ? "No contrast ratio available for this result." : threshold })
|
|
17809
|
+
] }),
|
|
17810
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17811
|
+
"span",
|
|
17812
|
+
{
|
|
17813
|
+
className: cn(
|
|
17814
|
+
"inline-flex items-center gap-1 rounded-sm px-2.5 py-1 text-[0.72rem] font-semibold tracking-[0.12em] uppercase",
|
|
17815
|
+
status === "pass" && "bg-success-700 text-white",
|
|
17816
|
+
status === "fail" && "bg-danger-700 text-white",
|
|
17817
|
+
status === "unavailable" && "bg-grey-100 text-foreground"
|
|
17818
|
+
),
|
|
17819
|
+
children: [
|
|
17820
|
+
status === "pass" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : status === "fail" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.close, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.info, { "data-slot": "icon", className: "size-4" }),
|
|
17821
|
+
status === "pass" ? "Pass" : status === "fail" ? "Fail" : "Unavailable"
|
|
17822
|
+
]
|
|
17823
|
+
}
|
|
17824
|
+
)
|
|
17825
|
+
] })
|
|
17826
|
+
}
|
|
17827
|
+
);
|
|
17828
|
+
}
|
|
17829
|
+
function ResultColorSummary({
|
|
17830
|
+
color: color2,
|
|
17831
|
+
fallbackLabel
|
|
17832
|
+
}) {
|
|
17833
|
+
if (!color2) {
|
|
17834
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: fallbackLabel ?? "Not available" });
|
|
17835
|
+
}
|
|
17836
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-4", children: [
|
|
17837
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17838
|
+
"span",
|
|
17839
|
+
{
|
|
17840
|
+
"aria-hidden": "true",
|
|
17841
|
+
className: "mt-1 size-6 shrink-0 rounded-full border border-black/10",
|
|
17842
|
+
style: { backgroundColor: color2.hex }
|
|
17843
|
+
}
|
|
17844
|
+
),
|
|
17845
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
17846
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "leading-7 font-semibold text-foreground", children: getPairingColorDisplayName3(color2) }),
|
|
17847
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 font-mono text-sm break-all text-muted-foreground", children: color2.token })
|
|
17848
|
+
] })
|
|
17849
|
+
] });
|
|
17850
|
+
}
|
|
17851
|
+
function CurrentResultCard({
|
|
17852
|
+
bestPair,
|
|
17853
|
+
familySummary,
|
|
17854
|
+
pair,
|
|
17855
|
+
selectedBackground
|
|
17856
|
+
}) {
|
|
17857
|
+
const previewForeground = pair?.foreground.hex ?? getReadableTextColor2(selectedBackground.tone);
|
|
17858
|
+
const isRecommended = pair ? pair.id === bestPair?.id : false;
|
|
17859
|
+
const whiteForeground = pair ? isWhiteForegroundPair3(pair) : false;
|
|
17860
|
+
const statusLabel = pair ? pair.passes.aaaText ? "Pass" : pair.passes.aaaLarge ? "Large text only" : "Example only" : "No recommendation";
|
|
17861
|
+
const fauxButtonStyle = pair ? {
|
|
17862
|
+
"--btn-bg": pair.foreground.hex,
|
|
17863
|
+
"--btn-border": pair.foreground.hex,
|
|
17864
|
+
"--btn-text": pair.background.hex,
|
|
17865
|
+
"--btn-icon": pair.background.hex,
|
|
17866
|
+
"--btn-hover-overlay": pair.background.hex
|
|
17867
|
+
} : null;
|
|
17868
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-0 overflow-hidden py-0", children: [
|
|
17869
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-6 sm:py-5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
17870
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
17871
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: "Current result" }),
|
|
17872
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 4, className: "text-foreground", trim: "normal", children: pair ? `${getPairingColorDisplayName3(pair.foreground)} on ${getPairingColorDisplayName3(pair.background)}` : `${getPairingColorDisplayName3(selectedBackground)} selected` })
|
|
17873
|
+
] }),
|
|
17874
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, className: "max-w-3xl text-grey-700", children: getResultExplanation(pair, bestPair) })
|
|
17875
|
+
] }) }),
|
|
17876
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17877
|
+
"div",
|
|
17878
|
+
{
|
|
17879
|
+
className: "p-4 sm:min-h-[26rem] sm:p-8",
|
|
17880
|
+
style: {
|
|
17881
|
+
backgroundColor: selectedBackground.hex,
|
|
17882
|
+
color: previewForeground
|
|
17883
|
+
},
|
|
17884
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-[18rem] flex-col justify-between gap-6 sm:min-h-[22rem] sm:gap-8", children: [
|
|
17885
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
17886
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17887
|
+
"span",
|
|
17888
|
+
{
|
|
17889
|
+
className: "inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[0.68rem] font-semibold tracking-[0.16em] uppercase sm:text-[0.72rem]",
|
|
17890
|
+
style: {
|
|
17891
|
+
borderColor: pair ? pair.foreground.hex : "currentColor",
|
|
17892
|
+
backgroundColor: pair ? pair.foreground.hex : "transparent",
|
|
17893
|
+
color: pair ? pair.background.hex : "currentColor"
|
|
17894
|
+
},
|
|
17895
|
+
children: [
|
|
17896
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
|
|
17897
|
+
familySummary
|
|
17898
|
+
]
|
|
17899
|
+
}
|
|
17900
|
+
),
|
|
17901
|
+
pair ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17902
|
+
"span",
|
|
17903
|
+
{
|
|
17904
|
+
className: "inline-flex rounded-full border px-3 py-1 text-[0.68rem] font-semibold tracking-[0.16em] uppercase sm:text-[0.72rem]",
|
|
17905
|
+
style: {
|
|
17906
|
+
borderColor: pair.foreground.hex
|
|
17907
|
+
},
|
|
17908
|
+
children: [
|
|
17909
|
+
pair.rating,
|
|
17910
|
+
" ",
|
|
17911
|
+
pair.contrastRatio.toFixed(2),
|
|
17912
|
+
":1"
|
|
17913
|
+
]
|
|
17914
|
+
}
|
|
17915
|
+
) : null
|
|
17916
|
+
] }),
|
|
17917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xl space-y-4 pb-8 sm:pb-16", children: [
|
|
17918
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: pair ? whiteForeground && !isRecommended ? "White on colour example" : whiteForeground ? "White on colour" : "Colour on colour" : "Approved background" }),
|
|
17919
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
17920
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "max-w-lg text-3xl leading-tight font-bold text-current sm:text-5xl sm:leading-none", children: "Pair colour with confidence." }),
|
|
17921
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-full text-base/6 sm:max-w-md sm:text-base/7", children: pair ? getPreviewGuidance3(pair, isRecommended) : "This approved background tone does not currently have a recommended AAA foreground in this tool. Choose another approved background tone to continue." }),
|
|
17922
|
+
pair && fauxButtonStyle ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
17923
|
+
"span",
|
|
17924
|
+
{
|
|
17925
|
+
"aria-hidden": "true",
|
|
17926
|
+
"data-variant": "solid",
|
|
17927
|
+
className: cn(
|
|
17928
|
+
buttonVariants({ variant: "solid", size: "default" }),
|
|
17929
|
+
"pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
|
|
17930
|
+
),
|
|
17931
|
+
style: fauxButtonStyle,
|
|
17932
|
+
children: "Get started"
|
|
17933
|
+
}
|
|
17934
|
+
) : null
|
|
17935
|
+
] })
|
|
17936
|
+
] }),
|
|
17937
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
17938
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17939
|
+
"span",
|
|
17940
|
+
{
|
|
17941
|
+
className: "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold",
|
|
17942
|
+
style: pair ? {
|
|
17943
|
+
backgroundColor: pair.foreground.hex,
|
|
17944
|
+
color: pair.background.hex
|
|
17945
|
+
} : {
|
|
17946
|
+
backgroundColor: "rgb(255 255 255 / 0.14)",
|
|
17947
|
+
color: "currentColor"
|
|
17948
|
+
},
|
|
17949
|
+
children: [
|
|
17950
|
+
statusLabel,
|
|
17951
|
+
pair && pair.passes.aaaText ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.info, { "data-slot": "icon", className: "size-4" })
|
|
17952
|
+
]
|
|
17953
|
+
}
|
|
17954
|
+
),
|
|
17955
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17956
|
+
"span",
|
|
17957
|
+
{
|
|
17958
|
+
className: "inline-flex max-w-full rounded-full border px-4 py-2 text-[0.82rem] break-all sm:text-sm",
|
|
17959
|
+
style: {
|
|
17960
|
+
borderColor: pair ? pair.foreground.hex : "currentColor"
|
|
17961
|
+
},
|
|
17962
|
+
children: pair ? `${pair.background.token} / ${pair.foreground.token}` : selectedBackground.token
|
|
17963
|
+
}
|
|
17964
|
+
)
|
|
17965
|
+
] })
|
|
17966
|
+
] })
|
|
17967
|
+
}
|
|
17968
|
+
),
|
|
17969
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-5 border-t border-grey-200 bg-grey-50 px-4 py-5 sm:px-6 sm:py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
|
|
17970
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResultSummaryTile, { label: "Background", children: /* @__PURE__ */ jsxRuntime.jsx(ResultColorSummary, { color: selectedBackground }) }),
|
|
17971
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResultSummaryTile, { label: "Foreground", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17972
|
+
ResultColorSummary,
|
|
17973
|
+
{
|
|
17974
|
+
color: pair?.foreground,
|
|
17975
|
+
fallbackLabel: "No AAA foreground available"
|
|
17976
|
+
}
|
|
17977
|
+
) }),
|
|
17978
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ResultSummaryTile, { label: "Contrast ratio", className: "lg:col-span-2", children: [
|
|
17979
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-4xl leading-none font-bold text-foreground", children: pair ? `${pair.contrastRatio.toFixed(2)}:1` : "N/A" }),
|
|
17980
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: pair ? pair.passes.aaaText ? "Meets AAA accessibility" : pair.passes.aaaLarge ? "Meets AAA for large text only" : "Does not meet accessibility requirements" : "Does not meet accessibility requirements" })
|
|
17981
|
+
] }),
|
|
17982
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17983
|
+
AccessibilityCheckTile,
|
|
17984
|
+
{
|
|
17985
|
+
className: "lg:col-span-2",
|
|
17986
|
+
label: "AAA normal text",
|
|
17987
|
+
passes: pair ? pair.passes.aaaText : null,
|
|
17988
|
+
threshold: AAA_NORMAL_TEXT_THRESHOLD2
|
|
17989
|
+
}
|
|
17990
|
+
),
|
|
17991
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17992
|
+
AccessibilityCheckTile,
|
|
17993
|
+
{
|
|
17994
|
+
className: "lg:col-span-2",
|
|
17995
|
+
label: "AAA large text",
|
|
17996
|
+
passes: pair ? pair.passes.aaaLarge : null,
|
|
17997
|
+
threshold: AAA_LARGE_TEXT_THRESHOLD2
|
|
17998
|
+
}
|
|
17999
|
+
)
|
|
18000
|
+
] }) })
|
|
18001
|
+
] });
|
|
18002
|
+
}
|
|
18003
|
+
function BestRecommendationCard({
|
|
18004
|
+
copiedKey,
|
|
18005
|
+
isCurrentSelection,
|
|
18006
|
+
onCopyPairing,
|
|
18007
|
+
onUsePairing,
|
|
18008
|
+
pair,
|
|
18009
|
+
reason
|
|
18010
|
+
}) {
|
|
18011
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-5 border-primary-200 bg-primary-50/60 px-6 py-6", children: [
|
|
18012
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-5", children: [
|
|
18013
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
18014
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
18015
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2 rounded-sm bg-primary-800 px-3 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-white uppercase", children: [
|
|
18016
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.check_circle, { "data-slot": "icon", className: "size-4" }),
|
|
18017
|
+
"Best recommended pairing"
|
|
18018
|
+
] }),
|
|
18019
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex rounded-sm border border-primary-300 px-3 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-primary-900 uppercase", children: [
|
|
18020
|
+
pair.contrastRatio.toFixed(2),
|
|
18021
|
+
":1"
|
|
18022
|
+
] })
|
|
18023
|
+
] }),
|
|
18024
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
18025
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: [
|
|
18026
|
+
pair.background.token,
|
|
18027
|
+
" / ",
|
|
18028
|
+
pair.foreground.token
|
|
18029
|
+
] }),
|
|
18030
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, className: "max-w-3xl text-grey-700", children: reason })
|
|
18031
|
+
] })
|
|
18032
|
+
] }),
|
|
18033
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center", children: [
|
|
18034
|
+
isCurrentSelection ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
18035
|
+
Button2,
|
|
18036
|
+
{
|
|
18037
|
+
className: "w-full justify-center sm:w-auto sm:min-w-56",
|
|
18038
|
+
color: "primary",
|
|
18039
|
+
onClick: onUsePairing,
|
|
18040
|
+
"aria-label": `Use ${pair.foreground.token} on ${pair.background.token}`,
|
|
18041
|
+
children: "Use best recommendation"
|
|
18042
|
+
}
|
|
18043
|
+
),
|
|
18044
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18045
|
+
Button2,
|
|
18046
|
+
{
|
|
18047
|
+
className: "w-full justify-center sm:w-auto sm:min-w-48",
|
|
18048
|
+
variant: "outline",
|
|
18049
|
+
color: "grey",
|
|
18050
|
+
onClick: onCopyPairing,
|
|
18051
|
+
children: [
|
|
18052
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
|
|
18053
|
+
copiedKey === "best-pairing" ? "Pairing copied" : "Copy pairing"
|
|
18054
|
+
]
|
|
18055
|
+
}
|
|
18056
|
+
)
|
|
18057
|
+
] })
|
|
18058
|
+
] }),
|
|
18059
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
|
|
18060
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResultSummaryTile, { label: "Background", children: /* @__PURE__ */ jsxRuntime.jsx(ResultColorSummary, { color: pair.background }) }),
|
|
18061
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResultSummaryTile, { label: "Foreground", children: /* @__PURE__ */ jsxRuntime.jsx(ResultColorSummary, { color: pair.foreground }) }),
|
|
18062
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ResultSummaryTile, { label: "Accessibility", className: "md:col-span-2", children: [
|
|
18063
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xl leading-8 font-semibold text-foreground", children: "Meets AAA accessibility" }),
|
|
18064
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-base/7 text-muted-foreground", children: "Best NSW default for this background." })
|
|
18065
|
+
] })
|
|
18066
|
+
] })
|
|
18067
|
+
] });
|
|
18068
|
+
}
|
|
18069
|
+
function RecommendationCard({
|
|
18070
|
+
copiedKey,
|
|
18071
|
+
isSelected,
|
|
18072
|
+
item,
|
|
18073
|
+
onCopyPairing,
|
|
18074
|
+
onSelect
|
|
18075
|
+
}) {
|
|
18076
|
+
const { pair } = item;
|
|
18077
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18078
|
+
"div",
|
|
18079
|
+
{
|
|
18080
|
+
className: cn(
|
|
18081
|
+
"relative rounded-sm border bg-white p-4 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
|
|
18082
|
+
isSelected ? "border-primary-800 bg-primary-50/50" : "border-grey-200 hover:border-primary-500 hover:bg-grey-50"
|
|
18083
|
+
),
|
|
18084
|
+
children: [
|
|
18085
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18086
|
+
"button",
|
|
18087
|
+
{
|
|
18088
|
+
type: "button",
|
|
18089
|
+
"aria-pressed": isSelected,
|
|
18090
|
+
"aria-label": `Use ${pair.foreground.token} on ${pair.background.token}`,
|
|
18091
|
+
onClick: onSelect,
|
|
18092
|
+
className: "absolute inset-0 rounded-sm focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden"
|
|
18093
|
+
}
|
|
18094
|
+
),
|
|
18095
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-none relative z-10", children: [
|
|
18096
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
18097
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18098
|
+
"span",
|
|
18099
|
+
{
|
|
18100
|
+
className: cn(
|
|
18101
|
+
"inline-flex items-center gap-2 rounded-sm px-2.5 py-1 text-[0.68rem] font-semibold tracking-[0.12em] uppercase",
|
|
18102
|
+
item.category === "best" ? "bg-primary-800 text-white" : "border border-grey-300 bg-grey-50 text-foreground"
|
|
18103
|
+
),
|
|
18104
|
+
children: [
|
|
18105
|
+
item.category === "best" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check_circle, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.info, { "data-slot": "icon", className: "size-4" }),
|
|
18106
|
+
item.categoryLabel
|
|
18107
|
+
]
|
|
18108
|
+
}
|
|
18109
|
+
),
|
|
18110
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto shrink-0 self-start", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18111
|
+
Button2,
|
|
18112
|
+
{
|
|
18113
|
+
variant: "ghost",
|
|
18114
|
+
color: "grey",
|
|
18115
|
+
size: "sm",
|
|
18116
|
+
onClick: onCopyPairing,
|
|
18117
|
+
"aria-label": `Copy pairing ${pair.background.token} and ${pair.foreground.token}`,
|
|
18118
|
+
children: [
|
|
18119
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
|
|
18120
|
+
copiedKey === `pair:${pair.id}` ? "Copied" : "Copy"
|
|
18121
|
+
]
|
|
18122
|
+
}
|
|
18123
|
+
) })
|
|
18124
|
+
] }),
|
|
18125
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4", children: [
|
|
18126
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 sm:grid-cols-[4rem_minmax(0,1fr)]", children: [
|
|
18127
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-[2px] border border-black/10", children: [
|
|
18128
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16 w-full", style: { backgroundColor: pair.background.hex } }),
|
|
18129
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-full", style: { backgroundColor: pair.foreground.hex } })
|
|
18130
|
+
] }),
|
|
18131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-2", children: [
|
|
18132
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
18133
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-semibold text-foreground", children: getPairingColorDisplayName3(pair.foreground) }),
|
|
18134
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 font-mono text-[0.74rem] break-all text-muted-foreground", children: pair.foreground.token })
|
|
18135
|
+
] }),
|
|
18136
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
18137
|
+
pair.foreground.familyLabel,
|
|
18138
|
+
" on ",
|
|
18139
|
+
pair.background.familyLabel
|
|
18140
|
+
] })
|
|
18141
|
+
] })
|
|
18142
|
+
] }),
|
|
18143
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex flex-col items-start gap-3 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: [
|
|
18144
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
18145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex rounded-sm border border-grey-300 px-2.5 py-1 text-sm font-semibold text-foreground", children: [
|
|
18146
|
+
pair.contrastRatio.toFixed(2),
|
|
18147
|
+
":1"
|
|
18148
|
+
] }),
|
|
18149
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex rounded-sm bg-success-700 px-2.5 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-white uppercase", children: "AAA" })
|
|
18150
|
+
] }),
|
|
18151
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-primary-800", children: isSelected ? "Selected" : "Use pairing" })
|
|
18152
|
+
] })
|
|
18153
|
+
] })
|
|
18154
|
+
] })
|
|
18155
|
+
]
|
|
18156
|
+
}
|
|
18157
|
+
);
|
|
18158
|
+
}
|
|
18159
|
+
function TechnicalDetailsPanel({
|
|
18160
|
+
color: color2,
|
|
18161
|
+
copiedKey,
|
|
18162
|
+
onCopyValue,
|
|
18163
|
+
title,
|
|
18164
|
+
visibleFormats
|
|
18165
|
+
}) {
|
|
18166
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-grey-200 bg-white", children: [
|
|
18167
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-5", children: [
|
|
18168
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: title }),
|
|
18169
|
+
color2 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18170
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: getPairingColorDisplayName3(color2) }),
|
|
18171
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 overflow-hidden rounded-sm border border-black/10 bg-white", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-20 w-full sm:h-24", style: { backgroundColor: color2.hex } }) })
|
|
18172
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "No AAA foreground available." })
|
|
18173
|
+
] }),
|
|
18174
|
+
color2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-grey-200", children: formatValueRows(color2, visibleFormats).map((row) => {
|
|
18175
|
+
const copyKey = `${title}-${row.key}`;
|
|
18176
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18177
|
+
"div",
|
|
18178
|
+
{
|
|
18179
|
+
className: "flex flex-col items-start gap-3 px-4 py-4 sm:flex-row sm:items-start sm:justify-between sm:gap-4 sm:px-5",
|
|
18180
|
+
children: [
|
|
18181
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
18182
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: row.label }),
|
|
18183
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18184
|
+
"p",
|
|
18185
|
+
{
|
|
18186
|
+
className: cn(
|
|
18187
|
+
"mt-2 text-sm text-foreground",
|
|
18188
|
+
row.key !== "tone" && "font-mono break-all"
|
|
18189
|
+
),
|
|
18190
|
+
children: row.value
|
|
18191
|
+
}
|
|
18192
|
+
)
|
|
18193
|
+
] }),
|
|
18194
|
+
row.copyable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
18195
|
+
Button2,
|
|
18196
|
+
{
|
|
18197
|
+
variant: "ghost",
|
|
18198
|
+
color: "grey",
|
|
18199
|
+
size: "sm",
|
|
18200
|
+
className: "self-start",
|
|
18201
|
+
onClick: () => onCopyValue(copyKey, row.value, `${row.label} copied`),
|
|
18202
|
+
"aria-label": `Copy ${title.toLowerCase()} ${row.label.toLowerCase()}`,
|
|
18203
|
+
children: copiedKey === copyKey ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18204
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.check_circle, { "data-slot": "icon", className: "size-5" }),
|
|
18205
|
+
"Copied"
|
|
18206
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18207
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
|
|
18208
|
+
"Copy"
|
|
18209
|
+
] })
|
|
18210
|
+
}
|
|
18211
|
+
) : null
|
|
18212
|
+
]
|
|
18213
|
+
},
|
|
18214
|
+
row.key
|
|
18215
|
+
);
|
|
18216
|
+
}) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-5", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "No technical values are shown because there is no AAA-compliant foreground for this background." }) })
|
|
18217
|
+
] });
|
|
18218
|
+
}
|
|
18219
|
+
function resolveSelectionState(nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) {
|
|
18220
|
+
const context = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
|
|
18221
|
+
const selectedBackgroundToken = resolveBackgroundToken3(
|
|
18222
|
+
context,
|
|
18223
|
+
preferredBackgroundToken,
|
|
18224
|
+
getToneFromToken3(preferredBackgroundToken)
|
|
18225
|
+
);
|
|
18226
|
+
const selectedPairId = getPreferredPairForBackground3(
|
|
18227
|
+
context.pairsByBackground[selectedBackgroundToken] ?? [],
|
|
18228
|
+
preferredPairId
|
|
18229
|
+
)?.id ?? "";
|
|
18230
|
+
return {
|
|
18231
|
+
accentKey: context.accent.key,
|
|
18232
|
+
context,
|
|
18233
|
+
primaryKey: context.primary.key,
|
|
18234
|
+
selectedBackgroundToken,
|
|
18235
|
+
selectedPairId,
|
|
18236
|
+
themeCategory: nextThemeCategory
|
|
18237
|
+
};
|
|
18238
|
+
}
|
|
18239
|
+
function ColorPairingToolV3Loading() {
|
|
18240
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-8 xl:grid-cols-[minmax(18rem,24rem)_minmax(0,1fr)]", children: [
|
|
18241
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
18242
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-52 rounded-sm border border-grey-200 bg-grey-50" }),
|
|
18243
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[32rem] rounded-sm border border-grey-200 bg-grey-50" })
|
|
18244
|
+
] }),
|
|
18245
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
18246
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-96 rounded-sm border border-grey-200 bg-grey-50" }),
|
|
18247
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 rounded-sm border border-grey-200 bg-grey-50" }),
|
|
18248
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-72 rounded-sm border border-grey-200 bg-grey-50" })
|
|
18249
|
+
] })
|
|
18250
|
+
] });
|
|
18251
|
+
}
|
|
18252
|
+
function ColorPairingToolV3Content({
|
|
18253
|
+
onAnalyticsEvent,
|
|
18254
|
+
visibleFormats
|
|
18255
|
+
}) {
|
|
18256
|
+
const searchParams = navigation.useSearchParams();
|
|
18257
|
+
const stickyOffset = useStickyOffset(24);
|
|
18258
|
+
const [initialState] = React5.useState(() => getInitialPairingState3(searchParams));
|
|
18259
|
+
const [themeCategory, setThemeCategory] = React5.useState(initialState.themeCategory);
|
|
18260
|
+
const [primaryFamilyKey, setPrimaryFamilyKey] = React5.useState(initialState.primaryKey);
|
|
18261
|
+
const [accentFamilyKey, setAccentFamilyKey] = React5.useState(initialState.accentKey);
|
|
18262
|
+
const [selectedBackgroundToken, setSelectedBackgroundToken] = React5.useState(
|
|
18263
|
+
initialState.selectedBackgroundToken
|
|
18264
|
+
);
|
|
18265
|
+
const [selectedPairId, setSelectedPairId] = React5.useState(initialState.selectedPairId);
|
|
18266
|
+
const [drawerStepIndex, setDrawerStepIndex] = React5.useState(0);
|
|
18267
|
+
const [isCompactControlsOpen, setIsCompactControlsOpen] = React5.useState(false);
|
|
18268
|
+
const [, copyToClipboardRaw] = usehooks.useCopyToClipboard();
|
|
18269
|
+
const [copiedKey, setCopiedKey] = React5.useState(null);
|
|
18270
|
+
const copiedKeyTimeoutRef = React5.useRef(null);
|
|
18271
|
+
const resultSectionRef = React5.useRef(null);
|
|
18272
|
+
const noValidStateRef = React5.useRef(/* @__PURE__ */ new Set());
|
|
18273
|
+
const technicalDetailsOpenedRef = React5.useRef(false);
|
|
18274
|
+
const emitAnalyticsEvent = React5.useCallback(
|
|
18275
|
+
(event) => {
|
|
18276
|
+
onAnalyticsEvent(event);
|
|
18277
|
+
if (typeof window !== "undefined") {
|
|
18278
|
+
window.dispatchEvent(
|
|
18279
|
+
new CustomEvent(COLOR_PAIRING_TOOL_V3_ANALYTICS_EVENT, {
|
|
18280
|
+
detail: event
|
|
18281
|
+
})
|
|
18282
|
+
);
|
|
18283
|
+
}
|
|
18284
|
+
},
|
|
18285
|
+
[onAnalyticsEvent]
|
|
18286
|
+
);
|
|
18287
|
+
React5.useEffect(() => {
|
|
18288
|
+
return () => {
|
|
18289
|
+
if (copiedKeyTimeoutRef.current) {
|
|
18290
|
+
clearTimeout(copiedKeyTimeoutRef.current);
|
|
18291
|
+
}
|
|
18292
|
+
};
|
|
18293
|
+
}, []);
|
|
18294
|
+
React5.useEffect(() => {
|
|
18295
|
+
if (typeof window === "undefined") {
|
|
18296
|
+
return;
|
|
18297
|
+
}
|
|
18298
|
+
const mediaQuery = window.matchMedia(PERSISTENT_DRAWER_MIN_WIDTH_QUERY);
|
|
18299
|
+
const handleChange = (event) => {
|
|
18300
|
+
if (event?.matches ?? mediaQuery.matches) {
|
|
18301
|
+
setIsCompactControlsOpen(false);
|
|
18302
|
+
}
|
|
18303
|
+
};
|
|
18304
|
+
handleChange();
|
|
18305
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
18306
|
+
return () => {
|
|
18307
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
18308
|
+
};
|
|
18309
|
+
}, []);
|
|
18310
|
+
const themeFamilies = React5.useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
|
|
18311
|
+
const context = React5.useMemo(
|
|
18312
|
+
() => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
|
|
18313
|
+
[themeCategory, primaryFamilyKey, accentFamilyKey]
|
|
18314
|
+
);
|
|
18315
|
+
const selectableFamilies = React5.useMemo(
|
|
18316
|
+
() => themeFamilies.filter((family) => family.key !== context.grey.key),
|
|
18317
|
+
[themeFamilies, context.grey.key]
|
|
18318
|
+
);
|
|
18319
|
+
const selectableAccentFamilies = React5.useMemo(
|
|
18320
|
+
() => selectableFamilies.filter((family) => family.key !== context.primary.key),
|
|
18321
|
+
[selectableFamilies, context.primary.key]
|
|
18322
|
+
);
|
|
18323
|
+
const selectedBackground = React5.useMemo(
|
|
18324
|
+
() => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
|
|
18325
|
+
[context.backgrounds, selectedBackgroundToken]
|
|
18326
|
+
);
|
|
18327
|
+
const selectedBackgroundPairs = React5.useMemo(
|
|
18328
|
+
() => selectedBackground ? context.pairsByBackground[selectedBackground.token] ?? [] : [],
|
|
18329
|
+
[context.pairsByBackground, selectedBackground]
|
|
18330
|
+
);
|
|
18331
|
+
const bestRecommendedPair = React5.useMemo(
|
|
18332
|
+
() => getPreferredPairForBackground3(selectedBackgroundPairs),
|
|
18333
|
+
[selectedBackgroundPairs]
|
|
18334
|
+
);
|
|
18335
|
+
const selectedPair = React5.useMemo(
|
|
18336
|
+
() => getPreferredPairForBackground3(selectedBackgroundPairs, selectedPairId),
|
|
18337
|
+
[selectedBackgroundPairs, selectedPairId]
|
|
18338
|
+
);
|
|
18339
|
+
const whiteForegroundExample = React5.useMemo(
|
|
18340
|
+
() => selectedBackground && supportsWhiteForegroundPreview(selectedBackground) ? getWhiteForegroundPair(selectedBackground) : null,
|
|
18341
|
+
[selectedBackground]
|
|
18342
|
+
);
|
|
18343
|
+
const previewPair = selectedPair ?? whiteForegroundExample ?? null;
|
|
18344
|
+
const detailForeground = selectedPair?.foreground ?? whiteForegroundExample?.foreground ?? null;
|
|
18345
|
+
const familySummary = React5.useMemo(
|
|
18346
|
+
() => [context.primary.label, context.accent.label, context.grey.label].join(" + "),
|
|
18347
|
+
[context.accent.label, context.grey.label, context.primary.label]
|
|
18348
|
+
);
|
|
18349
|
+
const recommendationItems = React5.useMemo(() => {
|
|
18350
|
+
return selectedBackgroundPairs.map((pair) => {
|
|
18351
|
+
const category = getRecommendationCategory(pair, bestRecommendedPair, context);
|
|
18352
|
+
return {
|
|
18353
|
+
category,
|
|
18354
|
+
categoryLabel: getRecommendationCategoryLabel(category),
|
|
18355
|
+
pair
|
|
18356
|
+
};
|
|
18357
|
+
}).sort(
|
|
18358
|
+
(left, right) => getRecommendationSortRank(left.category) - getRecommendationSortRank(right.category)
|
|
18359
|
+
);
|
|
18360
|
+
}, [bestRecommendedPair, context, selectedBackgroundPairs]);
|
|
18361
|
+
const liveAnnouncement = React5.useMemo(
|
|
18362
|
+
() => getLiveAnnouncement(previewPair, selectedBackground),
|
|
18363
|
+
[previewPair, selectedBackground]
|
|
18364
|
+
);
|
|
18365
|
+
const shareBackgroundToken = selectedBackground?.token ?? selectedBackgroundToken;
|
|
18366
|
+
const shareUrl = React5.useMemo(() => {
|
|
18367
|
+
const params = new URLSearchParams();
|
|
18368
|
+
params.set("palette", themeCategory);
|
|
18369
|
+
params.set("primary", context.primary.key);
|
|
18370
|
+
params.set("accent", context.accent.key);
|
|
18371
|
+
if (shareBackgroundToken) {
|
|
18372
|
+
params.set("background", shareBackgroundToken);
|
|
18373
|
+
}
|
|
18374
|
+
if (selectedPairId) {
|
|
18375
|
+
params.set("pair", selectedPairId);
|
|
18376
|
+
}
|
|
18377
|
+
const query = params.toString();
|
|
18378
|
+
return `${COLOR_PAIRING_TOOL_V3_PATH}${query ? `?${query}` : ""}`;
|
|
18379
|
+
}, [context.accent.key, context.primary.key, shareBackgroundToken, selectedPairId, themeCategory]);
|
|
18380
|
+
const activeDrawerStep = COLOR_PAIRING_TOOL_DRAWER_STEPS[drawerStepIndex];
|
|
18381
|
+
const isFirstDrawerStep = drawerStepIndex === 0;
|
|
18382
|
+
const isLastDrawerStep = drawerStepIndex === COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1;
|
|
18383
|
+
const desktopSidebarStyle = React5.useMemo(
|
|
18384
|
+
() => ({
|
|
18385
|
+
"--tool-sidebar-max-height": `calc(100vh - ${stickyOffset}px)`,
|
|
18386
|
+
"--tool-sidebar-top": `${stickyOffset}px`
|
|
18387
|
+
}),
|
|
18388
|
+
[stickyOffset]
|
|
18389
|
+
);
|
|
18390
|
+
const goToDrawerStep = React5.useCallback((stepIndex) => {
|
|
18391
|
+
setDrawerStepIndex(Math.max(0, Math.min(stepIndex, COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1)));
|
|
18392
|
+
}, []);
|
|
18393
|
+
const goToNextDrawerStep = React5.useCallback(() => {
|
|
18394
|
+
setDrawerStepIndex(
|
|
18395
|
+
(currentStep) => Math.min(currentStep + 1, COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1)
|
|
18396
|
+
);
|
|
18397
|
+
}, []);
|
|
18398
|
+
const goToPreviousDrawerStep = React5.useCallback(() => {
|
|
18399
|
+
setDrawerStepIndex((currentStep) => Math.max(currentStep - 1, 0));
|
|
18400
|
+
}, []);
|
|
18401
|
+
const updateUrlParams = React5.useCallback((nextState) => {
|
|
18402
|
+
const params = new URLSearchParams(window.location.search);
|
|
18403
|
+
params.delete("family");
|
|
18404
|
+
params.set("palette", nextState.themeCategory);
|
|
18405
|
+
params.set("primary", nextState.primaryKey);
|
|
18406
|
+
params.set("accent", nextState.accentKey);
|
|
18407
|
+
params.set("background", nextState.selectedBackgroundToken);
|
|
18408
|
+
if (nextState.selectedPairId) {
|
|
18409
|
+
params.set("pair", nextState.selectedPairId);
|
|
18410
|
+
} else {
|
|
18411
|
+
params.delete("pair");
|
|
18412
|
+
}
|
|
18413
|
+
window.history.replaceState(
|
|
18414
|
+
null,
|
|
18415
|
+
"",
|
|
18416
|
+
`${window.location.pathname}?${params.toString()}${window.location.hash}`
|
|
18417
|
+
);
|
|
18418
|
+
}, []);
|
|
18419
|
+
const applyResolvedSelection = React5.useCallback(
|
|
18420
|
+
(nextState) => {
|
|
18421
|
+
setThemeCategory(nextState.themeCategory);
|
|
18422
|
+
setPrimaryFamilyKey(nextState.primaryKey);
|
|
18423
|
+
setAccentFamilyKey(nextState.accentKey);
|
|
18424
|
+
setSelectedBackgroundToken(nextState.selectedBackgroundToken);
|
|
18425
|
+
setSelectedPairId(nextState.selectedPairId);
|
|
18426
|
+
updateUrlParams(nextState);
|
|
18427
|
+
},
|
|
18428
|
+
[updateUrlParams]
|
|
18429
|
+
);
|
|
18430
|
+
const buildAnalyticsContext = React5.useCallback(
|
|
18431
|
+
(overrides) => ({
|
|
18432
|
+
accentKey: context.accent.key,
|
|
18433
|
+
backgroundToken: selectedBackground?.token,
|
|
18434
|
+
foregroundToken: selectedPair?.foreground.token,
|
|
18435
|
+
pairId: selectedPair?.id,
|
|
18436
|
+
palette: themeCategory,
|
|
18437
|
+
primaryKey: context.primary.key,
|
|
18438
|
+
...overrides
|
|
18439
|
+
}),
|
|
18440
|
+
[context.accent.key, context.primary.key, selectedBackground, selectedPair, themeCategory]
|
|
18441
|
+
);
|
|
18442
|
+
const copyValue = React5.useCallback(
|
|
18443
|
+
(copyKey, value, toastLabel, analyticsEvent) => {
|
|
18444
|
+
copyToClipboardRaw(value);
|
|
18445
|
+
setCopiedKey(copyKey);
|
|
18446
|
+
sonner.toast(toastLabel, { duration: 2e3 });
|
|
18447
|
+
if (analyticsEvent) {
|
|
18448
|
+
emitAnalyticsEvent(analyticsEvent);
|
|
18449
|
+
}
|
|
18450
|
+
if (copiedKeyTimeoutRef.current) {
|
|
18451
|
+
clearTimeout(copiedKeyTimeoutRef.current);
|
|
18452
|
+
}
|
|
18453
|
+
copiedKeyTimeoutRef.current = setTimeout(() => {
|
|
18454
|
+
setCopiedKey(null);
|
|
18455
|
+
copiedKeyTimeoutRef.current = null;
|
|
18456
|
+
}, 2e3);
|
|
18457
|
+
},
|
|
18458
|
+
[copyToClipboardRaw, emitAnalyticsEvent]
|
|
18459
|
+
);
|
|
18460
|
+
const handleThemeCategoryChange = (nextThemeCategory) => {
|
|
18461
|
+
const nextState = resolveSelectionState(
|
|
18462
|
+
nextThemeCategory,
|
|
18463
|
+
primaryFamilyKey,
|
|
18464
|
+
accentFamilyKey,
|
|
18465
|
+
selectedBackgroundToken,
|
|
18466
|
+
selectedPairId
|
|
18467
|
+
);
|
|
18468
|
+
applyResolvedSelection(nextState);
|
|
18469
|
+
emitAnalyticsEvent({
|
|
18470
|
+
name: "palette_change",
|
|
18471
|
+
accentKey: nextState.accentKey,
|
|
18472
|
+
backgroundToken: nextState.selectedBackgroundToken,
|
|
18473
|
+
pairId: nextState.selectedPairId,
|
|
18474
|
+
palette: nextState.themeCategory,
|
|
18475
|
+
primaryKey: nextState.primaryKey
|
|
18476
|
+
});
|
|
18477
|
+
};
|
|
18478
|
+
const handlePrimaryColorChange = (nextPrimaryKey) => {
|
|
18479
|
+
const nextAccentKey = nextPrimaryKey === accentFamilyKey ? getDefaultAccentFamilyKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
|
|
18480
|
+
const nextState = resolveSelectionState(
|
|
18481
|
+
themeCategory,
|
|
18482
|
+
nextPrimaryKey,
|
|
18483
|
+
nextAccentKey,
|
|
18484
|
+
selectedBackgroundToken,
|
|
18485
|
+
selectedPairId
|
|
18486
|
+
);
|
|
18487
|
+
applyResolvedSelection(nextState);
|
|
18488
|
+
emitAnalyticsEvent({
|
|
18489
|
+
name: "primary_change",
|
|
18490
|
+
accentKey: nextState.accentKey,
|
|
18491
|
+
backgroundToken: nextState.selectedBackgroundToken,
|
|
18492
|
+
pairId: nextState.selectedPairId,
|
|
18493
|
+
palette: nextState.themeCategory,
|
|
18494
|
+
primaryKey: nextState.primaryKey
|
|
18495
|
+
});
|
|
18496
|
+
};
|
|
18497
|
+
const handleAccentColorChange = (nextAccentKey) => {
|
|
18498
|
+
if (nextAccentKey === primaryFamilyKey) return;
|
|
18499
|
+
const nextState = resolveSelectionState(
|
|
18500
|
+
themeCategory,
|
|
18501
|
+
primaryFamilyKey,
|
|
18502
|
+
nextAccentKey,
|
|
18503
|
+
selectedBackgroundToken,
|
|
18504
|
+
selectedPairId
|
|
18505
|
+
);
|
|
18506
|
+
applyResolvedSelection(nextState);
|
|
18507
|
+
emitAnalyticsEvent({
|
|
18508
|
+
name: "accent_change",
|
|
18509
|
+
accentKey: nextState.accentKey,
|
|
18510
|
+
backgroundToken: nextState.selectedBackgroundToken,
|
|
18511
|
+
pairId: nextState.selectedPairId,
|
|
18512
|
+
palette: nextState.themeCategory,
|
|
18513
|
+
primaryKey: nextState.primaryKey
|
|
18514
|
+
});
|
|
18515
|
+
};
|
|
18516
|
+
const handleBackgroundChange = (nextSelectedBackgroundToken) => {
|
|
18517
|
+
const nextSelectedPairId = getPreferredPairForBackground3(
|
|
18518
|
+
context.pairsByBackground[nextSelectedBackgroundToken] ?? [],
|
|
18519
|
+
selectedPairId
|
|
18520
|
+
)?.id ?? "";
|
|
18521
|
+
const nextState = {
|
|
18522
|
+
accentKey: context.accent.key,
|
|
18523
|
+
context,
|
|
18524
|
+
primaryKey: context.primary.key,
|
|
18525
|
+
selectedBackgroundToken: nextSelectedBackgroundToken,
|
|
18526
|
+
selectedPairId: nextSelectedPairId,
|
|
18527
|
+
themeCategory
|
|
18528
|
+
};
|
|
18529
|
+
applyResolvedSelection(nextState);
|
|
18530
|
+
emitAnalyticsEvent({
|
|
18531
|
+
name: "background_selection",
|
|
18532
|
+
...buildAnalyticsContext({
|
|
18533
|
+
backgroundToken: nextSelectedBackgroundToken,
|
|
18534
|
+
foregroundToken: context.pairsByBackground[nextSelectedBackgroundToken]?.find(
|
|
18535
|
+
(pair) => pair.id === nextSelectedPairId
|
|
18536
|
+
)?.foreground.token,
|
|
18537
|
+
pairId: nextSelectedPairId
|
|
18538
|
+
})
|
|
18539
|
+
});
|
|
18540
|
+
if (typeof window !== "undefined" && window.matchMedia(MOBILE_RESULT_SCROLL_QUERY).matches) {
|
|
18541
|
+
requestAnimationFrame(() => {
|
|
18542
|
+
resultSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
18543
|
+
});
|
|
18544
|
+
}
|
|
18545
|
+
};
|
|
18546
|
+
const handlePairChange = (nextSelectedPairId, source) => {
|
|
18547
|
+
if (!selectedBackground) return;
|
|
18548
|
+
const nextPair = selectedBackgroundPairs.find((pair) => pair.id === nextSelectedPairId) ?? null;
|
|
18549
|
+
setSelectedPairId(nextSelectedPairId);
|
|
18550
|
+
updateUrlParams({
|
|
18551
|
+
accentKey: context.accent.key,
|
|
18552
|
+
context,
|
|
18553
|
+
primaryKey: context.primary.key,
|
|
18554
|
+
selectedBackgroundToken: selectedBackground.token,
|
|
18555
|
+
selectedPairId: nextSelectedPairId,
|
|
18556
|
+
themeCategory
|
|
18557
|
+
});
|
|
18558
|
+
emitAnalyticsEvent({
|
|
18559
|
+
name: "foreground_selection",
|
|
18560
|
+
...buildAnalyticsContext({
|
|
18561
|
+
foregroundToken: nextPair?.foreground.token,
|
|
18562
|
+
pairId: nextSelectedPairId,
|
|
18563
|
+
source
|
|
18564
|
+
})
|
|
18565
|
+
});
|
|
18566
|
+
if (bestRecommendedPair && nextSelectedPairId !== bestRecommendedPair.id) {
|
|
18567
|
+
emitAnalyticsEvent({
|
|
18568
|
+
name: "alternative_combination_selected",
|
|
18569
|
+
...buildAnalyticsContext({
|
|
18570
|
+
foregroundToken: nextPair?.foreground.token,
|
|
18571
|
+
pairId: nextSelectedPairId,
|
|
18572
|
+
source
|
|
18573
|
+
})
|
|
18574
|
+
});
|
|
18575
|
+
}
|
|
18576
|
+
};
|
|
18577
|
+
React5.useEffect(() => {
|
|
18578
|
+
if (!selectedBackground || selectedBackgroundPairs.length > 0) {
|
|
18579
|
+
return;
|
|
18580
|
+
}
|
|
18581
|
+
const key = `${themeCategory}:${context.primary.key}:${context.accent.key}:${selectedBackground.token}`;
|
|
18582
|
+
if (noValidStateRef.current.has(key)) {
|
|
18583
|
+
return;
|
|
18584
|
+
}
|
|
18585
|
+
noValidStateRef.current.add(key);
|
|
18586
|
+
emitAnalyticsEvent({
|
|
18587
|
+
name: "no_valid_combination_state",
|
|
18588
|
+
...buildAnalyticsContext({
|
|
18589
|
+
backgroundToken: selectedBackground.token
|
|
18590
|
+
})
|
|
18591
|
+
});
|
|
18592
|
+
}, [
|
|
18593
|
+
buildAnalyticsContext,
|
|
18594
|
+
context.accent.key,
|
|
18595
|
+
context.primary.key,
|
|
18596
|
+
emitAnalyticsEvent,
|
|
18597
|
+
selectedBackground,
|
|
18598
|
+
selectedBackgroundPairs.length,
|
|
18599
|
+
themeCategory
|
|
18600
|
+
]);
|
|
18601
|
+
React5.useEffect(() => {
|
|
18602
|
+
if (technicalDetailsOpenedRef.current) {
|
|
18603
|
+
return;
|
|
18604
|
+
}
|
|
18605
|
+
technicalDetailsOpenedRef.current = true;
|
|
18606
|
+
emitAnalyticsEvent({
|
|
18607
|
+
name: "technical_details_opened",
|
|
18608
|
+
...buildAnalyticsContext({
|
|
18609
|
+
source: "details"
|
|
18610
|
+
})
|
|
18611
|
+
});
|
|
18612
|
+
}, [buildAnalyticsContext, emitAnalyticsEvent]);
|
|
18613
|
+
if (!selectedBackground) {
|
|
18614
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "px-6 py-6", children: [
|
|
18615
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "No approved background tones available" }),
|
|
18616
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, className: "mt-3", children: "No approved tones are available for the current palette and colour selection." })
|
|
18617
|
+
] });
|
|
18618
|
+
}
|
|
18619
|
+
const compactControlsSummary = `${themeCategory === "brand" ? "Brand" : "Aboriginal"} palette, ${context.primary.label} primary, ${context.accent.label} accent, ${getPairingColorDisplayName3(
|
|
18620
|
+
selectedBackground
|
|
18621
|
+
)} background.`;
|
|
18622
|
+
const renderControlsPanel = (isOverlay = false) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18623
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-grey-200 px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
18624
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Configuration" }),
|
|
18625
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
18626
|
+
!isFirstDrawerStep ? /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", color: "grey", size: "sm", onClick: goToPreviousDrawerStep, children: [
|
|
18627
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.west, { "data-slot": "icon", className: "size-5" }),
|
|
18628
|
+
"Back"
|
|
18629
|
+
] }) : null,
|
|
18630
|
+
isOverlay ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
18631
|
+
Button2,
|
|
18632
|
+
{
|
|
18633
|
+
variant: "ghost",
|
|
18634
|
+
color: "grey",
|
|
18635
|
+
size: "icon",
|
|
18636
|
+
onClick: () => setIsCompactControlsOpen(false),
|
|
18637
|
+
"aria-label": "Close configuration",
|
|
18638
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.close, { "data-slot": "icon", className: "size-5" })
|
|
18639
|
+
}
|
|
18640
|
+
) : null
|
|
18641
|
+
] })
|
|
18642
|
+
] }) }),
|
|
18643
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-grey-200 px-5 py-4", children: [
|
|
18644
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
18645
|
+
COLOR_PAIRING_TOOL_DRAWER_STEPS.map((step, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
18646
|
+
"button",
|
|
18647
|
+
{
|
|
18648
|
+
type: "button",
|
|
18649
|
+
"aria-current": index === drawerStepIndex ? "step" : void 0,
|
|
18650
|
+
"aria-label": `${step.eyebrow}: ${step.title}`,
|
|
18651
|
+
onClick: () => goToDrawerStep(index),
|
|
18652
|
+
className: "flex-1 rounded-sm focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
|
|
18653
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18654
|
+
"span",
|
|
18655
|
+
{
|
|
18656
|
+
className: cn(
|
|
18657
|
+
"block h-1.5 rounded-full transition-colors",
|
|
18658
|
+
index <= drawerStepIndex ? "bg-primary-800" : "bg-grey-200"
|
|
18659
|
+
)
|
|
18660
|
+
}
|
|
18661
|
+
)
|
|
18662
|
+
},
|
|
18663
|
+
step.id
|
|
18664
|
+
)),
|
|
18665
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-2 basis-full text-[0.68rem] font-semibold tracking-[0.12em] text-primary-800 uppercase sm:mt-0 sm:ml-2 sm:basis-auto sm:text-[0.72rem]", children: activeDrawerStep.eyebrow })
|
|
18666
|
+
] }),
|
|
18667
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 space-y-2", children: [
|
|
18668
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: activeDrawerStep.title }),
|
|
18669
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, children: activeDrawerStep.description })
|
|
18670
|
+
] })
|
|
18671
|
+
] }),
|
|
18672
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18673
|
+
"div",
|
|
18674
|
+
{
|
|
18675
|
+
className: "flex h-full transition-transform duration-300 ease-out",
|
|
18676
|
+
style: { transform: `translateX(-${drawerStepIndex * 100}%)` },
|
|
18677
|
+
children: [
|
|
18678
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 pr-1", children: [
|
|
18679
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
|
|
18680
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Palette" }),
|
|
18681
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: ["brand", "aboriginal"].map((palette) => {
|
|
18682
|
+
const isSelected = themeCategory === palette;
|
|
18683
|
+
const label = palette === "brand" ? "Brand palette" : "Aboriginal palette";
|
|
18684
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18685
|
+
SelectorButton,
|
|
18686
|
+
{
|
|
18687
|
+
label,
|
|
18688
|
+
isSelected,
|
|
18689
|
+
onClick: () => handleThemeCategoryChange(palette)
|
|
18690
|
+
},
|
|
18691
|
+
palette
|
|
18692
|
+
);
|
|
18693
|
+
}) })
|
|
18694
|
+
] }),
|
|
18695
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
|
|
18696
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Primary colour family" }),
|
|
18697
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: selectableFamilies.map((family) => {
|
|
18698
|
+
const label = getFamilySelectorLabel3(family, themeCategory, "primary colour");
|
|
18699
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18700
|
+
SelectorButton,
|
|
18701
|
+
{
|
|
18702
|
+
label,
|
|
18703
|
+
isSelected: family.key === context.primary.key,
|
|
18704
|
+
onClick: () => handlePrimaryColorChange(family.key),
|
|
18705
|
+
swatch: getFamilySwatchColor3(family, 800)
|
|
18706
|
+
},
|
|
18707
|
+
family.key
|
|
18708
|
+
);
|
|
18709
|
+
}) })
|
|
18710
|
+
] }),
|
|
18711
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
|
|
18712
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Accent colour family" }),
|
|
18713
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: selectableAccentFamilies.map((family) => {
|
|
18714
|
+
const label = getFamilySelectorLabel3(family, themeCategory, "accent colour");
|
|
18715
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18716
|
+
SelectorButton,
|
|
18717
|
+
{
|
|
18718
|
+
label,
|
|
18719
|
+
isSelected: family.key === context.accent.key,
|
|
18720
|
+
onClick: () => handleAccentColorChange(family.key),
|
|
18721
|
+
swatch: getFamilySwatchColor3(family, 600)
|
|
18722
|
+
},
|
|
18723
|
+
family.key
|
|
18724
|
+
);
|
|
18725
|
+
}) })
|
|
18726
|
+
] }),
|
|
18727
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-grey-200 pt-4", children: [
|
|
18728
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-foreground", children: "Grey is always included" }),
|
|
18729
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Neutral grey options are automatically added so every selection includes a practical fallback family." })
|
|
18730
|
+
] })
|
|
18731
|
+
] }) }),
|
|
18732
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6 pr-1", children: context.backgroundGroups.map((group, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18733
|
+
"section",
|
|
18734
|
+
{
|
|
18735
|
+
className: cn("space-y-3", index > 0 && "border-t border-grey-200 pt-6"),
|
|
18736
|
+
children: [
|
|
18737
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
18738
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Heading, { level: 4, size: 6, className: "text-foreground", trim: "normal", children: [
|
|
18739
|
+
group.family.label,
|
|
18740
|
+
" backgrounds"
|
|
18741
|
+
] }),
|
|
18742
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: group.label })
|
|
18743
|
+
] }),
|
|
18744
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-3", children: group.backgrounds.map((background) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
18745
|
+
BackgroundSwatchButton,
|
|
18746
|
+
{
|
|
18747
|
+
background,
|
|
18748
|
+
hasPairs: (context.pairsByBackground[background.token]?.length ?? 0) > 0,
|
|
18749
|
+
isSelected: selectedBackground.token === background.token,
|
|
18750
|
+
onClick: () => handleBackgroundChange(background.token)
|
|
18751
|
+
},
|
|
18752
|
+
background.token
|
|
18753
|
+
)) })
|
|
18754
|
+
]
|
|
18755
|
+
},
|
|
18756
|
+
group.key
|
|
18757
|
+
)) }) }),
|
|
18758
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4 pr-1", children: recommendationItems.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: recommendationItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
18759
|
+
RecommendationCard,
|
|
18760
|
+
{
|
|
18761
|
+
copiedKey,
|
|
18762
|
+
item,
|
|
18763
|
+
isSelected: item.pair.id === selectedPair?.id,
|
|
18764
|
+
onCopyPairing: () => copyValue(
|
|
18765
|
+
`pair:${item.pair.id}`,
|
|
18766
|
+
getPairingCopyText(item.pair),
|
|
18767
|
+
"Pairing copied",
|
|
18768
|
+
item.pair.id === bestRecommendedPair?.id ? {
|
|
18769
|
+
name: "best_recommendation_copied",
|
|
18770
|
+
...buildAnalyticsContext({
|
|
18771
|
+
foregroundToken: item.pair.foreground.token,
|
|
18772
|
+
pairId: item.pair.id,
|
|
18773
|
+
source: "recommendations-list"
|
|
18774
|
+
})
|
|
18775
|
+
} : void 0
|
|
18776
|
+
),
|
|
18777
|
+
onSelect: () => handlePairChange(item.pair.id, "recommendations-list")
|
|
18778
|
+
},
|
|
18779
|
+
item.pair.id
|
|
18780
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-grey-200 bg-white px-5 py-5", children: [
|
|
18781
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 4, size: 6, className: "text-foreground", trim: "normal", children: "No valid combinations available" }),
|
|
18782
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, className: "mt-3", children: "No AAA-compliant foreground options are available for this background." })
|
|
18783
|
+
] }) }) })
|
|
18784
|
+
]
|
|
18785
|
+
}
|
|
18786
|
+
) }),
|
|
18787
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-grey-200 px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
18788
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-10 flex-1", children: isLastDrawerStep ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Select a combination to update the result immediately." }) : null }),
|
|
18789
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2 sm:w-auto sm:flex-none", children: [
|
|
18790
|
+
isOverlay && isLastDrawerStep ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
18791
|
+
Button2,
|
|
18792
|
+
{
|
|
18793
|
+
color: "primary",
|
|
18794
|
+
className: "w-full sm:w-auto sm:min-w-40",
|
|
18795
|
+
onClick: () => setIsCompactControlsOpen(false),
|
|
18796
|
+
children: "Review result"
|
|
18797
|
+
}
|
|
18798
|
+
) : null,
|
|
18799
|
+
!isLastDrawerStep ? /* @__PURE__ */ jsxRuntime.jsxs(Button2, { color: "primary", className: "w-full sm:w-auto", onClick: goToNextDrawerStep, children: [
|
|
18800
|
+
"Continue",
|
|
18801
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.east, { "data-slot": "icon", className: "size-5" })
|
|
18802
|
+
] }) : null
|
|
18803
|
+
] })
|
|
18804
|
+
] }) })
|
|
18805
|
+
] });
|
|
18806
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-8 xl:grid-cols-[minmax(18rem,24rem)_minmax(0,1fr)]", children: [
|
|
18807
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18808
|
+
"div",
|
|
18809
|
+
{
|
|
18810
|
+
"data-slot": "tool-sidebar",
|
|
18811
|
+
className: "hidden xl:sticky xl:top-[var(--tool-sidebar-top)] xl:block xl:self-start",
|
|
18812
|
+
style: desktopSidebarStyle,
|
|
18813
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "h-[40rem] max-h-[40rem] gap-0 overflow-hidden py-0 sm:h-[44rem] sm:max-h-[44rem] xl:h-[var(--tool-sidebar-max-height)] xl:max-h-[var(--tool-sidebar-max-height)]", children: renderControlsPanel() })
|
|
18814
|
+
}
|
|
18815
|
+
),
|
|
18816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "tool-results", className: "space-y-6", children: [
|
|
18817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4 xl:hidden", children: [
|
|
18818
|
+
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "gap-4 px-5 py-5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between", children: [
|
|
18819
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
18820
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Configuration" }),
|
|
18821
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, children: "Open the colour pairing drawer to change palette, background, and recommended combinations." }),
|
|
18822
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: compactControlsSummary })
|
|
18823
|
+
] }),
|
|
18824
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18825
|
+
Button2,
|
|
18826
|
+
{
|
|
18827
|
+
color: "primary",
|
|
18828
|
+
className: "w-full sm:w-auto",
|
|
18829
|
+
onClick: () => setIsCompactControlsOpen(true),
|
|
18830
|
+
children: [
|
|
18831
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.edit_square, { "data-slot": "icon", className: "size-5" }),
|
|
18832
|
+
"Open configuration"
|
|
18833
|
+
]
|
|
18834
|
+
}
|
|
18835
|
+
)
|
|
18836
|
+
] }) }),
|
|
18837
|
+
/* @__PURE__ */ jsxRuntime.jsx(Sheet, { open: isCompactControlsOpen, onOpenChange: setIsCompactControlsOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18838
|
+
SheetContent,
|
|
18839
|
+
{
|
|
18840
|
+
side: "left",
|
|
18841
|
+
showClose: false,
|
|
18842
|
+
className: "w-[30rem] max-w-[90vw] overflow-hidden p-0",
|
|
18843
|
+
children: [
|
|
18844
|
+
/* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { className: "sr-only", children: "Colour pairing configuration" }),
|
|
18845
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-col bg-background", children: renderControlsPanel(true) })
|
|
18846
|
+
]
|
|
18847
|
+
}
|
|
18848
|
+
) })
|
|
18849
|
+
] }),
|
|
18850
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { ref: resultSectionRef, className: "space-y-6", "aria-label": "Current result", children: [
|
|
18851
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sr-only", "aria-live": "polite", children: liveAnnouncement }),
|
|
18852
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18853
|
+
CurrentResultCard,
|
|
18854
|
+
{
|
|
18855
|
+
bestPair: bestRecommendedPair,
|
|
18856
|
+
familySummary,
|
|
18857
|
+
pair: previewPair,
|
|
18858
|
+
selectedBackground
|
|
18859
|
+
}
|
|
18860
|
+
)
|
|
18861
|
+
] }),
|
|
18862
|
+
bestRecommendedPair ? /* @__PURE__ */ jsxRuntime.jsx("section", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18863
|
+
BestRecommendationCard,
|
|
18864
|
+
{
|
|
18865
|
+
copiedKey,
|
|
18866
|
+
isCurrentSelection: selectedPair?.id === bestRecommendedPair.id,
|
|
18867
|
+
pair: bestRecommendedPair,
|
|
18868
|
+
reason: getBestRecommendationReason(bestRecommendedPair, context),
|
|
18869
|
+
onCopyPairing: () => copyValue(
|
|
18870
|
+
"best-pairing",
|
|
18871
|
+
getPairingCopyText(bestRecommendedPair),
|
|
18872
|
+
"Pairing copied",
|
|
18873
|
+
{
|
|
18874
|
+
name: "best_recommendation_copied",
|
|
18875
|
+
...buildAnalyticsContext({
|
|
18876
|
+
foregroundToken: bestRecommendedPair.foreground.token,
|
|
18877
|
+
pairId: bestRecommendedPair.id,
|
|
18878
|
+
source: "best-recommendation"
|
|
18879
|
+
})
|
|
18880
|
+
}
|
|
18881
|
+
),
|
|
18882
|
+
onUsePairing: () => handlePairChange(bestRecommendedPair.id, "best-recommendation")
|
|
18883
|
+
}
|
|
18884
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "px-6 py-6", children: [
|
|
18885
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Best recommended pairing" }),
|
|
18886
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, className: "mt-3", children: "No AAA-compliant foreground options available for this selection." })
|
|
18887
|
+
] }),
|
|
18888
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
|
|
18889
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
18890
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Technical colour values" }),
|
|
18891
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: 2, children: "Token, tone, HEX, RGB, HSL, and OKLCH values for the current selection." })
|
|
18892
|
+
] }),
|
|
18893
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
|
|
18894
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18895
|
+
TechnicalDetailsPanel,
|
|
18896
|
+
{
|
|
18897
|
+
title: "Background values",
|
|
18898
|
+
color: selectedBackground,
|
|
18899
|
+
visibleFormats,
|
|
18900
|
+
copiedKey,
|
|
18901
|
+
onCopyValue: (copyKey, value, toastLabel) => copyValue(copyKey, value, toastLabel)
|
|
18902
|
+
}
|
|
18903
|
+
),
|
|
18904
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18905
|
+
TechnicalDetailsPanel,
|
|
18906
|
+
{
|
|
18907
|
+
title: "Foreground values",
|
|
18908
|
+
color: detailForeground,
|
|
18909
|
+
visibleFormats,
|
|
18910
|
+
copiedKey,
|
|
18911
|
+
onCopyValue: (copyKey, value, toastLabel) => copyValue(copyKey, value, toastLabel)
|
|
18912
|
+
}
|
|
18913
|
+
)
|
|
18914
|
+
] }),
|
|
18915
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
18916
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 3, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Share colour pairing" }),
|
|
18917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-grey-200 bg-white p-4", children: [
|
|
18918
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
18919
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Copy this URL to share your current colour pairing:" }),
|
|
18920
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18921
|
+
Button2,
|
|
18922
|
+
{
|
|
18923
|
+
variant: "ghost",
|
|
18924
|
+
color: "grey",
|
|
18925
|
+
size: "sm",
|
|
18926
|
+
className: "shrink-0",
|
|
18927
|
+
onClick: () => copyValue(
|
|
18928
|
+
"share-url",
|
|
18929
|
+
typeof window === "undefined" ? shareUrl : new URL(shareUrl, window.location.origin).toString(),
|
|
18930
|
+
"Colour pairing link copied"
|
|
18931
|
+
),
|
|
18932
|
+
"aria-label": copiedKey === "share-url" ? "Colour pairing URL copied to clipboard" : "Copy colour pairing URL to clipboard",
|
|
18933
|
+
title: copiedKey === "share-url" ? "Copied" : "Copy URL",
|
|
18934
|
+
children: copiedKey === "share-url" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18935
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-5" }),
|
|
18936
|
+
"Copied"
|
|
18937
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18938
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
|
|
18939
|
+
"Copy URL"
|
|
18940
|
+
] })
|
|
18941
|
+
}
|
|
18942
|
+
)
|
|
18943
|
+
] }),
|
|
18944
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "mt-3 block w-full rounded-sm border border-grey-200 bg-background px-3 py-2 font-mono text-[11px] break-all text-foreground sm:text-xs", children: shareUrl })
|
|
18945
|
+
] })
|
|
18946
|
+
] })
|
|
18947
|
+
] })
|
|
18948
|
+
] })
|
|
18949
|
+
] });
|
|
18950
|
+
}
|
|
18951
|
+
function ColorPairingToolV3({
|
|
18952
|
+
onAnalyticsEvent = () => {
|
|
18953
|
+
},
|
|
18954
|
+
visibleFormats = DEFAULT_VISIBLE_FORMATS3
|
|
18955
|
+
} = {}) {
|
|
18956
|
+
const normalizedVisibleFormats = [...new Set(visibleFormats)];
|
|
18957
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolV3Loading, {}), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18958
|
+
ColorPairingToolV3Content,
|
|
18959
|
+
{
|
|
18960
|
+
onAnalyticsEvent,
|
|
18961
|
+
visibleFormats: normalizedVisibleFormats
|
|
18962
|
+
}
|
|
18963
|
+
) });
|
|
18964
|
+
}
|
|
17231
18965
|
function ColorSwatches({ theme: theme2, format, viewMode }) {
|
|
17232
18966
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17233
18967
|
"div",
|
|
@@ -18141,23 +19875,23 @@ var ComboChart = React5__namespace.default.forwardRef((props, forwardedRef) => {
|
|
|
18141
19875
|
});
|
|
18142
19876
|
ComboChart.displayName = "ComboChart";
|
|
18143
19877
|
function Dialog({ ...props }) {
|
|
18144
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19878
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
|
|
18145
19879
|
}
|
|
18146
19880
|
function DialogTrigger({ ...props }) {
|
|
18147
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19881
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
18148
19882
|
}
|
|
18149
19883
|
function DialogPortal({ ...props }) {
|
|
18150
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19884
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
|
|
18151
19885
|
}
|
|
18152
19886
|
function DialogClose({ ...props }) {
|
|
18153
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19887
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Close, { "data-slot": "dialog-close", ...props });
|
|
18154
19888
|
}
|
|
18155
19889
|
function DialogOverlay({
|
|
18156
19890
|
className,
|
|
18157
19891
|
...props
|
|
18158
19892
|
}) {
|
|
18159
19893
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18160
|
-
|
|
19894
|
+
SheetPrimitive__namespace.Overlay,
|
|
18161
19895
|
{
|
|
18162
19896
|
"data-slot": "dialog-overlay",
|
|
18163
19897
|
className: cn(
|
|
@@ -18177,7 +19911,7 @@ function DialogContent({
|
|
|
18177
19911
|
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
18178
19912
|
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
18179
19913
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18180
|
-
|
|
19914
|
+
SheetPrimitive__namespace.Content,
|
|
18181
19915
|
{
|
|
18182
19916
|
"data-slot": "dialog-content",
|
|
18183
19917
|
className: cn(
|
|
@@ -18187,7 +19921,7 @@ function DialogContent({
|
|
|
18187
19921
|
...props,
|
|
18188
19922
|
children: [
|
|
18189
19923
|
children,
|
|
18190
|
-
showClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19924
|
+
showClose && /* @__PURE__ */ jsxRuntime.jsx(SheetPrimitive__namespace.Close, { className: "absolute top-1 right-1", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon", children: [
|
|
18191
19925
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
|
|
18192
19926
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
18193
19927
|
] }) })
|
|
@@ -18218,7 +19952,7 @@ function DialogFooter({ className, ...props }) {
|
|
|
18218
19952
|
}
|
|
18219
19953
|
function DialogTitle({ className, ...props }) {
|
|
18220
19954
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18221
|
-
|
|
19955
|
+
SheetPrimitive__namespace.Title,
|
|
18222
19956
|
{
|
|
18223
19957
|
"data-slot": "dialog-title",
|
|
18224
19958
|
className: cn("text-lg leading-none font-semibold", className),
|
|
@@ -18231,7 +19965,7 @@ function DialogDescription({
|
|
|
18231
19965
|
...props
|
|
18232
19966
|
}) {
|
|
18233
19967
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18234
|
-
|
|
19968
|
+
SheetPrimitive__namespace.Description,
|
|
18235
19969
|
{
|
|
18236
19970
|
"data-slot": "dialog-description",
|
|
18237
19971
|
className: cn("text-sm text-muted-foreground", className),
|
|
@@ -19500,7 +21234,7 @@ function FieldLabel({
|
|
|
19500
21234
|
}
|
|
19501
21235
|
);
|
|
19502
21236
|
}
|
|
19503
|
-
function
|
|
21237
|
+
function Description5({
|
|
19504
21238
|
className,
|
|
19505
21239
|
...props
|
|
19506
21240
|
}) {
|
|
@@ -19852,7 +21586,7 @@ function FormatToggle({ format, setFormat }) {
|
|
|
19852
21586
|
|
|
19853
21587
|
// package.json
|
|
19854
21588
|
var package_default = {
|
|
19855
|
-
version: "1.
|
|
21589
|
+
version: "1.103.0"};
|
|
19856
21590
|
function Logo(props) {
|
|
19857
21591
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
19858
21592
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "NSW Government" }),
|
|
@@ -21124,28 +22858,6 @@ function Loading() {
|
|
|
21124
22858
|
/* @__PURE__ */ jsxRuntime.jsx(Text, { children: "Loading..." })
|
|
21125
22859
|
] });
|
|
21126
22860
|
}
|
|
21127
|
-
function useSelectorHeight(selector = "header") {
|
|
21128
|
-
const [height, setHeight] = React5.useState(0);
|
|
21129
|
-
const elementRef = React5.useRef(null);
|
|
21130
|
-
const resizeObserverRef = React5.useRef(null);
|
|
21131
|
-
React5.useEffect(() => {
|
|
21132
|
-
const element = document.querySelector(selector);
|
|
21133
|
-
if (!element) return;
|
|
21134
|
-
elementRef.current = element;
|
|
21135
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
21136
|
-
const entry = entries[0];
|
|
21137
|
-
const target = entry?.target ?? elementRef.current;
|
|
21138
|
-
if (!target) return;
|
|
21139
|
-
setHeight(target.offsetHeight);
|
|
21140
|
-
});
|
|
21141
|
-
resizeObserverRef.current = resizeObserver;
|
|
21142
|
-
resizeObserver.observe(element);
|
|
21143
|
-
return () => {
|
|
21144
|
-
resizeObserverRef.current?.disconnect();
|
|
21145
|
-
};
|
|
21146
|
-
}, [selector]);
|
|
21147
|
-
return height;
|
|
21148
|
-
}
|
|
21149
22861
|
function MainNavigation({ navigation }) {
|
|
21150
22862
|
const headerHeight = useSelectorHeight();
|
|
21151
22863
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -30910,110 +32622,6 @@ function ResizableHandle({
|
|
|
30910
32622
|
}
|
|
30911
32623
|
);
|
|
30912
32624
|
}
|
|
30913
|
-
function Sheet({ ...props }) {
|
|
30914
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "sheet", ...props });
|
|
30915
|
-
}
|
|
30916
|
-
function SheetTrigger({ ...props }) {
|
|
30917
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "sheet-trigger", ...props });
|
|
30918
|
-
}
|
|
30919
|
-
function SheetClose({ ...props }) {
|
|
30920
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "sheet-close", ...props });
|
|
30921
|
-
}
|
|
30922
|
-
function SheetPortal({ ...props }) {
|
|
30923
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "sheet-portal", ...props });
|
|
30924
|
-
}
|
|
30925
|
-
function SheetOverlay({
|
|
30926
|
-
className,
|
|
30927
|
-
...props
|
|
30928
|
-
}) {
|
|
30929
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30930
|
-
DialogPrimitive__namespace.Overlay,
|
|
30931
|
-
{
|
|
30932
|
-
"data-slot": "sheet-overlay",
|
|
30933
|
-
className: cn(
|
|
30934
|
-
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
30935
|
-
className
|
|
30936
|
-
),
|
|
30937
|
-
...props
|
|
30938
|
-
}
|
|
30939
|
-
);
|
|
30940
|
-
}
|
|
30941
|
-
function SheetContent({
|
|
30942
|
-
className,
|
|
30943
|
-
children,
|
|
30944
|
-
side = "right",
|
|
30945
|
-
showClose = true,
|
|
30946
|
-
...props
|
|
30947
|
-
}) {
|
|
30948
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(SheetPortal, { children: [
|
|
30949
|
-
/* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, {}),
|
|
30950
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30951
|
-
DialogPrimitive__namespace.Content,
|
|
30952
|
-
{
|
|
30953
|
-
"data-slot": "sheet-content",
|
|
30954
|
-
className: cn(
|
|
30955
|
-
"fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=closed]:animate-out data-[state=open]:duration-500 data-[state=open]:animate-in",
|
|
30956
|
-
side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
|
30957
|
-
side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
|
30958
|
-
side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
|
30959
|
-
side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
|
30960
|
-
className
|
|
30961
|
-
),
|
|
30962
|
-
...props,
|
|
30963
|
-
children: [
|
|
30964
|
-
children,
|
|
30965
|
-
showClose && /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "sheet-close", className: "absolute top-4 right-4", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon", children: [
|
|
30966
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
|
|
30967
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
30968
|
-
] }) })
|
|
30969
|
-
]
|
|
30970
|
-
}
|
|
30971
|
-
)
|
|
30972
|
-
] });
|
|
30973
|
-
}
|
|
30974
|
-
function SheetHeader({ className, ...props }) {
|
|
30975
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30976
|
-
"div",
|
|
30977
|
-
{
|
|
30978
|
-
"data-slot": "sheet-header",
|
|
30979
|
-
className: cn("flex flex-col gap-1.5 p-4", className),
|
|
30980
|
-
...props
|
|
30981
|
-
}
|
|
30982
|
-
);
|
|
30983
|
-
}
|
|
30984
|
-
function SheetFooter({ className, ...props }) {
|
|
30985
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30986
|
-
"div",
|
|
30987
|
-
{
|
|
30988
|
-
"data-slot": "sheet-footer",
|
|
30989
|
-
className: cn("mt-auto flex flex-col gap-2 p-4", className),
|
|
30990
|
-
...props
|
|
30991
|
-
}
|
|
30992
|
-
);
|
|
30993
|
-
}
|
|
30994
|
-
function SheetTitle({ className, ...props }) {
|
|
30995
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30996
|
-
DialogPrimitive__namespace.Title,
|
|
30997
|
-
{
|
|
30998
|
-
"data-slot": "sheet-title",
|
|
30999
|
-
className: cn("font-semibold text-foreground", className),
|
|
31000
|
-
...props
|
|
31001
|
-
}
|
|
31002
|
-
);
|
|
31003
|
-
}
|
|
31004
|
-
function SheetDescription({
|
|
31005
|
-
className,
|
|
31006
|
-
...props
|
|
31007
|
-
}) {
|
|
31008
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
31009
|
-
DialogPrimitive__namespace.Description,
|
|
31010
|
-
{
|
|
31011
|
-
"data-slot": "sheet-description",
|
|
31012
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
31013
|
-
...props
|
|
31014
|
-
}
|
|
31015
|
-
);
|
|
31016
|
-
}
|
|
31017
32625
|
function Skeleton({ className, ...props }) {
|
|
31018
32626
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
31019
32627
|
"div",
|
|
@@ -35741,13 +37349,24 @@ function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
|
|
|
35741
37349
|
});
|
|
35742
37350
|
return result;
|
|
35743
37351
|
}
|
|
35744
|
-
function
|
|
37352
|
+
function areHeadingTreesEqual(left, right) {
|
|
37353
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
37354
|
+
}
|
|
37355
|
+
function usePageHeadings(enabled = true) {
|
|
35745
37356
|
const [headings, setHeadings] = React5.useState([]);
|
|
35746
37357
|
const pathname = navigation.usePathname();
|
|
35747
37358
|
const observerRef = React5.useRef(null);
|
|
35748
37359
|
const observedElRef = React5.useRef(null);
|
|
35749
37360
|
React5.useEffect(() => {
|
|
35750
|
-
|
|
37361
|
+
if (!enabled) {
|
|
37362
|
+
return;
|
|
37363
|
+
}
|
|
37364
|
+
const update = () => {
|
|
37365
|
+
const nextHeadings = getHeadings();
|
|
37366
|
+
setHeadings(
|
|
37367
|
+
(currentHeadings) => areHeadingTreesEqual(currentHeadings, nextHeadings) ? currentHeadings : nextHeadings
|
|
37368
|
+
);
|
|
37369
|
+
};
|
|
35751
37370
|
const attachToCurrentArticle = () => {
|
|
35752
37371
|
const article = document.querySelector("article");
|
|
35753
37372
|
if (!article || observedElRef.current === article) return;
|
|
@@ -35794,16 +37413,8 @@ function usePageHeadings() {
|
|
|
35794
37413
|
observerRef.current = null;
|
|
35795
37414
|
observedElRef.current = null;
|
|
35796
37415
|
};
|
|
35797
|
-
}, [pathname]);
|
|
35798
|
-
return headings;
|
|
35799
|
-
}
|
|
35800
|
-
function useStickyOffset(extraPadding = 0) {
|
|
35801
|
-
const headerHeight = useSelectorHeight("#nsw-header");
|
|
35802
|
-
const navigationHeight = useSelectorHeight("#nsw-main-navigation");
|
|
35803
|
-
return React5.useMemo(() => {
|
|
35804
|
-
const total = headerHeight + navigationHeight + extraPadding;
|
|
35805
|
-
return total > 0 ? total : 0;
|
|
35806
|
-
}, [extraPadding, headerHeight, navigationHeight]);
|
|
37416
|
+
}, [enabled, pathname]);
|
|
37417
|
+
return enabled ? headings : [];
|
|
35807
37418
|
}
|
|
35808
37419
|
function createFormStore(opts) {
|
|
35809
37420
|
const { storageKey, initialFormData, initialFormStatus } = opts;
|
|
@@ -35945,6 +37556,7 @@ exports.CollapsibleTrigger = CollapsibleTrigger2;
|
|
|
35945
37556
|
exports.ColorCard = ColorCard;
|
|
35946
37557
|
exports.ColorPairingTool = ColorPairingTool;
|
|
35947
37558
|
exports.ColorPairingToolV2 = ColorPairingToolV2;
|
|
37559
|
+
exports.ColorPairingToolV3 = ColorPairingToolV3;
|
|
35948
37560
|
exports.ColorSwatches = ColorSwatches;
|
|
35949
37561
|
exports.ColourScale = ColourScale;
|
|
35950
37562
|
exports.ComboChart = ComboChart;
|
|
@@ -35992,7 +37604,7 @@ exports.DataTableFacetedFilter = DataTableFacetedFilter;
|
|
|
35992
37604
|
exports.DataTablePagination = DataTablePagination;
|
|
35993
37605
|
exports.DataTableToolbar = DataTableToolbar;
|
|
35994
37606
|
exports.DataTableViewOptions = DataTableViewOptions;
|
|
35995
|
-
exports.Description =
|
|
37607
|
+
exports.Description = Description5;
|
|
35996
37608
|
exports.DescriptionDetails = DescriptionDetails;
|
|
35997
37609
|
exports.DescriptionList = DescriptionList;
|
|
35998
37610
|
exports.DescriptionTerm = DescriptionTerm;
|