react-ui-suite 1.1.6 → 1.1.8

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.
@@ -6,14 +6,18 @@
6
6
  border-color: #64748b;
7
7
  }
8
8
 
9
- .rui-combobox__listbox {
10
- max-height: 16rem;
11
- overflow: auto;
12
- padding-left: 0.25rem;
13
- padding-right: 1rem;
14
- margin: 0px;
15
- scrollbar-width: none;
16
- }
9
+ .rui-combobox__listbox {
10
+ max-height: 16rem;
11
+ overflow: auto;
12
+ padding-left: 0.25rem;
13
+ padding-right: 1rem;
14
+ margin: 0px;
15
+ scrollbar-width: none;
16
+ }
17
+
18
+ .rui-popover[data-scrollbar-visible="false"] .rui-combobox__listbox {
19
+ padding-right: 0.25rem;
20
+ }
17
21
 
18
22
  .rui-combobox__listbox::-webkit-scrollbar {
19
23
  width: 0;
@@ -120,6 +120,37 @@
120
120
  color: var(--rui-color-text-muted);
121
121
  }
122
122
 
123
+ .rui-file-picker__item-actions {
124
+ display: inline-flex;
125
+ align-items: center;
126
+ gap: 0.375rem;
127
+ }
128
+
129
+ .rui-file-picker__remove {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ width: 1.125rem;
134
+ height: 1.125rem;
135
+ border: 1px solid var(--rui-color-border);
136
+ border-radius: 999px;
137
+ background: var(--rui-color-surface);
138
+ color: var(--rui-color-text-muted);
139
+ font-size: 0.75rem;
140
+ line-height: 1;
141
+ cursor: pointer;
142
+ }
143
+
144
+ .rui-file-picker__remove:hover {
145
+ border-color: var(--rui-color-border-strong);
146
+ color: var(--rui-color-text-strong);
147
+ }
148
+
149
+ .rui-file-picker__remove:focus-visible {
150
+ outline: none;
151
+ box-shadow: 0 0 0 2px rgb(148 163 184 / 0.35);
152
+ }
153
+
123
154
  .rui-file-picker__description,
124
155
  .rui-file-picker__warning,
125
156
  .rui-file-picker__error {
@@ -152,4 +183,3 @@
152
183
  [data-theme="dark"] .rui-file-picker__warning {
153
184
  color: rgb(251 191 36);
154
185
  }
155
-
@@ -52,14 +52,18 @@
52
52
  font-weight: 600;
53
53
  }
54
54
 
55
- .rui-select__list {
56
- margin: 0;
57
- padding: 0rem 1rem 0rem 0.25rem;
58
- list-style: none;
59
- max-height: 16rem;
60
- overflow: auto;
61
- scrollbar-width: none;
62
- }
55
+ .rui-select__list {
56
+ margin: 0;
57
+ padding: 0rem 1rem 0rem 0.25rem;
58
+ list-style: none;
59
+ max-height: 16rem;
60
+ overflow: auto;
61
+ scrollbar-width: none;
62
+ }
63
+
64
+ .rui-popover[data-scrollbar-visible="false"] .rui-select__list {
65
+ padding-right: 0.25rem;
66
+ }
63
67
 
64
68
  .rui-select__list::-webkit-scrollbar {
65
69
  width: 0;
@@ -4,7 +4,6 @@
4
4
  height: 100%;
5
5
  position: relative;
6
6
  --rui-tab-border: 1px;
7
- --rui-tab-panel-radius: 15px;
8
7
  --rui-tab-radius: 10px;
9
8
  --rui-tab-min-main: 32px;
10
9
  }
@@ -252,16 +251,15 @@
252
251
  transform: none;
253
252
  }
254
253
 
255
- .rui-tab-group__panel {
256
- padding: 5px;
257
- flex: 1;
258
- border: var(--rui-tab-border) solid var(--rui-color-border);
259
- background-color: var(--rui-color-surface);
260
- min-width: 0;
261
- min-height: 0;
262
- position: relative;
263
- z-index: 0;
264
- }
254
+ .rui-tab-group__panel {
255
+ padding: 5px;
256
+ flex: 1;
257
+ background-color: var(--rui-color-surface);
258
+ min-width: 0;
259
+ min-height: 0;
260
+ position: relative;
261
+ z-index: 0;
262
+ }
265
263
 
