@sanity/themer 0.9.0 → 0.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/themer",
3
- "version": "0.9.0",
3
+ "version": "0.10.1",
4
4
  "description": "Generate Sanity Studio themes, and preview them with a Studio tool.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -50,13 +50,13 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@sanity/color": "^3.0.8",
53
- "@sanity/icons": "^5.2.2",
54
- "@sanity/themer-legacy": "^0.2.1",
55
- "@sanity/ui": "^4.3.0",
53
+ "@sanity/icons": "^5.2.3",
54
+ "@sanity/themer-legacy": "^0.2.2",
55
+ "@sanity/ui": "^4.4.0",
56
56
  "@vanilla-extract/dynamic": "^2.1.5",
57
57
  "@xstate/react": "^6.1.0",
58
58
  "dequal": "^2.0.3",
59
- "motion": "^13.4.4",
59
+ "motion": "^14.0.0",
60
60
  "react-refractor": "^4.0.0",
61
61
  "refractor": "^5.0.0",
62
62
  "scroll-into-view-if-needed": "^3.1.0",
@@ -66,13 +66,13 @@
66
66
  "devDependencies": {
67
67
  "@sanity/tsconfig": "^2.2.1",
68
68
  "@sanity/tsdown-config": "^0.27.1",
69
- "@sanity/vanilla-extract-vite-plugin": "^0.2.20",
69
+ "@sanity/vanilla-extract-vite-plugin": "^0.2.23",
70
70
  "@types/node": "^24.13.3",
71
71
  "@types/react": "^19.3.0",
72
72
  "@types/react-dom": "^19.3.0",
73
73
  "@vanilla-extract/css": "^1.21.2",
74
74
  "lightningcss": "^1.33.0",
75
- "oxc-transform-react": "^0.147.0",
75
+ "oxc-transform-react": "^0.153.0",
76
76
  "react": "^19.3.0",
77
77
  "react-dom": "^19.3.0",
78
78
  "sanity": "^6.16.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"AnimatedColorWheelIcon-DEy-cy3X.js","names":["(value) => (isSliceFilled(value, index) ? 1 : 0)","{opacity}","<motion.path d={SLICE_PATHS[index]} fill={SLICE_COLORS[index]} style={{opacity}} />","SLICE_PATHS[index]","SLICE_COLORS[index]","motion.path","{\n busy,\n ref,\n}: {\n busy: boolean\n ref: React.Ref<{spin: () => void}>\n}","(value) => wheelRotation(value)","() => ({\n spin: () => {\n // A run in progress plays out — hovering again does not cut it short\n if (progress.isAnimating()) return\n\n animate(progress, [0, 1], {duration: ANIMATION_DURATION, ease: 'linear'})\n },\n })","[progress]","() => {\n if (!busy) return undefined\n\n let looping = false\n const raf = setTimeout(() => {\n looping = true\n const lap = (from: number) => {\n animate(progress, [from, 1], {\n duration: (1 - from) * ANIMATION_DURATION,\n ease: 'linear',\n onComplete: () => {\n if (looping) lap(0)\n },\n })\n }\n\n lap(progress.get())\n }, 160)\n\n return () => {\n clearTimeout(raf)\n looping = false\n }\n }","[busy, progress]","() => () => progress.stop()","{rotate}","SLICE_COLORS.map((color, index) => (\n <Slice key={color} index={index} progress={progress} />\n ))","<path d={OUTLINE} stroke=\"currentColor\" strokeLinejoin=\"round\" strokeWidth={1.2} />","<motion.svg\n data-sanity-icon=\"color-wheel\"\n fill=\"none\"\n height=\"1em\"\n style={{rotate}}\n viewBox=\"0 0 25 25\"\n width=\"1em\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {SLICE_COLORS.map((color, index) => (\n <Slice key={color} index={index} progress={progress} />\n ))}\n <path d={OUTLINE} stroke=\"currentColor\" strokeLinejoin=\"round\" strokeWidth={1.2} />\n </motion.svg>","motion.svg","_c"],"sources":["../src/tool/colorWheel.ts","../src/tool/AnimatedColorWheelIcon.tsx"],"sourcesContent":["import {blue, cyan, green, magenta, orange, purple, red, yellow} from '@sanity/color'\n\n/**\n * The spokes of the color wheel icon (`ColorWheelIcon` from `@sanity/icons`)\n * cut its ring into this many slices, one of them centered on 12 o'clock\n */\nexport const SLICE_COUNT = 8\n\n/**\n * The colors the slices fill with, clockwise from 12 o'clock: the palette's\n * hues in rainbow order, like a real color swatch\n */\nexport const SLICE_COLORS: readonly string[] = [\n red[500].hex,\n orange[500].hex,\n yellow[400].hex,\n green[500].hex,\n cyan[500].hex,\n blue[500].hex,\n purple[500].hex,\n magenta[500].hex,\n]\n\n/**\n * The animation plays in acts of this length, in seconds. In the first act\n * the top half of the slices pop in, one at a time like the segments of a\n * classic spinner; in the second the wheel spins up while the bottom half pop\n * in; in the third the colors pop out again as the spin's speed carries over\n * into the clearing.\n */\nconst ACT_DURATION = 0.55\n\n/**\n * The clearing would take a whole act to come to rest, but its last slice\n * pops out as the clearing reaches that slice's leading edge — with nothing\n * left to show, the animation ends there\n */\nconst CLEARING_ACTS = 1 - Math.cbrt(1 / SLICE_COUNT)\n\nconst TOTAL_ACTS = 2 + CLEARING_ACTS\n\n/** How long the whole animation takes, in seconds */\nexport const ANIMATION_DURATION = ACT_DURATION * TOTAL_ACTS\n\nfunction actAt(progress: number): number {\n return progress * TOTAL_ACTS\n}\n\n/**\n * How far the wheel has turned at `progress` (0–1), in degrees.\n *\n * It stands still while the top half of the slices pop in. As the 6 o'clock\n * slice pops in it starts spinning — one full turn with a cubic ease-in, from\n * rest to top speed as the bottom half pop in — and it stands still again the\n * moment it is back upright: the clearing of {@link isSliceFilled} takes off\n * at the speed the spin reached, as if the wheel kept turning and eased out\n * over a second turn, so the two read as one movement.\n */\nexport function wheelRotation(progress: number): number {\n const spin = actAt(progress) - 1\n\n if (spin <= 0 || spin >= 1) return 0\n\n return 360 * spin ** 3\n}\n\n/**\n * Whether slice `index` (clockwise from 12 o'clock) shows its color at\n * `progress` (0–1). A slice pops in whole as the fill reaches its leading\n * edge, and pops out whole as the clearing does — stepped, never partial.\n *\n * The fill goes clockwise at a steady pace over the first two acts, half of\n * the slices in each. The clearing follows in the third act, the same way\n * round, on a cubic ease-out that starts at the speed the spin of\n * {@link wheelRotation} ends with: the slices at first pop out as quickly as\n * they were passing by, then ever more slowly.\n */\nexport function isSliceFilled(progress: number, index: number): boolean {\n const act = actAt(progress)\n const filling = (act * SLICE_COUNT) / 2\n\n if (filling <= index) return false\n\n const clearing = act - 2\n\n if (clearing <= 0) return true\n\n return (1 - (1 - clearing) ** 3) * SLICE_COUNT < index\n}\n","import {motion, MotionValue, useTransform, animate, useMotionValue} from 'motion/react'\nimport {useEffect, useImperativeHandle} from 'react'\n\nimport {\n isSliceFilled,\n SLICE_COLORS,\n SLICE_COUNT,\n wheelRotation,\n ANIMATION_DURATION,\n} from './colorWheel'\n\n/**\n * The geometry of `ColorWheelIcon` from `@sanity/icons`: a ring between two\n * circles around the center of a 25×25 viewBox, cut into eight slices by the\n * spokes of its outline path\n */\nconst CENTER = 12.5\nconst OUTER_RADIUS = 8\nconst INNER_RADIUS = 3.5\nconst OUTLINE =\n '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'\n\nconst SLICE_ANGLE = 360 / SLICE_COUNT\n\n/** A point on a circle around the center, at `degrees` clockwise from 3 o'clock */\nfunction point(radius: number, degrees: number): string {\n const radians = (degrees * Math.PI) / 180\n\n return `${CENTER + radius * Math.cos(radians)} ${CENTER + radius * Math.sin(radians)}`\n}\n\n/**\n * The part of the ring a slice colors in: between its two spokes, from the\n * inner circle out to the outer. The 12 o'clock slice is centered on 12, so\n * it starts half a slice before it.\n */\nfunction slicePath(index: number): string {\n const start = index * SLICE_ANGLE - SLICE_ANGLE / 2 - 90\n const end = start + SLICE_ANGLE\n\n return [\n `M${point(OUTER_RADIUS, start)}`,\n `A${OUTER_RADIUS} ${OUTER_RADIUS} 0 0 1 ${point(OUTER_RADIUS, end)}`,\n `L${point(INNER_RADIUS, end)}`,\n `A${INNER_RADIUS} ${INNER_RADIUS} 0 0 0 ${point(INNER_RADIUS, start)}`,\n 'Z',\n ].join('')\n}\n\nconst SLICE_PATHS = SLICE_COLORS.map((_, index) => slicePath(index))\n\n/**\n * A filled shape, not a stroked one: the icon styles of `@sanity/ui` force\n * `vector-effect: non-scaling-stroke` on every path in an icon, which fills\n * are none the wiser about\n */\nfunction Slice(props: {index: number; progress: MotionValue<number>}) {\n const {index, progress} = props\n const opacity = useTransform(progress, (value) => (isSliceFilled(value, index) ? 1 : 0))\n\n return <motion.path d={SLICE_PATHS[index]} fill={SLICE_COLORS[index]} style={{opacity}} />\n}\n\n/**\n * The `ColorWheelIcon` of `@sanity/icons`, with an animation driven by\n * `progress` (0–1): the slices pop in with color one at a time, clockwise\n * from 12 o'clock like the segments of a classic spinner, the wheel spins once\n * as the 6 o'clock slice pops in, and the colors pop out the same way round,\n * carrying the spin's speed to a rest (see `colorWheel.ts`). At rest — at\n * either end — it looks exactly like the icon it stands in for. With\n * `prefers-reduced-motion: reduce` the wheel keeps still; only the colors come\n * and go.\n *\n * @internal\n */\nexport default function AnimatedColorWheelIcon({\n busy,\n ref,\n}: {\n busy: boolean\n ref: React.Ref<{spin: () => void}>\n}) {\n const progress = useMotionValue(0)\n const rotate = useTransform(progress, (value) => wheelRotation(value))\n\n useImperativeHandle(\n ref,\n () => ({\n spin: () => {\n // A run in progress plays out — hovering again does not cut it short\n if (progress.isAnimating()) return\n\n animate(progress, [0, 1], {duration: ANIMATION_DURATION, ease: 'linear'})\n },\n }),\n [progress],\n )\n\n // Laps from wherever a hover's run has got to, so the wheel never jumps,\n // and the lap in progress as the code arrives plays out: at rest, the wheel\n // looks like the icon again\n useEffect(() => {\n if (!busy) return undefined\n\n let looping = false\n const raf = setTimeout(() => {\n looping = true\n const lap = (from: number) => {\n animate(progress, [from, 1], {\n duration: (1 - from) * ANIMATION_DURATION,\n ease: 'linear',\n onComplete: () => {\n if (looping) lap(0)\n },\n })\n }\n\n lap(progress.get())\n }, 160)\n\n return () => {\n clearTimeout(raf)\n looping = false\n }\n }, [busy, progress])\n\n useEffect(() => () => progress.stop(), [progress])\n\n return (\n <motion.svg\n data-sanity-icon=\"color-wheel\"\n fill=\"none\"\n height=\"1em\"\n style={{rotate}}\n viewBox=\"0 0 25 25\"\n width=\"1em\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {SLICE_COLORS.map((color, index) => (\n <Slice key={color} index={index} progress={progress} />\n ))}\n <path d={OUTLINE} stroke=\"currentColor\" strokeLinejoin=\"round\" strokeWidth={1.2} />\n </motion.svg>\n )\n}\n"],"mappings":"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"}