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.
- package/.editorconfig +9 -0
- package/.zou-flow +2 -0
- package/eslint.config.js +65 -0
- package/magicNavigation.js +7 -0
- package/package.json +45 -0
- package/widgets/dialog/widget.js +78 -0
- package/widgets/element-helpers/element-has-direct-text.js +9 -0
- package/widgets/element-helpers/is-empty-area-element.js +17 -0
- package/widgets/element-helpers/is-flat-element.js +52 -0
- package/widgets/get-modifiers/get-modifiers.js +34 -0
- package/widgets/input-group/styles.js +74 -0
- package/widgets/input-group/widget.js +24 -0
- package/widgets/magic-action/styles.js +45 -0
- package/widgets/magic-action/widget.js +44 -0
- package/widgets/magic-background/bg-alps.jpg +0 -0
- package/widgets/magic-background/bg-fur.png +0 -0
- package/widgets/magic-background/bg-milkyway.png +0 -0
- package/widgets/magic-background/bg-space.jpg +0 -0
- package/widgets/magic-background/bg-synth.jpg +0 -0
- package/widgets/magic-background/bg-white.png +0 -0
- package/widgets/magic-background/styles.js +81 -0
- package/widgets/magic-background/widget.js +20 -0
- package/widgets/magic-box/styles.js +10 -0
- package/widgets/magic-box/widget.js +28 -0
- package/widgets/magic-box-old/styles.js +111 -0
- package/widgets/magic-box-old/widget.js +30 -0
- package/widgets/magic-button/styles.js +156 -0
- package/widgets/magic-button/widget.js +89 -0
- package/widgets/magic-checkbox/styles.js +116 -0
- package/widgets/magic-checkbox/widget.js +68 -0
- package/widgets/magic-color-field/styles.js +22 -0
- package/widgets/magic-color-field/widget.js +68 -0
- package/widgets/magic-date-field/styles.js +9 -0
- package/widgets/magic-date-field/widget.js +145 -0
- package/widgets/magic-datetime-field/styles.js +11 -0
- package/widgets/magic-datetime-field/widget.js +95 -0
- package/widgets/magic-dialog/styles.js +39 -0
- package/widgets/magic-dialog/widget.js +116 -0
- package/widgets/magic-div/styles.js +22 -0
- package/widgets/magic-div/widget.js +20 -0
- package/widgets/magic-emoji/styles.js +14 -0
- package/widgets/magic-emoji/widget.js +33 -0
- package/widgets/magic-emoji-picker/styles.js +21 -0
- package/widgets/magic-emoji-picker/widget.js +44 -0
- package/widgets/magic-inplace-input/styles.js +55 -0
- package/widgets/magic-inplace-input/widget.js +26 -0
- package/widgets/magic-input/styles.js +50 -0
- package/widgets/magic-input/widget.js +397 -0
- package/widgets/magic-label/styles.js +20 -0
- package/widgets/magic-label/widget.js +24 -0
- package/widgets/magic-navigation/service.js +1306 -0
- package/widgets/magic-navigation/styles.js +103 -0
- package/widgets/magic-navigation/view-context.js +15 -0
- package/widgets/magic-navigation/widget.js +540 -0
- package/widgets/magic-number-field/styles.js +10 -0
- package/widgets/magic-number-field/widget.js +103 -0
- package/widgets/magic-panel/styles.js +61 -0
- package/widgets/magic-panel/widget.js +63 -0
- package/widgets/magic-radio/styles.js +93 -0
- package/widgets/magic-radio/widget.js +74 -0
- package/widgets/magic-scroll/styles.js +22 -0
- package/widgets/magic-scroll/widget.js +20 -0
- package/widgets/magic-select/styles.js +16 -0
- package/widgets/magic-select/widget.js +134 -0
- package/widgets/magic-table/reducer.js +63 -0
- package/widgets/magic-table/styles.js +170 -0
- package/widgets/magic-table/widget.js +627 -0
- package/widgets/magic-tag/styles.js +32 -0
- package/widgets/magic-tag/widget.js +32 -0
- package/widgets/magic-text-field/styles.js +58 -0
- package/widgets/magic-text-field/widget.js +66 -0
- package/widgets/magic-time-field/styles.js +8 -0
- package/widgets/magic-time-field/widget.js +142 -0
- package/widgets/magic-timer/styles.js +30 -0
- package/widgets/magic-timer/widget.js +162 -0
- package/widgets/magic-zen/styles.js +61 -0
- package/widgets/magic-zen/widget.js +42 -0
- package/widgets/main-tabs/styles.js +106 -0
- package/widgets/main-tabs/widget.js +23 -0
- package/widgets/menu/styles.js +156 -0
- package/widgets/menu/test-menu.html +154 -0
- package/widgets/menu/widget.js +575 -0
- package/widgets/movable/widget.js +80 -0
- package/widgets/splitter/styles.js +57 -0
- package/widgets/splitter/widget.js +40 -0
- package/widgets/tab-layout/styles.js +31 -0
- package/widgets/tab-layout/widget.js +59 -0
- package/widgets/with-computed-size/widget.js +52 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/******************************************************************************/
|
|
2
|
+
|
|
3
|
+
export default function styles() {
|
|
4
|
+
const disabledStyle = {
|
|
5
|
+
'backgroundColor': 'color-mix(in srgb, var(--text-color), transparent 95%)',
|
|
6
|
+
'color': 'color-mix(in srgb, var(--text-color), transparent 30%)',
|
|
7
|
+
'::placeholder': {
|
|
8
|
+
color: 'color-mix(in srgb, var(--text-color), transparent 80%)',
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const colorPickerStyle = {
|
|
13
|
+
width: '32px',
|
|
14
|
+
height: '20px',
|
|
15
|
+
padding: '0px 2px',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const inputEdit = {
|
|
19
|
+
'display': 'block',
|
|
20
|
+
// 'height': '40px',
|
|
21
|
+
'width': '100%',
|
|
22
|
+
// 'minHeight': '1em', // For contenteditable
|
|
23
|
+
'backgroundColor':
|
|
24
|
+
'color-mix(in srgb, var(--field-background-color), transparent 20%)',
|
|
25
|
+
'borderRadius': '5px',
|
|
26
|
+
'border': '1px solid transparent',
|
|
27
|
+
'padding': '7px 10px',
|
|
28
|
+
// 'fontSize': '14px',
|
|
29
|
+
'fontSize': 'inherit',
|
|
30
|
+
'fontWeight': 300,
|
|
31
|
+
'color': 'var(--text-color)',
|
|
32
|
+
'resize': 'vertical',
|
|
33
|
+
'::placeholder': {
|
|
34
|
+
color: 'color-mix(in srgb, var(--text-color), transparent 80%)',
|
|
35
|
+
// textTransform: 'uppercase',
|
|
36
|
+
fontWeight: 600,
|
|
37
|
+
},
|
|
38
|
+
':focus': {
|
|
39
|
+
outline: 'none',
|
|
40
|
+
borderColor: 'color-mix(in srgb, var(--text-color), transparent 60%)',
|
|
41
|
+
// backgroundColor: 'rgba(255,255,255,0.2)',
|
|
42
|
+
fontWeight: 300,
|
|
43
|
+
},
|
|
44
|
+
'&[data-disabled=true]': disabledStyle,
|
|
45
|
+
'&:disabled': disabledStyle,
|
|
46
|
+
'&[type="color"]': colorPickerStyle,
|
|
47
|
+
'&[contenteditable]': {
|
|
48
|
+
minHeight: '54px', // 2 lines
|
|
49
|
+
cursor: 'text',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
inputEdit,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/******************************************************************************/
|
|
@@ -0,0 +1,66 @@
|
|
|
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 MagicInput from '../magic-input/widget.js';
|
|
6
|
+
|
|
7
|
+
let inputCount = 0;
|
|
8
|
+
|
|
9
|
+
class MagicTextFieldNC extends Widget {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.styles = styles;
|
|
13
|
+
this.listId = `input-data-${inputCount++}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
renderDataList() {
|
|
17
|
+
if (!this.props.dataList) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
return (
|
|
21
|
+
<datalist id={this.listId}>
|
|
22
|
+
{this.props.dataList.map((value) => (
|
|
23
|
+
<option key={value} value={value} />
|
|
24
|
+
))}
|
|
25
|
+
</datalist>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
render() {
|
|
30
|
+
const {className = ''} = this.props;
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
<MagicInput
|
|
34
|
+
ref={this.props.inputRef}
|
|
35
|
+
className={this.styles.classNames.inputEdit + ' ' + className}
|
|
36
|
+
value={this.props.value}
|
|
37
|
+
onBlur={this.disableEdit}
|
|
38
|
+
onEnterKey={this.props.onEnterKey}
|
|
39
|
+
onKeyDown={this.props.onKeyDown}
|
|
40
|
+
onKeyUp={this.props.onKeyUp}
|
|
41
|
+
placeholder={this.props.placeholder}
|
|
42
|
+
changeMode={this.props.changeMode || 'blur'}
|
|
43
|
+
parse={this.props.parse}
|
|
44
|
+
format={this.props.format}
|
|
45
|
+
onChange={this.props.onChange}
|
|
46
|
+
onValidate={this.props.onValidate}
|
|
47
|
+
type={this.props.type}
|
|
48
|
+
step={this.props.step}
|
|
49
|
+
min={this.props.min}
|
|
50
|
+
max={this.props.max}
|
|
51
|
+
autoFocus={this.props.autoFocus}
|
|
52
|
+
selectAllOnFocus={this.props.selectAllOnFocus}
|
|
53
|
+
rows={this.props.rows}
|
|
54
|
+
autoRows={this.props.autoRows}
|
|
55
|
+
disabled={this.props.disabled}
|
|
56
|
+
emojiPicker={this.props.emojiPicker}
|
|
57
|
+
list={this.props.dataList ? this.listId : undefined}
|
|
58
|
+
/>
|
|
59
|
+
{this.renderDataList()}
|
|
60
|
+
</>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const MagicTextField = withC(MagicTextFieldNC, {value: 'onChange'});
|
|
65
|
+
MagicTextField.displayName = 'MagicTextField';
|
|
66
|
+
export default MagicTextField;
|
|
@@ -0,0 +1,142 @@
|
|
|
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 {time as TimeConverters} from 'xcraft-core-converters';
|
|
7
|
+
import InputGroup from '../input-group/widget.js';
|
|
8
|
+
import MagicButton from '../magic-button/widget.js';
|
|
9
|
+
import Icon from '@mdi/react';
|
|
10
|
+
import {mdiClockOutline} from '@mdi/js';
|
|
11
|
+
|
|
12
|
+
class MagicTimeFieldNC extends Widget {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.styles = styles;
|
|
16
|
+
this.inputRef = this.props.inputRef || React.createRef();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get input() {
|
|
20
|
+
return this.inputRef.current;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static parseEdited(value) {
|
|
24
|
+
if (!value) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const edited = TimeConverters.parseEdited(value);
|
|
28
|
+
return edited.value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
parse = (value) => {
|
|
32
|
+
const newValue = MagicTimeFieldNC.parseEdited(value);
|
|
33
|
+
if (this.props.required && !newValue) {
|
|
34
|
+
return TimeConverters.getNowCanonical();
|
|
35
|
+
}
|
|
36
|
+
return newValue;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
format = (value) => {
|
|
40
|
+
if (!value) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
return TimeConverters.getDisplayed(value.split(/[.\-+Z]/, 1)[0]);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
getPositionKind(position) {
|
|
47
|
+
// Value: h h : m m : s s
|
|
48
|
+
// Pos: 0 1 2 3 4 5 6 7 8
|
|
49
|
+
// Kind: 0 | 1 | 2
|
|
50
|
+
if (position <= 2) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
if (position <= 5) {
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
return 2;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getSelection(positionKind) {
|
|
60
|
+
// Kind: 0 | 1 | 2
|
|
61
|
+
// Pos: 0 1 2 3 4 5 6 7 8
|
|
62
|
+
// Value: h h : m m : s s
|
|
63
|
+
if (positionKind === 0) {
|
|
64
|
+
return [0, 2];
|
|
65
|
+
}
|
|
66
|
+
if (positionKind === 1) {
|
|
67
|
+
return [3, 5];
|
|
68
|
+
}
|
|
69
|
+
return [6, 8];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
handleKeyDown = (event) => {
|
|
73
|
+
this.props.onKeyDown?.(event);
|
|
74
|
+
|
|
75
|
+
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
|
|
76
|
+
const {value, selectionStart, selectionEnd} = event.target;
|
|
77
|
+
const cursorPosition =
|
|
78
|
+
selectionStart < 2
|
|
79
|
+
? selectionStart
|
|
80
|
+
: (selectionStart + selectionEnd) / 2;
|
|
81
|
+
const step = event.shiftKey ? 10 : 1;
|
|
82
|
+
const direction = event.key === 'ArrowUp' ? 1 : -1;
|
|
83
|
+
const result = TimeConverters.incEdited(
|
|
84
|
+
value,
|
|
85
|
+
cursorPosition,
|
|
86
|
+
direction,
|
|
87
|
+
step
|
|
88
|
+
);
|
|
89
|
+
if (result.edited) {
|
|
90
|
+
this.input.changeAndSelect(
|
|
91
|
+
result.edited,
|
|
92
|
+
result.selectionStart,
|
|
93
|
+
result.selectionEnd
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (event.ctrlKey && event.key === 'ArrowRight') {
|
|
100
|
+
const {value, selectionEnd} = event.target;
|
|
101
|
+
const positionKind = this.getPositionKind(selectionEnd);
|
|
102
|
+
const lastKind = 1;
|
|
103
|
+
const newKind = positionKind < lastKind ? positionKind + 1 : lastKind;
|
|
104
|
+
this.input.htmlInput.setSelectionRange(
|
|
105
|
+
...this.getSelection(newKind, value.length)
|
|
106
|
+
);
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
}
|
|
109
|
+
if (event.ctrlKey && event.key === 'ArrowLeft') {
|
|
110
|
+
const {value, selectionStart} = event.target;
|
|
111
|
+
const positionKind = this.getPositionKind(selectionStart);
|
|
112
|
+
const newKind = positionKind > 0 ? positionKind - 1 : 0;
|
|
113
|
+
this.input.htmlInput.setSelectionRange(
|
|
114
|
+
...this.getSelection(newKind, value.length)
|
|
115
|
+
);
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
render() {
|
|
121
|
+
const {className = '', ...props} = this.props;
|
|
122
|
+
return (
|
|
123
|
+
<InputGroup>
|
|
124
|
+
<MagicTextField
|
|
125
|
+
inputRef={this.inputRef}
|
|
126
|
+
format={this.format}
|
|
127
|
+
parse={this.parse}
|
|
128
|
+
{...props}
|
|
129
|
+
onKeyDown={this.handleKeyDown}
|
|
130
|
+
className={this.styles.classNames.timeField + ' ' + className}
|
|
131
|
+
/>
|
|
132
|
+
<MagicButton disabled>
|
|
133
|
+
<Icon path={mdiClockOutline} size={0.8} />
|
|
134
|
+
</MagicButton>
|
|
135
|
+
</InputGroup>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const MagicTimeField = withC(MagicTimeFieldNC, {value: 'onChange'});
|
|
140
|
+
MagicTimeField.displayName = 'MagicTimeField';
|
|
141
|
+
|
|
142
|
+
export default MagicTimeField;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/******************************************************************************/
|
|
2
|
+
|
|
3
|
+
export default function styles() {
|
|
4
|
+
const timer = {
|
|
5
|
+
'display': 'inline-flex',
|
|
6
|
+
'flexDirection': 'row',
|
|
7
|
+
'alignItems': 'center',
|
|
8
|
+
|
|
9
|
+
'& .button': {
|
|
10
|
+
'lineHeight': '10px',
|
|
11
|
+
'minHeight': '25px',
|
|
12
|
+
'minWidth': '24px',
|
|
13
|
+
'fontSize': '24px',
|
|
14
|
+
'overflow': 'hidden',
|
|
15
|
+
'& > svg': {
|
|
16
|
+
margin: '-6px',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
'& .text': {
|
|
21
|
+
marginLeft: '7px',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
timer,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/******************************************************************************/
|
|
@@ -0,0 +1,162 @@
|
|
|
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 {datetime as DateTimeConverters} from 'xcraft-core-converters';
|
|
6
|
+
import MagicButton from '../magic-button/widget.js';
|
|
7
|
+
import Icon from '@mdi/react';
|
|
8
|
+
import {mdiPlay, mdiPause} from '@mdi/js';
|
|
9
|
+
|
|
10
|
+
export class TimerUpdater extends Widget {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.state = {
|
|
14
|
+
timerValue: '',
|
|
15
|
+
};
|
|
16
|
+
this.updateTimer = this.updateTimer.bind(this);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static getDerivedStateFromProps(props) {
|
|
20
|
+
return {
|
|
21
|
+
timerValue: props.start ? TimerUpdater.getCurrentValue(props.start) : '',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
componentDidMount() {
|
|
26
|
+
this.startStopTimer();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
componentDidUpdate() {
|
|
30
|
+
this.startStopTimer();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
componentWillUnmount() {
|
|
34
|
+
this.stopTimer();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static getCurrentValue(start) {
|
|
38
|
+
const now = new Date().toISOString();
|
|
39
|
+
const value = DateTimeConverters.getDisplayedBetweenToDatetimes(start, now);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updateTimer() {
|
|
44
|
+
this.setState({
|
|
45
|
+
timerValue: TimerUpdater.getCurrentValue(this.props.start),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
stopTimer() {
|
|
50
|
+
if (this.timer) {
|
|
51
|
+
clearInterval(this.timer);
|
|
52
|
+
this.timer = null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
startTimer() {
|
|
57
|
+
if (!this.timer) {
|
|
58
|
+
this.timer = setInterval(this.updateTimer, 1000);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
startStopTimer() {
|
|
63
|
+
if (this.props.start) {
|
|
64
|
+
this.startTimer();
|
|
65
|
+
} else {
|
|
66
|
+
this.stopTimer();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
render() {
|
|
71
|
+
return this.props.children(this.state.timerValue);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class MagicTimerNC extends Widget {
|
|
76
|
+
constructor() {
|
|
77
|
+
super(...arguments);
|
|
78
|
+
this.styles = styles;
|
|
79
|
+
|
|
80
|
+
this.handleClick = this.handleClick.bind(this);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
handleClick() {
|
|
84
|
+
if (this.props.start) {
|
|
85
|
+
this.stop();
|
|
86
|
+
} else {
|
|
87
|
+
this.start();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
start() {
|
|
92
|
+
const now = new Date().toISOString();
|
|
93
|
+
this.props.onStart?.(now);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
stop() {
|
|
97
|
+
const now = new Date().toISOString();
|
|
98
|
+
this.props.onStop?.(now);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
render() {
|
|
102
|
+
const {start, onStart, onStop, className = '', ...props} = this.props;
|
|
103
|
+
return (
|
|
104
|
+
<div
|
|
105
|
+
{...props}
|
|
106
|
+
className={this.styles.classNames.timer + ' ' + className}
|
|
107
|
+
>
|
|
108
|
+
<MagicButton
|
|
109
|
+
className="button"
|
|
110
|
+
onClick={this.handleClick}
|
|
111
|
+
enabled={Boolean(start)}
|
|
112
|
+
big
|
|
113
|
+
>
|
|
114
|
+
{start ? (
|
|
115
|
+
<Icon path={mdiPause} size={0.8} />
|
|
116
|
+
) : (
|
|
117
|
+
<Icon path={mdiPlay} size={0.8} />
|
|
118
|
+
)}
|
|
119
|
+
</MagicButton>
|
|
120
|
+
<TimerUpdater start={this.props.start}>
|
|
121
|
+
{(timerValue) =>
|
|
122
|
+
timerValue && <span className="text">+ {timerValue}</span>
|
|
123
|
+
}
|
|
124
|
+
</TimerUpdater>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// export class MagicTimerTest extends Widget {
|
|
131
|
+
// constructor() {
|
|
132
|
+
// super(...arguments);
|
|
133
|
+
// this.state = {
|
|
134
|
+
// start: null,
|
|
135
|
+
// duration: 0,
|
|
136
|
+
// };
|
|
137
|
+
// this.handleChange = this.handleChange.bind(this);
|
|
138
|
+
// }
|
|
139
|
+
|
|
140
|
+
// handleChange(state) {
|
|
141
|
+
// this.setState(state);
|
|
142
|
+
// }
|
|
143
|
+
|
|
144
|
+
// componentDidUpdate() {
|
|
145
|
+
// console.log(this.state);
|
|
146
|
+
// }
|
|
147
|
+
|
|
148
|
+
// render() {
|
|
149
|
+
// return (
|
|
150
|
+
// <MagicTimerNC
|
|
151
|
+
// onChange={this.handleChange}
|
|
152
|
+
// {...this.state}
|
|
153
|
+
// {...this.props}
|
|
154
|
+
// />
|
|
155
|
+
// );
|
|
156
|
+
// }
|
|
157
|
+
// }
|
|
158
|
+
|
|
159
|
+
const MagicTimer = withC(MagicTimerNC);
|
|
160
|
+
MagicTimer.displayName = 'MagicTimer';
|
|
161
|
+
|
|
162
|
+
export default MagicTimer;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export default function styles() {
|
|
2
|
+
const zenDialog = {
|
|
3
|
+
width: '100%',
|
|
4
|
+
height: '100%',
|
|
5
|
+
maxWidth: '100%',
|
|
6
|
+
maxHeight: '100%',
|
|
7
|
+
padding: 0,
|
|
8
|
+
border: 'none',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const zen = {
|
|
12
|
+
width: '100%',
|
|
13
|
+
height: '100%',
|
|
14
|
+
padding: '15px',
|
|
15
|
+
// '--border-radius': '8px',
|
|
16
|
+
// 'background': 'transparent',
|
|
17
|
+
// 'borderRadius': '8px',
|
|
18
|
+
// 'boxShadow': '0 4px 30px rgba(0, 0, 0, 0.1)',
|
|
19
|
+
// 'backdropFilter': 'blur(50px) saturate(100%)',
|
|
20
|
+
// 'border':
|
|
21
|
+
// '1px solid color-mix(in srgb, var(--text-color), transparent 78%)',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const key = {
|
|
25
|
+
border: '1px solid var(--text-color)',
|
|
26
|
+
padding: '2px',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const notice = {
|
|
30
|
+
'pointerEvents': 'none',
|
|
31
|
+
'opacity': 0,
|
|
32
|
+
'zIndex': 2,
|
|
33
|
+
'borderRadius': '10px',
|
|
34
|
+
'position': 'fixed',
|
|
35
|
+
'top': '20px',
|
|
36
|
+
'left': '50%',
|
|
37
|
+
'transform': 'translate(-50%, -10%)',
|
|
38
|
+
'fontSize': '24px',
|
|
39
|
+
'padding': '15px',
|
|
40
|
+
'textAlign': 'center',
|
|
41
|
+
'backgroundColor': 'rgba(0,0,0,0.5)',
|
|
42
|
+
'--text-color': 'white',
|
|
43
|
+
'color': 'var(--text-color)',
|
|
44
|
+
'animationDirection': 'forwards',
|
|
45
|
+
'animationDuration': '3s',
|
|
46
|
+
'animationName': {
|
|
47
|
+
'0%': {opacity: 1},
|
|
48
|
+
'50%': {opacity: 1},
|
|
49
|
+
'100%': {opacity: 0},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
zen,
|
|
55
|
+
zenDialog,
|
|
56
|
+
notice,
|
|
57
|
+
key,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/******************************************************************************/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {createPortal} from 'react-dom';
|
|
3
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
4
|
+
import * as styles from './styles.js';
|
|
5
|
+
import Dialog from '../dialog/widget.js';
|
|
6
|
+
import MagicBackground from '../magic-background/widget.js';
|
|
7
|
+
import MagicDiv from '../magic-div/widget.js';
|
|
8
|
+
|
|
9
|
+
export default class MagicZen extends Widget {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.styles = styles;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
render() {
|
|
16
|
+
if (!this.props.active) {
|
|
17
|
+
return this.props.children;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const {className = ''} = this.props;
|
|
21
|
+
|
|
22
|
+
return createPortal(
|
|
23
|
+
<Dialog
|
|
24
|
+
className={this.styles.classNames.zenDialog}
|
|
25
|
+
modal={true}
|
|
26
|
+
open
|
|
27
|
+
onClose={this.props.onClose}
|
|
28
|
+
>
|
|
29
|
+
<MagicBackground>
|
|
30
|
+
<div className={this.styles.classNames.notice}>
|
|
31
|
+
Appuyez sur <span className={this.styles.classNames.key}>ESC</span>{' '}
|
|
32
|
+
pour quitter le mode zen
|
|
33
|
+
</div>
|
|
34
|
+
<MagicDiv className={this.styles.classNames.zen + ' ' + className}>
|
|
35
|
+
{this.props.children}
|
|
36
|
+
</MagicDiv>
|
|
37
|
+
</MagicBackground>
|
|
38
|
+
</Dialog>,
|
|
39
|
+
document.getElementById('root')
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export default function styles() {
|
|
2
|
+
const mainTabs = {
|
|
3
|
+
// 'color': 'white',
|
|
4
|
+
'padding': '4px 7px',
|
|
5
|
+
'display': 'flex',
|
|
6
|
+
'flexDirection': 'row',
|
|
7
|
+
'flexWrap': 'wrap',
|
|
8
|
+
'gap': '4px',
|
|
9
|
+
|
|
10
|
+
'&:focus-visible': {
|
|
11
|
+
'outline': 'none',
|
|
12
|
+
|
|
13
|
+
'& > [data-active=true]': {
|
|
14
|
+
borderColor: 'var(--text-color)',
|
|
15
|
+
boxShadow: '0px 0px 3px var(--text-color)',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
'& > *': {
|
|
20
|
+
'padding': '10px 8px 8px 12px',
|
|
21
|
+
'border':
|
|
22
|
+
'1px solid color-mix(in srgb, var(--text-color), transparent 75%)',
|
|
23
|
+
'borderRadius': '3px',
|
|
24
|
+
'backgroundColor':
|
|
25
|
+
'color-mix(in srgb, var(--text-color), transparent 87.5%)',
|
|
26
|
+
'backdropFilter': 'blur(10px)',
|
|
27
|
+
|
|
28
|
+
'display': 'inline-flex',
|
|
29
|
+
'flexDirection': 'row',
|
|
30
|
+
'alignItems': 'center',
|
|
31
|
+
'maxWidth': '300px',
|
|
32
|
+
|
|
33
|
+
'&[data-active=true]': {
|
|
34
|
+
'backgroundColor': 'rgba(255,255,255,0.25)',
|
|
35
|
+
'borderColor': 'color-mix(in srgb, var(--text-color), transparent 50%)',
|
|
36
|
+
':hover': {
|
|
37
|
+
backgroundColor:
|
|
38
|
+
'color-mix(in srgb, rgba(255,255,255,0.25), var(--accent-color) 15%)',
|
|
39
|
+
},
|
|
40
|
+
'@media (prefers-color-scheme: light)': {
|
|
41
|
+
'backgroundColor': 'rgba(248, 241, 248, 0.85)',
|
|
42
|
+
'borderColor':
|
|
43
|
+
'color-mix(in srgb, var(--text-color), transparent 70%)',
|
|
44
|
+
':hover': {
|
|
45
|
+
backgroundColor:
|
|
46
|
+
'color-mix(in srgb, rgba(248, 241, 248, 0.85), var(--accent-color) 15%)',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
'&[data-highlighted=true]': {
|
|
52
|
+
'backgroundColor': 'rgba(255,177,60,0.45)',
|
|
53
|
+
'borderColor': 'rgba(255,153,0,0.7)',
|
|
54
|
+
'boxShadow': '0px 0px 5px rgba(255,153,0,0.7)',
|
|
55
|
+
':hover': {
|
|
56
|
+
backgroundColor: 'rgb(255,185,82,0.6)',
|
|
57
|
+
borderColor: 'rgba(255,153,0,0.85)',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
'&[data-highlighted=true][data-active=true]': {
|
|
62
|
+
'backgroundColor':
|
|
63
|
+
'color-mix(in srgb, rgba(255,255,255,0.25), rgba(255,177,60,0.45) 25%)',
|
|
64
|
+
'borderColor':
|
|
65
|
+
'color-mix(in srgb, color-mix(in srgb, var(--text-color), transparent 50%), rgba(255,153,0,0.7) 25%)',
|
|
66
|
+
':hover': {
|
|
67
|
+
backgroundColor:
|
|
68
|
+
'color-mix(in srgb, color-mix(in srgb, rgba(255,255,255,0.25), rgba(255,177,60,0.45) 25%), var(--accent-color) 15%)',
|
|
69
|
+
borderColor:
|
|
70
|
+
'color-mix(in srgb, var(--button-accent-color), transparent 10%)',
|
|
71
|
+
},
|
|
72
|
+
'@media (prefers-color-scheme: light)': {
|
|
73
|
+
'backgroundColor':
|
|
74
|
+
'color-mix(in srgb, rgba(248, 241, 248, 0.85), rgba(255,177,60,0.45) 25%)',
|
|
75
|
+
'borderColor':
|
|
76
|
+
'color-mix(in srgb, color-mix(in srgb, var(--text-color), transparent 70%), rgba(255,153,0,0.7) 25%)',
|
|
77
|
+
':hover': {
|
|
78
|
+
backgroundColor:
|
|
79
|
+
'color-mix(in srgb, color-mix(in srgb, rgba(248, 241, 248, 0.85), rgba(255,177,60,0.45) 25%), var(--accent-color) 15%)',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
':hover': {
|
|
85
|
+
backgroundColor:
|
|
86
|
+
'color-mix(in srgb, var(--button-accent-color), transparent 70%)',
|
|
87
|
+
borderColor:
|
|
88
|
+
'color-mix(in srgb, var(--button-accent-color), transparent 10%)',
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
':active': {
|
|
92
|
+
opacity: 0.8,
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
'&:focus-visible': {
|
|
96
|
+
borderColor: 'var(--text-color)',
|
|
97
|
+
boxShadow: '0px 0px 3px var(--text-color)',
|
|
98
|
+
outline: 'none',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
mainTabs,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
3
|
+
import * as styles from './styles.js';
|
|
4
|
+
import TabLayout from '../tab-layout/widget.js';
|
|
5
|
+
|
|
6
|
+
class MainTabs extends Widget {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.styles = styles;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
render() {
|
|
13
|
+
const {className = '', ...props} = this.props;
|
|
14
|
+
return (
|
|
15
|
+
<TabLayout.Tabs
|
|
16
|
+
{...props}
|
|
17
|
+
className={this.styles.classNames.mainTabs + ' ' + className}
|
|
18
|
+
></TabLayout.Tabs>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default MainTabs;
|