@sanity/themer 0.1.0 → 0.2.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.
@@ -1,1237 +0,0 @@
1
- import { buildTheme, createColorTheme, multiply, parseColor, rgbToHex, rgba, screen } from "@sanity/ui/theme";
2
- import { COLOR_TINTS } from "@sanity/color";
3
- /**
4
- * Drops properties that are set to `undefined`, so that spreading the hue
5
- * over defaults doesn't shadow them. The hosted Themer service used a
6
- * `JSON.parse(JSON.stringify(…))` round trip for this.
7
- */
8
- function dropUndefined(hue) {
9
- if (!hue) return;
10
- let result = {};
11
- return hue.mid !== void 0 && (result.mid = hue.mid), hue.midPoint !== void 0 && (result.midPoint = hue.midPoint), hue.lightest !== void 0 && (result.lightest = hue.lightest), hue.darkest !== void 0 && (result.darkest = hue.darkest), result;
12
- }
13
- /**
14
- * The color palette from `@sanity/color@2.2.5`, vendored so that themes
15
- * generated by this module keep producing the exact same colors as the hosted
16
- * Themer service (themer.sanity.build), which bundles that version. The
17
- * current `@sanity/color` palette has different values, so it cannot be used
18
- * here without changing generated themes.
19
- */
20
- /** @internal */
21
- const black = {
22
- title: "Black",
23
- hex: "#101112"
24
- }, white = {
25
- title: "White",
26
- hex: "#fff"
27
- }, gray = {
28
- 50: {
29
- title: "Gray 50",
30
- hex: "#f2f3f5"
31
- },
32
- 100: {
33
- title: "Gray 100",
34
- hex: "#e6e8ec"
35
- },
36
- 200: {
37
- title: "Gray 200",
38
- hex: "#ced2d9"
39
- },
40
- 300: {
41
- title: "Gray 300",
42
- hex: "#b6bcc6"
43
- },
44
- 400: {
45
- title: "Gray 400",
46
- hex: "#9ea6b3"
47
- },
48
- 500: {
49
- title: "Gray 500",
50
- hex: "#8690a0"
51
- },
52
- 600: {
53
- title: "Gray 600",
54
- hex: "#6e7683"
55
- },
56
- 700: {
57
- title: "Gray 700",
58
- hex: "#565d67"
59
- },
60
- 800: {
61
- title: "Gray 800",
62
- hex: "#3f434a"
63
- },
64
- 900: {
65
- title: "Gray 900",
66
- hex: "#272a2e"
67
- },
68
- 950: {
69
- title: "Gray 950",
70
- hex: "#1b1d20"
71
- }
72
- }, blue = {
73
- 50: {
74
- title: "Blue 50",
75
- hex: "#e8f1fe"
76
- },
77
- 100: {
78
- title: "Blue 100",
79
- hex: "#d2e3fe"
80
- },
81
- 200: {
82
- title: "Blue 200",
83
- hex: "#a6c8fd"
84
- },
85
- 300: {
86
- title: "Blue 300",
87
- hex: "#7aacfd"
88
- },
89
- 400: {
90
- title: "Blue 400",
91
- hex: "#4e91fc"
92
- },
93
- 500: {
94
- title: "Blue 500",
95
- hex: "#2276fc"
96
- },
97
- 600: {
98
- title: "Blue 600",
99
- hex: "#1e61cd"
100
- },
101
- 700: {
102
- title: "Blue 700",
103
- hex: "#1a4d9e"
104
- },
105
- 800: {
106
- title: "Blue 800",
107
- hex: "#17396f"
108
- },
109
- 900: {
110
- title: "Blue 900",
111
- hex: "#132540"
112
- },
113
- 950: {
114
- title: "Blue 950",
115
- hex: "#111b29"
116
- }
117
- }, purple = {
118
- 50: {
119
- title: "Purple 50",
120
- hex: "#f8e9fe"
121
- },
122
- 100: {
123
- title: "Purple 100",
124
- hex: "#f2d3fe"
125
- },
126
- 200: {
127
- title: "Purple 200",
128
- hex: "#e6a7fd"
129
- },
130
- 300: {
131
- title: "Purple 300",
132
- hex: "#d97bfd"
133
- },
134
- 400: {
135
- title: "Purple 400",
136
- hex: "#cd4efc"
137
- },
138
- 500: {
139
- title: "Purple 500",
140
- hex: "#c123fc"
141
- },
142
- 600: {
143
- title: "Purple 600",
144
- hex: "#9d1fcd"
145
- },
146
- 700: {
147
- title: "Purple 700",
148
- hex: "#7a1b9e"
149
- },
150
- 800: {
151
- title: "Purple 800",
152
- hex: "#56186f"
153
- },
154
- 900: {
155
- title: "Purple 900",
156
- hex: "#331440"
157
- },
158
- 950: {
159
- title: "Purple 950",
160
- hex: "#211229"
161
- }
162
- }, magenta = {
163
- 50: {
164
- title: "Magenta 50",
165
- hex: "#fcebf5"
166
- },
167
- 100: {
168
- title: "Magenta 100",
169
- hex: "#f9d7eb"
170
- },
171
- 200: {
172
- title: "Magenta 200",
173
- hex: "#f4afd8"
174
- },
175
- 300: {
176
- title: "Magenta 300",
177
- hex: "#ef87c4"
178
- },
179
- 400: {
180
- title: "Magenta 400",
181
- hex: "#ea5fb1"
182
- },
183
- 500: {
184
- title: "Magenta 500",
185
- hex: "#e5389e"
186
- },
187
- 600: {
188
- title: "Magenta 600",
189
- hex: "#ba3082"
190
- },
191
- 700: {
192
- title: "Magenta 700",
193
- hex: "#8f2866"
194
- },
195
- 800: {
196
- title: "Magenta 800",
197
- hex: "#65204a"
198
- },
199
- 900: {
200
- title: "Magenta 900",
201
- hex: "#3a182d"
202
- },
203
- 950: {
204
- title: "Magenta 950",
205
- hex: "#25141f"
206
- }
207
- }, red = {
208
- 50: {
209
- title: "Red 50",
210
- hex: "#fdebea"
211
- },
212
- 100: {
213
- title: "Red 100",
214
- hex: "#fcd8d5"
215
- },
216
- 200: {
217
- title: "Red 200",
218
- hex: "#f9b1ab"
219
- },
220
- 300: {
221
- title: "Red 300",
222
- hex: "#f68b82"
223
- },
224
- 400: {
225
- title: "Red 400",
226
- hex: "#f36458"
227
- },
228
- 500: {
229
- title: "Red 500",
230
- hex: "#f03e2f"
231
- },
232
- 600: {
233
- title: "Red 600",
234
- hex: "#c33529"
235
- },
236
- 700: {
237
- title: "Red 700",
238
- hex: "#962c23"
239
- },
240
- 800: {
241
- title: "Red 800",
242
- hex: "#69231d"
243
- },
244
- 900: {
245
- title: "Red 900",
246
- hex: "#3c1a17"
247
- },
248
- 950: {
249
- title: "Red 950",
250
- hex: "#261514"
251
- }
252
- }, orange = {
253
- 50: {
254
- title: "Orange 50",
255
- hex: "#fef0e6"
256
- },
257
- 100: {
258
- title: "Orange 100",
259
- hex: "#fee2ce"
260
- },
261
- 200: {
262
- title: "Orange 200",
263
- hex: "#fdc59d"
264
- },
265
- 300: {
266
- title: "Orange 300",
267
- hex: "#fca86d"
268
- },
269
- 400: {
270
- title: "Orange 400",
271
- hex: "#fb8b3c"
272
- },
273
- 500: {
274
- title: "Orange 500",
275
- hex: "#e57322"
276
- },
277
- 600: {
278
- title: "Orange 600",
279
- hex: "#ba5f1f"
280
- },
281
- 700: {
282
- title: "Orange 700",
283
- hex: "#904b1b"
284
- },
285
- 800: {
286
- title: "Orange 800",
287
- hex: "#653818"
288
- },
289
- 900: {
290
- title: "Orange 900",
291
- hex: "#3a2415"
292
- },
293
- 950: {
294
- title: "Orange 950",
295
- hex: "#251a13"
296
- }
297
- }, yellow = {
298
- 50: {
299
- title: "Yellow 50",
300
- hex: "#fef7da"
301
- },
302
- 100: {
303
- title: "Yellow 100",
304
- hex: "#fdefb6"
305
- },
306
- 200: {
307
- title: "Yellow 200",
308
- hex: "#fcdf6d"
309
- },
310
- 300: {
311
- title: "Yellow 300",
312
- hex: "#fbd024"
313
- },
314
- 400: {
315
- title: "Yellow 400",
316
- hex: "#d9b421"
317
- },
318
- 500: {
319
- title: "Yellow 500",
320
- hex: "#b7991e"
321
- },
322
- 600: {
323
- title: "Yellow 600",
324
- hex: "#967e1c"
325
- },
326
- 700: {
327
- title: "Yellow 700",
328
- hex: "#746219"
329
- },
330
- 800: {
331
- title: "Yellow 800",
332
- hex: "#534717"
333
- },
334
- 900: {
335
- title: "Yellow 900",
336
- hex: "#312c14"
337
- },
338
- 950: {
339
- title: "Yellow 950",
340
- hex: "#201e13"
341
- }
342
- }, green = {
343
- 50: {
344
- title: "Green 50",
345
- hex: "#e7f9ed"
346
- },
347
- 100: {
348
- title: "Green 100",
349
- hex: "#d0f4dc"
350
- },
351
- 200: {
352
- title: "Green 200",
353
- hex: "#a1eaba"
354
- },
355
- 300: {
356
- title: "Green 300",
357
- hex: "#72e097"
358
- },
359
- 400: {
360
- title: "Green 400",
361
- hex: "#43d675"
362
- },
363
- 500: {
364
- title: "Green 500",
365
- hex: "#3ab564"
366
- },
367
- 600: {
368
- title: "Green 600",
369
- hex: "#329454"
370
- },
371
- 700: {
372
- title: "Green 700",
373
- hex: "#297343"
374
- },
375
- 800: {
376
- title: "Green 800",
377
- hex: "#215233"
378
- },
379
- 900: {
380
- title: "Green 900",
381
- hex: "#183122"
382
- },
383
- 950: {
384
- title: "Green 950",
385
- hex: "#14211a"
386
- }
387
- }, cyan = {
388
- 50: {
389
- title: "Cyan 50",
390
- hex: "#e3fafd"
391
- },
392
- 100: {
393
- title: "Cyan 100",
394
- hex: "#c7f5fc"
395
- },
396
- 200: {
397
- title: "Cyan 200",
398
- hex: "#90ecf9"
399
- },
400
- 300: {
401
- title: "Cyan 300",
402
- hex: "#59e3f6"
403
- },
404
- 400: {
405
- title: "Cyan 400",
406
- hex: "#22daf4"
407
- },
408
- 500: {
409
- title: "Cyan 500",
410
- hex: "#1fb8ce"
411
- },
412
- 600: {
413
- title: "Cyan 600",
414
- hex: "#1c97a8"
415
- },
416
- 700: {
417
- title: "Cyan 700",
418
- hex: "#197583"
419
- },
420
- 800: {
421
- title: "Cyan 800",
422
- hex: "#16545d"
423
- },
424
- 900: {
425
- title: "Cyan 900",
426
- hex: "#133237"
427
- },
428
- 950: {
429
- title: "Cyan 950",
430
- hex: "#112124"
431
- }
432
- }, lightest = white.hex.toLowerCase(), darkest = black.hex.toLowerCase(), defaultHues = {
433
- default: {
434
- lightest,
435
- darkest,
436
- mid: "#8690a0",
437
- midPoint: 500
438
- },
439
- primary: {
440
- lightest,
441
- darkest,
442
- mid: "#2276fc",
443
- midPoint: 500
444
- },
445
- transparent: {
446
- lightest,
447
- darkest,
448
- mid: "#8690a0",
449
- midPoint: 500
450
- },
451
- positive: {
452
- lightest,
453
- darkest,
454
- mid: "#43d675",
455
- midPoint: 400
456
- },
457
- caution: {
458
- lightest,
459
- darkest,
460
- mid: "#fbd024",
461
- midPoint: 300
462
- },
463
- critical: {
464
- lightest,
465
- darkest,
466
- mid: "#f03e2f",
467
- midPoint: 500
468
- }
469
- };
470
- /**
471
- * Merges partial hues over the defaults, exactly like the hosted Themer
472
- * service did. When a hue's `mid` color is customized without an explicit
473
- * `midPoint`, the mid point resets to `500`.
474
- */
475
- function applyHues(_hues, defaults = defaultHues) {
476
- let hues = {
477
- default: dropUndefined(_hues.default),
478
- primary: dropUndefined(_hues.primary),
479
- transparent: dropUndefined(_hues.transparent),
480
- positive: dropUndefined(_hues.positive),
481
- caution: dropUndefined(_hues.caution),
482
- critical: dropUndefined(_hues.critical)
483
- }, defaultMid = hues.default?.mid?.toLowerCase() || defaults.default.mid, primaryMid = hues.primary?.mid?.toLowerCase() || defaults.primary.mid, transparentMid = hues.transparent?.mid?.toLowerCase() || defaults.transparent.mid, positiveMid = hues.positive?.mid?.toLowerCase() || defaults.positive.mid, cautionMid = hues.caution?.mid?.toLowerCase() || defaults.caution.mid, criticalMid = hues.critical?.mid?.toLowerCase() || defaults.critical.mid;
484
- return {
485
- default: {
486
- ...defaults.default,
487
- midPoint: defaultMid === defaults.default.mid ? defaults.default.midPoint : 500,
488
- ...hues.default,
489
- mid: defaultMid
490
- },
491
- primary: {
492
- ...defaults.primary,
493
- midPoint: primaryMid === defaults.primary.mid ? defaults.primary.midPoint : 500,
494
- ...hues.primary,
495
- mid: primaryMid
496
- },
497
- transparent: {
498
- ...defaults.transparent,
499
- midPoint: transparentMid === defaults.transparent.mid ? defaults.transparent.midPoint : 500,
500
- ...hues.transparent,
501
- mid: transparentMid
502
- },
503
- positive: {
504
- ...defaults.positive,
505
- midPoint: positiveMid === defaults.positive.mid ? defaults.positive.midPoint : 500,
506
- ...hues.positive,
507
- mid: positiveMid
508
- },
509
- caution: {
510
- ...defaults.caution,
511
- midPoint: cautionMid === defaults.caution.mid ? defaults.caution.midPoint : 500,
512
- ...hues.caution,
513
- mid: cautionMid
514
- },
515
- critical: {
516
- ...defaults.critical,
517
- midPoint: criticalMid === defaults.critical.mid ? defaults.critical.midPoint : 500,
518
- ...hues.critical,
519
- mid: criticalMid
520
- }
521
- };
522
- }
523
- /**
524
- * Color mixing that is byte-for-byte compatible with the `mix` function from
525
- * `polished`, which the hosted Themer service (themer.sanity.build) used to
526
- * interpolate hue tints. Only opaque hex colors are supported, which is all
527
- * the theme generators ever pass.
528
- *
529
- * @internal
530
- */
531
- function mix(weight, color, otherColor) {
532
- if (weight === 0) return otherColor;
533
- let [r1, g1, b1] = hexToRgb(color), [r2, g2, b2] = hexToRgb(otherColor), w2 = 1 - weight;
534
- return reduceHex(`#${channelToHex(Math.floor(r1 * weight + r2 * w2))}${channelToHex(Math.floor(g1 * weight + g2 * w2))}${channelToHex(Math.floor(b1 * weight + b2 * w2))}`);
535
- }
536
- /**
537
- * Matches `#abc` and `#aabbcc` hex colors (the only formats the theme
538
- * generators accept), same as the hosted Themer service did.
539
- *
540
- * @internal
541
- */
542
- function isColor(input) {
543
- return /^#(?:[0-9a-f]{3}){1,2}$/i.test(input);
544
- }
545
- function hexToRgb(color) {
546
- if (!isColor(color)) throw TypeError(`Invalid color: ${JSON.stringify(color)} — expected a hex color`);
547
- let hex = color.length === 4 ? `${color[1]}${color[1]}${color[2]}${color[2]}${color[3]}${color[3]}` : color.slice(1);
548
- return [
549
- parseInt(hex.slice(0, 2), 16),
550
- parseInt(hex.slice(2, 4), 16),
551
- parseInt(hex.slice(4, 6), 16)
552
- ];
553
- }
554
- function channelToHex(value) {
555
- let hex = value.toString(16);
556
- return hex.length === 1 ? `0${hex}` : hex;
557
- }
558
- /** Shortens `#aabbcc` to `#abc` when possible, same as `polished` does */
559
- function reduceHex(hex) {
560
- return hex[1] === hex[2] && hex[3] === hex[4] && hex[5] === hex[6] ? `#${hex[1]}${hex[3]}${hex[5]}` : hex;
561
- }
562
- const VALID_MID_POINTS = /* @__PURE__ */ new Set([
563
- 50,
564
- 100,
565
- 200,
566
- 300,
567
- 400,
568
- 500,
569
- 600,
570
- 700,
571
- 800,
572
- 900,
573
- 950
574
- ]);
575
- /**
576
- * Parses hues from the query of a hosted Themer service URL, exactly like
577
- * `https://themer.sanity.build/api/hues` did — including its validation
578
- * errors.
579
- */
580
- function parseHuesFromSearchParams(searchParams) {
581
- let lightest = searchParams.has("lightest") ? assertValidColor(`#${(searchParams.get("lightest") ?? "").toLowerCase()}`) : void 0, darkest = searchParams.get("darkest") ? assertValidColor(`#${(searchParams.get("darkest") ?? "").toLowerCase()}`) : void 0;
582
- return {
583
- default: dropUndefined(parseHue("default", searchParams, lightest, darkest)),
584
- primary: dropUndefined(parseHue("primary", searchParams, lightest, darkest)),
585
- transparent: dropUndefined(parseHue("transparent", searchParams, lightest, darkest)),
586
- positive: dropUndefined(parseHue("positive", searchParams, lightest, darkest)),
587
- caution: dropUndefined(parseHue("caution", searchParams, lightest, darkest)),
588
- critical: dropUndefined(parseHue("critical", searchParams, lightest, darkest))
589
- };
590
- }
591
- function parseHue(key, searchParams, defaultLightest, defaultDarkest) {
592
- if (!searchParams.has(key)) return {
593
- lightest: defaultLightest,
594
- darkest: defaultDarkest
595
- };
596
- let input = (searchParams.get(key) ?? "").toLowerCase(), mid, midPoint, lightest, darkest, params = input.split(";");
597
- if (params.length > 4) throw TypeError(`Invalid number of params for the ${key} hue, it should be 4 or less instead it's ${params.length}: ${JSON.stringify(params)}`);
598
- for (let param of params) {
599
- let maybeMid = `#${param}`, maybeMidPoint = roundMidPoint(Number(param));
600
- switch (!0) {
601
- case param === "": break;
602
- case isColor(maybeMid) && !mid:
603
- mid = maybeMid;
604
- break;
605
- case !Number.isNaN(maybeMidPoint) && !midPoint:
606
- midPoint = assertValidMidPoint(maybeMidPoint);
607
- break;
608
- case param.startsWith("lightest:") && !lightest:
609
- lightest = assertValidColor(`#${param.replace(/^lightest:/, "")}`);
610
- break;
611
- case param.startsWith("darkest:") && !darkest:
612
- darkest = assertValidColor(`#${param.replace(/^darkest:/, "")}`);
613
- break;
614
- case isColor(maybeMid):
615
- throwDuplicate(key, mid?.replace(/^#/, ""), param, input);
616
- break;
617
- case !Number.isNaN(maybeMidPoint):
618
- throwDuplicate(key, midPoint, maybeMidPoint, input);
619
- break;
620
- case param.startsWith("lightest:"):
621
- throwDuplicate(key, lightest?.replace(/^#/, "lightest:"), param, input);
622
- break;
623
- case param.startsWith("darkest:"):
624
- throwDuplicate(key, darkest?.replace(/^#/, "darkest:"), param, input);
625
- break;
626
- default: throw TypeError(`Invalid param for the ${key} hue: ${param}`);
627
- }
628
- }
629
- return {
630
- mid,
631
- midPoint,
632
- lightest: lightest ?? defaultLightest,
633
- darkest: darkest ?? defaultDarkest
634
- };
635
- }
636
- function roundMidPoint(value) {
637
- return value < 75 ? 50 : value > 925 ? 950 : Math.round(value / 100) * 100;
638
- }
639
- function throwDuplicate(key, a, b, input) {
640
- throw TypeError(`Duplicate params detected. Remove at least ${a === b ? `one of the ${JSON.stringify(String(a))}` : `${JSON.stringify(String(a))} or ${JSON.stringify(String(b))}`} from the ${key} hue: ${JSON.stringify(input)}`);
641
- }
642
- function assertValidColor(input) {
643
- if (isColor(input)) return input;
644
- throw TypeError(`Invalid color: ${input}`);
645
- }
646
- function assertValidMidPoint(input) {
647
- if (isMidPoint(input)) return input;
648
- throw TypeError(`Invalid midPoint: ${input}`);
649
- }
650
- function isMidPoint(input) {
651
- return VALID_MID_POINTS.has(input);
652
- }
653
- function definePreset(slug, title, searchParams) {
654
- return {
655
- slug,
656
- title,
657
- searchParams,
658
- hues: applyHues(parseHuesFromSearchParams(new URLSearchParams(searchParams)))
659
- };
660
- }
661
- const defaultPreset = definePreset("default", "Studio v3", "lightest=fff&darkest=101112&default=8690a0;500&primary=2276fc;500&transparent=8690a0;500&positive=43d675;400&caution=fbd024;300&critical=f03e2f;500"), presets = [
662
- defaultPreset,
663
- definePreset("dew", "Dew", "default=5e63b4;600;lightest:fcfcfd;darkest:0d0d15&primary=d1a308;400;lightest:fcfcfd;darkest:0d0d15&transparent=6c6fa7;500;lightest:fcfcfd;darkest:0d0d15&positive=43D675;300;lightest:fcfcfd;darkest:0d0d15&caution=fb9f24;400;lightest:fcfcfd;darkest:0d0d15&critical=F03E2F;500;lightest:fcfcfd;darkest:0d0d15"),
664
- definePreset("pink-synth", "Pink Synth", "lightest=f7f2f5&darkest=171721&default=8b6584&primary=ec4899&transparent=503a4c&positive=10b981&caution=fde047;300&critical=fe3459"),
665
- definePreset("pixel-art", "Pixel Art", "default=57619c;600&primary=f10784&transparent=5b6498;600&positive=43d675;300&caution=fbd024;200&lightest=fcfcfd&darkest=0d0e15"),
666
- definePreset("retro-colonial", "Retro Colonial", "default=8bb9b5;400&primary=fa7a78;400&transparent=8bb9b5;400&positive=43d675;300&caution=fbd024;200&critical=f02f53&lightest=fcfdfd&darkest=0d1515"),
667
- definePreset("rosabel", "Rosabel", "default=9d8966&primary=ed2555;700&transparent=9d8966&positive=43d675;300&caution=fbd024;200&lightest=fdfdfc&darkest=15120d"),
668
- definePreset("stereofidelic", "Stereofidelic", "default=678e9a&primary=f13009&transparent=678e9a&positive=43d675;300&caution=fbd024;200&critical=f02f35&lightest=fcfdfd&darkest=0e1315"),
669
- definePreset("tw-cyan", "Tailwind Cyan", "default=677389;500;lightest:f9fafb;darkest:101728&primary=51b4d0;500;lightest:effefe;darkest:264d61&transparent=6b727f;500;lightest:f8fafb;darkest:131826&positive=55b785;500;lightest:eefdf5;darkest:214d3b&caution=e2b53e;500;lightest:fefbea;darkest:69411b&critical=e14f62;500;lightest:fdf2f2;darkest:7d2037"),
670
- definePreset("verdant", "Verdant", "default=5c9199;500;lightest:fcfdfd;darkest:0d1415&primary=1cb485;400;lightest:fcfdfd;darkest:0d1415&transparent=5c9199;500;lightest:fcfdfd;darkest:0d1415&positive=43D675;300;lightest:fcfdfd;darkest:0d1415&caution=FBD024;200;lightest:fcfdfd;darkest:0d1415&critical=F03E2F;500;lightest:fcfdfd;darkest:0d1415")
671
- ];
672
- /**
673
- * Finds a preset by its slug, falling back to the default Studio preset for
674
- * unknown slugs — the behavior of the hosted Themer service's `?preset`
675
- * param, which `parseHuesFromUrl` exposes.
676
- *
677
- * @internal
678
- */
679
- function getPreset(slug) {
680
- let needle = slug?.toLowerCase();
681
- return presets.find((preset) => preset.slug === needle) || defaultPreset;
682
- }
683
- /**
684
- * Generates the tint ramp for each of the six hues, exactly like the hosted
685
- * Themer service did.
686
- */
687
- function createTonesFromHues(hues) {
688
- return {
689
- default: createTintsFromHue(hues.default, "Default"),
690
- primary: createTintsFromHue(hues.primary, "Primary"),
691
- transparent: createTintsFromHue(hues.transparent, "Transparent"),
692
- positive: createTintsFromHue(hues.positive, "Positive"),
693
- caution: createTintsFromHue(hues.caution, "Caution"),
694
- critical: createTintsFromHue(hues.critical, "Critical")
695
- };
696
- }
697
- function createTintsFromHue(hue, title) {
698
- return COLOR_TINTS.reduce((tints, tint) => (tints[tint] = {
699
- title: `${title} ${tint}`,
700
- hex: getColorHex(hue, tint)
701
- }, tints), {});
702
- }
703
- function getColorHex(hue, tint) {
704
- let tintNum = Number(tint), midPoint = hue.midPoint, darkSize = 1e3 - midPoint, lightPosition = tintNum / midPoint, darkPosition = (tintNum - midPoint) / darkSize;
705
- return tintNum === midPoint ? hue.mid.toLowerCase() : tintNum < midPoint ? mix(lightPosition, hue.mid, hue.lightest) : mix(darkPosition, hue.darkest, hue.mid);
706
- }
707
- const NEUTRAL_TONES = /* @__PURE__ */ new Set(["default", "transparent"]), SPOT_TINTS = {
708
- blue,
709
- cyan,
710
- gray,
711
- green,
712
- magenta,
713
- orange,
714
- purple,
715
- red,
716
- yellow
717
- };
718
- function getTint(key) {
719
- let tints = SPOT_TINTS[key];
720
- if (!tints) throw Error(`Unknown tint: ${key}`);
721
- return tints;
722
- }
723
- const defaultTheme = buildTheme();
724
- /**
725
- * Generates a Studio theme from hues, producing the exact same colors as the
726
- * hosted Themer service (themer.sanity.build). This is a port of its
727
- * `themeFromHues` implementation:
728
- * https://github.com/sanity-io/themer/blob/main/apps/v1/utils/themeFromHues.ts
729
- */
730
- function themeFromHues(partialHues) {
731
- function multiply$1(bg, fg) {
732
- return rgbToHex(multiply(parseColor(bg), parseColor(fg)));
733
- }
734
- function screen$1(bg, fg) {
735
- return rgbToHex(screen(parseColor(bg), parseColor(fg)));
736
- }
737
- let hues = applyHues(partialHues), black = {
738
- title: "Black",
739
- hex: hues.default.darkest
740
- }, white = {
741
- title: "white",
742
- hex: hues.default.lightest
743
- }, tones = createTonesFromHues(hues), focusRingHue = tones.primary, accentHue = tones.critical, linkHue = tones.primary, color = createColorTheme({
744
- base: ({ dark, name }) => {
745
- if (name === "default") {
746
- let skeletonFrom = dark ? tones.transparent[900].hex : tones.transparent[100].hex;
747
- return {
748
- fg: dark ? white.hex : black.hex,
749
- bg: dark ? black.hex : white.hex,
750
- border: tones.transparent[dark ? 800 : 200].hex,
751
- focusRing: focusRingHue[500].hex,
752
- shadow: {
753
- outline: rgba(tones.transparent[500].hex, .4),
754
- umbra: rgba(dark ? black.hex : tones.transparent[500].hex, .2),
755
- penumbra: rgba(dark ? black.hex : tones.transparent[500].hex, .14),
756
- ambient: rgba(dark ? black.hex : tones.transparent[500].hex, .12)
757
- },
758
- skeleton: {
759
- from: skeletonFrom,
760
- to: rgba(skeletonFrom, .5)
761
- }
762
- };
763
- }
764
- if (name === "transparent") {
765
- let tints = tones.default, skeletonFrom = tints[dark ? 800 : 200].hex;
766
- return {
767
- fg: tints[dark ? 100 : 900].hex,
768
- bg: tints[dark ? 950 : 50].hex,
769
- border: tints[dark ? 800 : 300].hex,
770
- focusRing: focusRingHue[500].hex,
771
- shadow: {
772
- outline: rgba(tints[500].hex, dark ? .2 : .4),
773
- umbra: rgba(dark ? black.hex : tints[500].hex, .2),
774
- penumbra: rgba(dark ? black.hex : tints[500].hex, .14),
775
- ambient: rgba(dark ? black.hex : tints[500].hex, .12)
776
- },
777
- skeleton: {
778
- from: skeletonFrom,
779
- to: rgba(skeletonFrom, .5)
780
- }
781
- };
782
- }
783
- let tints = tones[name] || tones.default, skeletonFrom = tints[dark ? 800 : 200].hex;
784
- return {
785
- fg: tints[dark ? 100 : 900].hex,
786
- bg: tints[dark ? 950 : 50].hex,
787
- border: tints[dark ? 800 : 200].hex,
788
- focusRing: tints[500].hex,
789
- shadow: {
790
- outline: rgba(tints[500].hex, dark ? .2 : .4),
791
- umbra: rgba(dark ? black.hex : tints[500].hex, .2),
792
- penumbra: rgba(dark ? black.hex : tints[500].hex, .14),
793
- ambient: rgba(dark ? black.hex : tints[500].hex, .12)
794
- },
795
- skeleton: {
796
- from: skeletonFrom,
797
- to: rgba(skeletonFrom, .5)
798
- }
799
- };
800
- },
801
- solid: ({ base, dark, name, state, tone }) => {
802
- let mix = dark ? screen$1 : multiply$1, mix2 = dark ? multiply$1 : screen$1, defaultTints = tones[name] || tones.default, isNeutral = NEUTRAL_TONES.has(name) && NEUTRAL_TONES.has(tone), tints = tones[tone === "default" ? name : tone] || defaultTints;
803
- if (state === "disabled") {
804
- tints = defaultTints;
805
- let bg = mix(base.bg, tints[dark ? 800 : 200].hex), skeletonFrom = mix2(bg, tints[dark ? 200 : 800].hex);
806
- return {
807
- bg,
808
- bg2: mix2(bg, tints[dark ? 50 : 950].hex),
809
- border: mix(base.bg, tints[dark ? 800 : 200].hex),
810
- fg: mix(base.bg, dark ? black.hex : white.hex),
811
- icon: mix(base.bg, dark ? black.hex : white.hex),
812
- muted: { fg: mix(base.bg, tints[dark ? 950 : 50].hex) },
813
- accent: { fg: mix(base.bg, tints[dark ? 950 : 50].hex) },
814
- link: { fg: mix(base.bg, tints[dark ? 950 : 50].hex) },
815
- code: {
816
- bg,
817
- fg: mix(base.bg, tints[dark ? 950 : 50].hex)
818
- },
819
- skeleton: {
820
- from: skeletonFrom,
821
- to: rgba(skeletonFrom, .5)
822
- }
823
- };
824
- }
825
- if (state === "hovered") {
826
- let bg = mix(base.bg, tints[dark ? 300 : 600].hex), skeletonFrom = mix2(bg, tints[dark ? 200 : 800].hex);
827
- return {
828
- bg,
829
- bg2: mix2(bg, tints[dark ? 50 : 950].hex),
830
- border: mix(base.bg, tints[dark ? 300 : 600].hex),
831
- fg: mix(base.bg, dark ? black.hex : white.hex),
832
- icon: mix(base.bg, dark ? black.hex : white.hex),
833
- muted: { fg: mix(base.bg, tints[dark ? 800 : 200].hex) },
834
- accent: { fg: mix2(bg, accentHue[dark ? 800 : 200].hex) },
835
- link: { fg: mix2(bg, linkHue[dark ? 800 : 200].hex) },
836
- code: {
837
- bg: mix(bg, tints[dark ? 950 : 50].hex),
838
- fg: mix(base.bg, tints[dark ? 800 : 200].hex)
839
- },
840
- skeleton: {
841
- from: skeletonFrom,
842
- to: rgba(skeletonFrom, .5)
843
- }
844
- };
845
- }
846
- if (state === "pressed") {
847
- let bg = mix(base.bg, tints[dark ? 200 : 800].hex), skeletonFrom = mix2(bg, tints[dark ? 200 : 800].hex);
848
- return {
849
- bg: mix(base.bg, tints[dark ? 200 : 800].hex),
850
- bg2: mix2(bg, tints[dark ? 50 : 950].hex),
851
- border: mix(base.bg, tints[dark ? 200 : 800].hex),
852
- fg: mix(base.bg, dark ? black.hex : white.hex),
853
- icon: mix(base.bg, dark ? black.hex : white.hex),
854
- muted: { fg: mix(base.bg, tints[dark ? 800 : 200].hex) },
855
- accent: { fg: mix2(bg, accentHue[dark ? 800 : 200].hex) },
856
- link: { fg: mix2(bg, linkHue[dark ? 800 : 200].hex) },
857
- code: {
858
- bg: mix(bg, tints[dark ? 950 : 50].hex),
859
- fg: mix(base.bg, tints[dark ? 800 : 200].hex)
860
- },
861
- skeleton: {
862
- from: skeletonFrom,
863
- to: rgba(skeletonFrom, .5)
864
- }
865
- };
866
- }
867
- if (state === "selected") {
868
- isNeutral && (tints = tones.primary);
869
- let bg = mix(base.bg, tints[dark ? 200 : 800].hex), skeletonFrom = mix2(bg, tints[dark ? 200 : 800].hex);
870
- return {
871
- bg,
872
- bg2: mix2(bg, tints[dark ? 50 : 950].hex),
873
- border: mix(base.bg, tints[dark ? 200 : 800].hex),
874
- fg: mix(base.bg, dark ? black.hex : white.hex),
875
- icon: mix(base.bg, dark ? black.hex : white.hex),
876
- muted: { fg: mix(base.bg, tints[dark ? 800 : 200].hex) },
877
- accent: { fg: mix2(bg, accentHue[dark ? 800 : 200].hex) },
878
- link: { fg: mix2(bg, linkHue[dark ? 800 : 200].hex) },
879
- code: {
880
- bg: mix(bg, tints[dark ? 950 : 50].hex),
881
- fg: mix(base.bg, tints[dark ? 800 : 200].hex)
882
- },
883
- skeleton: {
884
- from: skeletonFrom,
885
- to: rgba(skeletonFrom, .5)
886
- }
887
- };
888
- }
889
- let bg = mix(base.bg, tints[dark ? 400 : 500].hex), skeletonFrom = mix2(bg, tints[dark ? 200 : 800].hex);
890
- return {
891
- bg,
892
- bg2: mix2(bg, tints[dark ? 50 : 950].hex),
893
- border: mix(base.bg, tints[dark ? 400 : 500].hex),
894
- fg: mix(base.bg, dark ? black.hex : white.hex),
895
- icon: mix(base.bg, dark ? black.hex : white.hex),
896
- muted: { fg: mix(base.bg, tints[dark ? 900 : 100].hex) },
897
- accent: { fg: mix2(bg, accentHue[dark ? 900 : 100].hex) },
898
- link: { fg: mix2(bg, linkHue[dark ? 900 : 100].hex) },
899
- code: {
900
- bg: mix(bg, tints[dark ? 950 : 50].hex),
901
- fg: mix(base.bg, tints[dark ? 900 : 100].hex)
902
- },
903
- skeleton: {
904
- from: skeletonFrom,
905
- to: rgba(skeletonFrom, .5)
906
- }
907
- };
908
- },
909
- muted: ({ base, dark, name, state, tone }) => {
910
- let mix = dark ? screen$1 : multiply$1, defaultTints = tones[name] || tones.default, isNeutral = NEUTRAL_TONES.has(name) && NEUTRAL_TONES.has(tone), tints = tones[tone === "default" ? name : tone] || defaultTints;
911
- if (state === "disabled") {
912
- tints = defaultTints;
913
- let bg = base.bg, skeletonFrom = mix(bg, tints[dark ? 900 : 100].hex);
914
- return {
915
- bg,
916
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
917
- border: mix(bg, tints[dark ? 950 : 50].hex),
918
- fg: mix(bg, tints[dark ? 800 : 200].hex),
919
- icon: mix(bg, tints[dark ? 800 : 200].hex),
920
- muted: { fg: mix(bg, tints[dark ? 900 : 100].hex) },
921
- accent: { fg: mix(bg, tints[dark ? 900 : 100].hex) },
922
- link: { fg: mix(bg, tints[dark ? 900 : 100].hex) },
923
- code: {
924
- bg,
925
- fg: mix(bg, tints[dark ? 900 : 100].hex)
926
- },
927
- skeleton: {
928
- from: rgba(skeletonFrom, .5),
929
- to: rgba(skeletonFrom, .25)
930
- }
931
- };
932
- }
933
- if (state === "hovered") {
934
- isNeutral && (tints = tones.primary);
935
- let bg = mix(base.bg, tints[dark ? 950 : 50].hex), skeletonFrom = mix(bg, tints[dark ? 900 : 100].hex);
936
- return {
937
- bg,
938
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
939
- border: mix(bg, tints[dark ? 900 : 100].hex),
940
- fg: mix(base.bg, tints[dark ? 200 : 800].hex),
941
- icon: mix(base.bg, tints[dark ? 200 : 800].hex),
942
- muted: { fg: mix(base.bg, tints[dark ? 400 : 600].hex) },
943
- accent: { fg: mix(base.bg, linkHue[dark ? 400 : 500].hex) },
944
- link: { fg: mix(base.bg, linkHue[dark ? 400 : 600].hex) },
945
- code: {
946
- bg: mix(bg, tints[dark ? 950 : 50].hex),
947
- fg: mix(base.bg, tints[dark ? 400 : 600].hex)
948
- },
949
- skeleton: {
950
- from: skeletonFrom,
951
- to: rgba(skeletonFrom, .5)
952
- }
953
- };
954
- }
955
- if (state === "pressed") {
956
- isNeutral && (tints = tones.primary);
957
- let bg = mix(base.bg, tints[dark ? 900 : 100].hex), skeletonFrom = mix(bg, tints[dark ? 900 : 100].hex);
958
- return {
959
- bg,
960
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
961
- border: mix(bg, tints[dark ? 900 : 100].hex),
962
- fg: mix(base.bg, tints[dark ? 200 : 800].hex),
963
- icon: mix(base.bg, tints[dark ? 200 : 800].hex),
964
- muted: { fg: mix(base.bg, tints[dark ? 400 : 600].hex) },
965
- accent: { fg: mix(bg, accentHue[dark ? 400 : 500].hex) },
966
- link: { fg: mix(bg, linkHue[dark ? 400 : 600].hex) },
967
- code: {
968
- bg: mix(bg, tints[dark ? 950 : 50].hex),
969
- fg: mix(base.bg, tints[dark ? 400 : 600].hex)
970
- },
971
- skeleton: {
972
- from: skeletonFrom,
973
- to: rgba(skeletonFrom, .5)
974
- }
975
- };
976
- }
977
- if (state === "selected") {
978
- isNeutral && (tints = tones.primary);
979
- let bg = mix(base.bg, tints[dark ? 900 : 100].hex), skeletonFrom = mix(bg, tints[dark ? 900 : 100].hex);
980
- return {
981
- bg,
982
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
983
- border: mix(bg, tints[dark ? 900 : 100].hex),
984
- fg: mix(base.bg, tints[dark ? 200 : 800].hex),
985
- icon: mix(base.bg, tints[dark ? 200 : 800].hex),
986
- muted: { fg: mix(base.bg, tints[dark ? 400 : 600].hex) },
987
- accent: { fg: mix(bg, accentHue[dark ? 400 : 500].hex) },
988
- link: { fg: mix(bg, linkHue[dark ? 400 : 600].hex) },
989
- code: {
990
- bg: mix(bg, tints[dark ? 950 : 50].hex),
991
- fg: mix(base.bg, tints[dark ? 400 : 600].hex)
992
- },
993
- skeleton: {
994
- from: skeletonFrom,
995
- to: rgba(skeletonFrom, .5)
996
- }
997
- };
998
- }
999
- let bg = base.bg, skeletonFrom = mix(bg, tints[dark ? 900 : 100].hex);
1000
- return {
1001
- bg,
1002
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
1003
- border: mix(bg, tints[dark ? 900 : 100].hex),
1004
- fg: mix(base.bg, tints[dark ? 300 : 700].hex),
1005
- icon: mix(base.bg, tints[dark ? 300 : 700].hex),
1006
- muted: { fg: mix(base.bg, tints[dark ? 400 : 600].hex) },
1007
- accent: { fg: mix(base.bg, accentHue[dark ? 400 : 500].hex) },
1008
- link: { fg: mix(base.bg, linkHue[dark ? 400 : 600].hex) },
1009
- code: {
1010
- bg: mix(base.bg, tints[dark ? 950 : 50].hex),
1011
- fg: mix(base.bg, tints[dark ? 400 : 600].hex)
1012
- },
1013
- skeleton: {
1014
- from: skeletonFrom,
1015
- to: rgba(skeletonFrom, .5)
1016
- }
1017
- };
1018
- },
1019
- button: ({ base, mode, muted, solid }) => mode === "bleed" ? {
1020
- enabled: {
1021
- ...muted.enabled,
1022
- border: muted.enabled.bg
1023
- },
1024
- hovered: {
1025
- ...muted.hovered,
1026
- border: muted.hovered.bg
1027
- },
1028
- pressed: {
1029
- ...muted.pressed,
1030
- border: muted.pressed.bg
1031
- },
1032
- selected: {
1033
- ...muted.selected,
1034
- border: muted.selected.bg
1035
- },
1036
- disabled: {
1037
- ...muted.disabled,
1038
- border: muted.disabled.bg
1039
- }
1040
- } : mode === "ghost" ? {
1041
- ...solid,
1042
- enabled: {
1043
- ...muted.enabled,
1044
- border: base.border
1045
- },
1046
- disabled: muted.disabled
1047
- } : solid,
1048
- card: ({ base, dark, muted, name, solid, state }) => {
1049
- if (state === "hovered") return muted[name].hovered;
1050
- if (state === "disabled") return muted[name].disabled;
1051
- let isNeutral = NEUTRAL_TONES.has(name), tints = tones[name] || tones.default, mix = dark ? screen$1 : multiply$1;
1052
- if (state === "pressed") return isNeutral ? muted.primary.pressed : muted[name].pressed;
1053
- if (state === "selected") return isNeutral ? solid.primary.enabled : solid[name].enabled;
1054
- let bg = base.bg, skeletonFrom = mix(base.bg, tints[dark ? 900 : 100].hex);
1055
- return {
1056
- bg,
1057
- bg2: mix(bg, tints[dark ? 950 : 50].hex),
1058
- fg: base.fg,
1059
- icon: base.fg,
1060
- border: base.border,
1061
- muted: { fg: mix(base.bg, tints[dark ? 400 : 600].hex) },
1062
- accent: { fg: mix(base.bg, red[dark ? 400 : 500].hex) },
1063
- link: { fg: mix(base.bg, blue[dark ? 400 : 600].hex) },
1064
- code: {
1065
- bg: mix(base.bg, tints[dark ? 950 : 50].hex),
1066
- fg: tints[dark ? 400 : 600].hex
1067
- },
1068
- skeleton: {
1069
- from: skeletonFrom,
1070
- to: rgba(skeletonFrom, .5)
1071
- }
1072
- };
1073
- },
1074
- input: ({ base, dark, mode, state }) => {
1075
- let mix = dark ? screen$1 : multiply$1;
1076
- if (mode === "invalid") {
1077
- let tints = tones.critical;
1078
- return {
1079
- bg: mix(base.bg, tints[dark ? 950 : 50].hex),
1080
- bg2: mix(base.bg, tints[dark ? 800 : 200].hex),
1081
- fg: mix(base.bg, tints[dark ? 400 : 600].hex),
1082
- border: mix(base.bg, tints[dark ? 800 : 200].hex),
1083
- placeholder: mix(base.bg, tints[dark ? 600 : 400].hex)
1084
- };
1085
- }
1086
- return state === "hovered" ? {
1087
- bg: base.bg,
1088
- bg2: mix(base.bg, gray[dark ? 700 : 300].hex),
1089
- fg: base.fg,
1090
- border: mix(base.bg, gray[dark ? 700 : 300].hex),
1091
- placeholder: mix(base.bg, gray[dark ? 600 : 400].hex)
1092
- } : state === "disabled" ? {
1093
- bg: mix(base.bg, gray[dark ? 950 : 50].hex),
1094
- bg2: mix(base.bg, gray[dark ? 900 : 100].hex),
1095
- fg: mix(base.bg, gray[dark ? 700 : 300].hex),
1096
- border: mix(base.bg, gray[dark ? 900 : 100].hex),
1097
- placeholder: mix(base.bg, gray[dark ? 800 : 200].hex)
1098
- } : state === "readOnly" ? {
1099
- bg: mix(base.bg, gray[dark ? 950 : 50].hex),
1100
- bg2: mix(base.bg, gray[dark ? 800 : 200].hex),
1101
- fg: mix(base.bg, gray[dark ? 200 : 800].hex),
1102
- border: mix(base.bg, gray[dark ? 800 : 200].hex),
1103
- placeholder: mix(base.bg, gray[dark ? 600 : 400].hex)
1104
- } : {
1105
- bg: base.bg,
1106
- bg2: base.border,
1107
- fg: base.fg,
1108
- border: base.border,
1109
- placeholder: mix(base.bg, gray[dark ? 600 : 400].hex)
1110
- };
1111
- },
1112
- selectable: ({ base, muted, tone, solid, state }) => state === "enabled" ? {
1113
- ...muted[tone].enabled,
1114
- bg: base.bg
1115
- } : state === "pressed" ? tone === "default" ? muted.primary.pressed : muted[tone].pressed : state === "selected" ? tone === "default" ? solid.primary.enabled : solid[tone].enabled : state === "disabled" ? {
1116
- ...muted[tone].disabled,
1117
- bg: base.bg
1118
- } : muted[tone][state],
1119
- spot: ({ base, dark, key }) => (dark ? screen$1 : multiply$1)(base.bg, getTint(key)[dark ? 400 : 500].hex),
1120
- syntax: ({ base, dark }) => {
1121
- let mix = dark ? screen$1 : multiply$1, mainShade = dark ? 400 : 600, secondaryShade = dark ? 600 : 400;
1122
- return {
1123
- atrule: mix(base.bg, purple[mainShade].hex),
1124
- attrName: mix(base.bg, green[mainShade].hex),
1125
- attrValue: mix(base.bg, yellow[mainShade].hex),
1126
- attribute: mix(base.bg, yellow[mainShade].hex),
1127
- boolean: mix(base.bg, purple[mainShade].hex),
1128
- builtin: mix(base.bg, purple[mainShade].hex),
1129
- cdata: mix(base.bg, yellow[mainShade].hex),
1130
- char: mix(base.bg, yellow[mainShade].hex),
1131
- class: mix(base.bg, orange[mainShade].hex),
1132
- className: mix(base.bg, cyan[mainShade].hex),
1133
- comment: mix(base.bg, gray[secondaryShade].hex),
1134
- constant: mix(base.bg, purple[mainShade].hex),
1135
- deleted: mix(base.bg, red[mainShade].hex),
1136
- doctype: mix(base.bg, gray[secondaryShade].hex),
1137
- entity: mix(base.bg, red[mainShade].hex),
1138
- function: mix(base.bg, green[mainShade].hex),
1139
- hexcode: mix(base.bg, blue[mainShade].hex),
1140
- id: mix(base.bg, purple[mainShade].hex),
1141
- important: mix(base.bg, purple[mainShade].hex),
1142
- inserted: mix(base.bg, yellow[mainShade].hex),
1143
- keyword: mix(base.bg, magenta[mainShade].hex),
1144
- number: mix(base.bg, purple[mainShade].hex),
1145
- operator: mix(base.bg, magenta[mainShade].hex),
1146
- prolog: mix(base.bg, gray[secondaryShade].hex),
1147
- property: mix(base.bg, blue[mainShade].hex),
1148
- pseudoClass: mix(base.bg, yellow[mainShade].hex),
1149
- pseudoElement: mix(base.bg, yellow[mainShade].hex),
1150
- punctuation: mix(base.bg, gray[mainShade].hex),
1151
- regex: mix(base.bg, blue[mainShade].hex),
1152
- selector: mix(base.bg, red[mainShade].hex),
1153
- string: mix(base.bg, yellow[mainShade].hex),
1154
- symbol: mix(base.bg, purple[mainShade].hex),
1155
- tag: mix(base.bg, red[mainShade].hex),
1156
- unit: mix(base.bg, orange[mainShade].hex),
1157
- url: mix(base.bg, red[mainShade].hex),
1158
- variable: mix(base.bg, red[mainShade].hex)
1159
- };
1160
- }
1161
- });
1162
- return {
1163
- ...defaultTheme,
1164
- color,
1165
- v2: void 0
1166
- };
1167
- }
1168
- /**
1169
- * Generates a Studio theme from hues, producing the same colors as importing
1170
- * the theme from the hosted Themer service (themer.sanity.build):
1171
- *
1172
- * ```ts
1173
- * import {createTheme, hues} from '@sanity/themer/legacy'
1174
- * import {defineConfig} from 'sanity'
1175
- *
1176
- * export default defineConfig({
1177
- * theme: createTheme({...hues, primary: {...hues.primary, mid: '#22fca8'}}),
1178
- * // ...rest of the config
1179
- * })
1180
- * ```
1181
- *
1182
- * @public
1183
- */
1184
- function createTheme(hues = {}) {
1185
- return themeFromHues(hues);
1186
- }
1187
- /**
1188
- * Parses the hues encoded in a hosted Themer service URL, returning the exact
1189
- * hues that `https://themer.sanity.build/api/hues` served for that query —
1190
- * presets and overrides included.
1191
- *
1192
- * ```ts
1193
- * import {createTheme, parseHuesFromUrl} from '@sanity/themer/legacy'
1194
- *
1195
- * const hues = parseHuesFromUrl(
1196
- * 'https://themer.sanity.build/api/hues?preset=verdant&primary=22fca8',
1197
- * )
1198
- * const theme = createTheme(hues)
1199
- * ```
1200
- *
1201
- * @public
1202
- */
1203
- function parseHuesFromUrl(url) {
1204
- let { searchParams } = new URL(url, "https://themer.sanity.build/api/hues"), preset = getPreset(searchParams.get("preset"));
1205
- return applyHues(parseHuesFromSearchParams(searchParams), preset.hues);
1206
- }
1207
- /**
1208
- * The one-line replacement for a theme imported from the hosted Themer
1209
- * service — pass the URL that used to be imported:
1210
- *
1211
- * ```ts
1212
- * // Before:
1213
- * // import {theme} from 'https://themer.sanity.build/api/hues?preset=verdant'
1214
- *
1215
- * // After:
1216
- * import {buildThemeFromUrl} from '@sanity/themer/legacy'
1217
- *
1218
- * const theme = buildThemeFromUrl(
1219
- * 'https://themer.sanity.build/api/hues?preset=verdant',
1220
- * )
1221
- * ```
1222
- *
1223
- * @public
1224
- */
1225
- function buildThemeFromUrl(url) {
1226
- return createTheme(parseHuesFromUrl(url));
1227
- }
1228
- /**
1229
- * The hues of the default Studio theme — the same `hues` export that
1230
- * `https://themer.sanity.build/api/hues` served without any parameters.
1231
- *
1232
- * @public
1233
- */
1234
- const hues = applyHues({}), theme = createTheme(hues);
1235
- export { parseHuesFromUrl as a, isColor as c, createTheme as i, applyHues as l, theme as n, createTonesFromHues as o, buildThemeFromUrl as r, presets as s, hues as t };
1236
-
1237
- //# sourceMappingURL=defaults-DJtuhI2W.js.map