@vuu-ui/vuu-ui-controls 0.8.63 → 0.8.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/dropdown-base/useClickAway.js +0 -1
- package/cjs/dropdown-base/useClickAway.js.map +1 -1
- package/cjs/editable-label/EditableLabel.js +17 -17
- package/cjs/editable-label/EditableLabel.js.map +1 -1
- package/cjs/tabstrip/Tabstrip.js +4 -1
- package/cjs/tabstrip/Tabstrip.js.map +1 -1
- package/cjs/tabstrip/useTabstrip.js +14 -42
- package/cjs/tabstrip/useTabstrip.js.map +1 -1
- package/esm/dropdown-base/useClickAway.js +0 -1
- package/esm/dropdown-base/useClickAway.js.map +1 -1
- package/esm/editable-label/EditableLabel.js +17 -17
- package/esm/editable-label/EditableLabel.js.map +1 -1
- package/esm/tabstrip/Tabstrip.js +4 -1
- package/esm/tabstrip/Tabstrip.js.map +1 -1
- package/esm/tabstrip/useTabstrip.js +15 -43
- package/esm/tabstrip/useTabstrip.js.map +1 -1
- package/package.json +7 -7
- package/types/tabstrip/useTabstrip.d.ts +8 -2
|
@@ -32,7 +32,6 @@ const useClickAway = ({
|
|
|
32
32
|
React.useEffect(() => {
|
|
33
33
|
const [clickHandler, escapeKeyHandler] = isOpen ? [
|
|
34
34
|
(evt) => {
|
|
35
|
-
console.log("click away");
|
|
36
35
|
const targetElement = evt.target;
|
|
37
36
|
if (!popperRef.current?.contains(targetElement) && !rootRef.current?.contains(targetElement)) {
|
|
38
37
|
if (!targetWithinSubPopup(popperRef.current, targetElement)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useClickAway.js","sources":["../../src/dropdown-base/useClickAway.ts"],"sourcesContent":["import { queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useEffect, useRef } from \"react\";\nimport { CloseReason } from \"./dropdownTypes\";\n\nexport type ClickawayHook = (props: {\n popperRef: RefObject<HTMLElement>;\n rootRef: RefObject<HTMLElement>;\n isOpen: boolean;\n onClose: (reason: CloseReason) => void;\n}) => void;\n\ntype MouseEventHandler = (e: MouseEvent) => void;\ntype KeyboardEventHandler = (e: KeyboardEvent) => void;\n\nconst NO_HANDLERS: [MouseEventHandler?, KeyboardEventHandler?] = [];\n\nexport const targetWithinSubPopup = (\n source: HTMLElement | null,\n target: HTMLElement\n) => {\n if (source === null) {\n return false;\n }\n\n const sourcePortal = queryClosest(source, \".vuuPortal\");\n const targetPortal = queryClosest(target, \".vuuPortal\");\n\n if (sourcePortal && targetPortal) {\n // If we have two portals, this can only be a popup launched from a popup.\n // There will be a relationship, described by aria attributes.\n const targetWithId = targetPortal.querySelector(\"[id]\");\n const targetOwner = sourcePortal.querySelector(\n `[aria-owns=\"${targetWithId?.id}\"]`\n );\n return targetOwner !== null;\n }\n\n return false;\n};\n\nexport const useClickAway: ClickawayHook = ({\n popperRef,\n rootRef,\n isOpen,\n onClose,\n}) => {\n //TODO usePropBackedRef\n const openRef = useRef(isOpen);\n useEffect(() => {\n openRef.current = isOpen;\n }, [isOpen]);\n\n useEffect(() => {\n const [clickHandler, escapeKeyHandler] = isOpen\n ? [\n (evt: MouseEvent) => {\n
|
|
1
|
+
{"version":3,"file":"useClickAway.js","sources":["../../src/dropdown-base/useClickAway.ts"],"sourcesContent":["import { queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useEffect, useRef } from \"react\";\nimport { CloseReason } from \"./dropdownTypes\";\n\nexport type ClickawayHook = (props: {\n popperRef: RefObject<HTMLElement>;\n rootRef: RefObject<HTMLElement>;\n isOpen: boolean;\n onClose: (reason: CloseReason) => void;\n}) => void;\n\ntype MouseEventHandler = (e: MouseEvent) => void;\ntype KeyboardEventHandler = (e: KeyboardEvent) => void;\n\nconst NO_HANDLERS: [MouseEventHandler?, KeyboardEventHandler?] = [];\n\nexport const targetWithinSubPopup = (\n source: HTMLElement | null,\n target: HTMLElement\n) => {\n if (source === null) {\n return false;\n }\n\n const sourcePortal = queryClosest(source, \".vuuPortal\");\n const targetPortal = queryClosest(target, \".vuuPortal\");\n\n if (sourcePortal && targetPortal) {\n // If we have two portals, this can only be a popup launched from a popup.\n // There will be a relationship, described by aria attributes.\n const targetWithId = targetPortal.querySelector(\"[id]\");\n const targetOwner = sourcePortal.querySelector(\n `[aria-owns=\"${targetWithId?.id}\"]`\n );\n return targetOwner !== null;\n }\n\n return false;\n};\n\nexport const useClickAway: ClickawayHook = ({\n popperRef,\n rootRef,\n isOpen,\n onClose,\n}) => {\n //TODO usePropBackedRef\n const openRef = useRef(isOpen);\n useEffect(() => {\n openRef.current = isOpen;\n }, [isOpen]);\n\n useEffect(() => {\n const [clickHandler, escapeKeyHandler] = isOpen\n ? [\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n if (\n !popperRef.current?.contains(targetElement) &&\n !rootRef.current?.contains(targetElement)\n ) {\n if (!targetWithinSubPopup(popperRef.current, targetElement)) {\n onClose(\"click-away\");\n }\n }\n },\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (openRef.current) {\n onClose(\"Escape\");\n e.stopPropagation();\n }\n }\n },\n ]\n : NO_HANDLERS;\n\n if (clickHandler && escapeKeyHandler) {\n document.body.addEventListener(\"mousedown\", clickHandler, true);\n document.body.addEventListener(\"keydown\", escapeKeyHandler, true);\n }\n\n return () => {\n if (clickHandler && escapeKeyHandler) {\n document.body.removeEventListener(\"mousedown\", clickHandler, true);\n document.body.removeEventListener(\"keydown\", escapeKeyHandler, true);\n }\n };\n }, [isOpen, onClose, popperRef, rootRef]);\n};\n"],"names":["queryClosest","useRef","useEffect"],"mappings":";;;;;AAcA,MAAM,cAA2D,EAAC,CAAA;AAErD,MAAA,oBAAA,GAAuB,CAClC,MAAA,EACA,MACG,KAAA;AACH,EAAA,IAAI,WAAW,IAAM,EAAA;AACnB,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,YAAA,GAAeA,qBAAa,CAAA,MAAA,EAAQ,YAAY,CAAA,CAAA;AACtD,EAAM,MAAA,YAAA,GAAeA,qBAAa,CAAA,MAAA,EAAQ,YAAY,CAAA,CAAA;AAEtD,EAAA,IAAI,gBAAgB,YAAc,EAAA;AAGhC,IAAM,MAAA,YAAA,GAAe,YAAa,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AACtD,IAAA,MAAM,cAAc,YAAa,CAAA,aAAA;AAAA,MAC/B,CAAA,YAAA,EAAe,cAAc,EAAE,CAAA,EAAA,CAAA;AAAA,KACjC,CAAA;AACA,IAAA,OAAO,WAAgB,KAAA,IAAA,CAAA;AAAA,GACzB;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,EAAA;AAEO,MAAM,eAA8B,CAAC;AAAA,EAC1C,SAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AACF,CAAM,KAAA;AAEJ,EAAM,MAAA,OAAA,GAAUC,aAAO,MAAM,CAAA,CAAA;AAC7B,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,OAAA,CAAQ,OAAU,GAAA,MAAA,CAAA;AAAA,GACpB,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,CAAC,YAAA,EAAc,gBAAgB,CAAA,GAAI,MACrC,GAAA;AAAA,MACE,CAAC,GAAoB,KAAA;AACnB,QAAA,MAAM,gBAAgB,GAAI,CAAA,MAAA,CAAA;AAC1B,QACE,IAAA,CAAC,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,aAAa,CAC1C,IAAA,CAAC,OAAQ,CAAA,OAAA,EAAS,QAAS,CAAA,aAAa,CACxC,EAAA;AACA,UAAA,IAAI,CAAC,oBAAA,CAAqB,SAAU,CAAA,OAAA,EAAS,aAAa,CAAG,EAAA;AAC3D,YAAA,OAAA,CAAQ,YAAY,CAAA,CAAA;AAAA,WACtB;AAAA,SACF;AAAA,OACF;AAAA,MACA,CAAC,CAAqB,KAAA;AACpB,QAAI,IAAA,CAAA,CAAE,QAAQ,QAAU,EAAA;AACtB,UAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,YAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAChB,YAAA,CAAA,CAAE,eAAgB,EAAA,CAAA;AAAA,WACpB;AAAA,SACF;AAAA,OACF;AAAA,KAEF,GAAA,WAAA,CAAA;AAEJ,IAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACpC,MAAA,QAAA,CAAS,IAAK,CAAA,gBAAA,CAAiB,WAAa,EAAA,YAAA,EAAc,IAAI,CAAA,CAAA;AAC9D,MAAA,QAAA,CAAS,IAAK,CAAA,gBAAA,CAAiB,SAAW,EAAA,gBAAA,EAAkB,IAAI,CAAA,CAAA;AAAA,KAClE;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACpC,QAAA,QAAA,CAAS,IAAK,CAAA,mBAAA,CAAoB,WAAa,EAAA,YAAA,EAAc,IAAI,CAAA,CAAA;AACjE,QAAA,QAAA,CAAS,IAAK,CAAA,mBAAA,CAAoB,SAAW,EAAA,gBAAA,EAAkB,IAAI,CAAA,CAAA;AAAA,OACrE;AAAA,KACF,CAAA;AAAA,KACC,CAAC,MAAA,EAAQ,OAAS,EAAA,SAAA,EAAW,OAAO,CAAC,CAAA,CAAA;AAC1C;;;;;"}
|
|
@@ -70,31 +70,31 @@ const EditableLabel = React.forwardRef(function EditableLabel2({
|
|
|
70
70
|
}),
|
|
71
71
|
[beginEdit]
|
|
72
72
|
);
|
|
73
|
-
const exitEditMode = (
|
|
74
|
-
cancelEdit = false,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
initialValue.current = value;
|
|
73
|
+
const exitEditMode = React.useCallback(
|
|
74
|
+
({ cancelEdit = false, allowDeactivation = false } = {}) => {
|
|
75
|
+
setEditing(false);
|
|
76
|
+
const originalValue = initialValue.current;
|
|
77
|
+
if (originalValue !== value) {
|
|
78
|
+
if (cancelEdit) {
|
|
79
|
+
setValue(originalValue);
|
|
80
|
+
} else {
|
|
81
|
+
initialValue.current = value;
|
|
82
|
+
}
|
|
84
83
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
onExitEditMode && onExitEditMode(originalValue, value, allowDeactivation, cancelEdit);
|
|
85
|
+
},
|
|
86
|
+
[onExitEditMode, setEditing, setValue, value]
|
|
87
|
+
);
|
|
88
88
|
const handleChange = (evt) => {
|
|
89
89
|
const { value: value2 } = evt.target;
|
|
90
90
|
setValue(value2);
|
|
91
91
|
onChange && onChange(value2);
|
|
92
92
|
};
|
|
93
|
-
const handleBlur = () => {
|
|
94
|
-
if (editingRef.current) {
|
|
93
|
+
const handleBlur = React.useCallback(() => {
|
|
94
|
+
if (editing || editingRef.current) {
|
|
95
95
|
exitEditMode({ allowDeactivation: true });
|
|
96
96
|
}
|
|
97
|
-
};
|
|
97
|
+
}, [editing, exitEditMode]);
|
|
98
98
|
const handleKeyDown = (evt) => {
|
|
99
99
|
if (editing && evt.key === "Enter") {
|
|
100
100
|
evt.stopPropagation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditableLabel.js","sources":["../../src/editable-label/EditableLabel.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useLayoutEffect,\n forwardRef,\n ForwardedRef,\n ReactElement,\n useRef,\n HTMLAttributes,\n useImperativeHandle,\n} from \"react\";\nimport { Input, useControlled } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport editableLabelCss from \"./EditableLabel.css\";\n\nconst classBase = \"vuuEditableLabel\";\n\nexport type ExitEditModeHandler = (\n originalLabel: string | undefined,\n editedLabel: string | undefined,\n allowDeactivation?: boolean,\n editCancelled?: boolean\n) => void;\n\nexport interface EditAPI {\n beginEdit: () => void;\n}\n\nexport const NullEditAPI: EditAPI = {\n beginEdit: () => undefined,\n};\n\nexport interface EditableLabelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n className?: string;\n defaultEditing?: boolean;\n defaultValue?: string;\n editLabelApiRef?: ForwardedRef<EditAPI>;\n editing?: boolean;\n onEnterEditMode: () => void;\n onChange?: (value: string) => void;\n onExitEditMode: ExitEditModeHandler;\n defaultIsEditing?: boolean;\n value?: string;\n}\n\nexport const EditableLabel = forwardRef(function EditableLabel(\n {\n className: classNameProp,\n defaultEditing,\n defaultValue,\n editLabelApiRef,\n editing: editingProp,\n onChange,\n onEnterEditMode,\n onExitEditMode,\n value: valueProp,\n ...restProps\n }: EditableLabelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n): ReactElement<EditableLabelProps> {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-editable-label\",\n css: editableLabelCss,\n window: targetWindow,\n });\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const editingRef = useRef<boolean>(false);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue ?? \"\",\n name: \"EditableLabel\",\n state: \"value\",\n });\n\n const [editing, _setEditing] = useControlled({\n controlled: editingProp,\n default: defaultEditing ?? false,\n name: \"EditableLabel\",\n state: \"editing\",\n });\n\n const setEditing = useCallback(\n (value: boolean) => {\n _setEditing((editingRef.current = value));\n },\n [_setEditing]\n );\n\n const initialValue = useRef(value);\n\n useLayoutEffect(() => {\n if (editing) {\n if (inputRef.current !== null) {\n inputRef.current.select();\n inputRef.current.focus();\n }\n }\n }, [editing, inputRef]);\n\n const beginEdit = useCallback(() => {\n setEditing(true);\n onEnterEditMode?.();\n }, [onEnterEditMode, setEditing]);\n\n useImperativeHandle(\n editLabelApiRef,\n () => ({\n beginEdit,\n }),\n [beginEdit]\n );\n\n const exitEditMode = (
|
|
1
|
+
{"version":3,"file":"EditableLabel.js","sources":["../../src/editable-label/EditableLabel.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useLayoutEffect,\n forwardRef,\n ForwardedRef,\n ReactElement,\n useRef,\n HTMLAttributes,\n useImperativeHandle,\n} from \"react\";\nimport { Input, useControlled } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport editableLabelCss from \"./EditableLabel.css\";\n\nconst classBase = \"vuuEditableLabel\";\n\nexport type ExitEditModeHandler = (\n originalLabel: string | undefined,\n editedLabel: string | undefined,\n allowDeactivation?: boolean,\n editCancelled?: boolean\n) => void;\n\nexport interface EditAPI {\n beginEdit: () => void;\n}\n\nexport const NullEditAPI: EditAPI = {\n beginEdit: () => undefined,\n};\n\nexport interface EditableLabelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n className?: string;\n defaultEditing?: boolean;\n defaultValue?: string;\n editLabelApiRef?: ForwardedRef<EditAPI>;\n editing?: boolean;\n onEnterEditMode: () => void;\n onChange?: (value: string) => void;\n onExitEditMode: ExitEditModeHandler;\n defaultIsEditing?: boolean;\n value?: string;\n}\n\nexport const EditableLabel = forwardRef(function EditableLabel(\n {\n className: classNameProp,\n defaultEditing,\n defaultValue,\n editLabelApiRef,\n editing: editingProp,\n onChange,\n onEnterEditMode,\n onExitEditMode,\n value: valueProp,\n ...restProps\n }: EditableLabelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n): ReactElement<EditableLabelProps> {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-editable-label\",\n css: editableLabelCss,\n window: targetWindow,\n });\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const editingRef = useRef<boolean>(false);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue ?? \"\",\n name: \"EditableLabel\",\n state: \"value\",\n });\n\n const [editing, _setEditing] = useControlled({\n controlled: editingProp,\n default: defaultEditing ?? false,\n name: \"EditableLabel\",\n state: \"editing\",\n });\n\n const setEditing = useCallback(\n (value: boolean) => {\n _setEditing((editingRef.current = value));\n },\n [_setEditing]\n );\n\n const initialValue = useRef(value);\n\n useLayoutEffect(() => {\n if (editing) {\n if (inputRef.current !== null) {\n inputRef.current.select();\n inputRef.current.focus();\n }\n }\n }, [editing, inputRef]);\n\n const beginEdit = useCallback(() => {\n setEditing(true);\n onEnterEditMode?.();\n }, [onEnterEditMode, setEditing]);\n\n useImperativeHandle(\n editLabelApiRef,\n () => ({\n beginEdit,\n }),\n [beginEdit]\n );\n\n const exitEditMode = useCallback(\n ({ cancelEdit = false, allowDeactivation = false } = {}) => {\n setEditing(false);\n const originalValue = initialValue.current;\n if (originalValue !== value) {\n if (cancelEdit) {\n setValue(originalValue);\n } else {\n initialValue.current = value;\n }\n }\n onExitEditMode &&\n onExitEditMode(originalValue, value, allowDeactivation, cancelEdit);\n },\n [onExitEditMode, setEditing, setValue, value]\n );\n\n const handleChange = (evt: ChangeEvent<HTMLInputElement>) => {\n const { value } = evt.target;\n setValue(value);\n onChange && onChange(value);\n };\n\n // We need the ref here as the blur fires before setEditing has taken effect,\n // so we get a double call to exitEditMode if edit is cancelled.\n const handleBlur = useCallback(() => {\n if (editing || editingRef.current) {\n exitEditMode({ allowDeactivation: true });\n }\n }, [editing, exitEditMode]);\n\n const handleKeyDown = (evt: KeyboardEvent<HTMLInputElement>) => {\n if (editing && evt.key === \"Enter\") {\n evt.stopPropagation();\n // we are likely to lose focus as a consequence of user response\n // to exitEdit transition, don't want it to trigger another\n //shouldn't we call setEditing here in case we are in uncontrolled mode ?\n exitEditMode();\n } else if (evt.key === \"ArrowRight\" || evt.key === \"ArrowLeft\") {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n exitEditMode({ cancelEdit: true });\n }\n };\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-editing`]: editing,\n });\n return (\n <div\n {...restProps}\n className={className}\n data-text={value}\n ref={forwardedRef}\n >\n {editing ? (\n <Input\n inputProps={{ className: `${classBase}-input`, spellCheck: false }}\n value={value}\n onBlur={handleBlur}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n inputRef={inputRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n variant=\"secondary\"\n />\n ) : (\n <span className={`${classBase}-label`}>{value}</span>\n )}\n </div>\n );\n});\n"],"names":["forwardRef","EditableLabel","useWindow","useComponentCssInjection","editableLabelCss","useRef","useControlled","useCallback","value","useLayoutEffect","useImperativeHandle","jsx","Input"],"mappings":"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"}
|
package/cjs/tabstrip/Tabstrip.js
CHANGED
|
@@ -45,10 +45,11 @@ const Tabstrip = ({
|
|
|
45
45
|
const rootRef = React.useRef(null);
|
|
46
46
|
const {
|
|
47
47
|
activeTabIndex,
|
|
48
|
-
focusVisible,
|
|
49
48
|
containerStyle,
|
|
49
|
+
focusVisible,
|
|
50
50
|
draggedItemIndex,
|
|
51
51
|
onClickAddTab,
|
|
52
|
+
interactedTabState,
|
|
52
53
|
tabProps,
|
|
53
54
|
...tabstripHook
|
|
54
55
|
} = useTabstrip.useTabstrip({
|
|
@@ -89,6 +90,7 @@ const Tabstrip = ({
|
|
|
89
90
|
"data-overflow-priority": selected ? "1" : void 0,
|
|
90
91
|
dragging: draggedItemIndex === index,
|
|
91
92
|
editable,
|
|
93
|
+
editing: interactedTabState?.index === index,
|
|
92
94
|
focusVisible: focusVisible === index,
|
|
93
95
|
id: tabId,
|
|
94
96
|
index,
|
|
@@ -128,6 +130,7 @@ const Tabstrip = ({
|
|
|
128
130
|
tabProps,
|
|
129
131
|
tabClassName,
|
|
130
132
|
draggedItemIndex,
|
|
133
|
+
interactedTabState,
|
|
131
134
|
focusVisible,
|
|
132
135
|
location
|
|
133
136
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabstrip.js","sources":["../../src/tabstrip/Tabstrip.tsx"],"sourcesContent":["import { asReactElements, useId } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport React, { useMemo, useRef } from \"react\";\nimport { TabProps, TabstripProps } from \"./TabsTypes\";\nimport { useTabstrip } from \"./useTabstrip\";\nimport { IconButton } from \"../icon-button\";\nimport { OverflowContainer } from \"../overflow-container\";\n\nimport tabstripCss from \"./Tabstrip.css\";\n\nconst classBase = \"vuuTabstrip\";\n\nexport const Tabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowAddTab,\n allowCloseTab,\n allowDragDrop = false,\n allowRenameTab = false,\n animateSelectionThumb = false,\n children,\n className: classNameProp,\n id: idProp,\n keyBoardActivation = \"manual\",\n location,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation = \"horizontal\",\n showTabMenuButton,\n style: styleProp,\n tabClassName,\n variant = \"secondary\",\n ...htmlAttributes\n}: TabstripProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tabstrip\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const rootRef = useRef<HTMLDivElement>(null);\n const {\n activeTabIndex,\n
|
|
1
|
+
{"version":3,"file":"Tabstrip.js","sources":["../../src/tabstrip/Tabstrip.tsx"],"sourcesContent":["import { asReactElements, useId } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport React, { useMemo, useRef } from \"react\";\nimport { TabProps, TabstripProps } from \"./TabsTypes\";\nimport { useTabstrip } from \"./useTabstrip\";\nimport { IconButton } from \"../icon-button\";\nimport { OverflowContainer } from \"../overflow-container\";\n\nimport tabstripCss from \"./Tabstrip.css\";\n\nconst classBase = \"vuuTabstrip\";\n\nexport const Tabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowAddTab,\n allowCloseTab,\n allowDragDrop = false,\n allowRenameTab = false,\n animateSelectionThumb = false,\n children,\n className: classNameProp,\n id: idProp,\n keyBoardActivation = \"manual\",\n location,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation = \"horizontal\",\n showTabMenuButton,\n style: styleProp,\n tabClassName,\n variant = \"secondary\",\n ...htmlAttributes\n}: TabstripProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tabstrip\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const rootRef = useRef<HTMLDivElement>(null);\n const {\n activeTabIndex,\n containerStyle,\n focusVisible,\n draggedItemIndex,\n onClickAddTab,\n interactedTabState,\n tabProps,\n ...tabstripHook\n } = useTabstrip({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef: rootRef,\n keyBoardActivation,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n });\n const id = useId(idProp);\n const className = cx(classBase, classNameProp);\n const style =\n styleProp || containerStyle\n ? {\n ...styleProp,\n ...containerStyle,\n }\n : undefined;\n\n const tabs = useMemo(\n () =>\n asReactElements(children)\n .map((child, index) => {\n const {\n id: tabId = `${id}-tab-${index}`,\n className,\n closeable = allowCloseTab,\n editable = allowRenameTab,\n location: tabLocation,\n showMenuButton = showTabMenuButton,\n } = child.props;\n const selected = index === activeTabIndex;\n return React.cloneElement(child, {\n ...tabProps,\n ...tabstripHook.navigationProps,\n className: cx(className, tabClassName),\n closeable,\n \"data-overflow-priority\": selected ? \"1\" : undefined,\n dragging: draggedItemIndex === index,\n editable,\n editing: interactedTabState?.index === index,\n focusVisible: focusVisible === index,\n id: tabId,\n index,\n key: index,\n location: cx(location, tabLocation),\n selected,\n showMenuButton,\n tabIndex: selected ? 0 : -1,\n } as Partial<TabProps>);\n })\n .concat(\n allowAddTab ? (\n <IconButton\n {...tabstripHook.navigationProps}\n aria-label=\"Create Tab\"\n className={`${classBase}-addTabButton`}\n data-embedded\n icon=\"add\"\n data-overflow-priority=\"1\"\n key=\"addButton\"\n onClick={onClickAddTab}\n variant=\"secondary\"\n tabIndex={-1}\n />\n ) : (\n []\n )\n ),\n [\n children,\n allowAddTab,\n tabstripHook.navigationProps,\n onClickAddTab,\n id,\n allowCloseTab,\n allowRenameTab,\n showTabMenuButton,\n activeTabIndex,\n tabProps,\n tabClassName,\n draggedItemIndex,\n interactedTabState,\n focusVisible,\n location,\n ]\n );\n\n return (\n <>\n <OverflowContainer\n {...htmlAttributes}\n {...tabstripHook.containerProps}\n className={cx(className, `${classBase}-${variant}`)}\n id={id}\n orientation={orientation}\n overflowIcon=\"more-horiz\"\n ref={rootRef}\n style={style}\n role=\"tablist\"\n >\n {tabs}\n </OverflowContainer>\n {tabstripHook.draggable}\n </>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tabstripCss","useRef","useTabstrip","useId","useMemo","asReactElements","className","createElement","IconButton","jsxs","Fragment","jsx","OverflowContainer"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
3
|
var React = require('react');
|
|
5
4
|
require('../drag-drop/DragDropProvider.js');
|
|
6
5
|
var useDragDrop = require('../drag-drop/useDragDrop.js');
|
|
6
|
+
require('@vuu-ui/vuu-utils');
|
|
7
7
|
var TabMenuOptions = require('./TabMenuOptions.js');
|
|
8
8
|
var tabstripDomUtils = require('./tabstrip-dom-utils.js');
|
|
9
9
|
var useAnimatedSelectionThumb = require('./useAnimatedSelectionThumb.js');
|
|
@@ -12,13 +12,6 @@ var useSelection = require('./useSelection.js');
|
|
|
12
12
|
|
|
13
13
|
const editKeys = /* @__PURE__ */ new Set(["Enter", " "]);
|
|
14
14
|
const isEditKey = (key) => editKeys.has(key);
|
|
15
|
-
const getElementWithIndex = (container, index) => {
|
|
16
|
-
if (container) {
|
|
17
|
-
return container.querySelector(`[data-index="${index}"]`);
|
|
18
|
-
} else {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
15
|
const useTabstrip = ({
|
|
23
16
|
activeTabIndex: activeTabIndexProp,
|
|
24
17
|
allowDragDrop,
|
|
@@ -33,6 +26,7 @@ const useTabstrip = ({
|
|
|
33
26
|
keyBoardActivation
|
|
34
27
|
}) => {
|
|
35
28
|
const lastSelection = React.useRef(activeTabIndexProp);
|
|
29
|
+
const [interactedTabState, setInteractedTabState] = React.useState();
|
|
36
30
|
const {
|
|
37
31
|
focusTab: keyboardHookFocusTab,
|
|
38
32
|
highlightedIdx,
|
|
@@ -106,9 +100,7 @@ const useTabstrip = ({
|
|
|
106
100
|
});
|
|
107
101
|
const handleExitEditMode = React.useCallback(
|
|
108
102
|
(originalValue, editedValue, allowDeactivation, tabIndex) => {
|
|
109
|
-
|
|
110
|
-
`handleExitEditMode ${originalValue} ${editedValue} ${allowDeactivation} ${tabIndex}`
|
|
111
|
-
);
|
|
103
|
+
setInteractedTabState(void 0);
|
|
112
104
|
onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);
|
|
113
105
|
if (!allowDeactivation) {
|
|
114
106
|
keyboardHookFocusTab(tabIndex, false, true);
|
|
@@ -124,33 +116,12 @@ const useTabstrip = ({
|
|
|
124
116
|
// [dragDropHook.isDragging, keyboardHook, selectionHook]
|
|
125
117
|
[keyboardHookHandleClick, selectionHookHandleClick]
|
|
126
118
|
);
|
|
127
|
-
const getEditableLabel = React.useCallback(
|
|
128
|
-
(tabIndex = highlightedIdx) => {
|
|
129
|
-
const targetEl = getElementWithIndex(containerRef.current, tabIndex);
|
|
130
|
-
if (targetEl) {
|
|
131
|
-
return targetEl.querySelector(".vuuEditableLabel");
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
[containerRef, highlightedIdx]
|
|
135
|
-
);
|
|
136
|
-
const tabInEditMode = React.useCallback(
|
|
137
|
-
(tabIndex = highlightedIdx) => {
|
|
138
|
-
const editableLabel = getEditableLabel(tabIndex);
|
|
139
|
-
if (editableLabel) {
|
|
140
|
-
return editableLabel.classList.contains("vuuEditableLabel-editing");
|
|
141
|
-
}
|
|
142
|
-
return false;
|
|
143
|
-
},
|
|
144
|
-
[getEditableLabel, highlightedIdx]
|
|
145
|
-
);
|
|
146
119
|
const editTab = React.useCallback(
|
|
147
120
|
(tabIndex = highlightedIdx) => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
vuuUtils.dispatchMouseEvent(editableLabelEl, "dblclick");
|
|
151
|
-
}
|
|
121
|
+
console.log(`set interacted tab state ${tabIndex}`);
|
|
122
|
+
setInteractedTabState({ index: tabIndex, state: "rename" });
|
|
152
123
|
},
|
|
153
|
-
[
|
|
124
|
+
[highlightedIdx]
|
|
154
125
|
);
|
|
155
126
|
const handleKeyDown = React.useCallback(
|
|
156
127
|
(evt) => {
|
|
@@ -201,16 +172,16 @@ const useTabstrip = ({
|
|
|
201
172
|
[handleCloseTabFromMenu, handleRenameTabFromMenu]
|
|
202
173
|
);
|
|
203
174
|
const handleTabMenuClose = React.useCallback(() => {
|
|
204
|
-
if (
|
|
205
|
-
keyboardHookFocusTab(highlightedIdx);
|
|
206
|
-
} else {
|
|
175
|
+
if (interactedTabState?.index === highlightedIdx) {
|
|
207
176
|
keyboardHookSetHighlightedIndex(highlightedIdx);
|
|
177
|
+
} else {
|
|
178
|
+
keyboardHookFocusTab(highlightedIdx);
|
|
208
179
|
}
|
|
209
180
|
}, [
|
|
210
181
|
highlightedIdx,
|
|
182
|
+
interactedTabState?.index,
|
|
211
183
|
keyboardHookFocusTab,
|
|
212
|
-
keyboardHookSetHighlightedIndex
|
|
213
|
-
tabInEditMode
|
|
184
|
+
keyboardHookSetHighlightedIndex
|
|
214
185
|
]);
|
|
215
186
|
const onSwitchWrappedItemIntoView = React.useCallback(
|
|
216
187
|
(item) => {
|
|
@@ -244,12 +215,13 @@ const useTabstrip = ({
|
|
|
244
215
|
};
|
|
245
216
|
return {
|
|
246
217
|
activeTabIndex: selectionHookSelected,
|
|
247
|
-
containerStyle,
|
|
248
|
-
focusVisible: keyboardHook.focusVisible,
|
|
249
218
|
containerProps: {
|
|
250
219
|
...keyboardHook.containerProps,
|
|
251
220
|
onSwitchWrappedItemIntoView
|
|
252
221
|
},
|
|
222
|
+
containerStyle,
|
|
223
|
+
focusVisible: keyboardHook.focusVisible,
|
|
224
|
+
interactedTabState,
|
|
253
225
|
navigationProps,
|
|
254
226
|
onClickAddTab: handleAddTabClick,
|
|
255
227
|
tabProps,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTabstrip.js","sources":["../../src/tabstrip/useTabstrip.ts"],"sourcesContent":["import type { MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport type { OverflowItem } from \"@vuu-ui/vuu-ui-controls\";\nimport { dispatchMouseEvent, orientationType } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent as ReactMouseEvent,\n RefObject,\n useCallback,\n useRef,\n} from \"react\";\nimport { DropOptions, useDragDrop as useDragDrop } from \"../drag-drop\";\nimport { isTabMenuOptions } from \"./TabMenuOptions\";\nimport { getIndexOfSelectedTab } from \"./tabstrip-dom-utils\";\nimport { useAnimatedSelectionThumb } from \"./useAnimatedSelectionThumb\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { useSelection } from \"./useSelection\";\n\nexport type ExitEditModeHandler = (\n originalValue: string,\n editedValue: string,\n allowDeactivation: boolean,\n tabIndex: number\n) => void;\n\nexport interface TabstripHookProps {\n activeTabIndex: number;\n allowDragDrop: boolean;\n animateSelectionThumb: boolean;\n containerRef: RefObject<HTMLElement>;\n onActiveChange?: (tabIndex: number) => void;\n onAddTab?: () => void;\n onCloseTab?: (tabIndex: number, newActiveTabIndex: number) => void;\n onExitEditMode?: ExitEditModeHandler;\n onMoveTab?: (fromIndex: number, toIndex: number) => void;\n orientation: orientationType;\n keyBoardActivation?: \"manual\" | \"automatic\";\n}\n\nconst editKeys = new Set([\"Enter\", \" \"]);\nconst isEditKey = (key: string) => editKeys.has(key);\n\nconst getElementWithIndex = (container: HTMLElement | null, index: number) => {\n if (container) {\n return container.querySelector(`[data-index=\"${index}\"]`) as HTMLElement;\n } else {\n return null;\n }\n};\n\nexport const useTabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n keyBoardActivation,\n}: TabstripHookProps) => {\n const lastSelection = useRef(activeTabIndexProp);\n\n const {\n focusTab: keyboardHookFocusTab,\n highlightedIdx,\n onClick: keyboardHookHandleClick,\n onKeyDown: keyboardHookHandleKeyDown,\n setHighlightedIdx: keyboardHookSetHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation({\n containerRef,\n keyBoardActivation,\n orientation,\n selectedIndex: lastSelection.current,\n });\n\n const {\n activateTab: selectionHookActivateTab,\n onClick: selectionHookHandleClick,\n onKeyDown: selectionHookHandleKeyDown,\n selected: selectionHookSelected,\n } = useSelection({\n highlightedIdx,\n onSelectionChange: onActiveChange,\n selected: activeTabIndexProp,\n });\n // We need this on reEntry for navigation hook to handle focus and for dragDropHook\n // to re-apply selection after drag drop. For some reason the value is stale if we\n // directly use selectionHookSelected within the drag, even though all dependencies\n //appear to be correctly declared.\n lastSelection.current = selectionHookSelected;\n\n const { containerStyle, resumeAnimation, suspendAnimation } =\n useAnimatedSelectionThumb(\n containerRef,\n animateSelectionThumb ? selectionHookSelected : -1,\n orientation\n );\n\n const handleDrop = useCallback(\n ({ fromIndex, toIndex }: DropOptions) => {\n const { current: selected } = lastSelection;\n console.log(\n `useTabstrip handleDrop ${fromIndex} - ${toIndex} ${selected}`\n );\n onMoveTab?.(fromIndex, toIndex);\n let nextSelectedTab = -1;\n if (toIndex !== -1) {\n if (selected === fromIndex) {\n nextSelectedTab = toIndex;\n } else if (fromIndex > selected && toIndex <= selected) {\n nextSelectedTab = selected + 1;\n } else if (fromIndex < selected && toIndex >= selected) {\n nextSelectedTab = selected - 1;\n }\n if (nextSelectedTab !== -1) {\n suspendAnimation();\n selectionHookActivateTab(nextSelectedTab);\n requestAnimationFrame(resumeAnimation);\n }\n keyboardHookFocusTab(toIndex, false, false, 350);\n }\n },\n [\n keyboardHookFocusTab,\n onMoveTab,\n resumeAnimation,\n selectionHookActivateTab,\n suspendAnimation,\n ]\n );\n\n const { onMouseDown: dragDropHookHandleMouseDown, ...dragDropHook } =\n useDragDrop({\n allowDragDrop,\n containerRef,\n // this is for useDragDropNext\n draggableClassName: `tabstrip-${orientation}`,\n // extendedDropZone: overflowedItems.length > 0,\n onDrop: handleDrop,\n orientation: \"horizontal\",\n itemQuery: \".vuuOverflowContainer-item\",\n });\n\n const handleExitEditMode = useCallback<ExitEditModeHandler>(\n (originalValue, editedValue, allowDeactivation, tabIndex) => {\n console.log(\n `handleExitEditMode ${originalValue} ${editedValue} ${allowDeactivation} ${tabIndex}`\n );\n onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);\n if (!allowDeactivation) {\n // this indicates that Enter or Esc key has been pressed, hence we\n // want to make sure keyboardHook treats this as a keyboard event\n // (and applies focusVisible). The last parameter here does that.\n keyboardHookFocusTab(tabIndex, false, true);\n }\n },\n [keyboardHookFocusTab, onExitEditMode]\n );\n\n const handleClick = useCallback(\n (evt: ReactMouseEvent<HTMLElement>, tabIndex: number) => {\n // releasing the mouse at end of drag will trigger a click, ignore those\n // if (!dragDropHook.isDragging) {\n keyboardHookHandleClick(evt, tabIndex);\n selectionHookHandleClick(evt, tabIndex);\n // }\n },\n // [dragDropHook.isDragging, keyboardHook, selectionHook]\n [keyboardHookHandleClick, selectionHookHandleClick]\n );\n\n const getEditableLabel = useCallback(\n (tabIndex = highlightedIdx) => {\n const targetEl = getElementWithIndex(containerRef.current, tabIndex);\n if (targetEl) {\n return targetEl.querySelector(\".vuuEditableLabel\") as HTMLElement;\n }\n },\n [containerRef, highlightedIdx]\n );\n\n const tabInEditMode = useCallback(\n (tabIndex = highlightedIdx) => {\n const editableLabel = getEditableLabel(tabIndex);\n if (editableLabel) {\n return editableLabel.classList.contains(\"vuuEditableLabel-editing\");\n }\n return false;\n },\n [getEditableLabel, highlightedIdx]\n );\n\n const editTab = useCallback(\n (tabIndex = highlightedIdx) => {\n const editableLabelEl = getEditableLabel(tabIndex);\n if (editableLabelEl) {\n dispatchMouseEvent(editableLabelEl, \"dblclick\");\n }\n },\n [getEditableLabel, highlightedIdx]\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n keyboardHookHandleKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHookHandleKeyDown(evt);\n }\n if (!evt.defaultPrevented && isEditKey(evt.key)) {\n editTab();\n }\n },\n [editTab, keyboardHookHandleKeyDown, selectionHookHandleKeyDown]\n );\n\n const handleCloseTabFromMenu = useCallback(\n (tabIndex: number) => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n const newActiveTabIndex =\n selectedTabIndex > tabIndex\n ? selectedTabIndex - 1\n : selectedTabIndex === tabIndex\n ? 0\n : selectedTabIndex;\n suspendAnimation();\n // containerRef.current?.classList.add(\"vuuTabThumb-noTransition\");\n onCloseTab?.(tabIndex, newActiveTabIndex);\n setTimeout(() => {\n resumeAnimation();\n // containerRef.current?.classList.remove(\"vuuTabThumb-noTransition\");\n }, 200);\n return true;\n },\n [containerRef, onCloseTab, resumeAnimation, suspendAnimation]\n );\n\n const handleRenameTabFromMenu = useCallback(\n (tabIndex: number) => {\n editTab(tabIndex);\n return true;\n },\n [editTab]\n );\n\n const handleTabMenuAction = useCallback<MenuActionHandler>(\n (action) => {\n if (isTabMenuOptions(action.options)) {\n switch (action.menuId) {\n case \"close-tab\":\n return handleCloseTabFromMenu(action.options.tabIndex);\n case \"rename-tab\":\n return handleRenameTabFromMenu(action.options.tabIndex);\n default:\n console.log(`tab menu action ${action.menuId}`);\n }\n }\n return false;\n },\n [handleCloseTabFromMenu, handleRenameTabFromMenu]\n );\n\n //TODO( why do we sometimes see this fired twice eg following rename)\n const handleTabMenuClose = useCallback(() => {\n if (!tabInEditMode()) {\n keyboardHookFocusTab(highlightedIdx);\n } else {\n keyboardHookSetHighlightedIndex(highlightedIdx);\n }\n }, [\n highlightedIdx,\n keyboardHookFocusTab,\n keyboardHookSetHighlightedIndex,\n tabInEditMode,\n ]);\n\n const onSwitchWrappedItemIntoView = useCallback(\n (item: OverflowItem) => {\n const index = parseInt(item.index);\n if (!isNaN(index)) {\n selectionHookActivateTab(index);\n }\n },\n [selectionHookActivateTab]\n );\n\n const navigationProps = {\n onFocus: keyboardHook.onFocus,\n onKeyDown: handleKeyDown,\n };\n\n const handleAddTabClick = useCallback(() => {\n onAddTab?.();\n requestAnimationFrame(() => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n if (selectedTabIndex !== -1) {\n keyboardHookFocusTab(selectedTabIndex);\n }\n });\n }, [containerRef, keyboardHookFocusTab, onAddTab]);\n\n const tabProps = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onExitEditMode: handleExitEditMode,\n onMenuAction: handleTabMenuAction,\n onMenuClose: handleTabMenuClose,\n onMouseDown: dragDropHookHandleMouseDown,\n };\n\n return {\n activeTabIndex: selectionHookSelected,\n containerStyle,\n focusVisible: keyboardHook.focusVisible,\n containerProps: {\n ...keyboardHook.containerProps,\n onSwitchWrappedItemIntoView,\n },\n navigationProps,\n onClickAddTab: handleAddTabClick,\n tabProps,\n ...dragDropHook,\n };\n};\n"],"names":["useRef","useKeyboardNavigation","useSelection","useAnimatedSelectionThumb","useCallback","useDragDrop","dispatchMouseEvent","getIndexOfSelectedTab","isTabMenuOptions"],"mappings":";;;;;;;;;;;;AAsCA,MAAM,2BAAe,IAAA,GAAA,CAAI,CAAC,OAAA,EAAS,GAAG,CAAC,CAAA,CAAA;AACvC,MAAM,SAAY,GAAA,CAAC,GAAgB,KAAA,QAAA,CAAS,IAAI,GAAG,CAAA,CAAA;AAEnD,MAAM,mBAAA,GAAsB,CAAC,SAAA,EAA+B,KAAkB,KAAA;AAC5E,EAAA,IAAI,SAAW,EAAA;AACb,IAAA,OAAO,SAAU,CAAA,aAAA,CAAc,CAAgB,aAAA,EAAA,KAAK,CAAI,EAAA,CAAA,CAAA,CAAA;AAAA,GACnD,MAAA;AACL,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,cAAgB,EAAA,kBAAA;AAAA,EAChB,aAAA;AAAA,EACA,qBAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AACF,CAAyB,KAAA;AACvB,EAAM,MAAA,aAAA,GAAgBA,aAAO,kBAAkB,CAAA,CAAA;AAE/C,EAAM,MAAA;AAAA,IACJ,QAAU,EAAA,oBAAA;AAAA,IACV,cAAA;AAAA,IACA,OAAS,EAAA,uBAAA;AAAA,IACT,SAAW,EAAA,yBAAA;AAAA,IACX,iBAAmB,EAAA,+BAAA;AAAA,IACnB,GAAG,YAAA;AAAA,MACDC,2CAAsB,CAAA;AAAA,IACxB,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,eAAe,aAAc,CAAA,OAAA;AAAA,GAC9B,CAAA,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,WAAa,EAAA,wBAAA;AAAA,IACb,OAAS,EAAA,wBAAA;AAAA,IACT,SAAW,EAAA,0BAAA;AAAA,IACX,QAAU,EAAA,qBAAA;AAAA,MACRC,yBAAa,CAAA;AAAA,IACf,cAAA;AAAA,IACA,iBAAmB,EAAA,cAAA;AAAA,IACnB,QAAU,EAAA,kBAAA;AAAA,GACX,CAAA,CAAA;AAKD,EAAA,aAAA,CAAc,OAAU,GAAA,qBAAA,CAAA;AAExB,EAAA,MAAM,EAAE,cAAA,EAAgB,eAAiB,EAAA,gBAAA,EACvC,GAAAC,mDAAA;AAAA,IACE,YAAA;AAAA,IACA,wBAAwB,qBAAwB,GAAA,CAAA,CAAA;AAAA,IAChD,WAAA;AAAA,GACF,CAAA;AAEF,EAAA,MAAM,UAAa,GAAAC,iBAAA;AAAA,IACjB,CAAC,EAAE,SAAW,EAAA,OAAA,EAA2B,KAAA;AACvC,MAAM,MAAA,EAAE,OAAS,EAAA,QAAA,EAAa,GAAA,aAAA,CAAA;AAC9B,MAAQ,OAAA,CAAA,GAAA;AAAA,QACN,CAA0B,uBAAA,EAAA,SAAS,CAAM,GAAA,EAAA,OAAO,KAAK,QAAQ,CAAA,CAAA;AAAA,OAC/D,CAAA;AACA,MAAA,SAAA,GAAY,WAAW,OAAO,CAAA,CAAA;AAC9B,MAAA,IAAI,eAAkB,GAAA,CAAA,CAAA,CAAA;AACtB,MAAA,IAAI,YAAY,CAAI,CAAA,EAAA;AAClB,QAAA,IAAI,aAAa,SAAW,EAAA;AAC1B,UAAkB,eAAA,GAAA,OAAA,CAAA;AAAA,SACT,MAAA,IAAA,SAAA,GAAY,QAAY,IAAA,OAAA,IAAW,QAAU,EAAA;AACtD,UAAA,eAAA,GAAkB,QAAW,GAAA,CAAA,CAAA;AAAA,SACpB,MAAA,IAAA,SAAA,GAAY,QAAY,IAAA,OAAA,IAAW,QAAU,EAAA;AACtD,UAAA,eAAA,GAAkB,QAAW,GAAA,CAAA,CAAA;AAAA,SAC/B;AACA,QAAA,IAAI,oBAAoB,CAAI,CAAA,EAAA;AAC1B,UAAiB,gBAAA,EAAA,CAAA;AACjB,UAAA,wBAAA,CAAyB,eAAe,CAAA,CAAA;AACxC,UAAA,qBAAA,CAAsB,eAAe,CAAA,CAAA;AAAA,SACvC;AACA,QAAqB,oBAAA,CAAA,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,GAAG,CAAA,CAAA;AAAA,OACjD;AAAA,KACF;AAAA,IACA;AAAA,MACE,oBAAA;AAAA,MACA,SAAA;AAAA,MACA,eAAA;AAAA,MACA,wBAAA;AAAA,MACA,gBAAA;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,EAAE,WAAa,EAAA,2BAAA,EAA6B,GAAG,YAAA,KACnDC,uBAAY,CAAA;AAAA,IACV,aAAA;AAAA,IACA,YAAA;AAAA;AAAA,IAEA,kBAAA,EAAoB,YAAY,WAAW,CAAA,CAAA;AAAA;AAAA,IAE3C,MAAQ,EAAA,UAAA;AAAA,IACR,WAAa,EAAA,YAAA;AAAA,IACb,SAAW,EAAA,4BAAA;AAAA,GACZ,CAAA,CAAA;AAEH,EAAA,MAAM,kBAAqB,GAAAD,iBAAA;AAAA,IACzB,CAAC,aAAA,EAAe,WAAa,EAAA,iBAAA,EAAmB,QAAa,KAAA;AAC3D,MAAQ,OAAA,CAAA,GAAA;AAAA,QACN,sBAAsB,aAAa,CAAA,CAAA,EAAI,WAAW,CAAI,CAAA,EAAA,iBAAiB,IAAI,QAAQ,CAAA,CAAA;AAAA,OACrF,CAAA;AACA,MAAiB,cAAA,GAAA,aAAA,EAAe,WAAa,EAAA,iBAAA,EAAmB,QAAQ,CAAA,CAAA;AACxE,MAAA,IAAI,CAAC,iBAAmB,EAAA;AAItB,QAAqB,oBAAA,CAAA,QAAA,EAAU,OAAO,IAAI,CAAA,CAAA;AAAA,OAC5C;AAAA,KACF;AAAA,IACA,CAAC,sBAAsB,cAAc,CAAA;AAAA,GACvC,CAAA;AAEA,EAAA,MAAM,WAAc,GAAAA,iBAAA;AAAA,IAClB,CAAC,KAAmC,QAAqB,KAAA;AAGvD,MAAA,uBAAA,CAAwB,KAAK,QAAQ,CAAA,CAAA;AACrC,MAAA,wBAAA,CAAyB,KAAK,QAAQ,CAAA,CAAA;AAAA,KAExC;AAAA;AAAA,IAEA,CAAC,yBAAyB,wBAAwB,CAAA;AAAA,GACpD,CAAA;AAEA,EAAA,MAAM,gBAAmB,GAAAA,iBAAA;AAAA,IACvB,CAAC,WAAW,cAAmB,KAAA;AAC7B,MAAA,MAAM,QAAW,GAAA,mBAAA,CAAoB,YAAa,CAAA,OAAA,EAAS,QAAQ,CAAA,CAAA;AACnE,MAAA,IAAI,QAAU,EAAA;AACZ,QAAO,OAAA,QAAA,CAAS,cAAc,mBAAmB,CAAA,CAAA;AAAA,OACnD;AAAA,KACF;AAAA,IACA,CAAC,cAAc,cAAc,CAAA;AAAA,GAC/B,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAAA,iBAAA;AAAA,IACpB,CAAC,WAAW,cAAmB,KAAA;AAC7B,MAAM,MAAA,aAAA,GAAgB,iBAAiB,QAAQ,CAAA,CAAA;AAC/C,MAAA,IAAI,aAAe,EAAA;AACjB,QAAO,OAAA,aAAA,CAAc,SAAU,CAAA,QAAA,CAAS,0BAA0B,CAAA,CAAA;AAAA,OACpE;AACA,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,kBAAkB,cAAc,CAAA;AAAA,GACnC,CAAA;AAEA,EAAA,MAAM,OAAU,GAAAA,iBAAA;AAAA,IACd,CAAC,WAAW,cAAmB,KAAA;AAC7B,MAAM,MAAA,eAAA,GAAkB,iBAAiB,QAAQ,CAAA,CAAA;AACjD,MAAA,IAAI,eAAiB,EAAA;AACnB,QAAAE,2BAAA,CAAmB,iBAAiB,UAAU,CAAA,CAAA;AAAA,OAChD;AAAA,KACF;AAAA,IACA,CAAC,kBAAkB,cAAc,CAAA;AAAA,GACnC,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAAF,iBAAA;AAAA,IACpB,CAAC,GAAuB,KAAA;AACtB,MAAA,yBAAA,CAA0B,GAAG,CAAA,CAAA;AAC7B,MAAI,IAAA,CAAC,IAAI,gBAAkB,EAAA;AACzB,QAAA,0BAAA,CAA2B,GAAG,CAAA,CAAA;AAAA,OAChC;AACA,MAAA,IAAI,CAAC,GAAI,CAAA,gBAAA,IAAoB,SAAU,CAAA,GAAA,CAAI,GAAG,CAAG,EAAA;AAC/C,QAAQ,OAAA,EAAA,CAAA;AAAA,OACV;AAAA,KACF;AAAA,IACA,CAAC,OAAS,EAAA,yBAAA,EAA2B,0BAA0B,CAAA;AAAA,GACjE,CAAA;AAEA,EAAA,MAAM,sBAAyB,GAAAA,iBAAA;AAAA,IAC7B,CAAC,QAAqB,KAAA;AACpB,MAAM,MAAA,gBAAA,GAAmBG,sCAAsB,CAAA,YAAA,CAAa,OAAO,CAAA,CAAA;AACnE,MAAA,MAAM,oBACJ,gBAAmB,GAAA,QAAA,GACf,mBAAmB,CACnB,GAAA,gBAAA,KAAqB,WACrB,CACA,GAAA,gBAAA,CAAA;AACN,MAAiB,gBAAA,EAAA,CAAA;AAEjB,MAAA,UAAA,GAAa,UAAU,iBAAiB,CAAA,CAAA;AACxC,MAAA,UAAA,CAAW,MAAM;AACf,QAAgB,eAAA,EAAA,CAAA;AAAA,SAEf,GAAG,CAAA,CAAA;AACN,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,YAAA,EAAc,UAAY,EAAA,eAAA,EAAiB,gBAAgB,CAAA;AAAA,GAC9D,CAAA;AAEA,EAAA,MAAM,uBAA0B,GAAAH,iBAAA;AAAA,IAC9B,CAAC,QAAqB,KAAA;AACpB,MAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAChB,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAA,MAAM,mBAAsB,GAAAA,iBAAA;AAAA,IAC1B,CAAC,MAAW,KAAA;AACV,MAAI,IAAAI,+BAAA,CAAiB,MAAO,CAAA,OAAO,CAAG,EAAA;AACpC,QAAA,QAAQ,OAAO,MAAQ;AAAA,UACrB,KAAK,WAAA;AACH,YAAO,OAAA,sBAAA,CAAuB,MAAO,CAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAAA,UACvD,KAAK,YAAA;AACH,YAAO,OAAA,uBAAA,CAAwB,MAAO,CAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAAA,UACxD;AACE,YAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,gBAAA,EAAmB,MAAO,CAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AAAA,SAClD;AAAA,OACF;AACA,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,wBAAwB,uBAAuB,CAAA;AAAA,GAClD,CAAA;AAGA,EAAM,MAAA,kBAAA,GAAqBJ,kBAAY,MAAM;AAC3C,IAAI,IAAA,CAAC,eAAiB,EAAA;AACpB,MAAA,oBAAA,CAAqB,cAAc,CAAA,CAAA;AAAA,KAC9B,MAAA;AACL,MAAA,+BAAA,CAAgC,cAAc,CAAA,CAAA;AAAA,KAChD;AAAA,GACC,EAAA;AAAA,IACD,cAAA;AAAA,IACA,oBAAA;AAAA,IACA,+BAAA;AAAA,IACA,aAAA;AAAA,GACD,CAAA,CAAA;AAED,EAAA,MAAM,2BAA8B,GAAAA,iBAAA;AAAA,IAClC,CAAC,IAAuB,KAAA;AACtB,MAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AACjC,MAAI,IAAA,CAAC,KAAM,CAAA,KAAK,CAAG,EAAA;AACjB,QAAA,wBAAA,CAAyB,KAAK,CAAA,CAAA;AAAA,OAChC;AAAA,KACF;AAAA,IACA,CAAC,wBAAwB,CAAA;AAAA,GAC3B,CAAA;AAEA,EAAA,MAAM,eAAkB,GAAA;AAAA,IACtB,SAAS,YAAa,CAAA,OAAA;AAAA,IACtB,SAAW,EAAA,aAAA;AAAA,GACb,CAAA;AAEA,EAAM,MAAA,iBAAA,GAAoBA,kBAAY,MAAM;AAC1C,IAAW,QAAA,IAAA,CAAA;AACX,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAM,MAAA,gBAAA,GAAmBG,sCAAsB,CAAA,YAAA,CAAa,OAAO,CAAA,CAAA;AACnE,MAAA,IAAI,qBAAqB,CAAI,CAAA,EAAA;AAC3B,QAAA,oBAAA,CAAqB,gBAAgB,CAAA,CAAA;AAAA,OACvC;AAAA,KACD,CAAA,CAAA;AAAA,GACA,EAAA,CAAC,YAAc,EAAA,oBAAA,EAAsB,QAAQ,CAAC,CAAA,CAAA;AAEjD,EAAA,MAAM,QAAW,GAAA;AAAA,IACf,OAAS,EAAA,WAAA;AAAA,IACT,SAAW,EAAA,aAAA;AAAA,IACX,cAAgB,EAAA,kBAAA;AAAA,IAChB,YAAc,EAAA,mBAAA;AAAA,IACd,WAAa,EAAA,kBAAA;AAAA,IACb,WAAa,EAAA,2BAAA;AAAA,GACf,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,cAAgB,EAAA,qBAAA;AAAA,IAChB,cAAA;AAAA,IACA,cAAc,YAAa,CAAA,YAAA;AAAA,IAC3B,cAAgB,EAAA;AAAA,MACd,GAAG,YAAa,CAAA,cAAA;AAAA,MAChB,2BAAA;AAAA,KACF;AAAA,IACA,eAAA;AAAA,IACA,aAAe,EAAA,iBAAA;AAAA,IACf,QAAA;AAAA,IACA,GAAG,YAAA;AAAA,GACL,CAAA;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"useTabstrip.js","sources":["../../src/tabstrip/useTabstrip.ts"],"sourcesContent":["import type { MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport type { OverflowItem } from \"@vuu-ui/vuu-ui-controls\";\nimport { orientationType } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent as ReactMouseEvent,\n RefObject,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { DropOptions, useDragDrop as useDragDrop } from \"../drag-drop\";\nimport { isTabMenuOptions } from \"./TabMenuOptions\";\nimport { getIndexOfSelectedTab } from \"./tabstrip-dom-utils\";\nimport { useAnimatedSelectionThumb } from \"./useAnimatedSelectionThumb\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { useSelection } from \"./useSelection\";\n\nexport type ExitEditModeHandler = (\n originalValue: string,\n editedValue: string,\n allowDeactivation: boolean,\n tabIndex: number\n) => void;\n\nexport interface TabstripHookProps {\n activeTabIndex: number;\n allowDragDrop: boolean;\n animateSelectionThumb: boolean;\n containerRef: RefObject<HTMLElement>;\n onActiveChange?: (tabIndex: number) => void;\n onAddTab?: () => void;\n onCloseTab?: (tabIndex: number, newActiveTabIndex: number) => void;\n onExitEditMode?: ExitEditModeHandler;\n onMoveTab?: (fromIndex: number, toIndex: number) => void;\n orientation: orientationType;\n keyBoardActivation?: \"manual\" | \"automatic\";\n}\n\nconst editKeys = new Set([\"Enter\", \" \"]);\nconst isEditKey = (key: string) => editKeys.has(key);\n\ntype InteractedTabState = {\n index: number;\n state: \"rename\";\n};\n\nexport const useTabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n keyBoardActivation,\n}: TabstripHookProps) => {\n const lastSelection = useRef(activeTabIndexProp);\n const [interactedTabState, setInteractedTabState] = useState<\n InteractedTabState | undefined\n >();\n\n const {\n focusTab: keyboardHookFocusTab,\n highlightedIdx,\n onClick: keyboardHookHandleClick,\n onKeyDown: keyboardHookHandleKeyDown,\n setHighlightedIdx: keyboardHookSetHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation({\n containerRef,\n keyBoardActivation,\n orientation,\n selectedIndex: lastSelection.current,\n });\n\n const {\n activateTab: selectionHookActivateTab,\n onClick: selectionHookHandleClick,\n onKeyDown: selectionHookHandleKeyDown,\n selected: selectionHookSelected,\n } = useSelection({\n highlightedIdx,\n onSelectionChange: onActiveChange,\n selected: activeTabIndexProp,\n });\n // We need this on reEntry for navigation hook to handle focus and for dragDropHook\n // to re-apply selection after drag drop. For some reason the value is stale if we\n // directly use selectionHookSelected within the drag, even though all dependencies\n //appear to be correctly declared.\n lastSelection.current = selectionHookSelected;\n\n const { containerStyle, resumeAnimation, suspendAnimation } =\n useAnimatedSelectionThumb(\n containerRef,\n animateSelectionThumb ? selectionHookSelected : -1,\n orientation\n );\n\n const handleDrop = useCallback(\n ({ fromIndex, toIndex }: DropOptions) => {\n const { current: selected } = lastSelection;\n console.log(\n `useTabstrip handleDrop ${fromIndex} - ${toIndex} ${selected}`\n );\n onMoveTab?.(fromIndex, toIndex);\n let nextSelectedTab = -1;\n if (toIndex !== -1) {\n if (selected === fromIndex) {\n nextSelectedTab = toIndex;\n } else if (fromIndex > selected && toIndex <= selected) {\n nextSelectedTab = selected + 1;\n } else if (fromIndex < selected && toIndex >= selected) {\n nextSelectedTab = selected - 1;\n }\n if (nextSelectedTab !== -1) {\n suspendAnimation();\n selectionHookActivateTab(nextSelectedTab);\n requestAnimationFrame(resumeAnimation);\n }\n keyboardHookFocusTab(toIndex, false, false, 350);\n }\n },\n [\n keyboardHookFocusTab,\n onMoveTab,\n resumeAnimation,\n selectionHookActivateTab,\n suspendAnimation,\n ]\n );\n\n const { onMouseDown: dragDropHookHandleMouseDown, ...dragDropHook } =\n useDragDrop({\n allowDragDrop,\n containerRef,\n // this is for useDragDropNext\n draggableClassName: `tabstrip-${orientation}`,\n // extendedDropZone: overflowedItems.length > 0,\n onDrop: handleDrop,\n orientation: \"horizontal\",\n itemQuery: \".vuuOverflowContainer-item\",\n });\n\n const handleExitEditMode = useCallback<ExitEditModeHandler>(\n (originalValue, editedValue, allowDeactivation, tabIndex) => {\n setInteractedTabState(undefined);\n onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);\n if (!allowDeactivation) {\n // this indicates that Enter or Esc key has been pressed, hence we\n // want to make sure keyboardHook treats this as a keyboard event\n // (and applies focusVisible). The last parameter here does that.\n keyboardHookFocusTab(tabIndex, false, true);\n }\n },\n [keyboardHookFocusTab, onExitEditMode]\n );\n\n const handleClick = useCallback(\n (evt: ReactMouseEvent<HTMLElement>, tabIndex: number) => {\n // releasing the mouse at end of drag will trigger a click, ignore those\n // if (!dragDropHook.isDragging) {\n keyboardHookHandleClick(evt, tabIndex);\n selectionHookHandleClick(evt, tabIndex);\n // }\n },\n // [dragDropHook.isDragging, keyboardHook, selectionHook]\n [keyboardHookHandleClick, selectionHookHandleClick]\n );\n\n const editTab = useCallback(\n (tabIndex = highlightedIdx) => {\n console.log(`set interacted tab state ${tabIndex}`);\n setInteractedTabState({ index: tabIndex, state: \"rename\" });\n },\n [highlightedIdx]\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n keyboardHookHandleKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHookHandleKeyDown(evt);\n }\n if (!evt.defaultPrevented && isEditKey(evt.key)) {\n editTab();\n }\n },\n [editTab, keyboardHookHandleKeyDown, selectionHookHandleKeyDown]\n );\n\n const handleCloseTabFromMenu = useCallback(\n (tabIndex: number) => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n const newActiveTabIndex =\n selectedTabIndex > tabIndex\n ? selectedTabIndex - 1\n : selectedTabIndex === tabIndex\n ? 0\n : selectedTabIndex;\n suspendAnimation();\n // containerRef.current?.classList.add(\"vuuTabThumb-noTransition\");\n onCloseTab?.(tabIndex, newActiveTabIndex);\n setTimeout(() => {\n resumeAnimation();\n // containerRef.current?.classList.remove(\"vuuTabThumb-noTransition\");\n }, 200);\n return true;\n },\n [containerRef, onCloseTab, resumeAnimation, suspendAnimation]\n );\n\n const handleRenameTabFromMenu = useCallback(\n (tabIndex: number) => {\n editTab(tabIndex);\n return true;\n },\n [editTab]\n );\n\n const handleTabMenuAction = useCallback<MenuActionHandler>(\n (action) => {\n if (isTabMenuOptions(action.options)) {\n switch (action.menuId) {\n case \"close-tab\":\n return handleCloseTabFromMenu(action.options.tabIndex);\n case \"rename-tab\":\n return handleRenameTabFromMenu(action.options.tabIndex);\n default:\n console.log(`tab menu action ${action.menuId}`);\n }\n }\n return false;\n },\n [handleCloseTabFromMenu, handleRenameTabFromMenu]\n );\n\n //TODO( why do we sometimes see this fired twice eg following rename)\n const handleTabMenuClose = useCallback(() => {\n if (interactedTabState?.index === highlightedIdx) {\n keyboardHookSetHighlightedIndex(highlightedIdx);\n } else {\n keyboardHookFocusTab(highlightedIdx);\n }\n }, [\n highlightedIdx,\n interactedTabState?.index,\n keyboardHookFocusTab,\n keyboardHookSetHighlightedIndex,\n ]);\n\n const onSwitchWrappedItemIntoView = useCallback(\n (item: OverflowItem) => {\n const index = parseInt(item.index);\n if (!isNaN(index)) {\n selectionHookActivateTab(index);\n }\n },\n [selectionHookActivateTab]\n );\n\n const navigationProps = {\n onFocus: keyboardHook.onFocus,\n onKeyDown: handleKeyDown,\n };\n\n const handleAddTabClick = useCallback(() => {\n onAddTab?.();\n requestAnimationFrame(() => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n if (selectedTabIndex !== -1) {\n keyboardHookFocusTab(selectedTabIndex);\n }\n });\n }, [containerRef, keyboardHookFocusTab, onAddTab]);\n\n const tabProps = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onExitEditMode: handleExitEditMode,\n onMenuAction: handleTabMenuAction,\n onMenuClose: handleTabMenuClose,\n onMouseDown: dragDropHookHandleMouseDown,\n };\n\n return {\n activeTabIndex: selectionHookSelected,\n containerProps: {\n ...keyboardHook.containerProps,\n onSwitchWrappedItemIntoView,\n },\n containerStyle,\n focusVisible: keyboardHook.focusVisible,\n interactedTabState,\n navigationProps,\n onClickAddTab: handleAddTabClick,\n tabProps,\n ...dragDropHook,\n };\n};\n"],"names":["useRef","useState","useKeyboardNavigation","useSelection","useAnimatedSelectionThumb","useCallback","useDragDrop","getIndexOfSelectedTab","isTabMenuOptions"],"mappings":"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"}
|
|
@@ -30,7 +30,6 @@ const useClickAway = ({
|
|
|
30
30
|
useEffect(() => {
|
|
31
31
|
const [clickHandler, escapeKeyHandler] = isOpen ? [
|
|
32
32
|
(evt) => {
|
|
33
|
-
console.log("click away");
|
|
34
33
|
const targetElement = evt.target;
|
|
35
34
|
if (!popperRef.current?.contains(targetElement) && !rootRef.current?.contains(targetElement)) {
|
|
36
35
|
if (!targetWithinSubPopup(popperRef.current, targetElement)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useClickAway.js","sources":["../../src/dropdown-base/useClickAway.ts"],"sourcesContent":["import { queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useEffect, useRef } from \"react\";\nimport { CloseReason } from \"./dropdownTypes\";\n\nexport type ClickawayHook = (props: {\n popperRef: RefObject<HTMLElement>;\n rootRef: RefObject<HTMLElement>;\n isOpen: boolean;\n onClose: (reason: CloseReason) => void;\n}) => void;\n\ntype MouseEventHandler = (e: MouseEvent) => void;\ntype KeyboardEventHandler = (e: KeyboardEvent) => void;\n\nconst NO_HANDLERS: [MouseEventHandler?, KeyboardEventHandler?] = [];\n\nexport const targetWithinSubPopup = (\n source: HTMLElement | null,\n target: HTMLElement\n) => {\n if (source === null) {\n return false;\n }\n\n const sourcePortal = queryClosest(source, \".vuuPortal\");\n const targetPortal = queryClosest(target, \".vuuPortal\");\n\n if (sourcePortal && targetPortal) {\n // If we have two portals, this can only be a popup launched from a popup.\n // There will be a relationship, described by aria attributes.\n const targetWithId = targetPortal.querySelector(\"[id]\");\n const targetOwner = sourcePortal.querySelector(\n `[aria-owns=\"${targetWithId?.id}\"]`\n );\n return targetOwner !== null;\n }\n\n return false;\n};\n\nexport const useClickAway: ClickawayHook = ({\n popperRef,\n rootRef,\n isOpen,\n onClose,\n}) => {\n //TODO usePropBackedRef\n const openRef = useRef(isOpen);\n useEffect(() => {\n openRef.current = isOpen;\n }, [isOpen]);\n\n useEffect(() => {\n const [clickHandler, escapeKeyHandler] = isOpen\n ? [\n (evt: MouseEvent) => {\n
|
|
1
|
+
{"version":3,"file":"useClickAway.js","sources":["../../src/dropdown-base/useClickAway.ts"],"sourcesContent":["import { queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useEffect, useRef } from \"react\";\nimport { CloseReason } from \"./dropdownTypes\";\n\nexport type ClickawayHook = (props: {\n popperRef: RefObject<HTMLElement>;\n rootRef: RefObject<HTMLElement>;\n isOpen: boolean;\n onClose: (reason: CloseReason) => void;\n}) => void;\n\ntype MouseEventHandler = (e: MouseEvent) => void;\ntype KeyboardEventHandler = (e: KeyboardEvent) => void;\n\nconst NO_HANDLERS: [MouseEventHandler?, KeyboardEventHandler?] = [];\n\nexport const targetWithinSubPopup = (\n source: HTMLElement | null,\n target: HTMLElement\n) => {\n if (source === null) {\n return false;\n }\n\n const sourcePortal = queryClosest(source, \".vuuPortal\");\n const targetPortal = queryClosest(target, \".vuuPortal\");\n\n if (sourcePortal && targetPortal) {\n // If we have two portals, this can only be a popup launched from a popup.\n // There will be a relationship, described by aria attributes.\n const targetWithId = targetPortal.querySelector(\"[id]\");\n const targetOwner = sourcePortal.querySelector(\n `[aria-owns=\"${targetWithId?.id}\"]`\n );\n return targetOwner !== null;\n }\n\n return false;\n};\n\nexport const useClickAway: ClickawayHook = ({\n popperRef,\n rootRef,\n isOpen,\n onClose,\n}) => {\n //TODO usePropBackedRef\n const openRef = useRef(isOpen);\n useEffect(() => {\n openRef.current = isOpen;\n }, [isOpen]);\n\n useEffect(() => {\n const [clickHandler, escapeKeyHandler] = isOpen\n ? [\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n if (\n !popperRef.current?.contains(targetElement) &&\n !rootRef.current?.contains(targetElement)\n ) {\n if (!targetWithinSubPopup(popperRef.current, targetElement)) {\n onClose(\"click-away\");\n }\n }\n },\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (openRef.current) {\n onClose(\"Escape\");\n e.stopPropagation();\n }\n }\n },\n ]\n : NO_HANDLERS;\n\n if (clickHandler && escapeKeyHandler) {\n document.body.addEventListener(\"mousedown\", clickHandler, true);\n document.body.addEventListener(\"keydown\", escapeKeyHandler, true);\n }\n\n return () => {\n if (clickHandler && escapeKeyHandler) {\n document.body.removeEventListener(\"mousedown\", clickHandler, true);\n document.body.removeEventListener(\"keydown\", escapeKeyHandler, true);\n }\n };\n }, [isOpen, onClose, popperRef, rootRef]);\n};\n"],"names":[],"mappings":";;;AAcA,MAAM,cAA2D,EAAC,CAAA;AAErD,MAAA,oBAAA,GAAuB,CAClC,MAAA,EACA,MACG,KAAA;AACH,EAAA,IAAI,WAAW,IAAM,EAAA;AACnB,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,YAAA,GAAe,YAAa,CAAA,MAAA,EAAQ,YAAY,CAAA,CAAA;AACtD,EAAM,MAAA,YAAA,GAAe,YAAa,CAAA,MAAA,EAAQ,YAAY,CAAA,CAAA;AAEtD,EAAA,IAAI,gBAAgB,YAAc,EAAA;AAGhC,IAAM,MAAA,YAAA,GAAe,YAAa,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AACtD,IAAA,MAAM,cAAc,YAAa,CAAA,aAAA;AAAA,MAC/B,CAAA,YAAA,EAAe,cAAc,EAAE,CAAA,EAAA,CAAA;AAAA,KACjC,CAAA;AACA,IAAA,OAAO,WAAgB,KAAA,IAAA,CAAA;AAAA,GACzB;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,EAAA;AAEO,MAAM,eAA8B,CAAC;AAAA,EAC1C,SAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AACF,CAAM,KAAA;AAEJ,EAAM,MAAA,OAAA,GAAU,OAAO,MAAM,CAAA,CAAA;AAC7B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,CAAQ,OAAU,GAAA,MAAA,CAAA;AAAA,GACpB,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,CAAC,YAAA,EAAc,gBAAgB,CAAA,GAAI,MACrC,GAAA;AAAA,MACE,CAAC,GAAoB,KAAA;AACnB,QAAA,MAAM,gBAAgB,GAAI,CAAA,MAAA,CAAA;AAC1B,QACE,IAAA,CAAC,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,aAAa,CAC1C,IAAA,CAAC,OAAQ,CAAA,OAAA,EAAS,QAAS,CAAA,aAAa,CACxC,EAAA;AACA,UAAA,IAAI,CAAC,oBAAA,CAAqB,SAAU,CAAA,OAAA,EAAS,aAAa,CAAG,EAAA;AAC3D,YAAA,OAAA,CAAQ,YAAY,CAAA,CAAA;AAAA,WACtB;AAAA,SACF;AAAA,OACF;AAAA,MACA,CAAC,CAAqB,KAAA;AACpB,QAAI,IAAA,CAAA,CAAE,QAAQ,QAAU,EAAA;AACtB,UAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,YAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAChB,YAAA,CAAA,CAAE,eAAgB,EAAA,CAAA;AAAA,WACpB;AAAA,SACF;AAAA,OACF;AAAA,KAEF,GAAA,WAAA,CAAA;AAEJ,IAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACpC,MAAA,QAAA,CAAS,IAAK,CAAA,gBAAA,CAAiB,WAAa,EAAA,YAAA,EAAc,IAAI,CAAA,CAAA;AAC9D,MAAA,QAAA,CAAS,IAAK,CAAA,gBAAA,CAAiB,SAAW,EAAA,gBAAA,EAAkB,IAAI,CAAA,CAAA;AAAA,KAClE;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACpC,QAAA,QAAA,CAAS,IAAK,CAAA,mBAAA,CAAoB,WAAa,EAAA,YAAA,EAAc,IAAI,CAAA,CAAA;AACjE,QAAA,QAAA,CAAS,IAAK,CAAA,mBAAA,CAAoB,SAAW,EAAA,gBAAA,EAAkB,IAAI,CAAA,CAAA;AAAA,OACrE;AAAA,KACF,CAAA;AAAA,KACC,CAAC,MAAA,EAAQ,OAAS,EAAA,SAAA,EAAW,OAAO,CAAC,CAAA,CAAA;AAC1C;;;;"}
|
|
@@ -68,31 +68,31 @@ const EditableLabel = forwardRef(function EditableLabel2({
|
|
|
68
68
|
}),
|
|
69
69
|
[beginEdit]
|
|
70
70
|
);
|
|
71
|
-
const exitEditMode = (
|
|
72
|
-
cancelEdit = false,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
initialValue.current = value;
|
|
71
|
+
const exitEditMode = useCallback(
|
|
72
|
+
({ cancelEdit = false, allowDeactivation = false } = {}) => {
|
|
73
|
+
setEditing(false);
|
|
74
|
+
const originalValue = initialValue.current;
|
|
75
|
+
if (originalValue !== value) {
|
|
76
|
+
if (cancelEdit) {
|
|
77
|
+
setValue(originalValue);
|
|
78
|
+
} else {
|
|
79
|
+
initialValue.current = value;
|
|
80
|
+
}
|
|
82
81
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
onExitEditMode && onExitEditMode(originalValue, value, allowDeactivation, cancelEdit);
|
|
83
|
+
},
|
|
84
|
+
[onExitEditMode, setEditing, setValue, value]
|
|
85
|
+
);
|
|
86
86
|
const handleChange = (evt) => {
|
|
87
87
|
const { value: value2 } = evt.target;
|
|
88
88
|
setValue(value2);
|
|
89
89
|
onChange && onChange(value2);
|
|
90
90
|
};
|
|
91
|
-
const handleBlur = () => {
|
|
92
|
-
if (editingRef.current) {
|
|
91
|
+
const handleBlur = useCallback(() => {
|
|
92
|
+
if (editing || editingRef.current) {
|
|
93
93
|
exitEditMode({ allowDeactivation: true });
|
|
94
94
|
}
|
|
95
|
-
};
|
|
95
|
+
}, [editing, exitEditMode]);
|
|
96
96
|
const handleKeyDown = (evt) => {
|
|
97
97
|
if (editing && evt.key === "Enter") {
|
|
98
98
|
evt.stopPropagation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditableLabel.js","sources":["../../src/editable-label/EditableLabel.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useLayoutEffect,\n forwardRef,\n ForwardedRef,\n ReactElement,\n useRef,\n HTMLAttributes,\n useImperativeHandle,\n} from \"react\";\nimport { Input, useControlled } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport editableLabelCss from \"./EditableLabel.css\";\n\nconst classBase = \"vuuEditableLabel\";\n\nexport type ExitEditModeHandler = (\n originalLabel: string | undefined,\n editedLabel: string | undefined,\n allowDeactivation?: boolean,\n editCancelled?: boolean\n) => void;\n\nexport interface EditAPI {\n beginEdit: () => void;\n}\n\nexport const NullEditAPI: EditAPI = {\n beginEdit: () => undefined,\n};\n\nexport interface EditableLabelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n className?: string;\n defaultEditing?: boolean;\n defaultValue?: string;\n editLabelApiRef?: ForwardedRef<EditAPI>;\n editing?: boolean;\n onEnterEditMode: () => void;\n onChange?: (value: string) => void;\n onExitEditMode: ExitEditModeHandler;\n defaultIsEditing?: boolean;\n value?: string;\n}\n\nexport const EditableLabel = forwardRef(function EditableLabel(\n {\n className: classNameProp,\n defaultEditing,\n defaultValue,\n editLabelApiRef,\n editing: editingProp,\n onChange,\n onEnterEditMode,\n onExitEditMode,\n value: valueProp,\n ...restProps\n }: EditableLabelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n): ReactElement<EditableLabelProps> {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-editable-label\",\n css: editableLabelCss,\n window: targetWindow,\n });\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const editingRef = useRef<boolean>(false);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue ?? \"\",\n name: \"EditableLabel\",\n state: \"value\",\n });\n\n const [editing, _setEditing] = useControlled({\n controlled: editingProp,\n default: defaultEditing ?? false,\n name: \"EditableLabel\",\n state: \"editing\",\n });\n\n const setEditing = useCallback(\n (value: boolean) => {\n _setEditing((editingRef.current = value));\n },\n [_setEditing]\n );\n\n const initialValue = useRef(value);\n\n useLayoutEffect(() => {\n if (editing) {\n if (inputRef.current !== null) {\n inputRef.current.select();\n inputRef.current.focus();\n }\n }\n }, [editing, inputRef]);\n\n const beginEdit = useCallback(() => {\n setEditing(true);\n onEnterEditMode?.();\n }, [onEnterEditMode, setEditing]);\n\n useImperativeHandle(\n editLabelApiRef,\n () => ({\n beginEdit,\n }),\n [beginEdit]\n );\n\n const exitEditMode = (
|
|
1
|
+
{"version":3,"file":"EditableLabel.js","sources":["../../src/editable-label/EditableLabel.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useLayoutEffect,\n forwardRef,\n ForwardedRef,\n ReactElement,\n useRef,\n HTMLAttributes,\n useImperativeHandle,\n} from \"react\";\nimport { Input, useControlled } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport editableLabelCss from \"./EditableLabel.css\";\n\nconst classBase = \"vuuEditableLabel\";\n\nexport type ExitEditModeHandler = (\n originalLabel: string | undefined,\n editedLabel: string | undefined,\n allowDeactivation?: boolean,\n editCancelled?: boolean\n) => void;\n\nexport interface EditAPI {\n beginEdit: () => void;\n}\n\nexport const NullEditAPI: EditAPI = {\n beginEdit: () => undefined,\n};\n\nexport interface EditableLabelProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n className?: string;\n defaultEditing?: boolean;\n defaultValue?: string;\n editLabelApiRef?: ForwardedRef<EditAPI>;\n editing?: boolean;\n onEnterEditMode: () => void;\n onChange?: (value: string) => void;\n onExitEditMode: ExitEditModeHandler;\n defaultIsEditing?: boolean;\n value?: string;\n}\n\nexport const EditableLabel = forwardRef(function EditableLabel(\n {\n className: classNameProp,\n defaultEditing,\n defaultValue,\n editLabelApiRef,\n editing: editingProp,\n onChange,\n onEnterEditMode,\n onExitEditMode,\n value: valueProp,\n ...restProps\n }: EditableLabelProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n): ReactElement<EditableLabelProps> {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-editable-label\",\n css: editableLabelCss,\n window: targetWindow,\n });\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const editingRef = useRef<boolean>(false);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue ?? \"\",\n name: \"EditableLabel\",\n state: \"value\",\n });\n\n const [editing, _setEditing] = useControlled({\n controlled: editingProp,\n default: defaultEditing ?? false,\n name: \"EditableLabel\",\n state: \"editing\",\n });\n\n const setEditing = useCallback(\n (value: boolean) => {\n _setEditing((editingRef.current = value));\n },\n [_setEditing]\n );\n\n const initialValue = useRef(value);\n\n useLayoutEffect(() => {\n if (editing) {\n if (inputRef.current !== null) {\n inputRef.current.select();\n inputRef.current.focus();\n }\n }\n }, [editing, inputRef]);\n\n const beginEdit = useCallback(() => {\n setEditing(true);\n onEnterEditMode?.();\n }, [onEnterEditMode, setEditing]);\n\n useImperativeHandle(\n editLabelApiRef,\n () => ({\n beginEdit,\n }),\n [beginEdit]\n );\n\n const exitEditMode = useCallback(\n ({ cancelEdit = false, allowDeactivation = false } = {}) => {\n setEditing(false);\n const originalValue = initialValue.current;\n if (originalValue !== value) {\n if (cancelEdit) {\n setValue(originalValue);\n } else {\n initialValue.current = value;\n }\n }\n onExitEditMode &&\n onExitEditMode(originalValue, value, allowDeactivation, cancelEdit);\n },\n [onExitEditMode, setEditing, setValue, value]\n );\n\n const handleChange = (evt: ChangeEvent<HTMLInputElement>) => {\n const { value } = evt.target;\n setValue(value);\n onChange && onChange(value);\n };\n\n // We need the ref here as the blur fires before setEditing has taken effect,\n // so we get a double call to exitEditMode if edit is cancelled.\n const handleBlur = useCallback(() => {\n if (editing || editingRef.current) {\n exitEditMode({ allowDeactivation: true });\n }\n }, [editing, exitEditMode]);\n\n const handleKeyDown = (evt: KeyboardEvent<HTMLInputElement>) => {\n if (editing && evt.key === \"Enter\") {\n evt.stopPropagation();\n // we are likely to lose focus as a consequence of user response\n // to exitEdit transition, don't want it to trigger another\n //shouldn't we call setEditing here in case we are in uncontrolled mode ?\n exitEditMode();\n } else if (evt.key === \"ArrowRight\" || evt.key === \"ArrowLeft\") {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n exitEditMode({ cancelEdit: true });\n }\n };\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-editing`]: editing,\n });\n return (\n <div\n {...restProps}\n className={className}\n data-text={value}\n ref={forwardedRef}\n >\n {editing ? (\n <Input\n inputProps={{ className: `${classBase}-input`, spellCheck: false }}\n value={value}\n onBlur={handleBlur}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n inputRef={inputRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n variant=\"secondary\"\n />\n ) : (\n <span className={`${classBase}-label`}>{value}</span>\n )}\n </div>\n );\n});\n"],"names":["EditableLabel","value"],"mappings":"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"}
|
package/esm/tabstrip/Tabstrip.js
CHANGED
|
@@ -43,10 +43,11 @@ const Tabstrip = ({
|
|
|
43
43
|
const rootRef = useRef(null);
|
|
44
44
|
const {
|
|
45
45
|
activeTabIndex,
|
|
46
|
-
focusVisible,
|
|
47
46
|
containerStyle,
|
|
47
|
+
focusVisible,
|
|
48
48
|
draggedItemIndex,
|
|
49
49
|
onClickAddTab,
|
|
50
|
+
interactedTabState,
|
|
50
51
|
tabProps,
|
|
51
52
|
...tabstripHook
|
|
52
53
|
} = useTabstrip({
|
|
@@ -87,6 +88,7 @@ const Tabstrip = ({
|
|
|
87
88
|
"data-overflow-priority": selected ? "1" : void 0,
|
|
88
89
|
dragging: draggedItemIndex === index,
|
|
89
90
|
editable,
|
|
91
|
+
editing: interactedTabState?.index === index,
|
|
90
92
|
focusVisible: focusVisible === index,
|
|
91
93
|
id: tabId,
|
|
92
94
|
index,
|
|
@@ -126,6 +128,7 @@ const Tabstrip = ({
|
|
|
126
128
|
tabProps,
|
|
127
129
|
tabClassName,
|
|
128
130
|
draggedItemIndex,
|
|
131
|
+
interactedTabState,
|
|
129
132
|
focusVisible,
|
|
130
133
|
location
|
|
131
134
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabstrip.js","sources":["../../src/tabstrip/Tabstrip.tsx"],"sourcesContent":["import { asReactElements, useId } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport React, { useMemo, useRef } from \"react\";\nimport { TabProps, TabstripProps } from \"./TabsTypes\";\nimport { useTabstrip } from \"./useTabstrip\";\nimport { IconButton } from \"../icon-button\";\nimport { OverflowContainer } from \"../overflow-container\";\n\nimport tabstripCss from \"./Tabstrip.css\";\n\nconst classBase = \"vuuTabstrip\";\n\nexport const Tabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowAddTab,\n allowCloseTab,\n allowDragDrop = false,\n allowRenameTab = false,\n animateSelectionThumb = false,\n children,\n className: classNameProp,\n id: idProp,\n keyBoardActivation = \"manual\",\n location,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation = \"horizontal\",\n showTabMenuButton,\n style: styleProp,\n tabClassName,\n variant = \"secondary\",\n ...htmlAttributes\n}: TabstripProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tabstrip\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const rootRef = useRef<HTMLDivElement>(null);\n const {\n activeTabIndex,\n
|
|
1
|
+
{"version":3,"file":"Tabstrip.js","sources":["../../src/tabstrip/Tabstrip.tsx"],"sourcesContent":["import { asReactElements, useId } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport React, { useMemo, useRef } from \"react\";\nimport { TabProps, TabstripProps } from \"./TabsTypes\";\nimport { useTabstrip } from \"./useTabstrip\";\nimport { IconButton } from \"../icon-button\";\nimport { OverflowContainer } from \"../overflow-container\";\n\nimport tabstripCss from \"./Tabstrip.css\";\n\nconst classBase = \"vuuTabstrip\";\n\nexport const Tabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowAddTab,\n allowCloseTab,\n allowDragDrop = false,\n allowRenameTab = false,\n animateSelectionThumb = false,\n children,\n className: classNameProp,\n id: idProp,\n keyBoardActivation = \"manual\",\n location,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation = \"horizontal\",\n showTabMenuButton,\n style: styleProp,\n tabClassName,\n variant = \"secondary\",\n ...htmlAttributes\n}: TabstripProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tabstrip\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const rootRef = useRef<HTMLDivElement>(null);\n const {\n activeTabIndex,\n containerStyle,\n focusVisible,\n draggedItemIndex,\n onClickAddTab,\n interactedTabState,\n tabProps,\n ...tabstripHook\n } = useTabstrip({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef: rootRef,\n keyBoardActivation,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n });\n const id = useId(idProp);\n const className = cx(classBase, classNameProp);\n const style =\n styleProp || containerStyle\n ? {\n ...styleProp,\n ...containerStyle,\n }\n : undefined;\n\n const tabs = useMemo(\n () =>\n asReactElements(children)\n .map((child, index) => {\n const {\n id: tabId = `${id}-tab-${index}`,\n className,\n closeable = allowCloseTab,\n editable = allowRenameTab,\n location: tabLocation,\n showMenuButton = showTabMenuButton,\n } = child.props;\n const selected = index === activeTabIndex;\n return React.cloneElement(child, {\n ...tabProps,\n ...tabstripHook.navigationProps,\n className: cx(className, tabClassName),\n closeable,\n \"data-overflow-priority\": selected ? \"1\" : undefined,\n dragging: draggedItemIndex === index,\n editable,\n editing: interactedTabState?.index === index,\n focusVisible: focusVisible === index,\n id: tabId,\n index,\n key: index,\n location: cx(location, tabLocation),\n selected,\n showMenuButton,\n tabIndex: selected ? 0 : -1,\n } as Partial<TabProps>);\n })\n .concat(\n allowAddTab ? (\n <IconButton\n {...tabstripHook.navigationProps}\n aria-label=\"Create Tab\"\n className={`${classBase}-addTabButton`}\n data-embedded\n icon=\"add\"\n data-overflow-priority=\"1\"\n key=\"addButton\"\n onClick={onClickAddTab}\n variant=\"secondary\"\n tabIndex={-1}\n />\n ) : (\n []\n )\n ),\n [\n children,\n allowAddTab,\n tabstripHook.navigationProps,\n onClickAddTab,\n id,\n allowCloseTab,\n allowRenameTab,\n showTabMenuButton,\n activeTabIndex,\n tabProps,\n tabClassName,\n draggedItemIndex,\n interactedTabState,\n focusVisible,\n location,\n ]\n );\n\n return (\n <>\n <OverflowContainer\n {...htmlAttributes}\n {...tabstripHook.containerProps}\n className={cx(className, `${classBase}-${variant}`)}\n id={id}\n orientation={orientation}\n overflowIcon=\"more-horiz\"\n ref={rootRef}\n style={style}\n role=\"tablist\"\n >\n {tabs}\n </OverflowContainer>\n {tabstripHook.draggable}\n </>\n );\n};\n"],"names":["className"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRef, useCallback } from 'react';
|
|
1
|
+
import { useRef, useState, useCallback } from 'react';
|
|
3
2
|
import '../drag-drop/DragDropProvider.js';
|
|
4
3
|
import { useDragDrop } from '../drag-drop/useDragDrop.js';
|
|
4
|
+
import '@vuu-ui/vuu-utils';
|
|
5
5
|
import { isTabMenuOptions } from './TabMenuOptions.js';
|
|
6
6
|
import { getIndexOfSelectedTab } from './tabstrip-dom-utils.js';
|
|
7
7
|
import { useAnimatedSelectionThumb } from './useAnimatedSelectionThumb.js';
|
|
@@ -10,13 +10,6 @@ import { useSelection } from './useSelection.js';
|
|
|
10
10
|
|
|
11
11
|
const editKeys = /* @__PURE__ */ new Set(["Enter", " "]);
|
|
12
12
|
const isEditKey = (key) => editKeys.has(key);
|
|
13
|
-
const getElementWithIndex = (container, index) => {
|
|
14
|
-
if (container) {
|
|
15
|
-
return container.querySelector(`[data-index="${index}"]`);
|
|
16
|
-
} else {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
13
|
const useTabstrip = ({
|
|
21
14
|
activeTabIndex: activeTabIndexProp,
|
|
22
15
|
allowDragDrop,
|
|
@@ -31,6 +24,7 @@ const useTabstrip = ({
|
|
|
31
24
|
keyBoardActivation
|
|
32
25
|
}) => {
|
|
33
26
|
const lastSelection = useRef(activeTabIndexProp);
|
|
27
|
+
const [interactedTabState, setInteractedTabState] = useState();
|
|
34
28
|
const {
|
|
35
29
|
focusTab: keyboardHookFocusTab,
|
|
36
30
|
highlightedIdx,
|
|
@@ -104,9 +98,7 @@ const useTabstrip = ({
|
|
|
104
98
|
});
|
|
105
99
|
const handleExitEditMode = useCallback(
|
|
106
100
|
(originalValue, editedValue, allowDeactivation, tabIndex) => {
|
|
107
|
-
|
|
108
|
-
`handleExitEditMode ${originalValue} ${editedValue} ${allowDeactivation} ${tabIndex}`
|
|
109
|
-
);
|
|
101
|
+
setInteractedTabState(void 0);
|
|
110
102
|
onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);
|
|
111
103
|
if (!allowDeactivation) {
|
|
112
104
|
keyboardHookFocusTab(tabIndex, false, true);
|
|
@@ -122,33 +114,12 @@ const useTabstrip = ({
|
|
|
122
114
|
// [dragDropHook.isDragging, keyboardHook, selectionHook]
|
|
123
115
|
[keyboardHookHandleClick, selectionHookHandleClick]
|
|
124
116
|
);
|
|
125
|
-
const getEditableLabel = useCallback(
|
|
126
|
-
(tabIndex = highlightedIdx) => {
|
|
127
|
-
const targetEl = getElementWithIndex(containerRef.current, tabIndex);
|
|
128
|
-
if (targetEl) {
|
|
129
|
-
return targetEl.querySelector(".vuuEditableLabel");
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
[containerRef, highlightedIdx]
|
|
133
|
-
);
|
|
134
|
-
const tabInEditMode = useCallback(
|
|
135
|
-
(tabIndex = highlightedIdx) => {
|
|
136
|
-
const editableLabel = getEditableLabel(tabIndex);
|
|
137
|
-
if (editableLabel) {
|
|
138
|
-
return editableLabel.classList.contains("vuuEditableLabel-editing");
|
|
139
|
-
}
|
|
140
|
-
return false;
|
|
141
|
-
},
|
|
142
|
-
[getEditableLabel, highlightedIdx]
|
|
143
|
-
);
|
|
144
117
|
const editTab = useCallback(
|
|
145
118
|
(tabIndex = highlightedIdx) => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
dispatchMouseEvent(editableLabelEl, "dblclick");
|
|
149
|
-
}
|
|
119
|
+
console.log(`set interacted tab state ${tabIndex}`);
|
|
120
|
+
setInteractedTabState({ index: tabIndex, state: "rename" });
|
|
150
121
|
},
|
|
151
|
-
[
|
|
122
|
+
[highlightedIdx]
|
|
152
123
|
);
|
|
153
124
|
const handleKeyDown = useCallback(
|
|
154
125
|
(evt) => {
|
|
@@ -199,16 +170,16 @@ const useTabstrip = ({
|
|
|
199
170
|
[handleCloseTabFromMenu, handleRenameTabFromMenu]
|
|
200
171
|
);
|
|
201
172
|
const handleTabMenuClose = useCallback(() => {
|
|
202
|
-
if (
|
|
203
|
-
keyboardHookFocusTab(highlightedIdx);
|
|
204
|
-
} else {
|
|
173
|
+
if (interactedTabState?.index === highlightedIdx) {
|
|
205
174
|
keyboardHookSetHighlightedIndex(highlightedIdx);
|
|
175
|
+
} else {
|
|
176
|
+
keyboardHookFocusTab(highlightedIdx);
|
|
206
177
|
}
|
|
207
178
|
}, [
|
|
208
179
|
highlightedIdx,
|
|
180
|
+
interactedTabState?.index,
|
|
209
181
|
keyboardHookFocusTab,
|
|
210
|
-
keyboardHookSetHighlightedIndex
|
|
211
|
-
tabInEditMode
|
|
182
|
+
keyboardHookSetHighlightedIndex
|
|
212
183
|
]);
|
|
213
184
|
const onSwitchWrappedItemIntoView = useCallback(
|
|
214
185
|
(item) => {
|
|
@@ -242,12 +213,13 @@ const useTabstrip = ({
|
|
|
242
213
|
};
|
|
243
214
|
return {
|
|
244
215
|
activeTabIndex: selectionHookSelected,
|
|
245
|
-
containerStyle,
|
|
246
|
-
focusVisible: keyboardHook.focusVisible,
|
|
247
216
|
containerProps: {
|
|
248
217
|
...keyboardHook.containerProps,
|
|
249
218
|
onSwitchWrappedItemIntoView
|
|
250
219
|
},
|
|
220
|
+
containerStyle,
|
|
221
|
+
focusVisible: keyboardHook.focusVisible,
|
|
222
|
+
interactedTabState,
|
|
251
223
|
navigationProps,
|
|
252
224
|
onClickAddTab: handleAddTabClick,
|
|
253
225
|
tabProps,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTabstrip.js","sources":["../../src/tabstrip/useTabstrip.ts"],"sourcesContent":["import type { MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport type { OverflowItem } from \"@vuu-ui/vuu-ui-controls\";\nimport { dispatchMouseEvent, orientationType } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent as ReactMouseEvent,\n RefObject,\n useCallback,\n useRef,\n} from \"react\";\nimport { DropOptions, useDragDrop as useDragDrop } from \"../drag-drop\";\nimport { isTabMenuOptions } from \"./TabMenuOptions\";\nimport { getIndexOfSelectedTab } from \"./tabstrip-dom-utils\";\nimport { useAnimatedSelectionThumb } from \"./useAnimatedSelectionThumb\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { useSelection } from \"./useSelection\";\n\nexport type ExitEditModeHandler = (\n originalValue: string,\n editedValue: string,\n allowDeactivation: boolean,\n tabIndex: number\n) => void;\n\nexport interface TabstripHookProps {\n activeTabIndex: number;\n allowDragDrop: boolean;\n animateSelectionThumb: boolean;\n containerRef: RefObject<HTMLElement>;\n onActiveChange?: (tabIndex: number) => void;\n onAddTab?: () => void;\n onCloseTab?: (tabIndex: number, newActiveTabIndex: number) => void;\n onExitEditMode?: ExitEditModeHandler;\n onMoveTab?: (fromIndex: number, toIndex: number) => void;\n orientation: orientationType;\n keyBoardActivation?: \"manual\" | \"automatic\";\n}\n\nconst editKeys = new Set([\"Enter\", \" \"]);\nconst isEditKey = (key: string) => editKeys.has(key);\n\nconst getElementWithIndex = (container: HTMLElement | null, index: number) => {\n if (container) {\n return container.querySelector(`[data-index=\"${index}\"]`) as HTMLElement;\n } else {\n return null;\n }\n};\n\nexport const useTabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n keyBoardActivation,\n}: TabstripHookProps) => {\n const lastSelection = useRef(activeTabIndexProp);\n\n const {\n focusTab: keyboardHookFocusTab,\n highlightedIdx,\n onClick: keyboardHookHandleClick,\n onKeyDown: keyboardHookHandleKeyDown,\n setHighlightedIdx: keyboardHookSetHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation({\n containerRef,\n keyBoardActivation,\n orientation,\n selectedIndex: lastSelection.current,\n });\n\n const {\n activateTab: selectionHookActivateTab,\n onClick: selectionHookHandleClick,\n onKeyDown: selectionHookHandleKeyDown,\n selected: selectionHookSelected,\n } = useSelection({\n highlightedIdx,\n onSelectionChange: onActiveChange,\n selected: activeTabIndexProp,\n });\n // We need this on reEntry for navigation hook to handle focus and for dragDropHook\n // to re-apply selection after drag drop. For some reason the value is stale if we\n // directly use selectionHookSelected within the drag, even though all dependencies\n //appear to be correctly declared.\n lastSelection.current = selectionHookSelected;\n\n const { containerStyle, resumeAnimation, suspendAnimation } =\n useAnimatedSelectionThumb(\n containerRef,\n animateSelectionThumb ? selectionHookSelected : -1,\n orientation\n );\n\n const handleDrop = useCallback(\n ({ fromIndex, toIndex }: DropOptions) => {\n const { current: selected } = lastSelection;\n console.log(\n `useTabstrip handleDrop ${fromIndex} - ${toIndex} ${selected}`\n );\n onMoveTab?.(fromIndex, toIndex);\n let nextSelectedTab = -1;\n if (toIndex !== -1) {\n if (selected === fromIndex) {\n nextSelectedTab = toIndex;\n } else if (fromIndex > selected && toIndex <= selected) {\n nextSelectedTab = selected + 1;\n } else if (fromIndex < selected && toIndex >= selected) {\n nextSelectedTab = selected - 1;\n }\n if (nextSelectedTab !== -1) {\n suspendAnimation();\n selectionHookActivateTab(nextSelectedTab);\n requestAnimationFrame(resumeAnimation);\n }\n keyboardHookFocusTab(toIndex, false, false, 350);\n }\n },\n [\n keyboardHookFocusTab,\n onMoveTab,\n resumeAnimation,\n selectionHookActivateTab,\n suspendAnimation,\n ]\n );\n\n const { onMouseDown: dragDropHookHandleMouseDown, ...dragDropHook } =\n useDragDrop({\n allowDragDrop,\n containerRef,\n // this is for useDragDropNext\n draggableClassName: `tabstrip-${orientation}`,\n // extendedDropZone: overflowedItems.length > 0,\n onDrop: handleDrop,\n orientation: \"horizontal\",\n itemQuery: \".vuuOverflowContainer-item\",\n });\n\n const handleExitEditMode = useCallback<ExitEditModeHandler>(\n (originalValue, editedValue, allowDeactivation, tabIndex) => {\n console.log(\n `handleExitEditMode ${originalValue} ${editedValue} ${allowDeactivation} ${tabIndex}`\n );\n onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);\n if (!allowDeactivation) {\n // this indicates that Enter or Esc key has been pressed, hence we\n // want to make sure keyboardHook treats this as a keyboard event\n // (and applies focusVisible). The last parameter here does that.\n keyboardHookFocusTab(tabIndex, false, true);\n }\n },\n [keyboardHookFocusTab, onExitEditMode]\n );\n\n const handleClick = useCallback(\n (evt: ReactMouseEvent<HTMLElement>, tabIndex: number) => {\n // releasing the mouse at end of drag will trigger a click, ignore those\n // if (!dragDropHook.isDragging) {\n keyboardHookHandleClick(evt, tabIndex);\n selectionHookHandleClick(evt, tabIndex);\n // }\n },\n // [dragDropHook.isDragging, keyboardHook, selectionHook]\n [keyboardHookHandleClick, selectionHookHandleClick]\n );\n\n const getEditableLabel = useCallback(\n (tabIndex = highlightedIdx) => {\n const targetEl = getElementWithIndex(containerRef.current, tabIndex);\n if (targetEl) {\n return targetEl.querySelector(\".vuuEditableLabel\") as HTMLElement;\n }\n },\n [containerRef, highlightedIdx]\n );\n\n const tabInEditMode = useCallback(\n (tabIndex = highlightedIdx) => {\n const editableLabel = getEditableLabel(tabIndex);\n if (editableLabel) {\n return editableLabel.classList.contains(\"vuuEditableLabel-editing\");\n }\n return false;\n },\n [getEditableLabel, highlightedIdx]\n );\n\n const editTab = useCallback(\n (tabIndex = highlightedIdx) => {\n const editableLabelEl = getEditableLabel(tabIndex);\n if (editableLabelEl) {\n dispatchMouseEvent(editableLabelEl, \"dblclick\");\n }\n },\n [getEditableLabel, highlightedIdx]\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n keyboardHookHandleKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHookHandleKeyDown(evt);\n }\n if (!evt.defaultPrevented && isEditKey(evt.key)) {\n editTab();\n }\n },\n [editTab, keyboardHookHandleKeyDown, selectionHookHandleKeyDown]\n );\n\n const handleCloseTabFromMenu = useCallback(\n (tabIndex: number) => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n const newActiveTabIndex =\n selectedTabIndex > tabIndex\n ? selectedTabIndex - 1\n : selectedTabIndex === tabIndex\n ? 0\n : selectedTabIndex;\n suspendAnimation();\n // containerRef.current?.classList.add(\"vuuTabThumb-noTransition\");\n onCloseTab?.(tabIndex, newActiveTabIndex);\n setTimeout(() => {\n resumeAnimation();\n // containerRef.current?.classList.remove(\"vuuTabThumb-noTransition\");\n }, 200);\n return true;\n },\n [containerRef, onCloseTab, resumeAnimation, suspendAnimation]\n );\n\n const handleRenameTabFromMenu = useCallback(\n (tabIndex: number) => {\n editTab(tabIndex);\n return true;\n },\n [editTab]\n );\n\n const handleTabMenuAction = useCallback<MenuActionHandler>(\n (action) => {\n if (isTabMenuOptions(action.options)) {\n switch (action.menuId) {\n case \"close-tab\":\n return handleCloseTabFromMenu(action.options.tabIndex);\n case \"rename-tab\":\n return handleRenameTabFromMenu(action.options.tabIndex);\n default:\n console.log(`tab menu action ${action.menuId}`);\n }\n }\n return false;\n },\n [handleCloseTabFromMenu, handleRenameTabFromMenu]\n );\n\n //TODO( why do we sometimes see this fired twice eg following rename)\n const handleTabMenuClose = useCallback(() => {\n if (!tabInEditMode()) {\n keyboardHookFocusTab(highlightedIdx);\n } else {\n keyboardHookSetHighlightedIndex(highlightedIdx);\n }\n }, [\n highlightedIdx,\n keyboardHookFocusTab,\n keyboardHookSetHighlightedIndex,\n tabInEditMode,\n ]);\n\n const onSwitchWrappedItemIntoView = useCallback(\n (item: OverflowItem) => {\n const index = parseInt(item.index);\n if (!isNaN(index)) {\n selectionHookActivateTab(index);\n }\n },\n [selectionHookActivateTab]\n );\n\n const navigationProps = {\n onFocus: keyboardHook.onFocus,\n onKeyDown: handleKeyDown,\n };\n\n const handleAddTabClick = useCallback(() => {\n onAddTab?.();\n requestAnimationFrame(() => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n if (selectedTabIndex !== -1) {\n keyboardHookFocusTab(selectedTabIndex);\n }\n });\n }, [containerRef, keyboardHookFocusTab, onAddTab]);\n\n const tabProps = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onExitEditMode: handleExitEditMode,\n onMenuAction: handleTabMenuAction,\n onMenuClose: handleTabMenuClose,\n onMouseDown: dragDropHookHandleMouseDown,\n };\n\n return {\n activeTabIndex: selectionHookSelected,\n containerStyle,\n focusVisible: keyboardHook.focusVisible,\n containerProps: {\n ...keyboardHook.containerProps,\n onSwitchWrappedItemIntoView,\n },\n navigationProps,\n onClickAddTab: handleAddTabClick,\n tabProps,\n ...dragDropHook,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useTabstrip.js","sources":["../../src/tabstrip/useTabstrip.ts"],"sourcesContent":["import type { MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport type { OverflowItem } from \"@vuu-ui/vuu-ui-controls\";\nimport { orientationType } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent as ReactMouseEvent,\n RefObject,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { DropOptions, useDragDrop as useDragDrop } from \"../drag-drop\";\nimport { isTabMenuOptions } from \"./TabMenuOptions\";\nimport { getIndexOfSelectedTab } from \"./tabstrip-dom-utils\";\nimport { useAnimatedSelectionThumb } from \"./useAnimatedSelectionThumb\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { useSelection } from \"./useSelection\";\n\nexport type ExitEditModeHandler = (\n originalValue: string,\n editedValue: string,\n allowDeactivation: boolean,\n tabIndex: number\n) => void;\n\nexport interface TabstripHookProps {\n activeTabIndex: number;\n allowDragDrop: boolean;\n animateSelectionThumb: boolean;\n containerRef: RefObject<HTMLElement>;\n onActiveChange?: (tabIndex: number) => void;\n onAddTab?: () => void;\n onCloseTab?: (tabIndex: number, newActiveTabIndex: number) => void;\n onExitEditMode?: ExitEditModeHandler;\n onMoveTab?: (fromIndex: number, toIndex: number) => void;\n orientation: orientationType;\n keyBoardActivation?: \"manual\" | \"automatic\";\n}\n\nconst editKeys = new Set([\"Enter\", \" \"]);\nconst isEditKey = (key: string) => editKeys.has(key);\n\ntype InteractedTabState = {\n index: number;\n state: \"rename\";\n};\n\nexport const useTabstrip = ({\n activeTabIndex: activeTabIndexProp,\n allowDragDrop,\n animateSelectionThumb,\n containerRef,\n onActiveChange,\n onAddTab,\n onCloseTab,\n onExitEditMode,\n onMoveTab,\n orientation,\n keyBoardActivation,\n}: TabstripHookProps) => {\n const lastSelection = useRef(activeTabIndexProp);\n const [interactedTabState, setInteractedTabState] = useState<\n InteractedTabState | undefined\n >();\n\n const {\n focusTab: keyboardHookFocusTab,\n highlightedIdx,\n onClick: keyboardHookHandleClick,\n onKeyDown: keyboardHookHandleKeyDown,\n setHighlightedIdx: keyboardHookSetHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation({\n containerRef,\n keyBoardActivation,\n orientation,\n selectedIndex: lastSelection.current,\n });\n\n const {\n activateTab: selectionHookActivateTab,\n onClick: selectionHookHandleClick,\n onKeyDown: selectionHookHandleKeyDown,\n selected: selectionHookSelected,\n } = useSelection({\n highlightedIdx,\n onSelectionChange: onActiveChange,\n selected: activeTabIndexProp,\n });\n // We need this on reEntry for navigation hook to handle focus and for dragDropHook\n // to re-apply selection after drag drop. For some reason the value is stale if we\n // directly use selectionHookSelected within the drag, even though all dependencies\n //appear to be correctly declared.\n lastSelection.current = selectionHookSelected;\n\n const { containerStyle, resumeAnimation, suspendAnimation } =\n useAnimatedSelectionThumb(\n containerRef,\n animateSelectionThumb ? selectionHookSelected : -1,\n orientation\n );\n\n const handleDrop = useCallback(\n ({ fromIndex, toIndex }: DropOptions) => {\n const { current: selected } = lastSelection;\n console.log(\n `useTabstrip handleDrop ${fromIndex} - ${toIndex} ${selected}`\n );\n onMoveTab?.(fromIndex, toIndex);\n let nextSelectedTab = -1;\n if (toIndex !== -1) {\n if (selected === fromIndex) {\n nextSelectedTab = toIndex;\n } else if (fromIndex > selected && toIndex <= selected) {\n nextSelectedTab = selected + 1;\n } else if (fromIndex < selected && toIndex >= selected) {\n nextSelectedTab = selected - 1;\n }\n if (nextSelectedTab !== -1) {\n suspendAnimation();\n selectionHookActivateTab(nextSelectedTab);\n requestAnimationFrame(resumeAnimation);\n }\n keyboardHookFocusTab(toIndex, false, false, 350);\n }\n },\n [\n keyboardHookFocusTab,\n onMoveTab,\n resumeAnimation,\n selectionHookActivateTab,\n suspendAnimation,\n ]\n );\n\n const { onMouseDown: dragDropHookHandleMouseDown, ...dragDropHook } =\n useDragDrop({\n allowDragDrop,\n containerRef,\n // this is for useDragDropNext\n draggableClassName: `tabstrip-${orientation}`,\n // extendedDropZone: overflowedItems.length > 0,\n onDrop: handleDrop,\n orientation: \"horizontal\",\n itemQuery: \".vuuOverflowContainer-item\",\n });\n\n const handleExitEditMode = useCallback<ExitEditModeHandler>(\n (originalValue, editedValue, allowDeactivation, tabIndex) => {\n setInteractedTabState(undefined);\n onExitEditMode?.(originalValue, editedValue, allowDeactivation, tabIndex);\n if (!allowDeactivation) {\n // this indicates that Enter or Esc key has been pressed, hence we\n // want to make sure keyboardHook treats this as a keyboard event\n // (and applies focusVisible). The last parameter here does that.\n keyboardHookFocusTab(tabIndex, false, true);\n }\n },\n [keyboardHookFocusTab, onExitEditMode]\n );\n\n const handleClick = useCallback(\n (evt: ReactMouseEvent<HTMLElement>, tabIndex: number) => {\n // releasing the mouse at end of drag will trigger a click, ignore those\n // if (!dragDropHook.isDragging) {\n keyboardHookHandleClick(evt, tabIndex);\n selectionHookHandleClick(evt, tabIndex);\n // }\n },\n // [dragDropHook.isDragging, keyboardHook, selectionHook]\n [keyboardHookHandleClick, selectionHookHandleClick]\n );\n\n const editTab = useCallback(\n (tabIndex = highlightedIdx) => {\n console.log(`set interacted tab state ${tabIndex}`);\n setInteractedTabState({ index: tabIndex, state: \"rename\" });\n },\n [highlightedIdx]\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n keyboardHookHandleKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHookHandleKeyDown(evt);\n }\n if (!evt.defaultPrevented && isEditKey(evt.key)) {\n editTab();\n }\n },\n [editTab, keyboardHookHandleKeyDown, selectionHookHandleKeyDown]\n );\n\n const handleCloseTabFromMenu = useCallback(\n (tabIndex: number) => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n const newActiveTabIndex =\n selectedTabIndex > tabIndex\n ? selectedTabIndex - 1\n : selectedTabIndex === tabIndex\n ? 0\n : selectedTabIndex;\n suspendAnimation();\n // containerRef.current?.classList.add(\"vuuTabThumb-noTransition\");\n onCloseTab?.(tabIndex, newActiveTabIndex);\n setTimeout(() => {\n resumeAnimation();\n // containerRef.current?.classList.remove(\"vuuTabThumb-noTransition\");\n }, 200);\n return true;\n },\n [containerRef, onCloseTab, resumeAnimation, suspendAnimation]\n );\n\n const handleRenameTabFromMenu = useCallback(\n (tabIndex: number) => {\n editTab(tabIndex);\n return true;\n },\n [editTab]\n );\n\n const handleTabMenuAction = useCallback<MenuActionHandler>(\n (action) => {\n if (isTabMenuOptions(action.options)) {\n switch (action.menuId) {\n case \"close-tab\":\n return handleCloseTabFromMenu(action.options.tabIndex);\n case \"rename-tab\":\n return handleRenameTabFromMenu(action.options.tabIndex);\n default:\n console.log(`tab menu action ${action.menuId}`);\n }\n }\n return false;\n },\n [handleCloseTabFromMenu, handleRenameTabFromMenu]\n );\n\n //TODO( why do we sometimes see this fired twice eg following rename)\n const handleTabMenuClose = useCallback(() => {\n if (interactedTabState?.index === highlightedIdx) {\n keyboardHookSetHighlightedIndex(highlightedIdx);\n } else {\n keyboardHookFocusTab(highlightedIdx);\n }\n }, [\n highlightedIdx,\n interactedTabState?.index,\n keyboardHookFocusTab,\n keyboardHookSetHighlightedIndex,\n ]);\n\n const onSwitchWrappedItemIntoView = useCallback(\n (item: OverflowItem) => {\n const index = parseInt(item.index);\n if (!isNaN(index)) {\n selectionHookActivateTab(index);\n }\n },\n [selectionHookActivateTab]\n );\n\n const navigationProps = {\n onFocus: keyboardHook.onFocus,\n onKeyDown: handleKeyDown,\n };\n\n const handleAddTabClick = useCallback(() => {\n onAddTab?.();\n requestAnimationFrame(() => {\n const selectedTabIndex = getIndexOfSelectedTab(containerRef.current);\n if (selectedTabIndex !== -1) {\n keyboardHookFocusTab(selectedTabIndex);\n }\n });\n }, [containerRef, keyboardHookFocusTab, onAddTab]);\n\n const tabProps = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onExitEditMode: handleExitEditMode,\n onMenuAction: handleTabMenuAction,\n onMenuClose: handleTabMenuClose,\n onMouseDown: dragDropHookHandleMouseDown,\n };\n\n return {\n activeTabIndex: selectionHookSelected,\n containerProps: {\n ...keyboardHook.containerProps,\n onSwitchWrappedItemIntoView,\n },\n containerStyle,\n focusVisible: keyboardHook.focusVisible,\n interactedTabState,\n navigationProps,\n onClickAddTab: handleAddTabClick,\n tabProps,\n ...dragDropHook,\n };\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.8.
|
|
2
|
+
"version": "0.8.64",
|
|
3
3
|
"description": "VUU UI Controls",
|
|
4
4
|
"author": "heswell",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@vuu-ui/vuu-data-types": "0.8.
|
|
8
|
-
"@vuu-ui/vuu-table-types": "0.8.
|
|
7
|
+
"@vuu-ui/vuu-data-types": "0.8.64",
|
|
8
|
+
"@vuu-ui/vuu-table-types": "0.8.64"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@vuu-ui/vuu-layout": "0.8.
|
|
12
|
-
"@vuu-ui/vuu-popups": "0.8.
|
|
13
|
-
"@vuu-ui/vuu-table": "0.8.
|
|
14
|
-
"@vuu-ui/vuu-utils": "0.8.
|
|
11
|
+
"@vuu-ui/vuu-layout": "0.8.64",
|
|
12
|
+
"@vuu-ui/vuu-popups": "0.8.64",
|
|
13
|
+
"@vuu-ui/vuu-table": "0.8.64",
|
|
14
|
+
"@vuu-ui/vuu-utils": "0.8.64",
|
|
15
15
|
"@floating-ui/react": "0.26.5",
|
|
16
16
|
"@salt-ds/core": "1.27.1",
|
|
17
17
|
"@salt-ds/icons": "1.9.1",
|
|
@@ -16,6 +16,10 @@ export interface TabstripHookProps {
|
|
|
16
16
|
orientation: orientationType;
|
|
17
17
|
keyBoardActivation?: "manual" | "automatic";
|
|
18
18
|
}
|
|
19
|
+
type InteractedTabState = {
|
|
20
|
+
index: number;
|
|
21
|
+
state: "rename";
|
|
22
|
+
};
|
|
19
23
|
export declare const useTabstrip: ({ activeTabIndex: activeTabIndexProp, allowDragDrop, animateSelectionThumb, containerRef, onActiveChange, onAddTab, onCloseTab, onExitEditMode, onMoveTab, orientation, keyBoardActivation, }: TabstripHookProps) => {
|
|
20
24
|
draggable?: JSX.Element | undefined;
|
|
21
25
|
dropIndicator?: JSX.Element | undefined;
|
|
@@ -24,8 +28,6 @@ export declare const useTabstrip: ({ activeTabIndex: activeTabIndexProp, allowDr
|
|
|
24
28
|
isScrolling: RefObject<boolean>;
|
|
25
29
|
revealOverflowedItems?: boolean | undefined;
|
|
26
30
|
activeTabIndex: number;
|
|
27
|
-
containerStyle: import("react").CSSProperties;
|
|
28
|
-
focusVisible: number;
|
|
29
31
|
containerProps: {
|
|
30
32
|
onSwitchWrappedItemIntoView: (item: OverflowItem) => void;
|
|
31
33
|
onBlur: import("react").FocusEventHandler;
|
|
@@ -33,6 +35,9 @@ export declare const useTabstrip: ({ activeTabIndex: activeTabIndexProp, allowDr
|
|
|
33
35
|
onMouseDownCapture: import("react").MouseEventHandler;
|
|
34
36
|
onMouseLeave: import("react").MouseEventHandler;
|
|
35
37
|
};
|
|
38
|
+
containerStyle: import("react").CSSProperties;
|
|
39
|
+
focusVisible: number;
|
|
40
|
+
interactedTabState: InteractedTabState | undefined;
|
|
36
41
|
navigationProps: {
|
|
37
42
|
onFocus: (evt: import("react").FocusEvent<HTMLElement, Element>) => void;
|
|
38
43
|
onKeyDown: (evt: KeyboardEvent) => void;
|
|
@@ -47,3 +52,4 @@ export declare const useTabstrip: ({ activeTabIndex: activeTabIndexProp, allowDr
|
|
|
47
52
|
onMouseDown: import("react").MouseEventHandler | undefined;
|
|
48
53
|
};
|
|
49
54
|
};
|
|
55
|
+
export {};
|