@stack-spot/portal-layout 1.0.2 → 1.1.0

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 (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/Layout.d.ts +2 -2
  3. package/dist/Layout.js +1 -1
  4. package/dist/LayoutOverlayManager.js +6 -6
  5. package/dist/LayoutOverlayManager.js.map +1 -1
  6. package/dist/components/Dialog.d.ts +1 -1
  7. package/dist/components/Dialog.js +1 -1
  8. package/dist/components/Header.d.ts +1 -1
  9. package/dist/components/Header.js +1 -1
  10. package/dist/components/OverlayContent.d.ts +1 -1
  11. package/dist/components/OverlayContent.js +20 -20
  12. package/dist/components/PortalSwitcher.d.ts +1 -1
  13. package/dist/components/PortalSwitcher.js +54 -54
  14. package/dist/components/Toaster.d.ts +2 -2
  15. package/dist/components/Toaster.js +1 -1
  16. package/dist/components/UserMenu.d.ts +1 -1
  17. package/dist/components/UserMenu.d.ts.map +1 -1
  18. package/dist/components/UserMenu.js +44 -42
  19. package/dist/components/UserMenu.js.map +1 -1
  20. package/dist/components/error/ErrorBoundary.d.ts +1 -1
  21. package/dist/components/error/ErrorBoundary.js +1 -1
  22. package/dist/components/error/SilentErrorBoundary.d.ts +1 -1
  23. package/dist/components/error/SilentErrorBoundary.js +1 -1
  24. package/dist/components/menu/MenuContent.d.ts +2 -2
  25. package/dist/components/menu/MenuContent.js +123 -123
  26. package/dist/components/menu/MenuContent.js.map +1 -1
  27. package/dist/components/menu/MenuSections.d.ts +1 -1
  28. package/dist/components/menu/MenuSections.js +1 -1
  29. package/dist/components/menu/MenuSections.js.map +1 -1
  30. package/dist/components/menu/PageSelector.d.ts +1 -1
  31. package/dist/components/menu/PageSelector.js +69 -69
  32. package/dist/components/menu/PageSelector.js.map +1 -1
  33. package/dist/components/tour/PortalSwitcherStep.js +1 -1
  34. package/dist/components/user-menu-manager.d.ts +13 -0
  35. package/dist/components/user-menu-manager.d.ts.map +1 -0
  36. package/dist/components/user-menu-manager.js +36 -0
  37. package/dist/components/user-menu-manager.js.map +1 -0
  38. package/dist/layout.css +477 -477
  39. package/dist/toaster.js +1 -1
  40. package/package.json +9 -6
  41. package/readme.md +146 -146
  42. package/src/Layout.tsx +171 -171
  43. package/src/LayoutOverlayManager.tsx +464 -464
  44. package/src/components/Dialog.tsx +140 -140
  45. package/src/components/Header.tsx +62 -62
  46. package/src/components/OverlayContent.tsx +80 -80
  47. package/src/components/PortalSwitcher.tsx +161 -161
  48. package/src/components/Toaster.tsx +95 -95
  49. package/src/components/UserMenu.tsx +127 -124
  50. package/src/components/error/ErrorBoundary.tsx +47 -47
  51. package/src/components/error/ErrorManager.ts +47 -47
  52. package/src/components/error/SilentErrorBoundary.tsx +64 -64
  53. package/src/components/menu/MenuContent.tsx +270 -270
  54. package/src/components/menu/MenuSections.tsx +320 -320
  55. package/src/components/menu/PageSelector.tsx +164 -164
  56. package/src/components/menu/constants.ts +2 -2
  57. package/src/components/menu/types.ts +205 -205
  58. package/src/components/tour/PortalSwitcherStep.tsx +39 -39
  59. package/src/components/types.ts +1 -1
  60. package/src/components/user-menu-manager.ts +31 -0
  61. package/src/dictionary.ts +28 -28
  62. package/src/elements.ts +30 -30
  63. package/src/errors.ts +11 -11
  64. package/src/index.ts +14 -14
  65. package/src/layout.css +477 -477
  66. package/src/toaster.tsx +153 -153
  67. package/src/utils.ts +29 -29
  68. package/tsconfig.json +8 -8
package/src/Layout.tsx CHANGED
@@ -1,171 +1,171 @@
1
- import { TourProps, TourProvider, defaultTourConfig, isNewTourStep } from '@stack-spot/portal-components/Tour'
2
- import { CSSToCitricAdapter, WithStyle, listToClass } from '@stack-spot/portal-theme'
3
- import '@stack-spot/portal-theme/dist/theme.css'
4
- import { ReactElement, ReactNode, useEffect } from 'react'
5
- import { overlay } from './LayoutOverlayManager'
6
- import { Header, HeaderProps } from './components/Header'
7
- import { Toaster } from './components/Toaster'
8
- import { ErrorBoundary } from './components/error/ErrorBoundary'
9
- import { DescriptionFn, ErrorHandler, ErrorManager } from './components/error/ErrorManager'
10
- import { SilentErrorBoundary } from './components/error/SilentErrorBoundary'
11
- import { MenuContent } from './components/menu/MenuContent'
12
- import { MenuSections } from './components/menu/MenuSections'
13
- import { MenuProps } from './components/menu/types'
14
- import { usePortalSwitcherStep } from './components/tour/PortalSwitcherStep'
15
- import { elementIds, getLayoutElements } from './elements'
16
- import './layout.css'
17
-
18
- interface Props extends WithStyle {
19
- /**
20
- * The config for the menu.
21
- */
22
- menu: MenuProps,
23
- /**
24
- * The config for the header.
25
- */
26
- header: HeaderProps,
27
- /**
28
- * The React node to go in the page content.
29
- */
30
- children: ReactNode,
31
- /**
32
- * A React node to place right after the page.
33
- */
34
- extra?: ReactNode,
35
- /**
36
- * A function to convert errors into a readable format so they're properly rendered and logged.
37
- */
38
- errorDescriptor?: DescriptionFn,
39
- /**
40
- * A function to run whenever an error is catch by an error boundary.
41
- */
42
- onError?: ErrorHandler,
43
- /**
44
- * The options for the React Tour's tutorial.
45
- */
46
- tourProps?: TourProps,
47
- }
48
-
49
- interface RawProps extends WithStyle {
50
- /**
51
- * The React element to go in the menu sections.
52
- */
53
- menuSections?: ReactElement,
54
- /**
55
- * The React element to go in the menu content.
56
- */
57
- menuContent?: ReactElement,
58
- /**
59
- * The React element to go in the header.
60
- */
61
- header?: ReactElement,
62
- /**
63
- * The React node to go in the page content.
64
- */
65
- children?: ReactNode,
66
- /**
67
- * A React node to place right after the page.
68
- */
69
- extra?: ReactNode,
70
- /**
71
- * A function to convert errors into a readable format so they're properly rendered and logged.
72
- */
73
- errorDescriptor?: DescriptionFn,
74
- /**
75
- * A function to run whenever an error is catch by an error boundary.
76
- */
77
- onError?: ErrorHandler,
78
- /**
79
- * The options for the React Tour's tutorial.
80
- */
81
- tourProps?: TourProps,
82
- }
83
-
84
- /**
85
- * Renders the layout with the React elements passed in the props.
86
- * @param props the component's props {@link RawProps}.
87
- */
88
- export const RawLayout = (
89
- { menuSections, menuContent, header, children, tourProps,
90
- extra, errorDescriptor, onError, className, style }:
91
- RawProps,
92
- ) => {
93
- // @ts-ignore
94
- const { bottomDialog, modal, rightPanel } = overlay.useOverlays()
95
- const { layout } = getLayoutElements()
96
- const isCompactedOnlyIcons = layout?.classList.contains('menu-compact')
97
- const portalSwitcherStep = usePortalSwitcherStep()
98
-
99
- const classes = [
100
- menuContent && !isCompactedOnlyIcons ? 'menu-content-visible' : undefined,
101
- menuSections ? undefined : 'no-menu-sections',
102
- className,
103
- isCompactedOnlyIcons ? 'menu-compact' : undefined,
104
- ]
105
-
106
- const tourPropsWithDefaults = { ...defaultTourConfig, ...(tourProps || {}) }
107
- tourPropsWithDefaults.steps = [
108
- portalSwitcherStep,
109
- ...tourPropsWithDefaults.steps,
110
- ].filter(isNewTourStep)
111
-
112
- useEffect(() => {
113
- if (errorDescriptor) ErrorManager.setDescriptionFunction(errorDescriptor)
114
- if (onError) ErrorManager.setErrorHandler(onError)
115
- }, [])
116
-
117
- return (
118
- <CSSToCitricAdapter>
119
- <TourProvider config={tourPropsWithDefaults} >
120
- <div id={elementIds.layout} className={listToClass(classes)} style={style}>
121
- {children && <div id={elementIds.page}>
122
- <article id={elementIds.content}><ErrorBoundary>{children}</ErrorBoundary></article>
123
- </div>}
124
- {extra && <SilentErrorBoundary>{extra}</SilentErrorBoundary>}
125
- <aside id={elementIds.menu}>
126
- <nav role="menu" id={elementIds.menuContent}><SilentErrorBoundary>{menuContent}</SilentErrorBoundary></nav>
127
- {menuSections &&
128
- <nav role="menu" id={elementIds.menuSections}><SilentErrorBoundary>{menuSections}</SilentErrorBoundary></nav>}
129
- </aside>
130
- {header && <header id={elementIds.header}><SilentErrorBoundary>{header}</SilentErrorBoundary></header>}
131
- <div id={elementIds.bottomDialog} role="dialog"><ErrorBoundary>{bottomDialog}</ErrorBoundary></div>
132
- <div id={elementIds.backdrop}>
133
- <div id={elementIds.rightPanel} aria-modal role="dialog"><ErrorBoundary>{rightPanel}</ErrorBoundary></div>
134
- <div id={elementIds.modal} aria-modal role="dialog"><ErrorBoundary>{modal}</ErrorBoundary></div>
135
- </div>
136
- <Toaster />
137
- <div id={elementIds.accessibilityAnnouncer} aria-atomic aria-live="assertive">
138
- </div>
139
- </div>
140
- </TourProvider>
141
- </CSSToCitricAdapter>
142
- )
143
- }
144
-
145
- const MenuContentRenderer = ({ content }: Required<Pick<Props['menu'], 'content'>>) => {
146
- const menuContent = typeof content === 'function' ? content() : content
147
- return <MenuContent {...menuContent} />
148
- }
149
-
150
- /**
151
- * Renders the layout with a menu and header that follow the config objects passed as parameter.
152
- * @param props the component's props {@link Props}.
153
- */
154
- export const Layout = ({ menu, header, children, extra, errorDescriptor, onError, className, style, tourProps }: Props) => (
155
- <RawLayout
156
- header={<Header {...header} />}
157
- menuSections={menu.sections ? <MenuSections {...menu} /> : undefined}
158
- menuContent={menu.content
159
- ? <MenuContentRenderer key={'contentKey' in menu ? menu.contentKey : undefined} content={menu.content} />
160
- : undefined
161
- }
162
- errorDescriptor={errorDescriptor}
163
- onError={onError}
164
- extra={extra}
165
- className={className}
166
- style={style}
167
- tourProps={tourProps}
168
- >
169
- {children}
170
- </RawLayout>
171
- )
1
+ import { TourProps, TourProvider, defaultTourConfig, isNewTourStep } from '@stack-spot/portal-components/Tour'
2
+ import { CSSToCitricAdapter, WithStyle, listToClass } from '@stack-spot/portal-theme'
3
+ import '@stack-spot/portal-theme/dist/theme.css'
4
+ import { ReactElement, ReactNode, useEffect } from 'react'
5
+ import { overlay } from './LayoutOverlayManager'
6
+ import { Header, HeaderProps } from './components/Header'
7
+ import { Toaster } from './components/Toaster'
8
+ import { ErrorBoundary } from './components/error/ErrorBoundary'
9
+ import { DescriptionFn, ErrorHandler, ErrorManager } from './components/error/ErrorManager'
10
+ import { SilentErrorBoundary } from './components/error/SilentErrorBoundary'
11
+ import { MenuContent } from './components/menu/MenuContent'
12
+ import { MenuSections } from './components/menu/MenuSections'
13
+ import { MenuProps } from './components/menu/types'
14
+ import { usePortalSwitcherStep } from './components/tour/PortalSwitcherStep'
15
+ import { elementIds, getLayoutElements } from './elements'
16
+ import './layout.css'
17
+
18
+ interface Props extends WithStyle {
19
+ /**
20
+ * The config for the menu.
21
+ */
22
+ menu: MenuProps,
23
+ /**
24
+ * The config for the header.
25
+ */
26
+ header: HeaderProps,
27
+ /**
28
+ * The React node to go in the page content.
29
+ */
30
+ children: ReactNode,
31
+ /**
32
+ * A React node to place right after the page.
33
+ */
34
+ extra?: ReactNode,
35
+ /**
36
+ * A function to convert errors into a readable format so they're properly rendered and logged.
37
+ */
38
+ errorDescriptor?: DescriptionFn,
39
+ /**
40
+ * A function to run whenever an error is catch by an error boundary.
41
+ */
42
+ onError?: ErrorHandler,
43
+ /**
44
+ * The options for the React Tour's tutorial.
45
+ */
46
+ tourProps?: TourProps,
47
+ }
48
+
49
+ interface RawProps extends WithStyle {
50
+ /**
51
+ * The React element to go in the menu sections.
52
+ */
53
+ menuSections?: ReactElement,
54
+ /**
55
+ * The React element to go in the menu content.
56
+ */
57
+ menuContent?: ReactElement,
58
+ /**
59
+ * The React element to go in the header.
60
+ */
61
+ header?: ReactElement,
62
+ /**
63
+ * The React node to go in the page content.
64
+ */
65
+ children?: ReactNode,
66
+ /**
67
+ * A React node to place right after the page.
68
+ */
69
+ extra?: ReactNode,
70
+ /**
71
+ * A function to convert errors into a readable format so they're properly rendered and logged.
72
+ */
73
+ errorDescriptor?: DescriptionFn,
74
+ /**
75
+ * A function to run whenever an error is catch by an error boundary.
76
+ */
77
+ onError?: ErrorHandler,
78
+ /**
79
+ * The options for the React Tour's tutorial.
80
+ */
81
+ tourProps?: TourProps,
82
+ }
83
+
84
+ /**
85
+ * Renders the layout with the React elements passed in the props.
86
+ * @param props the component's props {@link RawProps}.
87
+ */
88
+ export const RawLayout = (
89
+ { menuSections, menuContent, header, children, tourProps,
90
+ extra, errorDescriptor, onError, className, style }:
91
+ RawProps,
92
+ ) => {
93
+ // @ts-ignore
94
+ const { bottomDialog, modal, rightPanel } = overlay.useOverlays()
95
+ const { layout } = getLayoutElements()
96
+ const isCompactedOnlyIcons = layout?.classList.contains('menu-compact')
97
+ const portalSwitcherStep = usePortalSwitcherStep()
98
+
99
+ const classes = [
100
+ menuContent && !isCompactedOnlyIcons ? 'menu-content-visible' : undefined,
101
+ menuSections ? undefined : 'no-menu-sections',
102
+ className,
103
+ isCompactedOnlyIcons ? 'menu-compact' : undefined,
104
+ ]
105
+
106
+ const tourPropsWithDefaults = { ...defaultTourConfig, ...(tourProps || {}) }
107
+ tourPropsWithDefaults.steps = [
108
+ portalSwitcherStep,
109
+ ...tourPropsWithDefaults.steps,
110
+ ].filter(isNewTourStep)
111
+
112
+ useEffect(() => {
113
+ if (errorDescriptor) ErrorManager.setDescriptionFunction(errorDescriptor)
114
+ if (onError) ErrorManager.setErrorHandler(onError)
115
+ }, [])
116
+
117
+ return (
118
+ <CSSToCitricAdapter>
119
+ <TourProvider config={tourPropsWithDefaults} >
120
+ <div id={elementIds.layout} className={listToClass(classes)} style={style}>
121
+ {children && <div id={elementIds.page}>
122
+ <article id={elementIds.content}><ErrorBoundary>{children}</ErrorBoundary></article>
123
+ </div>}
124
+ {extra && <SilentErrorBoundary>{extra}</SilentErrorBoundary>}
125
+ <aside id={elementIds.menu}>
126
+ <nav role="menu" id={elementIds.menuContent}><SilentErrorBoundary>{menuContent}</SilentErrorBoundary></nav>
127
+ {menuSections &&
128
+ <nav role="menu" id={elementIds.menuSections}><SilentErrorBoundary>{menuSections}</SilentErrorBoundary></nav>}
129
+ </aside>
130
+ {header && <header id={elementIds.header}><SilentErrorBoundary>{header}</SilentErrorBoundary></header>}
131
+ <div id={elementIds.bottomDialog} role="dialog"><ErrorBoundary>{bottomDialog}</ErrorBoundary></div>
132
+ <div id={elementIds.backdrop}>
133
+ <div id={elementIds.rightPanel} aria-modal role="dialog"><ErrorBoundary>{rightPanel}</ErrorBoundary></div>
134
+ <div id={elementIds.modal} aria-modal role="dialog"><ErrorBoundary>{modal}</ErrorBoundary></div>
135
+ </div>
136
+ <Toaster />
137
+ <div id={elementIds.accessibilityAnnouncer} aria-atomic aria-live="assertive">
138
+ </div>
139
+ </div>
140
+ </TourProvider>
141
+ </CSSToCitricAdapter>
142
+ )
143
+ }
144
+
145
+ const MenuContentRenderer = ({ content }: Required<Pick<Props['menu'], 'content'>>) => {
146
+ const menuContent = typeof content === 'function' ? content() : content
147
+ return <MenuContent {...menuContent} />
148
+ }
149
+
150
+ /**
151
+ * Renders the layout with a menu and header that follow the config objects passed as parameter.
152
+ * @param props the component's props {@link Props}.
153
+ */
154
+ export const Layout = ({ menu, header, children, extra, errorDescriptor, onError, className, style, tourProps }: Props) => (
155
+ <RawLayout
156
+ header={<Header {...header} />}
157
+ menuSections={menu.sections ? <MenuSections {...menu} /> : undefined}
158
+ menuContent={menu.content
159
+ ? <MenuContentRenderer key={'contentKey' in menu ? menu.contentKey : undefined} content={menu.content} />
160
+ : undefined
161
+ }
162
+ errorDescriptor={errorDescriptor}
163
+ onError={onError}
164
+ extra={extra}
165
+ className={className}
166
+ style={style}
167
+ tourProps={tourProps}
168
+ >
169
+ {children}
170
+ </RawLayout>
171
+ )