superdesk-ui-framework 2.4.10 → 2.4.15

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.
Files changed (42) hide show
  1. package/app/scripts/modals.js +22 -9
  2. package/app/styles/app.scss +1 -0
  3. package/app/styles/form-elements/_select-grid.scss +77 -0
  4. package/app/styles/pr-superdesk-theme.scss +1 -0
  5. package/app/styles/primereact/_pr-skeleton.scss +35 -0
  6. package/app-typescript/components/IconPicker.tsx +277 -0
  7. package/app-typescript/components/ListItemLoader.tsx +30 -0
  8. package/app-typescript/components/SelectGrid.tsx +233 -0
  9. package/app-typescript/components/Skeleton.tsx +48 -0
  10. package/app-typescript/components/Tag.tsx +4 -3
  11. package/app-typescript/index.ts +5 -0
  12. package/dist/components/modals.html +1 -0
  13. package/dist/examples.bundle.js +3051 -1766
  14. package/dist/react/IconFont.tsx +7 -6
  15. package/dist/react/IconPicker.tsx +65 -0
  16. package/dist/react/Index.tsx +16 -1
  17. package/dist/react/ListItems.tsx +34 -0
  18. package/dist/react/SelectGrid.tsx +121 -0
  19. package/dist/react/Tags.tsx +14 -3
  20. package/dist/superdesk-ui.bundle.css +3356 -0
  21. package/dist/superdesk-ui.bundle.js +2563 -1480
  22. package/dist/vendor.bundle.js +49646 -49624
  23. package/examples/pages/components/modals.html +1 -0
  24. package/examples/pages/react/IconFont.tsx +7 -6
  25. package/examples/pages/react/IconPicker.tsx +65 -0
  26. package/examples/pages/react/Index.tsx +16 -1
  27. package/examples/pages/react/ListItems.tsx +34 -0
  28. package/examples/pages/react/SelectGrid.tsx +121 -0
  29. package/examples/pages/react/Tags.tsx +14 -3
  30. package/package.json +1 -1
  31. package/react/components/IconPicker.d.ts +24 -0
  32. package/react/components/IconPicker.js +283 -0
  33. package/react/components/ListItemLoader.d.ts +4 -0
  34. package/react/components/ListItemLoader.js +62 -0
  35. package/react/components/SelectGrid.d.ts +45 -0
  36. package/react/components/SelectGrid.js +179 -0
  37. package/react/components/Skeleton.d.ts +30 -0
  38. package/react/components/Skeleton.js +55 -0
  39. package/react/components/Tag.d.ts +2 -1
  40. package/react/components/Tag.js +3 -3
  41. package/react/index.d.ts +4 -0
  42. package/react/index.js +8 -0
@@ -4,12 +4,12 @@ sdModal.$inject = ['$document', '$rootScope'];
4
4
  function sdModal($document, $rootScope) {
5
5
  return {
6
6
  template:
7
- `<div class="modal" data-theme="{{theme}}" data-backdrop="static" data-test-id="{{testId}}">
8
- <div class="modal__dialog" ng-if="model">
9
- <div class="modal__content" ng-transclude></div>
10
- </div>
11
- </div>
12
- <div class="modal__backdrop fade in" ng-if="model"></div>`,
7
+ `<div class="modal" data-theme="{{theme}}" data-backdrop="static" data-test-id="{{testId}}">
8
+ <div class="modal__dialog" ng-if="model">
9
+ <div class="modal__content" ng-transclude></div>
10
+ </div>
11
+ </div>
12
+ <div class="modal__backdrop fade in" ng-if="model"></div>`,
13
13
  transclude: true,
14
14
  scope: {
15
15
  model: '=',
@@ -31,25 +31,38 @@ function sdModal($document, $rootScope) {
31
31
  content[0].style = 'z-index: ' + (1050 + $rootScope.modals);
32
32
  content[1].style = 'z-index: ' + (1049 + $rootScope.modals);
33
33
  _initialized = true;
34
+ console.log(content);
34
35
  }
35
36
  content.show().addClass('in');
36
37
  $document.find('body').addClass('modal-open');
37
38
  $rootScope.modals++;
38
39
  } else if (initialized()) {
39
40
  content.hide().removeClass('in');
40
- $document.find('body').removeClass('modal-open');
41
+
42
+ // If multiple modals are opened,
43
+ // remove modal class only when last one is closed
44
+ if ($rootScope.modals === 1) {
45
+ $document.find('body').removeClass('modal-open');
46
+ }
47
+
41
48
  closeModal();
42
49
  }
43
50
  });
