@sanity/themer 0.8.1 → 0.10.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,32 +1,34 @@
1
- import { c as resolveThemeOptions, l as isColor, n as buildTheme, o as SCHEMES, r as buildPalette } from "./presets-CqBgS3A-.js";
2
- import { _ as titleFromFileName, c as minimizeOptions, d as IMAGE_PALETTE_VARIANTS, f as applyImagePalette, g as pickLuckyVariant, h as optionsFromImagePalette, i as displayTitle, m as extractImagePalette, p as currentImageVariant, u as IMAGE_PALETTE_TITLES, y as useThemer } from "./ResizableSidebar.css.ts.vanilla-M9EuPu-q.js";
1
+ import { a as DEFAULT_BACKGROUND, c as resolveThemeOptions, d as hslToHex, f as relativeLuminance, i as DEFAULT_ACCENT, l as isColor, n as buildTheme, o as SCHEMES, r as buildPalette, s as deriveTextColor, u as hexToHsl } from "./presets-CqBgS3A-.js";
2
+ import { a as displayTitle, c as resolveThemes, l as addThemerTransitionType, n as CONFIG_TITLE, t as CONFIG_SLUG } from "./themes-au1BLKmY.js";
3
3
  import { c } from "react/compiler-runtime";
4
4
  import { useColorSchemeValue } from "sanity";
5
- import { Badge, Box, Button, Card, Dialog, Flex, Layer, Stack, Text, TextInput, ThemeProvider, useRootTheme, useTheme_v2 } from "@sanity/ui";
6
- import { createContext, useContext, useEffect, useRef, useState } from "react";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { Badge, BoundaryElementProvider, Box, Button, Card, Dialog, Flex, Layer, Stack, Text, TextInput, ThemeProvider, useMediaIndex, useRootTheme, useTheme_v2 } from "@sanity/ui";
8
6
  import { Tooltip } from "@sanity/ui/tooltip";
7
+ import { Activity, createContext, startTransition, useContext, useEffect, useId, useRef, useState } from "react";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import { dequal } from "dequal/lite";
10
+ import { useSelector } from "@xstate/react";
9
11
  import { MotionConfig, Reorder, useDragControls } from "motion/react";
10
- import { ArrowLeftIcon } from "@sanity/icons/ArrowLeft";
11
12
  import { CloseIcon } from "@sanity/icons/Close";
12
- import { CodeBlockIcon } from "@sanity/icons/CodeBlock";
13
13
  import { SplitVerticalIcon } from "@sanity/icons/SplitVertical";
14
+ import { CheckmarkIcon } from "@sanity/icons/Checkmark";
14
15
  import { assignInlineVars } from "@vanilla-extract/dynamic";
16
+ import { EllipsisHorizontalIcon } from "@sanity/icons/EllipsisHorizontal";
15
17
  import { ResetIcon } from "@sanity/icons/Reset";
16
18
  import { TrashIcon } from "@sanity/icons/Trash";
19
+ import { Menu, MenuButton, MenuDivider, MenuItem } from "@sanity/ui/menu";
17
20
  import { SparklesIcon } from "@sanity/icons/Sparkles";
18
21
  import { ImageIcon } from "@sanity/icons/Image";
19
22
  import { useToast } from "@sanity/ui/toast";
20
23
  import { AddIcon } from "@sanity/icons/Add";
21
24
  import { ClipboardIcon } from "@sanity/icons/Clipboard";
25
+ import { CodeBlockIcon } from "@sanity/icons/CodeBlock";
26
+ import { CopyIcon } from "@sanity/icons/Copy";
27
+ import { EditIcon } from "@sanity/icons/Edit";
22
28
  import { RestoreIcon } from "@sanity/icons/Restore";
23
29
  import { ArrowDownIcon } from "@sanity/icons/ArrowDown";
24
30
  import { ArrowUpIcon } from "@sanity/icons/ArrowUp";
25
- import { CopyIcon } from "@sanity/icons/Copy";
26
- import { EditIcon } from "@sanity/icons/Edit";
27
- import { EllipsisHorizontalIcon } from "@sanity/icons/EllipsisHorizontal";
28
31
  import { ShareIcon } from "@sanity/icons/Share";
29
- import { Menu, MenuButton, MenuDivider, MenuItem } from "@sanity/ui/menu";
30
32
  import scrollIntoView from "scroll-into-view-if-needed";
31
33
  import { Code } from "@sanity/ui/code";
32
34
  import { registerLanguage } from "react-refractor";
@@ -55,7 +57,7 @@ let lastGutter = 0;
55
57
  * @internal
56
58
  */
