@knkcs/anker 0.0.2 → 0.0.4

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 (44) hide show
  1. package/dist/atoms/index.d.ts +16 -3
  2. package/dist/atoms/index.js +89 -6
  3. package/dist/atoms/index.js.map +1 -1
  4. package/dist/chunk-5YDCDC4B.js +12 -0
  5. package/dist/chunk-5YDCDC4B.js.map +1 -0
  6. package/dist/{chunk-C4JI3JNA.js → chunk-6H4LQUMM.js} +4 -33
  7. package/dist/chunk-6H4LQUMM.js.map +1 -0
  8. package/dist/{chunk-PZCL4M6I.js → chunk-E7KRPPCQ.js} +5 -18
  9. package/dist/chunk-E7KRPPCQ.js.map +1 -0
  10. package/dist/{chunk-GJTQLZ4O.js → chunk-KVPN6T6J.js} +6 -28
  11. package/dist/chunk-KVPN6T6J.js.map +1 -0
  12. package/dist/chunk-OU6H3KU4.js +21 -0
  13. package/dist/chunk-OU6H3KU4.js.map +1 -0
  14. package/dist/chunk-SJ6YXNZW.js +30 -0
  15. package/dist/chunk-SJ6YXNZW.js.map +1 -0
  16. package/dist/chunk-SJIYWHIV.js +51 -0
  17. package/dist/chunk-SJIYWHIV.js.map +1 -0
  18. package/dist/chunk-WEP2AIQ5.js +37 -0
  19. package/dist/chunk-WEP2AIQ5.js.map +1 -0
  20. package/dist/chunk-WQIEF5N3.js +52 -0
  21. package/dist/chunk-WQIEF5N3.js.map +1 -0
  22. package/dist/{chunk-QU3FF5WI.js → chunk-ZFBDVERP.js} +4 -8
  23. package/dist/chunk-ZFBDVERP.js.map +1 -0
  24. package/dist/components/index.d.ts +171 -2
  25. package/dist/components/index.js +686 -11
  26. package/dist/components/index.js.map +1 -1
  27. package/dist/feedback/index.d.ts +20 -1
  28. package/dist/feedback/index.js +121 -4
  29. package/dist/feedback/index.js.map +1 -1
  30. package/dist/forms/index.d.ts +23 -15
  31. package/dist/forms/index.js +71 -47
  32. package/dist/forms/index.js.map +1 -1
  33. package/dist/primitives/index.d.ts +1 -1
  34. package/dist/primitives/index.js +9 -50
  35. package/dist/primitives/index.js.map +1 -1
  36. package/package.json +1 -1
  37. package/dist/chunk-7UJ4QEUW.js +0 -37
  38. package/dist/chunk-7UJ4QEUW.js.map +0 -1
  39. package/dist/chunk-C4JI3JNA.js.map +0 -1
  40. package/dist/chunk-GJTQLZ4O.js.map +0 -1
  41. package/dist/chunk-PZCL4M6I.js.map +0 -1
  42. package/dist/chunk-QU3FF5WI.js.map +0 -1
  43. package/dist/chunk-RJPEVNMJ.js +0 -23
  44. package/dist/chunk-RJPEVNMJ.js.map +0 -1
@@ -1,14 +1,99 @@
1
- import { HStack, Code, Box as Box$1, VStack, Text as Text$1, Link, Skeleton } from '../chunk-7UJ4QEUW.js';
2
- import { IconButton, formatRelativeDateTime, Button, StatusBadge } from '../chunk-GJTQLZ4O.js';
1
+ import { HStack as HStack$1, Code, Box as Box$1, VStack, Text as Text$1, Link, Skeleton, Checkbox as Checkbox$1 } from '../chunk-SJIYWHIV.js';
2
+ import { formatRelativeDateTime, StatusBadge } from '../chunk-KVPN6T6J.js';
3
3
  import { Tooltip, MenuRoot, MenuTrigger, MenuContent, MenuItem } from '../chunk-NJFF6S77.js';
4
- import { Switch } from '../chunk-RJPEVNMJ.js';
5
- import { createContext, Timeline, TreeView, Card as Card$1, Heading, Box, Flex, Grid, GridItem, Text, Menu, Portal, HStack as HStack$1, Checkbox, Table, Drawer, Spacer, ButtonGroup, Collapsible, Dialog, Separator, useSlotRecipe, chakra } from '@chakra-ui/react';
4
+ import { Popover, PopoverTrigger, PopoverContent, PopoverBody, Switch } from '../chunk-WQIEF5N3.js';
5
+ import { text_input_default } from '../chunk-OU6H3KU4.js';
6
+ import { Button, IconButton } from '../chunk-SJ6YXNZW.js';
7
+ import { createContext, Timeline, TreeView, Box, Flex, Collapsible, HStack, Text, Card as Card$1, Heading, Grid, GridItem, Menu, Portal, Checkbox, Table, Drawer, Spacer, ButtonGroup, Stack, Dialog, Separator, useSlotRecipe, chakra } from '@chakra-ui/react';
8
+ export { createTreeCollection } from '@chakra-ui/react';
9
+ import { X, Ellipsis, Plus, ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown, ChevronDown, Check, Upload } from 'lucide-react';
6
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
- import React2, { createContext as createContext$1, Children, useMemo, useCallback, useContext } from 'react';
8
- import { Ellipsis, ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown, X, ChevronDown, Check } from 'lucide-react';
11
+ import React2, { createContext as createContext$1, Children, useState, useMemo, useRef, useEffect, useCallback, useContext } from 'react';
9
12
  import dayjs from 'dayjs';
