@smwb/ui-react 2.3.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.
Files changed (52) hide show
  1. package/dist/components/clickAwayListener/clickAwayListener.js +19 -14
  2. package/dist/components/clickAwayListener/clickAwayListener.js.map +1 -1
  3. package/dist/components/dataDisplay/treeView/treeView.d.ts +5 -2
  4. package/dist/components/dataDisplay/treeView/treeView.js +78 -75
  5. package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
  6. package/dist/components/feedBack/modal/modal.js +40 -38
  7. package/dist/components/feedBack/modal/modal.js.map +1 -1
  8. package/dist/components/inputs/datePicker/datePicker.js +13 -12
  9. package/dist/components/inputs/datePicker/datePicker.js.map +1 -1
  10. package/dist/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
  11. package/dist/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
  12. package/dist/components/inputs/selectField/dropdownMenu.js +7 -6
  13. package/dist/components/inputs/selectField/dropdownMenu.js.map +1 -1
  14. package/dist/components/inputs/timePicker/timePicker.js +16 -15
  15. package/dist/components/inputs/timePicker/timePicker.js.map +1 -1
  16. package/dist/components/layout/sheet/sheet.js +102 -92
  17. package/dist/components/layout/sheet/sheet.js.map +1 -1
  18. package/dist/components/navigation/menu/menuSubmenu.d.ts +1 -1
  19. package/dist/headless/components/clickAwayListener/clickAwayListener.js +19 -14
  20. package/dist/headless/components/clickAwayListener/clickAwayListener.js.map +1 -1
  21. package/dist/headless/components/dataDisplay/treeView/treeView.js +78 -75
  22. package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
  23. package/dist/headless/components/feedBack/modal/modal.js +42 -40
  24. package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
  25. package/dist/headless/components/inputs/datePicker/datePicker.js +13 -12
  26. package/dist/headless/components/inputs/datePicker/datePicker.js.map +1 -1
  27. package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
  28. package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
  29. package/dist/headless/components/inputs/selectField/dropdownMenu.js +7 -6
  30. package/dist/headless/components/inputs/selectField/dropdownMenu.js.map +1 -1
  31. package/dist/headless/components/inputs/timePicker/timePicker.js +16 -15
  32. package/dist/headless/components/inputs/timePicker/timePicker.js.map +1 -1
  33. package/dist/headless/components/layout/sheet/sheet.js +95 -85
  34. package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
  35. package/dist/headless/hooks/useHoverPopover.js +117 -0
  36. package/dist/headless/hooks/useHoverPopover.js.map +1 -0
  37. package/dist/headless/index.js +242 -240
  38. package/dist/headless/index.js.map +1 -1
  39. package/dist/headless/utils/overlayLayer.js +11 -0
  40. package/dist/headless/utils/overlayLayer.js.map +1 -0
  41. package/dist/hooks/useHoverPopover.d.ts +73 -0
  42. package/dist/hooks/useHoverPopover.js +117 -0
  43. package/dist/hooks/useHoverPopover.js.map +1 -0
  44. package/dist/index.cjs +2 -2
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.js +242 -240
  48. package/dist/index.js.map +1 -1
  49. package/dist/utils/overlayLayer.d.ts +13 -0
  50. package/dist/utils/overlayLayer.js +11 -0
  51. package/dist/utils/overlayLayer.js.map +1 -0
  52. package/package.json +1 -1
