@sanity/themer 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/AnimatedColorWheelIcon-DEy-cy3X.js +171 -0
- package/dist/AnimatedColorWheelIcon-DEy-cy3X.js.map +1 -0
- package/dist/{ResizableSidebar-DD787kQr.js → ResizableSidebar-BpgLA4XQ.js} +817 -430
- package/dist/ResizableSidebar-BpgLA4XQ.js.map +1 -0
- package/dist/bundle.css +102 -322
- package/dist/index.d.ts +70 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/legacy.d.ts +13 -12
- package/dist/legacy.d.ts.map +1 -1
- package/dist/presets-CqBgS3A-.js.map +1 -1
- package/dist/themes-Bxgltjmb.js +139 -0
- package/dist/themes-Bxgltjmb.js.map +1 -0
- package/dist/tool.d.ts +5 -16
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +649 -818
- package/dist/tool.js.map +1 -1
- package/package.json +23 -20
- package/dist/ResizableSidebar-DD787kQr.js.map +0 -1
- package/dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js +0 -422
- package/dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js.map +0 -1
- package/dist/options-CU-emn_p.d.ts +0 -69
- package/dist/options-CU-emn_p.d.ts.map +0 -1
package/dist/tool.js
CHANGED
|
@@ -1,205 +1,442 @@
|
|
|
1
1
|
import "@sanity/themer/bundle.css";
|
|
2
2
|
import { l as isColor, n as buildTheme, o as SCHEMES, t as presets } from "./presets-CqBgS3A-.js";
|
|
3
|
-
import { a as
|
|
4
|
-
import { blue, cyan, green, magenta, orange, purple, red, yellow } from "@sanity/color";
|
|
3
|
+
import { a as displayTitle, c as resolveThemes, d as viewTransitionClasses, f as NAVBAR_SELECTOR, i as createCustomTheme, l as addThemerTransitionType, n as CONFIG_TITLE, o as duplicateTitle, s as initialThemerState, u as layout } from "./themes-Bxgltjmb.js";
|
|
5
4
|
import { c } from "react/compiler-runtime";
|
|
6
5
|
import { definePlugin, useColorSchemeValue } from "sanity";
|
|
7
|
-
import { Button, Card, Flex, Text, ThemeProvider, useMediaIndex, usePrefersReducedMotion } from "@sanity/ui";
|
|
8
|
-
import { useActor, useSelector } from "@xstate/react";
|
|
9
|
-
import { Activity, ViewTransition, addTransitionType, lazy, startTransition, useDeferredValue, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
10
|
-
import { assign, not, or, setup, stateIn } from "xstate";
|
|
11
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
6
|
import { ColorWheelIcon } from "@sanity/icons/ColorWheel";
|
|
7
|
+
import { BoundaryElementProvider, Box, Button, Card, Flex, Text, ThemeProvider, useMediaIndex } from "@sanity/ui";
|
|
13
8
|
import { Tooltip } from "@sanity/ui/tooltip";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
import { Activity, Suspense, ViewTransition, createContext, lazy, startTransition, use, useEffect, useReducer, useRef, useState, useTransition } from "react";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { browser } from "react-dom";
|
|
12
|
+
import { dequal } from "dequal/lite";
|
|
13
|
+
import * as v from "valibot";
|
|
14
|
+
import { useActorRef } from "@xstate/react";
|
|
15
|
+
import { assign, not, setup } from "xstate";
|
|
16
|
+
/** @internal */
|
|
17
|
+
const ToolIsOpenContext = createContext(!1), ToolDispatchContext = createContext(() => {
|
|
18
|
+
throw Error("ToolDispatchContext not initialized");
|
|
19
|
+
}), ToolSplitIsOpenContext = createContext(!1), ToolShouldDetectNavbarHeightContext = createContext(!1), PluginConfigContext = createContext(null), AnimatedColorWheelIcon = lazy(() => import("./AnimatedColorWheelIcon-DEy-cy3X.js"));
|
|
20
|
+
function ThemerNavbarButton() {
|
|
21
|
+
let $ = c(27), config = use(PluginConfigContext), dispatch = use(ToolDispatchContext), open = use(ToolIsOpenContext), shouldDetectNavbarHeight = use(ToolShouldDetectNavbarHeightContext), split = use(ToolSplitIsOpenContext);
|
|
22
|
+
if (!config) throw TypeError("PluginConfigContext.Provider is missing");
|
|
23
|
+
let [busy, startBusyTransition] = useTransition(), iconRef = useRef(null), t0;
|
|
24
|
+
$[0] !== dispatch || $[1] !== split ? (t0 = () => startBusyTransition(() => {
|
|
25
|
+
split && addThemerTransitionType("split-screen:open"), addThemerTransitionType("open"), dispatch({ type: "open" });
|
|
26
|
+
}), $[0] = dispatch, $[1] = split, $[2] = t0) : t0 = $[2];
|
|
27
|
+
let handleOpen = t0, t1;
|
|
28
|
+
$[3] !== dispatch || $[4] !== split ? (t1 = () => startBusyTransition(() => {
|
|
29
|
+
split && addThemerTransitionType("split-screen:close"), addThemerTransitionType("close"), dispatch({ type: "close" });
|
|
30
|
+
}), $[3] = dispatch, $[4] = split, $[5] = t1) : t1 = $[5];
|
|
31
|
+
let handleClose = t1, t2;
|
|
32
|
+
$[6] !== dispatch || $[7] !== open ? (t2 = () => startTransition(() => {
|
|
33
|
+
dispatch({ type: "prerender" }), open || iconRef.current?.spin();
|
|
34
|
+
}), $[6] = dispatch, $[7] = open, $[8] = t2) : t2 = $[8];
|
|
35
|
+
let handlePrerender = t2, t3;
|
|
36
|
+
$[9] === dispatch ? t3 = $[10] : (t3 = (root) => {
|
|
37
|
+
let navbar = root?.closest(NAVBAR_SELECTOR);
|
|
38
|
+
if (!navbar) return;
|
|
39
|
+
let resizeObserver = new ResizeObserver((entries) => {
|
|
40
|
+
let height = entries[0]?.borderBoxSize[0]?.blockSize;
|
|
41
|
+
height && startTransition(() => dispatch({
|
|
42
|
+
type: "set-navbar-height",
|
|
43
|
+
height
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
return resizeObserver.observe(navbar), () => resizeObserver.disconnect();
|
|
47
|
+
}, $[9] = dispatch, $[10] = t3);
|
|
48
|
+
let observeNavbarHeight = t3, { title } = config, t4;
|
|
49
|
+
$[11] === title ? t4 = $[12] : (t4 = /* @__PURE__ */ jsx(Text, {
|
|
50
|
+
size: 1,
|
|
51
|
+
children: title
|
|
52
|
+
}), $[11] = title, $[12] = t4);
|
|
53
|
+
let t5 = shouldDetectNavbarHeight ? observeNavbarHeight : void 0, t6;
|
|
54
|
+
$[13] === Symbol.for("react.memo_cache_sentinel") ? (t6 = /* @__PURE__ */ jsx(ColorWheelIcon, {}), $[13] = t6) : t6 = $[13];
|
|
55
|
+
let t7;
|
|
56
|
+
$[14] === busy ? t7 = $[15] : (t7 = /* @__PURE__ */ jsx(Suspense, {
|
|
57
|
+
fallback: t6,
|
|
58
|
+
children: /* @__PURE__ */ jsx(AnimatedColorWheelIcon, {
|
|
59
|
+
busy,
|
|
60
|
+
ref: iconRef
|
|
61
|
+
})
|
|
62
|
+
}), $[14] = busy, $[15] = t7);
|
|
63
|
+
let t8 = open ? handleClose : handleOpen, t9 = open || busy, t10;
|
|
64
|
+
$[16] !== busy || $[17] !== handlePrerender || $[18] !== t5 || $[19] !== t7 || $[20] !== t8 || $[21] !== t9 || $[22] !== title ? (t10 = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(ViewTransition, {
|
|
65
|
+
default: "none",
|
|
66
|
+
update: viewTransitionClasses.navbarButton.update,
|
|
67
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
68
|
+
ref: t5,
|
|
69
|
+
"aria-busy": busy,
|
|
70
|
+
"aria-label": title,
|
|
71
|
+
icon: t7,
|
|
72
|
+
mode: "bleed",
|
|
73
|
+
onClick: t8,
|
|
74
|
+
onFocus: handlePrerender,
|
|
75
|
+
onMouseEnter: handlePrerender,
|
|
76
|
+
padding: 2,
|
|
77
|
+
selected: t9
|
|
78
|
+
})
|
|
79
|
+
}) }), $[16] = busy, $[17] = handlePrerender, $[18] = t5, $[19] = t7, $[20] = t8, $[21] = t9, $[22] = title, $[23] = t10) : t10 = $[23];
|
|
80
|
+
let t11;
|
|
81
|
+
return $[24] !== t10 || $[25] !== t4 ? (t11 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
82
|
+
default: "none",
|
|
83
|
+
update: viewTransitionClasses.navbarButtonTooltip.update,
|
|
84
|
+
children: /* @__PURE__ */ jsx(Tooltip, {
|
|
85
|
+
animate: !0,
|
|
86
|
+
content: t4,
|
|
87
|
+
portal: !0,
|
|
88
|
+
children: t10
|
|
89
|
+
})
|
|
90
|
+
}), $[24] = t10, $[25] = t4, $[26] = t11) : t11 = $[26], t11;
|
|
18
91
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
92
|
+
function ThemerNavbar(props) {
|
|
93
|
+
"use memo";
|
|
94
|
+
let $ = c(4), t0;
|
|
95
|
+
if ($[0] !== props) {
|
|
96
|
+
let button = {
|
|
97
|
+
location: "topbar",
|
|
98
|
+
name: "themer-topbar",
|
|
99
|
+
render: ThemerNavbarButton
|
|
100
|
+
}, t1;
|
|
101
|
+
$[2] === props.__internal_actions ? t1 = $[3] : (t1 = props.__internal_actions ?? [], $[2] = props.__internal_actions, $[3] = t1), t0 = props.renderDefault({
|
|
102
|
+
...props,
|
|
103
|
+
__internal_actions: [...t1, button]
|
|
104
|
+
}), $[0] = props, $[1] = t0;
|
|
105
|
+
} else t0 = $[1];
|
|
106
|
+
return t0;
|
|
21
107
|
}
|
|
22
|
-
function
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
108
|
+
function ThemerNavbarProvider(t0) {
|
|
109
|
+
let $ = c(15), { children, config, dispatch, open, shouldDetectNavbarHeight, split } = t0, t1 = shouldDetectNavbarHeight ?? !1, t2;
|
|
110
|
+
$[0] !== children || $[1] !== t1 ? (t2 = /* @__PURE__ */ jsx(ToolShouldDetectNavbarHeightContext, {
|
|
111
|
+
value: t1,
|
|
112
|
+
children
|
|
113
|
+
}), $[0] = children, $[1] = t1, $[2] = t2) : t2 = $[2];
|
|
114
|
+
let t3;
|
|
115
|
+
$[3] !== split || $[4] !== t2 ? (t3 = /* @__PURE__ */ jsx(ToolSplitIsOpenContext, {
|
|
116
|
+
value: split,
|
|
117
|
+
children: t2
|
|
118
|
+
}), $[3] = split, $[4] = t2, $[5] = t3) : t3 = $[5];
|
|
119
|
+
let t4;
|
|
120
|
+
$[6] !== open || $[7] !== t3 ? (t4 = /* @__PURE__ */ jsx(ToolIsOpenContext, {
|
|
121
|
+
value: open,
|
|
122
|
+
children: t3
|
|
123
|
+
}), $[6] = open, $[7] = t3, $[8] = t4) : t4 = $[8];
|
|
124
|
+
let t5;
|
|
125
|
+
$[9] !== dispatch || $[10] !== t4 ? (t5 = /* @__PURE__ */ jsx(ToolDispatchContext, {
|
|
126
|
+
value: dispatch,
|
|
127
|
+
children: t4
|
|
128
|
+
}), $[9] = dispatch, $[10] = t4, $[11] = t5) : t5 = $[11];
|
|
129
|
+
let t6;
|
|
130
|
+
return $[12] !== config || $[13] !== t5 ? (t6 = /* @__PURE__ */ jsx(PluginConfigContext, {
|
|
131
|
+
value: config,
|
|
132
|
+
children: t5
|
|
133
|
+
}), $[12] = config, $[13] = t5, $[14] = t6) : t6 = $[14], t6;
|
|
134
|
+
}
|
|
135
|
+
function toolReducer(state, action) {
|
|
136
|
+
switch (action.type) {
|
|
137
|
+
case "set-navbar-height": return state.navbarHeight === action.height ? state : {
|
|
138
|
+
...state,
|
|
139
|
+
navbarHeight: action.height
|
|
140
|
+
};
|
|
141
|
+
case "prerender": return state.prerender ? state : {
|
|
142
|
+
...state,
|
|
143
|
+
prerender: !0
|
|
144
|
+
};
|
|
145
|
+
case "open": return state.open ? state : {
|
|
146
|
+
...state,
|
|
147
|
+
open: !0,
|
|
148
|
+
prerender: !0
|
|
149
|
+
};
|
|
150
|
+
case "close": return state.open ? {
|
|
151
|
+
...state,
|
|
152
|
+
open: !1
|
|
153
|
+
} : state;
|
|
154
|
+
case "split-screen:prerender": return state.prerenderSplitScreen ? state : {
|
|
155
|
+
...state,
|
|
156
|
+
prerenderSplitScreen: !0
|
|
157
|
+
};
|
|
158
|
+
case "split-screen:open": return state.split ? state : {
|
|
159
|
+
...state,
|
|
160
|
+
prerenderSplitScreen: !0,
|
|
161
|
+
split: !0
|
|
162
|
+
};
|
|
163
|
+
case "split-screen:close": return state.split ? {
|
|
164
|
+
...state,
|
|
165
|
+
split: !1
|
|
166
|
+
} : state;
|
|
167
|
+
case "unset-theme": return state.theme === null ? state : {
|
|
168
|
+
...state,
|
|
169
|
+
theme: null
|
|
170
|
+
};
|
|
171
|
+
case "set-theme": return dequal(state.theme, action.theme) ? state : {
|
|
172
|
+
...state,
|
|
173
|
+
theme: action.theme
|
|
174
|
+
};
|
|
175
|
+
default: throw Error(`Unknown themer tool action: ${JSON.stringify(action)}`);
|
|
176
|
+
}
|
|
27
177
|
}
|
|
178
|
+
const initialToolState = {
|
|
179
|
+
navbarHeight: null,
|
|
180
|
+
open: !1,
|
|
181
|
+
prerender: !1,
|
|
182
|
+
prerenderSplitScreen: !1,
|
|
183
|
+
split: !1,
|
|
184
|
+
theme: null
|
|
185
|
+
};
|
|
28
186
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
187
|
+
* The options of the applied theme — `null` for the configured theme, which
|
|
188
|
+
* applies nothing on top of the Studio's own, and for an applied theme that
|
|
189
|
+
* no longer resolves. Cheaper than resolving the whole list when only the
|
|
190
|
+
* applied theme matters.
|
|
191
|
+
*
|
|
192
|
+
* @internal
|
|
32
193
|
*/
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
let
|
|
37
|
-
|
|
38
|
-
let backgrounds = Reflect.get(value, "background"), options = {};
|
|
39
|
-
for (let scheme of SCHEMES) {
|
|
40
|
-
let background = backgrounds && typeof backgrounds == "object" ? sanitizeColor(Reflect.get(backgrounds, scheme)) : null;
|
|
41
|
-
options[scheme] = background ? {
|
|
42
|
-
...shared,
|
|
43
|
-
background
|
|
44
|
-
} : { ...shared };
|
|
45
|
-
}
|
|
46
|
-
return options;
|
|
194
|
+
function resolveActiveThemeOptions(state) {
|
|
195
|
+
if (state.active === null || state.removed.includes(state.active)) return null;
|
|
196
|
+
for (let theme of state.custom) if (theme.slug === state.active) return theme.options;
|
|
197
|
+
for (let preset of presets) if (preset.slug === state.active) return preset.options;
|
|
198
|
+
return null;
|
|
47
199
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
200
|
+
/** Drops the keys whose value is `undefined`, which a dropped option leaves behind */
|
|
201
|
+
function compact(value) {
|
|
202
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
|
|
203
|
+
}
|
|
204
|
+
/** A `#rgb` or `#rrggbb` color, lowercased */
|
|
205
|
+
const color = v.pipe(v.string(), v.check(isColor), v.toLowerCase()), optionalColor = v.fallback(v.optional(color), void 0), optionalContrast = v.fallback(v.optional(v.pipe(v.number(), v.finite(), v.toMinValue(15), v.toMaxValue(100))), void 0), schemeOptionsSchema = v.pipe(v.object({
|
|
206
|
+
accent: optionalColor,
|
|
207
|
+
text: optionalColor,
|
|
208
|
+
background: optionalColor,
|
|
209
|
+
contrast: optionalContrast
|
|
210
|
+
}), v.transform((options) => compact(options))), groupedOptionsSchema = v.pipe(v.looseObject({
|
|
211
|
+
light: v.fallback(v.optional(schemeOptionsSchema), void 0),
|
|
212
|
+
dark: v.fallback(v.optional(schemeOptionsSchema), void 0)
|
|
213
|
+
}), v.check((input) => !("accent" in input), "flat options"), v.transform(({ light, dark }) => {
|
|
51
214
|
let options = {};
|
|
215
|
+
return light && Object.keys(light).length > 0 && (options.light = light), dark && Object.keys(dark).length > 0 && (options.dark = dark), options;
|
|
216
|
+
})), flatOptionsSchema = v.pipe(v.object({
|
|
217
|
+
accent: color,
|
|
218
|
+
text: optionalColor,
|
|
219
|
+
contrast: optionalContrast,
|
|
220
|
+
background: v.fallback(v.optional(v.object({
|
|
221
|
+
light: optionalColor,
|
|
222
|
+
dark: optionalColor
|
|
223
|
+
})), void 0)
|
|
224
|
+
}), v.transform(({ accent, text, contrast, background }) => {
|
|
225
|
+
let shared = compact({
|
|
226
|
+
accent,
|
|
227
|
+
text,
|
|
228
|
+
contrast
|
|
229
|
+
}), options = {};
|
|
52
230
|
for (let scheme of SCHEMES) {
|
|
53
|
-
let
|
|
54
|
-
|
|
231
|
+
let schemeBackground = background?.[scheme];
|
|
232
|
+
options[scheme] = schemeBackground ? {
|
|
233
|
+
...shared,
|
|
234
|
+
background: schemeBackground
|
|
235
|
+
} : { ...shared };
|
|
55
236
|
}
|
|
56
237
|
return options;
|
|
57
|
-
}
|
|
238
|
+
})), themeOptionsSchema = v.union([flatOptionsSchema, groupedOptionsSchema]), swatch = v.fallback(v.optional(v.nullable(color), null), null), paletteSchema = v.pipe(v.object({
|
|
239
|
+
vibrant: swatch,
|
|
240
|
+
lightVibrant: swatch,
|
|
241
|
+
darkVibrant: swatch,
|
|
242
|
+
muted: swatch,
|
|
243
|
+
lightMuted: swatch,
|
|
244
|
+
darkMuted: swatch,
|
|
245
|
+
dominant: swatch
|
|
246
|
+
}), v.transform((palette) => Object.values(palette).some((item) => item !== null) ? palette : null));
|
|
58
247
|
function isReservedSlug(slug) {
|
|
59
248
|
return slug === "config" || presets.some((preset) => preset.slug === slug);
|
|
60
249
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
let
|
|
78
|
-
for (let
|
|
79
|
-
let
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
return swatches > 0 ? palette : null;
|
|
83
|
-
}
|
|
84
|
-
function sanitizeState(value) {
|
|
85
|
-
if (!value || typeof value != "object") return initialThemerState;
|
|
86
|
-
let custom = [], rawCustom = Reflect.get(value, "custom");
|
|
87
|
-
if (Array.isArray(rawCustom)) for (let item of rawCustom) {
|
|
88
|
-
let theme = sanitizeCustomTheme(item);
|
|
89
|
-
theme && !custom.some((existing) => existing.slug === theme.slug) && custom.push(theme);
|
|
250
|
+
const customThemeSchema = v.pipe(v.object({
|
|
251
|
+
slug: v.pipe(v.string(), v.nonEmpty(), v.check((slug) => !isReservedSlug(slug), "reserved slug")),
|
|
252
|
+
title: v.fallback(v.optional(v.string()), void 0),
|
|
253
|
+
options: themeOptionsSchema,
|
|
254
|
+
palette: v.fallback(v.optional(paletteSchema), void 0)
|
|
255
|
+
}), v.transform(({ slug, title, options, palette }) => ({
|
|
256
|
+
slug,
|
|
257
|
+
title: displayTitle(title ?? ""),
|
|
258
|
+
options,
|
|
259
|
+
...palette ? { palette } : {}
|
|
260
|
+
}))), lenientList = v.fallback(v.optional(v.array(v.unknown()), []), []), themerStateSchema = v.pipe(v.object({
|
|
261
|
+
active: v.fallback(v.nullable(v.string()), null),
|
|
262
|
+
custom: lenientList,
|
|
263
|
+
removed: lenientList,
|
|
264
|
+
order: lenientList
|
|
265
|
+
}), v.transform((state) => {
|
|
266
|
+
let custom = [];
|
|
267
|
+
for (let item of state.custom) {
|
|
268
|
+
let result = v.safeParse(customThemeSchema, item);
|
|
269
|
+
result.success && !custom.some((theme) => theme.slug === result.output.slug) && custom.push(result.output);
|
|
90
270
|
}
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
let order
|
|
94
|
-
if (Array.isArray(rawOrder)) for (let slug of rawOrder) typeof slug == "string" && (slug === "config" || presets.some((preset) => preset.slug === slug) || custom.some((theme) => theme.slug === slug)) && !order.includes(slug) && order.push(slug);
|
|
95
|
-
let rawActive = Reflect.get(value, "active");
|
|
271
|
+
let isCustom = (slug) => custom.some((theme) => theme.slug === slug), isPreset = (slug) => presets.some((preset) => preset.slug === slug), removed = [], order = [];
|
|
272
|
+
for (let slug of state.removed) typeof slug != "string" || slug === "config" || removed.includes(slug) || (isPreset(slug) || isCustom(slug)) && removed.push(slug);
|
|
273
|
+
for (let slug of state.order) typeof slug != "string" || order.includes(slug) || (slug === "config" || isPreset(slug) || isCustom(slug)) && order.push(slug);
|
|
96
274
|
return {
|
|
97
|
-
active:
|
|
275
|
+
active: state.active,
|
|
98
276
|
custom,
|
|
99
277
|
removed,
|
|
100
278
|
order
|
|
101
279
|
};
|
|
280
|
+
}));
|
|
281
|
+
/** The persisted themer state, or `null` for anything else @internal */
|
|
282
|
+
function parseThemerState(input) {
|
|
283
|
+
let result = v.safeParse(themerStateSchema, input);
|
|
284
|
+
return result.success ? result.output : null;
|
|
102
285
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
286
|
+
/** The machine's state value, as persisted — only what the machine has states for restores @internal */
|
|
287
|
+
const snapshotValueSchema = v.object({
|
|
288
|
+
flow: v.picklist([
|
|
289
|
+
"list",
|
|
290
|
+
"edit",
|
|
291
|
+
"removed"
|
|
292
|
+
]),
|
|
293
|
+
theme: v.picklist(["applied", "switching"])
|
|
294
|
+
});
|
|
295
|
+
/**
|
|
296
|
+
* A snapshot for the machine to start a session from: the given themes, with
|
|
297
|
+
* nothing being switched to, in the list unless a flow and its subject are
|
|
298
|
+
* given. It is how the themes alone — all that earlier versions persisted —
|
|
299
|
+
* are handed to a machine that only restores snapshots, and what a restored
|
|
300
|
+
* snapshot is made fit for this session as.
|
|
301
|
+
*
|
|
302
|
+
* @internal
|
|
303
|
+
*/
|
|
304
|
+
function snapshotFromState(state, editing = null, flow = "list") {
|
|
109
305
|
return {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
306
|
+
status: "active",
|
|
307
|
+
output: void 0,
|
|
308
|
+
error: void 0,
|
|
309
|
+
value: {
|
|
310
|
+
flow,
|
|
311
|
+
theme: "applied"
|
|
312
|
+
},
|
|
313
|
+
context: {
|
|
314
|
+
...state,
|
|
315
|
+
editing,
|
|
316
|
+
images: {}
|
|
317
|
+
},
|
|
318
|
+
historyValue: {},
|
|
319
|
+
children: {}
|
|
114
320
|
};
|
|
115
321
|
}
|
|
116
322
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
323
|
+
* The machine's snapshot as the last session persisted it, made fit for this
|
|
324
|
+
* one: the themes are parsed like any persisted state, the flow keeps its
|
|
325
|
+
* subject or falls back to the list, a switch that was under way is over,
|
|
326
|
+
* and the image URLs of the last session are gone with it.
|
|
120
327
|
*
|
|
121
328
|
* @internal
|
|
122
329
|
*/
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
330
|
+
const persistedSnapshotSchema = v.pipe(v.object({
|
|
331
|
+
status: v.literal("active"),
|
|
332
|
+
value: snapshotValueSchema,
|
|
333
|
+
context: v.pipe(v.looseObject({ editing: v.fallback(v.nullable(v.object({
|
|
334
|
+
slug: v.string(),
|
|
335
|
+
focusTitle: v.boolean()
|
|
336
|
+
})), null) }), v.transform(({ editing, ...state }) => ({
|
|
337
|
+
editing,
|
|
338
|
+
state: parseThemerState(state)
|
|
339
|
+
})), v.check(({ state }) => state !== null, "no themes"))
|
|
340
|
+
}), v.transform(({ value, context }) => {
|
|
341
|
+
let state = context.state ?? {
|
|
342
|
+
active: null,
|
|
343
|
+
custom: [],
|
|
344
|
+
removed: [],
|
|
345
|
+
order: []
|
|
346
|
+
}, editing = context.editing && state.custom.some((theme) => theme.slug === context.editing?.slug) && !state.removed.includes(context.editing.slug) ? context.editing : null;
|
|
347
|
+
return snapshotFromState(state, editing, value.flow === "edit" && editing === null || value.flow === "removed" && state.removed.length === 0 ? "list" : value.flow);
|
|
348
|
+
})), SNAPSHOT_STORAGE_KEY = "sanityStudio:themer:snapshot", STATE_STORAGE_KEY = "sanityStudio:themer:state", LEGACY_STORAGE_KEY = "sanityStudio:themer:options", LEGACY_DRAFT = {
|
|
349
|
+
slug: "custom-draft",
|
|
350
|
+
title: "Draft theme"
|
|
351
|
+
};
|
|
352
|
+
function readJson(key) {
|
|
353
|
+
let raw = localStorage.getItem(key);
|
|
354
|
+
return raw ? JSON.parse(raw) : void 0;
|
|
138
355
|
}
|
|
139
356
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
357
|
+
* Restores the machine's snapshot from what the last session persisted, for
|
|
358
|
+
* `createActor` to start from, so the user's themes survive Studio reloads:
|
|
359
|
+
* the snapshot itself where there is one that fits, and one made from the
|
|
360
|
+
* themes alone where the snapshot no longer fits the machine or where
|
|
361
|
+
* earlier versions of the tool stored the themes without a snapshot.
|
|
362
|
+
* `undefined` when nothing usable is stored — or storage cannot be read at
|
|
363
|
+
* all — leaves the machine to start from no themes.
|
|
364
|
+
*
|
|
365
|
+
* The parsing is the schemas' (see `schemas.ts`): nothing here or in the
|
|
366
|
+
* machine looks at what is stored beyond handing it over.
|
|
142
367
|
*
|
|
143
368
|
* @internal
|
|
144
369
|
*/
|
|
145
|
-
function
|
|
370
|
+
function readPersistedSnapshot() {
|
|
146
371
|
try {
|
|
147
|
-
|
|
372
|
+
if (typeof localStorage > "u") return;
|
|
373
|
+
let persisted = readJson(SNAPSHOT_STORAGE_KEY);
|
|
374
|
+
if (persisted !== void 0) {
|
|
375
|
+
let snapshot = v.safeParse(persistedSnapshotSchema, persisted);
|
|
376
|
+
if (snapshot.success) return snapshot.output;
|
|
377
|
+
let state = parseThemerState(persisted && typeof persisted == "object" ? Reflect.get(persisted, "context") : void 0);
|
|
378
|
+
if (state) return snapshotFromState(state);
|
|
379
|
+
}
|
|
380
|
+
let state = parseThemerState(readJson(STATE_STORAGE_KEY));
|
|
381
|
+
return state ? snapshotFromState(state) : readLegacyDraft();
|
|
148
382
|
} catch {
|
|
149
|
-
return
|
|
383
|
+
return;
|
|
150
384
|
}
|
|
151
385
|
}
|
|
386
|
+
function readLegacyDraft() {
|
|
387
|
+
let options = v.safeParse(themeOptionsSchema, readJson(LEGACY_STORAGE_KEY));
|
|
388
|
+
if (!options.success) return;
|
|
389
|
+
let theme = {
|
|
390
|
+
...LEGACY_DRAFT,
|
|
391
|
+
options: options.output
|
|
392
|
+
};
|
|
393
|
+
return snapshotFromState({
|
|
394
|
+
active: theme.slug,
|
|
395
|
+
custom: [theme],
|
|
396
|
+
removed: [],
|
|
397
|
+
order: []
|
|
398
|
+
});
|
|
399
|
+
}
|
|
152
400
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
401
|
+
* Persists the machine's snapshot for the next session, and lets go of what
|
|
402
|
+
* earlier versions stored once it is written — which completes their
|
|
403
|
+
* migration.
|
|
155
404
|
*
|
|
156
405
|
* @internal
|
|
157
406
|
*/
|
|
158
|
-
function
|
|
407
|
+
function writePersistedSnapshot(snapshot) {
|
|
159
408
|
try {
|
|
160
|
-
if (typeof localStorage > "u"
|
|
161
|
-
localStorage.setItem(
|
|
409
|
+
if (typeof localStorage > "u") return;
|
|
410
|
+
localStorage.setItem(SNAPSHOT_STORAGE_KEY, JSON.stringify(snapshot)), localStorage.removeItem(STATE_STORAGE_KEY), localStorage.removeItem(LEGACY_STORAGE_KEY);
|
|
162
411
|
} catch {}
|
|
163
412
|
}
|
|
164
|
-
/**
|
|
165
|
-
* How long the layout's motions — the panel's and the split preview's, and
|
|
166
|
-
* the cross-fade to another theme — are taken to last when the layout never
|
|
167
|
-
* says: it reports every view transition it starts, so this only ends a
|
|
168
|
-
* motion that has none (reduced motion, a browser without view transitions),
|
|
169
|
-
* where the `moving` and `switching` tags have nothing to affect. Generous,
|
|
170
|
-
* so that it never runs out before a slow deferred commit starts the real one.
|
|
171
|
-
*
|
|
172
|
-
* @internal
|
|
173
|
-
*/
|
|
174
|
-
const MOTION_DURATION = 2e3;
|
|
175
413
|
function themesOf(context) {
|
|
176
|
-
return resolveThemes(context
|
|
414
|
+
return resolveThemes(context);
|
|
177
415
|
}
|
|
178
416
|
function revokeObjectUrl(url) {
|
|
179
417
|
typeof URL < "u" && typeof URL.revokeObjectURL == "function" && URL.revokeObjectURL(url);
|
|
180
418
|
}
|
|
181
419
|
/**
|
|
182
|
-
* The
|
|
183
|
-
* `
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
420
|
+
* The themes of the themer tool and the sidebar's way through them: which
|
|
421
|
+
* `flow` the sidebar is in — picking a theme from the `list`, `edit`ing one of
|
|
422
|
+
* the user's own themes, or restoring `removed` ones — and, in a parallel
|
|
423
|
+
* `theme` region, whether another theme was just applied. The context carries
|
|
424
|
+
* the persisted state (the applied theme, the user's themes and what was
|
|
425
|
+
* removed) alongside what the flows need. Whether the sidebar is open and
|
|
426
|
+
* whether the Studio shows twice is not the machine's: the tool reducer in
|
|
427
|
+
* `ThemerProvider` owns that, so that the navbar toggle and the sidebar can
|
|
428
|
+
* change it in transitions of their own. Nor is persisting: the machine
|
|
429
|
+
* never touches storage and takes no input — it starts from no themes, and a
|
|
430
|
+
* session with something to pick up from restores its persisted snapshot
|
|
431
|
+
* instead (see `storage.ts` and `sync.ts`), while the persisted state of
|
|
432
|
+
* other tabs reaches it as a `themes.sync` event like any other.
|
|
189
433
|
*
|
|
190
|
-
* The
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* that applies another theme — picking one, adding, duplicating, importing or
|
|
197
|
-
* editing one, removing or deleting the applied one — when the layout
|
|
198
|
-
* cross-fades to it; edits to the applied theme's colors are not switches,
|
|
199
|
-
* they follow the pointer. These states last until the layout reports its
|
|
200
|
-
* transition under way — every boundary reports, the panel's and the copy's
|
|
201
|
-
* entering and leaving as much as the Studio's morphing — or for
|
|
202
|
-
* `MOTION_DURATION` when nothing animates.
|
|
434
|
+
* The `theme` region is `switching` (its tag) right after an event that
|
|
435
|
+
* applies another theme — picking one, adding, duplicating, importing or
|
|
436
|
+
* editing one, removing or deleting the applied one — which is when the
|
|
437
|
+
* layout cross-fades the Studio to it. Edits to the applied theme's colors are
|
|
438
|
+
* not switches, they follow the pointer: the first one ends the switch, and so
|
|
439
|
+
* does `MOTION_DURATION` when none follows.
|
|
203
440
|
*
|
|
204
441
|
* Theme operations are handled in every flow, and the flows leave on their
|
|
205
442
|
* own when they lose their subject: the editor when its theme is removed or
|
|
@@ -210,34 +447,30 @@ function revokeObjectUrl(url) {
|
|
|
210
447
|
const themerMachine = setup({
|
|
211
448
|
types: {
|
|
212
449
|
context: {},
|
|
213
|
-
events: {}
|
|
214
|
-
input: {}
|
|
450
|
+
events: {}
|
|
215
451
|
},
|
|
216
452
|
guards: {
|
|
217
453
|
isCustomTheme: ({ context }, params) => themesOf(context).themes.some((theme) => theme.slug === params.slug && theme.source === "custom"),
|
|
218
454
|
isEditingListedTheme: ({ context }) => context.editing !== null && themesOf(context).themes.some((theme) => theme.slug === context.editing?.slug && theme.source === "custom"),
|
|
219
455
|
hasRemovedThemes: ({ context }) => themesOf(context).removed.length > 0,
|
|
220
|
-
sidebarShown: or([stateIn({ sidebar: "opening" }), stateIn({ sidebar: "open" })]),
|
|
221
456
|
isAnotherTheme: ({ context }, params) => params.slug !== (context.active ?? "config"),
|
|
222
457
|
isAppliedTheme: ({ context }, params) => params.slug === context.active,
|
|
458
|
+
appliesAnotherTheme: ({ context }, params) => params.state.active !== context.active,
|
|
223
459
|
hasOptions: (_, params) => params.options !== void 0
|
|
224
460
|
},
|
|
225
461
|
actions: {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
order
|
|
233
|
-
});
|
|
234
|
-
},
|
|
462
|
+
sync: assign((_, params) => ({
|
|
463
|
+
active: params.state.active,
|
|
464
|
+
custom: params.state.custom,
|
|
465
|
+
removed: params.state.removed,
|
|
466
|
+
order: params.state.order
|
|
467
|
+
})),
|
|
235
468
|
revokeImage: (_, params) => {
|
|
236
469
|
params.url && revokeObjectUrl(params.url);
|
|
237
470
|
},
|
|
238
471
|
pick: assign((_, params) => ({ active: params.slug === "config" ? null : params.slug })),
|
|
239
472
|
add: assign(({ context }, params) => {
|
|
240
|
-
let theme = createCustomTheme(params.title ?? "Untitled theme", params.options ?? themesOf(context).active
|
|
473
|
+
let theme = createCustomTheme(params.title ?? "Untitled theme", params.options ?? themesOf(context).active?.options ?? {}, params.palette);
|
|
241
474
|
return {
|
|
242
475
|
active: theme.slug,
|
|
243
476
|
custom: [...context.custom, theme],
|
|
@@ -259,7 +492,11 @@ const themerMachine = setup({
|
|
|
259
492
|
};
|
|
260
493
|
}),
|
|
261
494
|
duplicate: assign(({ context }, params) => {
|
|
262
|
-
let { themes, removed } = themesOf(context), source =
|
|
495
|
+
let { themes, removed } = themesOf(context), source = params.slug === "config" ? {
|
|
496
|
+
title: CONFIG_TITLE,
|
|
497
|
+
options: {},
|
|
498
|
+
palette: void 0
|
|
499
|
+
} : [...themes, ...removed].find((theme) => theme.slug === params.slug);
|
|
263
500
|
if (!source) return {};
|
|
264
501
|
let theme = createCustomTheme(duplicateTitle(source.title), source.options, source.palette);
|
|
265
502
|
return {
|
|
@@ -313,83 +550,13 @@ const themerMachine = setup({
|
|
|
313
550
|
}
|
|
314
551
|
}).createMachine({
|
|
315
552
|
id: "themer",
|
|
316
|
-
context: (
|
|
317
|
-
...
|
|
318
|
-
baseOptions: input.baseOptions,
|
|
553
|
+
context: () => ({
|
|
554
|
+
...initialThemerState,
|
|
319
555
|
editing: null,
|
|
320
556
|
images: {}
|
|
321
557
|
}),
|
|
322
|
-
entry: "persist",
|
|
323
558
|
type: "parallel",
|
|
324
559
|
states: {
|
|
325
|
-
sidebar: {
|
|
326
|
-
initial: "closed",
|
|
327
|
-
states: {
|
|
328
|
-
closed: { on: { "sidebar.toggle": "opening" } },
|
|
329
|
-
opening: {
|
|
330
|
-
tags: ["panel", "moving"],
|
|
331
|
-
after: { [MOTION_DURATION]: "open" },
|
|
332
|
-
on: {
|
|
333
|
-
"layout.transitioned": "open",
|
|
334
|
-
"sidebar.toggle": "closing",
|
|
335
|
-
"sidebar.close": "closing"
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
open: {
|
|
339
|
-
tags: ["panel"],
|
|
340
|
-
on: {
|
|
341
|
-
"sidebar.toggle": "closing",
|
|
342
|
-
"sidebar.close": "closing"
|
|
343
|
-
}
|
|
344
|
-
},
|
|
345
|
-
closing: {
|
|
346
|
-
tags: ["moving"],
|
|
347
|
-
after: { [MOTION_DURATION]: "closed" },
|
|
348
|
-
on: {
|
|
349
|
-
"layout.transitioned": "closed",
|
|
350
|
-
"sidebar.toggle": "opening"
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
preview: {
|
|
356
|
-
initial: "single",
|
|
357
|
-
states: {
|
|
358
|
-
single: { on: { "preview.toggle": "splitting" } },
|
|
359
|
-
splitting: {
|
|
360
|
-
tags: ["split", "moving"],
|
|
361
|
-
after: { [MOTION_DURATION]: "split" },
|
|
362
|
-
on: {
|
|
363
|
-
"layout.transitioned": "split",
|
|
364
|
-
"preview.toggle": "unsplitting",
|
|
365
|
-
"sidebar.close": "unsplitting",
|
|
366
|
-
"sidebar.toggle": {
|
|
367
|
-
guard: "sidebarShown",
|
|
368
|
-
target: "unsplitting"
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
split: {
|
|
373
|
-
tags: ["split"],
|
|
374
|
-
on: {
|
|
375
|
-
"preview.toggle": "unsplitting",
|
|
376
|
-
"sidebar.close": "unsplitting",
|
|
377
|
-
"sidebar.toggle": {
|
|
378
|
-
guard: "sidebarShown",
|
|
379
|
-
target: "unsplitting"
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
unsplitting: {
|
|
384
|
-
tags: ["moving"],
|
|
385
|
-
after: { [MOTION_DURATION]: "single" },
|
|
386
|
-
on: {
|
|
387
|
-
"layout.transitioned": "single",
|
|
388
|
-
"preview.toggle": "splitting"
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
560
|
theme: {
|
|
394
561
|
initial: "applied",
|
|
395
562
|
states: {
|
|
@@ -436,13 +603,20 @@ const themerMachine = setup({
|
|
|
436
603
|
},
|
|
437
604
|
target: "switching"
|
|
438
605
|
},
|
|
439
|
-
"theme.import": "switching"
|
|
606
|
+
"theme.import": "switching",
|
|
607
|
+
"themes.sync": {
|
|
608
|
+
guard: {
|
|
609
|
+
type: "appliesAnotherTheme",
|
|
610
|
+
params: ({ event }) => ({ state: event.state })
|
|
611
|
+
},
|
|
612
|
+
target: "switching"
|
|
613
|
+
}
|
|
440
614
|
} },
|
|
441
615
|
switching: {
|
|
442
616
|
tags: ["switching"],
|
|
443
|
-
after: {
|
|
617
|
+
after: { 2e3: "applied" },
|
|
444
618
|
on: {
|
|
445
|
-
"
|
|
619
|
+
"theme.update": "applied",
|
|
446
620
|
"theme.pick": {
|
|
447
621
|
guard: {
|
|
448
622
|
type: "isAnotherTheme",
|
|
@@ -494,6 +668,14 @@ const themerMachine = setup({
|
|
|
494
668
|
"theme.import": {
|
|
495
669
|
target: "switching",
|
|
496
670
|
reenter: !0
|
|
671
|
+
},
|
|
672
|
+
"themes.sync": {
|
|
673
|
+
guard: {
|
|
674
|
+
type: "appliesAnotherTheme",
|
|
675
|
+
params: ({ event }) => ({ state: event.state })
|
|
676
|
+
},
|
|
677
|
+
target: "switching",
|
|
678
|
+
reenter: !0
|
|
497
679
|
}
|
|
498
680
|
}
|
|
499
681
|
}
|
|
@@ -505,7 +687,7 @@ const themerMachine = setup({
|
|
|
505
687
|
"theme.pick": { actions: [{
|
|
506
688
|
type: "pick",
|
|
507
689
|
params: ({ event }) => ({ slug: event.slug })
|
|
508
|
-
}
|
|
690
|
+
}] },
|
|
509
691
|
"theme.add": {
|
|
510
692
|
target: ".edit",
|
|
511
693
|
actions: [{
|
|
@@ -516,14 +698,14 @@ const themerMachine = setup({
|
|
|
516
698
|
palette: event.palette,
|
|
517
699
|
imageUrl: event.imageUrl
|
|
518
700
|
})
|
|
519
|
-
}
|
|
701
|
+
}]
|
|
520
702
|
},
|
|
521
703
|
"theme.duplicate": {
|
|
522
704
|
target: ".edit",
|
|
523
705
|
actions: [{
|
|
524
706
|
type: "duplicate",
|
|
525
707
|
params: ({ event }) => ({ slug: event.slug })
|
|
526
|
-
}
|
|
708
|
+
}]
|
|
527
709
|
},
|
|
528
710
|
"theme.edit": {
|
|
529
711
|
target: ".edit",
|
|
@@ -534,55 +716,51 @@ const themerMachine = setup({
|
|
|
534
716
|
actions: [{
|
|
535
717
|
type: "startEditing",
|
|
536
718
|
params: ({ event }) => ({ slug: event.slug })
|
|
537
|
-
}
|
|
719
|
+
}]
|
|
538
720
|
},
|
|
539
|
-
"theme.update": { actions: [
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
{
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
})
|
|
553
|
-
},
|
|
554
|
-
"persist"
|
|
555
|
-
] },
|
|
721
|
+
"theme.update": { actions: [{
|
|
722
|
+
type: "revokeImage",
|
|
723
|
+
params: ({ context, event }) => ({ url: event.imageUrl ? context.images[event.slug] : void 0 })
|
|
724
|
+
}, {
|
|
725
|
+
type: "update",
|
|
726
|
+
params: ({ event }) => ({
|
|
727
|
+
slug: event.slug,
|
|
728
|
+
title: event.title,
|
|
729
|
+
options: event.options,
|
|
730
|
+
palette: event.palette,
|
|
731
|
+
imageUrl: event.imageUrl
|
|
732
|
+
})
|
|
733
|
+
}] },
|
|
556
734
|
"theme.remove": { actions: [{
|
|
557
735
|
type: "remove",
|
|
558
736
|
params: ({ event }) => ({ slug: event.slug })
|
|
559
|
-
}
|
|
737
|
+
}] },
|
|
560
738
|
"theme.restore": { actions: [{
|
|
561
739
|
type: "restore",
|
|
562
740
|
params: ({ event }) => ({ slug: event.slug })
|
|
563
|
-
}
|
|
564
|
-
"theme.delete": { actions: [
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
{
|
|
570
|
-
|
|
571
|
-
params: ({ event }) => ({ slug: event.slug })
|
|
572
|
-
},
|
|
573
|
-
"persist"
|
|
574
|
-
] },
|
|
741
|
+
}] },
|
|
742
|
+
"theme.delete": { actions: [{
|
|
743
|
+
type: "revokeImage",
|
|
744
|
+
params: ({ context, event }) => ({ url: context.images[event.slug] })
|
|
745
|
+
}, {
|
|
746
|
+
type: "delete",
|
|
747
|
+
params: ({ event }) => ({ slug: event.slug })
|
|
748
|
+
}] },
|
|
575
749
|
"theme.reorder": { actions: [{
|
|
576
750
|
type: "reorder",
|
|
577
751
|
params: ({ event }) => ({ order: event.order })
|
|
578
|
-
}
|
|
752
|
+
}] },
|
|
579
753
|
"theme.import": { actions: [{
|
|
580
754
|
type: "import",
|
|
581
755
|
params: ({ event }) => ({
|
|
582
756
|
title: event.title,
|
|
583
757
|
options: event.options
|
|
584
758
|
})
|
|
585
|
-
}
|
|
759
|
+
}] },
|
|
760
|
+
"themes.sync": { actions: {
|
|
761
|
+
type: "sync",
|
|
762
|
+
params: ({ event }) => ({ state: event.state })
|
|
763
|
+
} },
|
|
586
764
|
"flow.list": ".list",
|
|
587
765
|
"flow.removed": {
|
|
588
766
|
target: ".removed",
|
|
@@ -606,140 +784,32 @@ const themerMachine = setup({
|
|
|
606
784
|
}
|
|
607
785
|
}
|
|
608
786
|
});
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function subscribe(onChange) {
|
|
621
|
-
let media = matchMedia(QUERY);
|
|
622
|
-
return media.addEventListener("change", onChange), () => media.removeEventListener("change", onChange);
|
|
623
|
-
}
|
|
624
|
-
function getSnapshot() {
|
|
625
|
-
return matchMedia(QUERY).matches;
|
|
626
|
-
}
|
|
627
|
-
function getServerSnapshot() {
|
|
628
|
-
return !1;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Whether the user prefers reduced motion — live, so that turning the
|
|
632
|
-
* setting on while the Studio is open takes effect right away.
|
|
633
|
-
*
|
|
634
|
-
* @internal
|
|
635
|
-
*/
|
|
636
|
-
function usePrefersReducedMotion$1() {
|
|
637
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* The Studio navbar's root, the `Card` that draws its bottom border — its
|
|
641
|
-
* test id is stable and unique to the navbar, unlike its `data-ui` name
|
|
642
|
-
*
|
|
643
|
-
* @internal
|
|
644
|
-
*/
|
|
645
|
-
const NAVBAR_SELECTOR = "[data-testid=\"studio-navbar\"]";
|
|
646
|
-
/**
|
|
647
|
-
* The height of the Studio navbar inside the given element, in pixels — kept
|
|
648
|
-
* up to date as the navbar renders, remounts and resizes, and `null` until
|
|
649
|
-
* there is one. The themer's header takes this height, so that its bottom
|
|
650
|
-
* border lines up with the navbar's whatever height the Studio version, its
|
|
651
|
-
* breakpoint or a custom navbar gives it.
|
|
652
|
-
*
|
|
653
|
-
* @internal
|
|
654
|
-
*/
|
|
655
|
-
function useStudioNavbarHeight(ref) {
|
|
656
|
-
let $ = c(3), [height, setHeight] = useState(null), t0, t1;
|
|
657
|
-
return $[0] === ref ? (t0 = $[1], t1 = $[2]) : (t0 = () => {
|
|
658
|
-
let root = ref.current;
|
|
659
|
-
if (!root) return;
|
|
660
|
-
let navbar = null, resizeObserver = new ResizeObserver(() => {
|
|
661
|
-
navbar && setHeight(navbar.getBoundingClientRect().height);
|
|
662
|
-
}), observeNavbar = () => {
|
|
663
|
-
let next = root.querySelector(NAVBAR_SELECTOR);
|
|
664
|
-
next !== navbar && (navbar && resizeObserver.unobserve(navbar), navbar = next, navbar ? (resizeObserver.observe(navbar), setHeight(navbar.getBoundingClientRect().height)) : setHeight(null));
|
|
665
|
-
}, mutationObserver = new MutationObserver(observeNavbar);
|
|
666
|
-
return mutationObserver.observe(root, {
|
|
667
|
-
childList: !0,
|
|
668
|
-
subtree: !0
|
|
669
|
-
}), observeNavbar(), () => {
|
|
670
|
-
mutationObserver.disconnect(), resizeObserver.disconnect();
|
|
671
|
-
};
|
|
672
|
-
}, t1 = [ref], $[0] = ref, $[1] = t0, $[2] = t1), useEffect(t0, t1), height;
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* `useDeferredValue` with a transition type: the returned value lags behind
|
|
676
|
-
* `value` like a deferred one — rendered in a transition, which React
|
|
677
|
-
* animates — and the view transition React starts for it carries the given
|
|
678
|
-
* type (`document.startViewTransition({types})`), so a stylesheet tells it
|
|
679
|
-
* from any other transition on the page through
|
|
680
|
-
* `:active-view-transition-type()`.
|
|
681
|
-
*
|
|
682
|
-
* React only takes types from `startTransition`, and a deferred render is
|
|
683
|
-
* not one. So while the deferred value lags, a transition of the type joins
|
|
684
|
-
* it, with a state update of its own for the type to belong to: React renders
|
|
685
|
-
* every pending transition in one go, and the commit — the view transition
|
|
686
|
-
* — carries the types of all of them. The value itself stays with
|
|
687
|
-
* `useDeferredValue`, which reads the latest `value` as the deferred render
|
|
688
|
-
* runs: should `value` change back before that render commits, nothing
|
|
689
|
-
* changes and nothing animates — a queued state update would commit the
|
|
690
|
-
* stale value and animate it, only to animate back.
|
|
691
|
-
*
|
|
692
|
-
* @internal
|
|
693
|
-
*/
|
|
694
|
-
function useTypedDeferredValue(value, type) {
|
|
695
|
-
let $ = c(5), deferred = useDeferredValue(value), [, setTransitions] = useState(0), t0, t1;
|
|
696
|
-
return $[0] !== deferred || $[1] !== type || $[2] !== value ? (t0 = () => {
|
|
697
|
-
Object.is(deferred, value) || startTransition(() => {
|
|
698
|
-
addTransitionType(type), setTransitions(_temp);
|
|
787
|
+
function PersistActorSnapshot(t0) {
|
|
788
|
+
let $ = c(3), { actorRef } = t0, t1, t2;
|
|
789
|
+
return $[0] === actorRef ? (t1 = $[1], t2 = $[2]) : (t1 = () => {
|
|
790
|
+
let cancel, cancelOrClear = function cancelOrClear() {
|
|
791
|
+
"cancelIdleCallback" in window ? cancelIdleCallback(cancel) : clearTimeout(cancel);
|
|
792
|
+
}, subscription = actorRef.subscribe(() => {
|
|
793
|
+
cancelOrClear();
|
|
794
|
+
let callback = () => {
|
|
795
|
+
writePersistedSnapshot(actorRef.getPersistedSnapshot());
|
|
796
|
+
};
|
|
797
|
+
cancel = "cancelIdleCallback" in window ? requestIdleCallback(callback) : setTimeout(callback, 1e3);
|
|
699
798
|
});
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
], $[0] = deferred, $[1] = type, $[2] = value, $[3] = t0, $[4] = t1) : (t0 = $[3], t1 = $[4]), useEffect(t0, t1), deferred;
|
|
705
|
-
}
|
|
706
|
-
function _temp(count) {
|
|
707
|
-
return count + 1;
|
|
799
|
+
return () => {
|
|
800
|
+
subscription.unsubscribe(), cancelOrClear();
|
|
801
|
+
};
|
|
802
|
+
}, t2 = [actorRef], $[0] = actorRef, $[1] = t1, $[2] = t2), useEffect(t1, t2), null;
|
|
708
803
|
}
|
|
709
|
-
var layout = "_1yq4ar78", layoutTransitionType = "sanity-themer", panelTransitionClasses = {
|
|
710
|
-
slideIn: "_1yq4ar76",
|
|
711
|
-
slideOut: "_1yq4ar77"
|
|
712
|
-
}, splitTransitionClasses = {
|
|
713
|
-
resize: "_1yq4ar70",
|
|
714
|
-
crossfade: "_1yq4ar71",
|
|
715
|
-
slideIn: "_1yq4ar72",
|
|
716
|
-
slideOut: "_1yq4ar73",
|
|
717
|
-
dropIn: "_1yq4ar74",
|
|
718
|
-
dropOut: "_1yq4ar75"
|
|
719
|
-
}, studioScheme = {
|
|
720
|
-
light: "_1yq4ar79",
|
|
721
|
-
dark: "_1yq4ar7a"
|
|
722
|
-
};
|
|
723
804
|
/**
|
|
724
|
-
*
|
|
725
|
-
* the
|
|
726
|
-
*
|
|
805
|
+
* The sidebar — everything in it, from the theme list to the snippet dialog —
|
|
806
|
+
* loads the first time it opens. There is no `Suspense` boundary around it,
|
|
807
|
+
* so it must only ever mount from a deferred render: that keeps the Studio as
|
|
808
|
+
* it was while the code loads, with the navbar toggle showing the deferred
|
|
809
|
+
* value as pending, where an urgent render would suspend up to the Studio's
|
|
810
|
+
* own boundary and swap the whole Studio for its loading screen.
|
|
727
811
|
*/
|
|
728
|
-
const ResizableSidebar = lazy(() => import("./ResizableSidebar-
|
|
729
|
-
function sameStoredState(a, b) {
|
|
730
|
-
return a.active === b.active && a.custom === b.custom && a.removed === b.removed && a.order === b.order;
|
|
731
|
-
}
|
|
732
|
-
function selectView(snapshot) {
|
|
733
|
-
let { editing } = snapshot.context;
|
|
734
|
-
return snapshot.matches({ flow: "edit" }) && editing ? {
|
|
735
|
-
name: "edit",
|
|
736
|
-
slug: editing.slug,
|
|
737
|
-
focusTitle: editing.focusTitle
|
|
738
|
-
} : snapshot.matches({ flow: "removed" }) ? { name: "removed" } : { name: "list" };
|
|
739
|
-
}
|
|
740
|
-
function sameView(a, b) {
|
|
741
|
-
return a.name === b.name ? a.name !== "edit" || b.name !== "edit" || a.slug === b.slug && a.focusTitle === b.focusTitle : !1;
|
|
742
|
-
}
|
|
812
|
+
const ResizableSidebar = lazy(() => import("./ResizableSidebar-BpgLA4XQ.js"));
|
|
743
813
|
/**
|
|
744
814
|
* Wraps the whole Studio so that the theme picked in the themer sidebar
|
|
745
815
|
* applies everywhere while the user browses around, runs the themer machine
|
|
@@ -768,146 +838,94 @@ function sameView(a, b) {
|
|
|
768
838
|
*
|
|
769
839
|
* @internal
|
|
770
840
|
*/
|
|
771
|
-
function ThemerLayout(
|
|
772
|
-
let $ = c(
|
|
773
|
-
$[0] ===
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
let open = t2, t3;
|
|
782
|
-
$[6] === snapshot ? t3 = $[7] : (t3 = snapshot.hasTag("split"), $[6] = snapshot, $[7] = t3);
|
|
783
|
-
let split = t3, t4;
|
|
784
|
-
$[8] === snapshot ? t4 = $[9] : (t4 = snapshot.hasTag("moving"), $[8] = snapshot, $[9] = t4);
|
|
785
|
-
let moving = t4, t5;
|
|
786
|
-
$[10] === snapshot ? t5 = $[11] : (t5 = snapshot.hasTag("switching"), $[10] = snapshot, $[11] = t5);
|
|
787
|
-
let switching = t5, { images } = snapshot.context, mobile = useMediaIndex() <= 1, studioRef = useRef(null), navbarHeight = useStudioNavbarHeight(studioRef), reduceMotion = usePrefersReducedMotion$1(), deferredOpen = useTypedDeferredValue(reduceMotion ? null : open, layoutTransitionType), deferredSplit = useTypedDeferredValue(reduceMotion ? null : split, layoutTransitionType), shownOpen = deferredOpen ?? open, shownSplit = deferredSplit ?? split, [panelShown, setPanelShown] = useState(!1), panelWanted = open || panelShown, panelMounted = useTypedDeferredValue(panelWanted, layoutTransitionType);
|
|
788
|
-
panelMounted && !panelShown && setPanelShown(!0);
|
|
789
|
-
let loading = panelWanted !== panelMounted, t6;
|
|
790
|
-
$[12] !== baseOptions || $[13] !== stored ? (t6 = resolveThemes(stored, baseOptions), $[12] = baseOptions, $[13] = stored, $[14] = t6) : t6 = $[14];
|
|
791
|
-
let { themes, removed, active } = t6, activeOptions = active.source === "config" ? null : active.options, t7;
|
|
792
|
-
$[15] === activeOptions ? t7 = $[16] : (t7 = activeOptions === null ? null : buildTheme(activeOptions), $[15] = activeOptions, $[16] = t7);
|
|
793
|
-
let theme = t7, deferredTheme = useTypedDeferredValue(reduceMotion ? void 0 : theme, layoutTransitionType), shownTheme = deferredTheme === void 0 ? theme : deferredTheme, scheme = useColorSchemeValue(), oppositeScheme = scheme === "dark" ? "light" : "dark", t8;
|
|
794
|
-
$[17] !== scheme || $[18] !== shownTheme?.v2?.color ? (t8 = () => {
|
|
795
|
-
let background = shownTheme?.v2?.color[scheme].default.bg;
|
|
796
|
-
if (background === void 0) return;
|
|
797
|
-
let { style } = document.body, previous = style.backgroundColor;
|
|
798
|
-
return style.backgroundColor = background, () => {
|
|
799
|
-
style.backgroundColor = previous;
|
|
800
|
-
};
|
|
801
|
-
}, $[17] = scheme, $[18] = shownTheme?.v2?.color, $[19] = t8) : t8 = $[19];
|
|
802
|
-
let t9;
|
|
803
|
-
$[20] !== scheme || $[21] !== shownTheme ? (t9 = [scheme, shownTheme], $[20] = scheme, $[21] = shownTheme, $[22] = t9) : t9 = $[22], useEffect(t8, t9);
|
|
804
|
-
let t10, t11;
|
|
805
|
-
$[23] === actorRef ? (t10 = $[24], t11 = $[25]) : (t10 = () => () => {
|
|
806
|
-
for (let url of Object.values(actorRef.getSnapshot().context.images)) URL.revokeObjectURL(url);
|
|
807
|
-
}, t11 = [actorRef], $[23] = actorRef, $[24] = t10, $[25] = t11), useEffect(t10, t11);
|
|
808
|
-
let t12;
|
|
809
|
-
$[26] !== active || $[27] !== baseOptions || $[28] !== images || $[29] !== loading || $[30] !== mobile || $[31] !== navbarHeight || $[32] !== open || $[33] !== removed || $[34] !== send || $[35] !== split || $[36] !== themes || $[37] !== view ? (t12 = {
|
|
810
|
-
baseOptions,
|
|
811
|
-
themes,
|
|
812
|
-
removed,
|
|
813
|
-
active,
|
|
814
|
-
images,
|
|
815
|
-
view,
|
|
841
|
+
function ThemerLayout(t0) {
|
|
842
|
+
let $ = c(50), { children, backgroundColor, config, dispatch, navbarHeight, open, persistedSnapshot, prerender, prerenderSplitScreen, scheme, split } = t0, t1;
|
|
843
|
+
$[0] === persistedSnapshot ? t1 = $[1] : (t1 = { snapshot: persistedSnapshot }, $[0] = persistedSnapshot, $[1] = t1);
|
|
844
|
+
let actorRef = useActorRef(themerMachine, t1), oppositeScheme = scheme === "dark" ? "light" : "dark", t2;
|
|
845
|
+
$[2] === backgroundColor ? t2 = $[3] : (t2 = { backgroundColor }, $[2] = backgroundColor, $[3] = t2);
|
|
846
|
+
let t3 = split && open ? "visible" : "hidden", t4;
|
|
847
|
+
$[4] !== children || $[5] !== config || $[6] !== dispatch || $[7] !== open || $[8] !== oppositeScheme || $[9] !== prerenderSplitScreen || $[10] !== split ? (t4 = prerenderSplitScreen && /* @__PURE__ */ jsx(StudioPreview, {
|
|
848
|
+
borderRight: !0,
|
|
849
|
+
config,
|
|
850
|
+
dispatch,
|
|
816
851
|
open,
|
|
817
|
-
|
|
852
|
+
scheme: oppositeScheme,
|
|
818
853
|
split,
|
|
819
|
-
|
|
854
|
+
children
|
|
855
|
+
}), $[4] = children, $[5] = config, $[6] = dispatch, $[7] = open, $[8] = oppositeScheme, $[9] = prerenderSplitScreen, $[10] = split, $[11] = t4) : t4 = $[11];
|
|
856
|
+
let t5;
|
|
857
|
+
$[12] === t4 ? t5 = $[13] : (t5 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
858
|
+
default: "none",
|
|
859
|
+
enter: viewTransitionClasses.splitscreen.enter,
|
|
860
|
+
update: viewTransitionClasses.splitscreen.update,
|
|
861
|
+
exit: viewTransitionClasses.splitscreen.exit,
|
|
862
|
+
children: t4
|
|
863
|
+
}), $[12] = t4, $[13] = t5);
|
|
864
|
+
let t6;
|
|
865
|
+
$[14] !== t3 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsx(Activity, {
|
|
866
|
+
mode: t3,
|
|
867
|
+
children: t5
|
|
868
|
+
}), $[14] = t3, $[15] = t5, $[16] = t6) : t6 = $[16];
|
|
869
|
+
let t7;
|
|
870
|
+
$[17] !== children || $[18] !== config || $[19] !== dispatch || $[20] !== open || $[21] !== split ? (t7 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
871
|
+
default: "none",
|
|
872
|
+
update: viewTransitionClasses.studio.update,
|
|
873
|
+
children: /* @__PURE__ */ jsx(StudioPreview, {
|
|
874
|
+
config,
|
|
875
|
+
dispatch,
|
|
876
|
+
open,
|
|
877
|
+
shouldDetectNavbarHeight: !0,
|
|
878
|
+
split,
|
|
879
|
+
children
|
|
880
|
+
})
|
|
881
|
+
}), $[17] = children, $[18] = config, $[19] = dispatch, $[20] = open, $[21] = split, $[22] = t7) : t7 = $[22];
|
|
882
|
+
let t8 = open ? "visible" : "hidden", t9;
|
|
883
|
+
$[23] !== actorRef || $[24] !== dispatch || $[25] !== navbarHeight || $[26] !== prerender || $[27] !== split ? (t9 = prerender && /* @__PURE__ */ jsx(ResizableSidebar, {
|
|
884
|
+
actorRef,
|
|
885
|
+
dispatch,
|
|
820
886
|
navbarHeight,
|
|
821
|
-
|
|
822
|
-
}, $[
|
|
823
|
-
let
|
|
824
|
-
$[
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
update: switching ? splitTransitionClasses.crossfade : "none",
|
|
839
|
-
studioUpdate: moving ? splitTransitionClasses.resize : switching ? splitTransitionClasses.crossfade : "none"
|
|
840
|
-
}, $[41] = mobile, $[42] = moving, $[43] = reduceMotion, $[44] = switching, $[45] = t14) : t14 = $[45];
|
|
841
|
-
let classes = t14, t15 = mobile ? "column" : "row", t16;
|
|
842
|
-
$[46] !== classes.copyEnter || $[47] !== classes.copyExit || $[48] !== classes.update || $[49] !== mobile || $[50] !== oppositeScheme || $[51] !== shownOpen || $[52] !== shownSplit || $[53] !== shownTheme || $[54] !== studio || $[55] !== transitioned ? (t16 = shownOpen && /* @__PURE__ */ jsx(Activity, {
|
|
843
|
-
mode: shownSplit ? "visible" : "hidden",
|
|
844
|
-
children: /* @__PURE__ */ jsx(ViewTransition, {
|
|
845
|
-
enter: classes.copyEnter,
|
|
846
|
-
exit: classes.copyExit,
|
|
847
|
-
onEnter: transitioned,
|
|
848
|
-
onExit: transitioned,
|
|
849
|
-
onUpdate: transitioned,
|
|
850
|
-
update: classes.update,
|
|
851
|
-
children: /* @__PURE__ */ jsx(StudioPreview, {
|
|
852
|
-
borderBottom: mobile,
|
|
853
|
-
borderRight: !mobile,
|
|
854
|
-
scheme: oppositeScheme,
|
|
855
|
-
theme: shownTheme,
|
|
856
|
-
children: studio
|
|
857
|
-
})
|
|
858
|
-
}, "opposite")
|
|
859
|
-
}), $[46] = classes.copyEnter, $[47] = classes.copyExit, $[48] = classes.update, $[49] = mobile, $[50] = oppositeScheme, $[51] = shownOpen, $[52] = shownSplit, $[53] = shownTheme, $[54] = studio, $[55] = transitioned, $[56] = t16) : t16 = $[56];
|
|
860
|
-
let t17;
|
|
861
|
-
$[57] !== shownTheme || $[58] !== studio ? (t17 = /* @__PURE__ */ jsx(StudioPreview, {
|
|
862
|
-
ref: studioRef,
|
|
863
|
-
theme: shownTheme,
|
|
864
|
-
children: studio
|
|
865
|
-
}), $[57] = shownTheme, $[58] = studio, $[59] = t17) : t17 = $[59];
|
|
866
|
-
let t18;
|
|
867
|
-
$[60] !== classes.studioUpdate || $[61] !== t17 || $[62] !== transitioned ? (t18 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
868
|
-
onUpdate: transitioned,
|
|
869
|
-
update: classes.studioUpdate,
|
|
870
|
-
children: t17
|
|
871
|
-
}, "primary"), $[60] = classes.studioUpdate, $[61] = t17, $[62] = transitioned, $[63] = t18) : t18 = $[63];
|
|
872
|
-
let t19 = shownOpen ? "visible" : "hidden", t20 = shownTheme ?? void 0, t21;
|
|
873
|
-
$[64] !== mobile || $[65] !== panelMounted ? (t21 = panelMounted && /* @__PURE__ */ jsx(ResizableSidebar, { overlay: mobile }), $[64] = mobile, $[65] = panelMounted, $[66] = t21) : t21 = $[66];
|
|
874
|
-
let t22;
|
|
875
|
-
$[67] !== t20 || $[68] !== t21 ? (t22 = /* @__PURE__ */ jsx(ThemeProvider, {
|
|
876
|
-
theme: t20,
|
|
877
|
-
children: t21
|
|
878
|
-
}), $[67] = t20, $[68] = t21, $[69] = t22) : t22 = $[69];
|
|
879
|
-
let t23;
|
|
880
|
-
$[70] !== classes.panelEnter || $[71] !== classes.panelExit || $[72] !== classes.update || $[73] !== t22 || $[74] !== transitioned ? (t23 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
881
|
-
enter: classes.panelEnter,
|
|
882
|
-
exit: classes.panelExit,
|
|
883
|
-
onEnter: transitioned,
|
|
884
|
-
onExit: transitioned,
|
|
885
|
-
onUpdate: transitioned,
|
|
886
|
-
update: classes.update,
|
|
887
|
-
children: t22
|
|
888
|
-
}, "panel"), $[70] = classes.panelEnter, $[71] = classes.panelExit, $[72] = classes.update, $[73] = t22, $[74] = transitioned, $[75] = t23) : t23 = $[75];
|
|
889
|
-
let t24;
|
|
890
|
-
$[76] !== t19 || $[77] !== t23 ? (t24 = /* @__PURE__ */ jsx(Activity, {
|
|
891
|
-
mode: t19,
|
|
892
|
-
children: t23
|
|
893
|
-
}), $[76] = t19, $[77] = t23, $[78] = t24) : t24 = $[78];
|
|
894
|
-
let t25;
|
|
895
|
-
$[79] !== t15 || $[80] !== t16 || $[81] !== t18 || $[82] !== t24 ? (t25 = /* @__PURE__ */ jsxs(Flex, {
|
|
887
|
+
split
|
|
888
|
+
}), $[23] = actorRef, $[24] = dispatch, $[25] = navbarHeight, $[26] = prerender, $[27] = split, $[28] = t9) : t9 = $[28];
|
|
889
|
+
let t10;
|
|
890
|
+
$[29] === t9 ? t10 = $[30] : (t10 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
891
|
+
default: "none",
|
|
892
|
+
enter: viewTransitionClasses.sidebar.enter,
|
|
893
|
+
update: viewTransitionClasses.sidebar.update,
|
|
894
|
+
exit: viewTransitionClasses.sidebar.exit,
|
|
895
|
+
children: t9
|
|
896
|
+
}), $[29] = t9, $[30] = t10);
|
|
897
|
+
let t11;
|
|
898
|
+
$[31] !== t10 || $[32] !== t8 ? (t11 = /* @__PURE__ */ jsx(Activity, {
|
|
899
|
+
mode: t8,
|
|
900
|
+
children: t10
|
|
901
|
+
}), $[31] = t10, $[32] = t8, $[33] = t11) : t11 = $[33];
|
|
902
|
+
let t12;
|
|
903
|
+
$[34] !== t11 || $[35] !== t2 || $[36] !== t6 || $[37] !== t7 ? (t12 = /* @__PURE__ */ jsxs(Flex, {
|
|
896
904
|
className: layout,
|
|
897
|
-
direction:
|
|
905
|
+
direction: "row",
|
|
898
906
|
height: "fill",
|
|
899
907
|
sizing: "border",
|
|
908
|
+
style: t2,
|
|
900
909
|
children: [
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
910
|
+
t6,
|
|
911
|
+
t7,
|
|
912
|
+
t11
|
|
904
913
|
]
|
|
905
|
-
}), $[
|
|
906
|
-
let
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
}), $[
|
|
914
|
+
}), $[34] = t11, $[35] = t2, $[36] = t6, $[37] = t7, $[38] = t12) : t12 = $[38];
|
|
915
|
+
let t13;
|
|
916
|
+
$[39] !== actorRef || $[40] !== dispatch ? (t13 = /* @__PURE__ */ jsx(ThemerThemeCrossfader, {
|
|
917
|
+
actorRef,
|
|
918
|
+
dispatch
|
|
919
|
+
}), $[39] = actorRef, $[40] = dispatch, $[41] = t13) : t13 = $[41];
|
|
920
|
+
let t14, t15;
|
|
921
|
+
$[42] === actorRef ? (t14 = $[43], t15 = $[44]) : (t14 = /* @__PURE__ */ jsx(RevokeImageUrls, { actorRef }), t15 = /* @__PURE__ */ jsx(PersistActorSnapshot, { actorRef }), $[42] = actorRef, $[43] = t14, $[44] = t15);
|
|
922
|
+
let t16;
|
|
923
|
+
return $[45] !== t12 || $[46] !== t13 || $[47] !== t14 || $[48] !== t15 ? (t16 = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
924
|
+
t12,
|
|
925
|
+
t13,
|
|
926
|
+
t14,
|
|
927
|
+
t15
|
|
928
|
+
] }), $[45] = t12, $[46] = t13, $[47] = t14, $[48] = t15, $[49] = t16) : t16 = $[49], t16;
|
|
911
929
|
}
|
|
912
930
|
/**
|
|
913
931
|
* One copy of the Studio, in the given color scheme — or, without one, in the
|
|
@@ -920,292 +938,100 @@ function ThemerLayout(props) {
|
|
|
920
938
|
* they stay in sync while navigating. The `color-scheme` of a forced scheme
|
|
921
939
|
* keeps native form controls and scrollbars in step with it.
|
|
922
940
|
*/
|
|
923
|
-
function StudioPreview(
|
|
924
|
-
let $ = c(
|
|
925
|
-
$[0]
|
|
926
|
-
|
|
941
|
+
function StudioPreview(t0) {
|
|
942
|
+
let $ = c(17), { borderRight, children, config, dispatch, open, scheme, shouldDetectNavbarHeight, split } = t0, [boundaryElement, setBoundaryElement] = useState(null), t1;
|
|
943
|
+
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = (boundaryElement_0) => (startTransition(() => setBoundaryElement(boundaryElement_0)), _temp), $[0] = t1) : t1 = $[0];
|
|
944
|
+
let t2;
|
|
945
|
+
$[1] === children ? t2 = $[2] : (t2 = /* @__PURE__ */ jsx(ViewTransition, {
|
|
946
|
+
update: "none",
|
|
947
|
+
children
|
|
948
|
+
}), $[1] = children, $[2] = t2);
|
|
949
|
+
let t3;
|
|
950
|
+
$[3] !== config || $[4] !== dispatch || $[5] !== open || $[6] !== shouldDetectNavbarHeight || $[7] !== split || $[8] !== t2 ? (t3 = /* @__PURE__ */ jsx(ThemerNavbarProvider, {
|
|
951
|
+
config,
|
|
952
|
+
dispatch,
|
|
953
|
+
open,
|
|
954
|
+
shouldDetectNavbarHeight,
|
|
955
|
+
split,
|
|
956
|
+
children: t2
|
|
957
|
+
}), $[3] = config, $[4] = dispatch, $[5] = open, $[6] = shouldDetectNavbarHeight, $[7] = split, $[8] = t2, $[9] = t3) : t3 = $[9];
|
|
958
|
+
let t4;
|
|
959
|
+
$[10] !== boundaryElement || $[11] !== t3 ? (t4 = /* @__PURE__ */ jsx(BoundaryElementProvider, {
|
|
960
|
+
element: boundaryElement,
|
|
961
|
+
children: t3
|
|
962
|
+
}), $[10] = boundaryElement, $[11] = t3, $[12] = t4) : t4 = $[12];
|
|
963
|
+
let t5;
|
|
964
|
+
return $[13] !== borderRight || $[14] !== scheme || $[15] !== t4 ? (t5 = /* @__PURE__ */ jsx(Card, {
|
|
927
965
|
borderRight,
|
|
928
|
-
className: t1,
|
|
929
966
|
flex: 1,
|
|
930
967
|
height: "fill",
|
|
931
968
|
overflow: "hidden",
|
|
932
|
-
ref,
|
|
933
|
-
children
|
|
934
|
-
}), $[0] = borderBottom, $[1] = borderRight, $[2] = children, $[3] = ref, $[4] = t1, $[5] = t2) : t2 = $[5];
|
|
935
|
-
let t3;
|
|
936
|
-
return $[6] !== scheme || $[7] !== t0 || $[8] !== t2 ? (t3 = /* @__PURE__ */ jsx(ThemeProvider, {
|
|
937
969
|
scheme,
|
|
938
|
-
|
|
939
|
-
children:
|
|
940
|
-
}), $[
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* The colors the slices fill with, clockwise from 12 o'clock: the palette's
|
|
944
|
-
* hues in rainbow order, like a real color swatch
|
|
945
|
-
*/
|
|
946
|
-
const SLICE_COLORS = [
|
|
947
|
-
red[500].hex,
|
|
948
|
-
orange[500].hex,
|
|
949
|
-
yellow[400].hex,
|
|
950
|
-
green[500].hex,
|
|
951
|
-
cyan[500].hex,
|
|
952
|
-
blue[500].hex,
|
|
953
|
-
purple[500].hex,
|
|
954
|
-
magenta[500].hex
|
|
955
|
-
], TOTAL_ACTS = 2 + (1 - Math.cbrt(1 / 8)), ANIMATION_DURATION = .55 * TOTAL_ACTS;
|
|
956
|
-
function actAt(progress) {
|
|
957
|
-
return progress * TOTAL_ACTS;
|
|
958
|
-
}
|
|
959
|
-
/**
|
|
960
|
-
* How far the wheel has turned at `progress` (0–1), in degrees.
|
|
961
|
-
*
|
|
962
|
-
* It stands still while the top half of the slices pop in. As the 6 o'clock
|
|
963
|
-
* slice pops in it starts spinning — one full turn with a cubic ease-in, from
|
|
964
|
-
* rest to top speed as the bottom half pop in — and it stands still again the
|
|
965
|
-
* moment it is back upright: the clearing of {@link isSliceFilled} takes off
|
|
966
|
-
* at the speed the spin reached, as if the wheel kept turning and eased out
|
|
967
|
-
* over a second turn, so the two read as one movement.
|
|
968
|
-
*/
|
|
969
|
-
function wheelRotation(progress) {
|
|
970
|
-
let spin = actAt(progress) - 1;
|
|
971
|
-
return spin <= 0 || spin >= 1 ? 0 : 360 * spin ** 3;
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Whether slice `index` (clockwise from 12 o'clock) shows its color at
|
|
975
|
-
* `progress` (0–1). A slice pops in whole as the fill reaches its leading
|
|
976
|
-
* edge, and pops out whole as the clearing does — stepped, never partial.
|
|
977
|
-
*
|
|
978
|
-
* The fill goes clockwise at a steady pace over the first two acts, half of
|
|
979
|
-
* the slices in each. The clearing follows in the third act, the same way
|
|
980
|
-
* round, on a cubic ease-out that starts at the speed the spin of
|
|
981
|
-
* {@link wheelRotation} ends with: the slices at first pop out as quickly as
|
|
982
|
-
* they were passing by, then ever more slowly.
|
|
983
|
-
*/
|
|
984
|
-
function isSliceFilled(progress, index) {
|
|
985
|
-
let act = actAt(progress);
|
|
986
|
-
if (act * 8 / 2 <= index) return !1;
|
|
987
|
-
let clearing = act - 2;
|
|
988
|
-
return clearing <= 0 || (1 - (1 - clearing) ** 3) * 8 < index;
|
|
989
|
-
}
|
|
990
|
-
/**
|
|
991
|
-
* The geometry of `ColorWheelIcon` from `@sanity/icons`: a ring between two
|
|
992
|
-
* circles around the center of a 25×25 viewBox, cut into eight slices by the
|
|
993
|
-
* spokes of its outline path
|
|
994
|
-
*/
|
|
995
|
-
const CENTER = 12.5, INNER_RADIUS = 3.5;
|
|
996
|
-
/** A point on a circle around the center, at `degrees` clockwise from 3 o'clock */
|
|
997
|
-
function point(radius, degrees) {
|
|
998
|
-
let radians = degrees * Math.PI / 180;
|
|
999
|
-
return `${CENTER + radius * Math.cos(radians)} ${CENTER + radius * Math.sin(radians)}`;
|
|
970
|
+
ref: t1,
|
|
971
|
+
children: t4
|
|
972
|
+
}), $[13] = borderRight, $[14] = scheme, $[15] = t4, $[16] = t5) : t5 = $[16], t5;
|
|
1000
973
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
`A${INNER_RADIUS} ${INNER_RADIUS} 0 0 0 ${point(INNER_RADIUS, start)}`,
|
|
1013
|
-
"Z"
|
|
1014
|
-
].join("");
|
|
1015
|
-
}
|
|
1016
|
-
const SLICE_PATHS = SLICE_COLORS.map((_, index) => slicePath(index));
|
|
1017
|
-
/**
|
|
1018
|
-
* A filled shape, not a stroked one: the icon styles of `@sanity/ui` force
|
|
1019
|
-
* `vector-effect: non-scaling-stroke` on every path in an icon, which fills
|
|
1020
|
-
* are none the wiser about
|
|
1021
|
-
*/
|
|
1022
|
-
function Slice(props) {
|
|
1023
|
-
let $ = c(8), { index, progress } = props, t0;
|
|
1024
|
-
$[0] === index ? t0 = $[1] : (t0 = (value) => +!!isSliceFilled(value, index), $[0] = index, $[1] = t0);
|
|
1025
|
-
let opacity = useTransform(progress, t0), t1 = SLICE_PATHS[index], t2 = SLICE_COLORS[index], t3;
|
|
1026
|
-
$[2] === opacity ? t3 = $[3] : (t3 = { opacity }, $[2] = opacity, $[3] = t3);
|
|
1027
|
-
let t4;
|
|
1028
|
-
return $[4] !== t1 || $[5] !== t2 || $[6] !== t3 ? (t4 = /* @__PURE__ */ jsx(motion.path, {
|
|
1029
|
-
d: t1,
|
|
1030
|
-
fill: t2,
|
|
1031
|
-
style: t3
|
|
1032
|
-
}), $[4] = t1, $[5] = t2, $[6] = t3, $[7] = t4) : t4 = $[7], t4;
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* The `ColorWheelIcon` of `@sanity/icons`, with an animation driven by
|
|
1036
|
-
* `progress` (0–1): the slices pop in with color one at a time, clockwise
|
|
1037
|
-
* from 12 o'clock like the segments of a classic spinner, the wheel spins once
|
|
1038
|
-
* as the 6 o'clock slice pops in, and the colors pop out the same way round,
|
|
1039
|
-
* carrying the spin's speed to a rest (see `colorWheel.ts`). At rest — at
|
|
1040
|
-
* either end — it looks exactly like the icon it stands in for. With
|
|
1041
|
-
* `prefers-reduced-motion: reduce` the wheel keeps still; only the colors come
|
|
1042
|
-
* and go.
|
|
1043
|
-
*
|
|
1044
|
-
* @internal
|
|
1045
|
-
*/
|
|
1046
|
-
function AnimatedColorWheelIcon(props) {
|
|
1047
|
-
let $ = c(10), { progress } = props, prefersReducedMotion = usePrefersReducedMotion(), t0;
|
|
1048
|
-
$[0] === prefersReducedMotion ? t0 = $[1] : (t0 = (value) => prefersReducedMotion ? 0 : wheelRotation(value), $[0] = prefersReducedMotion, $[1] = t0);
|
|
1049
|
-
let rotate = useTransform(progress, t0), t1;
|
|
1050
|
-
$[2] === rotate ? t1 = $[3] : (t1 = { rotate }, $[2] = rotate, $[3] = t1);
|
|
1051
|
-
let t2;
|
|
1052
|
-
$[4] === progress ? t2 = $[5] : (t2 = SLICE_COLORS.map((color, index) => /* @__PURE__ */ jsx(Slice, {
|
|
1053
|
-
index,
|
|
1054
|
-
progress
|
|
1055
|
-
}, color)), $[4] = progress, $[5] = t2);
|
|
1056
|
-
let t3;
|
|
1057
|
-
$[6] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx("path", {
|
|
1058
|
-
d: "M9.43853 5.10896L11.1606 9.26642M13.8394 15.7336L15.5615 19.891M15.7336 11.1606L19.891 9.43853M9.26642 13.8394L5.10896 15.5615M5.3139 9.52342L9.23359 11.147M15.7664 13.853L19.6861 15.4766M13.853 9.23359L15.4766 5.3139M9.52342 19.6861L11.147 15.7664M20.5 12.5C20.5 16.9183 16.9183 20.5 12.5 20.5C8.08172 20.5 4.5 16.9183 4.5 12.5C4.5 8.08172 8.08172 4.5 12.5 4.5C16.9183 4.5 20.5 8.08172 20.5 12.5ZM16 12.5C16 14.433 14.433 16 12.5 16C10.567 16 9 14.433 9 12.5C9 10.567 10.567 9 12.5 9C14.433 9 16 10.567 16 12.5Z",
|
|
1059
|
-
stroke: "currentColor",
|
|
1060
|
-
strokeLinejoin: "round",
|
|
1061
|
-
strokeWidth: 1.2
|
|
1062
|
-
}), $[6] = t3) : t3 = $[6];
|
|
1063
|
-
let t4;
|
|
1064
|
-
return $[7] !== t1 || $[8] !== t2 ? (t4 = /* @__PURE__ */ jsxs(motion.svg, {
|
|
1065
|
-
"data-sanity-icon": "color-wheel",
|
|
1066
|
-
fill: "none",
|
|
1067
|
-
height: "1em",
|
|
1068
|
-
style: t1,
|
|
1069
|
-
viewBox: "0 0 25 25",
|
|
1070
|
-
width: "1em",
|
|
1071
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1072
|
-
children: [t2, t3]
|
|
1073
|
-
}), $[7] = t1, $[8] = t2, $[9] = t4) : t4 = $[9], t4;
|
|
1074
|
-
}
|
|
1075
|
-
/**
|
|
1076
|
-
* Starts loading the sidebar's code as the toggle is about to be pressed —
|
|
1077
|
-
* the same import `React.lazy` makes, which then waits for this one
|
|
1078
|
-
*/
|
|
1079
|
-
function preloadSidebar() {
|
|
1080
|
-
import("./ResizableSidebar-DD787kQr.js").catch(() => {});
|
|
1081
|
-
}
|
|
1082
|
-
/**
|
|
1083
|
-
* Opens or closes the sidebar — and notes the visit, which is what stops the
|
|
1084
|
-
* navbar from introducing the tool
|
|
1085
|
-
*/
|
|
1086
|
-
function toggleSidebar(send) {
|
|
1087
|
-
markVisited(), send({ type: "sidebar.toggle" });
|
|
1088
|
-
}
|
|
1089
|
-
/**
|
|
1090
|
-
* Whether the navbar has had its one chance per page load to introduce the
|
|
1091
|
-
* tool. Module state rather than component state on purpose: the button
|
|
1092
|
-
* remounts with the navbar (switching workspaces, crossing the narrow-screen
|
|
1093
|
-
* breakpoint) and renders once per Studio copy in the split preview, and none
|
|
1094
|
-
* of those should earn another introduction — only loading the page again does.
|
|
1095
|
-
*/
|
|
1096
|
-
let introduced = !1;
|
|
1097
|
-
/**
|
|
1098
|
-
* The topbar toggle, with an icon that plays its color wheel animation: on
|
|
1099
|
-
* hovering the button, every time; on hovering the navbar it sits in, once —
|
|
1100
|
-
* a "hey, look, new tool!" for anyone who has never opened the sidebar, which
|
|
1101
|
-
* the visit noted by {@link toggleSidebar} ends for good; and lap after lap
|
|
1102
|
-
* while the sidebar's code loads, the way a spinner would.
|
|
1103
|
-
*/
|
|
1104
|
-
function ThemerNavbarButton() {
|
|
1105
|
-
let $ = c(26), { open, loading, send } = useThemer(), progress = useMotionValue(0), [button, setButton] = useState(null), t0;
|
|
1106
|
-
$[0] === progress ? t0 = $[1] : (t0 = () => {
|
|
1107
|
-
progress.isAnimating() || animate(progress, [0, 1], {
|
|
1108
|
-
duration: ANIMATION_DURATION,
|
|
1109
|
-
ease: "linear"
|
|
1110
|
-
});
|
|
1111
|
-
}, $[0] = progress, $[1] = t0);
|
|
1112
|
-
let play = t0, t1, t2;
|
|
1113
|
-
$[2] !== loading || $[3] !== progress ? (t1 = () => {
|
|
1114
|
-
if (!loading) return;
|
|
1115
|
-
let looping = !0, lap = (from) => {
|
|
1116
|
-
animate(progress, [from, 1], {
|
|
1117
|
-
duration: (1 - from) * ANIMATION_DURATION,
|
|
1118
|
-
ease: "linear",
|
|
1119
|
-
onComplete: () => {
|
|
1120
|
-
looping && lap(0);
|
|
1121
|
-
}
|
|
974
|
+
function _temp() {}
|
|
975
|
+
function ThemerThemeCrossfader(t0) {
|
|
976
|
+
let $ = c(4), { actorRef, dispatch } = t0, t1, t2;
|
|
977
|
+
return $[0] !== actorRef || $[1] !== dispatch ? (t1 = () => {
|
|
978
|
+
let subscription = actorRef.subscribe((snapshot) => {
|
|
979
|
+
let switching = snapshot.hasTag("switching"), theme = resolveActiveThemeOptions(snapshot.context);
|
|
980
|
+
startTransition(() => {
|
|
981
|
+
switching && addThemerTransitionType("crossfade"), dispatch(theme ? {
|
|
982
|
+
type: "set-theme",
|
|
983
|
+
theme
|
|
984
|
+
} : { type: "unset-theme" });
|
|
1122
985
|
});
|
|
1123
|
-
};
|
|
1124
|
-
return
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
let
|
|
1129
|
-
$[
|
|
1130
|
-
|
|
1131
|
-
$[
|
|
1132
|
-
let navbar = button?.closest(NAVBAR_SELECTOR);
|
|
1133
|
-
if (!navbar || introduced) return;
|
|
1134
|
-
let introduce = () => {
|
|
1135
|
-
introduced || (introduced = !0, hasVisited() || play());
|
|
1136
|
-
};
|
|
1137
|
-
return navbar.addEventListener("mouseenter", introduce, { once: !0 }), () => navbar.removeEventListener("mouseenter", introduce);
|
|
1138
|
-
}, t6 = [button, play], $[9] = button, $[10] = play, $[11] = t5, $[12] = t6) : (t5 = $[11], t6 = $[12]), useEffect(t5, t6);
|
|
1139
|
-
let t7;
|
|
1140
|
-
$[13] === Symbol.for("react.memo_cache_sentinel") ? (t7 = /* @__PURE__ */ jsx(Text, {
|
|
1141
|
-
size: 1,
|
|
1142
|
-
children: "Themer"
|
|
1143
|
-
}), $[13] = t7) : t7 = $[13];
|
|
1144
|
-
let t8;
|
|
1145
|
-
$[14] === progress ? t8 = $[15] : (t8 = /* @__PURE__ */ jsx(AnimatedColorWheelIcon, { progress }), $[14] = progress, $[15] = t8);
|
|
1146
|
-
let t9;
|
|
1147
|
-
$[16] === send ? t9 = $[17] : (t9 = () => toggleSidebar(send), $[16] = send, $[17] = t9);
|
|
1148
|
-
let t10;
|
|
1149
|
-
$[18] === play ? t10 = $[19] : (t10 = () => {
|
|
1150
|
-
preloadSidebar(), play();
|
|
1151
|
-
}, $[18] = play, $[19] = t10);
|
|
1152
|
-
let t11;
|
|
1153
|
-
return $[20] !== loading || $[21] !== open || $[22] !== t10 || $[23] !== t8 || $[24] !== t9 ? (t11 = /* @__PURE__ */ jsx(Tooltip, {
|
|
1154
|
-
animate: !0,
|
|
1155
|
-
content: t7,
|
|
1156
|
-
portal: !0,
|
|
1157
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
1158
|
-
"aria-busy": loading,
|
|
1159
|
-
"aria-label": "Themer",
|
|
1160
|
-
disabled: loading,
|
|
1161
|
-
icon: t8,
|
|
1162
|
-
mode: "bleed",
|
|
1163
|
-
onClick: t9,
|
|
1164
|
-
onFocus: preloadSidebar,
|
|
1165
|
-
onMouseEnter: t10,
|
|
1166
|
-
padding: 2,
|
|
1167
|
-
ref: setButton,
|
|
1168
|
-
selected: open
|
|
1169
|
-
})
|
|
1170
|
-
}), $[20] = loading, $[21] = open, $[22] = t10, $[23] = t8, $[24] = t9, $[25] = t11) : t11 = $[25], t11;
|
|
986
|
+
});
|
|
987
|
+
return () => subscription.unsubscribe();
|
|
988
|
+
}, t2 = [actorRef, dispatch], $[0] = actorRef, $[1] = dispatch, $[2] = t1, $[3] = t2) : (t1 = $[2], t2 = $[3]), useEffect(t1, t2), null;
|
|
989
|
+
}
|
|
990
|
+
function RevokeImageUrls(t0) {
|
|
991
|
+
let $ = c(3), { actorRef } = t0, t1, t2;
|
|
992
|
+
return $[0] === actorRef ? (t1 = $[1], t2 = $[2]) : (t1 = () => () => {
|
|
993
|
+
for (let url of Object.values(actorRef.getSnapshot().context.images)) URL.revokeObjectURL(url);
|
|
994
|
+
}, t2 = [actorRef], $[0] = actorRef, $[1] = t1, $[2] = t2), useEffect(t1, t2), null;
|
|
1171
995
|
}
|
|
1172
996
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
* navbar
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
* In the split preview every Studio copy renders its own navbar, so the
|
|
1178
|
-
* toggle shows up in both — they drive the same sidebar.
|
|
1179
|
-
*
|
|
1180
|
-
* @internal
|
|
997
|
+
* Keep this component extremely lightweight, and only include state that are needed by both
|
|
998
|
+
* `studio.components.layout` and `studio.components.navbar`, where it's not possible to prop-drill into `studio.components.navbar`,
|
|
999
|
+
* and that need to survive open/close of the tool
|
|
1000
|
+
* @TODO will mount on the future `studio.components.provider` entrypoint to ensure other plugins using `studio.components.layout` is correctly wrapped in the top-level theme regardless of plugin ordering
|
|
1181
1001
|
*/
|
|
1182
|
-
function
|
|
1183
|
-
let $ = c(
|
|
1184
|
-
|
|
1185
|
-
let t1;
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1002
|
+
function ThemerProvider(t0) {
|
|
1003
|
+
let $ = c(18), { children, config } = t0;
|
|
1004
|
+
use(browser("The current theme is stored in localStorage."));
|
|
1005
|
+
let [persistedSnapshot] = useState(readPersistedSnapshot), t1;
|
|
1006
|
+
$[0] === persistedSnapshot ? t1 = $[1] : (t1 = (initialState) => {
|
|
1007
|
+
if (!persistedSnapshot) return initialState;
|
|
1008
|
+
let theme = resolveActiveThemeOptions(persistedSnapshot.context);
|
|
1009
|
+
return theme ? {
|
|
1010
|
+
...initialState,
|
|
1011
|
+
theme
|
|
1012
|
+
} : initialState;
|
|
1013
|
+
}, $[0] = persistedSnapshot, $[1] = t1);
|
|
1014
|
+
let [state, dispatch] = useReducer(toolReducer, initialToolState, t1), scheme = useColorSchemeValue(), index = useMediaIndex(), isMobile = index <= 2, isTooSmallForSplitScreen = index <= 3, open = state.open && !isMobile, split = state.split && !isTooSmallForSplitScreen, t2;
|
|
1015
|
+
$[2] === state.theme ? t2 = $[3] : (t2 = (state.theme === null ? null : buildTheme(state.theme)) ?? void 0, $[2] = state.theme, $[3] = t2);
|
|
1016
|
+
let t3 = state.theme?.[scheme]?.background, t4;
|
|
1017
|
+
$[4] !== children || $[5] !== config || $[6] !== open || $[7] !== persistedSnapshot || $[8] !== scheme || $[9] !== split || $[10] !== state.navbarHeight || $[11] !== state.prerender || $[12] !== state.prerenderSplitScreen || $[13] !== t3 ? (t4 = /* @__PURE__ */ jsx(ThemerLayout, {
|
|
1018
|
+
config,
|
|
1019
|
+
backgroundColor: t3,
|
|
1020
|
+
dispatch,
|
|
1021
|
+
navbarHeight: state.navbarHeight,
|
|
1022
|
+
open,
|
|
1023
|
+
persistedSnapshot,
|
|
1024
|
+
prerender: state.prerender,
|
|
1025
|
+
prerenderSplitScreen: state.prerenderSplitScreen,
|
|
1026
|
+
scheme,
|
|
1027
|
+
split,
|
|
1028
|
+
children
|
|
1029
|
+
}), $[4] = children, $[5] = config, $[6] = open, $[7] = persistedSnapshot, $[8] = scheme, $[9] = split, $[10] = state.navbarHeight, $[11] = state.prerender, $[12] = state.prerenderSplitScreen, $[13] = t3, $[14] = t4) : t4 = $[14];
|
|
1030
|
+
let t5;
|
|
1031
|
+
return $[15] !== t2 || $[16] !== t4 ? (t5 = /* @__PURE__ */ jsx(ThemeProvider, {
|
|
1032
|
+
theme: t2,
|
|
1033
|
+
children: t4
|
|
1034
|
+
}), $[15] = t2, $[16] = t4, $[17] = t5) : t5 = $[17], t5;
|
|
1209
1035
|
}
|
|
1210
1036
|
/**
|
|
1211
1037
|
* A Studio plugin that adds a themer sidebar for `buildTheme` themes: a
|
|
@@ -1236,22 +1062,27 @@ function ThemerNavbar(props) {
|
|
|
1236
1062
|
* @alpha
|
|
1237
1063
|
*/
|
|
1238
1064
|
const themerTool = definePlugin((options) => {
|
|
1239
|
-
let
|
|
1240
|
-
function ThemerLayoutWithOptions(props) {
|
|
1241
|
-
let $ = c(2), t0;
|
|
1242
|
-
return $[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx(ThemerLayout, {
|
|
1243
|
-
...props,
|
|
1244
|
-
baseOptions
|
|
1245
|
-
}), $[0] = props, $[1] = t0), t0;
|
|
1246
|
-
}
|
|
1065
|
+
let { title = "Themer" } = options ?? {};
|
|
1247
1066
|
return {
|
|
1248
1067
|
name: "@sanity/themer/tool",
|
|
1249
1068
|
studio: { components: {
|
|
1250
|
-
layout:
|
|
1069
|
+
layout: defineThemerLayout({ title }),
|
|
1251
1070
|
navbar: ThemerNavbar
|
|
1252
1071
|
} }
|
|
1253
1072
|
};
|
|
1254
1073
|
});
|
|
1074
|
+
function defineThemerLayout(config) {
|
|
1075
|
+
return function DefinedThemerLayoutProvider(props) {
|
|
1076
|
+
"use memo";
|
|
1077
|
+
let $ = c(4), t0;
|
|
1078
|
+
$[0] === props ? t0 = $[1] : (t0 = props.renderDefault(props), $[0] = props, $[1] = t0);
|
|
1079
|
+
let t1;
|
|
1080
|
+
return $[2] === t0 ? t1 = $[3] : (t1 = /* @__PURE__ */ jsx(ThemerProvider, {
|
|
1081
|
+
config,
|
|
1082
|
+
children: t0
|
|
1083
|
+
}), $[2] = t0, $[3] = t1), t1;
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1255
1086
|
export { themerTool };
|
|
1256
1087
|
|
|
1257
1088
|
//# sourceMappingURL=tool.js.map
|