@vuu-ui/vuu-ui-controls 0.9.0 → 0.9.2

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 (59) hide show
  1. package/cjs/cycle-state-button/CycleStateButton.js +2 -6
  2. package/cjs/cycle-state-button/CycleStateButton.js.map +1 -1
  3. package/cjs/editable/useEditableText.js +69 -50
  4. package/cjs/editable/useEditableText.js.map +1 -1
  5. package/cjs/icon-button/ToggleIconButton.css.js +6 -0
  6. package/cjs/icon-button/ToggleIconButton.css.js.map +1 -0
  7. package/cjs/icon-button/ToggleIconButton.js +38 -0
  8. package/cjs/icon-button/ToggleIconButton.js.map +1 -0
  9. package/cjs/index.js +2 -1
  10. package/cjs/index.js.map +1 -1
  11. package/cjs/tree/Tree.js.map +1 -1
  12. package/cjs/tree/hierarchical-data-utils.js.map +1 -1
  13. package/cjs/tree/treeTypeUtils.js.map +1 -1
  14. package/cjs/tree/use-collapsible-groups.js.map +1 -1
  15. package/cjs/tree/use-hierarchical-data.js.map +1 -1
  16. package/cjs/tree/use-items-with-ids.js.map +1 -1
  17. package/cjs/tree/use-keyboard-navigation.js.map +1 -1
  18. package/cjs/tree/use-selection.js.map +1 -1
  19. package/cjs/tree/use-tree-keyboard-navigation.js.map +1 -1
  20. package/cjs/tree/useTree.js +2 -2
  21. package/cjs/tree/useTree.js.map +1 -1
  22. package/esm/cycle-state-button/CycleStateButton.js +2 -6
  23. package/esm/cycle-state-button/CycleStateButton.js.map +1 -1
  24. package/esm/editable/useEditableText.js +72 -52
  25. package/esm/editable/useEditableText.js.map +1 -1
  26. package/esm/icon-button/ToggleIconButton.css.js +4 -0
  27. package/esm/icon-button/ToggleIconButton.css.js.map +1 -0
  28. package/esm/icon-button/ToggleIconButton.js +36 -0
  29. package/esm/icon-button/ToggleIconButton.js.map +1 -0
  30. package/esm/index.js +2 -1
  31. package/esm/index.js.map +1 -1
  32. package/esm/tree/Tree.js.map +1 -1
  33. package/esm/tree/hierarchical-data-utils.js.map +1 -1
  34. package/esm/tree/treeTypeUtils.js.map +1 -1
  35. package/esm/tree/use-collapsible-groups.js.map +1 -1
  36. package/esm/tree/use-hierarchical-data.js.map +1 -1
  37. package/esm/tree/use-items-with-ids.js.map +1 -1
  38. package/esm/tree/use-keyboard-navigation.js.map +1 -1
  39. package/esm/tree/use-selection.js.map +1 -1
  40. package/esm/tree/use-tree-keyboard-navigation.js.map +1 -1
  41. package/esm/tree/useTree.js +2 -2
  42. package/esm/tree/useTree.js.map +1 -1
  43. package/package.json +8 -8
  44. package/types/cycle-state-button/CycleStateButton.d.ts +3 -4
  45. package/types/editable/useEditableText.d.ts +5 -6
  46. package/types/icon-button/ToggleIconButton.d.ts +6 -0
  47. package/types/icon-button/index.d.ts +1 -0
  48. package/types/tree/Tree.d.ts +1 -1
  49. package/types/tree/hierarchical-data-utils.d.ts +1 -1
  50. package/types/tree/index.d.ts +0 -1
  51. package/types/tree/treeTypeUtils.d.ts +1 -1
  52. package/types/tree/use-collapsible-groups.d.ts +1 -1
  53. package/types/tree/use-hierarchical-data.d.ts +1 -1
  54. package/types/tree/use-items-with-ids.d.ts +1 -1
  55. package/types/tree/use-keyboard-navigation.d.ts +1 -1
  56. package/types/tree/use-selection.d.ts +1 -1
  57. package/types/tree/use-tree-keyboard-navigation.d.ts +1 -1
  58. package/types/tree/useTree.d.ts +1 -1
  59. package/types/tree/treeTypes.d.ts +0 -17
