goblin-magic 1.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.
Files changed (88) hide show
  1. package/.editorconfig +9 -0
  2. package/.zou-flow +2 -0
  3. package/eslint.config.js +65 -0
  4. package/magicNavigation.js +7 -0
  5. package/package.json +45 -0
  6. package/widgets/dialog/widget.js +78 -0
  7. package/widgets/element-helpers/element-has-direct-text.js +9 -0
  8. package/widgets/element-helpers/is-empty-area-element.js +17 -0
  9. package/widgets/element-helpers/is-flat-element.js +52 -0
  10. package/widgets/get-modifiers/get-modifiers.js +34 -0
  11. package/widgets/input-group/styles.js +74 -0
  12. package/widgets/input-group/widget.js +24 -0
  13. package/widgets/magic-action/styles.js +45 -0
  14. package/widgets/magic-action/widget.js +44 -0
  15. package/widgets/magic-background/bg-alps.jpg +0 -0
  16. package/widgets/magic-background/bg-fur.png +0 -0
  17. package/widgets/magic-background/bg-milkyway.png +0 -0
  18. package/widgets/magic-background/bg-space.jpg +0 -0
  19. package/widgets/magic-background/bg-synth.jpg +0 -0
  20. package/widgets/magic-background/bg-white.png +0 -0
  21. package/widgets/magic-background/styles.js +81 -0
  22. package/widgets/magic-background/widget.js +20 -0
  23. package/widgets/magic-box/styles.js +10 -0
  24. package/widgets/magic-box/widget.js +28 -0
  25. package/widgets/magic-box-old/styles.js +111 -0
  26. package/widgets/magic-box-old/widget.js +30 -0
  27. package/widgets/magic-button/styles.js +156 -0
  28. package/widgets/magic-button/widget.js +89 -0
  29. package/widgets/magic-checkbox/styles.js +116 -0
  30. package/widgets/magic-checkbox/widget.js +68 -0
  31. package/widgets/magic-color-field/styles.js +22 -0
  32. package/widgets/magic-color-field/widget.js +68 -0
  33. package/widgets/magic-date-field/styles.js +9 -0
  34. package/widgets/magic-date-field/widget.js +145 -0
  35. package/widgets/magic-datetime-field/styles.js +11 -0
  36. package/widgets/magic-datetime-field/widget.js +95 -0
  37. package/widgets/magic-dialog/styles.js +39 -0
  38. package/widgets/magic-dialog/widget.js +116 -0
  39. package/widgets/magic-div/styles.js +22 -0
  40. package/widgets/magic-div/widget.js +20 -0
  41. package/widgets/magic-emoji/styles.js +14 -0
  42. package/widgets/magic-emoji/widget.js +33 -0
  43. package/widgets/magic-emoji-picker/styles.js +21 -0
  44. package/widgets/magic-emoji-picker/widget.js +44 -0
  45. package/widgets/magic-inplace-input/styles.js +55 -0
  46. package/widgets/magic-inplace-input/widget.js +26 -0
  47. package/widgets/magic-input/styles.js +50 -0
  48. package/widgets/magic-input/widget.js +397 -0
  49. package/widgets/magic-label/styles.js +20 -0
  50. package/widgets/magic-label/widget.js +24 -0
  51. package/widgets/magic-navigation/service.js +1306 -0
  52. package/widgets/magic-navigation/styles.js +103 -0
  53. package/widgets/magic-navigation/view-context.js +15 -0
  54. package/widgets/magic-navigation/widget.js +540 -0
  55. package/widgets/magic-number-field/styles.js +10 -0
  56. package/widgets/magic-number-field/widget.js +103 -0
  57. package/widgets/magic-panel/styles.js +61 -0
  58. package/widgets/magic-panel/widget.js +63 -0
  59. package/widgets/magic-radio/styles.js +93 -0
  60. package/widgets/magic-radio/widget.js +74 -0
  61. package/widgets/magic-scroll/styles.js +22 -0
  62. package/widgets/magic-scroll/widget.js +20 -0
  63. package/widgets/magic-select/styles.js +16 -0
  64. package/widgets/magic-select/widget.js +134 -0
  65. package/widgets/magic-table/reducer.js +63 -0
  66. package/widgets/magic-table/styles.js +170 -0
  67. package/widgets/magic-table/widget.js +627 -0
  68. package/widgets/magic-tag/styles.js +32 -0
  69. package/widgets/magic-tag/widget.js +32 -0
  70. package/widgets/magic-text-field/styles.js +58 -0
  71. package/widgets/magic-text-field/widget.js +66 -0
  72. package/widgets/magic-time-field/styles.js +8 -0
  73. package/widgets/magic-time-field/widget.js +142 -0
  74. package/widgets/magic-timer/styles.js +30 -0
  75. package/widgets/magic-timer/widget.js +162 -0
  76. package/widgets/magic-zen/styles.js +61 -0
  77. package/widgets/magic-zen/widget.js +42 -0
  78. package/widgets/main-tabs/styles.js +106 -0
  79. package/widgets/main-tabs/widget.js +23 -0
  80. package/widgets/menu/styles.js +156 -0
  81. package/widgets/menu/test-menu.html +154 -0
  82. package/widgets/menu/widget.js +575 -0
  83. package/widgets/movable/widget.js +80 -0
  84. package/widgets/splitter/styles.js +57 -0
  85. package/widgets/splitter/widget.js +40 -0
  86. package/widgets/tab-layout/styles.js +31 -0
  87. package/widgets/tab-layout/widget.js +59 -0
  88. package/widgets/with-computed-size/widget.js +52 -0
