@stack-spot/portal-layout 0.0.1

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 (110) hide show
  1. package/dist/Layout.d.ts +22 -0
  2. package/dist/Layout.d.ts.map +1 -0
  3. package/dist/Layout.js +21 -0
  4. package/dist/Layout.js.map +1 -0
  5. package/dist/LayoutOverlayManager.d.ts +32 -0
  6. package/dist/LayoutOverlayManager.d.ts.map +1 -0
  7. package/dist/LayoutOverlayManager.js +154 -0
  8. package/dist/LayoutOverlayManager.js.map +1 -0
  9. package/dist/components/BottomNotification.d.ts +1 -0
  10. package/dist/components/BottomNotification.d.ts.map +1 -0
  11. package/dist/components/BottomNotification.js +2 -0
  12. package/dist/components/BottomNotification.js.map +1 -0
  13. package/dist/components/BottomPanel.d.ts +1 -0
  14. package/dist/components/BottomPanel.d.ts.map +1 -0
  15. package/dist/components/BottomPanel.js +2 -0
  16. package/dist/components/BottomPanel.js.map +1 -0
  17. package/dist/components/Dialog.d.ts +21 -0
  18. package/dist/components/Dialog.d.ts.map +1 -0
  19. package/dist/components/Dialog.js +19 -0
  20. package/dist/components/Dialog.js.map +1 -0
  21. package/dist/components/Header.d.ts +12 -0
  22. package/dist/components/Header.d.ts.map +1 -0
  23. package/dist/components/Header.js +6 -0
  24. package/dist/components/Header.js.map +1 -0
  25. package/dist/components/Logo.d.ts +2 -0
  26. package/dist/components/Logo.d.ts.map +1 -0
  27. package/dist/components/Logo.js +4 -0
  28. package/dist/components/Logo.js.map +1 -0
  29. package/dist/components/Menu/MenuContent.d.ts +3 -0
  30. package/dist/components/Menu/MenuContent.d.ts.map +1 -0
  31. package/dist/components/Menu/MenuContent.js +126 -0
  32. package/dist/components/Menu/MenuContent.js.map +1 -0
  33. package/dist/components/Menu/MenuSections.d.ts +3 -0
  34. package/dist/components/Menu/MenuSections.d.ts.map +1 -0
  35. package/dist/components/Menu/MenuSections.js +70 -0
  36. package/dist/components/Menu/MenuSections.js.map +1 -0
  37. package/dist/components/Menu/PageSelector.d.ts +3 -0
  38. package/dist/components/Menu/PageSelector.d.ts.map +1 -0
  39. package/dist/components/Menu/PageSelector.js +87 -0
  40. package/dist/components/Menu/PageSelector.js.map +1 -0
  41. package/dist/components/Menu/constants.d.ts +3 -0
  42. package/dist/components/Menu/constants.d.ts.map +1 -0
  43. package/dist/components/Menu/constants.js +3 -0
  44. package/dist/components/Menu/constants.js.map +1 -0
  45. package/dist/components/Menu/types.d.ts +45 -0
  46. package/dist/components/Menu/types.d.ts.map +1 -0
  47. package/dist/components/Menu/types.js +2 -0
  48. package/dist/components/Menu/types.js.map +1 -0
  49. package/dist/components/OverlayContent.d.ts +15 -0
  50. package/dist/components/OverlayContent.d.ts.map +1 -0
  51. package/dist/components/OverlayContent.js +26 -0
  52. package/dist/components/OverlayContent.js.map +1 -0
  53. package/dist/components/SelectionList.d.ts +34 -0
  54. package/dist/components/SelectionList.d.ts.map +1 -0
  55. package/dist/components/SelectionList.js +104 -0
  56. package/dist/components/SelectionList.js.map +1 -0
  57. package/dist/components/Toaster.d.ts +3 -0
  58. package/dist/components/Toaster.d.ts.map +1 -0
  59. package/dist/components/Toaster.js +8 -0
  60. package/dist/components/Toaster.js.map +1 -0
  61. package/dist/components/UserMenu.d.ts +9 -0
  62. package/dist/components/UserMenu.d.ts.map +1 -0
  63. package/dist/components/UserMenu.js +57 -0
  64. package/dist/components/UserMenu.js.map +1 -0
  65. package/dist/components/types.d.ts +6 -0
  66. package/dist/components/types.d.ts.map +1 -0
  67. package/dist/components/types.js +2 -0
  68. package/dist/components/types.js.map +1 -0
  69. package/dist/errors.d.ts +7 -0
  70. package/dist/errors.d.ts.map +1 -0
  71. package/dist/errors.js +11 -0
  72. package/dist/errors.js.map +1 -0
  73. package/dist/index.d.ts +11 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +11 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/layout.css +383 -0
  78. package/dist/toaster.d.ts +23 -0
  79. package/dist/toaster.d.ts.map +1 -0
  80. package/dist/toaster.js +41 -0
  81. package/dist/toaster.js.map +1 -0
  82. package/dist/utils.d.ts +2 -0
  83. package/dist/utils.d.ts.map +1 -0
  84. package/dist/utils.js +8 -0
  85. package/dist/utils.js.map +1 -0
  86. package/package.json +39 -0
  87. package/src/Layout.tsx +68 -0
  88. package/src/LayoutOverlayManager.tsx +180 -0
  89. package/src/citric.fix.d.ts +7 -0
  90. package/src/components/BottomNotification.tsx +0 -0
  91. package/src/components/BottomPanel.tsx +0 -0
  92. package/src/components/Dialog.tsx +55 -0
  93. package/src/components/Header.tsx +23 -0
  94. package/src/components/Logo.tsx +35 -0
  95. package/src/components/Menu/MenuContent.tsx +179 -0
  96. package/src/components/Menu/MenuSections.tsx +105 -0
  97. package/src/components/Menu/PageSelector.tsx +108 -0
  98. package/src/components/Menu/constants.ts +2 -0
  99. package/src/components/Menu/types.ts +53 -0
  100. package/src/components/OverlayContent.tsx +50 -0
  101. package/src/components/SelectionList.tsx +200 -0
  102. package/src/components/Toaster.tsx +12 -0
  103. package/src/components/UserMenu.tsx +91 -0
  104. package/src/components/types.ts +5 -0
  105. package/src/errors.ts +11 -0
  106. package/src/index.ts +10 -0
  107. package/src/layout.css +383 -0
  108. package/src/toaster.tsx +72 -0
  109. package/src/utils.ts +7 -0
  110. package/tsconfig.json +8 -0
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export { Layout } from './Layout';
2
+ export { overlay } from './LayoutOverlayManager';
3
+ export { Header } from './components/Header';
4
+ export { StackspotLogo } from './components/Logo';
5
+ export { MenuContent } from './components/Menu/MenuContent';
6
+ export { MenuSections } from './components/Menu/MenuSections';
7
+ export * from './components/Menu/types';
8
+ export { SelectionList } from './components/SelectionList';
9
+ export * from './components/types';
10
+ export * from './errors';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAc,aAAa,EAAsB,MAAM,4BAA4B,CAAA;AAC1F,cAAc,oBAAoB,CAAA;AAClC,cAAc,UAAU,CAAA"}
@@ -0,0 +1,383 @@
1
+ /* Scrollbars */
2
+
3
+ ::-webkit-scrollbar-track {
4
+ background-color: transparent;
5
+ }
6
+
7
+ ::-webkit-scrollbar {
8
+ width: 0.25rem;
9
+ background-color: transparent;
10
+ }
11
+
12
+ ::-webkit-scrollbar-thumb {
13
+ background-color: var(--light-600);
14
+ }
15
+
16
+ /* Layout */
17
+
18
+ html {
19
+ display: flex;
20
+ flex-direction: column;
21
+ height: 100%;
22
+ }
23
+
24
+ body {
25
+ margin: 0;
26
+ display: flex;
27
+ flex-direction: column;
28
+ flex: 1;
29
+ background: var(--light-400);
30
+ font: var(--font);
31
+ color: var(--light-contrastText);
32
+ }
33
+
34
+ #root, #layout {
35
+ display: flex;
36
+ flex-direction: column;
37
+ flex: 1;
38
+ }
39
+
40
+ #layout {
41
+ --header-height: 56px;
42
+ --menu-sections-width: 87px;
43
+ --menu-content-width: 233px;
44
+ --menu-item-height: 74px;
45
+ --modal-animation-duration: 0.3s;
46
+ --right-panel-animation-duration: 0.3s;
47
+ --menu-animation-duration: 0.3s;
48
+ --toastify-font-family: 'Roboto', sans-serif;
49
+ }
50
+
51
+ #layout.menu-compact {
52
+ --menu-sections-width: 56px;
53
+ --menu-item-height: 56px;
54
+ }
55
+
56
+ #header {
57
+ height: var(--header-height);
58
+ padding: 0 24px;
59
+ align-items: center;
60
+ flex-direction: row;
61
+ display: flex;
62
+ justify-content: space-between;
63
+ position: fixed;
64
+ left: 0;
65
+ right: 0;
66
+ top: 0;
67
+ background-color: var(--light-400);
68
+ }
69
+
70
+ #page {
71
+ flex: 1;
72
+ display: flex;
73
+ flex-direction: column;
74
+ background-color: var(--light-300);
75
+ border-top-left-radius: 0.5rem;
76
+ align-items: center;
77
+ padding: 24px;
78
+ margin-top: var(--header-height);
79
+ margin-left: var(--menu-sections-width);
80
+ transition: margin ease-in-out var(--menu-animation-duration);
81
+ }
82
+
83
+ #layout.menu-content-visible #page {
84
+ margin-left: calc(var(--menu-sections-width) + var(--menu-content-width));
85
+ }
86
+
87
+ #content {
88
+ width: 100%;
89
+ max-width: 1144px;
90
+ display: flex;
91
+ flex-direction: column;
92
+ }
93
+
94
+ /* Menu */
95
+
96
+ #menu {
97
+ position: fixed;
98
+ display: flex;
99
+ flex-direction: row;
100
+ top: var(--header-height);
101
+ bottom: 0;
102
+ }
103
+
104
+ #menu svg {
105
+ fill: var(--light-contrastText);
106
+ }
107
+
108
+ #menu .toggle .expand {
109
+ fill: var(--primary-500);
110
+ }
111
+
112
+ #menu .toggle .expand,
113
+ #menu .toggle .collapse {
114
+ position: absolute;
115
+ transition: opacity 0.3s;
116
+ }
117
+
118
+ #menu .toggle .expand,
119
+ #layout.menu-content-visible .toggle .collapse {
120
+ opacity: 1;
121
+ }
122
+
123
+ #menu .toggle .collapse,
124
+ #layout.menu-content-visible .toggle .expand {
125
+ opacity: 0;
126
+ }
127
+
128
+ #menuSections {
129
+ width: var(--menu-sections-width);
130
+ display: flex;
131
+ flex-direction: column;
132
+ padding: 10px 0;
133
+ justify-content: space-between;
134
+ background-color: var(--light-400);
135
+ z-index: 1;
136
+ }
137
+
138
+ #layout.menu-compact .section-label {
139
+ display: none;
140
+ }
141
+
142
+ #menuSections .toggle,
143
+ #menuSections > ul li a {
144
+ background: transparent;
145
+ border: none;
146
+ outline: none;
147
+ width: var(--menu-sections-width);
148
+ height: var(--menu-item-height);
149
+ display: flex;
150
+ flex-direction: column;
151
+ gap: 10px;
152
+ align-items: center;
153
+ justify-content: center;
154
+ transition: background-color 0.2s;
155
+ cursor: pointer;
156
+ position: relative;
157
+ }
158
+
159
+ #menuSections > ul li a:before {
160
+ content: '';
161
+ position: absolute;
162
+ width: 2px;
163
+ height: 24px;
164
+ transform: scaleY(0);
165
+ transition: transform ease-in 0.2s;
166
+ background-color: var(--primary-500);
167
+ border-radius: 50%;
168
+ left: 0;
169
+ }
170
+
171
+ #menuSections > ul li.active a {
172
+ background-color: var(--light-500);
173
+ }
174
+
175
+ #menuSections > ul li.active a:before {
176
+ transform: scaleY(1);
177
+ }
178
+
179
+ #menuSections .toggle:hover,
180
+ #menuSections > ul li a:hover {
181
+ background: var(--light-500);
182
+ }
183
+
184
+ #menuSections .toggle i {
185
+ position: relative;
186
+ }
187
+
188
+ #menuContentOverlay {
189
+ width: 232px;
190
+ position: fixed;
191
+ top: calc(var(--header-height) + 15px);
192
+ left: calc(var(--menu-sections-width) + 15px);
193
+ bottom: 15px;
194
+ background-color: var(--light-400);
195
+ box-shadow: 2px 2px 16px #000;
196
+ border-radius: 16px;
197
+ display: flex;
198
+ flex-direction: column;
199
+ overflow: hidden;
200
+ opacity: 0;
201
+ pointer-events: none;
202
+ z-index: 1;
203
+ transition: opacity 0.3s;
204
+ }
205
+
206
+ #menuContentOverlay.visible {
207
+ opacity: 1;
208
+ pointer-events: auto;
209
+ }
210
+
211
+ #menuContentOverlay > div {
212
+ flex: 1;
213
+ overflow: auto;
214
+ }
215
+
216
+ #menuContentOverlay > .arrow {
217
+ width: 0;
218
+ height: 0;
219
+ border-top: 12px solid transparent;
220
+ border-bottom: 12px solid transparent;
221
+ border-right: 12px solid var(--light-400);
222
+ position: fixed;
223
+ /* header + menu sections padding + item height / 2 - arrow height / 2 */
224
+ top: calc(var(--header-height) + 10px + var(--menu-item-height) / 2 - 12px);
225
+ left: calc(var(--menu-sections-width) + 3px);
226
+ transition: top ease-out 0.3s;
227
+ }
228
+
229
+ #menuContent {
230
+ width: var(--menu-content-width);
231
+ transition: left ease-out var(--menu-animation-duration);
232
+ background-color: var(--light-400);
233
+ overflow: auto;
234
+ position: absolute;
235
+ top: 0;
236
+ bottom: 0;
237
+ left: calc(var(--menu-sections-width) - var(--menu-content-width) - 2px); /* 2px from border */
238
+ border-left: 2px solid var(--light-500);
239
+ }
240
+
241
+ #layout.menu-content-visible #menuContent {
242
+ left: var(--menu-sections-width);
243
+ }
244
+
245
+ /* Overlays */
246
+
247
+ #backdrop {
248
+ position: fixed;
249
+ top: 0;
250
+ right: 0;
251
+ bottom: 0;
252
+ left: 0;
253
+ background-color: var(--backdrop-color);
254
+ opacity: 0;
255
+ pointer-events: none;
256
+ transition: opacity ease-in-out var(--modal-animation-duration);
257
+ display: flex;
258
+ flex-direction: column;
259
+ align-items: center;
260
+ justify-content: center;
261
+ }
262
+
263
+ #backdrop.visible {
264
+ opacity: 1;
265
+ pointer-events: auto;
266
+ }
267
+
268
+ #modal {
269
+ transform: scale(0);
270
+ display: flex;
271
+ flex-direction: column;
272
+ transition: transform ease-in-out var(--modal-animation-duration);
273
+ width: calc(100% - 60px);
274
+ }
275
+
276
+ #modal.fit-content {
277
+ width: auto;
278
+ }
279
+
280
+ #modal.large {
281
+ max-width: 1000px;
282
+ }
283
+
284
+ #modal.medium {
285
+ max-width: 800px;
286
+ }
287
+
288
+ #modal.small {
289
+ max-width: 600px;
290
+ }
291
+
292
+ #modal.visible {
293
+ transform: scale(1);
294
+ }
295
+
296
+ #rightPanel {
297
+ position: fixed;
298
+ display: flex;
299
+ flex-direction: column;
300
+ top: var(--header-height);
301
+ right: -307px;
302
+ bottom: 0;
303
+ width: 307px;
304
+ transition: right var(--right-panel-animation-duration);
305
+ background-color: var(--light-400);
306
+ }
307
+
308
+ #rightPanel.visible {
309
+ right: 0;
310
+ }
311
+
312
+ #bottomPanel {
313
+ position: fixed;
314
+ display: flex;
315
+ flex-direction: column;
316
+ bottom: -420px;
317
+ left: 20px;
318
+ height: 400px;
319
+ transition: transform bottom 0.3s;
320
+ }
321
+
322
+ #bottomPanel.visible {
323
+ bottom: 20px;
324
+ }
325
+
326
+ #bottomDialog {
327
+ position: fixed;
328
+ display: flex;
329
+ flex-direction: column;
330
+ bottom: -80px;
331
+ left: 0;
332
+ right: 0;
333
+ height: 80px;
334
+ transition: transform bottom 0.3s;
335
+ }
336
+
337
+ #bottomDialog.visible {
338
+ bottom: 0;
339
+ }
340
+
341
+ /* Overlay: toaster */
342
+
343
+ .main-toaster h1 {
344
+ font-size: 14px;
345
+ font-weight: 500;
346
+ margin: 0 0 8px 0;
347
+ }
348
+
349
+ .main-toaster p {
350
+ margin: 0;
351
+ font-size: 12px;
352
+ }
353
+
354
+ .main-toaster .toast-body {
355
+ align-items: start;
356
+ }
357
+
358
+ .main-toaster .Toastify__toast-icon {
359
+ margin-top: 2px;
360
+ width: auto;
361
+ }
362
+
363
+ /* Other */
364
+
365
+ svg path.stackspot-text {
366
+ fill: var(--light-contrastText)
367
+ }
368
+
369
+ a {
370
+ color: var(--light-contrastText);
371
+ text-decoration: none;
372
+ cursor: pointer;
373
+ }
374
+
375
+ ul {
376
+ list-style: none;
377
+ margin: 0;
378
+ padding: 0;
379
+ }
380
+
381
+ i {
382
+ fill: var(--light-contrastText);
383
+ }
@@ -0,0 +1,23 @@
1
+ /// <reference types="react" />
2
+ import 'react-toastify/dist/ReactToastify.css';
3
+ type ToastType = 'error' | 'success' | 'warning' | 'info';
4
+ interface BaseProps {
5
+ type?: ToastType;
6
+ /**
7
+ * Seconds until auto-close or false to not auto-close.
8
+ * @default 10
9
+ */
10
+ autoClose?: number | false;
11
+ }
12
+ interface BasicMessageProps extends BaseProps {
13
+ message: string;
14
+ title?: string;
15
+ onClick?: () => void;
16
+ }
17
+ interface RichMessageProps extends BaseProps {
18
+ content: React.ReactElement;
19
+ }
20
+ type Props = BasicMessageProps | RichMessageProps;
21
+ export declare function showToaster({ type, autoClose, ...props }: Props): void;
22
+ export {};
23
+ //# sourceMappingURL=toaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":";AAIA,OAAO,uCAAuC,CAAA;AAE9C,KAAK,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;AAEzD,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC5B;AAED,UAAU,iBAAkB,SAAQ,SAAS;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,UAAU,gBAAiB,SAAQ,SAAS;IAC1C,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC;CAC7B;AAED,KAAK,KAAK,GAAG,iBAAiB,GAAG,gBAAgB,CAAA;AAqBjD,wBAAgB,WAAW,CAAC,EAAE,IAAa,EAAE,SAAc,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,QAuB7E"}
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconBox } from '@citric/core';
3
+ import { CheckCircleFill, ExclamationTriangleFill, InfoCircleFill, TimesCircleFill } from '@citric/icons';
4
+ import { toast } from 'react-toastify';
5
+ import 'react-toastify/dist/ReactToastify.css';
6
+ const icons = {
7
+ error: {
8
+ element: _jsx(TimesCircleFill, {}),
9
+ color: 'danger',
10
+ },
11
+ success: {
12
+ element: _jsx(CheckCircleFill, {}),
13
+ color: 'success',
14
+ },
15
+ warning: {
16
+ element: _jsx(ExclamationTriangleFill, {}),
17
+ color: 'warning',
18
+ },
19
+ info: {
20
+ element: _jsx(InfoCircleFill, {}),
21
+ color: 'inverse',
22
+ },
23
+ };
24
+ export function showToaster({ type = 'info', autoClose = 10, ...props }) {
25
+ const icon = icons[type];
26
+ const bg = `var(--${icon.color}-500)`;
27
+ const bgDark = `var(--${icon.color}-600)`;
28
+ const fg = `var(--${icon.color}-contrastText)`;
29
+ toast('message' in props
30
+ ? _jsxs("div", { onClick: props.onClick, children: [_jsx("h1", { style: { textTransform: 'capitalize' }, children: props.title ?? type }), _jsx("p", { children: props.message })] })
31
+ : props.content, {
32
+ type,
33
+ autoClose: autoClose === false ? false : autoClose * 1000,
34
+ className: 'main-toaster',
35
+ style: { backgroundColor: bg, color: fg },
36
+ progressStyle: { background: bgDark },
37
+ bodyClassName: 'toast-body',
38
+ icon: 'message' in props ? () => (_jsx(IconBox, { colorScheme: fg, children: icon.element })) : undefined,
39
+ });
40
+ }
41
+ //# sourceMappingURL=toaster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toaster.js","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACzG,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,uCAAuC,CAAA;AAyB9C,MAAM,KAAK,GAAsE;IAC/E,KAAK,EAAE;QACL,OAAO,EAAE,KAAC,eAAe,KAAG;QAC5B,KAAK,EAAE,QAAQ;KAChB;IACD,OAAO,EAAE;QACP,OAAO,EAAE,KAAC,eAAe,KAAG;QAC5B,KAAK,EAAE,SAAS;KACjB;IACD,OAAO,EAAE;QACP,OAAO,EAAE,KAAC,uBAAuB,KAAG;QACpC,KAAK,EAAE,SAAS;KACjB;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,KAAC,cAAc,KAAG;QAC3B,KAAK,EAAE,SAAS;KACjB;CACF,CAAA;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,KAAK,EAAS;IAC5E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACxB,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,KAAK,OAAO,CAAA;IACrC,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,KAAK,OAAO,CAAA;IACzC,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,KAAK,gBAAgB,CAAA;IAC9C,KAAK,CACH,SAAS,IAAI,KAAK;QAChB,CAAC,CAAC,eAAK,OAAO,EAAE,KAAK,CAAC,OAAO,aAAE,aAAI,KAAK,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,YAAG,KAAK,CAAC,KAAK,IAAI,IAAI,GAAM,EAAA,sBAAI,KAAK,CAAC,OAAO,GAAK,IAAM;QACjI,CAAC,CAAC,KAAK,CAAC,OAAO,EACjB;QACE,IAAI;QACJ,SAAS,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI;QACzD,SAAS,EAAC,cAAc;QACxB,KAAK,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QACzC,aAAa,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;QACrC,aAAa,EAAE,YAAY;QAC3B,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAC/B,KAAC,OAAO,IAAC,WAAW,EAAE,EAAmC,YACtD,IAAI,CAAC,OAAO,GACL,CACX,CAAC,CAAC,CAAC,SAAS;KACd,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function valueOfLayoutVar(varname: string): string;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxD"}
package/dist/utils.js ADDED
@@ -0,0 +1,8 @@
1
+ import { valueOf } from '@stack-spot/portal-theme';
2
+ export function valueOfLayoutVar(varname) {
3
+ const layout = document.getElementById('layout');
4
+ if (!layout)
5
+ return '';
6
+ return valueOf(varname, layout);
7
+ }
8
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAElD,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAA;IACtB,OAAO,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@stack-spot/portal-layout",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "peerDependencies": {
8
+ "@citric/core": "^5.2.0",
9
+ "@citric/icons": "^5.2.0",
10
+ "@citric/ui": "^5.2.0",
11
+ "@stack-spot/portal-theme": "0.0.1",
12
+ "react": "^18.2.0",
13
+ "react-dom": "^18.2.0",
14
+ "styled-components": "6.1.1"
15
+ },
16
+ "devDependencies": {
17
+ "@types/react": "^18.2.37",
18
+ "@types/react-dom": "^18.2.15",
19
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
20
+ "@typescript-eslint/parser": "^6.10.0",
21
+ "cpy-cli": "^5.0.0",
22
+ "eslint": "^8.53.0",
23
+ "eslint-plugin-filenames": "^1.3.2",
24
+ "eslint-plugin-import": "^2.29.0",
25
+ "eslint-plugin-lodash": "^7.4.0",
26
+ "eslint-plugin-promise": "^6.1.1",
27
+ "eslint-plugin-react": "^7.33.2",
28
+ "eslint-plugin-react-hooks": "^4.6.0",
29
+ "eslint-plugin-react-refresh": "^0.4.4",
30
+ "typescript": "^5.2.2"
31
+ },
32
+ "dependencies": {
33
+ "react-toastify": "^9.1.3"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc && cpy src/layout.css dist --flat",
37
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
38
+ }
39
+ }
package/src/Layout.tsx ADDED
@@ -0,0 +1,68 @@
1
+ import { CSSToCitricAdapter, listToClass, WithStyle } from '@stack-spot/portal-theme'
2
+ import '@stack-spot/portal-theme/dist/theme.css'
3
+ import { ReactElement } from 'react'
4
+ import { Header, HeaderProps } from './components/Header'
5
+ import { MenuContent } from './components/Menu/MenuContent'
6
+ import { MenuSections } from './components/Menu/MenuSections'
7
+ import { MenuProps } from './components/Menu/types'
8
+ import { Toaster } from './components/Toaster'
9
+ import './layout.css'
10
+ import { overlay } from './LayoutOverlayManager'
11
+
12
+ interface Props extends WithStyle {
13
+ menu: MenuProps,
14
+ header: HeaderProps,
15
+ children: ReactElement,
16
+ }
17
+
18
+ interface RawProps extends WithStyle {
19
+ menuSections: ReactElement,
20
+ menuContent?: ReactElement,
21
+ header: ReactElement,
22
+ children: ReactElement,
23
+ compactMenu?: boolean,
24
+ }
25
+
26
+ export const RawLayout = ({ menuSections, menuContent, header, compactMenu = true, children, className, style }: RawProps) => {
27
+ // @ts-ignore
28
+ const { bottomDialog, modal, rightPanel } = overlay.useOverlays()
29
+ const classes = [
30
+ menuContent ? 'menu-content-visible' : undefined,
31
+ compactMenu ? 'menu-compact' : undefined,
32
+ className,
33
+ ]
34
+
35
+ return (
36
+ <CSSToCitricAdapter>
37
+ <div id="layout" className={listToClass(classes)} style={style}>
38
+ <header id="header">{header}</header>
39
+ <aside id="menu">
40
+ <nav id="menuContent">{menuContent}</nav>
41
+ <nav id="menuSections">{menuSections}</nav>
42
+ </aside>
43
+ <div id="page">
44
+ <article id="content">{children}</article>
45
+ </div>
46
+ <div id="rightPanel">{rightPanel}</div>
47
+ <div id="bottomDialog">{bottomDialog}</div>
48
+ <div id="backdrop">
49
+ <div id="modal">{modal}</div>
50
+ </div>
51
+ <Toaster />
52
+ </div>
53
+ </CSSToCitricAdapter>
54
+ )
55
+ }
56
+
57
+ export const Layout = ({ menu, header, children, className, style }: Props) => (
58
+ <RawLayout
59
+ header={<Header {...header} />}
60
+ menuSections={<MenuSections sections={menu.sections} />}
61
+ menuContent={menu.content ? <MenuContent {...menu.content} /> : undefined}
62
+ compactMenu={menu.compact}
63
+ className={className}
64
+ style={style}
65
+ >
66
+ {children}
67
+ </RawLayout>
68
+ )