@salt-ds/lab 1.0.0-alpha.91 → 1.0.0-alpha.93
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 +21 -0
- package/css/salt-lab.css +24 -142
- package/dist-cjs/index.js +0 -16
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/tree/Tree.js +4 -1
- package/dist-cjs/tree/Tree.js.map +1 -1
- package/dist-cjs/tree/TreeNode.css.js +1 -1
- package/dist-cjs/tree/TreeNodeExpansionIcon.css.js +1 -1
- package/dist-cjs/tree/TreeNodeTrigger.css.js +1 -1
- package/dist-es/index.js +0 -8
- package/dist-es/index.js.map +1 -1
- package/dist-es/tree/Tree.js +4 -1
- package/dist-es/tree/Tree.js.map +1 -1
- package/dist-es/tree/TreeNode.css.js +1 -1
- package/dist-es/tree/TreeNodeExpansionIcon.css.js +1 -1
- package/dist-es/tree/TreeNodeTrigger.css.js +1 -1
- package/dist-types/index.d.ts +0 -1
- package/package.json +2 -2
- package/dist-cjs/side-panel/SidePanel.css.js +0 -6
- package/dist-cjs/side-panel/SidePanel.css.js.map +0 -1
- package/dist-cjs/side-panel/SidePanel.js +0 -151
- package/dist-cjs/side-panel/SidePanel.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelCloseButton.js +0 -38
- package/dist-cjs/side-panel/SidePanelCloseButton.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelContent.css.js +0 -6
- package/dist-cjs/side-panel/SidePanelContent.css.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelContent.js +0 -66
- package/dist-cjs/side-panel/SidePanelContent.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelHeader.css.js +0 -6
- package/dist-cjs/side-panel/SidePanelHeader.css.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelHeader.js +0 -26
- package/dist-cjs/side-panel/SidePanelHeader.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelProvider.js +0 -89
- package/dist-cjs/side-panel/SidePanelProvider.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelTitle.css.js +0 -6
- package/dist-cjs/side-panel/SidePanelTitle.css.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelTitle.js +0 -48
- package/dist-cjs/side-panel/SidePanelTitle.js.map +0 -1
- package/dist-cjs/side-panel/SidePanelTrigger.js +0 -37
- package/dist-cjs/side-panel/SidePanelTrigger.js.map +0 -1
- package/dist-cjs/side-panel/internal/SidePanelContext.js +0 -34
- package/dist-cjs/side-panel/internal/SidePanelContext.js.map +0 -1
- package/dist-cjs/side-panel/internal/useIsScrollable.js +0 -50
- package/dist-cjs/side-panel/internal/useIsScrollable.js.map +0 -1
- package/dist-cjs/side-panel/internal/useSidePanelTabOrder.js +0 -121
- package/dist-cjs/side-panel/internal/useSidePanelTabOrder.js.map +0 -1
- package/dist-cjs/side-panel/useSidePanel.js +0 -43
- package/dist-cjs/side-panel/useSidePanel.js.map +0 -1
- package/dist-es/side-panel/SidePanel.css.js +0 -4
- package/dist-es/side-panel/SidePanel.css.js.map +0 -1
- package/dist-es/side-panel/SidePanel.js +0 -149
- package/dist-es/side-panel/SidePanel.js.map +0 -1
- package/dist-es/side-panel/SidePanelCloseButton.js +0 -36
- package/dist-es/side-panel/SidePanelCloseButton.js.map +0 -1
- package/dist-es/side-panel/SidePanelContent.css.js +0 -4
- package/dist-es/side-panel/SidePanelContent.css.js.map +0 -1
- package/dist-es/side-panel/SidePanelContent.js +0 -64
- package/dist-es/side-panel/SidePanelContent.js.map +0 -1
- package/dist-es/side-panel/SidePanelHeader.css.js +0 -4
- package/dist-es/side-panel/SidePanelHeader.css.js.map +0 -1
- package/dist-es/side-panel/SidePanelHeader.js +0 -24
- package/dist-es/side-panel/SidePanelHeader.js.map +0 -1
- package/dist-es/side-panel/SidePanelProvider.js +0 -87
- package/dist-es/side-panel/SidePanelProvider.js.map +0 -1
- package/dist-es/side-panel/SidePanelTitle.css.js +0 -4
- package/dist-es/side-panel/SidePanelTitle.css.js.map +0 -1
- package/dist-es/side-panel/SidePanelTitle.js +0 -46
- package/dist-es/side-panel/SidePanelTitle.js.map +0 -1
- package/dist-es/side-panel/SidePanelTrigger.js +0 -35
- package/dist-es/side-panel/SidePanelTrigger.js.map +0 -1
- package/dist-es/side-panel/internal/SidePanelContext.js +0 -31
- package/dist-es/side-panel/internal/SidePanelContext.js.map +0 -1
- package/dist-es/side-panel/internal/useIsScrollable.js +0 -48
- package/dist-es/side-panel/internal/useIsScrollable.js.map +0 -1
- package/dist-es/side-panel/internal/useSidePanelTabOrder.js +0 -119
- package/dist-es/side-panel/internal/useSidePanelTabOrder.js.map +0 -1
- package/dist-es/side-panel/useSidePanel.js +0 -41
- package/dist-es/side-panel/useSidePanel.js.map +0 -1
- package/dist-types/side-panel/SidePanel.d.ts +0 -27
- package/dist-types/side-panel/SidePanelCloseButton.d.ts +0 -2
- package/dist-types/side-panel/SidePanelContent.d.ts +0 -4
- package/dist-types/side-panel/SidePanelHeader.d.ts +0 -4
- package/dist-types/side-panel/SidePanelProvider.d.ts +0 -20
- package/dist-types/side-panel/SidePanelTitle.d.ts +0 -4
- package/dist-types/side-panel/SidePanelTrigger.d.ts +0 -4
- package/dist-types/side-panel/index.d.ts +0 -8
- package/dist-types/side-panel/internal/SidePanelContext.d.ts +0 -56
- package/dist-types/side-panel/internal/index.d.ts +0 -3
- package/dist-types/side-panel/internal/useIsScrollable.d.ts +0 -2
- package/dist-types/side-panel/internal/useSidePanelTabOrder.d.ts +0 -7
- package/dist-types/side-panel/useSidePanel.d.ts +0 -39
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useFloatingRootContext } from '@floating-ui/react';
|
|
3
|
-
import { useControlled } from '@salt-ds/core';
|
|
4
|
-
import { useCallback, useState, useEffect, useMemo } from 'react';
|
|
5
|
-
import { SidePanelContext } from './internal/SidePanelContext.js';
|
|
6
|
-
import { useSidePanelTabOrder } from './internal/useSidePanelTabOrder.js';
|
|
7
|
-
|
|
8
|
-
function SidePanelProvider(props) {
|
|
9
|
-
const { children, open: openProp, defaultOpen, onOpenChange } = props;
|
|
10
|
-
const [openState, setOpenState] = useControlled({
|
|
11
|
-
default: Boolean(defaultOpen),
|
|
12
|
-
controlled: openProp,
|
|
13
|
-
name: "SidePanelProvider",
|
|
14
|
-
state: "open"
|
|
15
|
-
});
|
|
16
|
-
const handleOpenChange = useCallback(
|
|
17
|
-
(newOpen) => {
|
|
18
|
-
setOpenState(newOpen);
|
|
19
|
-
onOpenChange == null ? void 0 : onOpenChange(newOpen);
|
|
20
|
-
},
|
|
21
|
-
[onOpenChange]
|
|
22
|
-
);
|
|
23
|
-
const [reference, setReference] = useState(null);
|
|
24
|
-
const [floating, setFloating] = useState(null);
|
|
25
|
-
const [panelId, setPanelId] = useState(void 0);
|
|
26
|
-
const [titleId, setTitleId] = useState(void 0);
|
|
27
|
-
const [position, setPosition] = useState(
|
|
28
|
-
void 0
|
|
29
|
-
);
|
|
30
|
-
const floatingRootContext = useFloatingRootContext({
|
|
31
|
-
open: openState,
|
|
32
|
-
onOpenChange: handleOpenChange,
|
|
33
|
-
elements: {
|
|
34
|
-
reference,
|
|
35
|
-
floating
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (!openState || !floating) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const onKeyDown = (event) => {
|
|
43
|
-
if (event.key !== "Escape") {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
event.preventDefault();
|
|
47
|
-
event.stopPropagation();
|
|
48
|
-
handleOpenChange(false);
|
|
49
|
-
};
|
|
50
|
-
floating.addEventListener("keydown", onKeyDown);
|
|
51
|
-
return () => {
|
|
52
|
-
floating.removeEventListener("keydown", onKeyDown);
|
|
53
|
-
};
|
|
54
|
-
}, [floating, openState, handleOpenChange]);
|
|
55
|
-
useSidePanelTabOrder({
|
|
56
|
-
floating,
|
|
57
|
-
open: openState,
|
|
58
|
-
reference
|
|
59
|
-
});
|
|
60
|
-
const context = useMemo(
|
|
61
|
-
() => ({
|
|
62
|
-
openState,
|
|
63
|
-
floatingRootContext,
|
|
64
|
-
setFloating,
|
|
65
|
-
setReference,
|
|
66
|
-
setOpen: handleOpenChange,
|
|
67
|
-
panelId,
|
|
68
|
-
setPanelId,
|
|
69
|
-
titleId,
|
|
70
|
-
setTitleId,
|
|
71
|
-
position,
|
|
72
|
-
setPosition
|
|
73
|
-
}),
|
|
74
|
-
[
|
|
75
|
-
openState,
|
|
76
|
-
floatingRootContext,
|
|
77
|
-
handleOpenChange,
|
|
78
|
-
panelId,
|
|
79
|
-
titleId,
|
|
80
|
-
position
|
|
81
|
-
]
|
|
82
|
-
);
|
|
83
|
-
return /* @__PURE__ */ jsx(SidePanelContext.Provider, { value: context, children });
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export { SidePanelProvider };
|
|
87
|
-
//# sourceMappingURL=SidePanelProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelProvider.js","sources":["../src/side-panel/SidePanelProvider.tsx"],"sourcesContent":["import { useFloatingRootContext } from \"@floating-ui/react\";\nimport { useControlled } from \"@salt-ds/core\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { SidePanelContext, useSidePanelTabOrder } from \"./internal\";\n\nexport interface SidePanelProviderProps {\n /**\n * Whether the panel is open.\n */\n open?: boolean;\n /**\n * Default open state when initially rendered.\n */\n defaultOpen?: boolean;\n /**\n * Callback when open state changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * SidePanelProvider children, should include SidePanel and SidePanelTrigger.\n */\n children: ReactNode;\n}\n\nexport function SidePanelProvider(props: SidePanelProviderProps) {\n const { children, open: openProp, defaultOpen, onOpenChange } = props;\n\n const [openState, setOpenState] = useControlled({\n default: Boolean(defaultOpen),\n controlled: openProp,\n name: \"SidePanelProvider\",\n state: \"open\",\n });\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setOpenState(newOpen);\n onOpenChange?.(newOpen);\n },\n [onOpenChange],\n );\n\n const [reference, setReference] = useState<HTMLElement | null>(null);\n const [floating, setFloating] = useState<HTMLDivElement | null>(null);\n const [panelId, setPanelId] = useState<string | undefined>(undefined);\n const [titleId, setTitleId] = useState<string | undefined>(undefined);\n const [position, setPosition] = useState<\"right\" | \"left\" | undefined>(\n undefined,\n );\n\n const floatingRootContext = useFloatingRootContext({\n open: openState,\n onOpenChange: handleOpenChange,\n elements: {\n reference,\n floating,\n },\n });\n\n useEffect(() => {\n if (!openState || !floating) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n handleOpenChange(false);\n };\n\n floating.addEventListener(\"keydown\", onKeyDown);\n return () => {\n floating.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [floating, openState, handleOpenChange]);\n\n useSidePanelTabOrder({\n floating,\n open: openState,\n reference,\n });\n\n const context = useMemo(\n () => ({\n openState,\n floatingRootContext,\n setFloating,\n setReference,\n setOpen: handleOpenChange,\n panelId,\n setPanelId,\n titleId,\n setTitleId,\n position,\n setPosition,\n }),\n [\n openState,\n floatingRootContext,\n handleOpenChange,\n panelId,\n titleId,\n position,\n ],\n );\n\n return (\n <SidePanelContext.Provider value={context}>\n {children}\n </SidePanelContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;AA8BO,SAAS,kBAAkB,KAAA,EAA+B;AAC/D,EAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,cAAa,GAAI,KAAA;AAEhE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,aAAA,CAAc;AAAA,IAC9C,OAAA,EAAS,QAAQ,WAAW,CAAA;AAAA,IAC5B,UAAA,EAAY,QAAA;AAAA,IACZ,IAAA,EAAM,mBAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAqB;AACpB,MAAA,YAAA,CAAa,OAAO,CAAA;AACpB,MAAA,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAe,OAAA,CAAA;AAAA,IACjB,CAAA;AAAA,IACA,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAA6B,IAAI,CAAA;AACnE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAgC,IAAI,CAAA;AACpE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA6B,MAAS,CAAA;AACpE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA6B,MAAS,CAAA;AACpE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA;AAAA,IAC9B;AAAA,GACF;AAEA,EAAA,MAAM,sBAAsB,sBAAA,CAAuB;AAAA,IACjD,IAAA,EAAM,SAAA;AAAA,IACN,YAAA,EAAc,gBAAA;AAAA,IACd,QAAA,EAAU;AAAA,MACR,SAAA;AAAA,MACA;AAAA;AACF,GACD,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,QAAA,EAAU;AAC3B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,IACxB,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,SAAA,EAAW,gBAAgB,CAAC,CAAA;AAE1C,EAAA,oBAAA,CAAqB;AAAA,IACnB,QAAA;AAAA,IACA,IAAA,EAAM,SAAA;AAAA,IACN;AAAA,GACD,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,OAAO;AAAA,MACL,SAAA;AAAA,MACA,mBAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA,EAAS,gBAAA;AAAA,MACT,OAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,SAAA;AAAA,MACA,mBAAA;AAAA,MACA,gBAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,2BACG,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,SAC/B,QAAA,EACH,CAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelTitle.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { makePrefixer, useId, useIsomorphicLayoutEffect, Text } from '@salt-ds/core';
|
|
3
|
-
import { useComponentCssInjection } from '@salt-ds/styles';
|
|
4
|
-
import { useWindow } from '@salt-ds/window';
|
|
5
|
-
import { clsx } from 'clsx';
|
|
6
|
-
import { forwardRef } from 'react';
|
|
7
|
-
import { useSidePanelContext } from './internal/SidePanelContext.js';
|
|
8
|
-
import 'tabbable';
|
|
9
|
-
import css_248z from './SidePanelTitle.css.js';
|
|
10
|
-
|
|
11
|
-
const withBaseName = makePrefixer("saltSidePanelTitle");
|
|
12
|
-
const SidePanelTitle = forwardRef(
|
|
13
|
-
function SidePanelTitle2(props, ref) {
|
|
14
|
-
const { children, className, id, styleAs = "h2", ...rest } = props;
|
|
15
|
-
const { setTitleId } = useSidePanelContext();
|
|
16
|
-
const targetWindow = useWindow();
|
|
17
|
-
useComponentCssInjection({
|
|
18
|
-
testId: "salt-side-panel-title",
|
|
19
|
-
css: css_248z,
|
|
20
|
-
window: targetWindow
|
|
21
|
-
});
|
|
22
|
-
const titleId = useId(id);
|
|
23
|
-
useIsomorphicLayoutEffect(() => {
|
|
24
|
-
if (titleId) {
|
|
25
|
-
setTitleId(titleId);
|
|
26
|
-
}
|
|
27
|
-
return () => {
|
|
28
|
-
setTitleId(void 0);
|
|
29
|
-
};
|
|
30
|
-
}, [titleId, setTitleId]);
|
|
31
|
-
return /* @__PURE__ */ jsx(
|
|
32
|
-
Text,
|
|
33
|
-
{
|
|
34
|
-
ref,
|
|
35
|
-
id: titleId,
|
|
36
|
-
styleAs,
|
|
37
|
-
className: clsx(withBaseName(), className),
|
|
38
|
-
...rest,
|
|
39
|
-
children
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
export { SidePanelTitle };
|
|
46
|
-
//# sourceMappingURL=SidePanelTitle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelTitle.js","sources":["../src/side-panel/SidePanelTitle.tsx"],"sourcesContent":["import {\n makePrefixer,\n Text,\n type TextProps,\n useId,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport { forwardRef } from \"react\";\nimport { useSidePanelContext } from \"./internal\";\nimport sidePanelTitleCss from \"./SidePanelTitle.css\";\n\nconst withBaseName = makePrefixer(\"saltSidePanelTitle\");\n\nexport interface SidePanelTitleProps extends TextProps<\"div\"> {}\n\nexport const SidePanelTitle = forwardRef<HTMLDivElement, SidePanelTitleProps>(\n function SidePanelTitle(props, ref) {\n const { children, className, id, styleAs = \"h2\", ...rest } = props;\n\n const { setTitleId } = useSidePanelContext();\n const targetWindow = useWindow();\n\n useComponentCssInjection({\n testId: \"salt-side-panel-title\",\n css: sidePanelTitleCss,\n window: targetWindow,\n });\n\n const titleId = useId(id);\n\n useIsomorphicLayoutEffect(() => {\n if (titleId) {\n setTitleId(titleId);\n }\n\n return () => {\n setTitleId(undefined);\n };\n }, [titleId, setTitleId]);\n\n return (\n <Text\n ref={ref}\n id={titleId}\n styleAs={styleAs}\n className={clsx(withBaseName(), className)}\n {...rest}\n >\n {children}\n </Text>\n );\n },\n);\n"],"names":["SidePanelTitle","sidePanelTitleCss"],"mappings":";;;;;;;;;;AAcA,MAAM,YAAA,GAAe,aAAa,oBAAoB,CAAA;AAI/C,MAAM,cAAA,GAAiB,UAAA;AAAA,EAC5B,SAASA,eAAAA,CAAe,KAAA,EAAO,GAAA,EAAK;AAClC,IAAA,MAAM,EAAE,UAAU,SAAA,EAAW,EAAA,EAAI,UAAU,IAAA,EAAM,GAAG,MAAK,GAAI,KAAA;AAE7D,IAAA,MAAM,EAAE,UAAA,EAAW,GAAI,mBAAA,EAAoB;AAC3C,IAAA,MAAM,eAAe,SAAA,EAAU;AAE/B,IAAA,wBAAA,CAAyB;AAAA,MACvB,MAAA,EAAQ,uBAAA;AAAA,MACR,GAAA,EAAKC,QAAA;AAAA,MACL,MAAA,EAAQ;AAAA,KACT,CAAA;AAED,IAAA,MAAM,OAAA,GAAU,MAAM,EAAE,CAAA;AAExB,IAAA,yBAAA,CAA0B,MAAM;AAC9B,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,UAAA,CAAW,OAAO,CAAA;AAAA,MACpB;AAEA,MAAA,OAAO,MAAM;AACX,QAAA,UAAA,CAAW,MAAS,CAAA;AAAA,MACtB,CAAA;AAAA,IACF,CAAA,EAAG,CAAC,OAAA,EAAS,UAAU,CAAC,CAAA;AAExB,IAAA,uBACE,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,EAAA,EAAI,OAAA;AAAA,QACJ,OAAA;AAAA,QACA,SAAA,EAAW,IAAA,CAAK,YAAA,EAAa,EAAG,SAAS,CAAA;AAAA,QACxC,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;;;;"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useForkRef, getRefFromChildren, mergeProps } from '@salt-ds/core';
|
|
3
|
-
import { forwardRef, isValidElement, cloneElement } from 'react';
|
|
4
|
-
import { useSidePanelContext } from './internal/SidePanelContext.js';
|
|
5
|
-
import 'tabbable';
|
|
6
|
-
|
|
7
|
-
const SidePanelTrigger = forwardRef(function SidePanelTrigger2(props, ref) {
|
|
8
|
-
const { children, onClick, ...rest } = props;
|
|
9
|
-
const { setReference, openState, setOpen, panelId } = useSidePanelContext();
|
|
10
|
-
const combinedRef = useForkRef(setReference, ref);
|
|
11
|
-
const handleRef = useForkRef(combinedRef, getRefFromChildren(children));
|
|
12
|
-
const handleClick = (event) => {
|
|
13
|
-
onClick == null ? void 0 : onClick(event);
|
|
14
|
-
setOpen(!openState);
|
|
15
|
-
};
|
|
16
|
-
if (!children || !isValidElement(children)) {
|
|
17
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
18
|
-
}
|
|
19
|
-
const mergedProps = mergeProps(
|
|
20
|
-
{
|
|
21
|
-
"aria-expanded": openState,
|
|
22
|
-
"aria-controls": openState ? panelId : void 0,
|
|
23
|
-
onClick: handleClick,
|
|
24
|
-
...rest
|
|
25
|
-
},
|
|
26
|
-
children.props
|
|
27
|
-
);
|
|
28
|
-
return cloneElement(children, {
|
|
29
|
-
...mergedProps,
|
|
30
|
-
ref: handleRef
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
export { SidePanelTrigger };
|
|
35
|
-
//# sourceMappingURL=SidePanelTrigger.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelTrigger.js","sources":["../src/side-panel/SidePanelTrigger.tsx"],"sourcesContent":["import { getRefFromChildren, mergeProps, useForkRef } from \"@salt-ds/core\";\nimport {\n type ComponentPropsWithoutRef,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n} from \"react\";\nimport { useSidePanelContext } from \"./internal\";\n\nexport interface SidePanelTriggerProps\n extends ComponentPropsWithoutRef<\"button\"> {}\n\nexport const SidePanelTrigger = forwardRef<\n HTMLButtonElement,\n SidePanelTriggerProps\n>(function SidePanelTrigger(props, ref) {\n const { children, onClick, ...rest } = props;\n const { setReference, openState, setOpen, panelId } = useSidePanelContext();\n\n const combinedRef = useForkRef(setReference, ref);\n const handleRef = useForkRef(combinedRef, getRefFromChildren(children));\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n setOpen(!openState);\n };\n\n if (!children || !isValidElement(children)) {\n return <>{children}</>;\n }\n\n const mergedProps = mergeProps(\n {\n \"aria-expanded\": openState,\n \"aria-controls\": openState ? panelId : undefined,\n onClick: handleClick,\n ...rest,\n },\n children.props,\n );\n\n return cloneElement(children, {\n ...mergedProps,\n ref: handleRef,\n });\n});\n"],"names":["SidePanelTrigger"],"mappings":";;;;;;AAaO,MAAM,gBAAA,GAAmB,UAAA,CAG9B,SAASA,iBAAAA,CAAiB,OAAO,GAAA,EAAK;AACtC,EAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAS,GAAG,MAAK,GAAI,KAAA;AACvC,EAAA,MAAM,EAAE,YAAA,EAAc,SAAA,EAAW,OAAA,EAAS,OAAA,KAAY,mBAAA,EAAoB;AAE1E,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,YAAA,EAAc,GAAG,CAAA;AAChD,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,WAAA,EAAa,kBAAA,CAAmB,QAAQ,CAAC,CAAA;AAEtE,EAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAAyC;AAC5D,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,KAAA,CAAA;AACV,IAAA,OAAA,CAAQ,CAAC,SAAS,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,cAAA,CAAe,QAAQ,CAAA,EAAG;AAC1C,IAAA,uCAAU,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,MAAM,WAAA,GAAc,UAAA;AAAA,IAClB;AAAA,MACE,eAAA,EAAiB,SAAA;AAAA,MACjB,eAAA,EAAiB,YAAY,OAAA,GAAU,MAAA;AAAA,MACvC,OAAA,EAAS,WAAA;AAAA,MACT,GAAG;AAAA,KACL;AAAA,IACA,QAAA,CAAS;AAAA,GACX;AAEA,EAAA,OAAO,aAAa,QAAA,EAAU;AAAA,IAC5B,GAAG,WAAA;AAAA,IACH,GAAA,EAAK;AAAA,GACN,CAAA;AACH,CAAC;;;;"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { createContext } from '@salt-ds/core';
|
|
2
|
-
import { useContext } from 'react';
|
|
3
|
-
|
|
4
|
-
const SidePanelContext = createContext(
|
|
5
|
-
"SidePanelContext",
|
|
6
|
-
{
|
|
7
|
-
openState: false,
|
|
8
|
-
floatingRootContext: {},
|
|
9
|
-
setFloating: () => {
|
|
10
|
-
},
|
|
11
|
-
setReference: () => {
|
|
12
|
-
},
|
|
13
|
-
setOpen: () => {
|
|
14
|
-
},
|
|
15
|
-
panelId: void 0,
|
|
16
|
-
setPanelId: () => {
|
|
17
|
-
},
|
|
18
|
-
titleId: void 0,
|
|
19
|
-
setTitleId: () => {
|
|
20
|
-
},
|
|
21
|
-
position: void 0,
|
|
22
|
-
setPosition: () => {
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
);
|
|
26
|
-
function useSidePanelContext() {
|
|
27
|
-
return useContext(SidePanelContext);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export { SidePanelContext, useSidePanelContext };
|
|
31
|
-
//# sourceMappingURL=SidePanelContext.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelContext.js","sources":["../src/side-panel/internal/SidePanelContext.ts"],"sourcesContent":["import type { FloatingRootContext } from \"@floating-ui/react\";\nimport { createContext } from \"@salt-ds/core\";\nimport { type Dispatch, type SetStateAction, useContext } from \"react\";\n\nexport interface SidePanelContextValue {\n /**\n * Whether the side panel is currently open.\n */\n openState: boolean;\n /**\n * The floating-ui root context shared between the trigger and the panel.\n * Coordinates interactions (click, dismiss, role) across both elements.\n */\n floatingRootContext: FloatingRootContext;\n /**\n * Ref setter for the panel element.\n * Registers the panel DOM node with floating-ui.\n */\n setFloating: Dispatch<SetStateAction<HTMLDivElement | null>>;\n /**\n * Ref setter for the reference (trigger) element.\n * Registers the trigger DOM node with floating-ui for focus return.\n */\n setReference: Dispatch<SetStateAction<HTMLElement | null>>;\n /**\n * Sets the open state of the panel.\n * Called by the close button in SidePanelHeader, or any consumer that needs to close the panel.\n */\n setOpen: (open: boolean) => void;\n /**\n * Side panel id used for aria-controls on the trigger.\n */\n panelId?: string;\n /**\n * Registers or clears the side panel id used for aria-controls/id linkage.\n */\n setPanelId: Dispatch<SetStateAction<string | undefined>>;\n /**\n * The auto-generated id placed on SidePanelTitle.\n * Used for aria-labelledby on the panel region and the scrollable body.\n */\n titleId?: string;\n /**\n * Registers the title id from SidePanelTitle back to the context\n * so that SidePanel and SidePanelContent can use it for aria-labelledby.\n */\n setTitleId: Dispatch<SetStateAction<string | undefined>>;\n /**\n * Edge the panel is anchored to.\n */\n position?: \"right\" | \"left\";\n /**\n * Registers the position from SidePanel back to the context.\n */\n setPosition: Dispatch<SetStateAction<\"right\" | \"left\" | undefined>>;\n}\n\nexport const SidePanelContext = createContext<SidePanelContextValue>(\n \"SidePanelContext\",\n {\n openState: false,\n floatingRootContext: {} as FloatingRootContext,\n setFloating: () => {},\n setReference: () => {},\n setOpen: () => {},\n panelId: undefined,\n setPanelId: () => {},\n titleId: undefined,\n setTitleId: () => {},\n position: undefined,\n setPosition: () => {},\n },\n);\n\nexport function useSidePanelContext() {\n return useContext(SidePanelContext);\n}\n"],"names":[],"mappings":";;;AAyDO,MAAM,gBAAA,GAAmB,aAAA;AAAA,EAC9B,kBAAA;AAAA,EACA;AAAA,IACE,SAAA,EAAW,KAAA;AAAA,IACX,qBAAqB,EAAC;AAAA,IACtB,aAAa,MAAM;AAAA,IAAC,CAAA;AAAA,IACpB,cAAc,MAAM;AAAA,IAAC,CAAA;AAAA,IACrB,SAAS,MAAM;AAAA,IAAC,CAAA;AAAA,IAChB,OAAA,EAAS,MAAA;AAAA,IACT,YAAY,MAAM;AAAA,IAAC,CAAA;AAAA,IACnB,OAAA,EAAS,MAAA;AAAA,IACT,YAAY,MAAM;AAAA,IAAC,CAAA;AAAA,IACnB,QAAA,EAAU,MAAA;AAAA,IACV,aAAa,MAAM;AAAA,IAAC;AAAA;AAExB;AAEO,SAAS,mBAAA,GAAsB;AACpC,EAAA,OAAO,WAAW,gBAAgB,CAAA;AACpC;;;;"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
const observedAttributes = ["class", "hidden", "style"];
|
|
4
|
-
function useIsScrollable(ref) {
|
|
5
|
-
const [isScrollable, setIsScrollable] = useState(false);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const element = ref.current;
|
|
8
|
-
const win = element == null ? void 0 : element.ownerDocument.defaultView;
|
|
9
|
-
if (!element || !win) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
let animationFrame;
|
|
13
|
-
const checkScrollable = () => {
|
|
14
|
-
animationFrame = void 0;
|
|
15
|
-
const nextIsScrollable = element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
|
|
16
|
-
setIsScrollable(
|
|
17
|
-
(currentIsScrollable) => currentIsScrollable === nextIsScrollable ? currentIsScrollable : nextIsScrollable
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
const scheduleCheck = () => {
|
|
21
|
-
if (animationFrame === void 0) {
|
|
22
|
-
animationFrame = win.requestAnimationFrame(checkScrollable);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
scheduleCheck();
|
|
26
|
-
const resizeObserver = win.ResizeObserver ? new win.ResizeObserver(scheduleCheck) : void 0;
|
|
27
|
-
resizeObserver == null ? void 0 : resizeObserver.observe(element);
|
|
28
|
-
const mutationObserver = win.MutationObserver ? new win.MutationObserver(scheduleCheck) : void 0;
|
|
29
|
-
mutationObserver == null ? void 0 : mutationObserver.observe(element, {
|
|
30
|
-
attributeFilter: observedAttributes,
|
|
31
|
-
attributes: true,
|
|
32
|
-
characterData: true,
|
|
33
|
-
childList: true,
|
|
34
|
-
subtree: true
|
|
35
|
-
});
|
|
36
|
-
return () => {
|
|
37
|
-
if (animationFrame !== void 0) {
|
|
38
|
-
win.cancelAnimationFrame(animationFrame);
|
|
39
|
-
}
|
|
40
|
-
resizeObserver == null ? void 0 : resizeObserver.disconnect();
|
|
41
|
-
mutationObserver == null ? void 0 : mutationObserver.disconnect();
|
|
42
|
-
};
|
|
43
|
-
}, [ref]);
|
|
44
|
-
return isScrollable;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export { useIsScrollable };
|
|
48
|
-
//# sourceMappingURL=useIsScrollable.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useIsScrollable.js","sources":["../src/side-panel/internal/useIsScrollable.ts"],"sourcesContent":["import { type RefObject, useEffect, useState } from \"react\";\n\nconst observedAttributes = [\"class\", \"hidden\", \"style\"];\n\nexport function useIsScrollable(ref: RefObject<HTMLElement>) {\n const [isScrollable, setIsScrollable] = useState(false);\n\n useEffect(() => {\n const element = ref.current;\n const win = element?.ownerDocument.defaultView;\n if (!element || !win) {\n return;\n }\n\n let animationFrame: number | undefined;\n\n const checkScrollable = () => {\n animationFrame = undefined;\n const nextIsScrollable =\n element.scrollHeight > element.clientHeight ||\n element.scrollWidth > element.clientWidth;\n\n setIsScrollable((currentIsScrollable) =>\n currentIsScrollable === nextIsScrollable\n ? currentIsScrollable\n : nextIsScrollable,\n );\n };\n\n const scheduleCheck = () => {\n if (animationFrame === undefined) {\n animationFrame = win.requestAnimationFrame(checkScrollable);\n }\n };\n\n scheduleCheck();\n\n const resizeObserver = win.ResizeObserver\n ? new win.ResizeObserver(scheduleCheck)\n : undefined;\n resizeObserver?.observe(element);\n\n const mutationObserver = win.MutationObserver\n ? new win.MutationObserver(scheduleCheck)\n : undefined;\n mutationObserver?.observe(element, {\n attributeFilter: observedAttributes,\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n });\n\n return () => {\n if (animationFrame !== undefined) {\n win.cancelAnimationFrame(animationFrame);\n }\n resizeObserver?.disconnect();\n mutationObserver?.disconnect();\n };\n }, [ref]);\n\n return isScrollable;\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kBAAA,GAAqB,CAAC,OAAA,EAAS,QAAA,EAAU,OAAO,CAAA;AAE/C,SAAS,gBAAgB,GAAA,EAA6B;AAC3D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,GAAA,CAAI,OAAA;AACpB,IAAA,MAAM,GAAA,GAAM,mCAAS,aAAA,CAAc,WAAA;AACnC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,GAAA,EAAK;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,cAAA;AAEJ,IAAA,MAAM,kBAAkB,MAAM;AAC5B,MAAA,cAAA,GAAiB,MAAA;AACjB,MAAA,MAAM,mBACJ,OAAA,CAAQ,YAAA,GAAe,QAAQ,YAAA,IAC/B,OAAA,CAAQ,cAAc,OAAA,CAAQ,WAAA;AAEhC,MAAA,eAAA;AAAA,QAAgB,CAAC,mBAAA,KACf,mBAAA,KAAwB,gBAAA,GACpB,mBAAA,GACA;AAAA,OACN;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,gBAAgB,MAAM;AAC1B,MAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,QAAA,cAAA,GAAiB,GAAA,CAAI,sBAAsB,eAAe,CAAA;AAAA,MAC5D;AAAA,IACF,CAAA;AAEA,IAAA,aAAA,EAAc;AAEd,IAAA,MAAM,iBAAiB,GAAA,CAAI,cAAA,GACvB,IAAI,GAAA,CAAI,cAAA,CAAe,aAAa,CAAA,GACpC,MAAA;AACJ,IAAA,cAAA,IAAA,IAAA,GAAA,MAAA,GAAA,cAAA,CAAgB,OAAA,CAAQ,OAAA,CAAA;AAExB,IAAA,MAAM,mBAAmB,GAAA,CAAI,gBAAA,GACzB,IAAI,GAAA,CAAI,gBAAA,CAAiB,aAAa,CAAA,GACtC,MAAA;AACJ,IAAA,gBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,gBAAA,CAAkB,QAAQ,OAAA,EAAS;AAAA,MACjC,eAAA,EAAiB,kBAAA;AAAA,MACjB,UAAA,EAAY,IAAA;AAAA,MACZ,aAAA,EAAe,IAAA;AAAA,MACf,SAAA,EAAW,IAAA;AAAA,MACX,OAAA,EAAS;AAAA,KACX,CAAA;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,QAAA,GAAA,CAAI,qBAAqB,cAAc,CAAA;AAAA,MACzC;AACA,MAAA,cAAA,IAAA,IAAA,GAAA,MAAA,GAAA,cAAA,CAAgB,UAAA,EAAA;AAChB,MAAA,gBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,gBAAA,CAAkB,UAAA,EAAA;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,OAAO,YAAA;AACT;;;;"}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { useRef, useEffect } from 'react';
|
|
2
|
-
import { tabbable } from 'tabbable';
|
|
3
|
-
|
|
4
|
-
function isPlainTabKey(event) {
|
|
5
|
-
return event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
6
|
-
}
|
|
7
|
-
function getPanelTabbableElements(panel) {
|
|
8
|
-
return tabbable(panel);
|
|
9
|
-
}
|
|
10
|
-
function focusFirstPanelElement(panel) {
|
|
11
|
-
const [firstTabbableElement] = getPanelTabbableElements(panel);
|
|
12
|
-
(firstTabbableElement ?? panel).focus();
|
|
13
|
-
}
|
|
14
|
-
function focusLastPanelElement(panel) {
|
|
15
|
-
const tabbableElements = getPanelTabbableElements(panel);
|
|
16
|
-
(tabbableElements[tabbableElements.length - 1] ?? panel).focus();
|
|
17
|
-
}
|
|
18
|
-
function containsTarget(container, target) {
|
|
19
|
-
const targetWindow = container.ownerDocument.defaultView;
|
|
20
|
-
return Boolean(
|
|
21
|
-
(targetWindow == null ? void 0 : targetWindow.Node) && target instanceof targetWindow.Node && container.contains(target)
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
function getNextTabbableAfterReference(reference, panel) {
|
|
25
|
-
const { body } = reference.ownerDocument;
|
|
26
|
-
const tabbableElements = tabbable(body).filter(
|
|
27
|
-
(element) => !panel.contains(element)
|
|
28
|
-
);
|
|
29
|
-
const referenceIndex = tabbableElements.findIndex(
|
|
30
|
-
(element) => element === reference || reference.contains(element)
|
|
31
|
-
);
|
|
32
|
-
if (referenceIndex === -1) {
|
|
33
|
-
return void 0;
|
|
34
|
-
}
|
|
35
|
-
return tabbableElements[referenceIndex + 1];
|
|
36
|
-
}
|
|
37
|
-
function useSidePanelTabOrder(props) {
|
|
38
|
-
const { floating, open, reference } = props;
|
|
39
|
-
const followsReferenceOrder = useRef(false);
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (!open || !reference || !floating) {
|
|
42
|
-
followsReferenceOrder.current = false;
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const { ownerDocument } = reference;
|
|
46
|
-
const onReferenceKeyDown = (event) => {
|
|
47
|
-
if (event.defaultPrevented || !isPlainTabKey(event) || event.shiftKey) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
event.preventDefault();
|
|
51
|
-
followsReferenceOrder.current = true;
|
|
52
|
-
focusFirstPanelElement(floating);
|
|
53
|
-
};
|
|
54
|
-
const onFloatingKeyDown = (event) => {
|
|
55
|
-
if (event.defaultPrevented || !isPlainTabKey(event)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const panelTabbableElements = getPanelTabbableElements(floating);
|
|
59
|
-
const activeElement = floating.ownerDocument.activeElement;
|
|
60
|
-
if (event.shiftKey) {
|
|
61
|
-
const firstPanelElement = panelTabbableElements[0] ?? floating;
|
|
62
|
-
if (activeElement === firstPanelElement && followsReferenceOrder.current) {
|
|
63
|
-
event.preventDefault();
|
|
64
|
-
followsReferenceOrder.current = false;
|
|
65
|
-
reference.focus();
|
|
66
|
-
}
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const lastPanelElement = panelTabbableElements[panelTabbableElements.length - 1] ?? floating;
|
|
70
|
-
if (activeElement === lastPanelElement && followsReferenceOrder.current) {
|
|
71
|
-
const nextElement = getNextTabbableAfterReference(reference, floating);
|
|
72
|
-
if (nextElement) {
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
followsReferenceOrder.current = false;
|
|
75
|
-
nextElement.focus();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
const onDocumentKeyDown = (event) => {
|
|
80
|
-
if (event.defaultPrevented || !isPlainTabKey(event) || !event.shiftKey) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const nextElement = getNextTabbableAfterReference(reference, floating);
|
|
84
|
-
if (!nextElement || !containsTarget(nextElement, event.target)) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
event.preventDefault();
|
|
88
|
-
followsReferenceOrder.current = true;
|
|
89
|
-
focusLastPanelElement(floating);
|
|
90
|
-
};
|
|
91
|
-
const onFloatingFocusIn = (event) => {
|
|
92
|
-
if (containsTarget(reference, event.relatedTarget)) {
|
|
93
|
-
followsReferenceOrder.current = true;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const nextElement = getNextTabbableAfterReference(reference, floating);
|
|
97
|
-
if (nextElement && containsTarget(nextElement, event.relatedTarget)) {
|
|
98
|
-
followsReferenceOrder.current = true;
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (!containsTarget(floating, event.relatedTarget)) {
|
|
102
|
-
followsReferenceOrder.current = false;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
reference.addEventListener("keydown", onReferenceKeyDown);
|
|
106
|
-
floating.addEventListener("keydown", onFloatingKeyDown);
|
|
107
|
-
floating.addEventListener("focusin", onFloatingFocusIn);
|
|
108
|
-
ownerDocument.addEventListener("keydown", onDocumentKeyDown);
|
|
109
|
-
return () => {
|
|
110
|
-
reference.removeEventListener("keydown", onReferenceKeyDown);
|
|
111
|
-
floating.removeEventListener("keydown", onFloatingKeyDown);
|
|
112
|
-
floating.removeEventListener("focusin", onFloatingFocusIn);
|
|
113
|
-
ownerDocument.removeEventListener("keydown", onDocumentKeyDown);
|
|
114
|
-
};
|
|
115
|
-
}, [floating, open, reference]);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export { useSidePanelTabOrder };
|
|
119
|
-
//# sourceMappingURL=useSidePanelTabOrder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useSidePanelTabOrder.js","sources":["../src/side-panel/internal/useSidePanelTabOrder.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { tabbable } from \"tabbable\";\n\ninterface UseSidePanelTabOrderProps {\n floating: HTMLElement | null;\n open: boolean;\n reference: HTMLElement | null;\n}\n\nfunction isPlainTabKey(event: KeyboardEvent) {\n return (\n event.key === \"Tab\" && !event.altKey && !event.ctrlKey && !event.metaKey\n );\n}\n\nfunction getPanelTabbableElements(panel: HTMLElement) {\n return tabbable(panel);\n}\n\nfunction focusFirstPanelElement(panel: HTMLElement) {\n const [firstTabbableElement] = getPanelTabbableElements(panel);\n (firstTabbableElement ?? panel).focus();\n}\n\nfunction focusLastPanelElement(panel: HTMLElement) {\n const tabbableElements = getPanelTabbableElements(panel);\n (tabbableElements[tabbableElements.length - 1] ?? panel).focus();\n}\n\nfunction containsTarget(container: Element, target: EventTarget | null) {\n const targetWindow = container.ownerDocument.defaultView;\n\n return Boolean(\n targetWindow?.Node &&\n target instanceof targetWindow.Node &&\n container.contains(target),\n );\n}\n\nfunction getNextTabbableAfterReference(\n reference: HTMLElement,\n panel: HTMLElement,\n) {\n const { body } = reference.ownerDocument;\n const tabbableElements = tabbable(body).filter(\n (element) => !panel.contains(element),\n );\n const referenceIndex = tabbableElements.findIndex(\n (element) => element === reference || reference.contains(element),\n );\n\n if (referenceIndex === -1) {\n return undefined;\n }\n\n return tabbableElements[referenceIndex + 1];\n}\n\nexport function useSidePanelTabOrder(props: UseSidePanelTabOrderProps) {\n const { floating, open, reference } = props;\n const followsReferenceOrder = useRef(false);\n\n useEffect(() => {\n if (!open || !reference || !floating) {\n followsReferenceOrder.current = false;\n return;\n }\n\n const { ownerDocument } = reference;\n\n const onReferenceKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || !isPlainTabKey(event) || event.shiftKey) {\n return;\n }\n\n event.preventDefault();\n followsReferenceOrder.current = true;\n focusFirstPanelElement(floating);\n };\n\n const onFloatingKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || !isPlainTabKey(event)) {\n return;\n }\n\n const panelTabbableElements = getPanelTabbableElements(floating);\n const activeElement = floating.ownerDocument.activeElement;\n\n if (event.shiftKey) {\n const firstPanelElement = panelTabbableElements[0] ?? floating;\n\n if (\n activeElement === firstPanelElement &&\n followsReferenceOrder.current\n ) {\n event.preventDefault();\n followsReferenceOrder.current = false;\n reference.focus();\n }\n return;\n }\n\n const lastPanelElement =\n panelTabbableElements[panelTabbableElements.length - 1] ?? floating;\n\n if (activeElement === lastPanelElement && followsReferenceOrder.current) {\n const nextElement = getNextTabbableAfterReference(reference, floating);\n\n if (nextElement) {\n event.preventDefault();\n followsReferenceOrder.current = false;\n nextElement.focus();\n }\n }\n };\n\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || !isPlainTabKey(event) || !event.shiftKey) {\n return;\n }\n\n const nextElement = getNextTabbableAfterReference(reference, floating);\n if (!nextElement || !containsTarget(nextElement, event.target)) {\n return;\n }\n\n event.preventDefault();\n followsReferenceOrder.current = true;\n focusLastPanelElement(floating);\n };\n\n const onFloatingFocusIn = (event: FocusEvent) => {\n if (containsTarget(reference, event.relatedTarget)) {\n followsReferenceOrder.current = true;\n return;\n }\n\n const nextElement = getNextTabbableAfterReference(reference, floating);\n if (nextElement && containsTarget(nextElement, event.relatedTarget)) {\n followsReferenceOrder.current = true;\n return;\n }\n\n if (!containsTarget(floating, event.relatedTarget)) {\n followsReferenceOrder.current = false;\n }\n };\n\n reference.addEventListener(\"keydown\", onReferenceKeyDown);\n floating.addEventListener(\"keydown\", onFloatingKeyDown);\n floating.addEventListener(\"focusin\", onFloatingFocusIn);\n ownerDocument.addEventListener(\"keydown\", onDocumentKeyDown);\n\n return () => {\n reference.removeEventListener(\"keydown\", onReferenceKeyDown);\n floating.removeEventListener(\"keydown\", onFloatingKeyDown);\n floating.removeEventListener(\"focusin\", onFloatingFocusIn);\n ownerDocument.removeEventListener(\"keydown\", onDocumentKeyDown);\n };\n }, [floating, open, reference]);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
import { useSidePanelContext } from './internal/SidePanelContext.js';
|
|
3
|
-
import 'tabbable';
|
|
4
|
-
|
|
5
|
-
function useSidePanel() {
|
|
6
|
-
const { openState, setOpen, setReference, panelId } = useSidePanelContext();
|
|
7
|
-
const getTriggerProps = useCallback(
|
|
8
|
-
(userProps) => {
|
|
9
|
-
const userOnClick = userProps == null ? void 0 : userProps.onClick;
|
|
10
|
-
return {
|
|
11
|
-
"aria-expanded": openState,
|
|
12
|
-
"aria-controls": openState ? panelId : void 0,
|
|
13
|
-
...userProps,
|
|
14
|
-
onClick: (e) => {
|
|
15
|
-
userOnClick == null ? void 0 : userOnClick(e);
|
|
16
|
-
setOpen(!openState);
|
|
17
|
-
},
|
|
18
|
-
ref: (node) => {
|
|
19
|
-
setReference(node);
|
|
20
|
-
const userRef = userProps == null ? void 0 : userProps.ref;
|
|
21
|
-
if (typeof userRef === "function") {
|
|
22
|
-
userRef(node);
|
|
23
|
-
} else if (userRef && typeof userRef === "object" && "current" in userRef) {
|
|
24
|
-
userRef.current = node;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
[openState, panelId, setReference, setOpen]
|
|
30
|
-
);
|
|
31
|
-
return {
|
|
32
|
-
openState,
|
|
33
|
-
setOpen,
|
|
34
|
-
getTriggerProps,
|
|
35
|
-
setTriggerRef: setReference,
|
|
36
|
-
panelId
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export { useSidePanel };
|
|
41
|
-
//# sourceMappingURL=useSidePanel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useSidePanel.js","sources":["../src/side-panel/useSidePanel.ts"],"sourcesContent":["import {\n type MouseEvent,\n type MutableRefObject,\n type RefCallback,\n useCallback,\n} from \"react\";\nimport { useSidePanelContext } from \"./internal\";\n\nexport interface SidePanelValue {\n /**\n * Whether the side panel is currently open.\n */\n openState: boolean;\n /**\n * Sets the open state of the panel.\n */\n setOpen: (open: boolean) => void;\n /**\n * Props getter for a trigger element outside of `SidePanelTrigger`.\n * Returns `aria-expanded`, `aria-controls`, a `ref` (for focus-return),\n * and an `onClick` that toggles the panel.\n *\n * Spread the result onto a Button to get full trigger behavior:\n * ```tsx\n * <Button {...getTriggerProps()}>Toggle panel</Button>\n * ```\n *\n * You can pass additional props which are merged in. If you provide your\n * own `onClick`, it runs before the built-in toggle.\n *\n * For multi-trigger scenarios (e.g. table rows), use `setTriggerRef` and\n * manage ARIA attributes yourself instead.\n */\n getTriggerProps: (\n userProps?: Record<string, unknown>,\n ) => Record<string, unknown>;\n /**\n * Registers the element that should receive focus when the panel closes.\n * Use this in multi-trigger scenarios (e.g. table rows) where each trigger\n * needs explicit control over which element is the reference.\n */\n setTriggerRef: (element: HTMLElement | null) => void;\n /**\n * The panel's DOM id. Use this for `aria-controls` in multi-trigger\n * scenarios where you manage ARIA attributes yourself.\n */\n panelId: string | undefined;\n}\n\nexport function useSidePanel(): SidePanelValue {\n const { openState, setOpen, setReference, panelId } = useSidePanelContext();\n\n const getTriggerProps = useCallback(\n (userProps?: Record<string, unknown>) => {\n const userOnClick = userProps?.onClick as\n | ((e: MouseEvent<HTMLElement>) => void)\n | undefined;\n\n return {\n \"aria-expanded\": openState,\n \"aria-controls\": openState ? panelId : undefined,\n ...userProps,\n onClick: (e: MouseEvent<HTMLElement>) => {\n userOnClick?.(e);\n setOpen(!openState);\n },\n ref: (node: HTMLElement | null) => {\n // Register this element as the trigger for focus return\n setReference(node);\n // Forward the consumer's ref if provided\n const userRef = userProps?.ref as\n | RefCallback<HTMLElement | null>\n | MutableRefObject<HTMLElement | null>;\n if (typeof userRef === \"function\") {\n userRef(node);\n } else if (\n userRef &&\n typeof userRef === \"object\" &&\n \"current\" in userRef\n ) {\n userRef.current = node;\n }\n },\n };\n },\n [openState, panelId, setReference, setOpen],\n );\n\n return {\n openState,\n setOpen,\n getTriggerProps,\n setTriggerRef: setReference,\n panelId,\n };\n}\n"],"names":[],"mappings":";;;;AAiDO,SAAS,YAAA,GAA+B;AAC7C,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,YAAA,EAAc,OAAA,KAAY,mBAAA,EAAoB;AAE1E,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IACtB,CAAC,SAAA,KAAwC;AACvC,MAAA,MAAM,cAAc,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,OAAA;AAI/B,MAAA,OAAO;AAAA,QACL,eAAA,EAAiB,SAAA;AAAA,QACjB,eAAA,EAAiB,YAAY,OAAA,GAAU,MAAA;AAAA,QACvC,GAAG,SAAA;AAAA,QACH,OAAA,EAAS,CAAC,CAAA,KAA+B;AACvC,UAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAc,CAAA,CAAA;AACd,UAAA,OAAA,CAAQ,CAAC,SAAS,CAAA;AAAA,QACpB,CAAA;AAAA,QACA,GAAA,EAAK,CAAC,IAAA,KAA6B;AAEjC,UAAA,YAAA,CAAa,IAAI,CAAA;AAEjB,UAAA,MAAM,UAAU,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,GAAA;AAG3B,UAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd,WACE,OAAA,IACA,OAAO,OAAA,KAAY,QAAA,IACnB,aAAa,OAAA,EACb;AACA,YAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAAA,UACpB;AAAA,QACF;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,OAAA,EAAS,YAAA,EAAc,OAAO;AAAA,GAC5C;AAEA,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,OAAA;AAAA,IACA,eAAA;AAAA,IACA,aAAA,EAAe,YAAA;AAAA,IACf;AAAA,GACF;AACF;;;;"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { FloatingFocusManager } from "@floating-ui/react";
|
|
2
|
-
import { type ComponentProps, type ComponentPropsWithRef } from "react";
|
|
3
|
-
export interface SidePanelProps extends ComponentPropsWithRef<"div"> {
|
|
4
|
-
/**
|
|
5
|
-
* Disable the panel's own open/close animation.
|
|
6
|
-
* Set to `true` when the parent controls sizing and animation (e.g. inside a splitter).
|
|
7
|
-
* @default false
|
|
8
|
-
*/
|
|
9
|
-
disableAnimation?: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Edge the panel is anchored to; controls animation direction and divider side.
|
|
12
|
-
* @default "right"
|
|
13
|
-
*/
|
|
14
|
-
position?: "right" | "left";
|
|
15
|
-
/**
|
|
16
|
-
* Which element receives focus when the panel opens.
|
|
17
|
-
* Pass a number for the tabbable element index (0 = first), or a ref to a specific element.
|
|
18
|
-
* Defaults to the side panel close button.
|
|
19
|
-
*/
|
|
20
|
-
initialFocus?: ComponentProps<typeof FloatingFocusManager>["initialFocus"];
|
|
21
|
-
/**
|
|
22
|
-
* The background color palette. Options are 'primary', 'secondary', 'tertiary' and 'none'.
|
|
23
|
-
* @default "primary"
|
|
24
|
-
*/
|
|
25
|
-
variant?: "primary" | "secondary" | "tertiary" | "none";
|
|
26
|
-
}
|
|
27
|
-
export declare const SidePanel: import("react").ForwardRefExoticComponent<Omit<SidePanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type ComponentPropsWithRef } from "react";
|
|
2
|
-
export interface SidePanelContentProps extends ComponentPropsWithRef<"div"> {
|
|
3
|
-
}
|
|
4
|
-
export declare const SidePanelContent: import("react").ForwardRefExoticComponent<Omit<SidePanelContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type ComponentPropsWithRef } from "react";
|
|
2
|
-
export interface SidePanelHeaderProps extends ComponentPropsWithRef<"div"> {
|
|
3
|
-
}
|
|
4
|
-
export declare const SidePanelHeader: import("react").ForwardRefExoticComponent<Omit<SidePanelHeaderProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
2
|
-
export interface SidePanelProviderProps {
|
|
3
|
-
/**
|
|
4
|
-
* Whether the panel is open.
|
|
5
|
-
*/
|
|
6
|
-
open?: boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Default open state when initially rendered.
|
|
9
|
-
*/
|
|
10
|
-
defaultOpen?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Callback when open state changes.
|
|
13
|
-
*/
|
|
14
|
-
onOpenChange?: (open: boolean) => void;
|
|
15
|
-
/**
|
|
16
|
-
* SidePanelProvider children, should include SidePanel and SidePanelTrigger.
|
|
17
|
-
*/
|
|
18
|
-
children: ReactNode;
|
|
19
|
-
}
|
|
20
|
-
export declare function SidePanelProvider(props: SidePanelProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type TextProps } from "@salt-ds/core";
|
|
2
|
-
export interface SidePanelTitleProps extends TextProps<"div"> {
|
|
3
|
-
}
|
|
4
|
-
export declare const SidePanelTitle: import("react").ForwardRefExoticComponent<Omit<SidePanelTitleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type ComponentPropsWithoutRef } from "react";
|
|
2
|
-
export interface SidePanelTriggerProps extends ComponentPropsWithoutRef<"button"> {
|
|
3
|
-
}
|
|
4
|
-
export declare const SidePanelTrigger: import("react").ForwardRefExoticComponent<SidePanelTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from "./SidePanel";
|
|
2
|
-
export * from "./SidePanelCloseButton";
|
|
3
|
-
export * from "./SidePanelContent";
|
|
4
|
-
export * from "./SidePanelHeader";
|
|
5
|
-
export * from "./SidePanelProvider";
|
|
6
|
-
export * from "./SidePanelTitle";
|
|
7
|
-
export * from "./SidePanelTrigger";
|
|
8
|
-
export * from "./useSidePanel";
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { FloatingRootContext } from "@floating-ui/react";
|
|
2
|
-
import { type Dispatch, type SetStateAction } from "react";
|
|
3
|
-
export interface SidePanelContextValue {
|
|
4
|
-
/**
|
|
5
|
-
* Whether the side panel is currently open.
|
|
6
|
-
*/
|
|
7
|
-
openState: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* The floating-ui root context shared between the trigger and the panel.
|
|
10
|
-
* Coordinates interactions (click, dismiss, role) across both elements.
|
|
11
|
-
*/
|
|
12
|
-
floatingRootContext: FloatingRootContext;
|
|
13
|
-
/**
|
|
14
|
-
* Ref setter for the panel element.
|
|
15
|
-
* Registers the panel DOM node with floating-ui.
|
|
16
|
-
*/
|
|
17
|
-
setFloating: Dispatch<SetStateAction<HTMLDivElement | null>>;
|
|
18
|
-
/**
|
|
19
|
-
* Ref setter for the reference (trigger) element.
|
|
20
|
-
* Registers the trigger DOM node with floating-ui for focus return.
|
|
21
|
-
*/
|
|
22
|
-
setReference: Dispatch<SetStateAction<HTMLElement | null>>;
|
|
23
|
-
/**
|
|
24
|
-
* Sets the open state of the panel.
|
|
25
|
-
* Called by the close button in SidePanelHeader, or any consumer that needs to close the panel.
|
|
26
|
-
*/
|
|
27
|
-
setOpen: (open: boolean) => void;
|
|
28
|
-
/**
|
|
29
|
-
* Side panel id used for aria-controls on the trigger.
|
|
30
|
-
*/
|
|
31
|
-
panelId?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Registers or clears the side panel id used for aria-controls/id linkage.
|
|
34
|
-
*/
|
|
35
|
-
setPanelId: Dispatch<SetStateAction<string | undefined>>;
|
|
36
|
-
/**
|
|
37
|
-
* The auto-generated id placed on SidePanelTitle.
|
|
38
|
-
* Used for aria-labelledby on the panel region and the scrollable body.
|
|
39
|
-
*/
|
|
40
|
-
titleId?: string;
|
|
41
|
-
/**
|
|
42
|
-
* Registers the title id from SidePanelTitle back to the context
|
|
43
|
-
* so that SidePanel and SidePanelContent can use it for aria-labelledby.
|
|
44
|
-
*/
|
|
45
|
-
setTitleId: Dispatch<SetStateAction<string | undefined>>;
|
|
46
|
-
/**
|
|
47
|
-
* Edge the panel is anchored to.
|
|
48
|
-
*/
|
|
49
|
-
position?: "right" | "left";
|
|
50
|
-
/**
|
|
51
|
-
* Registers the position from SidePanel back to the context.
|
|
52
|
-
*/
|
|
53
|
-
setPosition: Dispatch<SetStateAction<"right" | "left" | undefined>>;
|
|
54
|
-
}
|
|
55
|
-
export declare const SidePanelContext: import("react").Context<SidePanelContextValue>;
|
|
56
|
-
export declare function useSidePanelContext(): SidePanelContextValue;
|