@stack-spot/portal-layout 0.0.33 → 0.0.34
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/dist/Layout.d.ts +1 -2
- package/dist/Layout.d.ts.map +1 -1
- package/dist/Layout.js +6 -4
- package/dist/Layout.js.map +1 -1
- package/dist/LayoutOverlayManager.js.map +1 -1
- package/dist/components/SelectionList.d.ts.map +1 -1
- package/dist/components/SelectionList.js +22 -2
- package/dist/components/SelectionList.js.map +1 -1
- package/dist/components/menu/MenuContent.d.ts +2 -545
- package/dist/components/menu/MenuContent.d.ts.map +1 -1
- package/dist/components/menu/MenuContent.js.map +1 -1
- package/dist/components/menu/MenuSections.d.ts.map +1 -1
- package/dist/components/menu/MenuSections.js +42 -26
- package/dist/components/menu/MenuSections.js.map +1 -1
- package/dist/components/menu/PageSelector.js.map +1 -1
- package/dist/components/menu/types.d.ts +0 -1
- package/dist/components/menu/types.d.ts.map +1 -1
- package/dist/components/menu/use-check-text-overflow.js.map +1 -1
- package/dist/components/menu/use-keyboard-controls.d.ts +16 -3
- package/dist/components/menu/use-keyboard-controls.d.ts.map +1 -1
- package/dist/components/menu/use-keyboard-controls.js +21 -46
- package/dist/components/menu/use-keyboard-controls.js.map +1 -1
- package/dist/layout.css +14 -8
- package/dist/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/Layout.tsx +6 -5
- package/src/components/SelectionList.tsx +24 -2
- package/src/components/menu/MenuSections.tsx +47 -29
- package/src/components/menu/types.ts +0 -1
- package/src/components/menu/use-keyboard-controls.tsx +32 -50
- package/src/layout.css +14 -8
- package/dist/components/error/ErrorDescriptor.d.ts +0 -12
- package/dist/components/error/ErrorDescriptor.d.ts.map +0 -1
- package/dist/components/error/ErrorDescriptor.js +0 -17
- package/dist/components/error/ErrorDescriptor.js.map +0 -1
- package/dist/components/menu/useCheckTextOverflow.d.ts +0 -6
- package/dist/components/menu/useCheckTextOverflow.d.ts.map +0 -1
- package/dist/components/menu/useCheckTextOverflow.js +0 -20
- package/dist/components/menu/useCheckTextOverflow.js.map +0 -1
|
@@ -2,6 +2,8 @@ import { Flex, IconBox, Text } from '@citric/core'
|
|
|
2
2
|
import { ChevronRight, Cog, Collapse, Expand } from '@citric/icons'
|
|
3
3
|
import { Dictionary, interpolate, useTranslate } from '@stack-spot/portal-translate'
|
|
4
4
|
import { useCallback, useMemo, useState } from 'react'
|
|
5
|
+
import { getLayoutElements } from '../../elements'
|
|
6
|
+
import { elementIds } from '../../elements'
|
|
5
7
|
import { MenuContent } from './MenuContent'
|
|
6
8
|
import { MenuProps, MenuSection } from './types'
|
|
7
9
|
import { useKeyboardControls } from './use-keyboard-controls'
|
|
@@ -12,14 +14,27 @@ const MENU_OVERLAY_ID = 'menuContentOverlay'
|
|
|
12
14
|
|
|
13
15
|
let hideOverlayTask: number | undefined
|
|
14
16
|
|
|
17
|
+
// fixme: this should definitely not be handled like this...
|
|
18
|
+
let attachKeyboardListenersForOverlay: () => void
|
|
19
|
+
let detachKeyboardListenersForOverlay: () => void
|
|
20
|
+
|
|
15
21
|
function hideOverlay() {
|
|
16
22
|
if (hideOverlayTask !== undefined) return
|
|
17
23
|
hideOverlayTask = window.setTimeout(hideOverlayImmediately, HIDE_OVERLAY_DELAY_MS)
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
function getAccessibilityButtonOfSectionWithActiveOverlay(): HTMLElement | null | undefined {
|
|
27
|
+
return document.getElementById(elementIds.menuSections)?.querySelector('button[aria-expanded="true"]')
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
21
31
|
export function hideOverlayImmediately() {
|
|
22
|
-
|
|
32
|
+
detachKeyboardListenersForOverlay?.()
|
|
33
|
+
const overlay = document.getElementById(MENU_OVERLAY_ID)
|
|
34
|
+
overlay?.setAttribute('inert', '')
|
|
35
|
+
overlay?.setAttribute('aria-hidden', '')
|
|
36
|
+
overlay?.classList.remove('visible')
|
|
37
|
+
getAccessibilityButtonOfSectionWithActiveOverlay()?.setAttribute('aria-expanded', 'false')
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
function cancelHideOverlayTask() {
|
|
@@ -30,7 +45,11 @@ function cancelHideOverlayTask() {
|
|
|
30
45
|
|
|
31
46
|
function showOverlay() {
|
|
32
47
|
cancelHideOverlayTask()
|
|
33
|
-
document.getElementById(MENU_OVERLAY_ID)
|
|
48
|
+
const overlay = document.getElementById(MENU_OVERLAY_ID)
|
|
49
|
+
overlay?.removeAttribute('inert')
|
|
50
|
+
overlay?.removeAttribute('aria-hidden')
|
|
51
|
+
overlay?.classList.add('visible')
|
|
52
|
+
attachKeyboardListenersForOverlay?.()
|
|
34
53
|
}
|
|
35
54
|
|
|
36
55
|
function isMenuContentVisible() {
|
|
@@ -60,19 +79,20 @@ const Section = ({
|
|
|
60
79
|
/* The overlay should appear if:
|
|
61
80
|
* 1. The menu is compacted showing only the icons
|
|
62
81
|
* 2. The section has some content to render OR:
|
|
63
|
-
*
|
|
64
|
-
* 3. The section is inactive OR:
|
|
65
|
-
* 2.1. The contextual menu is hidden.
|
|
82
|
+
* 3. The section is active and there is a contextual menu for the active page.
|
|
66
83
|
*/
|
|
67
|
-
const layout =
|
|
68
|
-
const isCompactedOnlyIcons = layout?.classList.contains('menu-compact
|
|
69
|
-
return isCompactedOnlyIcons && (!!contentToRender || !!customContent || (hasContent && active))
|
|
84
|
+
const { layout } = getLayoutElements()
|
|
85
|
+
const isCompactedOnlyIcons = layout?.classList.contains('menu-compact')
|
|
86
|
+
return isCompactedOnlyIcons && (!!contentToRender || !!customContent || (hasContent && active))
|
|
70
87
|
}
|
|
71
88
|
|
|
72
89
|
function showOverlayAndFixArrowPosition(event: React.MouseEvent<HTMLAnchorElement, MouseEvent> | React.KeyboardEvent<any>) {
|
|
73
90
|
if (!shouldShowOverlay()) return
|
|
74
91
|
onOpen?.()
|
|
75
|
-
const
|
|
92
|
+
const anchorElement = event.target as HTMLElement
|
|
93
|
+
const accessibilityButton = anchorElement?.parentElement?.querySelector('button') as HTMLElement
|
|
94
|
+
accessibilityButton?.setAttribute('aria-expanded', 'true')
|
|
95
|
+
const rect = anchorElement?.getBoundingClientRect()
|
|
76
96
|
const arrow: HTMLElement | null = document.querySelector(`#${MENU_OVERLAY_ID} .arrow`)
|
|
77
97
|
setCurrentOverlay(id)
|
|
78
98
|
showOverlay()
|
|
@@ -104,7 +124,7 @@ const Section = ({
|
|
|
104
124
|
{...(!href ? { 'tabIndex': 0 } : undefined)}
|
|
105
125
|
>
|
|
106
126
|
<Flex alignItems="center" justifyContent="center" px={5}>
|
|
107
|
-
{icon}
|
|
127
|
+
<IconBox>{icon}</IconBox>
|
|
108
128
|
{typeof label === 'string' ? <Text appearance="microtext1" className="section-label" ml={3}>{label}</Text> : label.element}
|
|
109
129
|
</Flex>
|
|
110
130
|
</a>
|
|
@@ -113,13 +133,12 @@ const Section = ({
|
|
|
113
133
|
as="button"
|
|
114
134
|
aria-label={interpolate(t.menuOptions, label)}
|
|
115
135
|
aria-controls={MENU_OVERLAY_ID}
|
|
116
|
-
aria-expanded={
|
|
136
|
+
aria-expanded={false}
|
|
117
137
|
onKeyDown={(event) => {
|
|
118
138
|
if (event.key === 'Enter') {
|
|
119
139
|
showOverlayAndFixArrowPosition(event)
|
|
120
140
|
}
|
|
121
|
-
}
|
|
122
|
-
}>
|
|
141
|
+
}}>
|
|
123
142
|
<ChevronRight />
|
|
124
143
|
</IconBox>
|
|
125
144
|
}
|
|
@@ -130,7 +149,7 @@ const Section = ({
|
|
|
130
149
|
|
|
131
150
|
const OverlayRenderer = ({ content, customContent }: Pick<MenuSection, 'content' | 'customContent'>) => {
|
|
132
151
|
if (customContent) {
|
|
133
|
-
return
|
|
152
|
+
return <div id="custom-selectable-item"> {customContent} </div>
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
const data = typeof content === 'function' ? content() : content
|
|
@@ -141,15 +160,14 @@ export const MenuSections = ({ sections = [], ...props }: MenuProps) => {
|
|
|
141
160
|
const t = useTranslate(dictionary)
|
|
142
161
|
// this is a mock state only used to force an update on the component.
|
|
143
162
|
const [_, setUpdate] = useState(0)
|
|
144
|
-
const onHide = () => hideOverlay()
|
|
145
163
|
|
|
146
164
|
const toggleMenu = useCallback((hasContent: boolean) => {
|
|
147
165
|
const layout = document.getElementById('layout')
|
|
148
166
|
if (!layout) return
|
|
149
|
-
if (layout.classList.contains('menu-compact
|
|
150
|
-
layout.classList.remove('menu-compact
|
|
167
|
+
if (layout.classList.contains('menu-compact')) {
|
|
168
|
+
layout.classList.remove('menu-compact')
|
|
151
169
|
} else {
|
|
152
|
-
layout.classList.add('menu-compact
|
|
170
|
+
layout.classList.add('menu-compact')
|
|
153
171
|
}
|
|
154
172
|
|
|
155
173
|
if (hasContent) {
|
|
@@ -171,19 +189,19 @@ export const MenuSections = ({ sections = [], ...props }: MenuProps) => {
|
|
|
171
189
|
)
|
|
172
190
|
|
|
173
191
|
function onPressEscape() {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (!!items && !!currentOverlay && items.length > currentOverlay && items[currentOverlay].children.length > 1) {
|
|
177
|
-
(items[currentOverlay].children[1] as HTMLElement).focus()
|
|
178
|
-
}
|
|
192
|
+
getAccessibilityButtonOfSectionWithActiveOverlay()?.focus()
|
|
193
|
+
hideOverlayImmediately()
|
|
179
194
|
}
|
|
180
195
|
|
|
181
|
-
const
|
|
182
|
-
|
|
196
|
+
const { keyboardControlledElement: overlayRef, attachKeyboardListeners, detachKeyboardListeners } = useKeyboardControls({
|
|
197
|
+
onPressEscape,
|
|
183
198
|
querySelectors: 'li a.action, #custom-selectable-item button, #custom-selectable-item input',
|
|
184
|
-
onPressEscape: () => onPressEscape(),
|
|
185
199
|
})
|
|
186
200
|
|
|
201
|
+
// fixme: this should definitely not be handled like this...
|
|
202
|
+
attachKeyboardListenersForOverlay = attachKeyboardListeners
|
|
203
|
+
detachKeyboardListenersForOverlay = detachKeyboardListeners
|
|
204
|
+
|
|
187
205
|
/* This function renders the section preview in the overlay in normal circumstances. If the menu is hidden and the section is active,
|
|
188
206
|
instead of rendering the section preview, it will render the actual menu content, which would be invisible otherwise.
|
|
189
207
|
Below, the key is of extreme importance. It ensures React will consider every section content to be an entirely different
|
|
@@ -206,7 +224,7 @@ export const MenuSections = ({ sections = [], ...props }: MenuProps) => {
|
|
|
206
224
|
|
|
207
225
|
<Flex mb={7} alignItems="center">
|
|
208
226
|
<button className="toggle sections-footer" onClick={() => toggleMenu(!!props.content || !!props.customContent)}
|
|
209
|
-
title={t.toggle} tabIndex={-1}
|
|
227
|
+
title={t.toggle} tabIndex={-1}>
|
|
210
228
|
<IconBox>
|
|
211
229
|
<Expand className="expand" />
|
|
212
230
|
<Collapse className="collapse" />
|
|
@@ -217,7 +235,7 @@ export const MenuSections = ({ sections = [], ...props }: MenuProps) => {
|
|
|
217
235
|
<a href={props.settings?.href} onClick={props.settings?.onClick}
|
|
218
236
|
className="sections-footer"
|
|
219
237
|
{...(props.settings.active ? { 'aria-current': 'page' } : undefined)}>
|
|
220
|
-
<Flex alignItems="center" >
|
|
238
|
+
<Flex alignItems="center" justifyContent="center">
|
|
221
239
|
<IconBox aria-label={t.settingsIcon}>
|
|
222
240
|
<Cog />
|
|
223
241
|
</IconBox>
|
|
@@ -227,7 +245,7 @@ export const MenuSections = ({ sections = [], ...props }: MenuProps) => {
|
|
|
227
245
|
}
|
|
228
246
|
</Flex>
|
|
229
247
|
|
|
230
|
-
<div id={MENU_OVERLAY_ID} onMouseEnter={showOverlay} onMouseLeave={hideOverlay} ref={
|
|
248
|
+
<div id={MENU_OVERLAY_ID} onMouseEnter={showOverlay} onMouseLeave={hideOverlay} ref={overlayRef}>
|
|
231
249
|
{renderMenuOverlay()}
|
|
232
250
|
<div className="arrow"></div>
|
|
233
251
|
</div>
|
|
@@ -1,29 +1,34 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useRef } from 'react'
|
|
2
2
|
|
|
3
3
|
interface Props {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A query selector that returns every html element that must be navigable through the keyboard.
|
|
6
|
+
*/
|
|
6
7
|
querySelectors: string,
|
|
8
|
+
/**
|
|
9
|
+
* Function to call when ESC is pressed. or when TAB is pressed at the last item in the list of items returned by the query selector.
|
|
10
|
+
*/
|
|
7
11
|
onPressEscape?: () => void,
|
|
12
|
+
/**
|
|
13
|
+
* Function to call when TAB is pressed at the last item in the list of items returned by the query selector. Will be the same as
|
|
14
|
+
* onPressEscape if not specified.
|
|
15
|
+
*/
|
|
16
|
+
onPressLastTab?: () => void,
|
|
8
17
|
}
|
|
9
18
|
|
|
10
|
-
export function useKeyboardControls({
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
document.removeEventListener('keydown', keyboardControls)
|
|
15
|
-
document.removeEventListener('click', hide)
|
|
16
|
-
}
|
|
19
|
+
export function useKeyboardControls({ querySelectors, onPressEscape, onPressLastTab = onPressEscape }: Props) {
|
|
20
|
+
const keyboardControlledElement = useRef<HTMLDivElement>(null)
|
|
21
|
+
const listeners = useRef<Pick<Props, 'onPressEscape' | 'onPressLastTab'>>({})
|
|
22
|
+
listeners.current = { onPressEscape, onPressLastTab }
|
|
17
23
|
|
|
18
24
|
const keyboardControls = useCallback((event: KeyboardEvent) => {
|
|
19
25
|
const target = event?.target as HTMLElement | null
|
|
20
26
|
|
|
21
27
|
function getSelectableAnchors() {
|
|
22
|
-
return
|
|
28
|
+
return keyboardControlledElement.current?.querySelectorAll(querySelectors) ?? []
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
function handleArrows(key = event.key) {
|
|
26
|
-
|
|
27
32
|
const anchors = getSelectableAnchors()
|
|
28
33
|
let i = 0
|
|
29
34
|
while (i < anchors.length && document.activeElement !== anchors[i]) i++
|
|
@@ -33,56 +38,33 @@ export function useKeyboardControls({ onHide, visible, querySelectors, onPressEs
|
|
|
33
38
|
|
|
34
39
|
const handlers: Record<string, (() => void) | undefined> = {
|
|
35
40
|
Escape: () => {
|
|
36
|
-
onPressEscape?.()
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
listeners.current.onPressEscape?.()
|
|
42
|
+
event.stopPropagation()
|
|
43
|
+
event.preventDefault()
|
|
39
44
|
},
|
|
40
45
|
Enter: () => {
|
|
41
46
|
target?.click()
|
|
42
47
|
},
|
|
43
48
|
Tab: () => {
|
|
44
49
|
const anchors = getSelectableAnchors()
|
|
45
|
-
if (document.activeElement === anchors[anchors.length - 1])
|
|
46
|
-
else
|
|
47
|
-
|
|
48
|
-
event.preventDefault()
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
ArrowUp: () => {
|
|
52
|
-
handleArrows()
|
|
53
|
-
},
|
|
54
|
-
ArrowDown: () => {
|
|
55
|
-
handleArrows()
|
|
50
|
+
if (document.activeElement === anchors[anchors.length - 1]) listeners.current.onPressLastTab?.()
|
|
51
|
+
else handleArrows('ArrowDown')
|
|
52
|
+
event.preventDefault()
|
|
56
53
|
},
|
|
54
|
+
ArrowUp: handleArrows,
|
|
55
|
+
ArrowDown: handleArrows,
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
handlers[event.key]?.()
|
|
60
|
-
}, [
|
|
59
|
+
}, [])
|
|
61
60
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
// if the element is not in the DOM anymore, we'll consider the click was inside the selection list
|
|
65
|
-
const isClickInsideSelectionList = !target?.isConnected || wrapper.current?.contains(target)
|
|
66
|
-
const isAction = target?.classList?.contains('action') || !!target?.closest('.action')
|
|
67
|
-
if (!isClickInsideSelectionList || isAction) onHide?.()
|
|
61
|
+
const attachKeyboardListeners = useCallback(() => {
|
|
62
|
+
document.addEventListener('keydown', keyboardControls)
|
|
68
63
|
}, [])
|
|
69
64
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
document.addEventListener('keydown', keyboardControls)
|
|
74
|
-
if (onHide) setTimeout(() => document.addEventListener('click', hide), 50)
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
onRemoveListeners()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return () => {
|
|
81
|
-
// Remove the event listener
|
|
82
|
-
document.removeEventListener('keydown', keyboardControls)
|
|
83
|
-
document.removeEventListener('click', hide)
|
|
84
|
-
}
|
|
85
|
-
}, [visible, keyboardControls])
|
|
65
|
+
const detachKeyboardListeners = useCallback(() => {
|
|
66
|
+
document.removeEventListener('keydown', keyboardControls)
|
|
67
|
+
}, [])
|
|
86
68
|
|
|
87
|
-
return
|
|
69
|
+
return { keyboardControlledElement, attachKeyboardListeners, detachKeyboardListeners }
|
|
88
70
|
}
|
package/src/layout.css
CHANGED
|
@@ -49,12 +49,12 @@ body {
|
|
|
49
49
|
--toastify-font-family: 'Roboto', sans-serif;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
#layout
|
|
52
|
+
#layout:not(.menu-compact) {
|
|
53
53
|
--menu-sections-width: 135px;
|
|
54
54
|
--menu-item-height: 56px;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
#layout.menu-compact
|
|
57
|
+
#layout.menu-compact {
|
|
58
58
|
--menu-sections-width: 56px;
|
|
59
59
|
--menu-item-height: 56px;
|
|
60
60
|
}
|
|
@@ -133,20 +133,24 @@ body {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
#menu .toggle .expand,
|
|
136
|
-
#layout.menu-compact
|
|
136
|
+
#layout.menu-compact .toggle .collapse {
|
|
137
137
|
opacity: 0;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
#menu .toggle .collapse,
|
|
141
|
-
#layout.menu-compact
|
|
141
|
+
#layout.menu-compact .toggle .expand {
|
|
142
142
|
opacity: 1;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
#layout
|
|
145
|
+
#layout .section-label {
|
|
146
|
+
line-height: 0.875rem;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#layout.menu-compact .section-label {
|
|
146
150
|
display: none;
|
|
147
151
|
}
|
|
148
152
|
|
|
149
|
-
#layout:not(.menu-compact
|
|
153
|
+
#layout:not(.menu-compact) .section-label {
|
|
150
154
|
display: block;
|
|
151
155
|
}
|
|
152
156
|
|
|
@@ -179,6 +183,7 @@ body {
|
|
|
179
183
|
transition: background-color 0.2s;
|
|
180
184
|
cursor: pointer;
|
|
181
185
|
position: relative;
|
|
186
|
+
z-index: 2;
|
|
182
187
|
}
|
|
183
188
|
|
|
184
189
|
#menuSections > ul li a:before {
|
|
@@ -224,7 +229,7 @@ body {
|
|
|
224
229
|
left: calc(var(--menu-sections-width) + 15px);
|
|
225
230
|
bottom: 15px;
|
|
226
231
|
background-color: var(--light-500);
|
|
227
|
-
border-radius:
|
|
232
|
+
border-radius: 8px;
|
|
228
233
|
display: flex;
|
|
229
234
|
flex-direction: column;
|
|
230
235
|
overflow: hidden;
|
|
@@ -249,7 +254,7 @@ body {
|
|
|
249
254
|
height: 0;
|
|
250
255
|
border-top: 12px solid transparent;
|
|
251
256
|
border-bottom: 12px solid transparent;
|
|
252
|
-
border-right: 12px solid var(--light-
|
|
257
|
+
border-right: 12px solid var(--light-500);
|
|
253
258
|
position: fixed;
|
|
254
259
|
/* header + menu sections padding + item height / 2 - arrow height / 2 */
|
|
255
260
|
top: calc(var(--header-height) + 10px + var(--menu-item-height) / 2 - 12px);
|
|
@@ -458,6 +463,7 @@ i {
|
|
|
458
463
|
top: 27%;
|
|
459
464
|
right: 10px;
|
|
460
465
|
background-color: inherit;
|
|
466
|
+
z-index: 1;
|
|
461
467
|
}
|
|
462
468
|
|
|
463
469
|
#menuSections .section-submenu-icon:focus-visible {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface ErrorDescription {
|
|
2
|
-
code?: number;
|
|
3
|
-
message?: string;
|
|
4
|
-
debug?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export type DescriptionFn = (error: any) => ErrorDescription;
|
|
7
|
-
export declare class ErrorDescriptor {
|
|
8
|
-
private static descriptionFunction;
|
|
9
|
-
static setDescriptionFunction(fn: DescriptionFn): void;
|
|
10
|
-
static describe(error: any): ErrorDescription;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=ErrorDescriptor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorDescriptor.d.ts","sourceRoot":"","sources":["../../../src/components/error/ErrorDescriptor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,gBAAgB,CAAA;AAE5D,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAEhC;IAEF,MAAM,CAAC,sBAAsB,CAAC,EAAE,EAAE,aAAa;IAI/C,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG;CAG3B"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export class ErrorDescriptor {
|
|
2
|
-
static setDescriptionFunction(fn) {
|
|
3
|
-
this.descriptionFunction = fn;
|
|
4
|
-
}
|
|
5
|
-
static describe(error) {
|
|
6
|
-
return this.descriptionFunction(error);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(ErrorDescriptor, "descriptionFunction", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: error => ({
|
|
14
|
-
message: error.message || `${error}`,
|
|
15
|
-
})
|
|
16
|
-
});
|
|
17
|
-
//# sourceMappingURL=ErrorDescriptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorDescriptor.js","sourceRoot":"","sources":["../../../src/components/error/ErrorDescriptor.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,eAAe;IAK1B,MAAM,CAAC,sBAAsB,CAAC,EAAiB;QAC7C,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAA;IAC/B,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,KAAU;QACxB,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAA;IACxC,CAAC;;AAVc;;;;WAAqC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,GAAG,KAAK,EAAE;KACrC,CAAC;GAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCheckTextOverflow.d.ts","sourceRoot":"","sources":["../../../src/components/menu/useCheckTextOverflow.tsx"],"names":[],"mappings":";AAEA,wBAAgB,oBAAoB;;;EAuBnC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { useState, useRef, useEffect } from 'react';
|
|
2
|
-
export function useCheckTextOverflow() {
|
|
3
|
-
const [overflow, setOverflow] = useState(false);
|
|
4
|
-
const ref = useRef(null);
|
|
5
|
-
const checkOverflow = () => {
|
|
6
|
-
if (!ref.current) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
const hasOverflow = ref.current.offsetWidth < ref.current.scrollWidth;
|
|
10
|
-
if (hasOverflow === overflow) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
setOverflow(hasOverflow);
|
|
14
|
-
};
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
checkOverflow();
|
|
17
|
-
}, [ref.current]);
|
|
18
|
-
return { overflow, ref };
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=useCheckTextOverflow.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCheckTextOverflow.js","sourceRoot":"","sources":["../../../src/components/menu/useCheckTextOverflow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpD,MAAM,UAAU,oBAAoB;IAClC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAA;IACxD,MAAM,GAAG,GAAG,MAAM,CAAuB,IAAI,CAAC,CAAA;IAE9C,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAA;QAErE,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAM;QACR,CAAC;QAED,WAAW,CAAC,WAAW,CAAC,CAAA;IAC1B,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,EAAE,CAAA;IACjB,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAEjB,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;AAC1B,CAAC"}
|