react-ui-suite 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{TabGroup-CV2AC3EO.css → TabGroup-3NH74LET.css} +53 -27
- package/dist/index.d.ts +14 -3
- package/dist/index.js +152 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
.rui-tab-group {
|
|
2
|
-
display: flex;
|
|
3
|
-
width: 100%;
|
|
4
|
-
height: 100%;
|
|
5
|
-
|
|
6
|
-
--rui-tab-
|
|
7
|
-
--rui-tab-radius:
|
|
8
|
-
--rui-tab-
|
|
9
|
-
|
|
1
|
+
.rui-tab-group {
|
|
2
|
+
display: flex;
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
position: relative;
|
|
6
|
+
--rui-tab-border: 1px;
|
|
7
|
+
--rui-tab-panel-radius: 15px;
|
|
8
|
+
--rui-tab-radius: 10px;
|
|
9
|
+
--rui-tab-min-main: 32px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rui-tab-group__measure {
|
|
13
|
+
position: fixed;
|
|
14
|
+
left: 0;
|
|
15
|
+
top: 0;
|
|
16
|
+
visibility: hidden;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
z-index: -1;
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
gap: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.rui-tab-group__measure .rui-tab-group__tab {
|
|
24
|
+
flex: 0 0 auto !important;
|
|
25
|
+
width: auto !important;
|
|
26
|
+
height: auto !important;
|
|
27
|
+
}
|
|
10
28
|
|
|
11
29
|
.rui-tab-group[data-position="top"],
|
|
12
30
|
.rui-tab-group[data-position="bottom"] {
|
|
@@ -70,20 +88,21 @@
|
|
|
70
88
|
justify-content: flex-end;
|
|
71
89
|
}
|
|
72
90
|
|
|
73
|
-
.rui-tab-group__tab {
|
|
74
|
-
border: var(--rui-tab-border) solid var(--rui-color-border);
|
|
75
|
-
background-color: var(--rui-color-surface-muted);
|
|
76
|
-
position: relative;
|
|
91
|
+
.rui-tab-group__tab {
|
|
92
|
+
border: var(--rui-tab-border) solid var(--rui-color-border);
|
|
93
|
+
background-color: var(--rui-color-surface-muted);
|
|
94
|
+
position: relative;
|
|
77
95
|
padding: 5px;
|
|
78
96
|
font-weight: 500;
|
|
79
97
|
display: inline-flex;
|
|
80
98
|
align-items: center;
|
|
81
99
|
justify-content: center;
|
|
82
100
|
transform: none;
|
|
83
|
-
min-width: 0;
|
|
84
|
-
min-height: 0;
|
|
85
|
-
flex: 0 0 auto;
|
|
86
|
-
|
|
101
|
+
min-width: 0;
|
|
102
|
+
min-height: 0;
|
|
103
|
+
flex: 0 0 auto;
|
|
104
|
+
overflow: hidden;
|
|
105
|
+
}
|
|
87
106
|
|
|
88
107
|
.rui-tab-group__scroll {
|
|
89
108
|
border: var(--rui-tab-border) solid var(--rui-color-border);
|
|
@@ -108,12 +127,19 @@
|
|
|
108
127
|
line-height: 1;
|
|
109
128
|
}
|
|
110
129
|
|
|
111
|
-
.rui-tab-group__label {
|
|
112
|
-
display: inline-flex;
|
|
113
|
-
align-items: center;
|
|
114
|
-
justify-content: center;
|
|
115
|
-
line-height: 1;
|
|
116
|
-
|
|
130
|
+
.rui-tab-group__label {
|
|
131
|
+
display: inline-flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
justify-content: center;
|
|
134
|
+
line-height: 1;
|
|
135
|
+
white-space: normal;
|
|
136
|
+
overflow: hidden;
|
|
137
|
+
overflow-wrap: normal;
|
|
138
|
+
word-break: normal;
|
|
139
|
+
hyphens: none;
|
|
140
|
+
max-width: 100%;
|
|
141
|
+
max-height: 100%;
|
|
142
|
+
}
|
|
117
143
|
|
|
118
144
|
.rui-tab-group__tab.is-active {
|
|
119
145
|
background-color: var(--rui-color-surface);
|
|
@@ -205,10 +231,10 @@
|
|
|
205
231
|
border-bottom-right-radius: var(--rui-tab-radius);
|
|
206
232
|
}
|
|
207
233
|
|
|
208
|
-
.rui-tab-group[data-rotation="vertical"] .rui-tab-group__label {
|
|
209
|
-
writing-mode: vertical-rl;
|
|
210
|
-
text-orientation: mixed;
|
|
211
|
-
}
|
|
234
|
+
.rui-tab-group[data-rotation="vertical"] .rui-tab-group__label {
|
|
235
|
+
writing-mode: vertical-rl;
|
|
236
|
+
text-orientation: mixed;
|
|
237
|
+
}
|
|
212
238
|
|
|
213
239
|
.rui-tab-group[data-position="top"][data-rotation="vertical"] .rui-tab-group__label {
|
|
214
240
|
transform: rotate(180deg);
|
package/dist/index.d.ts
CHANGED
|
@@ -197,13 +197,22 @@ type DropdownProps = {
|
|
|
197
197
|
declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<HTMLDivElement>>;
|
|
198
198
|
|
|
199
199
|
type NativeInputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "type">;
|
|
200
|
+
type FilePickerMode = "path" | "content" | "both";
|
|
201
|
+
type FileSelection = {
|
|
202
|
+
file: File;
|
|
203
|
+
path?: string;
|
|
204
|
+
text?: string;
|
|
205
|
+
bytes?: Uint8Array;
|
|
206
|
+
};
|
|
200
207
|
type FilePickerProps = NativeInputProps & {
|
|
201
208
|
label?: string;
|
|
202
209
|
description?: string;
|
|
203
210
|
error?: string;
|
|
204
211
|
dropzoneLabel?: string;
|
|
205
212
|
maxFiles?: number;
|
|
206
|
-
|
|
213
|
+
mode?: FilePickerMode;
|
|
214
|
+
resolvePath?: (file: File) => string | undefined | Promise<string | undefined>;
|
|
215
|
+
onFilesChange?: (files: FileSelection[]) => void;
|
|
207
216
|
};
|
|
208
217
|
declare const FilePicker: React.ForwardRefExoticComponent<NativeInputProps & {
|
|
209
218
|
label?: string;
|
|
@@ -211,7 +220,9 @@ declare const FilePicker: React.ForwardRefExoticComponent<NativeInputProps & {
|
|
|
211
220
|
error?: string;
|
|
212
221
|
dropzoneLabel?: string;
|
|
213
222
|
maxFiles?: number;
|
|
214
|
-
|
|
223
|
+
mode?: FilePickerMode;
|
|
224
|
+
resolvePath?: (file: File) => string | undefined | Promise<string | undefined>;
|
|
225
|
+
onFilesChange?: (files: FileSelection[]) => void;
|
|
215
226
|
} & React.RefAttributes<HTMLInputElement>>;
|
|
216
227
|
|
|
217
228
|
type InputFieldProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
@@ -530,4 +541,4 @@ declare const Toggle: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttri
|
|
|
530
541
|
onChange?: (checked: boolean) => void;
|
|
531
542
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
532
543
|
|
|
533
|
-
export { Alert, type AlertProps, type AlertVariant, Badge, type BadgeProps, type BadgeVariant, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, ColorPicker, type ColorPickerProps, Combobox, type ComboboxOption, type ComboboxProps, type ComboboxRenderState, DatalistInput, type DatalistInputProps, DatePicker, type DatePickerProps, Dialog, type DialogProps, Disclosure, type DisclosureProps, Dropdown, type DropdownProps, FilePicker, type FilePickerProps, InputField, type InputFieldProps, Meter, type MeterProps, NumberInput, type NumberInputProps, OutputChip, type OutputChipProps, Popover, type PopoverProps, Progress, type ProgressProps, Radio, type RadioColor, type RadioProps, ResizableContainer, type ResizableContainerProps, Select, type SelectOption, type SelectProps, Slider, type SliderProps, StackedList, type StackedListItem, type StackedListProps, TabGroup, TabGroupAlign, TabGroupFill, TabGroupPosition, type TabGroupProps, TabGroupRotation, type TabGroupTab, Table, type TableColumn, type TableProps, Textarea, type TextareaProps, Toggle, type ToggleProps };
|
|
544
|
+
export { Alert, type AlertProps, type AlertVariant, Badge, type BadgeProps, type BadgeVariant, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, ColorPicker, type ColorPickerProps, Combobox, type ComboboxOption, type ComboboxProps, type ComboboxRenderState, DatalistInput, type DatalistInputProps, DatePicker, type DatePickerProps, Dialog, type DialogProps, Disclosure, type DisclosureProps, Dropdown, type DropdownProps, FilePicker, type FilePickerMode, type FilePickerProps, type FileSelection, InputField, type InputFieldProps, Meter, type MeterProps, NumberInput, type NumberInputProps, OutputChip, type OutputChipProps, Popover, type PopoverProps, Progress, type ProgressProps, Radio, type RadioColor, type RadioProps, ResizableContainer, type ResizableContainerProps, Select, type SelectOption, type SelectProps, Slider, type SliderProps, StackedList, type StackedListItem, type StackedListProps, TabGroup, TabGroupAlign, TabGroupFill, TabGroupPosition, type TabGroupProps, TabGroupRotation, type TabGroupTab, Table, type TableColumn, type TableProps, Textarea, type TextareaProps, Toggle, type ToggleProps };
|
package/dist/index.js
CHANGED
|
@@ -1016,7 +1016,16 @@ var Dropdown = React6.forwardRef(
|
|
|
1016
1016
|
ref: chevronRef,
|
|
1017
1017
|
type: "button",
|
|
1018
1018
|
"aria-label": isOpen ? "Close" : "Open",
|
|
1019
|
-
|
|
1019
|
+
onPointerDown: (event) => {
|
|
1020
|
+
if (!onChevronClick) return;
|
|
1021
|
+
if (event.button !== 0) return;
|
|
1022
|
+
event.preventDefault();
|
|
1023
|
+
onChevronClick();
|
|
1024
|
+
},
|
|
1025
|
+
onClick: (event) => {
|
|
1026
|
+
if (!onChevronClick || event.detail !== 0) return;
|
|
1027
|
+
onChevronClick();
|
|
1028
|
+
},
|
|
1020
1029
|
className: buttonClasses,
|
|
1021
1030
|
disabled: !!disabled,
|
|
1022
1031
|
children: /* @__PURE__ */ jsx8(
|
|
@@ -1635,10 +1644,7 @@ function InnerCombobox({
|
|
|
1635
1644
|
openList();
|
|
1636
1645
|
return;
|
|
1637
1646
|
}
|
|
1638
|
-
|
|
1639
|
-
var _a2;
|
|
1640
|
-
return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
1641
|
-
});
|
|
1647
|
+
setOpen(false);
|
|
1642
1648
|
},
|
|
1643
1649
|
children: isEffectivelyOpen && /* @__PURE__ */ jsx11(
|
|
1644
1650
|
Popover,
|
|
@@ -2820,12 +2826,55 @@ function formatBytes(bytes) {
|
|
|
2820
2826
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
2821
2827
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2822
2828
|
}
|
|
2829
|
+
function decodeUtf8IfPossible(bytes) {
|
|
2830
|
+
try {
|
|
2831
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
2832
|
+
return decoder.decode(bytes);
|
|
2833
|
+
} catch {
|
|
2834
|
+
return void 0;
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
async function derivePath(file, resolvePath) {
|
|
2838
|
+
const resolved = await (resolvePath == null ? void 0 : resolvePath(file));
|
|
2839
|
+
if (resolved) return resolved;
|
|
2840
|
+
const fileWithPath = file;
|
|
2841
|
+
if (typeof fileWithPath.path === "string" && fileWithPath.path.length > 0) {
|
|
2842
|
+
return fileWithPath.path;
|
|
2843
|
+
}
|
|
2844
|
+
if (typeof fileWithPath.webkitRelativePath === "string" && fileWithPath.webkitRelativePath.length > 0) {
|
|
2845
|
+
return fileWithPath.webkitRelativePath;
|
|
2846
|
+
}
|
|
2847
|
+
return void 0;
|
|
2848
|
+
}
|
|
2849
|
+
async function readFileBytes(file) {
|
|
2850
|
+
const fileWithArrayBuffer = file;
|
|
2851
|
+
if (typeof fileWithArrayBuffer.arrayBuffer === "function") {
|
|
2852
|
+
return new Uint8Array(await fileWithArrayBuffer.arrayBuffer());
|
|
2853
|
+
}
|
|
2854
|
+
if (typeof Blob !== "undefined" && typeof Blob.prototype.arrayBuffer === "function") {
|
|
2855
|
+
return new Uint8Array(await Blob.prototype.arrayBuffer.call(file));
|
|
2856
|
+
}
|
|
2857
|
+
if (typeof FileReader !== "undefined") {
|
|
2858
|
+
return await new Promise((resolve) => {
|
|
2859
|
+
const reader = new FileReader();
|
|
2860
|
+
reader.onload = () => {
|
|
2861
|
+
const result = reader.result;
|
|
2862
|
+
resolve(result instanceof ArrayBuffer ? new Uint8Array(result) : void 0);
|
|
2863
|
+
};
|
|
2864
|
+
reader.onerror = () => resolve(void 0);
|
|
2865
|
+
reader.readAsArrayBuffer(file);
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2868
|
+
return void 0;
|
|
2869
|
+
}
|
|
2823
2870
|
var FilePicker = React15.forwardRef(function FilePicker2({
|
|
2824
2871
|
label,
|
|
2825
2872
|
description,
|
|
2826
2873
|
error,
|
|
2827
2874
|
dropzoneLabel = "Drop files here or click to browse",
|
|
2828
2875
|
maxFiles,
|
|
2876
|
+
mode = "path",
|
|
2877
|
+
resolvePath,
|
|
2829
2878
|
id,
|
|
2830
2879
|
className,
|
|
2831
2880
|
accept,
|
|
@@ -2843,6 +2892,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
|
|
|
2843
2892
|
const [selectedFiles, setSelectedFiles] = React15.useState([]);
|
|
2844
2893
|
const [restrictedCount, setRestrictedCount] = React15.useState(0);
|
|
2845
2894
|
const inputRef = React15.useRef(null);
|
|
2895
|
+
const selectionRequestIdRef = React15.useRef(0);
|
|
2846
2896
|
const setRefs = React15.useCallback(
|
|
2847
2897
|
(node) => {
|
|
2848
2898
|
inputRef.current = node;
|
|
@@ -2861,22 +2911,43 @@ var FilePicker = React15.forwardRef(function FilePicker2({
|
|
|
2861
2911
|
return Math.max(1, Math.floor(maxFiles));
|
|
2862
2912
|
}, [maxFiles]);
|
|
2863
2913
|
const applySelectedFiles = React15.useCallback(
|
|
2864
|
-
(files) => {
|
|
2914
|
+
async (files) => {
|
|
2865
2915
|
const acceptedFiles = filterFilesByAccept(files, accept);
|
|
2866
2916
|
const selectionLimit = multiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
|
|
2867
2917
|
const nextFiles = acceptedFiles.slice(0, selectionLimit);
|
|
2868
2918
|
const nextRestrictedCount = files.length - nextFiles.length;
|
|
2869
|
-
|
|
2919
|
+
const requestId = selectionRequestIdRef.current + 1;
|
|
2920
|
+
selectionRequestIdRef.current = requestId;
|
|
2921
|
+
const nextSelections = await Promise.all(
|
|
2922
|
+
nextFiles.map(async (file) => {
|
|
2923
|
+
const selection = { file };
|
|
2924
|
+
if (mode === "path" || mode === "both") {
|
|
2925
|
+
selection.path = await derivePath(file, resolvePath);
|
|
2926
|
+
}
|
|
2927
|
+
if (mode === "content" || mode === "both") {
|
|
2928
|
+
const bytes = await readFileBytes(file);
|
|
2929
|
+
if (bytes) {
|
|
2930
|
+
selection.bytes = bytes;
|
|
2931
|
+
selection.text = decodeUtf8IfPossible(bytes);
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
return selection;
|
|
2935
|
+
})
|
|
2936
|
+
);
|
|
2937
|
+
if (selectionRequestIdRef.current !== requestId) {
|
|
2938
|
+
return [];
|
|
2939
|
+
}
|
|
2940
|
+
setSelectedFiles(nextSelections);
|
|
2870
2941
|
setRestrictedCount(nextRestrictedCount);
|
|
2871
|
-
onFilesChange == null ? void 0 : onFilesChange(
|
|
2872
|
-
return
|
|
2942
|
+
onFilesChange == null ? void 0 : onFilesChange(nextSelections);
|
|
2943
|
+
return nextSelections;
|
|
2873
2944
|
},
|
|
2874
|
-
[accept, multiple, onFilesChange, resolvedMaxFiles]
|
|
2945
|
+
[accept, mode, multiple, onFilesChange, resolvePath, resolvedMaxFiles]
|
|
2875
2946
|
);
|
|
2876
2947
|
const handleInputChange = (event) => {
|
|
2877
2948
|
var _a;
|
|
2878
2949
|
const incomingFiles = Array.from((_a = event.target.files) != null ? _a : []);
|
|
2879
|
-
applySelectedFiles(incomingFiles);
|
|
2950
|
+
void applySelectedFiles(incomingFiles);
|
|
2880
2951
|
onChange == null ? void 0 : onChange(event);
|
|
2881
2952
|
};
|
|
2882
2953
|
const openFileDialog = () => {
|
|
@@ -2892,7 +2963,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
|
|
|
2892
2963
|
if (disabled) return;
|
|
2893
2964
|
setIsDragActive(false);
|
|
2894
2965
|
const files = Array.from((_a = event.dataTransfer.files) != null ? _a : []);
|
|
2895
|
-
applySelectedFiles(files);
|
|
2966
|
+
void applySelectedFiles(files);
|
|
2896
2967
|
};
|
|
2897
2968
|
const hasSelection = selectedFiles.length > 0;
|
|
2898
2969
|
return /* @__PURE__ */ jsxs15("div", { className: "rui-file-picker rui-root", children: [
|
|
@@ -2954,10 +3025,17 @@ var FilePicker = React15.forwardRef(function FilePicker2({
|
|
|
2954
3025
|
"Maximum files: ",
|
|
2955
3026
|
resolvedMaxFiles
|
|
2956
3027
|
] }) : null,
|
|
2957
|
-
hasSelection ? /* @__PURE__ */ jsx17("ul", { className: "rui-file-picker__list", "aria-label": "Selected files", children: selectedFiles.map((
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3028
|
+
hasSelection ? /* @__PURE__ */ jsx17("ul", { className: "rui-file-picker__list", "aria-label": "Selected files", children: selectedFiles.map((selection) => /* @__PURE__ */ jsxs15(
|
|
3029
|
+
"li",
|
|
3030
|
+
{
|
|
3031
|
+
className: "rui-file-picker__item",
|
|
3032
|
+
children: [
|
|
3033
|
+
/* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-name rui-text-wrap", children: selection.file.name }),
|
|
3034
|
+
/* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-meta", children: formatBytes(selection.file.size) })
|
|
3035
|
+
]
|
|
3036
|
+
},
|
|
3037
|
+
`${selection.file.name}-${selection.file.size}-${selection.file.lastModified}`
|
|
3038
|
+
)) }) : null
|
|
2961
3039
|
]
|
|
2962
3040
|
}
|
|
2963
3041
|
),
|
|
@@ -3788,7 +3866,7 @@ function StackedList({ items, dense, className, ...rest }) {
|
|
|
3788
3866
|
|
|
3789
3867
|
// components/TabGroup/TabGroup.tsx
|
|
3790
3868
|
import React21 from "react";
|
|
3791
|
-
import "./TabGroup-
|
|
3869
|
+
import "./TabGroup-3NH74LET.css";
|
|
3792
3870
|
import { Fragment as Fragment2, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3793
3871
|
function TabGroup({
|
|
3794
3872
|
align = "start",
|
|
@@ -3804,11 +3882,16 @@ function TabGroup({
|
|
|
3804
3882
|
var _a, _b;
|
|
3805
3883
|
const rootRef = React21.useRef(null);
|
|
3806
3884
|
const tabStripRef = React21.useRef(null);
|
|
3885
|
+
const measureRef = React21.useRef(null);
|
|
3807
3886
|
const idBase = React21.useId();
|
|
3808
3887
|
const [effectiveFill, setEffectiveFill] = React21.useState(fill);
|
|
3809
3888
|
const [availableMain, setAvailableMain] = React21.useState(0);
|
|
3810
|
-
const [
|
|
3889
|
+
const [cssMinMain, setCssMinMain] = React21.useState(32);
|
|
3890
|
+
const [contentMinMain, setContentMinMain] = React21.useState(0);
|
|
3811
3891
|
const count = tabs.length;
|
|
3892
|
+
const isVertical = position === "left" || position === "right";
|
|
3893
|
+
const minMain = Math.max(cssMinMain, contentMinMain);
|
|
3894
|
+
const partialMainSize = Math.max(Number.isFinite(size) ? size : 0, minMain);
|
|
3812
3895
|
const clampIndex = React21.useCallback(
|
|
3813
3896
|
(i) => {
|
|
3814
3897
|
if (count <= 0) {
|
|
@@ -3851,14 +3934,16 @@ function TabGroup({
|
|
|
3851
3934
|
const radius = parseFloat(computed.getPropertyValue("--rui-tab-panel-radius")) || 0;
|
|
3852
3935
|
const border = parseFloat(computed.getPropertyValue("--rui-tab-border")) || 0;
|
|
3853
3936
|
const minMainValue = parseFloat(computed.getPropertyValue("--rui-tab-min-main")) || 32;
|
|
3937
|
+
const effectiveMinMain = Math.max(minMainValue, contentMinMain);
|
|
3854
3938
|
const wiggle = border * 2 + 1;
|
|
3855
3939
|
const available = position === "top" || position === "bottom" ? rect.width : rect.height;
|
|
3856
|
-
const
|
|
3857
|
-
const
|
|
3940
|
+
const requiredPerTab = Math.max(size != null ? size : 0, effectiveMinMain);
|
|
3941
|
+
const required = requiredPerTab * tabs.length;
|
|
3942
|
+
const slots2 = effectiveMinMain > 0 ? Math.floor(available / effectiveMinMain) : tabs.length;
|
|
3858
3943
|
const hasOverflowControls = slots2 < tabs.length;
|
|
3859
3944
|
const shouldFill = available - 2 * radius - wiggle <= required;
|
|
3860
3945
|
setEffectiveFill(shouldFill || hasOverflowControls ? "full" : "partial");
|
|
3861
|
-
}, [fill, position, size, tabs.length]);
|
|
3946
|
+
}, [contentMinMain, fill, position, size, tabs.length]);
|
|
3862
3947
|
React21.useLayoutEffect(() => {
|
|
3863
3948
|
if (fill === "full") {
|
|
3864
3949
|
setEffectiveFill("full");
|
|
@@ -3873,14 +3958,43 @@ function TabGroup({
|
|
|
3873
3958
|
observer.observe(node);
|
|
3874
3959
|
return () => observer.disconnect();
|
|
3875
3960
|
}, [fill, updateEffectiveFill]);
|
|
3876
|
-
const isVertical = position === "left" || position === "right";
|
|
3877
3961
|
React21.useLayoutEffect(() => {
|
|
3878
3962
|
const root = rootRef.current;
|
|
3879
3963
|
if (!root) return;
|
|
3880
3964
|
const computed = getComputedStyle(root);
|
|
3881
3965
|
const cssMin = parseFloat(computed.getPropertyValue("--rui-tab-min-main"));
|
|
3882
|
-
|
|
3966
|
+
setCssMinMain(Number.isFinite(cssMin) && cssMin > 0 ? cssMin : 32);
|
|
3883
3967
|
}, [position]);
|
|
3968
|
+
React21.useLayoutEffect(() => {
|
|
3969
|
+
const node = measureRef.current;
|
|
3970
|
+
if (!node) return;
|
|
3971
|
+
const measure = () => {
|
|
3972
|
+
const sampleTab = node.querySelector(".rui-tab-group__tab");
|
|
3973
|
+
const labels = Array.from(node.querySelectorAll(".rui-tab-group__label"));
|
|
3974
|
+
if (!sampleTab || labels.length === 0) {
|
|
3975
|
+
setContentMinMain(0);
|
|
3976
|
+
return;
|
|
3977
|
+
}
|
|
3978
|
+
const tabStyle = getComputedStyle(sampleTab);
|
|
3979
|
+
const paddingMain = isVertical ? (parseFloat(tabStyle.paddingTop) || 0) + (parseFloat(tabStyle.paddingBottom) || 0) : (parseFloat(tabStyle.paddingLeft) || 0) + (parseFloat(tabStyle.paddingRight) || 0);
|
|
3980
|
+
const borderMain = isVertical ? (parseFloat(tabStyle.borderTopWidth) || 0) + (parseFloat(tabStyle.borderBottomWidth) || 0) : (parseFloat(tabStyle.borderLeftWidth) || 0) + (parseFloat(tabStyle.borderRightWidth) || 0);
|
|
3981
|
+
let largestLabelMain = 0;
|
|
3982
|
+
for (const label of labels) {
|
|
3983
|
+
const rect = label.getBoundingClientRect();
|
|
3984
|
+
const labelMain = isVertical ? rect.height : rect.width;
|
|
3985
|
+
if (labelMain > largestLabelMain) {
|
|
3986
|
+
largestLabelMain = labelMain;
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
const next = Math.ceil(largestLabelMain + paddingMain + borderMain);
|
|
3990
|
+
setContentMinMain((prev) => prev === next ? prev : next);
|
|
3991
|
+
};
|
|
3992
|
+
measure();
|
|
3993
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
3994
|
+
const observer = new ResizeObserver(() => measure());
|
|
3995
|
+
observer.observe(node);
|
|
3996
|
+
return () => observer.disconnect();
|
|
3997
|
+
}, [isVertical, position, rotation, tabs]);
|
|
3884
3998
|
React21.useLayoutEffect(() => {
|
|
3885
3999
|
const node = tabStripRef.current;
|
|
3886
4000
|
if (!node) return;
|
|
@@ -3896,7 +4010,8 @@ function TabGroup({
|
|
|
3896
4010
|
}, [isVertical]);
|
|
3897
4011
|
const slots = availableMain > 0 && minMain > 0 ? Math.floor(availableMain / minMain) : count;
|
|
3898
4012
|
const overflow = slots < count;
|
|
3899
|
-
const
|
|
4013
|
+
const layoutSlots = overflow ? Math.max(3, slots) : Math.max(1, slots);
|
|
4014
|
+
const windowSize = overflow ? Math.max(1, layoutSlots - 2) : count;
|
|
3900
4015
|
const maxStart = Math.max(0, count - windowSize);
|
|
3901
4016
|
const [startIndex, setStartIndex] = React21.useState(0);
|
|
3902
4017
|
React21.useEffect(() => {
|
|
@@ -3916,9 +4031,9 @@ function TabGroup({
|
|
|
3916
4031
|
});
|
|
3917
4032
|
}, [currentActive, overflow, windowSize]);
|
|
3918
4033
|
const visibleTabs = overflow ? tabs.slice(startIndex, startIndex + windowSize) : tabs;
|
|
3919
|
-
const slotSize = overflow &&
|
|
4034
|
+
const slotSize = overflow && layoutSlots > 0 ? availableMain / layoutSlots : 0;
|
|
3920
4035
|
const overflowMainStyle = overflow && slotSize > 0 ? isVertical ? { height: slotSize } : { width: slotSize } : void 0;
|
|
3921
|
-
const mainStyle = overflow ? overflowMainStyle : effectiveFill === "partial" ? isVertical ? { height:
|
|
4036
|
+
const mainStyle = overflow ? overflowMainStyle : effectiveFill === "partial" ? isVertical ? { height: partialMainSize } : { width: partialMainSize } : void 0;
|
|
3922
4037
|
const scrollLabels = isVertical ? { back: "Scroll tabs up", forward: "Scroll tabs down" } : { back: "Scroll tabs left", forward: "Scroll tabs right" };
|
|
3923
4038
|
const scrollMainStyle = overflowMainStyle;
|
|
3924
4039
|
const panelId = `${idBase}-panel`;
|
|
@@ -4053,7 +4168,7 @@ function TabGroup({
|
|
|
4053
4168
|
children: (_b = (_a = tabs[currentActive]) == null ? void 0 : _a.content) != null ? _b : null
|
|
4054
4169
|
}
|
|
4055
4170
|
);
|
|
4056
|
-
return /* @__PURE__ */
|
|
4171
|
+
return /* @__PURE__ */ jsxs23(
|
|
4057
4172
|
"div",
|
|
4058
4173
|
{
|
|
4059
4174
|
ref: rootRef,
|
|
@@ -4064,13 +4179,16 @@ function TabGroup({
|
|
|
4064
4179
|
"data-requested-fill": fill,
|
|
4065
4180
|
"data-rotation": rotation,
|
|
4066
4181
|
"data-overflow": overflow ? "true" : "false",
|
|
4067
|
-
children:
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4182
|
+
children: [
|
|
4183
|
+
/* @__PURE__ */ jsx25("div", { ref: measureRef, className: "rui-tab-group__measure", "aria-hidden": "true", children: tabs.map((tab, index) => /* @__PURE__ */ jsx25("button", { type: "button", className: "rui-tab-group__tab", children: /* @__PURE__ */ jsx25("span", { className: "rui-tab-group__label", children: tab.label }) }, index)) }),
|
|
4184
|
+
tabsFirst ? /* @__PURE__ */ jsxs23(Fragment2, { children: [
|
|
4185
|
+
tabList,
|
|
4186
|
+
panel
|
|
4187
|
+
] }) : /* @__PURE__ */ jsxs23(Fragment2, { children: [
|
|
4188
|
+
panel,
|
|
4189
|
+
tabList
|
|
4190
|
+
] })
|
|
4191
|
+
]
|
|
4074
4192
|
}
|
|
4075
4193
|
);
|
|
4076
4194
|
}
|