44
51
 
45
52
  var closeModal = function () {
46
53
  scope.model = false;
47
- $rootScope.modals--;
54
+
55
+ if ($rootScope.modals > 0) {
56
+ $rootScope.modals--;
57
+ }
58
+
48
59
  scope.$evalAsync();
49
60
  };
50
61
 
51
62
  $document.bind('keydown', (evt) => {
52
- if (evt.which === 27) {
63
+ evt.preventDefault();
64
+
65
+ if (evt.which === 27 && $rootScope.modals > 0) {
53
66
  closeModal();
54
67
  }
55
68
  });
@@ -73,6 +73,7 @@
73
73
  @import 'form-elements/checkbox';
74
74
  @import 'form-elements/radio';
75
75
  @import 'form-elements/autocomplete';
76
+ @import 'form-elements/select-grid';
76
77
 
77
78
  // Menus
78
79
  @import 'menus/sd-sidebar-menu';
@@ -0,0 +1,77 @@
1
+ .select-grid__overlay-panel {
2
+ z-index: 1500 !important;
3
+ margin-top: 1px;
4
+ }
5
+
6
+ .select-grid__panel {
7
+ width: 450px;
8
+ max-height: 550px;
9
+ background-color: var(--color-bg-00);
10
+ display: flex;
11
+ flex-direction: column;
12
+ }
13
+
14
+ .select-grid__header {
15
+ padding: 1rem;
16
+ box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.1);
17
+ }
18
+
19
+ .select-grid__body {
20
+ overflow-y: auto;
21
+ margin: 0;
22
+ padding: 1rem;
23
+ position: relative;
24
+ }
25
+
26
+ .select-grid__item {
27
+ display: flex;
28
+ flex-direction: column;
29
+ align-items: center;
30
+ color: $sd-text;
31
+
32
+ &:hover, &:focus {
33
+ color: $sd-blue;
34
+ cursor: pointer;
35
+
36
+ i {
37
+ color: $sd-blue;
38
+ }
39
+ }
40
+
41
+ &:hover {
42
+ background: $sd-colour-background__menu-item--hover;
43
+ }
44
+
45
+ &:focus {
46
+ outline: 2px solid $sd-colour-interactive__base;
47
+ outline-offset: -2px;
48
+ }
49
+ }
50
+
51
+ .sd-input--grid-select {
52
+ .btn {
53
+ grid-row: 2/3;
54
+ grid-column: 2/4;
55
+ background-color: var(--color-input-bg);
56
+ border-bottom: 1px solid var(--color-input-border);
57
+ width: 3.2rem;
58
+ }
59
+
60
+ .btn:hover {
61
+ background-color: var(--color-input-bg--hover);
62
+ border-color: var(--color-input-border-hover);
63
+ }
64
+
65
+ .btn:focus {
66
+ background-color: var(--color-input-bg--focus);
67
+ box-shadow: 0 1px 0 0 $sd-blue;
68
+ }
69
+ }
70
+
71
+ .form__item--auto-width {
72
+ .sd-input--grid-select {
73
+ .btn {
74
+ margin-top: 0;
75
+ }
76
+ }
77
+ }
@@ -4,3 +4,4 @@
4
4
  @import 'primereact/pr-datepicker.scss';
5
5
  @import 'primereact/pr-dialog.scss';
6
6
  @import 'primereact/pr-menu.scss';
7
+ @import 'primereact/pr-skeleton.scss';
@@ -0,0 +1,35 @@
1
+ .p-skeleton {
2
+ position: relative;
3
+ overflow: hidden;
4
+ background-color: #e9ecef;
5
+ }
6
+
7
+ .p-skeleton::after {
8
+ content: "";
9
+ animation: p-skeleton-animation 1.2s infinite;
10
+ height: 100%;
11
+ left: 0;
12
+ position: absolute;
13
+ right: 0;
14
+ top: 0;
15
+ transform: translateX(-100%);
16
+ z-index: 1;
17
+ background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0));
18
+ }
19
+
20
+ .p-skeleton-circle {
21
+ border-radius: 50%;
22
+ }
23
+
24
+ .p-skeleton-none::after {
25
+ animation: none;
26
+ }
27
+
28
+ @keyframes p-skeleton-animation {
29
+ from {
30
+ transform: translateX(-100%);
31
+ }
32
+ to {
33
+ transform: translateX(100%);
34
+ }
35
+ }
@@ -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
+ };
@@ -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
+ }