266
264
  [data-theme="dark"] .rui-tab-group__tab {
267
265
  background-color: var(--rui-color-surface);
@@ -276,58 +274,6 @@
276
274
  --rui-tab-active-bg: var(--rui-color-surface-muted);
277
275
  }
278
276
 
279
- [data-theme="dark"] .rui-tab-group__panel {
280
- background-color: var(--rui-color-surface-muted);
281
- }
282
-
283
- .rui-tab-group[data-position="top"] .rui-tab-group__panel {
284
- border-bottom-left-radius: var(--rui-tab-panel-radius);
285
- border-bottom-right-radius: var(--rui-tab-panel-radius);
286
- }
287
-
288
- .rui-tab-group[data-position="bottom"] .rui-tab-group__panel {
289
- border-top-left-radius: var(--rui-tab-panel-radius);
290
- border-top-right-radius: var(--rui-tab-panel-radius);
291
- }
292
-
293
- .rui-tab-group[data-position="left"] .rui-tab-group__panel {
294
- border-top-right-radius: var(--rui-tab-panel-radius);
295
- border-bottom-right-radius: var(--rui-tab-panel-radius);
296
- }
297
-
298
- .rui-tab-group[data-position="right"] .rui-tab-group__panel {
299
- border-top-left-radius: var(--rui-tab-panel-radius);
300
- border-bottom-left-radius: var(--rui-tab-panel-radius);
301
- }
302
-
303
- .rui-tab-group[data-position="top"][data-fill="partial"]:not([data-align="start"]) .rui-tab-group__panel {
304
- border-top-left-radius: var(--rui-tab-panel-radius);
305
- }
306
-
307
- .rui-tab-group[data-position="top"][data-fill="partial"]:not([data-align="end"]) .rui-tab-group__panel {
308
- border-top-right-radius: var(--rui-tab-panel-radius);
309
- }
310
-
311
- .rui-tab-group[data-position="bottom"][data-fill="partial"]:not([data-align="start"]) .rui-tab-group__panel {
312
- border-bottom-left-radius: var(--rui-tab-panel-radius);
313
- }
314
-
315
- .rui-tab-group[data-position="bottom"][data-fill="partial"]:not([data-align="end"]) .rui-tab-group__panel {
316
- border-bottom-right-radius: var(--rui-tab-panel-radius);
317
- }
318
-
319
- .rui-tab-group[data-position="left"][data-fill="partial"]:not([data-align="start"]) .rui-tab-group__panel {
320
- border-top-left-radius: var(--rui-tab-panel-radius);
321
- }
322
-
323
- .rui-tab-group[data-position="left"][data-fill="partial"]:not([data-align="end"]) .rui-tab-group__panel {
324
- border-bottom-left-radius: var(--rui-tab-panel-radius);
325
- }
326
-
327
- .rui-tab-group[data-position="right"][data-fill="partial"]:not([data-align="start"]) .rui-tab-group__panel {
328
- border-top-right-radius: var(--rui-tab-panel-radius);
329
- }
330
-
331
- .rui-tab-group[data-position="right"][data-fill="partial"]:not([data-align="end"]) .rui-tab-group__panel {
332
- border-bottom-right-radius: var(--rui-tab-panel-radius);
333
- }
277
+ [data-theme="dark"] .rui-tab-group__panel {
278
+ background-color: var(--rui-color-surface-muted);
279
+ }
package/dist/index.d.ts CHANGED
@@ -203,6 +203,15 @@ type FileSelection = {
203
203
  path?: string;
204
204
  text?: string;
205
205
  bytes?: Uint8Array;
206
+ size?: number;
207
+ };
208
+ type FilePickerExternalRequest = {
209
+ directory: boolean;
210
+ multiple: boolean;
211
+ mode: FilePickerMode;
212
+ accept?: string;
213
+ maxFiles?: number;
214
+ currentSelections: FileSelection[];
206
215
  };
