@wordpress-gcb/fields 0.2.1 → 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.
Files changed (91) hide show
  1. package/dist/conditional-logic.js +83 -0
  2. package/{src → dist}/control-context.js +3 -2
  3. package/{src → dist}/controls/MediaCapabilityGate.js +12 -8
  4. package/dist/controls/MediaPicker.js +149 -0
  5. package/dist/controls/MediaTriggerBadges.js +35 -0
  6. package/{src → dist}/controls/PopoverOrModal.js +49 -43
  7. package/dist/controls/SortableItem.js +126 -0
  8. package/dist/controls/button-group.js +46 -0
  9. package/dist/controls/checkbox-group.js +65 -0
  10. package/dist/controls/checkbox.js +15 -0
  11. package/dist/controls/code.js +24 -0
  12. package/dist/controls/color.js +249 -0
  13. package/dist/controls/date.js +55 -0
  14. package/dist/controls/datetime.js +61 -0
  15. package/dist/controls/email.js +17 -0
  16. package/dist/controls/file.js +163 -0
  17. package/dist/controls/gallery.js +371 -0
  18. package/dist/controls/google-map.js +143 -0
  19. package/dist/controls/heading-level.js +93 -0
  20. package/dist/controls/icon.js +292 -0
  21. package/dist/controls/image.js +360 -0
  22. package/dist/controls/index.js +88 -0
  23. package/dist/controls/message.js +86 -0
  24. package/dist/controls/number.js +19 -0
  25. package/dist/controls/oembed.js +42 -0
  26. package/{src → dist}/controls/page-link.js +1 -2
  27. package/dist/controls/post-object.js +913 -0
  28. package/dist/controls/radio.js +19 -0
  29. package/dist/controls/range.js +108 -0
  30. package/{src → dist}/controls/relationship.js +12 -7
  31. package/dist/controls/repeater.js +277 -0
  32. package/dist/controls/richtext.js +494 -0
  33. package/dist/controls/select.js +144 -0
  34. package/dist/controls/size.js +59 -0
  35. package/dist/controls/spacing.js +172 -0
  36. package/dist/controls/taxonomy.js +569 -0
  37. package/dist/controls/text.js +16 -0
  38. package/dist/controls/textarea.js +17 -0
  39. package/dist/controls/toggle-group.js +28 -0
  40. package/dist/controls/toggle.js +15 -0
  41. package/dist/controls/url.js +235 -0
  42. package/dist/controls/user.js +383 -0
  43. package/{src → dist}/controls/wysiwyg.js +1 -1
  44. package/{src → dist}/hooks/useTokens.js +25 -21
  45. package/{src → dist}/index.js +2 -8
  46. package/dist/inspector.js +163 -0
  47. package/{src → dist}/provider.js +18 -17
  48. package/dist/utils/map-utils.js +54 -0
  49. package/dist/utils/token-helper.js +396 -0
  50. package/{src → dist}/validation-context.js +4 -4
  51. package/package.json +20 -13
  52. package/src/conditional-logic.js +0 -77
  53. package/src/controls/MediaPicker.js +0 -139
  54. package/src/controls/MediaTriggerBadges.js +0 -31
  55. package/src/controls/SortableItem.js +0 -110
  56. package/src/controls/button-group.js +0 -49
  57. package/src/controls/checkbox-group.js +0 -55
  58. package/src/controls/checkbox.js +0 -13
  59. package/src/controls/code.js +0 -21
  60. package/src/controls/color.js +0 -235
  61. package/src/controls/date.js +0 -37
  62. package/src/controls/datetime.js +0 -54
  63. package/src/controls/email.js +0 -15
  64. package/src/controls/file.js +0 -134
  65. package/src/controls/gallery.js +0 -338
  66. package/src/controls/google-map.js +0 -117
  67. package/src/controls/heading-level.js +0 -99
  68. package/src/controls/icon.js +0 -301
  69. package/src/controls/image.js +0 -334
  70. package/src/controls/index.js +0 -95
  71. package/src/controls/message.js +0 -56
  72. package/src/controls/number.js +0 -17
  73. package/src/controls/oembed.js +0 -32
  74. package/src/controls/post-object.js +0 -788
  75. package/src/controls/radio.js +0 -18
  76. package/src/controls/range.js +0 -110
  77. package/src/controls/repeater.js +0 -290
  78. package/src/controls/richtext.js +0 -505
  79. package/src/controls/select.js +0 -141
  80. package/src/controls/size.js +0 -49
  81. package/src/controls/spacing.js +0 -141
  82. package/src/controls/taxonomy.js +0 -488
  83. package/src/controls/text.js +0 -14
  84. package/src/controls/textarea.js +0 -15
  85. package/src/controls/toggle-group.js +0 -34
  86. package/src/controls/toggle.js +0 -13
  87. package/src/controls/url.js +0 -164
  88. package/src/controls/user.js +0 -343
  89. package/src/inspector.js +0 -174
  90. package/src/utils/map-utils.js +0 -51
  91. package/src/utils/token-helper.js +0 -243