10
13
  import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
11
14
 
15
+ var BulkAction = ({
16
+ label,
17
+ icon,
18
+ onClick,
19
+ colorPalette,
20
+ disabled,
21
+ loading
22
+ }) => /* @__PURE__ */ jsxs(
23
+ Button,
24
+ {
25
+ size: "sm",
26
+ onClick,
27
+ colorPalette,
28
+ disabled,
29
+ loading,
30
+ children: [
31
+ icon,
32
+ label
33
+ ]
34
+ }
35
+ );
36
+ BulkAction.displayName = "BulkActionBar.Action";
37
+ var BulkPopoverAction = ({
38
+ label,
39
+ icon,
40
+ children,
41
+ disabled
42
+ }) => /* @__PURE__ */ jsxs(Popover, { children: [
43
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { size: "sm", disabled, children: [
44
+ icon,
45
+ label
46
+ ] }) }),
47
+ /* @__PURE__ */ jsx(PopoverContent, { children })
48
+ ] });
49
+ BulkPopoverAction.displayName = "BulkActionBar.PopoverAction";
50
+ var BulkActionBar = ({
51
+ selectedCount,
52
+ onClear,
53
+ visible,
54
+ position = "fixed",
55
+ children,
56
+ countLabel
57
+ }) => {
58
+ const isVisible = visible ?? selectedCount > 0;
59
+ const label = countLabel ? countLabel(selectedCount) : `${selectedCount} items selected`;
60
+ return /* @__PURE__ */ jsx(Collapsible.Root, { open: isVisible, children: /* @__PURE__ */ jsx(Collapsible.Content, { children: /* @__PURE__ */ jsxs(
61
+ Flex,
62
+ {
63
+ position,
64
+ bottom: 0,
65
+ insetInline: 0,
66
+ zIndex: "sticky",
67
+ bg: "bg.surface",
68
+ borderTopWidth: "1px",
69
+ borderColor: "border",
70
+ shadow: "lg",
71
+ px: 4,
72
+ py: 3,
73
+ align: "center",
74
+ justify: "space-between",
75
+ children: [
76
+ /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
77
+ /* @__PURE__ */ jsx(Text, { fontWeight: "medium", fontSize: "sm", children: label }),
78
+ /* @__PURE__ */ jsx(
79
+ IconButton,
80
+ {
81
+ "aria-label": "Clear selection",
82
+ size: "sm",
83
+ variant: "ghost",
84
+ onClick: onClear,
85
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
86
+ }
87
+ )
88
+ ] }),
89
+ /* @__PURE__ */ jsx(HStack, { gap: 2, children })
90
+ ]
91
+ }
92
+ ) }) });
93
+ };
94
+ BulkActionBar.displayName = "BulkActionBar";
95
+ BulkActionBar.Action = BulkAction;
96
+ BulkActionBar.PopoverAction = BulkPopoverAction;
12
97
  var Card = ({
13
98
  ref,
14
99
  maxW = "full",
@@ -189,8 +274,121 @@ var CardListItem = ({
189
274
  );
190
275
  };
191
276
  CardListItem.displayName = "CardListItem";
277
+ function ChipPickerInner(props) {
278
+ const {
279
+ assigned,
280
+ available,
281
+ onAdd,
282
+ onRemove,
283
+ getItemId,
284
+ getItemLabel,
285
+ getItemColor,
286
+ addLabel = "Add",
287
+ emptyLabel = "None",
288
+ searchable = false,
289
+ disabled = false
290
+ } = props;
291
+ const [search, setSearch] = useState("");
292
+ const assignedIds = new Set(assigned.map(getItemId));
293
+ const unassigned = available.filter(
294
+ (item) => !assignedIds.has(getItemId(item))
295
+ );
296
+ const filteredUnassigned = searchable && search.trim() ? unassigned.filter(
297
+ (item) => getItemLabel(item).toLowerCase().includes(search.toLowerCase())
298
+ ) : unassigned;
299
+ return /* @__PURE__ */ jsxs(Flex, { wrap: "wrap", gap: 2, align: "center", children: [
300
+ assigned.length === 0 && /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", children: emptyLabel }),
301
+ assigned.map((item) => {
302
+ const id = getItemId(item);
303
+ const label = getItemLabel(item);
304
+ const color = getItemColor?.(item);
305
+ return /* @__PURE__ */ jsxs(
306
+ Flex,
307
+ {
308
+ borderRadius: "full",
309
+ px: 3,
310
+ py: 1,
311
+ fontSize: "sm",
312
+ display: "inline-flex",
313
+ align: "center",
314
+ gap: 1,
315
+ bg: color ? `${color}33` : "bg.muted",
316
+ color: color ?? "fg.default",
317
+ children: [
318
+ /* @__PURE__ */ jsx(Text, { as: "span", lineHeight: "1", children: label }),
319
+ !disabled && /* @__PURE__ */ jsx(
320
+ "button",
321
+ {
322
+ type: "button",
323
+ style: {
324
+ display: "inline-flex",
325
+ alignItems: "center",
326
+ cursor: "pointer",
327
+ lineHeight: 1,
328
+ padding: 0,
329
+ border: "none",
330
+ background: "transparent",
331
+ color: "inherit"
332
+ },
333
+ "aria-label": `Remove ${label}`,
334
+ onClick: () => onRemove(item),
335
+ children: /* @__PURE__ */ jsx(X, { size: 12 })
336
+ }
337
+ )
338
+ ]
339
+ },
340
+ id
341
+ );
342
+ }),
343
+ unassigned.length > 0 && !disabled && /* @__PURE__ */ jsxs(Popover, { children: [
344
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
345
+ IconButton,
346
+ {
347
+ variant: "ghost",
348
+ size: "sm",
349
+ "aria-label": addLabel,
350
+ minWidth: "44px",
351
+ minHeight: "44px",
352
+ children: /* @__PURE__ */ jsx(Plus, { size: 14 })
353
+ }
354
+ ) }),
355
+ /* @__PURE__ */ jsx(PopoverContent, { portalled: true, children: /* @__PURE__ */ jsxs(PopoverBody, { children: [
356
+ searchable && /* @__PURE__ */ jsx(
357
+ text_input_default,
358
+ {
359
+ placeholder: "Search...",
360
+ size: "sm",
361
+ mb: 2,
362
+ value: search,
363
+ onChange: (e) => setSearch(e.target.value)
364
+ }
365
+ ),
366
+ filteredUnassigned.map((item) => /* @__PURE__ */ jsx(
367
+ Box,
368
+ {
369
+ px: 2,
370
+ py: 1.5,
371
+ rounded: "md",
372
+ cursor: "pointer",
373
+ fontSize: "sm",
374
+ _hover: { bg: "bg.subtle" },
375
+ onClick: () => {
376
+ onAdd(item);
377
+ setSearch("");
378
+ },
379
+ children: getItemLabel(item)
380
+ },
381
+ getItemId(item)
382
+ )),
383
+ filteredUnassigned.length === 0 && /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", px: 2, py: 1.5, children: "No results" })
384
+ ] }) })
385
+ ] })
386
+ ] });
387
+ }
388
+ var ChipPicker = ChipPickerInner;
389
+ ChipPicker.displayName = "ChipPicker";
192
390
  var ActionCell = ({ actions }) => {
193
- return /* @__PURE__ */ jsx(HStack, { gap: 1, children: actions.map((action) => /* @__PURE__ */ jsx(Tooltip, { content: action.label, children: action.href ? /* @__PURE__ */ jsx(
391
+ return /* @__PURE__ */ jsx(HStack$1, { gap: 1, children: actions.map((action) => /* @__PURE__ */ jsx(Tooltip, { content: action.label, children: action.href ? /* @__PURE__ */ jsx(
194
392
  IconButton,
195
393
  {
196
394
  "aria-label": action.label,
@@ -254,7 +452,7 @@ var CodeCell = ({
254
452
  CodeCell.displayName = "CodeCell";
255
453
  var ColorSwatchCell = ({ value }) => {
256
454
  if (value == null) return /* @__PURE__ */ jsx("span", { children: emptyCellValue });
257
- return /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
455
+ return /* @__PURE__ */ jsxs(HStack$1, { gap: 2, children: [
258
456
  /* @__PURE__ */ jsx(
259
457
  Box$1,
260
458
  {
@@ -403,7 +601,7 @@ var Pagination = (props) => {
403
601
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
404
602
  const currentPage = Math.min(Math.max(1, page), totalPages);
405
603
  const pages = getVisiblePages(currentPage, totalPages, maxVisiblePages);
406
- return /* @__PURE__ */ jsxs(HStack$1, { gap: 1, children: [
604
+ return /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
407
605
  /* @__PURE__ */ jsx(
408
606
  IconButton,
409
607
  {
@@ -733,7 +931,7 @@ var FactBox = (props) => {
733
931
  alignItems: { md: "center" },
734
932
  justifyContent: { md: "space-between" },
735
933
  children: [
736
- /* @__PURE__ */ jsx(Box, { minW: 0, flex: "1 1 0%", children: /* @__PURE__ */ jsxs(HStack$1, { children: [
934
+ /* @__PURE__ */ jsx(Box, { minW: 0, flex: "1 1 0%", children: /* @__PURE__ */ jsxs(HStack, { children: [
737
935
  /* @__PURE__ */ jsx(
738
936
  IconButton,
739
937
  {
@@ -794,6 +992,199 @@ var FactBox = (props) => {
794
992
  ] });
795
993
  };
796
994
  FactBox.displayName = "FactBox";
995
+ function InlineCreatableListInner(props) {
996
+ const {
997
+ items,
998
+ activeIds = [],
999
+ onToggle,
1000
+ onCreate,
1001
+ getItemId,
1002
+ getItemLabel,
1003
+ getItemColor,
1004
+ variant = "wrap",
1005
+ createPlaceholder = "New item...",
1006
+ createLabel = "New item",
1007
+ createIcon = /* @__PURE__ */ jsx(Plus, { size: 14 }),
1008
+ emptyText = "No items",
1009
+ disabled = false
1010
+ } = props;
1011
+ const [isCreating, setIsCreating] = useState(false);
1012
+ const [isSubmitting, setIsSubmitting] = useState(false);
1013
+ const inputRef = useRef(null);
1014
+ useEffect(() => {
1015
+ if (isCreating) {
1016
+ inputRef.current?.focus();
1017
+ }
1018
+ }, [isCreating]);
1019
+ const activeIdSet = new Set(activeIds);
1020
+ const handleSubmit = async (value) => {
1021
+ const trimmed = value.trim();
1022
+ if (!trimmed) {
1023
+ setIsCreating(false);
1024
+ return;
1025
+ }
1026
+ setIsSubmitting(true);
1027
+ try {
1028
+ await onCreate?.(trimmed);
1029
+ setIsCreating(false);
1030
+ } catch {
1031
+ } finally {
1032
+ setIsSubmitting(false);
1033
+ }
1034
+ };
1035
+ const handleKeyDown = (e) => {
1036
+ if (e.key === "Enter") {
1037
+ e.preventDefault();
1038
+ handleSubmit(e.target.value);
1039
+ } else if (e.key === "Escape") {
1040
+ setIsCreating(false);
1041
+ }
1042
+ };
1043
+ const handleBlur = (e) => {
1044
+ const value = e.target.value.trim();
1045
+ if (value) {
1046
+ handleSubmit(value);
1047
+ } else {
1048
+ setIsCreating(false);
1049
+ }
1050
+ };
1051
+ const wrapItemBaseStyle = {
1052
+ borderRadius: "6px",
1053
+ paddingInline: "12px",
1054
+ paddingBlock: "4px",
1055
+ fontSize: "0.875rem",
1056
+ cursor: "pointer",
1057
+ transition: "all 0.15s",
1058
+ border: "none",
1059
+ lineHeight: 1.5
1060
+ };
1061
+ const listItemBaseStyle = {
1062
+ paddingInline: "8px",
1063
+ paddingBlock: "6px",
1064
+ borderRadius: "6px",
1065
+ cursor: "pointer",
1066
+ fontSize: "0.875rem",
1067
+ transition: "all 0.15s",
1068
+ border: "none",
1069
+ textAlign: "start",
1070
+ width: "100%",
1071
+ display: "block"
1072
+ };
1073
+ const disabledStyle = disabled ? { opacity: 0.5, cursor: "not-allowed" } : {};
1074
+ const renderWrapItems = () => items.map((item) => {
1075
+ const id = getItemId(item);
1076
+ const label = getItemLabel(item);
1077
+ const color = getItemColor?.(item);
1078
+ const isActive = activeIdSet.has(id);
1079
+ let bgStyle;
1080
+ let colorStyle;
1081
+ if (isActive) {
1082
+ bgStyle = color ? `${color}33` : "var(--chakra-colors-primary-subtle)";
1083
+ colorStyle = color ?? "var(--chakra-colors-primary-fg)";
1084
+ } else {
1085
+ bgStyle = "var(--chakra-colors-bg-muted)";
1086
+ colorStyle = "var(--chakra-colors-fg-default)";
1087
+ }
1088
+ return /* @__PURE__ */ jsx(
1089
+ Box,
1090
+ {
1091
+ as: "button",
1092
+ rounded: "md",
1093
+ px: 3,
1094
+ py: 1,
1095
+ fontSize: "sm",
1096
+ cursor: disabled ? "not-allowed" : "pointer",
1097
+ transition: "all 0.15s",
1098
+ opacity: disabled ? 0.5 : 1,
1099
+ style: {
1100
+ ...wrapItemBaseStyle,
1101
+ ...disabledStyle,
1102
+ background: bgStyle,
1103
+ color: colorStyle
1104
+ },
1105
+ onClick: !disabled ? () => onToggle?.(id) : void 0,
1106
+ children: label
1107
+ },
1108
+ id
1109
+ );
1110
+ });
1111
+ const renderListItems = () => items.map((item) => {
1112
+ const id = getItemId(item);
1113
+ const label = getItemLabel(item);
1114
+ const isActive = activeIdSet.has(id);
1115
+ const bgStyle = isActive ? "var(--chakra-colors-primary-subtle)" : "transparent";
1116
+ const colorStyle = isActive ? "var(--chakra-colors-primary-fg)" : "var(--chakra-colors-fg-default)";
1117
+ return /* @__PURE__ */ jsx(
1118
+ Box,
1119
+ {
1120
+ as: "button",
1121
+ px: 2,
1122
+ py: 1.5,
1123
+ rounded: "md",
1124
+ cursor: disabled ? "not-allowed" : "pointer",
1125
+ fontSize: "sm",
1126
+ opacity: disabled ? 0.5 : 1,
1127
+ _hover: { bg: isActive ? "primary.subtle" : "bg.subtle" },
1128
+ style: {
1129
+ ...listItemBaseStyle,
1130
+ ...disabledStyle,
1131
+ background: bgStyle,
1132
+ color: colorStyle
1133
+ },
1134
+ onClick: !disabled ? () => onToggle?.(id) : void 0,
1135
+ children: label
1136
+ },
1137
+ id
1138
+ );
1139
+ });
1140
+ const showEmpty = items.length === 0 && !isCreating;
1141
+ const showCreateLink = !!onCreate && !isCreating && !disabled;
1142
+ return /* @__PURE__ */ jsxs(Box, { children: [
1143
+ variant === "wrap" ? /* @__PURE__ */ jsxs(Flex, { wrap: "wrap", gap: 2, children: [
1144
+ showEmpty && /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", children: emptyText }),
1145
+ renderWrapItems()
1146
+ ] }) : /* @__PURE__ */ jsxs(Stack, { gap: 0, children: [
1147
+ showEmpty && /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", px: 2, py: 1.5, children: emptyText }),
1148
+ renderListItems()
1149
+ ] }),
1150
+ showCreateLink && /* @__PURE__ */ jsxs(
1151
+ "button",
1152
+ {
1153
+ type: "button",
1154
+ style: {
1155
+ display: "inline-flex",
1156
+ alignItems: "center",
1157
+ gap: "4px",
1158
+ cursor: "pointer",
1159
+ fontSize: "0.875rem",
1160
+ color: "var(--chakra-colors-fg-muted)",
1161
+ marginBlockStart: items.length > 0 ? "8px" : "4px",
1162
+ border: "none",
1163
+ background: "transparent",
1164
+ padding: 0
1165
+ },
1166
+ onClick: () => setIsCreating(true),
1167
+ children: [
1168
+ createIcon,
1169
+ /* @__PURE__ */ jsx("span", { children: createLabel })
1170
+ ]
1171
+ }
1172
+ ),
1173
+ isCreating && /* @__PURE__ */ jsx(Box, { mt: items.length > 0 ? 2 : 1, children: /* @__PURE__ */ jsx(
1174
+ text_input_default,
1175
+ {
1176
+ ref: inputRef,
1177
+ size: "sm",
1178
+ placeholder: createPlaceholder,
1179
+ disabled: isSubmitting,
1180
+ onKeyDown: handleKeyDown,
1181
+ onBlur: handleBlur
1182
+ }
1183
+ ) })
1184
+ ] });
1185
+ }
1186
+ var InlineCreatableList = InlineCreatableListInner;
1187
+ InlineCreatableList.displayName = "InlineCreatableList";
797
1188
  var LabeledSwitch = ({
798
1189
  ref,
799
1190
  ...props
@@ -866,6 +1257,147 @@ var Modal = ({
866
1257
  );
867
1258
  };
868
1259
  Modal.displayName = "Modal";
1260
+ var SelectableCardThumbnail = ({
1261
+ height = "160px",
1262
+ children
1263
+ }) => /* @__PURE__ */ jsx(
1264
+ Box,
1265
+ {
1266
+ h: height,
1267
+ overflow: "hidden",
1268
+ bg: "bg.subtle",
1269
+ display: "flex",
1270
+ alignItems: "center",
1271
+ justifyContent: "center",
1272
+ children
1273
+ }
1274
+ );
1275
+ SelectableCardThumbnail.displayName = "SelectableCard.Thumbnail";
1276
+ var SelectableCardBody = ({ children }) => /* @__PURE__ */ jsx(Box, { p: 3, children });
1277
+ SelectableCardBody.displayName = "SelectableCard.Body";
1278
+ var SelectableCardFooter = ({ children }) => /* @__PURE__ */ jsx(
1279
+ Flex,
1280
+ {
1281
+ p: 3,
1282
+ borderTopWidth: "1px",
1283
+ borderColor: "border",
1284
+ justify: "space-between",
1285
+ align: "center",
1286
+ children
1287
+ }
1288
+ );
1289
+ SelectableCardFooter.displayName = "SelectableCard.Footer";
1290
+ var SelectableCard = ({
1291
+ selected,
1292
+ selectionVisible,
1293
+ onSelect,
1294
+ onClick,
1295
+ disabled,
1296
+ children
1297
+ }) => {
1298
+ return /* @__PURE__ */ jsxs(Box, { role: "group", position: "relative", children: [
1299
+ /* @__PURE__ */ jsx(
1300
+ Box,
1301
+ {
1302
+ rounded: "lg",
1303
+ overflow: "hidden",
1304
+ borderWidth: "1px",
1305
+ borderColor: "border",
1306
+ bg: "bg.surface",
1307
+ cursor: onClick ? "pointer" : void 0,
1308
+ onClick: disabled ? void 0 : onClick,
1309
+ outline: selected ? "2px solid" : void 0,
1310
+ outlineColor: selected ? "accent" : void 0,
1311
+ outlineOffset: selected ? "-2px" : void 0,
1312
+ opacity: disabled ? 0.5 : void 0,
1313
+ transition: "all 0.2s",
1314
+ _hover: { shadow: "md" },
1315
+ children
1316
+ }
1317
+ ),
1318
+ onSelect && /* @__PURE__ */ jsx(
1319
+ Box,
1320
+ {
1321
+ position: "absolute",
1322
+ top: 2,
1323
+ insetInlineStart: 2,
1324
+ zIndex: 1,
1325
+ opacity: selected || selectionVisible ? 1 : 0,
1326
+ _groupHover: { opacity: 1 },
1327
+ transition: "opacity 0.15s",
1328
+ children: /* @__PURE__ */ jsx(
1329
+ Checkbox$1,
1330
+ {
1331
+ checked: selected,
1332
+ onCheckedChange: () => onSelect(),
1333
+ onClick: (e) => e.stopPropagation(),
1334
+ size: "sm"
1335
+ }
1336
+ )
1337
+ }
1338
+ )
1339
+ ] });
1340
+ };
1341
+ SelectableCard.displayName = "SelectableCard";
1342
+ SelectableCard.Thumbnail = SelectableCardThumbnail;
1343
+ SelectableCard.Body = SelectableCardBody;
1344
+ SelectableCard.Footer = SelectableCardFooter;
1345
+ var SidebarSection = ({
1346
+ label,
1347
+ children,
1348
+ actionIcon,
1349
+ onAction,
1350
+ editContent,
1351
+ emptyText,
1352
+ defaultEditing
1353
+ }) => {
1354
+ const [isEditing, setEditing] = useState(defaultEditing ?? false);
1355
+ const hasActionButton = Boolean(actionIcon && (onAction || editContent));
1356
+ const handleActionClick = () => {
1357
+ if (onAction) {
1358
+ onAction();
1359
+ } else if (editContent) {
1360
+ setEditing((prev) => !prev);
1361
+ }
1362
+ };
1363
+ const resolvedIcon = isEditing && !onAction && editContent ? /* @__PURE__ */ jsx(X, { size: 14 }) : actionIcon;
1364
+ let content;
1365
+ if (typeof children === "function") {
1366
+ content = children({ isEditing, setEditing });
1367
+ } else if (isEditing && editContent) {
1368
+ content = editContent;
1369
+ } else {
1370
+ content = children;
1371
+ }
1372
+ const isEmpty = content === null || content === void 0 || content === "" || content === false;
1373
+ return /* @__PURE__ */ jsxs(Box, { py: 3, children: [
1374
+ /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", children: [
1375
+ /* @__PURE__ */ jsx(
1376
+ Text,
1377
+ {
1378
+ fontSize: "xs",
1379
+ fontWeight: "semibold",
1380
+ color: "fg.muted",
1381
+ textTransform: "uppercase",
1382
+ letterSpacing: "wide",
1383
+ children: label
1384
+ }
1385
+ ),
1386
+ hasActionButton && /* @__PURE__ */ jsx(
1387
+ IconButton,
1388
+ {
1389
+ "aria-label": isEditing && !onAction ? "Cancel edit" : label,
1390
+ size: "xs",
1391
+ variant: "ghost",
1392
+ onClick: handleActionClick,
1393
+ children: resolvedIcon
1394
+ }
1395
+ )
1396
+ ] }),
1397
+ /* @__PURE__ */ jsx(Box, { py: 2, children: isEmpty && emptyText ? /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.subtle", children: emptyText }) : content })
1398
+ ] });
1399
+ };
1400
+ SidebarSection.displayName = "SidebarSection";
869
1401
  var [StepperProvider, useStepperContext] = createContext({
870
1402
  name: "StepperContext",
871
1403
  errorMessage: "useStepperContext: `context` is undefined. Seems you forgot to wrap stepper components in `<Stepper />`"
@@ -1199,6 +1731,149 @@ var TreeViewNode = TreeView.Node;
1199
1731
  TreeViewNode.displayName = "TreeViewNode";
1200
1732
  var TreeViewLabel = TreeView.Label;
1201
1733
  TreeViewLabel.displayName = "TreeViewLabel";
1734
+ function matchesAccept(file, accept) {
1735
+ const tokens = accept.split(",").map((t) => t.trim());
1736
+ for (const token of tokens) {
1737
+ if (token.startsWith(".")) {
1738
+ if (file.name.toLowerCase().endsWith(token.toLowerCase())) {
1739
+ return true;
1740
+ }
1741
+ } else if (token.includes("/*")) {
1742
+ const prefix = token.slice(0, token.indexOf("/*"));
1743
+ if (file.type.startsWith(prefix)) {
1744
+ return true;
1745
+ }
1746
+ } else {
1747
+ if (file.type === token) {
1748
+ return true;
1749
+ }
1750
+ }
1751
+ }
1752
+ return false;
1753
+ }
1754
+ var UploadDropZone = ({
1755
+ onFiles,
1756
+ onError,
1757
+ accept,
1758
+ multiple = true,
1759
+ compact = false,
1760
+ disabled = false,
1761
+ children,
1762
+ maxSize,
1763
+ dragActiveText = "Release to upload",
1764
+ dropHintText = "Drag and drop files here",
1765
+ buttonLabel = "Browse Files"
1766
+ }) => {
1767
+ const [isDragActive, setIsDragActive] = useState(false);
1768
+ const inputRef = useRef(null);
1769
+ const processFiles = (fileList) => {
1770
+ const files = Array.from(fileList);
1771
+ const accepted = [];
1772
+ for (const file of files) {
1773
+ if (maxSize !== void 0 && file.size > maxSize) {
1774
+ onError?.({ file, reason: "size" });
1775
+ continue;
1776
+ }
1777
+ if (accept && !matchesAccept(file, accept)) {
1778
+ onError?.({ file, reason: "type" });
1779
+ continue;
1780
+ }
1781
+ accepted.push(file);
1782
+ }
1783
+ if (accepted.length > 0) {
1784
+ onFiles(multiple ? accepted : [accepted[0]]);
1785
+ }
1786
+ };
1787
+ const handleDragOver = (e) => {
1788
+ e.preventDefault();
1789
+ if (!disabled) {
1790
+ setIsDragActive(true);
1791
+ }
1792
+ };
1793
+ const handleDragLeave = () => {
1794
+ setIsDragActive(false);
1795
+ };
1796
+ const handleDrop = (e) => {
1797
+ e.preventDefault();
1798
+ setIsDragActive(false);
1799
+ if (disabled) return;
1800
+ if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
1801
+ processFiles(e.dataTransfer.files);
1802
+ }
1803
+ };
1804
+ const handleInputChange = (e) => {
1805
+ if (e.target.files && e.target.files.length > 0) {
1806
+ processFiles(e.target.files);
1807
+ }
1808
+ e.target.value = "";
1809
+ };
1810
+ const handleBrowseClick = () => {
1811
+ if (!disabled) {
1812
+ inputRef.current?.click();
1813
+ }
1814
+ };
1815
+ const defaultContent = isDragActive ? /* @__PURE__ */ jsx(Text, { color: "fg.muted", fontSize: "sm", children: dragActiveText }) : compact ? /* @__PURE__ */ jsxs(HStack, { gap: 3, align: "center", children: [
1816
+ /* @__PURE__ */ jsx(Upload, { size: 24 }),
1817
+ /* @__PURE__ */ jsx(Text, { color: "fg.muted", fontSize: "sm", children: dropHintText }),
1818
+ /* @__PURE__ */ jsx(
1819
+ Button,
1820
+ {
1821
+ variant: "outline",
1822
+ size: "sm",
1823
+ onClick: handleBrowseClick,
1824
+ disabled,
1825
+ children: buttonLabel
1826
+ }
1827
+ )
1828
+ ] }) : /* @__PURE__ */ jsxs(Stack, { align: "center", gap: 3, children: [
1829
+ /* @__PURE__ */ jsx(Upload, { size: 48 }),
1830
+ /* @__PURE__ */ jsx(Text, { color: "fg.muted", fontSize: "sm", children: dropHintText }),
1831
+ /* @__PURE__ */ jsx(
1832
+ Button,
1833
+ {
1834
+ variant: "outline",
1835
+ size: "sm",
1836
+ onClick: handleBrowseClick,
1837
+ disabled,
1838
+ children: buttonLabel
1839
+ }
1840
+ )
1841
+ ] });
1842
+ return /* @__PURE__ */ jsxs(
1843
+ Box,
1844
+ {
1845
+ borderStyle: "dashed",
1846
+ borderWidth: "2px",
1847
+ borderColor: isDragActive ? "accent" : "border",
1848
+ bg: isDragActive ? "bg.accent-subtle" : "bg.subtle",
1849
+ rounded: "lg",
1850
+ textAlign: "center",
1851
+ transition: "all 0.2s",
1852
+ p: compact ? 3 : 6,
1853
+ opacity: disabled ? 0.5 : 1,
1854
+ cursor: disabled ? "not-allowed" : "default",
1855
+ onDragOver: handleDragOver,
1856
+ onDragLeave: handleDragLeave,
1857
+ onDrop: handleDrop,
1858
+ children: [
1859
+ /* @__PURE__ */ jsx(
1860
+ "input",
1861
+ {
1862
+ ref: inputRef,
1863
+ type: "file",
1864
+ accept,
1865
+ multiple,
1866
+ style: { display: "none" },
1867
+ onChange: handleInputChange,
1868
+ disabled
1869
+ }
1870
+ ),
1871
+ children !== void 0 ? children : defaultContent
1872
+ ]
1873
+ }
1874
+ );
1875
+ };
1876
+ UploadDropZone.displayName = "UploadDropZone";
1202
1877
  var Widget = ({
1203
1878
  heading,
1204
1879
  subHeading,
@@ -1218,6 +1893,6 @@ var Widget = ({
1218
1893
  };
1219
1894
  Widget.displayName = "Widget";
1220
1895
 
1221
- export { ActionCell, BooleanCell, Card, CardList, CardListData, CardListItem, CodeCell, ColorSwatchCell, CountCell, DataTable, DateCell, DrawerRoot, FactBox, LabeledSwitch, Modal, NumberCell, Pagination, SlugCell, StatusBadgeCell, Stepper, StepperCompleted, StepperContainer, StepperContent, StepperIcon, StepperProvider, StepperSeparator, StepperStep, StepperStepTitle, StepperSteps, SwitchCell, CardList as Table, CardListData as TableData, CardListItem as TableItem, TimelineConnector, TimelineContent, TimelineDescription, TimelineIndicator, TimelineItem, TimelineRoot, TimelineSeparator, TimelineTitle, TreeViewBranch, TreeViewBranchContent, TreeViewBranchControl, TreeViewBranchIndicator, TreeViewBranchText, TreeViewBranchTrigger, TreeViewItem, TreeViewItemIndicator, TreeViewItemText, TreeViewLabel, TreeViewNode, TreeViewRoot, TreeViewTree, TruncatedTextCell, UrlCell, Widget, emptyCellValue, pluralize, truncateText, useStep, useStepper, useStepperContext, useStepperNextButton, useStepperPrevButton };
1896
+ export { ActionCell, BooleanCell, BulkActionBar, Card, CardList, CardListData, CardListItem, ChipPicker, CodeCell, ColorSwatchCell, CountCell, DataTable, DateCell, DrawerRoot, FactBox, InlineCreatableList, LabeledSwitch, Modal, NumberCell, Pagination, SelectableCard, SidebarSection, SlugCell, StatusBadgeCell, Stepper, StepperCompleted, StepperContainer, StepperContent, StepperIcon, StepperProvider, StepperSeparator, StepperStep, StepperStepTitle, StepperSteps, SwitchCell, CardList as Table, CardListData as TableData, CardListItem as TableItem, TimelineConnector, TimelineContent, TimelineDescription, TimelineIndicator, TimelineItem, TimelineRoot, TimelineSeparator, TimelineTitle, TreeViewBranch, TreeViewBranchContent, TreeViewBranchControl, TreeViewBranchIndicator, TreeViewBranchText, TreeViewBranchTrigger, TreeViewItem, TreeViewItemIndicator, TreeViewItemText, TreeViewLabel, TreeViewNode, TreeViewRoot, TreeViewTree, TruncatedTextCell, UploadDropZone, UrlCell, Widget, emptyCellValue, pluralize, truncateText, useStep, useStepper, useStepperContext, useStepperNextButton, useStepperPrevButton };
1222
1897
  //# sourceMappingURL=index.js.map
1223
1898
  //# sourceMappingURL=index.js.map