@wordpress-gcb/fields 0.2.2 → 0.2.3

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.
@@ -156,7 +156,8 @@ function ColorFieldImpl({
156
156
  disableCustomGradients = false,
157
157
  showGradients = true,
158
158
  className = '',
159
- help
159
+ help,
160
+ tokenKeys
160
161
  }) {
161
162
  const themeColors = useSetting('color.palette');
162
163
  const themeGradients = useSetting('color.gradients');
@@ -164,8 +165,14 @@ function ColorFieldImpl({
164
165
  // Always end up with arrays — `useSetting('color.gradients')` returns
165
166
  // undefined on themes that don't declare any gradients, and feeding that
166
167
  // to <GradientPicker> crashes on `.orientation`.
167
- const finalColors = colors && colors.length ? colors : themeColors || [];
168
+ let finalColors = colors && colors.length ? colors : themeColors || [];
168
169
  const finalGradients = gradients && gradients.length ? gradients : themeGradients || [];
170
+
171
+ // When the field was built with a token subset (tokenKeys), restrict the
172
+ // palette to those theme colours by slug. Empty/absent = offer all.
173
+ if (Array.isArray(tokenKeys) && tokenKeys.length > 0) {
174
+ finalColors = finalColors.filter(c => tokenKeys.includes(c.slug));
175
+ }
169
176
  return /*#__PURE__*/_jsx(BaseControl, {
170
177
  label: label,
171
178
  help: help,
@@ -236,6 +243,7 @@ export default function ColorField({
236
243
  showGradients: control.showGradients !== false,
237
244
  enableAlpha: control.enableAlpha !== false,
238
245
  disableCustomColors: control.disableCustomColors === true,
239
- disableCustomGradients: control.disableCustomGradients === true
246
+ disableCustomGradients: control.disableCustomGradients === true,
247
+ tokenKeys: control.tokenKeys
240
248
  });
241
249
  }
@@ -10,6 +10,7 @@ import { __ } from '@wordpress/i18n';
10
10
  import { Button, TextControl, Notice } from '@wordpress/components';
11
11
  import { useState } from '@wordpress/element';
12
12
  import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalHStack as HStack } from '@wordpress/components';
13
+ import { useTokens, getTokensByGroup } from '../hooks/useTokens';
13
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
15
  const DEFAULT_PRESETS = [{
15
16
  label: 'None',
@@ -25,6 +26,27 @@ const DEFAULT_PRESETS = [{
25
26
  value: 'large'
26
27
  }];
27
28
  const PRESET_KEYS = new Set(['none', 'small', 'medium', 'large']);
29
+
30
+ /**
31
+ * Build the toggle presets from the theme's spacing tokens when the field was
32
+ * configured with a token group (and optional checked subset). Falls back to
33
+ * the simple None/S/M/L presets when no tokens are configured.
34
+ */
35
+ function tokenPresets(control, tokens) {
36
+ const group = control.tokenGroup;
37
+ if (!group || !tokens) return null;
38
+ let list = getTokensByGroup(tokens, group);
39
+ if (!Array.isArray(list) || list.length === 0) return null;
40
+ if (Array.isArray(control.tokenKeys) && control.tokenKeys.length > 0) {
41
+ list = list.filter(t => control.tokenKeys.includes(t.slug || t.key));
42
+ }
43
+ if (list.length === 0) return null;
44
+ // Compact label (the slug or short name) — the value is the slug.
45
+ return list.map(t => ({
46
+ label: t.name || t.label || t.slug || t.key,
47
+ value: t.slug || t.key
48
+ }));
49
+ }
28
50
  function isValidCSSValue(input) {
29
51
  if (!input) return true;
30
52
  return /^(\d*\.?\d+)(px|rem|em|%|vw|vh|vmin|vmax)?$/.test(String(input).trim());
@@ -34,13 +56,22 @@ export default function SpacingField({
34
56
  value,
35
57
  onChange
36
58
  }) {
59
+ const {
60
+ tokens
61
+ } = useTokens();
62
+
63
+ // Token-driven presets (from theme.json) take priority over the explicit
64
+ // `presets` config and the simple None/S/M/L fallback.
65
+ const presets = tokenPresets(control, tokens) || control.presets || DEFAULT_PRESETS;
66
+ const presetKeys = new Set(presets.map(p => p.value));
67
+ const firstPreset = presets[0]?.value || 'medium';
68
+
37
69
  // Decide if value is a preset or a custom string.
38
- const isCustom = typeof value === 'string' && value !== '' && !PRESET_KEYS.has(value);
39
- const presetValue = isCustom ? 'medium' : value || 'medium';
70
+ const isCustom = typeof value === 'string' && value !== '' && !presetKeys.has(value);
71
+ const presetValue = isCustom ? firstPreset : value || firstPreset;
40
72
  const [showCustom, setShowCustom] = useState(isCustom);
41
73
  const [customInput, setCustomInput] = useState(isCustom ? value : '');
42
74
  const [error, setError] = useState(null);
43
- const presets = control.presets || DEFAULT_PRESETS;
44
75
  const handlePreset = next => {
45
76
  setShowCustom(false);
46
77
  setCustomInput('');
@@ -54,13 +85,13 @@ export default function SpacingField({
54
85
  return;
55
86
  }
56
87
  setError(null);
57
- onChange(next || 'medium');
88
+ onChange(next || firstPreset);
58
89
  };
59
90
  const handleReset = () => {
60
91
  setShowCustom(false);
61
92
  setCustomInput('');
62
93
  setError(null);
63
- onChange('medium');
94
+ onChange(firstPreset);
64
95
  };
65
96
  const displayHint = showCustom ? 'Custom' : presetValue.charAt(0).toUpperCase() + presetValue.slice(1);
66
97
  return /*#__PURE__*/_jsx("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress-gcb/fields",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "GCB typed-field controls, inspector renderer, and schema — decoupled from the WordPress plugin so any Gutenberg/headless editor can use them.",
5
5
  "license": "GPL-2.0-or-later",
6
6
  "homepage": "https://gutenbergcontrolblocks.com",