@nswds/app 1.97.15 → 1.98.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/index.cjs CHANGED
@@ -40,6 +40,8 @@ var LabelPrimitive = require('@radix-ui/react-label');
40
40
  var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
41
41
  var TabsPrimitives = require('@radix-ui/react-tabs');
42
42
  var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
43
+ var ToggleGroupPrimitive = require('@radix-ui/react-toggle-group');
44
+ var TogglePrimitive = require('@radix-ui/react-toggle');
43
45
  var cmdk = require('cmdk');
44
46
  var DialogPrimitive = require('@radix-ui/react-dialog');
45
47
  var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
@@ -47,8 +49,6 @@ var reactTable = require('@tanstack/react-table');
47
49
  var SeparatorPrimitive = require('@radix-ui/react-separator');
48
50
  var vaul = require('vaul');
49
51
  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);
113
115
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
114
116
  var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
115
117
  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);
@@ -14972,6 +14972,734 @@ function ColorCard({ name, token, hex: hex2, rgb: rgb2, hsl, oklch: oklch2, form
14972
14972
  ] })
14973
14973
  ] }) });
14974
14974
  }
14975
+ var recommendedBackgroundTones = [100, 200, 400, 500, 600, 700, 800];
14976
+ var AAA_NORMAL_TEXT_RATIO = 7;
14977
+ function extractTone(token) {
14978
+ const match = token.match(/-(\d+)$/);
14979
+ return match ? Number.parseInt(match[1], 10) : 0;
14980
+ }
14981
+ function formatFamilyLabel(name, key) {
14982
+ if (key === "grey") return "Grey";
14983
+ return name.replace(/^NSW Aboriginal\s+/i, "").replace(/^NSW\s+/i, "").trim();
14984
+ }
14985
+ function toPairingColor(color2) {
14986
+ return {
14987
+ ...color2,
14988
+ tone: extractTone(color2.token)
14989
+ };
14990
+ }
14991
+ function getPreferredForegroundTone(backgroundTone) {
14992
+ if (backgroundTone <= 200) return 800;
14993
+ if (backgroundTone <= 500) return 700;
14994
+ if (backgroundTone <= 650) return 250;
14995
+ return 200;
14996
+ }
14997
+ function getPairRating(contrastRatio) {
14998
+ if (contrastRatio >= 7) return "AAA";
14999
+ if (contrastRatio >= 4.5) return "AA";
15000
+ return "AA Large";
15001
+ }
15002
+ function isPreferredDirection(backgroundTone, foregroundTone, preferredForegroundTone) {
15003
+ if (preferredForegroundTone < backgroundTone) {
15004
+ return foregroundTone < backgroundTone;
15005
+ }
15006
+ return foregroundTone > backgroundTone;
15007
+ }
15008
+ function buildPair(background, foreground) {
15009
+ const contrastRatio = culori__namespace.wcagContrast(background.hex, foreground.hex);
15010
+ return {
15011
+ id: `${background.token}:${foreground.token}`,
15012
+ background,
15013
+ foreground,
15014
+ contrastRatio,
15015
+ passes: {
15016
+ aaLarge: contrastRatio >= 3,
15017
+ aaText: contrastRatio >= 4.5,
15018
+ aaaLarge: contrastRatio >= 4.5,
15019
+ aaaText: contrastRatio >= 7
15020
+ },
15021
+ rating: getPairRating(contrastRatio)
15022
+ };
15023
+ }
15024
+ function pickForeground(colorsToPair, background, minimumRatio) {
15025
+ const preferredForegroundTone = getPreferredForegroundTone(background.tone);
15026
+ const passingCandidates = colorsToPair.filter((color2) => color2.token !== background.token).map((color2) => buildPair(background, color2)).filter((pair) => pair.contrastRatio >= minimumRatio);
15027
+ if (passingCandidates.length === 0) return null;
15028
+ const preferredCandidates = passingCandidates.filter(
15029
+ (pair) => isPreferredDirection(background.tone, pair.foreground.tone, preferredForegroundTone)
15030
+ );
15031
+ const candidates = preferredCandidates.length > 0 ? preferredCandidates : passingCandidates;
15032
+ return candidates.sort((left, right) => {
15033
+ const leftTargetDelta = Math.abs(left.foreground.tone - preferredForegroundTone);
15034
+ const rightTargetDelta = Math.abs(right.foreground.tone - preferredForegroundTone);
15035
+ if (leftTargetDelta !== rightTargetDelta) {
15036
+ return leftTargetDelta - rightTargetDelta;
15037
+ }
15038
+ const leftToneGap = Math.abs(left.foreground.tone - background.tone);
15039
+ const rightToneGap = Math.abs(right.foreground.tone - background.tone);
15040
+ if (leftToneGap !== rightToneGap) {
15041
+ return rightToneGap - leftToneGap;
15042
+ }
15043
+ return right.contrastRatio - left.contrastRatio;
15044
+ })[0];
15045
+ }
15046
+ function buildRecommendedPairs(colorsToPair, minimumRatio) {
15047
+ const backgrounds = recommendedBackgroundTones.map((tone) => colorsToPair.find((color2) => color2.tone === tone)).filter((color2) => Boolean(color2));
15048
+ const recommendedPairs = [];
15049
+ for (const background of backgrounds) {
15050
+ const pair = pickForeground(colorsToPair, background, minimumRatio);
15051
+ if (!pair || recommendedPairs.some((item) => item.id === pair.id)) {
15052
+ continue;
15053
+ }
15054
+ recommendedPairs.push(pair);
15055
+ }
15056
+ return recommendedPairs;
15057
+ }
15058
+ function buildRecommendedCollections(minimumRatio) {
15059
+ return {
15060
+ brand: Object.entries(colors.brand).map(([key, palette]) => {
15061
+ const scale2 = palette.colors.map(toPairingColor);
15062
+ return {
15063
+ key,
15064
+ label: formatFamilyLabel(palette.name, key),
15065
+ paletteName: palette.name,
15066
+ colors: scale2,
15067
+ recommendedPairs: buildRecommendedPairs(scale2, minimumRatio)
15068
+ };
15069
+ }),
15070
+ aboriginal: Object.entries(colors.aboriginal).map(([key, palette]) => {
15071
+ const scale2 = palette.colors.map(toPairingColor);
15072
+ return {
15073
+ key,
15074
+ label: formatFamilyLabel(palette.name, key),
15075
+ paletteName: palette.name,
15076
+ colors: scale2,
15077
+ recommendedPairs: buildRecommendedPairs(scale2, minimumRatio)
15078
+ };
15079
+ })
15080
+ };
15081
+ }
15082
+ var recommendedAaaPairingCollections = buildRecommendedCollections(AAA_NORMAL_TEXT_RATIO);
15083
+ function getPairingColorValue(color2, format) {
15084
+ return getColorValue(color2, format);
15085
+ }
15086
+ var styles3 = {
15087
+ base: [
15088
+ // Base
15089
+ "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",
15090
+ // States
15091
+ "data-[state=on]:bg-grey-100 data-[state=on]:text-grey-850",
15092
+ // Hover
15093
+ "hover:bg-grey-100 hover:text-grey-850",
15094
+ // Focus
15095
+ "focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-(--toggle-border)",
15096
+ // Dark mode
15097
+ "dark:text-white",
15098
+ // Dark mode states
15099
+ "dark:data-[state=on]:bg-white/10 dark:data-[state=on]:text-white",
15100
+ // Dark mode hover
15101
+ "dark:hover:bg-white/10 dark:hover:text-white",
15102
+ // Disabled
15103
+ "disabled:pointer-events-none disabled:opacity-50",
15104
+ // Icon
15105
+ '[&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 [&_svg]:shrink-0',
15106
+ // Aria invalid
15107
+ "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
15108
+ // Aria invalid dark mode
15109
+ "dark:aria-invalid:ring-destructive/40"
15110
+ ],
15111
+ outline: [
15112
+ // Base
15113
+ "text-grey-800 border [--toggle-border:var(--color-grey-300)]",
15114
+ // States
15115
+ "hover:[--toggle-border:var(--color-grey-400)]",
15116
+ // Dark mode
15117
+ "dark:[--toggle-border:white]/40",
15118
+ // Dark mode states
15119
+ "dark:hover:[--toggle-border:white]/50",
15120
+ // Data on
15121
+ "data-[state=on]:bg-primary-800/10"
15122
+ ]
15123
+ };
15124
+ var toggleVariants = classVarianceAuthority.cva(styles3.base, {
15125
+ variants: {
15126
+ variant: {
15127
+ ghost: "",
15128
+ outline: clsx12__default.default(styles3.outline)
15129
+ },
15130
+ size: {
15131
+ default: "h-9 px-2 min-w-9",
15132
+ sm: "h-8 px-1.5 min-w-8",
15133
+ lg: "h-10 px-2.5 min-w-10"
15134
+ }
15135
+ },
15136
+ defaultVariants: {
15137
+ variant: "ghost",
15138
+ size: "default"
15139
+ }
15140
+ });
15141
+ function Toggle({
15142
+ className,
15143
+ variant,
15144
+ size,
15145
+ ...props
15146
+ }) {
15147
+ return /* @__PURE__ */ jsxRuntime.jsx(
15148
+ TogglePrimitive__namespace.Root,
15149
+ {
15150
+ "data-slot": "toggle",
15151
+ className: cn(toggleVariants({ variant, size, className })),
15152
+ ...props
15153
+ }
15154
+ );
15155
+ }
15156
+ var ToggleGroupContext = React5__namespace.createContext({
15157
+ size: "default",
15158
+ variant: "ghost"
15159
+ });
15160
+ function ToggleGroup({
15161
+ className,
15162
+ variant,
15163
+ size,
15164
+ children,
15165
+ ...props
15166
+ }) {
15167
+ return /* @__PURE__ */ jsxRuntime.jsx(
15168
+ ToggleGroupPrimitive__namespace.Root,
15169
+ {
15170
+ "data-slot": "toggle-group",
15171
+ "data-variant": variant,
15172
+ "data-size": size,
15173
+ className: cn(
15174
+ "group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
15175
+ className
15176
+ ),
15177
+ ...props,
15178
+ children: /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
15179
+ }
15180
+ );
15181
+ }
15182
+ function ToggleGroupItem({
15183
+ className,
15184
+ children,
15185
+ variant,
15186
+ size,
15187
+ ...props
15188
+ }) {
15189
+ const context = React5__namespace.useContext(ToggleGroupContext);
15190
+ return /* @__PURE__ */ jsxRuntime.jsx(
15191
+ ToggleGroupPrimitive__namespace.Item,
15192
+ {
15193
+ "data-slot": "toggle-group-item",
15194
+ "data-variant": context.variant || variant,
15195
+ "data-size": context.size || size,
15196
+ className: cn(
15197
+ toggleVariants({
15198
+ variant: context.variant || variant,
15199
+ size: context.size || size
15200
+ }),
15201
+ "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",
15202
+ className
15203
+ ),
15204
+ ...props,
15205
+ children
15206
+ }
15207
+ );
15208
+ }
15209
+ function FormatToggle({ format, setFormat }) {
15210
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15211
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Format:" }),
15212
+ /* @__PURE__ */ jsxRuntime.jsxs(
15213
+ ToggleGroup,
15214
+ {
15215
+ type: "single",
15216
+ value: format,
15217
+ onValueChange: (value) => value && setFormat(value),
15218
+ children: [
15219
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hex", "aria-label": "HEX format", children: "HEX" }),
15220
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "rgb", "aria-label": "RGB format", children: "RGB" }),
15221
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hsl", "aria-label": "HSL format", children: "HSL" }),
15222
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "oklch", "aria-label": "OKLCH format", children: "OKLCH" })
15223
+ ]
15224
+ }
15225
+ )
15226
+ ] });
15227
+ }
15228
+ function getPreferredFamilyKey(families) {
15229
+ return families.find((family) => family.key === "green")?.key ?? families[0]?.key ?? "";
15230
+ }
15231
+ function getDefaultPair(family) {
15232
+ if (!family || family.recommendedPairs.length === 0) return null;
15233
+ return family.recommendedPairs.reduce((bestPair, pair) => {
15234
+ const bestDelta = Math.abs(bestPair.background.tone - 600);
15235
+ const currentDelta = Math.abs(pair.background.tone - 600);
15236
+ return currentDelta < bestDelta ? pair : bestPair;
15237
+ }, family.recommendedPairs[0]);
15238
+ }
15239
+ function getFamilySwatchColor(family) {
15240
+ 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";
15241
+ }
15242
+ function ColorPairingToolLoading() {
15243
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
15244
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-40 rounded-md border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
15245
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1.3fr)_minmax(20rem,0.9fr)]", children: [
15246
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-96 rounded-md border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
15247
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-96 rounded-md border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" })
15248
+ ] })
15249
+ ] });
15250
+ }
15251
+ function getInitialPairingState(searchParams) {
15252
+ const paletteParam = searchParams.get("palette");
15253
+ const familyParam = searchParams.get("family");
15254
+ const pairParam = searchParams.get("pair");
15255
+ const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
15256
+ const families = recommendedAaaPairingCollections[themeCategory];
15257
+ const familyKey = families.some((family) => family.key === familyParam) ? familyParam : getPreferredFamilyKey(families);
15258
+ const activeFamily = families.find((family) => family.key === familyKey) ?? families[0];
15259
+ const defaultPair = getDefaultPair(activeFamily);
15260
+ const selectedPairId = activeFamily?.recommendedPairs.some((pair) => pair.id === pairParam) ? pairParam : defaultPair?.id ?? "";
15261
+ return { familyKey, selectedPairId, themeCategory };
15262
+ }
15263
+ function PairPreview({ family, pair }) {
15264
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "gap-0 overflow-hidden py-0", children: /* @__PURE__ */ jsxRuntime.jsx(
15265
+ "div",
15266
+ {
15267
+ className: "p-6 sm:min-h-[26rem] sm:p-8",
15268
+ style: {
15269
+ backgroundColor: pair.background.hex,
15270
+ color: pair.foreground.hex
15271
+ },
15272
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-[22rem] flex-col justify-between gap-8", children: [
15273
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
15274
+ /* @__PURE__ */ jsxRuntime.jsxs(
15275
+ "span",
15276
+ {
15277
+ className: "inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
15278
+ style: {
15279
+ borderColor: pair.foreground.hex,
15280
+ backgroundColor: pair.foreground.hex,
15281
+ color: pair.background.hex
15282
+ },
15283
+ children: [
15284
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
15285
+ family.label
15286
+ ]
15287
+ }
15288
+ ),
15289
+ /* @__PURE__ */ jsxRuntime.jsxs(
15290
+ "span",
15291
+ {
15292
+ className: "inline-flex rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
15293
+ style: {
15294
+ borderColor: pair.foreground.hex
15295
+ },
15296
+ children: [
15297
+ pair.rating,
15298
+ " ",
15299
+ pair.contrastRatio.toFixed(2),
15300
+ ":1"
15301
+ ]
15302
+ }
15303
+ )
15304
+ ] }),
15305
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xl space-y-4 pb-12 sm:pb-16", children: [
15306
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: "Tone on tone" }),
15307
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
15308
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "max-w-lg text-4xl leading-none font-bold text-current sm:text-5xl", children: "Pair colour with confidence." }),
15309
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-sm/6 sm:text-base/7", children: "Use only AAA-approved tone-on-tone combinations for headings, body copy, and calls to action on colour." })
15310
+ ] })
15311
+ ] }),
15312
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
15313
+ /* @__PURE__ */ jsxRuntime.jsxs(
15314
+ "span",
15315
+ {
15316
+ className: "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold",
15317
+ style: {
15318
+ backgroundColor: pair.foreground.hex,
15319
+ color: pair.background.hex
15320
+ },
15321
+ children: [
15322
+ "Pass",
15323
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" })
15324
+ ]
15325
+ }
15326
+ ),
15327
+ /* @__PURE__ */ jsxRuntime.jsxs(
15328
+ "span",
15329
+ {
15330
+ className: "inline-flex rounded-full border px-4 py-2 text-sm",
15331
+ style: {
15332
+ borderColor: pair.foreground.hex
15333
+ },
15334
+ children: [
15335
+ pair.background.token,
15336
+ " / ",
15337
+ pair.foreground.token
15338
+ ]
15339
+ }
15340
+ )
15341
+ ] })
15342
+ ] })
15343
+ }
15344
+ ) });
15345
+ }
15346
+ function PairDetailCard({
15347
+ color: color2,
15348
+ format,
15349
+ role
15350
+ }) {
15351
+ const [, copyToClipboardRaw] = usehooks.useCopyToClipboard();
15352
+ const [copiedField, setCopiedField] = React5.useState(null);
15353
+ const valueLabel = format.toUpperCase();
15354
+ const formattedValue = getPairingColorValue(color2, format);
15355
+ const copyField = (field) => {
15356
+ const fieldValue = field === "token" ? color2.token : field === "tone" ? String(color2.tone) : formattedValue;
15357
+ copyToClipboardRaw(fieldValue);
15358
+ setCopiedField(field);
15359
+ const toastLabel = field === "token" ? "Token" : field === "tone" ? "Tone" : `${valueLabel} value`;
15360
+ sonner.toast(`${toastLabel} copied to clipboard`, {
15361
+ duration: 2e3
15362
+ });
15363
+ setTimeout(() => setCopiedField(null), 2e3);
15364
+ };
15365
+ const renderCopyButton = (field, srLabel, className) => /* @__PURE__ */ jsxRuntime.jsxs(
15366
+ Button2,
15367
+ {
15368
+ variant: "ghost",
15369
+ size: "icon",
15370
+ className: cn("shrink-0", className),
15371
+ onClick: () => copyField(field),
15372
+ children: [
15373
+ copiedField === field ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
15374
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: srLabel })
15375
+ ]
15376
+ }
15377
+ );
15378
+ return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "gap-4", children: [
15379
+ /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { className: "gap-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
15380
+ /* @__PURE__ */ jsxRuntime.jsx(
15381
+ "div",
15382
+ {
15383
+ className: "size-14 rounded-2xl border border-grey-200 shadow-sm dark:border-grey-700",
15384
+ style: { backgroundColor: color2.hex }
15385
+ }
15386
+ ),
15387
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
15388
+ /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: role }),
15389
+ /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: color2.name ?? color2.token })
15390
+ ] })
15391
+ ] }) }),
15392
+ /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "grid gap-4", children: [
15393
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
15394
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
15395
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: "Token" }),
15396
+ renderCopyButton("token", `Copy ${role.toLowerCase()} token`)
15397
+ ] }),
15398
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-base break-all", children: color2.token })
15399
+ ] }),
15400
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
15401
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
15402
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: "Tone" }),
15403
+ renderCopyButton("tone", `Copy ${role.toLowerCase()} tone`)
15404
+ ] }),
15405
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: color2.tone })
15406
+ ] }),
15407
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
15408
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
15409
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: valueLabel }),
15410
+ renderCopyButton("value", `Copy ${role.toLowerCase()} ${valueLabel} value`)
15411
+ ] }),
15412
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-sm break-all", children: formattedValue })
15413
+ ] })
15414
+ ] })
15415
+ ] });
15416
+ }
15417
+ function ComplianceRow({
15418
+ label,
15419
+ passes,
15420
+ threshold
15421
+ }) {
15422
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 rounded-xl border border-grey-200 px-4 py-3 dark:border-grey-700", children: [
15423
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
15424
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: label }),
15425
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: threshold })
15426
+ ] }),
15427
+ /* @__PURE__ */ jsxRuntime.jsxs(
15428
+ "span",
15429
+ {
15430
+ className: cn(
15431
+ "inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-semibold",
15432
+ 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"
15433
+ ),
15434
+ children: [
15435
+ passes ? /* @__PURE__ */ jsxRuntime.jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icons.close, { "data-slot": "icon", className: "size-4" }),
15436
+ passes ? "Pass" : "Fail"
15437
+ ]
15438
+ }
15439
+ )
15440
+ ] });
15441
+ }
15442
+ function PairComplianceCard({ pair }) {
15443
+ return /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
15444
+ /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-2 border-b", children: [
15445
+ /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: "AAA compliance" }),
15446
+ /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "Only pairs that pass AAA normal-text contrast are suggested here. Evaluation uses the raw contrast ratio, not the rounded display value." })
15447
+ ] }),
15448
+ /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-3", children: [
15449
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-grey-200 bg-grey-50 px-4 py-3 dark:border-grey-700 dark:bg-grey-900/60", children: [
15450
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: "Contrast ratio" }),
15451
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-2xl font-semibold", children: [
15452
+ pair.contrastRatio.toFixed(2),
15453
+ ":1"
15454
+ ] })
15455
+ ] }),
15456
+ /* @__PURE__ */ jsxRuntime.jsx(
15457
+ ComplianceRow,
15458
+ {
15459
+ label: "AAA normal text",
15460
+ passes: pair.passes.aaaText,
15461
+ threshold: "7.0:1 or higher"
15462
+ }
15463
+ ),
15464
+ /* @__PURE__ */ jsxRuntime.jsx(
15465
+ ComplianceRow,
15466
+ {
15467
+ label: "AAA large text",
15468
+ passes: pair.passes.aaaLarge,
15469
+ threshold: "4.5:1 or higher"
15470
+ }
15471
+ )
15472
+ ] })
15473
+ ] });
15474
+ }
15475
+ function ColorPairingToolContent() {
15476
+ const searchParams = navigation.useSearchParams();
15477
+ const {
15478
+ familyKey: initialFamilyKey,
15479
+ selectedPairId: initialSelectedPairId,
15480
+ themeCategory: initialThemeCategory
15481
+ } = getInitialPairingState(searchParams);
15482
+ const [themeCategory, setThemeCategory] = React5.useState(initialThemeCategory);
15483
+ const [format, setFormat] = React5.useState("hex");
15484
+ const [activeFamilyKey, setActiveFamilyKey] = React5.useState(initialFamilyKey);
15485
+ const [selectedPairId, setSelectedPairId] = React5.useState(initialSelectedPairId);
15486
+ const families = recommendedAaaPairingCollections[themeCategory];
15487
+ const resolvedActiveFamilyKey = families.some((family) => family.key === activeFamilyKey) ? activeFamilyKey : getPreferredFamilyKey(families);
15488
+ const activeFamily = families.find((family) => family.key === resolvedActiveFamilyKey) ?? families[0];
15489
+ const selectedPair = activeFamily?.recommendedPairs.find((pair) => pair.id === selectedPairId) ?? getDefaultPair(activeFamily);
15490
+ const updateUrlParams = (nextThemeCategory, nextFamilyKey, nextSelectedPairId) => {
15491
+ const params = new URLSearchParams(window.location.search);
15492
+ params.set("palette", nextThemeCategory);
15493
+ params.set("family", nextFamilyKey);
15494
+ if (nextSelectedPairId) {
15495
+ params.set("pair", nextSelectedPairId);
15496
+ } else {
15497
+ params.delete("pair");
15498
+ }
15499
+ window.history.replaceState(
15500
+ null,
15501
+ "",
15502
+ `${window.location.pathname}?${params.toString()}${window.location.hash}`
15503
+ );
15504
+ };
15505
+ const handleThemeCategoryChange = (nextThemeCategory) => {
15506
+ const nextFamilies = recommendedAaaPairingCollections[nextThemeCategory];
15507
+ const nextFamilyKey = nextFamilies.some((family) => family.key === activeFamilyKey) ? activeFamilyKey : getPreferredFamilyKey(nextFamilies);
15508
+ const nextActiveFamily = nextFamilies.find((family) => family.key === nextFamilyKey) ?? nextFamilies[0];
15509
+ const nextSelectedPair = nextActiveFamily?.recommendedPairs.find((pair) => pair.id === selectedPairId) ?? getDefaultPair(nextActiveFamily);
15510
+ setThemeCategory(nextThemeCategory);
15511
+ setActiveFamilyKey(nextFamilyKey);
15512
+ setSelectedPairId(nextSelectedPair?.id ?? "");
15513
+ updateUrlParams(nextThemeCategory, nextFamilyKey, nextSelectedPair?.id ?? "");
15514
+ };
15515
+ const handleFamilyChange = (nextFamilyKey) => {
15516
+ const nextActiveFamily = families.find((family) => family.key === nextFamilyKey);
15517
+ const nextSelectedPair = nextActiveFamily?.recommendedPairs.find((pair) => pair.id === selectedPairId) ?? getDefaultPair(nextActiveFamily);
15518
+ setActiveFamilyKey(nextFamilyKey);
15519
+ setSelectedPairId(nextSelectedPair?.id ?? "");
15520
+ updateUrlParams(themeCategory, nextFamilyKey, nextSelectedPair?.id ?? "");
15521
+ };
15522
+ const handlePairChange = (nextSelectedPairId) => {
15523
+ setSelectedPairId(nextSelectedPairId);
15524
+ updateUrlParams(themeCategory, resolvedActiveFamilyKey, nextSelectedPairId);
15525
+ };
15526
+ if (!activeFamily || !selectedPair) {
15527
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { children: [
15528
+ /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { children: "No recommended AAA pairs available" }),
15529
+ /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "No recommended pairs are available for the current palette." })
15530
+ ] }) });
15531
+ }
15532
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
15533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [
15534
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
15535
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Palette:" }),
15536
+ /* @__PURE__ */ jsxRuntime.jsx(
15537
+ SegmentedControl,
15538
+ {
15539
+ value: themeCategory,
15540
+ onValueChange: (value) => handleThemeCategoryChange(value),
15541
+ children: /* @__PURE__ */ jsxRuntime.jsxs(SegmentedControlList, { className: "w-full sm:w-fit", children: [
15542
+ /* @__PURE__ */ jsxRuntime.jsx(SegmentedControlTrigger, { value: "brand", children: "Brand palette" }),
15543
+ /* @__PURE__ */ jsxRuntime.jsx(SegmentedControlTrigger, { value: "aboriginal", children: "Aboriginal palette" })
15544
+ ] })
15545
+ }
15546
+ )
15547
+ ] }),
15548
+ /* @__PURE__ */ jsxRuntime.jsx(FormatToggle, { format, setFormat })
15549
+ ] }),
15550
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-2 lg:grid-cols-4 xl:grid-cols-5", children: families.map((family) => {
15551
+ const isActive = family.key === resolvedActiveFamilyKey;
15552
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15553
+ "button",
15554
+ {
15555
+ type: "button",
15556
+ onClick: () => handleFamilyChange(family.key),
15557
+ className: cn(
15558
+ "group relative flex w-full items-center gap-3 rounded-sm border px-3 py-2 text-left transition-colors",
15559
+ "border-grey-200 bg-background hover:bg-primary-800/10 hover:text-foreground dark:hover:bg-white/10",
15560
+ isActive && "border-grey-800 dark:border-grey-400"
15561
+ ),
15562
+ children: [
15563
+ /* @__PURE__ */ jsxRuntime.jsx(
15564
+ "span",
15565
+ {
15566
+ className: "size-4 shrink-0 rounded-full",
15567
+ style: { backgroundColor: getFamilySwatchColor(family) }
15568
+ }
15569
+ ),
15570
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: family.label })
15571
+ ]
15572
+ },
15573
+ family.key
15574
+ );
15575
+ }) }) }),
15576
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
15577
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid items-start gap-6 xl:grid-cols-[minmax(0,1.5fr)_minmax(17rem,0.68fr)]", children: [
15578
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
15579
+ /* @__PURE__ */ jsxRuntime.jsx(PairPreview, { family: activeFamily, pair: selectedPair }),
15580
+ /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
15581
+ /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-2 border-b", children: [
15582
+ /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: "Background tone strip" }),
15583
+ /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "Filled chips have a recommended AAA foreground pair. Select one to update the preview." })
15584
+ ] }),
15585
+ /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4", children: [
15586
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 gap-2 sm:grid-cols-7 lg:grid-cols-10 xl:grid-cols-[repeat(19,minmax(0,1fr))]", children: activeFamily.colors.map((color2) => {
15587
+ const pair = activeFamily.recommendedPairs.find(
15588
+ (item) => item.background.token === color2.token
15589
+ );
15590
+ const isSelected = selectedPair.background.token === color2.token;
15591
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15592
+ "button",
15593
+ {
15594
+ type: "button",
15595
+ disabled: !pair,
15596
+ onClick: () => pair && handlePairChange(pair.id),
15597
+ className: cn(
15598
+ "group relative h-12 rounded-xl border transition-transform",
15599
+ pair ? "cursor-pointer border-grey-200 hover:scale-[1.03] dark:border-grey-700" : "cursor-not-allowed border-grey-100 dark:border-grey-800",
15600
+ isSelected && "ring-2 ring-primary-500 ring-offset-2 ring-offset-background"
15601
+ ),
15602
+ style: { backgroundColor: color2.hex },
15603
+ children: [
15604
+ pair && /* @__PURE__ */ jsxRuntime.jsx(
15605
+ "span",
15606
+ {
15607
+ 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",
15608
+ style: { backgroundColor: pair.foreground.hex }
15609
+ }
15610
+ ),
15611
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
15612
+ color2.token,
15613
+ pair ? ` paired with ${pair.foreground.token}` : " has no recommended pair in this tool"
15614
+ ] })
15615
+ ]
15616
+ },
15617
+ color2.token
15618
+ );
15619
+ }) }),
15620
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground", children: [
15621
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
15622
+ "Selected background:",
15623
+ " ",
15624
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-foreground", children: selectedPair.background.token })
15625
+ ] }),
15626
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
15627
+ "Recommended foreground:",
15628
+ " ",
15629
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-foreground", children: selectedPair.foreground.token })
15630
+ ] })
15631
+ ] })
15632
+ ] })
15633
+ ] }),
15634
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
15635
+ /* @__PURE__ */ jsxRuntime.jsx(PairDetailCard, { color: selectedPair.background, format, role: "Background" }),
15636
+ /* @__PURE__ */ jsxRuntime.jsx(PairDetailCard, { color: selectedPair.foreground, format, role: "Foreground" })
15637
+ ] })
15638
+ ] }),
15639
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "h-fit", children: [
15640
+ /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-2 border-b", children: [
15641
+ /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: "Recommended pairs" }),
15642
+ /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: "Recommended same-family combinations that meet AAA normal-text contrast." })
15643
+ ] }),
15644
+ /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "grid gap-3", children: activeFamily.recommendedPairs.map((pair) => {
15645
+ const isActive = selectedPair.id === pair.id;
15646
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15647
+ "button",
15648
+ {
15649
+ type: "button",
15650
+ onClick: () => handlePairChange(pair.id),
15651
+ className: cn(
15652
+ "rounded-2xl border p-4 text-left transition-colors",
15653
+ 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"
15654
+ ),
15655
+ children: [
15656
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
15657
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
15658
+ /* @__PURE__ */ jsxRuntime.jsx(
15659
+ "div",
15660
+ {
15661
+ className: "size-11 rounded-2xl border border-grey-200 shadow-sm dark:border-grey-700",
15662
+ style: { backgroundColor: pair.background.hex }
15663
+ }
15664
+ ),
15665
+ /* @__PURE__ */ jsxRuntime.jsx(
15666
+ "div",
15667
+ {
15668
+ className: "size-11 rounded-2xl border border-grey-200 shadow-sm dark:border-grey-700",
15669
+ style: { backgroundColor: pair.foreground.hex }
15670
+ }
15671
+ )
15672
+ ] }),
15673
+ /* @__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: [
15674
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.contrast, { "data-slot": "icon", className: "size-4" }),
15675
+ pair.rating
15676
+ ] })
15677
+ ] }),
15678
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 space-y-1", children: [
15679
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "font-medium text-foreground", children: [
15680
+ pair.background.token,
15681
+ " / ",
15682
+ pair.foreground.token
15683
+ ] }),
15684
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
15685
+ pair.contrastRatio.toFixed(2),
15686
+ ":1 contrast ratio"
15687
+ ] })
15688
+ ] })
15689
+ ]
15690
+ },
15691
+ pair.id
15692
+ );
15693
+ }) })
15694
+ ] }) })
15695
+ ] }),
15696
+ /* @__PURE__ */ jsxRuntime.jsx(PairComplianceCard, { pair: selectedPair })
15697
+ ] })
15698
+ ] });
15699
+ }
15700
+ function ColorPairingTool() {
15701
+ return /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolLoading, {}), children: /* @__PURE__ */ jsxRuntime.jsx(ColorPairingToolContent, {}) });
15702
+ }
14975
15703
  function ColorSwatches({ theme: theme2, format, viewMode }) {
14976
15704
  return /* @__PURE__ */ jsxRuntime.jsx(
14977
15705
  "div",
@@ -17451,152 +18179,10 @@ function FormMessage({ className, ...props }) {
17451
18179
  }
17452
18180
  );
17453
18181
  }
