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
package/.editorconfig
ADDED
package/.zou-flow
ADDED
package/eslint.config.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const js = require('@eslint/js');
|
|
2
|
+
const globals = require('globals');
|
|
3
|
+
const react = require('eslint-plugin-react');
|
|
4
|
+
const jsdoc = require('eslint-plugin-jsdoc');
|
|
5
|
+
const babel = require('@babel/eslint-plugin');
|
|
6
|
+
const prettier = require('eslint-config-prettier');
|
|
7
|
+
const babelParser = require('@babel/eslint-parser');
|
|
8
|
+
|
|
9
|
+
module.exports = [
|
|
10
|
+
js.configs.recommended,
|
|
11
|
+
react.configs.flat.recommended,
|
|
12
|
+
jsdoc.configs['flat/recommended'],
|
|
13
|
+
prettier,
|
|
14
|
+
{
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: babelParser,
|
|
17
|
+
parserOptions: {
|
|
18
|
+
requireConfigFile: false, // Évite de devoir spécifier un fichier de configuration Babel
|
|
19
|
+
babelOptions: {
|
|
20
|
+
presets: ['@babel/preset-react'],
|
|
21
|
+
},
|
|
22
|
+
ecmaFeatures: {
|
|
23
|
+
jsx: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
globals: {
|
|
27
|
+
...globals.browser,
|
|
28
|
+
...globals.node,
|
|
29
|
+
...globals.es2022,
|
|
30
|
+
...globals.mocha,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
plugins: {
|
|
34
|
+
'react': react,
|
|
35
|
+
'jsdoc': jsdoc,
|
|
36
|
+
'@babel': babel,
|
|
37
|
+
},
|
|
38
|
+
rules: {
|
|
39
|
+
'eqeqeq': 'error',
|
|
40
|
+
'no-console': 'off',
|
|
41
|
+
'react/display-name': 'off',
|
|
42
|
+
'@babel/no-unused-expressions': 'error', // Utilisation de règles spécifiques à Babel
|
|
43
|
+
'no-unused-vars': [
|
|
44
|
+
'error',
|
|
45
|
+
{
|
|
46
|
+
vars: 'all',
|
|
47
|
+
args: 'none',
|
|
48
|
+
ignoreRestSiblings: true,
|
|
49
|
+
destructuredArrayIgnorePattern: '^_',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
'jsdoc/require-jsdoc': 'off',
|
|
53
|
+
'jsdoc/require-param-description': 'off',
|
|
54
|
+
'jsdoc/require-returns-description': 'off',
|
|
55
|
+
},
|
|
56
|
+
settings: {
|
|
57
|
+
react: {
|
|
58
|
+
version: 'detect',
|
|
59
|
+
},
|
|
60
|
+
jsdoc: {
|
|
61
|
+
mode: 'typescript',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "goblin-magic",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "goblin-magic",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"config": {
|
|
8
|
+
"xcraft": {
|
|
9
|
+
"commands": true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"lodash": "^4.17.21",
|
|
17
|
+
"xcraft-core-goblin": "^5.34.1",
|
|
18
|
+
"xcraft-core-shredder": "^5.3.2",
|
|
19
|
+
"xcraft-core-stones": "^0.4.13"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"emoji-mart": "^5.6.0",
|
|
23
|
+
"@emoji-mart/data": "^1.2.1",
|
|
24
|
+
"@emoji-mart/react": "^1.1.1",
|
|
25
|
+
"@mdi/js": "^7.4.47",
|
|
26
|
+
"@mdi/react": "^1.6.1",
|
|
27
|
+
"goblin-laboratory": "^4.5.0",
|
|
28
|
+
"goblin-nabu": "^2.4.18",
|
|
29
|
+
"mousetrap": "^1.6.5",
|
|
30
|
+
"react": "^17.0.1",
|
|
31
|
+
"react-dom": "^17.0.1",
|
|
32
|
+
"react-splitter-layout": "^4.0.0",
|
|
33
|
+
"xcraft-core-converters": "^4.5.0",
|
|
34
|
+
"xcraft-core-utils": "^4.14.2",
|
|
35
|
+
"xcraft-dev-fontawesome": "^0.1.2",
|
|
36
|
+
"xcraft-dev-prettier": "^2.0.0",
|
|
37
|
+
"xcraft-dev-rules": "^4.4.2"
|
|
38
|
+
},
|
|
39
|
+
"overrides": {
|
|
40
|
+
"react-splitter-layout": {
|
|
41
|
+
"react": "^17.0.1"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"prettier": "xcraft-dev-prettier"
|
|
45
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
3
|
+
import {createPortal} from 'react-dom';
|
|
4
|
+
|
|
5
|
+
export default class Dialog extends Widget {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
|
|
9
|
+
/** @type {React.RefObject<HTMLDialogElement>} */
|
|
10
|
+
this.dialog = React.createRef();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
componentDidMount() {
|
|
14
|
+
this.update();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
componentDidUpdate() {
|
|
18
|
+
this.update();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
close = () => {
|
|
22
|
+
this.dialog.current?.close();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
handleClose = (event) => {
|
|
26
|
+
this.props.onClose?.(event);
|
|
27
|
+
event.stopPropagation();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
handlePointerDown = (event) => {
|
|
31
|
+
this.props.onPointerDown?.(event);
|
|
32
|
+
if (event.target === this.dialog.current) {
|
|
33
|
+
this.closeEnabled = true;
|
|
34
|
+
} else {
|
|
35
|
+
this.closeEnabled = false;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
handlePointerUp = (event) => {
|
|
40
|
+
this.props.onPointerUp?.(event);
|
|
41
|
+
if (this.closeEnabled && event.target === this.dialog.current) {
|
|
42
|
+
this.dialog.current.close();
|
|
43
|
+
}
|
|
44
|
+
this.closeEnabled = false;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
update() {
|
|
48
|
+
if (this.props.open) {
|
|
49
|
+
if (!this.dialog.current?.open) {
|
|
50
|
+
if (this.props.modal) {
|
|
51
|
+
this.dialog.current?.showModal();
|
|
52
|
+
} else {
|
|
53
|
+
this.dialog.current?.show();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
this.dialog.current?.close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
render() {
|
|
62
|
+
const {open, modal, portal = false, ...props} = this.props;
|
|
63
|
+
const dialog = (
|
|
64
|
+
<dialog
|
|
65
|
+
{...props}
|
|
66
|
+
ref={this.dialog}
|
|
67
|
+
onClose={this.handleClose}
|
|
68
|
+
onPointerDown={this.handlePointerDown}
|
|
69
|
+
onPointerUp={this.handlePointerUp}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
if (portal) {
|
|
74
|
+
return createPortal(dialog, document.getElementById('root'));
|
|
75
|
+
}
|
|
76
|
+
return dialog;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import elementHasDirectText from './element-has-direct-text.js';
|
|
2
|
+
import isFlatElement from './is-flat-element.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {HTMLElement} element
|
|
6
|
+
* @param {HTMLElement} [stopAtElement]
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/
|
|
9
|
+
export default function isEmptyAreaElement(element, stopAtElement) {
|
|
10
|
+
for (let e = element; e && e !== stopAtElement; e = e.parentElement) {
|
|
11
|
+
if (!isFlatElement(e) || elementHasDirectText(e)) {
|
|
12
|
+
// console.log(e);
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const nonInteractiveTags = [
|
|
2
|
+
'ARTICLE',
|
|
3
|
+
'ASIDE',
|
|
4
|
+
'BODY',
|
|
5
|
+
'DIV',
|
|
6
|
+
'FOOTER',
|
|
7
|
+
'HEADER',
|
|
8
|
+
'HGROUP',
|
|
9
|
+
'HTML',
|
|
10
|
+
'MAIN',
|
|
11
|
+
'NAV',
|
|
12
|
+
'SECTION',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const interactiveRoles = [
|
|
16
|
+
'button',
|
|
17
|
+
'checkbox',
|
|
18
|
+
'grid',
|
|
19
|
+
'input',
|
|
20
|
+
'menu',
|
|
21
|
+
'option',
|
|
22
|
+
'radio',
|
|
23
|
+
'slider',
|
|
24
|
+
'spinbutton',
|
|
25
|
+
'switch',
|
|
26
|
+
'table',
|
|
27
|
+
'tree',
|
|
28
|
+
'treegrid',
|
|
29
|
+
'widget',
|
|
30
|
+
// More roles could be added
|
|
31
|
+
// see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {HTMLElement} element
|
|
36
|
+
* @returns {boolean}
|
|
37
|
+
*/
|
|
38
|
+
export function hasInteractiveRole(element) {
|
|
39
|
+
return element.role
|
|
40
|
+
?.split(' ')
|
|
41
|
+
.some((role) => interactiveRoles.includes(role));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {HTMLElement} element
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
export default function isFlatElement(element) {
|
|
49
|
+
return (
|
|
50
|
+
nonInteractiveTags.includes(element.tagName) && !hasInteractiveRole(element)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function getPlatform(ua) {
|
|
2
|
+
if (!ua) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
ua = ua.toLowerCase();
|
|
6
|
+
if (ua.includes('linux')) {
|
|
7
|
+
return 'linux';
|
|
8
|
+
}
|
|
9
|
+
if (ua.includes('windows')) {
|
|
10
|
+
return 'windows';
|
|
11
|
+
}
|
|
12
|
+
if (ua.includes('mac os')) {
|
|
13
|
+
return 'macos';
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function getModifiers(event) {
|
|
19
|
+
const platform = getPlatform(navigator.userAgent);
|
|
20
|
+
if (platform === 'macos') {
|
|
21
|
+
return {
|
|
22
|
+
shiftKey: event.shiftKey,
|
|
23
|
+
ctrlKey: event.metaKey,
|
|
24
|
+
altKey: event.altKey,
|
|
25
|
+
metaKey: event.ctrlKey,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
shiftKey: event.shiftKey,
|
|
30
|
+
ctrlKey: event.ctrlKey,
|
|
31
|
+
altKey: event.altKey,
|
|
32
|
+
metaKey: event.metaKey,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export default function styles() {
|
|
2
|
+
const inputGroup = {
|
|
3
|
+
'display': 'inline-flex',
|
|
4
|
+
'flexDirection': 'row',
|
|
5
|
+
'borderRadius': '5px',
|
|
6
|
+
'backgroundColor':
|
|
7
|
+
'color-mix(in srgb, var(--field-background-color), transparent 20%)',
|
|
8
|
+
'outline':
|
|
9
|
+
'1px solid color-mix(in srgb, var(--text-color), transparent 60%)',
|
|
10
|
+
'outlineOffset': '-1px',
|
|
11
|
+
|
|
12
|
+
'& > input': {
|
|
13
|
+
backgroundColor: 'transparent',
|
|
14
|
+
paddingRight: '2px',
|
|
15
|
+
border: 'none',
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
'& > :nth-last-child(n + 2 of :not(dialog))': {
|
|
19
|
+
'borderTopRightRadius': 0,
|
|
20
|
+
'borderBottomRightRadius': 0,
|
|
21
|
+
'&.button:not(:not(:disabled):hover)': {
|
|
22
|
+
borderRightColor:
|
|
23
|
+
'color-mix(in srgb, var(--text-color), transparent 70%)',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
'& > :nth-child(n + 2 of :not(dialog))': {
|
|
28
|
+
'borderTopLeftRadius': 0,
|
|
29
|
+
'borderBottomLeftRadius': 0,
|
|
30
|
+
'&.button:not(:not(:disabled):hover)': {
|
|
31
|
+
borderLeftColor:
|
|
32
|
+
'color-mix(in srgb, var(--text-color), transparent 70%)',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
'& > :hover': {
|
|
37
|
+
zIndex: 0, // Above other buttons in the group
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
'& > .button': {
|
|
41
|
+
'&:not(:hover)': {
|
|
42
|
+
borderColor: 'transparent',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
'&:disabled': {
|
|
46
|
+
'opacity': 1,
|
|
47
|
+
'&:hover': {
|
|
48
|
+
backgroundColor:
|
|
49
|
+
'color-mix(in srgb, var(--button-background-color), transparent 80%)',
|
|
50
|
+
borderColor: 'transparent',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
'&[data-simple=true]': {
|
|
55
|
+
'borderLeft': 'none',
|
|
56
|
+
'borderRight': 'none',
|
|
57
|
+
'color': 'color-mix(in srgb, var(--text-color), transparent 60%)',
|
|
58
|
+
'&:hover': {
|
|
59
|
+
color: 'inherit',
|
|
60
|
+
backgroundColor: 'transparent',
|
|
61
|
+
borderColor: 'transparent',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
'&:focus-within': {
|
|
67
|
+
outlineColor: 'color-mix(in srgb, var(--text-color), transparent 40%)',
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
inputGroup,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
3
|
+
import * as styles from './styles.js';
|
|
4
|
+
|
|
5
|
+
class InputGroup extends Widget {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.styles = styles;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
render() {
|
|
12
|
+
const {className = '', children, ...props} = this.props;
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
{...props}
|
|
16
|
+
className={this.styles.classNames.inputGroup + ' ' + className}
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default InputGroup;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/******************************************************************************/
|
|
2
|
+
export const propNames = ['selected', 'disabled', 'size'];
|
|
3
|
+
export default function styles(theme, props) {
|
|
4
|
+
let size = 16;
|
|
5
|
+
if (props.size) {
|
|
6
|
+
size = props.size;
|
|
7
|
+
}
|
|
8
|
+
let hoverSize = size + 2;
|
|
9
|
+
const action = {
|
|
10
|
+
display: 'inline-block',
|
|
11
|
+
fontSize: `${size}px`,
|
|
12
|
+
margin: `${size / 4}px`,
|
|
13
|
+
fontWeight: 'bold',
|
|
14
|
+
// textTransform: 'uppercase',
|
|
15
|
+
// color: '#fff',
|
|
16
|
+
textDecoration: 'none',
|
|
17
|
+
transition: 'font-size 0.1s ease-in-out',
|
|
18
|
+
cursor: 'default',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const text = {
|
|
22
|
+
':hover': {
|
|
23
|
+
fontSize: `${hoverSize}px`,
|
|
24
|
+
lineHeight: '1em',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (props.selected) {
|
|
29
|
+
action.textShadow = '0 0 20px var(--text-color)';
|
|
30
|
+
text[':hover'] = null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (props.disabled) {
|
|
34
|
+
action.color = 'color-mix(in srgb, var(--text-color), transparent 40%)';
|
|
35
|
+
action.userSelect = 'none';
|
|
36
|
+
text[':hover'] = null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
action,
|
|
41
|
+
text,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/******************************************************************************/
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
class MagicActionNC extends Widget {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.styles = styles;
|
|
10
|
+
this.doCmd = this.doCmd.bind(this);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
doCmd() {
|
|
14
|
+
let [serviceId, action] = this.props.cmd.split('.');
|
|
15
|
+
this.doFor(serviceId, action, this.props.arguments || {});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
togglePanel() {
|
|
19
|
+
this.setState({hidden: !this.state.hidden});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
render() {
|
|
23
|
+
const {disabled} = this.props;
|
|
24
|
+
|
|
25
|
+
const baseProps = {};
|
|
26
|
+
if (!disabled) {
|
|
27
|
+
baseProps.onClick = this.props.onClick || this.doCmd;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div>
|
|
32
|
+
<span className={this.styles.classNames.action} {...baseProps}>
|
|
33
|
+
<span className={this.styles.classNames.text}>{this.props.text}</span>
|
|
34
|
+
</span>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/******************************************************************************/
|
|
41
|
+
|
|
42
|
+
const MagicAction = withC(MagicActionNC);
|
|
43
|
+
|
|
44
|
+
export default MagicAction;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import BG_MILK from './bg-milkyway.png';
|
|
2
|
+
import BG_WHITE from './bg-white.png';
|
|
3
|
+
|
|
4
|
+
/******************************************************************************/
|
|
5
|
+
|
|
6
|
+
const images = {
|
|
7
|
+
milk: BG_MILK,
|
|
8
|
+
white: BG_WHITE,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
window.CSS.registerProperty({
|
|
12
|
+
name: '--aurora-color',
|
|
13
|
+
syntax: '<color>',
|
|
14
|
+
inherits: false,
|
|
15
|
+
initialValue: `transparent`,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
window.CSS.registerProperty({
|
|
19
|
+
name: '--space-dark',
|
|
20
|
+
inherits: false,
|
|
21
|
+
initialValue: `url(${BG_MILK})`,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
window.CSS.registerProperty({
|
|
25
|
+
name: '--space-light',
|
|
26
|
+
inherits: false,
|
|
27
|
+
initialValue: `url(${BG_WHITE})`,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const propNames = [
|
|
31
|
+
'useBackgroundColor',
|
|
32
|
+
'backgroundColor',
|
|
33
|
+
'plainColor',
|
|
34
|
+
];
|
|
35
|
+
export default function styles(theme, props) {
|
|
36
|
+
const {plainColor} = props;
|
|
37
|
+
|
|
38
|
+
const main = {
|
|
39
|
+
'--space-dark': plainColor ? '#0D1D3C' : `url(${images['milk']})`,
|
|
40
|
+
'--space-light': plainColor ? '#CDDFEC' : `url(${images['white']})`,
|
|
41
|
+
'--accent-color': `${props.backgroundColor || 'white'}`,
|
|
42
|
+
'--button-accent-color':
|
|
43
|
+
'color-mix(in srgb, var(--accent-color), #ccc 40%)',
|
|
44
|
+
'--aurora-color': `transparent`,
|
|
45
|
+
'height': '100vh',
|
|
46
|
+
'width': '100vw',
|
|
47
|
+
'display': 'flex',
|
|
48
|
+
'flexDirection': 'column',
|
|
49
|
+
'background': `linear-gradient(to bottom, transparent 40%, var(--aurora-color)), var(--space-dark)`,
|
|
50
|
+
'backgroundSize': 'cover',
|
|
51
|
+
'overflow': 'auto',
|
|
52
|
+
'transition': '--space-dark 3s, --aurora-color 3s',
|
|
53
|
+
|
|
54
|
+
'@media (prefers-color-scheme: light)': {
|
|
55
|
+
// backgroundImage: `linear-gradient(170deg, rgba(207,255,245,1) 0%, rgba(201,216,247,1) 100%)`,
|
|
56
|
+
// backgroundImage: `linear-gradient(to bottom, transparent 40%, var(--aurora-color)), linear-gradient(170deg, rgba(234,255,251,1) 0%, rgba(243,247,255,1) 100%)`,
|
|
57
|
+
background: `linear-gradient(to bottom, transparent 40%, var(--aurora-color)), var(--space-light)`,
|
|
58
|
+
transition: '--space-light 3s, --aurora-color 3s',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (props.useBackgroundColor) {
|
|
63
|
+
main[':hover'] = {
|
|
64
|
+
'--aurora-color': `${props.backgroundColor}42`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const proto = {
|
|
69
|
+
textShadow: 'rgb(179 150 177 / 70%) -2px 0px 40px',
|
|
70
|
+
color: 'rgb(0 0 0)',
|
|
71
|
+
fontSize: '6em',
|
|
72
|
+
textAlign: 'center',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
main,
|
|
77
|
+
proto,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/******************************************************************************/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
3
|
+
import * as styles from './styles.js';
|
|
4
|
+
|
|
5
|
+
/******************************************************************************/
|
|
6
|
+
export default class MagicBackground 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
|
+
{/* <div className={this.styles.classNames.proto}></div> */}
|
|
16
|
+
{this.props.children}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
3
|
+
import * as styles from './styles.js';
|
|
4
|
+
import MagicDiv from '../magic-div/widget.js';
|
|
5
|
+
import MagicScroll from '../magic-scroll/widget.js';
|
|
6
|
+
|
|
7
|
+
class MagicBox extends Widget {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.styles = styles;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
render() {
|
|
14
|
+
const {className = '', children, ...props} = this.props;
|
|
15
|
+
return (
|
|
16
|
+
<MagicDiv
|
|
17
|
+
{...props}
|
|
18
|
+
className={this.styles.classNames.magicBox + ' ' + className}
|
|
19
|
+
>
|
|
20
|
+
<MagicScroll>{children}</MagicScroll>
|
|
21
|
+
</MagicDiv>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/******************************************************************************/
|
|
27
|
+
|
|
28
|
+
export default MagicBox;
|