207
216
  type FilePickerProps = NativeInputProps & {
208
217
  label?: string;
@@ -210,8 +219,10 @@ type FilePickerProps = NativeInputProps & {
210
219
  error?: string;
211
220
  dropzoneLabel?: string;
212
221
  maxFiles?: number;
222
+ directory?: boolean;
213
223
  mode?: FilePickerMode;
214
224
  resolvePath?: (file: File) => string | undefined | Promise<string | undefined>;
225
+ externalPicker?: (request: FilePickerExternalRequest) => Promise<FileSelection[] | null | undefined>;
215
226
  onFilesChange?: (files: FileSelection[]) => void;
216
227
  };
217
228
  declare const FilePicker: React.ForwardRefExoticComponent<NativeInputProps & {
@@ -220,8 +231,10 @@ declare const FilePicker: React.ForwardRefExoticComponent<NativeInputProps & {
220
231
  error?: string;
221
232
  dropzoneLabel?: string;
222
233
  maxFiles?: number;
234
+ directory?: boolean;
223
235
  mode?: FilePickerMode;
224
236
  resolvePath?: (file: File) => string | undefined | Promise<string | undefined>;
237
+ externalPicker?: (request: FilePickerExternalRequest) => Promise<FileSelection[] | null | undefined>;
225
238
  onFilesChange?: (files: FileSelection[]) => void;
226
239
  } & React.RefAttributes<HTMLInputElement>>;
227
240
 
@@ -541,4 +554,4 @@ declare const Toggle: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttri
541
554
  onChange?: (checked: boolean) => void;
542
555
  } & React.RefAttributes<HTMLButtonElement>>;
543
556
 
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 };
557
+ 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 FilePickerExternalRequest, 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
@@ -1062,7 +1062,10 @@ function getAnchorPosition(anchor) {
1062
1062
  width: rect.width
1063
1063
  };
1064
1064
  }
