@nswds/app 1.99.0 → 1.101.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 +171 -31
- package/dist/index.cjs +1151 -674
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1147 -670
- package/dist/index.js.map +1 -1
- package/dist/styles.css +181 -31
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,8 +40,6 @@ 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 ToggleGroupPrimitive = require('@radix-ui/react-toggle-group');
|
|
44
|
-
var TogglePrimitive = require('@radix-ui/react-toggle');
|
|
45
43
|
var cmdk = require('cmdk');
|
|
46
44
|
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
47
45
|
var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
|
|
@@ -49,6 +47,8 @@ var reactTable = require('@tanstack/react-table');
|
|
|
49
47
|
var SeparatorPrimitive = require('@radix-ui/react-separator');
|
|
50
48
|
var vaul = require('vaul');
|
|
51
49
|
var reactHookForm = require('react-hook-form');
|
|
50
|
+
var ToggleGroupPrimitive = require('@radix-ui/react-toggle-group');
|
|
51
|
+
var TogglePrimitive = require('@radix-ui/react-toggle');
|
|
52
52
|
var Image2 = require('next/image');
|
|
53
53
|
var HoverCardPrimitive = require('@radix-ui/react-hover-card');
|
|
54
54
|
var inputOtp = require('input-otp');
|
|
@@ -110,11 +110,11 @@ 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 ToggleGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToggleGroupPrimitive);
|
|
114
|
-
var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive);
|
|
115
113
|
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
116
114
|
var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
|
|
117
115
|
var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
|
|
116
|
+
var ToggleGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToggleGroupPrimitive);
|
|
117
|
+
var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive);
|
|
118
118
|
var Image2__default = /*#__PURE__*/_interopDefault(Image2);
|
|
119
119
|
var HoverCardPrimitive__namespace = /*#__PURE__*/_interopNamespace(HoverCardPrimitive);
|
|
120
120
|
var MenubarPrimitive__namespace = /*#__PURE__*/_interopNamespace(MenubarPrimitive);
|
|
@@ -7761,7 +7761,7 @@ function CardDescription({ className, ...props }) {
|
|
|
7761
7761
|
"div",
|
|
7762
7762
|
{
|
|
7763
7763
|
"data-slot": "card-description",
|
|
7764
|
-
className: cn("text-
|
|
7764
|
+
className: cn("text-base text-muted-foreground", className),
|
|
7765
7765
|
...props
|
|
7766
7766
|
}
|
|
7767
7767
|
);
|
|
@@ -14973,7 +14973,10 @@ function ColorCard({ name, token, hex: hex2, rgb: rgb2, hsl, oklch: oklch2, form
|
|
|
14973
14973
|
] }) });
|
|
14974
14974
|
}
|
|
14975
14975
|
var recommendedBackgroundTones = [50, 100, 200, 400, 600, 800];
|
|
14976
|
+
var recommendedForegroundTones = [50, 200, 400, 600, 800];
|
|
14976
14977
|
var AAA_NORMAL_TEXT_RATIO = 7;
|
|
14978
|
+
var DEFAULT_PRIMARY_FAMILY_KEY = "blue";
|
|
14979
|
+
var DEFAULT_ACCENT_FAMILY_KEY = "red";
|
|
14977
14980
|
var MIN_DARK_BACKGROUND_TONE_FOR_WHITE = 600;
|
|
14978
14981
|
var WHITE_FOREGROUND = {
|
|
14979
14982
|
token: "white",
|
|
@@ -14982,6 +14985,8 @@ var WHITE_FOREGROUND = {
|
|
|
14982
14985
|
rgb: "rgb(255, 255, 255)",
|
|
14983
14986
|
hsl: "hsl(0, 0%, 100%)",
|
|
14984
14987
|
oklch: "oklch(1 0 0)",
|
|
14988
|
+
familyKey: "white",
|
|
14989
|
+
familyLabel: "White",
|
|
14985
14990
|
tone: 0
|
|
14986
14991
|
};
|
|
14987
14992
|
function extractTone(token) {
|
|
@@ -14992,23 +14997,47 @@ function formatFamilyLabel(name, key) {
|
|
|
14992
14997
|
if (key === "grey") return "Grey";
|
|
14993
14998
|
return name.replace(/^NSW Aboriginal\s+/i, "").replace(/^NSW\s+/i, "").trim();
|
|
14994
14999
|
}
|
|
14995
|
-
function toPairingColor(color2) {
|
|
15000
|
+
function toPairingColor(color2, familyKey, familyLabel) {
|
|
14996
15001
|
return {
|
|
14997
15002
|
...color2,
|
|
15003
|
+
familyKey,
|
|
15004
|
+
familyLabel,
|
|
14998
15005
|
tone: extractTone(color2.token)
|
|
14999
15006
|
};
|
|
15000
15007
|
}
|
|
15001
|
-
function
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15008
|
+
function buildPairingCollections() {
|
|
15009
|
+
return {
|
|
15010
|
+
brand: Object.entries(colors.brand).map(([key, palette]) => {
|
|
15011
|
+
const familyLabel = formatFamilyLabel(palette.name, key);
|
|
15012
|
+
return {
|
|
15013
|
+
key,
|
|
15014
|
+
label: familyLabel,
|
|
15015
|
+
paletteName: palette.name,
|
|
15016
|
+
colors: palette.colors.map((color2) => toPairingColor(color2, key, familyLabel))
|
|
15017
|
+
};
|
|
15018
|
+
}),
|
|
15019
|
+
aboriginal: Object.entries(colors.aboriginal).map(([key, palette]) => {
|
|
15020
|
+
const familyLabel = formatFamilyLabel(palette.name, key);
|
|
15021
|
+
return {
|
|
15022
|
+
key,
|
|
15023
|
+
label: familyLabel,
|
|
15024
|
+
paletteName: palette.name,
|
|
15025
|
+
colors: palette.colors.map((color2) => toPairingColor(color2, key, familyLabel))
|
|
15026
|
+
};
|
|
15027
|
+
})
|
|
15028
|
+
};
|
|
15006
15029
|
}
|
|
15030
|
+
var pairingFamilyCollections = buildPairingCollections();
|
|
15007
15031
|
function getPairRating(contrastRatio) {
|
|
15008
15032
|
if (contrastRatio >= 7) return "AAA";
|
|
15009
15033
|
if (contrastRatio >= 4.5) return "AA";
|
|
15010
15034
|
return "AA Large";
|
|
15011
15035
|
}
|
|
15036
|
+
function getPreferredForegroundTone(backgroundTone) {
|
|
15037
|
+
if (backgroundTone <= 200) return 800;
|
|
15038
|
+
if (backgroundTone <= 500) return 600;
|
|
15039
|
+
return 200;
|
|
15040
|
+
}
|
|
15012
15041
|
function isPreferredDirection(backgroundTone, foregroundTone, preferredForegroundTone) {
|
|
15013
15042
|
if (preferredForegroundTone < backgroundTone) {
|
|
15014
15043
|
return foregroundTone < backgroundTone;
|
|
@@ -15031,15 +15060,27 @@ function buildPair(background, foreground) {
|
|
|
15031
15060
|
rating: getPairRating(contrastRatio)
|
|
15032
15061
|
};
|
|
15033
15062
|
}
|
|
15034
|
-
function
|
|
15063
|
+
function sortRecommendedPairs(background, pairs) {
|
|
15035
15064
|
const preferredForegroundTone = getPreferredForegroundTone(background.tone);
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15065
|
+
return [...pairs].sort((left, right) => {
|
|
15066
|
+
const leftPreferred = isPreferredDirection(
|
|
15067
|
+
background.tone,
|
|
15068
|
+
left.foreground.tone,
|
|
15069
|
+
preferredForegroundTone
|
|
15070
|
+
) ? 0 : 1;
|
|
15071
|
+
const rightPreferred = isPreferredDirection(
|
|
15072
|
+
background.tone,
|
|
15073
|
+
right.foreground.tone,
|
|
15074
|
+
preferredForegroundTone
|
|
15075
|
+
) ? 0 : 1;
|
|
15076
|
+
if (leftPreferred !== rightPreferred) {
|
|
15077
|
+
return leftPreferred - rightPreferred;
|
|
15078
|
+
}
|
|
15079
|
+
const leftWhitePenalty = left.foreground.token === WHITE_FOREGROUND.token ? 1 : 0;
|
|
15080
|
+
const rightWhitePenalty = right.foreground.token === WHITE_FOREGROUND.token ? 1 : 0;
|
|
15081
|
+
if (leftWhitePenalty !== rightWhitePenalty) {
|
|
15082
|
+
return leftWhitePenalty - rightWhitePenalty;
|
|
15083
|
+
}
|
|
15043
15084
|
const leftTargetDelta = Math.abs(left.foreground.tone - preferredForegroundTone);
|
|
15044
15085
|
const rightTargetDelta = Math.abs(right.foreground.tone - preferredForegroundTone);
|
|
15045
15086
|
if (leftTargetDelta !== rightTargetDelta) {
|
|
@@ -15050,258 +15091,359 @@ function pickForeground(colorsToPair, background, minimumRatio) {
|
|
|
15050
15091
|
if (leftToneGap !== rightToneGap) {
|
|
15051
15092
|
return rightToneGap - leftToneGap;
|
|
15052
15093
|
}
|
|
15053
|
-
|
|
15054
|
-
|
|
15055
|
-
}
|
|
15056
|
-
function buildRecommendedPairs(colorsToPair, minimumRatio) {
|
|
15057
|
-
const backgrounds = recommendedBackgroundTones.map((tone) => colorsToPair.find((color2) => color2.tone === tone)).filter((color2) => Boolean(color2));
|
|
15058
|
-
const recommendedPairs = [];
|
|
15059
|
-
for (const background of backgrounds) {
|
|
15060
|
-
const pair = pickForeground(colorsToPair, background, minimumRatio);
|
|
15061
|
-
const whitePair = background.tone >= MIN_DARK_BACKGROUND_TONE_FOR_WHITE ? buildPair(background, WHITE_FOREGROUND) : null;
|
|
15062
|
-
if (pair && !recommendedPairs.some((item) => item.id === pair.id)) {
|
|
15063
|
-
recommendedPairs.push(pair);
|
|
15094
|
+
if (left.foreground.familyKey === background.familyKey && right.foreground.familyKey !== background.familyKey) {
|
|
15095
|
+
return -1;
|
|
15064
15096
|
}
|
|
15065
|
-
if (
|
|
15066
|
-
|
|
15097
|
+
if (right.foreground.familyKey === background.familyKey && left.foreground.familyKey !== background.familyKey) {
|
|
15098
|
+
return 1;
|
|
15067
15099
|
}
|
|
15100
|
+
return right.contrastRatio - left.contrastRatio;
|
|
15101
|
+
});
|
|
15102
|
+
}
|
|
15103
|
+
function dedupeColors(colorsToDedupe) {
|
|
15104
|
+
return Array.from(new Map(colorsToDedupe.map((color2) => [color2.token, color2])).values());
|
|
15105
|
+
}
|
|
15106
|
+
function buildRecommendedPairsForBackground(background, foregrounds, minimumRatio) {
|
|
15107
|
+
const candidatePairs = foregrounds.filter((foreground) => foreground.token !== background.token).map((foreground) => buildPair(background, foreground)).filter((pair) => pair.contrastRatio >= minimumRatio);
|
|
15108
|
+
const whitePair = background.tone >= MIN_DARK_BACKGROUND_TONE_FOR_WHITE ? buildPair(background, WHITE_FOREGROUND) : null;
|
|
15109
|
+
if (whitePair && whitePair.contrastRatio >= minimumRatio) {
|
|
15110
|
+
candidatePairs.push(whitePair);
|
|
15068
15111
|
}
|
|
15069
|
-
|
|
15112
|
+
const dedupedPairs = Array.from(new Map(candidatePairs.map((pair) => [pair.id, pair])).values());
|
|
15113
|
+
return sortRecommendedPairs(background, dedupedPairs);
|
|
15114
|
+
}
|
|
15115
|
+
function findGreyFamily(families) {
|
|
15116
|
+
return families.find((family) => family.key.toLowerCase().includes("grey")) ?? families[0];
|
|
15117
|
+
}
|
|
15118
|
+
function getNonGreyFamilies(families) {
|
|
15119
|
+
const greyFamily = findGreyFamily(families);
|
|
15120
|
+
return families.filter((family) => family.key !== greyFamily.key);
|
|
15121
|
+
}
|
|
15122
|
+
function findFamilyByKey(families, key) {
|
|
15123
|
+
return key ? families.find((family) => family.key === key) : void 0;
|
|
15124
|
+
}
|
|
15125
|
+
function getDefaultPrimaryFamily(families) {
|
|
15126
|
+
const nonGreyFamilies = getNonGreyFamilies(families);
|
|
15127
|
+
return findFamilyByKey(nonGreyFamilies, DEFAULT_PRIMARY_FAMILY_KEY) ?? findFamilyByKey(nonGreyFamilies, "green") ?? nonGreyFamilies[0] ?? families[0];
|
|
15128
|
+
}
|
|
15129
|
+
function getDefaultAccentFamily(families, primaryKey) {
|
|
15130
|
+
const nonGreyFamilies = getNonGreyFamilies(families).filter((family) => family.key !== primaryKey);
|
|
15131
|
+
return findFamilyByKey(nonGreyFamilies, DEFAULT_ACCENT_FAMILY_KEY) ?? nonGreyFamilies[0] ?? getDefaultPrimaryFamily(families);
|
|
15132
|
+
}
|
|
15133
|
+
function isApprovedBackgroundTone(color2) {
|
|
15134
|
+
return recommendedBackgroundTones.includes(
|
|
15135
|
+
color2.tone
|
|
15136
|
+
);
|
|
15137
|
+
}
|
|
15138
|
+
function isApprovedForegroundTone(color2) {
|
|
15139
|
+
return recommendedForegroundTones.includes(
|
|
15140
|
+
color2.tone
|
|
15141
|
+
);
|
|
15142
|
+
}
|
|
15143
|
+
function getPairingFamilies(themeCategory) {
|
|
15144
|
+
return pairingFamilyCollections[themeCategory];
|
|
15070
15145
|
}
|
|
15071
|
-
function
|
|
15146
|
+
function getDefaultAccentFamilyKey(themeCategory, primaryKey) {
|
|
15147
|
+
return getDefaultAccentFamily(getPairingFamilies(themeCategory), primaryKey).key;
|
|
15148
|
+
}
|
|
15149
|
+
function getPairingContext(themeCategory, primaryKey, accentKey) {
|
|
15150
|
+
const families = getPairingFamilies(themeCategory);
|
|
15151
|
+
const primary = findFamilyByKey(getNonGreyFamilies(families), primaryKey) ?? getDefaultPrimaryFamily(families);
|
|
15152
|
+
const accent = findFamilyByKey(
|
|
15153
|
+
getNonGreyFamilies(families).filter((family) => family.key !== primary.key),
|
|
15154
|
+
accentKey
|
|
15155
|
+
) ?? getDefaultAccentFamily(families, primary.key);
|
|
15156
|
+
const grey = findGreyFamily(families);
|
|
15157
|
+
const allFamilies = [primary, accent, grey];
|
|
15158
|
+
const backgroundGroups = [
|
|
15159
|
+
{
|
|
15160
|
+
key: "primary",
|
|
15161
|
+
label: "Primary backgrounds",
|
|
15162
|
+
family: primary,
|
|
15163
|
+
backgrounds: primary.colors.filter(isApprovedBackgroundTone)
|
|
15164
|
+
},
|
|
15165
|
+
{
|
|
15166
|
+
key: "accent",
|
|
15167
|
+
label: "Accent backgrounds",
|
|
15168
|
+
family: accent,
|
|
15169
|
+
backgrounds: accent.colors.filter(isApprovedBackgroundTone)
|
|
15170
|
+
},
|
|
15171
|
+
{
|
|
15172
|
+
key: "grey",
|
|
15173
|
+
label: "Grey backgrounds",
|
|
15174
|
+
family: grey,
|
|
15175
|
+
backgrounds: grey.colors.filter(isApprovedBackgroundTone)
|
|
15176
|
+
}
|
|
15177
|
+
];
|
|
15178
|
+
const backgrounds = backgroundGroups.flatMap((group) => group.backgrounds);
|
|
15179
|
+
const candidateForegrounds = dedupeColors(
|
|
15180
|
+
allFamilies.flatMap((family) => family.colors.filter(isApprovedForegroundTone))
|
|
15181
|
+
);
|
|
15182
|
+
const pairsByBackground = {};
|
|
15183
|
+
for (const background of backgrounds) {
|
|
15184
|
+
pairsByBackground[background.token] = buildRecommendedPairsForBackground(
|
|
15185
|
+
background,
|
|
15186
|
+
candidateForegrounds,
|
|
15187
|
+
AAA_NORMAL_TEXT_RATIO
|
|
15188
|
+
);
|
|
15189
|
+
}
|
|
15072
15190
|
return {
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
|
|
15076
|
-
|
|
15077
|
-
|
|
15078
|
-
|
|
15079
|
-
|
|
15080
|
-
|
|
15081
|
-
|
|
15082
|
-
|
|
15083
|
-
|
|
15084
|
-
const scale2 = palette.colors.map(toPairingColor);
|
|
15085
|
-
return {
|
|
15086
|
-
key,
|
|
15087
|
-
label: formatFamilyLabel(palette.name, key),
|
|
15088
|
-
paletteName: palette.name,
|
|
15089
|
-
colors: scale2,
|
|
15090
|
-
recommendedPairs: buildRecommendedPairs(scale2, minimumRatio)
|
|
15091
|
-
};
|
|
15092
|
-
})
|
|
15191
|
+
accent,
|
|
15192
|
+
allFamilies,
|
|
15193
|
+
backgroundGroups,
|
|
15194
|
+
backgrounds,
|
|
15195
|
+
grey,
|
|
15196
|
+
pairsByBackground,
|
|
15197
|
+
primary,
|
|
15198
|
+
recommendedPairs: backgrounds.flatMap(
|
|
15199
|
+
(background) => pairsByBackground[background.token] ?? []
|
|
15200
|
+
),
|
|
15201
|
+
themeCategory
|
|
15093
15202
|
};
|
|
15094
15203
|
}
|
|
15095
|
-
var recommendedAaaPairingCollections = buildRecommendedCollections(AAA_NORMAL_TEXT_RATIO);
|
|
15096
15204
|
function getWhiteForegroundPair(background) {
|
|
15097
15205
|
return buildPair(background, WHITE_FOREGROUND);
|
|
15098
15206
|
}
|
|
15099
15207
|
function supportsWhiteForegroundPreview(background) {
|
|
15100
15208
|
return background.tone >= MIN_DARK_BACKGROUND_TONE_FOR_WHITE;
|
|
15101
15209
|
}
|
|
15102
|
-
|
|
15103
|
-
|
|
15104
|
-
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
|
|
15109
|
-
|
|
15110
|
-
"data-[state=on]:bg-grey-100 data-[state=on]:text-grey-850",
|
|
15111
|
-
// Hover
|
|
15112
|
-
"hover:bg-grey-100 hover:text-grey-850",
|
|
15113
|
-
// Focus
|
|
15114
|
-
"focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-(--toggle-border)",
|
|
15115
|
-
// Dark mode
|
|
15116
|
-
"dark:text-white",
|
|
15117
|
-
// Dark mode states
|
|
15118
|
-
"dark:data-[state=on]:bg-white/10 dark:data-[state=on]:text-white",
|
|
15119
|
-
// Dark mode hover
|
|
15120
|
-
"dark:hover:bg-white/10 dark:hover:text-white",
|
|
15121
|
-
// Disabled
|
|
15122
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
15123
|
-
// Icon
|
|
15124
|
-
'[&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 [&_svg]:shrink-0',
|
|
15125
|
-
// Aria invalid
|
|
15126
|
-
"aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
|
|
15127
|
-
// Aria invalid dark mode
|
|
15128
|
-
"dark:aria-invalid:ring-destructive/40"
|
|
15129
|
-
],
|
|
15130
|
-
outline: [
|
|
15131
|
-
// Base
|
|
15132
|
-
"text-grey-800 border [--toggle-border:var(--color-grey-300)]",
|
|
15133
|
-
// States
|
|
15134
|
-
"hover:[--toggle-border:var(--color-grey-400)]",
|
|
15135
|
-
// Dark mode
|
|
15136
|
-
"dark:[--toggle-border:white]/40",
|
|
15137
|
-
// Dark mode states
|
|
15138
|
-
"dark:hover:[--toggle-border:white]/50",
|
|
15139
|
-
// Data on
|
|
15140
|
-
"data-[state=on]:bg-primary-800/10"
|
|
15141
|
-
]
|
|
15142
|
-
};
|
|
15143
|
-
var toggleVariants = classVarianceAuthority.cva(styles3.base, {
|
|
15144
|
-
variants: {
|
|
15145
|
-
variant: {
|
|
15146
|
-
ghost: "",
|
|
15147
|
-
outline: clsx12__default.default(styles3.outline)
|
|
15148
|
-
},
|
|
15149
|
-
size: {
|
|
15150
|
-
default: "h-9 px-2 min-w-9",
|
|
15151
|
-
sm: "h-8 px-1.5 min-w-8",
|
|
15152
|
-
lg: "h-10 px-2.5 min-w-10"
|
|
15153
|
-
}
|
|
15154
|
-
},
|
|
15155
|
-
defaultVariants: {
|
|
15156
|
-
variant: "ghost",
|
|
15157
|
-
size: "default"
|
|
15210
|
+
var SluggerContext = React5__namespace.default.createContext(null);
|
|
15211
|
+
function flattenText(nodes) {
|
|
15212
|
+
if (nodes == null || typeof nodes === "boolean") return "";
|
|
15213
|
+
if (typeof nodes === "string" || typeof nodes === "number" || typeof nodes === "bigint")
|
|
15214
|
+
return String(nodes);
|
|
15215
|
+
if (Array.isArray(nodes)) return nodes.map(flattenText).join("");
|
|
15216
|
+
if (React5__namespace.default.isValidElement(nodes)) {
|
|
15217
|
+
return flattenText(nodes.props.children);
|
|
15158
15218
|
}
|
|
15159
|
-
|
|
15160
|
-
function Toggle({
|
|
15161
|
-
className,
|
|
15162
|
-
variant,
|
|
15163
|
-
size,
|
|
15164
|
-
...props
|
|
15165
|
-
}) {
|
|
15166
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15167
|
-
TogglePrimitive__namespace.Root,
|
|
15168
|
-
{
|
|
15169
|
-
"data-slot": "toggle",
|
|
15170
|
-
className: cn(toggleVariants({ variant, size, className })),
|
|
15171
|
-
...props
|
|
15172
|
-
}
|
|
15173
|
-
);
|
|
15219
|
+
return "";
|
|
15174
15220
|
}
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
function ToggleGroup({
|
|
15221
|
+
function baseSlug(input) {
|
|
15222
|
+
return input.toLowerCase().trim().replace(/[\s\W]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15223
|
+
}
|
|
15224
|
+
function Heading({
|
|
15180
15225
|
className,
|
|
15181
|
-
|
|
15182
|
-
size,
|
|
15226
|
+
trim = "normal",
|
|
15227
|
+
size = 1,
|
|
15228
|
+
level = 1,
|
|
15229
|
+
display = false,
|
|
15230
|
+
id: idProp,
|
|
15183
15231
|
children,
|
|
15184
15232
|
...props
|
|
15185
15233
|
}) {
|
|
15234
|
+
const Tag = `h${level}`;
|
|
15235
|
+
const slugger = React5.useContext(SluggerContext);
|
|
15236
|
+
const headingSizeClasses = {
|
|
15237
|
+
1: "text-[calc(var(--heading-font-size-1)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-52)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
15238
|
+
2: "text-[calc(var(--heading-font-size-2)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-44)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
15239
|
+
3: "text-[calc(var(--heading-font-size-3)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-40)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
15240
|
+
4: "text-[calc(var(--heading-font-size-4)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-36)] tracking-[calc(var(--heading-letter-spacing-1)_+_var(--heading-letter-spacing))]",
|
|
15241
|
+
5: "text-[calc(var(--heading-font-size-5)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-32)] tracking-[calc(var(--heading-letter-spacing-1)_+_var(--heading-letter-spacing))]",
|
|
15242
|
+
6: "text-[calc(var(--heading-font-size-6)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-28)] tracking-[calc(var(--letter-spacing-0)_+_var(--heading-letter-spacing))]"
|
|
15243
|
+
};
|
|
15244
|
+
const displaySizeClasses = {
|
|
15245
|
+
1: "text-[calc(var(--display-font-size-1)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-96)] tracking-[calc(var(--heading-letter-spacing-3)_+_var(--heading-letter-spacing))]",
|
|
15246
|
+
2: "text-[calc(var(--display-font-size-2)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-60)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
15247
|
+
3: "text-[calc(var(--display-font-size-3)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-52)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
15248
|
+
4: "text-[calc(var(--display-font-size-4)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-44)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]"
|
|
15249
|
+
};
|
|
15250
|
+
const sizeClass = display ? displaySizeClasses[size] : headingSizeClasses[size];
|
|
15251
|
+
const trimClasses = {
|
|
15252
|
+
normal: ["before:content-none after:content-none"],
|
|
15253
|
+
start: [
|
|
15254
|
+
'before:content-[""] before:table after:content-none',
|
|
15255
|
+
"before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
15256
|
+
],
|
|
15257
|
+
end: [
|
|
15258
|
+
'before:content-none after:content-[""] after:table',
|
|
15259
|
+
"after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
15260
|
+
],
|
|
15261
|
+
both: [
|
|
15262
|
+
'before:content-[""] before:table after:content-[""] after:table',
|
|
15263
|
+
"before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]",
|
|
15264
|
+
"after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
15265
|
+
]
|
|
15266
|
+
};
|
|
15267
|
+
const computedId = React5.useMemo(() => {
|
|
15268
|
+
if (idProp) return idProp;
|
|
15269
|
+
const text = flattenText(children);
|
|
15270
|
+
if (!text) return void 0;
|
|
15271
|
+
const base = baseSlug(text);
|
|
15272
|
+
return slugger ? slugger.slug(base) : base;
|
|
15273
|
+
}, [idProp, children, slugger]);
|
|
15186
15274
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15187
|
-
|
|
15275
|
+
Tag,
|
|
15188
15276
|
{
|
|
15189
|
-
"data-slot": "toggle-group",
|
|
15190
|
-
"data-variant": variant,
|
|
15191
|
-
"data-size": size,
|
|
15192
|
-
className: cn(
|
|
15193
|
-
"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
|
|
15194
|
-
className
|
|
15195
|
-
),
|
|
15196
15277
|
...props,
|
|
15197
|
-
|
|
15278
|
+
id: computedId,
|
|
15279
|
+
"data-anchor": true,
|
|
15280
|
+
className: clsx12__default.default(
|
|
15281
|
+
className,
|
|
15282
|
+
trimClasses[trim],
|
|
15283
|
+
"m-0",
|
|
15284
|
+
"leading-[var(--line-height)] font-[var(--heading-font-family)] font-bold",
|
|
15285
|
+
"[--leading-trim-end:var(--heading-leading-trim-end)] [--leading-trim-start:var(--heading-leading-trim-start)]",
|
|
15286
|
+
"text-primary-800 dark:text-white",
|
|
15287
|
+
sizeClass
|
|
15288
|
+
),
|
|
15289
|
+
children
|
|
15198
15290
|
}
|
|
15199
15291
|
);
|
|
15200
15292
|
}
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
}) {
|
|
15208
|
-
const context = React5__namespace.useContext(ToggleGroupContext);
|
|
15209
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15210
|
-
ToggleGroupPrimitive__namespace.Item,
|
|
15211
|
-
{
|
|
15212
|
-
"data-slot": "toggle-group-item",
|
|
15213
|
-
"data-variant": context.variant || variant,
|
|
15214
|
-
"data-size": context.size || size,
|
|
15215
|
-
className: cn(
|
|
15216
|
-
toggleVariants({
|
|
15217
|
-
variant: context.variant || variant,
|
|
15218
|
-
size: context.size || size
|
|
15219
|
-
}),
|
|
15220
|
-
"min-w-0 shrink-0 rounded-none shadow-none first:rounded-l-sm last:rounded-r-sm focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
|
|
15221
|
-
className
|
|
15222
|
-
),
|
|
15223
|
-
...props,
|
|
15224
|
-
children
|
|
15225
|
-
}
|
|
15226
|
-
);
|
|
15227
|
-
}
|
|
15228
|
-
function FormatToggle({ format, setFormat }) {
|
|
15229
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
15230
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Format:" }),
|
|
15231
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15232
|
-
ToggleGroup,
|
|
15233
|
-
{
|
|
15234
|
-
type: "single",
|
|
15235
|
-
value: format,
|
|
15236
|
-
onValueChange: (value) => value && setFormat(value),
|
|
15237
|
-
children: [
|
|
15238
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hex", "aria-label": "HEX format", children: "HEX" }),
|
|
15239
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "rgb", "aria-label": "RGB format", children: "RGB" }),
|
|
15240
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hsl", "aria-label": "HSL format", children: "HSL" }),
|
|
15241
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "oklch", "aria-label": "OKLCH format", children: "OKLCH" })
|
|
15242
|
-
]
|
|
15243
|
-
}
|
|
15244
|
-
)
|
|
15245
|
-
] });
|
|
15246
|
-
}
|
|
15247
|
-
function getPreferredFamilyKey(families) {
|
|
15248
|
-
return families.find((family) => family.key === "green")?.key ?? families[0]?.key ?? "";
|
|
15249
|
-
}
|
|
15250
|
-
function getDefaultPair(family) {
|
|
15251
|
-
if (!family || family.recommendedPairs.length === 0) return null;
|
|
15252
|
-
return family.recommendedPairs.reduce((bestPair, pair) => {
|
|
15253
|
-
const bestDelta = Math.abs(bestPair.background.tone - 600);
|
|
15254
|
-
const currentDelta = Math.abs(pair.background.tone - 600);
|
|
15255
|
-
return currentDelta < bestDelta ? pair : bestPair;
|
|
15256
|
-
}, family.recommendedPairs[0]);
|
|
15257
|
-
}
|
|
15258
|
-
function getFamilySwatchColor(family) {
|
|
15259
|
-
return family.colors.find((color2) => color2.tone === 500)?.hex ?? family.colors.find((color2) => color2.tone === 400)?.hex ?? family.colors[Math.min(3, family.colors.length - 1)]?.hex ?? "transparent";
|
|
15260
|
-
}
|
|
15293
|
+
var AAA_NORMAL_TEXT_THRESHOLD = "7.0:1 for text below the WCAG large-text threshold. Sentence-case body copy should generally stay at 16px+ unless it is microcopy.";
|
|
15294
|
+
var AAA_LARGE_TEXT_THRESHOLD = "4.5:1 for WCAG large text: 24px+, or 18.5px+ bold";
|
|
15295
|
+
var PREFERRED_BACKGROUND_TONES = [400, 600, 200, 800, 100, 50];
|
|
15296
|
+
var DEFAULT_VISIBLE_FORMATS = ["hex", "rgb", "hsl", "oklch"];
|
|
15297
|
+
var DEFAULT_INITIAL_BACKGROUND_TOKEN = "nsw-blue-800";
|
|
15298
|
+
var DEFAULT_INITIAL_PAIR_ID = "nsw-blue-800:nsw-blue-200";
|
|
15261
15299
|
function getToneFromToken(token) {
|
|
15262
15300
|
if (!token) return null;
|
|
15263
15301
|
const match = token.match(/-(\d+)$/);
|
|
15264
15302
|
return match ? Number.parseInt(match[1], 10) : null;
|
|
15265
15303
|
}
|
|
15266
|
-
function
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
|
|
15304
|
+
function getFamilySwatchColor(family, preferredTone = 600) {
|
|
15305
|
+
const exactMatch = family.colors.find((color2) => color2.tone === preferredTone);
|
|
15306
|
+
if (exactMatch) {
|
|
15307
|
+
return exactMatch.hex;
|
|
15308
|
+
}
|
|
15309
|
+
const closestMatch = [...family.colors].sort(
|
|
15310
|
+
(left, right) => Math.abs(left.tone - preferredTone) - Math.abs(right.tone - preferredTone)
|
|
15311
|
+
)[0];
|
|
15312
|
+
return closestMatch?.hex ?? "transparent";
|
|
15270
15313
|
}
|
|
15271
|
-
function
|
|
15272
|
-
|
|
15314
|
+
function getFamilySelectorLabel(family, themeCategory, selectionRole) {
|
|
15315
|
+
if (themeCategory !== "aboriginal") {
|
|
15316
|
+
return family.label;
|
|
15317
|
+
}
|
|
15318
|
+
const preferredTone = selectionRole === "primary colour" ? 800 : 600;
|
|
15319
|
+
return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
|
|
15320
|
+
}
|
|
15321
|
+
function getActivePaletteFamilyLabel(family, themeCategory, paletteRole) {
|
|
15322
|
+
if (themeCategory !== "aboriginal") {
|
|
15323
|
+
return family.label;
|
|
15324
|
+
}
|
|
15325
|
+
const preferredTone = paletteRole === "primary" ? 800 : paletteRole === "accent" ? 600 : 800;
|
|
15326
|
+
return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
|
|
15273
15327
|
}
|
|
15274
15328
|
function isWhiteForegroundPair(pair) {
|
|
15275
15329
|
return pair.foreground.token === "white";
|
|
15276
15330
|
}
|
|
15277
|
-
function
|
|
15278
|
-
if (
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
)
|
|
15282
|
-
|
|
15331
|
+
function getWhiteForegroundGuidance(pair) {
|
|
15332
|
+
if (pair.passes.aaaText) {
|
|
15333
|
+
return "White is approved for headings, body copy, and calls to action on this background.";
|
|
15334
|
+
}
|
|
15335
|
+
if (pair.passes.aaaLarge) {
|
|
15336
|
+
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.";
|
|
15337
|
+
}
|
|
15338
|
+
return "Do not use white on this background. Choose one of the recommended foregrounds below instead.";
|
|
15339
|
+
}
|
|
15340
|
+
function getPreviewGuidance(pair, isRecommended) {
|
|
15341
|
+
if (!isWhiteForegroundPair(pair)) {
|
|
15342
|
+
return "Use only AAA-recommended combinations across your selected primary, accent, and grey families.";
|
|
15343
|
+
}
|
|
15344
|
+
if (isRecommended) {
|
|
15345
|
+
return "Use white text on dark colour only when it meets AAA for headings, body copy, and calls to action.";
|
|
15346
|
+
}
|
|
15347
|
+
return getWhiteForegroundGuidance(pair);
|
|
15348
|
+
}
|
|
15349
|
+
function getPairingColorDisplayName(color2) {
|
|
15350
|
+
return color2.name ?? color2.token;
|
|
15351
|
+
}
|
|
15352
|
+
function WorkflowStep({
|
|
15353
|
+
step,
|
|
15354
|
+
title,
|
|
15355
|
+
description,
|
|
15356
|
+
level = 2,
|
|
15357
|
+
variant = "section",
|
|
15358
|
+
className
|
|
15359
|
+
}) {
|
|
15360
|
+
if (variant === "card") {
|
|
15361
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", className), children: [
|
|
15362
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 items-center justify-center rounded-full bg-primary-800 text-sm font-semibold text-white dark:bg-primary-700", children: step }),
|
|
15363
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
15364
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15365
|
+
Heading,
|
|
15366
|
+
{
|
|
15367
|
+
level,
|
|
15368
|
+
size: 5,
|
|
15369
|
+
className: "text-primary-800 dark:text-white",
|
|
15370
|
+
trim: "normal",
|
|
15371
|
+
children: title
|
|
15372
|
+
}
|
|
15373
|
+
),
|
|
15374
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base/6 text-muted-foreground", children: description }) : null
|
|
15375
|
+
] })
|
|
15376
|
+
] });
|
|
15377
|
+
}
|
|
15378
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-4", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-4", children: [
|
|
15379
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-full bg-primary-800 text-sm font-semibold text-white dark:bg-primary-700", children: step }),
|
|
15380
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-3", children: [
|
|
15381
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15382
|
+
Heading,
|
|
15383
|
+
{
|
|
15384
|
+
level,
|
|
15385
|
+
size: 4,
|
|
15386
|
+
className: "text-primary-800 dark:text-white",
|
|
15387
|
+
trim: "normal",
|
|
15388
|
+
children: title
|
|
15389
|
+
}
|
|
15390
|
+
),
|
|
15391
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base/6 text-muted-foreground", children: description }) : null
|
|
15392
|
+
] })
|
|
15393
|
+
] }) });
|
|
15394
|
+
}
|
|
15395
|
+
function getPreferredPairForBackground(pairs, preferredPairId) {
|
|
15283
15396
|
if (preferredPairId) {
|
|
15284
|
-
const preferredPair =
|
|
15397
|
+
const preferredPair = pairs.find((pair) => pair.id === preferredPairId);
|
|
15285
15398
|
if (preferredPair) {
|
|
15286
15399
|
return preferredPair;
|
|
15287
15400
|
}
|
|
15288
15401
|
}
|
|
15289
|
-
return
|
|
15402
|
+
return pairs.find((pair) => !isWhiteForegroundPair(pair)) ?? pairs[0] ?? null;
|
|
15403
|
+
}
|
|
15404
|
+
function getDefaultBackgroundToken(context) {
|
|
15405
|
+
for (const tone of PREFERRED_BACKGROUND_TONES) {
|
|
15406
|
+
for (const group of context.backgroundGroups) {
|
|
15407
|
+
const match = group.backgrounds.find(
|
|
15408
|
+
(background) => background.tone === tone && (context.pairsByBackground[background.token]?.length ?? 0) > 0
|
|
15409
|
+
);
|
|
15410
|
+
if (match) {
|
|
15411
|
+
return match.token;
|
|
15412
|
+
}
|
|
15413
|
+
}
|
|
15414
|
+
}
|
|
15415
|
+
for (const tone of PREFERRED_BACKGROUND_TONES) {
|
|
15416
|
+
for (const group of context.backgroundGroups) {
|
|
15417
|
+
const match = group.backgrounds.find((background) => background.tone === tone);
|
|
15418
|
+
if (match) {
|
|
15419
|
+
return match.token;
|
|
15420
|
+
}
|
|
15421
|
+
}
|
|
15422
|
+
}
|
|
15423
|
+
return context.backgrounds[0]?.token ?? "";
|
|
15290
15424
|
}
|
|
15291
|
-
function
|
|
15292
|
-
|
|
15293
|
-
|
|
15294
|
-
|
|
15295
|
-
|
|
15296
|
-
|
|
15425
|
+
function resolveBackgroundToken(context, preferredToken, preferredTone) {
|
|
15426
|
+
if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
|
|
15427
|
+
return preferredToken;
|
|
15428
|
+
}
|
|
15429
|
+
if (preferredTone !== null && preferredTone !== void 0) {
|
|
15430
|
+
for (const group of context.backgroundGroups) {
|
|
15431
|
+
const match = group.backgrounds.find((background) => background.tone === preferredTone);
|
|
15432
|
+
if (match) {
|
|
15433
|
+
return match.token;
|
|
15434
|
+
}
|
|
15297
15435
|
}
|
|
15298
15436
|
}
|
|
15299
|
-
return
|
|
15437
|
+
return getDefaultBackgroundToken(context);
|
|
15300
15438
|
}
|
|
15301
15439
|
function ColorPairingToolLoading() {
|
|
15302
15440
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
|
|
15303
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-
|
|
15304
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6
|
|
15441
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-32 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
|
|
15442
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-2", children: [
|
|
15443
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-48 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
|
|
15444
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-48 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" })
|
|
15445
|
+
] }),
|
|
15446
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1.5fr)_minmax(18rem,0.72fr)]", children: [
|
|
15305
15447
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-96 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
|
|
15306
15448
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-96 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" })
|
|
15307
15449
|
] })
|
|
@@ -15309,30 +15451,52 @@ function ColorPairingToolLoading() {
|
|
|
15309
15451
|
}
|
|
15310
15452
|
function getInitialPairingState(searchParams) {
|
|
15311
15453
|
const paletteParam = searchParams.get("palette");
|
|
15312
|
-
const
|
|
15454
|
+
const primaryParam = searchParams.get("primary");
|
|
15455
|
+
const accentParam = searchParams.get("accent");
|
|
15313
15456
|
const pairParam = searchParams.get("pair");
|
|
15314
15457
|
const backgroundParam = searchParams.get("background");
|
|
15315
15458
|
const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
|
|
15316
|
-
const
|
|
15317
|
-
const
|
|
15318
|
-
const
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
const
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
);
|
|
15325
|
-
const
|
|
15326
|
-
|
|
15459
|
+
const context = getPairingContext(themeCategory, primaryParam, accentParam);
|
|
15460
|
+
const shouldUseDefaultBrandExample = !backgroundParam && !pairParam && themeCategory === "brand" && context.primary.key === "blue" && context.accent.key === "red";
|
|
15461
|
+
const defaultBackgroundToken = shouldUseDefaultBrandExample ? context.backgrounds.some(
|
|
15462
|
+
(background) => background.token === DEFAULT_INITIAL_BACKGROUND_TOKEN
|
|
15463
|
+
) ? DEFAULT_INITIAL_BACKGROUND_TOKEN : null : null;
|
|
15464
|
+
const defaultPairId = shouldUseDefaultBrandExample && defaultBackgroundToken && context.pairsByBackground[defaultBackgroundToken]?.some(
|
|
15465
|
+
(pair) => pair.id === DEFAULT_INITIAL_PAIR_ID
|
|
15466
|
+
) ? DEFAULT_INITIAL_PAIR_ID : null;
|
|
15467
|
+
const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
|
|
15468
|
+
const selectedBackgroundToken = resolveBackgroundToken(
|
|
15469
|
+
context,
|
|
15470
|
+
backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
|
|
15471
|
+
getToneFromToken(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
|
|
15472
|
+
);
|
|
15473
|
+
const selectedPairId = getPreferredPairForBackground(
|
|
15474
|
+
context.pairsByBackground[selectedBackgroundToken] ?? [],
|
|
15475
|
+
pairParam ?? defaultPairId
|
|
15476
|
+
)?.id ?? "";
|
|
15477
|
+
return {
|
|
15478
|
+
accentKey: context.accent.key,
|
|
15479
|
+
primaryKey: context.primary.key,
|
|
15480
|
+
selectedBackgroundToken,
|
|
15481
|
+
selectedPairId,
|
|
15482
|
+
themeCategory
|
|
15483
|
+
};
|
|
15327
15484
|
}
|
|
15328
15485
|
function PairPreview({
|
|
15329
|
-
|
|
15486
|
+
familySummary,
|
|
15330
15487
|
isRecommended,
|
|
15331
15488
|
pair
|
|
15332
15489
|
}) {
|
|
15333
15490
|
const whiteForeground = isWhiteForegroundPair(pair);
|
|
15334
15491
|
const statusLabel = isRecommended ? "Pass" : pair.passes.aaaLarge ? "Large text only" : "Example only";
|
|
15335
15492
|
const StatusIcon = isRecommended ? Icons.check : Icons.info;
|
|
15493
|
+
const fauxButtonStyle = {
|
|
15494
|
+
"--btn-bg": pair.foreground.hex,
|
|
15495
|
+
"--btn-border": pair.foreground.hex,
|
|
15496
|
+
"--btn-text": pair.background.hex,
|
|
15497
|
+
"--btn-icon": pair.background.hex,
|
|
15498
|
+
"--btn-hover-overlay": pair.background.hex
|
|
15499
|
+
};
|
|
15336
15500
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "gap-0 overflow-hidden py-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15337
15501
|
"div",
|
|
15338
15502
|
{
|
|
@@ -15354,7 +15518,7 @@ function PairPreview({
|
|
|
15354
15518
|
},
|
|
15355
15519
|
children: [
|
|
15356
15520
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
|
|
15357
|
-
|
|
15521
|
+
familySummary
|
|
15358
15522
|
]
|
|
15359
15523
|
}
|
|
15360
15524
|
),
|
|
@@ -15375,10 +15539,23 @@ function PairPreview({
|
|
|
15375
15539
|
)
|
|
15376
15540
|
] }),
|
|
15377
15541
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xl space-y-4 pb-12 sm:pb-16", children: [
|
|
15378
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: whiteForeground && !isRecommended ? "White on colour example" : whiteForeground ? "White on colour" : "
|
|
15542
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: whiteForeground && !isRecommended ? "White on colour example" : whiteForeground ? "White on colour" : "Colour on colour" }),
|
|
15379
15543
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
15380
15544
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "max-w-lg text-4xl leading-none font-bold text-current sm:text-5xl", children: "Pair colour with confidence." }),
|
|
15381
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-
|
|
15545
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-base/6 sm:text-base/7", children: getPreviewGuidance(pair, isRecommended) }),
|
|
15546
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15547
|
+
"span",
|
|
15548
|
+
{
|
|
15549
|
+
"aria-hidden": "true",
|
|
15550
|
+
"data-variant": "solid",
|
|
15551
|
+
className: cn(
|
|
15552
|
+
buttonVariants({ variant: "solid", size: "default" }),
|
|
15553
|
+
"pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
|
|
15554
|
+
),
|
|
15555
|
+
style: fauxButtonStyle,
|
|
15556
|
+
children: "Get started"
|
|
15557
|
+
}
|
|
15558
|
+
)
|
|
15382
15559
|
] })
|
|
15383
15560
|
] }),
|
|
15384
15561
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
@@ -15415,24 +15592,94 @@ function PairPreview({
|
|
|
15415
15592
|
}
|
|
15416
15593
|
) });
|
|
15417
15594
|
}
|
|
15595
|
+
function PreviewFallbackCard({
|
|
15596
|
+
familySummary,
|
|
15597
|
+
selectedBackground
|
|
15598
|
+
}) {
|
|
15599
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "gap-0 overflow-hidden py-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15600
|
+
"div",
|
|
15601
|
+
{
|
|
15602
|
+
className: "p-6 sm:min-h-[26rem] sm:p-8",
|
|
15603
|
+
style: {
|
|
15604
|
+
backgroundColor: selectedBackground.hex,
|
|
15605
|
+
color: selectedBackground.tone >= 600 ? "#ffffff" : "#002664"
|
|
15606
|
+
},
|
|
15607
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-[22rem] flex-col justify-between gap-8", children: [
|
|
15608
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2 rounded-full border border-current bg-transparent px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase", children: [
|
|
15609
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
|
|
15610
|
+
familySummary
|
|
15611
|
+
] }) }),
|
|
15612
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xl space-y-4 pb-12 sm:pb-16", children: [
|
|
15613
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: "Approved background" }),
|
|
15614
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
15615
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "max-w-lg text-4xl leading-none font-bold text-current sm:text-5xl", children: "Pair colour with confidence." }),
|
|
15616
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-base/6 sm:text-base/7", children: "This approved background tone does not currently have a recommended AAA foreground in this tool. Choose another approved background tone to continue." })
|
|
15617
|
+
] })
|
|
15618
|
+
] }),
|
|
15619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
15620
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2 rounded-full bg-current/10 px-4 py-2 text-sm font-semibold", children: [
|
|
15621
|
+
"No recommendation",
|
|
15622
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.info, { "data-slot": "icon", className: "size-4" })
|
|
15623
|
+
] }),
|
|
15624
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex rounded-full border border-current px-4 py-2 text-sm", children: selectedBackground.token })
|
|
15625
|
+
] })
|
|
15626
|
+
] })
|
|
15627
|
+
}
|
|
15628
|
+
) });
|
|
15629
|
+
}
|
|
15418
15630
|
function PairDetailCard({
|
|
15419
15631
|
color: color2,
|
|
15420
|
-
|
|
15421
|
-
|
|
15632
|
+
role,
|
|
15633
|
+
visibleFormats
|
|
15422
15634
|
}) {
|
|
15423
15635
|
const [, copyToClipboardRaw] = usehooks.useCopyToClipboard();
|
|
15424
15636
|
const [copiedField, setCopiedField] = React5.useState(null);
|
|
15425
|
-
const
|
|
15426
|
-
const
|
|
15637
|
+
const copiedFieldTimeoutRef = React5.useRef(null);
|
|
15638
|
+
const hasDisplayTone = color2.token !== "white";
|
|
15639
|
+
const formatRows = visibleFormats.map((format) => ({
|
|
15640
|
+
key: format,
|
|
15641
|
+
label: format.toUpperCase(),
|
|
15642
|
+
value: color2[format],
|
|
15643
|
+
mono: true,
|
|
15644
|
+
copyable: true
|
|
15645
|
+
}));
|
|
15646
|
+
const valueRows = [
|
|
15647
|
+
{ key: "token", label: "Token", value: color2.token, mono: true, copyable: true },
|
|
15648
|
+
{
|
|
15649
|
+
key: "tone",
|
|
15650
|
+
label: "Tone",
|
|
15651
|
+
value: hasDisplayTone ? String(color2.tone) : "Not applicable",
|
|
15652
|
+
mono: false,
|
|
15653
|
+
copyable: hasDisplayTone
|
|
15654
|
+
},
|
|
15655
|
+
...formatRows
|
|
15656
|
+
];
|
|
15657
|
+
React5.useEffect(() => {
|
|
15658
|
+
return () => {
|
|
15659
|
+
if (copiedFieldTimeoutRef.current) {
|
|
15660
|
+
clearTimeout(copiedFieldTimeoutRef.current);
|
|
15661
|
+
}
|
|
15662
|
+
};
|
|
15663
|
+
}, []);
|
|
15427
15664
|
const copyField = (field) => {
|
|
15428
|
-
|
|
15665
|
+
if (field === "tone" && !hasDisplayTone) {
|
|
15666
|
+
return;
|
|
15667
|
+
}
|
|
15668
|
+
const fieldValue = valueRows.find((row) => row.key === field)?.value;
|
|
15669
|
+
if (!fieldValue) return;
|
|
15429
15670
|
copyToClipboardRaw(fieldValue);
|
|
15430
15671
|
setCopiedField(field);
|
|
15431
|
-
const toastLabel =
|
|
15672
|
+
const toastLabel = valueRows.find((row) => row.key === field)?.label ?? "Value";
|
|
15432
15673
|
sonner.toast(`${toastLabel} copied to clipboard`, {
|
|
15433
15674
|
duration: 2e3
|
|
15434
15675
|
});
|
|
15435
|
-
|
|
15676
|
+
if (copiedFieldTimeoutRef.current) {
|
|
15677
|
+
clearTimeout(copiedFieldTimeoutRef.current);
|
|
15678
|
+
}
|
|
15679
|
+
copiedFieldTimeoutRef.current = setTimeout(() => {
|
|
15680
|
+
setCopiedField(null);
|
|
15681
|
+
copiedFieldTimeoutRef.current = null;
|
|
15682
|
+
}, 2e3);
|
|
15436
15683
|
};
|
|
15437
15684
|
const renderCopyButton = (field, srLabel, className) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15438
15685
|
Button2,
|
|
@@ -15447,43 +15694,39 @@ function PairDetailCard({
|
|
|
15447
15694
|
]
|
|
15448
15695
|
}
|
|
15449
15696
|
);
|
|
15450
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-
|
|
15451
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15697
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-0", children: [
|
|
15698
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-4 border-b", children: [
|
|
15699
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
15700
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: role }),
|
|
15701
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: color2.name ?? color2.token })
|
|
15702
|
+
] }),
|
|
15452
15703
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15453
15704
|
"div",
|
|
15454
15705
|
{
|
|
15455
|
-
className: "
|
|
15706
|
+
className: "h-14 w-full rounded-sm border border-grey-200 shadow-sm dark:border-grey-700",
|
|
15456
15707
|
style: { backgroundColor: color2.hex }
|
|
15457
15708
|
}
|
|
15458
|
-
)
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: color2.tone })
|
|
15478
|
-
] }),
|
|
15479
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
15480
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
15481
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: valueLabel }),
|
|
15482
|
-
renderCopyButton("value", `Copy ${role.toLowerCase()} ${valueLabel} value`)
|
|
15483
|
-
] }),
|
|
15484
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-sm break-all", children: formattedValue })
|
|
15709
|
+
)
|
|
15710
|
+
] }),
|
|
15711
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "px-0", children: /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "divide-y divide-grey-100 dark:divide-grey-800", children: valueRows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 px-6 py-3", children: [
|
|
15712
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: row.label }),
|
|
15713
|
+
/* @__PURE__ */ jsxRuntime.jsxs("dd", { className: "flex items-start justify-between gap-4", children: [
|
|
15714
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15715
|
+
"span",
|
|
15716
|
+
{
|
|
15717
|
+
className: cn(
|
|
15718
|
+
"min-w-0 flex-1 text-base text-foreground",
|
|
15719
|
+
row.mono && "font-mono text-sm break-all sm:text-base"
|
|
15720
|
+
),
|
|
15721
|
+
children: row.value
|
|
15722
|
+
}
|
|
15723
|
+
),
|
|
15724
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 justify-end", children: row.copyable ? renderCopyButton(
|
|
15725
|
+
row.key,
|
|
15726
|
+
`Copy ${role.toLowerCase()} ${row.label.toLowerCase()}`
|
|
15727
|
+
) : null })
|
|
15485
15728
|
] })
|
|
15486
|
-
] })
|
|
15729
|
+
] }, row.key)) }) })
|
|
15487
15730
|
] });
|
|
15488
15731
|
}
|
|
15489
15732
|
function ComplianceRow({
|
|
@@ -15491,31 +15734,40 @@ function ComplianceRow({
|
|
|
15491
15734
|
passes,
|
|
15492
15735
|
threshold
|
|
15493
15736
|
}) {
|
|
15494
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
className:
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
),
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
|
|
15737
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15738
|
+
"div",
|
|
15739
|
+
{
|
|
15740
|
+
className: cn(
|
|
15741
|
+
"flex items-center justify-between gap-4 rounded-sm border px-4 py-3",
|
|
15742
|
+
passes ? "border-success-200 bg-success-50 dark:border-success-900/60 dark:bg-success-950/20" : "border-danger-200 bg-danger-50 dark:border-danger-900/60 dark:bg-danger-950/20"
|
|
15743
|
+
),
|
|
15744
|
+
children: [
|
|
15745
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
15746
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: label }),
|
|
15747
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: threshold })
|
|
15748
|
+
] }),
|
|
15749
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15750
|
+
"span",
|
|
15751
|
+
{
|
|
15752
|
+
className: cn(
|
|
15753
|
+
"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-semibold",
|
|
15754
|
+
passes ? "bg-success-50 text-success-800 dark:bg-success-950/30 dark:text-success-200" : "bg-danger-50 text-danger-800 dark:bg-danger-950/30 dark:text-danger-200"
|
|
15755
|
+
),
|
|
15756
|
+
children: [
|
|
15757
|
+
passes ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.close, { "data-slot": "icon", className: "size-4" }),
|
|
15758
|
+
passes ? "Pass" : "Fail"
|
|
15759
|
+
]
|
|
15760
|
+
}
|
|
15761
|
+
)
|
|
15762
|
+
]
|
|
15763
|
+
}
|
|
15764
|
+
);
|
|
15513
15765
|
}
|
|
15514
15766
|
function PairComplianceCard({ pair }) {
|
|
15515
15767
|
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
|
|
15516
15768
|
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-2 border-b", children: [
|
|
15517
15769
|
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: "AAA compliance" }),
|
|
15518
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "
|
|
15770
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "This card shows the contrast result for the example above. Evaluation uses the raw contrast ratio, not the rounded display value." })
|
|
15519
15771
|
] }),
|
|
15520
15772
|
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-3", children: [
|
|
15521
15773
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-grey-200 bg-grey-50 px-4 py-3 dark:border-grey-700 dark:bg-grey-900/60", children: [
|
|
@@ -15530,7 +15782,7 @@ function PairComplianceCard({ pair }) {
|
|
|
15530
15782
|
{
|
|
15531
15783
|
label: "AAA normal text",
|
|
15532
15784
|
passes: pair.passes.aaaText,
|
|
15533
|
-
threshold:
|
|
15785
|
+
threshold: AAA_NORMAL_TEXT_THRESHOLD
|
|
15534
15786
|
}
|
|
15535
15787
|
),
|
|
15536
15788
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15538,105 +15790,115 @@ function PairComplianceCard({ pair }) {
|
|
|
15538
15790
|
{
|
|
15539
15791
|
label: "AAA large text",
|
|
15540
15792
|
passes: pair.passes.aaaLarge,
|
|
15541
|
-
threshold:
|
|
15793
|
+
threshold: AAA_LARGE_TEXT_THRESHOLD
|
|
15542
15794
|
}
|
|
15543
15795
|
)
|
|
15544
15796
|
] })
|
|
15545
15797
|
] });
|
|
15546
15798
|
}
|
|
15547
|
-
function
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15799
|
+
function ColorFamilySelector({
|
|
15800
|
+
families,
|
|
15801
|
+
label,
|
|
15802
|
+
selectedKey,
|
|
15803
|
+
selectionRole,
|
|
15804
|
+
themeCategory,
|
|
15805
|
+
onSelect
|
|
15806
|
+
}) {
|
|
15807
|
+
const swatchTone = selectionRole === "primary colour" ? 800 : 600;
|
|
15808
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0", children: [
|
|
15809
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 3, size: 6, className: "mb-4 text-foreground", trim: "normal", children: label }),
|
|
15810
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-2 lg:grid-cols-4 xl:grid-cols-5", children: families.map((family) => {
|
|
15811
|
+
const isSelected = family.key === selectedKey;
|
|
15812
|
+
const familySelectorLabel = getFamilySelectorLabel(family, themeCategory, selectionRole);
|
|
15813
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15814
|
+
"button",
|
|
15556
15815
|
{
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15564
|
-
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
] })
|
|
15581
|
-
}
|
|
15582
|
-
),
|
|
15583
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
15584
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-grey-200 bg-grey-50 px-4 py-3 dark:border-grey-700 dark:bg-grey-900/60", children: [
|
|
15585
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: "Contrast ratio" }),
|
|
15586
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-2xl font-semibold", children: [
|
|
15587
|
-
pair.contrastRatio.toFixed(2),
|
|
15588
|
-
":1"
|
|
15589
|
-
] })
|
|
15590
|
-
] }),
|
|
15591
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15592
|
-
ComplianceRow,
|
|
15593
|
-
{
|
|
15594
|
-
label: "AAA normal text",
|
|
15595
|
-
passes: pair.passes.aaaText,
|
|
15596
|
-
threshold: "7.0:1 or higher"
|
|
15597
|
-
}
|
|
15598
|
-
),
|
|
15599
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15600
|
-
ComplianceRow,
|
|
15601
|
-
{
|
|
15602
|
-
label: "AAA large text",
|
|
15603
|
-
passes: pair.passes.aaaLarge,
|
|
15604
|
-
threshold: "4.5:1 or higher"
|
|
15605
|
-
}
|
|
15606
|
-
)
|
|
15607
|
-
] })
|
|
15608
|
-
] })
|
|
15816
|
+
type: "button",
|
|
15817
|
+
"aria-label": `Select ${familySelectorLabel} as ${selectionRole}`,
|
|
15818
|
+
"aria-pressed": isSelected,
|
|
15819
|
+
onClick: () => onSelect(family.key),
|
|
15820
|
+
className: cn(
|
|
15821
|
+
"group relative flex w-full items-center gap-3 rounded-sm border px-3 py-2 text-left transition-colors",
|
|
15822
|
+
"border-grey-200 bg-background hover:bg-primary-800/10 hover:text-foreground dark:hover:bg-white/10",
|
|
15823
|
+
isSelected && "border-grey-800 dark:border-grey-400"
|
|
15824
|
+
),
|
|
15825
|
+
children: [
|
|
15826
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15827
|
+
"span",
|
|
15828
|
+
{
|
|
15829
|
+
className: "size-4 shrink-0 rounded-full",
|
|
15830
|
+
style: { backgroundColor: getFamilySwatchColor(family, swatchTone) }
|
|
15831
|
+
}
|
|
15832
|
+
),
|
|
15833
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: familySelectorLabel })
|
|
15834
|
+
]
|
|
15835
|
+
},
|
|
15836
|
+
family.key
|
|
15837
|
+
);
|
|
15838
|
+
}) })
|
|
15609
15839
|
] });
|
|
15610
15840
|
}
|
|
15611
|
-
function ColorPairingToolContent() {
|
|
15841
|
+
function ColorPairingToolContent({ visibleFormats }) {
|
|
15612
15842
|
const searchParams = navigation.useSearchParams();
|
|
15613
|
-
const
|
|
15614
|
-
|
|
15615
|
-
|
|
15616
|
-
|
|
15617
|
-
|
|
15618
|
-
|
|
15619
|
-
const
|
|
15620
|
-
const [format, setFormat] = React5.useState("hex");
|
|
15621
|
-
const [activeFamilyKey, setActiveFamilyKey] = React5.useState(initialFamilyKey);
|
|
15843
|
+
const [initialState] = React5.useState(() => getInitialPairingState(searchParams));
|
|
15844
|
+
const [themeCategory, setThemeCategory] = React5.useState(initialState.themeCategory);
|
|
15845
|
+
const [primaryFamilyKey, setPrimaryFamilyKey] = React5.useState(initialState.primaryKey);
|
|
15846
|
+
const [accentFamilyKey, setAccentFamilyKey] = React5.useState(initialState.accentKey);
|
|
15847
|
+
const [, copyShareLinkRaw] = usehooks.useCopyToClipboard();
|
|
15848
|
+
const [copiedShareLink, setCopiedShareLink] = React5.useState(false);
|
|
15849
|
+
const copiedShareLinkTimeoutRef = React5.useRef(null);
|
|
15622
15850
|
const [selectedBackgroundToken, setSelectedBackgroundToken] = React5.useState(
|
|
15623
|
-
|
|
15624
|
-
);
|
|
15625
|
-
const [selectedPairId, setSelectedPairId] = React5.useState(
|
|
15626
|
-
const
|
|
15627
|
-
const
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
const
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15851
|
+
initialState.selectedBackgroundToken
|
|
15852
|
+
);
|
|
15853
|
+
const [selectedPairId, setSelectedPairId] = React5.useState(initialState.selectedPairId);
|
|
15854
|
+
const themeFamilies = React5.useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
|
|
15855
|
+
const context = React5.useMemo(
|
|
15856
|
+
() => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
|
|
15857
|
+
[themeCategory, primaryFamilyKey, accentFamilyKey]
|
|
15858
|
+
);
|
|
15859
|
+
const selectableFamilies = React5.useMemo(
|
|
15860
|
+
() => themeFamilies.filter((family) => family.key !== context.grey.key),
|
|
15861
|
+
[themeFamilies, context.grey.key]
|
|
15862
|
+
);
|
|
15863
|
+
const selectableAccentFamilies = React5.useMemo(
|
|
15864
|
+
() => selectableFamilies.filter((family) => family.key !== context.primary.key),
|
|
15865
|
+
[selectableFamilies, context.primary.key]
|
|
15866
|
+
);
|
|
15867
|
+
const selectedBackground = React5.useMemo(
|
|
15868
|
+
() => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
|
|
15869
|
+
[context.backgrounds, selectedBackgroundToken]
|
|
15870
|
+
);
|
|
15871
|
+
const selectedBackgroundPairs = React5.useMemo(
|
|
15872
|
+
() => selectedBackground ? context.pairsByBackground[selectedBackground.token] ?? [] : [],
|
|
15873
|
+
[context.pairsByBackground, selectedBackground]
|
|
15874
|
+
);
|
|
15875
|
+
const selectedPair = React5.useMemo(
|
|
15876
|
+
() => getPreferredPairForBackground(selectedBackgroundPairs, selectedPairId),
|
|
15877
|
+
[selectedBackgroundPairs, selectedPairId]
|
|
15878
|
+
);
|
|
15879
|
+
const whiteForegroundExample = React5.useMemo(
|
|
15880
|
+
() => selectedBackground && supportsWhiteForegroundPreview(selectedBackground) ? getWhiteForegroundPair(selectedBackground) : null,
|
|
15881
|
+
[selectedBackground]
|
|
15882
|
+
);
|
|
15883
|
+
const previewPair = selectedPair ?? whiteForegroundExample ?? null;
|
|
15635
15884
|
const detailForeground = selectedPair?.foreground ?? whiteForegroundExample?.foreground ?? null;
|
|
15636
|
-
const
|
|
15885
|
+
const familySummary = React5.useMemo(
|
|
15886
|
+
() => [context.primary.label, context.accent.label, context.grey.label].join(" + "),
|
|
15887
|
+
[context.primary.label, context.accent.label, context.grey.label]
|
|
15888
|
+
);
|
|
15889
|
+
React5.useEffect(() => {
|
|
15890
|
+
return () => {
|
|
15891
|
+
if (copiedShareLinkTimeoutRef.current) {
|
|
15892
|
+
clearTimeout(copiedShareLinkTimeoutRef.current);
|
|
15893
|
+
}
|
|
15894
|
+
};
|
|
15895
|
+
}, []);
|
|
15896
|
+
const updateUrlParams = (nextThemeCategory, nextPrimaryKey, nextAccentKey, nextSelectedBackgroundToken, nextSelectedPairId) => {
|
|
15637
15897
|
const params = new URLSearchParams(window.location.search);
|
|
15898
|
+
params.delete("family");
|
|
15638
15899
|
params.set("palette", nextThemeCategory);
|
|
15639
|
-
params.set("
|
|
15900
|
+
params.set("primary", nextPrimaryKey);
|
|
15901
|
+
params.set("accent", nextAccentKey);
|
|
15640
15902
|
params.set("background", nextSelectedBackgroundToken);
|
|
15641
15903
|
if (nextSelectedPairId) {
|
|
15642
15904
|
params.set("pair", nextSelectedPairId);
|
|
@@ -15649,294 +15911,450 @@ function ColorPairingToolContent() {
|
|
|
15649
15911
|
`${window.location.pathname}?${params.toString()}${window.location.hash}`
|
|
15650
15912
|
);
|
|
15651
15913
|
};
|
|
15652
|
-
const
|
|
15653
|
-
const
|
|
15654
|
-
const
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
getToneFromToken(selectedBackgroundToken)
|
|
15659
|
-
);
|
|
15660
|
-
const nextSelectedPair = getRecommendedPairForBackground(
|
|
15661
|
-
nextActiveFamily,
|
|
15662
|
-
nextSelectedBackgroundToken,
|
|
15663
|
-
selectedPairId
|
|
15914
|
+
const syncSelection = (nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) => {
|
|
15915
|
+
const nextContext = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
|
|
15916
|
+
const nextSelectedBackgroundToken = resolveBackgroundToken(
|
|
15917
|
+
nextContext,
|
|
15918
|
+
preferredBackgroundToken,
|
|
15919
|
+
getToneFromToken(preferredBackgroundToken)
|
|
15664
15920
|
);
|
|
15921
|
+
const nextSelectedPairId = getPreferredPairForBackground(
|
|
15922
|
+
nextContext.pairsByBackground[nextSelectedBackgroundToken] ?? [],
|
|
15923
|
+
preferredPairId
|
|
15924
|
+
)?.id ?? "";
|
|
15665
15925
|
setThemeCategory(nextThemeCategory);
|
|
15666
|
-
|
|
15926
|
+
setPrimaryFamilyKey(nextContext.primary.key);
|
|
15927
|
+
setAccentFamilyKey(nextContext.accent.key);
|
|
15667
15928
|
setSelectedBackgroundToken(nextSelectedBackgroundToken);
|
|
15668
|
-
setSelectedPairId(
|
|
15929
|
+
setSelectedPairId(nextSelectedPairId);
|
|
15669
15930
|
updateUrlParams(
|
|
15670
15931
|
nextThemeCategory,
|
|
15671
|
-
|
|
15932
|
+
nextContext.primary.key,
|
|
15933
|
+
nextContext.accent.key,
|
|
15672
15934
|
nextSelectedBackgroundToken,
|
|
15673
|
-
|
|
15935
|
+
nextSelectedPairId
|
|
15674
15936
|
);
|
|
15675
15937
|
};
|
|
15676
|
-
const
|
|
15677
|
-
|
|
15678
|
-
|
|
15679
|
-
|
|
15680
|
-
|
|
15938
|
+
const handleThemeCategoryChange = (nextThemeCategory) => {
|
|
15939
|
+
syncSelection(
|
|
15940
|
+
nextThemeCategory,
|
|
15941
|
+
primaryFamilyKey,
|
|
15942
|
+
accentFamilyKey,
|
|
15943
|
+
selectedBackgroundToken,
|
|
15944
|
+
selectedPairId
|
|
15681
15945
|
);
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15946
|
+
};
|
|
15947
|
+
const handlePrimaryColorChange = (nextPrimaryKey) => {
|
|
15948
|
+
const nextAccentKey = nextPrimaryKey === accentFamilyKey ? getDefaultAccentFamilyKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
|
|
15949
|
+
syncSelection(
|
|
15950
|
+
themeCategory,
|
|
15951
|
+
nextPrimaryKey,
|
|
15952
|
+
nextAccentKey,
|
|
15953
|
+
selectedBackgroundToken,
|
|
15685
15954
|
selectedPairId
|
|
15686
15955
|
);
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15690
|
-
|
|
15956
|
+
};
|
|
15957
|
+
const handleAccentColorChange = (nextAccentKey) => {
|
|
15958
|
+
if (nextAccentKey === primaryFamilyKey) return;
|
|
15959
|
+
syncSelection(
|
|
15691
15960
|
themeCategory,
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15961
|
+
primaryFamilyKey,
|
|
15962
|
+
nextAccentKey,
|
|
15963
|
+
selectedBackgroundToken,
|
|
15964
|
+
selectedPairId
|
|
15695
15965
|
);
|
|
15696
15966
|
};
|
|
15697
15967
|
const handleBackgroundChange = (nextSelectedBackgroundToken) => {
|
|
15698
|
-
const
|
|
15699
|
-
|
|
15700
|
-
nextSelectedBackgroundToken,
|
|
15968
|
+
const nextSelectedPairId = getPreferredPairForBackground(
|
|
15969
|
+
context.pairsByBackground[nextSelectedBackgroundToken] ?? [],
|
|
15701
15970
|
selectedPairId
|
|
15702
|
-
);
|
|
15971
|
+
)?.id ?? "";
|
|
15703
15972
|
setSelectedBackgroundToken(nextSelectedBackgroundToken);
|
|
15704
|
-
setSelectedPairId(
|
|
15973
|
+
setSelectedPairId(nextSelectedPairId);
|
|
15705
15974
|
updateUrlParams(
|
|
15706
15975
|
themeCategory,
|
|
15707
|
-
|
|
15976
|
+
context.primary.key,
|
|
15977
|
+
context.accent.key,
|
|
15708
15978
|
nextSelectedBackgroundToken,
|
|
15709
|
-
|
|
15979
|
+
nextSelectedPairId
|
|
15710
15980
|
);
|
|
15711
15981
|
};
|
|
15712
15982
|
const handlePairChange = (nextSelectedPairId) => {
|
|
15713
|
-
const nextSelectedPair =
|
|
15714
|
-
if (!nextSelectedPair) return;
|
|
15715
|
-
setSelectedBackgroundToken(nextSelectedPair.background.token);
|
|
15983
|
+
const nextSelectedPair = selectedBackgroundPairs.find((pair) => pair.id === nextSelectedPairId);
|
|
15984
|
+
if (!nextSelectedPair || !selectedBackground) return;
|
|
15716
15985
|
setSelectedPairId(nextSelectedPairId);
|
|
15717
15986
|
updateUrlParams(
|
|
15718
15987
|
themeCategory,
|
|
15719
|
-
|
|
15720
|
-
|
|
15988
|
+
context.primary.key,
|
|
15989
|
+
context.accent.key,
|
|
15990
|
+
selectedBackground.token,
|
|
15721
15991
|
nextSelectedPairId
|
|
15722
15992
|
);
|
|
15723
15993
|
};
|
|
15724
|
-
if (!
|
|
15994
|
+
if (!selectedBackground) {
|
|
15725
15995
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { children: [
|
|
15726
15996
|
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: "No approved background tones available" }),
|
|
15727
15997
|
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "No approved tones are available for the current palette." })
|
|
15728
15998
|
] }) });
|
|
15729
15999
|
}
|
|
15730
|
-
|
|
15731
|
-
|
|
15732
|
-
|
|
15733
|
-
|
|
16000
|
+
const handleCopyShareLink = () => {
|
|
16001
|
+
copyShareLinkRaw(window.location.href);
|
|
16002
|
+
setCopiedShareLink(true);
|
|
16003
|
+
sonner.toast("Colour pairing link copied to clipboard", {
|
|
16004
|
+
duration: 2e3
|
|
16005
|
+
});
|
|
16006
|
+
if (copiedShareLinkTimeoutRef.current) {
|
|
16007
|
+
clearTimeout(copiedShareLinkTimeoutRef.current);
|
|
16008
|
+
}
|
|
16009
|
+
copiedShareLinkTimeoutRef.current = setTimeout(() => {
|
|
16010
|
+
setCopiedShareLink(false);
|
|
16011
|
+
copiedShareLinkTimeoutRef.current = null;
|
|
16012
|
+
}, 2e3);
|
|
16013
|
+
};
|
|
16014
|
+
const activePaletteEntries = [
|
|
16015
|
+
{
|
|
16016
|
+
key: `primary-${context.primary.key}`,
|
|
16017
|
+
label: "Primary",
|
|
16018
|
+
family: context.primary,
|
|
16019
|
+
familyLabel: getActivePaletteFamilyLabel(context.primary, themeCategory, "primary"),
|
|
16020
|
+
swatchTone: 800
|
|
16021
|
+
},
|
|
16022
|
+
{
|
|
16023
|
+
key: `accent-${context.accent.key}`,
|
|
16024
|
+
label: "Accent",
|
|
16025
|
+
family: context.accent,
|
|
16026
|
+
familyLabel: getActivePaletteFamilyLabel(context.accent, themeCategory, "accent"),
|
|
16027
|
+
swatchTone: 600
|
|
16028
|
+
},
|
|
16029
|
+
{
|
|
16030
|
+
key: `grey-${context.grey.key}`,
|
|
16031
|
+
label: "Grey",
|
|
16032
|
+
family: context.grey,
|
|
16033
|
+
familyLabel: getActivePaletteFamilyLabel(context.grey, themeCategory, "grey"),
|
|
16034
|
+
swatchTone: 800
|
|
16035
|
+
}
|
|
16036
|
+
];
|
|
16037
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-8", children: [
|
|
16038
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
16039
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16040
|
+
WorkflowStep,
|
|
16041
|
+
{
|
|
16042
|
+
step: 1,
|
|
16043
|
+
title: "Select your palette",
|
|
16044
|
+
description: "Choose the palette family you want to work from.",
|
|
16045
|
+
level: 2
|
|
16046
|
+
}
|
|
16047
|
+
),
|
|
16048
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
16049
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
16050
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Palette:" }),
|
|
16051
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16052
|
+
SegmentedControl,
|
|
16053
|
+
{
|
|
16054
|
+
value: themeCategory,
|
|
16055
|
+
onValueChange: (value) => handleThemeCategoryChange(value),
|
|
16056
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(SegmentedControlList, { className: "w-full sm:w-fit", children: [
|
|
16057
|
+
/* @__PURE__ */ jsxRuntime.jsx(SegmentedControlTrigger, { value: "brand", children: "Brand palette" }),
|
|
16058
|
+
/* @__PURE__ */ jsxRuntime.jsx(SegmentedControlTrigger, { value: "aboriginal", children: "Aboriginal palette" })
|
|
16059
|
+
] })
|
|
16060
|
+
}
|
|
16061
|
+
)
|
|
16062
|
+
] }),
|
|
16063
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "outline", size: "sm", onClick: handleCopyShareLink, children: [
|
|
16064
|
+
copiedShareLink ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-4" }),
|
|
16065
|
+
copiedShareLink ? "Link copied" : "Copy link"
|
|
16066
|
+
] }) })
|
|
16067
|
+
] })
|
|
16068
|
+
] }),
|
|
16069
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
16070
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16071
|
+
WorkflowStep,
|
|
16072
|
+
{
|
|
16073
|
+
step: 2,
|
|
16074
|
+
title: "Choose your colours",
|
|
16075
|
+
description: "Pick a primary and accent colour. Grey is added automatically.",
|
|
16076
|
+
level: 2
|
|
16077
|
+
}
|
|
16078
|
+
),
|
|
16079
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6", children: [
|
|
15734
16080
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15735
|
-
|
|
16081
|
+
ColorFamilySelector,
|
|
15736
16082
|
{
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
16083
|
+
label: "Primary colour",
|
|
16084
|
+
families: selectableFamilies,
|
|
16085
|
+
selectedKey: context.primary.key,
|
|
16086
|
+
selectionRole: "primary colour",
|
|
16087
|
+
themeCategory,
|
|
16088
|
+
onSelect: handlePrimaryColorChange
|
|
16089
|
+
}
|
|
16090
|
+
),
|
|
16091
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16092
|
+
ColorFamilySelector,
|
|
16093
|
+
{
|
|
16094
|
+
label: "Accent colour",
|
|
16095
|
+
families: selectableAccentFamilies,
|
|
16096
|
+
selectedKey: context.accent.key,
|
|
16097
|
+
selectionRole: "accent colour",
|
|
16098
|
+
themeCategory,
|
|
16099
|
+
onSelect: handleAccentColorChange
|
|
15743
16100
|
}
|
|
15744
16101
|
)
|
|
15745
|
-
] })
|
|
15746
|
-
/* @__PURE__ */ jsxRuntime.jsx(FormatToggle, { format, setFormat })
|
|
16102
|
+
] })
|
|
15747
16103
|
] }),
|
|
15748
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
"
|
|
16104
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-sm border border-grey-200 bg-grey-50 px-4 py-4 dark:border-grey-700 dark:bg-grey-900/40", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
16105
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.14em] text-foreground uppercase", children: "Active palette" }),
|
|
16106
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 text-sm text-foreground", children: activePaletteEntries.map(({ family, familyLabel, key, label, swatchTone }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16107
|
+
"span",
|
|
15752
16108
|
{
|
|
15753
|
-
|
|
15754
|
-
onClick: () => handleFamilyChange(family.key),
|
|
15755
|
-
className: cn(
|
|
15756
|
-
"group relative flex w-full items-center gap-3 rounded-sm border px-3 py-2 text-left transition-colors",
|
|
15757
|
-
"border-grey-200 bg-background hover:bg-primary-800/10 hover:text-foreground dark:hover:bg-white/10",
|
|
15758
|
-
isActive && "border-grey-800 dark:border-grey-400"
|
|
15759
|
-
),
|
|
16109
|
+
className: "inline-flex items-center gap-2 rounded-sm border border-grey-200 bg-background px-3 py-2 dark:border-grey-700",
|
|
15760
16110
|
children: [
|
|
15761
16111
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15762
16112
|
"span",
|
|
15763
16113
|
{
|
|
15764
|
-
className: "size-
|
|
15765
|
-
style: { backgroundColor: getFamilySwatchColor(family) }
|
|
16114
|
+
className: "size-2.5 rounded-full",
|
|
16115
|
+
style: { backgroundColor: getFamilySwatchColor(family, swatchTone) }
|
|
15766
16116
|
}
|
|
15767
16117
|
),
|
|
15768
|
-
/* @__PURE__ */ jsxRuntime.
|
|
16118
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
16119
|
+
label,
|
|
16120
|
+
":"
|
|
16121
|
+
] }),
|
|
16122
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: familyLabel })
|
|
15769
16123
|
]
|
|
15770
16124
|
},
|
|
15771
|
-
|
|
15772
|
-
)
|
|
15773
|
-
|
|
15774
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15775
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
15776
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
|
|
15784
|
-
|
|
15785
|
-
|
|
15786
|
-
|
|
15787
|
-
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
|
|
15802
|
-
|
|
15803
|
-
|
|
15804
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
15805
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2 rounded-full bg-current/10 px-4 py-2 text-sm font-semibold", children: [
|
|
15806
|
-
"No recommendation",
|
|
15807
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icons.info, { "data-slot": "icon", className: "size-4" })
|
|
15808
|
-
] }),
|
|
15809
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex rounded-full border border-current px-4 py-2 text-sm", children: selectedBackground.token })
|
|
16125
|
+
key
|
|
16126
|
+
)) })
|
|
16127
|
+
] }) }),
|
|
16128
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid items-start gap-6 xl:grid-cols-[minmax(0,1.5fr)_minmax(18rem,0.72fr)]", children: [
|
|
16129
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
16130
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
|
|
16131
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-4 border-b", children: [
|
|
16132
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16133
|
+
WorkflowStep,
|
|
16134
|
+
{
|
|
16135
|
+
step: 3,
|
|
16136
|
+
title: "Pick a background",
|
|
16137
|
+
description: "Select an approved background tone from your primary, accent, or grey families.",
|
|
16138
|
+
level: 3,
|
|
16139
|
+
variant: "card"
|
|
16140
|
+
}
|
|
16141
|
+
),
|
|
16142
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "The centre dot shows the recommended foreground colour. A white slash means there is no recommended AAA foreground in this tool." })
|
|
16143
|
+
] }),
|
|
16144
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-5", children: [
|
|
16145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 rounded-sm border border-grey-200 bg-grey-50 p-4 sm:grid-cols-2 dark:border-grey-700 dark:bg-grey-900/40", children: [
|
|
16146
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 rounded-sm border border-grey-200 bg-background px-3 py-3 dark:border-grey-700", children: [
|
|
16147
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative block size-8 rounded-[4px] border border-grey-400 bg-background dark:border-grey-500", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-1/2 left-1/2 size-2.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-grey-800 dark:bg-grey-100" }) }),
|
|
16148
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
16149
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: "Recommended foreground available" }),
|
|
16150
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "The centre dot marks the recommended foreground colour." })
|
|
16151
|
+
] })
|
|
16152
|
+
] }),
|
|
16153
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 rounded-sm border border-dashed border-grey-300 bg-background px-3 py-3 dark:border-grey-600", children: [
|
|
16154
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative block size-8 rounded-[4px] border-2 border-dashed border-grey-400 bg-grey-500 dark:border-grey-500 dark:bg-grey-700", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-1/2 left-1/2 h-0.5 w-5 -translate-x-1/2 -translate-y-1/2 rotate-45 rounded-full bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.28)]" }) }),
|
|
16155
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
16156
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: "No recommended AAA foreground" }),
|
|
16157
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "A white slash marks swatches that do not currently have a recommended AAA foreground in this tool." })
|
|
15810
16158
|
] })
|
|
15811
16159
|
] })
|
|
15812
|
-
}
|
|
15813
|
-
) }),
|
|
15814
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
|
|
15815
|
-
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-2 border-b", children: [
|
|
15816
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: "Background tone strip" }),
|
|
15817
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "Only approved background tones are shown. Filled chips have a recommended AAA foreground pair, and dark backgrounds may also offer white text where it passes AAA." })
|
|
15818
16160
|
] }),
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
"button",
|
|
15826
|
-
{
|
|
15827
|
-
type: "button",
|
|
15828
|
-
onClick: () => handleBackgroundChange(color2.token),
|
|
15829
|
-
className: cn(
|
|
15830
|
-
"group relative h-12 rounded-sm border border-grey-200 transition-transform hover:scale-[1.03] dark:border-grey-700",
|
|
15831
|
-
isSelected && "ring-2 ring-primary-500 ring-offset-2 ring-offset-background"
|
|
15832
|
-
),
|
|
15833
|
-
style: { backgroundColor: color2.hex },
|
|
15834
|
-
children: [
|
|
15835
|
-
pair ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
15836
|
-
"span",
|
|
15837
|
-
{
|
|
15838
|
-
className: "absolute top-1/2 left-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full border border-white/30 shadow-sm",
|
|
15839
|
-
style: { backgroundColor: pair.foreground.hex }
|
|
15840
|
-
}
|
|
15841
|
-
) : null,
|
|
15842
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
15843
|
-
color2.token,
|
|
15844
|
-
pair ? ` paired with ${pair.foreground.token}` : hasWhiteExample ? " has a white text example in this tool" : " has no recommended pair in this tool"
|
|
15845
|
-
] })
|
|
15846
|
-
]
|
|
15847
|
-
},
|
|
15848
|
-
color2.token
|
|
15849
|
-
);
|
|
15850
|
-
}) }),
|
|
15851
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground", children: [
|
|
15852
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
15853
|
-
"Selected background:",
|
|
15854
|
-
" ",
|
|
15855
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-foreground", children: selectedBackground.token })
|
|
16161
|
+
context.backgroundGroups.map((group) => {
|
|
16162
|
+
const groupFamilyLabel = selectedBackground.familyKey === group.family.key ? selectedBackground.name ?? selectedBackground.token : group.family.label;
|
|
16163
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
16164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 text-sm", children: [
|
|
16165
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: group.label }),
|
|
16166
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: groupFamilyLabel })
|
|
15856
16167
|
] }),
|
|
15857
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15858
|
-
|
|
15859
|
-
|
|
15860
|
-
|
|
15861
|
-
|
|
16168
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-3 gap-2 sm:grid-cols-6", children: group.backgrounds.map((background) => {
|
|
16169
|
+
const pairs = context.pairsByBackground[background.token] ?? [];
|
|
16170
|
+
const hasRecommendedForeground = pairs.length > 0;
|
|
16171
|
+
const preferredPair = selectedBackground.token === background.token ? selectedPair ?? getPreferredPairForBackground(pairs) : getPreferredPairForBackground(pairs);
|
|
16172
|
+
const hasWhiteExample = supportsWhiteForegroundPreview(background);
|
|
16173
|
+
const isSelected = selectedBackground.token === background.token;
|
|
16174
|
+
const ariaLabel = pairs.length > 0 ? `Select ${background.token} background, recommended with ${preferredPair?.foreground.token ?? "an AAA foreground"}` : hasWhiteExample ? `Select ${background.token} background, white text example available` : `Select ${background.token} background, no recommended foreground in this tool`;
|
|
16175
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16176
|
+
"button",
|
|
16177
|
+
{
|
|
16178
|
+
type: "button",
|
|
16179
|
+
"aria-label": ariaLabel,
|
|
16180
|
+
"aria-pressed": isSelected,
|
|
16181
|
+
onClick: () => handleBackgroundChange(background.token),
|
|
16182
|
+
className: cn(
|
|
16183
|
+
"group relative h-12 rounded-sm border transition-all",
|
|
16184
|
+
hasRecommendedForeground && "border-grey-200 hover:scale-[1.03] hover:shadow-sm dark:border-grey-700",
|
|
16185
|
+
!hasRecommendedForeground && hasWhiteExample && "border-grey-300/80 hover:scale-[1.01] dark:border-grey-600/80",
|
|
16186
|
+
!hasRecommendedForeground && !hasWhiteExample && "border-dashed border-grey-300/70 hover:scale-[1.01] dark:border-grey-600/70",
|
|
16187
|
+
isSelected && "ring-2 ring-primary-500 ring-offset-2 ring-offset-background"
|
|
16188
|
+
),
|
|
16189
|
+
style: { backgroundColor: background.hex },
|
|
16190
|
+
children: [
|
|
16191
|
+
preferredPair ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16192
|
+
"span",
|
|
16193
|
+
{
|
|
16194
|
+
className: "absolute top-1/2 left-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full border border-white/30 shadow-sm",
|
|
16195
|
+
style: { backgroundColor: preferredPair.foreground.hex }
|
|
16196
|
+
}
|
|
16197
|
+
) : null,
|
|
16198
|
+
!hasRecommendedForeground ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-1/2 left-1/2 h-0.5 w-6 -translate-x-1/2 -translate-y-1/2 rotate-45 rounded-full bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.28)]" }) : null
|
|
16199
|
+
]
|
|
16200
|
+
},
|
|
16201
|
+
background.token
|
|
16202
|
+
);
|
|
16203
|
+
}) })
|
|
16204
|
+
] }, group.key);
|
|
16205
|
+
}),
|
|
16206
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground", children: [
|
|
16207
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
16208
|
+
"Selected background:",
|
|
16209
|
+
" ",
|
|
16210
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-foreground", children: selectedBackground.token })
|
|
16211
|
+
] }),
|
|
16212
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
16213
|
+
selectedPair ? "Selected foreground:" : "White text example:",
|
|
16214
|
+
" ",
|
|
16215
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-foreground", children: selectedPair?.foreground.token ?? whiteForegroundExample?.foreground.token ?? "None" })
|
|
15862
16216
|
] })
|
|
15863
16217
|
] })
|
|
15864
|
-
] }),
|
|
15865
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
|
|
15866
|
-
/* @__PURE__ */ jsxRuntime.jsx(PairDetailCard, { color: selectedBackground, format, role: "Background" }),
|
|
15867
|
-
detailForeground ? /* @__PURE__ */ jsxRuntime.jsx(PairDetailCard, { color: detailForeground, format, role: "Foreground" }) : /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-4", children: [
|
|
15868
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardHeader, { className: "gap-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
15869
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: "Foreground" }),
|
|
15870
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "No recommended foreground available" })
|
|
15871
|
-
] }) }),
|
|
15872
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Select another approved tone or review the recommended pairs list for the same family." }) })
|
|
15873
|
-
] })
|
|
15874
16218
|
] })
|
|
15875
16219
|
] }),
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
|
|
15881
|
-
|
|
15882
|
-
|
|
15883
|
-
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
16220
|
+
previewPair ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16221
|
+
PairPreview,
|
|
16222
|
+
{
|
|
16223
|
+
familySummary,
|
|
16224
|
+
isRecommended: Boolean(selectedPair),
|
|
16225
|
+
pair: previewPair
|
|
16226
|
+
}
|
|
16227
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
16228
|
+
PreviewFallbackCard,
|
|
16229
|
+
{
|
|
16230
|
+
familySummary,
|
|
16231
|
+
selectedBackground
|
|
16232
|
+
}
|
|
16233
|
+
),
|
|
16234
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
|
|
16235
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16236
|
+
PairDetailCard,
|
|
16237
|
+
{
|
|
16238
|
+
color: selectedBackground,
|
|
16239
|
+
role: "Background",
|
|
16240
|
+
visibleFormats
|
|
16241
|
+
}
|
|
16242
|
+
),
|
|
16243
|
+
detailForeground ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16244
|
+
PairDetailCard,
|
|
16245
|
+
{
|
|
16246
|
+
color: detailForeground,
|
|
16247
|
+
role: "Foreground",
|
|
16248
|
+
visibleFormats
|
|
16249
|
+
}
|
|
16250
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-4", children: [
|
|
16251
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardHeader, { className: "gap-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
16252
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: "Foreground" }),
|
|
16253
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "No recommended foreground available" })
|
|
16254
|
+
] }) }),
|
|
16255
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Select another approved tone or review the recommended foregrounds for the same background." }) })
|
|
16256
|
+
] })
|
|
16257
|
+
] }),
|
|
16258
|
+
previewPair ? /* @__PURE__ */ jsxRuntime.jsx(PairComplianceCard, { pair: previewPair }) : null
|
|
16259
|
+
] }),
|
|
16260
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "h-fit", children: [
|
|
16261
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-4 border-b", children: [
|
|
16262
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16263
|
+
WorkflowStep,
|
|
16264
|
+
{
|
|
16265
|
+
step: 4,
|
|
16266
|
+
title: "Choose a foreground",
|
|
16267
|
+
description: `Review the AAA combinations available for ${selectedBackground.token}.`,
|
|
16268
|
+
level: 3,
|
|
16269
|
+
variant: "card"
|
|
16270
|
+
}
|
|
16271
|
+
),
|
|
16272
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardDescription, { children: [
|
|
16273
|
+
"Recommended foregrounds are drawn from ",
|
|
16274
|
+
context.primary.label,
|
|
16275
|
+
",",
|
|
16276
|
+
" ",
|
|
16277
|
+
context.accent.label,
|
|
16278
|
+
", Grey, and white where it meets AAA."
|
|
16279
|
+
] })
|
|
16280
|
+
] }),
|
|
16281
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "grid gap-3", children: selectedBackgroundPairs.length > 0 ? selectedBackgroundPairs.map((pair) => {
|
|
16282
|
+
const isActive = selectedPair?.id === pair.id;
|
|
16283
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16284
|
+
"button",
|
|
16285
|
+
{
|
|
16286
|
+
type: "button",
|
|
16287
|
+
"aria-label": `Use ${getPairingColorDisplayName(pair.foreground)} on ${getPairingColorDisplayName(pair.background)}`,
|
|
16288
|
+
"aria-pressed": isActive,
|
|
16289
|
+
onClick: () => handlePairChange(pair.id),
|
|
16290
|
+
className: cn(
|
|
16291
|
+
"rounded-sm border p-4 text-left transition-colors",
|
|
16292
|
+
isActive ? "border-primary-500 bg-primary-50/70 dark:bg-primary-950/30" : "border-grey-200 hover:border-grey-400 hover:bg-grey-50 dark:border-grey-700 dark:hover:border-grey-500 dark:hover:bg-grey-900/70"
|
|
16293
|
+
),
|
|
16294
|
+
children: [
|
|
16295
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
16296
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
16297
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 text-[0.65rem] font-semibold tracking-[0.14em] text-muted-foreground uppercase", children: [
|
|
16298
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-11 text-center", children: "BG" }),
|
|
16299
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-11 text-center", children: "FG" })
|
|
16300
|
+
] }),
|
|
16301
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
15895
16302
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15896
16303
|
"div",
|
|
15897
16304
|
{
|
|
15898
16305
|
className: "size-11 rounded-sm border border-grey-200 shadow-sm dark:border-grey-700",
|
|
15899
|
-
style: {
|
|
16306
|
+
style: {
|
|
16307
|
+
backgroundColor: pair.background.hex
|
|
16308
|
+
}
|
|
15900
16309
|
}
|
|
15901
16310
|
),
|
|
15902
16311
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15903
16312
|
"div",
|
|
15904
16313
|
{
|
|
15905
16314
|
className: "size-11 rounded-sm border border-grey-200 shadow-sm dark:border-grey-700",
|
|
15906
|
-
style: {
|
|
16315
|
+
style: {
|
|
16316
|
+
backgroundColor: pair.foreground.hex
|
|
16317
|
+
}
|
|
15907
16318
|
}
|
|
15908
16319
|
)
|
|
15909
|
-
] }),
|
|
15910
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-grey-200 px-2.5 py-1 text-xs font-semibold text-muted-foreground dark:border-grey-700", children: [
|
|
15911
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icons.contrast, { "data-slot": "icon", className: "size-4" }),
|
|
15912
|
-
pair.rating
|
|
15913
16320
|
] })
|
|
15914
16321
|
] }),
|
|
15915
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
15916
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15917
|
-
|
|
15918
|
-
" / ",
|
|
15919
|
-
pair.foreground.token
|
|
15920
|
-
] }),
|
|
15921
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
15922
|
-
pair.contrastRatio.toFixed(2),
|
|
15923
|
-
":1 contrast ratio"
|
|
15924
|
-
] })
|
|
16322
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-success-200 bg-success-50 px-2.5 py-1 text-xs font-semibold text-success-800 dark:border-success-900/60 dark:bg-success-950/20 dark:text-success-200", children: [
|
|
16323
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.contrast, { "data-slot": "icon", className: "size-4" }),
|
|
16324
|
+
pair.rating
|
|
15925
16325
|
] })
|
|
15926
|
-
]
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
15935
|
-
|
|
16326
|
+
] }),
|
|
16327
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 space-y-1", children: [
|
|
16328
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "font-medium text-foreground", children: [
|
|
16329
|
+
getPairingColorDisplayName(pair.background),
|
|
16330
|
+
" /",
|
|
16331
|
+
" ",
|
|
16332
|
+
getPairingColorDisplayName(pair.foreground)
|
|
16333
|
+
] }),
|
|
16334
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
16335
|
+
pair.foreground.familyLabel,
|
|
16336
|
+
" on ",
|
|
16337
|
+
pair.background.familyLabel
|
|
16338
|
+
] }),
|
|
16339
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
16340
|
+
pair.contrastRatio.toFixed(2),
|
|
16341
|
+
":1 contrast ratio"
|
|
16342
|
+
] })
|
|
16343
|
+
] })
|
|
16344
|
+
]
|
|
16345
|
+
},
|
|
16346
|
+
pair.id
|
|
16347
|
+
);
|
|
16348
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-sm border border-grey-200 p-4 text-sm text-muted-foreground dark:border-grey-700", children: "No recommended AAA foregrounds are available for this background." }) })
|
|
16349
|
+
] }) })
|
|
16350
|
+
] }) })
|
|
15936
16351
|
] });
|
|
15937
16352
|
}
|
|
15938
|
-
function ColorPairingTool(
|
|
15939
|
-
|
|
16353
|
+
function ColorPairingTool({
|
|
16354
|
+
visibleFormats = DEFAULT_VISIBLE_FORMATS
|
|
16355
|
+
} = {}) {
|
|
16356
|
+
const normalizedVisibleFormats = [...new Set(visibleFormats)];
|
|
16357
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolLoading, {}), children: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolContent, { visibleFormats: normalizedVisibleFormats }) });
|
|
15940
16358
|
}
|
|
15941
16359
|
function ColorSwatches({ theme: theme2, format, viewMode }) {
|
|
15942
16360
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -18417,93 +18835,152 @@ function FormMessage({ className, ...props }) {
|
|
|
18417
18835
|
}
|
|
18418
18836
|
);
|
|
18419
18837
|
}
|
|
18420
|
-
|
|
18421
|
-
|
|
18422
|
-
|
|
18423
|
-
|
|
18424
|
-
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18838
|
+
var styles3 = {
|
|
18839
|
+
base: [
|
|
18840
|
+
// Base
|
|
18841
|
+
"inline-flex items-center justify-center gap-2 rounded-sm text-sm font-medium bg-transparent transition-all whitespace-nowrap cursor-pointer border-(--toggle-border) [--toggle-border:var(--color-grey-200)] text-grey-800",
|
|
18842
|
+
// States
|
|
18843
|
+
"data-[state=on]:bg-grey-100 data-[state=on]:text-grey-850",
|
|
18844
|
+
// Hover
|
|
18845
|
+
"hover:bg-grey-100 hover:text-grey-850",
|
|
18846
|
+
// Focus
|
|
18847
|
+
"focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-(--toggle-border)",
|
|
18848
|
+
// Dark mode
|
|
18849
|
+
"dark:text-white",
|
|
18850
|
+
// Dark mode states
|
|
18851
|
+
"dark:data-[state=on]:bg-white/10 dark:data-[state=on]:text-white",
|
|
18852
|
+
// Dark mode hover
|
|
18853
|
+
"dark:hover:bg-white/10 dark:hover:text-white",
|
|
18854
|
+
// Disabled
|
|
18855
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
18856
|
+
// Icon
|
|
18857
|
+
'[&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 [&_svg]:shrink-0',
|
|
18858
|
+
// Aria invalid
|
|
18859
|
+
"aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
|
|
18860
|
+
// Aria invalid dark mode
|
|
18861
|
+
"dark:aria-invalid:ring-destructive/40"
|
|
18862
|
+
],
|
|
18863
|
+
outline: [
|
|
18864
|
+
// Base
|
|
18865
|
+
"text-grey-800 border [--toggle-border:var(--color-grey-300)]",
|
|
18866
|
+
// States
|
|
18867
|
+
"hover:[--toggle-border:var(--color-grey-400)]",
|
|
18868
|
+
// Dark mode
|
|
18869
|
+
"dark:[--toggle-border:white]/40",
|
|
18870
|
+
// Dark mode states
|
|
18871
|
+
"dark:hover:[--toggle-border:white]/50",
|
|
18872
|
+
// Data on
|
|
18873
|
+
"data-[state=on]:bg-primary-800/10"
|
|
18874
|
+
]
|
|
18875
|
+
};
|
|
18876
|
+
var toggleVariants = classVarianceAuthority.cva(styles3.base, {
|
|
18877
|
+
variants: {
|
|
18878
|
+
variant: {
|
|
18879
|
+
ghost: "",
|
|
18880
|
+
outline: clsx12__default.default(styles3.outline)
|
|
18881
|
+
},
|
|
18882
|
+
size: {
|
|
18883
|
+
default: "h-9 px-2 min-w-9",
|
|
18884
|
+
sm: "h-8 px-1.5 min-w-8",
|
|
18885
|
+
lg: "h-10 px-2.5 min-w-10"
|
|
18886
|
+
}
|
|
18887
|
+
},
|
|
18888
|
+
defaultVariants: {
|
|
18889
|
+
variant: "ghost",
|
|
18890
|
+
size: "default"
|
|
18432
18891
|
}
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18892
|
+
});
|
|
18893
|
+
function Toggle({
|
|
18894
|
+
className,
|
|
18895
|
+
variant,
|
|
18896
|
+
size,
|
|
18897
|
+
...props
|
|
18898
|
+
}) {
|
|
18899
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18900
|
+
TogglePrimitive__namespace.Root,
|
|
18901
|
+
{
|
|
18902
|
+
"data-slot": "toggle",
|
|
18903
|
+
className: cn(toggleVariants({ variant, size, className })),
|
|
18904
|
+
...props
|
|
18905
|
+
}
|
|
18906
|
+
);
|
|
18437
18907
|
}
|
|
18438
|
-
|
|
18908
|
+
var ToggleGroupContext = React5__namespace.createContext({
|
|
18909
|
+
size: "default",
|
|
18910
|
+
variant: "ghost"
|
|
18911
|
+
});
|
|
18912
|
+
function ToggleGroup({
|
|
18439
18913
|
className,
|
|
18440
|
-
|
|
18441
|
-
size
|
|
18442
|
-
level = 1,
|
|
18443
|
-
display = false,
|
|
18444
|
-
id: idProp,
|
|
18914
|
+
variant,
|
|
18915
|
+
size,
|
|
18445
18916
|
children,
|
|
18446
18917
|
...props
|
|
18447
18918
|
}) {
|
|
18448
|
-
const Tag = `h${level}`;
|
|
18449
|
-
const slugger = React5.useContext(SluggerContext);
|
|
18450
|
-
const headingSizeClasses = {
|
|
18451
|
-
1: "text-[calc(var(--heading-font-size-1)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-52)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
18452
|
-
2: "text-[calc(var(--heading-font-size-2)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-44)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
18453
|
-
3: "text-[calc(var(--heading-font-size-3)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-40)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
18454
|
-
4: "text-[calc(var(--heading-font-size-4)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-36)] tracking-[calc(var(--heading-letter-spacing-1)_+_var(--heading-letter-spacing))]",
|
|
18455
|
-
5: "text-[calc(var(--heading-font-size-5)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-32)] tracking-[calc(var(--heading-letter-spacing-1)_+_var(--heading-letter-spacing))]",
|
|
18456
|
-
6: "text-[calc(var(--heading-font-size-6)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-28)] tracking-[calc(var(--letter-spacing-0)_+_var(--heading-letter-spacing))]"
|
|
18457
|
-
};
|
|
18458
|
-
const displaySizeClasses = {
|
|
18459
|
-
1: "text-[calc(var(--display-font-size-1)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-96)] tracking-[calc(var(--heading-letter-spacing-3)_+_var(--heading-letter-spacing))]",
|
|
18460
|
-
2: "text-[calc(var(--display-font-size-2)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-60)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
18461
|
-
3: "text-[calc(var(--display-font-size-3)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-52)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
|
|
18462
|
-
4: "text-[calc(var(--display-font-size-4)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-44)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]"
|
|
18463
|
-
};
|
|
18464
|
-
const sizeClass = display ? displaySizeClasses[size] : headingSizeClasses[size];
|
|
18465
|
-
const trimClasses = {
|
|
18466
|
-
normal: ["before:content-none after:content-none"],
|
|
18467
|
-
start: [
|
|
18468
|
-
'before:content-[""] before:table after:content-none',
|
|
18469
|
-
"before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
18470
|
-
],
|
|
18471
|
-
end: [
|
|
18472
|
-
'before:content-none after:content-[""] after:table',
|
|
18473
|
-
"after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
18474
|
-
],
|
|
18475
|
-
both: [
|
|
18476
|
-
'before:content-[""] before:table after:content-[""] after:table',
|
|
18477
|
-
"before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]",
|
|
18478
|
-
"after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
|
|
18479
|
-
]
|
|
18480
|
-
};
|
|
18481
|
-
const computedId = React5.useMemo(() => {
|
|
18482
|
-
if (idProp) return idProp;
|
|
18483
|
-
const text = flattenText(children);
|
|
18484
|
-
if (!text) return void 0;
|
|
18485
|
-
const base = baseSlug(text);
|
|
18486
|
-
return slugger ? slugger.slug(base) : base;
|
|
18487
|
-
}, [idProp, children, slugger]);
|
|
18488
18919
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18489
|
-
|
|
18920
|
+
ToggleGroupPrimitive__namespace.Root,
|
|
18490
18921
|
{
|
|
18922
|
+
"data-slot": "toggle-group",
|
|
18923
|
+
"data-variant": variant,
|
|
18924
|
+
"data-size": size,
|
|
18925
|
+
className: cn(
|
|
18926
|
+
"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
|
|
18927
|
+
className
|
|
18928
|
+
),
|
|
18491
18929
|
...props,
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
|
|
18501
|
-
|
|
18930
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
|
|
18931
|
+
}
|
|
18932
|
+
);
|
|
18933
|
+
}
|
|
18934
|
+
function ToggleGroupItem({
|
|
18935
|
+
className,
|
|
18936
|
+
children,
|
|
18937
|
+
variant,
|
|
18938
|
+
size,
|
|
18939
|
+
...props
|
|
18940
|
+
}) {
|
|
18941
|
+
const context = React5__namespace.useContext(ToggleGroupContext);
|
|
18942
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18943
|
+
ToggleGroupPrimitive__namespace.Item,
|
|
18944
|
+
{
|
|
18945
|
+
"data-slot": "toggle-group-item",
|
|
18946
|
+
"data-variant": context.variant || variant,
|
|
18947
|
+
"data-size": context.size || size,
|
|
18948
|
+
className: cn(
|
|
18949
|
+
toggleVariants({
|
|
18950
|
+
variant: context.variant || variant,
|
|
18951
|
+
size: context.size || size
|
|
18952
|
+
}),
|
|
18953
|
+
"min-w-0 shrink-0 rounded-none shadow-none first:rounded-l-sm last:rounded-r-sm focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
|
|
18954
|
+
className
|
|
18502
18955
|
),
|
|
18956
|
+
...props,
|
|
18503
18957
|
children
|
|
18504
18958
|
}
|
|
18505
18959
|
);
|
|
18506
18960
|
}
|
|
18961
|
+
function FormatToggle({ format, setFormat }) {
|
|
18962
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
18963
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Format:" }),
|
|
18964
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18965
|
+
ToggleGroup,
|
|
18966
|
+
{
|
|
18967
|
+
type: "single",
|
|
18968
|
+
value: format,
|
|
18969
|
+
onValueChange: (value) => value && setFormat(value),
|
|
18970
|
+
children: [
|
|
18971
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hex", "aria-label": "HEX format", children: "HEX" }),
|
|
18972
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "rgb", "aria-label": "RGB format", children: "RGB" }),
|
|
18973
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hsl", "aria-label": "HSL format", children: "HSL" }),
|
|
18974
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "oklch", "aria-label": "OKLCH format", children: "OKLCH" })
|
|
18975
|
+
]
|
|
18976
|
+
}
|
|
18977
|
+
)
|
|
18978
|
+
] });
|
|
18979
|
+
}
|
|
18980
|
+
|
|
18981
|
+
// package.json
|
|
18982
|
+
var package_default = {
|
|
18983
|
+
version: "1.100.0"};
|
|
18507
18984
|
function Logo(props) {
|
|
18508
18985
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
18509
18986
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "NSW Government" }),
|