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,103 @@
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 {number as NumberConverters} 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 {mdiMinus, mdiPlus} from '@mdi/js';
11
+
12
+ class MagicNumberFieldNC 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
+ parse = (value) => {
24
+ const {min, max} = this.props;
25
+ const edited = NumberConverters.parseEdited(value, min, max);
26
+ return edited.value;
27
+ };
28
+
29
+ format = (value) => {
30
+ if (!value && value !== 0) {
31
+ return '';
32
+ }
33
+ return NumberConverters.getDisplayed(value);
34
+ };
35
+
36
+ increase = () => {
37
+ const {value, max, step = 1} = this.props;
38
+ if (max === undefined || value < max) {
39
+ this.props.onChange?.(value + step);
40
+ }
41
+ };
42
+
43
+ decrease = () => {
44
+ const {value, min, step = 1} = this.props;
45
+ if (min === undefined || value > min) {
46
+ this.props.onChange?.(value - step);
47
+ }
48
+ };
49
+
50
+ handleKeyDown = (event) => {
51
+ this.props.onKeyDown?.(event);
52
+
53
+ if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
54
+ const {max, min, step = 1} = this.props;
55
+ const value = this.parse(event.target.value);
56
+ const newStep = event.shiftKey ? 10 * step : step;
57
+ const direction = event.key === 'ArrowUp' ? 1 : -1;
58
+ let newValue = value + newStep * direction;
59
+ if (max !== undefined && newValue > max) {
60
+ newValue = max;
61
+ }
62
+ if (min !== undefined && newValue < min) {
63
+ newValue = min;
64
+ }
65
+ if (newValue !== value) {
66
+ const text = this.format(newValue);
67
+ this.input.changeAndSelect(
68
+ text,
69
+ event.shiftKey ? 0 : text.length,
70
+ text.length
71
+ );
72
+ }
73
+
74
+ event.preventDefault();
75
+ }
76
+ };
77
+
78
+ render() {
79
+ const {className = '', ...props} = this.props;
80
+ return (
81
+ <InputGroup>
82
+ <MagicTextField
83
+ inputRef={this.inputRef}
84
+ format={this.format}
85
+ parse={this.parse}
86
+ {...props}
87
+ onKeyDown={this.handleKeyDown}
88
+ className={this.styles.classNames.numberField + ' ' + className}
89
+ />
90
+ <MagicButton onClick={this.decrease} disabled={props.disabled}>
91
+ <Icon path={mdiMinus} size={0.8} />
92
+ </MagicButton>
93
+ <MagicButton onClick={this.increase} disabled={props.disabled}>
94
+ <Icon path={mdiPlus} size={0.8} />
95
+ </MagicButton>
96
+ </InputGroup>
97
+ );
98
+ }
99
+ }
100
+ const MagicNumberField = withC(MagicNumberFieldNC, {value: 'onChange'});
101
+ MagicNumberField.displayName = 'MagicNumberField';
102
+
103
+ export default MagicNumberField;
@@ -0,0 +1,61 @@
1
+ /******************************************************************************/
2
+
3
+ export default function styles() {
4
+ const action = {
5
+ padding: '4px',
6
+ };
7
+
8
+ const show = {
9
+ position: 'fixed',
10
+ top: '47px',
11
+ left: 0,
12
+ width: '50%',
13
+ height: 'auto',
14
+ transition: 'width 0.2s ease, opacity 0.2s ease',
15
+ // zIndex: 10000,
16
+ };
17
+
18
+ const hidden = {
19
+ ...show,
20
+ left: '-2px',
21
+ width: '0%',
22
+ };
23
+
24
+ const content = {
25
+ display: 'flex',
26
+ flexDirection: 'column',
27
+ };
28
+
29
+ const hiddenContent = {
30
+ visibility: 'hidden',
31
+ };
32
+
33
+ const shortcut = {
34
+ fontSize: '80%',
35
+ };
36
+
37
+ const closeButton = {
38
+ 'position': 'absolute',
39
+ 'top': 0,
40
+ 'right': 0,
41
+ 'fontSize': '20px',
42
+ 'padding': '7px 10px',
43
+ 'opacity': 0.6,
44
+ 'cursor': 'pointer',
45
+ ':hover': {
46
+ opacity: 1,
47
+ },
48
+ };
49
+
50
+ return {
51
+ hiddenContent,
52
+ content,
53
+ action,
54
+ hidden,
55
+ show,
56
+ shortcut,
57
+ closeButton,
58
+ };
59
+ }
60
+
61
+ /******************************************************************************/
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import Widget from 'goblin-laboratory/widgets/widget';
3
+ import * as styles from './styles.js';
4
+ import MagicButton from '../magic-button/widget.js';
5
+ import MagicDiv from '../magic-div/widget.js';
6
+ import Icon from '@mdi/react';
7
+ import {mdiClose} from '@mdi/js';
8
+
9
+ class MagicPanel extends Widget {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.styles = styles;
13
+ this.state = {
14
+ hidden: true,
15
+ };
16
+ this.togglePanel = this.togglePanel.bind(this);
17
+ }
18
+
19
+ componentDidMount() {
20
+ // Mousetrap.bind('ctrl+space', this.togglePanel);
21
+ }
22
+
23
+ togglePanel() {
24
+ this.setState({hidden: !this.state.hidden});
25
+ }
26
+
27
+ render() {
28
+ const classState = this.state.hidden ? 'hidden' : 'show';
29
+ return (
30
+ <>
31
+ <div className={this.styles.classNames.action}>
32
+ <MagicButton onClick={this.togglePanel}>
33
+ Menu{' '}
34
+ <span className={this.styles.classNames.shortcut}>
35
+ (ctrl+space)
36
+ </span>
37
+ </MagicButton>
38
+ </div>
39
+ <MagicDiv className={this.styles.classNames[classState]}>
40
+ <div
41
+ className={
42
+ classState === 'hidden'
43
+ ? this.styles.classNames.hiddenContent
44
+ : this.styles.classNames.content
45
+ }
46
+ >
47
+ <div
48
+ className={this.styles.classNames.closeButton}
49
+ onClick={this.togglePanel}
50
+ >
51
+ <Icon path={mdiClose} />
52
+ </div>
53
+ {this.props.children}
54
+ </div>
55
+ </MagicDiv>
56
+ </>
57
+ );
58
+ }
59
+ }
60
+
61
+ /******************************************************************************/
62
+
63
+ export default MagicPanel;
@@ -0,0 +1,93 @@
1
+ /******************************************************************************/
2
+
3
+ export default function styles() {
4
+ const input = {
5
+ 'display': 'flex',
6
+ 'justifyContent': 'center',
7
+ 'alignItems': 'center',
8
+ 'width': '24px',
9
+ 'height': '24px',
10
+ 'margin': '1px 0',
11
+ 'flexShrink': 0,
12
+ 'position': 'relative',
13
+ // 'bottom': '1px',
14
+ 'top': '1px',
15
+ 'cursor': 'pointer',
16
+
17
+ 'appearance': 'none',
18
+ 'backgroundColor': 'color-mix(in srgb, var(--text-color), transparent 80%)',
19
+ 'border':
20
+ '1px solid color-mix(in srgb, var(--text-color), transparent 60%)',
21
+ 'borderRadius': '50%',
22
+
23
+ '&::after': {
24
+ content: "''",
25
+ display: 'block',
26
+ width: '16px',
27
+ height: '16px',
28
+ borderRadius: '50%',
29
+ backgroundColor: 'rgba(15, 26, 54, 0.8)',
30
+ opacity: 0,
31
+ },
32
+
33
+ '&:checked::after': {
34
+ opacity: 1,
35
+ },
36
+
37
+ '&:focus-visible': {
38
+ borderColor: 'var(--text-color)',
39
+ boxShadow: '0px 0px 3px var(--text-color)',
40
+ outline: 'none',
41
+ },
42
+
43
+ '&:focus': {
44
+ outline: 'none',
45
+ },
46
+
47
+ '&:active': {
48
+ transform: 'scale(0.9)',
49
+ },
50
+
51
+ '&:disabled': {
52
+ 'borderColor': 'transparent',
53
+ 'backgroundColor':
54
+ 'color-mix(in srgb, var(--text-color), transparent 90%)',
55
+ '&:hover': {
56
+ cursor: 'unset',
57
+ },
58
+ },
59
+ };
60
+
61
+ const radioLabel = {
62
+ 'display': 'flex',
63
+ 'alignItems': 'center',
64
+ // 'alignItems': 'baseline',
65
+
66
+ '&:hover input[type=radio]': {
67
+ 'backgroundColor':
68
+ 'color-mix(in srgb, var(--text-color), transparent 60%)',
69
+
70
+ '&:disabled': {
71
+ backgroundColor:
72
+ 'color-mix(in srgb, var(--text-color), transparent 90%)',
73
+ },
74
+ },
75
+ };
76
+
77
+ const text = {
78
+ // 'display': 'flex',
79
+ // 'alignItems': 'baseline',
80
+ 'marginLeft': '8px',
81
+ '&:empty': {
82
+ marginLeft: 0,
83
+ },
84
+ };
85
+
86
+ return {
87
+ radioLabel,
88
+ input,
89
+ text,
90
+ };
91
+ }
92
+
93
+ /******************************************************************************/
@@ -0,0 +1,74 @@
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 InputRadio 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.value);
15
+ }
16
+
17
+ render() {
18
+ const {name, value, checked, state, ...props} = this.props;
19
+ return (
20
+ <input
21
+ {...props}
22
+ type="radio"
23
+ name={name}
24
+ value={value}
25
+ checked={state !== undefined ? state === value : checked}
26
+ className={this.styles.classNames.input}
27
+ onChange={this.onChange}
28
+ />
29
+ );
30
+ }
31
+ }
32
+
33
+ class MagicRadioNC extends Widget {
34
+ constructor() {
35
+ super(...arguments);
36
+ this.styles = styles;
37
+ }
38
+
39
+ render() {
40
+ const {
41
+ name,
42
+ value,
43
+ checked,
44
+ state,
45
+ onChange,
46
+ text,
47
+ title,
48
+ disabled,
49
+ children,
50
+ className = '',
51
+ ...props
52
+ } = this.props;
53
+ return (
54
+ <label
55
+ className={this.styles.classNames.radioLabel + ' ' + className}
56
+ title={title}
57
+ >
58
+ <InputRadio
59
+ {...props}
60
+ name={name}
61
+ value={value}
62
+ checked={checked}
63
+ state={state}
64
+ onChange={onChange}
65
+ disabled={disabled}
66
+ />
67
+ <span className={this.styles.classNames.text}>{text || children}</span>
68
+ </label>
69
+ );
70
+ }
71
+ }
72
+ const MagicRadio = withC(MagicRadioNC, {state: 'onChange'});
73
+ MagicRadio.displayName = 'MagicRadio';
74
+ export default MagicRadio;
@@ -0,0 +1,22 @@
1
+ export default function styles() {
2
+ const scroll = {
3
+ 'padding': '20px',
4
+ 'overflow': 'auto',
5
+
6
+ '& > h1:first-child': {
7
+ marginTop: 0,
8
+ },
9
+ '& > h2:first-child': {
10
+ marginTop: 0,
11
+ },
12
+ '& > h3:first-child': {
13
+ marginTop: 0,
14
+ },
15
+ };
16
+
17
+ return {
18
+ scroll,
19
+ };
20
+ }
21
+
22
+ /******************************************************************************/
@@ -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
+ export default class MagicScroll extends Widget {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.styles = styles;
9
+ }
10
+
11
+ render() {
12
+ const {className = '', ...props} = this.props;
13
+ return (
14
+ <div
15
+ className={this.styles.classNames.scroll + ' ' + className}
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+ }
@@ -0,0 +1,16 @@
1
+ export default function styles() {
2
+ const selectButton = {
3
+ flexGrow: 0,
4
+ };
5
+
6
+ const chevronDown = {
7
+ position: 'relative',
8
+ top: '1px',
9
+ fontSize: '13px',
10
+ };
11
+
12
+ return {
13
+ selectButton,
14
+ chevronDown,
15
+ };
16
+ }
@@ -0,0 +1,134 @@
1
+ import React from 'react';
2
+ import Widget from 'goblin-laboratory/widgets/widget';
3
+ import * as styles from './styles.js';
4
+ import Menu from '../menu/widget.js';
5
+ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
6
+ import {faChevronDown} from '@fortawesome/free-solid-svg-icons';
7
+ import withC from 'goblin-laboratory/widgets/connect-helpers/with-c.js';
8
+ import C from 'goblin-laboratory/widgets/connect-helpers/c.js';
9
+
10
+ const SelectContext = React.createContext();
11
+
12
+ function examples() {
13
+ <MagicSelect value={C('.type')}>
14
+ <option value="external">External</option>
15
+ <option value="internal">Internal</option>
16
+ <option value="personal">Personal</option>
17
+ </MagicSelect>;
18
+
19
+ <MagicSelect
20
+ value={C('.type')}
21
+ options={{
22
+ external: <>External</>,
23
+ internal: <>Internal</>,
24
+ personal: <>Personal</>,
25
+ }}
26
+ />;
27
+
28
+ <MagicSelect
29
+ value={C('.type')}
30
+ options={[
31
+ {value: 'external', text: <>External</>},
32
+ {value: 'internal', text: <>Internal</>},
33
+ {value: 'personal', text: <>Personal</>},
34
+ ]}
35
+ />;
36
+ }
37
+
38
+ class MagicSelectOption extends Widget {
39
+ constructor() {
40
+ super(...arguments);
41
+ this.styles = styles;
42
+ }
43
+
44
+ render() {
45
+ const {value, children} = this.props;
46
+ return (
47
+ <SelectContext.Consumer>
48
+ {(select) => (
49
+ <Menu.Item value={value} onPointerUp={select.setValue}>
50
+ {children}
51
+ </Menu.Item>
52
+ )}
53
+ </SelectContext.Consumer>
54
+ );
55
+ }
56
+ }
57
+
58
+ class MagicSelectNC extends Widget {
59
+ constructor() {
60
+ super(...arguments);
61
+ this.styles = styles;
62
+ }
63
+
64
+ setValue = (event) => {
65
+ const value = event.currentTarget.value;
66
+ this.props.onChange?.(value, event);
67
+ };
68
+
69
+ render() {
70
+ let {
71
+ className = '',
72
+ value,
73
+ options,
74
+ position,
75
+ onChange,
76
+ children,
77
+ ...props
78
+ } = this.props;
79
+
80
+ let displayedValue = value;
81
+ let list;
82
+ if (options) {
83
+ list = Array.isArray(options)
84
+ ? options
85
+ : Object.entries(options).map(([value, text]) => ({value, text}));
86
+
87
+ displayedValue = list.find((item) => item.value === value)?.text || value;
88
+ } else {
89
+ children = React.Children.map(children, (child) => {
90
+ if (React.isValidElement(child) && child.type === 'option') {
91
+ return <MagicSelectOption {...child.props} />;
92
+ }
93
+ return child;
94
+ });
95
+ React.Children.forEach(children, (child) => {
96
+ if (!React.isValidElement(child)) {
97
+ return;
98
+ }
99
+ if (child.type === MagicSelectOption && child.props.value === value) {
100
+ displayedValue = child.props.children;
101
+ }
102
+ });
103
+ }
104
+
105
+ return (
106
+ <SelectContext.Provider value={this}>
107
+ <Menu>
108
+ <Menu.Button {...props} className={'input no-grow ' + className}>
109
+ {displayedValue}
110
+ <FontAwesomeIcon
111
+ className={this.styles.classNames.chevronDown}
112
+ icon={faChevronDown}
113
+ />
114
+ </Menu.Button>
115
+ <Menu.Content position={position}>
116
+ {list &&
117
+ list.map(({value, text}) => (
118
+ <MagicSelectOption key={value} value={value}>
119
+ {text || value}
120
+ </MagicSelectOption>
121
+ ))}
122
+ {children}
123
+ </Menu.Content>
124
+ </Menu>
125
+ </SelectContext.Provider>
126
+ );
127
+ }
128
+ }
129
+
130
+ const MagicSelect = withC(MagicSelectNC, {value: 'onChange'});
131
+
132
+ MagicSelect.Option = MagicSelectOption;
133
+
134
+ export default MagicSelect;
@@ -0,0 +1,63 @@
1
+ import Shredder from 'xcraft-core-shredder';
2
+ /******************************************************************************/
3
+
4
+ const initialState = new Shredder({
5
+ id: null,
6
+ sortIndex: null,
7
+ sortType: null,
8
+ sortOrder: '-',
9
+ sortCustom: null,
10
+ showMenu: false,
11
+ });
12
+
13
+ /******************************************************************************/
14
+
15
+ export default (state = initialState, action = {}) => {
16
+ switch (action.type) {
17
+ case 'INITIALISE': {
18
+ const {id, columns} = action;
19
+ state = initialState;
20
+ state = state.set('id', id);
21
+ for (const [index, column] of columns.entries()) {
22
+ if (column.sortable && column.sortOrder) {
23
+ state = state.set('sortIndex', index);
24
+ state = state.set('sortType', column.type);
25
+ state = state.set('sortOrder', column.sortOrder);
26
+ state = state.set('sortCustom', column.sortCustom);
27
+ }
28
+ }
29
+ return state;
30
+ }
31
+ case 'TOGGLE_MENU': {
32
+ const {sortIndex, sortType, sortCustom} = action;
33
+ state = state.set('sortIndex', sortIndex);
34
+ state = state.set('sortType', sortType);
35
+ state = state.set('sortCustom', sortCustom);
36
+ state = state.set('showMenu', !state.get('showMenu'));
37
+ return state;
38
+ }
39
+ case 'SORT_COLUMN': {
40
+ const {sortIndex, sortType, sortCustom} = action;
41
+ const current = state.get('sortIndex');
42
+ state = state.set('sortIndex', sortIndex);
43
+ state = state.set('sortType', sortType);
44
+ state = state.set('sortCustom', sortCustom);
45
+
46
+ //set new asc sort for column
47
+ if (current !== sortIndex) {
48
+ state = state.set('sortOrder', 'asc');
49
+ return state;
50
+ }
51
+ //cycle sort
52
+ if (state.get('sortOrder') === '-') {
53
+ state = state.set('sortOrder', 'asc');
54
+ } else if (state.get('sortOrder') === 'asc') {
55
+ state = state.set('sortOrder', 'desc');
56
+ } else {
57
+ state = state.set('sortOrder', '-');
58
+ }
59
+ return state;
60
+ }
61
+ }
62
+ return state;
63
+ };