lupine.web 1.0.14

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/jsx-runtime/index.js +14 -0
  4. package/jsx-runtime/package.json +16 -0
  5. package/jsx-runtime/src/index.d.ts +2 -0
  6. package/package.json +51 -0
  7. package/src/assets/themes/base-themes.ts +16 -0
  8. package/src/assets/themes/dark-themes.ts +85 -0
  9. package/src/assets/themes/index.ts +4 -0
  10. package/src/assets/themes/light-themes.ts +92 -0
  11. package/src/assets/themes/shared-themes.ts +50 -0
  12. package/src/components/button-push-animation.tsx +138 -0
  13. package/src/components/button.tsx +55 -0
  14. package/src/components/drag-refresh.tsx +110 -0
  15. package/src/components/editable-label.tsx +83 -0
  16. package/src/components/float-window.tsx +226 -0
  17. package/src/components/grid.tsx +18 -0
  18. package/src/components/html-var.tsx +41 -0
  19. package/src/components/index.ts +36 -0
  20. package/src/components/input-with-title.tsx +24 -0
  21. package/src/components/link-item.tsx +13 -0
  22. package/src/components/link-list.tsx +62 -0
  23. package/src/components/menu-bar.tsx +220 -0
  24. package/src/components/menu-item-props.tsx +10 -0
  25. package/src/components/menu-sidebar.tsx +289 -0
  26. package/src/components/message-box.tsx +44 -0
  27. package/src/components/meta-data.tsx +54 -0
  28. package/src/components/meta-description.tsx +19 -0
  29. package/src/components/meta-title.tsx +19 -0
  30. package/src/components/modal.tsx +29 -0
  31. package/src/components/notice-message.tsx +119 -0
  32. package/src/components/paging-link.tsx +100 -0
  33. package/src/components/panel.tsx +24 -0
  34. package/src/components/popup-menu.tsx +218 -0
  35. package/src/components/progress.tsx +91 -0
  36. package/src/components/redirect.tsx +19 -0
  37. package/src/components/resizable-splitter.tsx +129 -0
  38. package/src/components/select-with-title.tsx +37 -0
  39. package/src/components/spinner.tsx +100 -0
  40. package/src/components/svg.tsx +24 -0
  41. package/src/components/tabs.tsx +252 -0
  42. package/src/components/text-glow.tsx +36 -0
  43. package/src/components/text-wave.tsx +54 -0
  44. package/src/components/theme-selector.tsx +35 -0
  45. package/src/components/toggle-base.tsx +260 -0
  46. package/src/components/toggle-switch.tsx +156 -0
  47. package/src/core/bind-attributes.ts +58 -0
  48. package/src/core/bind-lang.ts +51 -0
  49. package/src/core/bind-links.ts +16 -0
  50. package/src/core/bind-ref.ts +33 -0
  51. package/src/core/bind-styles.ts +180 -0
  52. package/src/core/bind-theme.ts +51 -0
  53. package/src/core/camel-to-hyphens.ts +3 -0
  54. package/src/core/core.ts +179 -0
  55. package/src/core/index.ts +15 -0
  56. package/src/core/mount-components.ts +259 -0
  57. package/src/core/page-loaded-events.ts +16 -0
  58. package/src/core/page-router.ts +170 -0
  59. package/src/core/replace-innerhtml.ts +10 -0
  60. package/src/core/server-cookie.ts +22 -0
  61. package/src/core/web-version.ts +12 -0
  62. package/src/global.d.ts +66 -0
  63. package/src/index.ts +15 -0
  64. package/src/jsx.ts +1041 -0
  65. package/src/lib/date-utils.ts +317 -0
  66. package/src/lib/debug-watch.ts +31 -0
  67. package/src/lib/deep-merge.ts +37 -0
  68. package/src/lib/document-ready.ts +36 -0
  69. package/src/lib/dom/calculate-text-width.ts +13 -0
  70. package/src/lib/dom/cookie.ts +41 -0
  71. package/src/lib/dom/download-stream.ts +17 -0
  72. package/src/lib/dom/download.ts +12 -0
  73. package/src/lib/dom/index.ts +71 -0
  74. package/src/lib/dynamical-load.ts +138 -0
  75. package/src/lib/format-bytes.ts +11 -0
  76. package/src/lib/index.ts +17 -0
  77. package/src/lib/lite-dom.ts +227 -0
  78. package/src/lib/logger.ts +55 -0
  79. package/src/lib/message-hub.ts +105 -0
  80. package/src/lib/observable.ts +188 -0
  81. package/src/lib/promise-timeout.ts +1 -0
  82. package/src/lib/simple-storage.ts +40 -0
  83. package/src/lib/stop-propagation.ts +7 -0
  84. package/src/lib/unique-id.ts +39 -0
  85. package/src/lib/upload-file.ts +68 -0
  86. package/src/lib/web-env.ts +98 -0
  87. package/src/models/index.ts +2 -0
  88. package/src/models/simple-storage-props.ts +9 -0
  89. package/src/models/to-client-delivery-props.ts +8 -0
  90. package/src/types/css-styles.ts +814 -0
  91. package/src/types/css-types.ts +17 -0
  92. package/src/types/index.ts +6 -0
  93. package/src/types/media-query.ts +93 -0
  94. package/tsconfig.json +113 -0
