@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.
- package/CHANGELOG.md +12 -0
- package/dist/Layout.d.ts +2 -2
- package/dist/Layout.js +1 -1
- package/dist/LayoutOverlayManager.js +6 -6
- package/dist/LayoutOverlayManager.js.map +1 -1
- package/dist/components/Dialog.d.ts +1 -1
- package/dist/components/Dialog.js +1 -1
- package/dist/components/Header.d.ts +1 -1
- package/dist/components/Header.js +1 -1
- package/dist/components/OverlayContent.d.ts +1 -1
- package/dist/components/OverlayContent.js +20 -20
- package/dist/components/PortalSwitcher.d.ts +1 -1
- package/dist/components/PortalSwitcher.js +54 -54
- package/dist/components/Toaster.d.ts +2 -2
- package/dist/components/Toaster.js +1 -1
- package/dist/components/UserMenu.d.ts +1 -1
- package/dist/components/UserMenu.d.ts.map +1 -1
- package/dist/components/UserMenu.js +44 -42
- package/dist/components/UserMenu.js.map +1 -1
- package/dist/components/error/ErrorBoundary.d.ts +1 -1
- package/dist/components/error/ErrorBoundary.js +1 -1
- package/dist/components/error/SilentErrorBoundary.d.ts +1 -1
- package/dist/components/error/SilentErrorBoundary.js +1 -1
- package/dist/components/menu/MenuContent.d.ts +2 -2
- package/dist/components/menu/MenuContent.js +123 -123
- package/dist/components/menu/MenuContent.js.map +1 -1
- package/dist/components/menu/MenuSections.d.ts +1 -1
- package/dist/components/menu/MenuSections.js +1 -1
- package/dist/components/menu/MenuSections.js.map +1 -1
- package/dist/components/menu/PageSelector.d.ts +1 -1
- package/dist/components/menu/PageSelector.js +69 -69
- package/dist/components/menu/PageSelector.js.map +1 -1
- package/dist/components/tour/PortalSwitcherStep.js +1 -1
- package/dist/components/user-menu-manager.d.ts +13 -0
- package/dist/components/user-menu-manager.d.ts.map +1 -0
- package/dist/components/user-menu-manager.js +36 -0
- package/dist/components/user-menu-manager.js.map +1 -0
- package/dist/layout.css +477 -477
- package/dist/toaster.js +1 -1
- package/package.json +9 -6
- package/readme.md +146 -146
- package/src/Layout.tsx +171 -171
- package/src/LayoutOverlayManager.tsx +464 -464
- package/src/components/Dialog.tsx +140 -140
- package/src/components/Header.tsx +62 -62
- package/src/components/OverlayContent.tsx +80 -80
- package/src/components/PortalSwitcher.tsx +161 -161
- package/src/components/Toaster.tsx +95 -95
- package/src/components/UserMenu.tsx +127 -124
- package/src/components/error/ErrorBoundary.tsx +47 -47
- package/src/components/error/ErrorManager.ts +47 -47
- package/src/components/error/SilentErrorBoundary.tsx +64 -64
- package/src/components/menu/MenuContent.tsx +270 -270
- package/src/components/menu/MenuSections.tsx +320 -320
- package/src/components/menu/PageSelector.tsx +164 -164
- package/src/components/menu/constants.ts +2 -2
- package/src/components/menu/types.ts +205 -205
- package/src/components/tour/PortalSwitcherStep.tsx +39 -39
- package/src/components/types.ts +1 -1
- package/src/components/user-menu-manager.ts +31 -0
- package/src/dictionary.ts +28 -28
- package/src/elements.ts +30 -30
- package/src/errors.ts +11 -11
- package/src/index.ts +14 -14
- package/src/layout.css +477 -477
- package/src/toaster.tsx +153 -153
- package/src/utils.ts +29 -29
- package/tsconfig.json +8 -8
package/src/toaster.tsx
CHANGED
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
import { IconBox, OneOfColorSchemesWithVariants } from '@citric/core'
|
|
2
|
-
import { CheckCircleFill, ExclamationCircleFill, ExclamationTriangleFill, InfoCircleFill } from '@citric/icons'
|
|
3
|
-
import { Dictionary, translate } from '@stack-spot/portal-translate'
|
|
4
|
-
import { toast } from 'react-toastify'
|
|
5
|
-
import 'react-toastify/dist/ReactToastify.css'
|
|
6
|
-
import { ToasterAction, ToasterContent } from './components/Toaster'
|
|
7
|
-
|
|
8
|
-
type ToastType = 'error' | 'success' | 'warning' | 'info'
|
|
9
|
-
|
|
10
|
-
interface BaseOptions {
|
|
11
|
-
/**
|
|
12
|
-
* An identifier for the toaster, if not provided, `Math.random()` will be used.
|
|
13
|
-
*
|
|
14
|
-
* The id can be used to programmatically control the toaster.
|
|
15
|
-
*/
|
|
16
|
-
id?: number | string,
|
|
17
|
-
/**
|
|
18
|
-
* The message to show.
|
|
19
|
-
* Can be either a string or a React element.
|
|
20
|
-
*/
|
|
21
|
-
message: React.ReactNode,
|
|
22
|
-
/**
|
|
23
|
-
* Level/severity of this message.
|
|
24
|
-
* @default 'info'
|
|
25
|
-
*/
|
|
26
|
-
type?: ToastType,
|
|
27
|
-
/**
|
|
28
|
-
* Seconds until auto-close or false to not auto-close.
|
|
29
|
-
* @default 3s for success toast and 10s for the others
|
|
30
|
-
*/
|
|
31
|
-
autoClose?: number | false,
|
|
32
|
-
/**
|
|
33
|
-
* If true, `message` must be a React Element and none of the default toaster UI is rendered (title, icon and close button).
|
|
34
|
-
* @default false
|
|
35
|
-
*/
|
|
36
|
-
custom?: boolean,
|
|
37
|
-
/**
|
|
38
|
-
* Whether or not to close the toaster when the user clicks it.
|
|
39
|
-
* @default false
|
|
40
|
-
*/
|
|
41
|
-
closeOnClick?: boolean,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface DefaultToasterOptions extends BaseOptions {
|
|
45
|
-
/**
|
|
46
|
-
* The title of the toaster.
|
|
47
|
-
*/
|
|
48
|
-
title?: string,
|
|
49
|
-
/**
|
|
50
|
-
* A function to call when the user clicks the toaster. By default, it closes the toaster.
|
|
51
|
-
*/
|
|
52
|
-
onClick?: () => void,
|
|
53
|
-
/**
|
|
54
|
-
* A set of buttons (or links/anchors) to show after the message.
|
|
55
|
-
*/
|
|
56
|
-
actions?: ToasterAction[],
|
|
57
|
-
custom?: false,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface CustomToasterOptions extends BaseOptions {
|
|
61
|
-
/**
|
|
62
|
-
* The whole content to render inside the toaster.
|
|
63
|
-
*/
|
|
64
|
-
message: React.ReactElement,
|
|
65
|
-
custom: true,
|
|
66
|
-
/**
|
|
67
|
-
* A close button to render on the top right corner of the toaster. If not provided, a close button won't be rendered.
|
|
68
|
-
*/
|
|
69
|
-
closeButton?: React.ReactElement,
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export type ToasterOptions = DefaultToasterOptions | CustomToasterOptions | React.ReactNode
|
|
73
|
-
|
|
74
|
-
const toasterConfig: Record<ToastType, { element: React.ReactElement, color: string, duration: number }> = {
|
|
75
|
-
error: {
|
|
76
|
-
element: <ExclamationCircleFill />,
|
|
77
|
-
color: 'danger',
|
|
78
|
-
duration: 10,
|
|
79
|
-
},
|
|
80
|
-
success: {
|
|
81
|
-
element: <CheckCircleFill />,
|
|
82
|
-
color: 'success',
|
|
83
|
-
duration: 3,
|
|
84
|
-
},
|
|
85
|
-
warning: {
|
|
86
|
-
element: <ExclamationTriangleFill />,
|
|
87
|
-
color: 'warning',
|
|
88
|
-
duration: 10,
|
|
89
|
-
},
|
|
90
|
-
info: {
|
|
91
|
-
element: <InfoCircleFill />,
|
|
92
|
-
color: 'inverse',
|
|
93
|
-
duration: 10,
|
|
94
|
-
},
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function showToaster(defaultToasterConfig: DefaultToasterOptions): number | string
|
|
98
|
-
export function showToaster(customToasterConfig: CustomToasterOptions): number | string
|
|
99
|
-
export function showToaster(message: React.ReactNode): number | string
|
|
100
|
-
export function showToaster(options: ToasterOptions): number | string {
|
|
101
|
-
const isToasterConfig = options && typeof options === 'object' && 'message' in options
|
|
102
|
-
const { type = 'info', autoClose, ...opts }: DefaultToasterOptions | CustomToasterOptions = isToasterConfig
|
|
103
|
-
? options
|
|
104
|
-
: { message: options }
|
|
105
|
-
const config = toasterConfig[type]
|
|
106
|
-
const id = opts.id ?? Math.random()
|
|
107
|
-
const closeTime = autoClose ? autoClose : config.duration
|
|
108
|
-
const bg = `var(--${config.color}-500)`
|
|
109
|
-
const bgDark = `var(--${config.color}-600)`
|
|
110
|
-
const fg = `var(--${config.color}-contrastText)`
|
|
111
|
-
|
|
112
|
-
toast(
|
|
113
|
-
opts.custom
|
|
114
|
-
? opts.message
|
|
115
|
-
: <ToasterContent {...opts} id={id} title={opts.title ?? translate(dictionary)[type]} />,
|
|
116
|
-
{
|
|
117
|
-
toastId: id,
|
|
118
|
-
type,
|
|
119
|
-
autoClose: autoClose === false ? false : closeTime * 1000,
|
|
120
|
-
className: 'main-toaster',
|
|
121
|
-
style: { backgroundColor: bg, color: fg },
|
|
122
|
-
progressStyle: { background: bgDark },
|
|
123
|
-
bodyClassName: 'toast-body',
|
|
124
|
-
icon: opts.custom ? false : () => (
|
|
125
|
-
<IconBox colorIcon={`${config.color}.contrastText` as OneOfColorSchemesWithVariants} size="xs">
|
|
126
|
-
{config.element}
|
|
127
|
-
</IconBox>
|
|
128
|
-
),
|
|
129
|
-
closeOnClick: opts.closeOnClick ?? false,
|
|
130
|
-
closeButton: opts.custom ? (opts.closeButton ?? false) : undefined,
|
|
131
|
-
},
|
|
132
|
-
)
|
|
133
|
-
return id
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function closeReactToaster(id: number | string) {
|
|
137
|
-
toast.dismiss(id)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const dictionary = {
|
|
141
|
-
en: {
|
|
142
|
-
success: 'Success',
|
|
143
|
-
error: 'Error',
|
|
144
|
-
info: 'Info',
|
|
145
|
-
warning: 'Warning',
|
|
146
|
-
},
|
|
147
|
-
pt: {
|
|
148
|
-
success: 'Sucesso',
|
|
149
|
-
error: 'Erro',
|
|
150
|
-
info: 'Info',
|
|
151
|
-
warning: 'Atenção',
|
|
152
|
-
},
|
|
153
|
-
} satisfies Dictionary
|
|
1
|
+
import { IconBox, OneOfColorSchemesWithVariants } from '@citric/core'
|
|
2
|
+
import { CheckCircleFill, ExclamationCircleFill, ExclamationTriangleFill, InfoCircleFill } from '@citric/icons'
|
|
3
|
+
import { Dictionary, translate } from '@stack-spot/portal-translate'
|
|
4
|
+
import { toast } from 'react-toastify'
|
|
5
|
+
import 'react-toastify/dist/ReactToastify.css'
|
|
6
|
+
import { ToasterAction, ToasterContent } from './components/Toaster'
|
|
7
|
+
|
|
8
|
+
type ToastType = 'error' | 'success' | 'warning' | 'info'
|
|
9
|
+
|
|
10
|
+
interface BaseOptions {
|
|
11
|
+
/**
|
|
12
|
+
* An identifier for the toaster, if not provided, `Math.random()` will be used.
|
|
13
|
+
*
|
|
14
|
+
* The id can be used to programmatically control the toaster.
|
|
15
|
+
*/
|
|
16
|
+
id?: number | string,
|
|
17
|
+
/**
|
|
18
|
+
* The message to show.
|
|
19
|
+
* Can be either a string or a React element.
|
|
20
|
+
*/
|
|
21
|
+
message: React.ReactNode,
|
|
22
|
+
/**
|
|
23
|
+
* Level/severity of this message.
|
|
24
|
+
* @default 'info'
|
|
25
|
+
*/
|
|
26
|
+
type?: ToastType,
|
|
27
|
+
/**
|
|
28
|
+
* Seconds until auto-close or false to not auto-close.
|
|
29
|
+
* @default 3s for success toast and 10s for the others
|
|
30
|
+
*/
|
|
31
|
+
autoClose?: number | false,
|
|
32
|
+
/**
|
|
33
|
+
* If true, `message` must be a React Element and none of the default toaster UI is rendered (title, icon and close button).
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
custom?: boolean,
|
|
37
|
+
/**
|
|
38
|
+
* Whether or not to close the toaster when the user clicks it.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
closeOnClick?: boolean,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface DefaultToasterOptions extends BaseOptions {
|
|
45
|
+
/**
|
|
46
|
+
* The title of the toaster.
|
|
47
|
+
*/
|
|
48
|
+
title?: string,
|
|
49
|
+
/**
|
|
50
|
+
* A function to call when the user clicks the toaster. By default, it closes the toaster.
|
|
51
|
+
*/
|
|
52
|
+
onClick?: () => void,
|
|
53
|
+
/**
|
|
54
|
+
* A set of buttons (or links/anchors) to show after the message.
|
|
55
|
+
*/
|
|
56
|
+
actions?: ToasterAction[],
|
|
57
|
+
custom?: false,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface CustomToasterOptions extends BaseOptions {
|
|
61
|
+
/**
|
|
62
|
+
* The whole content to render inside the toaster.
|
|
63
|
+
*/
|
|
64
|
+
message: React.ReactElement,
|
|
65
|
+
custom: true,
|
|
66
|
+
/**
|
|
67
|
+
* A close button to render on the top right corner of the toaster. If not provided, a close button won't be rendered.
|
|
68
|
+
*/
|
|
69
|
+
closeButton?: React.ReactElement,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type ToasterOptions = DefaultToasterOptions | CustomToasterOptions | React.ReactNode
|
|
73
|
+
|
|
74
|
+
const toasterConfig: Record<ToastType, { element: React.ReactElement, color: string, duration: number }> = {
|
|
75
|
+
error: {
|
|
76
|
+
element: <ExclamationCircleFill />,
|
|
77
|
+
color: 'danger',
|
|
78
|
+
duration: 10,
|
|
79
|
+
},
|
|
80
|
+
success: {
|
|
81
|
+
element: <CheckCircleFill />,
|
|
82
|
+
color: 'success',
|
|
83
|
+
duration: 3,
|
|
84
|
+
},
|
|
85
|
+
warning: {
|
|
86
|
+
element: <ExclamationTriangleFill />,
|
|
87
|
+
color: 'warning',
|
|
88
|
+
duration: 10,
|
|
89
|
+
},
|
|
90
|
+
info: {
|
|
91
|
+
element: <InfoCircleFill />,
|
|
92
|
+
color: 'inverse',
|
|
93
|
+
duration: 10,
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function showToaster(defaultToasterConfig: DefaultToasterOptions): number | string
|
|
98
|
+
export function showToaster(customToasterConfig: CustomToasterOptions): number | string
|
|
99
|
+
export function showToaster(message: React.ReactNode): number | string
|
|
100
|
+
export function showToaster(options: ToasterOptions): number | string {
|
|
101
|
+
const isToasterConfig = options && typeof options === 'object' && 'message' in options
|
|
102
|
+
const { type = 'info', autoClose, ...opts }: DefaultToasterOptions | CustomToasterOptions = isToasterConfig
|
|
103
|
+
? options
|
|
104
|
+
: { message: options }
|
|
105
|
+
const config = toasterConfig[type]
|
|
106
|
+
const id = opts.id ?? Math.random()
|
|
107
|
+
const closeTime = autoClose ? autoClose : config.duration
|
|
108
|
+
const bg = `var(--${config.color}-500)`
|
|
109
|
+
const bgDark = `var(--${config.color}-600)`
|
|
110
|
+
const fg = `var(--${config.color}-contrastText)`
|
|
111
|
+
|
|
112
|
+
toast(
|
|
113
|
+
opts.custom
|
|
114
|
+
? opts.message
|
|
115
|
+
: <ToasterContent {...opts} id={id} title={opts.title ?? translate(dictionary)[type]} />,
|
|
116
|
+
{
|
|
117
|
+
toastId: id,
|
|
118
|
+
type,
|
|
119
|
+
autoClose: autoClose === false ? false : closeTime * 1000,
|
|
120
|
+
className: 'main-toaster',
|
|
121
|
+
style: { backgroundColor: bg, color: fg },
|
|
122
|
+
progressStyle: { background: bgDark },
|
|
123
|
+
bodyClassName: 'toast-body',
|
|
124
|
+
icon: opts.custom ? false : () => (
|
|
125
|
+
<IconBox colorIcon={`${config.color}.contrastText` as OneOfColorSchemesWithVariants} size="xs">
|
|
126
|
+
{config.element}
|
|
127
|
+
</IconBox>
|
|
128
|
+
),
|
|
129
|
+
closeOnClick: opts.closeOnClick ?? false,
|
|
130
|
+
closeButton: opts.custom ? (opts.closeButton ?? false) : undefined,
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
return id
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function closeReactToaster(id: number | string) {
|
|
137
|
+
toast.dismiss(id)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const dictionary = {
|
|
141
|
+
en: {
|
|
142
|
+
success: 'Success',
|
|
143
|
+
error: 'Error',
|
|
144
|
+
info: 'Info',
|
|
145
|
+
warning: 'Warning',
|
|
146
|
+
},
|
|
147
|
+
pt: {
|
|
148
|
+
success: 'Sucesso',
|
|
149
|
+
error: 'Erro',
|
|
150
|
+
info: 'Info',
|
|
151
|
+
warning: 'Atenção',
|
|
152
|
+
},
|
|
153
|
+
} satisfies Dictionary
|
package/src/utils.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { valueOf } from '@stack-spot/portal-theme'
|
|
2
|
-
import { getLayoutElements } from './elements'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Gets the value for a css variable of the layout.
|
|
6
|
-
*
|
|
7
|
-
* Supposing the actual name of the variable is name-of-variable, the value passed to the first parameter (varname) may be: name-of-variable
|
|
8
|
-
* or --name-of-variable or var(--name-of-variable). All these formats work.
|
|
9
|
-
*
|
|
10
|
-
* @param varname the name of css variable.
|
|
11
|
-
* @returns the value of `varname`.
|
|
12
|
-
*/
|
|
13
|
-
export function valueOfLayoutVar(varname: string): string {
|
|
14
|
-
const layout = document.getElementById('layout')
|
|
15
|
-
if (!layout) return ''
|
|
16
|
-
return valueOf(varname, layout)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Accessibility: makes the screen reader announce some text out loud.
|
|
21
|
-
*
|
|
22
|
-
* @param text the message for the screen reader to read.
|
|
23
|
-
*/
|
|
24
|
-
export function announce(text: string) {
|
|
25
|
-
const { accessibilityAnnouncer } = getLayoutElements()
|
|
26
|
-
if (!accessibilityAnnouncer) return
|
|
27
|
-
accessibilityAnnouncer.textContent = text
|
|
28
|
-
setTimeout(() => accessibilityAnnouncer.textContent = '', 1000)
|
|
29
|
-
}
|
|
1
|
+
import { valueOf } from '@stack-spot/portal-theme'
|
|
2
|
+
import { getLayoutElements } from './elements'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gets the value for a css variable of the layout.
|
|
6
|
+
*
|
|
7
|
+
* Supposing the actual name of the variable is name-of-variable, the value passed to the first parameter (varname) may be: name-of-variable
|
|
8
|
+
* or --name-of-variable or var(--name-of-variable). All these formats work.
|
|
9
|
+
*
|
|
10
|
+
* @param varname the name of css variable.
|
|
11
|
+
* @returns the value of `varname`.
|
|
12
|
+
*/
|
|
13
|
+
export function valueOfLayoutVar(varname: string): string {
|
|
14
|
+
const layout = document.getElementById('layout')
|
|
15
|
+
if (!layout) return ''
|
|
16
|
+
return valueOf(varname, layout)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Accessibility: makes the screen reader announce some text out loud.
|
|
21
|
+
*
|
|
22
|
+
* @param text the message for the screen reader to read.
|
|
23
|
+
*/
|
|
24
|
+
export function announce(text: string) {
|
|
25
|
+
const { accessibilityAnnouncer } = getLayoutElements()
|
|
26
|
+
if (!accessibilityAnnouncer) return
|
|
27
|
+
accessibilityAnnouncer.textContent = text
|
|
28
|
+
setTimeout(() => accessibilityAnnouncer.textContent = '', 1000)
|
|
29
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"outDir": "dist"
|
|
6
|
-
},
|
|
7
|
-
"include": ["src"]
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"outDir": "dist"
|
|
6
|
+
},
|
|
7
|
+
"include": ["src"]
|
|
8
|
+
}
|