@@ -1,30 +1,31 @@
1
- import { jsx as g, Fragment as k } from "react/jsx-runtime";
2
- import P, { useRef as a, useEffect as p } from "react";
3
- import { useForkRef as y } from "../../hooks/useForkRef.js";
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 M(t, s) {
9
- return s.documentElement.clientWidth < t.clientX || s.documentElement.clientHeight < t.clientY;
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: s = !1,
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), u = a(null), l = a(!1), d = 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 T = y(t.ref, u), o = C((e) => {
26
+ const g = P(t.ref, s), o = C((e) => {
26
27
  const c = d.current;
27
- if (d.current = !1, !v || !l.current || !u.current || "clientX" in e && M(e, document))
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(u.current) > -1;
36
+ i = e.composedPath().indexOf(s.current) > -1;
36
37
  else {
37
38
  const R = e.target;
38
- i = !document.documentElement.contains(R) || u.current.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: T };
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__ */ g(k, { children: P.cloneElement(t, m) });
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":";;;;AAOA,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,IAAI,CAACD,MAAchB,KAAoB,CAACe,MACtCb,EAAYN,CAAK;AAAA,EAErB,CAAC,GAEKsB,IAAwB,CAACC,MAAwB,CAACvB,MAAgC;AACtF,IAAAa,EAAkB,UAAU;AAG5B,UAAMW,IAAuBrB,EAAS,MAAMoB,CAAW;AAEvD,IAAIC,KAEFA,EAAqBxB,CAAK;AAAA,EAE9B,GAEMyB,IAGF,EAAE,KAAKV,EAAA;AAEX,SAAIR,MAAe,OACjBkB,EAAclB,CAAU,IAAIe,EAAsBf,CAAU,IAG9DO,EAAU,MAAM;AACd,QAAIP,MAAe,IAAO;AACxB,YAAMmB,IAAmB7B,EAAoBU,CAAU,GAEjDoB,IAAkB,MAAM;AAC5B,QAAAlB,EAAS,UAAU;AAAA,MACrB;AAEA,sBAAS,iBAAiBiB,GAAkBT,CAAe,GAC3D,SAAS,iBAAiB,aAAaU,CAAe,GAE/C,MAAM;AACX,iBAAS,oBAAoBD,GAAkBT,CAAe,GAC9D,SAAS,oBAAoB,aAAaU,CAAe;AAAA,MAC3D;AAAA,IACF;AAAA,EAGF,GAAG,CAACV,GAAiBV,CAAU,CAAC,GAE5BF,MAAe,OACjBoB,EAAcpB,CAAU,IAAIiB,EAAsBjB,CAAU,IAG9DS,EAAU,MAAM;AACd,QAAIT,MAAe,IAAO;AACxB,YAAMuB,IAAmB/B,EAAoBQ,CAAU;AAEvD,sBAAS,iBAAiBuB,GAAkBX,CAAe,GAEpD,MAAM;AACX,iBAAS,oBAAoBW,GAAkBX,CAAe;AAAA,MAChE;AAAA,IACF;AAAA,EAGF,GAAG,CAACA,GAAiBZ,CAAU,CAAC,GAEzB,gBAAAwB,EAAAC,GAAA,EAAG,UAAAC,EAAM,aAAa5B,GAAUsB,CAAa,GAAE;AACxD;"}
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":"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"}
@@ -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[]) => void;
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 p } from "react/jsx-runtime";
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 Z, useState as A, useMemo as v } from "react";
4
- import D from "clsx";
5
- import { Icon as g } from "../../base/icon/icon.js";
6
- import { useControllableState as O } from "../../../hooks/useControllableState.js";
7
- const re = Z(function({
8
- className: R,
9
- listIcon: w = "draft",
10
- nodeIcon: r = { closed: "folder", opened: "folder_open" },
11
- data: b = [],
12
- expanded: T,
13
- defaultExpanded: K = [],
14
- onExpandedChange: M,
15
- selected: P,
16
- defaultSelected: q = [],
17
- onSelectedChange: B,
18
- selectable: c = !1,
19
- checkboxes: f = !1,
20
- renderLabel: u,
21
- loadChildren: m,
22
- ...F
23
- }, G) {
24
- const [o, H] = A({}), [N, k] = A([]), [x, y] = 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: q,
31
- onChange: B
32
- }), Q = (s) => {
33
- y((t) => t.includes(s) ? t.filter((e) => e !== s) : [...t, s]);
34
- }, L = (s, t) => {
35
- y((e) => {
36
- const l = e.includes(s);
37
- return t && !l ? [...e, s] : !t && l ? e.filter((_) => _ !== s) : e;
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
- }, S = (s) => {
40
- J((t) => t.includes(s) ? t.filter((e) => e !== s) : [...t, s]);
41
- }, z = (s, t) => {
42
- !m || o[t] || s.children && s.children.length > 0 || (k((e) => e.includes(t) ? e : [...e, t]), m(s, t).then((e) => {
43
- H((l) => ({ ...l, [t]: e }));
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
- k((e) => e.filter((l) => l !== t));
48
+ L((s) => s.filter((l) => l !== t));
46
49
  }));
47
- }, V = (s, t) => {
48
- var $, j;
49
- const e = ($ = s.id) != null ? $ : t, l = (j = s.children) != null ? j : o[e], _ = !!m && (s.hasChildren || !!o[e]), i = !!l && l.length > 0 || _, d = x.includes(e), h = C.includes(e), W = N.includes(e), E = () => {
50
- i && (d || z(s, e), Q(e)), c && S(e);
51
- }, X = (a) => {
52
- a.key === "Enter" || a.key === " " ? (a.preventDefault(), E()) : a.key === "ArrowRight" && i ? (z(s, e), L(e, !0)) : a.key === "ArrowLeft" && i && L(e, !1);
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__ */ p(
57
+ return /* @__PURE__ */ b(
55
58
  "div",
56
59
  {
57
- className: D("smwb-tree__node", { "smwb-tree__node_selected": h }),
60
+ className: O("smwb-tree__node", { "smwb-tree__node_selected": g }),
58
61
  role: "treeitem",
59
- "aria-expanded": i ? d : void 0,
60
- "aria-selected": c || f ? h : void 0,
62
+ "aria-expanded": i ? c : void 0,
63
+ "aria-selected": f || u ? g : void 0,
61
64
  children: [
62
- /* @__PURE__ */ p(
65
+ /* @__PURE__ */ b(
63
66
  "span",
64
67
  {
65
68
  className: "smwb-tree__node__content",
66
- onClick: E,
67
- onKeyDown: X,
69
+ onClick: $,
70
+ onKeyDown: Y,
68
71
  tabIndex: 0,
69
72
  role: "button",
70
73
  children: [
71
- f && /* @__PURE__ */ n(
74
+ u && /* @__PURE__ */ n(
72
75
  "input",
73
76
  {
74
77
  type: "checkbox",
75
78
  className: "smwb-tree__node__checkbox",
76
- checked: h,
77
- onClick: (a) => a.stopPropagation(),
78
- onChange: () => S(e),
79
- "aria-label": s.label
79
+ checked: g,
80
+ onClick: (r) => r.stopPropagation(),
81
+ onChange: () => V(s),
82
+ "aria-label": e.label
80
83
  }
81
84
  ),
82
- /* @__PURE__ */ p("span", { className: "smwb-tree__node__label", children: [
83
- i && d ? /* @__PURE__ */ n(g, { name: r == null ? void 0 : r.opened, fill: 1, size: 20 }) : i ? /* @__PURE__ */ n(g, { name: r == null ? void 0 : r.closed, fill: 1, size: 20 }) : /* @__PURE__ */ n(g, { name: w, size: 20 }),
84
- u ? u(s, e) : s.label
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 && d && /* @__PURE__ */ n("div", { role: "group", children: W && !l ? /* @__PURE__ */ n("div", { className: "smwb-tree__node__loading", role: "status", children: "Загрузка…" }) : l == null ? void 0 : l.map((a, Y) => V(a, `${t}.${Y}`)) })
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
- e
95
+ s
93
96
  );
94
- }, U = v(
95
- () => b.map((s, t) => V(s, `${t}`)),
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
- C,
101
- c,
102
+ z,
103
+ h,
102
104
  f,
103
- w,
104
- r,
105
105
  u,
106
+ k,
107
+ a,
108
+ m,
106
109
  o,
107
- N
110
+ y
108
111
  ]
109
112
  );
110
- return /* @__PURE__ */ n("div", { "data-testid": "tree-view", ...F, ref: G, role: "tree", className: D("smwb-tree", R), children: U.map((s, t) => /* @__PURE__ */ n("div", { className: "smwb-tree__wrapper", role: "presentation", children: s }, t)) });
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
- re as TreeView,
114
- re as default
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 t, Fragment as D } from "react/jsx-runtime";
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 S, useState as $, useRef as c, useEffect as h } from "react";
4
- import { CSSTransition as A } from "react-transition-group";
5
- import { createPortal as F } from "react-dom";
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 L } from "../../../hooks/useSafeLayoutEffect.js";
7
+ import { useSafeLayoutEffect as F } from "../../../hooks/useSafeLayoutEffect.js";
8
8
  import { useForkRef as M } from "../../../hooks/useForkRef.js";
9
- const j = S(function({
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: s = "large",
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: i = !0,
22
+ closeOnEsc: d = !0,
22
23
  ...y
23
24
  }, k) {
24
- const [d, x] = $(), l = c(null), R = c(null), E = M(k, R);
25
- if (L(() => {
25
+ const [l, x] = S(), s = c(null), R = c(null), E = M(k, R);
26
+ if (F(() => {
26
27
  x(document.body);
27
- }, []), h(() => {
28
- if (!m || !i || !r)
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, i, r]), !d)
35
- return /* @__PURE__ */ t(D, {});
35
+ }, [m, d, r]), !l)
36
+ return /* @__PURE__ */ o(D, {});
36
37
  const N = _ ? "form" : "div";
37
- return F(
38
- /* @__PURE__ */ t(
39
- A,
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: l,
61
- children: /* @__PURE__ */ t(
61
+ nodeRef: s,
62
+ children: /* @__PURE__ */ o(
62
63
  "div",
63
64
  {
64
- ref: l,
65
- className: a("smwb-modal__overlay", `smwb-${p}`, `smwb-${s}`),
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__ */ t(
69
+ children: /* @__PURE__ */ o(
68
70
  N,
69
71
  {
70
72
  ref: E,
71
- className: a("smwb-modal", `smwb-${s}`, `smwb-${u}`, f),
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
- d
85
+ l
84
86
  );
85
87
  });
86
- function C({ className: o, children: e }) {
87
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__header", o), children: e });
88
+ function C({ className: t, children: e }) {
89
+ return /* @__PURE__ */ o("div", { className: a("smwb-modal__header", t), children: e });
88
90
  }
89
- function O({ className: o, children: e }) {
90
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__content", o), children: e });
91
+ function P({ className: t, children: e }) {
92
+ return /* @__PURE__ */ o("div", { className: a("smwb-modal__content", t), children: e });
91
93
  }
92
- function P({ className: o, children: e }) {
93
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__footer", o), children: e });
94
+ function T({ className: t, children: e }) {
95
+ return /* @__PURE__ */ o("div", { className: a("smwb-modal__footer", t), children: e });
94
96
  }
95
- const Q = Object.assign(j, {
96
- Footer: P,
97
+ const V = Object.assign(j, {
98
+ Footer: T,
97
99
  Header: C,
98
- Content: O
100
+ Content: P
99
101
  });
100
102
  export {
101
- O as Content,
102
- P as Footer,
103
+ P as Content,
104
+ T as Footer,
103
105
  C as Header,
104
- Q as Modal,
105
- Q as default
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":";;;;;;;;AA2BA,MAAMA,IAAYC,EAA0D,SAC1E;AAAA,EACE,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,MAAAC,IAAO;AAAA,EACP,qBAAAC,IAAsB;AAAA,EACtB,QAAAC,IAAS;AAAA,EACT,wBAAAC,IAAyB;AAAA,EACzB,MAAAC,IAAO;AAAA,EACP,YAAAC,IAAa;AAAA,EACb,GAAGC;AACL,GACAC,GACA;AACA,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAA,GAExBC,IAAUC,EAAuB,IAAI,GACrCC,IAAaD,EAAuB,IAAI,GACxCE,IAAmBC,EAA2BR,GAAKM,CAAU;AAoBnE,MAlBAG,EAAoB,MAAM;AACxB,IAAAP,EAAW,SAAS,IAAI;AAAA,EAC1B,GAAG,CAAA,CAAE,GAELQ,EAAU,MAAM;AACd,QAAI,CAACrB,KAAQ,CAACS,KAAc,CAACV;AAC3B;AAEF,UAAMuB,IAAY,CAACC,MAAyB;AAC1C,MAAIA,EAAM,QAAQ,YAChBxB,EAAA;AAAA,IAEJ;AACA,oBAAS,iBAAiB,WAAWuB,CAAS,GAEvC,MAAM,SAAS,oBAAoB,WAAWA,CAAS;AAAA,EAChE,GAAG,CAACtB,GAAMS,GAAYV,CAAO,CAAC,GAE1B,CAACa;AACH,WAAO,gBAAAY,EAAAC,GAAA,EAAE;AAGX,QAAMC,IAAapB,IAAS,SAAS;AAErC,SAAOqB;AAAA,IACL,gBAAAH;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,MAAM;AAAA,QAAA;AAAA,QAER,IAAI5B;AAAA,QACJ,YAAY;AAAA,UACV,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,aAAa;AAAA,UACb,WAAW;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,QAAA;AAAA,QAEd,QAAQ,CAACO;AAAA,QACT,cAAY;AAAA,QACZ,eAAa;AAAA,QACb,SAAAQ;AAAA,QAEA,UAAA,gBAAAS;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKT;AAAA,YACL,WAAWc,EAAG,uBAAuB,QAAQ1B,CAAQ,IAAI,QAAQC,CAAI,EAAE;AAAA,YACvE,SAASC,KAAuBN,IAAUA,IAAU;AAAA,YAEpD,UAAA,gBAAAyB;AAAA,cAACE;AAAA,cAAA;AAAA,gBACC,KAAKR;AAAA,gBACL,WAAWW,EAAG,cAAc,QAAQzB,CAAI,IAAI,QAAQF,CAAS,IAAID,CAAS;AAAA,gBAC1E,SAAS,CAAC6B,MAAMA,EAAE,gBAAA;AAAA,gBAClB,MAAAtB;AAAA,gBACA,cAAW;AAAA,gBACV,GAAGE;AAAA,gBAEH,UAAAZ;AAAA,cAAA;AAAA,YAAA;AAAA,UACH;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAEFc;AAAA,EAAA;AAEJ,CAAC;AAMM,SAASmB,EAAO,EAAE,WAAA9B,GAAW,UAAAH,KAA4C;AAC9E,2BAAQ,OAAA,EAAI,WAAW+B,EAAG,sBAAsB5B,CAAS,GAAI,UAAAH,GAAS;AACxE;AAMO,SAASkC,EAAQ,EAAE,WAAA/B,GAAW,UAAAH,KAA6C;AAChF,2BAAQ,OAAA,EAAI,WAAW+B,EAAG,uBAAuB5B,CAAS,GAAI,UAAAH,GAAS;AACzE;AAMO,SAASmC,EAAO,EAAE,WAAAhC,GAAW,UAAAH,KAA4C;AAC9E,2BAAQ,OAAA,EAAI,WAAW+B,EAAG,sBAAsB5B,CAAS,GAAI,UAAAH,GAAS;AACxE;AAEO,MAAMoC,IAAQ,OAAO,OAAOtC,GAAW;AAAA,EAC5C,QAAAqC;AAAA,EACA,QAAAF;AAAA,EACA,SAAAC;AACF,CAAC;"}
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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"}