1065
- function Scrollbar({ scrollRef }) {
1065
+ function Scrollbar({
1066
+ scrollRef,
1067
+ onVisibilityChange
1068
+ }) {
1066
1069
  const [{ visible, size, offset }, setThumbState] = React7.useState({
1067
1070
  visible: false,
1068
1071
  size: MIN_THUMB_SIZE,
@@ -1103,6 +1106,9 @@ function Scrollbar({ scrollRef }) {
1103
1106
  cancelAnimationFrame(raf);
1104
1107
  };
1105
1108
  }, [scrollRef]);
1109
+ React7.useEffect(() => {
1110
+ onVisibilityChange == null ? void 0 : onVisibilityChange(visible);
1111
+ }, [onVisibilityChange, visible]);
1106
1112
  React7.useEffect(() => {
1107
1113
  const handlePointerMove = (event) => {
1108
1114
  const drag = dragState.current;
@@ -1188,6 +1194,7 @@ function Scrollbar({ scrollRef }) {
1188
1194
  }
1189
1195
  function Popover({ className, anchorRef, rootRef, children }) {
1190
1196
  const scrollRef = React7.useRef(null);
1197
+ const [scrollbarVisible, setScrollbarVisible] = React7.useState(false);
1191
1198
  const [position, setPosition] = React7.useState(
1192
1199
  () => {
1193
1200
  var _a;
@@ -1228,10 +1235,11 @@ function Popover({ className, anchorRef, rootRef, children }) {
1228
1235
  shouldPortal && "rui-popover--portal",
1229
1236
  className
1230
1237
  ),
1238
+ "data-scrollbar-visible": scrollbarVisible ? "true" : "false",
1231
1239
  style: popoverStyle,
1232
1240
  children: /* @__PURE__ */ jsxs8("div", { className: "rui-popover__inner", children: [
1233
1241
  children({ scrollRef }),
1234
- /* @__PURE__ */ jsx9(Scrollbar, { scrollRef })
1242
+ /* @__PURE__ */ jsx9(Scrollbar, { scrollRef, onVisibilityChange: setScrollbarVisible })
1235
1243
  ] })
1236
1244
  }
1237
1245
  );
@@ -1269,7 +1277,7 @@ function useOutsideClick(refs, handler) {
1269
1277
  // components/Combobox/Listbox.tsx
1270
1278
  import * as React8 from "react";
1271
1279
  import clsx9 from "clsx";
1272
- import "./Combobox-UQBN7KFK.css";
1280
+ import "./Combobox-YP4UGGM7.css";
1273
1281
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1274
1282
  function Listbox({
1275
1283
  id,
@@ -1343,7 +1351,7 @@ function Listbox({
1343
1351
 
1344
1352
  // components/Combobox/Combobox.tsx
1345
1353
  import clsx10 from "clsx";
1346
- import "./Combobox-UQBN7KFK.css";
1354
+ import "./Combobox-YP4UGGM7.css";
1347
1355
  import { jsx as jsx11 } from "react/jsx-runtime";
1348
1356
  function InnerCombobox({
1349
1357
  options,
@@ -1846,7 +1854,7 @@ import * as React12 from "react";
1846
1854
  // components/Select/Select.tsx
1847
1855
  import * as React11 from "react";
1848
1856
  import clsx12 from "clsx";
1849
- import "./Select-UA2CM52H.css";
1857
+ import "./Select-HD5HKBTM.css";
1850
1858
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1851
1859
  function Select({
1852
1860
  label,
@@ -2804,7 +2812,7 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2804
2812
  // components/FilePicker/FilePicker.tsx
2805
2813
  import * as React15 from "react";
2806
2814
  import clsx16 from "clsx";
2807
- import "./FilePicker-N72M7PZO.css";
2815
+ import "./FilePicker-QFTDWVCF.css";
2808
2816
  import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2809
2817
  function matchesAcceptToken(file, token) {
2810
2818
  const normalizedToken = token.trim().toLowerCase();
@@ -2872,14 +2880,39 @@ async function readFileBytes(file) {
2872
2880
  }
2873
2881
  return void 0;
2874
2882
  }
2883
+ async function readDirectorySize(handle) {
2884
+ if (typeof handle.values !== "function") {
2885
+ return void 0;
2886
+ }
2887
+ let total = 0;
2888
+ for await (const entry of handle.values()) {
2889
+ if (entry.kind === "file" && typeof entry.getFile === "function") {
2890
+ const file = await entry.getFile();
2891
+ total += file.size;
2892
+ continue;
2893
+ }
2894
+ if (entry.kind === "directory" && typeof entry.values === "function") {
2895
+ const nestedSize = await readDirectorySize({
2896
+ name: "",
2897
+ values: entry.values
2898
+ });
2899
+ if (typeof nestedSize === "number") {
2900
+ total += nestedSize;
2901
+ }
2902
+ }
2903
+ }
2904
+ return total;
2905
+ }
2875
2906
  var FilePicker = React15.forwardRef(function FilePicker2({
2876
2907
  label,
2877
2908
  description,
2878
2909
  error,
2879
2910
  dropzoneLabel = "Drop files here or click to browse",
2880
2911
  maxFiles,
2912
+ directory = false,
2881
2913
  mode = "path",
2882
2914
  resolvePath,
2915
+ externalPicker,
2883
2916
  id,
2884
2917
  className,
2885
2918
  accept,
@@ -2898,6 +2931,9 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2898
2931
  const [restrictedCount, setRestrictedCount] = React15.useState(0);
2899
2932
  const inputRef = React15.useRef(null);
2900
2933
  const selectionRequestIdRef = React15.useRef(0);
2934
+ const canUseDirectoryHandlePicker = typeof window !== "undefined" && typeof window.showDirectoryPicker === "function";
2935
+ const isFolderPathOnlyMode = directory && mode === "path";
2936
+ const useDirectoryInputAttributes = directory && (!isFolderPathOnlyMode || !canUseDirectoryHandlePicker);
2901
2937
  const setRefs = React15.useCallback(
2902
2938
  (node) => {
2903
2939
  inputRef.current = node;
@@ -2911,14 +2947,72 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2911
2947
  );
2912
2948
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
2913
2949
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
2950
+ const resolvedMultiple = multiple || useDirectoryInputAttributes;
2914
2951
  const resolvedMaxFiles = React15.useMemo(() => {
2915
2952
  if (typeof maxFiles !== "number" || !Number.isFinite(maxFiles)) return void 0;
2916
2953
  return Math.max(1, Math.floor(maxFiles));
2917
2954
  }, [maxFiles]);
2955
+ const directoryAttributes = useDirectoryInputAttributes ? { directory: "", webkitdirectory: "" } : void 0;
2956
+ const selectDirectoryPath = React15.useCallback(async () => {
2957
+ if (!isFolderPathOnlyMode || !canUseDirectoryHandlePicker) {
2958
+ return false;
2959
+ }
2960
+ const picker = window.showDirectoryPicker;
2961
+ if (!picker) {
2962
+ return false;
2963
+ }
2964
+ try {
2965
+ const directoryHandle = await picker();
2966
+ const requestId = selectionRequestIdRef.current + 1;
2967
+ selectionRequestIdRef.current = requestId;
2968
+ const selection = {
2969
+ file: new File([], directoryHandle.name, { type: "application/x-directory" }),
2970
+ path: directoryHandle.name
2971
+ };
2972
+ const directorySize = await readDirectorySize(directoryHandle);
2973
+ if (typeof directorySize === "number") {
2974
+ selection.size = directorySize;
2975
+ }
2976
+ const selectionLimit = multiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
2977
+ const mergedSelections = multiple ? [...selectedFiles, selection] : [selection];
2978
+ const nextSelections = mergedSelections.slice(0, selectionLimit);
2979
+ const nextRestrictedCount = mergedSelections.length - nextSelections.length;
2980
+ setSelectedFiles(nextSelections);
2981
+ setRestrictedCount(nextRestrictedCount);
2982
+ onFilesChange == null ? void 0 : onFilesChange(nextSelections);
2983
+ if (inputRef.current) {
2984
+ inputRef.current.value = "";
2985
+ }
2986
+ return true;
2987
+ } catch (error2) {
2988
+ if (error2 instanceof DOMException && error2.name === "AbortError") {
2989
+ return true;
2990
+ }
2991
+ return false;
2992
+ }
2993
+ }, [
2994
+ canUseDirectoryHandlePicker,
2995
+ isFolderPathOnlyMode,
2996
+ multiple,
2997
+ onFilesChange,
2998
+ resolvedMaxFiles,
2999
+ selectedFiles
3000
+ ]);
3001
+ const applyExternalSelections = React15.useCallback(
3002
+ (incomingSelections) => {
3003
+ const selectionLimit = resolvedMultiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
3004
+ const nextSelections = incomingSelections.slice(0, selectionLimit);
3005
+ const nextRestrictedCount = incomingSelections.length - nextSelections.length;
3006
+ setSelectedFiles(nextSelections);
3007
+ setRestrictedCount(nextRestrictedCount);
3008
+ onFilesChange == null ? void 0 : onFilesChange(nextSelections);
3009
+ },
3010
+ [onFilesChange, resolvedMaxFiles, resolvedMultiple]
3011
+ );
2918
3012
  const applySelectedFiles = React15.useCallback(
2919
3013
  async (files) => {
2920
3014
  const acceptedFiles = filterFilesByAccept(files, accept);
2921
- const selectionLimit = multiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
3015
+ const selectionLimit = resolvedMultiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
2922
3016
  const nextFiles = acceptedFiles.slice(0, selectionLimit);
2923
3017
  const nextRestrictedCount = files.length - nextFiles.length;
2924
3018
  const requestId = selectionRequestIdRef.current + 1;
@@ -2926,9 +3020,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2926
3020
  const nextSelections = await Promise.all(
2927
3021
  nextFiles.map(async (file) => {
2928
3022
  const selection = { file };
2929
- if (mode === "path" || mode === "both") {
2930
- selection.path = await derivePath(file, resolvePath);
2931
- }
3023
+ selection.path = await derivePath(file, resolvePath);
2932
3024
  if (mode === "content" || mode === "both") {
2933
3025
  const bytes = await readFileBytes(file);
2934
3026
  if (bytes) {
@@ -2947,7 +3039,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2947
3039
  onFilesChange == null ? void 0 : onFilesChange(nextSelections);
2948
3040
  return nextSelections;
2949
3041
  },
2950
- [accept, mode, multiple, onFilesChange, resolvePath, resolvedMaxFiles]
3042
+ [accept, mode, onFilesChange, resolvePath, resolvedMaxFiles, resolvedMultiple]
2951
3043
  );
2952
3044
  const handleInputChange = (event) => {
2953
3045
  var _a;
@@ -2955,8 +3047,29 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2955
3047
  void applySelectedFiles(incomingFiles);
2956
3048
  onChange == null ? void 0 : onChange(event);
2957
3049
  };
2958
- const openFileDialog = () => {
3050
+ const openFileDialog = async () => {
2959
3051
  if (disabled) return;
3052
+ if (externalPicker) {
3053
+ try {
3054
+ const nextSelections = await externalPicker({
3055
+ directory,
3056
+ multiple: resolvedMultiple,
3057
+ mode,
3058
+ accept,
3059
+ maxFiles: resolvedMaxFiles,
3060
+ currentSelections: selectedFiles
3061
+ });
3062
+ if (Array.isArray(nextSelections)) {
3063
+ applyExternalSelections(nextSelections);
3064
+ }
3065
+ } catch {
3066
+ }
3067
+ return;
3068
+ }
3069
+ const handledByDirectoryPicker = await selectDirectoryPath();
3070
+ if (handledByDirectoryPicker) {
3071
+ return;
3072
+ }
2960
3073
  if (inputRef.current) {
2961
3074
  inputRef.current.value = "";
2962
3075
  inputRef.current.click();
@@ -2966,11 +3079,24 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2966
3079
  var _a;
2967
3080
  event.preventDefault();
2968
3081
  if (disabled) return;
3082
+ if (isFolderPathOnlyMode && canUseDirectoryHandlePicker) {
3083
+ return;
3084
+ }
2969
3085
  setIsDragActive(false);
2970
3086
  const files = Array.from((_a = event.dataTransfer.files) != null ? _a : []);
2971
3087
  void applySelectedFiles(files);
2972
3088
  };
2973
3089
  const hasSelection = selectedFiles.length > 0;
3090
+ const allowSelectionRemoval = Boolean(multiple);
3091
+ const removeSelection = React15.useCallback(
3092
+ (indexToRemove) => {
3093
+ const nextSelections = selectedFiles.filter((_, index) => index !== indexToRemove);
3094
+ setSelectedFiles(nextSelections);
3095
+ setRestrictedCount(0);
3096
+ onFilesChange == null ? void 0 : onFilesChange(nextSelections);
3097
+ },
3098
+ [onFilesChange, selectedFiles]
3099
+ );
2974
3100
  return /* @__PURE__ */ jsxs15("div", { className: "rui-file-picker rui-root", children: [
2975
3101
  label ? /* @__PURE__ */ jsx17("label", { htmlFor: inputId, className: "rui-file-picker__label rui-text-wrap", children: label }) : null,
2976
3102
  /* @__PURE__ */ jsxs15(
@@ -2986,11 +3112,13 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2986
3112
  tabIndex: disabled ? -1 : 0,
2987
3113
  "aria-label": label ? `${label} file picker` : "File picker",
2988
3114
  "aria-disabled": disabled ? true : void 0,
2989
- onClick: openFileDialog,
3115
+ onClick: () => {
3116
+ void openFileDialog();
3117
+ },
2990
3118
  onKeyDown: (event) => {
2991
3119
  if (event.key === "Enter" || event.key === " ") {
2992
3120
  event.preventDefault();
2993
- openFileDialog();
3121
+ void openFileDialog();
2994
3122
  }
2995
3123
  },
2996
3124
  onDragEnter: (event) => {
@@ -3012,13 +3140,21 @@ var FilePicker = React15.forwardRef(function FilePicker2({
3012
3140
  "input",
3013
3141
  {
3014
3142
  ...rest,
3143
+ ...directoryAttributes,
3015
3144
  id: inputId,
3016
3145
  ref: setRefs,
3017
3146
  type: "file",
3018
3147
  className: clsx16("rui-file-picker__input", className),
3019
3148
  accept,
3020
3149
  disabled,
3021
- multiple,
3150
+ multiple: resolvedMultiple,
3151
+ onClick: (event) => {
3152
+ event.stopPropagation();
3153
+ if (isFolderPathOnlyMode && canUseDirectoryHandlePicker) {
3154
+ event.preventDefault();
3155
+ void openFileDialog();
3156
+ }
3157
+ },
3022
3158
  onChange: handleInputChange,
3023
3159
  "aria-invalid": error ? true : void 0,
3024
3160
  "aria-describedby": resolvedAriaDescribedBy
@@ -3030,17 +3166,35 @@ var FilePicker = React15.forwardRef(function FilePicker2({
3030
3166
  "Maximum files: ",
3031
3167
  resolvedMaxFiles
3032
3168
  ] }) : null,
3033
- hasSelection ? /* @__PURE__ */ jsx17("ul", { className: "rui-file-picker__list", "aria-label": "Selected files", children: selectedFiles.map((selection) => /* @__PURE__ */ jsxs15(
3034
- "li",
3035
- {
3036
- className: "rui-file-picker__item",
3037
- children: [
3038
- /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-name rui-text-wrap", children: selection.file.name }),
3039
- /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-meta", children: formatBytes(selection.file.size) })
3040
- ]
3041
- },
3042
- `${selection.file.name}-${selection.file.size}-${selection.file.lastModified}`
3043
- )) }) : null
3169
+ hasSelection ? /* @__PURE__ */ jsx17("ul", { className: "rui-file-picker__list", "aria-label": "Selected files", children: selectedFiles.map((selection, index) => {
3170
+ var _a, _b, _c, _d;
3171
+ return /* @__PURE__ */ jsxs15(
3172
+ "li",
3173
+ {
3174
+ className: "rui-file-picker__item",
3175
+ children: [
3176
+ /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-name rui-text-wrap", children: /* @__PURE__ */ jsx17("span", { title: (_a = selection.path) != null ? _a : selection.file.name, children: (_b = selection.path) != null ? _b : selection.file.name }) }),
3177
+ /* @__PURE__ */ jsxs15("div", { className: "rui-file-picker__item-actions", children: [
3178
+ /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-meta", children: formatBytes((_c = selection.size) != null ? _c : selection.file.size) }),
3179
+ allowSelectionRemoval ? /* @__PURE__ */ jsx17(
3180
+ "button",
3181
+ {
3182
+ type: "button",
3183
+ className: "rui-file-picker__remove",
3184
+ "aria-label": `Remove ${(_d = selection.path) != null ? _d : selection.file.name}`,
3185
+ onClick: (event) => {
3186
+ event.stopPropagation();
3187
+ removeSelection(index);
3188
+ },
3189
+ children: "x"
3190
+ }
3191
+ ) : null
3192
+ ] })
3193
+ ]
3194
+ },
3195
+ `${selection.file.name}-${selection.file.size}-${selection.file.lastModified}`
3196
+ );
3197
+ }) }) : null
3044
3198
  ]
3045
3199
  }
3046
3200
  ),
@@ -3871,7 +4025,7 @@ function StackedList({ items, dense, className, ...rest }) {
3871
4025
 
3872
4026
  // components/TabGroup/TabGroup.tsx
3873
4027
  import React21 from "react";
3874
- import "./TabGroup-3NH74LET.css";
4028
+ import "./TabGroup-7GEU6J3L.css";
3875
4029
  import { Fragment as Fragment2, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3876
4030
  function TabGroup({
3877
4031
  align = "start",