lupine.components 1.1.13 → 1.1.15

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 (92) hide show
  1. package/README.md +3 -3
  2. package/package.json +42 -42
  3. package/src/components/action-sheet.tsx +419 -419
  4. package/src/components/button-push-animation.tsx +147 -138
  5. package/src/components/button.tsx +55 -55
  6. package/src/components/desktop-footer.tsx +17 -17
  7. package/src/components/desktop-header.tsx +52 -52
  8. package/src/components/drag-refresh.tsx +129 -129
  9. package/src/components/editable-label.tsx +83 -83
  10. package/src/components/float-window.tsx +233 -233
  11. package/src/components/grid.tsx +18 -18
  12. package/src/components/html-load.tsx +41 -41
  13. package/src/components/html-var.tsx +81 -81
  14. package/src/components/index.ts +43 -44
  15. package/src/components/input-with-title.tsx +24 -24
  16. package/src/components/link-item.tsx +13 -13
  17. package/src/components/link-list.tsx +62 -62
  18. package/src/components/menu-bar.tsx +219 -219
  19. package/src/components/menu-item-props.tsx +13 -13
  20. package/src/components/menu-sidebar.tsx +325 -318
  21. package/src/components/message-box.tsx +44 -44
  22. package/src/components/meta-data.tsx +36 -36
  23. package/src/components/meta-description.tsx +12 -12
  24. package/src/components/mobile-components/icon-menu-item-props.ts +6 -6
  25. package/src/components/mobile-components/index.ts +8 -9
  26. package/src/components/mobile-components/mobile-footer-menu.tsx +95 -95
  27. package/src/components/mobile-components/mobile-header-component.tsx +101 -101
  28. package/src/components/mobile-components/mobile-header-title-icon.tsx +109 -101
  29. package/src/components/mobile-components/mobile-header-with-back.tsx +127 -117
  30. package/src/components/mobile-components/mobile-side-menu.tsx +154 -154
  31. package/src/components/mobile-components/mobile-top-sys-icon.tsx +18 -18
  32. package/src/components/mobile-components/mobile-top-sys-menu.tsx +62 -62
  33. package/src/components/modal.tsx +33 -33
  34. package/src/components/notice-message.tsx +118 -118
  35. package/src/components/page-title.tsx +6 -6
  36. package/src/components/paging-link.tsx +175 -175
  37. package/src/components/panel.tsx +21 -21
  38. package/src/components/popup-menu.tsx +289 -289
  39. package/src/components/progress.tsx +91 -91
  40. package/src/components/radio-label-component.tsx +36 -36
  41. package/src/components/redirect.tsx +19 -19
  42. package/src/components/resizable-splitter.tsx +128 -128
  43. package/src/components/select-angle-component.tsx +127 -127
  44. package/src/components/select-with-title.tsx +37 -37
  45. package/src/components/slide-tab-component.tsx +144 -149
  46. package/src/components/spinner.tsx +106 -100
  47. package/src/components/stars-component.tsx +66 -66
  48. package/src/components/svg.tsx +24 -24
  49. package/src/components/tabs.tsx +279 -279
  50. package/src/components/text-glow.tsx +37 -37
  51. package/src/components/text-scale.tsx +42 -42
  52. package/src/components/text-wave.tsx +55 -55
  53. package/src/components/theme-selector.tsx +28 -28
  54. package/src/components/toggle-base.tsx +285 -269
  55. package/src/components/toggle-switch.tsx +160 -160
  56. package/src/frames/index.ts +3 -3
  57. package/src/frames/responsive-frame.tsx +83 -83
  58. package/src/frames/slider-frame.tsx +111 -111
  59. package/src/frames/top-frame.tsx +30 -30
  60. package/src/index.ts +5 -5
  61. package/src/lib/back-action-helper.ts +54 -54
  62. package/src/lib/base62.ts +23 -23
  63. package/src/lib/blob-utils.ts +23 -23
  64. package/src/lib/calculate-text-width.ts +13 -13
  65. package/src/lib/date-utils.ts +317 -317
  66. package/src/lib/deep-merge.ts +37 -37
  67. package/src/lib/document-ready.ts +34 -34
  68. package/src/lib/dom-utils.ts +32 -32
  69. package/src/lib/download-file.ts +118 -118
  70. package/src/lib/download-link.ts +12 -12
  71. package/src/lib/download-stream.ts +19 -19
  72. package/src/lib/drag-util.ts +118 -118
  73. package/src/lib/dynamical-load.ts +134 -134
  74. package/src/lib/encode-html.ts +27 -27
  75. package/src/lib/find-parent-tag.ts +8 -8
  76. package/src/lib/format-bytes.ts +11 -11
  77. package/src/lib/index.ts +24 -24
  78. package/src/lib/lite-dom.ts +225 -225
  79. package/src/lib/message-hub.ts +103 -104
  80. package/src/lib/observable.ts +188 -188
  81. package/src/lib/path-utils.ts +42 -42
  82. package/src/lib/promise-timeout.ts +1 -1
  83. package/src/lib/simple-storage.ts +40 -40
  84. package/src/lib/stop-propagation.ts +7 -7
  85. package/src/lib/upload-file.ts +101 -101
  86. package/src/styles/base-themes.ts +17 -17
  87. package/src/styles/dark-themes.ts +99 -99
  88. package/src/styles/index.ts +5 -5
  89. package/src/styles/light-themes.ts +106 -106
  90. package/src/styles/media-query.ts +93 -93
  91. package/src/styles/shared-themes.ts +57 -57
  92. package/tsconfig.json +113 -113
