superdesk-ui-framework 2.4.14 → 2.4.18
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/index.js +1 -0
- package/app/scripts/modals.js +22 -9
- package/app/styles/_accessibility.scss +3 -2
- package/app/styles/_buttons.scss +17 -0
- package/app/styles/_modals.scss +23 -17
- package/app/styles/_tooltips.scss +66 -0
- package/app/styles/app.scss +1 -0
- package/app/styles/components/_sd-toaster.scss +6 -5
- package/app/styles/form-elements/_inputs.scss +1 -0
- package/app/styles/form-elements/_select-grid.scss +77 -0
- package/app/styles/pr-superdesk-theme.scss +3 -1
- package/app/styles/primereact/_pr-menu.scss +38 -0
- package/app/styles/primereact/_pr-skeleton.scss +35 -0
- package/app/styles/variables/_colors.scss +30 -18
- package/app-typescript/components/Button.tsx +2 -2
- package/app-typescript/components/Dropdown.tsx +0 -1
- package/app-typescript/components/DropdownFirst.tsx +2 -2
- package/app-typescript/components/IconPicker.tsx +277 -0
- package/app-typescript/components/Input.tsx +8 -3
- package/app-typescript/components/ListItemLoader.tsx +30 -0
- package/app-typescript/components/Menu.tsx +149 -0
- package/app-typescript/components/PropsList.tsx +2 -2
- package/app-typescript/components/Radio.tsx +19 -10
- package/app-typescript/components/Select.tsx +6 -3
- package/app-typescript/components/SelectGrid.tsx +233 -0
- package/app-typescript/components/SelectWithTemplate.tsx +0 -2
- package/app-typescript/components/Skeleton.tsx +48 -0
- package/app-typescript/components/Tag.tsx +2 -2
- package/app-typescript/components/Toast.tsx +31 -5
- package/app-typescript/components/ToastMessage.tsx +9 -16
- package/app-typescript/components/ToastText.tsx +2 -4
- package/app-typescript/components/ToastWrapper.tsx +4 -4
- package/app-typescript/components/Togglebox.tsx +108 -0
- package/app-typescript/components/Tooltip.tsx +25 -1
- package/app-typescript/index.ts +8 -0
- package/dist/components/modals.html +180 -4
- package/dist/examples.bundle.css +52 -36
- package/dist/examples.bundle.js +5775 -3059
- package/dist/playgrounds/react-playgrounds/SamsPlayground.tsx +14 -1
- package/dist/react/Alerts.tsx +4 -4
- package/dist/react/Autocomplete.tsx +17 -17
- package/dist/react/Badges.tsx +4 -4
- package/dist/react/BigIconFont.tsx +3 -3
- package/dist/react/ButtonGroups.tsx +6 -6
- package/dist/react/Buttons.tsx +11 -11
- package/dist/react/Carousel.tsx +15 -15
- package/dist/react/Checkboxs.tsx +10 -10
- package/dist/react/DatePicker.tsx +6 -6
- package/dist/react/Dropdowns.tsx +15 -15
- package/dist/react/EmptyStates.tsx +4 -4
- package/dist/react/GridItem.tsx +8 -8
- package/dist/react/GridList.tsx +3 -3
- package/dist/react/IconButtons.tsx +3 -3
- package/dist/react/IconFont.tsx +10 -9
- package/dist/react/IconLabels.tsx +4 -4
- package/dist/react/IconPicker.tsx +65 -0
- package/dist/react/Index.tsx +27 -2
- package/dist/react/Inputs.tsx +29 -11
- package/dist/react/Labels.tsx +6 -6
- package/dist/react/LeftNavigations.tsx +6 -6
- package/dist/react/ListItems.tsx +34 -0
- package/dist/react/Menu.tsx +159 -0
- package/dist/react/Modal.tsx +9 -9
- package/dist/react/NavButtons.tsx +7 -7
- package/dist/react/Popover.tsx +5 -5
- package/dist/react/Radios.tsx +29 -29
- package/dist/react/SelectGrid.tsx +121 -0
- package/dist/react/Selects.tsx +31 -9
- package/dist/react/Switch.tsx +5 -5
- package/dist/react/Tabs.tsx +12 -12
- package/dist/react/TimePicker.tsx +4 -4
- package/dist/react/Toasts.tsx +44 -56
- package/dist/react/Togglebox.tsx +51 -0
- package/dist/react/Tooltips.tsx +48 -4
- package/dist/superdesk-ui.bundle.css +3774 -96
- package/dist/superdesk-ui.bundle.js +4503 -2050
- package/dist/vendor.bundle.js +53312 -53308
- package/examples/pages/components/modals.html +180 -4
- package/examples/pages/playgrounds/react-playgrounds/SamsPlayground.tsx +14 -1
- package/examples/pages/react/Alerts.tsx +4 -4
- package/examples/pages/react/Autocomplete.tsx +17 -17
- package/examples/pages/react/Badges.tsx +4 -4
- package/examples/pages/react/BigIconFont.tsx +3 -3
- package/examples/pages/react/ButtonGroups.tsx +6 -6
- package/examples/pages/react/Buttons.tsx +11 -11
- package/examples/pages/react/Carousel.tsx +15 -15
- package/examples/pages/react/Checkboxs.tsx +10 -10
- package/examples/pages/react/DatePicker.tsx +6 -6
- package/examples/pages/react/Dropdowns.tsx +15 -15
- package/examples/pages/react/EmptyStates.tsx +4 -4
- package/examples/pages/react/GridItem.tsx +8 -8
- package/examples/pages/react/GridList.tsx +3 -3
- package/examples/pages/react/IconButtons.tsx +3 -3
- package/examples/pages/react/IconFont.tsx +10 -9
- package/examples/pages/react/IconLabels.tsx +4 -4
- package/examples/pages/react/IconPicker.tsx +65 -0
- package/examples/pages/react/Index.tsx +27 -2
- package/examples/pages/react/Inputs.tsx +29 -11
- package/examples/pages/react/Labels.tsx +6 -6
- package/examples/pages/react/LeftNavigations.tsx +6 -6
- package/examples/pages/react/ListItems.tsx +34 -0
- package/examples/pages/react/Menu.tsx +159 -0
- package/examples/pages/react/Modal.tsx +9 -9
- package/examples/pages/react/NavButtons.tsx +7 -7
- package/examples/pages/react/Popover.tsx +5 -5
- package/examples/pages/react/Radios.tsx +29 -29
- package/examples/pages/react/SelectGrid.tsx +121 -0
- package/examples/pages/react/Selects.tsx +31 -9
- package/examples/pages/react/Switch.tsx +5 -5
- package/examples/pages/react/Tabs.tsx +12 -12
- package/examples/pages/react/TimePicker.tsx +4 -4
- package/examples/pages/react/Toasts.tsx +44 -56
- package/examples/pages/react/Togglebox.tsx +51 -0
- package/examples/pages/react/Tooltips.tsx +48 -4
- package/package.json +2 -2
- package/patches/@superdesk+primereact+5.0.2-4.patch +13 -0
- package/react/components/Button.d.ts +1 -1
- package/react/components/Button.js +2 -1
- package/react/components/Dropdown.js +0 -1
- package/react/components/DropdownFirst.js +1 -1
- package/react/components/IconPicker.d.ts +24 -0
- package/react/components/IconPicker.js +283 -0
- package/react/components/Input.d.ts +2 -1
- package/react/components/Input.js +4 -1
- package/react/components/ListItemLoader.d.ts +4 -0
- package/react/components/ListItemLoader.js +62 -0
- package/react/components/Menu.d.ts +59 -0
- package/react/components/Menu.js +92 -0
- package/react/components/PropsList.d.ts +1 -1
- package/react/components/PropsList.js +1 -1
- package/react/components/Radio.d.ts +8 -7
- package/react/components/Radio.js +1 -1
- package/react/components/Select.d.ts +2 -1
- package/react/components/Select.js +4 -2
- package/react/components/SelectGrid.d.ts +45 -0
- package/react/components/SelectGrid.js +179 -0
- package/react/components/SelectWithTemplate.js +0 -1
- package/react/components/Skeleton.d.ts +30 -0
- package/react/components/Skeleton.js +55 -0
- package/react/components/Tag.js +1 -1
- package/react/components/Toast.d.ts +15 -0
- package/react/components/Toast.js +69 -0
- package/react/components/ToastMessage.d.ts +18 -0
- package/react/components/ToastMessage.js +66 -0
- package/react/components/ToastText.d.ts +9 -0
- package/react/components/ToastText.js +42 -0
- package/react/components/ToastWrapper.d.ts +31 -0
- package/react/components/ToastWrapper.js +116 -0
- package/react/components/Togglebox.d.ts +27 -0
- package/react/components/Togglebox.js +76 -0
- package/react/components/Tooltip.d.ts +2 -5
- package/react/components/Tooltip.js +48 -7
- package/react/index.d.ts +7 -0
- package/react/index.js +14 -0
@@ -0,0 +1,277 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
// @ts-ignore
|
3
|
+
import * as iconFont from '../../app/styles/_icon-font.scss';
|
4
|
+
import { Button } from './Button';
|
5
|
+
import { Icon } from './Icon';
|
6
|
+
import { IItem, SelectGrid } from "./SelectGrid";
|
7
|
+
|
8
|
+
interface IProps {
|
9
|
+
label?: string;
|
10
|
+
filterPlaceholder?: string;
|
11
|
+
translateFunction?: (text: string) => string;
|
12
|
+
value: string;
|
13
|
+
onChange(icon: string): void;
|
14
|
+
}
|
15
|
+
|
16
|
+
interface IState {
|
17
|
+
icons: Array<IItem>;
|
18
|
+
}
|
19
|
+
|
20
|
+
export class IconPicker extends React.PureComponent<IProps, IState> {
|
21
|
+
|
22
|
+
constructor(props: IProps) {
|
23
|
+
super(props);
|
24
|
+
this.state = { icons: [] };
|
25
|
+
}
|
26
|
+
|
27
|
+
componentDidMount() {
|
28
|
+
const translateFunction = this.props.translateFunction ?
|
29
|
+
this.props.translateFunction : (text: string): string => text;
|
30
|
+
this.setState({
|
31
|
+
icons: getIcons(translateFunction),
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
getItems = (searchString: string | null): Promise<Array<IItem>> => {
|
36
|
+
return new Promise((resolve) => {
|
37
|
+
let icons = [...this.state.icons];
|
38
|
+
|
39
|
+
if (searchString) {
|
40
|
+
icons = icons.filter(
|
41
|
+
(icon) => (
|
42
|
+
icon.value.toLowerCase().includes(searchString) ||
|
43
|
+
icon.label.toLowerCase().includes(searchString)
|
44
|
+
),
|
45
|
+
);
|
46
|
+
}
|
47
|
+
resolve(icons);
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
onChange = (item: IItem) => {
|
52
|
+
this.props.onChange(item.value);
|
53
|
+
}
|
54
|
+
|
55
|
+
triggerTemplate = (props: any) => <Button
|
56
|
+
icon={this.props.value}
|
57
|
+
text={this.props.value}
|
58
|
+
onClick={(e) => { props.onClick(e); }}
|
59
|
+
iconOnly={true} />
|
60
|
+
|
61
|
+
itemTemplate = ({ item }: { item: IItem | null }) => item ?
|
62
|
+
(<>
|
63
|
+
<Icon name={item.value} />
|
64
|
+
<span className="sd-text__normal sd-padding-t--1">
|
65
|
+
{item.label}
|
66
|
+
</span>
|
67
|
+
</>) : null
|
68
|
+
|
69
|
+
render() {
|
70
|
+
return (
|
71
|
+
<SelectGrid
|
72
|
+
label={this.props.label || "Icon"}
|
73
|
+
filterPlaceholder={this.props.filterPlaceholder || "Search..."}
|
74
|
+
getItems={this.getItems}
|
75
|
+
onChange={this.onChange}
|
76
|
+
itemTemplate={this.itemTemplate}
|
77
|
+
triggerTemplate={this.triggerTemplate}
|
78
|
+
/>
|
79
|
+
);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
const getIcons = (translateFunction: (text: string) => string): Array<IItem> => {
|
84
|
+
const translatedIconNameMap: any = {
|
85
|
+
'add-gallery': 'Add Gallery',
|
86
|
+
'add-image': 'Add Image',
|
87
|
+
'adjust': 'Adjust',
|
88
|
+
'align-center': 'Align Center',
|
89
|
+
'align-justify': 'Align Justify',
|
90
|
+
'align-left': 'Align Left',
|
91
|
+
'align-right': 'Align Right',
|
92
|
+
'amp': 'AMP',
|
93
|
+
'analytics': 'Analytics',
|
94
|
+
'archive': 'Archive',
|
95
|
+
'arrow-left': 'Arrow Left',
|
96
|
+
'arrow-right': 'Arrow Right',
|
97
|
+
'arrow-small': 'Arrow Small',
|
98
|
+
'ascending': 'Ascending',
|
99
|
+
'assign': 'Assign',
|
100
|
+
'attachment': 'Attachment',
|
101
|
+
'attachment-large': 'Attachment Large',
|
102
|
+
'audio': 'Audio',
|
103
|
+
'backward-thin': 'Backward Thin',
|
104
|
+
'ban-circle': 'Ban Circle',
|
105
|
+
'bell': 'Bell',
|
106
|
+
'bold': 'Bold',
|
107
|
+
'broadcast': 'Broadcast',
|
108
|
+
'broadcast-create': 'Broadcast Create',
|
109
|
+
'business': 'Business',
|
110
|
+
'calendar': 'Calendar',
|
111
|
+
'calendar-list': 'Calendar List',
|
112
|
+
'chevron-down-thin': 'Chevron Down Thin',
|
113
|
+
'chevron-left-thin': 'Chevron Left Thin',
|
114
|
+
'chevron-right-thin': 'Chevron Right Thin',
|
115
|
+
'chevron-up-thin': 'Chevron Up Thin',
|
116
|
+
'clear-all': 'Clear All',
|
117
|
+
'clear-format': 'Clear Format',
|
118
|
+
'close-small': 'Close Small',
|
119
|
+
'close-thick': 'Close Thick',
|
120
|
+
'code': 'Code',
|
121
|
+
'collapse': 'Collapse',
|
122
|
+
'comment': 'Comment',
|
123
|
+
'composite': 'Composite',
|
124
|
+
'copy': 'Copy',
|
125
|
+
'crop': 'Crop',
|
126
|
+
'cut': 'Cut',
|
127
|
+
'descending': 'Descending',
|
128
|
+
'dots': 'Dots',
|
129
|
+
'dots-vertical': 'Dots Vertical',
|
130
|
+
'download': 'Download',
|
131
|
+
'download-alt': 'Download Alternate',
|
132
|
+
'edit-line': 'Edit Line',
|
133
|
+
'envelope': 'Envelope',
|
134
|
+
'event': 'Event',
|
135
|
+
'exclamation-sign': 'Exclamation Sign',
|
136
|
+
'expand': 'Expand',
|
137
|
+
'expand-thin': 'Expand Thin',
|
138
|
+
'external': 'External',
|
139
|
+
'eye-open': 'Eye Open',
|
140
|
+
'facebook': 'Facebook',
|
141
|
+
'facebook-circle': 'Facebook Circle',
|
142
|
+
'fast_forward': 'Fast Forward',
|
143
|
+
'fast_rewind': 'Fast Rewind',
|
144
|
+
'fetch-as': 'Fetch As',
|
145
|
+
'file': 'File',
|
146
|
+
'filter-large': 'Filter Large',
|
147
|
+
'flip-horizontal': 'Flip Horizontal',
|
148
|
+
'flip-vertical': 'Flip Vertical',
|
149
|
+
'folder-close': 'Folder Close',
|
150
|
+
'folder-open': 'Folder Open',
|
151
|
+
'font': 'Font',
|
152
|
+
'forward-thin': 'Forward Thin',
|
153
|
+
'fullscreen': 'Fullscreen',
|
154
|
+
'globe': 'Globe',
|
155
|
+
'graphic': 'Graphic',
|
156
|
+
'grid-view': 'Grid View',
|
157
|
+
'grid-view-large': 'Grid View Large',
|
158
|
+
'heading-1': 'Heading 1',
|
159
|
+
'heading-2': 'Heading 2',
|
160
|
+
'heading-3': 'Heading 3',
|
161
|
+
'heading-4': 'Heading 4',
|
162
|
+
'heading-5': 'Heading 5',
|
163
|
+
'heading-6': 'Heading 6',
|
164
|
+
'heart': 'Heart',
|
165
|
+
'help-large': 'Help Large',
|
166
|
+
'highlight-package': 'Highlight Package',
|
167
|
+
'home': 'Home',
|
168
|
+
'indent-left': 'Indent Left',
|
169
|
+
'indent-right': 'Indent Right',
|
170
|
+
'info-large': 'Info Large',
|
171
|
+
'info-sign': 'Info Sign',
|
172
|
+
'ingest': 'Ingest',
|
173
|
+
'instagram': 'Instagram',
|
174
|
+
'italic': 'Italic',
|
175
|
+
'kanban-view': 'Kanban View',
|
176
|
+
'kill': 'Kill',
|
177
|
+
'link': 'Link',
|
178
|
+
'linked-in': 'LinkedIn',
|
179
|
+
'linked-in-circle': 'LinkedIn Circle',
|
180
|
+
'list-alt': 'List Alternate',
|
181
|
+
'list-menu': 'List Menu',
|
182
|
+
'list-plus': 'List Plus',
|
183
|
+
'list-view': 'List View',
|
184
|
+
'lock': 'Lock',
|
185
|
+
'map-marker': 'Map Marker',
|
186
|
+
'minus-sign': 'Minus Sign',
|
187
|
+
'minus-small': 'Minus Small',
|
188
|
+
'mobile': 'Mobile',
|
189
|
+
'move': 'Move',
|
190
|
+
'multi-star': 'Multi Start',
|
191
|
+
'multiedit': 'Multi Edit',
|
192
|
+
'new-doc': 'New Document',
|
193
|
+
'ok': 'Okay',
|
194
|
+
'ordered-list': 'Ordered List',
|
195
|
+
'package-create': 'Package Create',
|
196
|
+
'package-plus': 'Package Plus',
|
197
|
+
'paragraph': 'Paragraph',
|
198
|
+
'paste': 'Paste',
|
199
|
+
'pause': 'Pause',
|
200
|
+
'paywall': 'Paywall',
|
201
|
+
'pencil': 'Pencil',
|
202
|
+
'phone': 'Phone',
|
203
|
+
'photo': 'Photo',
|
204
|
+
'pick': 'Pick',
|
205
|
+
'picture': 'Picture',
|
206
|
+
'pin': 'Pin',
|
207
|
+
'play': 'Play',
|
208
|
+
'plus-large': 'Plus Large',
|
209
|
+
'plus-sign': 'Plus Sign',
|
210
|
+
'plus-small': 'Plus Small',
|
211
|
+
'post': 'Post',
|
212
|
+
'preformatted': 'Preformatted',
|
213
|
+
'preview-mode': 'Preview Mode',
|
214
|
+
'print': 'Print',
|
215
|
+
'question-sign': 'Question Sign',
|
216
|
+
'quote': 'Quote',
|
217
|
+
'random': 'Random',
|
218
|
+
'recurring': 'Recurring',
|
219
|
+
'redo': 'Redo',
|
220
|
+
'refresh': 'Refresh',
|
221
|
+
'remove-sign': 'Remove Sign',
|
222
|
+
'repeat': 'Repeat',
|
223
|
+
'retweet': 'Retweet',
|
224
|
+
'revert': 'Revert',
|
225
|
+
'rotate-left': 'Rotate Left',
|
226
|
+
'rotate-right': 'Rotate Right',
|
227
|
+
'search': 'Search',
|
228
|
+
'settings': 'Settings',
|
229
|
+
'share-alt': 'Share Alternate',
|
230
|
+
'signal': 'Signal',
|
231
|
+
'skip_next': 'Skip Next',
|
232
|
+
'skip_previous': 'Skip Previous',
|
233
|
+
'slideshow': 'Slideshow',
|
234
|
+
'star': 'Star',
|
235
|
+
'star-empty': 'Star Empty',
|
236
|
+
'stop': 'Stop',
|
237
|
+
'stream': 'Stream',
|
238
|
+
'strikethrough': 'Strikethrough',
|
239
|
+
'subscript': 'Subscript',
|
240
|
+
'suggestion': 'Suggestion',
|
241
|
+
'superscript': 'Superscript',
|
242
|
+
'switches': 'Switches',
|
243
|
+
'table': 'Table',
|
244
|
+
'takes-package': 'Takes Package',
|
245
|
+
'tasks': 'Tasks',
|
246
|
+
'text': 'Text',
|
247
|
+
'text-format': 'Text Format',
|
248
|
+
'th': 'Table Header',
|
249
|
+
'th-large': 'Table Header Large',
|
250
|
+
'th-list': 'Table Header List',
|
251
|
+
'time': 'Time',
|
252
|
+
'to-lowercase': 'To Lowercase',
|
253
|
+
'to-uppercase': 'To Uppercase',
|
254
|
+
'trash': 'Trash',
|
255
|
+
'twitter': 'Twitter',
|
256
|
+
'twitter-circle': 'Twitter Circle',
|
257
|
+
'underline': 'Underline',
|
258
|
+
'undo': 'Undo',
|
259
|
+
'unlocked': 'Unlocked',
|
260
|
+
'unordered-list': 'Unordered List',
|
261
|
+
'unspike': 'Unspike',
|
262
|
+
'upload': 'Upload',
|
263
|
+
'user': 'User',
|
264
|
+
'video': 'Video',
|
265
|
+
'warning-sign': 'Warning Sign',
|
266
|
+
'zoom-in': 'Zoom In',
|
267
|
+
'zoom-out': 'Zoom Out',
|
268
|
+
};
|
269
|
+
|
270
|
+
return iconFont.icon
|
271
|
+
.split(', ')
|
272
|
+
.sort()
|
273
|
+
.map((icon: string) => ({
|
274
|
+
value: icon,
|
275
|
+
label: translatedIconNameMap[icon] ? translateFunction(translatedIconNameMap[icon]) : icon,
|
276
|
+
}));
|
277
|
+
};
|
@@ -4,7 +4,7 @@ import nextId from "react-id-generator";
|
|
4
4
|
|
5
5
|
interface IProps {
|
6
6
|
value?: string;
|
7
|
-
label
|
7
|
+
label: string;
|
8
8
|
maxLength?: number;
|
9
9
|
info?: string;
|
10
10
|
error?: string;
|
@@ -12,6 +12,7 @@ interface IProps {
|
|
12
12
|
disabled?: boolean;
|
13
13
|
invalid?: boolean;
|
14
14
|
inlineLabel?: boolean;
|
15
|
+
labelHidden?: boolean;
|
15
16
|
onChange(newValue: string): void;
|
16
17
|
}
|
17
18
|
|
@@ -50,11 +51,15 @@ export class Input extends React.Component<IProps, IState> {
|
|
50
51
|
'sd-input--disabled': this.props.disabled,
|
51
52
|
'sd-input--invalid': this.props.invalid || this.state.invalid,
|
52
53
|
});
|
54
|
+
const labelClasses = classNames('sd-input__label', {
|
55
|
+
'a11y-only': this.props.labelHidden,
|
56
|
+
});
|
53
57
|
|
54
58
|
return (
|
55
59
|
<div className={classes}>
|
56
|
-
{this.
|
57
|
-
|
60
|
+
<label className={labelClasses} htmlFor={this.htmlId} id={this.htmlId + 'label'}>
|
61
|
+
{this.props.label}
|
62
|
+
</label>
|
58
63
|
|
59
64
|
<input className='sd-input__input'
|
60
65
|
type='text'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import { Skeleton } from './Skeleton';
|
3
|
+
|
4
|
+
export class ListItemLoader extends React.Component<{}> {
|
5
|
+
render() {
|
6
|
+
return (
|
7
|
+
<div className="sd-list-item sd-shadow--z1 sd-list-item--no-hover">
|
8
|
+
<div className="sd-list-item__border"></div>
|
9
|
+
<div className="sd-list-item__column">
|
10
|
+
<Skeleton shape="circle" size="2rem" />
|
11
|
+
</div>
|
12
|
+
<div className="sd-list-item__column sd-padding-y--1">
|
13
|
+
<Skeleton shape="circle" size="2rem" className="sd-margin-b--0-5" />
|
14
|
+
<Skeleton shape="circle" size="2rem" />
|
15
|
+
</div>
|
16
|
+
<div className="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
|
17
|
+
<div className="sd-list-item__row sd-padding-b--0-5">
|
18
|
+
<Skeleton borderRadius="16px" />
|
19
|
+
<Skeleton width="10rem" borderRadius="16px" className="sd-margin-l--0-5" />
|
20
|
+
</div>
|
21
|
+
<div className="sd-list-item__row">
|
22
|
+
<Skeleton width="8rem" borderRadius="16px" />
|
23
|
+
<Skeleton width="8rem" borderRadius="16px" className="sd-margin-l--0-5" />
|
24
|
+
<Skeleton width="8rem" borderRadius="16px" className="sd-margin-l--0-5" />
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
);
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,149 @@
|
|
1
|
+
import React, {SyntheticEvent} from 'react';
|
2
|
+
import {TieredMenu} from '@superdesk/primereact/tieredmenu';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Known issues:
|
6
|
+
*
|
7
|
+
* 1. Menu detaches from trigger element when scrolling.
|
8
|
+
* Closing the menu on scroll would fix it,
|
9
|
+
* but in case there are more items than
|
10
|
+
* can fit in the screen, some wouldn't be selectable.
|
11
|
+
*
|
12
|
+
* 2. In some cases, menus will be rendered outside of viewport.
|
13
|
+
* When the menu is triggered, it will check whether
|
14
|
+
* there is more space available on the left or right
|
15
|
+
* and will render submenus in that direction.
|
16
|
+
* It only checks available space relatively to the trigger element.
|
17
|
+
* If there's no space left after n submenus have been opened,
|
18
|
+
* it won't change direction.
|
19
|
+
*
|
20
|
+
* Accessibility features:
|
21
|
+
* * ESC closes the last sub-menu or entire menu
|
22
|
+
* * When menu is closed via ESC, focus returns to the element that was focused before opening the menu
|
23
|
+
* * Focuses the first item on activation
|
24
|
+
* * Focuses first sub-menu item when sub-menu opens
|
25
|
+
* * ENTER/ESC or arrow keys work for entering/leaving submenus
|
26
|
+
*/
|
27
|
+
|
28
|
+
export type IMenuItem = IMenuBranch | IMenuLeaf | ISeparator;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Available icons are listed here:
|
32
|
+
* https://ui-framework.superdesk.org/#/components/icons
|
33
|
+
*/
|
34
|
+
type IIconName = string;
|
35
|
+
|
36
|
+
interface ISeparator {
|
37
|
+
separator: true;
|
38
|
+
}
|
39
|
+
|
40
|
+
interface IMenuLeaf {
|
41
|
+
label: string;
|
42
|
+
icon?: IIconName;
|
43
|
+
onClick(): void;
|
44
|
+
disabled?: boolean;
|
45
|
+
}
|
46
|
+
|
47
|
+
interface IMenuBranch {
|
48
|
+
label: string;
|
49
|
+
icon?: IIconName;
|
50
|
+
children: Array<IMenuItem>;
|
51
|
+
}
|
52
|
+
|
53
|
+
interface IProps {
|
54
|
+
items: Array<IMenuItem>;
|
55
|
+
children: (toggle: (event: SyntheticEvent) => void) => JSX.Element;
|
56
|
+
zIndex?: number;
|
57
|
+
}
|
58
|
+
|
59
|
+
const superdeskTopBarZIndex = 1030;
|
60
|
+
|
61
|
+
export class Menu extends React.Component<IProps, {}> {
|
62
|
+
private menu: TieredMenu | null;
|
63
|
+
private focusedBefore: Element | null;
|
64
|
+
|
65
|
+
constructor(props: IProps) {
|
66
|
+
super(props);
|
67
|
+
|
68
|
+
this.menu = null;
|
69
|
+
this.focusedBefore = null;
|
70
|
+
|
71
|
+
this.close = this.close.bind(this);
|
72
|
+
this.toggle = this.toggle.bind(this);
|
73
|
+
this.toPrimeReactInterface = this.toPrimeReactInterface.bind(this);
|
74
|
+
}
|
75
|
+
|
76
|
+
private toPrimeReactInterface(items: Array<any>): any {
|
77
|
+
return items.map((item) => {
|
78
|
+
if (item.separator != null) {
|
79
|
+
return {separator: true};
|
80
|
+
} else if (item.children != null) {
|
81
|
+
return {
|
82
|
+
label: item.label,
|
83
|
+
icon: item.icon,
|
84
|
+
items: this.toPrimeReactInterface(item.children),
|
85
|
+
};
|
86
|
+
} else {
|
87
|
+
return {
|
88
|
+
label: item.label,
|
89
|
+
icon: item.icon,
|
90
|
+
command: (event: SyntheticEvent) => {
|
91
|
+
this.close(event);
|
92
|
+
item.onClick();
|
93
|
+
},
|
94
|
+
disabled: item.disabled,
|
95
|
+
};
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
private toggle(event: SyntheticEvent) {
|
101
|
+
this.menu?.toggle(event);
|
102
|
+
}
|
103
|
+
|
104
|
+
private close(event: SyntheticEvent) {
|
105
|
+
this.menu?.toggle(event);
|
106
|
+
}
|
107
|
+
|
108
|
+
render() {
|
109
|
+
return (
|
110
|
+
<div>
|
111
|
+
{
|
112
|
+
this.props.children(this.toggle)
|
113
|
+
}
|
114
|
+
|
115
|
+
<div
|
116
|
+
onKeyDown={(event) => {
|
117
|
+
if (event.key === 'Escape') {
|
118
|
+
event.stopPropagation();
|
119
|
+
|
120
|
+
this.close(event);
|
121
|
+
|
122
|
+
if (this.focusedBefore instanceof HTMLElement) {
|
123
|
+
this.focusedBefore.focus();
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}}
|
127
|
+
>
|
128
|
+
<TieredMenu
|
129
|
+
popup
|
130
|
+
model={this.toPrimeReactInterface(this.props.items)}
|
131
|
+
ref={(el) => this.menu = el}
|
132
|
+
appendTo={document.body}
|
133
|
+
onShow={() => {
|
134
|
+
this.focusedBefore = document.activeElement;
|
135
|
+
|
136
|
+
const firstMenuItem = document.querySelectorAll('.p-tieredmenu [role="menuitem"]')[0];
|
137
|
+
|
138
|
+
if (firstMenuItem instanceof HTMLElement) {
|
139
|
+
firstMenuItem.focus();
|
140
|
+
}
|
141
|
+
}}
|
142
|
+
data-test-id="menu"
|
143
|
+
baseZIndex={this.props.zIndex ?? superdeskTopBarZIndex}
|
144
|
+
/>
|
145
|
+
</div>
|
146
|
+
</div>
|
147
|
+
);
|
148
|
+
}
|
149
|
+
}
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
2
2
|
|
3
3
|
interface IProps {
|
4
4
|
name: string;
|
5
|
-
|
5
|
+
isRequired: boolean;
|
6
6
|
type: string;
|
7
7
|
default: string;
|
8
8
|
description: string;
|
@@ -14,7 +14,7 @@ class Prop extends React.PureComponent<IProps> {
|
|
14
14
|
<React.Fragment>
|
15
15
|
<tr>
|
16
16
|
<td>{this.props.name}</td>
|
17
|
-
<td>{this.props.
|
17
|
+
<td>{this.props.isRequired ? 'yes' : 'no'}</td>
|
18
18
|
<td>{this.props.type}</td>
|
19
19
|
<td>{this.props.default}</td>
|
20
20
|
<td>{this.props.description}</td>
|
@@ -1,15 +1,18 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
-
import nextId from
|
2
|
+
import nextId from 'react-id-generator';
|
3
|
+
|
4
|
+
interface IOption {
|
5
|
+
label: string;
|
6
|
+
value: string;
|
7
|
+
disabled?: boolean;
|
8
|
+
}
|
9
|
+
|
3
10
|
interface IProps {
|
4
|
-
value?:
|
5
|
-
options: Array<
|
6
|
-
label: string,
|
7
|
-
value: string,
|
8
|
-
disabled?: boolean
|
9
|
-
}>;
|
11
|
+
value?: IOption['value'];
|
12
|
+
options: Array<IOption>;
|
10
13
|
labelSide?: 'left' | 'right'; // defaults to 'right'
|
11
14
|
required?: boolean;
|
12
|
-
onChange(nextValue:
|
15
|
+
onChange(nextValue: IOption['value']): void;
|
13
16
|
}
|
14
17
|
export class Radio extends React.Component<IProps> {
|
15
18
|
htmlId = nextId();
|
@@ -33,11 +36,17 @@ export class Radio extends React.Component<IProps> {
|
|
33
36
|
label-position={this.props.labelSide || null}
|
34
37
|
tabIndex={-1}>
|
35
38
|
|
36
|
-
<input
|
39
|
+
<input
|
40
|
+
type="radio"
|
41
|
+
className="sd-check-new__input"
|
42
|
+
id={this.htmlId + index}
|
43
|
+
tabIndex={0}
|
37
44
|
name={this.htmlId}
|
38
45
|
onChange={() => this.handleChange(item)}
|
39
46
|
disabled={item.disabled}
|
40
|
-
required={this.props.required}
|
47
|
+
required={this.props.required}
|
48
|
+
checked={item.value === this.props.value}
|
49
|
+
/>
|
41
50
|
|
42
51
|
<span className="sd-radio-new"></span>
|
43
52
|
<label htmlFor={this.htmlId + index} >{item.label}</label>
|
@@ -4,13 +4,14 @@ import nextId from "react-id-generator";
|
|
4
4
|
|
5
5
|
interface ISelect {
|
6
6
|
value?: string;
|
7
|
-
label
|
7
|
+
label: string;
|
8
8
|
info?: string;
|
9
9
|
error?: string;
|
10
10
|
required?: boolean;
|
11
11
|
disabled?: boolean;
|
12
12
|
invalid?: boolean;
|
13
13
|
inlineLabel?: boolean;
|
14
|
+
labelHidden?: boolean;
|
14
15
|
onChange(newValue: string): void;
|
15
16
|
}
|
16
17
|
|
@@ -45,11 +46,13 @@ class Select extends React.Component<ISelect, IState> {
|
|
45
46
|
'sd-input--disabled': this.props.disabled,
|
46
47
|
'sd-input--invalid': this.props.invalid || this.state.invalid,
|
47
48
|
});
|
49
|
+
const labelClasses = classNames('sd-input__label', {
|
50
|
+
'a11y-only': this.props.labelHidden,
|
51
|
+
});
|
48
52
|
|
49
53
|
return (
|
50
54
|
<div className={classes}>
|
51
|
-
{this.props.label
|
52
|
-
<label className='sd-input__label' htmlFor={this.htmlId}>{this.props.label}</label> : null}
|
55
|
+
<label className={labelClasses} htmlFor={this.htmlId}>{this.props.label}</label>
|
53
56
|
|
54
57
|
<select className='sd-input__select'
|
55
58
|
id={this.htmlId}
|