@madebywild/sanity-color-field 0.2.3 → 0.2.5

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/dist/index.cjs CHANGED
@@ -1,66 +1,83 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), asyncAutocomplete = require("@madebywild/sanity-utils/async-autocomplete"), ui = require("@sanity/ui"), color2k = require("color2k");
4
- function maybeGetLuminance(maybeColor) {
3
+ var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), compilerRuntime = require("react/compiler-runtime"), asyncAutocomplete = require("@madebywild/sanity-utils/async-autocomplete"), ui = require("@sanity/ui"), color2k = require("color2k");
4
+ function maybeGetColorValue(source) {
5
+ const varMatch = source.match(/^var\((.+)\)$/), cssVarName = (varMatch?.[1] ? varMatch[1].trim() : source.trim()).split(",")[0]?.trim();
6
+ return (cssVarName?.startsWith("--") ? getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim() : null) || source;
7
+ }
8
+ function safeGetLuminance(maybeColor) {
5
9
  try {
6
- const safeVar = maybeColor.replace(/^var\((.*)\)$/, "$1"), color = (safeVar.startsWith("--") ? getComputedStyle(document.documentElement).getPropertyValue(safeVar) : void 0)?.trim() || maybeColor;
7
- return color2k.getLuminance(color);
10
+ return color2k.getLuminance(maybeColor);
8
11
  } catch (e) {
9
- console.warn("Failed to extract color luminance", e);
12
+ console.warn("Failed to get luminance", e);
10
13
  return;
11
14
  }
12
15
  }