@@ -1 +1 @@
1
- {"version":3,"file":"use-selection.js","sources":["../../src/tree/use-selection.ts"],"sourcesContent":["import {\n KeyboardEvent,\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { NormalisedTreeSourceNode } from \"./treeTypes\";\n\nexport type TreeSelection =\n | \"none\"\n | \"single\"\n | \"checkbox\"\n | \"multi\"\n | \"extended\";\n\nexport const SINGLE = \"single\";\nexport const CHECKBOX = \"checkbox\";\nexport const MULTI = \"multi\";\nexport const EXTENDED = \"extended\";\n\nexport type GroupSelection = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst NO_HANDLERS = {};\n\nconst isCollapsibleItem = (item: NormalisedTreeSourceNode) =>\n item.expanded !== undefined;\n\nexport type TreeNodeSelectionHandler = (\n evt: SyntheticEvent,\n selected: string[]\n) => void;\n\nexport const groupSelectionEnabled = (groupSelection: GroupSelection) =>\n groupSelection && groupSelection !== \"none\";\n\nexport interface SelectionHookProps {\n defaultSelected?: string[];\n highlightedIdx: number;\n onChange: TreeNodeSelectionHandler;\n selected?: string[];\n selection: TreeSelection;\n selectionKeys?: string[];\n treeNodes: NormalisedTreeSourceNode[];\n}\n\nexport interface SelectionHookResult {\n listHandlers: {\n onKeyDown?: (evt: KeyboardEvent) => void;\n onKeyboardNavigation?: (evt: KeyboardEvent, currentIndex: number) => void;\n };\n listItemHandlers: {\n onClick?: (evt: MouseEvent) => void;\n };\n selected: string[];\n setSelected: (selected: string[]) => void;\n}\n\nexport const useSelection = ({\n defaultSelected,\n highlightedIdx,\n treeNodes,\n onChange,\n selected: selectedProp,\n selection = SINGLE,\n selectionKeys = defaultSelectionKeys,\n}: SelectionHookProps): SelectionHookResult => {\n const singleSelect = selection === SINGLE;\n const multiSelect = selection === MULTI || selection.startsWith(CHECKBOX);\n const extendedSelect = selection === EXTENDED;\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt) => selectionKeys.includes(evt.key),\n [selectionKeys]\n );\n\n const [selected, setSelected] = useControlled({\n controlled: selectedProp,\n default: defaultSelected ?? [],\n name: \"selected\",\n });\n\n // const highlightedIdxRef = useRef();\n // highlightedIdxRef.current = highlightedIdx;\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n id: string,\n rangeSelect: boolean,\n preserveExistingSelection = false\n ) => {\n const { current: active } = lastActive;\n const isSelected = selected?.includes(id);\n const inactiveRange = active === -1;\n const actsLikeSingleSelect =\n singleSelect ||\n (extendedSelect &&\n !preserveExistingSelection &&\n (!rangeSelect || inactiveRange));\n const actsLikeMultiSelect =\n multiSelect ||\n (extendedSelect && preserveExistingSelection && !rangeSelect);\n\n let newSelected: string[] = [];\n if (actsLikeSingleSelect && isSelected) {\n newSelected = [];\n } else if (actsLikeSingleSelect) {\n newSelected = [id];\n } else if (actsLikeMultiSelect && isSelected) {\n newSelected = selected.filter((i) => i !== id);\n } else if (actsLikeMultiSelect) {\n newSelected = selected.concat(id);\n } else if (extendedSelect) {\n const [from, to] = idx > active ? [active, idx] : [idx, active];\n newSelected = selected.slice();\n for (let i = from; i <= to; i++) {\n const { id } = treeNodes[i];\n if (!selected.includes(id)) {\n newSelected.push(id);\n }\n }\n }\n setSelected(newSelected);\n if (onChange) {\n onChange(evt, newSelected);\n }\n },\n [\n extendedSelect,\n treeNodes,\n multiSelect,\n onChange,\n selected,\n setSelected,\n singleSelect,\n ]\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n if (~highlightedIdx && isSelectionEvent(evt)) {\n evt.preventDefault();\n const item = treeNodes[highlightedIdx];\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item.id,\n false,\n evt.ctrlKey || evt.metaKey\n );\n if (extendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n },\n [\n extendedSelect,\n highlightedIdx,\n treeNodes,\n isSelectionEvent,\n selectItemAtIndex,\n ]\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (extendedSelect && evt.shiftKey) {\n const item = treeNodes[currentIndex];\n selectItemAtIndex(evt, currentIndex, item.id, true);\n }\n },\n [extendedSelect, treeNodes, selectItemAtIndex]\n );\n\n const listHandlers =\n selection === \"none\"\n ? NO_HANDLERS\n : {\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n if (highlightedIdx !== -1) {\n const item = treeNodes[highlightedIdx];\n if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item.id,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey\n );\n if (extendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [extendedSelect, highlightedIdx, treeNodes, selectItemAtIndex]\n );\n\n const listItemHandlers =\n selection === \"none\"\n ? NO_HANDLERS\n : {\n onClick: handleClick,\n };\n\n return {\n listHandlers,\n listItemHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":["useRef","useCallback","useControlled","id"],"mappings":"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"}
1
+ {"version":3,"file":"use-selection.js","sources":["../../src/tree/use-selection.ts"],"sourcesContent":["import {\n KeyboardEvent,\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport type TreeSelection =\n | \"none\"\n | \"single\"\n | \"checkbox\"\n | \"multi\"\n | \"extended\";\n\nexport const SINGLE = \"single\";\nexport const CHECKBOX = \"checkbox\";\nexport const MULTI = \"multi\";\nexport const EXTENDED = \"extended\";\n\nexport type GroupSelection = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst NO_HANDLERS = {};\n\nconst isCollapsibleItem = (item: NormalisedTreeSourceNode) =>\n item.expanded !== undefined;\n\nexport type TreeNodeSelectionHandler = (\n evt: SyntheticEvent,\n selected: string[],\n) => void;\n\nexport const groupSelectionEnabled = (groupSelection: GroupSelection) =>\n groupSelection && groupSelection !== \"none\";\n\nexport interface SelectionHookProps {\n defaultSelected?: string[];\n highlightedIdx: number;\n onChange: TreeNodeSelectionHandler;\n selected?: string[];\n selection: TreeSelection;\n selectionKeys?: string[];\n treeNodes: NormalisedTreeSourceNode[];\n}\n\nexport interface SelectionHookResult {\n listHandlers: {\n onKeyDown?: (evt: KeyboardEvent) => void;\n onKeyboardNavigation?: (evt: KeyboardEvent, currentIndex: number) => void;\n };\n listItemHandlers: {\n onClick?: (evt: MouseEvent) => void;\n };\n selected: string[];\n setSelected: (selected: string[]) => void;\n}\n\nexport const useSelection = ({\n defaultSelected,\n highlightedIdx,\n treeNodes,\n onChange,\n selected: selectedProp,\n selection = SINGLE,\n selectionKeys = defaultSelectionKeys,\n}: SelectionHookProps): SelectionHookResult => {\n const singleSelect = selection === SINGLE;\n const multiSelect = selection === MULTI || selection.startsWith(CHECKBOX);\n const extendedSelect = selection === EXTENDED;\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const [selected, setSelected] = useControlled({\n controlled: selectedProp,\n default: defaultSelected ?? [],\n name: \"selected\",\n });\n\n // const highlightedIdxRef = useRef();\n // highlightedIdxRef.current = highlightedIdx;\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n id: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n ) => {\n const { current: active } = lastActive;\n const isSelected = selected?.includes(id);\n const inactiveRange = active === -1;\n const actsLikeSingleSelect =\n singleSelect ||\n (extendedSelect &&\n !preserveExistingSelection &&\n (!rangeSelect || inactiveRange));\n const actsLikeMultiSelect =\n multiSelect ||\n (extendedSelect && preserveExistingSelection && !rangeSelect);\n\n let newSelected: string[] = [];\n if (actsLikeSingleSelect && isSelected) {\n newSelected = [];\n } else if (actsLikeSingleSelect) {\n newSelected = [id];\n } else if (actsLikeMultiSelect && isSelected) {\n newSelected = selected.filter((i) => i !== id);\n } else if (actsLikeMultiSelect) {\n newSelected = selected.concat(id);\n } else if (extendedSelect) {\n const [from, to] = idx > active ? [active, idx] : [idx, active];\n newSelected = selected.slice();\n for (let i = from; i <= to; i++) {\n const { id } = treeNodes[i];\n if (!selected.includes(id)) {\n newSelected.push(id);\n }\n }\n }\n setSelected(newSelected);\n if (onChange) {\n onChange(evt, newSelected);\n }\n },\n [\n extendedSelect,\n treeNodes,\n multiSelect,\n onChange,\n selected,\n setSelected,\n singleSelect,\n ],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n if (~highlightedIdx && isSelectionEvent(evt)) {\n evt.preventDefault();\n const item = treeNodes[highlightedIdx];\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item.id,\n false,\n evt.ctrlKey || evt.metaKey,\n );\n if (extendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n },\n [\n extendedSelect,\n highlightedIdx,\n treeNodes,\n isSelectionEvent,\n selectItemAtIndex,\n ],\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (extendedSelect && evt.shiftKey) {\n const item = treeNodes[currentIndex];\n selectItemAtIndex(evt, currentIndex, item.id, true);\n }\n },\n [extendedSelect, treeNodes, selectItemAtIndex],\n );\n\n const listHandlers =\n selection === \"none\"\n ? NO_HANDLERS\n : {\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n if (highlightedIdx !== -1) {\n const item = treeNodes[highlightedIdx];\n if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item.id,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey,\n );\n if (extendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [extendedSelect, highlightedIdx, treeNodes, selectItemAtIndex],\n );\n\n const listItemHandlers =\n selection === \"none\"\n ? NO_HANDLERS\n : {\n onClick: handleClick,\n };\n\n return {\n listHandlers,\n listItemHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":["useRef","useCallback","useControlled","id"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-tree-keyboard-navigation.js","sources":["../../src/tree/use-tree-keyboard-navigation.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { ArrowLeft } from \"./key-code\";\nimport {\n getNodeById,\n getNodeParentPath,\n getIndexOfNode,\n} from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"./treeTypes\";\n\nexport interface TreeKeyboardNavigationHookProps {\n highlightedIdx: number;\n hiliteItemAtIndex: (idx: number) => void;\n indexPositions: NormalisedTreeSourceNode[];\n source: NormalisedTreeSourceNode[];\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useTreeKeyboardNavigation = ({\n highlightedIdx,\n hiliteItemAtIndex,\n indexPositions,\n source,\n}: TreeKeyboardNavigationHookProps) => {\n const handleKeyDown = useCallback(\n (e) => {\n if (e.key === ArrowLeft) {\n const node = indexPositions[highlightedIdx];\n const parentId = getNodeParentPath(node);\n if (parentId) {\n e.preventDefault();\n const parentNode = getNodeById(source, parentId);\n if (parentNode) {\n const idx = getIndexOfNode(indexPositions, parentNode);\n if (idx !== undefined) {\n hiliteItemAtIndex(idx);\n }\n }\n }\n }\n },\n [highlightedIdx, hiliteItemAtIndex, indexPositions, source]\n );\n\n const listHandlers = {\n onKeyDown: handleKeyDown,\n };\n\n return {\n listHandlers,\n };\n};\n"],"names":["useCallback","ArrowLeft","getNodeParentPath","getNodeById","getIndexOfNode"],"mappings":";;;;;;AAiBO,MAAM,4BAA4B,CAAC;AAAA,EACxC,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,MAAA;AACF,CAAuC,KAAA;AACrC,EAAA,MAAM,aAAgB,GAAAA,iBAAA;AAAA,IACpB,CAAC,CAAM,KAAA;AACL,MAAI,IAAA,CAAA,CAAE,QAAQC,iBAAW,EAAA;AACvB,QAAM,MAAA,IAAA,GAAO,eAAe,cAAc,CAAA,CAAA;AAC1C,QAAM,MAAA,QAAA,GAAWC,wCAAkB,IAAI,CAAA,CAAA;AACvC,QAAA,IAAI,QAAU,EAAA;AACZ,UAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,UAAM,MAAA,UAAA,GAAaC,iCAAY,CAAA,MAAA,EAAQ,QAAQ,CAAA,CAAA;AAC/C,UAAA,IAAI,UAAY,EAAA;AACd,YAAM,MAAA,GAAA,GAAMC,oCAAe,CAAA,cAAA,EAAgB,UAAU,CAAA,CAAA;AACrD,YAAA,IAAI,QAAQ,KAAW,CAAA,EAAA;AACrB,cAAA,iBAAA,CAAkB,GAAG,CAAA,CAAA;AAAA,aACvB;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,cAAA,EAAgB,iBAAmB,EAAA,cAAA,EAAgB,MAAM,CAAA;AAAA,GAC5D,CAAA;AAEA,EAAA,MAAM,YAAe,GAAA;AAAA,IACnB,SAAW,EAAA,aAAA;AAAA,GACb,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"use-tree-keyboard-navigation.js","sources":["../../src/tree/use-tree-keyboard-navigation.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { ArrowLeft } from \"./key-code\";\nimport {\n getNodeById,\n getNodeParentPath,\n getIndexOfNode,\n} from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport interface TreeKeyboardNavigationHookProps {\n highlightedIdx: number;\n hiliteItemAtIndex: (idx: number) => void;\n indexPositions: NormalisedTreeSourceNode[];\n source: NormalisedTreeSourceNode[];\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useTreeKeyboardNavigation = ({\n highlightedIdx,\n hiliteItemAtIndex,\n indexPositions,\n source,\n}: TreeKeyboardNavigationHookProps) => {\n const handleKeyDown = useCallback(\n (e) => {\n if (e.key === ArrowLeft) {\n const node = indexPositions[highlightedIdx];\n const parentId = getNodeParentPath(node);\n if (parentId) {\n e.preventDefault();\n const parentNode = getNodeById(source, parentId);\n if (parentNode) {\n const idx = getIndexOfNode(indexPositions, parentNode);\n if (idx !== undefined) {\n hiliteItemAtIndex(idx);\n }\n }\n }\n }\n },\n [highlightedIdx, hiliteItemAtIndex, indexPositions, source],\n );\n\n const listHandlers = {\n onKeyDown: handleKeyDown,\n };\n\n return {\n listHandlers,\n };\n};\n"],"names":["useCallback","ArrowLeft","getNodeParentPath","getNodeById","getIndexOfNode"],"mappings":";;;;;;AAiBO,MAAM,4BAA4B,CAAC;AAAA,EACxC,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,MAAA;AACF,CAAuC,KAAA;AACrC,EAAA,MAAM,aAAgB,GAAAA,iBAAA;AAAA,IACpB,CAAC,CAAM,KAAA;AACL,MAAI,IAAA,CAAA,CAAE,QAAQC,iBAAW,EAAA;AACvB,QAAM,MAAA,IAAA,GAAO,eAAe,cAAc,CAAA,CAAA;AAC1C,QAAM,MAAA,QAAA,GAAWC,wCAAkB,IAAI,CAAA,CAAA;AACvC,QAAA,IAAI,QAAU,EAAA;AACZ,UAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,UAAM,MAAA,UAAA,GAAaC,iCAAY,CAAA,MAAA,EAAQ,QAAQ,CAAA,CAAA;AAC/C,UAAA,IAAI,UAAY,EAAA;AACd,YAAM,MAAA,GAAA,GAAMC,oCAAe,CAAA,cAAA,EAAgB,UAAU,CAAA,CAAA;AACrD,YAAA,IAAI,QAAQ,KAAW,CAAA,EAAA;AACrB,cAAA,iBAAA,CAAkB,GAAG,CAAA,CAAA;AAAA,aACvB;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,cAAA,EAAgB,iBAAmB,EAAA,cAAA,EAAgB,MAAM,CAAA;AAAA,GAC5D,CAAA;AAEA,EAAA,MAAM,YAAe,GAAA;AAAA,IACnB,SAAW,EAAA,aAAA;AAAA,GACb,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
+ var useCollapsibleGroups = require('./use-collapsible-groups.js');
5
+ var useHierarchicalData = require('./use-hierarchical-data.js');
4
6
  var useKeyboardNavigation = require('./use-keyboard-navigation.js');
5
7
  var useSelection = require('./use-selection.js');
6
- var useHierarchicalData = require('./use-hierarchical-data.js');
7
- var useCollapsibleGroups = require('./use-collapsible-groups.js');
8
8
  var useTreeKeyboardNavigation = require('./use-tree-keyboard-navigation.js');
9
9
 
10
10
  const EMPTY_ARRAY = [];
@@ -1 +1 @@
1
- {"version":3,"file":"useTree.js","sources":["../../src/tree/useTree.ts"],"sourcesContent":["import { KeyboardEvent, useCallback, useRef } from \"react\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n useSelection,\n} from \"./use-selection\";\nimport { useHierarchicalData } from \"./use-hierarchical-data\";\nimport { useCollapsibleGroups } from \"./use-collapsible-groups\";\nimport { useTreeKeyboardNavigation } from \"./use-tree-keyboard-navigation\";\nimport type { NormalisedTreeSourceNode } from \"./treeTypes\";\n\nconst EMPTY_ARRAY: string[] = [];\n\nexport interface TreeHookProps {\n defaultSelected?: string[];\n groupSelection: GroupSelection;\n onChange: TreeNodeSelectionHandler;\n onHighlight?: (index: number) => void;\n selected?: string[];\n selection: TreeSelection;\n sourceWithIds: NormalisedTreeSourceNode[];\n}\n\nexport const useTree = ({\n defaultSelected,\n sourceWithIds,\n onChange,\n onHighlight: onHighlightProp,\n selected: selectedProp,\n selection,\n}: TreeHookProps) => {\n const lastSelection = useRef<string[]>(EMPTY_ARRAY);\n const dataHook = useHierarchicalData(sourceWithIds);\n\n const handleKeyboardNavigation = (evt: KeyboardEvent, nextIdx: number) => {\n selectionHook.listHandlers.onKeyboardNavigation?.(evt, nextIdx);\n };\n\n const { highlightedIdx, ...keyboardHook } = useKeyboardNavigation({\n treeNodes: dataHook.indexPositions,\n onHighlight: onHighlightProp,\n onKeyboardNavigation: handleKeyboardNavigation,\n selected: lastSelection.current,\n });\n\n const collapsibleHook = useCollapsibleGroups({\n collapsibleHeaders: true,\n highlightedIdx,\n treeNodes: dataHook.indexPositions,\n setVisibleData: dataHook.setData,\n source: dataHook.data,\n });\n\n const selectionHook = useSelection({\n defaultSelected,\n highlightedIdx,\n treeNodes: dataHook.indexPositions,\n onChange,\n selected: selectedProp,\n selection,\n });\n\n const treeNavigationHook = useTreeKeyboardNavigation({\n source: dataHook.data,\n highlightedIdx,\n hiliteItemAtIndex: keyboardHook.hiliteItemAtIndex,\n indexPositions: dataHook.indexPositions,\n });\n\n const handleClick = useCallback(\n (evt) => {\n collapsibleHook.listItemHandlers?.onClick(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listItemHandlers?.onClick?.(evt);\n }\n },\n [collapsibleHook, selectionHook]\n );\n\n const handleKeyDown = useCallback(\n (evt) => {\n keyboardHook.listProps.onKeyDown?.(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n collapsibleHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n treeNavigationHook.listHandlers.onKeyDown?.(evt);\n }\n },\n [\n collapsibleHook.listHandlers,\n keyboardHook.listProps,\n selectionHook.listHandlers,\n treeNavigationHook.listHandlers,\n ]\n );\n\n const getActiveDescendant = () =>\n highlightedIdx === undefined || highlightedIdx === -1\n ? undefined\n : dataHook.indexPositions[highlightedIdx]?.id;\n\n // We need this on reEntry for navigation hook to handle focus\n lastSelection.current = selectionHook.selected;\n\n const listProps = {\n \"aria-activedescendant\": getActiveDescendant(),\n onBlur: keyboardHook.listProps.onBlur,\n onFocus: keyboardHook.listProps.onFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: keyboardHook.listProps.onMouseDownCapture,\n onMouseLeave: keyboardHook.listProps.onMouseLeave,\n onMouseMove: keyboardHook.listProps.onMouseMove,\n };\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n focusVisible: keyboardHook.focusVisible,\n highlightedIdx,\n hiliteItemAtIndex: keyboardHook.hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected: selectionHook.selected,\n visibleData: dataHook.data,\n };\n};\n"],"names":["useRef","useHierarchicalData","useKeyboardNavigation","useCollapsibleGroups","useSelection","useTreeKeyboardNavigation","useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"useTree.js","sources":["../../src/tree/useTree.ts"],"sourcesContent":["import type { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent, useCallback, useRef } from \"react\";\nimport { useCollapsibleGroups } from \"./use-collapsible-groups\";\nimport { useHierarchicalData } from \"./use-hierarchical-data\";\nimport { useKeyboardNavigation } from \"./use-keyboard-navigation\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n useSelection,\n} from \"./use-selection\";\nimport { useTreeKeyboardNavigation } from \"./use-tree-keyboard-navigation\";\n\nconst EMPTY_ARRAY: string[] = [];\n\nexport interface TreeHookProps {\n defaultSelected?: string[];\n groupSelection: GroupSelection;\n onChange: TreeNodeSelectionHandler;\n onHighlight?: (index: number) => void;\n selected?: string[];\n selection: TreeSelection;\n sourceWithIds: NormalisedTreeSourceNode[];\n}\n\nexport const useTree = ({\n defaultSelected,\n sourceWithIds,\n onChange,\n onHighlight: onHighlightProp,\n selected: selectedProp,\n selection,\n}: TreeHookProps) => {\n const lastSelection = useRef<string[]>(EMPTY_ARRAY);\n const dataHook = useHierarchicalData(sourceWithIds);\n\n const handleKeyboardNavigation = (evt: KeyboardEvent, nextIdx: number) => {\n selectionHook.listHandlers.onKeyboardNavigation?.(evt, nextIdx);\n };\n\n const { highlightedIdx, ...keyboardHook } = useKeyboardNavigation({\n treeNodes: dataHook.indexPositions,\n onHighlight: onHighlightProp,\n onKeyboardNavigation: handleKeyboardNavigation,\n selected: lastSelection.current,\n });\n\n const collapsibleHook = useCollapsibleGroups({\n collapsibleHeaders: true,\n highlightedIdx,\n treeNodes: dataHook.indexPositions,\n setVisibleData: dataHook.setData,\n source: dataHook.data,\n });\n\n const selectionHook = useSelection({\n defaultSelected,\n highlightedIdx,\n treeNodes: dataHook.indexPositions,\n onChange,\n selected: selectedProp,\n selection,\n });\n\n const treeNavigationHook = useTreeKeyboardNavigation({\n source: dataHook.data,\n highlightedIdx,\n hiliteItemAtIndex: keyboardHook.hiliteItemAtIndex,\n indexPositions: dataHook.indexPositions,\n });\n\n const handleClick = useCallback(\n (evt) => {\n collapsibleHook.listItemHandlers?.onClick(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listItemHandlers?.onClick?.(evt);\n }\n },\n [collapsibleHook, selectionHook],\n );\n\n const handleKeyDown = useCallback(\n (evt) => {\n keyboardHook.listProps.onKeyDown?.(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n collapsibleHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n treeNavigationHook.listHandlers.onKeyDown?.(evt);\n }\n },\n [\n collapsibleHook.listHandlers,\n keyboardHook.listProps,\n selectionHook.listHandlers,\n treeNavigationHook.listHandlers,\n ],\n );\n\n const getActiveDescendant = () =>\n highlightedIdx === undefined || highlightedIdx === -1\n ? undefined\n : dataHook.indexPositions[highlightedIdx]?.id;\n\n // We need this on reEntry for navigation hook to handle focus\n lastSelection.current = selectionHook.selected;\n\n const listProps = {\n \"aria-activedescendant\": getActiveDescendant(),\n onBlur: keyboardHook.listProps.onBlur,\n onFocus: keyboardHook.listProps.onFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: keyboardHook.listProps.onMouseDownCapture,\n onMouseLeave: keyboardHook.listProps.onMouseLeave,\n onMouseMove: keyboardHook.listProps.onMouseMove,\n };\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n focusVisible: keyboardHook.focusVisible,\n highlightedIdx,\n hiliteItemAtIndex: keyboardHook.hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected: selectionHook.selected,\n visibleData: dataHook.data,\n };\n};\n"],"names":["useRef","useHierarchicalData","useKeyboardNavigation","useCollapsibleGroups","useSelection","useTreeKeyboardNavigation","useCallback"],"mappings":";;;;;;;;;AAaA,MAAM,cAAwB,EAAC,CAAA;AAYxB,MAAM,UAAU,CAAC;AAAA,EACtB,eAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAa,EAAA,eAAA;AAAA,EACb,QAAU,EAAA,YAAA;AAAA,EACV,SAAA;AACF,CAAqB,KAAA;AACnB,EAAM,MAAA,aAAA,GAAgBA,aAAiB,WAAW,CAAA,CAAA;AAClD,EAAM,MAAA,QAAA,GAAWC,wCAAoB,aAAa,CAAA,CAAA;AAElD,EAAM,MAAA,wBAAA,GAA2B,CAAC,GAAA,EAAoB,OAAoB,KAAA;AACxE,IAAc,aAAA,CAAA,YAAA,CAAa,oBAAuB,GAAA,GAAA,EAAK,OAAO,CAAA,CAAA;AAAA,GAChE,CAAA;AAEA,EAAA,MAAM,EAAE,cAAA,EAAgB,GAAG,YAAA,KAAiBC,2CAAsB,CAAA;AAAA,IAChE,WAAW,QAAS,CAAA,cAAA;AAAA,IACpB,WAAa,EAAA,eAAA;AAAA,IACb,oBAAsB,EAAA,wBAAA;AAAA,IACtB,UAAU,aAAc,CAAA,OAAA;AAAA,GACzB,CAAA,CAAA;AAED,EAAA,MAAM,kBAAkBC,yCAAqB,CAAA;AAAA,IAC3C,kBAAoB,EAAA,IAAA;AAAA,IACpB,cAAA;AAAA,IACA,WAAW,QAAS,CAAA,cAAA;AAAA,IACpB,gBAAgB,QAAS,CAAA,OAAA;AAAA,IACzB,QAAQ,QAAS,CAAA,IAAA;AAAA,GAClB,CAAA,CAAA;AAED,EAAA,MAAM,gBAAgBC,yBAAa,CAAA;AAAA,IACjC,eAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAW,QAAS,CAAA,cAAA;AAAA,IACpB,QAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,SAAA;AAAA,GACD,CAAA,CAAA;AAED,EAAA,MAAM,qBAAqBC,mDAA0B,CAAA;AAAA,IACnD,QAAQ,QAAS,CAAA,IAAA;AAAA,IACjB,cAAA;AAAA,IACA,mBAAmB,YAAa,CAAA,iBAAA;AAAA,IAChC,gBAAgB,QAAS,CAAA,cAAA;AAAA,GAC1B,CAAA,CAAA;AAED,EAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,IAClB,CAAC,GAAQ,KAAA;AACP,MAAgB,eAAA,CAAA,gBAAA,EAAkB,QAAQ,GAAG,CAAA,CAAA;AAC7C,MAAI,IAAA,CAAC,IAAI,gBAAkB,EAAA;AACzB,QAAc,aAAA,CAAA,gBAAA,EAAkB,UAAU,GAAG,CAAA,CAAA;AAAA,OAC/C;AAAA,KACF;AAAA,IACA,CAAC,iBAAiB,aAAa,CAAA;AAAA,GACjC,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAAA,iBAAA;AAAA,IACpB,CAAC,GAAQ,KAAA;AACP,MAAa,YAAA,CAAA,SAAA,CAAU,YAAY,GAAG,CAAA,CAAA;AACtC,MAAI,IAAA,CAAC,IAAI,gBAAkB,EAAA;AACzB,QAAc,aAAA,CAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AAAA,OAC5C;AACA,MAAI,IAAA,CAAC,IAAI,gBAAkB,EAAA;AACzB,QAAgB,eAAA,CAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AAAA,OAC9C;AACA,MAAI,IAAA,CAAC,IAAI,gBAAkB,EAAA;AACzB,QAAmB,kBAAA,CAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AAAA,OACjD;AAAA,KACF;AAAA,IACA;AAAA,MACE,eAAgB,CAAA,YAAA;AAAA,MAChB,YAAa,CAAA,SAAA;AAAA,MACb,aAAc,CAAA,YAAA;AAAA,MACd,kBAAmB,CAAA,YAAA;AAAA,KACrB;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,mBAAA,GAAsB,MAC1B,cAAA,KAAmB,KAAa,CAAA,IAAA,cAAA,KAAmB,KAC/C,KACA,CAAA,GAAA,QAAA,CAAS,cAAe,CAAA,cAAc,CAAG,EAAA,EAAA,CAAA;AAG/C,EAAA,aAAA,CAAc,UAAU,aAAc,CAAA,QAAA,CAAA;AAEtC,EAAA,MAAM,SAAY,GAAA;AAAA,IAChB,yBAAyB,mBAAoB,EAAA;AAAA,IAC7C,MAAA,EAAQ,aAAa,SAAU,CAAA,MAAA;AAAA,IAC/B,OAAA,EAAS,aAAa,SAAU,CAAA,OAAA;AAAA,IAChC,SAAW,EAAA,aAAA;AAAA,IACX,kBAAA,EAAoB,aAAa,SAAU,CAAA,kBAAA;AAAA,IAC3C,YAAA,EAAc,aAAa,SAAU,CAAA,YAAA;AAAA,IACrC,WAAA,EAAa,aAAa,SAAU,CAAA,WAAA;AAAA,GACtC,CAAA;AAEA,EAAA,MAAM,gBAAmB,GAAA;AAAA,IACvB,OAAS,EAAA,WAAA;AAAA,GACX,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,cAAc,YAAa,CAAA,YAAA;AAAA,IAC3B,cAAA;AAAA,IACA,mBAAmB,YAAa,CAAA,iBAAA;AAAA,IAChC,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAU,aAAc,CAAA,QAAA;AAAA,IACxB,aAAa,QAAS,CAAA,IAAA;AAAA,GACxB,CAAA;AACF;;;;"}
@@ -21,14 +21,10 @@ const CycleStateButton = forwardRef(function CycleStateButton2({
21
21
  ...buttonProps
22
22
  }, forwardedRef) {
23
23
  const handleClick = useCallback(
24
- (evt) => {
24
+ async (evt) => {
25
25
  const nextValue = getNextValue(value, values);
26
26
  onChange?.(nextValue);
27
- onCommit?.(evt, nextValue).then((response) => {
28
- if (response !== true) {
29
- console.error(response);
30
- }
31
- });
27
+ onCommit?.(evt, nextValue);
32
28
  },
33
29
  [onChange, onCommit, value, values]
34
30
  );
@@ -1 +1 @@
1
- {"version":3,"file":"CycleStateButton.js","sources":["../../src/cycle-state-button/CycleStateButton.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport type { CommitResponse } from \"@vuu-ui/vuu-table-types\";\nimport type {\n VuuColumnDataType,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { ForwardedRef, forwardRef, SyntheticEvent, useCallback } from \"react\";\n\nconst classBase = \"vuuCycleStateButton\";\n\nexport type CycleStateCommitHandler = (\n evt: SyntheticEvent,\n value: VuuRowDataItemType,\n) => CommitResponse;\n\nexport interface CycleStateButtonProps extends Omit<ButtonProps, \"onChange\"> {\n onChange?: (value: VuuRowDataItemType) => void;\n onCommit?: CycleStateCommitHandler;\n values: string[];\n value: string;\n}\n\nconst getNextValue = (value: string, valueList: string[]) => {\n const index = valueList\n .map((v) => v.toUpperCase())\n .indexOf(value.toUpperCase());\n if (index === valueList.length - 1) {\n return valueList[0];\n } else {\n return valueList[index + 1];\n }\n};\n\nexport const CycleStateButton = forwardRef(function CycleStateButton(\n {\n className,\n onChange,\n onCommit,\n value = \"\",\n values,\n ...buttonProps\n }: CycleStateButtonProps,\n forwardedRef: ForwardedRef<HTMLButtonElement>,\n) {\n const handleClick = useCallback(\n (evt: SyntheticEvent<HTMLButtonElement>) => {\n const nextValue = getNextValue(value, values);\n onChange?.(nextValue);\n onCommit?.(evt, nextValue as VuuColumnDataType).then((response) => {\n if (response !== true) {\n console.error(response);\n }\n });\n },\n [onChange, onCommit, value, values],\n );\n\n return (\n <Button\n {...buttonProps}\n className={cx(\n classBase,\n className,\n `${classBase}-${value.toLowerCase()}`,\n )}\n onClick={handleClick}\n ref={forwardedRef}\n >\n {value}\n </Button>\n );\n});\n"],"names":["CycleStateButton"],"mappings":";;;;;AASA,MAAM,SAAY,GAAA,qBAAA,CAAA;AAclB,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,SAAwB,KAAA;AAC3D,EAAA,MAAM,KAAQ,GAAA,SAAA,CACX,GAAI,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,WAAY,EAAC,CAC1B,CAAA,OAAA,CAAQ,KAAM,CAAA,WAAA,EAAa,CAAA,CAAA;AAC9B,EAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,IAAA,OAAO,UAAU,CAAC,CAAA,CAAA;AAAA,GACb,MAAA;AACL,IAAO,OAAA,SAAA,CAAU,QAAQ,CAAC,CAAA,CAAA;AAAA,GAC5B;AACF,CAAA,CAAA;AAEa,MAAA,gBAAA,GAAmB,UAAW,CAAA,SAASA,iBAClD,CAAA;AAAA,EACE,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAQ,GAAA,EAAA;AAAA,EACR,MAAA;AAAA,EACA,GAAG,WAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,GAA2C,KAAA;AAC1C,MAAM,MAAA,SAAA,GAAY,YAAa,CAAA,KAAA,EAAO,MAAM,CAAA,CAAA;AAC5C,MAAA,QAAA,GAAW,SAAS,CAAA,CAAA;AACpB,MAAA,QAAA,GAAW,GAAK,EAAA,SAA8B,CAAE,CAAA,IAAA,CAAK,CAAC,QAAa,KAAA;AACjE,QAAA,IAAI,aAAa,IAAM,EAAA;AACrB,UAAA,OAAA,CAAQ,MAAM,QAAQ,CAAA,CAAA;AAAA,SACxB;AAAA,OACD,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,QAAA,EAAU,QAAU,EAAA,KAAA,EAAO,MAAM,CAAA;AAAA,GACpC,CAAA;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,SAAW,EAAA,EAAA;AAAA,QACT,SAAA;AAAA,QACA,SAAA;AAAA,QACA,CAAG,EAAA,SAAS,CAAI,CAAA,EAAA,KAAA,CAAM,aAAa,CAAA,CAAA;AAAA,OACrC;AAAA,MACA,OAAS,EAAA,WAAA;AAAA,MACT,GAAK,EAAA,YAAA;AAAA,MAEJ,QAAA,EAAA,KAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"CycleStateButton.js","sources":["../../src/cycle-state-button/CycleStateButton.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport type {\n VuuColumnDataType,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { ForwardedRef, forwardRef, SyntheticEvent, useCallback } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuCycleStateButton\";\n\nexport interface CycleStateButtonProps extends Omit<ButtonProps, \"onChange\"> {\n onChange?: (value: VuuRowDataItemType) => void;\n onCommit?: CommitHandler<HTMLButtonElement>;\n values: string[];\n value: string;\n}\n\nconst getNextValue = (value: string, valueList: string[]) => {\n const index = valueList\n .map((v) => v.toUpperCase())\n .indexOf(value.toUpperCase());\n if (index === valueList.length - 1) {\n return valueList[0];\n } else {\n return valueList[index + 1];\n }\n};\n\nexport const CycleStateButton = forwardRef(function CycleStateButton(\n {\n className,\n onChange,\n onCommit,\n value = \"\",\n values,\n ...buttonProps\n }: CycleStateButtonProps,\n forwardedRef: ForwardedRef<HTMLButtonElement>,\n) {\n const handleClick = useCallback(\n async (evt: SyntheticEvent<HTMLButtonElement>) => {\n const nextValue = getNextValue(value, values);\n onChange?.(nextValue);\n onCommit?.(evt, nextValue as VuuColumnDataType);\n },\n [onChange, onCommit, value, values],\n );\n\n return (\n <Button\n {...buttonProps}\n className={cx(\n classBase,\n className,\n `${classBase}-${value.toLowerCase()}`,\n )}\n onClick={handleClick}\n ref={forwardedRef}\n >\n {value}\n </Button>\n );\n});\n"],"names":["CycleStateButton"],"mappings":";;;;;AASA,MAAM,SAAY,GAAA,qBAAA,CAAA;AASlB,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,SAAwB,KAAA;AAC3D,EAAA,MAAM,KAAQ,GAAA,SAAA,CACX,GAAI,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,WAAY,EAAC,CAC1B,CAAA,OAAA,CAAQ,KAAM,CAAA,WAAA,EAAa,CAAA,CAAA;AAC9B,EAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,IAAA,OAAO,UAAU,CAAC,CAAA,CAAA;AAAA,GACb,MAAA;AACL,IAAO,OAAA,SAAA,CAAU,QAAQ,CAAC,CAAA,CAAA;AAAA,GAC5B;AACF,CAAA,CAAA;AAEa,MAAA,gBAAA,GAAmB,UAAW,CAAA,SAASA,iBAClD,CAAA;AAAA,EACE,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAQ,GAAA,EAAA;AAAA,EACR,MAAA;AAAA,EACA,GAAG,WAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,OAAO,GAA2C,KAAA;AAChD,MAAM,MAAA,SAAA,GAAY,YAAa,CAAA,KAAA,EAAO,MAAM,CAAA,CAAA;AAC5C,MAAA,QAAA,GAAW,SAAS,CAAA,CAAA;AACpB,MAAA,QAAA,GAAW,KAAK,SAA8B,CAAA,CAAA;AAAA,KAChD;AAAA,IACA,CAAC,QAAA,EAAU,QAAU,EAAA,KAAA,EAAO,MAAM,CAAA;AAAA,GACpC,CAAA;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,SAAW,EAAA,EAAA;AAAA,QACT,SAAA;AAAA,QACA,SAAA;AAAA,QACA,CAAG,EAAA,SAAS,CAAI,CAAA,EAAA,KAAA,CAAM,aAAa,CAAA,CAAA;AAAA,OACrC;AAAA,MACA,OAAS,EAAA,WAAA;AAAA,MACT,GAAK,EAAA,YAAA;AAAA,MAEJ,QAAA,EAAA,KAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,CAAC;;;;"}
@@ -1,51 +1,54 @@
1
- import { useLayoutEffectSkipFirst, dispatchCustomEvent } from '@vuu-ui/vuu-utils';
2
- import { useState, useRef, useCallback } from 'react';
1
+ import { dispatchCustomEvent, getTypedValue } from '@vuu-ui/vuu-utils';
2
+ import { useState, useRef, useMemo, useCallback } from 'react';
3
3
 
4
- const WarnCommit = () => {
5
- console.warn(
6
- "onCommit handler has not been provided to InputCell cell renderer"
7
- );
8
- return Promise.resolve(true);
9
- };
4
+ const stringValueOf = (value) => value?.toString() ?? "";
10
5
  const useEditableText = ({
11
6
  clientSideEditValidationCheck,
12
- initialValue,
13
- onCommit,
14
- type
7
+ value,
8
+ onEdit,
9
+ type = "string"
15
10
  }) => {
16
- const [message, setMessage] = useState();
17
- const [value, setValue] = useState(initialValue);
18
- const initialValueRef = useRef(initialValue);
11
+ const [editState, setEditState] = useState({
12
+ value: stringValueOf(value)
13
+ });
14
+ const initialValueRef = useRef(value?.toString() ?? "");
19
15
  const isDirtyRef = useRef(false);
20
- const hasCommittedRef = useRef(false);
21
- useLayoutEffectSkipFirst(() => {
22
- setValue(initialValue);
23
- }, [initialValue]);
16
+ useMemo(() => {
17
+ if (initialValueRef.current !== value?.toString()) {
18
+ initialValueRef.current = stringValueOf(value);
19
+ setEditState({ message: "", value: stringValueOf(value) });
20
+ console.log("initial value changed to: ", value);
21
+ }
22
+ }, [value]);
24
23
  const commit = useCallback(
25
- (target) => {
24
+ async (target) => {
25
+ const { value: value2 } = editState;
26
26
  if (isDirtyRef.current) {
27
- hasCommittedRef.current = true;
28
- const result = clientSideEditValidationCheck?.(value);
27
+ const result = clientSideEditValidationCheck?.(value2, "*");
29
28
  if (result?.ok === false) {
30
- setMessage(result?.messages?.join(","));
29
+ setEditState((state) => ({
30
+ ...state,
31
+ message: result?.messages?.join(",")
32
+ }));
31
33
  } else {
32
- setMessage(void 0);
33
- console.log(`commit value ${value}`);
34
- onCommit(value).then((response) => {
35
- if (response === true) {
36
- isDirtyRef.current = false;
37
- dispatchCustomEvent(target, "vuu-commit");
38
- } else {
39
- setMessage(response);
40
- }
41
- });
34
+ setEditState((state) => ({ ...state, message: void 0 }));
35
+ const response = await onEdit?.(
36
+ { editType: "commit", value: value2, isValid: true },
37
+ "commit"
38
+ );
39
+ if (response === true) {
40
+ isDirtyRef.current = false;
41
+ initialValueRef.current = value2;
42
+ dispatchCustomEvent(target, "vuu-commit");
43
+ } else if (typeof response === "string") {
44
+ setEditState((state) => ({ ...state, message: response }));
45
+ }
42
46
  }
43
47
  } else {
44
48
  dispatchCustomEvent(target, "vuu-commit");
45
- hasCommittedRef.current = false;
46
49
  }
47
50
  },
48
- [clientSideEditValidationCheck, onCommit, value]
51
+ [clientSideEditValidationCheck, editState, onEdit]
49
52
  );
50
53
  const handleKeyDown = useCallback(
51
54
  (evt) => {
@@ -55,13 +58,22 @@ const useEditableText = ({
55
58
  evt.stopPropagation();
56
59
  } else if (evt.key === "Escape") {
57
60
  if (isDirtyRef.current) {
61
+ const { value: previousValue } = editState;
58
62
  isDirtyRef.current = false;
59
- setMessage(void 0);
60
- setValue(initialValueRef.current);
63
+ setEditState({ value: initialValueRef.current, message: void 0 });
64
+ onEdit?.(
65
+ {
66
+ editType: "cancel",
67
+ isValid: true,
68
+ previousValue,
69
+ value: initialValueRef.current
70
+ },
71
+ "cancel"
72
+ );
61
73
  }
62
74
  }
63
75
  },
64
- [commit]
76
+ [commit, editState, onEdit]
65
77
  );
66
78
  const handleBlur = useCallback(
67
79
  (evt) => {
@@ -73,31 +85,39 @@ const useEditableText = ({
73
85
  );
74
86
  const handleChange = useCallback(
75
87
  (evt) => {
76
- let typedValue = evt.target.value;
77
- if (type === "number" && !isNaN(parseFloat(typedValue))) {
78
- typedValue = parseFloat(typedValue);
79
- }
80
- isDirtyRef.current = value !== initialValueRef.current;
81
- setValue(typedValue);
82
- if (hasCommittedRef.current && value !== void 0) {
83
- const result = clientSideEditValidationCheck?.(value);
84
- if (result?.ok === false) {
85
- setMessage(result.messages?.join(","));
86
- }
88
+ const { value: value2 } = evt.target;
89
+ const typedValue = getTypedValue(value2, type);
90
+ console.log(
91
+ `[useEditableText] handleChange '${value2}' typedValue ${typedValue}
92
+ initial value ${initialValueRef.current}
93
+ `
94
+ );
95
+ isDirtyRef.current = value2 !== initialValueRef.current;
96
+ const result = clientSideEditValidationCheck?.(value2, "change");
97
+ console.log({ result, value: value2 });
98
+ setEditState({ value: value2 });
99
+ onEdit?.(
100
+ { editType: "change", isValid: result?.ok !== false, value: value2 },
101
+ "change"
102
+ );
103
+ if (result?.ok === false) {
104
+ console.log("cell fails validation");
105
+ setEditState({ value: value2, message: result.messages?.join(",") });
87
106
  }
88
107
  },
89
- [clientSideEditValidationCheck, type, value]
108
+ [clientSideEditValidationCheck, onEdit, type]
90
109
  );
91
110
  return {
111
+ //TODO why are we detecting commit here, why not use VuuInput ?
92
112
  inputProps: {
93
113
  onBlur: handleBlur,
94
114
  onKeyDown: handleKeyDown
95
115
  },
96
116
  onChange: handleChange,
97
- value: value ?? "",
98
- warningMessage: message
117
+ value: editState.value,
118
+ warningMessage: editState.message
99
119
  };
100
120
  };
101
121
 
102
- export { WarnCommit, useEditableText };
122
+ export { useEditableText };
103
123
  //# sourceMappingURL=useEditableText.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport { DataItemCommitHandler } from \"@vuu-ui/vuu-table-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { dispatchCustomEvent } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nexport const WarnCommit = (): Promise<true> => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\",\n );\n return Promise.resolve(true);\n};\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: DataValueValidationChecker;\n initialValue?: T;\n onCommit: DataItemCommitHandler<T>;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\nexport const useEditableText = <T extends string | number = string>({\n clientSideEditValidationCheck,\n initialValue,\n onCommit,\n type,\n}: EditableTextHookProps<T>) => {\n const [message, setMessage] = useState<string | undefined>();\n const [value, setValue] = useState<T | undefined>(initialValue);\n const initialValueRef = useRef<T | undefined>(initialValue);\n const isDirtyRef = useRef(false);\n const hasCommittedRef = useRef(false);\n\n useLayoutEffectSkipFirst(() => {\n //TODO this isn't right, review the state we're using\n setValue(initialValue);\n }, [initialValue]);\n\n const commit = useCallback(\n (target: HTMLElement) => {\n if (isDirtyRef.current) {\n hasCommittedRef.current = true;\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result?.messages?.join(\",\"));\n } else {\n setMessage(undefined);\n console.log(`commit value ${value}`);\n onCommit(value as T).then((response) => {\n if (response === true) {\n isDirtyRef.current = false;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else {\n setMessage(response);\n }\n });\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n hasCommittedRef.current = false;\n }\n },\n [clientSideEditValidationCheck, onCommit, value],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n isDirtyRef.current = false;\n setMessage(undefined);\n setValue(initialValueRef.current);\n }\n }\n },\n [commit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n let typedValue: VuuRowDataItemType = (evt.target as HTMLInputElement)\n .value;\n if (type === \"number\" && !isNaN(parseFloat(typedValue))) {\n typedValue = parseFloat(typedValue);\n }\n isDirtyRef.current = value !== initialValueRef.current;\n setValue(typedValue as T);\n if (hasCommittedRef.current && value !== undefined) {\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result.messages?.join(\",\"));\n }\n }\n },\n [clientSideEditValidationCheck, type, value],\n );\n\n return {\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: value ?? \"\",\n warningMessage: message,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataItemEditHandler } from \"@vuu-ui/vuu-table-types\";\nimport { dispatchCustomEvent, getTypedValue } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: DataValueValidationChecker;\n value?: T;\n onEdit?: DataItemEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n message?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n clientSideEditValidationCheck,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n // console.log(\"initial value: \", initialValue);\n const [editState, setEditState] = useState<EditState>({\n value: stringValueOf(value),\n });\n // console.log(\"edit state: \", editState);\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState({ message: \"\", value: stringValueOf(value) });\n console.log(\"initial value changed to: \", value);\n }\n }, [value]);\n\n const commit = useCallback(\n async (target: HTMLElement) => {\n const { value } = editState;\n if (isDirtyRef.current) {\n const result = clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n } else {\n setEditState((state) => ({ ...state, message: undefined }));\n const response = await onEdit?.(\n { editType: \"commit\", value, isValid: true },\n \"commit\",\n );\n if (response === true) {\n isDirtyRef.current = false;\n initialValueRef.current = value;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else if (typeof response === \"string\") {\n setEditState((state) => ({ ...state, message: response }));\n }\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n }\n },\n [clientSideEditValidationCheck, editState, onEdit],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({ value: initialValueRef.current, message: undefined });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n }\n }\n },\n [commit, editState, onEdit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n const typedValue = getTypedValue(value, type);\n console.log(\n `[useEditableText] handleChange '${value}' typedValue ${typedValue}\n initial value ${initialValueRef.current}\n `,\n );\n isDirtyRef.current = value !== initialValueRef.current;\n const result = clientSideEditValidationCheck?.(value, \"change\");\n console.log({ result, value });\n setEditState({ value });\n\n onEdit?.(\n { editType: \"change\", isValid: result?.ok !== false, value },\n \"change\",\n );\n if (result?.ok === false) {\n console.log(\"cell fails validation\");\n setEditState({ value, message: result.messages?.join(\",\") });\n }\n },\n [clientSideEditValidationCheck, onEdit, type],\n );\n\n return {\n //TODO why are we detecting commit here, why not use VuuInput ?\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["value"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var toggleIconCss = ".vuuToggleIconButton {\n &.saltButton {\n &:active {\n --saltButton-background-active: transparent;\n }\n &:hover {\n --saltButton-background-hover: transparent;\n }\n .vuuIcon {\n --vuu-icon-height: 18px;\n --vuu-icon-left: -3px;\n --vuu-icon-width: 18px;\n &:after {\n transition: transform 0.1s linear;\n }\n &[data-icon=\"triangle-down\"]:after {\n --vuu-icon-left: -1px;\n --vuu-icon-top: -3px;\n }\n }\n border: none;\n border-radius: 0;\n height: 18px;\n left: 0;\n min-width: 16px;\n padding: 0;\n width: 18px;\n }\n}\n\n.vuuTableGroupCell:hover {\n .vuuToggleIconButton {\n .vuuIcon:after {\n --vuu-icon-color: var(--salt-palette-interact-cta-background-hover);\n }\n }\n}\n";
2
+
3
+ export { toggleIconCss as default };
4
+ //# sourceMappingURL=ToggleIconButton.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToggleIconButton.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,36 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import cx from 'clsx';
5
+ import { IconButton } from './IconButton.js';
6
+ import toggleIconCss from './ToggleIconButton.css.js';
7
+
8
+ const classBase = "vuuToggleIconButton";
9
+ const ToggleIconButton = ({
10
+ className,
11
+ isExpanded,
12
+ size = 7,
13
+ variant = "secondary",
14
+ ...props
15
+ }) => {
16
+ const targetWindow = useWindow();
17
+ useComponentCssInjection({
18
+ testId: "vuu-toggle-icon-button",
19
+ css: toggleIconCss,
20
+ window: targetWindow
21
+ });
22
+ const icon = isExpanded ? "triangle-down" : "triangle-right";
23
+ return /* @__PURE__ */ jsx(
24
+ IconButton,
25
+ {
26
+ ...props,
27
+ className: cx(classBase, className),
28
+ icon,
29
+ size,
30
+ variant
31
+ }
32
+ );
33
+ };
34
+
35
+ export { ToggleIconButton };
36
+ //# sourceMappingURL=ToggleIconButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToggleIconButton.js","sources":["../../src/icon-button/ToggleIconButton.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { IconButton, IconButtonProps } from \"./IconButton\";\n\nimport toggleIconCss from \"./ToggleIconButton.css\";\n\nconst classBase = \"vuuToggleIconButton\";\n\nexport interface ToggleIconButtonProps extends Omit<IconButtonProps, \"icon\"> {\n isExpanded: boolean;\n}\n\nexport const ToggleIconButton = ({\n className,\n isExpanded,\n size = 7,\n variant = \"secondary\",\n ...props\n}: ToggleIconButtonProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toggle-icon-button\",\n css: toggleIconCss,\n window: targetWindow,\n });\n\n const icon = isExpanded ? \"triangle-down\" : \"triangle-right\";\n return (\n <IconButton\n {...props}\n className={cx(classBase, className)}\n icon={icon}\n size={size}\n variant={variant}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAOA,MAAM,SAAY,GAAA,qBAAA,CAAA;AAMX,MAAM,mBAAmB,CAAC;AAAA,EAC/B,SAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAO,GAAA,CAAA;AAAA,EACP,OAAU,GAAA,WAAA;AAAA,EACV,GAAG,KAAA;AACL,CAA6B,KAAA;AAC3B,EAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAA,aAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAM,MAAA,IAAA,GAAO,aAAa,eAAkB,GAAA,gBAAA,CAAA;AAC5C,EACE,uBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ;;;;"}
package/esm/index.js CHANGED
@@ -19,11 +19,12 @@ export { DragDropState } from './drag-drop/DragDropState.js';
19
19
  export { useDragDrop } from './drag-drop/useDragDrop.js';
20
20
  export { NOT_HIDDEN, NOT_OVERFLOWED, cloneElement, constrainRect, dimensions, dropTargetsDebugString, getIndexOfDraggedItem, getItemById, getItemParentContainer, getNextDropTarget, getScrollableContainer, isContainerScrollable, measureDropTargets, measureElementSizeAndPosition, mutateDropTargetsSwitchDropTargetPosition, removeDraggedItem } from './drag-drop/drop-target-utils.js';
21
21
  export { useGlobalDragDrop } from './drag-drop/useGlobalDragDrop.js';
22
- export { WarnCommit, useEditableText } from './editable/useEditableText.js';
22
+ export { useEditableText } from './editable/useEditableText.js';
23
23
  export { EditableLabel, NullEditAPI } from './editable-label/EditableLabel.js';
24
24
  export { ExpandoInput } from './expando-input/ExpandoInput.js';
25
25
  export { Icon } from './icon-button/Icon.js';
26
26
  export { IconButton } from './icon-button/IconButton.js';
27
+ export { ToggleIconButton } from './icon-button/ToggleIconButton.js';
27
28
  export { TablePicker } from './instrument-picker/TablePicker.js';
28
29
  export { TableSearch } from './table-search/TableSearch.js';
29
30
  export { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Enter, Escape, Home, PageDown, PageUp, Space, isCharacterKey, isNavigationKey } from './list/common-hooks/keyUtils.js';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.js","sources":["../../src/tree/Tree.tsx"],"sourcesContent":["import { useForkRef, useIdMemo as useId } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n ForwardedRef,\n HTMLAttributes,\n MouseEvent,\n forwardRef,\n useRef,\n} from \"react\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport type { NormalisedTreeSourceNode, TreeSourceNode } from \"./treeTypes\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n groupSelectionEnabled,\n} from \"./use-selection\";\nimport { useViewportTracking } from \"./use-viewport-tracking\";\nimport { useTree } from \"./useTree\";\n\nimport treeCss from \"./Tree.css\";\n\nconst classBase = \"vuuTree\";\n\ntype Indexer = {\n value: number;\n};\n\nexport interface TreeNodeProps extends HTMLAttributes<HTMLLIElement> {\n idx?: number;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport const TreeNode = ({ children, idx, ...props }: TreeNodeProps) => {\n return <li {...props}>{children}</li>;\n};\n\nexport interface TreeProps extends HTMLAttributes<HTMLUListElement> {\n allowDragDrop?: boolean;\n defaultSelected?: any;\n groupSelection?: GroupSelection;\n onHighlight?: (index: number) => void;\n onSelectionChange?: (selected: TreeSourceNode[]) => void;\n revealSelected?: boolean;\n selected?: string[];\n selection?: TreeSelection;\n source: TreeSourceNode[];\n}\n\nexport const Tree = forwardRef(function Tree(\n {\n allowDragDrop,\n className,\n defaultSelected,\n groupSelection = \"none\",\n id: idProp,\n onHighlight,\n onSelectionChange,\n revealSelected,\n selected: selectedProp,\n selection = \"single\",\n source,\n ...htmlAttributes\n }: TreeProps,\n forwardedRef: ForwardedRef<HTMLUListElement>\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tree\",\n css: treeCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const rootRef = useRef<HTMLUListElement>(null);\n // returns the full source data\n const [, sourceWithIds, sourceItemById] = useItemsWithIds(source, id, {\n revealSelected: revealSelected\n ? selectedProp ?? defaultSelected ?? false\n : undefined,\n });\n\n const handleSelectionChange: TreeNodeSelectionHandler = (evt, selected) => {\n if (onSelectionChange) {\n const sourceItems = selected\n .map((id) => sourceItemById(id))\n .filter((sourceItem) => sourceItem !== undefined) as TreeSourceNode[];\n onSelectionChange(sourceItems);\n }\n };\n\n const {\n focusVisible,\n highlightedIdx,\n hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected,\n visibleData,\n } = useTree({\n defaultSelected,\n groupSelection,\n onChange: handleSelectionChange,\n onHighlight,\n selected: selectedProp,\n selection,\n sourceWithIds,\n });\n\n // const isScrolling = useViewportTracking(root, highlightedIdx);\n useViewportTracking(rootRef, highlightedIdx);\n\n const defaultItemHandlers = {\n onMouseEnter: (evt: MouseEvent) => {\n // if (!isScrolling.current) {\n const targetEl = evt.target as HTMLElement;\n const idx = closestListItemIndex(targetEl);\n hiliteItemAtIndex(idx);\n // onMouseEnterListItem && onMouseEnterListItem(evt, idx);\n // }\n },\n };\n\n const propsCommonToAllListItems = {\n ...defaultItemHandlers,\n ...listItemHandlers,\n role: \"treeitem\",\n };\n const allowGroupSelect = groupSelectionEnabled(groupSelection);\n\n /**\n * Add a ListItem from source item\n */\n function addLeafNode(\n list: JSX.Element[],\n item: NormalisedTreeSourceNode,\n idx: Indexer\n ) {\n list.push(\n <TreeNode\n {...propsCommonToAllListItems}\n {...getListItemProps(item, idx, highlightedIdx, selected, focusVisible)}\n >\n {item.icon ? (\n <span className={`${classBase}Node-icon`} data-icon={item.icon} />\n ) : null}\n <span>{item.label}</span>\n </TreeNode>\n );\n idx.value += 1;\n }\n\n function addGroupNode(\n list: JSX.Element[],\n child: NormalisedTreeSourceNode,\n idx: Indexer,\n id: string,\n title: string\n ) {\n const { value: i } = idx;\n idx.value += 1;\n list.push(\n <TreeNode\n {...listItemHandlers}\n aria-expanded={child.expanded}\n aria-level={child.level}\n aria-selected={selected.includes(id) || undefined}\n className={cx(`${classBase}Node`, {\n focusVisible: focusVisible === i,\n [`${classBase}Node-toggle`]: !allowGroupSelect,\n })}\n data-idx={i}\n data-highlighted={i === highlightedIdx || undefined}\n data-selectable\n id={id}\n key={`header-${i}`}\n >\n {allowGroupSelect ? (\n <div className={`${classBase}Node-label`}>\n <span className={`${classBase}Node-toggle`} />\n {title}\n </div>\n ) : (\n <div className={`${classBase}Node-label`}>\n {child.icon ? (\n <span\n className={`${classBase}Node-icon`}\n data-icon={child.icon}\n />\n ) : null}\n <span>{title}</span>\n </div>\n )}\n <ul role=\"group\">\n {isExpanded(child) ? renderSourceContent(child.childNodes, idx) : \"\"}\n </ul>\n </TreeNode>\n );\n }\n\n function renderSourceContent(\n items: NormalisedTreeSourceNode[],\n idx = { value: 0 }\n ) {\n if (items?.length > 0) {\n const listItems: JSX.Element[] = [];\n for (const item of items) {\n if (item.childNodes) {\n addGroupNode(listItems, item, idx, item.id, item.label);\n } else {\n addLeafNode(listItems, item, idx);\n }\n }\n return listItems;\n }\n }\n\n return (\n <ul\n {...htmlAttributes}\n {...listProps}\n className={cx(classBase, className)}\n id={`Tree-${id}`}\n ref={useForkRef<HTMLUListElement>(rootRef, forwardedRef)}\n role=\"tree\"\n tabIndex={0}\n >\n {renderSourceContent(visibleData)}\n </ul>\n );\n});\n\nconst getListItemProps = (\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n highlightedIdx: number,\n selected: string[],\n focusVisible: number,\n className?: string\n) => ({\n id: item.id,\n key: item.id,\n \"aria-level\": item.level,\n \"aria-selected\": selected.includes(item.id) || undefined,\n \"data-idx\": idx.value,\n \"data-highlighted\": idx.value === highlightedIdx || undefined,\n className: cx(\"vuuTreeNode\", className, {\n focusVisible: focusVisible === idx.value,\n }),\n});\n\nTree.displayName = \"Tree\";\n"],"names":["Tree","useId","selected","id"],"mappings":"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"}
1
+ {"version":3,"file":"Tree.js","sources":["../../src/tree/Tree.tsx"],"sourcesContent":["import { useForkRef, useIdMemo as useId } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n ForwardedRef,\n HTMLAttributes,\n MouseEvent,\n forwardRef,\n useRef,\n} from \"react\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n groupSelectionEnabled,\n} from \"./use-selection\";\nimport { useViewportTracking } from \"./use-viewport-tracking\";\nimport { useTree } from \"./useTree\";\n\nimport treeCss from \"./Tree.css\";\nimport { NormalisedTreeSourceNode, TreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuTree\";\n\ntype Indexer = {\n value: number;\n};\n\nexport interface TreeNodeProps extends HTMLAttributes<HTMLLIElement> {\n idx?: number;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport const TreeNode = ({ children, idx, ...props }: TreeNodeProps) => {\n return <li {...props}>{children}</li>;\n};\n\nexport interface TreeProps extends HTMLAttributes<HTMLUListElement> {\n allowDragDrop?: boolean;\n defaultSelected?: any;\n groupSelection?: GroupSelection;\n onHighlight?: (index: number) => void;\n onSelectionChange?: (selected: TreeSourceNode[]) => void;\n revealSelected?: boolean;\n selected?: string[];\n selection?: TreeSelection;\n source: TreeSourceNode[];\n}\n\nexport const Tree = forwardRef(function Tree(\n {\n allowDragDrop,\n className,\n defaultSelected,\n groupSelection = \"none\",\n id: idProp,\n onHighlight,\n onSelectionChange,\n revealSelected,\n selected: selectedProp,\n selection = \"single\",\n source,\n ...htmlAttributes\n }: TreeProps,\n forwardedRef: ForwardedRef<HTMLUListElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tree\",\n css: treeCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const rootRef = useRef<HTMLUListElement>(null);\n // returns the full source data\n const [, sourceWithIds, sourceItemById] = useItemsWithIds(source, id, {\n revealSelected: revealSelected\n ? (selectedProp ?? defaultSelected ?? false)\n : undefined,\n });\n\n const handleSelectionChange: TreeNodeSelectionHandler = (evt, selected) => {\n if (onSelectionChange) {\n const sourceItems = selected\n .map((id) => sourceItemById(id))\n .filter((sourceItem) => sourceItem !== undefined) as TreeSourceNode[];\n onSelectionChange(sourceItems);\n }\n };\n\n const {\n focusVisible,\n highlightedIdx,\n hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected,\n visibleData,\n } = useTree({\n defaultSelected,\n groupSelection,\n onChange: handleSelectionChange,\n onHighlight,\n selected: selectedProp,\n selection,\n sourceWithIds,\n });\n\n // const isScrolling = useViewportTracking(root, highlightedIdx);\n useViewportTracking(rootRef, highlightedIdx);\n\n const defaultItemHandlers = {\n onMouseEnter: (evt: MouseEvent) => {\n // if (!isScrolling.current) {\n const targetEl = evt.target as HTMLElement;\n const idx = closestListItemIndex(targetEl);\n hiliteItemAtIndex(idx);\n // onMouseEnterListItem && onMouseEnterListItem(evt, idx);\n // }\n },\n };\n\n const propsCommonToAllListItems = {\n ...defaultItemHandlers,\n ...listItemHandlers,\n role: \"treeitem\",\n };\n const allowGroupSelect = groupSelectionEnabled(groupSelection);\n\n /**\n * Add a ListItem from source item\n */\n function addLeafNode(\n list: JSX.Element[],\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n ) {\n list.push(\n <TreeNode\n {...propsCommonToAllListItems}\n {...getListItemProps(item, idx, highlightedIdx, selected, focusVisible)}\n >\n {item.icon ? (\n <span className={`${classBase}Node-icon`} data-icon={item.icon} />\n ) : null}\n <span>{item.label}</span>\n </TreeNode>,\n );\n idx.value += 1;\n }\n\n function addGroupNode(\n list: JSX.Element[],\n child: NormalisedTreeSourceNode,\n idx: Indexer,\n id: string,\n title: string,\n ) {\n const { value: i } = idx;\n idx.value += 1;\n list.push(\n <TreeNode\n {...listItemHandlers}\n aria-expanded={child.expanded}\n aria-level={child.level}\n aria-selected={selected.includes(id) || undefined}\n className={cx(`${classBase}Node`, {\n focusVisible: focusVisible === i,\n [`${classBase}Node-toggle`]: !allowGroupSelect,\n })}\n data-idx={i}\n data-highlighted={i === highlightedIdx || undefined}\n data-selectable\n id={id}\n key={`header-${i}`}\n >\n {allowGroupSelect ? (\n <div className={`${classBase}Node-label`}>\n <span className={`${classBase}Node-toggle`} />\n {title}\n </div>\n ) : (\n <div className={`${classBase}Node-label`}>\n {child.icon ? (\n <span\n className={`${classBase}Node-icon`}\n data-icon={child.icon}\n />\n ) : null}\n <span>{title}</span>\n </div>\n )}\n <ul role=\"group\">\n {isExpanded(child) ? renderSourceContent(child.childNodes, idx) : \"\"}\n </ul>\n </TreeNode>,\n );\n }\n\n function renderSourceContent(\n items: NormalisedTreeSourceNode[],\n idx = { value: 0 },\n ) {\n if (items?.length > 0) {\n const listItems: JSX.Element[] = [];\n for (const item of items) {\n if (item.childNodes) {\n addGroupNode(listItems, item, idx, item.id, item.label);\n } else {\n addLeafNode(listItems, item, idx);\n }\n }\n return listItems;\n }\n }\n\n return (\n <ul\n {...htmlAttributes}\n {...listProps}\n className={cx(classBase, className)}\n id={`Tree-${id}`}\n ref={useForkRef<HTMLUListElement>(rootRef, forwardedRef)}\n role=\"tree\"\n tabIndex={0}\n >\n {renderSourceContent(visibleData)}\n </ul>\n );\n});\n\nconst getListItemProps = (\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n highlightedIdx: number,\n selected: string[],\n focusVisible: number,\n className?: string,\n) => ({\n id: item.id,\n key: item.id,\n \"aria-level\": item.level,\n \"aria-selected\": selected.includes(item.id) || undefined,\n \"data-idx\": idx.value,\n \"data-highlighted\": idx.value === highlightedIdx || undefined,\n className: cx(\"vuuTreeNode\", className, {\n focusVisible: focusVisible === idx.value,\n }),\n});\n\nTree.displayName = \"Tree\";\n"],"names":["Tree","useId","selected","id"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hierarchical-data-utils.js","sources":["../../src/tree/hierarchical-data-utils.ts"],"sourcesContent":["import { NonLeafNode, NormalisedTreeSourceNode } from \"./treeTypes\";\n\nexport const getNodeParentPath = ({ id }: NormalisedTreeSourceNode) => {\n let pos = id.lastIndexOf(\"-\");\n if (pos !== -1) {\n // using the built-in hierarchical id scheme\n // rootId-n-n.n\n const path = id.slice(pos + 1);\n const steps = path.split(\".\");\n if (steps.length === 1) {\n return null;\n } else {\n steps.pop();\n return `${id.slice(0, pos)}-${steps.join(\".\")}`;\n }\n } else if ((pos = id.lastIndexOf(\"/\")) !== -1) {\n // using a path scheme step/step/step\n return id.slice(0, pos);\n }\n};\n\nexport const isGroupNode = (node: NormalisedTreeSourceNode) =>\n node.childNodes !== undefined;\nexport const isCollapsibleGroupNode = (node: NormalisedTreeSourceNode) =>\n isGroupNode(node) && node.expanded !== undefined;\nexport const isHeader = (node: NormalisedTreeSourceNode) =>\n node.header === true;\n\nconst PATH_SEPARATORS = new Set([\".\", \"/\"]);\n\nconst isDescendantOf = (\n node: NormalisedTreeSourceNode,\n targetPath: string\n): node is NonLeafNode => {\n if (!targetPath.startsWith(node.id)) {\n return false;\n } else {\n return PATH_SEPARATORS.has(targetPath.charAt(node.id.length));\n }\n};\n\nexport const getNodeById = (\n nodes: NormalisedTreeSourceNode[],\n id: string\n): NormalisedTreeSourceNode | undefined => {\n for (const node of nodes) {\n if (node.id === id) {\n return node;\n } else if (isDescendantOf(node, id)) {\n return getNodeById(node.childNodes, id);\n }\n }\n};\n\nexport const getIndexOfNode = (\n treeNodes: NormalisedTreeSourceNode[],\n node: NormalisedTreeSourceNode\n) => {\n const id = typeof node === \"string\" ? node : node.id;\n for (let i = 0; i < treeNodes.length; i++) {\n if (treeNodes[i].id === id) {\n return i;\n }\n }\n};\n\nexport const replaceNode = (\n nodes: NormalisedTreeSourceNode[],\n id: string,\n props: Partial<NormalisedTreeSourceNode>\n): NormalisedTreeSourceNode[] => {\n let childNodes;\n const newNodes = nodes.map((node) => {\n if (node.id === id) {\n return {\n ...node,\n ...props,\n };\n } else if (isDescendantOf(node, id)) {\n childNodes = replaceNode(node.childNodes, id, props);\n return {\n ...node,\n childNodes,\n };\n } else {\n return node;\n }\n });\n\n return newNodes;\n};\n"],"names":[],"mappings":"AAEO,MAAM,iBAAoB,GAAA,CAAC,EAAE,EAAA,EAAmC,KAAA;AACrE,EAAI,IAAA,GAAA,GAAM,EAAG,CAAA,WAAA,CAAY,GAAG,CAAA,CAAA;AAC5B,EAAA,IAAI,QAAQ,CAAI,CAAA,EAAA;AAGd,IAAA,MAAM,IAAO,GAAA,EAAA,CAAG,KAAM,CAAA,GAAA,GAAM,CAAC,CAAA,CAAA;AAC7B,IAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAC5B,IAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,MAAO,OAAA,IAAA,CAAA;AAAA,KACF,MAAA;AACL,MAAA,KAAA,CAAM,GAAI,EAAA,CAAA;AACV,MAAO,OAAA,CAAA,EAAG,EAAG,CAAA,KAAA,CAAM,CAAG,EAAA,GAAG,CAAC,CAAI,CAAA,EAAA,KAAA,CAAM,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,KAC/C;AAAA,cACU,GAAM,GAAA,EAAA,CAAG,WAAY,CAAA,GAAG,OAAO,CAAI,CAAA,EAAA;AAE7C,IAAO,OAAA,EAAA,CAAG,KAAM,CAAA,CAAA,EAAG,GAAG,CAAA,CAAA;AAAA,GACxB;AACF,EAAA;AAEO,MAAM,WAAc,GAAA,CAAC,IAC1B,KAAA,IAAA,CAAK,UAAe,KAAA,KAAA,EAAA;AAGf,MAAM,QAAW,GAAA,CAAC,IACvB,KAAA,IAAA,CAAK,MAAW,KAAA,KAAA;AAElB,MAAM,kCAAsB,IAAA,GAAA,CAAI,CAAC,GAAA,EAAK,GAAG,CAAC,CAAA,CAAA;AAE1C,MAAM,cAAA,GAAiB,CACrB,IAAA,EACA,UACwB,KAAA;AACxB,EAAA,IAAI,CAAC,UAAA,CAAW,UAAW,CAAA,IAAA,CAAK,EAAE,CAAG,EAAA;AACnC,IAAO,OAAA,KAAA,CAAA;AAAA,GACF,MAAA;AACL,IAAA,OAAO,gBAAgB,GAAI,CAAA,UAAA,CAAW,OAAO,IAAK,CAAA,EAAA,CAAG,MAAM,CAAC,CAAA,CAAA;AAAA,GAC9D;AACF,CAAA,CAAA;AAEa,MAAA,WAAA,GAAc,CACzB,KAAA,EACA,EACyC,KAAA;AACzC,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAI,IAAA,IAAA,CAAK,OAAO,EAAI,EAAA;AAClB,MAAO,OAAA,IAAA,CAAA;AAAA,KACE,MAAA,IAAA,cAAA,CAAe,IAAM,EAAA,EAAE,CAAG,EAAA;AACnC,MAAO,OAAA,WAAA,CAAY,IAAK,CAAA,UAAA,EAAY,EAAE,CAAA,CAAA;AAAA,KACxC;AAAA,GACF;AACF,EAAA;AAEa,MAAA,cAAA,GAAiB,CAC5B,SAAA,EACA,IACG,KAAA;AACH,EAAA,MAAM,EAAK,GAAA,OAAO,IAAS,KAAA,QAAA,GAAW,OAAO,IAAK,CAAA,EAAA,CAAA;AAClD,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,SAAA,CAAU,QAAQ,CAAK,EAAA,EAAA;AACzC,IAAA,IAAI,SAAU,CAAA,CAAC,CAAE,CAAA,EAAA,KAAO,EAAI,EAAA;AAC1B,MAAO,OAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AACF,EAAA;AAEO,MAAM,WAAc,GAAA,CACzB,KACA,EAAA,EAAA,EACA,KAC+B,KAAA;AAC/B,EAAI,IAAA,UAAA,CAAA;AACJ,EAAA,MAAM,QAAW,GAAA,KAAA,CAAM,GAAI,CAAA,CAAC,IAAS,KAAA;AACnC,IAAI,IAAA,IAAA,CAAK,OAAO,EAAI,EAAA;AAClB,MAAO,OAAA;AAAA,QACL,GAAG,IAAA;AAAA,QACH,GAAG,KAAA;AAAA,OACL,CAAA;AAAA,KACS,MAAA,IAAA,cAAA,CAAe,IAAM,EAAA,EAAE,CAAG,EAAA;AACnC,MAAA,UAAA,GAAa,WAAY,CAAA,IAAA,CAAK,UAAY,EAAA,EAAA,EAAI,KAAK,CAAA,CAAA;AACnD,MAAO,OAAA;AAAA,QACL,GAAG,IAAA;AAAA,QACH,UAAA;AAAA,OACF,CAAA;AAAA,KACK,MAAA;AACL,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,GACD,CAAA,CAAA;AAED,EAAO,OAAA,QAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"hierarchical-data-utils.js","sources":["../../src/tree/hierarchical-data-utils.ts"],"sourcesContent":["import { NonLeafNode, NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport const getNodeParentPath = ({ id }: NormalisedTreeSourceNode) => {\n let pos = id.lastIndexOf(\"-\");\n if (pos !== -1) {\n // using the built-in hierarchical id scheme\n // rootId-n-n.n\n const path = id.slice(pos + 1);\n const steps = path.split(\".\");\n if (steps.length === 1) {\n return null;\n } else {\n steps.pop();\n return `${id.slice(0, pos)}-${steps.join(\".\")}`;\n }\n } else if ((pos = id.lastIndexOf(\"/\")) !== -1) {\n // using a path scheme step/step/step\n return id.slice(0, pos);\n }\n};\n\nexport const isGroupNode = (node: NormalisedTreeSourceNode) =>\n node.childNodes !== undefined;\nexport const isCollapsibleGroupNode = (node: NormalisedTreeSourceNode) =>\n isGroupNode(node) && node.expanded !== undefined;\nexport const isHeader = (node: NormalisedTreeSourceNode) =>\n node.header === true;\n\nconst PATH_SEPARATORS = new Set([\".\", \"/\"]);\n\nconst isDescendantOf = (\n node: NormalisedTreeSourceNode,\n targetPath: string,\n): node is NonLeafNode => {\n if (!targetPath.startsWith(node.id)) {\n return false;\n } else {\n return PATH_SEPARATORS.has(targetPath.charAt(node.id.length));\n }\n};\n\nexport const getNodeById = (\n nodes: NormalisedTreeSourceNode[],\n id: string,\n): NormalisedTreeSourceNode | undefined => {\n for (const node of nodes) {\n if (node.id === id) {\n return node;\n } else if (isDescendantOf(node, id)) {\n return getNodeById(node.childNodes, id);\n }\n }\n};\n\nexport const getIndexOfNode = (\n treeNodes: NormalisedTreeSourceNode[],\n node: NormalisedTreeSourceNode,\n) => {\n const id = typeof node === \"string\" ? node : node.id;\n for (let i = 0; i < treeNodes.length; i++) {\n if (treeNodes[i].id === id) {\n return i;\n }\n }\n};\n\nexport const replaceNode = (\n nodes: NormalisedTreeSourceNode[],\n id: string,\n props: Partial<NormalisedTreeSourceNode>,\n): NormalisedTreeSourceNode[] => {\n let childNodes;\n const newNodes = nodes.map((node) => {\n if (node.id === id) {\n return {\n ...node,\n ...props,\n };\n } else if (isDescendantOf(node, id)) {\n childNodes = replaceNode(node.childNodes, id, props);\n return {\n ...node,\n childNodes,\n };\n } else {\n return node;\n }\n });\n\n return newNodes;\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"treeTypeUtils.js","sources":["../../src/tree/treeTypeUtils.ts"],"sourcesContent":["import type { NonLeafNode, NormalisedTreeSourceNode } from \"./treeTypes\";\n\nexport const isExpanded = (\n node: NormalisedTreeSourceNode\n): node is NonLeafNode => node.expanded === true;\n"],"names":[],"mappings":"AAEO,MAAM,UAAa,GAAA,CACxB,IACwB,KAAA,IAAA,CAAK,QAAa,KAAA;;;;"}
1
+ {"version":3,"file":"treeTypeUtils.js","sources":["../../src/tree/treeTypeUtils.ts"],"sourcesContent":["import type { NonLeafNode, NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport const isExpanded = (\n node: NormalisedTreeSourceNode,\n): node is NonLeafNode => node.expanded === true;\n"],"names":[],"mappings":"AAEO,MAAM,UAAa,GAAA,CACxB,IACwB,KAAA,IAAA,CAAK,QAAa,KAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-collapsible-groups.js","sources":["../../src/tree/use-collapsible-groups.ts"],"sourcesContent":["import { KeyboardEvent, MouseEvent, useCallback, useRef } from \"react\";\nimport { closestListItem } from \"./list-dom-utils\";\nimport { ArrowLeft, ArrowRight, Enter } from \"./key-code\";\nimport { getNodeById, replaceNode } from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"./treeTypes\";\n\nconst NO_HANDLERS: CollapsibleHookResult[\"listHandlers\"] = {};\nconst isToggleElement = (element: HTMLElement) =>\n element && element.hasAttribute(\"aria-expanded\");\n\nexport interface CollapsibleGroupsHookProps {\n collapsibleHeaders?: boolean;\n highlightedIdx: number;\n treeNodes: NormalisedTreeSourceNode[];\n setVisibleData: (nodes: NormalisedTreeSourceNode[]) => void;\n source: NormalisedTreeSourceNode[];\n}\n\nexport interface CollapsibleHookResult {\n listHandlers: {\n onKeyDown?: (e: KeyboardEvent) => void;\n };\n listItemHandlers: {\n onClick: (e: MouseEvent) => void;\n };\n}\n\nexport const useCollapsibleGroups = ({\n collapsibleHeaders,\n highlightedIdx,\n treeNodes,\n setVisibleData,\n source,\n}: CollapsibleGroupsHookProps): CollapsibleHookResult => {\n const fullSource = useRef<NormalisedTreeSourceNode[]>(source);\n const stateSource = useRef<NormalisedTreeSourceNode[]>(fullSource.current);\n\n const setSource = useCallback(\n (value) => {\n setVisibleData((stateSource.current = value));\n },\n [setVisibleData]\n );\n\n const expandNode = useCallback(\n (nodeList: NormalisedTreeSourceNode[], { id }: NormalisedTreeSourceNode) =>\n replaceNode(nodeList, id, { expanded: true }),\n []\n );\n\n const collapseNode = useCallback(\n (nodeList, { id }) => replaceNode(nodeList, id, { expanded: false }),\n []\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === ArrowRight || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded === false) {\n e.preventDefault();\n setSource(expandNode(stateSource.current, node));\n }\n }\n }\n\n if (e.key === ArrowLeft || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded) {\n e.preventDefault();\n setSource(collapseNode(stateSource.current, node));\n }\n }\n }\n },\n [collapseNode, expandNode, highlightedIdx, treeNodes, setSource]\n );\n\n /**\n * These are List handlers, so we will not have reference to the actual node\n * element. We must rely on highlightedIdx to tell us which node is interactive.\n */\n const listHandlers = collapsibleHeaders\n ? {\n onKeyDown: handleKeyDown,\n }\n : NO_HANDLERS;\n\n const handleClick = useCallback(\n (evt) => {\n const el = closestListItem(evt.target);\n if (isToggleElement(el)) {\n evt.stopPropagation();\n evt.preventDefault();\n const node = getNodeById(source, el.id);\n if (node?.expanded === false) {\n setSource(expandNode(source, node));\n } else if (node?.expanded === true) {\n setSource(collapseNode(source, node));\n }\n }\n },\n [collapseNode, expandNode, setSource, source]\n );\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n listHandlers,\n listItemHandlers,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-collapsible-groups.js","sources":["../../src/tree/use-collapsible-groups.ts"],"sourcesContent":["import { KeyboardEvent, MouseEvent, useCallback, useRef } from \"react\";\nimport { closestListItem } from \"./list-dom-utils\";\nimport { ArrowLeft, ArrowRight, Enter } from \"./key-code\";\nimport { getNodeById, replaceNode } from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst NO_HANDLERS: CollapsibleHookResult[\"listHandlers\"] = {};\nconst isToggleElement = (element: HTMLElement) =>\n element && element.hasAttribute(\"aria-expanded\");\n\nexport interface CollapsibleGroupsHookProps {\n collapsibleHeaders?: boolean;\n highlightedIdx: number;\n treeNodes: NormalisedTreeSourceNode[];\n setVisibleData: (nodes: NormalisedTreeSourceNode[]) => void;\n source: NormalisedTreeSourceNode[];\n}\n\nexport interface CollapsibleHookResult {\n listHandlers: {\n onKeyDown?: (e: KeyboardEvent) => void;\n };\n listItemHandlers: {\n onClick: (e: MouseEvent) => void;\n };\n}\n\nexport const useCollapsibleGroups = ({\n collapsibleHeaders,\n highlightedIdx,\n treeNodes,\n setVisibleData,\n source,\n}: CollapsibleGroupsHookProps): CollapsibleHookResult => {\n const fullSource = useRef<NormalisedTreeSourceNode[]>(source);\n const stateSource = useRef<NormalisedTreeSourceNode[]>(fullSource.current);\n\n const setSource = useCallback(\n (value) => {\n setVisibleData((stateSource.current = value));\n },\n [setVisibleData],\n );\n\n const expandNode = useCallback(\n (nodeList: NormalisedTreeSourceNode[], { id }: NormalisedTreeSourceNode) =>\n replaceNode(nodeList, id, { expanded: true }),\n [],\n );\n\n const collapseNode = useCallback(\n (nodeList, { id }) => replaceNode(nodeList, id, { expanded: false }),\n [],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === ArrowRight || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded === false) {\n e.preventDefault();\n setSource(expandNode(stateSource.current, node));\n }\n }\n }\n\n if (e.key === ArrowLeft || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded) {\n e.preventDefault();\n setSource(collapseNode(stateSource.current, node));\n }\n }\n }\n },\n [collapseNode, expandNode, highlightedIdx, treeNodes, setSource],\n );\n\n /**\n * These are List handlers, so we will not have reference to the actual node\n * element. We must rely on highlightedIdx to tell us which node is interactive.\n */\n const listHandlers = collapsibleHeaders\n ? {\n onKeyDown: handleKeyDown,\n }\n : NO_HANDLERS;\n\n const handleClick = useCallback(\n (evt) => {\n const el = closestListItem(evt.target);\n if (isToggleElement(el)) {\n evt.stopPropagation();\n evt.preventDefault();\n const node = getNodeById(source, el.id);\n if (node?.expanded === false) {\n setSource(expandNode(source, node));\n } else if (node?.expanded === true) {\n setSource(collapseNode(source, node));\n }\n }\n },\n [collapseNode, expandNode, setSource, source],\n );\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n listHandlers,\n listItemHandlers,\n };\n};\n"],"names":[],"mappings":"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"}