|
1 | 1 | /** |
2 | 2 | * WordPress dependencies |
3 | 3 | */ |
| 4 | +import { Button } from '@wordpress/components'; |
| 5 | +import type { DataFormControlProps, Field, Form } from '@wordpress/dataviews'; |
4 | 6 | import { __ } from '@wordpress/i18n'; |
5 | | -import type { Field, Form } from '@wordpress/dataviews'; |
| 7 | +import { trash } from '@wordpress/icons'; |
| 8 | + |
| 9 | +import { Stack, Text } from '@wordpress/ui'; |
6 | 10 |
|
7 | 11 | /** |
8 | 12 | * Internal dependencies |
9 | 13 | */ |
10 | 14 | import type { StoredLabels, TaxonomyFormData } from '../types'; |
11 | | -import { STRING_LABEL_KEYS } from '../utils'; |
| 15 | +import { deriveLabels, STRING_LABEL_KEYS } from '../utils'; |
12 | 16 |
|
13 | 17 | type LabelFieldOptions = { |
14 | 18 | placeholder?: string; |
@@ -157,8 +161,95 @@ export const chooseFromMostUsedField = labelField( |
157 | 161 | } |
158 | 162 | ); |
159 | 163 |
|
| 164 | +function LabelsActionsEdit( { |
| 165 | + data, |
| 166 | + onChange, |
| 167 | +}: DataFormControlProps< TaxonomyFormData > ) { |
| 168 | + const plural = data.title.raw.trim(); |
| 169 | + const singular = data.config.labels.singular_name.trim(); |
| 170 | + const canAutoFill = !! plural.length && !! singular.length; |
| 171 | + const hasOverrides = STRING_LABEL_KEYS.some( |
| 172 | + ( key ) => |
| 173 | + key !== 'singular_name' && |
| 174 | + ( data.config.labels[ key ] ?? '' ) !== '' |
| 175 | + ); |
| 176 | + return ( |
| 177 | + <Stack direction="column" gap="md"> |
| 178 | + <Text variant="body-md" className="taxonomy-form__help-text"> |
| 179 | + { __( |
| 180 | + 'Override the text WordPress shows in admin lists, menus, and forms. Auto-fill replaces every label below with values derived from the current plural and singular names — including any you have already customized. Clearing removes all overrides so WordPress falls back to its defaults. If you rename the taxonomy after auto-filling, click Auto-fill again to keep them in sync.' |
| 181 | + ) } |
| 182 | + </Text> |
| 183 | + <Stack direction="row" justify="flex-end" gap="sm"> |
| 184 | + <Button |
| 185 | + __next40pxDefaultSize |
| 186 | + variant="secondary" |
| 187 | + size="compact" |
| 188 | + accessibleWhenDisabled |
| 189 | + disabled={ ! canAutoFill } |
| 190 | + onClick={ () => |
| 191 | + onChange( { |
| 192 | + config: { |
| 193 | + ...data.config, |
| 194 | + labels: { |
| 195 | + ...data.config.labels, |
| 196 | + ...deriveLabels( plural, singular ), |
| 197 | + }, |
| 198 | + }, |
| 199 | + } ) |
| 200 | + } |
| 201 | + > |
| 202 | + { __( 'Auto-fill labels' ) } |
| 203 | + </Button> |
| 204 | + <Button |
| 205 | + __next40pxDefaultSize |
| 206 | + size="compact" |
| 207 | + icon={ trash } |
| 208 | + isDestructive |
| 209 | + label={ __( 'Clear labels' ) } |
| 210 | + accessibleWhenDisabled |
| 211 | + disabled={ ! hasOverrides } |
| 212 | + onClick={ () => { |
| 213 | + const cleared: StoredLabels = { |
| 214 | + singular_name: data.config.labels.singular_name, |
| 215 | + }; |
| 216 | + for ( const key of STRING_LABEL_KEYS ) { |
| 217 | + if ( key !== 'singular_name' ) { |
| 218 | + cleared[ key ] = ''; |
| 219 | + } |
| 220 | + } |
| 221 | + onChange( { |
| 222 | + config: { ...data.config, labels: cleared }, |
| 223 | + } ); |
| 224 | + } } |
| 225 | + /> |
| 226 | + </Stack> |
| 227 | + </Stack> |
| 228 | + ); |
| 229 | +} |
| 230 | + |
| 231 | +// TODO: Replace this phantom field once DataForm supports per-card header |
| 232 | +// actions or arbitrary React among children. We register a no-value Field |
| 233 | +// solely to render the Labels card's description and action buttons, |
| 234 | +// suppressing its label via labelPosition: 'none'. |
| 235 | +export const labelsActionsField: Field< TaxonomyFormData > = { |
| 236 | + id: '__labels_actions', |
| 237 | + label: '', |
| 238 | + getValue: () => '', |
| 239 | + setValue: () => ( {} ), |
| 240 | + Edit: LabelsActionsEdit, |
| 241 | + enableSorting: false, |
| 242 | + filterBy: false, |
| 243 | +}; |
| 244 | + |
160 | 245 | export const labelsForm: Form = { |
161 | 246 | layout: { type: 'regular' }, |
162 | 247 | // singular_name lives in the General card, so exclude it here. |
163 | | - fields: STRING_LABEL_KEYS.filter( ( key ) => key !== 'singular_name' ), |
| 248 | + fields: [ |
| 249 | + { |
| 250 | + id: '__labels_actions', |
| 251 | + layout: { type: 'regular', labelPosition: 'none' }, |
| 252 | + }, |
| 253 | + ...STRING_LABEL_KEYS.filter( ( key ) => key !== 'singular_name' ), |
| 254 | + ], |
164 | 255 | }; |
0 commit comments