@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.
- package/dist/conditional-logic.js +83 -0
- package/{src → dist}/control-context.js +3 -2
- package/{src → dist}/controls/MediaCapabilityGate.js +12 -8
- package/dist/controls/MediaPicker.js +149 -0
- package/dist/controls/MediaTriggerBadges.js +35 -0
- package/{src → dist}/controls/PopoverOrModal.js +49 -43
- package/dist/controls/SortableItem.js +126 -0
- package/dist/controls/button-group.js +46 -0
- package/dist/controls/checkbox-group.js +65 -0
- package/dist/controls/checkbox.js +15 -0
- package/dist/controls/code.js +24 -0
- package/dist/controls/color.js +249 -0
- package/dist/controls/date.js +55 -0
- package/dist/controls/datetime.js +61 -0
- package/dist/controls/email.js +17 -0
- package/dist/controls/file.js +163 -0
- package/dist/controls/gallery.js +371 -0
- package/dist/controls/google-map.js +143 -0
- package/dist/controls/heading-level.js +93 -0
- package/dist/controls/icon.js +292 -0
- package/dist/controls/image.js +360 -0
- package/dist/controls/index.js +88 -0
- package/dist/controls/message.js +86 -0
- package/dist/controls/number.js +19 -0
- package/dist/controls/oembed.js +42 -0
- package/{src → dist}/controls/page-link.js +1 -2
- package/dist/controls/post-object.js +913 -0
- package/dist/controls/radio.js +19 -0
- package/dist/controls/range.js +108 -0
- package/{src → dist}/controls/relationship.js +12 -7
- package/dist/controls/repeater.js +277 -0
- package/dist/controls/richtext.js +494 -0
- package/dist/controls/select.js +144 -0
- package/dist/controls/size.js +59 -0
- package/dist/controls/spacing.js +172 -0
- package/dist/controls/taxonomy.js +569 -0
- package/dist/controls/text.js +16 -0
- package/dist/controls/textarea.js +17 -0
- package/dist/controls/toggle-group.js +28 -0
- package/dist/controls/toggle.js +15 -0
- package/dist/controls/url.js +235 -0
- package/dist/controls/user.js +383 -0
- package/{src → dist}/controls/wysiwyg.js +1 -1
- package/{src → dist}/hooks/useTokens.js +25 -21
- package/{src → dist}/index.js +2 -8
- package/dist/inspector.js +163 -0
- package/{src → dist}/provider.js +18 -17
- package/dist/utils/map-utils.js +54 -0
- package/dist/utils/token-helper.js +396 -0
- package/{src → dist}/validation-context.js +4 -4
- package/package.json +20 -13
- package/src/conditional-logic.js +0 -77
- package/src/controls/MediaPicker.js +0 -139
- package/src/controls/MediaTriggerBadges.js +0 -31
- package/src/controls/SortableItem.js +0 -110
- package/src/controls/button-group.js +0 -49
- package/src/controls/checkbox-group.js +0 -55
- package/src/controls/checkbox.js +0 -13
- package/src/controls/code.js +0 -21
- package/src/controls/color.js +0 -235
- package/src/controls/date.js +0 -37
- package/src/controls/datetime.js +0 -54
- package/src/controls/email.js +0 -15
- package/src/controls/file.js +0 -134
- package/src/controls/gallery.js +0 -338
- package/src/controls/google-map.js +0 -117
- package/src/controls/heading-level.js +0 -99
- package/src/controls/icon.js +0 -301
- package/src/controls/image.js +0 -334
- package/src/controls/index.js +0 -95
- package/src/controls/message.js +0 -56
- package/src/controls/number.js +0 -17
- package/src/controls/oembed.js +0 -32
- package/src/controls/post-object.js +0 -788
- package/src/controls/radio.js +0 -18
- package/src/controls/range.js +0 -110
- package/src/controls/repeater.js +0 -290
- package/src/controls/richtext.js +0 -505
- package/src/controls/select.js +0 -141
- package/src/controls/size.js +0 -49
- package/src/controls/spacing.js +0 -141
- package/src/controls/taxonomy.js +0 -488
- package/src/controls/text.js +0 -14
- package/src/controls/textarea.js +0 -15
- package/src/controls/toggle-group.js +0 -34
- package/src/controls/toggle.js +0 -13
- package/src/controls/url.js +0 -164
- package/src/controls/user.js +0 -343
- package/src/inspector.js +0 -174
- package/src/utils/map-utils.js +0 -51
- package/src/utils/token-helper.js +0 -243
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ColorField — ported verbatim from the original GCB.
|
|
3
|
+
* Tabbed color/gradient picker that uses theme.json palettes via useSetting.
|
|
4
|
+
*
|
|
5
|
+
* Control config can opt out of gradients with `showGradients: false`.
|
|
6
|
+
* For dual-attribute mode (separate color + gradient attrs), set
|
|
7
|
+
* `gradientAttributeKey` on the control config.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
11
|
+
import { BaseControl, Button, ColorPalette, GradientPicker, TabPanel, __experimentalHStack as HStack } from '@wordpress/components';
|
|
12
|
+
import { useSetting } from '@wordpress/block-editor';
|
|
13
|
+
import PopoverOrModal from './PopoverOrModal';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The popover contents — palette + (optional) gradient tab.
|
|
17
|
+
*/
|
|
18
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
function ColorPanel({
|
|
20
|
+
colorValue,
|
|
21
|
+
gradientValue,
|
|
22
|
+
onColorChange,
|
|
23
|
+
onGradientChange,
|
|
24
|
+
colors,
|
|
25
|
+
gradients,
|
|
26
|
+
enableAlpha,
|
|
27
|
+
disableCustomColors,
|
|
28
|
+
disableCustomGradients,
|
|
29
|
+
showGradients
|
|
30
|
+
}) {
|
|
31
|
+
const palette = /*#__PURE__*/_jsxs(_Fragment, {
|
|
32
|
+
children: [/*#__PURE__*/_jsx(ColorPalette, {
|
|
33
|
+
colors: colors,
|
|
34
|
+
value: colorValue,
|
|
35
|
+
onChange: onColorChange,
|
|
36
|
+
clearable: true,
|
|
37
|
+
disableCustomColors: disableCustomColors,
|
|
38
|
+
enableAlpha: enableAlpha
|
|
39
|
+
}), colorValue && /*#__PURE__*/_jsx(Button, {
|
|
40
|
+
variant: "secondary",
|
|
41
|
+
onClick: () => onColorChange(''),
|
|
42
|
+
style: {
|
|
43
|
+
marginTop: 10
|
|
44
|
+
},
|
|
45
|
+
children: __('Reset Color', 'gcblite')
|
|
46
|
+
})]
|
|
47
|
+
});
|
|
48
|
+
if (!showGradients) {
|
|
49
|
+
return /*#__PURE__*/_jsx("div", {
|
|
50
|
+
style: {
|
|
51
|
+
minWidth: 260,
|
|
52
|
+
padding: 12
|
|
53
|
+
},
|
|
54
|
+
children: palette
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return /*#__PURE__*/_jsx("div", {
|
|
58
|
+
style: {
|
|
59
|
+
minWidth: 260,
|
|
60
|
+
padding: 12
|
|
61
|
+
},
|
|
62
|
+
children: /*#__PURE__*/_jsx(TabPanel, {
|
|
63
|
+
className: "gcb-color-field-tabs",
|
|
64
|
+
activeClass: "is-active",
|
|
65
|
+
tabs: [{
|
|
66
|
+
name: 'color',
|
|
67
|
+
title: __('Color', 'gcblite'),
|
|
68
|
+
className: 'tab-color'
|
|
69
|
+
}, {
|
|
70
|
+
name: 'gradient',
|
|
71
|
+
title: __('Gradient', 'gcblite'),
|
|
72
|
+
className: 'tab-gradient'
|
|
73
|
+
}],
|
|
74
|
+
children: tab => /*#__PURE__*/_jsxs(_Fragment, {
|
|
75
|
+
children: [tab.name === 'color' && palette, tab.name === 'gradient' && /*#__PURE__*/_jsxs(_Fragment, {
|
|
76
|
+
children: [/*#__PURE__*/_jsx(GradientPicker, {
|
|
77
|
+
value: gradientValue || undefined,
|
|
78
|
+
onChange: next => onGradientChange(next || ''),
|
|
79
|
+
gradients: gradients || [],
|
|
80
|
+
clearable: true,
|
|
81
|
+
disableCustomGradients: disableCustomGradients,
|
|
82
|
+
__experimentalIsRenderedInSidebar: true
|
|
83
|
+
}), gradientValue && /*#__PURE__*/_jsx(Button, {
|
|
84
|
+
variant: "secondary",
|
|
85
|
+
onClick: () => onGradientChange(''),
|
|
86
|
+
style: {
|
|
87
|
+
marginTop: 10
|
|
88
|
+
},
|
|
89
|
+
children: __('Reset Gradient', 'gcblite')
|
|
90
|
+
})]
|
|
91
|
+
})]
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The trigger swatch — large white tile with a colour swatch on the left,
|
|
99
|
+
* the resolved value (or label) on the right. Same "popout" pattern as the
|
|
100
|
+
* image / post-object controls.
|
|
101
|
+
*/
|
|
102
|
+
function ColorTrigger({
|
|
103
|
+
label,
|
|
104
|
+
colorValue,
|
|
105
|
+
gradientValue,
|
|
106
|
+
onToggle,
|
|
107
|
+
isOpen
|
|
108
|
+
}) {
|
|
109
|
+
const hasValue = !!(colorValue || gradientValue);
|
|
110
|
+
const swatchBackground = gradientValue || colorValue || 'transparent';
|
|
111
|
+
const isCheckered = !hasValue;
|
|
112
|
+
return /*#__PURE__*/_jsx(Button, {
|
|
113
|
+
onClick: onToggle,
|
|
114
|
+
"aria-expanded": isOpen,
|
|
115
|
+
"aria-label": label,
|
|
116
|
+
className: "gcb-modal-toggle-button gcb-color-trigger",
|
|
117
|
+
children: /*#__PURE__*/_jsxs(HStack, {
|
|
118
|
+
spacing: 3,
|
|
119
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
120
|
+
"aria-hidden": true,
|
|
121
|
+
className: isCheckered ? 'gcb-color-trigger__swatch is-empty' : 'gcb-color-trigger__swatch',
|
|
122
|
+
style: {
|
|
123
|
+
width: 24,
|
|
124
|
+
height: 24,
|
|
125
|
+
borderRadius: '100%',
|
|
126
|
+
background: swatchBackground,
|
|
127
|
+
flexShrink: 0,
|
|
128
|
+
border: '1px solid #ddd',
|
|
129
|
+
display: 'inline-block'
|
|
130
|
+
}
|
|
131
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
132
|
+
style: {
|
|
133
|
+
flex: 1,
|
|
134
|
+
textAlign: 'left',
|
|
135
|
+
fontSize: 13,
|
|
136
|
+
color: '#1e1e1e',
|
|
137
|
+
overflow: 'hidden',
|
|
138
|
+
textOverflow: 'ellipsis',
|
|
139
|
+
whiteSpace: 'nowrap'
|
|
140
|
+
},
|
|
141
|
+
children: hasValue ? gradientValue ? __('Gradient', 'gcblite') : colorValue : __('Select a color', 'gcblite')
|
|
142
|
+
})]
|
|
143
|
+
})
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function ColorFieldImpl({
|
|
147
|
+
label = __('Color', 'gcblite'),
|
|
148
|
+
colorValue,
|
|
149
|
+
gradientValue,
|
|
150
|
+
onColorChange,
|
|
151
|
+
onGradientChange,
|
|
152
|
+
colors,
|
|
153
|
+
gradients,
|
|
154
|
+
enableAlpha = true,
|
|
155
|
+
disableCustomColors = false,
|
|
156
|
+
disableCustomGradients = false,
|
|
157
|
+
showGradients = true,
|
|
158
|
+
className = '',
|
|
159
|
+
help,
|
|
160
|
+
tokenKeys
|
|
161
|
+
}) {
|
|
162
|
+
const themeColors = useSetting('color.palette');
|
|
163
|
+
const themeGradients = useSetting('color.gradients');
|
|
164
|
+
|
|
165
|
+
// Always end up with arrays — `useSetting('color.gradients')` returns
|
|
166
|
+
// undefined on themes that don't declare any gradients, and feeding that
|
|
167
|
+
// to <GradientPicker> crashes on `.orientation`.
|
|
168
|
+
let finalColors = colors && colors.length ? colors : themeColors || [];
|
|
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
|
+
}
|
|
176
|
+
return /*#__PURE__*/_jsx(BaseControl, {
|
|
177
|
+
label: label,
|
|
178
|
+
help: help,
|
|
179
|
+
className: `gcb-color-control components-base-control ${className}`.trim(),
|
|
180
|
+
__nextHasNoMarginBottom: true,
|
|
181
|
+
children: /*#__PURE__*/_jsx(PopoverOrModal, {
|
|
182
|
+
modalTitle: label,
|
|
183
|
+
dropdownProps: {
|
|
184
|
+
popoverProps: {
|
|
185
|
+
placement: 'left-start'
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
renderToggle: ({
|
|
189
|
+
isOpen,
|
|
190
|
+
onToggle
|
|
191
|
+
}) => /*#__PURE__*/_jsx(ColorTrigger, {
|
|
192
|
+
label: label,
|
|
193
|
+
colorValue: colorValue,
|
|
194
|
+
gradientValue: gradientValue,
|
|
195
|
+
onToggle: onToggle,
|
|
196
|
+
isOpen: isOpen
|
|
197
|
+
}),
|
|
198
|
+
renderContent: () => /*#__PURE__*/_jsx(ColorPanel, {
|
|
199
|
+
colorValue: colorValue,
|
|
200
|
+
gradientValue: gradientValue,
|
|
201
|
+
onColorChange: onColorChange,
|
|
202
|
+
onGradientChange: onGradientChange,
|
|
203
|
+
colors: finalColors,
|
|
204
|
+
gradients: finalGradients,
|
|
205
|
+
enableAlpha: enableAlpha,
|
|
206
|
+
disableCustomColors: disableCustomColors,
|
|
207
|
+
disableCustomGradients: disableCustomGradients,
|
|
208
|
+
showGradients: showGradients
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Adapter for the registry contract.
|
|
216
|
+
*
|
|
217
|
+
* The control stores a single string value — either a colour (e.g. `#ff0000`,
|
|
218
|
+
* `var(--wp--preset--color--primary)`) or a gradient (e.g. `linear-gradient(...)`).
|
|
219
|
+
* When the user picks one, the other is cleared. This matches the WP attribute
|
|
220
|
+
* type `string` that the loader generates for `color` controls.
|
|
221
|
+
*
|
|
222
|
+
* For separate color + gradient attributes on the same block, declare two
|
|
223
|
+
* controls (one with `showGradients: false`, one purely gradient — coming in v0.2).
|
|
224
|
+
*/
|
|
225
|
+
export default function ColorField({
|
|
226
|
+
control,
|
|
227
|
+
value,
|
|
228
|
+
onChange
|
|
229
|
+
}) {
|
|
230
|
+
const stringValue = typeof value === 'string' ? value : '';
|
|
231
|
+
const isGradient = stringValue.includes('gradient(');
|
|
232
|
+
const colorValue = isGradient ? '' : stringValue;
|
|
233
|
+
const gradientValue = isGradient ? stringValue : '';
|
|
234
|
+
const handleColor = next => onChange(next || '');
|
|
235
|
+
const handleGradient = next => onChange(next || '');
|
|
236
|
+
return /*#__PURE__*/_jsx(ColorFieldImpl, {
|
|
237
|
+
label: control.label,
|
|
238
|
+
help: control.helpText,
|
|
239
|
+
colorValue: colorValue,
|
|
240
|
+
gradientValue: gradientValue,
|
|
241
|
+
onColorChange: handleColor,
|
|
242
|
+
onGradientChange: handleGradient,
|
|
243
|
+
showGradients: control.showGradients !== false,
|
|
244
|
+
enableAlpha: control.enableAlpha !== false,
|
|
245
|
+
disableCustomColors: control.disableCustomColors === true,
|
|
246
|
+
disableCustomGradients: control.disableCustomGradients === true,
|
|
247
|
+
tokenKeys: control.tokenKeys
|
|
248
|
+
});
|
|
249
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { BaseControl, Button, DatePicker } from '@wordpress/components';
|
|
2
|
+
import { __ } from '@wordpress/i18n';
|
|
3
|
+
import PopoverOrModal from './PopoverOrModal';
|
|
4
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
export default function DateField({
|
|
6
|
+
control,
|
|
7
|
+
value,
|
|
8
|
+
onChange
|
|
9
|
+
}) {
|
|
10
|
+
return /*#__PURE__*/_jsx(BaseControl, {
|
|
11
|
+
label: control.label,
|
|
12
|
+
help: control.helpText,
|
|
13
|
+
__nextHasNoMarginBottom: true,
|
|
14
|
+
children: /*#__PURE__*/_jsx(PopoverOrModal, {
|
|
15
|
+
modalTitle: control.label || __('Pick a date', 'gcblite'),
|
|
16
|
+
dropdownProps: {
|
|
17
|
+
popoverProps: {
|
|
18
|
+
placement: 'bottom-start'
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
renderToggle: ({
|
|
22
|
+
onToggle
|
|
23
|
+
}) => /*#__PURE__*/_jsxs(_Fragment, {
|
|
24
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
25
|
+
variant: "secondary",
|
|
26
|
+
onClick: onToggle,
|
|
27
|
+
children: value ? new Date(value).toLocaleDateString() : __('Pick a date', 'gcblite')
|
|
28
|
+
}), value && /*#__PURE__*/_jsx(Button, {
|
|
29
|
+
variant: "tertiary",
|
|
30
|
+
size: "small",
|
|
31
|
+
isDestructive: true,
|
|
32
|
+
onClick: () => onChange(''),
|
|
33
|
+
style: {
|
|
34
|
+
marginLeft: 8
|
|
35
|
+
},
|
|
36
|
+
children: __('Clear', 'gcblite')
|
|
37
|
+
})]
|
|
38
|
+
}),
|
|
39
|
+
renderContent: ({
|
|
40
|
+
close
|
|
41
|
+
}) => /*#__PURE__*/_jsx("div", {
|
|
42
|
+
style: {
|
|
43
|
+
padding: 8
|
|
44
|
+
},
|
|
45
|
+
children: /*#__PURE__*/_jsx(DatePicker, {
|
|
46
|
+
currentDate: value || undefined,
|
|
47
|
+
onChange: next => {
|
|
48
|
+
onChange(next || '');
|
|
49
|
+
close();
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DateTime — like Date, but with a time picker too. Stores an ISO 8601
|
|
3
|
+
* timestamp string (e.g. "2026-05-25T14:30:00").
|
|
4
|
+
*
|
|
5
|
+
* Uses WP's DateTimePicker rather than DatePicker so the panel shows hours
|
|
6
|
+
* and minutes alongside the calendar. Renders inside PopoverOrModal so it
|
|
7
|
+
* behaves correctly in both sidebar (popover) and metabox (modal) contexts.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { BaseControl, Button, DateTimePicker } from '@wordpress/components';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import PopoverOrModal from './PopoverOrModal';
|
|
13
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
export default function DatetimeField({
|
|
15
|
+
control,
|
|
16
|
+
value,
|
|
17
|
+
onChange
|
|
18
|
+
}) {
|
|
19
|
+
const displayLabel = value ? new Date(value).toLocaleString() : __('Pick a date and time', 'gcblite');
|
|
20
|
+
return /*#__PURE__*/_jsx(BaseControl, {
|
|
21
|
+
label: control.label,
|
|
22
|
+
help: control.helpText,
|
|
23
|
+
__nextHasNoMarginBottom: true,
|
|
24
|
+
children: /*#__PURE__*/_jsx(PopoverOrModal, {
|
|
25
|
+
modalTitle: control.label || __('Pick a date and time', 'gcblite'),
|
|
26
|
+
dropdownProps: {
|
|
27
|
+
popoverProps: {
|
|
28
|
+
placement: 'bottom-start'
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
renderToggle: ({
|
|
32
|
+
onToggle
|
|
33
|
+
}) => /*#__PURE__*/_jsxs(_Fragment, {
|
|
34
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
35
|
+
variant: "secondary",
|
|
36
|
+
onClick: onToggle,
|
|
37
|
+
children: displayLabel
|
|
38
|
+
}), value && /*#__PURE__*/_jsx(Button, {
|
|
39
|
+
variant: "tertiary",
|
|
40
|
+
size: "small",
|
|
41
|
+
isDestructive: true,
|
|
42
|
+
onClick: () => onChange(''),
|
|
43
|
+
style: {
|
|
44
|
+
marginLeft: 8
|
|
45
|
+
},
|
|
46
|
+
children: __('Clear', 'gcblite')
|
|
47
|
+
})]
|
|
48
|
+
}),
|
|
49
|
+
renderContent: () => /*#__PURE__*/_jsx("div", {
|
|
50
|
+
style: {
|
|
51
|
+
padding: 8
|
|
52
|
+
},
|
|
53
|
+
children: /*#__PURE__*/_jsx(DateTimePicker, {
|
|
54
|
+
currentDate: value || undefined,
|
|
55
|
+
onChange: next => onChange(next || ''),
|
|
56
|
+
is12Hour: true
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TextControl } from '@wordpress/components';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
export default function EmailField({
|
|
4
|
+
control,
|
|
5
|
+
value,
|
|
6
|
+
onChange
|
|
7
|
+
}) {
|
|
8
|
+
return /*#__PURE__*/_jsx(TextControl, {
|
|
9
|
+
label: control.label,
|
|
10
|
+
help: control.helpText,
|
|
11
|
+
placeholder: control.placeholder ?? 'name@example.com',
|
|
12
|
+
type: "email",
|
|
13
|
+
value: value ?? '',
|
|
14
|
+
onChange: onChange,
|
|
15
|
+
__nextHasNoMarginBottom: true
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileField — non-image attachment picker. Stores `{ id, url, filename, title }`.
|
|
3
|
+
*
|
|
4
|
+
* The trigger button mirrors the image control's "popout" tile (file icon +
|
|
5
|
+
* filename + chevron) so the Inspector feels consistent.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
import { Button, __experimentalHStack as HStack, __experimentalTruncate as Truncate } from '@wordpress/components';
|
|
10
|
+
import MediaPicker from './MediaPicker';
|
|
11
|
+
import PopoverOrModal from './PopoverOrModal';
|
|
12
|
+
import MediaCapabilityGate from './MediaCapabilityGate';
|
|
13
|
+
import MediaTriggerBadges from './MediaTriggerBadges';
|
|
14
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
const TOGGLE_BUTTON_STYLE = {
|
|
16
|
+
width: '100%',
|
|
17
|
+
height: 'auto',
|
|
18
|
+
padding: '12px',
|
|
19
|
+
justifyContent: 'flex-start',
|
|
20
|
+
border: '1px solid #ddd',
|
|
21
|
+
borderRadius: '2px',
|
|
22
|
+
backgroundColor: '#fff'
|
|
23
|
+
};
|
|
24
|
+
function FileIcon() {
|
|
25
|
+
return /*#__PURE__*/_jsx("svg", {
|
|
26
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
27
|
+
viewBox: "0 0 24 24",
|
|
28
|
+
width: "20",
|
|
29
|
+
height: "20",
|
|
30
|
+
style: {
|
|
31
|
+
flexShrink: 0,
|
|
32
|
+
fill: '#1e1e1e'
|
|
33
|
+
},
|
|
34
|
+
"aria-hidden": true,
|
|
35
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
36
|
+
d: "M14 9V3.5L19.5 9H14zM6 2h9l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2zm0 2v16h12V11h-5V4H6z"
|
|
37
|
+
})
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export default function FileField({
|
|
41
|
+
control,
|
|
42
|
+
value,
|
|
43
|
+
onChange
|
|
44
|
+
}) {
|
|
45
|
+
const fileValue = typeof value === 'object' && value !== null ? value : {
|
|
46
|
+
id: null,
|
|
47
|
+
url: value || '',
|
|
48
|
+
filename: '',
|
|
49
|
+
title: ''
|
|
50
|
+
};
|
|
51
|
+
const hasFile = !!(fileValue.id || fileValue.url);
|
|
52
|
+
const displayTitle = fileValue.title || fileValue.filename || __('(no title)', 'gcblite');
|
|
53
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
54
|
+
className: "components-base-control gcb-file-control",
|
|
55
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
56
|
+
className: "components-base-control__field",
|
|
57
|
+
children: /*#__PURE__*/_jsx("label", {
|
|
58
|
+
className: "components-base-control__label",
|
|
59
|
+
children: control.label
|
|
60
|
+
})
|
|
61
|
+
}), control.helpText && /*#__PURE__*/_jsx("p", {
|
|
62
|
+
className: "components-base-control__help",
|
|
63
|
+
children: control.helpText
|
|
64
|
+
}), /*#__PURE__*/_jsx(MediaCapabilityGate, {
|
|
65
|
+
children: /*#__PURE__*/_jsx(MediaPicker, {
|
|
66
|
+
onSelect: media => onChange({
|
|
67
|
+
id: media.id,
|
|
68
|
+
url: media.url,
|
|
69
|
+
filename: media.filename,
|
|
70
|
+
title: media.title
|
|
71
|
+
}),
|
|
72
|
+
allowedTypes: control.allowedTypes || ['application', 'text', 'image', 'video', 'audio'],
|
|
73
|
+
value: fileValue.id,
|
|
74
|
+
render: ({
|
|
75
|
+
open
|
|
76
|
+
}) => /*#__PURE__*/_jsxs("div", {
|
|
77
|
+
children: [!hasFile && /*#__PURE__*/_jsx(Button, {
|
|
78
|
+
onClick: open,
|
|
79
|
+
variant: "secondary",
|
|
80
|
+
style: {
|
|
81
|
+
marginBottom: 8
|
|
82
|
+
},
|
|
83
|
+
children: __('Select File', 'gcblite')
|
|
84
|
+
}), hasFile && /*#__PURE__*/_jsx(PopoverOrModal, {
|
|
85
|
+
modalTitle: control.label || __('File', 'gcblite'),
|
|
86
|
+
dropdownProps: {
|
|
87
|
+
popoverProps: {
|
|
88
|
+
placement: 'left-start'
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
renderToggle: ({
|
|
92
|
+
isOpen,
|
|
93
|
+
onToggle
|
|
94
|
+
}) => /*#__PURE__*/_jsx(MediaTriggerBadges, {
|
|
95
|
+
onClear: () => onChange({
|
|
96
|
+
id: null,
|
|
97
|
+
url: '',
|
|
98
|
+
filename: '',
|
|
99
|
+
title: ''
|
|
100
|
+
}),
|
|
101
|
+
children: /*#__PURE__*/_jsx(Button, {
|
|
102
|
+
onClick: onToggle,
|
|
103
|
+
"aria-expanded": isOpen,
|
|
104
|
+
className: "gcb-modal-toggle-button gcb-file-control-toggle",
|
|
105
|
+
style: TOGGLE_BUTTON_STYLE,
|
|
106
|
+
children: /*#__PURE__*/_jsxs(HStack, {
|
|
107
|
+
spacing: 3,
|
|
108
|
+
children: [/*#__PURE__*/_jsx(FileIcon, {}), /*#__PURE__*/_jsx(Truncate, {
|
|
109
|
+
numberOfLines: 1,
|
|
110
|
+
children: displayTitle
|
|
111
|
+
})]
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
}),
|
|
115
|
+
renderContent: ({
|
|
116
|
+
close
|
|
117
|
+
}) => /*#__PURE__*/_jsxs("div", {
|
|
118
|
+
style: {
|
|
119
|
+
padding: 16,
|
|
120
|
+
minWidth: 280
|
|
121
|
+
},
|
|
122
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
123
|
+
onClick: () => {
|
|
124
|
+
close();
|
|
125
|
+
open();
|
|
126
|
+
},
|
|
127
|
+
variant: "secondary",
|
|
128
|
+
style: {
|
|
129
|
+
width: '100%',
|
|
130
|
+
marginBottom: 12
|
|
131
|
+
},
|
|
132
|
+
children: __('Replace File', 'gcblite')
|
|
133
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
134
|
+
onClick: () => {
|
|
135
|
+
onChange({
|
|
136
|
+
id: null,
|
|
137
|
+
url: '',
|
|
138
|
+
filename: '',
|
|
139
|
+
title: ''
|
|
140
|
+
});
|
|
141
|
+
close();
|
|
142
|
+
},
|
|
143
|
+
variant: "tertiary",
|
|
144
|
+
isDestructive: true,
|
|
145
|
+
style: {
|
|
146
|
+
width: '100%'
|
|
147
|
+
},
|
|
148
|
+
children: __('Remove File', 'gcblite')
|
|
149
|
+
})]
|
|
150
|
+
})
|
|
151
|
+
}), !hasFile && /*#__PURE__*/_jsx("p", {
|
|
152
|
+
style: {
|
|
153
|
+
fontSize: 13,
|
|
154
|
+
color: '#757575',
|
|
155
|
+
margin: 0
|
|
156
|
+
},
|
|
157
|
+
children: __('No file selected', 'gcblite')
|
|
158
|
+
})]
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
})]
|
|
162
|
+
});
|
|
163
|
+
}
|