react-ui-suite 1.1.7 → 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.
@@ -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
-
@@ -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
@@ -2812,7 +2812,7 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2812
2812
  // components/FilePicker/FilePicker.tsx
2813
2813
  import * as React15 from "react";
2814
2814
  import clsx16 from "clsx";
2815
- import "./FilePicker-N72M7PZO.css";
2815
+ import "./FilePicker-QFTDWVCF.css";
2816
2816
  import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2817
2817
  function matchesAcceptToken(file, token) {
2818
2818
  const normalizedToken = token.trim().toLowerCase();
@@ -2880,14 +2880,39 @@ async function readFileBytes(file) {
2880
2880
  }
2881
2881
  return void 0;
2882
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
+ }
2883
2906
  var FilePicker = React15.forwardRef(function FilePicker2({
2884
2907
  label,
2885
2908
  description,
2886
2909
  error,
2887
2910
  dropzoneLabel = "Drop files here or click to browse",
2888
2911
  maxFiles,
2912
+ directory = false,
2889
2913
  mode = "path",
2890
2914
  resolvePath,
2915
+ externalPicker,
2891
2916
  id,
2892
2917
  className,
2893
2918
  accept,
@@ -2906,6 +2931,9 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2906
2931
  const [restrictedCount, setRestrictedCount] = React15.useState(0);
2907
2932
  const inputRef = React15.useRef(null);
2908
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);
2909
2937
  const setRefs = React15.useCallback(
2910
2938
  (node) => {
2911
2939
  inputRef.current = node;
@@ -2919,14 +2947,72 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2919
2947
  );
2920
2948
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
2921
2949
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
2950
+ const resolvedMultiple = multiple || useDirectoryInputAttributes;
2922
2951
  const resolvedMaxFiles = React15.useMemo(() => {
2923
2952
  if (typeof maxFiles !== "number" || !Number.isFinite(maxFiles)) return void 0;
2924
2953
  return Math.max(1, Math.floor(maxFiles));
2925
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
+ );
2926
3012
  const applySelectedFiles = React15.useCallback(
2927
3013
  async (files) => {
2928
3014
  const acceptedFiles = filterFilesByAccept(files, accept);
2929
- const selectionLimit = multiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
3015
+ const selectionLimit = resolvedMultiple ? resolvedMaxFiles != null ? resolvedMaxFiles : Infinity : 1;
2930
3016
  const nextFiles = acceptedFiles.slice(0, selectionLimit);
2931
3017
  const nextRestrictedCount = files.length - nextFiles.length;
2932
3018
  const requestId = selectionRequestIdRef.current + 1;
@@ -2934,9 +3020,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2934
3020
  const nextSelections = await Promise.all(
2935
3021
  nextFiles.map(async (file) => {
2936
3022
  const selection = { file };
2937
- if (mode === "path" || mode === "both") {
2938
- selection.path = await derivePath(file, resolvePath);
2939
- }
3023
+ selection.path = await derivePath(file, resolvePath);
2940
3024
  if (mode === "content" || mode === "both") {
2941
3025
  const bytes = await readFileBytes(file);
2942
3026
  if (bytes) {
@@ -2955,7 +3039,7 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2955
3039
  onFilesChange == null ? void 0 : onFilesChange(nextSelections);
2956
3040
  return nextSelections;
2957
3041
  },
2958
- [accept, mode, multiple, onFilesChange, resolvePath, resolvedMaxFiles]
3042
+ [accept, mode, onFilesChange, resolvePath, resolvedMaxFiles, resolvedMultiple]
2959
3043
  );
2960
3044
  const handleInputChange = (event) => {
2961
3045
  var _a;
@@ -2963,8 +3047,29 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2963
3047
  void applySelectedFiles(incomingFiles);
2964
3048
  onChange == null ? void 0 : onChange(event);
2965
3049
  };
2966
- const openFileDialog = () => {
3050
+ const openFileDialog = async () => {
2967
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
+ }
2968
3073
  if (inputRef.current) {
2969
3074
  inputRef.current.value = "";
2970
3075
  inputRef.current.click();
@@ -2974,11 +3079,24 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2974
3079
  var _a;
2975
3080
  event.preventDefault();
2976
3081
  if (disabled) return;
3082
+ if (isFolderPathOnlyMode && canUseDirectoryHandlePicker) {
3083
+ return;
3084
+ }
2977
3085
  setIsDragActive(false);
2978
3086
  const files = Array.from((_a = event.dataTransfer.files) != null ? _a : []);
2979
3087
  void applySelectedFiles(files);
2980
3088
  };
2981
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
+ );
2982
3100
  return /* @__PURE__ */ jsxs15("div", { className: "rui-file-picker rui-root", children: [
2983
3101
  label ? /* @__PURE__ */ jsx17("label", { htmlFor: inputId, className: "rui-file-picker__label rui-text-wrap", children: label }) : null,
2984
3102
  /* @__PURE__ */ jsxs15(
@@ -2994,11 +3112,13 @@ var FilePicker = React15.forwardRef(function FilePicker2({
2994
3112
  tabIndex: disabled ? -1 : 0,
2995
3113
  "aria-label": label ? `${label} file picker` : "File picker",
2996
3114
  "aria-disabled": disabled ? true : void 0,
2997
- onClick: openFileDialog,
3115
+ onClick: () => {
3116
+ void openFileDialog();
3117
+ },
2998
3118
  onKeyDown: (event) => {
2999
3119
  if (event.key === "Enter" || event.key === " ") {
3000
3120
  event.preventDefault();
3001
- openFileDialog();
3121
+ void openFileDialog();
3002
3122
  }
3003
3123
  },
3004
3124
  onDragEnter: (event) => {
@@ -3020,13 +3140,21 @@ var FilePicker = React15.forwardRef(function FilePicker2({
3020
3140
  "input",
3021
3141
  {
3022
3142
  ...rest,
3143
+ ...directoryAttributes,
3023
3144
  id: inputId,
3024
3145
  ref: setRefs,
3025
3146
  type: "file",
3026
3147
  className: clsx16("rui-file-picker__input", className),
3027
3148
  accept,
3028
3149
  disabled,
3029
- multiple,
3150
+ multiple: resolvedMultiple,
3151
+ onClick: (event) => {
3152
+ event.stopPropagation();
3153
+ if (isFolderPathOnlyMode && canUseDirectoryHandlePicker) {
3154
+ event.preventDefault();
3155
+ void openFileDialog();
3156
+ }
3157
+ },
3030
3158
  onChange: handleInputChange,
3031
3159
  "aria-invalid": error ? true : void 0,
3032
3160
  "aria-describedby": resolvedAriaDescribedBy
@@ -3038,17 +3166,35 @@ var FilePicker = React15.forwardRef(function FilePicker2({
3038
3166
  "Maximum files: ",
3039
3167
  resolvedMaxFiles
3040
3168
  ] }) : null,
3041
- hasSelection ? /* @__PURE__ */ jsx17("ul", { className: "rui-file-picker__list", "aria-label": "Selected files", children: selectedFiles.map((selection) => /* @__PURE__ */ jsxs15(
3042
- "li",
3043
- {
3044
- className: "rui-file-picker__item",
3045
- children: [
3046
- /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-name rui-text-wrap", children: selection.file.name }),
3047
- /* @__PURE__ */ jsx17("span", { className: "rui-file-picker__file-meta", children: formatBytes(selection.file.size) })
3048
- ]
3049
- },
3050
- `${selection.file.name}-${selection.file.size}-${selection.file.lastModified}`
3051
- )) }) : 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
3052
3198
  ]
3053
3199
  }
3054
3200
  ),
@@ -3879,7 +4025,7 @@ function StackedList({ items, dense, className, ...rest }) {
3879
4025
 
3880
4026
  // components/TabGroup/TabGroup.tsx
3881
4027
  import React21 from "react";
3882
- import "./TabGroup-3NH74LET.css";
4028
+ import "./TabGroup-7GEU6J3L.css";
3883
4029
  import { Fragment as Fragment2, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3884
4030
  function TabGroup({
3885
4031
  align = "start",