@salt-ds/lab 1.0.0-alpha.34 → 1.0.0-alpha.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/css/salt-lab.css +253 -192
  2. package/dist-cjs/combo-box-next/ComboBoxNext.css.js +6 -0
  3. package/dist-cjs/combo-box-next/ComboBoxNext.css.js.map +1 -0
  4. package/dist-cjs/combo-box-next/ComboBoxNext.js +31 -3
  5. package/dist-cjs/combo-box-next/ComboBoxNext.js.map +1 -1
  6. package/dist-cjs/dropdown-next/DropdownNext.js +1 -1
  7. package/dist-cjs/dropdown-next/DropdownNext.js.map +1 -1
  8. package/dist-cjs/index.js +0 -14
  9. package/dist-cjs/index.js.map +1 -1
  10. package/dist-cjs/option/Option.css.js +1 -1
  11. package/dist-cjs/option/OptionList.css.js +1 -1
  12. package/dist-cjs/overlay/Overlay.css.js +1 -1
  13. package/dist-cjs/overlay/Overlay.js +1 -7
  14. package/dist-cjs/overlay/Overlay.js.map +1 -1
  15. package/dist-cjs/overlay/OverlayPanel.js +18 -24
  16. package/dist-cjs/overlay/OverlayPanel.js.map +1 -1
  17. package/dist-cjs/overlay/OverlayPanelBase.js +2 -4
  18. package/dist-cjs/overlay/OverlayPanelBase.js.map +1 -1
  19. package/dist-cjs/pill-input/PillInput.css.js +6 -0
  20. package/dist-cjs/pill-input/PillInput.css.js.map +1 -0
  21. package/dist-cjs/pill-input/PillInput.js +256 -0
  22. package/dist-cjs/pill-input/PillInput.js.map +1 -0
  23. package/dist-cjs/pill-input/useTruncatePills.js +85 -0
  24. package/dist-cjs/pill-input/useTruncatePills.js.map +1 -0
  25. package/dist-cjs/tabs/Tab.js +1 -1
  26. package/dist-cjs/tabs/Tab.js.map +1 -1
  27. package/dist-cjs/tabs-next/TabNextContext.js.map +1 -1
  28. package/dist-cjs/tabs-next/TabstripNext.css.js +1 -1
  29. package/dist-cjs/tabs-next/TabstripNext.js +23 -21
  30. package/dist-cjs/tabs-next/TabstripNext.js.map +1 -1
  31. package/dist-cjs/utils/useValueEffect.js +40 -0
  32. package/dist-cjs/utils/useValueEffect.js.map +1 -0
  33. package/dist-es/combo-box-next/ComboBoxNext.css.js +4 -0
  34. package/dist-es/combo-box-next/ComboBoxNext.css.js.map +1 -0
  35. package/dist-es/combo-box-next/ComboBoxNext.js +32 -4
  36. package/dist-es/combo-box-next/ComboBoxNext.js.map +1 -1
  37. package/dist-es/dropdown-next/DropdownNext.js +1 -1
  38. package/dist-es/dropdown-next/DropdownNext.js.map +1 -1
  39. package/dist-es/index.js +0 -6
  40. package/dist-es/index.js.map +1 -1
  41. package/dist-es/option/Option.css.js +1 -1
  42. package/dist-es/option/OptionList.css.js +1 -1
  43. package/dist-es/overlay/Overlay.css.js +1 -1
  44. package/dist-es/overlay/Overlay.js +1 -7
  45. package/dist-es/overlay/Overlay.js.map +1 -1
  46. package/dist-es/overlay/OverlayPanel.js +19 -25
  47. package/dist-es/overlay/OverlayPanel.js.map +1 -1
  48. package/dist-es/overlay/OverlayPanelBase.js +2 -4
  49. package/dist-es/overlay/OverlayPanelBase.js.map +1 -1
  50. package/dist-es/pill-input/PillInput.css.js +4 -0
  51. package/dist-es/pill-input/PillInput.css.js.map +1 -0
  52. package/dist-es/pill-input/PillInput.js +252 -0
  53. package/dist-es/pill-input/PillInput.js.map +1 -0
  54. package/dist-es/pill-input/useTruncatePills.js +81 -0
  55. package/dist-es/pill-input/useTruncatePills.js.map +1 -0
  56. package/dist-es/tabs/Tab.js +1 -1
  57. package/dist-es/tabs/Tab.js.map +1 -1
  58. package/dist-es/tabs-next/TabNextContext.js.map +1 -1
  59. package/dist-es/tabs-next/TabstripNext.css.js +1 -1
  60. package/dist-es/tabs-next/TabstripNext.js +23 -21
  61. package/dist-es/tabs-next/TabstripNext.js.map +1 -1
  62. package/dist-es/utils/useValueEffect.js +36 -0
  63. package/dist-es/utils/useValueEffect.js.map +1 -0
  64. package/dist-types/combo-box-next/ComboBoxNext.d.ts +3 -3
  65. package/dist-types/index.d.ts +0 -1
  66. package/dist-types/pill-input/PillInput.d.ts +48 -0
  67. package/dist-types/pill-input/index.d.ts +1 -0
  68. package/dist-types/pill-input/useTruncatePills.d.ts +8 -0
  69. package/dist-types/tabs/drag-drop/drag-utils.d.ts +6 -6
  70. package/dist-types/tabs-next/TabNextContext.d.ts +2 -2
  71. package/dist-types/utils/useValueEffect.d.ts +4 -0
  72. package/package.json +2 -2
  73. package/dist-cjs/dialog/Dialog.css.js +0 -6
  74. package/dist-cjs/dialog/Dialog.css.js.map +0 -1
  75. package/dist-cjs/dialog/Dialog.js +0 -115
  76. package/dist-cjs/dialog/Dialog.js.map +0 -1
  77. package/dist-cjs/dialog/DialogActions.css.js +0 -6
  78. package/dist-cjs/dialog/DialogActions.css.js.map +0 -1
  79. package/dist-cjs/dialog/DialogActions.js +0 -33
  80. package/dist-cjs/dialog/DialogActions.js.map +0 -1
  81. package/dist-cjs/dialog/DialogCloseButton.css.js +0 -6
  82. package/dist-cjs/dialog/DialogCloseButton.css.js.map +0 -1
  83. package/dist-cjs/dialog/DialogCloseButton.js +0 -39
  84. package/dist-cjs/dialog/DialogCloseButton.js.map +0 -1
  85. package/dist-cjs/dialog/DialogContent.css.js +0 -6
  86. package/dist-cjs/dialog/DialogContent.css.js.map +0 -1
  87. package/dist-cjs/dialog/DialogContent.js +0 -45
  88. package/dist-cjs/dialog/DialogContent.js.map +0 -1
  89. package/dist-cjs/dialog/DialogContext.js +0 -17
  90. package/dist-cjs/dialog/DialogContext.js.map +0 -1
  91. package/dist-cjs/dialog/DialogHeader.css.js +0 -6
  92. package/dist-cjs/dialog/DialogHeader.css.js.map +0 -1
  93. package/dist-cjs/dialog/DialogHeader.js +0 -67
  94. package/dist-cjs/dialog/DialogHeader.js.map +0 -1
  95. package/dist-es/dialog/Dialog.css.js +0 -4
  96. package/dist-es/dialog/Dialog.css.js.map +0 -1
  97. package/dist-es/dialog/Dialog.js +0 -110
  98. package/dist-es/dialog/Dialog.js.map +0 -1
  99. package/dist-es/dialog/DialogActions.css.js +0 -4
  100. package/dist-es/dialog/DialogActions.css.js.map +0 -1
  101. package/dist-es/dialog/DialogActions.js +0 -29
  102. package/dist-es/dialog/DialogActions.js.map +0 -1
  103. package/dist-es/dialog/DialogCloseButton.css.js +0 -4
  104. package/dist-es/dialog/DialogCloseButton.css.js.map +0 -1
  105. package/dist-es/dialog/DialogCloseButton.js +0 -31
  106. package/dist-es/dialog/DialogCloseButton.js.map +0 -1
  107. package/dist-es/dialog/DialogContent.css.js +0 -4
  108. package/dist-es/dialog/DialogContent.css.js.map +0 -1
  109. package/dist-es/dialog/DialogContent.js +0 -41
  110. package/dist-es/dialog/DialogContent.js.map +0 -1
  111. package/dist-es/dialog/DialogContext.js +0 -12
  112. package/dist-es/dialog/DialogContext.js.map +0 -1
  113. package/dist-es/dialog/DialogHeader.css.js +0 -4
  114. package/dist-es/dialog/DialogHeader.css.js.map +0 -1
  115. package/dist-es/dialog/DialogHeader.js +0 -59
  116. package/dist-es/dialog/DialogHeader.js.map +0 -1
  117. package/dist-types/dialog/Dialog.d.ts +0 -46
  118. package/dist-types/dialog/DialogActions.d.ts +0 -8
  119. package/dist-types/dialog/DialogCloseButton.d.ts +0 -2
  120. package/dist-types/dialog/DialogContent.d.ts +0 -8
  121. package/dist-types/dialog/DialogContext.d.ts +0 -8
  122. package/dist-types/dialog/DialogHeader.d.ts +0 -22
  123. package/dist-types/dialog/index.d.ts +0 -6
