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,111 @@
1
+ /******************************************************************************/
2
+
3
+ function getBackgroundMood(mood, customOpacity) {
4
+ let o = 0.5;
5
+ if (customOpacity !== undefined) {
6
+ o = customOpacity;
7
+ }
8
+ switch (mood) {
9
+ case 'unicorn':
10
+ return `linear-gradient(109.6deg, rgba(9, 9, 121, ${o}) 11.2%, rgba(144, 6, 161, ${o}) 53.7%, rgba(0, 212, 255, ${o}) 100.2%)`;
11
+ case 'sunset':
12
+ return `linear-gradient(111.1deg, rgba(0, 40, 70, ${o}) -4.8%, rgba(255, 115, 115, ${o}) 82.7%, rgba(255, 175, 123, ${o}) 97.2%)`;
13
+ case 'velvet':
14
+ return `radial-gradient(circle at 52.1% -29.6%, rgba(144, 17, 105, ${o}) 0%, rgba(51, 0, 131, ${o}) 100.2%)`;
15
+ default:
16
+ return `rgba(248, 241, 248, 0.1)`;
17
+ }
18
+ }
19
+
20
+ function assignProp(className, propName, properties, defaultValue) {
21
+ if (properties[propName]) {
22
+ className[propName] = properties[propName];
23
+ } else if (defaultValue) {
24
+ className[propName] = defaultValue;
25
+ }
26
+ }
27
+
28
+ export const propNames = [
29
+ 'z',
30
+ 'mood',
31
+ 'top',
32
+ 'left',
33
+ 'right',
34
+ 'bottom',
35
+ 'height',
36
+ 'width',
37
+ 'opacity',
38
+ ];
39
+
40
+ export default function styles(theme, props) {
41
+ let background = getBackgroundMood(props.mood, props.opacity);
42
+ const main = {
43
+ 'overflowX': 'auto',
44
+ 'overflowY': 'auto',
45
+ '::-webkit-scrollbar-track': {
46
+ width: '4px',
47
+ borderRadius: '2px',
48
+ backgroundColor: background,
49
+ },
50
+ '::-webkit-scrollbar': {
51
+ boxShadow: 'inset 0 0 6px rgba(0,0,0,0.3)',
52
+ borderRadius: '2px',
53
+ backgroundColor: background,
54
+ },
55
+ '::-webkit-scrollbar-thumb': {
56
+ borderRadius: ' 10px',
57
+ boxShadow: 'inset 0 0 6px rgba(0,0,0,.3)',
58
+ backgroundColor: 'rgba(255,255,255,0.1)',
59
+ },
60
+ 'color': 'white',
61
+ background,
62
+ 'borderRadius': '8px',
63
+ 'boxShadow': '0 4px 30px rgba(0, 0, 0, 0.1)',
64
+ 'backdropFilter': 'blur(10px) saturate(100%)',
65
+ 'border': '1px solid rgba(209, 213, 219, 0.3)',
66
+ };
67
+
68
+ if (props.top || props.bottom) {
69
+ main.position = 'absolute';
70
+ main.height = props.height || '500px';
71
+ // assignProp(main, 'zIndex', props, 1);
72
+ assignProp(main, 'width', props, '450px');
73
+
74
+ if (props.top) {
75
+ assignProp(main, 'top', props, '10vh');
76
+ } else if (props.bottom) {
77
+ assignProp(main, 'bottom', props, '10vh');
78
+ } else {
79
+ assignProp(main, 'top', props, '10vh');
80
+ }
81
+
82
+ if (props.left) {
83
+ assignProp(main, 'left', props, '10vw');
84
+ } else if (props.right) {
85
+ assignProp(main, 'right', props, '10vw');
86
+ } else {
87
+ assignProp(main, 'left', props, '10vw');
88
+ }
89
+ }
90
+
91
+ // background = getBackgroundMood(props.mood);
92
+
93
+ const content = {
94
+ minHeight: '100%',
95
+ padding: '20px',
96
+ };
97
+
98
+ const close = {
99
+ position: 'absolute',
100
+ right: '10px',
101
+ top: '0px',
102
+ };
103
+
104
+ return {
105
+ main,
106
+ content,
107
+ close,
108
+ };
109
+ }
110
+
111
+ /******************************************************************************/
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import Widget from 'goblin-laboratory/widgets/widget';
3
+ import MagicAction from '../magic-action/widget.js';
4
+ import * as styles from './styles.js';
5
+
6
+ class MagicBoxOld extends Widget {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.styles = styles;
10
+ }
11
+
12
+ render() {
13
+ return (
14
+ <div className={this.styles.classNames.main}>
15
+ {this.props.closable ? (
16
+ <div className={this.styles.classNames.close}>
17
+ <MagicAction onClick={this.props.onClose} text="fermer" />
18
+ </div>
19
+ ) : null}
20
+ <div className={this.styles.classNames.content}>
21
+ {this.props.children}
22
+ </div>
23
+ </div>
24
+ );
25
+ }
26
+ }
27
+
28
+ /******************************************************************************/
29
+
30
+ export default MagicBoxOld;
@@ -0,0 +1,156 @@
1
+ /******************************************************************************/
2
+
3
+ export default function styles() {
4
+ const button = {
5
+ 'position': 'relative',
6
+ 'minHeight': '32px',
7
+ 'minWidth': '31px',
8
+ 'cursor': 'pointer',
9
+ 'backgroundColor':
10
+ 'color-mix(in srgb, var(--button-background-color), transparent 80%)',
11
+ 'border':
12
+ '1px solid color-mix(in srgb, var(--text-color), transparent 50%)',
13
+ 'borderRadius': '5px',
14
+ 'padding': '6px 8px',
15
+ 'color': 'inherit',
16
+ 'display': 'inline-flex',
17
+ 'flexDirection': 'row',
18
+ 'alignItems': 'center',
19
+ 'justifyContent': 'center',
20
+ 'gap': '4px',
21
+
22
+ '&:hover': {
23
+ // backgroundColor: 'color-mix(in srgb, var(--text-color), transparent 70%)',
24
+ backgroundColor:
25
+ 'color-mix(in srgb, var(--button-accent-color), transparent 70%)',
26
+ borderColor:
27
+ 'color-mix(in srgb, var(--button-accent-color), transparent 10%)',
28
+ },
29
+
30
+ '&:enabled:active': {
31
+ '&::before': {
32
+ content: "''",
33
+ position: 'absolute',
34
+ width: '100%',
35
+ height: '100%',
36
+ transform: 'scale(1.1)',
37
+ border: '2px solid transparent',
38
+ borderRadius: '5px',
39
+ // outline: '1px solid red',
40
+ },
41
+ 'transform': 'scale(0.9)',
42
+ // paddingTop: '8px',
43
+ 'opacity': '0.85',
44
+ },
45
+
46
+ '&:focus-visible': {
47
+ borderColor: 'var(--text-color)',
48
+ boxShadow: '0px 0px 3px var(--text-color)',
49
+ outline: 'none',
50
+ },
51
+
52
+ '&[data-enabled=true]': {
53
+ // 'backgroundColor': 'rgba(255,255,255,0.4)',
54
+ 'backgroundColor': 'rgba(255,177,60,0.5)',
55
+ 'border': '1px solid rgb(255,153,0)',
56
+ 'boxShadow': '0px 0px 3px rgb(255,153,0)',
57
+ '&:hover': {
58
+ // backgroundColor: 'rgba(255,255,255,0.5)',
59
+ backgroundColor: 'rgba(255,177,60,0.6)',
60
+ },
61
+ },
62
+
63
+ '&[data-len1=true]': {
64
+ fontSize: '20px',
65
+ padding: 0,
66
+ },
67
+
68
+ '&[data-big=true]': {
69
+ fontSize: '24px',
70
+ },
71
+
72
+ '&[data-simple=true]': {
73
+ 'backgroundColor': 'transparent',
74
+ 'borderColor': 'transparent',
75
+ '&:not(:disabled):hover': {
76
+ opacity: 1,
77
+ backgroundColor:
78
+ 'color-mix(in srgb, var(--button-accent-color), transparent 70%)',
79
+ borderColor:
80
+ 'color-mix(in srgb, var(--button-accent-color), transparent 50%)',
81
+ },
82
+ '&:disabled:hover': {
83
+ backgroundColor: 'transparent',
84
+ },
85
+ },
86
+
87
+ '& > i': {
88
+ fontSize: '24px',
89
+ fontStyle: 'normal',
90
+ },
91
+
92
+ '& > svg': {
93
+ // These styles work because spans are added around text nodes in the render function
94
+
95
+ '&:only-child': {
96
+ // Reduce padding when there is only one icon
97
+ margin: '-1px',
98
+ },
99
+
100
+ // mdi icon case
101
+ '&[role=presentation]': {
102
+ margin: '-3px',
103
+ },
104
+
105
+ ':not(:last-child)': {
106
+ marginRight: '1px',
107
+ },
108
+
109
+ ':not(:first-child)': {
110
+ marginLeft: '1px',
111
+ },
112
+ },
113
+
114
+ '&:disabled': {
115
+ 'opacity': '0.4',
116
+ '&:hover': {
117
+ backgroundColor:
118
+ 'color-mix(in srgb, var(--button-accent-color), transparent 80%)',
119
+ cursor: 'unset',
120
+ },
121
+ },
122
+ };
123
+
124
+ const spinner = {
125
+ 'display': 'block',
126
+ 'width': '29px',
127
+ 'height': '29px',
128
+ '&::after': {
129
+ content: "''",
130
+ display: 'inline-block',
131
+ borderWidth: '2px',
132
+ borderColor:
133
+ 'var(--text-color) var(--text-color) var(--text-color) transparent',
134
+ borderStyle: 'solid',
135
+ borderRadius: '100%',
136
+ width: '17px',
137
+ height: '17px',
138
+ margin: '4px',
139
+ animationDuration: '1.5s',
140
+ animationDelay: '0s',
141
+ animationIterationCount: 'infinite',
142
+ animationTimingFunction: 'linear',
143
+ animationName: {
144
+ '0%': {transform: 'rotate(0deg)'},
145
+ '100%': {transform: 'rotate(360deg)'},
146
+ },
147
+ },
148
+ };
149
+
150
+ return {
151
+ button,
152
+ spinner,
153
+ };
154
+ }
155
+
156
+ /******************************************************************************/
@@ -0,0 +1,89 @@
1
+ import * as styles from './styles.js';
2
+ import React from 'react';
3
+ import Widget from 'goblin-laboratory/widgets/widget';
4
+ import withC from 'goblin-laboratory/widgets/connect-helpers/with-c';
5
+ import {TranslatableButton} from 'goblin-nabu/widgets/helpers/element-helpers.js';
6
+
7
+ class MagicButtonNC extends Widget {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.styles = styles;
11
+ this.handlePointerDown = this.handlePointerDown.bind(this);
12
+ }
13
+
14
+ /**
15
+ * @param {PointerEvent} event
16
+ */
17
+ handlePointerDown(event) {
18
+ const button = event.currentTarget;
19
+ const disabled = [
20
+ ...button.parentElement.querySelectorAll(':disabled'),
21
+ ].includes(button);
22
+ if (disabled) {
23
+ return;
24
+ }
25
+ this.props.onPointerDown(event);
26
+ }
27
+
28
+ renderChildren(spinner, len1) {
29
+ const children = React.Children.map(this.props.children, (child) => {
30
+ if (typeof child === 'string') {
31
+ return <span>{child}</span>;
32
+ }
33
+ return child;
34
+ });
35
+ return (
36
+ <>
37
+ {!(Boolean(spinner) && len1) && children}
38
+ {spinner && <span className={this.styles.classNames.spinner} />}
39
+ </>
40
+ );
41
+ }
42
+
43
+ render() {
44
+ const {
45
+ enabled,
46
+ big,
47
+ simple,
48
+ spinner,
49
+ onPointerDown,
50
+ className = '',
51
+ title,
52
+ ...props
53
+ } = this.props;
54
+ const len1 =
55
+ typeof this.props.children === 'string' &&
56
+ this.props.children.length === 1;
57
+
58
+ return title ? (
59
+ <TranslatableButton
60
+ {...props}
61
+ className={this.styles.classNames.button + ' button ' + className}
62
+ data-enabled={this.props.enabled}
63
+ data-big={big}
64
+ data-simple={simple}
65
+ data-len1={len1}
66
+ onPointerDown={onPointerDown && this.handlePointerDown}
67
+ title={title}
68
+ >
69
+ {this.renderChildren(spinner, len1)}
70
+ </TranslatableButton>
71
+ ) : (
72
+ <button
73
+ {...props}
74
+ className={this.styles.classNames.button + ' button ' + className}
75
+ data-enabled={this.props.enabled}
76
+ data-big={big}
77
+ data-simple={simple}
78
+ data-len1={len1}
79
+ onPointerDown={onPointerDown && this.handlePointerDown}
80
+ >
81
+ {this.renderChildren(spinner, len1)}
82
+ </button>
83
+ );
84
+ }
85
+ }
86
+ const MagicButton = withC(MagicButtonNC);
87
+ MagicButton.displayName = 'MagicButton';
88
+
89
+ export default MagicButton;
@@ -0,0 +1,116 @@
1
+ /******************************************************************************/
2
+
3
+ export default function styles() {
4
+ const input = {
5
+ 'display': 'block',
6
+ 'width': '24px',
7
+ 'height': '24px',
8
+ 'verticalAlign': 'middle',
9
+ 'position': 'relative',
10
+ 'bottom': '1px',
11
+ 'cursor': 'pointer',
12
+
13
+ 'appearance': 'none',
14
+ 'backgroundColor':
15
+ 'color-mix(in srgb, var(--button-background-color), transparent 80%)',
16
+ 'border':
17
+ '1px solid color-mix(in srgb, var(--text-color), transparent 50%)',
18
+ 'borderRadius': '4px',
19
+
20
+ '&[data-small=true]': {
21
+ 'borderColor': 'color-mix(in srgb, var(--text-color), transparent 70%)',
22
+ 'backgroundColor': 'rgba(0,0,0,0.2)',
23
+ 'width': '21px',
24
+ 'height': '21px',
25
+ '&::after': {
26
+ width: '4px',
27
+ height: '8px',
28
+ left: '7px',
29
+ top: '4px',
30
+ },
31
+ },
32
+
33
+ '&::after': {
34
+ content: "''",
35
+ display: 'block',
36
+ position: 'absolute',
37
+ width: '5px',
38
+ height: '9px',
39
+ border:
40
+ '2px solid color-mix(in srgb, var(--text-color), transparent 10%)',
41
+ borderTop: 'none',
42
+ borderLeft: 'none',
43
+ left: '8px',
44
+ top: '4px',
45
+ transform: 'rotate(43deg)',
46
+ opacity: 0,
47
+ },
48
+
49
+ '&:checked::after': {
50
+ opacity: 1,
51
+ },
52
+
53
+ '&:focus-visible': {
54
+ borderColor: 'var(--text-color)',
55
+ boxShadow: '0px 0px 3px var(--text-color)',
56
+ outline: 'none',
57
+ },
58
+
59
+ '&:focus': {
60
+ outline: 'none',
61
+ },
62
+
63
+ '&:active': {
64
+ transform: 'scale(0.9)',
65
+ },
66
+
67
+ '&:disabled': {
68
+ 'borderColor': 'transparent',
69
+ 'backgroundColor':
70
+ 'color-mix(in srgb, var(--text-color), transparent 90%)',
71
+ '&:hover': {
72
+ cursor: 'unset',
73
+ },
74
+ },
75
+ };
76
+
77
+ const checkboxLabel = {
78
+ 'display': 'flex',
79
+ 'alignItems': 'center',
80
+ // 'width': '100%',
81
+ // 'textTransform': 'uppercase',
82
+
83
+ '&:hover input[type=checkbox]': {
84
+ 'backgroundColor':
85
+ 'color-mix(in srgb, var(--button-accent-color), transparent 60%)',
86
+ 'borderColor': 'var(--button-accent-color)',
87
+
88
+ '&[data-small=true]': {
89
+ backgroundColor:
90
+ 'color-mix(in srgb, var(--button-accent-color), transparent 80%)',
91
+ },
92
+
93
+ '&:disabled': {
94
+ backgroundColor:
95
+ 'color-mix(in srgb, var(--text-color), transparent 90%)',
96
+ borderColor: 'transparent',
97
+ },
98
+ },
99
+ };
100
+
101
+ const text = {
102
+ 'display': 'flex',
103
+ 'marginLeft': '8px',
104
+ '&:empty': {
105
+ marginLeft: 0,
106
+ },
107
+ };
108
+
109
+ return {
110
+ checkboxLabel,
111
+ input,
112
+ text,
113
+ };
114
+ }
115
+
116
+ /******************************************************************************/
@@ -0,0 +1,68 @@
1
+ import * as styles from './styles.js';
2
+ import React from 'react';
3
+ import Widget from 'goblin-laboratory/widgets/widget';
4
+ import withC from 'goblin-laboratory/widgets/connect-helpers/with-c';
5
+
6
+ class InputCheckbox extends Widget {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.onChange = this.onChange.bind(this);
10
+ this.styles = styles;
11
+ }
12
+
13
+ onChange(e) {
14
+ this.props.onChange(e.target.checked);
15
+ }
16
+
17
+ render() {
18
+ const {value, ...props} = this.props;
19
+ return (
20
+ <input
21
+ {...props}
22
+ type="checkbox"
23
+ className={this.styles.classNames.input}
24
+ onChange={this.onChange}
25
+ checked={value}
26
+ />
27
+ );
28
+ }
29
+ }
30
+
31
+ class MagicCheckboxNC extends Widget {
32
+ constructor() {
33
+ super(...arguments);
34
+ this.styles = styles;
35
+ }
36
+
37
+ render() {
38
+ const {
39
+ value,
40
+ onChange,
41
+ text,
42
+ title,
43
+ disabled,
44
+ small,
45
+ children,
46
+ className = '',
47
+ ...props
48
+ } = this.props;
49
+ return (
50
+ <label
51
+ className={this.styles.classNames.checkboxLabel + ' ' + className}
52
+ title={title}
53
+ >
54
+ <InputCheckbox
55
+ {...props}
56
+ data-small={small}
57
+ value={value}
58
+ onChange={onChange}
59
+ disabled={disabled}
60
+ />
61
+ <span className={this.styles.classNames.text}>{text || children}</span>
62
+ </label>
63
+ );
64
+ }
65
+ }
66
+ const MagicCheckbox = withC(MagicCheckboxNC, {value: 'onChange'});
67
+ MagicCheckbox.displayName = 'MagicCheckbox';
68
+ export default MagicCheckbox;
@@ -0,0 +1,22 @@
1
+ export default function styles() {
2
+ const colorField = {
3
+ // width: '120px',
4
+ };
5
+
6
+ const colorPreview = {
7
+ 'width': '21px',
8
+ 'height': '21px',
9
+ 'margin': '-4px',
10
+
11
+ '& > input': {
12
+ width: 0,
13
+ height: 0,
14
+ opacity: 0,
15
+ },
16
+ };
17
+
18
+ return {
19
+ colorField,
20
+ colorPreview,
21
+ };
22
+ }
@@ -0,0 +1,68 @@
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';
5
+ import MagicTextField from '../magic-text-field/widget.js';
6
+ import InputGroup from '../input-group/widget.js';
7
+ import MagicButton from '../magic-button/widget.js';
8
+ import Icon from '@mdi/react';
9
+ import {mdiPalette} from '@mdi/js';
10
+
11
+ class MagicColorFieldButtonNC extends Widget {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.styles = styles;
15
+ }
16
+
17
+ render() {
18
+ const {value, onChange, className = '', ...props} = this.props;
19
+
20
+ return (
21
+ <MagicButton disabled>
22
+ <label
23
+ {...props}
24
+ className={this.styles.classNames.colorPreview + ' ' + className}
25
+ style={{
26
+ backgroundColor: value,
27
+ }}
28
+ >
29
+ {!value && <Icon path={mdiPalette} size={0.8} />}
30
+ <input
31
+ type="color"
32
+ value={value || ''}
33
+ onChange={(event) => onChange?.(event.target.value)}
34
+ />
35
+ </label>
36
+ </MagicButton>
37
+ );
38
+ }
39
+ }
40
+
41
+ export const MagicColorFieldButton = withC(MagicColorFieldButtonNC, {
42
+ value: 'onChange',
43
+ });
44
+ MagicColorFieldButton.displayName = 'MagicColorFieldButton';
45
+
46
+ class MagicColorFieldNC extends Widget {
47
+ constructor() {
48
+ super(...arguments);
49
+ this.styles = styles;
50
+ }
51
+
52
+ render() {
53
+ const {className = '', ...props} = this.props;
54
+ return (
55
+ <InputGroup>
56
+ <MagicTextField
57
+ {...props}
58
+ className={this.styles.classNames.colorField + ' ' + className}
59
+ />
60
+ <MagicColorFieldButton value={props.value} onChange={props.onChange} />
61
+ </InputGroup>
62
+ );
63
+ }
64
+ }
65
+ const MagicColorField = withC(MagicColorFieldNC, {value: 'onChange'});
66
+ MagicColorField.displayName = 'MagicColorField';
67
+
68
+ export default MagicColorField;
@@ -0,0 +1,9 @@
1
+ export default function styles() {
2
+ const dateField = {
3
+ width: '120px',
4
+ };
5
+
6
+ return {
7
+ dateField,
8
+ };
9
+ }