57
59
  function ScrollArea(props) {
58
- let $ = c(15), { children, padding } = props, { space } = useTheme_v2(), ref = useRef(null), [gutter, setGutter] = useState(_temp$6), t0, t1;
60
+ let $ = c(15), { children, padding } = props, { space } = useTheme_v2(), ref = useRef(null), [gutter, setGutter] = useState(_temp$8), t0, t1;
59
61
  $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => {
60
62
  let element = ref.current;
61
63
  if (!element) return;
@@ -75,7 +77,7 @@ function ScrollArea(props) {
75
77
  let inset = t5, t6;
76
78
  $[6] === inset.right ? t6 = $[7] : (t6 = { paddingRight: inset.right }, $[6] = inset.right, $[7] = t6);
77
79
  let t7;
78
- $[8] !== children || $[9] !== inset ? (t7 = /* @__PURE__ */ jsx(ScrollAreaInsetContext.Provider, {
80
+ $[8] !== children || $[9] !== inset ? (t7 = /* @__PURE__ */ jsx(ScrollAreaInsetContext, {
79
81
  value: inset,
80
82
  children
81
83
  }), $[8] = children, $[9] = inset, $[10] = t7) : t7 = $[10];
@@ -90,7 +92,7 @@ function ScrollArea(props) {
90
92
  children: t7
91
93
  }), $[11] = padding, $[12] = t6, $[13] = t7, $[14] = t8) : t8 = $[14], t8;
92
94
  }
93
- function _temp$6() {
95
+ function _temp$8() {
94
96
  return lastGutter;
95
97
  }
96
98
  /**
@@ -210,7 +212,7 @@ function MockStudio(props) {
210
212
  let t4;
211
213
  $[13] === Symbol.for("react.memo_cache_sentinel") ? (t4 = /* @__PURE__ */ jsx("div", {
212
214
  className: list,
213
- children: LIST_ROWS.map(_temp$5)
215
+ children: LIST_ROWS.map(_temp$7)
214
216
  }), $[13] = t4) : t4 = $[13];
215
217
  let t5;
216
218
  $[14] === Symbol.for("react.memo_cache_sentinel") ? (t5 = /* @__PURE__ */ jsxs("div", {
@@ -218,7 +220,7 @@ function MockStudio(props) {
218
220
  children: [/* @__PURE__ */ jsx("div", {
219
221
  className: line.fg,
220
222
  style: { width: "45%" }
221
- }), FIELDS$1.map(_temp2)]
223
+ }), FIELDS$1.map(_temp2$1)]
222
224
  }), $[14] = t5) : t5 = $[14];
223
225
  let t6;
224
226
  $[15] === Symbol.for("react.memo_cache_sentinel") ? (t6 = /* @__PURE__ */ jsxs("div", {
@@ -238,7 +240,7 @@ function MockStudio(props) {
238
240
  children: [t3, t6]
239
241
  }), $[16] = t0, $[17] = t1, $[18] = t7) : t7 = $[18], t7;
240
242
  }
241
- function _temp2(width_0) {
243
+ function _temp2$1(width_0) {
242
244
  return /* @__PURE__ */ jsxs("div", {
243
245
  className: field,
244
246
  children: [/* @__PURE__ */ jsx("div", {
@@ -247,7 +249,7 @@ function _temp2(width_0) {
247
249
  }), /* @__PURE__ */ jsx("div", { className: input })]
248
250
  }, width_0);
249
251
  }
250
- function _temp$5(width, index) {
252
+ function _temp$7(width, index) {
251
253
  let isSelected = index === 1;
252
254
  return /* @__PURE__ */ jsx("div", {
253
255
  className: listRow,
@@ -277,16 +279,17 @@ var removedThumbnail = "_1vdkp0v0";
277
279
  /**
278
280
  * The flow for restoring removed themes: the presets and custom themes the
279
281
  * user took out of the list, each with a button to put it back — and, for
280
- * custom themes, one to delete it for good. The machine leaves the flow once
281
- * the last one is gone.
282
+ * custom themes, one to delete it for good. The footer leads back to the
283
+ * list, and the machine leaves the flow on its own once the last theme is
284
+ * gone.
282
285
  *
283
286
  * @internal
284
287
  */
285
- function RemovedThemes() {
286
- let $ = c(7), { removed, send } = useThemer(), t0;
287
- if ($[0] !== removed || $[1] !== send) {
288
- let t1;
289
- $[3] === send ? t1 = $[4] : (t1 = (theme) => /* @__PURE__ */ jsxs(Stack, {
288
+ function RemovedThemes(t0) {
289
+ let $ = c(12), { actorRef, removed } = t0, t1;
290
+ if ($[0] !== actorRef || $[1] !== removed) {
291
+ let t2;
292
+ $[3] === actorRef ? t2 = $[4] : (t2 = (theme) => /* @__PURE__ */ jsxs(Stack, {
290
293
  gap: 3,
291
294
  children: [
292
295
  /* @__PURE__ */ jsx(Box, {
@@ -304,7 +307,7 @@ function RemovedThemes() {
304
307
  justify: "center",
305
308
  children: [/* @__PURE__ */ jsx(Button, {
306
309
  mode: "ghost",
307
- onClick: () => send({
310
+ onClick: () => actorRef.send({
308
311
  type: "theme.restore",
309
312
  slug: theme.slug
310
313
  }),
@@ -312,7 +315,7 @@ function RemovedThemes() {
312
315
  text: "Restore"
313
316
  }), theme.source === "custom" && /* @__PURE__ */ jsx(Button, {
314
317
  mode: "ghost",
315
- onClick: () => send({
318
+ onClick: () => actorRef.send({
316
319
  type: "theme.delete",
317
320
  slug: theme.slug
318
321
  }),
@@ -322,16 +325,331 @@ function RemovedThemes() {
322
325
  })]
323
326
  })
324
327
  ]
325
- }, theme.slug), $[3] = send, $[4] = t1), t0 = removed.map(t1), $[0] = removed, $[1] = send, $[2] = t0;
326
- } else t0 = $[2];
327
- let t1;
328
- return $[5] === t0 ? t1 = $[6] : (t1 = /* @__PURE__ */ jsx(ScrollArea, {
328
+ }, theme.slug), $[3] = actorRef, $[4] = t2), t1 = removed.map(t2), $[0] = actorRef, $[1] = removed, $[2] = t1;
329
+ } else t1 = $[2];
330
+ let t2;
331
+ $[5] === t1 ? t2 = $[6] : (t2 = /* @__PURE__ */ jsx(ScrollArea, {
329
332
  padding: 3,
330
333
  children: /* @__PURE__ */ jsx(Stack, {
331
334
  gap: 5,
332
- children: t0
335
+ children: t1
336
+ })
337
+ }), $[5] = t1, $[6] = t2);
338
+ let t3;
339
+ $[7] === actorRef ? t3 = $[8] : (t3 = /* @__PURE__ */ jsx(Card, {
340
+ borderTop: !0,
341
+ padding: 3,
342
+ children: /* @__PURE__ */ jsx(Flex, {
343
+ justify: "flex-end",
344
+ children: /* @__PURE__ */ jsx(Button, {
345
+ gap: 2,
346
+ icon: CheckmarkIcon,
347
+ onClick: () => actorRef.send({ type: "flow.list" }),
348
+ padding: 2,
349
+ text: "Done",
350
+ mode: "ghost"
351
+ })
333
352
  })
334
- }), $[5] = t0, $[6] = t1), t1;
353
+ }), $[7] = actorRef, $[8] = t3);
354
+ let t4;
355
+ return $[9] !== t2 || $[10] !== t3 ? (t4 = /* @__PURE__ */ jsxs(Fragment, { children: [t2, t3] }), $[9] = t2, $[10] = t3, $[11] = t4) : t4 = $[11], t4;
356
+ }
357
+ /** The variants in the order the tool offers them @internal */
358
+ const IMAGE_PALETTE_VARIANTS = [
359
+ "muted",
360
+ "vibrant",
361
+ "lightMuted",
362
+ "lightVibrant",
363
+ "darkMuted",
364
+ "darkVibrant"
365
+ ], IMAGE_PALETTE_TITLES = {
366
+ dominant: "Dominant",
367
+ vibrant: "Vibrant",
368
+ lightVibrant: "Light vibrant",
369
+ darkVibrant: "Dark vibrant",
370
+ muted: "Muted",
371
+ lightMuted: "Light muted",
372
+ darkMuted: "Dark muted"
373
+ }, TARGETS = [
374
+ ["vibrant", {
375
+ lightness: [
376
+ .5,
377
+ .3,
378
+ .7
379
+ ],
380
+ saturation: [
381
+ 1,
382
+ .35,
383
+ 1
384
+ ]
385
+ }],
386
+ ["lightVibrant", {
387
+ lightness: [
388
+ .74,
389
+ .55,
390
+ 1
391
+ ],
392
+ saturation: [
393
+ 1,
394
+ .35,
395
+ 1
396
+ ]
397
+ }],
398
+ ["darkVibrant", {
399
+ lightness: [
400
+ .26,
401
+ 0,
402
+ .45
403
+ ],
404
+ saturation: [
405
+ 1,
406
+ .35,
407
+ 1
408
+ ]
409
+ }],
410
+ ["muted", {
411
+ lightness: [
412
+ .5,
413
+ .3,
414
+ .7
415
+ ],
416
+ saturation: [
417
+ .3,
418
+ 0,
419
+ .4
420
+ ]
421
+ }],
422
+ ["lightMuted", {
423
+ lightness: [
424
+ .74,
425
+ .55,
426
+ 1
427
+ ],
428
+ saturation: [
429
+ .3,
430
+ 0,
431
+ .4
432
+ ]
433
+ }],
434
+ ["darkMuted", {
435
+ lightness: [
436
+ .26,
437
+ 0,
438
+ .45
439
+ ],
440
+ saturation: [
441
+ .3,
442
+ 0,
443
+ .4
444
+ ]
445
+ }]
446
+ ];
447
+ /**
448
+ * Extracts the color palette of an image from its pixels, the way the Vibrant
449
+ * algorithm does: the colors are quantized into a coarse histogram, and each
450
+ * swatch claims the color that comes closest to its target lightness and
451
+ * saturation — weighted by how much of the image it covers — that no other
452
+ * swatch has claimed yet. The dominant swatch is simply the most common
453
+ * color. Runs anywhere pixels come from, so it can run on device.
454
+ *
455
+ * @internal
456
+ */
457
+ function extractImagePalette(pixels) {
458
+ let candidates = quantize(pixels), palette = {
459
+ dominant: null,
460
+ vibrant: null,
461
+ lightVibrant: null,
462
+ darkVibrant: null,
463
+ muted: null,
464
+ lightMuted: null,
465
+ darkMuted: null
466
+ };
467
+ if (candidates.length === 0) return palette;
468
+ let maximumPopulation = Math.max(...candidates.map((candidate) => candidate.population)), claimed = /* @__PURE__ */ new Set();
469
+ for (let [key, target] of TARGETS) {
470
+ let best = null, bestScore = -Infinity;
471
+ for (let candidate of candidates) {
472
+ if (claimed.has(candidate.hex) || !matchesTarget(candidate, target)) continue;
473
+ let score = scoreCandidate(candidate, target, maximumPopulation);
474
+ score > bestScore && (best = candidate, bestScore = score);
475
+ }
476
+ best && (palette[key] = best.hex, claimed.add(best.hex));
477
+ }
478
+ return palette.dominant = candidates.reduce((most, candidate) => candidate.population > most.population ? candidate : most).hex, palette;
479
+ }
480
+ /**
481
+ * Turns the pixels into a histogram of quantized colors, each averaged over
482
+ * the pixels it stands for, leaving out transparent pixels and the near-black
483
+ * and near-white ones that are backdrop rather than color.
484
+ */
485
+ function quantize(pixels) {
486
+ let { data } = pixels, buckets = /* @__PURE__ */ new Map(), length = Math.min(data.length, pixels.width * pixels.height * 4);
487
+ for (let offset = 0; offset + 3 < length; offset += 4) {
488
+ let r = data[offset], g = data[offset + 1], b = data[offset + 2];
489
+ if (data[offset + 3] < 125) continue;
490
+ let lightness = (Math.max(r, g, b) + Math.min(r, g, b)) / 510;
491
+ if (lightness < .05 || lightness > .95) continue;
492
+ let key = r >> 3 << 10 | g >> 3 << 5 | b >> 3, bucket = buckets.get(key);
493
+ bucket ? (bucket.count++, bucket.r += r, bucket.g += g, bucket.b += b) : buckets.set(key, {
494
+ count: 1,
495
+ r,
496
+ g,
497
+ b
498
+ });
499
+ }
500
+ let candidates = [];
501
+ for (let bucket of buckets.values()) {
502
+ let r = Math.round(bucket.r / bucket.count), g = Math.round(bucket.g / bucket.count), b = Math.round(bucket.b / bucket.count), { saturation, lightness } = saturationAndLightness(r, g, b);
503
+ candidates.push({
504
+ hex: rgbToHex(r, g, b),
505
+ population: bucket.count,
506
+ saturation,
507
+ lightness
508
+ });
509
+ }
510
+ return candidates;
511
+ }
512
+ function matchesTarget(candidate, target) {
513
+ return candidate.lightness >= target.lightness[1] && candidate.lightness <= target.lightness[2] && candidate.saturation >= target.saturation[1] && candidate.saturation <= target.saturation[2];
514
+ }
515
+ function scoreCandidate(candidate, target, maximumPopulation) {
516
+ return 3 * (1 - Math.abs(candidate.saturation - target.saturation[0])) + 6.5 * (1 - Math.abs(candidate.lightness - target.lightness[0])) + .5 * (candidate.population / maximumPopulation);
517
+ }
518
+ function saturationAndLightness(r, g, b) {
519
+ let max = Math.max(r, g, b) / 255, min = Math.min(r, g, b) / 255, lightness = (max + min) / 2, delta = max - min;
520
+ return {
521
+ saturation: delta === 0 ? 0 : lightness > .5 ? delta / (2 - max - min) : delta / (max + min),
522
+ lightness
523
+ };
524
+ }
525
+ function rgbToHex(r, g, b) {
526
+ return `#${[
527
+ r,
528
+ g,
529
+ b
530
+ ].map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
531
+ }
532
+ /** Reads `#rgb` and `#rrggbb` alike — stored palettes may hold either */
533
+ function hexToRgb(hex) {
534
+ let expanded = hex.length === 4 ? `${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex.slice(1);
535
+ return [
536
+ parseInt(expanded.slice(0, 2), 16),
537
+ parseInt(expanded.slice(2, 4), 16),
538
+ parseInt(expanded.slice(4, 6), 16)
539
+ ];
540
+ }
541
+ /** Mixes `amount` of `color` into `base` */
542
+ function tint(base, color, amount) {
543
+ let [r1, g1, b1] = hexToRgb(base), [r2, g2, b2] = hexToRgb(color);
544
+ return rgbToHex(Math.round(r1 + (r2 - r1) * amount), Math.round(g1 + (g2 - g1) * amount), Math.round(b1 + (b2 - b1) * amount));
545
+ }
546
+ /** How much of the palette tints each scheme's stock background */
547
+ const BACKGROUND_TINT = {
548
+ light: .08,
549
+ dark: .3
550
+ }, BUTTON_LABEL = {
551
+ light: "#ffffff",
552
+ dark: "#000000"
553
+ }, ACCENT_LIGHTNESS_STEP = .01;
554
+ function contrastRatio(a, b) {
555
+ let [lighter, darker] = [relativeLuminance(a), relativeLuminance(b)].sort((x, y) => y - x);
556
+ return (lighter + .05) / (darker + .05);
557
+ }
558
+ /**
559
+ * Makes an accent readable as a button in the given scheme: a light scheme
560
+ * accent is darkened until white text on it reaches AA contrast, a dark
561
+ * scheme accent lightened until black text does — as far as the accent's
562
+ * hue and saturation allow. Accents that already pass come back untouched.
563
+ *
564
+ * @internal
565
+ */
566
+ function readableAccent(hex, scheme) {
567
+ let label = BUTTON_LABEL[scheme], { h, s } = hexToHsl(hex), { l } = hexToHsl(hex), current = hex;
568
+ for (; contrastRatio(current, label) < 4.5;) {
569
+ let next = scheme === "light" ? l - ACCENT_LIGHTNESS_STEP : l + ACCENT_LIGHTNESS_STEP;
570
+ if (next < 0 || next > 1) break;
571
+ l = next, current = hslToHex({
572
+ h,
573
+ s,
574
+ l
575
+ });
576
+ }
577
+ return current;
578
+ }
579
+ /** The accent a variant gives a scheme, made readable on a button */
580
+ function variantAccent(palette, variant, scheme) {
581
+ let swatch = (variant ? palette[variant] : null) ?? palette.vibrant ?? (scheme === "light" ? palette.darkVibrant : palette.lightVibrant) ?? palette.dominant;
582
+ return swatch === null ? null : readableAccent(swatch, scheme);
583
+ }
584
+ /**
585
+ * Derives theme options from an image palette: the accent of both schemes is
586
+ * the swatch of the chosen variant — or, without one, the vibrant swatch,
587
+ * each scheme falling back to the vibrant swatch of its own end of the scale —
588
+ * adjusted until it is readable as a button. The muted swatch becomes the text color, and the light and dark muted
589
+ * swatches tint the stock backgrounds of their scheme — enough to carry the
590
+ * image's tone without giving up a usable canvas. Whatever the palette lacks
591
+ * stays at the theme defaults.
592
+ *
593
+ * @internal
594
+ */
595
+ function optionsFromImagePalette(palette, variant) {
596
+ let options = {}, light = schemeFromPalette(variantAccent(palette, variant ?? null, "light"), palette.muted ?? palette.darkMuted, palette.lightMuted ?? palette.muted ?? palette.lightVibrant, "light"), dark = schemeFromPalette(variantAccent(palette, variant ?? null, "dark"), palette.muted ?? palette.lightMuted, palette.darkMuted ?? palette.muted ?? palette.darkVibrant, "dark");
597
+ return light && (options.light = light), dark && (options.dark = dark), options;
598
+ }
599
+ function schemeFromPalette(accent, text, backgroundTint, scheme) {
600
+ let options = {};
601
+ return accent && (options.accent = accent), text && (options.text = text), backgroundTint && (options.background = tint(DEFAULT_BACKGROUND[scheme], backgroundTint, BACKGROUND_TINT[scheme])), Object.keys(options).length > 0 ? options : null;
602
+ }
603
+ /**
604
+ * Applies an image palette to existing theme options: the colors the palette
605
+ * provides replace the current ones scheme by scheme, and whatever it does
606
+ * not touch — like the contrast — stays as it is.
607
+ *
608
+ * @internal
609
+ */
610
+ function applyImagePalette(options, palette, variant) {
611
+ let derived = optionsFromImagePalette(palette, variant), next = { ...options };
612
+ for (let scheme of SCHEMES) derived[scheme] && (next[scheme] = {
613
+ ...options[scheme],
614
+ ...derived[scheme]
615
+ });
616
+ return next;
617
+ }
618
+ /**
619
+ * The variant a theme is built around: the one whose swatch is the theme's
620
+ * accent, or `null` when the accent comes from somewhere else.
621
+ *
622
+ * @internal
623
+ */
624
+ function currentImageVariant(options, palette) {
625
+ let accent = options.light?.accent;
626
+ return accent ? IMAGE_PALETTE_VARIANTS.find((variant) => palette[variant] !== null && variantAccent(palette, variant, "light") === accent) ?? null : null;
627
+ }
628
+ /**
629
+ * How much a swatch has going for it as an accent: saturation first, then
630
+ * closeness to mid lightness — the range where an accent reads best.
631
+ */
632
+ function interest(hex) {
633
+ let { s, l } = hexToHsl(hex);
634
+ return .1 + .55 * s + .35 * (1 - Math.abs(l - .5) * 2);
635
+ }
636
+ /**
637
+ * Picks a variant for the "I'm feeling lucky" button: a random one, weighted
638
+ * by how interesting its swatch is as an accent, and never the one the theme
639
+ * already uses while there are others to pick from.
640
+ *
641
+ * @internal
642
+ */
643
+ function pickLuckyVariant(palette, options = {}) {
644
+ let { exclude = null, random = Math.random } = options, candidates = IMAGE_PALETTE_VARIANTS.filter((variant) => palette[variant] !== null);
645
+ if (candidates.length > 1 && (candidates = candidates.filter((variant) => variant !== exclude)), candidates.length === 0) return null;
646
+ let weights = candidates.map((variant) => interest(palette[variant])), total = weights.reduce((sum, weight) => sum + weight, 0), pick = random() * total;
647
+ for (let [index, variant] of candidates.entries()) if (pick -= weights[index], pick < 0) return variant;
648
+ return candidates.at(-1) ?? null;
649
+ }
650
+ /** A theme title for the image a palette came from, e.g. `sunset-beach.jpg` → `sunset beach` @internal */
651
+ function titleFromFileName(name) {
652
+ return name.replace(/\.[^.]+$/, "").replace(/[-_]+/g, " ").trim() || "Image theme";
335
653
  }
336
654
  /**
337
655
  * A button with an animated tooltip instead of a `title` attribute, sized like
@@ -365,8 +683,30 @@ function TooltipButton(props) {
365
683
  }), $[8] = t0, $[9] = t2, $[10] = t3) : t3 = $[10], t3;
366
684
  }
367
685
  /**
686
+ * The file picker for an image, as a hidden file input that a button or menu
687
+ * item clicks: the chosen file goes to `onFile`, and nowhere else — nothing
688
+ * is uploaded.
689
+ *
690
+ * @internal
691
+ */
692
+ function ImageFileInput(t0) {
693
+ let $ = c(5), { onFile, ref } = t0, t1;
694
+ $[0] === onFile ? t1 = $[1] : (t1 = (event) => {
695
+ let file = event.currentTarget.files?.[0];
696
+ event.currentTarget.value = "", file && onFile(file);
697
+ }, $[0] = onFile, $[1] = t1);
698
+ let t2;
699
+ return $[2] !== ref || $[3] !== t1 ? (t2 = /* @__PURE__ */ jsx("input", {
700
+ accept: "image/*",
701
+ hidden: !0,
702
+ onChange: t1,
703
+ ref,
704
+ type: "file"
705
+ }), $[2] = ref, $[3] = t1, $[4] = t2) : t2 = $[4], t2;
706
+ }
707
+ /**
368
708
  * A button that opens the file picker for an image, and hands the chosen file
369
- * over — the picker is a hidden file input, so nothing is uploaded anywhere.
709
+ * over.
370
710
  *
371
711
  * @internal
372
712
  */
@@ -382,15 +722,9 @@ function ImageFileButton(props) {
382
722
  onClick: t0
383
723
  }), $[4] = buttonProps, $[5] = t1);
384
724
  let t2;
385
- $[6] === onFile ? t2 = $[7] : (t2 = /* @__PURE__ */ jsx("input", {
386
- accept: "image/*",
387
- hidden: !0,
388
- onChange: (event) => {
389
- let file = event.currentTarget.files?.[0];
390
- event.currentTarget.value = "", file && onFile(file);
391
- },
392
- ref: inputRef,
393
- type: "file"
725
+ $[6] === onFile ? t2 = $[7] : (t2 = /* @__PURE__ */ jsx(ImageFileInput, {
726
+ onFile,
727
+ ref: inputRef
394
728
  }), $[6] = onFile, $[7] = t2);
395
729
  let t3;
396
730
  return $[8] !== t1 || $[9] !== t2 ? (t3 = /* @__PURE__ */ jsxs(Fragment, { children: [t1, t2] }), $[8] = t1, $[9] = t2, $[10] = t3) : t3 = $[10], t3;
@@ -438,21 +772,17 @@ async function decodeImage(file) {
438
772
  * @internal
439
773
  */
440
774
  function useImagePalette(onPalette) {
441
- let $ = c(10), toast = useToast(), [busy, setBusy] = useState(!1), onPaletteRef = useRef(onPalette), mountedRef = useRef(!0), latestPickRef = useRef(0), t0, t1;
775
+ let $ = c(8), toast = useToast(), [busy, setBusy] = useState(!1), onPaletteRef = useRef(onPalette), latestPickRef = useRef(0), t0, t1;
442
776
  $[0] === onPalette ? (t0 = $[1], t1 = $[2]) : (t0 = () => {
443
777
  onPaletteRef.current = onPalette;
444
778
  }, t1 = [onPalette], $[0] = onPalette, $[1] = t0, $[2] = t1), useEffect(t0, t1);
445
- let t2, t3;
446
- $[3] === Symbol.for("react.memo_cache_sentinel") ? (t2 = () => (mountedRef.current = !0, () => {
447
- mountedRef.current = !1;
448
- }), t3 = [], $[3] = t2, $[4] = t3) : (t2 = $[3], t3 = $[4]), useEffect(t2, t3);
449
- let t4;
450
- $[5] === toast ? t4 = $[6] : (t4 = (file) => {
779
+ let t2;
780
+ $[3] === toast ? t2 = $[4] : (t2 = (file) => {
451
781
  let pick = latestPickRef.current += 1;
452
782
  setBusy(!0);
453
- let isCurrent = () => mountedRef.current && latestPickRef.current === pick, extract = async () => {
783
+ let isCurrent = () => latestPickRef.current === pick, extract = async () => {
454
784
  let palette = extractImagePalette(await readImagePixels(file));
455
- isCurrent() && (Object.values(palette).every(_temp$4) ? toast.push({
785
+ isCurrent() && (Object.values(palette).every(_temp$6) ? toast.push({
456
786
  status: "warning",
457
787
  title: "Found no colors in that image"
458
788
  }) : onPaletteRef.current(palette, file));
@@ -465,14 +795,14 @@ function useImagePalette(onPalette) {
465
795
  }).finally(() => {
466
796
  isCurrent() && setBusy(!1);
467
797
  });
468
- }, $[5] = toast, $[6] = t4);
469
- let pickImage = t4, t5;
470
- return $[7] !== busy || $[8] !== pickImage ? (t5 = {
798
+ }, $[3] = toast, $[4] = t2);
799
+ let pickImage = t2, t3;
800
+ return $[5] !== busy || $[6] !== pickImage ? (t3 = {
471
801
  busy,
472
802
  pickImage
473
- }, $[7] = busy, $[8] = pickImage, $[9] = t5) : t5 = $[9], t5;
803
+ }, $[5] = busy, $[6] = pickImage, $[7] = t3) : t3 = $[7], t3;
474
804
  }
475
- function _temp$4(swatch) {
805
+ function _temp$6(swatch) {
476
806
  return swatch === null;
477
807
  }
478
808
  var paletteGrid = "_17s80v42", tile = "_17s80v44", variantButton = "_17s80v46", variantFrame = "_17s80v47", variantRow = "_17s80v45", variantScale = "var(--_17s80v41)", variantScaleBox = "_17s80v48", variantWidth = "var(--_17s80v40)";
@@ -663,7 +993,7 @@ function ImagePaletteSection(props) {
663
993
  border: !0,
664
994
  onDragEnter: t4,
665
995
  onDragLeave: t5,
666
- onDragOver: _temp$3,
996
+ onDragOver: _temp$5,
667
997
  onDrop: t6,
668
998
  padding: 3,
669
999
  radius: 3,
@@ -671,7 +1001,7 @@ function ImagePaletteSection(props) {
671
1001
  children: t12
672
1002
  }), $[34] = t12, $[35] = t6, $[36] = t7, $[37] = t13) : t13 = $[37], t13;
673
1003
  }
674
- function _temp$3(event_0) {
1004
+ function _temp$5(event_0) {
675
1005
  event_0.preventDefault();
676
1006
  }
677
1007
  var colorRowText = "os3rj2", range = "os3rj1", swatch = "os3rj0";
@@ -684,8 +1014,8 @@ const SCHEME_TITLES = {
684
1014
  * to the sidebar (or at the bottom, stacked on small screens), the other one
685
1015
  * takes the far side
686
1016
  */
687
- function splitHint(own, mobile) {
688
- return mobile ? own ? "Shown at the bottom" : "Shown at the top" : own ? "Shown on the right, next to the themer" : "Shown on the left";
1017
+ function splitHint(own) {
1018
+ return own ? "Shown on the right, next to the themer" : "Shown on the left";
689
1019
  }
690
1020
  const SCHEME_OPTION_KEYS = [
691
1021
  "accent",
@@ -707,71 +1037,73 @@ const SCHEME_OPTION_KEYS = [
707
1037
  *
708
1038
  * @internal
709
1039
  */
710
- function ThemeEditor(props) {
711
- let $ = c(42), { focusTitle, slug } = props, { themes, images, split, mobile, send } = useThemer(), t0;
1040
+ function ThemeEditor(t0) {
1041
+ let $ = c(41), { actorRef, focusTitle, slug, split, themes } = t0, images = useSelector(actorRef, _temp$4), t1;
712
1042
  if ($[0] !== slug || $[1] !== themes) {
713
- let t1;
714
- $[3] === slug ? t1 = $[4] : (t1 = (candidate) => candidate.slug === slug && candidate.source === "custom", $[3] = slug, $[4] = t1), t0 = themes.find(t1), $[0] = slug, $[1] = themes, $[2] = t0;
715
- } else t0 = $[2];
716
- let theme = t0;
1043
+ let t2;
1044
+ $[3] === slug ? t2 = $[4] : (t2 = (candidate) => candidate.slug === slug && candidate.source === "custom", $[3] = slug, $[4] = t2), t1 = themes.find(t2), $[0] = slug, $[1] = themes, $[2] = t1;
1045
+ } else t1 = $[2];
1046
+ let theme = t1;
717
1047
  if (!theme) return null;
718
- let t1;
719
- $[5] !== send || $[6] !== slug || $[7] !== theme.options || $[8] !== theme.palette ? (t1 = (variant) => {
720
- theme.palette && variant !== null && send({
1048
+ let t2;
1049
+ $[5] !== actorRef || $[6] !== slug || $[7] !== theme.options || $[8] !== theme.palette ? (t2 = (variant) => {
1050
+ theme.palette && variant !== null && actorRef.send({
721
1051
  type: "theme.update",
722
1052
  slug,
723
1053
  options: applyImagePalette(theme.options, theme.palette, variant)
724
1054
  });
725
- }, $[5] = send, $[6] = slug, $[7] = theme.options, $[8] = theme.palette, $[9] = t1) : t1 = $[9];
726
- let applyVariant = t1, t2 = images[slug], t3;
727
- $[10] === send ? t3 = $[11] : (t3 = () => send({ type: "flow.list" }), $[10] = send, $[11] = t3);
728
- let t4;
729
- $[12] !== applyVariant || $[13] !== theme.options || $[14] !== theme.palette ? (t4 = () => {
730
- theme.palette && applyVariant(pickLuckyVariant(theme.palette, { exclude: currentImageVariant(theme.options, theme.palette) }));
731
- }, $[12] = applyVariant, $[13] = theme.options, $[14] = theme.palette, $[15] = t4) : t4 = $[15];
1055
+ }, $[5] = actorRef, $[6] = slug, $[7] = theme.options, $[8] = theme.palette, $[9] = t2) : t2 = $[9];
1056
+ let applyVariant = t2, t3 = images[slug], t4;
1057
+ $[10] === actorRef ? t4 = $[11] : (t4 = () => actorRef.send({ type: "flow.list" }), $[10] = actorRef, $[11] = t4);
732
1058
  let t5;
733
- $[16] !== send || $[17] !== slug ? (t5 = (options) => send({
1059
+ $[12] !== applyVariant || $[13] !== theme.options || $[14] !== theme.palette ? (t5 = () => {
1060
+ theme.palette && applyVariant(pickLuckyVariant(theme.palette, { exclude: currentImageVariant(theme.options, theme.palette) }));
1061
+ }, $[12] = applyVariant, $[13] = theme.options, $[14] = theme.palette, $[15] = t5) : t5 = $[15];
1062
+ let t6;
1063
+ $[16] !== actorRef || $[17] !== slug ? (t6 = (options) => actorRef.send({
734
1064
  type: "theme.update",
735
1065
  slug,
736
1066
  options
737
- }), $[16] = send, $[17] = slug, $[18] = t5) : t5 = $[18];
738
- let t6;
739
- $[19] !== send || $[20] !== slug || $[21] !== theme.options ? (t6 = (palette, file) => send({
1067
+ }), $[16] = actorRef, $[17] = slug, $[18] = t6) : t6 = $[18];
1068
+ let t7;
1069
+ $[19] !== actorRef || $[20] !== slug || $[21] !== theme.options ? (t7 = (palette, file) => actorRef.send({
740
1070
  type: "theme.update",
741
1071
  slug,
742
1072
  options: applyImagePalette(theme.options, palette),
743
1073
  palette,
744
1074
  imageUrl: URL.createObjectURL(file)
745
- }), $[19] = send, $[20] = slug, $[21] = theme.options, $[22] = t6) : t6 = $[22];
746
- let t7, t8;
747
- $[23] !== send || $[24] !== slug ? (t7 = () => send({
1075
+ }), $[19] = actorRef, $[20] = slug, $[21] = theme.options, $[22] = t7) : t7 = $[22];
1076
+ let t8, t9;
1077
+ $[23] !== actorRef || $[24] !== slug ? (t8 = () => actorRef.send({
748
1078
  type: "theme.remove",
749
1079
  slug
750
- }), t8 = (title) => send({
1080
+ }), t9 = (title) => actorRef.send({
751
1081
  type: "theme.update",
752
1082
  slug,
753
1083
  title
754
- }), $[23] = send, $[24] = slug, $[25] = t7, $[26] = t8) : (t7 = $[25], t8 = $[26]);
755
- let t9;
756
- return $[27] !== applyVariant || $[28] !== focusTitle || $[29] !== mobile || $[30] !== split || $[31] !== t2 || $[32] !== t3 || $[33] !== t4 || $[34] !== t5 || $[35] !== t6 || $[36] !== t7 || $[37] !== t8 || $[38] !== theme.options || $[39] !== theme.palette || $[40] !== theme.title ? (t9 = /* @__PURE__ */ jsx(ThemeEditorForm, {
1084
+ }), $[23] = actorRef, $[24] = slug, $[25] = t8, $[26] = t9) : (t8 = $[25], t9 = $[26]);
1085
+ let t10;
1086
+ return $[27] !== applyVariant || $[28] !== focusTitle || $[29] !== split || $[30] !== t3 || $[31] !== t4 || $[32] !== t5 || $[33] !== t6 || $[34] !== t7 || $[35] !== t8 || $[36] !== t9 || $[37] !== theme.options || $[38] !== theme.palette || $[39] !== theme.title ? (t10 = /* @__PURE__ */ jsx(ThemeEditorForm, {
757
1087
  focusTitle,
758
- imageUrl: t2,
759
- onDone: t3,
760
- onLucky: t4,
761
- onOptionsChange: t5,
762
- onPalette: t6,
763
- onRemove: t7,
764
- onTitleChange: t8,
1088
+ imageUrl: t3,
1089
+ onDone: t4,
1090
+ onLucky: t5,
1091
+ onOptionsChange: t6,
1092
+ onPalette: t7,
1093
+ onRemove: t8,
1094
+ onTitleChange: t9,
765
1095
  onVariant: applyVariant,
766
1096
  options: theme.options,
767
1097
  palette: theme.palette,
768
1098
  split,
769
- mobile,
770
1099
  title: theme.title
771
- }), $[27] = applyVariant, $[28] = focusTitle, $[29] = mobile, $[30] = split, $[31] = t2, $[32] = t3, $[33] = t4, $[34] = t5, $[35] = t6, $[36] = t7, $[37] = t8, $[38] = theme.options, $[39] = theme.palette, $[40] = theme.title, $[41] = t9) : t9 = $[41], t9;
1100
+ }), $[27] = applyVariant, $[28] = focusTitle, $[29] = split, $[30] = t3, $[31] = t4, $[32] = t5, $[33] = t6, $[34] = t7, $[35] = t8, $[36] = t9, $[37] = theme.options, $[38] = theme.palette, $[39] = theme.title, $[40] = t10) : t10 = $[40], t10;
1101
+ }
1102
+ function _temp$4(snapshot) {
1103
+ return snapshot.context.images;
772
1104
  }
773
1105
  function ThemeEditorForm(props) {
774
- let $ = c(50), { focusTitle, imageUrl, onDone, onLucky, onOptionsChange, onPalette, onRemove, onTitleChange, onVariant, options, palette, split, mobile, title } = props, studioScheme = useColorSchemeValue(), t0;
1106
+ let $ = c(53), { focusTitle, imageUrl, onDone, onLucky, onOptionsChange, onPalette, onRemove, onTitleChange, onVariant, options, palette, split, title } = props, studioScheme = useColorSchemeValue(), actionsId = useId(), t0;
775
1107
  $[0] === options ? t0 = $[1] : (t0 = resolveThemeOptions(options), $[0] = options, $[1] = t0);
776
1108
  let resolved = t0, t1;
777
1109
  $[2] === options ? t1 = $[3] : (t1 = buildPalette(options), $[2] = options, $[3] = t1);
@@ -795,7 +1127,7 @@ function ThemeEditorForm(props) {
795
1127
  }), $[9] = t4) : t4 = $[9];
796
1128
  let t5;
797
1129
  $[10] === onTitleChange ? t5 = $[11] : (t5 = (event) => onTitleChange(event.currentTarget.value), $[10] = onTitleChange, $[11] = t5);
798
- let t6 = focusTitle ? _temp$2 : void 0, t7;
1130
+ let t6 = focusTitle ? _temp2 : void 0, t7;
799
1131
  $[12] !== focusTitle || $[13] !== t5 || $[14] !== t6 || $[15] !== title ? (t7 = /* @__PURE__ */ jsxs(Stack, {
800
1132
  gap: 2,
801
1133
  children: [t4, /* @__PURE__ */ jsx(TextInput, {
@@ -818,7 +1150,7 @@ function ThemeEditorForm(props) {
818
1150
  palette
819
1151
  }), $[17] = imageUrl, $[18] = onLucky, $[19] = onPalette, $[20] = onVariant, $[21] = options, $[22] = palette, $[23] = t8) : t8 = $[23];
820
1152
  let t9;
821
- $[24] !== mobile || $[25] !== options || $[26] !== palettes || $[27] !== patchScheme || $[28] !== resolved || $[29] !== split || $[30] !== studioScheme ? (t9 = SCHEMES.map((scheme_0) => /* @__PURE__ */ jsx(SchemeCard, {
1153
+ $[24] !== options || $[25] !== palettes || $[26] !== patchScheme || $[27] !== resolved || $[28] !== split || $[29] !== studioScheme ? (t9 = SCHEMES.map((scheme_0) => /* @__PURE__ */ jsx(SchemeCard, {
822
1154
  active: split || scheme_0 === studioScheme,
823
1155
  onChange: (changes_0) => patchScheme(scheme_0, changes_0),
824
1156
  options: options[scheme_0] ?? {},
@@ -826,12 +1158,12 @@ function ThemeEditorForm(props) {
826
1158
  resolved: resolved[scheme_0],
827
1159
  scheme: scheme_0,
828
1160
  split,
829
- splitHint: splitHint(scheme_0 === studioScheme, mobile)
830
- }, scheme_0)), $[24] = mobile, $[25] = options, $[26] = palettes, $[27] = patchScheme, $[28] = resolved, $[29] = split, $[30] = studioScheme, $[31] = t9) : t9 = $[31];
1161
+ splitHint: splitHint(scheme_0 === studioScheme)
1162
+ }, scheme_0)), $[24] = options, $[25] = palettes, $[26] = patchScheme, $[27] = resolved, $[28] = split, $[29] = studioScheme, $[30] = t9) : t9 = $[30];
831
1163
  let t10;
832
- $[32] === t9 ? t10 = $[33] : (t10 = /* @__PURE__ */ jsx(ScrollAreaBleed, { children: t9 }), $[32] = t9, $[33] = t10);
1164
+ $[31] === t9 ? t10 = $[32] : (t10 = /* @__PURE__ */ jsx(ScrollAreaBleed, { children: t9 }), $[31] = t9, $[32] = t10);
833
1165
  let t11;
834
- $[34] !== t10 || $[35] !== t3 || $[36] !== t7 || $[37] !== t8 ? (t11 = /* @__PURE__ */ jsx(ScrollArea, {
1166
+ $[33] !== t10 || $[34] !== t3 || $[35] !== t7 || $[36] !== t8 ? (t11 = /* @__PURE__ */ jsx(ScrollArea, {
835
1167
  padding: 3,
836
1168
  children: /* @__PURE__ */ jsxs(Stack, {
837
1169
  gap: 4,
@@ -842,42 +1174,58 @@ function ThemeEditorForm(props) {
842
1174
  t10
843
1175
  ]
844
1176
  })
845
- }), $[34] = t10, $[35] = t3, $[36] = t7, $[37] = t8, $[38] = t11) : t11 = $[38];
1177
+ }), $[33] = t10, $[34] = t3, $[35] = t7, $[36] = t8, $[37] = t11) : t11 = $[37];
846
1178
  let t12;
847
- $[39] === onRemove ? t12 = $[40] : (t12 = /* @__PURE__ */ jsx(TooltipButton, {
1179
+ $[38] === onDone ? t12 = $[39] : (t12 = /* @__PURE__ */ jsx(Button, {
1180
+ gap: 2,
1181
+ icon: CheckmarkIcon,
1182
+ onClick: onDone,
1183
+ padding: 2,
1184
+ text: "Done",
1185
+ mode: "ghost"
1186
+ }), $[38] = onDone, $[39] = t12);
1187
+ let t13;
1188
+ $[40] === Symbol.for("react.memo_cache_sentinel") ? (t13 = /* @__PURE__ */ jsx(Button, {
1189
+ "aria-label": "More actions",
1190
+ icon: EllipsisHorizontalIcon,
1191
+ mode: "bleed",
1192
+ padding: 2
1193
+ }), $[40] = t13) : t13 = $[40];
1194
+ let t14;
1195
+ $[41] === onRemove ? t14 = $[42] : (t14 = /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx(MenuItem, {
848
1196
  icon: TrashIcon,
849
- mode: "ghost",
850
1197
  onClick: onRemove,
851
1198
  text: "Remove",
852
- tone: "critical",
853
- tooltip: "Remove the theme — it can be restored until it is deleted"
854
- }), $[39] = onRemove, $[40] = t12);
855
- let t13;
856
- $[41] === Symbol.for("react.memo_cache_sentinel") ? (t13 = /* @__PURE__ */ jsx(Box, { flex: 1 }), $[41] = t13) : t13 = $[41];
857
- let t14;
858
- $[42] === onDone ? t14 = $[43] : (t14 = /* @__PURE__ */ jsx(Button, {
859
- mode: "ghost",
860
- onClick: onDone,
861
- padding: 2,
862
- text: "Done"
863
- }), $[42] = onDone, $[43] = t14);
1199
+ tone: "critical"
1200
+ }) }), $[41] = onRemove, $[42] = t14);
864
1201
  let t15;
865
- $[44] !== t12 || $[45] !== t14 ? (t15 = /* @__PURE__ */ jsx(Card, {
1202
+ $[43] === Symbol.for("react.memo_cache_sentinel") ? (t15 = {
1203
+ animate: !0,
1204
+ placement: "top-end",
1205
+ portal: !0
1206
+ }, $[43] = t15) : t15 = $[43];
1207
+ let t16;
1208
+ $[44] !== actionsId || $[45] !== t14 ? (t16 = /* @__PURE__ */ jsx(MenuButton, {
1209
+ button: t13,
1210
+ id: actionsId,
1211
+ menu: t14,
1212
+ popover: t15
1213
+ }), $[44] = actionsId, $[45] = t14, $[46] = t16) : t16 = $[46];
1214
+ let t17;
1215
+ $[47] !== t12 || $[48] !== t16 ? (t17 = /* @__PURE__ */ jsx(Card, {
866
1216
  borderTop: !0,
867
1217
  padding: 3,
868
1218
  children: /* @__PURE__ */ jsxs(Flex, {
1219
+ align: "center",
869
1220
  gap: 2,
870
- children: [
871
- t12,
872
- t13,
873
- t14
874
- ]
1221
+ justify: "flex-end",
1222
+ children: [t12, t16]
875
1223
  })
876
- }), $[44] = t12, $[45] = t14, $[46] = t15) : t15 = $[46];
877
- let t16;
878
- return $[47] !== t11 || $[48] !== t15 ? (t16 = /* @__PURE__ */ jsxs(Fragment, { children: [t11, t15] }), $[47] = t11, $[48] = t15, $[49] = t16) : t16 = $[49], t16;
1224
+ }), $[47] = t12, $[48] = t16, $[49] = t17) : t17 = $[49];
1225
+ let t18;
1226
+ return $[50] !== t11 || $[51] !== t17 ? (t18 = /* @__PURE__ */ jsxs(Fragment, { children: [t11, t17] }), $[50] = t11, $[51] = t17, $[52] = t18) : t18 = $[52], t18;
879
1227
  }
880
- function _temp$2(event_0) {
1228
+ function _temp2(event_0) {
881
1229
  return event_0.currentTarget.select();
882
1230
  }
883
1231
  /**
@@ -1196,9 +1544,9 @@ function fromBase64Url(code) {
1196
1544
  *
1197
1545
  * @internal
1198
1546
  */
1199
- function useThemeCodes() {
1200
- let $ = c(11), { send } = useThemer(), toast = useToast(), t0;
1201
- $[0] === toast ? t0 = $[1] : (t0 = async (theme) => {
1547
+ function useThemeCodes(t0) {
1548
+ let $ = c(11), { actorRef } = t0, toast = useToast(), t1;
1549
+ $[0] === toast ? t1 = $[1] : (t1 = async (theme) => {
1202
1550
  let title = displayTitle(theme.title);
1203
1551
  try {
1204
1552
  await navigator.clipboard.writeText(encodeTheme(theme)), toast.push({
@@ -1212,11 +1560,11 @@ function useThemeCodes() {
1212
1560
  title: `Could not copy ${title}`
1213
1561
  });
1214
1562
  }
1215
- }, $[0] = toast, $[1] = t0);
1216
- let copyTheme = t0, t1;
1217
- $[2] !== send || $[3] !== toast ? (t1 = (text) => {
1563
+ }, $[0] = toast, $[1] = t1);
1564
+ let copyTheme = t1, t2;
1565
+ $[2] !== actorRef || $[3] !== toast ? (t2 = (text) => {
1218
1566
  let theme_0 = decodeTheme(text);
1219
- return theme_0 ? (send({
1567
+ return theme_0 ? (actorRef.send({
1220
1568
  type: "theme.import",
1221
1569
  title: theme_0.title,
1222
1570
  options: theme_0.options
@@ -1224,9 +1572,9 @@ function useThemeCodes() {
1224
1572
  status: "success",
1225
1573
  title: `Added ${theme_0.title}`
1226
1574
  }), !0) : !1;
1227
- }, $[2] = send, $[3] = toast, $[4] = t1) : t1 = $[4];
1228
- let addThemeFromText = t1, t2;
1229
- $[5] === addThemeFromText ? t2 = $[6] : (t2 = async () => {
1575
+ }, $[2] = actorRef, $[3] = toast, $[4] = t2) : t2 = $[4];
1576
+ let addThemeFromText = t2, t3;
1577
+ $[5] === addThemeFromText ? t3 = $[6] : (t3 = async () => {
1230
1578
  let text_0;
1231
1579
  try {
1232
1580
  text_0 = await navigator.clipboard.readText();
@@ -1234,13 +1582,13 @@ function useThemeCodes() {
1234
1582
  return "no-clipboard";
1235
1583
  }
1236
1584
  return addThemeFromText(text_0) ? "added" : "no-theme";
1237
- }, $[5] = addThemeFromText, $[6] = t2);
1238
- let addThemeFromClipboard = t2, t3;
1239
- return $[7] !== addThemeFromClipboard || $[8] !== addThemeFromText || $[9] !== copyTheme ? (t3 = {
1585
+ }, $[5] = addThemeFromText, $[6] = t3);
1586
+ let addThemeFromClipboard = t3, t4;
1587
+ return $[7] !== addThemeFromClipboard || $[8] !== addThemeFromText || $[9] !== copyTheme ? (t4 = {
1240
1588
  copyTheme,
1241
1589
  addThemeFromText,
1242
1590
  addThemeFromClipboard
1243
- }, $[7] = addThemeFromClipboard, $[8] = addThemeFromText, $[9] = copyTheme, $[10] = t3) : t3 = $[10], t3;
1591
+ }, $[7] = addThemeFromClipboard, $[8] = addThemeFromText, $[9] = copyTheme, $[10] = t4) : t4 = $[10], t4;
1244
1592
  }
1245
1593
  /**
1246
1594
  * Adds a theme pasted anywhere in the Studio while the themer's list is
@@ -1248,14 +1596,13 @@ function useThemeCodes() {
1248
1596
  *
1249
1597
  * @internal
1250
1598
  */
1251
- function usePasteThemeCodes() {
1252
- let $ = c(5), { open, send } = useThemer(), toast = useToast(), t0, t1;
1253
- $[0] !== open || $[1] !== send || $[2] !== toast ? (t0 = () => {
1254
- if (!open) return;
1599
+ function usePasteThemeCodes(t0) {
1600
+ let $ = c(4), { actorRef } = t0, toast = useToast(), t1, t2;
1601
+ $[0] !== actorRef || $[1] !== toast ? (t1 = () => {
1255
1602
  let handlePaste = (event) => {
1256
1603
  if (isEditable(event.target)) return;
1257
1604
  let theme = decodeTheme(event.clipboardData?.getData("text/plain") ?? "");
1258
- theme && (event.preventDefault(), send({
1605
+ theme && (event.preventDefault(), actorRef.send({
1259
1606
  type: "theme.import",
1260
1607
  title: theme.title,
1261
1608
  options: theme.options
@@ -1265,11 +1612,7 @@ function usePasteThemeCodes() {
1265
1612
  }));
1266
1613
  };
1267
1614
  return document.addEventListener("paste", handlePaste), () => document.removeEventListener("paste", handlePaste);
1268
- }, t1 = [
1269
- open,
1270
- send,
1271
- toast
1272
- ], $[0] = open, $[1] = send, $[2] = toast, $[3] = t0, $[4] = t1) : (t0 = $[3], t1 = $[4]), useEffect(t0, t1);
1615
+ }, t2 = [actorRef, toast], $[0] = actorRef, $[1] = toast, $[2] = t1, $[3] = t2) : (t1 = $[2], t2 = $[3]), useEffect(t1, t2);
1273
1616
  }
1274
1617
  function isEditable(target) {
1275
1618
  return target instanceof HTMLElement && (target.isContentEditable || target.matches("input, textarea, select"));
@@ -1281,63 +1624,65 @@ function isEditable(target) {
1281
1624
  * @internal
1282
1625
  */
1283
1626
  function PasteThemeDialog(props) {
1284
- let $ = c(35), { onClose } = props, { addThemeFromText } = useThemeCodes(), [text, setText] = useState(""), [invalid, setInvalid] = useState(!1), t0;
1285
- $[0] !== addThemeFromText || $[1] !== onClose || $[2] !== text ? (t0 = () => {
1627
+ let $ = c(39), { actorRef, onClose } = props, t0;
1628
+ $[0] === actorRef ? t0 = $[1] : (t0 = { actorRef }, $[0] = actorRef, $[1] = t0);
1629
+ let { addThemeFromText } = useThemeCodes(t0), [text, setText] = useState(""), [invalid, setInvalid] = useState(!1), id = useId(), errorId = `${id}-error`, t1;
1630
+ $[2] !== addThemeFromText || $[3] !== onClose || $[4] !== text ? (t1 = () => {
1286
1631
  addThemeFromText(text) ? onClose() : setInvalid(!0);
1287
- }, $[0] = addThemeFromText, $[1] = onClose, $[2] = text, $[3] = t0) : t0 = $[3];
1288
- let add = t0, t1;
1289
- $[4] === onClose ? t1 = $[5] : (t1 = /* @__PURE__ */ jsx(Button, {
1632
+ }, $[2] = addThemeFromText, $[3] = onClose, $[4] = text, $[5] = t1) : t1 = $[5];
1633
+ let add = t1, t2;
1634
+ $[6] === onClose ? t2 = $[7] : (t2 = /* @__PURE__ */ jsx(Button, {
1290
1635
  mode: "ghost",
1291
1636
  onClick: onClose,
1292
1637
  padding: 2,
1293
1638
  text: "Cancel"
1294
- }), $[4] = onClose, $[5] = t1);
1295
- let t2;
1296
- $[6] === text ? t2 = $[7] : (t2 = text.trim(), $[6] = text, $[7] = t2);
1297
- let t3 = t2 === "", t4;
1298
- $[8] !== add || $[9] !== t3 ? (t4 = /* @__PURE__ */ jsx(Button, {
1299
- disabled: t3,
1639
+ }), $[6] = onClose, $[7] = t2);
1640
+ let t3;
1641
+ $[8] === text ? t3 = $[9] : (t3 = text.trim(), $[8] = text, $[9] = t3);
1642
+ let t4 = t3 === "", t5;
1643
+ $[10] !== add || $[11] !== t4 ? (t5 = /* @__PURE__ */ jsx(Button, {
1644
+ disabled: t4,
1300
1645
  onClick: add,
1301
1646
  padding: 2,
1302
1647
  text: "Add theme",
1303
1648
  tone: "primary"
1304
- }), $[8] = add, $[9] = t3, $[10] = t4) : t4 = $[10];
1305
- let t5;
1306
- $[11] !== t1 || $[12] !== t4 ? (t5 = /* @__PURE__ */ jsxs(Flex, {
1649
+ }), $[10] = add, $[11] = t4, $[12] = t5) : t5 = $[12];
1650
+ let t6;
1651
+ $[13] !== t2 || $[14] !== t5 ? (t6 = /* @__PURE__ */ jsxs(Flex, {
1307
1652
  gap: 2,
1308
1653
  justify: "flex-end",
1309
1654
  padding: 3,
1310
- children: [t1, t4]
1311
- }), $[11] = t1, $[12] = t4, $[13] = t5) : t5 = $[13];
1312
- let t6;
1313
- $[14] === add ? t6 = $[15] : (t6 = (event) => {
1314
- event.preventDefault(), add();
1315
- }, $[14] = add, $[15] = t6);
1655
+ children: [t2, t5]
1656
+ }), $[13] = t2, $[14] = t5, $[15] = t6) : t6 = $[15];
1316
1657
  let t7;
1317
- $[16] === Symbol.for("react.memo_cache_sentinel") ? (t7 = /* @__PURE__ */ jsx(Text, {
1658
+ $[16] === add ? t7 = $[17] : (t7 = (event) => {
1659
+ event.preventDefault(), add();
1660
+ }, $[16] = add, $[17] = t7);
1661
+ let t8;
1662
+ $[18] === Symbol.for("react.memo_cache_sentinel") ? (t8 = /* @__PURE__ */ jsx(Text, {
1318
1663
  muted: !0,
1319
1664
  size: 1,
1320
1665
  children: "Paste the code someone copied from their themer — the theme is added to your list and applied."
1321
- }), $[16] = t7) : t7 = $[16];
1322
- let t8 = invalid ? "themer-paste-error" : void 0, t9 = invalid ? "That is not a theme code" : void 0, t10;
1323
- $[17] === Symbol.for("react.memo_cache_sentinel") ? (t10 = (event_0) => {
1666
+ }), $[18] = t8) : t8 = $[18];
1667
+ let t9 = invalid ? errorId : void 0, t10 = invalid ? "That is not a theme code" : void 0, t11;
1668
+ $[19] === Symbol.for("react.memo_cache_sentinel") ? (t11 = (event_0) => {
1324
1669
  setText(event_0.currentTarget.value), setInvalid(!1);
1325
- }, $[17] = t10) : t10 = $[17];
1326
- let t11;
1327
- $[18] !== invalid || $[19] !== t8 || $[20] !== t9 || $[21] !== text ? (t11 = /* @__PURE__ */ jsx(TextInput, {
1328
- "aria-describedby": t8,
1670
+ }, $[19] = t11) : t11 = $[19];
1671
+ let t12;
1672
+ $[20] !== invalid || $[21] !== t10 || $[22] !== t9 || $[23] !== text ? (t12 = /* @__PURE__ */ jsx(TextInput, {
1673
+ "aria-describedby": t9,
1329
1674
  "aria-invalid": invalid,
1330
1675
  "aria-label": "Theme code",
1331
1676
  autoFocus: !0,
1332
- customValidity: t9,
1677
+ customValidity: t10,
1333
1678
  fontSize: 1,
1334
- onChange: t10,
1679
+ onChange: t11,
1335
1680
  placeholder: "AQ…",
1336
1681
  value: text
1337
- }), $[18] = invalid, $[19] = t8, $[20] = t9, $[21] = text, $[22] = t11) : t11 = $[22];
1338
- let t12;
1339
- $[23] === invalid ? t12 = $[24] : (t12 = invalid && /* @__PURE__ */ jsx(Card, {
1340
- id: "themer-paste-error",
1682
+ }), $[20] = invalid, $[21] = t10, $[22] = t9, $[23] = text, $[24] = t12) : t12 = $[24];
1683
+ let t13;
1684
+ $[25] !== errorId || $[26] !== invalid ? (t13 = invalid && /* @__PURE__ */ jsx(Card, {
1685
+ id: errorId,
1341
1686
  padding: 3,
1342
1687
  radius: 2,
1343
1688
  role: "alert",
@@ -1346,33 +1691,33 @@ function PasteThemeDialog(props) {
1346
1691
  size: 1,
1347
1692
  children: "That is not a theme code — codes are one word, copied from a theme's menu."
1348
1693
  })
1349
- }), $[23] = invalid, $[24] = t12);
1350
- let t13;
1351
- $[25] !== t11 || $[26] !== t12 ? (t13 = /* @__PURE__ */ jsxs(Stack, {
1694
+ }), $[25] = errorId, $[26] = invalid, $[27] = t13) : t13 = $[27];
1695
+ let t14;
1696
+ $[28] !== t12 || $[29] !== t13 ? (t14 = /* @__PURE__ */ jsxs(Stack, {
1352
1697
  gap: 3,
1353
1698
  padding: 4,
1354
1699
  children: [
1355
- t7,
1356
- t11,
1357
- t12
1700
+ t8,
1701
+ t12,
1702
+ t13
1358
1703
  ]
1359
- }), $[25] = t11, $[26] = t12, $[27] = t13) : t13 = $[27];
1360
- let t14;
1361
- $[28] !== t13 || $[29] !== t6 ? (t14 = /* @__PURE__ */ jsx("form", {
1362
- onSubmit: t6,
1363
- children: t13
1364
- }), $[28] = t13, $[29] = t6, $[30] = t14) : t14 = $[30];
1704
+ }), $[28] = t12, $[29] = t13, $[30] = t14) : t14 = $[30];
1365
1705
  let t15;
1366
- return $[31] !== onClose || $[32] !== t14 || $[33] !== t5 ? (t15 = /* @__PURE__ */ jsx(Dialog, {
1706
+ $[31] !== t14 || $[32] !== t7 ? (t15 = /* @__PURE__ */ jsx("form", {
1707
+ onSubmit: t7,
1708
+ children: t14
1709
+ }), $[31] = t14, $[32] = t7, $[33] = t15) : t15 = $[33];
1710
+ let t16;
1711
+ return $[34] !== id || $[35] !== onClose || $[36] !== t15 || $[37] !== t6 ? (t16 = /* @__PURE__ */ jsx(Dialog, {
1367
1712
  animate: !0,
1368
- footer: t5,
1713
+ footer: t6,
1369
1714
  header: "Add a shared theme",
1370
- id: "themer-paste",
1715
+ id,
1371
1716
  onClickOutside: onClose,
1372
1717
  onClose,
1373
1718
  width: 0,
1374
- children: t14
1375
- }), $[31] = onClose, $[32] = t14, $[33] = t5, $[34] = t15) : t15 = $[34], t15;
1719
+ children: t15
1720
+ }), $[34] = id, $[35] = onClose, $[36] = t15, $[37] = t6, $[38] = t16) : t16 = $[38], t16;
1376
1721
  }
1377
1722
  var frame$1 = "_1wsn7882", menuCard = "_1wsn7884", menuSlot = "_1wsn7883", pickButton = "_1wsn7881", root = "_1wsn7880";
1378
1723
  /**
@@ -1395,47 +1740,49 @@ function scrollRefIntoViewIfNeeded(node) {
1395
1740
  *
1396
1741
  * @internal
1397
1742
  */
1398
- function ThemeCard(props) {
1399
- let $ = c(85), { active, theme } = props, { themes, send } = useThemer(), { copyTheme } = useThemeCodes(), { scheme } = useRootTheme(), [menuOpen, setMenuOpen] = useState(!1), dragControls = useDragControls(), dragged = useRef(!1), t0;
1400
- $[0] === theme.title ? t0 = $[1] : (t0 = displayTitle(theme.title), $[0] = theme.title, $[1] = t0);
1401
- let title = t0, t1;
1402
- $[2] === theme.slug ? t1 = $[3] : (t1 = (candidate) => candidate.slug === theme.slug, $[2] = theme.slug, $[3] = t1);
1403
- let index = themes.findIndex(t1), t2;
1404
- $[4] !== index || $[5] !== send || $[6] !== themes ? (t2 = (to) => {
1405
- let order = themes.map(_temp$1);
1406
- order.splice(to, 0, ...order.splice(index, 1)), send({
1743
+ function ThemeCard(t0) {
1744
+ let $ = c(79), { actorRef, active, theme, themes } = t0, t1;
1745
+ $[0] === actorRef ? t1 = $[1] : (t1 = { actorRef }, $[0] = actorRef, $[1] = t1);
1746
+ let { copyTheme } = useThemeCodes(t1), { scheme } = useRootTheme(), [menuOpen, setMenuOpen] = useState(!1), dragControls = useDragControls(), menuId = useId(), dragged = useRef(!1), t2;
1747
+ $[2] === theme.title ? t2 = $[3] : (t2 = displayTitle(theme.title), $[2] = theme.title, $[3] = t2);
1748
+ let title = t2, t3;
1749
+ $[4] === theme.slug ? t3 = $[5] : (t3 = (candidate) => candidate.slug === theme.slug, $[4] = theme.slug, $[5] = t3);
1750
+ let index = themes.findIndex(t3), listed = index !== -1, t4;
1751
+ $[6] !== actorRef || $[7] !== index || $[8] !== themes ? (t4 = (to) => {
1752
+ let order = themes.map(_temp$3);
1753
+ order.splice(to, 0, ...order.splice(index, 1)), actorRef.send({
1407
1754
  type: "theme.reorder",
1408
1755
  order
1409
1756
  });
1410
- }, $[4] = index, $[5] = send, $[6] = themes, $[7] = t2) : t2 = $[7];
1411
- let moveTo = t2, t3, t4;
1412
- $[8] === Symbol.for("react.memo_cache_sentinel") ? (t3 = () => {
1757
+ }, $[6] = actorRef, $[7] = index, $[8] = themes, $[9] = t4) : t4 = $[9];
1758
+ let moveTo = t4, t5, t6;
1759
+ $[10] === Symbol.for("react.memo_cache_sentinel") ? (t5 = () => {
1413
1760
  requestAnimationFrame(() => {
1414
1761
  dragged.current = !1;
1415
1762
  });
1416
- }, t4 = () => {
1763
+ }, t6 = () => {
1417
1764
  dragged.current = !0;
1418
- }, $[8] = t3, $[9] = t4) : (t3 = $[8], t4 = $[9]);
1419
- let t5 = active ? scrollRefIntoViewIfNeeded : void 0, t6;
1420
- $[10] === Symbol.for("react.memo_cache_sentinel") ? (t6 = { scale: 1.04 }, $[10] = t6) : t6 = $[10];
1421
- let t7;
1422
- $[11] !== send || $[12] !== theme.slug ? (t7 = () => {
1423
- dragged.current || send({
1765
+ }, $[10] = t5, $[11] = t6) : (t5 = $[10], t6 = $[11]);
1766
+ let t7 = active ? scrollRefIntoViewIfNeeded : void 0, t8;
1767
+ $[12] === Symbol.for("react.memo_cache_sentinel") ? (t8 = { scale: 1.04 }, $[12] = t8) : t8 = $[12];
1768
+ let t9;
1769
+ $[13] !== actorRef || $[14] !== theme.slug ? (t9 = () => {
1770
+ dragged.current || actorRef.send({
1424
1771
  type: "theme.pick",
1425
1772
  slug: theme.slug
1426
1773
  });
1427
- }, $[11] = send, $[12] = theme.slug, $[13] = t7) : t7 = $[13];
1428
- let t8;
1429
- $[14] === dragControls ? t8 = $[15] : (t8 = (event) => {
1430
- event.pointerType !== "touch" && dragControls.start(event);
1431
- }, $[14] = dragControls, $[15] = t8);
1432
- let t9;
1433
- $[16] === theme.options ? t9 = $[17] : (t9 = /* @__PURE__ */ jsx("span", {
1774
+ }, $[13] = actorRef, $[14] = theme.slug, $[15] = t9) : t9 = $[15];
1775
+ let t10;
1776
+ $[16] !== dragControls || $[17] !== listed ? (t10 = (event) => {
1777
+ listed && event.pointerType !== "touch" && dragControls.start(event);
1778
+ }, $[16] = dragControls, $[17] = listed, $[18] = t10) : t10 = $[18];
1779
+ let t11;
1780
+ $[19] === theme.options ? t11 = $[20] : (t11 = /* @__PURE__ */ jsx("span", {
1434
1781
  className: frame$1,
1435
1782
  children: /* @__PURE__ */ jsx(ThemeThumbnail, { options: theme.options })
1436
- }), $[16] = theme.options, $[17] = t9);
1437
- let t10 = active ? "medium" : "regular", t11;
1438
- $[18] !== t10 || $[19] !== title ? (t11 = /* @__PURE__ */ jsx(Box, {
1783
+ }), $[19] = theme.options, $[20] = t11);
1784
+ let t12 = active ? "medium" : "regular", t13;
1785
+ $[21] !== t12 || $[22] !== title ? (t13 = /* @__PURE__ */ jsx(Box, {
1439
1786
  as: "span",
1440
1787
  display: "block",
1441
1788
  paddingTop: 2,
@@ -1445,112 +1792,106 @@ function ThemeCard(props) {
1445
1792
  as: "span",
1446
1793
  size: 1,
1447
1794
  textOverflow: "ellipsis",
1448
- weight: t10,
1795
+ weight: t12,
1449
1796
  children: title
1450
1797
  })
1451
- }), $[18] = t10, $[19] = title, $[20] = t11) : t11 = $[20];
1452
- let t12;
1453
- $[21] !== active || $[22] !== t11 || $[23] !== t7 || $[24] !== t8 || $[25] !== t9 ? (t12 = /* @__PURE__ */ jsxs("button", {
1798
+ }), $[21] = t12, $[22] = title, $[23] = t13) : t13 = $[23];
1799
+ let t14;
1800
+ $[24] !== active || $[25] !== t10 || $[26] !== t11 || $[27] !== t13 || $[28] !== t9 ? (t14 = /* @__PURE__ */ jsxs("button", {
1454
1801
  "aria-pressed": active,
1455
1802
  className: pickButton,
1456
- onClick: t7,
1457
- onPointerDown: t8,
1803
+ onClick: t9,
1804
+ onPointerDown: t10,
1458
1805
  type: "button",
1459
- children: [t9, t11]
1460
- }), $[21] = active, $[22] = t11, $[23] = t7, $[24] = t8, $[25] = t9, $[26] = t12) : t12 = $[26];
1461
- let t13;
1462
- $[27] === Symbol.for("react.memo_cache_sentinel") ? (t13 = /* @__PURE__ */ jsx(Text, {
1806
+ children: [t11, t13]
1807
+ }), $[24] = active, $[25] = t10, $[26] = t11, $[27] = t13, $[28] = t9, $[29] = t14) : t14 = $[29];
1808
+ let t15;
1809
+ $[30] === Symbol.for("react.memo_cache_sentinel") ? (t15 = /* @__PURE__ */ jsx(Text, {
1463
1810
  size: 1,
1464
1811
  children: "Show more"
1465
- }), $[27] = t13) : t13 = $[27];
1466
- let t14 = `Show more for ${title}`, t15;
1467
- $[28] === t14 ? t15 = $[29] : (t15 = /* @__PURE__ */ jsx(Button, {
1468
- "aria-label": t14,
1812
+ }), $[30] = t15) : t15 = $[30];
1813
+ let t16 = `Show more for ${title}`, t17;
1814
+ $[31] === t16 ? t17 = $[32] : (t17 = /* @__PURE__ */ jsx(Button, {
1815
+ "aria-label": t16,
1469
1816
  fontSize: 1,
1470
1817
  icon: EllipsisHorizontalIcon,
1471
1818
  mode: "ghost",
1472
1819
  padding: 1,
1473
1820
  radius: 2
1474
- }), $[28] = t14, $[29] = t15);
1475
- let t16 = `themer-theme-${theme.slug}`, t17 = index <= 0, t18;
1476
- $[30] !== index || $[31] !== moveTo ? (t18 = () => moveTo(index - 1), $[30] = index, $[31] = moveTo, $[32] = t18) : t18 = $[32];
1821
+ }), $[31] = t16, $[32] = t17);
1822
+ let t18;
1823
+ $[33] !== index || $[34] !== listed || $[35] !== moveTo || $[36] !== themes.length ? (t18 = listed && /* @__PURE__ */ jsxs(Fragment, { children: [
1824
+ /* @__PURE__ */ jsx(MenuItem, {
1825
+ disabled: index <= 0,
1826
+ icon: ArrowUpIcon,
1827
+ onClick: () => moveTo(index - 1),
1828
+ text: "Move up"
1829
+ }),
1830
+ /* @__PURE__ */ jsx(MenuItem, {
1831
+ disabled: index >= themes.length - 1,
1832
+ icon: ArrowDownIcon,
1833
+ onClick: () => moveTo(index + 1),
1834
+ text: "Move down"
1835
+ }),
1836
+ /* @__PURE__ */ jsx(MenuDivider, {})
1837
+ ] }), $[33] = index, $[34] = listed, $[35] = moveTo, $[36] = themes.length, $[37] = t18) : t18 = $[37];
1477
1838
  let t19;
1478
- $[33] !== t17 || $[34] !== t18 ? (t19 = /* @__PURE__ */ jsx(MenuItem, {
1479
- disabled: t17,
1480
- icon: ArrowUpIcon,
1481
- onClick: t18,
1482
- text: "Move up"
1483
- }), $[33] = t17, $[34] = t18, $[35] = t19) : t19 = $[35];
1484
- let t20 = index >= themes.length - 1, t21;
1485
- $[36] !== index || $[37] !== moveTo ? (t21 = () => moveTo(index + 1), $[36] = index, $[37] = moveTo, $[38] = t21) : t21 = $[38];
1486
- let t22;
1487
- $[39] !== t20 || $[40] !== t21 ? (t22 = /* @__PURE__ */ jsx(MenuItem, {
1488
- disabled: t20,
1489
- icon: ArrowDownIcon,
1490
- onClick: t21,
1491
- text: "Move down"
1492
- }), $[39] = t20, $[40] = t21, $[41] = t22) : t22 = $[41];
1493
- let t23;
1494
- $[42] === Symbol.for("react.memo_cache_sentinel") ? (t23 = /* @__PURE__ */ jsx(MenuDivider, {}), $[42] = t23) : t23 = $[42];
1495
- let t24;
1496
- $[43] !== send || $[44] !== theme.slug || $[45] !== theme.source ? (t24 = theme.source === "custom" && /* @__PURE__ */ jsx(MenuItem, {
1839
+ $[38] !== actorRef || $[39] !== theme.slug || $[40] !== theme.source ? (t19 = theme.source === "custom" && /* @__PURE__ */ jsx(MenuItem, {
1497
1840
  icon: EditIcon,
1498
- onClick: () => send({
1841
+ onClick: () => actorRef.send({
1499
1842
  type: "theme.edit",
1500
1843
  slug: theme.slug
1501
1844
  }),
1502
1845
  text: "Edit"
1503
- }), $[43] = send, $[44] = theme.slug, $[45] = theme.source, $[46] = t24) : t24 = $[46];
1504
- let t25;
1505
- $[47] !== send || $[48] !== theme.slug ? (t25 = () => send({
1846
+ }), $[38] = actorRef, $[39] = theme.slug, $[40] = theme.source, $[41] = t19) : t19 = $[41];
1847
+ let t20;
1848
+ $[42] !== actorRef || $[43] !== theme.slug ? (t20 = () => actorRef.send({
1506
1849
  type: "theme.duplicate",
1507
1850
  slug: theme.slug
1508
- }), $[47] = send, $[48] = theme.slug, $[49] = t25) : t25 = $[49];
1509
- let t26 = theme.source === "custom" ? "Duplicate" : "Duplicate to edit", t27;
1510
- $[50] !== t25 || $[51] !== t26 ? (t27 = /* @__PURE__ */ jsx(MenuItem, {
1851
+ }), $[42] = actorRef, $[43] = theme.slug, $[44] = t20) : t20 = $[44];
1852
+ let t21 = theme.source === "custom" ? "Duplicate" : "Duplicate to edit", t22;
1853
+ $[45] !== t20 || $[46] !== t21 ? (t22 = /* @__PURE__ */ jsx(MenuItem, {
1511
1854
  icon: CopyIcon,
1512
- onClick: t25,
1513
- text: t26
1514
- }), $[50] = t25, $[51] = t26, $[52] = t27) : t27 = $[52];
1515
- let t28;
1516
- $[53] !== copyTheme || $[54] !== theme ? (t28 = /* @__PURE__ */ jsx(MenuItem, {
1855
+ onClick: t20,
1856
+ text: t21
1857
+ }), $[45] = t20, $[46] = t21, $[47] = t22) : t22 = $[47];
1858
+ let t23;
1859
+ $[48] !== copyTheme || $[49] !== theme ? (t23 = /* @__PURE__ */ jsx(MenuItem, {
1517
1860
  icon: ShareIcon,
1518
1861
  onClick: () => void copyTheme(theme),
1519
1862
  text: "Copy to share"
1520
- }), $[53] = copyTheme, $[54] = theme, $[55] = t28) : t28 = $[55];
1521
- let t29;
1522
- $[56] !== send || $[57] !== theme.slug || $[58] !== theme.source ? (t29 = theme.source !== "config" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuDivider, {}), /* @__PURE__ */ jsx(MenuItem, {
1863
+ }), $[48] = copyTheme, $[49] = theme, $[50] = t23) : t23 = $[50];
1864
+ let t24;
1865
+ $[51] !== actorRef || $[52] !== theme.slug || $[53] !== theme.source ? (t24 = theme.source !== "config" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuDivider, {}), /* @__PURE__ */ jsx(MenuItem, {
1523
1866
  icon: TrashIcon,
1524
- onClick: () => send({
1867
+ onClick: () => actorRef.send({
1525
1868
  type: "theme.remove",
1526
1869
  slug: theme.slug
1527
1870
  }),
1528
1871
  text: "Remove",
1529
1872
  tone: "critical"
1530
- })] }), $[56] = send, $[57] = theme.slug, $[58] = theme.source, $[59] = t29) : t29 = $[59];
1531
- let t30;
1532
- $[60] !== t19 || $[61] !== t22 || $[62] !== t24 || $[63] !== t27 || $[64] !== t28 || $[65] !== t29 ? (t30 = /* @__PURE__ */ jsxs(Menu, { children: [
1873
+ })] }), $[51] = actorRef, $[52] = theme.slug, $[53] = theme.source, $[54] = t24) : t24 = $[54];
1874
+ let t25;
1875
+ $[55] !== t18 || $[56] !== t19 || $[57] !== t22 || $[58] !== t23 || $[59] !== t24 ? (t25 = /* @__PURE__ */ jsxs(Menu, { children: [
1876
+ t18,
1533
1877
  t19,
1534
1878
  t22,
1535
1879
  t23,
1536
- t24,
1537
- t27,
1538
- t28,
1539
- t29
1540
- ] }), $[60] = t19, $[61] = t22, $[62] = t24, $[63] = t27, $[64] = t28, $[65] = t29, $[66] = t30) : t30 = $[66];
1541
- let t31, t32;
1542
- $[67] === Symbol.for("react.memo_cache_sentinel") ? (t31 = () => setMenuOpen(!1), t32 = () => setMenuOpen(!0), $[67] = t31, $[68] = t32) : (t31 = $[67], t32 = $[68]);
1543
- let t33;
1544
- $[69] === scheme ? t33 = $[70] : (t33 = {
1880
+ t24
1881
+ ] }), $[55] = t18, $[56] = t19, $[57] = t22, $[58] = t23, $[59] = t24, $[60] = t25) : t25 = $[60];
1882
+ let t26, t27;
1883
+ $[61] === Symbol.for("react.memo_cache_sentinel") ? (t26 = () => setMenuOpen(!1), t27 = () => setMenuOpen(!0), $[61] = t26, $[62] = t27) : (t26 = $[61], t27 = $[62]);
1884
+ let t28;
1885
+ $[63] === scheme ? t28 = $[64] : (t28 = {
1545
1886
  animate: !0,
1546
1887
  placement: "bottom-end",
1547
1888
  portal: !0,
1548
1889
  scheme
1549
- }, $[69] = scheme, $[70] = t33);
1550
- let t34;
1551
- $[71] !== t15 || $[72] !== t16 || $[73] !== t30 || $[74] !== t33 ? (t34 = /* @__PURE__ */ jsx(Tooltip, {
1890
+ }, $[63] = scheme, $[64] = t28);
1891
+ let t29;
1892
+ $[65] !== menuId || $[66] !== t17 || $[67] !== t25 || $[68] !== t28 ? (t29 = /* @__PURE__ */ jsx(Tooltip, {
1552
1893
  animate: !0,
1553
- content: t13,
1894
+ content: t15,
1554
1895
  placement: "bottom",
1555
1896
  portal: !0,
1556
1897
  children: /* @__PURE__ */ jsx(Card, {
@@ -1558,158 +1899,55 @@ function ThemeCard(props) {
1558
1899
  radius: 2,
1559
1900
  scheme: "dark",
1560
1901
  children: /* @__PURE__ */ jsx(MenuButton, {
1561
- button: t15,
1562
- id: t16,
1563
- menu: t30,
1564
- onClose: t31,
1565
- onOpen: t32,
1566
- popover: t33
1902
+ button: t17,
1903
+ id: menuId,
1904
+ menu: t25,
1905
+ onClose: t26,
1906
+ onOpen: t27,
1907
+ popover: t28
1567
1908
  })
1568
1909
  })
1569
- }), $[71] = t15, $[72] = t16, $[73] = t30, $[74] = t33, $[75] = t34) : t34 = $[75];
1570
- let t35;
1571
- $[76] !== menuOpen || $[77] !== t34 ? (t35 = /* @__PURE__ */ jsx("div", {
1910
+ }), $[65] = menuId, $[66] = t17, $[67] = t25, $[68] = t28, $[69] = t29) : t29 = $[69];
1911
+ let t30;
1912
+ $[70] !== menuOpen || $[71] !== t29 ? (t30 = /* @__PURE__ */ jsx("div", {
1572
1913
  className: menuSlot,
1573
1914
  "data-visible": menuOpen,
1574
- children: t34
1575
- }), $[76] = menuOpen, $[77] = t34, $[78] = t35) : t35 = $[78];
1576
- let t36;
1577
- return $[79] !== dragControls || $[80] !== t12 || $[81] !== t35 || $[82] !== t5 || $[83] !== theme.slug ? (t36 = /* @__PURE__ */ jsxs(Reorder.Item, {
1915
+ children: t29
1916
+ }), $[70] = menuOpen, $[71] = t29, $[72] = t30) : t30 = $[72];
1917
+ let t31;
1918
+ return $[73] !== dragControls || $[74] !== t14 || $[75] !== t30 || $[76] !== t7 || $[77] !== theme.slug ? (t31 = /* @__PURE__ */ jsxs(Reorder.Item, {
1578
1919
  as: "div",
1579
1920
  className: root,
1580
1921
  dragControls,
1581
1922
  dragListener: !1,
1582
- onDragEnd: t3,
1583
- onDragStart: t4,
1584
- ref: t5,
1923
+ onDragEnd: t5,
1924
+ onDragStart: t6,
1925
+ ref: t7,
1585
1926
  value: theme.slug,
1586
- whileDrag: t6,
1587
- children: [t12, t35]
1588
- }), $[79] = dragControls, $[80] = t12, $[81] = t35, $[82] = t5, $[83] = theme.slug, $[84] = t36) : t36 = $[84], t36;
1927
+ whileDrag: t8,
1928
+ children: [t14, t30]
1929
+ }), $[73] = dragControls, $[74] = t14, $[75] = t30, $[76] = t7, $[77] = theme.slug, $[78] = t31) : t31 = $[78], t31;
1589
1930
  }
1590
- function _temp$1(candidate_0) {
1931
+ function _temp$3(candidate_0) {
1591
1932
  return candidate_0.slug;
1592
1933
  }
1593
- var cardGrid = "twjqgh0";
1594
- /**
1595
- * One column at the sidebar's default width; wider sidebars — and the
1596
- * overlay on small screens — fit more cards per row
1597
- */
1598
1934
  /**
1599
- * The flow for picking a theme: a grid of theme cards — the configured theme,
1600
- * the presets and the user's own themes — that drag into the order the user
1601
- * wants, with the entry points to the add and restore flows below. A theme
1602
- * code someone shared pastes right into the list, or through the paste button.
1935
+ * Reduces theme options to the minimal object that recreates them through
1936
+ * `buildTheme`: in each scheme the accent is dropped when it is the stock
1937
+ * one, the text color when it matches the one derived from the accent, and
1938
+ * the background and contrast when they match the defaults — and a scheme
1939
+ * with nothing left is dropped altogether. Options that boil down to the
1940
+ * stock Studio theme reduce to `null` — they need nothing from this package.
1603
1941
  *
1604
1942
  * @internal
1605
1943
  */
1606
- function ThemeList() {
1607
- let $ = c(38), { themes, removed, active, send } = useThemer(), { addThemeFromClipboard } = useThemeCodes(), [pasting, setPasting] = useState(!1);
1608
- usePasteThemeCodes();
1609
- let t0;
1610
- $[0] === send ? t0 = $[1] : (t0 = (palette, file) => send({
1611
- type: "theme.add",
1612
- title: titleFromFileName(file.name),
1613
- options: optionsFromImagePalette(palette),
1614
- palette,
1615
- imageUrl: URL.createObjectURL(file)
1616
- }), $[0] = send, $[1] = t0);
1617
- let { busy, pickImage } = useImagePalette(t0), t1;
1618
- $[2] === send ? t1 = $[3] : (t1 = (order) => send({
1619
- type: "theme.reorder",
1620
- order
1621
- }), $[2] = send, $[3] = t1);
1622
- let t2;
1623
- $[4] === themes ? t2 = $[5] : (t2 = themes.map(_temp), $[4] = themes, $[5] = t2);
1624
- let t3;
1625
- if ($[6] !== active || $[7] !== themes) {
1626
- let t4;
1627
- $[9] === active ? t4 = $[10] : (t4 = (theme_0) => /* @__PURE__ */ jsx(ThemeCard, {
1628
- active: theme_0.slug === active.slug,
1629
- theme: theme_0
1630
- }, theme_0.slug), $[9] = active, $[10] = t4), t3 = themes.map(t4), $[6] = active, $[7] = themes, $[8] = t3;
1631
- } else t3 = $[8];
1632
- let t4;
1633
- $[11] !== t1 || $[12] !== t2 || $[13] !== t3 ? (t4 = /* @__PURE__ */ jsx(MotionConfig, {
1634
- reducedMotion: "user",
1635
- children: /* @__PURE__ */ jsx(Reorder.Group, {
1636
- as: "div",
1637
- className: cardGrid,
1638
- onReorder: t1,
1639
- values: t2,
1640
- children: t3
1641
- })
1642
- }), $[11] = t1, $[12] = t2, $[13] = t3, $[14] = t4) : t4 = $[14];
1643
- let t5;
1644
- $[15] !== removed.length || $[16] !== send ? (t5 = removed.length > 0 && /* @__PURE__ */ jsx(Button, {
1645
- gap: 2,
1646
- icon: RestoreIcon,
1647
- mode: "bleed",
1648
- onClick: () => send({ type: "flow.removed" }),
1649
- padding: 2,
1650
- text: `Show removed (${removed.length})`,
1651
- width: "fill"
1652
- }), $[15] = removed.length, $[16] = send, $[17] = t5) : t5 = $[17];
1653
- let t6;
1654
- $[18] !== t4 || $[19] !== t5 ? (t6 = /* @__PURE__ */ jsx(ScrollArea, {
1655
- padding: 3,
1656
- children: /* @__PURE__ */ jsxs(Stack, {
1657
- gap: 4,
1658
- children: [t4, t5]
1659
- })
1660
- }), $[18] = t4, $[19] = t5, $[20] = t6) : t6 = $[20];
1661
- let t7;
1662
- $[21] === send ? t7 = $[22] : (t7 = /* @__PURE__ */ jsx(Box, {
1663
- flex: 1,
1664
- children: /* @__PURE__ */ jsx(TooltipButton, {
1665
- icon: AddIcon,
1666
- mode: "ghost",
1667
- onClick: () => send({ type: "theme.add" }),
1668
- text: "Add theme",
1669
- tooltip: "Add a theme based on the applied one",
1670
- width: "fill"
1671
- })
1672
- }), $[21] = send, $[22] = t7);
1673
- let t8;
1674
- $[23] !== busy || $[24] !== pickImage ? (t8 = /* @__PURE__ */ jsx(ImageFileButton, {
1675
- loading: busy,
1676
- mode: "ghost",
1677
- onFile: pickImage,
1678
- tooltip: "Add a theme from the colors of an image"
1679
- }), $[23] = busy, $[24] = pickImage, $[25] = t8) : t8 = $[25];
1680
- let t9;
1681
- $[26] === addThemeFromClipboard ? t9 = $[27] : (t9 = /* @__PURE__ */ jsx(TooltipButton, {
1682
- icon: ClipboardIcon,
1683
- mode: "ghost",
1684
- onClick: async () => {
1685
- await addThemeFromClipboard() !== "added" && setPasting(!0);
1686
- },
1687
- tooltip: "Add a theme from a code someone shared"
1688
- }), $[26] = addThemeFromClipboard, $[27] = t9);
1689
- let t10;
1690
- $[28] !== t7 || $[29] !== t8 || $[30] !== t9 ? (t10 = /* @__PURE__ */ jsx(Card, {
1691
- borderTop: !0,
1692
- padding: 3,
1693
- children: /* @__PURE__ */ jsxs(Flex, {
1694
- gap: 2,
1695
- children: [
1696
- t7,
1697
- t8,
1698
- t9
1699
- ]
1700
- })
1701
- }), $[28] = t7, $[29] = t8, $[30] = t9, $[31] = t10) : t10 = $[31];
1702
- let t11;
1703
- $[32] === pasting ? t11 = $[33] : (t11 = pasting && /* @__PURE__ */ jsx(PasteThemeDialog, { onClose: () => setPasting(!1) }), $[32] = pasting, $[33] = t11);
1704
- let t12;
1705
- return $[34] !== t10 || $[35] !== t11 || $[36] !== t6 ? (t12 = /* @__PURE__ */ jsxs(Fragment, { children: [
1706
- t6,
1707
- t10,
1708
- t11
1709
- ] }), $[34] = t10, $[35] = t11, $[36] = t6, $[37] = t12) : t12 = $[37], t12;
1710
- }
1711
- function _temp(theme) {
1712
- return theme.slug;
1944
+ function minimizeOptions(options) {
1945
+ let resolved = resolveThemeOptions(options), minimized = {};
1946
+ for (let scheme of SCHEMES) {
1947
+ let values = resolved[scheme], kept = {};
1948
+ values.accent !== DEFAULT_ACCENT && (kept.accent = values.accent), values.text !== deriveTextColor(values.accent) && (kept.text = values.text), values.background !== DEFAULT_BACKGROUND[scheme] && (kept.background = values.background), values.contrast !== 85 && (kept.contrast = values.contrast), Object.keys(kept).length > 0 && (minimized[scheme] = kept);
1949
+ }
1950
+ return Object.keys(minimized).length === 0 ? null : minimized;
1713
1951
  }
1714
1952
  /**
1715
1953
  * Serializes theme options into the `buildTheme` call to paste into
@@ -1746,7 +1984,7 @@ registerLanguage(typescript);
1746
1984
  * @internal
1747
1985
  */
1748
1986
  function ThemeSnippetDialog(props) {
1749
- let $ = c(23), { onClose, theme } = props, toast = useToast(), t0;
1987
+ let $ = c(24), { onClose, theme } = props, toast = useToast(), id = useId(), t0;
1750
1988
  $[0] === theme.options ? t0 = $[1] : (t0 = createThemeSnippet(theme.options), $[0] = theme.options, $[1] = t0);
1751
1989
  let snippet = t0, t1;
1752
1990
  $[2] !== snippet || $[3] !== toast ? (t1 = async () => {
@@ -1823,16 +2061,219 @@ function ThemeSnippetDialog(props) {
1823
2061
  })
1824
2062
  }), $[16] = t7, $[17] = t8, $[18] = t9) : t9 = $[18];
1825
2063
  let t10;
1826
- return $[19] !== onClose || $[20] !== t2 || $[21] !== t9 ? (t10 = /* @__PURE__ */ jsx(Dialog, {
2064
+ return $[19] !== id || $[20] !== onClose || $[21] !== t2 || $[22] !== t9 ? (t10 = /* @__PURE__ */ jsx(Dialog, {
1827
2065
  animate: !0,
1828
2066
  footer: t2,
1829
2067
  header: "Add to your config",
1830
- id: "themer-snippet",
2068
+ id,
1831
2069
  onClickOutside: onClose,
1832
2070
  onClose,
1833
2071
  width: 1,
1834
2072
  children: t9
1835
- }), $[19] = onClose, $[20] = t2, $[21] = t9, $[22] = t10) : t10 = $[22], t10;
2073
+ }), $[19] = id, $[20] = onClose, $[21] = t2, $[22] = t9, $[23] = t10) : t10 = $[23], t10;
2074
+ }
2075
+ var cardGrid = "twjqgh0";
2076
+ /**
2077
+ * The flow for picking a theme: a grid of theme cards — the configured theme,
2078
+ * the presets and the user's own themes — that drag into the order the user
2079
+ * wants, with the entry point to the restore flow below. The footer takes the
2080
+ * applied theme on to the editor — a copy of it, for a preset or the
2081
+ * configured theme — and keeps the ways to add a theme and the applied
2082
+ * theme's code behind its menu. A theme code someone shared pastes right into
2083
+ * the list too.
2084
+ *
2085
+ * @internal
2086
+ */
2087
+ function ThemeList(t0) {
2088
+ let $ = c(71), { actorRef, themes, removed, active } = t0, t1;
2089
+ $[0] === actorRef ? t1 = $[1] : (t1 = { actorRef }, $[0] = actorRef, $[1] = t1);
2090
+ let { addThemeFromClipboard } = useThemeCodes(t1), dialog = useSelector(actorRef, selectDialog), imageInputRef = useRef(null), actionsId = useId(), t2;
2091
+ $[2] === actorRef ? t2 = $[3] : (t2 = { actorRef }, $[2] = actorRef, $[3] = t2), usePasteThemeCodes(t2);
2092
+ let t3;
2093
+ $[4] === actorRef ? t3 = $[5] : (t3 = (palette, file) => actorRef.send({
2094
+ type: "theme.add",
2095
+ title: titleFromFileName(file.name),
2096
+ options: optionsFromImagePalette(palette),
2097
+ palette,
2098
+ imageUrl: URL.createObjectURL(file)
2099
+ }), $[4] = actorRef, $[5] = t3);
2100
+ let { busy, pickImage } = useImagePalette(t3), t4;
2101
+ $[6] === actorRef ? t4 = $[7] : (t4 = (order) => actorRef.send({
2102
+ type: "theme.reorder",
2103
+ order
2104
+ }), $[6] = actorRef, $[7] = t4);
2105
+ let t5;
2106
+ $[8] === themes ? t5 = $[9] : (t5 = themes.map(_temp$2), $[8] = themes, $[9] = t5);
2107
+ let t6 = !active, t7;
2108
+ $[10] === Symbol.for("react.memo_cache_sentinel") ? (t7 = {
2109
+ slug: CONFIG_SLUG,
2110
+ title: CONFIG_TITLE,
2111
+ options: {},
2112
+ source: "config"
2113
+ }, $[10] = t7) : t7 = $[10];
2114
+ let t8;
2115
+ $[11] !== actorRef || $[12] !== t6 || $[13] !== themes ? (t8 = /* @__PURE__ */ jsx(ThemeCard, {
2116
+ actorRef,
2117
+ active: t6,
2118
+ theme: t7,
2119
+ themes
2120
+ }), $[11] = actorRef, $[12] = t6, $[13] = themes, $[14] = t8) : t8 = $[14];
2121
+ let t9;
2122
+ $[15] !== active?.slug || $[16] !== actorRef || $[17] !== themes ? (t9 = themes.map((theme_0) => /* @__PURE__ */ jsx(ThemeCard, {
2123
+ actorRef,
2124
+ active: theme_0.slug === active?.slug,
2125
+ theme: theme_0,
2126
+ themes
2127
+ }, theme_0.slug)), $[15] = active?.slug, $[16] = actorRef, $[17] = themes, $[18] = t9) : t9 = $[18];
2128
+ let t10;
2129
+ $[19] !== t4 || $[20] !== t5 || $[21] !== t8 || $[22] !== t9 ? (t10 = /* @__PURE__ */ jsx(MotionConfig, {
2130
+ reducedMotion: "user",
2131
+ children: /* @__PURE__ */ jsxs(Reorder.Group, {
2132
+ as: "div",
2133
+ className: cardGrid,
2134
+ onReorder: t4,
2135
+ values: t5,
2136
+ children: [t8, t9]
2137
+ })
2138
+ }), $[19] = t4, $[20] = t5, $[21] = t8, $[22] = t9, $[23] = t10) : t10 = $[23];
2139
+ let t11;
2140
+ $[24] !== actorRef || $[25] !== removed.length ? (t11 = removed.length > 0 && /* @__PURE__ */ jsx(Button, {
2141
+ gap: 2,
2142
+ icon: RestoreIcon,
2143
+ mode: "bleed",
2144
+ onClick: () => actorRef.send({ type: "flow.removed" }),
2145
+ padding: 2,
2146
+ text: `Show removed (${removed.length})`,
2147
+ width: "fill"
2148
+ }), $[24] = actorRef, $[25] = removed.length, $[26] = t11) : t11 = $[26];
2149
+ let t12;
2150
+ $[27] !== t10 || $[28] !== t11 ? (t12 = /* @__PURE__ */ jsx(ScrollArea, {
2151
+ padding: 3,
2152
+ children: /* @__PURE__ */ jsxs(Stack, {
2153
+ gap: 4,
2154
+ children: [t10, t11]
2155
+ })
2156
+ }), $[27] = t10, $[28] = t11, $[29] = t12) : t12 = $[29];
2157
+ let t13;
2158
+ $[30] !== active || $[31] !== actorRef ? (t13 = active?.source === "custom" ? /* @__PURE__ */ jsx(Button, {
2159
+ gap: 2,
2160
+ icon: EditIcon,
2161
+ onClick: () => actorRef.send({
2162
+ type: "theme.edit",
2163
+ slug: active.slug
2164
+ }),
2165
+ padding: 2,
2166
+ text: "Edit",
2167
+ mode: "ghost"
2168
+ }) : /* @__PURE__ */ jsx(Button, {
2169
+ gap: 2,
2170
+ icon: CopyIcon,
2171
+ onClick: () => actorRef.send({
2172
+ type: "theme.duplicate",
2173
+ slug: active?.slug ?? "config"
2174
+ }),
2175
+ padding: 2,
2176
+ text: "Duplicate & Edit",
2177
+ mode: "ghost"
2178
+ }), $[30] = active, $[31] = actorRef, $[32] = t13) : t13 = $[32];
2179
+ let t14;
2180
+ $[33] === busy ? t14 = $[34] : (t14 = /* @__PURE__ */ jsx(Button, {
2181
+ "aria-label": "More actions",
2182
+ icon: EllipsisHorizontalIcon,
2183
+ loading: busy,
2184
+ mode: "bleed",
2185
+ padding: 2
2186
+ }), $[33] = busy, $[34] = t14);
2187
+ let t15;
2188
+ $[35] === actorRef ? t15 = $[36] : (t15 = /* @__PURE__ */ jsx(MenuItem, {
2189
+ icon: AddIcon,
2190
+ onClick: () => actorRef.send({ type: "theme.add" }),
2191
+ text: "Add theme"
2192
+ }), $[35] = actorRef, $[36] = t15);
2193
+ let t16;
2194
+ $[37] === Symbol.for("react.memo_cache_sentinel") ? (t16 = /* @__PURE__ */ jsx(MenuItem, {
2195
+ icon: ImageIcon,
2196
+ onClick: () => imageInputRef.current?.click(),
2197
+ text: "Add from image"
2198
+ }), $[37] = t16) : t16 = $[37];
2199
+ let t17;
2200
+ $[38] !== actorRef || $[39] !== addThemeFromClipboard ? (t17 = /* @__PURE__ */ jsx(MenuItem, {
2201
+ icon: ClipboardIcon,
2202
+ onClick: async () => {
2203
+ await addThemeFromClipboard() !== "added" && actorRef.send({ type: "dialog.paste" });
2204
+ },
2205
+ text: "Add from code"
2206
+ }), $[38] = actorRef, $[39] = addThemeFromClipboard, $[40] = t17) : t17 = $[40];
2207
+ let t18;
2208
+ $[41] !== active || $[42] !== actorRef ? (t18 = active && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuDivider, {}), /* @__PURE__ */ jsx(MenuItem, {
2209
+ icon: CodeBlockIcon,
2210
+ onClick: () => actorRef.send({ type: "dialog.snippet" }),
2211
+ text: "Show theme code"
2212
+ })] }), $[41] = active, $[42] = actorRef, $[43] = t18) : t18 = $[43];
2213
+ let t19;
2214
+ $[44] !== t15 || $[45] !== t17 || $[46] !== t18 ? (t19 = /* @__PURE__ */ jsxs(Menu, { children: [
2215
+ t15,
2216
+ t16,
2217
+ t17,
2218
+ t18
2219
+ ] }), $[44] = t15, $[45] = t17, $[46] = t18, $[47] = t19) : t19 = $[47];
2220
+ let t20;
2221
+ $[48] === Symbol.for("react.memo_cache_sentinel") ? (t20 = {
2222
+ animate: !0,
2223
+ placement: "top-end",
2224
+ portal: !0
2225
+ }, $[48] = t20) : t20 = $[48];
2226
+ let t21;
2227
+ $[49] !== actionsId || $[50] !== t14 || $[51] !== t19 ? (t21 = /* @__PURE__ */ jsx(MenuButton, {
2228
+ button: t14,
2229
+ id: actionsId,
2230
+ menu: t19,
2231
+ popover: t20
2232
+ }), $[49] = actionsId, $[50] = t14, $[51] = t19, $[52] = t21) : t21 = $[52];
2233
+ let t22;
2234
+ $[53] !== t13 || $[54] !== t21 ? (t22 = /* @__PURE__ */ jsx(Card, {
2235
+ borderTop: !0,
2236
+ padding: 3,
2237
+ children: /* @__PURE__ */ jsxs(Flex, {
2238
+ align: "center",
2239
+ gap: 2,
2240
+ justify: "flex-end",
2241
+ children: [t13, t21]
2242
+ })
2243
+ }), $[53] = t13, $[54] = t21, $[55] = t22) : t22 = $[55];
2244
+ let t23;
2245
+ $[56] === pickImage ? t23 = $[57] : (t23 = /* @__PURE__ */ jsx(ImageFileInput, {
2246
+ onFile: pickImage,
2247
+ ref: imageInputRef
2248
+ }), $[56] = pickImage, $[57] = t23);
2249
+ let t24;
2250
+ $[58] !== actorRef || $[59] !== dialog ? (t24 = dialog === "paste" && /* @__PURE__ */ jsx(PasteThemeDialog, {
2251
+ actorRef,
2252
+ onClose: () => actorRef.send({ type: "dialog.close" })
2253
+ }), $[58] = actorRef, $[59] = dialog, $[60] = t24) : t24 = $[60];
2254
+ let t25;
2255
+ $[61] !== active || $[62] !== actorRef || $[63] !== dialog ? (t25 = dialog === "snippet" && active && /* @__PURE__ */ jsx(ThemeSnippetDialog, {
2256
+ onClose: () => actorRef.send({ type: "dialog.close" }),
2257
+ theme: active
2258
+ }), $[61] = active, $[62] = actorRef, $[63] = dialog, $[64] = t25) : t25 = $[64];
2259
+ let t26;
2260
+ return $[65] !== t12 || $[66] !== t22 || $[67] !== t23 || $[68] !== t24 || $[69] !== t25 ? (t26 = /* @__PURE__ */ jsxs(Fragment, { children: [
2261
+ t12,
2262
+ t22,
2263
+ t23,
2264
+ t24,
2265
+ t25
2266
+ ] }), $[65] = t12, $[66] = t22, $[67] = t23, $[68] = t24, $[69] = t25, $[70] = t26) : t26 = $[70], t26;
2267
+ }
2268
+ function _temp$2(theme) {
2269
+ return theme.slug;
2270
+ }
2271
+ /** The dialog the list has open, if any — a state of the machine's list flow */
2272
+ function selectDialog(snapshot) {
2273
+ return snapshot.matches({ flow: { list: "pasting" } }) ? "paste" : snapshot.matches({ flow: { list: "snippet" } }) ? "snippet" : null;
2274
+ }
2275
+ function useIsTooSmallForSplitScreen() {
2276
+ return useMediaIndex() <= 3;
1836
2277
  }
1837
2278
  var title = "c2pqej0";
1838
2279
  const VIEW_TITLES = {
@@ -1841,26 +2282,20 @@ const VIEW_TITLES = {
1841
2282
  removed: "Removed themes"
1842
2283
  };
1843
2284
  /**
1844
- * The themer sidebar: a header that navigates between the flows and toggles
1845
- * the split preview, the flow itself — picking a theme, editing one, or
1846
- * restoring removed ones — and the dialog with the `buildTheme` snippet of
1847
- * the applied theme.
2285
+ * The themer sidebar: a header with the flow's title, the split preview
2286
+ * toggle and the close button, and the flow itself — picking a theme, editing
2287
+ * one, or restoring removed ones. Each flow ends in a footer like the
2288
+ * Studio's document footer: one primary action, with the rest of its actions
2289
+ * behind a menu button, and the way back to the list where the flow is not
2290
+ * the list.
1848
2291
  *
1849
2292
  * @internal
1850
2293
  */
1851
- function ThemerSidebar() {
1852
- let $ = c(42), { active, split, view, navbarHeight, send } = useThemer(), [snippetOpen, setSnippetOpen] = useState(!1), inList = view.name === "list", t0;
1853
- $[0] === navbarHeight ? t0 = $[1] : (t0 = navbarHeight === null ? void 0 : { height: navbarHeight }, $[0] = navbarHeight, $[1] = t0);
1854
- let t1;
1855
- $[2] !== inList || $[3] !== send ? (t1 = !inList && /* @__PURE__ */ jsx(TooltipButton, {
1856
- icon: ArrowLeftIcon,
1857
- mode: "bleed",
1858
- onClick: () => send({ type: "flow.list" }),
1859
- padding: 2,
1860
- tooltip: "Back to the themes"
1861
- }), $[2] = inList, $[3] = send, $[4] = t1) : t1 = $[4];
2294
+ function ThemerSidebar(t0) {
2295
+ let $ = c(46), { actorRef, dispatch, navbarHeight, split } = t0, view = useSelector(actorRef, selectView, sameView), isTooSmallForSplitScreen = useIsTooSmallForSplitScreen(), { themes, removed, active } = useSelector(actorRef, _temp$1, dequal), t1;
2296
+ $[0] === navbarHeight ? t1 = $[1] : (t1 = navbarHeight === null ? void 0 : { height: navbarHeight }, $[0] = navbarHeight, $[1] = t1);
1862
2297
  let t2 = VIEW_TITLES[view.name], t3;
1863
- $[5] === t2 ? t3 = $[6] : (t3 = /* @__PURE__ */ jsx(Box, {
2298
+ $[2] === t2 ? t3 = $[3] : (t3 = /* @__PURE__ */ jsx(Box, {
1864
2299
  className: title,
1865
2300
  flex: 1,
1866
2301
  children: /* @__PURE__ */ jsx(Text, {
@@ -1869,84 +2304,110 @@ function ThemerSidebar() {
1869
2304
  weight: "semibold",
1870
2305
  children: t2
1871
2306
  })
1872
- }), $[5] = t2, $[6] = t3);
2307
+ }), $[2] = t2, $[3] = t3);
1873
2308
  let t4;
1874
- $[7] !== send || $[8] !== split || $[9] !== view.name ? (t4 = view.name !== "removed" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(TooltipButton, {
2309
+ $[4] !== dispatch || $[5] !== isTooSmallForSplitScreen || $[6] !== split ? (t4 = !isTooSmallForSplitScreen && /* @__PURE__ */ jsx(TooltipButton, {
1875
2310
  "aria-pressed": split,
1876
2311
  icon: SplitVerticalIcon,
1877
2312
  mode: "bleed",
1878
- onClick: () => send({ type: "preview.toggle" }),
2313
+ onClick: () => startTransition(() => {
2314
+ let type = split ? "split-screen:close" : "split-screen:open";
2315
+ addThemerTransitionType(type), dispatch({ type });
2316
+ }),
2317
+ onMouseEnter: () => startTransition(() => {
2318
+ dispatch({ type: "split-screen:prerender" });
2319
+ }),
1879
2320
  padding: 2,
1880
2321
  selected: split,
1881
2322
  tooltip: "Show light and dark side by side"
1882
- }), /* @__PURE__ */ jsx(TooltipButton, {
1883
- icon: CodeBlockIcon,
1884
- mode: "bleed",
1885
- onClick: () => setSnippetOpen(!0),
1886
- padding: 2,
1887
- tooltip: "Show the code for the applied theme"
1888
- })] }), $[7] = send, $[8] = split, $[9] = view.name, $[10] = t4) : t4 = $[10];
2323
+ }), $[4] = dispatch, $[5] = isTooSmallForSplitScreen, $[6] = split, $[7] = t4) : t4 = $[7];
1889
2324
  let t5;
1890
- $[11] === send ? t5 = $[12] : (t5 = /* @__PURE__ */ jsx(TooltipButton, {
2325
+ $[8] !== dispatch || $[9] !== split ? (t5 = /* @__PURE__ */ jsx(TooltipButton, {
1891
2326
  icon: CloseIcon,
1892
2327
  mode: "bleed",
1893
- onClick: () => send({ type: "sidebar.close" }),
2328
+ onClick: () => startTransition(() => {
2329
+ split && addThemerTransitionType("split-screen:close"), addThemerTransitionType("close"), dispatch({ type: "close" });
2330
+ }),
1894
2331
  padding: 2,
1895
2332
  tooltip: "Close themer"
1896
- }), $[11] = send, $[12] = t5);
2333
+ }), $[8] = dispatch, $[9] = split, $[10] = t5) : t5 = $[10];
1897
2334
  let t6;
1898
- $[13] !== t4 || $[14] !== t5 ? (t6 = /* @__PURE__ */ jsxs(Flex, { children: [t4, t5] }), $[13] = t4, $[14] = t5, $[15] = t6) : t6 = $[15];
2335
+ $[11] !== t4 || $[12] !== t5 ? (t6 = /* @__PURE__ */ jsxs(Flex, { children: [t4, t5] }), $[11] = t4, $[12] = t5, $[13] = t6) : t6 = $[13];
1899
2336
  let t7;
1900
- $[16] !== t1 || $[17] !== t3 || $[18] !== t6 ? (t7 = /* @__PURE__ */ jsxs(Flex, {
2337
+ $[14] !== t3 || $[15] !== t6 ? (t7 = /* @__PURE__ */ jsxs(Flex, {
1901
2338
  align: "center",
1902
2339
  gap: 1,
1903
2340
  height: "fill",
1904
- children: [
1905
- t1,
1906
- t3,
1907
- t6
1908
- ]
1909
- }), $[16] = t1, $[17] = t3, $[18] = t6, $[19] = t7) : t7 = $[19];
2341
+ children: [t3, t6]
2342
+ }), $[14] = t3, $[15] = t6, $[16] = t7) : t7 = $[16];
1910
2343
  let t8;
1911
- $[20] !== t0 || $[21] !== t7 ? (t8 = /* @__PURE__ */ jsx(Card, {
2344
+ $[17] !== t1 || $[18] !== t7 ? (t8 = /* @__PURE__ */ jsx(Card, {
1912
2345
  borderBottom: !0,
1913
2346
  padding: 3,
1914
2347
  sizing: "border",
1915
- style: t0,
2348
+ style: t1,
1916
2349
  children: t7
1917
- }), $[20] = t0, $[21] = t7, $[22] = t8) : t8 = $[22];
1918
- let t9;
1919
- $[23] === view.name ? t9 = $[24] : (t9 = view.name === "list" && /* @__PURE__ */ jsx(ThemeList, {}), $[23] = view.name, $[24] = t9);
1920
- let t10;
1921
- $[25] !== view.focusTitle || $[26] !== view.name || $[27] !== view.slug ? (t10 = view.name === "edit" && /* @__PURE__ */ jsx(ThemeEditor, {
1922
- focusTitle: view.focusTitle,
1923
- slug: view.slug
1924
- }), $[25] = view.focusTitle, $[26] = view.name, $[27] = view.slug, $[28] = t10) : t10 = $[28];
2350
+ }), $[17] = t1, $[18] = t7, $[19] = t8) : t8 = $[19];
2351
+ let t9 = view.name === "list" ? "visible" : "hidden", t10;
2352
+ $[20] !== active || $[21] !== actorRef || $[22] !== removed || $[23] !== themes ? (t10 = /* @__PURE__ */ jsx(ThemeList, {
2353
+ actorRef,
2354
+ active,
2355
+ removed,
2356
+ themes
2357
+ }), $[20] = active, $[21] = actorRef, $[22] = removed, $[23] = themes, $[24] = t10) : t10 = $[24];
1925
2358
  let t11;
1926
- $[29] === view.name ? t11 = $[30] : (t11 = view.name === "removed" && /* @__PURE__ */ jsx(RemovedThemes, {}), $[29] = view.name, $[30] = t11);
2359
+ $[25] !== t10 || $[26] !== t9 ? (t11 = /* @__PURE__ */ jsx(Activity, {
2360
+ mode: t9,
2361
+ children: t10
2362
+ }, "list"), $[25] = t10, $[26] = t9, $[27] = t11) : t11 = $[27];
1927
2363
  let t12;
1928
- $[31] !== t10 || $[32] !== t11 || $[33] !== t8 || $[34] !== t9 ? (t12 = /* @__PURE__ */ jsxs(Flex, {
1929
- direction: "column",
1930
- height: "fill",
1931
- children: [
1932
- t8,
1933
- t9,
1934
- t10,
1935
- t11
1936
- ]
1937
- }), $[31] = t10, $[32] = t11, $[33] = t8, $[34] = t9, $[35] = t12) : t12 = $[35];
1938
- let t13;
1939
- $[36] !== active || $[37] !== snippetOpen ? (t13 = snippetOpen && /* @__PURE__ */ jsx(ThemeSnippetDialog, {
1940
- onClose: () => setSnippetOpen(!1),
1941
- theme: active
1942
- }), $[36] = active, $[37] = snippetOpen, $[38] = t13) : t13 = $[38];
1943
- let t14;
1944
- return $[39] !== t12 || $[40] !== t13 ? (t14 = /* @__PURE__ */ jsxs(Card, {
2364
+ $[28] !== actorRef || $[29] !== split || $[30] !== themes || $[31] !== view.focusTitle || $[32] !== view.name || $[33] !== view.slug ? (t12 = view.name === "edit" && /* @__PURE__ */ jsx(ThemeEditor, {
2365
+ actorRef,
2366
+ focusTitle: view.focusTitle,
2367
+ slug: view.slug,
2368
+ split,
2369
+ themes
2370
+ }), $[28] = actorRef, $[29] = split, $[30] = themes, $[31] = view.focusTitle, $[32] = view.name, $[33] = view.slug, $[34] = t12) : t12 = $[34];
2371
+ let t13 = view.name === "removed" ? "visible" : "hidden", t14;
2372
+ $[35] !== actorRef || $[36] !== removed ? (t14 = /* @__PURE__ */ jsx(RemovedThemes, {
2373
+ actorRef,
2374
+ removed
2375
+ }), $[35] = actorRef, $[36] = removed, $[37] = t14) : t14 = $[37];
2376
+ let t15;
2377
+ $[38] !== t13 || $[39] !== t14 ? (t15 = /* @__PURE__ */ jsx(Activity, {
2378
+ mode: t13,
2379
+ children: t14
2380
+ }, "removed"), $[38] = t13, $[39] = t14, $[40] = t15) : t15 = $[40];
2381
+ let t16;
2382
+ return $[41] !== t11 || $[42] !== t12 || $[43] !== t15 || $[44] !== t8 ? (t16 = /* @__PURE__ */ jsx(Card, {
1945
2383
  height: "fill",
1946
- children: [t12, t13]
1947
- }), $[39] = t12, $[40] = t13, $[41] = t14) : t14 = $[41], t14;
2384
+ children: /* @__PURE__ */ jsxs(Flex, {
2385
+ direction: "column",
2386
+ height: "fill",
2387
+ children: [
2388
+ t8,
2389
+ t11,
2390
+ t12,
2391
+ t15
2392
+ ]
2393
+ })
2394
+ }), $[41] = t11, $[42] = t12, $[43] = t15, $[44] = t8, $[45] = t16) : t16 = $[45], t16;
2395
+ }
2396
+ function _temp$1(snapshot) {
2397
+ return resolveThemes(snapshot.context);
2398
+ }
2399
+ function selectView(snapshot) {
2400
+ let { editing } = snapshot.context;
2401
+ return snapshot.matches({ flow: "edit" }) && editing ? {
2402
+ name: "edit",
2403
+ slug: editing.slug,
2404
+ focusTitle: editing.focusTitle
2405
+ } : snapshot.matches({ flow: "removed" }) ? { name: "removed" } : { name: "list" };
2406
+ }
2407
+ function sameView(a, b) {
2408
+ return a.name === b.name ? a.name !== "edit" || b.name !== "edit" || a.slug === b.slug && a.focusTitle === b.focusTitle : !1;
1948
2409
  }
1949
- var content = "bgn4np4", frame = "bgn4np3", sidebar = "bgn4np2";
2410
+ var content = "bgn4np3", frame = "bgn4np2", resizeHandle = "bgn4np4", sidebar = "bgn4np1";
1950
2411
  /** How far one arrow key press resizes the sidebar */
1951
2412
  const WIDTH_STORAGE_KEY = "sanityStudio:themer:width";
1952
2413
  function clampWidth(width) {
@@ -1973,27 +2434,27 @@ function writeStoredWidth(width) {
1973
2434
  *
1974
2435
  * @internal
1975
2436
  */
1976
- function ResizableSidebar(props) {
1977
- let $ = c(24), { overlay } = props, [width, setWidth] = useState(readStoredWidth), [dragging, setDragging] = useState(!1), drag = useRef(null), t0, t1;
1978
- $[0] === width ? (t0 = $[1], t1 = $[2]) : (t0 = () => writeStoredWidth(width), t1 = [width], $[0] = width, $[1] = t0, $[2] = t1), useEffect(t0, t1);
1979
- let t2;
1980
- $[3] === width ? t2 = $[4] : (t2 = (event) => {
2437
+ function ResizableSidebar(t0) {
2438
+ let $ = c(30), { actorRef, dispatch, navbarHeight, split } = t0, [width, setWidth] = useState(readStoredWidth), [dragging, setDragging] = useState(!1), drag = useRef(null), t1, t2;
2439
+ $[0] === width ? (t1 = $[1], t2 = $[2]) : (t1 = () => writeStoredWidth(width), t2 = [width], $[0] = width, $[1] = t1, $[2] = t2), useEffect(t1, t2);
2440
+ let t3;
2441
+ $[3] === width ? t3 = $[4] : (t3 = (event) => {
1981
2442
  event.button === 0 && (event.preventDefault(), event.currentTarget.setPointerCapture(event.pointerId), drag.current = {
1982
2443
  pointerId: event.pointerId,
1983
2444
  startX: event.clientX,
1984
2445
  startWidth: width
1985
2446
  }, setDragging(!0));
1986
- }, $[3] = width, $[4] = t2);
1987
- let handlePointerDown = t2, t3;
1988
- $[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = (event_0) => {
2447
+ }, $[3] = width, $[4] = t3);
2448
+ let handlePointerDown = t3, t4;
2449
+ $[5] === Symbol.for("react.memo_cache_sentinel") ? (t4 = (event_0) => {
1989
2450
  drag.current && drag.current.pointerId === event_0.pointerId && setWidth(clampWidth(drag.current.startWidth - (event_0.clientX - drag.current.startX)));
1990
- }, $[5] = t3) : t3 = $[5];
1991
- let handlePointerMove = t3, t4;
1992
- $[6] === Symbol.for("react.memo_cache_sentinel") ? (t4 = (event_1) => {
2451
+ }, $[5] = t4) : t4 = $[5];
2452
+ let handlePointerMove = t4, t5;
2453
+ $[6] === Symbol.for("react.memo_cache_sentinel") ? (t5 = (event_1) => {
1993
2454
  drag.current && drag.current.pointerId === event_1.pointerId && (drag.current = null, setDragging(!1));
1994
- }, $[6] = t4) : t4 = $[6];
1995
- let handlePointerUp = t4, t5;
1996
- $[7] === Symbol.for("react.memo_cache_sentinel") ? (t5 = (event_2) => {
2455
+ }, $[6] = t5) : t5 = $[6];
2456
+ let handlePointerUp = t5, t6;
2457
+ $[7] === Symbol.for("react.memo_cache_sentinel") ? (t6 = (event_2) => {
1997
2458
  let step = {
1998
2459
  ArrowLeft: 16,
1999
2460
  ArrowRight: -16,
@@ -2001,19 +2462,23 @@ function ResizableSidebar(props) {
2001
2462
  End: -400
2002
2463
  }[event_2.key];
2003
2464
  step !== void 0 && (event_2.preventDefault(), setWidth((current) => clampWidth(current + step)));
2004
- }, $[7] = t5) : t5 = $[7];
2005
- let handleKeyDown = t5, t6;
2006
- $[8] !== overlay || $[9] !== width ? (t6 = overlay ? void 0 : { width }, $[8] = overlay, $[9] = width, $[10] = t6) : t6 = $[10];
2007
- let t7 = !overlay, t8;
2008
- $[11] !== dragging || $[12] !== handlePointerDown || $[13] !== overlay || $[14] !== width ? (t8 = !overlay && /* @__PURE__ */ jsx("div", {
2465
+ }, $[7] = t6) : t6 = $[7];
2466
+ let handleKeyDown = t6, [boundaryElement, setBoundaryElement] = useState(null), t7;
2467
+ $[8] === width ? t7 = $[9] : (t7 = { width }, $[8] = width, $[9] = t7);
2468
+ let t8;
2469
+ $[10] === Symbol.for("react.memo_cache_sentinel") ? (t8 = (boundaryElement_0) => (startTransition(() => setBoundaryElement(boundaryElement_0)), _temp), $[10] = t8) : t8 = $[10];
2470
+ let t9;
2471
+ $[11] === Symbol.for("react.memo_cache_sentinel") ? (t9 = () => setWidth(200), $[11] = t9) : t9 = $[11];
2472
+ let t10;
2473
+ $[12] !== dragging || $[13] !== handlePointerDown || $[14] !== width ? (t10 = /* @__PURE__ */ jsx("div", {
2009
2474
  "aria-label": "Resize the themer",
2010
- className: "bgn4np5",
2475
+ className: resizeHandle,
2011
2476
  "aria-orientation": "vertical",
2012
2477
  "aria-valuemax": 400,
2013
2478
  "aria-valuemin": 200,
2014
2479
  "aria-valuenow": width,
2015
2480
  "data-dragging": dragging,
2016
- onDoubleClick: () => setWidth(200),
2481
+ onDoubleClick: t9,
2017
2482
  onKeyDown: handleKeyDown,
2018
2483
  onPointerCancel: handlePointerUp,
2019
2484
  onPointerDown: handlePointerDown,
@@ -2021,30 +2486,41 @@ function ResizableSidebar(props) {
2021
2486
  onPointerUp: handlePointerUp,
2022
2487
  role: "separator",
2023
2488
  tabIndex: 0
2024
- }), $[11] = dragging, $[12] = handlePointerDown, $[13] = overlay, $[14] = width, $[15] = t8) : t8 = $[15];
2025
- let t9;
2026
- $[16] === Symbol.for("react.memo_cache_sentinel") ? (t9 = /* @__PURE__ */ jsx(Box, {
2489
+ }), $[12] = dragging, $[13] = handlePointerDown, $[14] = width, $[15] = t10) : t10 = $[15];
2490
+ let t11;
2491
+ $[16] !== actorRef || $[17] !== dispatch || $[18] !== navbarHeight || $[19] !== split ? (t11 = /* @__PURE__ */ jsx(ThemerSidebar, {
2492
+ split,
2493
+ navbarHeight,
2494
+ actorRef,
2495
+ dispatch
2496
+ }), $[16] = actorRef, $[17] = dispatch, $[18] = navbarHeight, $[19] = split, $[20] = t11) : t11 = $[20];
2497
+ let t12;
2498
+ $[21] !== boundaryElement || $[22] !== t11 ? (t12 = /* @__PURE__ */ jsx(Box, {
2027
2499
  className: content,
2028
2500
  height: "fill",
2029
2501
  overflow: "hidden",
2030
- children: /* @__PURE__ */ jsx(ThemerSidebar, {})
2031
- }), $[16] = t9) : t9 = $[16];
2032
- let t10;
2033
- $[17] !== t7 || $[18] !== t8 ? (t10 = /* @__PURE__ */ jsxs(Card, {
2034
- borderLeft: t7,
2502
+ children: /* @__PURE__ */ jsx(BoundaryElementProvider, {
2503
+ element: boundaryElement,
2504
+ children: t11
2505
+ })
2506
+ }), $[21] = boundaryElement, $[22] = t11, $[23] = t12) : t12 = $[23];
2507
+ let t13;
2508
+ $[24] !== t10 || $[25] !== t12 ? (t13 = /* @__PURE__ */ jsxs(Card, {
2509
+ borderLeft: !0,
2035
2510
  className: frame,
2036
2511
  height: "fill",
2037
- children: [t8, t9]
2038
- }), $[17] = t7, $[18] = t8, $[19] = t10) : t10 = $[19];
2039
- let t11;
2040
- return $[20] !== overlay || $[21] !== t10 || $[22] !== t6 ? (t11 = /* @__PURE__ */ jsx(Layer, {
2512
+ ref: t8,
2513
+ children: [t10, t12]
2514
+ }), $[24] = t10, $[25] = t12, $[26] = t13) : t13 = $[26];
2515
+ let t14;
2516
+ return $[27] !== t13 || $[28] !== t7 ? (t14 = /* @__PURE__ */ jsx(Layer, {
2041
2517
  className: sidebar,
2042
- "data-overlay": overlay,
2043
- style: t6,
2518
+ style: t7,
2044
2519
  zOffset: 100,
2045
- children: t10
2046
- }), $[20] = overlay, $[21] = t10, $[22] = t6, $[23] = t11) : t11 = $[23], t11;
2520
+ children: t13
2521
+ }), $[27] = t13, $[28] = t7, $[29] = t14) : t14 = $[29], t14;
2047
2522
  }
2523
+ function _temp() {}
2048
2524
  export { ResizableSidebar as default };
2049
2525
 
2050
- //# sourceMappingURL=ResizableSidebar-DD787kQr.js.map
2526
+ //# sourceMappingURL=ResizableSidebar-C1nr3Ls2.js.map