17454
- var styles3 = {
17455
- base: [
17456
- // Base
17457
- "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",
17458
- // States
17459
- "data-[state=on]:bg-grey-100 data-[state=on]:text-grey-850",
17460
- // Hover
17461
- "hover:bg-grey-100 hover:text-grey-850",
17462
- // Focus
17463
- "focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-(--toggle-border)",
17464
- // Dark mode
17465
- "dark:text-white",
17466
- // Dark mode states
17467
- "dark:data-[state=on]:bg-white/10 dark:data-[state=on]:text-white",
17468
- // Dark mode hover
17469
- "dark:hover:bg-white/10 dark:hover:text-white",
17470
- // Disabled
17471
- "disabled:pointer-events-none disabled:opacity-50",
17472
- // Icon
17473
- '[&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 [&_svg]:shrink-0',
17474
- // Aria invalid
17475
- "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
17476
- // Aria invalid dark mode
17477
- "dark:aria-invalid:ring-destructive/40"
17478
- ],
17479
- outline: [
17480
- // Base
17481
- "text-grey-800 border [--toggle-border:var(--color-grey-300)]",
17482
- // States
17483
- "hover:[--toggle-border:var(--color-grey-400)]",
17484
- // Dark mode
17485
- "dark:[--toggle-border:white]/40",
17486
- // Dark mode states
17487
- "dark:hover:[--toggle-border:white]/50",
17488
- // Data on
17489
- "data-[state=on]:bg-primary-800/10"
17490
- ]
17491
- };
17492
- var toggleVariants = classVarianceAuthority.cva(styles3.base, {
17493
- variants: {
17494
- variant: {
17495
- ghost: "",
17496
- outline: clsx12__default.default(styles3.outline)
17497
- },
17498
- size: {
17499
- default: "h-9 px-2 min-w-9",
17500
- sm: "h-8 px-1.5 min-w-8",
17501
- lg: "h-10 px-2.5 min-w-10"
17502
- }
17503
- },
17504
- defaultVariants: {
17505
- variant: "ghost",
17506
- size: "default"
17507
- }
17508
- });
17509
- function Toggle({
17510
- className,
17511
- variant,
17512
- size,
17513
- ...props
17514
- }) {
17515
- return /* @__PURE__ */ jsxRuntime.jsx(
17516
- TogglePrimitive__namespace.Root,
17517
- {
17518
- "data-slot": "toggle",
17519
- className: cn(toggleVariants({ variant, size, className })),
17520
- ...props
17521
- }
17522
- );
17523
- }
17524
- var ToggleGroupContext = React5__namespace.createContext({
17525
- size: "default",
17526
- variant: "ghost"
17527
- });
17528
- function ToggleGroup({
17529
- className,
17530
- variant,
17531
- size,
17532
- children,
17533
- ...props
17534
- }) {
17535
- return /* @__PURE__ */ jsxRuntime.jsx(
17536
- ToggleGroupPrimitive__namespace.Root,
17537
- {
17538
- "data-slot": "toggle-group",
17539
- "data-variant": variant,
17540
- "data-size": size,
17541
- className: cn(
17542
- "group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
17543
- className
17544
- ),
17545
- ...props,
17546
- children: /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
17547
- }
17548
- );
17549
- }
17550
- function ToggleGroupItem({
17551
- className,
17552
- children,
17553
- variant,
17554
- size,
17555
- ...props
17556
- }) {
17557
- const context = React5__namespace.useContext(ToggleGroupContext);
17558
- return /* @__PURE__ */ jsxRuntime.jsx(
17559
- ToggleGroupPrimitive__namespace.Item,
17560
- {
17561
- "data-slot": "toggle-group-item",
17562
- "data-variant": context.variant || variant,
17563
- "data-size": context.size || size,
17564
- className: cn(
17565
- toggleVariants({
17566
- variant: context.variant || variant,
17567
- size: context.size || size
17568
- }),
17569
- "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",
17570
- className
17571
- ),
17572
- ...props,
17573
- children
17574
- }
17575
- );
17576
- }
17577
- function FormatToggle({ format, setFormat }) {
17578
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
17579
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Format:" }),
17580
- /* @__PURE__ */ jsxRuntime.jsxs(
17581
- ToggleGroup,
17582
- {
17583
- type: "single",
17584
- value: format,
17585
- onValueChange: (value) => value && setFormat(value),
17586
- children: [
17587
- /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hex", "aria-label": "HEX format", children: "HEX" }),
17588
- /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "rgb", "aria-label": "RGB format", children: "RGB" }),
17589
- /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "hsl", "aria-label": "HSL format", children: "HSL" }),
17590
- /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupItem, { value: "oklch", "aria-label": "OKLCH format", children: "OKLCH" })
17591
- ]
17592
- }
17593
- )
17594
- ] });
17595
- }
17596
18182
 
17597
18183
  // package.json
17598
18184
  var package_default = {
17599
- version: "1.96.0"};
18185
+ version: "1.97.13"};
17600
18186
  var SluggerContext = React5__namespace.default.createContext(null);
17601
18187
  function flattenText(nodes) {
17602
18188
  if (nodes == null || typeof nodes === "boolean") return "";
@@ -33838,6 +34424,7 @@ exports.Collapsible = Collapsible;
33838
34424
  exports.CollapsibleContent = CollapsibleContent2;
33839
34425
  exports.CollapsibleTrigger = CollapsibleTrigger2;
33840
34426
  exports.ColorCard = ColorCard;
34427
+ exports.ColorPairingTool = ColorPairingTool;
33841
34428
  exports.ColorSwatches = ColorSwatches;
33842
34429
  exports.ColourScale = ColourScale;
33843
34430
  exports.ComboChart = ComboChart;