@@ -0,0 +1,172 @@
1
+ /**
2
+ * SpacingField — preset spacing (None / S / M / L) with a custom-value escape hatch.
3
+ *
4
+ * Stored value is either one of the preset keys (`'small'`, etc.) or a CSS
5
+ * length string (e.g. `'2rem'`). When set to a custom value, the toggle group
6
+ * is disabled and a "custom value applied" hint shows.
7
+ */
8
+
9
+ import { __ } from '@wordpress/i18n';
10
+ import { Button, TextControl, Notice } from '@wordpress/components';
11
+ import { useState } from '@wordpress/element';
12
+ import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalHStack as HStack } from '@wordpress/components';
13
+ import { useTokens, getTokensByGroup } from '../hooks/useTokens';
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ const DEFAULT_PRESETS = [{
16
+ label: 'None',
17
+ value: 'none'
18
+ }, {
19
+ label: 'S',
20
+ value: 'small'
21
+ }, {
22
+ label: 'M',
23
+ value: 'medium'
24
+ }, {
25
+ label: 'L',
26
+ value: 'large'
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
+ }
50
+ function isValidCSSValue(input) {
51
+ if (!input) return true;
52
+ return /^(\d*\.?\d+)(px|rem|em|%|vw|vh|vmin|vmax)?$/.test(String(input).trim());
53
+ }
54
+ export default function SpacingField({
55
+ control,
56
+ value,
57
+ onChange
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
+
69
+ // Decide if value is a preset or a custom string.
70
+ const isCustom = typeof value === 'string' && value !== '' && !presetKeys.has(value);
71
+ const presetValue = isCustom ? firstPreset : value || firstPreset;
72
+ const [showCustom, setShowCustom] = useState(isCustom);
73
+ const [customInput, setCustomInput] = useState(isCustom ? value : '');
74
+ const [error, setError] = useState(null);
75
+ const handlePreset = next => {
76
+ setShowCustom(false);
77
+ setCustomInput('');
78
+ setError(null);
79
+ onChange(next);
80
+ };
81
+ const handleCustom = next => {
82
+ setCustomInput(next);
83
+ if (next && !isValidCSSValue(next)) {
84
+ setError(__('Invalid spacing value. Use a number with a unit (e.g. 2rem, 20px).', 'gcblite'));
85
+ return;
86
+ }
87
+ setError(null);
88
+ onChange(next || firstPreset);
89
+ };
90
+ const handleReset = () => {
91
+ setShowCustom(false);
92
+ setCustomInput('');
93
+ setError(null);
94
+ onChange(firstPreset);
95
+ };
96
+ const displayHint = showCustom ? 'Custom' : presetValue.charAt(0).toUpperCase() + presetValue.slice(1);
97
+ return /*#__PURE__*/_jsx("div", {
98
+ className: `gcb-spacing-field components-base-control ${control.className || ''}`.trim(),
99
+ children: /*#__PURE__*/_jsxs("div", {
100
+ className: "components-base-control__field",
101
+ children: [/*#__PURE__*/_jsxs(HStack, {
102
+ children: [/*#__PURE__*/_jsxs("span", {
103
+ className: "components-base-control__label",
104
+ children: [control.label, /*#__PURE__*/_jsx("span", {
105
+ className: "components-font-size-picker__header__hint",
106
+ children: displayHint
107
+ })]
108
+ }), /*#__PURE__*/_jsx(Button, {
109
+ size: "small",
110
+ label: __('Set custom spacing', 'gcblite'),
111
+ onClick: () => setShowCustom(true),
112
+ isPressed: showCustom,
113
+ icon: /*#__PURE__*/_jsxs("svg", {
114
+ xmlns: "http://www.w3.org/2000/svg",
115
+ viewBox: "0 0 24 24",
116
+ width: "24",
117
+ height: "24",
118
+ "aria-hidden": true,
119
+ focusable: "false",
120
+ children: [/*#__PURE__*/_jsx("path", {
121
+ d: "m19 7.5h-7.628c-.3089-.87389-1.1423-1.5-2.122-1.5-.97966 0-1.81309.62611-2.12197 1.5h-2.12803v1.5h2.12803c.30888.87389 1.14231 1.5 2.12197 1.5.9797 0 1.8131-.62611 2.122-1.5h7.628z"
122
+ }), /*#__PURE__*/_jsx("path", {
123
+ d: "m19 15h-2.128c-.3089-.8739-1.1423-1.5-2.122-1.5s-1.8131.6261-2.122 1.5h-7.628v1.5h7.628c.3089.8739 1.1423 1.5 2.122 1.5s1.8131-.6261 2.122-1.5h2.128z"
124
+ })]
125
+ })
126
+ })]
127
+ }), error && /*#__PURE__*/_jsx(Notice, {
128
+ status: "warning",
129
+ isDismissible: true,
130
+ onRemove: () => setError(null),
131
+ children: error
132
+ }), showCustom && /*#__PURE__*/_jsxs("div", {
133
+ style: {
134
+ marginBottom: 16,
135
+ fontSize: 13
136
+ },
137
+ children: [/*#__PURE__*/_jsx("span", {
138
+ children: __('Custom value applied', 'gcblite')
139
+ }), /*#__PURE__*/_jsx(Button, {
140
+ variant: "link",
141
+ onClick: handleReset,
142
+ style: {
143
+ marginLeft: 8,
144
+ fontSize: 13
145
+ },
146
+ children: __('Reset', 'gcblite')
147
+ })]
148
+ }), /*#__PURE__*/_jsx(ToggleGroupControl, {
149
+ label: control.label,
150
+ value: presetValue,
151
+ onChange: handlePreset,
152
+ isBlock: true,
153
+ hideLabelFromVision: true,
154
+ disabled: showCustom,
155
+ className: showCustom ? 'is-disabled' : '',
156
+ __nextHasNoMarginBottom: true,
157
+ __next40pxDefaultSize: true,
158
+ children: presets.map(preset => /*#__PURE__*/_jsx(ToggleGroupControlOption, {
159
+ value: preset.value,
160
+ label: preset.label
161
+ }, preset.value))
162
+ }), showCustom && /*#__PURE__*/_jsx(TextControl, {
163
+ label: __('Custom Spacing', 'gcblite'),
164
+ value: customInput,
165
+ onChange: handleCustom,
166
+ placeholder: "e.g. 2rem or 20px",
167
+ help: __('Enter a value with unit (e.g. 2rem, 20px, 5%) or leave empty for 0.', 'gcblite'),
168
+ __nextHasNoMarginBottom: true
169
+ })]
170
+ })
171
+ });
172
+ }