-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
index.js
160 lines (154 loc) · 5.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
* WordPress dependencies
*/
import { _x, __ } from '@wordpress/i18n';
import { dateI18n } from '@wordpress/date';
import { useState, createInterpolateElement } from '@wordpress/element';
import {
TextControl,
ExternalLink,
VisuallyHidden,
CustomSelectControl,
BaseControl,
ToggleControl,
} from '@wordpress/components';
// So that we can illustrate the different formats in the dropdown properly,
// show a date that has a day greater than 12 and a month with more than three
// letters. Here we're using 2022-01-25 which is when WordPress 5.9 was
// released.
const EXAMPLE_DATE = new Date( 2022, 0, 25 );
/**
* The `DateFormatPicker` component renders controls that let the user choose a
* _date format_. That is, how they want their dates to be formatted.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/date-format-picker/README.md
*
* @param {Object} props
* @param {string|null} props.format The selected date
* format. If
* `null`,
* _Default_ is
* selected.
* @param {string} props.defaultFormat The date format that
* will be used if the
* user selects
* 'Default'.
* @param {( format: string|null ) => void} props.onChange Called when a
* selection is
* made. If `null`,
* _Default_ is
* selected.
*/
export default function DateFormatPicker( {
format,
defaultFormat,
onChange,
} ) {
return (
<fieldset className="block-editor-date-format-picker">
<VisuallyHidden as="legend">{ __( 'Date format' ) }</VisuallyHidden>
<ToggleControl
label={
<>
{ __( 'Default format' ) }
<span className="block-editor-date-format-picker__default-format-toggle-control__hint">
{ dateI18n( defaultFormat, EXAMPLE_DATE ) }
</span>
</>
}
checked={ ! format }
onChange={ ( checked ) =>
onChange( checked ? null : defaultFormat )
}
/>
{ format && (
<NonDefaultControls format={ format } onChange={ onChange } />
) }
</fieldset>
);
}
function NonDefaultControls( { format, onChange } ) {
// Suggest a short format, medium format, long format, and a standardised
// (YYYY-MM-DD) format. The short, medium, and long formats are localised as
// different languages have different ways of writing these. For example, 'F
// j, Y' (April 20, 2022) in American English (en_US) is 'j. F Y' (20. April
// 2022) in German (de). The resultant array is de-duplicated as some
// languages will use the same format string for short, medium, and long
// formats.
const suggestedFormats = [
...new Set( [
'Y-m-d',
_x( 'n/j/Y', 'short date format' ),
_x( 'n/j/Y g:i A', 'short date format with time' ),
_x( 'M j, Y', 'medium date format' ),
_x( 'M j, Y g:i A', 'medium date format with time' ),
_x( 'F j, Y', 'long date format' ),
_x( 'M j', 'short date format without the year' ),
] ),
];
const suggestedOptions = suggestedFormats.map(
( suggestedFormat, index ) => ( {
key: `suggested-${ index }`,
name: dateI18n( suggestedFormat, EXAMPLE_DATE ),
format: suggestedFormat,
} )
);
const customOption = {
key: 'custom',
name: __( 'Custom' ),
className:
'block-editor-date-format-picker__custom-format-select-control__custom-option',
__experimentalHint: __( 'Enter your own date format' ),
};
const [ isCustom, setIsCustom ] = useState(
() => !! format && ! suggestedFormats.includes( format )
);
return (
<>
<BaseControl className="block-editor-date-format-picker__custom-format-select-control">
<CustomSelectControl
__nextUnconstrainedWidth
label={ __( 'Choose a format' ) }
options={ [ ...suggestedOptions, customOption ] }
value={
isCustom
? customOption
: suggestedOptions.find(
( option ) => option.format === format
) ?? customOption
}
onChange={ ( { selectedItem } ) => {
if ( selectedItem === customOption ) {
setIsCustom( true );
} else {
setIsCustom( false );
onChange( selectedItem.format );
}
} }
/>
</BaseControl>
{ isCustom && (
<TextControl
label={ __( 'Custom format' ) }
hideLabelFromVision
help={ createInterpolateElement(
__(
'Enter a date or time <Link>format string</Link>.'
),
{
Link: (
<ExternalLink
href={ __(
'https://wordpress.org/support/article/formatting-date-and-time/'
) }
/>
),
}
) }
value={ format }
onChange={ ( value ) => onChange( value ) }
/>
) }
</>
);
}