@smwb/ui-react 2.4.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/clickAwayListener/clickAwayListener.js +19 -14
- package/dist/components/clickAwayListener/clickAwayListener.js.map +1 -1
- package/dist/components/dataDisplay/treeView/treeView.d.ts +5 -2
- package/dist/components/dataDisplay/treeView/treeView.js +78 -75
- package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/components/feedBack/modal/modal.js +40 -38
- package/dist/components/feedBack/modal/modal.js.map +1 -1
- package/dist/components/inputs/datePicker/datePicker.js +13 -12
- package/dist/components/inputs/datePicker/datePicker.js.map +1 -1
- package/dist/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
- package/dist/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
- package/dist/components/inputs/selectField/dropdownMenu.js +7 -6
- package/dist/components/inputs/selectField/dropdownMenu.js.map +1 -1
- package/dist/components/inputs/timePicker/timePicker.js +16 -15
- package/dist/components/inputs/timePicker/timePicker.js.map +1 -1
- package/dist/components/layout/sheet/sheet.js +102 -92
- package/dist/components/layout/sheet/sheet.js.map +1 -1
- package/dist/headless/components/clickAwayListener/clickAwayListener.js +19 -14
- package/dist/headless/components/clickAwayListener/clickAwayListener.js.map +1 -1
- package/dist/headless/components/dataDisplay/treeView/treeView.js +78 -75
- package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/headless/components/feedBack/modal/modal.js +42 -40
- package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
- package/dist/headless/components/inputs/datePicker/datePicker.js +13 -12
- package/dist/headless/components/inputs/datePicker/datePicker.js.map +1 -1
- package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
- package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
- package/dist/headless/components/inputs/selectField/dropdownMenu.js +7 -6
- package/dist/headless/components/inputs/selectField/dropdownMenu.js.map +1 -1
- package/dist/headless/components/inputs/timePicker/timePicker.js +16 -15
- package/dist/headless/components/inputs/timePicker/timePicker.js.map +1 -1
- package/dist/headless/components/layout/sheet/sheet.js +95 -85
- package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
- package/dist/headless/utils/overlayLayer.js +11 -0
- package/dist/headless/utils/overlayLayer.js.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/utils/overlayLayer.d.ts +13 -0
- package/dist/utils/overlayLayer.js +11 -0
- package/dist/utils/overlayLayer.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import { useForkRef as
|
|
1
|
+
import { jsx as T, Fragment as k } from "react/jsx-runtime";
|
|
2
|
+
import y, { useRef as a, useEffect as p } from "react";
|
|
3
|
+
import { useForkRef as P } from "../../hooks/useForkRef.js";
|
|
4
4
|
import { useEventCallback as C } from "../../hooks/useEventCallback.js";
|
|
5
|
+
import { isEventInForeignOverlay as M } from "../../utils/overlayLayer.js";
|
|
5
6
|
function E(t) {
|
|
6
7
|
return t.substring(2).toLowerCase();
|
|
7
8
|
}
|
|
8
|
-
function
|
|
9
|
-
return
|
|
9
|
+
function b(t, u) {
|
|
10
|
+
return u.documentElement.clientWidth < t.clientX || u.documentElement.clientHeight < t.clientY;
|
|
10
11
|
}
|
|
11
12
|
function A({
|
|
12
13
|
children: t,
|
|
13
|
-
disableReactTree:
|
|
14
|
+
disableReactTree: u = !1,
|
|
14
15
|
mouseEvent: n = "onMouseUp",
|
|
15
16
|
onClickAway: L,
|
|
16
17
|
touchEvent: r = "onTouchEnd",
|
|
17
18
|
enabled: v = !0
|
|
18
19
|
}) {
|
|
19
|
-
const f = a(!1),
|
|
20
|
+
const f = a(!1), s = a(null), l = a(!1), d = a(!1);
|
|
20
21
|
p(() => (setTimeout(() => {
|
|
21
22
|
l.current = !0;
|
|
22
23
|
}, 0), () => {
|
|
23
24
|
l.current = !1;
|
|
24
25
|
}), []);
|
|
25
|
-
const
|
|
26
|
+
const g = P(t.ref, s), o = C((e) => {
|
|
26
27
|
const c = d.current;
|
|
27
|
-
if (d.current = !1, !v || !l.current || !
|
|
28
|
+
if (d.current = !1, !v || !l.current || !s.current || "clientX" in e && b(e, document))
|
|
28
29
|
return;
|
|
29
30
|
if (f.current) {
|
|
30
31
|
f.current = !1;
|
|
@@ -32,17 +33,21 @@ function A({
|
|
|
32
33
|
}
|
|
33
34
|
let i;
|
|
34
35
|
if (e.composedPath)
|
|
35
|
-
i = e.composedPath().indexOf(
|
|
36
|
+
i = e.composedPath().indexOf(s.current) > -1;
|
|
36
37
|
else {
|
|
37
38
|
const R = e.target;
|
|
38
|
-
i = !document.documentElement.contains(R) ||
|
|
39
|
+
i = !document.documentElement.contains(R) || s.current.contains(R);
|
|
40
|
+
}
|
|
41
|
+
if (!i && (u || !c)) {
|
|
42
|
+
if (M(e, s.current))
|
|
43
|
+
return;
|
|
44
|
+
L(e);
|
|
39
45
|
}
|
|
40
|
-
!i && (s || !c) && L(e);
|
|
41
46
|
}), h = (e) => (c) => {
|
|
42
47
|
d.current = !0;
|
|
43
48
|
const i = t.props[e];
|
|
44
49
|
i && i(c);
|
|
45
|
-
}, m = { ref:
|
|
50
|
+
}, m = { ref: g };
|
|
46
51
|
return r !== !1 && (m[r] = h(r)), p(() => {
|
|
47
52
|
if (r !== !1) {
|
|
48
53
|
const e = E(r), c = () => {
|
|
@@ -59,7 +64,7 @@ function A({
|
|
|
59
64
|
document.removeEventListener(e, o);
|
|
60
65
|
};
|
|
61
66
|
}
|
|
62
|
-
}, [o, n]), /* @__PURE__ */
|
|
67
|
+
}, [o, n]), /* @__PURE__ */ T(k, { children: y.cloneElement(t, m) });
|
|
63
68
|
}
|
|
64
69
|
export {
|
|
65
70
|
A as ClickAwayListener
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickAwayListener.js","sources":["../../../src/components/clickAwayListener/clickAwayListener.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useForkRef } from \"../../hooks/useForkRef\";\nimport { useEventCallback } from \"../../hooks/useEventCallback\";\n\ntype ClickAwayMouseEventHandler = \"onClick\" | \"onMouseDown\" | \"onMouseUp\" | \"onPointerDown\" | \"onPointerUp\";\ntype ClickAwayTouchEventHandler = \"onTouchStart\" | \"onTouchEnd\";\n\nfunction mapEventPropToEvent(eventProp: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler) {\n return eventProp.substring(2).toLowerCase() as\n | \"click\"\n | \"mousedown\"\n | \"mouseup\"\n | \"touchstart\"\n | \"touchend\"\n | \"pointerdown\"\n | \"pointerup\";\n}\n\nfunction clickedRootScrollbar(event: MouseEvent, doc: Document) {\n return doc.documentElement.clientWidth < event.clientX || doc.documentElement.clientHeight < event.clientY;\n}\n\nexport interface ClickAwayListenerProps {\n children: React.ReactElement;\n disableReactTree?: boolean;\n mouseEvent?: ClickAwayMouseEventHandler | false;\n onClickAway: (event: MouseEvent | TouchEvent) => void;\n touchEvent?: ClickAwayTouchEventHandler | false;\n /** When false, the listener is inert without unmounting the child. */\n enabled?: boolean;\n}\n\nexport function ClickAwayListener({\n children,\n disableReactTree = false,\n mouseEvent = \"onMouseUp\",\n onClickAway,\n touchEvent = \"onTouchEnd\",\n enabled = true,\n}: ClickAwayListenerProps) {\n const movedRef = useRef(false);\n const nodeRef = useRef<Element>(null);\n const activatedRef = useRef(false);\n const syntheticEventRef = useRef(false);\n\n useEffect(() => {\n // https://github.com/facebook/react/issues/20074\n setTimeout(() => {\n activatedRef.current = true;\n }, 0);\n return () => {\n activatedRef.current = false;\n };\n }, []);\n\n const handleRef = useForkRef((children as React.ReactElement & { ref: React.Ref<Element> }).ref, nodeRef);\n\n const handleClickAway = useEventCallback((event: MouseEvent | TouchEvent) => {\n const insideReactTree = syntheticEventRef.current;\n syntheticEventRef.current = false;\n\n if (\n !enabled ||\n !activatedRef.current ||\n !nodeRef.current ||\n (\"clientX\" in event && clickedRootScrollbar(event, document))\n ) {\n return;\n }\n\n if (movedRef.current) {\n movedRef.current = false;\n return;\n }\n\n let insideDOM;\n\n if (event.composedPath) {\n insideDOM = event.composedPath().indexOf(nodeRef.current) > -1;\n } else {\n const target = event.target as HTMLElement;\n\n insideDOM = !document.documentElement.contains(target) || nodeRef.current.contains(target);\n }\n\n if (!insideDOM && (disableReactTree || !insideReactTree)) {\n onClickAway(event);\n }\n });\n\n const createHandleSynthetic = (handlerName: string) => (event: React.SyntheticEvent) => {\n syntheticEventRef.current = true;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const childrenPropsHandler = children.props[handlerName];\n\n if (childrenPropsHandler) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n childrenPropsHandler(event);\n }\n };\n\n const childrenProps: { ref: React.Ref<Element> } & Pick<\n React.DOMAttributes<Element>,\n ClickAwayMouseEventHandler | ClickAwayTouchEventHandler\n > = { ref: handleRef };\n\n if (touchEvent !== false) {\n childrenProps[touchEvent] = createHandleSynthetic(touchEvent);\n }\n\n useEffect(() => {\n if (touchEvent !== false) {\n const mappedTouchEvent = mapEventPropToEvent(touchEvent);\n\n const handleTouchMove = () => {\n movedRef.current = true;\n };\n\n document.addEventListener(mappedTouchEvent, handleClickAway);\n document.addEventListener(\"touchmove\", handleTouchMove);\n\n return () => {\n document.removeEventListener(mappedTouchEvent, handleClickAway);\n document.removeEventListener(\"touchmove\", handleTouchMove);\n };\n }\n\n return undefined;\n }, [handleClickAway, touchEvent]);\n\n if (mouseEvent !== false) {\n childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent);\n }\n\n useEffect(() => {\n if (mouseEvent !== false) {\n const mappedMouseEvent = mapEventPropToEvent(mouseEvent);\n\n document.addEventListener(mappedMouseEvent, handleClickAway);\n\n return () => {\n document.removeEventListener(mappedMouseEvent, handleClickAway);\n };\n }\n\n return undefined;\n }, [handleClickAway, mouseEvent]);\n\n return <>{React.cloneElement(children, childrenProps)}</>;\n}\n"],"names":["mapEventPropToEvent","eventProp","clickedRootScrollbar","event","doc","ClickAwayListener","children","disableReactTree","mouseEvent","onClickAway","touchEvent","enabled","movedRef","useRef","nodeRef","activatedRef","syntheticEventRef","useEffect","handleRef","useForkRef","handleClickAway","useEventCallback","insideReactTree","insideDOM","target","createHandleSynthetic","handlerName","childrenPropsHandler","childrenProps","mappedTouchEvent","handleTouchMove","mappedMouseEvent","jsx","Fragment","React"],"mappings":"
|
|
1
|
+
{"version":3,"file":"clickAwayListener.js","sources":["../../../src/components/clickAwayListener/clickAwayListener.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useForkRef } from \"../../hooks/useForkRef\";\nimport { useEventCallback } from \"../../hooks/useEventCallback\";\nimport { isEventInForeignOverlay } from \"../../utils/overlayLayer\";\n\ntype ClickAwayMouseEventHandler = \"onClick\" | \"onMouseDown\" | \"onMouseUp\" | \"onPointerDown\" | \"onPointerUp\";\ntype ClickAwayTouchEventHandler = \"onTouchStart\" | \"onTouchEnd\";\n\nfunction mapEventPropToEvent(eventProp: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler) {\n return eventProp.substring(2).toLowerCase() as\n | \"click\"\n | \"mousedown\"\n | \"mouseup\"\n | \"touchstart\"\n | \"touchend\"\n | \"pointerdown\"\n | \"pointerup\";\n}\n\nfunction clickedRootScrollbar(event: MouseEvent, doc: Document) {\n return doc.documentElement.clientWidth < event.clientX || doc.documentElement.clientHeight < event.clientY;\n}\n\nexport interface ClickAwayListenerProps {\n children: React.ReactElement;\n disableReactTree?: boolean;\n mouseEvent?: ClickAwayMouseEventHandler | false;\n onClickAway: (event: MouseEvent | TouchEvent) => void;\n touchEvent?: ClickAwayTouchEventHandler | false;\n /** When false, the listener is inert without unmounting the child. */\n enabled?: boolean;\n}\n\nexport function ClickAwayListener({\n children,\n disableReactTree = false,\n mouseEvent = \"onMouseUp\",\n onClickAway,\n touchEvent = \"onTouchEnd\",\n enabled = true,\n}: ClickAwayListenerProps) {\n const movedRef = useRef(false);\n const nodeRef = useRef<Element>(null);\n const activatedRef = useRef(false);\n const syntheticEventRef = useRef(false);\n\n useEffect(() => {\n // https://github.com/facebook/react/issues/20074\n setTimeout(() => {\n activatedRef.current = true;\n }, 0);\n return () => {\n activatedRef.current = false;\n };\n }, []);\n\n const handleRef = useForkRef((children as React.ReactElement & { ref: React.Ref<Element> }).ref, nodeRef);\n\n const handleClickAway = useEventCallback((event: MouseEvent | TouchEvent) => {\n const insideReactTree = syntheticEventRef.current;\n syntheticEventRef.current = false;\n\n if (\n !enabled ||\n !activatedRef.current ||\n !nodeRef.current ||\n (\"clientX\" in event && clickedRootScrollbar(event, document))\n ) {\n return;\n }\n\n if (movedRef.current) {\n movedRef.current = false;\n return;\n }\n\n let insideDOM;\n\n if (event.composedPath) {\n insideDOM = event.composedPath().indexOf(nodeRef.current) > -1;\n } else {\n const target = event.target as HTMLElement;\n\n insideDOM = !document.documentElement.contains(target) || nodeRef.current.contains(target);\n }\n\n if (!insideDOM && (disableReactTree || !insideReactTree)) {\n // Interactions inside a portaled overlay layer above the child (modal,\n // dropdown, picker…) are not \"away\" from the child.\n if (isEventInForeignOverlay(event, nodeRef.current)) {\n return;\n }\n onClickAway(event);\n }\n });\n\n const createHandleSynthetic = (handlerName: string) => (event: React.SyntheticEvent) => {\n syntheticEventRef.current = true;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const childrenPropsHandler = children.props[handlerName];\n\n if (childrenPropsHandler) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n childrenPropsHandler(event);\n }\n };\n\n const childrenProps: { ref: React.Ref<Element> } & Pick<\n React.DOMAttributes<Element>,\n ClickAwayMouseEventHandler | ClickAwayTouchEventHandler\n > = { ref: handleRef };\n\n if (touchEvent !== false) {\n childrenProps[touchEvent] = createHandleSynthetic(touchEvent);\n }\n\n useEffect(() => {\n if (touchEvent !== false) {\n const mappedTouchEvent = mapEventPropToEvent(touchEvent);\n\n const handleTouchMove = () => {\n movedRef.current = true;\n };\n\n document.addEventListener(mappedTouchEvent, handleClickAway);\n document.addEventListener(\"touchmove\", handleTouchMove);\n\n return () => {\n document.removeEventListener(mappedTouchEvent, handleClickAway);\n document.removeEventListener(\"touchmove\", handleTouchMove);\n };\n }\n\n return undefined;\n }, [handleClickAway, touchEvent]);\n\n if (mouseEvent !== false) {\n childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent);\n }\n\n useEffect(() => {\n if (mouseEvent !== false) {\n const mappedMouseEvent = mapEventPropToEvent(mouseEvent);\n\n document.addEventListener(mappedMouseEvent, handleClickAway);\n\n return () => {\n document.removeEventListener(mappedMouseEvent, handleClickAway);\n };\n }\n\n return undefined;\n }, [handleClickAway, mouseEvent]);\n\n return <>{React.cloneElement(children, childrenProps)}</>;\n}\n"],"names":["mapEventPropToEvent","eventProp","clickedRootScrollbar","event","doc","ClickAwayListener","children","disableReactTree","mouseEvent","onClickAway","touchEvent","enabled","movedRef","useRef","nodeRef","activatedRef","syntheticEventRef","useEffect","handleRef","useForkRef","handleClickAway","useEventCallback","insideReactTree","insideDOM","target","isEventInForeignOverlay","createHandleSynthetic","handlerName","childrenPropsHandler","childrenProps","mappedTouchEvent","handleTouchMove","mappedMouseEvent","jsx","Fragment","React"],"mappings":";;;;;AAQA,SAASA,EAAoBC,GAAoE;AAC/F,SAAOA,EAAU,UAAU,CAAC,EAAE,YAAA;AAQhC;AAEA,SAASC,EAAqBC,GAAmBC,GAAe;AAC9D,SAAOA,EAAI,gBAAgB,cAAcD,EAAM,WAAWC,EAAI,gBAAgB,eAAeD,EAAM;AACrG;AAYO,SAASE,EAAkB;AAAA,EAChC,UAAAC;AAAA,EACA,kBAAAC,IAAmB;AAAA,EACnB,YAAAC,IAAa;AAAA,EACb,aAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,SAAAC,IAAU;AACZ,GAA2B;AACzB,QAAMC,IAAWC,EAAO,EAAK,GACvBC,IAAUD,EAAgB,IAAI,GAC9BE,IAAeF,EAAO,EAAK,GAC3BG,IAAoBH,EAAO,EAAK;AAEtC,EAAAI,EAAU,OAER,WAAW,MAAM;AACf,IAAAF,EAAa,UAAU;AAAA,EACzB,GAAG,CAAC,GACG,MAAM;AACX,IAAAA,EAAa,UAAU;AAAA,EACzB,IACC,CAAA,CAAE;AAEL,QAAMG,IAAYC,EAAYb,EAA8D,KAAKQ,CAAO,GAElGM,IAAkBC,EAAiB,CAAClB,MAAmC;AAC3E,UAAMmB,IAAkBN,EAAkB;AAG1C,QAFAA,EAAkB,UAAU,IAG1B,CAACL,KACD,CAACI,EAAa,WACd,CAACD,EAAQ,WACR,aAAaX,KAASD,EAAqBC,GAAO,QAAQ;AAE3D;AAGF,QAAIS,EAAS,SAAS;AACpB,MAAAA,EAAS,UAAU;AACnB;AAAA,IACF;AAEA,QAAIW;AAEJ,QAAIpB,EAAM;AACR,MAAAoB,IAAYpB,EAAM,aAAA,EAAe,QAAQW,EAAQ,OAAO,IAAI;AAAA,SACvD;AACL,YAAMU,IAASrB,EAAM;AAErB,MAAAoB,IAAY,CAAC,SAAS,gBAAgB,SAASC,CAAM,KAAKV,EAAQ,QAAQ,SAASU,CAAM;AAAA,IAC3F;AAEA,QAAI,CAACD,MAAchB,KAAoB,CAACe,IAAkB;AAGxD,UAAIG,EAAwBtB,GAAOW,EAAQ,OAAO;AAChD;AAEF,MAAAL,EAAYN,CAAK;AAAA,IACnB;AAAA,EACF,CAAC,GAEKuB,IAAwB,CAACC,MAAwB,CAACxB,MAAgC;AACtF,IAAAa,EAAkB,UAAU;AAG5B,UAAMY,IAAuBtB,EAAS,MAAMqB,CAAW;AAEvD,IAAIC,KAEFA,EAAqBzB,CAAK;AAAA,EAE9B,GAEM0B,IAGF,EAAE,KAAKX,EAAA;AAEX,SAAIR,MAAe,OACjBmB,EAAcnB,CAAU,IAAIgB,EAAsBhB,CAAU,IAG9DO,EAAU,MAAM;AACd,QAAIP,MAAe,IAAO;AACxB,YAAMoB,IAAmB9B,EAAoBU,CAAU,GAEjDqB,IAAkB,MAAM;AAC5B,QAAAnB,EAAS,UAAU;AAAA,MACrB;AAEA,sBAAS,iBAAiBkB,GAAkBV,CAAe,GAC3D,SAAS,iBAAiB,aAAaW,CAAe,GAE/C,MAAM;AACX,iBAAS,oBAAoBD,GAAkBV,CAAe,GAC9D,SAAS,oBAAoB,aAAaW,CAAe;AAAA,MAC3D;AAAA,IACF;AAAA,EAGF,GAAG,CAACX,GAAiBV,CAAU,CAAC,GAE5BF,MAAe,OACjBqB,EAAcrB,CAAU,IAAIkB,EAAsBlB,CAAU,IAG9DS,EAAU,MAAM;AACd,QAAIT,MAAe,IAAO;AACxB,YAAMwB,IAAmBhC,EAAoBQ,CAAU;AAEvD,sBAAS,iBAAiBwB,GAAkBZ,CAAe,GAEpD,MAAM;AACX,iBAAS,oBAAoBY,GAAkBZ,CAAe;AAAA,MAChE;AAAA,IACF;AAAA,EAGF,GAAG,CAACA,GAAiBZ,CAAU,CAAC,GAEzB,gBAAAyB,EAAAC,GAAA,EAAG,UAAAC,EAAM,aAAa7B,GAAUuB,CAAa,GAAE;AACxD;"}
|
|
@@ -24,8 +24,11 @@ export interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
24
24
|
selected?: string[];
|
|
25
25
|
/** Initially selected node ids (uncontrolled). */
|
|
26
26
|
defaultSelected?: string[];
|
|
27
|
-
/** Called with the next selected ids. */
|
|
28
|
-
onSelectedChange?: (selected: string[]
|
|
27
|
+
/** Called with the next selected ids plus, for user toggles, the node that just changed. */
|
|
28
|
+
onSelectedChange?: (selected: string[], changed?: {
|
|
29
|
+
id: string;
|
|
30
|
+
selected: boolean;
|
|
31
|
+
}) => void;
|
|
29
32
|
/** Enables label click selection. */
|
|
30
33
|
selectable?: boolean;
|
|
31
34
|
/** Renders a checkbox per node bound to selection. */
|
|
@@ -1,116 +1,119 @@
|
|
|
1
|
-
import { jsx as n, jsxs as
|
|
1
|
+
import { jsx as n, jsxs as b } from "react/jsx-runtime";
|
|
2
2
|
import '../../../assets/styles/less/components/treeView/treeView.entry.css';/* empty css */
|
|
3
|
-
import { forwardRef as
|
|
4
|
-
import
|
|
5
|
-
import { Icon as
|
|
6
|
-
import { useControllableState as
|
|
7
|
-
const
|
|
8
|
-
className:
|
|
9
|
-
listIcon:
|
|
10
|
-
nodeIcon:
|
|
11
|
-
data:
|
|
12
|
-
expanded:
|
|
13
|
-
defaultExpanded:
|
|
14
|
-
onExpandedChange:
|
|
15
|
-
selected:
|
|
16
|
-
defaultSelected:
|
|
17
|
-
onSelectedChange:
|
|
18
|
-
selectable:
|
|
19
|
-
checkboxes:
|
|
20
|
-
renderLabel:
|
|
21
|
-
loadChildren:
|
|
22
|
-
...
|
|
23
|
-
},
|
|
24
|
-
const [o,
|
|
25
|
-
value: T,
|
|
26
|
-
defaultValue: K,
|
|
27
|
-
onChange: M
|
|
28
|
-
}), [C, J] = O({
|
|
3
|
+
import { forwardRef as v, useState as D, useRef as I, useMemo as ee } from "react";
|
|
4
|
+
import O from "clsx";
|
|
5
|
+
import { Icon as N } from "../../base/icon/icon.js";
|
|
6
|
+
import { useControllableState as K } from "../../../hooks/useControllableState.js";
|
|
7
|
+
const oe = v(function({
|
|
8
|
+
className: M,
|
|
9
|
+
listIcon: k = "draft",
|
|
10
|
+
nodeIcon: a = { closed: "folder", opened: "folder_open" },
|
|
11
|
+
data: x = [],
|
|
12
|
+
expanded: P,
|
|
13
|
+
defaultExpanded: S = [],
|
|
14
|
+
onExpandedChange: q,
|
|
15
|
+
selected: B,
|
|
16
|
+
defaultSelected: F = [],
|
|
17
|
+
onSelectedChange: d,
|
|
18
|
+
selectable: f = !1,
|
|
19
|
+
checkboxes: u = !1,
|
|
20
|
+
renderLabel: m,
|
|
21
|
+
loadChildren: _,
|
|
22
|
+
...G
|
|
23
|
+
}, H) {
|
|
24
|
+
const [o, J] = D({}), [y, L] = D([]), [z, C] = K({
|
|
29
25
|
value: P,
|
|
30
|
-
defaultValue:
|
|
31
|
-
onChange:
|
|
32
|
-
}),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
26
|
+
defaultValue: S,
|
|
27
|
+
onChange: q
|
|
28
|
+
}), p = I(), [h, Q] = K({
|
|
29
|
+
value: B,
|
|
30
|
+
defaultValue: F,
|
|
31
|
+
onChange: (e) => {
|
|
32
|
+
const t = p.current;
|
|
33
|
+
p.current = void 0, d == null || d(e, t);
|
|
34
|
+
}
|
|
35
|
+
}), U = (e) => {
|
|
36
|
+
C((t) => t.includes(e) ? t.filter((s) => s !== e) : [...t, e]);
|
|
37
|
+
}, R = (e, t) => {
|
|
38
|
+
C((s) => {
|
|
39
|
+
const l = s.includes(e);
|
|
40
|
+
return t && !l ? [...s, e] : !t && l ? s.filter((w) => w !== e) : s;
|
|
38
41
|
});
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
!
|
|
43
|
-
|
|
42
|
+
}, V = (e) => {
|
|
43
|
+
p.current = { id: e, selected: !h.includes(e) }, Q((t) => t.includes(e) ? t.filter((s) => s !== e) : [...t, e]);
|
|
44
|
+
}, E = (e, t) => {
|
|
45
|
+
!_ || o[t] || e.children && e.children.length > 0 || (L((s) => s.includes(t) ? s : [...s, t]), _(e, t).then((s) => {
|
|
46
|
+
J((l) => ({ ...l, [t]: s }));
|
|
44
47
|
}).finally(() => {
|
|
45
|
-
|
|
48
|
+
L((s) => s.filter((l) => l !== t));
|
|
46
49
|
}));
|
|
47
|
-
},
|
|
48
|
-
var
|
|
49
|
-
const
|
|
50
|
-
i && (
|
|
51
|
-
},
|
|
52
|
-
|
|
50
|
+
}, T = (e, t) => {
|
|
51
|
+
var j, A;
|
|
52
|
+
const s = (j = e.id) != null ? j : t, l = (A = e.children) != null ? A : o[s], w = !!_ && (e.hasChildren || !!o[s]), i = !!l && l.length > 0 || w, c = z.includes(s), g = h.includes(s), X = y.includes(s), $ = () => {
|
|
53
|
+
i && (c || E(e, s), U(s)), f && V(s);
|
|
54
|
+
}, Y = (r) => {
|
|
55
|
+
r.key === "Enter" || r.key === " " ? (r.preventDefault(), $()) : r.key === "ArrowRight" && i ? (E(e, s), R(s, !0)) : r.key === "ArrowLeft" && i && R(s, !1);
|
|
53
56
|
};
|
|
54
|
-
return /* @__PURE__ */
|
|
57
|
+
return /* @__PURE__ */ b(
|
|
55
58
|
"div",
|
|
56
59
|
{
|
|
57
|
-
className:
|
|
60
|
+
className: O("smwb-tree__node", { "smwb-tree__node_selected": g }),
|
|
58
61
|
role: "treeitem",
|
|
59
|
-
"aria-expanded": i ?
|
|
60
|
-
"aria-selected":
|
|
62
|
+
"aria-expanded": i ? c : void 0,
|
|
63
|
+
"aria-selected": f || u ? g : void 0,
|
|
61
64
|
children: [
|
|
62
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ b(
|
|
63
66
|
"span",
|
|
64
67
|
{
|
|
65
68
|
className: "smwb-tree__node__content",
|
|
66
|
-
onClick:
|
|
67
|
-
onKeyDown:
|
|
69
|
+
onClick: $,
|
|
70
|
+
onKeyDown: Y,
|
|
68
71
|
tabIndex: 0,
|
|
69
72
|
role: "button",
|
|
70
73
|
children: [
|
|
71
|
-
|
|
74
|
+
u && /* @__PURE__ */ n(
|
|
72
75
|
"input",
|
|
73
76
|
{
|
|
74
77
|
type: "checkbox",
|
|
75
78
|
className: "smwb-tree__node__checkbox",
|
|
76
|
-
checked:
|
|
77
|
-
onClick: (
|
|
78
|
-
onChange: () =>
|
|
79
|
-
"aria-label":
|
|
79
|
+
checked: g,
|
|
80
|
+
onClick: (r) => r.stopPropagation(),
|
|
81
|
+
onChange: () => V(s),
|
|
82
|
+
"aria-label": e.label
|
|
80
83
|
}
|
|
81
84
|
),
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
i &&
|
|
84
|
-
|
|
85
|
+
/* @__PURE__ */ b("span", { className: "smwb-tree__node__label", children: [
|
|
86
|
+
i && c ? /* @__PURE__ */ n(N, { name: a == null ? void 0 : a.opened, fill: 1, size: 20 }) : i ? /* @__PURE__ */ n(N, { name: a == null ? void 0 : a.closed, fill: 1, size: 20 }) : /* @__PURE__ */ n(N, { name: k, size: 20 }),
|
|
87
|
+
m ? m(e, s) : e.label
|
|
85
88
|
] })
|
|
86
89
|
]
|
|
87
90
|
}
|
|
88
91
|
),
|
|
89
|
-
i &&
|
|
92
|
+
i && c && /* @__PURE__ */ n("div", { role: "group", children: X && !l ? /* @__PURE__ */ n("div", { className: "smwb-tree__node__loading", role: "status", children: "Загрузка…" }) : l == null ? void 0 : l.map((r, Z) => T(r, `${t}.${Z}`)) })
|
|
90
93
|
]
|
|
91
94
|
},
|
|
92
|
-
|
|
95
|
+
s
|
|
93
96
|
);
|
|
94
|
-
},
|
|
95
|
-
() =>
|
|
97
|
+
}, W = ee(
|
|
98
|
+
() => x.map((e, t) => T(e, `${t}`)),
|
|
96
99
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
97
100
|
[
|
|
98
|
-
b,
|
|
99
101
|
x,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
z,
|
|
103
|
+
h,
|
|
102
104
|
f,
|
|
103
|
-
w,
|
|
104
|
-
r,
|
|
105
105
|
u,
|
|
106
|
+
k,
|
|
107
|
+
a,
|
|
108
|
+
m,
|
|
106
109
|
o,
|
|
107
|
-
|
|
110
|
+
y
|
|
108
111
|
]
|
|
109
112
|
);
|
|
110
|
-
return /* @__PURE__ */ n("div", { "data-testid": "tree-view", ...
|
|
113
|
+
return /* @__PURE__ */ n("div", { "data-testid": "tree-view", ...G, ref: H, role: "tree", className: O("smwb-tree", M), children: W.map((e, t) => /* @__PURE__ */ n("div", { className: "smwb-tree__wrapper", role: "presentation", children: e }, t)) });
|
|
111
114
|
});
|
|
112
115
|
export {
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
oe as TreeView,
|
|
117
|
+
oe as default
|
|
115
118
|
};
|
|
116
119
|
//# sourceMappingURL=treeView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeView.js","sources":["../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import React, { forwardRef, KeyboardEvent, ReactNode, useMemo, useState } from \"react\";\nimport cn from \"clsx\";\nimport Icon from \"../../base/icon/icon\";\nimport { useControllableState } from \"../../../hooks/useControllableState\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: {\n opened?: string;\n closed?: string;\n };\n listIcon?: string;\n data: ITreeNodeItem[];\n /** Controlled list of expanded node ids. */\n expanded?: string[];\n /** Initially expanded node ids (uncontrolled). */\n defaultExpanded?: string[];\n /** Called with the next expanded ids. */\n onExpandedChange?: (expanded: string[]) => void;\n /** Controlled list of selected node ids. */\n selected?: string[];\n /** Initially selected node ids (uncontrolled). */\n defaultSelected?: string[];\n /** Called with the next selected ids. */\n onSelectedChange?: (selected: string[]) => void;\n /** Enables label click selection. */\n selectable?: boolean;\n /** Renders a checkbox per node bound to selection. */\n checkboxes?: boolean;\n /** Custom node renderer. */\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => ReactNode;\n /** Lazily resolves children the first time a node is expanded. */\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n}\n\nexport const TreeView = forwardRef<HTMLDivElement, TreeViewProps>(function TreeView(\n {\n className,\n listIcon = \"draft\",\n nodeIcon = { closed: \"folder\", opened: \"folder_open\" },\n data = [],\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n selected,\n defaultSelected = [],\n onSelectedChange,\n selectable = false,\n checkboxes = false,\n renderLabel,\n loadChildren,\n ...props\n },\n ref\n) {\n const [loadedChildren, setLoadedChildren] = useState<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = useState<string[]>([]);\n const [expandedIds, setExpandedIds] = useControllableState<string[]>({\n value: expanded,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const [selectedIds, setSelectedIds] = useControllableState<string[]>({\n value: selected,\n defaultValue: defaultSelected,\n onChange: onSelectedChange,\n });\n\n const toggleExpanded = (id: string) => {\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const setOpen = (id: string, open: boolean) => {\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n };\n\n const toggleSelected = (id: string) => {\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string) => {\n if (!loadChildren || loadedChildren[nodeId] || (item.children && item.children.length > 0)) {\n return;\n }\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void loadChildren(item, nodeId)\n .then((children) => {\n setLoadedChildren((prev) => ({ ...prev, [nodeId]: children }));\n })\n .finally(() => {\n setLoadingIds((prev) => prev.filter((x) => x !== nodeId));\n });\n };\n\n const renderNode = (item: ITreeNodeItem, path: string): ReactNode => {\n const nodeId = item.id ?? path;\n const resolvedChildren = item.children ?? loadedChildren[nodeId];\n const isLazy = !!loadChildren && (item.hasChildren || !!loadedChildren[nodeId]);\n const hasChildNodes = (!!resolvedChildren && resolvedChildren.length > 0) || isLazy;\n const isOpen = expandedIds.includes(nodeId);\n const isSelected = selectedIds.includes(nodeId);\n const isLoading = loadingIds.includes(nodeId);\n\n const onLabelClick = () => {\n if (hasChildNodes) {\n if (!isOpen) {\n ensureLoaded(item, nodeId);\n }\n toggleExpanded(nodeId);\n }\n if (selectable) {\n toggleSelected(nodeId);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onLabelClick();\n } else if (event.key === \"ArrowRight\" && hasChildNodes) {\n ensureLoaded(item, nodeId);\n setOpen(nodeId, true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes) {\n setOpen(nodeId, false);\n }\n };\n\n return (\n <div\n className={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected })}\n role=\"treeitem\"\n aria-expanded={hasChildNodes ? isOpen : undefined}\n aria-selected={selectable || checkboxes ? isSelected : undefined}\n key={nodeId}\n >\n <span\n className=\"smwb-tree__node__content\"\n onClick={onLabelClick}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"button\"\n >\n {checkboxes && (\n <input\n type=\"checkbox\"\n className=\"smwb-tree__node__checkbox\"\n checked={isSelected}\n onClick={(e) => e.stopPropagation()}\n onChange={() => toggleSelected(nodeId)}\n aria-label={item.label}\n />\n )}\n <span className=\"smwb-tree__node__label\">\n {hasChildNodes && isOpen ? (\n <Icon name={nodeIcon?.opened as string} fill={1} size={20} />\n ) : hasChildNodes ? (\n <Icon name={nodeIcon?.closed as string} fill={1} size={20} />\n ) : (\n <Icon name={listIcon} size={20} />\n )}\n {renderLabel ? renderLabel(item, nodeId) : item.label}\n </span>\n </span>\n {hasChildNodes && isOpen && (\n <div role=\"group\">\n {isLoading && !resolvedChildren ? (\n <div className=\"smwb-tree__node__loading\" role=\"status\">\n Загрузка…\n </div>\n ) : (\n resolvedChildren?.map((c, idx) => renderNode(c, `${path}.${idx}`))\n )}\n </div>\n )}\n </div>\n );\n };\n\n const tree = useMemo(\n () => data.map((d, idx) => renderNode(d, `${idx}`)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n data,\n expandedIds,\n selectedIds,\n selectable,\n checkboxes,\n listIcon,\n nodeIcon,\n renderLabel,\n loadedChildren,\n loadingIds,\n ]\n );\n\n return (\n <div data-testid=\"tree-view\" {...props} ref={ref} role=\"tree\" className={cn(\"smwb-tree\", className)}>\n {tree.map((node, idx) => (\n <div className=\"smwb-tree__wrapper\" key={idx} role=\"presentation\">\n {node}\n </div>\n ))}\n </div>\n );\n});\n\nexport default TreeView;\n"],"names":["TreeView","forwardRef","className","listIcon","nodeIcon","data","expanded","defaultExpanded","onExpandedChange","selected","defaultSelected","onSelectedChange","selectable","checkboxes","renderLabel","loadChildren","props","ref","loadedChildren","setLoadedChildren","useState","loadingIds","setLoadingIds","expandedIds","setExpandedIds","useControllableState","selectedIds","setSelectedIds","toggleExpanded","id","prev","x","setOpen","open","has","toggleSelected","ensureLoaded","item","nodeId","children","renderNode","path","_a","resolvedChildren","_b","isLazy","hasChildNodes","isOpen","isSelected","isLoading","onLabelClick","onKeyDown","event","jsxs","cn","jsx","e","Icon","c","idx","tree","useMemo","d","node"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"treeView.js","sources":["../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import React, { forwardRef, KeyboardEvent, ReactNode, useMemo, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport Icon from \"../../base/icon/icon\";\nimport { useControllableState } from \"../../../hooks/useControllableState\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: {\n opened?: string;\n closed?: string;\n };\n listIcon?: string;\n data: ITreeNodeItem[];\n /** Controlled list of expanded node ids. */\n expanded?: string[];\n /** Initially expanded node ids (uncontrolled). */\n defaultExpanded?: string[];\n /** Called with the next expanded ids. */\n onExpandedChange?: (expanded: string[]) => void;\n /** Controlled list of selected node ids. */\n selected?: string[];\n /** Initially selected node ids (uncontrolled). */\n defaultSelected?: string[];\n /** Called with the next selected ids plus, for user toggles, the node that just changed. */\n onSelectedChange?: (selected: string[], changed?: { id: string; selected: boolean }) => void;\n /** Enables label click selection. */\n selectable?: boolean;\n /** Renders a checkbox per node bound to selection. */\n checkboxes?: boolean;\n /** Custom node renderer. */\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => ReactNode;\n /** Lazily resolves children the first time a node is expanded. */\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n}\n\nexport const TreeView = forwardRef<HTMLDivElement, TreeViewProps>(function TreeView(\n {\n className,\n listIcon = \"draft\",\n nodeIcon = { closed: \"folder\", opened: \"folder_open\" },\n data = [],\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n selected,\n defaultSelected = [],\n onSelectedChange,\n selectable = false,\n checkboxes = false,\n renderLabel,\n loadChildren,\n ...props\n },\n ref\n) {\n const [loadedChildren, setLoadedChildren] = useState<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = useState<string[]>([]);\n const [expandedIds, setExpandedIds] = useControllableState<string[]>({\n value: expanded,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const lastToggledRef = useRef<{ id: string; selected: boolean }>();\n const [selectedIds, setSelectedIds] = useControllableState<string[]>({\n value: selected,\n defaultValue: defaultSelected,\n onChange: (next) => {\n // useControllableState calls onChange synchronously from the setter,\n // so lastToggledRef still refers to the toggle that caused this change.\n const changed = lastToggledRef.current;\n lastToggledRef.current = undefined;\n onSelectedChange?.(next, changed);\n },\n });\n\n const toggleExpanded = (id: string) => {\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const setOpen = (id: string, open: boolean) => {\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n };\n\n const toggleSelected = (id: string) => {\n lastToggledRef.current = { id, selected: !selectedIds.includes(id) };\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string) => {\n if (!loadChildren || loadedChildren[nodeId] || (item.children && item.children.length > 0)) {\n return;\n }\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void loadChildren(item, nodeId)\n .then((children) => {\n setLoadedChildren((prev) => ({ ...prev, [nodeId]: children }));\n })\n .finally(() => {\n setLoadingIds((prev) => prev.filter((x) => x !== nodeId));\n });\n };\n\n const renderNode = (item: ITreeNodeItem, path: string): ReactNode => {\n const nodeId = item.id ?? path;\n const resolvedChildren = item.children ?? loadedChildren[nodeId];\n const isLazy = !!loadChildren && (item.hasChildren || !!loadedChildren[nodeId]);\n const hasChildNodes = (!!resolvedChildren && resolvedChildren.length > 0) || isLazy;\n const isOpen = expandedIds.includes(nodeId);\n const isSelected = selectedIds.includes(nodeId);\n const isLoading = loadingIds.includes(nodeId);\n\n const onLabelClick = () => {\n if (hasChildNodes) {\n if (!isOpen) {\n ensureLoaded(item, nodeId);\n }\n toggleExpanded(nodeId);\n }\n if (selectable) {\n toggleSelected(nodeId);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onLabelClick();\n } else if (event.key === \"ArrowRight\" && hasChildNodes) {\n ensureLoaded(item, nodeId);\n setOpen(nodeId, true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes) {\n setOpen(nodeId, false);\n }\n };\n\n return (\n <div\n className={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected })}\n role=\"treeitem\"\n aria-expanded={hasChildNodes ? isOpen : undefined}\n aria-selected={selectable || checkboxes ? isSelected : undefined}\n key={nodeId}\n >\n <span\n className=\"smwb-tree__node__content\"\n onClick={onLabelClick}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"button\"\n >\n {checkboxes && (\n <input\n type=\"checkbox\"\n className=\"smwb-tree__node__checkbox\"\n checked={isSelected}\n onClick={(e) => e.stopPropagation()}\n onChange={() => toggleSelected(nodeId)}\n aria-label={item.label}\n />\n )}\n <span className=\"smwb-tree__node__label\">\n {hasChildNodes && isOpen ? (\n <Icon name={nodeIcon?.opened as string} fill={1} size={20} />\n ) : hasChildNodes ? (\n <Icon name={nodeIcon?.closed as string} fill={1} size={20} />\n ) : (\n <Icon name={listIcon} size={20} />\n )}\n {renderLabel ? renderLabel(item, nodeId) : item.label}\n </span>\n </span>\n {hasChildNodes && isOpen && (\n <div role=\"group\">\n {isLoading && !resolvedChildren ? (\n <div className=\"smwb-tree__node__loading\" role=\"status\">\n Загрузка…\n </div>\n ) : (\n resolvedChildren?.map((c, idx) => renderNode(c, `${path}.${idx}`))\n )}\n </div>\n )}\n </div>\n );\n };\n\n const tree = useMemo(\n () => data.map((d, idx) => renderNode(d, `${idx}`)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n data,\n expandedIds,\n selectedIds,\n selectable,\n checkboxes,\n listIcon,\n nodeIcon,\n renderLabel,\n loadedChildren,\n loadingIds,\n ]\n );\n\n return (\n <div data-testid=\"tree-view\" {...props} ref={ref} role=\"tree\" className={cn(\"smwb-tree\", className)}>\n {tree.map((node, idx) => (\n <div className=\"smwb-tree__wrapper\" key={idx} role=\"presentation\">\n {node}\n </div>\n ))}\n </div>\n );\n});\n\nexport default TreeView;\n"],"names":["TreeView","forwardRef","className","listIcon","nodeIcon","data","expanded","defaultExpanded","onExpandedChange","selected","defaultSelected","onSelectedChange","selectable","checkboxes","renderLabel","loadChildren","props","ref","loadedChildren","setLoadedChildren","useState","loadingIds","setLoadingIds","expandedIds","setExpandedIds","useControllableState","lastToggledRef","useRef","selectedIds","setSelectedIds","next","changed","toggleExpanded","id","prev","x","setOpen","open","has","toggleSelected","ensureLoaded","item","nodeId","children","renderNode","path","_a","resolvedChildren","_b","isLazy","hasChildNodes","isOpen","isSelected","isLoading","onLabelClick","onKeyDown","event","jsxs","cn","jsx","e","Icon","c","idx","tree","useMemo","d","node"],"mappings":"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"}
|
|
@@ -1,42 +1,43 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as o, Fragment as D } from "react/jsx-runtime";
|
|
2
2
|
import '../../../assets/styles/less/components/modal/modal.entry.css';/* empty css */
|
|
3
|
-
import { forwardRef as
|
|
4
|
-
import { CSSTransition as
|
|
5
|
-
import { createPortal as
|
|
3
|
+
import { forwardRef as L, useState as S, useRef as c, useEffect as $ } from "react";
|
|
4
|
+
import { CSSTransition as h } from "react-transition-group";
|
|
5
|
+
import { createPortal as A } from "react-dom";
|
|
6
6
|
import a from "clsx";
|
|
7
|
-
import { useSafeLayoutEffect as
|
|
7
|
+
import { useSafeLayoutEffect as F } from "../../../hooks/useSafeLayoutEffect.js";
|
|
8
8
|
import { useForkRef as M } from "../../../hooks/useForkRef.js";
|
|
9
|
-
|
|
9
|
+
import { isTopOverlayLayer as O } from "../../../utils/overlayLayer.js";
|
|
10
|
+
const j = L(function({
|
|
10
11
|
children: e,
|
|
11
12
|
onClose: r,
|
|
12
13
|
open: m,
|
|
13
14
|
className: f,
|
|
14
15
|
animation: u = "fade",
|
|
15
16
|
backdrop: p = "dark",
|
|
16
|
-
size:
|
|
17
|
+
size: i = "large",
|
|
17
18
|
closeOnOutsideClick: v = !0,
|
|
18
19
|
asForm: _ = !1,
|
|
19
20
|
disableAppearAnimation: w = !1,
|
|
20
21
|
role: b = "dialog",
|
|
21
|
-
closeOnEsc:
|
|
22
|
+
closeOnEsc: d = !0,
|
|
22
23
|
...y
|
|
23
24
|
}, k) {
|
|
24
|
-
const [
|
|
25
|
-
if (
|
|
25
|
+
const [l, x] = S(), s = c(null), R = c(null), E = M(k, R);
|
|
26
|
+
if (F(() => {
|
|
26
27
|
x(document.body);
|
|
27
|
-
}, []),
|
|
28
|
-
if (!m || !
|
|
28
|
+
}, []), $(() => {
|
|
29
|
+
if (!m || !d || !r)
|
|
29
30
|
return;
|
|
30
31
|
const n = (g) => {
|
|
31
|
-
g.key === "Escape" && r();
|
|
32
|
+
g.key === "Escape" && O(s.current) && r();
|
|
32
33
|
};
|
|
33
34
|
return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
|
|
34
|
-
}, [m,
|
|
35
|
-
return /* @__PURE__ */
|
|
35
|
+
}, [m, d, r]), !l)
|
|
36
|
+
return /* @__PURE__ */ o(D, {});
|
|
36
37
|
const N = _ ? "form" : "div";
|
|
37
|
-
return
|
|
38
|
-
/* @__PURE__ */
|
|
39
|
-
|
|
38
|
+
return A(
|
|
39
|
+
/* @__PURE__ */ o(
|
|
40
|
+
h,
|
|
40
41
|
{
|
|
41
42
|
timeout: {
|
|
42
43
|
appear: 225,
|
|
@@ -57,18 +58,19 @@ const j = S(function({
|
|
|
57
58
|
appear: !w,
|
|
58
59
|
mountOnEnter: !0,
|
|
59
60
|
unmountOnExit: !0,
|
|
60
|
-
nodeRef:
|
|
61
|
-
children: /* @__PURE__ */
|
|
61
|
+
nodeRef: s,
|
|
62
|
+
children: /* @__PURE__ */ o(
|
|
62
63
|
"div",
|
|
63
64
|
{
|
|
64
|
-
ref:
|
|
65
|
-
|
|
65
|
+
ref: s,
|
|
66
|
+
"data-smwb-overlay-layer": "",
|
|
67
|
+
className: a("smwb-modal__overlay", `smwb-${p}`, `smwb-${i}`),
|
|
66
68
|
onClick: v && r ? r : void 0,
|
|
67
|
-
children: /* @__PURE__ */
|
|
69
|
+
children: /* @__PURE__ */ o(
|
|
68
70
|
N,
|
|
69
71
|
{
|
|
70
72
|
ref: E,
|
|
71
|
-
className: a("smwb-modal", `smwb-${
|
|
73
|
+
className: a("smwb-modal", `smwb-${i}`, `smwb-${u}`, f),
|
|
72
74
|
onClick: (n) => n.stopPropagation(),
|
|
73
75
|
role: b,
|
|
74
76
|
"aria-modal": "true",
|
|
@@ -80,28 +82,28 @@ const j = S(function({
|
|
|
80
82
|
)
|
|
81
83
|
}
|
|
82
84
|
),
|
|
83
|
-
|
|
85
|
+
l
|
|
84
86
|
);
|
|
85
87
|
});
|
|
86
|
-
function C({ className:
|
|
87
|
-
return /* @__PURE__ */
|
|
88
|
+
function C({ className: t, children: e }) {
|
|
89
|
+
return /* @__PURE__ */ o("div", { className: a("smwb-modal__header", t), children: e });
|
|
88
90
|
}
|
|
89
|
-
function
|
|
90
|
-
return /* @__PURE__ */
|
|
91
|
+
function P({ className: t, children: e }) {
|
|
92
|
+
return /* @__PURE__ */ o("div", { className: a("smwb-modal__content", t), children: e });
|
|
91
93
|
}
|
|
92
|
-
function
|
|
93
|
-
return /* @__PURE__ */
|
|
94
|
+
function T({ className: t, children: e }) {
|
|
95
|
+
return /* @__PURE__ */ o("div", { className: a("smwb-modal__footer", t), children: e });
|
|
94
96
|
}
|
|
95
|
-
const
|
|
96
|
-
Footer:
|
|
97
|
+
const V = Object.assign(j, {
|
|
98
|
+
Footer: T,
|
|
97
99
|
Header: C,
|
|
98
|
-
Content:
|
|
100
|
+
Content: P
|
|
99
101
|
});
|
|
100
102
|
export {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
P as Content,
|
|
104
|
+
T as Footer,
|
|
103
105
|
C as Header,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
V as Modal,
|
|
107
|
+
V as default
|
|
106
108
|
};
|
|
107
109
|
//# sourceMappingURL=modal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.js","sources":["../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import React, { forwardRef, PropsWithChildren, useEffect, useRef, useState } from \"react\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport cn from \"clsx\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n className?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n}\n\nconst ModalBase = forwardRef<HTMLDivElement, PropsWithChildren<ModalProps>>(function Modal(\n {\n children,\n onClose,\n open,\n className,\n animation = \"fade\",\n backdrop = \"dark\",\n size = \"large\",\n closeOnOutsideClick = true,\n asForm = false,\n disableAppearAnimation = false,\n role = \"dialog\",\n closeOnEsc = true,\n ...rest\n },\n ref\n) {\n const [domRoot, setDomRoot] = useState<HTMLElement>();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const forkedContentRef = useForkRef<HTMLDivElement>(ref, contentRef);\n\n useSafeLayoutEffect(() => {\n setDomRoot(document.body);\n }, []);\n\n useEffect(() => {\n if (!open || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, closeOnEsc, onClose]);\n\n if (!domRoot) {\n return <></>;\n }\n\n const Component = (asForm ? \"form\" : \"div\") as \"div\";\n\n return createPortal(\n <CSSTransition\n timeout={{\n appear: 225,\n enter: 225,\n exit: 150,\n }}\n in={open}\n classNames={{\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n }}\n appear={!disableAppearAnimation}\n mountOnEnter\n unmountOnExit\n nodeRef={nodeRef}\n >\n <div\n ref={nodeRef}\n className={cn(\"smwb-modal__overlay\", `smwb-${backdrop}`, `smwb-${size}`)}\n onClick={closeOnOutsideClick && onClose ? onClose : undefined}\n >\n <Component\n ref={forkedContentRef}\n className={cn(\"smwb-modal\", `smwb-${size}`, `smwb-${animation}`, className)}\n onClick={(e) => e.stopPropagation()}\n role={role}\n aria-modal=\"true\"\n {...rest}\n >\n {children}\n </Component>\n </div>\n </CSSTransition>,\n domRoot\n );\n});\n\nexport interface HeaderProps {\n className?: string;\n}\n\nexport function Header({ className, children }: PropsWithChildren<HeaderProps>) {\n return <div className={cn(\"smwb-modal__header\", className)}>{children}</div>;\n}\n\nexport interface ContentProps {\n className?: string;\n}\n\nexport function Content({ className, children }: PropsWithChildren<ContentProps>) {\n return <div className={cn(\"smwb-modal__content\", className)}>{children}</div>;\n}\n\nexport interface FooterProps {\n className?: string;\n}\n\nexport function Footer({ className, children }: PropsWithChildren<FooterProps>) {\n return <div className={cn(\"smwb-modal__footer\", className)}>{children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, {\n Footer,\n Header,\n Content,\n});\n\nexport default Modal;\n"],"names":["ModalBase","forwardRef","children","onClose","open","className","animation","backdrop","size","closeOnOutsideClick","asForm","disableAppearAnimation","role","closeOnEsc","rest","ref","domRoot","setDomRoot","useState","nodeRef","useRef","contentRef","forkedContentRef","useForkRef","useSafeLayoutEffect","useEffect","onKeyDown","event","jsx","Fragment","Component","createPortal","CSSTransition","cn","e","Header","Content","Footer","Modal"],"mappings":"
|
|
1
|
+
{"version":3,"file":"modal.js","sources":["../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import React, { forwardRef, PropsWithChildren, useEffect, useRef, useState } from \"react\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport cn from \"clsx\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { isTopOverlayLayer } from \"../../../utils/overlayLayer\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n className?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n}\n\nconst ModalBase = forwardRef<HTMLDivElement, PropsWithChildren<ModalProps>>(function Modal(\n {\n children,\n onClose,\n open,\n className,\n animation = \"fade\",\n backdrop = \"dark\",\n size = \"large\",\n closeOnOutsideClick = true,\n asForm = false,\n disableAppearAnimation = false,\n role = \"dialog\",\n closeOnEsc = true,\n ...rest\n },\n ref\n) {\n const [domRoot, setDomRoot] = useState<HTMLElement>();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const forkedContentRef = useForkRef<HTMLDivElement>(ref, contentRef);\n\n useSafeLayoutEffect(() => {\n setDomRoot(document.body);\n }, []);\n\n useEffect(() => {\n if (!open || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n // Only the topmost overlay layer reacts to Escape.\n if (event.key === \"Escape\" && isTopOverlayLayer(nodeRef.current)) {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, closeOnEsc, onClose]);\n\n if (!domRoot) {\n return <></>;\n }\n\n const Component = (asForm ? \"form\" : \"div\") as \"div\";\n\n return createPortal(\n <CSSTransition\n timeout={{\n appear: 225,\n enter: 225,\n exit: 150,\n }}\n in={open}\n classNames={{\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n }}\n appear={!disableAppearAnimation}\n mountOnEnter\n unmountOnExit\n nodeRef={nodeRef}\n >\n <div\n ref={nodeRef}\n data-smwb-overlay-layer=\"\"\n className={cn(\"smwb-modal__overlay\", `smwb-${backdrop}`, `smwb-${size}`)}\n onClick={closeOnOutsideClick && onClose ? onClose : undefined}\n >\n <Component\n ref={forkedContentRef}\n className={cn(\"smwb-modal\", `smwb-${size}`, `smwb-${animation}`, className)}\n onClick={(e) => e.stopPropagation()}\n role={role}\n aria-modal=\"true\"\n {...rest}\n >\n {children}\n </Component>\n </div>\n </CSSTransition>,\n domRoot\n );\n});\n\nexport interface HeaderProps {\n className?: string;\n}\n\nexport function Header({ className, children }: PropsWithChildren<HeaderProps>) {\n return <div className={cn(\"smwb-modal__header\", className)}>{children}</div>;\n}\n\nexport interface ContentProps {\n className?: string;\n}\n\nexport function Content({ className, children }: PropsWithChildren<ContentProps>) {\n return <div className={cn(\"smwb-modal__content\", className)}>{children}</div>;\n}\n\nexport interface FooterProps {\n className?: string;\n}\n\nexport function Footer({ className, children }: PropsWithChildren<FooterProps>) {\n return <div className={cn(\"smwb-modal__footer\", className)}>{children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, {\n Footer,\n Header,\n Content,\n});\n\nexport default Modal;\n"],"names":["ModalBase","forwardRef","children","onClose","open","className","animation","backdrop","size","closeOnOutsideClick","asForm","disableAppearAnimation","role","closeOnEsc","rest","ref","domRoot","setDomRoot","useState","nodeRef","useRef","contentRef","forkedContentRef","useForkRef","useSafeLayoutEffect","useEffect","onKeyDown","event","isTopOverlayLayer","jsx","Fragment","Component","createPortal","CSSTransition","cn","e","Header","Content","Footer","Modal"],"mappings":"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"}
|