@@ -0,0 +1,627 @@
1
+ import * as styles from './styles.js';
2
+ import React from 'react';
3
+ import debounce from 'lodash/debounce.js';
4
+ import Widget from 'goblin-laboratory/widgets/widget';
5
+ import withC from 'goblin-laboratory/widgets/connect-helpers/with-c';
6
+ import {faSquare, faCheckSquare} from '@fortawesome/free-regular-svg-icons';
7
+ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
8
+ import Shredder from 'xcraft-core-shredder';
9
+ import getModifiers from '../get-modifiers/get-modifiers.js';
10
+ import ErrorHandler from 'goblin-laboratory/widgets/error-handler/widget.js';
11
+ import Icon from '@mdi/react';
12
+ import {
13
+ mdiChevronUp,
14
+ mdiChevronDown,
15
+ mdiMenuDown,
16
+ mdiSetNone,
17
+ mdiSortAlphabeticalAscending,
18
+ mdiSortAlphabeticalDescending,
19
+ } from '@mdi/js';
20
+
21
+ function parseDate(value) {
22
+ if (!value) {
23
+ return '';
24
+ }
25
+ const [d, m, y] = value.split('.');
26
+ const day = parseInt(d);
27
+ const month = parseInt(m) - 1;
28
+ if (y.length > 4) {
29
+ const [year, time] = y.split(' ');
30
+ const [h, m] = time.split(':');
31
+ return new Date(parseInt(year), month, day, parseInt(h), parseInt(m));
32
+ } else {
33
+ const year = parseInt(y);
34
+ return new Date(year, month, day);
35
+ }
36
+ }
37
+
38
+ function parseString(value) {
39
+ if (!value) {
40
+ return '';
41
+ }
42
+ return value;
43
+ }
44
+
45
+ function defaultGetRowId(row) {
46
+ if (Shredder.isShredder(row) || Shredder.isImmutable(row)) {
47
+ if (row.has('id')) {
48
+ return row.get('id');
49
+ }
50
+ throw new Error(
51
+ "Unable to get the row id. Please define the 'getRowId' prop of <MagicTable>."
52
+ );
53
+ }
54
+ if (typeof row === 'object' && row !== null) {
55
+ if ('id' in row) {
56
+ return row.id;
57
+ }
58
+ throw new Error(
59
+ "Unable to get the row id. Please define the 'getRowId' prop of <MagicTable>."
60
+ );
61
+ }
62
+ return row;
63
+ }
64
+
65
+ function defaultRenderRow(row, columns) {
66
+ return columns.map((col, index) => (
67
+ <React.Fragment key={index}>
68
+ {col.renderItem ? col.renderItem(row) : <span>{row[col.id]}</span>}
69
+ </React.Fragment>
70
+ ));
71
+ }
72
+
73
+ const hr = Symbol('magic-table-hr');
74
+
75
+ class MagicTableRow extends Widget {
76
+ constructor() {
77
+ super(...arguments);
78
+ this.styles = styles;
79
+ this.row = React.createRef();
80
+ this.observer = null;
81
+ }
82
+
83
+ componentDidMount() {
84
+ this.observer = new MutationObserver((mutations, observer) => {
85
+ for (const mutation of mutations) {
86
+ this.props.onUpdate(mutation.target.data);
87
+ }
88
+ });
89
+ this.observer.observe(this.row.current, {
90
+ subtree: true,
91
+ childList: true,
92
+ characterData: true,
93
+ attributeFilter: ['data-rowId'],
94
+ });
95
+ }
96
+
97
+ componentWillUnmount() {
98
+ this.observer.disconnect();
99
+ }
100
+
101
+ handleClick = (event) => {
102
+ this.props.onRowClick?.(this.props.row, event);
103
+ };
104
+
105
+ render() {
106
+ const {
107
+ index,
108
+ renderRow = defaultRenderRow,
109
+ row,
110
+ onRowClick,
111
+ columns,
112
+ children,
113
+ className = '',
114
+ onUpdate,
115
+ ...props
116
+ } = this.props;
117
+ return (
118
+ <div
119
+ {...props}
120
+ onClick={this.handleClick}
121
+ className={this.styles.classNames.magicTableRow + ' ' + className}
122
+ data-clickable={Boolean(onRowClick)}
123
+ data-rowid={index}
124
+ ref={this.row}
125
+ >
126
+ {children || renderRow(row, columns, index)}
127
+ </div>
128
+ );
129
+ }
130
+ }
131
+
132
+ class MagicTableRows extends Widget {
133
+ constructor() {
134
+ super(...arguments);
135
+ this.styles = styles;
136
+ }
137
+
138
+ renderRow = (row, index) => {
139
+ const {
140
+ rows,
141
+ columns,
142
+ renderRow,
143
+ getRowId,
144
+ onRowClick,
145
+ ...props
146
+ } = this.props;
147
+ if (row === hr) {
148
+ return (
149
+ <React.Fragment key={index}>
150
+ {/* Empty row to keep the same style for :nth-child(2n) */}
151
+ <div className={this.styles.classNames.emptyRow} />
152
+ <div className={this.styles.classNames.rowSeparator} />
153
+ </React.Fragment>
154
+ );
155
+ }
156
+ const rowId = getRowId(row, index);
157
+ const rowKey = rowId !== undefined ? rowId : index;
158
+ return (
159
+ <MagicTableRow
160
+ {...props}
161
+ key={rowKey}
162
+ index={index}
163
+ renderRow={renderRow}
164
+ row={row}
165
+ onRowClick={onRowClick}
166
+ columns={columns}
167
+ />
168
+ );
169
+ };
170
+
171
+ render() {
172
+ const {rows} = this.props;
173
+ return (
174
+ <ErrorHandler>
175
+ {rows.map((row, index) => this.renderRow(row, index))}
176
+ </ErrorHandler>
177
+ );
178
+ }
179
+ }
180
+
181
+ class MagicTableContainer extends Widget {
182
+ constructor() {
183
+ super(...arguments);
184
+ this.styles = styles;
185
+ this.table = React.createRef();
186
+ }
187
+
188
+ getColumnSet = (colIndex) => {
189
+ const table = this.table.current;
190
+ if (!table) {
191
+ return [];
192
+ }
193
+ const rows = Array.from(table.children);
194
+
195
+ return Array.from(
196
+ new Set(
197
+ rows
198
+ .filter((el) => el.getAttribute('data-rowId') !== null)
199
+ .map((el) => el.childNodes[colIndex]?.textContent || 'vide')
200
+ ).values()
201
+ );
202
+ };
203
+
204
+ sort = (colIndex, type, sortOrder, sortCustom) => {
205
+ const table = this.table.current;
206
+ if (!table) {
207
+ console.warn('sort not ready');
208
+ setTimeout(this.sort, 50);
209
+ return;
210
+ }
211
+ const rows = Array.from(table.children);
212
+ if (sortOrder === '-') {
213
+ rows
214
+ .filter((el) => el.getAttribute('data-rowId') !== null)
215
+ .sort((a, b) => {
216
+ let valueA = a.getAttribute('data-rowId');
217
+ let valueB = b.getAttribute('data-rowId');
218
+ return valueA - valueB;
219
+ })
220
+ .forEach((el) => {
221
+ table.append(el);
222
+ });
223
+ return;
224
+ }
225
+ rows
226
+ .filter((el) => el.getAttribute('data-rowId') !== null)
227
+ .sort((a, b) => {
228
+ let valueA = a.childNodes[colIndex]?.textContent;
229
+ let valueB = b.childNodes[colIndex]?.textContent;
230
+ switch (type) {
231
+ case 'date':
232
+ valueA = parseDate(valueA);
233
+ valueB = parseDate(valueB);
234
+ break;
235
+ case 'number':
236
+ case 'money':
237
+ valueA = parseInt(valueA);
238
+ valueB = parseInt(valueB);
239
+ break;
240
+ case 'custom': {
241
+ const res = sortCustom(
242
+ a.childNodes[colIndex],
243
+ b.childNodes[colIndex]
244
+ );
245
+ return sortOrder === 'asc' ? res : res * -1;
246
+ }
247
+ default: {
248
+ valueA = parseString(valueA);
249
+ valueB = parseString(valueB);
250
+ const res = new Intl.Collator().compare(valueA, valueB);
251
+ return sortOrder === 'asc' ? res : res * -1;
252
+ }
253
+ }
254
+ if (valueA < valueB) {
255
+ return sortOrder === 'asc' ? -1 : 1;
256
+ }
257
+ if (valueA > valueB) {
258
+ return sortOrder === 'asc' ? 1 : -1;
259
+ }
260
+ return 0;
261
+ })
262
+ .forEach((el) => {
263
+ table.append(el);
264
+ });
265
+ };
266
+
267
+ updateSort = (reason) => {
268
+ const {sortable, sortIndex, sortType, sortOrder, sortCustom} = this.props;
269
+ if (sortable) {
270
+ this.sort(sortIndex, sortType, sortOrder, sortCustom);
271
+ console.log('sort updated :', reason);
272
+ }
273
+ };
274
+
275
+ componentDidMount() {
276
+ super.componentDidMount();
277
+ this.updateSort('table container mounted');
278
+ }
279
+
280
+ componentDidUpdate() {
281
+ this.updateSort('table container updated');
282
+ }
283
+
284
+ render() {
285
+ const {
286
+ className = '',
287
+ children,
288
+ sortable,
289
+ sortIndex,
290
+ sortType,
291
+ sortOrder,
292
+ sortCustom,
293
+ showMenu,
294
+ dispatch,
295
+ ...props
296
+ } = this.props;
297
+
298
+ return (
299
+ <div
300
+ {...props}
301
+ className={this.styles.classNames.magicTable + ' ' + className}
302
+ ref={this.table}
303
+ >
304
+ {children}
305
+ </div>
306
+ );
307
+ }
308
+ }
309
+
310
+ class TableCheck extends Widget {
311
+ constructor() {
312
+ super(...arguments);
313
+ this.styles = styles;
314
+ }
315
+
316
+ render() {
317
+ const {checked, onClick} = this.props;
318
+ return (
319
+ <div
320
+ onClick={onClick}
321
+ className={this.styles.classNames.tableCheck}
322
+ data-checked={checked}
323
+ >
324
+ {checked ? (
325
+ <FontAwesomeIcon icon={faCheckSquare} />
326
+ ) : (
327
+ <FontAwesomeIcon icon={faSquare} />
328
+ )}
329
+ </div>
330
+ );
331
+ }
332
+ }
333
+
334
+ let MagicTable = class extends Widget {
335
+ selectedRows = new Map();
336
+
337
+ constructor() {
338
+ super(...arguments);
339
+ this.styles = styles;
340
+ this.container = React.createRef();
341
+ this.state = {
342
+ selection: [],
343
+ };
344
+ if (this.props.id) {
345
+ this.dispatch({
346
+ type: 'INITIALISE',
347
+ id: this.props.id,
348
+ columns: this.props.columns,
349
+ });
350
+ }
351
+ this.onUpdate = debounce(this.onUpdate, 1000);
352
+ }
353
+
354
+ componentDidUpdate() {
355
+ this.onUpdate();
356
+ }
357
+
358
+ handleRowClick = (row, event) => {
359
+ const modifiers = getModifiers(event);
360
+ if (
361
+ this.props.selectable &&
362
+ modifiers.ctrlKey &&
363
+ !modifiers.altKey &&
364
+ !modifiers.metaKey
365
+ ) {
366
+ this.toggleSelection(row, event);
367
+ } else {
368
+ this.props.onRowClick?.(row, event);
369
+ }
370
+ };
371
+
372
+ setSelection(selection) {
373
+ this.setState({
374
+ selection,
375
+ });
376
+ this.props.onSelectionChange?.(selection);
377
+ }
378
+
379
+ toggleAll = (event) => {
380
+ const currentSelection = this.props.selection ?? this.state.selection;
381
+ if (currentSelection.length > 0) {
382
+ this.setSelection([]);
383
+ } else {
384
+ this.setSelection([...this.props.data]);
385
+ }
386
+ event.stopPropagation();
387
+ };
388
+
389
+ toggleSelection = (row, event) => {
390
+ const {getRowId = defaultGetRowId} = this.props;
391
+ const currentSelection = this.props.selection ?? this.state.selection;
392
+ const rowId = getRowId(row);
393
+ const index = currentSelection.findIndex(
394
+ (selectedRow) => getRowId(selectedRow) === rowId
395
+ );
396
+ if (index >= 0) {
397
+ this.setSelection(currentSelection.toSpliced(index, 1));
398
+ } else {
399
+ this.setSelection([...currentSelection, row]);
400
+ }
401
+ event.stopPropagation();
402
+ };
403
+
404
+ onUpdate = (reason = 'onUpdate') => {
405
+ if (this.container.current) {
406
+ this.container.current.updateSort(reason);
407
+ }
408
+ };
409
+
410
+ render() {
411
+ let {
412
+ data,
413
+ columns,
414
+ renderRow = defaultRenderRow,
415
+ onRowClick = undefined,
416
+ selectable = false,
417
+ selection = this.state.selection,
418
+ onSelectionChange,
419
+ getRowId = defaultGetRowId,
420
+ className = '',
421
+ rowClassName = '',
422
+ style = {},
423
+ children,
424
+ ...props
425
+ } = this.props;
426
+
427
+ let additionalRows;
428
+ if (selectable) {
429
+ const selectedRowIds = selection.map(getRowId);
430
+ const rowIds = data.map(getRowId);
431
+ additionalRows = selection.filter(
432
+ (row) => !rowIds.includes(getRowId(row))
433
+ );
434
+ columns = [
435
+ {
436
+ title: (
437
+ <div
438
+ className={this.styles.classNames.selectionTitle}
439
+ onClick={this.toggleAll}
440
+ >
441
+ <FontAwesomeIcon icon={faSquare} />
442
+ </div>
443
+ ),
444
+ },
445
+ ...columns,
446
+ ];
447
+ renderRow = ((_renderRow) => (row, ...args) => (
448
+ <>
449
+ <TableCheck
450
+ checked={selectedRowIds.includes(getRowId(row))}
451
+ onClick={(event) => this.toggleSelection(row, event)}
452
+ />
453
+ {_renderRow(row, ...args)}
454
+ </>
455
+ ))(renderRow);
456
+ }
457
+
458
+ let last = '1fr';
459
+ const gridTemplateColumns = columns
460
+ .map((col, idx) => {
461
+ if (col.width) last = 'fit-content(100%)';
462
+ return (
463
+ col.width || (idx === columns.length - 1 ? last : 'fit-content(100%)')
464
+ );
465
+ })
466
+ .join(' ');
467
+
468
+ const hasClick = selectable || onRowClick;
469
+ const sortable = columns.some((col) => col.sortable);
470
+
471
+ const rows =
472
+ additionalRows && additionalRows.length > 0
473
+ ? [...additionalRows, hr, ...data]
474
+ : data;
475
+
476
+ return (
477
+ <MagicTableContainer
478
+ {...props}
479
+ className={className}
480
+ style={{gridTemplateColumns, ...style}}
481
+ ref={this.container}
482
+ sortable={sortable}
483
+ sortIndex={this.props.sortIndex}
484
+ sortType={this.props.sortType}
485
+ sortOrder={this.props.sortOrder}
486
+ sortCustom={this.props.sortCustom}
487
+ >
488
+ <div className={this.styles.classNames.tableHeader}>
489
+ {columns.map((col, index) => {
490
+ let sort = null;
491
+ const useMenu = col.autoFilter;
492
+ const isSorted =
493
+ this.props.sortIndex === index && this.props.sortOrder !== '-';
494
+ let sortIcon = null;
495
+ if (isSorted) {
496
+ if (this.props.sortOrder === 'asc') {
497
+ sortIcon = mdiChevronDown;
498
+ } else {
499
+ sortIcon = mdiChevronUp;
500
+ }
501
+ }
502
+ if (col.sortable) {
503
+ sort = () => {
504
+ if (useMenu) {
505
+ this.dispatch({
506
+ type: 'TOGGLE_MENU',
507
+ sortIndex: index,
508
+ sortType: col.type,
509
+ sortCustom: col.sortCustom,
510
+ });
511
+ return;
512
+ }
513
+ this.dispatch({
514
+ type: 'SORT_COLUMN',
515
+ sortIndex: index,
516
+ sortType: col.type,
517
+ sortCustom: col.sortCustom,
518
+ });
519
+ };
520
+ }
521
+
522
+ return (
523
+ <div
524
+ key={index}
525
+ onClick={sort}
526
+ className={col.sortable ? 'sortable' : ''}
527
+ title={col.sortable ? 'Cliquer pour changer le tri' : null}
528
+ >
529
+ {useMenu ? (
530
+ <div>
531
+ {isSorted && !this.props.showMenu ? (
532
+ <Icon path={sortIcon} size="1em" />
533
+ ) : null}
534
+ <Icon path={mdiMenuDown} size="1.5em" />
535
+ </div>
536
+ ) : isSorted ? (
537
+ <Icon className="icon" path={sortIcon} size="1em" />
538
+ ) : null}
539
+ <span className="text">{col.title}</span>
540
+ </div>
541
+ );
542
+ })}
543
+ </div>
544
+ {this.props.showMenu ? (
545
+ <div className={this.styles.classNames.tableOptions}>
546
+ {columns.map((col, index) => {
547
+ if (this.props.sortIndex !== index) {
548
+ return <div key={index} className="none"></div>;
549
+ }
550
+ const sort = () => {
551
+ this.dispatch({
552
+ type: 'SORT_COLUMN',
553
+ sortIndex: index,
554
+ sortType: col.type,
555
+ sortCustom: col.sortCustom,
556
+ });
557
+ };
558
+ let sortIcon = null;
559
+
560
+ if (this.props.sortOrder === 'asc') {
561
+ sortIcon = mdiSortAlphabeticalAscending;
562
+ } else if (this.props.sortOrder === 'desc') {
563
+ sortIcon = mdiSortAlphabeticalDescending;
564
+ } else {
565
+ sortIcon = mdiSetNone;
566
+ }
567
+
568
+ return (
569
+ <div key={index} className="menu">
570
+ <div>
571
+ <Icon path={sortIcon} size="1em" onClick={sort} />
572
+ </div>
573
+ <div>
574
+ <input
575
+ list="column-values"
576
+ id="column-values"
577
+ name="column-values"
578
+ />
579
+ <datalist id="column-values">
580
+ {this.container.current
581
+ ?.getColumnSet(index)
582
+ .map((v, i) => {
583
+ return <option key={i} value={v}></option>;
584
+ })}
585
+ </datalist>
586
+ </div>
587
+ </div>
588
+ );
589
+ })}
590
+ </div>
591
+ ) : null}
592
+ <MagicTableRows
593
+ rows={rows}
594
+ columns={columns}
595
+ renderRow={renderRow}
596
+ getRowId={getRowId}
597
+ className={rowClassName}
598
+ onRowClick={hasClick ? this.handleRowClick : null}
599
+ onUpdate={this.onUpdate}
600
+ />
601
+ {children}
602
+ </MagicTableContainer>
603
+ );
604
+ }
605
+ };
606
+
607
+ MagicTable = Widget.connect((state, props) => {
608
+ const tableState = state.get('widgets').get(props.id);
609
+ if (!tableState) {
610
+ return {};
611
+ } else {
612
+ return tableState.pick(
613
+ 'id',
614
+ 'sortIndex',
615
+ 'sortType',
616
+ 'sortOrder',
617
+ 'sortCustom',
618
+ 'showMenu'
619
+ );
620
+ }
621
+ })(MagicTable);
622
+
623
+ MagicTable = withC(MagicTable);
624
+ MagicTable.displayName = 'MagicTable';
625
+ MagicTable.Row = MagicTableRow;
626
+
627
+ export default MagicTable;
@@ -0,0 +1,32 @@
1
+ /******************************************************************************/
2
+ export default function styles() {
3
+ const tag = {
4
+ 'borderRadius': '10em',
5
+ 'padding': ' 0.4em 0.8em',
6
+ 'border':
7
+ '1px solid color-mix(in srgb, var(--text-color), transparent 70%)',
8
+ 'backgroundColor':
9
+ 'color-mix(in srgb, var(--field-background-color), transparent 20%)',
10
+
11
+ '&[data-has-click=true]': {
12
+ 'cursor': 'pointer',
13
+ ':hover': {
14
+ opacity: '0.7',
15
+ },
16
+ },
17
+
18
+ '&[disabled]': {
19
+ 'cursor': 'default',
20
+ 'opacity': 0.7,
21
+ ':hover': {
22
+ opacity: 0.7,
23
+ },
24
+ },
25
+ };
26
+
27
+ return {
28
+ tag,
29
+ };
30
+ }
31
+
32
+ /******************************************************************************/
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import Widget from 'goblin-laboratory/widgets/widget';
3
+ import * as styles from './styles.js';
4
+ import withC from 'goblin-laboratory/widgets/connect-helpers/with-c.js';
5
+
6
+ let MagicTag = class extends Widget {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.styles = styles;
10
+ }
11
+
12
+ render() {
13
+ const {disabled, onClick, className = '', children, ...props} = this.props;
14
+ return (
15
+ <span
16
+ {...props}
17
+ disabled={disabled}
18
+ className={this.styles.classNames.tag + ' ' + className}
19
+ onClick={!disabled ? onClick : undefined}
20
+ data-has-click={Boolean(onClick)}
21
+ >
22
+ {children}
23
+ </span>
24
+ );
25
+ }
26
+ };
27
+
28
+ /******************************************************************************/
29
+
30
+ MagicTag = withC(MagicTag);
31
+
32
+ export default MagicTag;