@@ -1,318 +1,325 @@
1
- import { bindGlobalStyle, CssProps, getRenderPageProps, RefProps } from 'lupine.web';
2
- import { stopPropagation } from '../lib';
3
- import { MediaQueryMaxWidth } from '../styles';
4
- import { NestMenuItemProps } from './menu-item-props';
5
-
6
- // const fetchMenu = async (menuId: string) => {
7
- // const data = await getRenderPageProps().renderPageFunctions.fetchData(`/api/menu/get/${menuId}`);
8
- // return data.json;
9
- // };
10
-
11
- export type MenuSidebarProps = {
12
- mobileMenu?: boolean;
13
- desktopMenu?: boolean;
14
- menuId?: string;
15
- items: NestMenuItemProps[];
16
- className?: string;
17
- maxWidthMobileMenu?: string;
18
- maxWidth?: string;
19
- color?: string;
20
- backgroundColor?: string;
21
- isDevAdmin?: boolean;
22
- };
23
- export const MenuSidebar = ({
24
- mobileMenu,
25
- desktopMenu,
26
- menuId,
27
- items,
28
- className,
29
- color = 'white',
30
- backgroundColor = 'dark',
31
- maxWidth = '100%',
32
- maxWidthMobileMenu = MediaQueryMaxWidth.TabletMax,
33
- isDevAdmin = false,
34
- }: MenuSidebarProps) => {
35
- const css: CssProps = {
36
- // backgroundColor,
37
- '.menu-sidebar-top': {
38
- width: '100%',
39
- backgroundColor: 'var(--sidebar-bg-color)',
40
- maxWidth: maxWidth,
41
- margin: 'auto',
42
- // height: 'auto',
43
- position: 'relative',
44
-
45
- display: 'flex',
46
- // width: '100%',
47
- justifyContent: 'center',
48
- flexDirection: 'column',
49
- },
50
- // '&.mobile .menu-sidebar-top': {
51
- // position: 'absolute',
52
- // },
53
- '.menu-sidebar-item': {
54
- display: 'inline-block',
55
- color,
56
- cursor: 'pointer',
57
- padding: '14px 16px',
58
- textDecoration: 'none',
59
- position: 'relative',
60
- borderBottom: 'var(--sidebar-border)',
61
- },
62
- // select parent when hover on a child, .menu-sidebar-sub-box:hover > .menu-sidebar-item
63
- '.menu-sidebar-item:hover': {
64
- color: 'var(--activatable-color-hover)',
65
- backgroundColor: 'var(--activatable-bg-color-hover)',
66
- },
67
- '.menu-sidebar-sub-box .menu-sidebar-sub': {
68
- display: 'none',
69
- // position: 'absolute',
70
- // color: 'var(--sidebar-sub-color)',
71
- // backgroundColor: 'var(--sidebar-sub-bg-color)',
72
- minWidth: '165px',
73
- // boxShadow: '0px 8px 16px 0px rgba(0,0,0,0.2)',
74
- zIndex: 'var(--layer-sidebar-sub)',
75
- flexDirection: 'column',
76
- },
77
- '.menu-sidebar-sub-box > .menu-sidebar-item': {
78
- padding: '14px 26px 14px 16px',
79
- width: '100%',
80
- },
81
- '.menu-sidebar-sub-box > .menu-sidebar-sub > .menu-sidebar-item': {
82
- paddingLeft: '32px',
83
- },
84
- '.menu-sidebar-sub-box > .menu-sidebar-item::after': {
85
- content: '""',
86
- position: 'absolute',
87
- top: '50%',
88
- transform: 'translateY(-50%) rotate(-90deg)',
89
- marginLeft: '6px',
90
- width: 0,
91
- height: 0,
92
- borderLeft: '5px solid transparent',
93
- borderRight: '5px solid transparent',
94
- borderTop: '5px solid ' + color,
95
- right: '10px',
96
- transition: 'all 300ms ease-in-out',
97
- },
98
- '.menu-sidebar-sub-box.open > .menu-sidebar-item::after': {
99
- transform: 'rotate(0deg)',
100
- },
101
- '&.mobile .menu-sidebar-sub-box > .menu-sidebar-item::after': {
102
- transform: 'rotate(0deg)',
103
- },
104
- // '.menu-sidebar-sub-box .menu-sidebar-sub > .menu-sidebar-item': {
105
- // color: 'black',
106
- // },
107
- '.menu-sidebar-sub-box.open > .menu-sidebar-sub': {
108
- display: 'flex',
109
- },
110
- '.menu-sidebar-sub-box .menu-sidebar-sub .menu-sidebar-item:hover': {
111
- color: 'var(--activatable-color-hover)',
112
- backgroundColor: 'var(--activatable-bg-color-hover)',
113
- },
114
- '.menu-sidebar-mobile': {
115
- display: 'none',
116
- position: 'relative',
117
- // backgroundColor: 'var(--primary-bg-color)',
118
- padding: '5px 4px 6px',
119
- '.menu-sidebar-toggle': {
120
- cursor: 'pointer',
121
- padding: '6px 0 8px 0',
122
- 'span, span::before, span::after': {
123
- cursor: 'pointer',
124
- height: '3px',
125
- width: '25px',
126
- borderRadius: '1px',
127
- background: 'var(--primary-color)',
128
- position: 'absolute',
129
- display: 'block',
130
- transition: 'all 300ms ease-in-out',
131
- },
132
- 'span::before, span::after': {
133
- content: '""',
134
- },
135
- 'span::before': {
136
- top: '-7px',
137
- },
138
- 'span::after': {
139
- bottom: '-7px',
140
- },
141
- },
142
- '.menu-sidebar-toggle.active span': {
143
- backgroundColor: 'transparent',
144
- },
145
- '.menu-sidebar-toggle.active span::before': {
146
- transform: 'rotate(45deg)',
147
- top: 0,
148
- },
149
- '.menu-sidebar-toggle.active span::after': {
150
- transform: 'rotate(-45deg)',
151
- top: 0,
152
- },
153
- },
154
- // hide menu for mobile place
155
- '&.mobile': {
156
- display: 'none',
157
- // width: '33px',
158
- },
159
- '&.mobile .menu-sidebar-mobile': {
160
- display: 'block',
161
- width: '33px',
162
- },
163
- ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
164
- // hide menu for not mobile place
165
- display: 'none',
166
- // show menu for mobile place
167
- '&.mobile': {
168
- display: 'block',
169
- },
170
- '&.mobile.open': {
171
- position: 'absolute',
172
- width: '100%',
173
- height: '100%',
174
- top: 0,
175
- left: 0,
176
- display: 'flex',
177
- flexDirection: 'column',
178
- backgroundColor: '#ccccccc2',
179
- zIndex: 'var(--layer-sidebar)',
180
- },
181
- '.menu-sidebar-top': {
182
- display: 'none',
183
- },
184
- '.menu-sidebar-top.open': {
185
- display: 'flex',
186
- flexDirection: 'column',
187
- // left: 0,
188
- // top: 0,
189
- flex: 1,
190
- overflowY: 'auto',
191
- // paddingTop: '200px',
192
- width: '200px',
193
- marginLeft: 'unset',
194
- justifyContent: 'start',
195
- },
196
- '.menu-sidebar-top.open .menu-sidebar-sub-box > .menu-sidebar-sub': {
197
- display: 'flex',
198
- position: 'unset',
199
- '.menu-sidebar-item': {
200
- paddingLeft: '32px',
201
- color,
202
- backgroundColor,
203
- },
204
- '.menu-sidebar-item:hover': {
205
- color: 'var(--activatable-color-hover)',
206
- backgroundColor: 'var(--activatable-bg-color-hover)',
207
- },
208
- },
209
- '.menu-sidebar-sub-box:hover > .menu-sidebar-item': {
210
- backgroundColor: 'unset',
211
- },
212
- '.menu-sidebar-sub-box:hover > .menu-sidebar-item:hover': {
213
- color: 'var(--activatable-color-hover)',
214
- backgroundColor: 'var(--activatable-bg-color-hover)',
215
- },
216
- },
217
- };
218
-
219
- // first level is grouped
220
- const renderItems = (items: NestMenuItemProps[], className: string) => {
221
- return (
222
- <div class={className}>
223
- {items.filter((item) => isDevAdmin || !item.devAdmin).map((item) => {
224
- if (item.hide === true) {
225
- return null;
226
- }
227
- let ref: RefProps = {};
228
- return item.items ? (
229
- <div ref={ref} class='menu-sidebar-sub-box' onClick={() => onItemToggleClick(ref)}>
230
- <div class='menu-sidebar-item'>{item.text}</div>
231
- {renderItems(item.items, 'menu-sidebar-sub')}
232
- </div>
233
- ) : item.js ? (
234
- <a
235
- class='menu-sidebar-item'
236
- href='javascript:void(0)'
237
- alt={item.alt || item.text}
238
- onClick={(event) => {
239
- stopPropagation(event);
240
- // hide menu
241
- onToggleClick(event);
242
- item.js && item.js();
243
- }}
244
- >
245
- {item.text}
246
- </a>
247
- ) : (
248
- <a class='menu-sidebar-item' href={item.url} alt={item.alt || item.text} target='_blank'>
249
- {item.text}
250
- </a>
251
- );
252
- })}
253
- </div>
254
- );
255
- };
256
-
257
- const ref: RefProps = {
258
- // onLoad: async () => {
259
- // if (menuId) {
260
- // const menu = await fetchMenu(menuId);
261
- // if (menu.result.items.length > 0) {
262
- // const items = menu.result.items.map((i: any) => {
263
- // const l = i.split('\t');
264
- // return { text: l[5], url: l[4] };
265
- // });
266
- // const newDom = renderItems(items, 'menu-sidebar-top');
267
- // //mountComponents('.menu-sidebar-top', newDom);
268
- // }
269
- // }
270
- // },
271
- };
272
- const onToggleClick = (event: Event) => {
273
- event.stopPropagation();
274
- const menu = ref.$('.menu-sidebar-mobile .menu-sidebar-toggle');
275
- menu.classList.toggle('active');
276
- const topMenu = ref.$('.menu-sidebar-top');
277
- topMenu.classList.toggle('open');
278
- ref.current.classList.toggle('open');
279
- };
280
- const onItemToggleClick = (ref: RefProps) => {
281
- // if (event.target != ref.current && (event.target as any).parentNode != ref.current) {
282
- // return;
283
- // }
284
- ref.current.classList.toggle('open');
285
- };
286
-
287
- // if this component is used twice, then the Global styles is only set at the first time
288
- bindGlobalStyle('menu-sidebar-box', css);
289
-
290
- // show the menu on both mobile and desktop
291
- const newCss: CssProps =
292
- (!desktopMenu && !mobileMenu) || (desktopMenu && mobileMenu)
293
- ? {
294
- ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
295
- display: 'block',
296
- '.menu-sidebar-top': {
297
- display: 'block',
298
- },
299
- },
300
- }
301
- : {};
302
- const onMaskClick = (event: MouseEvent) => {
303
- if (ref.current.classList.contains('open')) {
304
- onToggleClick(event);
305
- }
306
- };
307
- return (
308
- <div css={newCss} ref={ref} class={['menu-sidebar-box', className, mobileMenu ? 'mobile' : ''].join(' ')} onClick={onMaskClick}>
309
- <div class='menu-sidebar-mobile'>
310
- <div class='menu-sidebar-toggle' onClick={onToggleClick}>
311
- <span></span>
312
- </div>
313
- </div>
314
-
315
- {renderItems(items, 'menu-sidebar-top')}
316
- </div>
317
- );
318
- };
1
+ import { bindGlobalStyle, CssProps, getRenderPageProps, RefProps } from 'lupine.web';
2
+ import { stopPropagation } from '../lib';
3
+ import { MediaQueryMaxWidth } from '../styles';
4
+ import { NestMenuItemProps } from './menu-item-props';
5
+
6
+ // const fetchMenu = async (menuId: string) => {
7
+ // const data = await getRenderPageProps().renderPageFunctions.fetchData(`/api/menu/get/${menuId}`);
8
+ // return data.json;
9
+ // };
10
+
11
+ export type MenuSidebarProps = {
12
+ mobileMenu?: boolean;
13
+ desktopMenu?: boolean;
14
+ menuId?: string;
15
+ items: NestMenuItemProps[];
16
+ className?: string;
17
+ maxWidthMobileMenu?: string;
18
+ maxWidth?: string;
19
+ color?: string;
20
+ backgroundColor?: string;
21
+ isDevAdmin?: boolean;
22
+ };
23
+ export const MenuSidebar = ({
24
+ mobileMenu,
25
+ desktopMenu,
26
+ menuId,
27
+ items,
28
+ className,
29
+ color = 'white',
30
+ backgroundColor = 'dark',
31
+ maxWidth = '100%',
32
+ maxWidthMobileMenu = MediaQueryMaxWidth.TabletMax,
33
+ isDevAdmin = false,
34
+ }: MenuSidebarProps) => {
35
+ const css: CssProps = {
36
+ // backgroundColor,
37
+ '.menu-sidebar-top': {
38
+ width: '100%',
39
+ backgroundColor: 'var(--sidebar-bg-color)',
40
+ maxWidth: maxWidth,
41
+ margin: 'auto',
42
+ // height: 'auto',
43
+ position: 'relative',
44
+
45
+ display: 'flex',
46
+ // width: '100%',
47
+ justifyContent: 'center',
48
+ flexDirection: 'column',
49
+ },
50
+ // '&.mobile .menu-sidebar-top': {
51
+ // position: 'absolute',
52
+ // },
53
+ '.menu-sidebar-item': {
54
+ display: 'inline-block',
55
+ color,
56
+ cursor: 'pointer',
57
+ padding: '14px 16px',
58
+ textDecoration: 'none',
59
+ position: 'relative',
60
+ borderBottom: 'var(--sidebar-border)',
61
+ },
62
+ // select parent when hover on a child, .menu-sidebar-sub-box:hover > .menu-sidebar-item
63
+ '.menu-sidebar-item:hover': {
64
+ color: 'var(--activatable-color-hover)',
65
+ backgroundColor: 'var(--activatable-bg-color-hover)',
66
+ },
67
+ '.menu-sidebar-sub-box .menu-sidebar-sub': {
68
+ display: 'none',
69
+ // position: 'absolute',
70
+ // color: 'var(--sidebar-sub-color)',
71
+ // backgroundColor: 'var(--sidebar-sub-bg-color)',
72
+ minWidth: '165px',
73
+ // boxShadow: '0px 8px 16px 0px rgba(0,0,0,0.2)',
74
+ zIndex: 'var(--layer-sidebar-sub)',
75
+ flexDirection: 'column',
76
+ },
77
+ '.menu-sidebar-sub-box > .menu-sidebar-item': {
78
+ padding: '14px 26px 14px 16px',
79
+ width: '100%',
80
+ },
81
+ '.menu-sidebar-sub-box > .menu-sidebar-sub > .menu-sidebar-item': {
82
+ paddingLeft: '32px',
83
+ },
84
+ '.menu-sidebar-sub-box > .menu-sidebar-item::after': {
85
+ content: '""',
86
+ position: 'absolute',
87
+ top: '50%',
88
+ transform: 'translateY(-50%) rotate(-90deg)',
89
+ marginLeft: '6px',
90
+ width: 0,
91
+ height: 0,
92
+ borderLeft: '5px solid transparent',
93
+ borderRight: '5px solid transparent',
94
+ borderTop: '5px solid ' + color,
95
+ right: '10px',
96
+ transition: 'all 300ms ease-in-out',
97
+ },
98
+ '.menu-sidebar-sub-box.open > .menu-sidebar-item::after': {
99
+ transform: 'rotate(0deg)',
100
+ },
101
+ '&.mobile .menu-sidebar-sub-box > .menu-sidebar-item::after': {
102
+ transform: 'rotate(0deg)',
103
+ },
104
+ // '.menu-sidebar-sub-box .menu-sidebar-sub > .menu-sidebar-item': {
105
+ // color: 'black',
106
+ // },
107
+ '.menu-sidebar-sub-box.open > .menu-sidebar-sub': {
108
+ display: 'flex',
109
+ },
110
+ '.menu-sidebar-sub-box .menu-sidebar-sub .menu-sidebar-item:hover': {
111
+ color: 'var(--activatable-color-hover)',
112
+ backgroundColor: 'var(--activatable-bg-color-hover)',
113
+ },
114
+ '.menu-sidebar-mobile': {
115
+ display: 'none',
116
+ position: 'relative',
117
+ // backgroundColor: 'var(--primary-bg-color)',
118
+ padding: '5px 4px 6px',
119
+ '.menu-sidebar-toggle': {
120
+ cursor: 'pointer',
121
+ padding: '6px 0 8px 0',
122
+ 'span, span::before, span::after': {
123
+ cursor: 'pointer',
124
+ height: '3px',
125
+ width: '25px',
126
+ borderRadius: '1px',
127
+ background: 'var(--primary-color)',
128
+ position: 'absolute',
129
+ display: 'block',
130
+ transition: 'all 300ms ease-in-out',
131
+ },
132
+ 'span::before, span::after': {
133
+ content: '""',
134
+ },
135
+ 'span::before': {
136
+ top: '-7px',
137
+ },
138
+ 'span::after': {
139
+ bottom: '-7px',
140
+ },
141
+ },
142
+ '.menu-sidebar-toggle.active span': {
143
+ backgroundColor: 'transparent',
144
+ },
145
+ '.menu-sidebar-toggle.active span::before': {
146
+ transform: 'rotate(45deg)',
147
+ top: 0,
148
+ },
149
+ '.menu-sidebar-toggle.active span::after': {
150
+ transform: 'rotate(-45deg)',
151
+ top: 0,
152
+ },
153
+ },
154
+ // hide menu for mobile place
155
+ '&.mobile': {
156
+ display: 'none',
157
+ // width: '33px',
158
+ },
159
+ '&.mobile .menu-sidebar-mobile': {
160
+ display: 'block',
161
+ width: '33px',
162
+ },
163
+ ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
164
+ // hide menu for not mobile place
165
+ display: 'none',
166
+ // show menu for mobile place
167
+ '&.mobile': {
168
+ display: 'block',
169
+ },
170
+ '&.mobile.open': {
171
+ position: 'absolute',
172
+ width: '100%',
173
+ height: '100%',
174
+ top: 0,
175
+ left: 0,
176
+ display: 'flex',
177
+ flexDirection: 'column',
178
+ backgroundColor: '#ccccccc2',
179
+ zIndex: 'var(--layer-sidebar)',
180
+ },
181
+ '.menu-sidebar-top': {
182
+ display: 'none',
183
+ },
184
+ '.menu-sidebar-top.open': {
185
+ display: 'flex',
186
+ flexDirection: 'column',
187
+ // left: 0,
188
+ // top: 0,
189
+ flex: 1,
190
+ overflowY: 'auto',
191
+ // paddingTop: '200px',
192
+ width: '200px',
193
+ marginLeft: 'unset',
194
+ justifyContent: 'start',
195
+ },
196
+ '.menu-sidebar-top.open .menu-sidebar-sub-box > .menu-sidebar-sub': {
197
+ display: 'flex',
198
+ position: 'unset',
199
+ '.menu-sidebar-item': {
200
+ paddingLeft: '32px',
201
+ color,
202
+ backgroundColor,
203
+ },
204
+ '.menu-sidebar-item:hover': {
205
+ color: 'var(--activatable-color-hover)',
206
+ backgroundColor: 'var(--activatable-bg-color-hover)',
207
+ },
208
+ },
209
+ '.menu-sidebar-sub-box:hover > .menu-sidebar-item': {
210
+ backgroundColor: 'unset',
211
+ },
212
+ '.menu-sidebar-sub-box:hover > .menu-sidebar-item:hover': {
213
+ color: 'var(--activatable-color-hover)',
214
+ backgroundColor: 'var(--activatable-bg-color-hover)',
215
+ },
216
+ },
217
+ };
218
+
219
+ // first level is grouped
220
+ const renderItems = (items: NestMenuItemProps[], className: string) => {
221
+ return (
222
+ <div class={className}>
223
+ {items
224
+ .filter((item) => isDevAdmin || !item.devAdmin)
225
+ .map((item) => {
226
+ if (item.hide === true) {
227
+ return null;
228
+ }
229
+ let ref: RefProps = {};
230
+ return item.items ? (
231
+ <div ref={ref} class='menu-sidebar-sub-box' onClick={() => onItemToggleClick(ref)}>
232
+ <div class='menu-sidebar-item'>{item.text}</div>
233
+ {renderItems(item.items, 'menu-sidebar-sub')}
234
+ </div>
235
+ ) : item.js ? (
236
+ <a
237
+ class='menu-sidebar-item'
238
+ href='javascript:void(0)'
239
+ alt={item.alt || item.text}
240
+ onClick={(event) => {
241
+ stopPropagation(event);
242
+ // hide menu
243
+ onToggleClick(event);
244
+ item.js && item.js();
245
+ }}
246
+ >
247
+ {item.text}
248
+ </a>
249
+ ) : (
250
+ <a class='menu-sidebar-item' href={item.url} alt={item.alt || item.text} target='_blank'>
251
+ {item.text}
252
+ </a>
253
+ );
254
+ })}
255
+ </div>
256
+ );
257
+ };
258
+
259
+ const ref: RefProps = {
260
+ // onLoad: async () => {
261
+ // if (menuId) {
262
+ // const menu = await fetchMenu(menuId);
263
+ // if (menu.result.items.length > 0) {
264
+ // const items = menu.result.items.map((i: any) => {
265
+ // const l = i.split('\t');
266
+ // return { text: l[5], url: l[4] };
267
+ // });
268
+ // const newDom = renderItems(items, 'menu-sidebar-top');
269
+ // //mountComponents('.menu-sidebar-top', newDom);
270
+ // }
271
+ // }
272
+ // },
273
+ };
274
+ const onToggleClick = (event: Event) => {
275
+ event.stopPropagation();
276
+ const menu = ref.$('.menu-sidebar-mobile .menu-sidebar-toggle');
277
+ menu.classList.toggle('active');
278
+ const topMenu = ref.$('.menu-sidebar-top');
279
+ topMenu.classList.toggle('open');
280
+ ref.current.classList.toggle('open');
281
+ };
282
+ const onItemToggleClick = (ref: RefProps) => {
283
+ // if (event.target != ref.current && (event.target as any).parentNode != ref.current) {
284
+ // return;
285
+ // }
286
+ ref.current.classList.toggle('open');
287
+ };
288
+
289
+ // if this component is used twice, then the Global styles is only set at the first time
290
+ bindGlobalStyle('menu-sidebar-box', css);
291
+
292
+ // show the menu on both mobile and desktop
293
+ const newCss: CssProps =
294
+ (!desktopMenu && !mobileMenu) || (desktopMenu && mobileMenu)
295
+ ? {
296
+ ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
297
+ display: 'block',
298
+ '.menu-sidebar-top': {
299
+ display: 'block',
300
+ },
301
+ },
302
+ }
303
+ : {};
304
+ const onMaskClick = (event: MouseEvent) => {
305
+ if (ref.current.classList.contains('open')) {
306
+ onToggleClick(event);
307
+ }
308
+ };
309
+ return (
310
+ <div
311
+ css={newCss}
312
+ ref={ref}
313
+ class={['menu-sidebar-box', className, mobileMenu ? 'mobile' : ''].join(' ')}
314
+ onClick={onMaskClick}
315
+ >
316
+ <div class='menu-sidebar-mobile'>
317
+ <div class='menu-sidebar-toggle' onClick={onToggleClick}>
318
+ <span></span>
319
+ </div>
320
+ </div>
321
+
322
+ {renderItems(items, 'menu-sidebar-top')}
323
+ </div>
324
+ );
325
+ };