@@ -0,0 +1,220 @@
1
+ import { getRenderPageProps } from '../core';
2
+ import { RefProps } from '../jsx';
3
+ import { MediaQueryMaxWidth } from '../types';
4
+ import { LinkItem } from './link-item';
5
+ import { NestMenuItemProps } from './menu-item-props';
6
+
7
+ const fetchMenu = async (menuId: string) => {
8
+ const data = await getRenderPageProps().renderPageFunctions.fetchData(`/api/menu/get/${menuId}`);
9
+ return data.json;
10
+ };
11
+
12
+ export type MenuBarProps = {
13
+ menuId?: string;
14
+ items: NestMenuItemProps[];
15
+ className?: string;
16
+ textColor?: string;
17
+ hoverColor?: string;
18
+ hoverBgColor?: string;
19
+ maxWidthMobileMenu?: string;
20
+ maxWidth?: string;
21
+ backgroundColor?: string;
22
+ };
23
+ export const MenuBar = ({
24
+ menuId,
25
+ items,
26
+ className,
27
+ textColor = 'var(--menubar-color)',
28
+ backgroundColor = 'var(--menubar-bg-color)', //'black',
29
+ hoverColor = 'var(--activatable-color-hover)', //'#ffffff',
30
+ hoverBgColor = 'var(--activatable-bg-color-hover)', //'#d12121',
31
+ maxWidth = '100%',
32
+ maxWidthMobileMenu = MediaQueryMaxWidth.TabletMax,
33
+ }: MenuBarProps) => {
34
+ const css: any = {
35
+ width: '100%',
36
+ maxWidth: maxWidth,
37
+ margin: 'auto',
38
+ // height: 'auto',
39
+ backgroundColor,
40
+ position: 'relative',
41
+ '.menu-bar-top': {
42
+ display: 'flex',
43
+ width: '100%',
44
+ justifyContent: 'center',
45
+ },
46
+ '.menu-bar-item': {
47
+ display: 'inline-block',
48
+ color: textColor,
49
+ padding: '14px 16px',
50
+ textDecoration: 'none',
51
+ position: 'relative',
52
+ },
53
+ '.menu-bar-item:hover, .menu-bar-sub-box:hover > .menu-bar-item': {
54
+ // for desktop, make parent menu hover when sub menu is hover
55
+ color: hoverColor,
56
+ backgroundColor: hoverBgColor,
57
+ },
58
+ '.menu-bar-sub-box .menu-bar-sub': {
59
+ display: 'none',
60
+ position: 'absolute',
61
+ backgroundColor: 'var(--menubar-sub-bg-color)', //'#f9f9f9',
62
+ minWidth: '160px',
63
+ boxShadow: '0px 8px 16px 0px rgba(0,0,0,0.2)',
64
+ zIndex: 'var(--layer-menu-sub)',
65
+ flexDirection: 'column',
66
+ },
67
+ '.menu-bar-sub-box > .menu-bar-item': {
68
+ padding: '14px 26px 14px 16px',
69
+ width: '100%',
70
+ },
71
+ '.menu-bar-sub-box > .menu-bar-item::after': {
72
+ content: '""',
73
+ position: 'absolute',
74
+ top: '50%',
75
+ transform: 'translateY(-50%)',
76
+ marginLeft: '6px',
77
+ width: 0,
78
+ height: 0,
79
+ borderLeft: '5px solid transparent',
80
+ borderRight: '5px solid transparent',
81
+ borderTop: '5px solid ' + textColor,
82
+ },
83
+ '.menu-bar-sub-box .menu-bar-sub > .menu-bar-item': {
84
+ color: 'black',
85
+ },
86
+ '.menu-bar-sub-box:hover > .menu-bar-sub': {
87
+ display: 'flex',
88
+ },
89
+ '.menu-bar-sub-box .menu-bar-sub .menu-bar-item:hover': {
90
+ // backgroundColor: '#ddd',
91
+ color: hoverColor,
92
+ backgroundColor: hoverBgColor,
93
+ },
94
+ '.menu-bar-mobile': {
95
+ display: 'none',
96
+ position: 'relative',
97
+ backgroundColor,
98
+ padding: '5px 18px 6px',
99
+ '.menu-bar-toggle': {
100
+ cursor: 'pointer',
101
+ padding: '14px 0 19px 0',
102
+ 'span, span::before, span::after': {
103
+ cursor: 'pointer',
104
+ height: '3px',
105
+ width: '25px',
106
+ borderRadius: '1px',
107
+ background: '#ffffff',
108
+ position: 'absolute',
109
+ display: 'block',
110
+ transition: 'all 300ms ease-in-out',
111
+ },
112
+ 'span::before, span::after': {
113
+ content: '""',
114
+ },
115
+ 'span::before': {
116
+ top: '-10px',
117
+ },
118
+ 'span::after': {
119
+ bottom: '-10px',
120
+ },
121
+ },
122
+ '.menu-bar-toggle.active span': {
123
+ backgroundColor: 'transparent',
124
+ },
125
+ '.menu-bar-toggle.active span::before': {
126
+ transform: 'rotate(45deg)',
127
+ top: 0,
128
+ },
129
+ '.menu-bar-toggle.active span::after': {
130
+ transform: 'rotate(-45deg)',
131
+ top: 0,
132
+ },
133
+ },
134
+ ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
135
+ '.menu-bar-mobile': {
136
+ display: 'block',
137
+ },
138
+ '.menu-bar-top': {
139
+ display: 'none',
140
+ },
141
+ '.menu-bar-top.open': {
142
+ display: 'flex',
143
+ flexDirection: 'column',
144
+ },
145
+ '.menu-bar-top.open .menu-bar-sub-box > .menu-bar-sub': {
146
+ display: 'flex',
147
+ position: 'unset',
148
+ '.menu-bar-item': {
149
+ paddingLeft: '32px',
150
+ color: textColor,
151
+ backgroundColor,
152
+ },
153
+ '.menu-bar-item:hover': {
154
+ color: hoverColor,
155
+ backgroundColor: hoverBgColor,
156
+ },
157
+ },
158
+ '.menu-bar-sub-box:hover > .menu-bar-item': {
159
+ // for mobile, no parent menu hover when sub menu is hover
160
+ color: textColor,
161
+ backgroundColor: backgroundColor,
162
+ },
163
+ '.menu-bar-sub-box:hover > .menu-bar-item:hover': {
164
+ color: hoverColor,
165
+ backgroundColor: hoverBgColor,
166
+ },
167
+ },
168
+ };
169
+
170
+ const renderItems = (items: NestMenuItemProps[], className: string) => {
171
+ return (
172
+ <div class={className}>
173
+ {items.map((item) => {
174
+ return item.items ? (
175
+ <div class='menu-bar-sub-box'>
176
+ <div class='menu-bar-item'>{item.text}</div>
177
+ {renderItems(item.items, 'menu-bar-sub')}
178
+ </div>
179
+ ) : (
180
+ <LinkItem className='menu-bar-item' url={item.url} alt={item.alt} text={item.text} />
181
+ );
182
+ })}
183
+ </div>
184
+ );
185
+ };
186
+
187
+ const ref: RefProps = {
188
+ onLoad: async () => {
189
+ if (menuId) {
190
+ const menu = await fetchMenu(menuId);
191
+ if (menu.result && menu.result.items.length > 0) {
192
+ const items = menu.result.items.map((i: any) => {
193
+ const l = i.split('\t');
194
+ return { text: l[5], url: l[4] };
195
+ });
196
+ const newDom = renderItems(items, 'menu-bar-top');
197
+ //mountComponents('.menu-bar-top', newDom);
198
+ }
199
+ }
200
+ },
201
+ };
202
+ const onToggleClick = () => {
203
+ const menu = ref.$('.menu-bar-mobile .menu-bar-toggle');
204
+ menu.classList.toggle('active');
205
+ const topMenu = ref.$('.menu-bar-top');
206
+ topMenu.classList.toggle('open');
207
+ };
208
+
209
+ return (
210
+ <div ref={ref} css={css} class={['menu-bar-box', className].join(' ')}>
211
+ <div class='menu-bar-mobile'>
212
+ <div class='menu-bar-toggle' onClick={onToggleClick}>
213
+ <span></span>
214
+ </div>
215
+ </div>
216
+
217
+ {renderItems(items, 'menu-bar-top')}
218
+ </div>
219
+ );
220
+ };
@@ -0,0 +1,10 @@
1
+ export type MenuItemProps = {
2
+ text: string; // "-" for break line
3
+ url: string;
4
+ js?: () => void;
5
+ alt?: string;
6
+ };
7
+
8
+ export type NestMenuItemProps = MenuItemProps & {
9
+ items?: NestMenuItemProps[];
10
+ };
@@ -0,0 +1,289 @@
1
+ import { bindGlobalStyles, getRenderPageProps } from '../core';
2
+ import { CssProps, RefProps } from '../jsx';
3
+ import { stopPropagation } from '../lib';
4
+ import { MediaQueryMaxWidth } from '../types';
5
+ import { NestMenuItemProps } from './menu-item-props';
6
+
7
+ const fetchMenu = async (menuId: string) => {
8
+ const data = await getRenderPageProps().renderPageFunctions.fetchData(`/api/menu/get/${menuId}`);
9
+ return data.json;
10
+ };
11
+
12
+ export type MenuSidebarProps = {
13
+ mobileMenu?: boolean;
14
+ desktopMenu?: boolean;
15
+ menuId?: string;
16
+ items: NestMenuItemProps[];
17
+ className?: string;
18
+ maxWidthMobileMenu?: string;
19
+ maxWidth?: string;
20
+ color?: string;
21
+ backgroundColor?: string;
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
+ }: MenuSidebarProps) => {
34
+ const css: CssProps = {
35
+ backgroundColor,
36
+ '.menu-sidebar-top': {
37
+ width: '100%',
38
+ backgroundColor: 'var(--sidebar-bg-color)',
39
+ maxWidth: maxWidth,
40
+ margin: 'auto',
41
+ // height: 'auto',
42
+ position: 'relative',
43
+
44
+ display: 'flex',
45
+ // width: '100%',
46
+ justifyContent: 'center',
47
+ flexDirection: 'column',
48
+ },
49
+ '&.mobile .menu-sidebar-top': {
50
+ position: 'absolute',
51
+ },
52
+ '.menu-sidebar-item': {
53
+ display: 'inline-block',
54
+ color,
55
+ cursor: 'pointer',
56
+ padding: '14px 16px',
57
+ textDecoration: 'none',
58
+ position: 'relative',
59
+ borderBottom: 'var(--sidebar-border)',
60
+ },
61
+ // select parent when hover on a child, .menu-sidebar-sub-box:hover > .menu-sidebar-item
62
+ '.menu-sidebar-item:hover': {
63
+ color: 'var(--activatable-color-hover)',
64
+ backgroundColor: 'var(--activatable-bg-color-hover)',
65
+ },
66
+ '.menu-sidebar-sub-box .menu-sidebar-sub': {
67
+ display: 'none',
68
+ // position: 'absolute',
69
+ // color: 'var(--sidebar-sub-color)',
70
+ // backgroundColor: 'var(--sidebar-sub-bg-color)',
71
+ minWidth: '160px',
72
+ // boxShadow: '0px 8px 16px 0px rgba(0,0,0,0.2)',
73
+ zIndex: 'var(--layer-sidebar-sub)',
74
+ flexDirection: 'column',
75
+ },
76
+ '.menu-sidebar-sub-box > .menu-sidebar-item': {
77
+ padding: '14px 26px 14px 16px',
78
+ width: '100%',
79
+ },
80
+ '.menu-sidebar-sub-box > .menu-sidebar-sub > .menu-sidebar-item': {
81
+ paddingLeft: '32px',
82
+ },
83
+ '.menu-sidebar-sub-box > .menu-sidebar-item::after': {
84
+ content: '""',
85
+ position: 'absolute',
86
+ top: '50%',
87
+ transform: 'translateY(-50%) rotate(-90deg)',
88
+ marginLeft: '6px',
89
+ width: 0,
90
+ height: 0,
91
+ borderLeft: '5px solid transparent',
92
+ borderRight: '5px solid transparent',
93
+ borderTop: '5px solid ' + color,
94
+ right: '10px',
95
+ transition: 'all 300ms ease-in-out',
96
+ },
97
+ '.menu-sidebar-sub-box.open > .menu-sidebar-item::after': {
98
+ transform: 'rotate(0deg)',
99
+ },
100
+ '&.mobile .menu-sidebar-sub-box > .menu-sidebar-item::after': {
101
+ transform: 'rotate(0deg)',
102
+ },
103
+ // '.menu-sidebar-sub-box .menu-sidebar-sub > .menu-sidebar-item': {
104
+ // color: 'black',
105
+ // },
106
+ '.menu-sidebar-sub-box.open > .menu-sidebar-sub': {
107
+ display: 'flex',
108
+ },
109
+ '.menu-sidebar-sub-box .menu-sidebar-sub .menu-sidebar-item:hover': {
110
+ color: 'var(--activatable-color-hover)',
111
+ backgroundColor: 'var(--activatable-bg-color-hover)',
112
+ },
113
+ '.menu-sidebar-mobile': {
114
+ display: 'none',
115
+ position: 'relative',
116
+ backgroundColor: 'var(--primary-bg-color)',
117
+ padding: '5px 4px 6px',
118
+ '.menu-sidebar-toggle': {
119
+ cursor: 'pointer',
120
+ padding: '6px 0 8px 0',
121
+ 'span, span::before, span::after': {
122
+ cursor: 'pointer',
123
+ height: '3px',
124
+ width: '25px',
125
+ borderRadius: '1px',
126
+ background: 'var(--primary-color)',
127
+ position: 'absolute',
128
+ display: 'block',
129
+ transition: 'all 300ms ease-in-out',
130
+ },
131
+ 'span::before, span::after': {
132
+ content: '""',
133
+ },
134
+ 'span::before': {
135
+ top: '-7px',
136
+ },
137
+ 'span::after': {
138
+ bottom: '-7px',
139
+ },
140
+ },
141
+ '.menu-sidebar-toggle.active span': {
142
+ backgroundColor: 'transparent',
143
+ },
144
+ '.menu-sidebar-toggle.active span::before': {
145
+ transform: 'rotate(45deg)',
146
+ top: 0,
147
+ },
148
+ '.menu-sidebar-toggle.active span::after': {
149
+ transform: 'rotate(-45deg)',
150
+ top: 0,
151
+ },
152
+ },
153
+ // hide menu for mobile place
154
+ '&.mobile': {
155
+ display: 'none',
156
+ // width: '33px',
157
+ },
158
+ '&.mobile .menu-sidebar-mobile': {
159
+ display: 'block',
160
+ width: '33px',
161
+ },
162
+ ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
163
+ // hide menu for not mobile place
164
+ display: 'none',
165
+ // show menu for mobile place
166
+ '&.mobile': {
167
+ display: 'block',
168
+ },
169
+ '.menu-sidebar-top': {
170
+ display: 'none',
171
+ },
172
+ '.menu-sidebar-top.open': {
173
+ display: 'flex',
174
+ flexDirection: 'column',
175
+ zIndex: 'var(--layer-sidebar)',
176
+ },
177
+ '.menu-sidebar-top.open .menu-sidebar-sub-box > .menu-sidebar-sub': {
178
+ display: 'flex',
179
+ position: 'unset',
180
+ '.menu-sidebar-item': {
181
+ paddingLeft: '32px',
182
+ color,
183
+ backgroundColor,
184
+ },
185
+ '.menu-sidebar-item:hover': {
186
+ color: 'var(--activatable-color-hover)',
187
+ backgroundColor: 'var(--activatable-bg-color-hover)',
188
+ },
189
+ },
190
+ '.menu-sidebar-sub-box:hover > .menu-sidebar-item': {
191
+ backgroundColor: 'unset',
192
+ },
193
+ '.menu-sidebar-sub-box:hover > .menu-sidebar-item:hover': {
194
+ color: 'var(--activatable-color-hover)',
195
+ backgroundColor: 'var(--activatable-bg-color-hover)',
196
+ },
197
+ },
198
+ };
199
+
200
+ // first level is grouped
201
+ const renderItems = (items: NestMenuItemProps[], className: string) => {
202
+ return (
203
+ <div class={className}>
204
+ {items.map((item) => {
205
+ let ref: RefProps = {};
206
+ return item.items ? (
207
+ <div ref={ref} class='menu-sidebar-sub-box' onClick={() => onItemToggleClick(ref)}>
208
+ <div class='menu-sidebar-item'>{item.text}</div>
209
+ {renderItems(item.items, 'menu-sidebar-sub')}
210
+ </div>
211
+ ) : item.js ? (
212
+ <a
213
+ class='menu-sidebar-item'
214
+ href='javascript:void(0)'
215
+ alt={item.alt || item.text}
216
+ onClick={(event) => {
217
+ stopPropagation(event);
218
+ // hide menu
219
+ onToggleClick();
220
+ item.js && item.js();
221
+ }}
222
+ >
223
+ {item.text}
224
+ </a>
225
+ ) : (
226
+ <a class='menu-sidebar-item' href={item.url} alt={item.alt || item.text}>
227
+ {item.text}
228
+ </a>
229
+ );
230
+ })}
231
+ </div>
232
+ );
233
+ };
234
+
235
+ const ref: RefProps = {
236
+ onLoad: async () => {
237
+ if (menuId) {
238
+ const menu = await fetchMenu(menuId);
239
+ if (menu.result.items.length > 0) {
240
+ const items = menu.result.items.map((i: any) => {
241
+ const l = i.split('\t');
242
+ return { text: l[5], url: l[4] };
243
+ });
244
+ const newDom = renderItems(items, 'menu-sidebar-top');
245
+ //mountComponents('.menu-sidebar-top', newDom);
246
+ }
247
+ }
248
+ },
249
+ };
250
+ const onToggleClick = () => {
251
+ const menu = ref.$('.menu-sidebar-mobile .menu-sidebar-toggle');
252
+ menu.classList.toggle('active');
253
+ const topMenu = ref.$('.menu-sidebar-top');
254
+ topMenu.classList.toggle('open');
255
+ };
256
+ const onItemToggleClick = (ref: RefProps) => {
257
+ // if (event.target != ref.current && (event.target as any).parentNode != ref.current) {
258
+ // return;
259
+ // }
260
+ ref.current.classList.toggle('open');
261
+ };
262
+
263
+ // if this component is used twice, then the Global styles is only set at the first time
264
+ bindGlobalStyles('menu-sidebar-box', '.menu-sidebar-box', css);
265
+
266
+ // show the menu on both mobile and desktop
267
+ const newCss: CssProps =
268
+ (!desktopMenu && !mobileMenu) || (desktopMenu && mobileMenu)
269
+ ? {
270
+ ['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
271
+ display: 'block',
272
+ '.menu-sidebar-top': {
273
+ display: 'block',
274
+ },
275
+ },
276
+ }
277
+ : {};
278
+ return (
279
+ <div css={newCss} ref={ref} class={['menu-sidebar-box', className, mobileMenu ? 'mobile' : ''].join(' ')}>
280
+ <div class='menu-sidebar-mobile'>
281
+ <div class='menu-sidebar-toggle' onClick={onToggleClick}>
282
+ <span></span>
283
+ </div>
284
+ </div>
285
+
286
+ {renderItems(items, 'menu-sidebar-top')}
287
+ </div>
288
+ );
289
+ };
@@ -0,0 +1,44 @@
1
+ import { FloatWindow, FloatWindowCloseProps, FloatWindowShowProps } from './float-window';
2
+
3
+ export enum MessageBoxButtonProps {
4
+ YesNo = 'yesno',
5
+ OkCancel = 'okcancel',
6
+ Ok = 'ok',
7
+ }
8
+ export type MessageBoxProps = FloatWindowShowProps & {
9
+ buttonType: MessageBoxButtonProps;
10
+ };
11
+
12
+ export class MessageBox {
13
+ static async show({
14
+ title,
15
+ children,
16
+ contentMaxHeight,
17
+ contentMinWidth,
18
+ buttonType = MessageBoxButtonProps.OkCancel,
19
+ noMoving = false,
20
+ noModal = false,
21
+ closeEvent,
22
+ handleClicked,
23
+ closeWhenClickOutside = false,
24
+ }: MessageBoxProps): Promise<FloatWindowCloseProps> {
25
+ const buttons =
26
+ buttonType === MessageBoxButtonProps.OkCancel
27
+ ? ['OK', 'Cancel']
28
+ : buttonType === MessageBoxButtonProps.YesNo
29
+ ? ['Yes', 'No']
30
+ : ['OK'];
31
+ return FloatWindow.show({
32
+ title,
33
+ children,
34
+ contentMaxHeight,
35
+ contentMinWidth,
36
+ buttons,
37
+ noMoving,
38
+ noModal,
39
+ closeEvent,
40
+ handleClicked,
41
+ closeWhenClickOutside,
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,54 @@
1
+ // import { bindPageResetEvent } from '../core/page-reset-events';
2
+ import { getMetaDescription } from './meta-description';
3
+
4
+ type NameMeta = { name: string; content: string };
5
+ type PropertyMeta = { property: string; content: string };
6
+ type HttpEquivMeta = { httpEquiv: string; content: string };
7
+ type AllMeta = NameMeta | PropertyMeta | HttpEquivMeta;
8
+
9
+ function isNameMeta(data: any): data is NameMeta {
10
+ return !!(data.name && data.content);
11
+ }
12
+ function isPropertyMeta(data: any): data is PropertyMeta {
13
+ return !!(data.property && data.content);
14
+ }
15
+ function isHttpEquivMeta(data: any): data is HttpEquivMeta {
16
+ return !!(data.httpEquiv && data.content);
17
+ }
18
+
19
+ let _metaData: { [key: string]: string } = {};
20
+ // Shouldn't include <meta name="description" content="...">
21
+ export const MetaData = (data: AllMeta) => {
22
+ if (isNameMeta(data)) {
23
+ _metaData[`name:${data.name}`] = `<meta name="${data.name}" content="${data.content}">`;
24
+ } else if (isPropertyMeta(data)) {
25
+ _metaData[`property:${data.property}`] = `<meta property="${data.property}" content="${data.content}">`;
26
+ } else if (isHttpEquivMeta(data)) {
27
+ _metaData[`http-equiv:${data.httpEquiv}`] = `<meta http-equiv="${data.httpEquiv}" content="${data.content}">`;
28
+ } else if ((data as any).key && (data as any).string) {
29
+ _metaData[`${(data as any).key}`] = `${(data as any).string}`;
30
+ } else {
31
+ console.warn('Unknown meta data:', data);
32
+ }
33
+ return <></>;
34
+ };
35
+
36
+ export const getMetaDataTags = () => {
37
+ return Object.values(getMetaDataObject()).join('\n');
38
+ };
39
+
40
+ export const getMetaDataObject = () => {
41
+ const metaDescription = getMetaDescription();
42
+ return metaDescription
43
+ ? Object.assign(
44
+ {
45
+ 'name:description': `<meta name="description" content="${metaDescription}">`,
46
+ },
47
+ _metaData
48
+ )
49
+ : _metaData;
50
+ };
51
+
52
+ // bindPageResetEvent(() => {
53
+ // _metaData = {};
54
+ // });
@@ -0,0 +1,19 @@
1
+ // import { bindPageResetEvent } from '../core/page-reset-events';
2
+
3
+ let _description = { value: '', defaultValue: '' };
4
+ export const MetaDescription = ({ children }: { children: string }) => {
5
+ _description.value = children;
6
+ return <></>;
7
+ };
8
+
9
+ export const getMetaDescription = () => {
10
+ return _description.value || _description.defaultValue;
11
+ };
12
+
13
+ export const setDefaultMetaDescription = (children: string) => {
14
+ _description.defaultValue = children;
15
+ };
16
+
17
+ // bindPageResetEvent(() => {
18
+ // _description.value = '';
19
+ // });
@@ -0,0 +1,19 @@
1
+ // import { bindPageResetEvent } from '../core/page-reset-events';
2
+
3
+ let _title = { value: '', defaultValue: '' };
4
+ export const MetaTitle = ({ children }: { children: string }) => {
5
+ _title.value = children;
6
+ return <></>;
7
+ };
8
+
9
+ export const getMetaTitle = () => {
10
+ return _title.value || _title.defaultValue;
11
+ };
12
+
13
+ export const setDefaultMetaTitle = (children: string) => {
14
+ _title.defaultValue = children;
15
+ };
16
+
17
+ // bindPageResetEvent(() => {
18
+ // _title.value = '';
19
+ // });
@@ -0,0 +1,29 @@
1
+ import { FloatWindow, FloatWindowCloseProps, FloatWindowShowProps } from './float-window';
2
+
3
+ export class ModalWindow {
4
+ static async show({
5
+ title,
6
+ children,
7
+ contentMaxHeight,
8
+ contentMinWidth,
9
+ buttons,
10
+ noMoving = true,
11
+ noModal = false,
12
+ closeEvent,
13
+ handleClicked,
14
+ closeWhenClickOutside = true,
15
+ }: FloatWindowShowProps): Promise<FloatWindowCloseProps> {
16
+ return FloatWindow.show({
17
+ title,
18
+ children,
19
+ contentMaxHeight,
20
+ contentMinWidth,
21
+ buttons,
22
+ noMoving,
23
+ noModal,
24
+ closeEvent,
25
+ handleClicked,
26
+ closeWhenClickOutside,
27
+ });
28
+ }
29
+ }