@sanity/themer

0.8.10.9.0
dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js
−dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.jsDeleted
−422
Index: package/dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js
===================================================================
--- package/dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js
+++ package/dist/ResizableSidebar.css.ts.vanilla-M9EuPu-q.js
@@ -1,422 +0,0 @@
-import { a as DEFAULT_BACKGROUND, c as resolveThemeOptions, d as hslToHex, f as relativeLuminance, i as DEFAULT_ACCENT, o as SCHEMES, s as deriveTextColor, t as presets, u as hexToHsl } from "./presets-CqBgS3A-.js";
-import { createContext, useContext } from "react";
-/** @internal */
-const ThemerContext = createContext(null);
-/** @internal */
-function useThemer() {
-	let context = useContext(ThemerContext);
-	if (!context) throw Error("useThemer must be used within the `themerTool` plugin");
-	return context;
-}
-/** @internal */
-const IMAGE_PALETTE_KEYS = [
-	"vibrant",
-	"lightVibrant",
-	"darkVibrant",
-	"muted",
-	"lightMuted",
-	"darkMuted",
-	"dominant"
-], IMAGE_PALETTE_VARIANTS = [
-	"muted",
-	"vibrant",
-	"lightMuted",
-	"lightVibrant",
-	"darkMuted",
-	"darkVibrant"
-], IMAGE_PALETTE_TITLES = {
-	dominant: "Dominant",
-	vibrant: "Vibrant",
-	lightVibrant: "Light vibrant",
-	darkVibrant: "Dark vibrant",
-	muted: "Muted",
-	lightMuted: "Light muted",
-	darkMuted: "Dark muted"
-}, TARGETS = [
-	["vibrant", {
-		lightness: [
-			.5,
-			.3,
-			.7
-		],
-		saturation: [
-			1,
-			.35,
-			1
-		]
-	}],
-	["lightVibrant", {
-		lightness: [
-			.74,
-			.55,
-			1
-		],
-		saturation: [
-			1,
-			.35,
-			1
-		]
-	}],
-	["darkVibrant", {
-		lightness: [
-			.26,
-			0,
-			.45
-		],
-		saturation: [
-			1,
-			.35,
-			1
-		]
-	}],
-	["muted", {
-		lightness: [
-			.5,
-			.3,
-			.7
-		],
-		saturation: [
-			.3,
-			0,
-			.4
-		]
-	}],
-	["lightMuted", {
-		lightness: [
-			.74,
-			.55,
-			1
-		],
-		saturation: [
-			.3,
-			0,
-			.4
-		]
-	}],
-	["darkMuted", {
-		lightness: [
-			.26,
-			0,
-			.45
-		],
-		saturation: [
-			.3,
-			0,
-			.4
-		]
-	}]
-];
-/**
-* Extracts the color palette of an image from its pixels, the way the Vibrant
-* algorithm does: the colors are quantized into a coarse histogram, and each
-* swatch claims the color that comes closest to its target lightness and
-* saturation — weighted by how much of the image it covers — that no other
-* swatch has claimed yet. The dominant swatch is simply the most common
-* color. Runs anywhere pixels come from, so it can run on device.
-*
-* @internal
-*/
-function extractImagePalette(pixels) {
-	let candidates = quantize(pixels), palette = {
-		dominant: null,
-		vibrant: null,
-		lightVibrant: null,
-		darkVibrant: null,
-		muted: null,
-		lightMuted: null,
-		darkMuted: null
-	};
-	if (candidates.length === 0) return palette;
-	let maximumPopulation = Math.max(...candidates.map((candidate) => candidate.population)), claimed = /* @__PURE__ */ new Set();
-	for (let [key, target] of TARGETS) {
-		let best = null, bestScore = -Infinity;
-		for (let candidate of candidates) {
-			if (claimed.has(candidate.hex) || !matchesTarget(candidate, target)) continue;
-			let score = scoreCandidate(candidate, target, maximumPopulation);
-			score > bestScore && (best = candidate, bestScore = score);
-		}
-		best && (palette[key] = best.hex, claimed.add(best.hex));
-	}
-	return palette.dominant = candidates.reduce((most, candidate) => candidate.population > most.population ? candidate : most).hex, palette;
-}
-/**
-* Turns the pixels into a histogram of quantized colors, each averaged over
-* the pixels it stands for, leaving out transparent pixels and the near-black
-* and near-white ones that are backdrop rather than color.
-*/
-function quantize(pixels) {
-	let { data } = pixels, buckets = /* @__PURE__ */ new Map(), length = Math.min(data.length, pixels.width * pixels.height * 4);
-	for (let offset = 0; offset + 3 < length; offset += 4) {
-		let r = data[offset], g = data[offset + 1], b = data[offset + 2];
-		if (data[offset + 3] < 125) continue;
-		let lightness = (Math.max(r, g, b) + Math.min(r, g, b)) / 510;
-		if (lightness < .05 || lightness > .95) continue;
-		let key = r >> 3 << 10 | g >> 3 << 5 | b >> 3, bucket = buckets.get(key);
-		bucket ? (bucket.count++, bucket.r += r, bucket.g += g, bucket.b += b) : buckets.set(key, {
-			count: 1,
-			r,
-			g,
-			b
-		});
-	}
-	let candidates = [];
-	for (let bucket of buckets.values()) {
-		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);
-		candidates.push({
-			hex: rgbToHex(r, g, b),
-			population: bucket.count,
-			saturation,
-			lightness
-		});
-	}
-	return candidates;
-}
-function matchesTarget(candidate, target) {
-	return candidate.lightness >= target.lightness[1] && candidate.lightness <= target.lightness[2] && candidate.saturation >= target.saturation[1] && candidate.saturation <= target.saturation[2];
-}
-function scoreCandidate(candidate, target, maximumPopulation) {
-	return 3 * (1 - Math.abs(candidate.saturation - target.saturation[0])) + 6.5 * (1 - Math.abs(candidate.lightness - target.lightness[0])) + .5 * (candidate.population / maximumPopulation);
-}
-function saturationAndLightness(r, g, b) {
-	let max = Math.max(r, g, b) / 255, min = Math.min(r, g, b) / 255, lightness = (max + min) / 2, delta = max - min;
-	return {
-		saturation: delta === 0 ? 0 : lightness > .5 ? delta / (2 - max - min) : delta / (max + min),
-		lightness
-	};
-}
-function rgbToHex(r, g, b) {
-	return `#${[
-		r,
-		g,
-		b
-	].map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
-}
-/** Reads `#rgb` and `#rrggbb` alike — stored palettes may hold either */
-function hexToRgb(hex) {
-	let expanded = hex.length === 4 ? `${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex.slice(1);
-	return [
-		parseInt(expanded.slice(0, 2), 16),
-		parseInt(expanded.slice(2, 4), 16),
-		parseInt(expanded.slice(4, 6), 16)
-	];
-}
-/** Mixes `amount` of `color` into `base` */
-function tint(base, color, amount) {
-	let [r1, g1, b1] = hexToRgb(base), [r2, g2, b2] = hexToRgb(color);
-	return rgbToHex(Math.round(r1 + (r2 - r1) * amount), Math.round(g1 + (g2 - g1) * amount), Math.round(b1 + (b2 - b1) * amount));
-}
-/** How much of the palette tints each scheme's stock background */
-const BACKGROUND_TINT = {
-	light: .08,
-	dark: .3
-}, BUTTON_LABEL = {
-	light: "#ffffff",
-	dark: "#000000"
-}, ACCENT_LIGHTNESS_STEP = .01;
-function contrastRatio(a, b) {
-	let [lighter, darker] = [relativeLuminance(a), relativeLuminance(b)].sort((x, y) => y - x);
-	return (lighter + .05) / (darker + .05);
-}
-/**
-* Makes an accent readable as a button in the given scheme: a light scheme
-* accent is darkened until white text on it reaches AA contrast, a dark
-* scheme accent lightened until black text does — as far as the accent's
-* hue and saturation allow. Accents that already pass come back untouched.
-*
-* @internal
-*/
-function readableAccent(hex, scheme) {
-	let label = BUTTON_LABEL[scheme], { h, s } = hexToHsl(hex), { l } = hexToHsl(hex), current = hex;
-	for (; contrastRatio(current, label) < 4.5;) {
-		let next = scheme === "light" ? l - ACCENT_LIGHTNESS_STEP : l + ACCENT_LIGHTNESS_STEP;
-		if (next < 0 || next > 1) break;
-		l = next, current = hslToHex({
-			h,
-			s,
-			l
-		});
-	}
-	return current;
-}
-/** The accent a variant gives a scheme, made readable on a button */
-function variantAccent(palette, variant, scheme) {
-	let swatch = (variant ? palette[variant] : null) ?? palette.vibrant ?? (scheme === "light" ? palette.darkVibrant : palette.lightVibrant) ?? palette.dominant;
-	return swatch === null ? null : readableAccent(swatch, scheme);
-}
-/**
-* Derives theme options from an image palette: the accent of both schemes is
-* the swatch of the chosen variant — or, without one, the vibrant swatch,
-* each scheme falling back to the vibrant swatch of its own end of the scale —
-* adjusted until it is readable as a button. The muted swatch becomes the text color, and the light and dark muted
-* swatches tint the stock backgrounds of their scheme — enough to carry the
-* image's tone without giving up a usable canvas. Whatever the palette lacks
-* stays at the theme defaults.
-*
-* @internal
-*/
-function optionsFromImagePalette(palette, variant) {
-	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");
-	return light && (options.light = light), dark && (options.dark = dark), options;
-}
-function schemeFromPalette(accent, text, backgroundTint, scheme) {
-	let options = {};
-	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;
-}
-/**
-* Applies an image palette to existing theme options: the colors the palette
-* provides replace the current ones scheme by scheme, and whatever it does
-* not touch — like the contrast — stays as it is.
-*
-* @internal
-*/
-function applyImagePalette(options, palette, variant) {
-	let derived = optionsFromImagePalette(palette, variant), next = { ...options };
-	for (let scheme of SCHEMES) derived[scheme] && (next[scheme] = {
-		...options[scheme],
-		...derived[scheme]
-	});
-	return next;
-}
-/**
-* The variant a theme is built around: the one whose swatch is the theme's
-* accent, or `null` when the accent comes from somewhere else.
-*
-* @internal
-*/
-function currentImageVariant(options, palette) {
-	let accent = options.light?.accent;
-	return accent ? IMAGE_PALETTE_VARIANTS.find((variant) => palette[variant] !== null && variantAccent(palette, variant, "light") === accent) ?? null : null;
-}
-/**
-* How much a swatch has going for it as an accent: saturation first, then
-* closeness to mid lightness — the range where an accent reads best.
-*/
-function interest(hex) {
-	let { s, l } = hexToHsl(hex);
-	return .1 + .55 * s + .35 * (1 - Math.abs(l - .5) * 2);
-}
-/**
-* Picks a variant for the "I'm feeling lucky" button: a random one, weighted
-* by how interesting its swatch is as an accent, and never the one the theme
-* already uses while there are others to pick from.
-*
-* @internal
-*/
-function pickLuckyVariant(palette, options = {}) {
-	let { exclude = null, random = Math.random } = options, candidates = IMAGE_PALETTE_VARIANTS.filter((variant) => palette[variant] !== null);
-	if (candidates.length > 1 && (candidates = candidates.filter((variant) => variant !== exclude)), candidates.length === 0) return null;
-	let weights = candidates.map((variant) => interest(palette[variant])), total = weights.reduce((sum, weight) => sum + weight, 0), pick = random() * total;
-	for (let [index, variant] of candidates.entries()) if (pick -= weights[index], pick < 0) return variant;
-	return candidates.at(-1) ?? null;
-}
-/** A theme title for the image a palette came from, e.g. `sunset-beach.jpg` → `sunset beach` @internal */
-function titleFromFileName(name) {
-	return name.replace(/\.[^.]+$/, "").replace(/[-_]+/g, " ").trim() || "Image theme";
-}
-/**
-* Reduces theme options to the minimal object that recreates them through
-* `buildTheme`: in each scheme the accent is dropped when it is the stock
-* one, the text color when it matches the one derived from the accent, and
-* the background and contrast when they match the defaults — and a scheme
-* with nothing left is dropped altogether. Options that boil down to the
-* stock Studio theme reduce to `null` — they need nothing from this package.
-*
-* @internal
-*/
-function minimizeOptions(options) {
-	let resolved = resolveThemeOptions(options), minimized = {};
-	for (let scheme of SCHEMES) {
-		let values = resolved[scheme], kept = {};
-		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);
-	}
-	return Object.keys(minimized).length === 0 ? null : minimized;
-}
-/**
-* Whether two sets of theme options generate the same theme, comparing their
-* resolved forms so that derived and explicit values (and hex casing) don't
-* matter.
-*
-* @internal
-*/
-function sameOptions(a, b) {
-	let left = resolveThemeOptions(a), right = resolveThemeOptions(b);
-	return SCHEMES.every((scheme) => sameScheme(left[scheme], right[scheme]));
-}
-function sameScheme(a, b) {
-	return a.accent === b.accent && a.text === b.text && a.background === b.background && a.contrast === b.contrast;
-}
-/** The slug of the theme the Studio config was generated from @internal */
-const CONFIG_SLUG = "config", UNTITLED_THEME = "Untitled theme", initialThemerState = {
-	active: null,
-	custom: [],
-	removed: [],
-	order: []
-};
-/**
-* Resolves the list of themes: the configured theme first, then the presets
-* (minus the ones that would only repeat the configured theme), then the
-* user's own themes — rearranged into the order the user dragged them into,
-* with themes that order does not know about kept in that default order after
-* the ones it does. Removed themes are set aside so they can be restored, and
-* the active theme falls back to the configured one when its slug no longer
-* resolves.
-*
-* @internal
-*/
-function resolveThemes(state, baseOptions) {
-	let config = {
-		slug: CONFIG_SLUG,
-		title: "Studio config",
-		options: baseOptions,
-		source: "config"
-	}, all = [config];
-	for (let preset of presets) sameOptions(preset.options, baseOptions) || all.push({
-		slug: preset.slug,
-		title: preset.title,
-		options: preset.options,
-		source: "preset"
-	});
-	for (let theme of state.custom) all.push({
-		slug: theme.slug,
-		title: theme.title,
-		options: theme.options,
-		source: "custom",
-		...theme.palette ? { palette: theme.palette } : {}
-	});
-	let position = new Map(state.order.map((slug, index) => [slug, index])), rank = (theme) => position.get(theme.slug) ?? state.order.length;
-	all.sort((a, b) => rank(a) - rank(b));
-	let removedSlugs = new Set(state.removed), themes = all.filter((theme) => !removedSlugs.has(theme.slug));
-	return {
-		themes,
-		removed: all.filter((theme) => removedSlugs.has(theme.slug)),
-		active: themes.find((theme) => theme.slug === state.active) ?? config
-	};
-}
-/**
-* Creates a custom theme with a slug that cannot collide with the presets or
-* the configured theme.
-*
-* @internal
-*/
-function createCustomTheme(title, options, palette) {
-	return {
-		slug: `custom-${randomId()}`,
-		title,
-		options,
-		...palette ? { palette } : {}
-	};
-}
-/** The title of a duplicated theme @internal */
-function duplicateTitle(title) {
-	return `${displayTitle(title)} copy`;
-}
-/** The title to show for a theme, falling back when the user cleared it @internal */
-function displayTitle(title) {
-	return title.trim() || "Untitled theme";
-}
-function randomId() {
-	return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
-}
-export { titleFromFileName as _, duplicateTitle as a, minimizeOptions as c, IMAGE_PALETTE_VARIANTS as d, applyImagePalette as f, pickLuckyVariant as g, optionsFromImagePalette as h, displayTitle as i, IMAGE_PALETTE_KEYS as l, extractImagePalette as m, UNTITLED_THEME as n, initialThemerState as o, currentImageVariant as p, createCustomTheme as r, resolveThemes as s, CONFIG_SLUG as t, IMAGE_PALETTE_TITLES as u, ThemerContext as v, useThemer as y };
-
-//# sourceMappingURL=ResizableSidebar.css.ts.vanilla-M9EuPu-q.js.map
\ No newline at end of file