@knkcs/anker 0.0.3 → 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 (43) 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 -3
  25. package/dist/components/index.js +685 -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.js +8 -49
  34. package/dist/primitives/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/dist/chunk-7UJ4QEUW.js +0 -37
  37. package/dist/chunk-7UJ4QEUW.js.map +0 -1
  38. package/dist/chunk-C4JI3JNA.js.map +0 -1
  39. package/dist/chunk-GJTQLZ4O.js.map +0 -1
  40. package/dist/chunk-PZCL4M6I.js.map +0 -1
  41. package/dist/chunk-QU3FF5WI.js.map +0 -1
  42. package/dist/chunk-RJPEVNMJ.js +0 -23
  43. package/dist/chunk-RJPEVNMJ.js.map +0 -1
@@ -1,15 +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';
6
8
  export { createTreeCollection } from '@chakra-ui/react';
9
+ import { X, Ellipsis, Plus, ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown, ChevronDown, Check, Upload } from 'lucide-react';
7
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
- import React2, { createContext as createContext$1, Children, useMemo, useCallback, useContext } from 'react';
9
- 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';
10
12
  import dayjs from 'dayjs';
11
13
  import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
12
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;
13
97
  var Card = ({
14
98
  ref,
15
99
  maxW = "full",
@@ -190,8 +274,121 @@ var CardListItem = ({
190
274
  );
191
275
  };
192
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";
193
390
  var ActionCell = ({ actions }) => {
194
- 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(
195
392
  IconButton,
196
393
  {
197
394
  "aria-label": action.label,
@@ -255,7 +452,7 @@ var CodeCell = ({
255
452
  CodeCell.displayName = "CodeCell";
256
453
  var ColorSwatchCell = ({ value }) => {
257
454
  if (value == null) return /* @__PURE__ */ jsx("span", { children: emptyCellValue });
258
- return /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
455
+ return /* @__PURE__ */ jsxs(HStack$1, { gap: 2, children: [
259
456
  /* @__PURE__ */ jsx(
260
457
  Box$1,
261
458
  {
@@ -404,7 +601,7 @@ var Pagination = (props) => {
404
601
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
405
602
  const currentPage = Math.min(Math.max(1, page), totalPages);
406
603
  const pages = getVisiblePages(currentPage, totalPages, maxVisiblePages);
407
- return /* @__PURE__ */ jsxs(HStack$1, { gap: 1, children: [
604
+ return /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
408
605
  /* @__PURE__ */ jsx(
409
606
  IconButton,
410
607
  {
@@ -734,7 +931,7 @@ var FactBox = (props) => {
734
931
  alignItems: { md: "center" },
735
932
  justifyContent: { md: "space-between" },
736
933
  children: [
737
- /* @__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: [
738
935
  /* @__PURE__ */ jsx(
739
936
  IconButton,
740
937
  {
@@ -795,6 +992,199 @@ var FactBox = (props) => {
795
992
  ] });
796
993
  };
797
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";
798
1188
  var LabeledSwitch = ({
799
1189
  ref,
800
1190
  ...props
@@ -867,6 +1257,147 @@ var Modal = ({
867
1257
  );
868
1258
  };
869
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";
870
1401
  var [StepperProvider, useStepperContext] = createContext({
871
1402
  name: "StepperContext",
872
1403
  errorMessage: "useStepperContext: `context` is undefined. Seems you forgot to wrap stepper components in `<Stepper />`"
@@ -1200,6 +1731,149 @@ var TreeViewNode = TreeView.Node;
1200
1731
  TreeViewNode.displayName = "TreeViewNode";
1201
1732
  var TreeViewLabel = TreeView.Label;
1202
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";
1203
1877
  var Widget = ({
1204
1878
  heading,
1205
1879
  subHeading,
@@ -1219,6 +1893,6 @@ var Widget = ({
1219
1893
  };
1220
1894
  Widget.displayName = "Widget";
1221
1895
 
1222
- 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 };
1223
1897
  //# sourceMappingURL=index.js.map
1224
1898
  //# sourceMappingURL=index.js.map