@@ -0,0 +1,4 @@
1
+ var css_248z = "/* Style applied to the root element */\n.saltPillInput {\n --input-borderColor: var(--salt-editable-borderColor);\n --input-borderStyle: var(--salt-editable-borderStyle);\n --input-outlineColor: var(--salt-focused-outlineColor);\n --input-borderWidth: var(--salt-size-border);\n\n align-items: center;\n background: var(--saltInput-background, var(--input-background));\n color: var(--saltInput-color, var(--salt-content-primary-foreground));\n display: inline-flex;\n font-family: var(--salt-text-fontFamily);\n font-size: var(--saltInput-fontSize, var(--salt-text-fontSize));\n line-height: var(--saltInput-lineHeight, var(--salt-text-lineHeight));\n min-height: var(--saltInput-minHeight, var(--salt-size-base));\n min-width: var(--saltInput-minWidth, 4em);\n padding-left: var(--saltInput-paddingLeft, var(--salt-spacing-50));\n padding-right: var(--saltInput-paddingRight, var(--salt-spacing-100));\n position: relative;\n width: 100%;\n box-sizing: border-box;\n}\n\n.saltPillInput-truncate {\n height: var(--salt-size-base);\n}\n\n.saltPillInput-truncate .saltPillInput-inputWrapper {\n flex-wrap: nowrap;\n}\n\n.saltPillInput:hover {\n --input-borderStyle: var(--salt-editable-borderStyle-hover);\n --input-borderColor: var(--salt-editable-borderColor-hover);\n\n background: var(--saltInput-background-hover, var(--input-background-hover));\n cursor: var(--salt-editable-cursor-hover);\n}\n\n.saltPillInput:active {\n --input-borderColor: var(--salt-editable-borderColor-active);\n --input-borderStyle: var(--salt-editable-borderStyle-active);\n --input-borderWidth: var(--salt-editable-borderWidth-active);\n\n background: var(--saltInput-background-active, var(--input-background-active));\n cursor: var(--salt-editable-cursor-active);\n}\n\n/* Class applied if `variant=\"primary\"` */\n.saltPillInput-primary {\n --input-background: var(--salt-editable-primary-background);\n --input-background-active: var(--salt-editable-primary-background-active);\n --input-background-hover: var(--salt-editable-primary-background-hover);\n --input-background-disabled: var(--salt-editable-primary-background-disabled);\n --input-background-readonly: var(--salt-editable-primary-background-readonly);\n}\n\n/* Class applied if `variant=\"secondary\"` */\n.saltPillInput-secondary {\n --input-background: var(--salt-editable-secondary-background);\n --input-background-active: var(--salt-editable-secondary-background-active);\n --input-background-hover: var(--salt-editable-secondary-background-active);\n --input-background-disabled: var(--salt-editable-secondary-background-disabled);\n --input-background-readonly: var(--salt-editable-secondary-background-readonly);\n}\n\n/* Style applied to input if `validationState=\"error\"` */\n.saltPillInput-error,\n.saltPillInput-error:hover {\n --input-background: var(--salt-status-error-background);\n --input-background-active: var(--salt-status-error-background);\n --input-background-hover: var(--salt-status-error-background);\n --input-borderColor: var(--salt-status-error-borderColor);\n --input-outlineColor: var(--salt-status-error-borderColor);\n}\n\n/* Style applied to input if `validationState=\"warning\"` */\n.saltPillInput-warning,\n.saltPillInput-warning:hover {\n --input-background: var(--salt-status-warning-background);\n --input-background-active: var(--salt-status-warning-background);\n --input-background-hover: var(--salt-status-warning-background);\n --input-borderColor: var(--salt-status-warning-borderColor);\n --input-outlineColor: var(--salt-status-warning-borderColor);\n}\n\n/* Style applied to input if `validationState=\"success\"` */\n.saltPillInput-success,\n.saltPillInput-success:hover {\n --input-background: var(--salt-status-success-background);\n --input-background-active: var(--salt-status-success-background);\n --input-background-hover: var(--salt-status-success-background);\n --input-borderColor: var(--salt-status-success-borderColor);\n --input-outlineColor: var(--salt-status-success-borderColor);\n}\n\n/* Style applied to inner input component */\n.saltPillInput-input {\n background: none;\n border: none;\n box-sizing: content-box;\n color: inherit;\n cursor: inherit;\n display: block;\n flex: 1;\n font: inherit;\n height: 100%;\n letter-spacing: var(--saltInput-letterSpacing, 0);\n margin: 0;\n min-width: 0;\n overflow: hidden;\n padding: 0;\n text-align: var(--input-textAlign);\n width: 100%;\n}\n\n/* Reset in the class */\n.saltPillInput-input:focus {\n outline: none;\n}\n\n/* Style applied to selected input */\n.saltPillInput-input::selection {\n background: var(--salt-content-foreground-highlight);\n}\n\n/* Style applied to placeholder text */\n.saltPillInput-input::placeholder {\n color: var(--salt-content-secondary-foreground);\n font-weight: var(--salt-text-fontWeight-small);\n}\n\n/* Styling when focused */\n.saltPillInput-focused {\n --input-borderColor: var(--input-outlineColor);\n --input-borderWidth: var(--salt-editable-borderWidth-active);\n\n outline: var(--saltInput-outline, var(--salt-focused-outlineWidth) var(--salt-focused-outlineStyle) var(--input-outlineColor));\n}\n\n/* Style applied if `readOnly={true}` */\n.saltPillInput.saltPillInput-readOnly {\n --input-borderColor: var(--salt-editable-borderColor-readonly);\n --input-borderStyle: var(--salt-editable-borderStyle-readonly);\n --input-borderWidth: var(--salt-size-border);\n\n background: var(--input-background-readonly);\n cursor: var(--salt-editable-cursor-readonly);\n}\n\n/* Styling when focused if `disabled={true}` */\n.saltPillInput-focused.saltPillInput-disabled {\n --input-borderWidth: var(--salt-size-border);\n outline: none;\n}\n\n/* Styling when focused if `readOnly={true}` */\n.saltPillInput-focused.saltPillInput-readOnly {\n --input-borderWidth: var(--salt-size-border);\n}\n\n/* Style applied to selected input if `disabled={true}` */\n.saltPillInput-disabled .saltPillInput-input::selection {\n background: none;\n}\n\n/* Style applied to input if `disabled={true}` */\n.saltPillInput.saltPillInput-disabled,\n.saltPillInput.saltPillInput-disabled:hover,\n.saltPillInput.saltPillInput-disabled:active {\n --input-borderColor: var(--salt-editable-borderColor-disabled);\n --input-borderStyle: var(--salt-editable-borderStyle-disabled);\n --input-borderWidth: var(--salt-size-border);\n\n background: var(--input-background-disabled);\n cursor: var(--salt-editable-cursor-disabled);\n color: var(--saltInput-color-disabled, var(--salt-content-primary-foreground-disabled));\n}\n\n.saltPillInput-activationIndicator {\n left: 0;\n bottom: 0;\n width: 100%;\n position: absolute;\n border-bottom: var(--input-borderWidth) var(--input-borderStyle) var(--input-borderColor);\n}\n\n/* Style applied to start adornments */\n.saltPillInput-startAdornmentContainer {\n align-items: center;\n display: inline-flex;\n padding-right: var(--salt-spacing-100);\n column-gap: var(--salt-spacing-100);\n}\n\n/* Style applied to end adornments */\n.saltPillInput-endAdornmentContainer {\n align-items: center;\n display: inline-flex;\n padding-left: var(--salt-spacing-100);\n padding-top: var(--salt-spacing-50);\n column-gap: var(--salt-spacing-100);\n align-self: flex-start;\n}\n\n.saltPillInput-readOnly .saltPillInput-startAdornmentContainer {\n margin-left: var(--salt-spacing-50);\n}\n\n.saltPillInput-startAdornmentContainer .saltButton ~ .saltButton {\n margin-left: calc(-1 * var(--salt-spacing-50));\n}\n.saltPillInput-endAdornmentContainer .saltButton ~ .saltButton {\n margin-left: calc(-1 * var(--salt-spacing-50));\n}\n\n.saltPillInput-startAdornmentContainer .saltButton:first-child {\n margin-left: calc(var(--salt-spacing-50) * -1);\n}\n.saltPillInput-endAdornmentContainer .saltButton:last-child {\n margin-right: calc(var(--salt-spacing-50) * -1);\n}\n\n.saltPillInput-startAdornmentContainer > .saltButton,\n.saltPillInput-endAdornmentContainer > .saltButton {\n --saltButton-padding: var(--salt-spacing-50);\n --saltButton-height: calc(var(--salt-size-base) - var(--salt-spacing-100));\n}\n\n.saltPillInput-inputWrapper {\n display: flex;\n gap: var(--salt-spacing-50);\n align-items: center;\n flex: 1;\n padding: var(--salt-spacing-50) 0;\n flex-wrap: wrap;\n max-height: inherit;\n height: inherit;\n overflow-y: auto;\n box-sizing: border-box;\n}\n\n.saltPillInput-pillList {\n display: contents;\n}\n\n.saltPillInput .saltPill:focus-visible {\n background: var(--salt-selectable-background-hover);\n outline: none;\n}\n\n.saltPillInput .saltPill:hover {\n background: var(--salt-selectable-background-hover);\n}\n\n.saltPillInput .saltPill:active {\n background: var(--salt-actionable-primary-background-active);\n --saltPill-color: var(--salt-actionable-primary-foreground-active);\n --saltIcon-color: var(--salt-actionable-primary-foreground-active);\n}\n\ndiv[role=\"listitem\"] {\n display: inline;\n}\n\n.saltPillInput-overflowIndicator {\n width: calc(var(--salt-size-base) - var(--salt-spacing-100));\n height: calc(var(--salt-size-base) - var(--salt-spacing-100));\n display: flex;\n align-items: center;\n justify-content: center;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=PillInput.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PillInput.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,252 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { clsx } from 'clsx';
3
+ import { forwardRef, useState, useRef } from 'react';
4
+ import { useComponentCssInjection } from '@salt-ds/styles';
5
+ import { useWindow } from '@salt-ds/window';
6
+ import { makePrefixer, useFormFieldProps, useControlled, useId, useForkRef, Pill, StatusAdornment } from '@salt-ds/core';
7
+ import css_248z from './PillInput.css.js';
8
+ import { CloseIcon, OverflowMenuIcon } from '@salt-ds/icons';
9
+ import { useTruncatePills } from './useTruncatePills.js';
10
+
11
+ const withBaseName = makePrefixer("saltPillInput");
12
+ const PillInput = forwardRef(function PillInput2({
13
+ "aria-activedescendant": ariaActiveDescendant,
14
+ "aria-expanded": ariaExpanded,
15
+ "aria-owns": ariaOwns,
16
+ className: classNameProp,
17
+ disabled,
18
+ emptyReadOnlyMarker = "\u2014",
19
+ endAdornment,
20
+ hidePillClose,
21
+ id: idProp,
22
+ inputProps = {},
23
+ inputRef: inputRefProp,
24
+ placeholder,
25
+ pills = [],
26
+ onPillRemove,
27
+ readOnly: readOnlyProp,
28
+ role,
29
+ startAdornment,
30
+ style,
31
+ textAlign = "left",
32
+ value: valueProp,
33
+ defaultValue: defaultValueProp = valueProp === void 0 ? "" : void 0,
34
+ validationStatus: validationStatusProp,
35
+ variant = "primary",
36
+ truncate,
37
+ ...other
38
+ }, ref) {
39
+ const targetWindow = useWindow();
40
+ useComponentCssInjection({
41
+ testId: "salt-pill-input",
42
+ css: css_248z,
43
+ window: targetWindow
44
+ });
45
+ const {
46
+ a11yProps: {
47
+ "aria-describedby": formFieldDescribedBy,
48
+ "aria-labelledby": formFieldLabelledBy
49
+ } = {},
50
+ disabled: formFieldDisabled,
51
+ readOnly: formFieldReadOnly,
52
+ necessity: formFieldRequired,
53
+ validationStatus: formFieldValidationStatus
54
+ } = useFormFieldProps();
55
+ const restA11yProps = {
56
+ "aria-activedescendant": ariaActiveDescendant,
57
+ "aria-expanded": ariaExpanded,
58
+ "aria-owns": ariaOwns
59
+ };
60
+ const isDisabled = disabled || formFieldDisabled;
61
+ const isReadOnly = readOnlyProp || formFieldReadOnly;
62
+ const validationStatus = formFieldValidationStatus != null ? formFieldValidationStatus : validationStatusProp;
63
+ const [focusedPillIndex, setFocusedPillIndex] = useState(-1);
64
+ const isEmptyReadOnly = isReadOnly && !defaultValueProp && !valueProp;
65
+ const defaultValue = isEmptyReadOnly ? emptyReadOnlyMarker : defaultValueProp;
66
+ const {
67
+ "aria-describedby": inputDescribedBy,
68
+ "aria-labelledby": inputLabelledBy,
69
+ onChange,
70
+ required: inputPropsRequired,
71
+ onKeyDown: inputOnKeyDown,
72
+ ...restInputProps
73
+ } = inputProps;
74
+ const isRequired = formFieldRequired ? ["required", "asterisk"].includes(formFieldRequired) : inputPropsRequired;
75
+ const [value, setValue] = useControlled({
76
+ controlled: valueProp,
77
+ default: defaultValue,
78
+ name: "Input",
79
+ state: "value"
80
+ });
81
+ const { visiblePills, pillListRef } = useTruncatePills({
82
+ pills,
83
+ enable: truncate && pills.length > 0
84
+ });
85
+ const id = useId(idProp);
86
+ const pillListId = `${id}-optionsList`;
87
+ const pillElementsRef = useRef([]);
88
+ const inputRef = useRef(null);
89
+ const handleInputRef = useForkRef(inputRef, inputRefProp);
90
+ const handleChange = (event) => {
91
+ const value2 = event.target.value;
92
+ setValue(value2);
93
+ onChange == null ? void 0 : onChange(event);
94
+ };
95
+ const handleKeyDown = (event) => {
96
+ var _a;
97
+ const target = event.currentTarget;
98
+ if (target.selectionStart === 0 && target.selectionEnd == 0) {
99
+ const lastPillIndex = pills.length - 1;
100
+ const lastPill = pills[lastPillIndex];
101
+ if (event.key === "Backspace" && lastPill) {
102
+ event.preventDefault();
103
+ onPillRemove == null ? void 0 : onPillRemove(event, lastPillIndex);
104
+ } else if (event.key === "ArrowLeft") {
105
+ event.preventDefault();
106
+ (_a = pillElementsRef.current[lastPillIndex]) == null ? void 0 : _a.focus();
107
+ }
108
+ }
109
+ inputOnKeyDown == null ? void 0 : inputOnKeyDown(event);
110
+ };
111
+ const handlePillKeyDown = (event) => {
112
+ var _a, _b, _c, _d, _e, _f;
113
+ const target = event.currentTarget;
114
+ const index = Number(target.dataset.index);
115
+ if (event.key === "ArrowLeft") {
116
+ event.preventDefault();
117
+ (_a = pillElementsRef.current[index - 1]) == null ? void 0 : _a.focus();
118
+ } else if (event.key === "ArrowRight") {
119
+ event.preventDefault();
120
+ if (index === pills.length - 1) {
121
+ (_b = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _b.focus();
122
+ } else {
123
+ (_c = pillElementsRef.current[index + 1]) == null ? void 0 : _c.focus();
124
+ }
125
+ } else if (event.key == "Delete" || event.key === "Backspace") {
126
+ event.preventDefault();
127
+ onPillRemove == null ? void 0 : onPillRemove(event, index);
128
+ if (pills.length === 1) {
129
+ (_d = inputRef.current) == null ? void 0 : _d.focus();
130
+ } else if (index === pills.length - 1) {
131
+ (_e = pillElementsRef.current[pills.length - 2]) == null ? void 0 : _e.focus();
132
+ } else {
133
+ (_f = pillElementsRef.current[index]) == null ? void 0 : _f.focus();
134
+ }
135
+ }
136
+ };
137
+ const handlePillClick = (event) => {
138
+ var _a;
139
+ const target = event.currentTarget;
140
+ const index = Number(target.dataset.index);
141
+ onPillRemove == null ? void 0 : onPillRemove(event, index);
142
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
143
+ };
144
+ const inputStyle = {
145
+ "--input-textAlign": textAlign,
146
+ ...style
147
+ };
148
+ return /* @__PURE__ */ jsxs("div", {
149
+ className: clsx(
150
+ withBaseName(),
151
+ withBaseName(variant),
152
+ {
153
+ [withBaseName("disabled")]: isDisabled,
154
+ [withBaseName("readOnly")]: isReadOnly,
155
+ [withBaseName("truncate")]: truncate,
156
+ [withBaseName(validationStatus || "")]: validationStatus
157
+ },
158
+ classNameProp
159
+ ),
160
+ ref,
161
+ style: inputStyle,
162
+ ...other,
163
+ children: [
164
+ startAdornment && /* @__PURE__ */ jsx("div", {
165
+ className: withBaseName("startAdornmentContainer"),
166
+ children: startAdornment
167
+ }),
168
+ /* @__PURE__ */ jsxs("div", {
169
+ className: withBaseName("inputWrapper"),
170
+ ref: pillListRef,
171
+ children: [
172
+ /* @__PURE__ */ jsxs("div", {
173
+ role: "list",
174
+ className: withBaseName("pillList"),
175
+ "aria-labelledby": clsx(formFieldLabelledBy, pillListId),
176
+ "aria-label": "Selected Options",
177
+ id: pillListId,
178
+ children: [
179
+ visiblePills == null ? void 0 : visiblePills.map((pill, index) => /* @__PURE__ */ jsx("div", {
180
+ role: "listitem",
181
+ children: /* @__PURE__ */ jsxs(Pill, {
182
+ "data-index": index,
183
+ disabled,
184
+ ref: (element) => {
185
+ if (element) {
186
+ pillElementsRef.current[index] = element;
187
+ } else {
188
+ pillElementsRef.current = pillElementsRef.current.filter(
189
+ (pillEl) => pillEl !== element
190
+ );
191
+ }
192
+ },
193
+ onFocus: () => setFocusedPillIndex(index),
194
+ onKeyDown: handlePillKeyDown,
195
+ onClick: handlePillClick,
196
+ tabIndex: focusedPillIndex === -1 || focusedPillIndex === index ? 0 : -1,
197
+ children: [
198
+ pill,
199
+ !hidePillClose && /* @__PURE__ */ jsx(CloseIcon, {
200
+ "aria-label": "click to close"
201
+ })
202
+ ]
203
+ })
204
+ }, index)),
205
+ visiblePills.length < pills.length && /* @__PURE__ */ jsx("div", {
206
+ role: "listitem",
207
+ children: /* @__PURE__ */ jsx("div", {
208
+ "data-overflowindicator": true,
209
+ className: withBaseName("overflowIndicator"),
210
+ children: /* @__PURE__ */ jsx(OverflowMenuIcon, {
211
+ "aria-hidden": true
212
+ })
213
+ })
214
+ })
215
+ ]
216
+ }),
217
+ /* @__PURE__ */ jsx("input", {
218
+ "aria-describedby": clsx(formFieldDescribedBy, inputDescribedBy),
219
+ "aria-labelledby": clsx(formFieldLabelledBy, inputLabelledBy),
220
+ className: clsx(withBaseName("input"), inputProps == null ? void 0 : inputProps.className),
221
+ disabled: isDisabled,
222
+ id,
223
+ readOnly: isReadOnly,
224
+ ref: handleInputRef,
225
+ role,
226
+ tabIndex: isDisabled ? -1 : 0,
227
+ onChange: handleChange,
228
+ onKeyDown: handleKeyDown,
229
+ placeholder,
230
+ value,
231
+ ...restA11yProps,
232
+ ...restInputProps,
233
+ required: isRequired
234
+ })
235
+ ]
236
+ }),
237
+ !isDisabled && !isReadOnly && validationStatus && /* @__PURE__ */ jsx(StatusAdornment, {
238
+ status: validationStatus
239
+ }),
240
+ endAdornment && /* @__PURE__ */ jsx("div", {
241
+ className: withBaseName("endAdornmentContainer"),
242
+ children: endAdornment
243
+ }),
244
+ /* @__PURE__ */ jsx("div", {
245
+ className: withBaseName("activationIndicator")
246
+ })
247
+ ]
248
+ });
249
+ });
250
+
251
+ export { PillInput };
252
+ //# sourceMappingURL=PillInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PillInput.js","sources":["../src/pill-input/PillInput.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n SyntheticEvent,\n ComponentPropsWithoutRef,\n MouseEvent,\n ForwardedRef,\n forwardRef,\n InputHTMLAttributes,\n ReactNode,\n Ref,\n useState,\n useRef,\n} from \"react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n makePrefixer,\n useControlled,\n useFormFieldProps,\n StatusAdornment,\n useId,\n Pill,\n useForkRef,\n} from \"@salt-ds/core\";\n\nimport pillInputCss from \"./PillInput.css\";\nimport { CloseIcon, OverflowMenuIcon } from \"@salt-ds/icons\";\nimport { useTruncatePills } from \"./useTruncatePills\";\n\nconst withBaseName = makePrefixer(\"saltPillInput\");\n\nexport interface PillInputProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"defaultValue\">,\n Pick<\n ComponentPropsWithoutRef<\"input\">,\n \"disabled\" | \"value\" | \"defaultValue\" | \"placeholder\"\n > {\n /**\n * The marker to use in an empty read only Input.\n * Use `''` to disable this feature. Defaults to '—'.\n */\n emptyReadOnlyMarker?: string;\n /**\n * End adornment component\n */\n endAdornment?: ReactNode;\n /**\n * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.\n */\n inputProps?: InputHTMLAttributes<HTMLInputElement>;\n /**\n * Optional ref for the input component\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * If `true`, the component is read only.\n */\n readOnly?: boolean;\n /**\n * The tokens to display in the input.\n */\n pills?: any[];\n onPillRemove?: (event: SyntheticEvent, index: number) => void;\n /**\n * Start adornment component\n */\n startAdornment?: ReactNode;\n /**\n * Alignment of text within container. Defaults to \"left\"\n */\n textAlign?: \"left\" | \"center\" | \"right\";\n /**\n * Validation status.\n */\n validationStatus?: \"error\" | \"warning\" | \"success\";\n /**\n * Styling variant. Defaults to \"primary\".\n */\n variant?: \"primary\" | \"secondary\";\n hidePillClose?: boolean;\n truncate?: boolean;\n}\n\nexport const PillInput = forwardRef(function PillInput<Item>(\n {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n className: classNameProp,\n disabled,\n emptyReadOnlyMarker = \"—\",\n endAdornment,\n hidePillClose,\n id: idProp,\n inputProps = {},\n inputRef: inputRefProp,\n placeholder,\n pills = [],\n onPillRemove,\n readOnly: readOnlyProp,\n role,\n startAdornment,\n style,\n textAlign = \"left\",\n value: valueProp,\n defaultValue: defaultValueProp = valueProp === undefined ? \"\" : undefined,\n validationStatus: validationStatusProp,\n variant = \"primary\",\n truncate,\n ...other\n }: PillInputProps,\n ref: ForwardedRef<HTMLDivElement>\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-pill-input\",\n css: pillInputCss,\n window: targetWindow,\n });\n\n const {\n a11yProps: {\n \"aria-describedby\": formFieldDescribedBy,\n \"aria-labelledby\": formFieldLabelledBy,\n } = {},\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n necessity: formFieldRequired,\n validationStatus: formFieldValidationStatus,\n } = useFormFieldProps();\n\n const restA11yProps = {\n \"aria-activedescendant\": ariaActiveDescendant,\n \"aria-expanded\": ariaExpanded,\n \"aria-owns\": ariaOwns,\n };\n\n const isDisabled = disabled || formFieldDisabled;\n const isReadOnly = readOnlyProp || formFieldReadOnly;\n const validationStatus = formFieldValidationStatus ?? validationStatusProp;\n\n const [focusedPillIndex, setFocusedPillIndex] = useState(-1);\n\n const isEmptyReadOnly = isReadOnly && !defaultValueProp && !valueProp;\n const defaultValue = isEmptyReadOnly ? emptyReadOnlyMarker : defaultValueProp;\n\n const {\n \"aria-describedby\": inputDescribedBy,\n \"aria-labelledby\": inputLabelledBy,\n onChange,\n required: inputPropsRequired,\n onKeyDown: inputOnKeyDown,\n ...restInputProps\n } = inputProps;\n\n const isRequired = formFieldRequired\n ? [\"required\", \"asterisk\"].includes(formFieldRequired)\n : inputPropsRequired;\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"Input\",\n state: \"value\",\n });\n\n const { visiblePills, pillListRef } = useTruncatePills({\n pills,\n enable: truncate && pills.length > 0,\n });\n\n const id = useId(idProp);\n const pillListId = `${id}-optionsList`;\n\n const pillElementsRef = useRef<HTMLElement[]>([]);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleInputRef = useForkRef(inputRef, inputRefProp);\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const value = event.target.value;\n setValue(value);\n onChange?.(event);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n const target = event.currentTarget;\n if (target.selectionStart === 0 && target.selectionEnd == 0) {\n const lastPillIndex = pills.length - 1;\n const lastPill = pills[lastPillIndex];\n if (event.key === \"Backspace\" && lastPill) {\n event.preventDefault();\n onPillRemove?.(event, lastPillIndex);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n // Move focus to last pill\n pillElementsRef.current[lastPillIndex]?.focus();\n }\n }\n\n inputOnKeyDown?.(event);\n };\n\n const handlePillKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n const target = event.currentTarget;\n const index = Number(target.dataset.index);\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n // Move focus to previous pill\n pillElementsRef.current[index - 1]?.focus();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n // Move focus to next pill or input\n if (index === pills.length - 1) {\n inputRef?.current?.focus();\n } else {\n pillElementsRef.current[index + 1]?.focus();\n }\n } else if (event.key == \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n onPillRemove?.(event, index);\n\n if (pills.length === 1) {\n inputRef.current?.focus();\n } else if (index === pills.length - 1) {\n pillElementsRef.current[pills.length - 2]?.focus();\n } else {\n pillElementsRef.current[index]?.focus();\n }\n }\n };\n\n const handlePillClick = (event: MouseEvent<HTMLButtonElement>) => {\n const target = event.currentTarget;\n const index = Number(target.dataset.index);\n onPillRemove?.(event, index);\n inputRef.current?.focus();\n };\n\n const inputStyle = {\n \"--input-textAlign\": textAlign,\n ...style,\n };\n\n return (\n <div\n className={clsx(\n withBaseName(),\n withBaseName(variant),\n {\n [withBaseName(\"disabled\")]: isDisabled,\n [withBaseName(\"readOnly\")]: isReadOnly,\n [withBaseName(\"truncate\")]: truncate,\n [withBaseName(validationStatus || \"\")]: validationStatus,\n },\n classNameProp\n )}\n ref={ref}\n style={inputStyle}\n {...other}\n >\n {startAdornment && (\n <div className={withBaseName(\"startAdornmentContainer\")}>\n {startAdornment}\n </div>\n )}\n <div className={withBaseName(\"inputWrapper\")} ref={pillListRef}>\n <div\n role=\"list\"\n className={withBaseName(\"pillList\")}\n aria-labelledby={clsx(formFieldLabelledBy, pillListId)}\n aria-label=\"Selected Options\"\n id={pillListId}\n >\n {visiblePills?.map((pill, index) => (\n <div role=\"listitem\" key={index}>\n <Pill\n data-index={index}\n disabled={disabled}\n ref={(element) => {\n if (element) {\n pillElementsRef.current[index] = element;\n } else {\n pillElementsRef.current = pillElementsRef.current.filter(\n (pillEl) => pillEl !== element\n );\n }\n }}\n onFocus={() => setFocusedPillIndex(index)}\n onKeyDown={handlePillKeyDown}\n onClick={handlePillClick}\n tabIndex={\n focusedPillIndex === -1 || focusedPillIndex === index ? 0 : -1\n }\n >\n {pill}\n {!hidePillClose && <CloseIcon aria-label=\"click to close\" />}\n </Pill>\n </div>\n ))}\n {visiblePills.length < pills.length && (\n <div role=\"listitem\">\n <div\n data-overflowindicator\n className={withBaseName(\"overflowIndicator\")}\n >\n <OverflowMenuIcon aria-hidden />\n </div>\n </div>\n )}\n </div>\n <input\n aria-describedby={clsx(formFieldDescribedBy, inputDescribedBy)}\n aria-labelledby={clsx(formFieldLabelledBy, inputLabelledBy)}\n className={clsx(withBaseName(\"input\"), inputProps?.className)}\n disabled={isDisabled}\n id={id}\n readOnly={isReadOnly}\n ref={handleInputRef}\n role={role}\n tabIndex={isDisabled ? -1 : 0}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n value={value}\n {...restA11yProps}\n {...restInputProps}\n required={isRequired}\n />\n </div>\n {!isDisabled && !isReadOnly && validationStatus && (\n <StatusAdornment status={validationStatus} />\n )}\n {endAdornment && (\n <div className={withBaseName(\"endAdornmentContainer\")}>\n {endAdornment}\n </div>\n )}\n <div className={withBaseName(\"activationIndicator\")} />\n </div>\n );\n});\n"],"names":["PillInput","pillInputCss","value"],"mappings":";;;;;;;;;;AA+BA,MAAM,YAAA,GAAe,aAAa,eAAe,CAAA,CAAA;AAsDpC,MAAA,SAAA,GAAY,UAAW,CAAA,SAASA,UAC3C,CAAA;AAAA,EACE,uBAAyB,EAAA,oBAAA;AAAA,EACzB,eAAiB,EAAA,YAAA;AAAA,EACjB,WAAa,EAAA,QAAA;AAAA,EACb,SAAW,EAAA,aAAA;AAAA,EACX,QAAA;AAAA,EACA,mBAAsB,GAAA,QAAA;AAAA,EACtB,YAAA;AAAA,EACA,aAAA;AAAA,EACA,EAAI,EAAA,MAAA;AAAA,EACJ,aAAa,EAAC;AAAA,EACd,QAAU,EAAA,YAAA;AAAA,EACV,WAAA;AAAA,EACA,QAAQ,EAAC;AAAA,EACT,YAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,IAAA;AAAA,EACA,cAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAY,GAAA,MAAA;AAAA,EACZ,KAAO,EAAA,SAAA;AAAA,EACP,YAAc,EAAA,gBAAA,GAAmB,SAAc,KAAA,KAAA,CAAA,GAAY,EAAK,GAAA,KAAA,CAAA;AAAA,EAChE,gBAAkB,EAAA,oBAAA;AAAA,EAClB,OAAU,GAAA,SAAA;AAAA,EACV,QAAA;AAAA,EACG,GAAA,KAAA;AACL,CAAA,EACA,GACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,iBAAA;AAAA,IACR,GAAK,EAAAC,QAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,SAAW,EAAA;AAAA,MACT,kBAAoB,EAAA,oBAAA;AAAA,MACpB,iBAAmB,EAAA,mBAAA;AAAA,QACjB,EAAC;AAAA,IACL,QAAU,EAAA,iBAAA;AAAA,IACV,QAAU,EAAA,iBAAA;AAAA,IACV,SAAW,EAAA,iBAAA;AAAA,IACX,gBAAkB,EAAA,yBAAA;AAAA,MAChB,iBAAkB,EAAA,CAAA;AAEtB,EAAA,MAAM,aAAgB,GAAA;AAAA,IACpB,uBAAyB,EAAA,oBAAA;AAAA,IACzB,eAAiB,EAAA,YAAA;AAAA,IACjB,WAAa,EAAA,QAAA;AAAA,GACf,CAAA;AAEA,EAAA,MAAM,aAAa,QAAY,IAAA,iBAAA,CAAA;AAC/B,EAAA,MAAM,aAAa,YAAgB,IAAA,iBAAA,CAAA;AACnC,EAAA,MAAM,mBAAmB,yBAA6B,IAAA,IAAA,GAAA,yBAAA,GAAA,oBAAA,CAAA;AAEtD,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,CAAE,CAAA,CAAA,CAAA;AAE3D,EAAA,MAAM,eAAkB,GAAA,UAAA,IAAc,CAAC,gBAAA,IAAoB,CAAC,SAAA,CAAA;AAC5D,EAAM,MAAA,YAAA,GAAe,kBAAkB,mBAAsB,GAAA,gBAAA,CAAA;AAE7D,EAAM,MAAA;AAAA,IACJ,kBAAoB,EAAA,gBAAA;AAAA,IACpB,iBAAmB,EAAA,eAAA;AAAA,IACnB,QAAA;AAAA,IACA,QAAU,EAAA,kBAAA;AAAA,IACV,SAAW,EAAA,cAAA;AAAA,IACR,GAAA,cAAA;AAAA,GACD,GAAA,UAAA,CAAA;AAEJ,EAAM,MAAA,UAAA,GAAa,oBACf,CAAC,UAAA,EAAY,UAAU,CAAE,CAAA,QAAA,CAAS,iBAAiB,CACnD,GAAA,kBAAA,CAAA;AAEJ,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,aAAc,CAAA;AAAA,IACtC,UAAY,EAAA,SAAA;AAAA,IACZ,OAAS,EAAA,YAAA;AAAA,IACT,IAAM,EAAA,OAAA;AAAA,IACN,KAAO,EAAA,OAAA;AAAA,GACR,CAAA,CAAA;AAED,EAAA,MAAM,EAAE,YAAA,EAAc,WAAY,EAAA,GAAI,gBAAiB,CAAA;AAAA,IACrD,KAAA;AAAA,IACA,MAAA,EAAQ,QAAY,IAAA,KAAA,CAAM,MAAS,GAAA,CAAA;AAAA,GACpC,CAAA,CAAA;AAED,EAAM,MAAA,EAAA,GAAK,MAAM,MAAM,CAAA,CAAA;AACvB,EAAA,MAAM,aAAa,CAAG,EAAA,EAAA,CAAA,YAAA,CAAA,CAAA;AAEtB,EAAM,MAAA,eAAA,GAAkB,MAAsB,CAAA,EAAE,CAAA,CAAA;AAChD,EAAM,MAAA,QAAA,GAAW,OAAyB,IAAI,CAAA,CAAA;AAE9C,EAAM,MAAA,cAAA,GAAiB,UAAW,CAAA,QAAA,EAAU,YAAY,CAAA,CAAA;AAExD,EAAM,MAAA,YAAA,GAAe,CAAC,KAAyC,KAAA;AAC7D,IAAMC,MAAAA,MAAAA,GAAQ,MAAM,MAAO,CAAA,KAAA,CAAA;AAC3B,IAAA,QAAA,CAASA,MAAK,CAAA,CAAA;AACd,IAAW,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAA,KAAA,CAAA,CAAA;AAAA,GACb,CAAA;AAEA,EAAM,MAAA,aAAA,GAAgB,CAAC,KAA2C,KAAA;AA3LpE,IAAA,IAAA,EAAA,CAAA;AA4LI,IAAA,MAAM,SAAS,KAAM,CAAA,aAAA,CAAA;AACrB,IAAA,IAAI,MAAO,CAAA,cAAA,KAAmB,CAAK,IAAA,MAAA,CAAO,gBAAgB,CAAG,EAAA;AAC3D,MAAM,MAAA,aAAA,GAAgB,MAAM,MAAS,GAAA,CAAA,CAAA;AACrC,MAAA,MAAM,WAAW,KAAM,CAAA,aAAA,CAAA,CAAA;AACvB,MAAI,IAAA,KAAA,CAAM,GAAQ,KAAA,WAAA,IAAe,QAAU,EAAA;AACzC,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAe,KAAO,EAAA,aAAA,CAAA,CAAA;AAAA,OACxB,MAAA,IAAW,KAAM,CAAA,GAAA,KAAQ,WAAa,EAAA;AACpC,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,QAAgB,CAAA,EAAA,GAAA,eAAA,CAAA,OAAA,CAAQ,mBAAxB,IAAwC,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OAC1C;AAAA,KACF;AAEA,IAAiB,cAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,cAAA,CAAA,KAAA,CAAA,CAAA;AAAA,GACnB,CAAA;AAEA,EAAM,MAAA,iBAAA,GAAoB,CAAC,KAA4C,KAAA;AA7MzE,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AA8MI,IAAA,MAAM,SAAS,KAAM,CAAA,aAAA,CAAA;AACrB,IAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,MAAO,CAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AACzC,IAAI,IAAA,KAAA,CAAM,QAAQ,WAAa,EAAA;AAC7B,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAgB,CAAA,EAAA,GAAA,eAAA,CAAA,OAAA,CAAQ,KAAQ,GAAA,CAAA,CAAA,KAAhC,IAAoC,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,KACtC,MAAA,IAAW,KAAM,CAAA,GAAA,KAAQ,YAAc,EAAA;AACrC,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAI,IAAA,KAAA,KAAU,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AAC9B,QAAA,CAAA,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAU,YAAV,IAAmB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OACd,MAAA;AACL,QAAgB,CAAA,EAAA,GAAA,eAAA,CAAA,OAAA,CAAQ,KAAQ,GAAA,CAAA,CAAA,KAAhC,IAAoC,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OACtC;AAAA,eACS,KAAM,CAAA,GAAA,IAAO,QAAY,IAAA,KAAA,CAAM,QAAQ,WAAa,EAAA;AAC7D,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,MAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAe,KAAO,EAAA,KAAA,CAAA,CAAA;AAEtB,MAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,QAAA,CAAA,EAAA,GAAA,QAAA,CAAS,YAAT,IAAkB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OACT,MAAA,IAAA,KAAA,KAAU,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AACrC,QAAA,CAAA,EAAA,GAAA,eAAA,CAAgB,OAAQ,CAAA,KAAA,CAAM,MAAS,GAAA,CAAA,CAAA,KAAvC,IAA2C,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OACtC,MAAA;AACL,QAAgB,CAAA,EAAA,GAAA,eAAA,CAAA,OAAA,CAAQ,WAAxB,IAAgC,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OAClC;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,eAAA,GAAkB,CAAC,KAAyC,KAAA;AA1OpE,IAAA,IAAA,EAAA,CAAA;AA2OI,IAAA,MAAM,SAAS,KAAM,CAAA,aAAA,CAAA;AACrB,IAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,MAAO,CAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AACzC,IAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAe,KAAO,EAAA,KAAA,CAAA,CAAA;AACtB,IAAA,CAAA,EAAA,GAAA,QAAA,CAAS,YAAT,IAAkB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,GACpB,CAAA;AAEA,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,mBAAqB,EAAA,SAAA;AAAA,IACrB,GAAG,KAAA;AAAA,GACL,CAAA;AAEA,EAAA,uBACG,IAAA,CAAA,KAAA,EAAA;AAAA,IACC,SAAW,EAAA,IAAA;AAAA,MACT,YAAa,EAAA;AAAA,MACb,aAAa,OAAO,CAAA;AAAA,MACpB;AAAA,QACE,CAAC,YAAa,CAAA,UAAU,CAAI,GAAA,UAAA;AAAA,QAC5B,CAAC,YAAa,CAAA,UAAU,CAAI,GAAA,UAAA;AAAA,QAC5B,CAAC,YAAa,CAAA,UAAU,CAAI,GAAA,QAAA;AAAA,QAC5B,CAAC,YAAA,CAAa,gBAAoB,IAAA,EAAE,CAAI,GAAA,gBAAA;AAAA,OAC1C;AAAA,MACA,aAAA;AAAA,KACF;AAAA,IACA,GAAA;AAAA,IACA,KAAO,EAAA,UAAA;AAAA,IACN,GAAG,KAAA;AAAA,IAEH,QAAA,EAAA;AAAA,MAAA,cAAA,oBACE,GAAA,CAAA,KAAA,EAAA;AAAA,QAAI,SAAA,EAAW,aAAa,yBAAyB,CAAA;AAAA,QACnD,QAAA,EAAA,cAAA;AAAA,OACH,CAAA;AAAA,sBAED,IAAA,CAAA,KAAA,EAAA;AAAA,QAAI,SAAA,EAAW,aAAa,cAAc,CAAA;AAAA,QAAG,GAAK,EAAA,WAAA;AAAA,QACjD,QAAA,EAAA;AAAA,0BAAC,IAAA,CAAA,KAAA,EAAA;AAAA,YACC,IAAK,EAAA,MAAA;AAAA,YACL,SAAA,EAAW,aAAa,UAAU,CAAA;AAAA,YAClC,iBAAA,EAAiB,IAAK,CAAA,mBAAA,EAAqB,UAAU,CAAA;AAAA,YACrD,YAAW,EAAA,kBAAA;AAAA,YACX,EAAI,EAAA,UAAA;AAAA,YAEH,QAAA,EAAA;AAAA,cAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAc,GAAI,CAAA,CAAC,IAAM,EAAA,KAAA,qBACvB,GAAA,CAAA,KAAA,EAAA;AAAA,gBAAI,IAAK,EAAA,UAAA;AAAA,gBACR,QAAC,kBAAA,IAAA,CAAA,IAAA,EAAA;AAAA,kBACC,YAAY,EAAA,KAAA;AAAA,kBACZ,QAAA;AAAA,kBACA,GAAA,EAAK,CAAC,OAAY,KAAA;AAChB,oBAAA,IAAI,OAAS,EAAA;AACX,sBAAA,eAAA,CAAgB,QAAQ,KAAS,CAAA,GAAA,OAAA,CAAA;AAAA,qBAC5B,MAAA;AACL,sBAAgB,eAAA,CAAA,OAAA,GAAU,gBAAgB,OAAQ,CAAA,MAAA;AAAA,wBAChD,CAAC,WAAW,MAAW,KAAA,OAAA;AAAA,uBACzB,CAAA;AAAA,qBACF;AAAA,mBACF;AAAA,kBACA,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK,CAAA;AAAA,kBACxC,SAAW,EAAA,iBAAA;AAAA,kBACX,OAAS,EAAA,eAAA;AAAA,kBACT,QACE,EAAA,gBAAA,KAAqB,CAAM,CAAA,IAAA,gBAAA,KAAqB,QAAQ,CAAI,GAAA,CAAA,CAAA;AAAA,kBAG7D,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,oBACA,CAAC,iCAAkB,GAAA,CAAA,SAAA,EAAA;AAAA,sBAAU,YAAW,EAAA,gBAAA;AAAA,qBAAiB,CAAA;AAAA,mBAAA;AAAA,iBAC5D,CAAA;AAAA,eAAA,EAtBwB,KAuB1B,CAAA,CAAA;AAAA,cAED,YAAa,CAAA,MAAA,GAAS,KAAM,CAAA,MAAA,oBAC1B,GAAA,CAAA,KAAA,EAAA;AAAA,gBAAI,IAAK,EAAA,UAAA;AAAA,gBACR,QAAC,kBAAA,GAAA,CAAA,KAAA,EAAA;AAAA,kBACC,wBAAsB,EAAA,IAAA;AAAA,kBACtB,SAAA,EAAW,aAAa,mBAAmB,CAAA;AAAA,kBAE3C,QAAC,kBAAA,GAAA,CAAA,gBAAA,EAAA;AAAA,oBAAiB,aAAW,EAAA,IAAA;AAAA,mBAAC,CAAA;AAAA,iBAChC,CAAA;AAAA,eACF,CAAA;AAAA,aAAA;AAAA,WAEJ,CAAA;AAAA,0BACC,GAAA,CAAA,OAAA,EAAA;AAAA,YACC,kBAAA,EAAkB,IAAK,CAAA,oBAAA,EAAsB,gBAAgB,CAAA;AAAA,YAC7D,iBAAA,EAAiB,IAAK,CAAA,mBAAA,EAAqB,eAAe,CAAA;AAAA,YAC1D,WAAW,IAAK,CAAA,YAAA,CAAa,OAAO,CAAA,EAAG,yCAAY,SAAS,CAAA;AAAA,YAC5D,QAAU,EAAA,UAAA;AAAA,YACV,EAAA;AAAA,YACA,QAAU,EAAA,UAAA;AAAA,YACV,GAAK,EAAA,cAAA;AAAA,YACL,IAAA;AAAA,YACA,QAAA,EAAU,aAAa,CAAK,CAAA,GAAA,CAAA;AAAA,YAC5B,QAAU,EAAA,YAAA;AAAA,YACV,SAAW,EAAA,aAAA;AAAA,YACX,WAAA;AAAA,YACA,KAAA;AAAA,YACC,GAAG,aAAA;AAAA,YACH,GAAG,cAAA;AAAA,YACJ,QAAU,EAAA,UAAA;AAAA,WACZ,CAAA;AAAA,SAAA;AAAA,OACF,CAAA;AAAA,MACC,CAAC,UAAA,IAAc,CAAC,UAAA,IAAc,oCAC5B,GAAA,CAAA,eAAA,EAAA;AAAA,QAAgB,MAAQ,EAAA,gBAAA;AAAA,OAAkB,CAAA;AAAA,MAE5C,gCACE,GAAA,CAAA,KAAA,EAAA;AAAA,QAAI,SAAA,EAAW,aAAa,uBAAuB,CAAA;AAAA,QACjD,QAAA,EAAA,YAAA;AAAA,OACH,CAAA;AAAA,sBAED,GAAA,CAAA,KAAA,EAAA;AAAA,QAAI,SAAA,EAAW,aAAa,qBAAqB,CAAA;AAAA,OAAG,CAAA;AAAA,KAAA;AAAA,GACvD,CAAA,CAAA;AAEJ,CAAC;;;;"}
@@ -0,0 +1,81 @@
1
+ import { useRef, useCallback } from 'react';
2
+ import { useIsomorphicLayoutEffect } from '@salt-ds/core';
3
+ import { useValueEffect } from '../utils/useValueEffect.js';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import 'react/jsx-runtime';
6
+ import { useResizeObserver } from '../responsive/useResizeObserver.js';
7
+
8
+ function useTruncatePills({
9
+ pills,
10
+ enable
11
+ }) {
12
+ const pillListRef = useRef(null);
13
+ const [{ visibleCount }, setVisibleItems] = useValueEffect({
14
+ visibleCount: pills.length
15
+ });
16
+ const targetWindow = useWindow();
17
+ const updateOverflow = useCallback(() => {
18
+ if (!enable) {
19
+ return;
20
+ }
21
+ const computeVisible = (visibleCount2) => {
22
+ const pillList = pillListRef.current;
23
+ if (pillList && targetWindow) {
24
+ let pillElements = Array.from(
25
+ pillList.querySelectorAll('[role="listitem"]')
26
+ );
27
+ const maxWidth = pillList.getBoundingClientRect().width;
28
+ const listGap = parseInt(targetWindow.getComputedStyle(pillList).gap);
29
+ let isShowingOverflow = pillList.querySelector(
30
+ "[data-overflowindicator]"
31
+ );
32
+ let currentSize = 0;
33
+ let newVisibleCount = 0;
34
+ if (isShowingOverflow) {
35
+ let pill = pillElements.pop();
36
+ if (pill) {
37
+ let pillWidth = pill.getBoundingClientRect().width;
38
+ currentSize += pillWidth + listGap;
39
+ }
40
+ }
41
+ for (let pill of pillElements) {
42
+ let pillWidth = pill.getBoundingClientRect().width;
43
+ currentSize += pillWidth + listGap;
44
+ if (Math.round(currentSize) <= Math.round(maxWidth)) {
45
+ newVisibleCount++;
46
+ } else {
47
+ break;
48
+ }
49
+ }
50
+ return newVisibleCount;
51
+ }
52
+ return visibleCount2;
53
+ };
54
+ setVisibleItems(function* () {
55
+ yield {
56
+ visibleCount: pills.length
57
+ };
58
+ let newVisibleCount = computeVisible(pills.length);
59
+ let isMeasuring = newVisibleCount < pills.length && newVisibleCount > 0;
60
+ yield {
61
+ visibleCount: newVisibleCount
62
+ };
63
+ if (isMeasuring) {
64
+ newVisibleCount = computeVisible(visibleCount);
65
+ yield {
66
+ visibleCount: newVisibleCount
67
+ };
68
+ }
69
+ });
70
+ }, [pills, setVisibleItems, enable, targetWindow]);
71
+ useIsomorphicLayoutEffect(updateOverflow, [updateOverflow, pills]);
72
+ useResizeObserver(pillListRef, ["width"], updateOverflow, true);
73
+ return {
74
+ pillListRef,
75
+ visibleCount,
76
+ visiblePills: enable ? pills.slice(0, visibleCount) : pills
77
+ };
78
+ }
79
+
80
+ export { useTruncatePills };
81
+ //# sourceMappingURL=useTruncatePills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTruncatePills.js","sources":["../src/pill-input/useTruncatePills.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"@salt-ds/core\";\nimport { useValueEffect } from \"../utils/useValueEffect\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { useResizeObserver } from \"../responsive\";\n\nexport function useTruncatePills({\n pills,\n enable,\n}: {\n pills: string[];\n enable?: boolean;\n}) {\n const pillListRef = useRef<HTMLDivElement>(null);\n const [{ visibleCount }, setVisibleItems] = useValueEffect({\n visibleCount: pills.length,\n });\n const targetWindow = useWindow();\n\n const updateOverflow = useCallback(() => {\n if (!enable) {\n return;\n }\n\n const computeVisible = (visibleCount: number) => {\n const pillList = pillListRef.current;\n\n if (pillList && targetWindow) {\n let pillElements = Array.from(\n pillList.querySelectorAll('[role=\"listitem\"]')\n ) as HTMLLIElement[];\n const maxWidth = pillList.getBoundingClientRect().width;\n const listGap = parseInt(targetWindow.getComputedStyle(pillList).gap);\n let isShowingOverflow = pillList.querySelector(\n \"[data-overflowindicator]\"\n );\n\n let currentSize = 0;\n let newVisibleCount = 0;\n\n if (isShowingOverflow) {\n let pill = pillElements.pop();\n if (pill) {\n let pillWidth = pill.getBoundingClientRect().width;\n currentSize += pillWidth + listGap;\n }\n }\n\n for (let pill of pillElements) {\n let pillWidth = pill.getBoundingClientRect().width;\n currentSize += pillWidth + listGap;\n\n if (Math.round(currentSize) <= Math.round(maxWidth)) {\n newVisibleCount++;\n } else {\n break;\n }\n }\n return newVisibleCount;\n }\n return visibleCount;\n };\n\n setVisibleItems(function* () {\n // Show all\n yield {\n visibleCount: pills.length,\n };\n\n // Measure the visible count\n let newVisibleCount = computeVisible(pills.length);\n let isMeasuring = newVisibleCount < pills.length && newVisibleCount > 0;\n yield {\n visibleCount: newVisibleCount,\n };\n\n // ensure the visible count is correct\n if (isMeasuring) {\n newVisibleCount = computeVisible(visibleCount);\n yield {\n visibleCount: newVisibleCount,\n };\n }\n });\n }, [pills, setVisibleItems, enable, targetWindow]);\n\n useIsomorphicLayoutEffect(updateOverflow, [updateOverflow, pills]);\n useResizeObserver(pillListRef, [\"width\"], updateOverflow, true);\n\n return {\n pillListRef,\n visibleCount,\n visiblePills: enable ? pills.slice(0, visibleCount) : pills,\n };\n}\n"],"names":["visibleCount"],"mappings":"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"}
@@ -79,7 +79,7 @@ const Tab = forwardRef(function Tab2({
79
79
  switch (e.key) {
80
80
  case "Backspace":
81
81
  case "Delete":
82
- if (closeable) {
82
+ if (closeable && !editing) {
83
83
  e.stopPropagation();
84
84
  onClose && onClose(index);
85
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Tab.js","sources":["../src/tabs/Tab.tsx"],"sourcesContent":["// TODO close button needs to be a button. Hence tab needs to include 2 buttons\nimport { Button, ButtonProps, makePrefixer, useForkRef } from \"@salt-ds/core\";\nimport { CloseIcon } from \"@salt-ds/icons\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n FocusEvent,\n ForwardedRef,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { EditableLabel, EditableLabelProps } from \"../editable-label\";\nimport { TabProps } from \"./TabsTypes\";\n\nimport tabCss from \"./Tab.css\";\n\nconst noop = () => undefined;\n\nconst withBaseName = makePrefixer(\"saltTab\");\n\nconst CloseTabButton = (props: ButtonProps) => (\n // FIXME: use polymorphic button\n <Button\n {...props}\n aria-label=\"Close Tab (Delete or Backspace)\"\n className={withBaseName(\"closeButton\")}\n tabIndex={undefined}\n title=\"Close Tab (Delete or Backspace)\"\n variant=\"secondary\"\n >\n <CloseIcon\n aria-label=\"Close Tab (Delete or Backspace)\"\n className={withBaseName(\"close-icon\")}\n />\n </Button>\n);\n\nexport const Tab = forwardRef(function Tab(\n {\n ariaControls,\n children,\n className,\n closeable,\n dragging,\n editable,\n editing,\n focusVisible,\n index,\n label,\n onClick,\n onClose,\n onEnterEditMode = noop,\n onExitEditMode = noop,\n onFocus: onFocusProp,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n orientation,\n selected,\n tabChildIndex = 0,\n tabIndex,\n ...props\n }: TabProps,\n ref: ForwardedRef<HTMLDivElement>\n): ReactElement<TabProps> {\n if (index === undefined || onClick === undefined || onKeyDown === undefined) {\n throw Error(\n \"index, onClick, onKeyUp, onKeyDown are required props, they would nornally be injected by Tabstrip, are you creating a Tab outside of a Tabstrip\"\n );\n }\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tab\",\n css: tabCss,\n window: targetWindow,\n });\n\n const root = useRef<HTMLDivElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const setForkRef = useForkRef(ref, root);\n const [closeHover, setCloseHover] = useState(false);\n const handleClick = useCallback(\n (e: MouseEvent) => {\n if (!editing) {\n e.preventDefault();\n onClick(e, index);\n }\n },\n [editing, index, onClick]\n );\n const handleKeyDownMain = (e: KeyboardEvent<HTMLElement>) => {\n onKeyDown(e);\n };\n\n const handleOnExitEditMode: EditableLabelProps[\"onExitEditMode\"] = (\n originalValue = \"\",\n editedValue = \"\",\n allowDeactivation = true\n ) => onExitEditMode(originalValue, editedValue, allowDeactivation, index);\n\n const handleKeyUp = (e: KeyboardEvent) => {\n switch (e.key) {\n case \"Backspace\":\n case \"Delete\":\n if (closeable) {\n e.stopPropagation();\n onClose && onClose(index);\n }\n break;\n default:\n onKeyUp && onKeyUp(e, index);\n }\n };\n\n const handleCloseButtonClick = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n onClose && onClose(index);\n };\n\n const handleCloseButtonEnter = () => {\n setCloseHover(true);\n };\n\n const handleCloseButtonLeave = () => {\n setCloseHover(false);\n };\n\n const handleMouseDown = (e: MouseEvent<HTMLElement>): void => {\n onMouseDown?.(e);\n };\n\n const getLabel = () => {\n if (editable) {\n return (\n <EditableLabel\n editing={editing}\n defaultValue={label}\n // Create a fresh instance after each edit, so it can be uncontrolled ...\n key={label}\n onEnterEditMode={onEnterEditMode}\n onExitEditMode={handleOnExitEditMode}\n ref={editableRef}\n />\n );\n } else {\n return label;\n }\n };\n\n const handleFocus = (evt: FocusEvent<HTMLElement>) => {\n if (editableRef.current) {\n const editable = editableRef.current as HTMLElement;\n const input = editable.querySelector(\n \".saltEditableLabel-input\"\n ) as HTMLInputElement;\n input?.focus();\n }\n onFocusProp?.(evt);\n };\n\n return (\n <div\n {...props}\n aria-controls={ariaControls}\n aria-selected={selected}\n className={clsx(withBaseName(), {\n [withBaseName(\"closeable\")]: closeable,\n [withBaseName(\"closeHover\")]: closeHover,\n [withBaseName(\"dragAway\")]: dragging,\n [withBaseName(\"editing\")]: editing,\n [withBaseName(\"vertical\")]: orientation === \"vertical\",\n [`saltFocusVisible`]: focusVisible,\n })}\n data-editable={editable || undefined}\n onClick={handleClick}\n onFocus={handleFocus}\n onKeyDown={handleKeyDownMain}\n onKeyUp={handleKeyUp}\n onMouseDown={handleMouseDown}\n ref={setForkRef}\n role=\"tab\"\n tabIndex={tabIndex}\n >\n <div className={withBaseName(\"main\")}>\n <span\n className={withBaseName(\"text\")}\n // data-text is important, it determines the width of the tab. A pseudo\n // element assigns data-text as content. This is styled as selected tab\n // text. That means width of tab always corresponds to its selected state,\n // so tabs do not change size when selected (ie when the text is bolded).\n // Do not include if we have editable content, EditableLabel will determine\n // the width\n data-text={editable ? undefined : label}\n >\n {children ?? getLabel()}\n </span>\n </div>\n {closeable ? (\n <CloseTabButton\n onClick={handleCloseButtonClick}\n onMouseEnter={handleCloseButtonEnter}\n onMouseLeave={handleCloseButtonLeave}\n />\n ) : null}\n </div>\n );\n});\n"],"names":["Tab","tabCss","editable"],"mappings":"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"}
1
+ {"version":3,"file":"Tab.js","sources":["../src/tabs/Tab.tsx"],"sourcesContent":["// TODO close button needs to be a button. Hence tab needs to include 2 buttons\nimport { Button, ButtonProps, makePrefixer, useForkRef } from \"@salt-ds/core\";\nimport { CloseIcon } from \"@salt-ds/icons\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n FocusEvent,\n ForwardedRef,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { EditableLabel, EditableLabelProps } from \"../editable-label\";\nimport { TabProps } from \"./TabsTypes\";\n\nimport tabCss from \"./Tab.css\";\n\nconst noop = () => undefined;\n\nconst withBaseName = makePrefixer(\"saltTab\");\n\nconst CloseTabButton = (props: ButtonProps) => (\n // FIXME: use polymorphic button\n <Button\n {...props}\n aria-label=\"Close Tab (Delete or Backspace)\"\n className={withBaseName(\"closeButton\")}\n tabIndex={undefined}\n title=\"Close Tab (Delete or Backspace)\"\n variant=\"secondary\"\n >\n <CloseIcon\n aria-label=\"Close Tab (Delete or Backspace)\"\n className={withBaseName(\"close-icon\")}\n />\n </Button>\n);\n\nexport const Tab = forwardRef(function Tab(\n {\n ariaControls,\n children,\n className,\n closeable,\n dragging,\n editable,\n editing,\n focusVisible,\n index,\n label,\n onClick,\n onClose,\n onEnterEditMode = noop,\n onExitEditMode = noop,\n onFocus: onFocusProp,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n orientation,\n selected,\n tabChildIndex = 0,\n tabIndex,\n ...props\n }: TabProps,\n ref: ForwardedRef<HTMLDivElement>\n): ReactElement<TabProps> {\n if (index === undefined || onClick === undefined || onKeyDown === undefined) {\n throw Error(\n \"index, onClick, onKeyUp, onKeyDown are required props, they would nornally be injected by Tabstrip, are you creating a Tab outside of a Tabstrip\"\n );\n }\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tab\",\n css: tabCss,\n window: targetWindow,\n });\n\n const root = useRef<HTMLDivElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const setForkRef = useForkRef(ref, root);\n const [closeHover, setCloseHover] = useState(false);\n const handleClick = useCallback(\n (e: MouseEvent) => {\n if (!editing) {\n e.preventDefault();\n onClick(e, index);\n }\n },\n [editing, index, onClick]\n );\n const handleKeyDownMain = (e: KeyboardEvent<HTMLElement>) => {\n onKeyDown(e);\n };\n\n const handleOnExitEditMode: EditableLabelProps[\"onExitEditMode\"] = (\n originalValue = \"\",\n editedValue = \"\",\n allowDeactivation = true\n ) => onExitEditMode(originalValue, editedValue, allowDeactivation, index);\n\n const handleKeyUp = (e: KeyboardEvent) => {\n switch (e.key) {\n case \"Backspace\":\n case \"Delete\":\n if (closeable && !editing) {\n e.stopPropagation();\n onClose && onClose(index);\n }\n break;\n default:\n onKeyUp && onKeyUp(e, index);\n }\n };\n\n const handleCloseButtonClick = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n onClose && onClose(index);\n };\n\n const handleCloseButtonEnter = () => {\n setCloseHover(true);\n };\n\n const handleCloseButtonLeave = () => {\n setCloseHover(false);\n };\n\n const handleMouseDown = (e: MouseEvent<HTMLElement>): void => {\n onMouseDown?.(e);\n };\n\n const getLabel = () => {\n if (editable) {\n return (\n <EditableLabel\n editing={editing}\n defaultValue={label}\n // Create a fresh instance after each edit, so it can be uncontrolled ...\n key={label}\n onEnterEditMode={onEnterEditMode}\n onExitEditMode={handleOnExitEditMode}\n ref={editableRef}\n />\n );\n } else {\n return label;\n }\n };\n\n const handleFocus = (evt: FocusEvent<HTMLElement>) => {\n if (editableRef.current) {\n const editable = editableRef.current as HTMLElement;\n const input = editable.querySelector(\n \".saltEditableLabel-input\"\n ) as HTMLInputElement;\n input?.focus();\n }\n onFocusProp?.(evt);\n };\n\n return (\n <div\n {...props}\n aria-controls={ariaControls}\n aria-selected={selected}\n className={clsx(withBaseName(), {\n [withBaseName(\"closeable\")]: closeable,\n [withBaseName(\"closeHover\")]: closeHover,\n [withBaseName(\"dragAway\")]: dragging,\n [withBaseName(\"editing\")]: editing,\n [withBaseName(\"vertical\")]: orientation === \"vertical\",\n [`saltFocusVisible`]: focusVisible,\n })}\n data-editable={editable || undefined}\n onClick={handleClick}\n onFocus={handleFocus}\n onKeyDown={handleKeyDownMain}\n onKeyUp={handleKeyUp}\n onMouseDown={handleMouseDown}\n ref={setForkRef}\n role=\"tab\"\n tabIndex={tabIndex}\n >\n <div className={withBaseName(\"main\")}>\n <span\n className={withBaseName(\"text\")}\n // data-text is important, it determines the width of the tab. A pseudo\n // element assigns data-text as content. This is styled as selected tab\n // text. That means width of tab always corresponds to its selected state,\n // so tabs do not change size when selected (ie when the text is bolded).\n // Do not include if we have editable content, EditableLabel will determine\n // the width\n data-text={editable ? undefined : label}\n >\n {children ?? getLabel()}\n </span>\n </div>\n {closeable ? (\n <CloseTabButton\n onClick={handleCloseButtonClick}\n onMouseEnter={handleCloseButtonEnter}\n onMouseLeave={handleCloseButtonLeave}\n />\n ) : null}\n </div>\n );\n});\n"],"names":["Tab","tabCss","editable"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TabNextContext.js","sources":["../src/tabs-next/TabNextContext.tsx"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport { ReactNode, SyntheticEvent, useContext } from \"react\";\n\ntype TabValue = {\n value: string;\n label: ReactNode;\n};\n\nexport interface TabsContextValue {\n activeColor: \"primary\" | \"secondary\";\n disabled?: boolean;\n activate: (event: SyntheticEvent<HTMLButtonElement>) => void;\n isActive: (id: string) => boolean;\n setFocusable: (id: string) => void;\n isFocusable: (id: string) => boolean;\n registerTab: (tab: TabValue) => void;\n unregisterTab: (id: string) => void;\n variant: \"main\" | \"inline\";\n}\n\nexport const TabsContext = createContext<TabsContextValue>(\"TabsContext\", {\n activeColor: \"primary\",\n disabled: false,\n activate: () => undefined,\n isActive: () => false,\n setFocusable: () => undefined,\n isFocusable: () => false,\n registerTab: () => undefined,\n unregisterTab: () => undefined,\n variant: \"main\",\n});\n\nexport function useTabs() {\n return useContext(TabsContext);\n}\n"],"names":[],"mappings":";;;AAoBa,MAAA,WAAA,GAAc,cAAgC,aAAe,EAAA;AAAA,EACxE,WAAa,EAAA,SAAA;AAAA,EACb,QAAU,EAAA,KAAA;AAAA,EACV,UAAU,MAAM,KAAA,CAAA;AAAA,EAChB,UAAU,MAAM,KAAA;AAAA,EAChB,cAAc,MAAM,KAAA,CAAA;AAAA,EACpB,aAAa,MAAM,KAAA;AAAA,EACnB,aAAa,MAAM,KAAA,CAAA;AAAA,EACnB,eAAe,MAAM,KAAA,CAAA;AAAA,EACrB,OAAS,EAAA,MAAA;AACX,CAAC,EAAA;AAEM,SAAS,OAAU,GAAA;AACxB,EAAA,OAAO,WAAW,WAAW,CAAA,CAAA;AAC/B;;;;"}
1
+ {"version":3,"file":"TabNextContext.js","sources":["../src/tabs-next/TabNextContext.tsx"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport { ReactNode, SyntheticEvent, useContext } from \"react\";\n\ninterface TabValue {\n value: string;\n label: ReactNode;\n}\n\nexport interface TabsContextValue {\n activeColor: \"primary\" | \"secondary\";\n disabled?: boolean;\n activate: (event: SyntheticEvent<HTMLButtonElement>) => void;\n isActive: (id: string) => boolean;\n setFocusable: (id: string) => void;\n isFocusable: (id: string) => boolean;\n registerTab: (tab: TabValue) => void;\n unregisterTab: (id: string) => void;\n variant: \"main\" | \"inline\";\n}\n\nexport const TabsContext = createContext<TabsContextValue>(\"TabsContext\", {\n activeColor: \"primary\",\n disabled: false,\n activate: () => undefined,\n isActive: () => false,\n setFocusable: () => undefined,\n isFocusable: () => false,\n registerTab: () => undefined,\n unregisterTab: () => undefined,\n variant: \"main\",\n});\n\nexport function useTabs() {\n return useContext(TabsContext);\n}\n"],"names":[],"mappings":";;;AAoBa,MAAA,WAAA,GAAc,cAAgC,aAAe,EAAA;AAAA,EACxE,WAAa,EAAA,SAAA;AAAA,EACb,QAAU,EAAA,KAAA;AAAA,EACV,UAAU,MAAM,KAAA,CAAA;AAAA,EAChB,UAAU,MAAM,KAAA;AAAA,EAChB,cAAc,MAAM,KAAA,CAAA;AAAA,EACpB,aAAa,MAAM,KAAA;AAAA,EACnB,aAAa,MAAM,KAAA,CAAA;AAAA,EACnB,eAAe,MAAM,KAAA,CAAA;AAAA,EACrB,OAAS,EAAA,MAAA;AACX,CAAC,EAAA;AAEM,SAAS,OAAU,GAAA;AACxB,EAAA,OAAO,WAAW,WAAW,CAAA,CAAA;AAC/B;;;;"}
@@ -1,4 +1,4 @@
1
- var css_248z = "/* Component class applied to the root element */\n.saltTabstripNext {\n display: flex;\n flex-wrap: nowrap;\n justify-content: var(--tabstripNext-justifyContent);\n align-items: center;\n position: relative;\n background: transparent;\n width: 100%;\n\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n}\n\n.saltTabstripNext-main {\n padding-left: var(--salt-spacing-300);\n padding-right: var(--salt-spacing-300);\n box-sizing: border-box;\n}\n\n.saltTabstripNext-main::before {\n content: \"\";\n position: absolute;\n inset: auto 0 0 0;\n height: var(--salt-size-border);\n border-bottom: var(--salt-size-border) var(--salt-separable-borderStyle) var(--salt-separable-secondary-borderColor);\n}\n\n.saltTabstripNext .saltTabNext-wrapper:not(:last-child) {\n padding-right: var(--salt-spacing-100);\n box-sizing: border-box;\n}\n";
1
+ var css_248z = "/* Component class applied to the root element */\n.saltTabstripNext {\n display: flex;\n flex-wrap: nowrap;\n justify-content: var(--tabstripNext-justifyContent);\n align-items: center;\n position: relative;\n background: transparent;\n width: 100%;\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n}\n.saltTabstripNext-container {\n display: inherit;\n width: 100%;\n position: relative;\n}\n\n.saltTabstripNext-main {\n padding-left: var(--salt-spacing-300);\n padding-right: var(--salt-spacing-300);\n box-sizing: border-box;\n}\n\n.saltTabstripNext-main::before {\n content: \"\";\n position: absolute;\n inset: auto 0 0 0;\n height: var(--salt-size-border);\n border-bottom: var(--salt-size-border) var(--salt-separable-borderStyle) var(--salt-separable-secondary-borderColor);\n}\n\n.saltTabstripNext .saltTabNext-wrapper:not(:last-child) {\n padding-right: var(--salt-spacing-100);\n box-sizing: border-box;\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=TabstripNext.css.js.map
@@ -152,27 +152,29 @@ const TabstripNext = forwardRef(
152
152
  };
153
153
  return /* @__PURE__ */ jsx(TabsContext.Provider, {
154
154
  value: contextValue,
155
- children: /* @__PURE__ */ jsx(Overflow, {
156
- ref: handleRef,
157
- children: /* @__PURE__ */ jsxs("div", {
158
- role: "tablist",
159
- className: clsx(
160
- withBaseName(),
161
- withBaseName("horizontal"),
162
- withBaseName(variant),
163
- className
164
- ),
165
- onKeyDown: handleKeyDown,
166
- style: tabstripStyle,
167
- ...rest,
168
- children: [
169
- children,
170
- /* @__PURE__ */ jsx(OverflowMenu, {
171
- tabs: tabList,
172
- onOpenChange: handleOverflowOpenChange,
173
- onSelectionChange: handleOverflowItemClick
174
- })
175
- ]
155
+ children: /* @__PURE__ */ jsx("div", {
156
+ className: clsx(withBaseName("container"), withBaseName(variant)),
157
+ children: /* @__PURE__ */ jsx(Overflow, {
158
+ ref: handleRef,
159
+ children: /* @__PURE__ */ jsxs("div", {
160
+ role: "tablist",
161
+ className: clsx(
162
+ withBaseName(),
163
+ withBaseName("horizontal"),
164
+ className
165
+ ),
166
+ onKeyDown: handleKeyDown,
167
+ style: tabstripStyle,
168
+ ...rest,
169
+ children: [
170
+ children,
171
+ /* @__PURE__ */ jsx(OverflowMenu, {
172
+ tabs: tabList,
173
+ onOpenChange: handleOverflowOpenChange,
174
+ onSelectionChange: handleOverflowItemClick
175
+ })
176
+ ]
177
+ })
176
178
  })
177
179
  })
178
180
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TabstripNext.js","sources":["../src/tabs-next/TabstripNext.tsx"],"sourcesContent":["import { makePrefixer, useControlled, useForkRef } from \"@salt-ds/core\";\nimport clsx from \"clsx\";\nimport {\n ComponentPropsWithoutRef,\n forwardRef,\n ReactNode,\n SyntheticEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { Overflow } from \"@fluentui/react-overflow\";\nimport { OverflowMenu } from \"./OverflowMenu\";\nimport tabstripCss from \"./TabstripNext.css\";\nimport { TabsContext } from \"./TabNextContext\";\nimport { SelectionChangeHandler } from \"../common-hooks\";\n\nconst withBaseName = makePrefixer(\"saltTabstripNext\");\n\nexport interface TabstripNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /* Styling active color variant. Defaults to \"primary\". */\n activeColor?: \"primary\" | \"secondary\";\n /* Tabs alignment. Defaults to \"left\" */\n align?: \"left\" | \"center\" | \"right\";\n /* Value for the uncontrolled version. */\n value?: string;\n /* Callback for the controlled version. */\n onChange?: (e: SyntheticEvent, data: { value: string }) => void;\n /* Initial value for the uncontrolled version. */\n defaultValue?: string;\n /* The Tabs variant */\n variant?: \"main\" | \"inline\";\n}\n\ninterface TabValue {\n value: string;\n label: ReactNode;\n}\n\nexport const TabstripNext = forwardRef<HTMLDivElement, TabstripNextProps>(\n function TabstripNext(props, ref) {\n const {\n activeColor = \"primary\",\n align = \"left\",\n children,\n className,\n value: valueProp,\n defaultValue,\n onChange,\n onKeyDown,\n style,\n variant = \"main\",\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabstrip-next\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"TabstripNext\",\n state: \"selected\",\n });\n const [focusable, setFocusableState] = useState<string | undefined>(value);\n const [overflowOpen, setOverflowOpen] = useState(false);\n\n const activate = useCallback(\n (event: SyntheticEvent<HTMLButtonElement>) => {\n const newValue = event.currentTarget.value;\n setValue(newValue);\n if (value !== newValue) {\n onChange?.(event, { value: newValue });\n }\n },\n [onChange, value, setValue]\n );\n\n const isActive = useCallback(\n (id: string | undefined) => {\n return value === id;\n },\n [value]\n );\n\n const setFocusable = useCallback((id: string | undefined) => {\n setFocusableState(id);\n }, []);\n\n const isFocusable = useCallback(\n (id: string | undefined) => {\n return focusable === id || !focusable;\n },\n [focusable]\n );\n\n const [tabList, setTabList] = useState<TabValue[]>([]);\n const registerTab = useCallback((tab: TabValue) => {\n setTabList((list) => list.concat([tab]));\n }, []);\n\n const unregisterTab = useCallback((id: string) => {\n setTabList((list) => list.filter((item) => item.value !== id));\n }, []);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (overflowOpen) return;\n\n const elements: HTMLElement[] = Array.from(\n tabstripRef.current?.querySelectorAll(\n `div:not([data-overflowing]) > [role=\"tab\"]:not([disabled])`\n ) ?? []\n );\n\n const currentIndex = elements.findIndex(\n (element) => element === targetWindow?.document.activeElement\n );\n\n if (currentIndex < 0) return;\n\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n elements[Math.min(currentIndex + 1, elements.length)]?.focus();\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n elements[Math.max(0, currentIndex - 1)]?.focus();\n break;\n case \"Home\":\n elements[0]?.focus();\n break;\n case \"End\":\n elements[elements.length - 1]?.focus();\n }\n\n onKeyDown?.(event);\n };\n\n const handleOverflowItemClick: SelectionChangeHandler<TabValue> = (\n event,\n item\n ) => {\n if (item) {\n setValue(item.value);\n requestAnimationFrame(() => {\n const element = tabstripRef.current?.querySelector(\n `[value=\"${item.value}\"]`\n );\n if (element instanceof HTMLElement) {\n element?.focus();\n }\n });\n if (value !== item.value) {\n onChange?.(event, { value: item.value });\n }\n }\n };\n\n const handleOverflowOpenChange = (isOpen: boolean) => {\n setOverflowOpen(isOpen);\n };\n\n const contextValue = useMemo(\n () => ({\n activate,\n isActive,\n setFocusable,\n isFocusable,\n registerTab,\n unregisterTab,\n variant,\n activeColor,\n }),\n [\n activate,\n isActive,\n setFocusable,\n isFocusable,\n registerTab,\n unregisterTab,\n variant,\n activeColor,\n ]\n );\n\n const tabstripStyle = {\n \"--tabstripNext-justifyContent\": align,\n ...style,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <Overflow ref={handleRef}>\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(\"horizontal\"),\n withBaseName(variant),\n className\n )}\n onKeyDown={handleKeyDown}\n style={tabstripStyle}\n {...rest}\n >\n {children}\n <OverflowMenu\n tabs={tabList}\n onOpenChange={handleOverflowOpenChange}\n onSelectionChange={handleOverflowItemClick}\n />\n </div>\n </Overflow>\n </TabsContext.Provider>\n );\n }\n);\n"],"names":["TabstripNext","tabstripCss"],"mappings":"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"}
1
+ {"version":3,"file":"TabstripNext.js","sources":["../src/tabs-next/TabstripNext.tsx"],"sourcesContent":["import { makePrefixer, useControlled, useForkRef } from \"@salt-ds/core\";\nimport clsx from \"clsx\";\nimport {\n ComponentPropsWithoutRef,\n forwardRef,\n ReactNode,\n SyntheticEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { Overflow } from \"@fluentui/react-overflow\";\nimport { OverflowMenu } from \"./OverflowMenu\";\nimport tabstripCss from \"./TabstripNext.css\";\nimport { TabsContext } from \"./TabNextContext\";\nimport { SelectionChangeHandler } from \"../common-hooks\";\n\nconst withBaseName = makePrefixer(\"saltTabstripNext\");\n\nexport interface TabstripNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /* Styling active color variant. Defaults to \"primary\". */\n activeColor?: \"primary\" | \"secondary\";\n /* Tabs alignment. Defaults to \"left\" */\n align?: \"left\" | \"center\" | \"right\";\n /* Value for the uncontrolled version. */\n value?: string;\n /* Callback for the controlled version. */\n onChange?: (e: SyntheticEvent, data: { value: string }) => void;\n /* Initial value for the uncontrolled version. */\n defaultValue?: string;\n /* The Tabs variant */\n variant?: \"main\" | \"inline\";\n}\n\ninterface TabValue {\n value: string;\n label: ReactNode;\n}\n\nexport const TabstripNext = forwardRef<HTMLDivElement, TabstripNextProps>(\n function TabstripNext(props, ref) {\n const {\n activeColor = \"primary\",\n align = \"left\",\n children,\n className,\n value: valueProp,\n defaultValue,\n onChange,\n onKeyDown,\n style,\n variant = \"main\",\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabstrip-next\",\n css: tabstripCss,\n window: targetWindow,\n });\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"TabstripNext\",\n state: \"selected\",\n });\n const [focusable, setFocusableState] = useState<string | undefined>(value);\n const [overflowOpen, setOverflowOpen] = useState(false);\n\n const activate = useCallback(\n (event: SyntheticEvent<HTMLButtonElement>) => {\n const newValue = event.currentTarget.value;\n setValue(newValue);\n if (value !== newValue) {\n onChange?.(event, { value: newValue });\n }\n },\n [onChange, value, setValue]\n );\n\n const isActive = useCallback(\n (id: string | undefined) => {\n return value === id;\n },\n [value]\n );\n\n const setFocusable = useCallback((id: string | undefined) => {\n setFocusableState(id);\n }, []);\n\n const isFocusable = useCallback(\n (id: string | undefined) => {\n return focusable === id || !focusable;\n },\n [focusable]\n );\n\n const [tabList, setTabList] = useState<TabValue[]>([]);\n const registerTab = useCallback((tab: TabValue) => {\n setTabList((list) => list.concat([tab]));\n }, []);\n\n const unregisterTab = useCallback((id: string) => {\n setTabList((list) => list.filter((item) => item.value !== id));\n }, []);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (overflowOpen) return;\n\n const elements: HTMLElement[] = Array.from(\n tabstripRef.current?.querySelectorAll(\n `div:not([data-overflowing]) > [role=\"tab\"]:not([disabled])`\n ) ?? []\n );\n\n const currentIndex = elements.findIndex(\n (element) => element === targetWindow?.document.activeElement\n );\n\n if (currentIndex < 0) return;\n\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n elements[Math.min(currentIndex + 1, elements.length)]?.focus();\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n elements[Math.max(0, currentIndex - 1)]?.focus();\n break;\n case \"Home\":\n elements[0]?.focus();\n break;\n case \"End\":\n elements[elements.length - 1]?.focus();\n }\n\n onKeyDown?.(event);\n };\n\n const handleOverflowItemClick: SelectionChangeHandler<TabValue> = (\n event,\n item\n ) => {\n if (item) {\n setValue(item.value);\n requestAnimationFrame(() => {\n const element = tabstripRef.current?.querySelector(\n `[value=\"${item.value}\"]`\n );\n if (element instanceof HTMLElement) {\n element?.focus();\n }\n });\n if (value !== item.value) {\n onChange?.(event, { value: item.value });\n }\n }\n };\n\n const handleOverflowOpenChange = (isOpen: boolean) => {\n setOverflowOpen(isOpen);\n };\n\n const contextValue = useMemo(\n () => ({\n activate,\n isActive,\n setFocusable,\n isFocusable,\n registerTab,\n unregisterTab,\n variant,\n activeColor,\n }),\n [\n activate,\n isActive,\n setFocusable,\n isFocusable,\n registerTab,\n unregisterTab,\n variant,\n activeColor,\n ]\n );\n\n const tabstripStyle = {\n \"--tabstripNext-justifyContent\": align,\n ...style,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <div className={clsx(withBaseName(\"container\"), withBaseName(variant))}>\n <Overflow ref={handleRef}>\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(\"horizontal\"),\n className\n )}\n onKeyDown={handleKeyDown}\n style={tabstripStyle}\n {...rest}\n >\n {children}\n <OverflowMenu\n tabs={tabList}\n onOpenChange={handleOverflowOpenChange}\n onSelectionChange={handleOverflowItemClick}\n />\n </div>\n </Overflow>\n </div>\n </TabsContext.Provider>\n );\n }\n);\n"],"names":["TabstripNext","tabstripCss"],"mappings":"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"}