superdesk-ui-framework 4.0.1 → 4.0.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/app-typescript/components/DatePicker.tsx +8 -1
- package/app-typescript/components/DateTimePicker.tsx +101 -0
- package/app-typescript/components/Dropdown.tsx +1 -0
- package/app-typescript/components/ToggleBox/CustomHeaderToggleBox.tsx +1 -1
- package/app-typescript/components/ToggleBox/index.tsx +1 -1
- package/app-typescript/index.ts +1 -0
- package/dist/components/DateTimePicker.tsx +93 -0
- package/dist/components/Index.tsx +5 -0
- package/dist/examples.bundle.js +2790 -2572
- package/dist/superdesk-ui.bundle.js +2323 -2211
- package/dist/vendor.bundle.js +22 -22
- package/examples/pages/components/DateTimePicker.tsx +93 -0
- package/examples/pages/components/Index.tsx +5 -0
- package/package.json +1 -1
- package/react/components/DatePicker.d.ts +1 -0
- package/react/components/DatePicker.js +4 -1
- package/react/components/DateTimePicker.d.ts +20 -0
- package/react/components/DateTimePicker.js +98 -0
- package/react/components/Dropdown.js +1 -0
- package/react/components/ToggleBox/CustomHeaderToggleBox.js +1 -1
- package/react/components/ToggleBox/index.d.ts +1 -1
- package/react/index.d.ts +1 -0
- package/react/index.js +5 -3
@@ -33,6 +33,8 @@ interface IDatePickerBase extends IInputWrapper {
|
|
33
33
|
}}
|
34
34
|
*/
|
35
35
|
locale?: DatePickerLocaleSettings;
|
36
|
+
|
37
|
+
hideClearButton?: boolean;
|
36
38
|
}
|
37
39
|
|
38
40
|
interface IDatePicker extends IDatePickerBase {
|
@@ -146,6 +148,10 @@ export class DatePicker extends React.PureComponent<IDatePicker, IState> {
|
|
146
148
|
);
|
147
149
|
}
|
148
150
|
|
151
|
+
const showClearButton = this.props.required === true
|
152
|
+
? false
|
153
|
+
: this.props.hideClearButton !== true;
|
154
|
+
|
149
155
|
return (
|
150
156
|
<InputWrapper
|
151
157
|
label={this.props.label}
|
@@ -160,7 +166,8 @@ export class DatePicker extends React.PureComponent<IDatePicker, IState> {
|
|
160
166
|
tabindex={this.props.tabindex}
|
161
167
|
>
|
162
168
|
<Calendar
|
163
|
-
|
169
|
+
className='sd-input__input'
|
170
|
+
footerTemplate={showClearButton ? () => (
|
164
171
|
<div className='d-flex justify-end'>
|
165
172
|
<Button
|
166
173
|
onClick={() => {
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {DatePicker} from '../components/DatePicker';
|
3
|
+
import {Spacer} from '@superdesk/common';
|
4
|
+
import {defaultTo} from 'lodash';
|
5
|
+
import {TimePicker} from './TimePicker';
|
6
|
+
import {IconButton} from './IconButton';
|
7
|
+
|
8
|
+
interface IProps {
|
9
|
+
value: Date | null;
|
10
|
+
label: string;
|
11
|
+
dateFormat: string;
|
12
|
+
onChange: (value: string | null) => void;
|
13
|
+
preview?: boolean;
|
14
|
+
fullWidth?: boolean;
|
15
|
+
allowSeconds?: boolean;
|
16
|
+
required?: boolean;
|
17
|
+
width?: React.CSSProperties['width'];
|
18
|
+
disabled?: boolean;
|
19
|
+
}
|
20
|
+
|
21
|
+
const MIN_WIDTH = 348;
|
22
|
+
|
23
|
+
export class DateTimePicker extends React.PureComponent<IProps> {
|
24
|
+
handleTimeChange = (time: string) => {
|
25
|
+
const [hours, minutes] = time.split(':').map((x) => defaultTo(parseInt(x, 10), 0)); // handle NaN value
|
26
|
+
const origDate = this.props.value ?? new Date();
|
27
|
+
|
28
|
+
origDate.setHours(hours);
|
29
|
+
origDate.setMinutes(minutes);
|
30
|
+
|
31
|
+
this.props.onChange(origDate.toISOString());
|
32
|
+
}
|
33
|
+
|
34
|
+
handleDateChange = (date?: string) => {
|
35
|
+
if (date == null) {
|
36
|
+
this.props.onChange(null);
|
37
|
+
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
|
41
|
+
const selectedDate = new Date(date);
|
42
|
+
const origDate = this.props.value ?? new Date();
|
43
|
+
|
44
|
+
selectedDate.setHours(origDate.getHours());
|
45
|
+
selectedDate.setMinutes(origDate.getMinutes());
|
46
|
+
|
47
|
+
this.props.onChange(selectedDate.toISOString());
|
48
|
+
}
|
49
|
+
|
50
|
+
prepareFormat(unitOfTime: number) {
|
51
|
+
return unitOfTime.toString().padStart(2, '0');
|
52
|
+
}
|
53
|
+
|
54
|
+
render() {
|
55
|
+
const convertedValue = this.props.value ? new Date(this.props.value) : null;
|
56
|
+
const convertedTimeValue = convertedValue
|
57
|
+
? `${this.prepareFormat(convertedValue.getHours())}:${this.prepareFormat(convertedValue.getMinutes())}`
|
58
|
+
: '';
|
59
|
+
|
60
|
+
return (
|
61
|
+
<div style={{width: Number(this.props.width) > MIN_WIDTH ? this.props.width : MIN_WIDTH}}>
|
62
|
+
<Spacer h gap="0" noGrow alignItems='end'>
|
63
|
+
<DatePicker
|
64
|
+
disabled={this.props.disabled}
|
65
|
+
preview={this.props.preview}
|
66
|
+
required={this.props.required}
|
67
|
+
hideClearButton={true}
|
68
|
+
value={convertedValue}
|
69
|
+
onChange={(val) => {
|
70
|
+
this.handleDateChange(val?.toString());
|
71
|
+
}}
|
72
|
+
dateFormat={this.props.dateFormat}
|
73
|
+
label={this.props.label}
|
74
|
+
fullWidth={this.props.fullWidth}
|
75
|
+
/>
|
76
|
+
<TimePicker
|
77
|
+
disabled={this.props.disabled}
|
78
|
+
preview={this.props.preview}
|
79
|
+
value={convertedTimeValue}
|
80
|
+
onChange={(val) => {
|
81
|
+
this.handleTimeChange(val);
|
82
|
+
}}
|
83
|
+
allowSeconds={this.props.allowSeconds}
|
84
|
+
fullWidth={this.props.fullWidth}
|
85
|
+
required={this.props.required}
|
86
|
+
/>
|
87
|
+
{this.props.preview !== true && (
|
88
|
+
<IconButton
|
89
|
+
disabled={this.props.disabled}
|
90
|
+
icon='close-small'
|
91
|
+
onClick={() => {
|
92
|
+
this.props.onChange(null);
|
93
|
+
}}
|
94
|
+
ariaValue='Clear'
|
95
|
+
/>
|
96
|
+
)}
|
97
|
+
</Spacer>
|
98
|
+
</div>
|
99
|
+
);
|
100
|
+
}
|
101
|
+
}
|
@@ -67,7 +67,7 @@ export class CustomHeaderToggleBox extends React.PureComponent<IPropsCustomHeade
|
|
67
67
|
aria-controls={this.htmlId}
|
68
68
|
>
|
69
69
|
<span className='label label--translucent new-collapse-box__divider-label'>
|
70
|
-
{this.props.
|
70
|
+
{this.props.getToggleButtonLabel(isOpen)}
|
71
71
|
</span>
|
72
72
|
</button>
|
73
73
|
</div>
|
@@ -21,7 +21,7 @@ export interface IPropsCustomHeader {
|
|
21
21
|
variant: 'custom-header'; // always visible
|
22
22
|
header: React.ReactNode;
|
23
23
|
children: React.ReactNode;
|
24
|
-
|
24
|
+
getToggleButtonLabel: (isOpen: boolean) => string;
|
25
25
|
initiallyOpen?: boolean;
|
26
26
|
onToggle?(isOpen: boolean): void;
|
27
27
|
}
|
package/app-typescript/index.ts
CHANGED
@@ -24,6 +24,7 @@ export { Tooltip } from './components/Tooltip';
|
|
24
24
|
export { DurationInput } from './components/DurationInput';
|
25
25
|
export { getDurationString } from './components/DurationInput';
|
26
26
|
export { DatePicker } from './components/DatePicker';
|
27
|
+
export { DateTimePicker } from './components/DateTimePicker';
|
27
28
|
export { DatePickerISO } from './components/DatePicker';
|
28
29
|
export { DatePickerLocaleSettings } from './components/DatePicker';
|
29
30
|
export { TimePicker } from './components/TimePicker';
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import * as Markup from '../../js/react';
|
3
|
+
import {PropsList, Prop, DateTimePicker} from '../../../app-typescript';
|
4
|
+
|
5
|
+
class DateTimePickerExample extends React.PureComponent<{}, {dateTime: Date | null}> {
|
6
|
+
constructor(props) {
|
7
|
+
super(props);
|
8
|
+
|
9
|
+
this.state = {
|
10
|
+
dateTime: new Date(),
|
11
|
+
};
|
12
|
+
}
|
13
|
+
|
14
|
+
render() {
|
15
|
+
return (
|
16
|
+
<DateTimePicker
|
17
|
+
label='Planning datetime'
|
18
|
+
value={this.state.dateTime}
|
19
|
+
dateFormat="YYYY-MM-DD"
|
20
|
+
onChange={(val) => {
|
21
|
+
const parsedVal = val != null && (val.length > 0) ? new Date(val) : null;
|
22
|
+
|
23
|
+
this.setState({dateTime: parsedVal});
|
24
|
+
}}
|
25
|
+
/>
|
26
|
+
);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
interface IState {
|
31
|
+
today: string;
|
32
|
+
dateTime: Date | null;
|
33
|
+
}
|
34
|
+
|
35
|
+
export default class DateTimePickerDoc extends React.Component<{}, IState> {
|
36
|
+
constructor(props) {
|
37
|
+
super(props);
|
38
|
+
|
39
|
+
this.state = {
|
40
|
+
today: '',
|
41
|
+
dateTime: new Date(),
|
42
|
+
};
|
43
|
+
}
|
44
|
+
|
45
|
+
render() {
|
46
|
+
return (
|
47
|
+
<section className="docs-page__container">
|
48
|
+
<h2 className="docs-page__h2">Date picker</h2>
|
49
|
+
<Markup.ReactMarkupCodePreview>{`
|
50
|
+
<DateTimePicker
|
51
|
+
label="Planning datetime"
|
52
|
+
value={this.state.date}
|
53
|
+
dateFormat="YYYY-MM-DD"
|
54
|
+
onChange={(date) => {
|
55
|
+
this.setState({date});
|
56
|
+
}}
|
57
|
+
/>
|
58
|
+
`}</Markup.ReactMarkupCodePreview>
|
59
|
+
<Markup.ReactMarkup>
|
60
|
+
<Markup.ReactMarkupPreview>
|
61
|
+
<div className='docs-page__content-row'>
|
62
|
+
<DateTimePickerExample />
|
63
|
+
</div>
|
64
|
+
</Markup.ReactMarkupPreview>
|
65
|
+
<Markup.ReactMarkupCode>{`
|
66
|
+
<DateTimePicker
|
67
|
+
value={this.state.date}
|
68
|
+
onChange={(date) => {
|
69
|
+
this.setState({date});
|
70
|
+
}}
|
71
|
+
dateFormat="YYYY-MM-DD"
|
72
|
+
/>
|
73
|
+
`}</Markup.ReactMarkupCode>
|
74
|
+
</Markup.ReactMarkup>
|
75
|
+
|
76
|
+
<h3 className='docs-page__h3'>Props</h3>
|
77
|
+
<PropsList>
|
78
|
+
<Prop name='value' isRequired={false} type='Date' default='null' description='Value of the component.' />
|
79
|
+
<Prop name='dateFormat' isRequired={true} type='string' default='/' description='Date format to use, i.e. "MM/DD/YYYY".' />
|
80
|
+
<Prop name='onChange' isRequired={true} type='Function' default='/' description='Callback to invoke when value changes.'/>
|
81
|
+
<Prop name='label' isRequired={false} type='string' default='/' description='Label of component.' />
|
82
|
+
<Prop name='required' isRequired={false} type='boolean' default='false' description='Mark field as required.' />
|
83
|
+
<Prop name='disabled' isRequired={false} type='boolean' default='false' description='Mark field as disabled.' />
|
84
|
+
</PropsList>
|
85
|
+
|
86
|
+
<h3 className='docs-page__h3'>Events</h3>
|
87
|
+
<PropsList>
|
88
|
+
<Prop name='onChange' isRequired={true} type='function' default='/' description='Returns value of date input' />
|
89
|
+
</PropsList>
|
90
|
+
</section>
|
91
|
+
);
|
92
|
+
}
|
93
|
+
}
|
@@ -21,6 +21,7 @@ import IconButtonDoc from './IconButtons';
|
|
21
21
|
import IconLabelDoc from './IconLabels';
|
22
22
|
import TooltipDoc from './Tooltips';
|
23
23
|
import DatePickerDoc from './DatePicker';
|
24
|
+
import DateTimePickerDoc from './DateTimePicker';
|
24
25
|
import TimePickerDoc from './TimePicker';
|
25
26
|
import SwitchDoc from './Switch';
|
26
27
|
import RadioGroupDoc from './RadioGroup';
|
@@ -337,6 +338,10 @@ const pages: IPages = {
|
|
337
338
|
name: 'Date Picker',
|
338
339
|
component: DatePickerDoc,
|
339
340
|
},
|
341
|
+
'date-time-picker': {
|
342
|
+
name: 'DateTime Picker',
|
343
|
+
component: DateTimePickerDoc,
|
344
|
+
},
|
340
345
|
'time-picker': {
|
341
346
|
name: 'Time Picker',
|
342
347
|
component: TimePickerDoc,
|