13
- function ColorInput({
14
- pluginConfig,
15
- ...props
16
- }) {
17
- const options = props.schemaType.options, colorList = options?.colorList ?? pluginConfig.colorList, renderOption = options?.renderOption ?? pluginConfig.renderOption, renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;
18
- return /* @__PURE__ */ jsxRuntime.jsx(
19
- asyncAutocomplete.AsyncAutocomplete,
20
- {
21
- placeholder: "Select color",
22
- noOptionsPlaceholder: "No colors found",
23
- listItems: colorList,
24
- value: props.value?.value,
25
- renderValue: (value, opt) => opt?.label ?? value,
26
- onChange: (value) => {
27
- if (!value) return props.onChange(sanity.unset());
28
- const luminance = maybeGetLuminance(value);
29
- return props.onChange(sanity.set({ ...props.value, value, luminance }));
30
- },
31
- renderSelected: (value) => renderSelected ? renderSelected(value) : /* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { style: { backgroundColor: value } }),
32
- renderOption: ({ label, value }) => renderOption ? renderOption({ label, value }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { as: "button", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", padding: 2, children: [
33
- /* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { size: 1, style: { backgroundColor: value } }),
34
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, padding: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: label }) })
35
- ] }) })
36
- }
37
- );
16
+ function ColorInput(t0) {
17
+ const $ = compilerRuntime.c(15);
18
+ let pluginConfig, props;
19
+ $[0] !== t0 ? ({
20
+ pluginConfig,
21
+ ...props
22
+ } = t0, $[0] = t0, $[1] = pluginConfig, $[2] = props) : (pluginConfig = $[1], props = $[2]);
23
+ const options = props.schemaType.options, colorList = options?.colorList ?? pluginConfig.colorList, renderOption = options?.renderOption ?? pluginConfig.renderOption, renderSelected = options?.renderSelected ?? pluginConfig.renderSelected, t1 = props.value?.value;
24
+ let t2;
25
+ $[3] !== props ? (t2 = (value_0) => {
26
+ if (!value_0)
27
+ return props.onChange(sanity.unset());
28
+ const color = maybeGetColorValue(value_0), luminance = color ? safeGetLuminance(color) : void 0;
29
+ return props.onChange(sanity.set({
30
+ ...props.value,
31
+ value: value_0,
32
+ luminance
33
+ }));
34
+ }, $[3] = props, $[4] = t2) : t2 = $[4];
35
+ let t3;
36
+ $[5] !== renderSelected ? (t3 = (value_1) => renderSelected ? renderSelected(value_1) : /* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { style: {
37
+ backgroundColor: value_1
38
+ } }), $[5] = renderSelected, $[6] = t3) : t3 = $[6];
39
+ let t4;
40
+ $[7] !== renderOption ? (t4 = (t52) => {
41
+ const {
42
+ label,
43
+ value: value_2
44
+ } = t52;
45
+ return renderOption ? renderOption({
46
+ label,
47
+ value: value_2
48
+ }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { as: "button", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", padding: 2, children: [
49
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { size: 1, style: {
50
+ backgroundColor: value_2
51
+ } }),
52
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, padding: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: label }) })
53
+ ] }) });
54
+ }, $[7] = renderOption, $[8] = t4) : t4 = $[8];
55
+ let t5;
56
+ return $[9] !== colorList || $[10] !== t1 || $[11] !== t2 || $[12] !== t3 || $[13] !== t4 ? (t5 = /* @__PURE__ */ jsxRuntime.jsx(asyncAutocomplete.AsyncAutocomplete, { placeholder: "Select color", noOptionsPlaceholder: "No colors found", listItems: colorList, value: t1, renderValue: _temp, onChange: t2, renderSelected: t3, renderOption: t4 }), $[9] = colorList, $[10] = t1, $[11] = t2, $[12] = t3, $[13] = t4, $[14] = t5) : t5 = $[14], t5;
57
+ }
58
+ function _temp(value, opt) {
59
+ return opt?.label ?? value;
38
60
  }
39
61
  const typeName = "wild.color", wildSanityColorFieldPlugin = sanity.definePlugin((config) => ({
40
62
  name: "@madebywild/sanity-color-field",
41
63
  schema: {
42
- types: [
43
- sanity.defineType({
44
- name: typeName,
45
- type: "object",
46
- title: "Color",
47
- description: "Select a color.",
48
- icon: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u{1F3A8}" }),
49
- components: {
50
- input: (props) => /* @__PURE__ */ jsxRuntime.jsx(ColorInput, { pluginConfig: config, ...props })
51
- },
52
- fields: [
53
- sanity.defineField({
54
- name: "value",
55
- type: "string"
56
- }),
57
- sanity.defineField({
58
- name: "luminance",
59
- type: "number"
60
- })
61
- ]
62
- })
63
- ]
64
+ types: [sanity.defineType({
65
+ name: typeName,
66
+ type: "object",
67
+ title: "Color",
68
+ description: "Select a color.",
69
+ icon: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u{1F3A8}" }),
70
+ components: {
71
+ input: (props) => /* @__PURE__ */ jsxRuntime.jsx(ColorInput, { pluginConfig: config, ...props })
72
+ },
73
+ fields: [sanity.defineField({
74
+ name: "value",
75
+ type: "string"
76
+ }), sanity.defineField({
77
+ name: "luminance",
78
+ type: "number"
79
+ })]
80
+ })]
64
81
  }
65
82
  }));
66
83
  exports.typeName = typeName;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/input.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Avatar, Box, Card, Flex, Text } from \"@sanity/ui\";\nimport { getLuminance } from \"color2k\";\nimport { type ObjectInputProps, set, unset } from \"sanity\";\nimport type { FieldOptions, PluginConfig } from \"./types\";\n\ntype FieldValues = {\n // The selected value from the color list.\n value?: string;\n // The calculated luminance of the selected color (0 to 1).\n luminance?: number;\n};\n\nfunction maybeGetLuminance(maybeColor: string) {\n try {\n // Try to unwrap CSS variable and look up its value.\n // If it's not a CSS variable, assume it's a valid color string.\n const safeVar = maybeColor.replace(/^var\\((.*)\\)$/, \"$1\");\n const parsedVar = safeVar.startsWith(\"--\") ? getComputedStyle(document.documentElement).getPropertyValue(safeVar) : undefined;\n const color = parsedVar?.trim() || maybeColor;\n return getLuminance(color);\n } catch (e) {\n console.warn(\"Failed to extract color luminance\", e);\n return undefined;\n }\n}\n\nfunction ColorInput({\n pluginConfig,\n ...props\n}: ObjectInputProps<FieldValues> & {\n pluginConfig: PluginConfig;\n}) {\n const options = props.schemaType.options as FieldOptions | undefined;\n const colorList = options?.colorList ?? pluginConfig.colorList;\n const renderOption = options?.renderOption ?? pluginConfig.renderOption;\n const renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;\n\n return (\n <AsyncAutocomplete\n placeholder=\"Select color\"\n noOptionsPlaceholder=\"No colors found\"\n listItems={colorList}\n value={props.value?.value}\n renderValue={(value, opt) => opt?.label ?? value}\n onChange={(value) => {\n if (!value) return props.onChange(unset());\n const luminance = maybeGetLuminance(value);\n return props.onChange(set({ ...props.value, value, luminance }));\n }}\n renderSelected={(value) => {\n if (renderSelected) return renderSelected(value);\n return <Avatar style={{ backgroundColor: value }} />;\n }}\n renderOption={({ label, value }) => {\n if (renderOption) return renderOption({ label, value });\n return (\n <Card as=\"button\">\n <Flex align=\"center\" padding={2}>\n <Avatar size={1} style={{ backgroundColor: value }} />\n <Box flex={1} padding={2}>\n <Text size={2}>{label}</Text>\n </Box>\n </Flex>\n </Card>\n );\n }}\n />\n );\n}\n\nexport { ColorInput };\n","import type { ListItems } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { StringDefinition, StringOptions } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.color\" as const;\n\n/** @public */\nexport type PluginConfig = {\n colorList: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n/** @public */\nexport type FieldOptions = StringOptions & {\n colorList?: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { defineField, definePlugin, defineType } from \"sanity\";\nimport { ColorInput } from \"./input\";\nimport { type FieldOptions, type PluginConfig, typeName } from \"./types\";\n\n/** @public */\nconst wildSanityColorFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-color-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Color\",\n description: \"Select a color.\",\n icon: () => <>🎨</>,\n components: {\n input: (props) => <ColorInput pluginConfig={config} {...props} />,\n },\n fields: [\n defineField({\n name: \"value\",\n type: \"string\",\n }),\n defineField({\n name: \"luminance\",\n type: \"number\",\n }),\n ],\n }),\n ],\n },\n };\n});\n\nexport { wildSanityColorFieldPlugin, typeName, type PluginConfig, type FieldOptions };\n"],"names":["getLuminance","jsx","AsyncAutocomplete","unset","set","Avatar","Card","Flex","Box","Text","definePlugin","defineType","Fragment","defineField"],"mappings":";;;AAaA,SAAS,kBAAkB,YAAoB;AAC7C,MAAI;AAGF,UAAM,UAAU,WAAW,QAAQ,iBAAiB,IAAI,GAElD,SADY,QAAQ,WAAW,IAAI,IAAI,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,OAAO,IAAI,SAC3F,UAAU;AACnC,WAAOA,QAAAA,aAAa,KAAK;AAAA,EAC3B,SAAS,GAAG;AACV,YAAQ,KAAK,qCAAqC,CAAC;AACnD;AAAA,EACF;AACF;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA,GAAG;AACL,GAEG;AACD,QAAM,UAAU,MAAM,WAAW,SAC3B,YAAY,SAAS,aAAa,aAAa,WAC/C,eAAe,SAAS,gBAAgB,aAAa,cACrD,iBAAiB,SAAS,kBAAkB,aAAa;AAE/D,SACEC,2BAAAA;AAAAA,IAACC,kBAAAA;AAAAA,IAAA;AAAA,MACC,aAAY;AAAA,MACZ,sBAAqB;AAAA,MACrB,WAAW;AAAA,MACX,OAAO,MAAM,OAAO;AAAA,MACpB,aAAa,CAAC,OAAO,QAAQ,KAAK,SAAS;AAAA,MAC3C,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO,MAAM,SAASC,OAAAA,OAAO;AACzC,cAAM,YAAY,kBAAkB,KAAK;AACzC,eAAO,MAAM,SAASC,OAAAA,IAAI,EAAE,GAAG,MAAM,OAAO,OAAO,UAAA,CAAW,CAAC;AAAA,MACjE;AAAA,MACA,gBAAgB,CAAC,UACX,iBAAuB,eAAe,KAAK,IACxCH,+BAACI,GAAAA,QAAA,EAAO,OAAO,EAAE,iBAAiB,QAAM,CAAG;AAAA,MAEpD,cAAc,CAAC,EAAE,OAAO,YAClB,eAAqB,aAAa,EAAE,OAAO,MAAA,CAAO,IAEpDJ,2BAAAA,IAACK,WAAK,IAAG,UACP,0CAACC,GAAAA,MAAA,EAAK,OAAM,UAAS,SAAS,GAC5B,UAAA;AAAA,QAAAN,+BAACI,GAAAA,UAAO,MAAM,GAAG,OAAO,EAAE,iBAAiB,SAAS;AAAA,QACpDJ,2BAAAA,IAACO,GAAAA,KAAA,EAAI,MAAM,GAAG,SAAS,GACrB,UAAAP,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,MAAM,GAAI,UAAA,MAAA,CAAM,EAAA,CACxB;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAKV;ACjEO,MAAM,WAAW,cCClB,6BAA6BC,OAAAA,aAA2B,CAAC,YACtD;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,OAAO;AAAA,MACLC,kBAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,MAAM,MAAMV,2BAAAA,IAAAW,WAAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,QAChB,YAAY;AAAA,UACV,OAAO,CAAC,UAAUX,+BAAC,cAAW,cAAc,QAAS,GAAG,MAAA,CAAO;AAAA,QAAA;AAAA,QAEjE,QAAQ;AAAA,UACNY,mBAAY;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,UAAA,CACP;AAAA,UACDA,mBAAY;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,UAAA,CACP;AAAA,QAAA;AAAA,MACH,CACD;AAAA,IAAA;AAAA,EACH;AAEJ,EACD;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/input.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Avatar, Box, Card, Flex, Text } from \"@sanity/ui\";\nimport { getLuminance } from \"color2k\";\nimport { type ObjectInputProps, set, unset } from \"sanity\";\nimport type { FieldOptions, PluginConfig } from \"./types\";\n\ntype FieldValues = {\n // The selected value from the color list.\n value?: string;\n // The calculated luminance of the selected color (0 to 1).\n luminance?: number;\n};\n\n// Maybe parse CSS variable and return its computed value.\n// Handles var(--variable), --variable.\n// If the input is not a CSS variable, returns it as-is.\nfunction maybeGetColorValue(source: string) {\n const varMatch = source.match(/^var\\((.+)\\)$/);\n const inner = varMatch?.[1] ? varMatch[1].trim() : source.trim();\n\n // Only take the first part for var(--variable, fallback) and ignore the fallback.\n const cssVarName = inner.split(\",\")[0]?.trim();\n const resolved = cssVarName?.startsWith(\"--\")\n ? getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim()\n : null;\n\n const color = resolved || source;\n return color;\n}\n\n// The getLuminance function can throw for invalid colors.\nfunction safeGetLuminance(maybeColor: string) {\n try {\n return getLuminance(maybeColor);\n } catch (e) {\n console.warn(\"Failed to get luminance\", e);\n return undefined;\n }\n}\n\nfunction ColorInput({\n pluginConfig,\n ...props\n}: ObjectInputProps<FieldValues> & {\n pluginConfig: PluginConfig;\n}) {\n const options = props.schemaType.options as FieldOptions | undefined;\n const colorList = options?.colorList ?? pluginConfig.colorList;\n const renderOption = options?.renderOption ?? pluginConfig.renderOption;\n const renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;\n\n return (\n <AsyncAutocomplete\n placeholder=\"Select color\"\n noOptionsPlaceholder=\"No colors found\"\n listItems={colorList}\n value={props.value?.value}\n renderValue={(value, opt) => opt?.label ?? value}\n onChange={(value) => {\n if (!value) return props.onChange(unset());\n const color = maybeGetColorValue(value);\n const luminance = color ? safeGetLuminance(color) : undefined;\n return props.onChange(set({ ...props.value, value, luminance }));\n }}\n renderSelected={(value) => {\n if (renderSelected) return renderSelected(value);\n return <Avatar style={{ backgroundColor: value }} />;\n }}\n renderOption={({ label, value }) => {\n if (renderOption) return renderOption({ label, value });\n return (\n <Card as=\"button\">\n <Flex align=\"center\" padding={2}>\n <Avatar size={1} style={{ backgroundColor: value }} />\n <Box flex={1} padding={2}>\n <Text size={2}>{label}</Text>\n </Box>\n </Flex>\n </Card>\n );\n }}\n />\n );\n}\n\nexport { ColorInput };\n","import type { ListItems } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { StringDefinition, StringOptions } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.color\" as const;\n\n/** @public */\nexport type PluginConfig = {\n colorList: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n/** @public */\nexport type FieldOptions = StringOptions & {\n colorList?: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { defineField, definePlugin, defineType } from \"sanity\";\nimport { ColorInput } from \"./input\";\nimport { type FieldOptions, type PluginConfig, typeName } from \"./types\";\n\n/** @public */\nconst wildSanityColorFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-color-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Color\",\n description: \"Select a color.\",\n icon: () => <>🎨</>,\n components: {\n input: (props) => <ColorInput pluginConfig={config} {...props} />,\n },\n fields: [\n defineField({\n name: \"value\",\n type: \"string\",\n }),\n defineField({\n name: \"luminance\",\n type: \"number\",\n }),\n ],\n }),\n ],\n },\n };\n});\n\nexport { wildSanityColorFieldPlugin, typeName, type PluginConfig, type FieldOptions };\n"],"names":["maybeGetColorValue","source","varMatch","match","cssVarName","trim","split","startsWith","getComputedStyle","document","documentElement","getPropertyValue","safeGetLuminance","maybeColor","getLuminance","e","console","warn","ColorInput","t0","$","_c","pluginConfig","props","options","schemaType","colorList","renderOption","renderSelected","t1","value","t2","value_0","onChange","unset","color","luminance","undefined","set","t3","value_1","jsx","Avatar","backgroundColor","t4","t5","label","value_2","Card","jsxs","Flex","Box","Text","AsyncAutocomplete","_temp","opt","typeName","wildSanityColorFieldPlugin","definePlugin","config","name","schema","types","defineType","type","title","description","icon","Fragment","components","input","fields","defineField"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,68 +1,86 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { unset, set, definePlugin, defineType, defineField } from "sanity";
3
+ import { c } from "react/compiler-runtime";
3
4
  import { AsyncAutocomplete } from "@madebywild/sanity-utils/async-autocomplete";
4
- import { Card, Flex, Avatar, Box, Text } from "@sanity/ui";
5
+ import { Avatar, Card, Flex, Box, Text } from "@sanity/ui";
5
6
  import { getLuminance } from "color2k";
6
- function maybeGetLuminance(maybeColor) {
7
+ function maybeGetColorValue(source) {
8
+ const varMatch = source.match(/^var\((.+)\)$/), cssVarName = (varMatch?.[1] ? varMatch[1].trim() : source.trim()).split(",")[0]?.trim();
9
+ return (cssVarName?.startsWith("--") ? getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim() : null) || source;
10
+ }
11
+ function safeGetLuminance(maybeColor) {
7
12
  try {
8
- const safeVar = maybeColor.replace(/^var\((.*)\)$/, "$1"), color = (safeVar.startsWith("--") ? getComputedStyle(document.documentElement).getPropertyValue(safeVar) : void 0)?.trim() || maybeColor;
9
- return getLuminance(color);
13
+ return getLuminance(maybeColor);
10
14
  } catch (e) {
11
- console.warn("Failed to extract color luminance", e);
15
+ console.warn("Failed to get luminance", e);
12
16
  return;
13
17
  }
14
18
  }
15
- function ColorInput({
16
- pluginConfig,
17
- ...props
18
- }) {
19
- const options = props.schemaType.options, colorList = options?.colorList ?? pluginConfig.colorList, renderOption = options?.renderOption ?? pluginConfig.renderOption, renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;
20
- return /* @__PURE__ */ jsx(
21
- AsyncAutocomplete,
22
- {
23
- placeholder: "Select color",
24
- noOptionsPlaceholder: "No colors found",
25
- listItems: colorList,
26
- value: props.value?.value,
27
- renderValue: (value, opt) => opt?.label ?? value,
28
- onChange: (value) => {
29
- if (!value) return props.onChange(unset());
30
- const luminance = maybeGetLuminance(value);
31
- return props.onChange(set({ ...props.value, value, luminance }));
32
- },
33
- renderSelected: (value) => renderSelected ? renderSelected(value) : /* @__PURE__ */ jsx(Avatar, { style: { backgroundColor: value } }),
34
- renderOption: ({ label, value }) => renderOption ? renderOption({ label, value }) : /* @__PURE__ */ jsx(Card, { as: "button", children: /* @__PURE__ */ jsxs(Flex, { align: "center", padding: 2, children: [
35
- /* @__PURE__ */ jsx(Avatar, { size: 1, style: { backgroundColor: value } }),
36
- /* @__PURE__ */ jsx(Box, { flex: 1, padding: 2, children: /* @__PURE__ */ jsx(Text, { size: 2, children: label }) })
37
- ] }) })
38
- }
39
- );
19
+ function ColorInput(t0) {
20
+ const $ = c(15);
21
+ let pluginConfig, props;
22
+ $[0] !== t0 ? ({
23
+ pluginConfig,
24
+ ...props
25
+ } = t0, $[0] = t0, $[1] = pluginConfig, $[2] = props) : (pluginConfig = $[1], props = $[2]);
26
+ const options = props.schemaType.options, colorList = options?.colorList ?? pluginConfig.colorList, renderOption = options?.renderOption ?? pluginConfig.renderOption, renderSelected = options?.renderSelected ?? pluginConfig.renderSelected, t1 = props.value?.value;
27
+ let t2;
28
+ $[3] !== props ? (t2 = (value_0) => {
29
+ if (!value_0)
30
+ return props.onChange(unset());
31
+ const color = maybeGetColorValue(value_0), luminance = color ? safeGetLuminance(color) : void 0;
32
+ return props.onChange(set({
33
+ ...props.value,
34
+ value: value_0,
35
+ luminance
36
+ }));
37
+ }, $[3] = props, $[4] = t2) : t2 = $[4];
38
+ let t3;
39
+ $[5] !== renderSelected ? (t3 = (value_1) => renderSelected ? renderSelected(value_1) : /* @__PURE__ */ jsx(Avatar, { style: {
40
+ backgroundColor: value_1
41
+ } }), $[5] = renderSelected, $[6] = t3) : t3 = $[6];
42
+ let t4;
43
+ $[7] !== renderOption ? (t4 = (t52) => {
44
+ const {
45
+ label,
46
+ value: value_2
47
+ } = t52;
48
+ return renderOption ? renderOption({
49
+ label,
50
+ value: value_2
51
+ }) : /* @__PURE__ */ jsx(Card, { as: "button", children: /* @__PURE__ */ jsxs(Flex, { align: "center", padding: 2, children: [
52
+ /* @__PURE__ */ jsx(Avatar, { size: 1, style: {
53
+ backgroundColor: value_2
54
+ } }),
55
+ /* @__PURE__ */ jsx(Box, { flex: 1, padding: 2, children: /* @__PURE__ */ jsx(Text, { size: 2, children: label }) })
56
+ ] }) });
57
+ }, $[7] = renderOption, $[8] = t4) : t4 = $[8];
58
+ let t5;
59
+ return $[9] !== colorList || $[10] !== t1 || $[11] !== t2 || $[12] !== t3 || $[13] !== t4 ? (t5 = /* @__PURE__ */ jsx(AsyncAutocomplete, { placeholder: "Select color", noOptionsPlaceholder: "No colors found", listItems: colorList, value: t1, renderValue: _temp, onChange: t2, renderSelected: t3, renderOption: t4 }), $[9] = colorList, $[10] = t1, $[11] = t2, $[12] = t3, $[13] = t4, $[14] = t5) : t5 = $[14], t5;
60
+ }
61
+ function _temp(value, opt) {
62
+ return opt?.label ?? value;
40
63
  }
41
64
  const typeName = "wild.color", wildSanityColorFieldPlugin = definePlugin((config) => ({
42
65
  name: "@madebywild/sanity-color-field",
43
66
  schema: {
44
- types: [
45
- defineType({
46
- name: typeName,
47
- type: "object",
48
- title: "Color",
49
- description: "Select a color.",
50
- icon: () => /* @__PURE__ */ jsx(Fragment, { children: "\u{1F3A8}" }),
51
- components: {
52
- input: (props) => /* @__PURE__ */ jsx(ColorInput, { pluginConfig: config, ...props })
53
- },
54
- fields: [
55
- defineField({
56
- name: "value",
57
- type: "string"
58
- }),
59
- defineField({
60
- name: "luminance",
61
- type: "number"
62
- })
63
- ]
64
- })
65
- ]
67
+ types: [defineType({
68
+ name: typeName,
69
+ type: "object",
70
+ title: "Color",
71
+ description: "Select a color.",
72
+ icon: () => /* @__PURE__ */ jsx(Fragment, { children: "\u{1F3A8}" }),
73
+ components: {
74
+ input: (props) => /* @__PURE__ */ jsx(ColorInput, { pluginConfig: config, ...props })
75
+ },
76
+ fields: [defineField({
77
+ name: "value",
78
+ type: "string"
79
+ }), defineField({
80
+ name: "luminance",
81
+ type: "number"
82
+ })]
83
+ })]
66
84
  }
67
85
  }));
68
86
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/input.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Avatar, Box, Card, Flex, Text } from \"@sanity/ui\";\nimport { getLuminance } from \"color2k\";\nimport { type ObjectInputProps, set, unset } from \"sanity\";\nimport type { FieldOptions, PluginConfig } from \"./types\";\n\ntype FieldValues = {\n // The selected value from the color list.\n value?: string;\n // The calculated luminance of the selected color (0 to 1).\n luminance?: number;\n};\n\nfunction maybeGetLuminance(maybeColor: string) {\n try {\n // Try to unwrap CSS variable and look up its value.\n // If it's not a CSS variable, assume it's a valid color string.\n const safeVar = maybeColor.replace(/^var\\((.*)\\)$/, \"$1\");\n const parsedVar = safeVar.startsWith(\"--\") ? getComputedStyle(document.documentElement).getPropertyValue(safeVar) : undefined;\n const color = parsedVar?.trim() || maybeColor;\n return getLuminance(color);\n } catch (e) {\n console.warn(\"Failed to extract color luminance\", e);\n return undefined;\n }\n}\n\nfunction ColorInput({\n pluginConfig,\n ...props\n}: ObjectInputProps<FieldValues> & {\n pluginConfig: PluginConfig;\n}) {\n const options = props.schemaType.options as FieldOptions | undefined;\n const colorList = options?.colorList ?? pluginConfig.colorList;\n const renderOption = options?.renderOption ?? pluginConfig.renderOption;\n const renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;\n\n return (\n <AsyncAutocomplete\n placeholder=\"Select color\"\n noOptionsPlaceholder=\"No colors found\"\n listItems={colorList}\n value={props.value?.value}\n renderValue={(value, opt) => opt?.label ?? value}\n onChange={(value) => {\n if (!value) return props.onChange(unset());\n const luminance = maybeGetLuminance(value);\n return props.onChange(set({ ...props.value, value, luminance }));\n }}\n renderSelected={(value) => {\n if (renderSelected) return renderSelected(value);\n return <Avatar style={{ backgroundColor: value }} />;\n }}\n renderOption={({ label, value }) => {\n if (renderOption) return renderOption({ label, value });\n return (\n <Card as=\"button\">\n <Flex align=\"center\" padding={2}>\n <Avatar size={1} style={{ backgroundColor: value }} />\n <Box flex={1} padding={2}>\n <Text size={2}>{label}</Text>\n </Box>\n </Flex>\n </Card>\n );\n }}\n />\n );\n}\n\nexport { ColorInput };\n","import type { ListItems } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { StringDefinition, StringOptions } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.color\" as const;\n\n/** @public */\nexport type PluginConfig = {\n colorList: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n/** @public */\nexport type FieldOptions = StringOptions & {\n colorList?: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { defineField, definePlugin, defineType } from \"sanity\";\nimport { ColorInput } from \"./input\";\nimport { type FieldOptions, type PluginConfig, typeName } from \"./types\";\n\n/** @public */\nconst wildSanityColorFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-color-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Color\",\n description: \"Select a color.\",\n icon: () => <>🎨</>,\n components: {\n input: (props) => <ColorInput pluginConfig={config} {...props} />,\n },\n fields: [\n defineField({\n name: \"value\",\n type: \"string\",\n }),\n defineField({\n name: \"luminance\",\n type: \"number\",\n }),\n ],\n }),\n ],\n },\n };\n});\n\nexport { wildSanityColorFieldPlugin, typeName, type PluginConfig, type FieldOptions };\n"],"names":[],"mappings":";;;;;AAaA,SAAS,kBAAkB,YAAoB;AAC7C,MAAI;AAGF,UAAM,UAAU,WAAW,QAAQ,iBAAiB,IAAI,GAElD,SADY,QAAQ,WAAW,IAAI,IAAI,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,OAAO,IAAI,SAC3F,UAAU;AACnC,WAAO,aAAa,KAAK;AAAA,EAC3B,SAAS,GAAG;AACV,YAAQ,KAAK,qCAAqC,CAAC;AACnD;AAAA,EACF;AACF;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA,GAAG;AACL,GAEG;AACD,QAAM,UAAU,MAAM,WAAW,SAC3B,YAAY,SAAS,aAAa,aAAa,WAC/C,eAAe,SAAS,gBAAgB,aAAa,cACrD,iBAAiB,SAAS,kBAAkB,aAAa;AAE/D,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAY;AAAA,MACZ,sBAAqB;AAAA,MACrB,WAAW;AAAA,MACX,OAAO,MAAM,OAAO;AAAA,MACpB,aAAa,CAAC,OAAO,QAAQ,KAAK,SAAS;AAAA,MAC3C,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO,MAAM,SAAS,OAAO;AACzC,cAAM,YAAY,kBAAkB,KAAK;AACzC,eAAO,MAAM,SAAS,IAAI,EAAE,GAAG,MAAM,OAAO,OAAO,UAAA,CAAW,CAAC;AAAA,MACjE;AAAA,MACA,gBAAgB,CAAC,UACX,iBAAuB,eAAe,KAAK,IACxC,oBAAC,QAAA,EAAO,OAAO,EAAE,iBAAiB,QAAM,CAAG;AAAA,MAEpD,cAAc,CAAC,EAAE,OAAO,YAClB,eAAqB,aAAa,EAAE,OAAO,MAAA,CAAO,IAEpD,oBAAC,QAAK,IAAG,UACP,+BAAC,MAAA,EAAK,OAAM,UAAS,SAAS,GAC5B,UAAA;AAAA,QAAA,oBAAC,UAAO,MAAM,GAAG,OAAO,EAAE,iBAAiB,SAAS;AAAA,QACpD,oBAAC,KAAA,EAAI,MAAM,GAAG,SAAS,GACrB,UAAA,oBAAC,MAAA,EAAK,MAAM,GAAI,UAAA,MAAA,CAAM,EAAA,CACxB;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAKV;ACjEO,MAAM,WAAW,cCClB,6BAA6B,aAA2B,CAAC,YACtD;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,OAAO;AAAA,MACL,WAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,MAAM,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,QAChB,YAAY;AAAA,UACV,OAAO,CAAC,UAAU,oBAAC,cAAW,cAAc,QAAS,GAAG,MAAA,CAAO;AAAA,QAAA;AAAA,QAEjE,QAAQ;AAAA,UACN,YAAY;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,UAAA,CACP;AAAA,UACD,YAAY;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,UAAA,CACP;AAAA,QAAA;AAAA,MACH,CACD;AAAA,IAAA;AAAA,EACH;AAEJ,EACD;"}
1
+ {"version":3,"file":"index.js","sources":["../src/input.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Avatar, Box, Card, Flex, Text } from \"@sanity/ui\";\nimport { getLuminance } from \"color2k\";\nimport { type ObjectInputProps, set, unset } from \"sanity\";\nimport type { FieldOptions, PluginConfig } from \"./types\";\n\ntype FieldValues = {\n // The selected value from the color list.\n value?: string;\n // The calculated luminance of the selected color (0 to 1).\n luminance?: number;\n};\n\n// Maybe parse CSS variable and return its computed value.\n// Handles var(--variable), --variable.\n// If the input is not a CSS variable, returns it as-is.\nfunction maybeGetColorValue(source: string) {\n const varMatch = source.match(/^var\\((.+)\\)$/);\n const inner = varMatch?.[1] ? varMatch[1].trim() : source.trim();\n\n // Only take the first part for var(--variable, fallback) and ignore the fallback.\n const cssVarName = inner.split(\",\")[0]?.trim();\n const resolved = cssVarName?.startsWith(\"--\")\n ? getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim()\n : null;\n\n const color = resolved || source;\n return color;\n}\n\n// The getLuminance function can throw for invalid colors.\nfunction safeGetLuminance(maybeColor: string) {\n try {\n return getLuminance(maybeColor);\n } catch (e) {\n console.warn(\"Failed to get luminance\", e);\n return undefined;\n }\n}\n\nfunction ColorInput({\n pluginConfig,\n ...props\n}: ObjectInputProps<FieldValues> & {\n pluginConfig: PluginConfig;\n}) {\n const options = props.schemaType.options as FieldOptions | undefined;\n const colorList = options?.colorList ?? pluginConfig.colorList;\n const renderOption = options?.renderOption ?? pluginConfig.renderOption;\n const renderSelected = options?.renderSelected ?? pluginConfig.renderSelected;\n\n return (\n <AsyncAutocomplete\n placeholder=\"Select color\"\n noOptionsPlaceholder=\"No colors found\"\n listItems={colorList}\n value={props.value?.value}\n renderValue={(value, opt) => opt?.label ?? value}\n onChange={(value) => {\n if (!value) return props.onChange(unset());\n const color = maybeGetColorValue(value);\n const luminance = color ? safeGetLuminance(color) : undefined;\n return props.onChange(set({ ...props.value, value, luminance }));\n }}\n renderSelected={(value) => {\n if (renderSelected) return renderSelected(value);\n return <Avatar style={{ backgroundColor: value }} />;\n }}\n renderOption={({ label, value }) => {\n if (renderOption) return renderOption({ label, value });\n return (\n <Card as=\"button\">\n <Flex align=\"center\" padding={2}>\n <Avatar size={1} style={{ backgroundColor: value }} />\n <Box flex={1} padding={2}>\n <Text size={2}>{label}</Text>\n </Box>\n </Flex>\n </Card>\n );\n }}\n />\n );\n}\n\nexport { ColorInput };\n","import type { ListItems } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { StringDefinition, StringOptions } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.color\" as const;\n\n/** @public */\nexport type PluginConfig = {\n colorList: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n/** @public */\nexport type FieldOptions = StringOptions & {\n colorList?: ListItems;\n renderSelected?: (value: string) => React.JSX.Element;\n renderOption?: (item: { label?: string; value: string }) => React.JSX.Element;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { defineField, definePlugin, defineType } from \"sanity\";\nimport { ColorInput } from \"./input\";\nimport { type FieldOptions, type PluginConfig, typeName } from \"./types\";\n\n/** @public */\nconst wildSanityColorFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-color-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Color\",\n description: \"Select a color.\",\n icon: () => <>🎨</>,\n components: {\n input: (props) => <ColorInput pluginConfig={config} {...props} />,\n },\n fields: [\n defineField({\n name: \"value\",\n type: \"string\",\n }),\n defineField({\n name: \"luminance\",\n type: \"number\",\n }),\n ],\n }),\n ],\n },\n };\n});\n\nexport { wildSanityColorFieldPlugin, typeName, type PluginConfig, type FieldOptions };\n"],"names":["maybeGetColorValue","source","varMatch","match","cssVarName","trim","split","startsWith","getComputedStyle","document","documentElement","getPropertyValue","safeGetLuminance","maybeColor","getLuminance","e","console","warn","ColorInput","t0","$","_c","pluginConfig","props","options","schemaType","colorList","renderOption","renderSelected","t1","value","t2","value_0","onChange","unset","color","luminance","undefined","set","t3","value_1","backgroundColor","t4","t5","label","value_2","_temp","opt","typeName","wildSanityColorFieldPlugin","definePlugin","config","name","schema","types","defineType","type","title","description","icon","components","input","fields","defineField"],"mappings":";;;;;;AAgBA,SAASA,mBAAmBC,QAAgB;AAC1C,QAAMC,WAAWD,OAAOE,MAAM,eAAe,GAIvCC,cAHQF,WAAW,CAAC,IAAIA,SAAS,CAAC,EAAEG,KAAAA,IAASJ,OAAOI,KAAAA,GAGjCC,MAAM,GAAG,EAAE,CAAC,GAAGD,KAAAA;AAMxC,UALiBD,YAAYG,WAAW,IAAI,IACxCC,iBAAiBC,SAASC,eAAe,EAAEC,iBAAiBP,UAAU,EAAEC,KAAAA,IACxE,SAEsBJ;AAE5B;AAGA,SAASW,iBAAiBC,YAAoB;AAC5C,MAAI;AACF,WAAOC,aAAaD,UAAU;AAAA,EAChC,SAASE,GAAG;AACVC,YAAQC,KAAK,2BAA2BF,CAAC;AACzC;AAAA,EACF;AACF;AAEA,SAAAG,WAAAC,IAAA;AAAA,QAAAC,IAAAC,EAAA,EAAA;AAAA,MAAAC,cAAAC;AAAAH,WAAAD,MAAoB;AAAA,IAAAG;AAAAA,IAAA,GAAAC;AAAAA,EAAAA,IAAAJ,IAKnBC,OAAAD,IAAAC,OAAAE,cAAAF,OAAAG,UAAAD,eAAAF,EAAA,CAAA,GAAAG,QAAAH,EAAA,CAAA;AACC,QAAAI,UAAgBD,MAAKE,WAAWD,SAChCE,YAAkBF,SAAOE,aAAeJ,aAAYI,WACpDC,eAAqBH,SAAOG,gBAAkBL,aAAYK,cAC1DC,iBAAuBJ,SAAOI,kBAAoBN,aAAYM,gBAOnDC,KAAAN,MAAKO,OAAaA;AAAA,MAAAC;AAAAX,WAAAG,SAEfQ,KAAAC,CAAAA,YAAA;AACR,QAAI,CAACF;AAAK,aAASP,MAAKU,SAAUC,OAAO;AACzC,UAAAC,QAAcnC,mBAAmB8B,OAAK,GACtCM,YAAkBD,QAAQvB,iBAAiBuB,KAAiB,IAA1CE;AAA4C,WACvDd,MAAKU,SAAUK,IAAI;AAAA,MAAA,GAAKf,MAAKO;AAAAA,MAAMA,OAAEA;AAAAA,MAAKM;AAAAA,IAAAA,CAAa,CAAC;AAAA,EAAC,GACjEhB,OAAAG,OAAAH,OAAAW,MAAAA,KAAAX,EAAA,CAAA;AAAA,MAAAmB;AAAAnB,WAAAQ,kBACeW,KAAAC,CAAAA,YACVZ,iBAAuBA,eAAeE,OAAK,IACxC,oBAAC,QAAA,EAAc,OAAA;AAAA,IAAAW,iBAAmBX;AAAAA,EAAAA,EAAM,CAAC,GACjDV,OAAAQ,gBAAAR,OAAAmB,MAAAA,KAAAnB,EAAA,CAAA;AAAA,MAAAsB;AAAAtB,WAAAO,gBACae,KAAAC,CAAAA,QAAA;AAAC,UAAA;AAAA,MAAAC;AAAAA,MAAAd,OAAAe;AAAAA,IAAAA,IAAAF;AACb,WAAIhB,eAAqBA,aAAa;AAAA,MAAAiB;AAAAA,MAAAd,OAASA;AAAAA,IAAAA,CAAO,IAEpD,oBAAC,MAAA,EAAQ,IAAA,UACP,UAAA,qBAAC,MAAA,EAAW,OAAA,UAAkB,SAAA,GAC5B,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAa,MAAA,GAAU,OAAA;AAAA,QAAAW,iBAAmBX;AAAAA,MAAAA,GAAO;AAAA,MAClD,oBAAC,KAAA,EAAU,MAAA,GAAY,SAAA,GACrB,UAAA,oBAAC,MAAA,EAAW,MAAA,GAAIc,UAAAA,MAAAA,CAAM,EAAA,CACxB;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAO,GAEVxB,OAAAO,cAAAP,OAAAsB,MAAAA,KAAAtB,EAAA,CAAA;AAAA,MAAAuB;AAAA,SAAAvB,EAAA,CAAA,MAAAM,aAAAN,EAAA,EAAA,MAAAS,MAAAT,EAAA,EAAA,MAAAW,MAAAX,EAAA,EAAA,MAAAmB,MAAAnB,UAAAsB,MA5BHC,yBAAC,mBAAA,EACa,aAAA,gBACS,sBAAA,mBACVjB,sBACJ,OAAAG,IACM,aAAAiB,OACH,UAAAf,IAMM,gBAAAQ,IAIF,cAAAG,GAAAA,CAYb,GACDtB,OAAAM,WAAAN,QAAAS,IAAAT,QAAAW,IAAAX,QAAAmB,IAAAnB,QAAAsB,IAAAtB,QAAAuB,MAAAA,KAAAvB,EAAA,EAAA,GA7BFuB;AA6BE;AAzCN,SAAAG,MAAAhB,OAAAiB,KAAA;AAAA,SAiBmCA,KAAGH,SAAHd;AAAmB;ACrD/C,MAAMkB,WAAW,cCClBC,6BAA6BC,aAA4BC,CAAAA,YACtD;AAAA,EACLC,MAAM;AAAA,EACNC,QAAQ;AAAA,IACNC,OAAO,CACLC,WAAW;AAAA,MACTH,MAAMJ;AAAAA,MACNQ,MAAM;AAAA,MACNC,OAAO;AAAA,MACPC,aAAa;AAAA,MACbC,MAAMA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAChBC,YAAY;AAAA,QACVC,OAAQtC,CAAAA,UAAU,oBAAC,cAAW,cAAc4B,QAAQ,GAAI5B,MAAAA,CAAM;AAAA,MAAA;AAAA,MAEhEuC,QAAQ,CACNC,YAAY;AAAA,QACVX,MAAM;AAAA,QACNI,MAAM;AAAA,MAAA,CACP,GACDO,YAAY;AAAA,QACVX,MAAM;AAAA,QACNI,MAAM;AAAA,MAAA,CACP,CAAC;AAAA,IAAA,CAEL,CAAC;AAAA,EAAA;AAGR,EACD;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madebywild/sanity-color-field",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "UNLICENSED",
@@ -22,22 +22,23 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "color2k": "2.0.3",
25
- "@madebywild/sanity-utils": "0.2.3"
25
+ "@madebywild/sanity-utils": "0.2.5"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@sanity/ui": "^3.1",
29
- "sanity": "^4.17",
30
29
  "react": "^19",
31
- "react-dom": "^19"
30
+ "react-dom": "^19",
31
+ "sanity": "^4.17"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@sanity/pkg-utils": "^9.2",
35
- "sanity": "^4.17",
35
+ "@types/react": "^19",
36
+ "@types/react-dom": "^19",
37
+ "babel-plugin-react-compiler": "1.0.0",
36
38
  "react": "^19",
37
39
  "react-dom": "^19",
38
- "typescript": "^5",
39
- "@types/react": "^19",
40
- "@types/react-dom": "^19"
40
+ "sanity": "^4.17",
41
+ "typescript": "^5"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "pkg-utils build --strict",
package/src/input.tsx CHANGED
@@ -11,16 +11,29 @@ type FieldValues = {
11
11
  luminance?: number;
12
12
  };
13
13
 
14
- function maybeGetLuminance(maybeColor: string) {
14
+ // Maybe parse CSS variable and return its computed value.
15
+ // Handles var(--variable), --variable.
16
+ // If the input is not a CSS variable, returns it as-is.
17
+ function maybeGetColorValue(source: string) {
18
+ const varMatch = source.match(/^var\((.+)\)$/);
19
+ const inner = varMatch?.[1] ? varMatch[1].trim() : source.trim();
20
+
21
+ // Only take the first part for var(--variable, fallback) and ignore the fallback.
22
+ const cssVarName = inner.split(",")[0]?.trim();
23
+ const resolved = cssVarName?.startsWith("--")
24
+ ? getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim()
25
+ : null;
26
+
27
+ const color = resolved || source;
28
+ return color;
29
+ }
30
+
31
+ // The getLuminance function can throw for invalid colors.
32
+ function safeGetLuminance(maybeColor: string) {
15
33
  try {
16
- // Try to unwrap CSS variable and look up its value.
17
- // If it's not a CSS variable, assume it's a valid color string.
18
- const safeVar = maybeColor.replace(/^var\((.*)\)$/, "$1");
19
- const parsedVar = safeVar.startsWith("--") ? getComputedStyle(document.documentElement).getPropertyValue(safeVar) : undefined;
20
- const color = parsedVar?.trim() || maybeColor;
21
- return getLuminance(color);
34
+ return getLuminance(maybeColor);
22
35
  } catch (e) {
23
- console.warn("Failed to extract color luminance", e);
36
+ console.warn("Failed to get luminance", e);
24
37
  return undefined;
25
38
  }
26
39
  }
@@ -45,7 +58,8 @@ function ColorInput({
45
58
  renderValue={(value, opt) => opt?.label ?? value}
46
59
  onChange={(value) => {
47
60
  if (!value) return props.onChange(unset());
48
- const luminance = maybeGetLuminance(value);
61
+ const color = maybeGetColorValue(value);
62
+ const luminance = color ? safeGetLuminance(color) : undefined;
49
63
  return props.onChange(set({ ...props.value, value, luminance }));
50
64
  }}
51
65
  renderSelected={(value) => {