superdesk-ui-framework 5.0.2 → 5.0.4
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/.mocharc.json +1 -1
- package/app/scripts/helpers/dropdown.helper.js +9 -0
- package/app/styles/_buttons.scss +4 -1
- package/app/styles/_helpers.scss +25 -6
- package/app/styles/_popover.scss +8 -8
- package/app/styles/_tooltips.scss +83 -0
- package/app/styles/design-tokens/_design-tokens-general.scss +6 -0
- package/app/styles/form-elements/_checkbox.scss +9 -5
- package/app/styles/form-elements/_inputs.scss +7 -1
- package/app-typescript/components/Autocomplete.tsx +1 -1
- package/app-typescript/components/Form/InputWrapper.tsx +1 -1
- package/app-typescript/components/Popover.tsx +2 -0
- package/app-typescript/components/SelectGrid.tsx +3 -1
- package/app-typescript/components/TimePicker/TimePickerPopover.spec.ts +163 -0
- package/app-typescript/components/TimePicker/TimePickerPopover.tsx +286 -0
- package/app-typescript/components/TimePicker/TimeValueHolder.tsx +36 -0
- package/app-typescript/components/{TimePicker.tsx → TimePicker/index.tsx} +6 -12
- package/app-typescript/components/Tooltip.tsx +1 -1
- package/app-typescript/components/TooltipV2.tsx +10 -21
- package/app-typescript/components/_Positioner.tsx +2 -0
- package/dist/components/Popover.tsx +31 -8
- package/dist/components/TimePicker.tsx +7 -2
- package/dist/components/Tooltips.tsx +15 -13
- package/dist/components/utilities/SpacingUtilities.tsx +126 -126
- package/dist/components/utilities/TextUtilities.tsx +51 -37
- package/dist/examples.bundle.js +1354 -1199
- package/dist/superdesk-ui.bundle.css +146 -41
- package/dist/superdesk-ui.bundle.js +829 -741
- package/dist/vendor.bundle.js +15 -15
- package/package.json +1 -1
- package/react/components/Autocomplete.js +2 -1
- package/react/components/Form/InputWrapper.js +2 -1
- package/react/components/Popover.d.ts +1 -0
- package/react/components/Popover.js +1 -1
- package/react/components/SelectGrid.js +2 -1
- package/react/components/TimePicker/TimePickerPopover.d.ts +27 -0
- package/react/components/TimePicker/TimePickerPopover.js +231 -0
- package/react/components/TimePicker/TimeValueHolder.d.ts +13 -0
- package/react/components/TimePicker/TimeValueHolder.js +73 -0
- package/react/components/{TimePicker.d.ts → TimePicker/index.d.ts} +1 -1
- package/react/components/{TimePicker.js → TimePicker/index.js} +5 -9
- package/react/components/Tooltip.js +1 -1
- package/react/components/TooltipV2.js +10 -18
- package/react/components/_Positioner.d.ts +1 -0
- package/react/components/_Positioner.js +1 -1
- package/app-typescript/components/TimePickerPopover.tsx +0 -283
- package/react/components/TimePickerPopover.d.ts +0 -18
- package/react/components/TimePickerPopover.js +0 -222
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {Spacer} from '@sourcefabric/common';
|
|
3
|
+
import {ContentDivider} from '../ContentDivider';
|
|
4
|
+
import {RadioButtonGroup} from '../RadioButtonGroup';
|
|
5
|
+
import {getOptionsForTimeUnit} from '../../utils/time';
|
|
6
|
+
import {TimeValueHolder} from './TimeValueHolder';
|
|
7
|
+
|
|
8
|
+
export function convert12HourTo24Hour(hour: number, period: 'am' | 'pm'): number {
|
|
9
|
+
if (period === 'am' && hour === 12) {
|
|
10
|
+
return 0; // midnight
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (period === 'pm' && hour !== 12) {
|
|
14
|
+
return hour + 12; // PM and not 12
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return hour; // For 12PM, 1-11AM
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function convert24HourTo12Hour(hour: number) {
|
|
21
|
+
const remainder = hour % 12;
|
|
22
|
+
|
|
23
|
+
return remainder === 0 ? 12 : remainder;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isAm(hours: number) {
|
|
27
|
+
return hours < 12;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function toInternalState(
|
|
31
|
+
timeStr: string | undefined | null, // will always be in 24h format
|
|
32
|
+
): IState {
|
|
33
|
+
if (timeStr == null || (timeStr ?? '').trim().length < 1) {
|
|
34
|
+
return {
|
|
35
|
+
hours: null,
|
|
36
|
+
minutes: null,
|
|
37
|
+
seconds: null,
|
|
38
|
+
period: null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const [hours, minutes, seconds] = timeStr.split(':');
|
|
43
|
+
const secondsDefault = hours != null && minutes != null ? '00' : null;
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
hours: (() => {
|
|
47
|
+
if (hours == null) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (is12HourFormat) {
|
|
52
|
+
return convert24HourTo12Hour(parseInt(hours, 10)).toString().padStart(2, '0');
|
|
53
|
+
} else {
|
|
54
|
+
return hours;
|
|
55
|
+
}
|
|
56
|
+
})(),
|
|
57
|
+
minutes: minutes ?? null,
|
|
58
|
+
seconds: seconds ?? secondsDefault,
|
|
59
|
+
period: hours == null ? null : isAm(parseInt(hours, 10)) ? 'am' : 'pm',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const is12HourFormat: boolean = (() => {
|
|
64
|
+
const hour = new Date().toLocaleTimeString([]);
|
|
65
|
+
|
|
66
|
+
return hour.includes('AM') || hour.includes('PM');
|
|
67
|
+
})();
|
|
68
|
+
|
|
69
|
+
interface IProps {
|
|
70
|
+
headerTemplate?: React.ReactNode;
|
|
71
|
+
footerTemplate?: React.ReactNode;
|
|
72
|
+
allowSeconds?: boolean;
|
|
73
|
+
onChange: (nextValue: string) => void;
|
|
74
|
+
value: string | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// internal state is needed in order to be able to wait for all inputs to be filled before triggering `props.onChange`
|
|
78
|
+
interface IState {
|
|
79
|
+
hours: string | null;
|
|
80
|
+
minutes: string | null;
|
|
81
|
+
seconds: string | null;
|
|
82
|
+
period: 'am' | 'pm' | null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export class TimePickerPopover extends React.PureComponent<IProps, IState> {
|
|
86
|
+
// hour, minutes, seconds
|
|
87
|
+
private inputRefs: Array<React.RefObject<TimeValueHolder>>;
|
|
88
|
+
|
|
89
|
+
constructor(props: IProps) {
|
|
90
|
+
super(props);
|
|
91
|
+
|
|
92
|
+
this.inputRefs = [React.createRef(), React.createRef(), React.createRef()];
|
|
93
|
+
this.handleChange = this.handleChange.bind(this);
|
|
94
|
+
this.scrollToValues = this.scrollToValues.bind(this);
|
|
95
|
+
|
|
96
|
+
this.state = toInternalState(props.value);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private handleChange(nextState: IState) {
|
|
100
|
+
this.setState(nextState, () => {
|
|
101
|
+
let timeParts: Array<string> = [];
|
|
102
|
+
|
|
103
|
+
if (this.state.hours == null) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (is12HourFormat) {
|
|
108
|
+
if (this.state.period == null) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
timeParts.push(
|
|
113
|
+
convert12HourTo24Hour(parseInt(this.state.hours, 10), this.state.period)
|
|
114
|
+
.toString()
|
|
115
|
+
.padStart(2, '0'),
|
|
116
|
+
);
|
|
117
|
+
} else {
|
|
118
|
+
timeParts.push(this.state.hours);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.state.minutes == null) {
|
|
122
|
+
return;
|
|
123
|
+
} else {
|
|
124
|
+
timeParts.push(this.state.minutes);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.props.allowSeconds) {
|
|
128
|
+
if (this.state.seconds == null) {
|
|
129
|
+
return;
|
|
130
|
+
} else {
|
|
131
|
+
timeParts.push(this.state.seconds);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this.props.onChange(timeParts.join(':'));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
scrollToValues() {
|
|
140
|
+
this.inputRefs.forEach((unitOfTime) => unitOfTime?.current?.scrollToValue?.());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
componentDidMount(): void {
|
|
144
|
+
this.scrollToValues();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
componentDidUpdate(prevProps: Readonly<IProps>): void {
|
|
148
|
+
if (this.props.value !== prevProps.value) {
|
|
149
|
+
this.setState(toInternalState(this.props.value), () => {
|
|
150
|
+
this.scrollToValues();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
render(): React.ReactNode {
|
|
156
|
+
const styleForColumnOfUnit: React.CSSProperties = {
|
|
157
|
+
maxHeight: 190,
|
|
158
|
+
overflowY: 'auto',
|
|
159
|
+
scrollbarWidth: 'thin',
|
|
160
|
+
marginTop: 'var(--gap-1)',
|
|
161
|
+
scrollBehavior: 'smooth',
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div className="sd-shadow--z2 radius-md">
|
|
166
|
+
<Spacer
|
|
167
|
+
v
|
|
168
|
+
gap="0"
|
|
169
|
+
style={{
|
|
170
|
+
minWidth: 200,
|
|
171
|
+
maxWidth: 'max-content',
|
|
172
|
+
backgroundColor: 'var(--color-dropdown-menu-Bg)',
|
|
173
|
+
borderRadius: 'var(--b-radius--small)',
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
{this.props.headerTemplate && (
|
|
177
|
+
<div className="px-1-5 py-1" style={{borderBottom: '1px solid var(--color-line-x-light)'}}>
|
|
178
|
+
{this.props.headerTemplate}
|
|
179
|
+
</div>
|
|
180
|
+
)}
|
|
181
|
+
|
|
182
|
+
<Spacer
|
|
183
|
+
h
|
|
184
|
+
gap="4"
|
|
185
|
+
noWrap
|
|
186
|
+
justifyContent="center"
|
|
187
|
+
alignItems="start"
|
|
188
|
+
style={{paddingInline: 'var(--gap-1)'}}
|
|
189
|
+
>
|
|
190
|
+
<Spacer v gap="4" style={styleForColumnOfUnit} alignItems="center" noWrap>
|
|
191
|
+
{getOptionsForTimeUnit('hours', is12HourFormat).map((hour) => {
|
|
192
|
+
const isActiveHour = hour === this.state.hours;
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<TimeValueHolder
|
|
196
|
+
key={hour}
|
|
197
|
+
ref={isActiveHour ? this.inputRefs[0] : undefined}
|
|
198
|
+
onClick={() => {
|
|
199
|
+
this.handleChange({...this.state, hours: hour});
|
|
200
|
+
}}
|
|
201
|
+
isActive={isActiveHour}
|
|
202
|
+
value={hour}
|
|
203
|
+
/>
|
|
204
|
+
);
|
|
205
|
+
})}
|
|
206
|
+
</Spacer>
|
|
207
|
+
|
|
208
|
+
<ContentDivider align="center" border type="solid" orientation="vertical" margin="none" />
|
|
209
|
+
|
|
210
|
+
<Spacer v gap="4" style={styleForColumnOfUnit} alignItems="center" noWrap>
|
|
211
|
+
{getOptionsForTimeUnit('minutes', is12HourFormat).map((minute) => {
|
|
212
|
+
const isActiveMinute = minute === this.state.minutes;
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<TimeValueHolder
|
|
216
|
+
key={minute}
|
|
217
|
+
ref={isActiveMinute ? this.inputRefs[1] : undefined}
|
|
218
|
+
isActive={isActiveMinute}
|
|
219
|
+
value={minute}
|
|
220
|
+
onClick={() => {
|
|
221
|
+
this.handleChange({...this.state, minutes: minute});
|
|
222
|
+
}}
|
|
223
|
+
/>
|
|
224
|
+
);
|
|
225
|
+
})}
|
|
226
|
+
</Spacer>
|
|
227
|
+
|
|
228
|
+
{this.props.allowSeconds && (
|
|
229
|
+
<>
|
|
230
|
+
<ContentDivider
|
|
231
|
+
align="center"
|
|
232
|
+
border
|
|
233
|
+
type="solid"
|
|
234
|
+
orientation="vertical"
|
|
235
|
+
margin="none"
|
|
236
|
+
/>
|
|
237
|
+
<Spacer v gap="4" style={styleForColumnOfUnit} alignItems="center" noWrap>
|
|
238
|
+
{getOptionsForTimeUnit('seconds', is12HourFormat).map((second) => {
|
|
239
|
+
const isActiveSecond = second === this.state.seconds;
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<TimeValueHolder
|
|
243
|
+
key={second}
|
|
244
|
+
ref={isActiveSecond ? this.inputRefs[2] : undefined}
|
|
245
|
+
onClick={() => {
|
|
246
|
+
this.handleChange({...this.state, seconds: second});
|
|
247
|
+
}}
|
|
248
|
+
isActive={isActiveSecond}
|
|
249
|
+
value={second}
|
|
250
|
+
/>
|
|
251
|
+
);
|
|
252
|
+
})}
|
|
253
|
+
</Spacer>
|
|
254
|
+
</>
|
|
255
|
+
)}
|
|
256
|
+
|
|
257
|
+
{is12HourFormat && (
|
|
258
|
+
<div
|
|
259
|
+
style={{
|
|
260
|
+
marginTop: 'var(--gap-1)',
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
<RadioButtonGroup
|
|
264
|
+
onChange={(nextValue) => {
|
|
265
|
+
this.handleChange({...this.state, period: nextValue as 'am' | 'pm'});
|
|
266
|
+
}}
|
|
267
|
+
options={[
|
|
268
|
+
{label: 'AM', value: 'am'},
|
|
269
|
+
{label: 'PM', value: 'pm'},
|
|
270
|
+
]}
|
|
271
|
+
value={this.state.period == null ? '' : this.state.period}
|
|
272
|
+
/>
|
|
273
|
+
</div>
|
|
274
|
+
)}
|
|
275
|
+
</Spacer>
|
|
276
|
+
|
|
277
|
+
{this.props.footerTemplate && (
|
|
278
|
+
<div className="px-1-5 py-1" style={{borderTop: '1px solid var(--color-line-x-light)'}}>
|
|
279
|
+
{this.props.footerTemplate}
|
|
280
|
+
</div>
|
|
281
|
+
)}
|
|
282
|
+
</Spacer>
|
|
283
|
+
</div>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {classnames} from '@sourcefabric/common';
|
|
3
|
+
|
|
4
|
+
interface IProps {
|
|
5
|
+
isActive?: boolean;
|
|
6
|
+
value: string;
|
|
7
|
+
onClick(event: React.MouseEvent<HTMLSpanElement>): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class TimeValueHolder extends React.PureComponent<IProps> {
|
|
11
|
+
private spanEl: React.RefObject<HTMLSpanElement>;
|
|
12
|
+
|
|
13
|
+
constructor(props: IProps) {
|
|
14
|
+
super(props);
|
|
15
|
+
|
|
16
|
+
this.spanEl = React.createRef();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public scrollToValue() {
|
|
20
|
+
this.spanEl.current?.scrollIntoView({block: 'start', behavior: 'smooth'});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
render() {
|
|
24
|
+
return (
|
|
25
|
+
<span
|
|
26
|
+
ref={this.props.isActive ? this.spanEl : undefined}
|
|
27
|
+
onClick={this.props.onClick}
|
|
28
|
+
className={classnames('p-1 time-unit', {
|
|
29
|
+
'time-unit-highlight': this.props.isActive ?? false,
|
|
30
|
+
})}
|
|
31
|
+
>
|
|
32
|
+
{this.props.value}
|
|
33
|
+
</span>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import nextId from 'react-id-generator';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import {InputWrapper} from '
|
|
5
|
-
import {IInputWrapper} from '
|
|
4
|
+
import {InputWrapper} from '../Form';
|
|
5
|
+
import {IInputWrapper} from '../Form/InputWrapper';
|
|
6
6
|
import {TimePickerPopover} from './TimePickerPopover';
|
|
7
|
-
import {PopupPositioner} from '
|
|
8
|
-
import {Icon} from '
|
|
9
|
-
import {IconButton} from '
|
|
7
|
+
import {PopupPositioner} from '../ShowPopup';
|
|
8
|
+
import {Icon} from '../Icon';
|
|
9
|
+
import {IconButton} from '../IconButton';
|
|
10
10
|
|
|
11
11
|
interface IProps extends IInputWrapper {
|
|
12
12
|
value: string | null; // ISO8601 time string(e.g. 16:55) or null if there's no value
|
|
@@ -120,18 +120,12 @@ export class TimePicker extends React.PureComponent<IProps, IState> {
|
|
|
120
120
|
ref={this.timeInputRef}
|
|
121
121
|
value={this.props.value ?? ''}
|
|
122
122
|
type="time"
|
|
123
|
-
onClick={(
|
|
124
|
-
// don't show default popup
|
|
125
|
-
e.preventDefault();
|
|
126
|
-
|
|
123
|
+
onClick={() => {
|
|
127
124
|
this.setState({
|
|
128
125
|
popupOpen: !this.state.popupOpen,
|
|
129
126
|
});
|
|
130
127
|
}}
|
|
131
128
|
onKeyDown={(event) => {
|
|
132
|
-
// don't show default popup
|
|
133
|
-
event.preventDefault();
|
|
134
|
-
|
|
135
129
|
if (event.key === ' ') {
|
|
136
130
|
this.setState({
|
|
137
131
|
popupOpen: !this.state.popupOpen,
|
|
@@ -37,7 +37,7 @@ export class Tooltip extends React.PureComponent<IProps> {
|
|
|
37
37
|
return (
|
|
38
38
|
<TooltipV2 content={this.props.text ?? ''} placement={flowToPlacement(this.props.flow)}>
|
|
39
39
|
{({attributes}) => (
|
|
40
|
-
<div {...attributes} style={{display: '
|
|
40
|
+
<div {...attributes} style={{display: 'contents'}}>
|
|
41
41
|
{this.props.children}
|
|
42
42
|
</div>
|
|
43
43
|
)}
|
|
@@ -24,27 +24,16 @@ export class TooltipV2 extends React.PureComponent<IPropsTooltipV2> {
|
|
|
24
24
|
placement={this.props.placement ?? 'top'}
|
|
25
25
|
component={() => {
|
|
26
26
|
return (
|
|
27
|
-
<div
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
paddingInline: 'var(--space--0-5)',
|
|
34
|
-
fontSize: 'var(--text-size-x-small)',
|
|
35
|
-
margin: 2,
|
|
36
|
-
}}
|
|
37
|
-
>
|
|
38
|
-
{(() => {
|
|
39
|
-
if (typeof this.props.content === 'string') {
|
|
40
|
-
return <span>{this.props.content}</span>;
|
|
41
|
-
} else {
|
|
42
|
-
const Component = this.props.content;
|
|
27
|
+
<div className="tooltip">
|
|
28
|
+
{(() => {
|
|
29
|
+
if (typeof this.props.content === 'string') {
|
|
30
|
+
return <span>{this.props.content}</span>;
|
|
31
|
+
} else {
|
|
32
|
+
const Component = this.props.content;
|
|
43
33
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</div>
|
|
34
|
+
return <Component />;
|
|
35
|
+
}
|
|
36
|
+
})()}
|
|
48
37
|
</div>
|
|
49
38
|
);
|
|
50
39
|
}}
|
|
@@ -63,7 +52,7 @@ export class TooltipV2 extends React.PureComponent<IPropsTooltipV2> {
|
|
|
63
52
|
return this.props.children({attributes});
|
|
64
53
|
} else {
|
|
65
54
|
return (
|
|
66
|
-
<span {...attributes} style={{display: '
|
|
55
|
+
<span {...attributes} style={{display: 'contents'}}>
|
|
67
56
|
{this.props.children}
|
|
68
57
|
</span>
|
|
69
58
|
);
|
|
@@ -93,6 +93,7 @@ class PopperWrapper extends React.Component<IPropsPopperWrapper> {
|
|
|
93
93
|
}}
|
|
94
94
|
tabIndex={0}
|
|
95
95
|
role="dialog"
|
|
96
|
+
data-theme={this.props.theme}
|
|
96
97
|
aria-labelledby="popoverTitle"
|
|
97
98
|
onKeyDown={(event) => {
|
|
98
99
|
if (event.key === 'Escape') {
|
|
@@ -111,6 +112,7 @@ interface IPropsPositioner {
|
|
|
111
112
|
triggerSelector: string;
|
|
112
113
|
placement: PopperOptions['placement'];
|
|
113
114
|
className?: string;
|
|
115
|
+
theme?: 'light-ui' | 'dark-ui';
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
interface IStatePositioner {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {Popover, PropsList, Prop} from '../../../app-typescript';
|
|
2
|
+
import {Popover, PropsList, Prop, Button, ButtonGroup} from '../../../app-typescript';
|
|
3
3
|
|
|
4
4
|
import * as Markup from '../../js/react';
|
|
5
5
|
|
|
@@ -23,13 +23,20 @@ export class PopoverDoc extends React.Component {
|
|
|
23
23
|
<Markup.ReactMarkupPreview>
|
|
24
24
|
<div className="docs-page__content-row docs-page__content-row--no-margin">
|
|
25
25
|
<div className="form__row">
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
<ButtonGroup>
|
|
27
|
+
<Button
|
|
28
|
+
aria-haspopup="true"
|
|
29
|
+
id="button-view-content"
|
|
30
|
+
text="Open popover"
|
|
31
|
+
onClick={() => false}
|
|
32
|
+
/>
|
|
33
|
+
<Button
|
|
34
|
+
aria-haspopup="true"
|
|
35
|
+
id="button-view-content-dark"
|
|
36
|
+
text="Open popover"
|
|
37
|
+
onClick={() => false}
|
|
38
|
+
/>
|
|
39
|
+
</ButtonGroup>
|
|
33
40
|
|
|
34
41
|
<Popover
|
|
35
42
|
triggerSelector="#button-view-content"
|
|
@@ -38,6 +45,15 @@ export class PopoverDoc extends React.Component {
|
|
|
38
45
|
>
|
|
39
46
|
Donec sed odio dui. Aenean lacinia bibendum nulla sed consectetur.
|
|
40
47
|
</Popover>
|
|
48
|
+
<Popover
|
|
49
|
+
triggerSelector="#button-view-content-dark"
|
|
50
|
+
title="Popover test"
|
|
51
|
+
placement="top-end"
|
|
52
|
+
theme="dark-ui"
|
|
53
|
+
>
|
|
54
|
+
Enforce a dark theme. Donec sed odio dui. Aenean lacinia bibendum nulla sed
|
|
55
|
+
consectetur.
|
|
56
|
+
</Popover>
|
|
41
57
|
</div>
|
|
42
58
|
</div>
|
|
43
59
|
</Markup.ReactMarkupPreview>
|
|
@@ -83,6 +99,13 @@ export class PopoverDoc extends React.Component {
|
|
|
83
99
|
default="auto"
|
|
84
100
|
description="Define the placement of the Popover."
|
|
85
101
|
/>
|
|
102
|
+
<Prop
|
|
103
|
+
name="theme"
|
|
104
|
+
isRequired={false}
|
|
105
|
+
type="light-ui | dark-ui"
|
|
106
|
+
default="/"
|
|
107
|
+
description="Define the theme of the Popover. It will inherit the default theme if not set."
|
|
108
|
+
/>
|
|
86
109
|
</PropsList>
|
|
87
110
|
</section>
|
|
88
111
|
);
|
|
@@ -36,7 +36,12 @@ class TimePickerExample extends React.PureComponent<{}, {time: string | null}> {
|
|
|
36
36
|
<Button size="small" text="In 30 min" style="hollow" onClick={() => false} />
|
|
37
37
|
<Button size="small" text="In 1 hr" style="hollow" onClick={() => false} />
|
|
38
38
|
<Button size="small" text="In 2 hr" style="hollow" onClick={() => false} />
|
|
39
|
-
<Button
|
|
39
|
+
<Button
|
|
40
|
+
size="small"
|
|
41
|
+
text="16:32"
|
|
42
|
+
style="hollow"
|
|
43
|
+
onClick={() => this.setState({time: '16:32'})}
|
|
44
|
+
/>
|
|
40
45
|
</ButtonGroup>
|
|
41
46
|
}
|
|
42
47
|
footerTemplate={<div>Footer</div>}
|
|
@@ -65,7 +70,7 @@ export default class TimePickerDoc extends React.Component<{}, {time: string}> {
|
|
|
65
70
|
render() {
|
|
66
71
|
return (
|
|
67
72
|
<section className="docs-page__container">
|
|
68
|
-
<h2 className="docs-page__h2">Time picker</h2>
|
|
73
|
+
<h2 className="docs-page__h2">Time picker 1</h2>
|
|
69
74
|
<Markup.ReactMarkupCodePreview>{`
|
|
70
75
|
<TimePicker
|
|
71
76
|
value={this.state.time}
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import * as Markup from '../../js/react';
|
|
4
4
|
|
|
5
|
-
import {Tooltip, Prop, PropsList, Button} from '../../../app-typescript';
|
|
5
|
+
import {Tooltip, Prop, PropsList, Button, ButtonGroup} from '../../../app-typescript';
|
|
6
6
|
|
|
7
7
|
export default class TooltipDoc extends React.Component {
|
|
8
8
|
render() {
|
|
@@ -20,18 +20,20 @@ export default class TooltipDoc extends React.Component {
|
|
|
20
20
|
<Markup.ReactMarkup>
|
|
21
21
|
<Markup.ReactMarkupPreview>
|
|
22
22
|
<div className="docs-page__content-row docs-page__content-row--no-margin">
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
23
|
+
<ButtonGroup>
|
|
24
|
+
<Tooltip content="I'm on top">
|
|
25
|
+
<Button text="top" onClick={() => false} />
|
|
26
|
+
</Tooltip>
|
|
27
|
+
<Tooltip content="I'm at the bottom" placement="bottom">
|
|
28
|
+
<Button text="bottom" onClick={() => false} />
|
|
29
|
+
</Tooltip>
|
|
30
|
+
<Tooltip content="I open on the left" placement="left">
|
|
31
|
+
<Button text="left" onClick={() => false} />
|
|
32
|
+
</Tooltip>
|
|
33
|
+
<Tooltip content="Right on!" placement="right">
|
|
34
|
+
<Button text="right" onClick={() => false} />
|
|
35
|
+
</Tooltip>
|
|
36
|
+
</ButtonGroup>
|
|
35
37
|
</div>
|
|
36
38
|
</Markup.ReactMarkupPreview>
|
|
37
39
|
<Markup.ReactMarkupCode>
|