@knkcs/anker 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/atoms/index.d.ts +16 -3
  2. package/dist/atoms/index.js +112 -18
  3. package/dist/atoms/index.js.map +1 -1
  4. package/dist/{chunk-NJFF6S77.js → chunk-2QFOWHTU.js} +4 -3
  5. package/dist/chunk-2QFOWHTU.js.map +1 -0
  6. package/dist/chunk-5YDCDC4B.js +12 -0
  7. package/dist/chunk-5YDCDC4B.js.map +1 -0
  8. package/dist/{chunk-YSFUGIQM.js → chunk-7WPKYUHP.js} +232 -116
  9. package/dist/chunk-7WPKYUHP.js.map +1 -0
  10. package/dist/{chunk-PZCL4M6I.js → chunk-E7KRPPCQ.js} +5 -18
  11. package/dist/chunk-E7KRPPCQ.js.map +1 -0
  12. package/dist/chunk-G4QMIXLC.js +3 -0
  13. package/dist/chunk-G4QMIXLC.js.map +1 -0
  14. package/dist/{chunk-C4JI3JNA.js → chunk-M5WNB4K6.js} +13 -34
  15. package/dist/chunk-M5WNB4K6.js.map +1 -0
  16. package/dist/chunk-NFZMG6ZL.js +3 -0
  17. package/dist/chunk-NFZMG6ZL.js.map +1 -0
  18. package/dist/{chunk-GJTQLZ4O.js → chunk-NQN6LXYU.js} +5 -28
  19. package/dist/chunk-NQN6LXYU.js.map +1 -0
  20. package/dist/chunk-OU6H3KU4.js +21 -0
  21. package/dist/chunk-OU6H3KU4.js.map +1 -0
  22. package/dist/chunk-SJ6YXNZW.js +30 -0
  23. package/dist/chunk-SJ6YXNZW.js.map +1 -0
  24. package/dist/chunk-TXGJ7BNX.js +51 -0
  25. package/dist/chunk-TXGJ7BNX.js.map +1 -0
  26. package/dist/chunk-WEP2AIQ5.js +37 -0
  27. package/dist/chunk-WEP2AIQ5.js.map +1 -0
  28. package/dist/chunk-WQIEF5N3.js +52 -0
  29. package/dist/chunk-WQIEF5N3.js.map +1 -0
  30. package/dist/{chunk-QU3FF5WI.js → chunk-ZFBDVERP.js} +4 -8
  31. package/dist/chunk-ZFBDVERP.js.map +1 -0
  32. package/dist/components/index.d.ts +207 -3
  33. package/dist/components/index.js +764 -15
  34. package/dist/components/index.js.map +1 -1
  35. package/dist/feedback/index.d.ts +20 -1
  36. package/dist/feedback/index.js +121 -3
  37. package/dist/feedback/index.js.map +1 -1
  38. package/dist/forms/index.d.ts +23 -15
  39. package/dist/forms/index.js +74 -48
  40. package/dist/forms/index.js.map +1 -1
  41. package/dist/primitives/index.js +13 -52
  42. package/dist/primitives/index.js.map +1 -1
  43. package/dist/theme/index.d.ts +162 -1
  44. package/dist/theme/index.js +1 -1
  45. package/package.json +4 -2
  46. package/dist/chunk-7UJ4QEUW.js +0 -37
  47. package/dist/chunk-7UJ4QEUW.js.map +0 -1
  48. package/dist/chunk-C4JI3JNA.js.map +0 -1
  49. package/dist/chunk-GJTQLZ4O.js.map +0 -1
  50. package/dist/chunk-NJFF6S77.js.map +0 -1
  51. package/dist/chunk-PZCL4M6I.js.map +0 -1
  52. package/dist/chunk-QU3FF5WI.js.map +0 -1
  53. package/dist/chunk-RJPEVNMJ.js +0 -23
  54. package/dist/chunk-RJPEVNMJ.js.map +0 -1
  55. package/dist/chunk-YSFUGIQM.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { ButtonProps } from '@chakra-ui/react';
2
2
  import React__default from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
 
4
5
  interface ConfirmOptions {
5
6
  /** Dialog title text. */
@@ -24,4 +25,22 @@ interface ConfirmModalProviderProps {
24
25
  declare const ConfirmModalProvider: React__default.FC<ConfirmModalProviderProps>;
25
26
  declare const useConfirmModal: () => ConfirmModalContextType;
26
27
 
27
- export { ConfirmModalProvider, type ConfirmOptions, useConfirmModal };
28
+ interface UploadFileStatus {
29
+ id: string;
30
+ filename: string;
31
+ status: "pending" | "uploading" | "processing" | "done" | "error";
32
+ progress?: number;
33
+ error?: string;
34
+ }
35
+ interface UploadToastStackProps {
36
+ files: UploadFileStatus[];
37
+ onDismiss: () => void;
38
+ autoDismissMs?: number;
39
+ defaultExpanded?: boolean;
40
+ }
41
+ declare const UploadToastStack: {
42
+ ({ files, onDismiss, autoDismissMs, defaultExpanded, }: UploadToastStackProps): react_jsx_runtime.JSX.Element | null;
43
+ displayName: string;
44
+ };
45
+
46
+ export { ConfirmModalProvider, type ConfirmOptions, type UploadFileStatus, UploadToastStack, type UploadToastStackProps, useConfirmModal };
@@ -1,8 +1,12 @@
1
+ import { Progress } from '../chunk-WEP2AIQ5.js';
2
+ import { Spinner } from '../chunk-5YDCDC4B.js';
3
+ import { IconButton } from '../chunk-SJ6YXNZW.js';
4
+ import { Box, Flex, Text, Stack, HStack } from '../chunk-G4QMIXLC.js';
1
5
  import { Dialog, Portal, ButtonGroup, Button } from '@chakra-ui/react';
2
- import { createContext, useState, useRef, useCallback, useContext } from 'react';
6
+ import { createContext, useState, useRef, useCallback, useContext, useEffect } from 'react';
3
7
  import { jsxs, jsx } from 'react/jsx-runtime';
8
+ import { ChevronDown, ChevronUp, X, AlertCircle, Check, Clock } from 'lucide-react';
4
9
 
5
- // src/feedback/confirm-modal.tsx
6
10
  var ConfirmModalContext = createContext(
7
11
  void 0
8
12
  );
@@ -94,7 +98,121 @@ var ConfirmModalDialog = ({
94
98
  }
95
99
  );
96
100
  };
101
+ var FileStatusIcon = ({ status }) => {
102
+ switch (status) {
103
+ case "pending":
104
+ return /* @__PURE__ */ jsx(Clock, { size: 14, color: "var(--chakra-colors-fg-muted)" });
105
+ case "uploading":
106
+ case "processing":
107
+ return /* @__PURE__ */ jsx(Spinner, { size: "xs" });
108
+ case "done":
109
+ return /* @__PURE__ */ jsx(Check, { size: 14, color: "var(--chakra-colors-green-500)" });
110
+ case "error":
111
+ return /* @__PURE__ */ jsx(AlertCircle, { size: 14, color: "var(--chakra-colors-red-500)" });
112
+ }
113
+ };
114
+ var UploadToastStack = ({
115
+ files,
116
+ onDismiss,
117
+ autoDismissMs = 5e3,
118
+ defaultExpanded = true
119
+ }) => {
120
+ const [expanded, setExpanded] = useState(defaultExpanded);
121
+ const [hovered, setHovered] = useState(false);
122
+ const allComplete = files.every(
123
+ (f) => f.status === "done" || f.status === "error"
124
+ );
125
+ const totalProgress = files.length > 0 ? files.reduce((sum, f) => sum + (f.progress ?? 0), 0) / files.length : 0;
126
+ const doneCount = files.filter((f) => f.status === "done").length;
127
+ const errorCount = files.filter((f) => f.status === "error").length;
128
+ const headerText = allComplete ? `${doneCount} file${doneCount !== 1 ? "s" : ""} uploaded${errorCount > 0 ? `, ${errorCount} failed` : ""}` : `Uploading ${files.length} file${files.length !== 1 ? "s" : ""}...`;
129
+ useEffect(() => {
130
+ if (!allComplete || hovered || autoDismissMs === 0) return;
131
+ const timer = setTimeout(onDismiss, autoDismissMs);
132
+ return () => clearTimeout(timer);
133
+ }, [allComplete, hovered, autoDismissMs, onDismiss]);
134
+ if (files.length === 0) return null;
135
+ return /* @__PURE__ */ jsx(
136
+ Box,
137
+ {
138
+ position: "fixed",
139
+ bottom: 4,
140
+ insetInlineEnd: 4,
141
+ zIndex: "toast",
142
+ onMouseEnter: () => setHovered(true),
143
+ onMouseLeave: () => setHovered(false),
144
+ children: /* @__PURE__ */ jsxs(
145
+ Box,
146
+ {
147
+ bg: "bg.surface",
148
+ shadow: "lg",
149
+ rounded: "lg",
150
+ borderWidth: "1px",
151
+ borderColor: "border",
152
+ w: "320px",
153
+ overflow: "hidden",
154
+ children: [
155
+ /* @__PURE__ */ jsxs(Flex, { align: "center", px: 3, py: 2, gap: 1, children: [
156
+ /* @__PURE__ */ jsx(Text, { fontSize: "sm", fontWeight: "medium", flex: "1", children: headerText }),
157
+ /* @__PURE__ */ jsx(
158
+ IconButton,
159
+ {
160
+ "aria-label": expanded ? "Collapse upload list" : "Expand upload list",
161
+ size: "xs",
162
+ variant: "ghost",
163
+ onClick: () => setExpanded((v) => !v),
164
+ children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(ChevronUp, { size: 14 })
165
+ }
166
+ ),
167
+ /* @__PURE__ */ jsx(
168
+ IconButton,
169
+ {
170
+ "aria-label": "Dismiss upload toast",
171
+ size: "xs",
172
+ variant: "ghost",
173
+ onClick: onDismiss,
174
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
175
+ }
176
+ )
177
+ ] }),
178
+ /* @__PURE__ */ jsx(
179
+ Progress,
180
+ {
181
+ value: totalProgress,
182
+ size: "xs",
183
+ colorPalette: allComplete && errorCount === 0 ? "green" : "primary"
184
+ }
185
+ ),
186
+ expanded && /* @__PURE__ */ jsx(Stack, { gap: 0, maxH: "200px", overflowY: "auto", px: 3, py: 2, children: files.map((file) => /* @__PURE__ */ jsxs(Box, { py: 1, children: [
187
+ /* @__PURE__ */ jsxs(HStack, { gap: 2, align: "center", children: [
188
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(FileStatusIcon, { status: file.status }) }),
189
+ /* @__PURE__ */ jsx(
190
+ Text,
191
+ {
192
+ fontSize: "sm",
193
+ flex: "1",
194
+ overflow: "hidden",
195
+ textOverflow: "ellipsis",
196
+ whiteSpace: "nowrap",
197
+ title: file.filename,
198
+ children: file.filename
199
+ }
200
+ ),
201
+ file.progress !== void 0 && /* @__PURE__ */ jsxs(Text, { fontSize: "xs", color: "fg.muted", flexShrink: 0, children: [
202
+ Math.round(file.progress),
203
+ "%"
204
+ ] })
205
+ ] }),
206
+ file.status === "error" && file.error && /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "fg.error", ps: 5, children: file.error })
207
+ ] }, file.id)) })
208
+ ]
209
+ }
210
+ )
211
+ }
212
+ );
213
+ };
214
+ UploadToastStack.displayName = "UploadToastStack";
97
215
 
98
- export { ConfirmModalProvider, useConfirmModal };
216
+ export { ConfirmModalProvider, UploadToastStack, useConfirmModal };
99
217
  //# sourceMappingURL=index.js.map
100
218
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/feedback/confirm-modal.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tButton,\n\tButtonGroup,\n\ttype ButtonProps,\n\tDialog,\n\tPortal,\n} from \"@chakra-ui/react\";\nimport type React from \"react\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseRef,\n\tuseState,\n} from \"react\";\n\nexport interface ConfirmOptions {\n\t/** Dialog title text. */\n\ttitle: string;\n\t/** Dialog body content. */\n\tmessage: React.ReactNode;\n\t/** Label for the confirm button. @default \"Confirm\" */\n\tconfirmLabel?: string;\n\t/** Label for the cancel button. @default \"Cancel\" */\n\tcancelLabel?: string;\n\t/** Color palette for the confirm button. @default \"red\" */\n\tcolorPalette?: ButtonProps[\"colorPalette\"];\n\t/** Extra actions rendered before the confirm button. */\n\tbeforeConfirmActions?: React.ReactNode;\n}\n\ninterface ConfirmModalContextType {\n\tconfirm: (options: ConfirmOptions) => Promise<boolean>;\n}\n\nconst ConfirmModalContext = createContext<ConfirmModalContextType | undefined>(\n\tundefined,\n);\n\ninterface ConfirmModalProviderProps {\n\tchildren: React.ReactNode;\n}\n\nexport const ConfirmModalProvider: React.FC<ConfirmModalProviderProps> = ({\n\tchildren,\n}) => {\n\tconst [open, setOpen] = useState(false);\n\tconst [options, setOptions] = useState<ConfirmOptions>({\n\t\ttitle: \"\",\n\t\tmessage: \"\",\n\t});\n\tconst resolveRef = useRef<((value: boolean) => void) | null>(null);\n\n\tconst confirm = useCallback((opts: ConfirmOptions): Promise<boolean> => {\n\t\tsetOptions(opts);\n\t\tsetOpen(true);\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tresolveRef.current = resolve;\n\t\t});\n\t}, []);\n\n\tconst handleClose = useCallback(() => {\n\t\tsetOpen(false);\n\t\tresolveRef.current?.(false);\n\t\tresolveRef.current = null;\n\t}, []);\n\n\tconst handleConfirm = useCallback(() => {\n\t\tsetOpen(false);\n\t\tresolveRef.current?.(true);\n\t\tresolveRef.current = null;\n\t}, []);\n\n\treturn (\n\t\t<ConfirmModalContext.Provider value={{ confirm }}>\n\t\t\t{children}\n\t\t\t<ConfirmModalDialog\n\t\t\t\topen={open}\n\t\t\t\toptions={options}\n\t\t\t\tonClose={handleClose}\n\t\t\t\tonConfirm={handleConfirm}\n\t\t\t/>\n\t\t</ConfirmModalContext.Provider>\n\t);\n};\n\nConfirmModalProvider.displayName = \"ConfirmModalProvider\";\n\nexport const useConfirmModal = (): ConfirmModalContextType => {\n\tconst context = useContext(ConfirmModalContext);\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"useConfirmModal must be used within a ConfirmModalProvider\",\n\t\t);\n\t}\n\treturn context;\n};\n\ninterface ConfirmModalDialogProps {\n\topen: boolean;\n\toptions: ConfirmOptions;\n\tonClose: () => void;\n\tonConfirm: () => void;\n}\n\nconst ConfirmModalDialog: React.FC<ConfirmModalDialogProps> = ({\n\topen,\n\toptions,\n\tonClose,\n\tonConfirm,\n}) => {\n\tconst cancelRef = useRef<HTMLButtonElement>(null);\n\tconst {\n\t\ttitle,\n\t\tmessage,\n\t\tconfirmLabel = \"Confirm\",\n\t\tcancelLabel = \"Cancel\",\n\t\tcolorPalette = \"red\",\n\t\tbeforeConfirmActions,\n\t} = options;\n\n\treturn (\n\t\t<Dialog.Root\n\t\t\topen={open}\n\t\t\tinitialFocusEl={() => cancelRef.current}\n\t\t\tplacement=\"center\"\n\t\t\trole=\"alertdialog\"\n\t\t\tonOpenChange={(e) => {\n\t\t\t\tif (!e.open) {\n\t\t\t\t\tonClose();\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<Portal>\n\t\t\t\t<Dialog.Backdrop>\n\t\t\t\t\t<Dialog.Positioner>\n\t\t\t\t\t\t<Dialog.Content>\n\t\t\t\t\t\t\t<Dialog.Header fontSize=\"lg\" fontWeight=\"bold\">\n\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t</Dialog.Header>\n\t\t\t\t\t\t\t<Dialog.Body>{message}</Dialog.Body>\n\t\t\t\t\t\t\t<Dialog.Footer>\n\t\t\t\t\t\t\t\t<ButtonGroup size=\"sm\">\n\t\t\t\t\t\t\t\t\t<Button ref={cancelRef} variant=\"outline\" onClick={onClose}>\n\t\t\t\t\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t{beforeConfirmActions}\n\t\t\t\t\t\t\t\t\t<Button colorPalette={colorPalette} onClick={onConfirm}>\n\t\t\t\t\t\t\t\t\t\t{confirmLabel}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</ButtonGroup>\n\t\t\t\t\t\t\t</Dialog.Footer>\n\t\t\t\t\t\t</Dialog.Content>\n\t\t\t\t\t</Dialog.Positioner>\n\t\t\t\t</Dialog.Backdrop>\n\t\t\t</Portal>\n\t\t</Dialog.Root>\n\t);\n};\n"]}
1
+ {"version":3,"sources":["../../src/feedback/confirm-modal.tsx","../../src/feedback/upload-toast-stack.tsx"],"names":["jsx","useState","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tButton,\n\tButtonGroup,\n\ttype ButtonProps,\n\tDialog,\n\tPortal,\n} from \"@chakra-ui/react\";\nimport type React from \"react\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseRef,\n\tuseState,\n} from \"react\";\n\nexport interface ConfirmOptions {\n\t/** Dialog title text. */\n\ttitle: string;\n\t/** Dialog body content. */\n\tmessage: React.ReactNode;\n\t/** Label for the confirm button. @default \"Confirm\" */\n\tconfirmLabel?: string;\n\t/** Label for the cancel button. @default \"Cancel\" */\n\tcancelLabel?: string;\n\t/** Color palette for the confirm button. @default \"red\" */\n\tcolorPalette?: ButtonProps[\"colorPalette\"];\n\t/** Extra actions rendered before the confirm button. */\n\tbeforeConfirmActions?: React.ReactNode;\n}\n\ninterface ConfirmModalContextType {\n\tconfirm: (options: ConfirmOptions) => Promise<boolean>;\n}\n\nconst ConfirmModalContext = createContext<ConfirmModalContextType | undefined>(\n\tundefined,\n);\n\ninterface ConfirmModalProviderProps {\n\tchildren: React.ReactNode;\n}\n\nexport const ConfirmModalProvider: React.FC<ConfirmModalProviderProps> = ({\n\tchildren,\n}) => {\n\tconst [open, setOpen] = useState(false);\n\tconst [options, setOptions] = useState<ConfirmOptions>({\n\t\ttitle: \"\",\n\t\tmessage: \"\",\n\t});\n\tconst resolveRef = useRef<((value: boolean) => void) | null>(null);\n\n\tconst confirm = useCallback((opts: ConfirmOptions): Promise<boolean> => {\n\t\tsetOptions(opts);\n\t\tsetOpen(true);\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tresolveRef.current = resolve;\n\t\t});\n\t}, []);\n\n\tconst handleClose = useCallback(() => {\n\t\tsetOpen(false);\n\t\tresolveRef.current?.(false);\n\t\tresolveRef.current = null;\n\t}, []);\n\n\tconst handleConfirm = useCallback(() => {\n\t\tsetOpen(false);\n\t\tresolveRef.current?.(true);\n\t\tresolveRef.current = null;\n\t}, []);\n\n\treturn (\n\t\t<ConfirmModalContext.Provider value={{ confirm }}>\n\t\t\t{children}\n\t\t\t<ConfirmModalDialog\n\t\t\t\topen={open}\n\t\t\t\toptions={options}\n\t\t\t\tonClose={handleClose}\n\t\t\t\tonConfirm={handleConfirm}\n\t\t\t/>\n\t\t</ConfirmModalContext.Provider>\n\t);\n};\n\nConfirmModalProvider.displayName = \"ConfirmModalProvider\";\n\nexport const useConfirmModal = (): ConfirmModalContextType => {\n\tconst context = useContext(ConfirmModalContext);\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"useConfirmModal must be used within a ConfirmModalProvider\",\n\t\t);\n\t}\n\treturn context;\n};\n\ninterface ConfirmModalDialogProps {\n\topen: boolean;\n\toptions: ConfirmOptions;\n\tonClose: () => void;\n\tonConfirm: () => void;\n}\n\nconst ConfirmModalDialog: React.FC<ConfirmModalDialogProps> = ({\n\topen,\n\toptions,\n\tonClose,\n\tonConfirm,\n}) => {\n\tconst cancelRef = useRef<HTMLButtonElement>(null);\n\tconst {\n\t\ttitle,\n\t\tmessage,\n\t\tconfirmLabel = \"Confirm\",\n\t\tcancelLabel = \"Cancel\",\n\t\tcolorPalette = \"red\",\n\t\tbeforeConfirmActions,\n\t} = options;\n\n\treturn (\n\t\t<Dialog.Root\n\t\t\topen={open}\n\t\t\tinitialFocusEl={() => cancelRef.current}\n\t\t\tplacement=\"center\"\n\t\t\trole=\"alertdialog\"\n\t\t\tonOpenChange={(e) => {\n\t\t\t\tif (!e.open) {\n\t\t\t\t\tonClose();\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<Portal>\n\t\t\t\t<Dialog.Backdrop>\n\t\t\t\t\t<Dialog.Positioner>\n\t\t\t\t\t\t<Dialog.Content>\n\t\t\t\t\t\t\t<Dialog.Header fontSize=\"lg\" fontWeight=\"bold\">\n\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t</Dialog.Header>\n\t\t\t\t\t\t\t<Dialog.Body>{message}</Dialog.Body>\n\t\t\t\t\t\t\t<Dialog.Footer>\n\t\t\t\t\t\t\t\t<ButtonGroup size=\"sm\">\n\t\t\t\t\t\t\t\t\t<Button ref={cancelRef} variant=\"outline\" onClick={onClose}>\n\t\t\t\t\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t{beforeConfirmActions}\n\t\t\t\t\t\t\t\t\t<Button colorPalette={colorPalette} onClick={onConfirm}>\n\t\t\t\t\t\t\t\t\t\t{confirmLabel}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</ButtonGroup>\n\t\t\t\t\t\t\t</Dialog.Footer>\n\t\t\t\t\t\t</Dialog.Content>\n\t\t\t\t\t</Dialog.Positioner>\n\t\t\t\t</Dialog.Backdrop>\n\t\t\t</Portal>\n\t\t</Dialog.Root>\n\t);\n};\n","import {\n\tAlertCircle,\n\tCheck,\n\tChevronDown,\n\tChevronUp,\n\tClock,\n\tX,\n} from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { IconButton } from \"../atoms/button\";\nimport { Box, Flex, HStack, Stack } from \"../primitives/layout\";\nimport { Progress } from \"../primitives/progress\";\nimport { Spinner } from \"../primitives/spinner\";\nimport { Text } from \"../primitives/typography\";\n\nexport interface UploadFileStatus {\n\tid: string;\n\tfilename: string;\n\tstatus: \"pending\" | \"uploading\" | \"processing\" | \"done\" | \"error\";\n\tprogress?: number;\n\terror?: string;\n}\n\nexport interface UploadToastStackProps {\n\tfiles: UploadFileStatus[];\n\tonDismiss: () => void;\n\tautoDismissMs?: number;\n\tdefaultExpanded?: boolean;\n}\n\nconst FileStatusIcon = ({ status }: { status: UploadFileStatus[\"status\"] }) => {\n\tswitch (status) {\n\t\tcase \"pending\":\n\t\t\treturn <Clock size={14} color=\"var(--chakra-colors-fg-muted)\" />;\n\t\tcase \"uploading\":\n\t\tcase \"processing\":\n\t\t\treturn <Spinner size=\"xs\" />;\n\t\tcase \"done\":\n\t\t\treturn <Check size={14} color=\"var(--chakra-colors-green-500)\" />;\n\t\tcase \"error\":\n\t\t\treturn <AlertCircle size={14} color=\"var(--chakra-colors-red-500)\" />;\n\t}\n};\n\nexport const UploadToastStack = ({\n\tfiles,\n\tonDismiss,\n\tautoDismissMs = 5000,\n\tdefaultExpanded = true,\n}: UploadToastStackProps) => {\n\tconst [expanded, setExpanded] = useState(defaultExpanded);\n\tconst [hovered, setHovered] = useState(false);\n\n\tconst allComplete = files.every(\n\t\t(f) => f.status === \"done\" || f.status === \"error\",\n\t);\n\tconst totalProgress =\n\t\tfiles.length > 0\n\t\t\t? files.reduce((sum, f) => sum + (f.progress ?? 0), 0) / files.length\n\t\t\t: 0;\n\tconst doneCount = files.filter((f) => f.status === \"done\").length;\n\tconst errorCount = files.filter((f) => f.status === \"error\").length;\n\n\tconst headerText = allComplete\n\t\t? `${doneCount} file${doneCount !== 1 ? \"s\" : \"\"} uploaded${errorCount > 0 ? `, ${errorCount} failed` : \"\"}`\n\t\t: `Uploading ${files.length} file${files.length !== 1 ? \"s\" : \"\"}...`;\n\n\tuseEffect(() => {\n\t\tif (!allComplete || hovered || autoDismissMs === 0) return;\n\t\tconst timer = setTimeout(onDismiss, autoDismissMs);\n\t\treturn () => clearTimeout(timer);\n\t}, [allComplete, hovered, autoDismissMs, onDismiss]);\n\n\tif (files.length === 0) return null;\n\n\treturn (\n\t\t<Box\n\t\t\tposition=\"fixed\"\n\t\t\tbottom={4}\n\t\t\tinsetInlineEnd={4}\n\t\t\tzIndex=\"toast\"\n\t\t\tonMouseEnter={() => setHovered(true)}\n\t\t\tonMouseLeave={() => setHovered(false)}\n\t\t>\n\t\t\t<Box\n\t\t\t\tbg=\"bg.surface\"\n\t\t\t\tshadow=\"lg\"\n\t\t\t\trounded=\"lg\"\n\t\t\t\tborderWidth=\"1px\"\n\t\t\t\tborderColor=\"border\"\n\t\t\t\tw=\"320px\"\n\t\t\t\toverflow=\"hidden\"\n\t\t\t>\n\t\t\t\t{/* Header */}\n\t\t\t\t<Flex align=\"center\" px={3} py={2} gap={1}>\n\t\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\" flex=\"1\">\n\t\t\t\t\t\t{headerText}\n\t\t\t\t\t</Text>\n\t\t\t\t\t<IconButton\n\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\texpanded ? \"Collapse upload list\" : \"Expand upload list\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={() => setExpanded((v) => !v)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{expanded ? <ChevronDown size={14} /> : <ChevronUp size={14} />}\n\t\t\t\t\t</IconButton>\n\t\t\t\t\t<IconButton\n\t\t\t\t\t\taria-label=\"Dismiss upload toast\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={onDismiss}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X size={14} />\n\t\t\t\t\t</IconButton>\n\t\t\t\t</Flex>\n\n\t\t\t\t{/* Overall progress bar */}\n\t\t\t\t<Progress\n\t\t\t\t\tvalue={totalProgress}\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\tcolorPalette={allComplete && errorCount === 0 ? \"green\" : \"primary\"}\n\t\t\t\t/>\n\n\t\t\t\t{/* Per-file list */}\n\t\t\t\t{expanded && (\n\t\t\t\t\t<Stack gap={0} maxH=\"200px\" overflowY=\"auto\" px={3} py={2}>\n\t\t\t\t\t\t{files.map((file) => (\n\t\t\t\t\t\t\t<Box key={file.id} py={1}>\n\t\t\t\t\t\t\t\t<HStack gap={2} align=\"center\">\n\t\t\t\t\t\t\t\t\t<Box flexShrink={0}>\n\t\t\t\t\t\t\t\t\t\t<FileStatusIcon status={file.status} />\n\t\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\tfontSize=\"sm\"\n\t\t\t\t\t\t\t\t\t\tflex=\"1\"\n\t\t\t\t\t\t\t\t\t\toverflow=\"hidden\"\n\t\t\t\t\t\t\t\t\t\ttextOverflow=\"ellipsis\"\n\t\t\t\t\t\t\t\t\t\twhiteSpace=\"nowrap\"\n\t\t\t\t\t\t\t\t\t\ttitle={file.filename}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{file.filename}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t{file.progress !== undefined && (\n\t\t\t\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\" flexShrink={0}>\n\t\t\t\t\t\t\t\t\t\t\t{Math.round(file.progress)}%\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t{file.status === \"error\" && file.error && (\n\t\t\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.error\" ps={5}>\n\t\t\t\t\t\t\t\t\t\t{file.error}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Stack>\n\t\t\t\t)}\n\t\t\t</Box>\n\t\t</Box>\n\t);\n};\n\nUploadToastStack.displayName = \"UploadToastStack\";\n"]}
@@ -135,20 +135,6 @@ interface DirtyFormGuardProps {
135
135
  }
136
136
  declare const DirtyFormGuard: React__default.FC<DirtyFormGuardProps>;
137
137
 
138
- interface EditableHeadingProps {
139
- value?: string;
140
- onChange?: (nextValue: string) => void;
141
- onCancel?: (previousValue: string) => void;
142
- onSubmit?: (nextValue: string) => void;
143
- /** Aria label for the edit button. @default "Edit" */
144
- editLabel?: string;
145
- /** Font size for the heading. @default "3xl" */
146
- fontSize?: string;
147
- /** Max width constraint. @default "lg" */
148
- maxW?: string;
149
- }
150
- declare const EditableHeading: React__default.FC<EditableHeadingProps>;
151
-
152
138
  type DropzoneOptions = {
153
139
  noClick?: boolean;
154
140
  multiple?: boolean;
@@ -181,6 +167,28 @@ declare namespace FileField {
181
167
  var displayName: string;
182
168
  }
183
169
 
170
+ interface InlineEditProps {
171
+ value?: string;
172
+ onSubmit?: (nextValue: string) => void;
173
+ onChange?: (nextValue: string) => void;
174
+ onCancel?: (previousValue: string) => void;
175
+ /** @default "input" */
176
+ variant?: "input" | "textarea";
177
+ placeholder?: string;
178
+ /** @default "md" */
179
+ fontSize?: string;
180
+ fontWeight?: string;
181
+ maxW?: string;
182
+ disabled?: boolean;
183
+ /** When false, submitting an empty value reverts to the previous value. @default false */
184
+ allowEmpty?: boolean;
185
+ /** Number of rows used to calculate minH for textarea variant. @default 3 */
186
+ rows?: number;
187
+ /** Aria label for the edit button. @default "Edit" */
188
+ editLabel?: string;
189
+ }
190
+ declare const InlineEdit: React__default.FC<InlineEditProps>;
191
+
184
192
  interface InputFieldProps<T extends FieldValues> extends Omit<FormFieldProps<T>, "children"> {
185
193
  placeholder?: string;
186
194
  type?: InputProps["type"];
@@ -258,4 +266,4 @@ declare function TextareaField<T extends FieldValues>({ ref, ...props }: Textare
258
266
  ref?: React__default.Ref<HTMLTextAreaElement>;
259
267
  }): react_jsx_runtime.JSX.Element;
260
268
 
261
- export { ArrayField, type ArrayFieldProps, CheckboxField, type CheckboxFieldProps, CodeField, type CodeFieldProps, ColorPickerField, type ColorPickerFieldProps, ControlledFormField, type ControlledFormFieldProps, DatePickerField, type DatePickerFieldProps, DirtyFormGuard, type DirtyFormGuardProps, EditableHeading, type EditableHeadingProps, FileField, type FileFieldProps, FormField, type FormFieldProps, InputField, type InputFieldProps, MarkdownField, type MarkdownFieldProps, NumberInputField, type NumberInputFieldProps, RadioGroupField, type RadioGroupFieldProps, type RadioOption, SelectField, type SelectFieldProps, SwitchField, type SwitchFieldProps, TextareaField, type TextareaFieldProps };
269
+ export { ArrayField, type ArrayFieldProps, CheckboxField, type CheckboxFieldProps, CodeField, type CodeFieldProps, ColorPickerField, type ColorPickerFieldProps, ControlledFormField, type ControlledFormFieldProps, DatePickerField, type DatePickerFieldProps, DirtyFormGuard, type DirtyFormGuardProps, FileField, type FileFieldProps, FormField, type FormFieldProps, InlineEdit, type InlineEditProps, InputField, type InputFieldProps, MarkdownField, type MarkdownFieldProps, NumberInputField, type NumberInputFieldProps, RadioGroupField, type RadioGroupFieldProps, type RadioOption, SelectField, type SelectFieldProps, SwitchField, type SwitchFieldProps, TextareaField, type TextareaFieldProps };
@@ -1,10 +1,12 @@
1
- import { Popover, PopoverTrigger, PopoverContent, PopoverBody, LeavePageConfirmation, NumberInputRoot, NumberInputField, Radio, NativeSelect } from '../chunk-C4JI3JNA.js';
2
- import { Switch } from '../chunk-RJPEVNMJ.js';
3
- import { text_input_default } from '../chunk-PZCL4M6I.js';
4
- export { SearchInput } from '../chunk-PZCL4M6I.js';
5
- import { Stack, Grid, GridItem, Text, Input, IconButton, Box, ButtonGroup, Button, Field, HStack, Checkbox, Square, Editable, Flex, RadioGroup, Textarea, useEditableContext } from '@chakra-ui/react';
1
+ import { LeavePageConfirmation, NumberInputRoot, NumberInputField, RadioGroup, Radio, NativeSelect } from '../chunk-M5WNB4K6.js';
2
+ import { Popover, PopoverTrigger, PopoverContent, PopoverBody, Switch } from '../chunk-WQIEF5N3.js';
3
+ export { SearchInput } from '../chunk-E7KRPPCQ.js';
4
+ import { Textarea } from '../chunk-NFZMG6ZL.js';
5
+ import { text_input_default } from '../chunk-OU6H3KU4.js';
6
+ import { Stack, Grid, GridItem, Text, Box, HStack, Flex } from '../chunk-G4QMIXLC.js';
7
+ import { Input, IconButton, ButtonGroup, Button, Field, Checkbox, Square, Editable, useEditableContext } from '@chakra-ui/react';
6
8
  import { Trash2, Plus, Upload, Pencil } from 'lucide-react';
7
- import React, { useId, useCallback, useEffect } from 'react';
9
+ import React, { useId, useCallback, useEffect, useRef } from 'react';
8
10
  import { useFormContext, useFieldArray, Controller } from 'react-hook-form';
9
11
  import { jsxs, jsx } from 'react/jsx-runtime';
10
12
  import { useBlocker } from 'react-router-dom';
@@ -449,46 +451,6 @@ var DirtyFormGuard = ({
449
451
  );
450
452
  };
451
453
  DirtyFormGuard.displayName = "DirtyFormGuard";
452
- var EditableControls = ({ editLabel }) => {
453
- const { editing } = useEditableContext();
454
- if (editing) return null;
455
- return /* @__PURE__ */ jsx(ButtonGroup, { children: /* @__PURE__ */ jsx(Editable.EditTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
456
- IconButton,
457
- {
458
- variant: "ghost",
459
- marginInlineStart: 2,
460
- "aria-label": editLabel,
461
- children: /* @__PURE__ */ jsx(Pencil, { size: 20 })
462
- }
463
- ) }) });
464
- };
465
- var EditableHeading = ({
466
- value,
467
- onChange,
468
- onCancel,
469
- onSubmit,
470
- editLabel = "Edit",
471
- fontSize = "3xl",
472
- maxW = "lg"
473
- }) => {
474
- return /* @__PURE__ */ jsxs(
475
- Editable.Root,
476
- {
477
- fontSize,
478
- maxW,
479
- value: String(value ?? ""),
480
- onValueChange: (details) => onChange?.(details.value),
481
- onValueRevert: (details) => onCancel?.(details.value),
482
- onValueCommit: (details) => onSubmit?.(details.value),
483
- children: [
484
- /* @__PURE__ */ jsx(Editable.Preview, {}),
485
- /* @__PURE__ */ jsx(Editable.Input, {}),
486
- /* @__PURE__ */ jsx(EditableControls, { editLabel })
487
- ]
488
- }
489
- );
490
- };
491
- EditableHeading.displayName = "EditableHeading";
492
454
  function FileField(props) {
493
455
  const {
494
456
  name,
@@ -629,6 +591,70 @@ var DropzoneContent = ({
629
591
  )
630
592
  ] });
631
593
  };
594
+ var CancelRefCapture = ({ cancelRef }) => {
595
+ const { cancel } = useEditableContext();
596
+ cancelRef.current = cancel;
597
+ return null;
598
+ };
599
+ var EditControls = ({ editLabel }) => {
600
+ const { editing } = useEditableContext();
601
+ if (editing) return null;
602
+ return /* @__PURE__ */ jsx(ButtonGroup, { children: /* @__PURE__ */ jsx(Editable.EditTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
603
+ IconButton,
604
+ {
605
+ variant: "ghost",
606
+ marginInlineStart: 2,
607
+ "aria-label": editLabel,
608
+ children: /* @__PURE__ */ jsx(Pencil, { size: 16 })
609
+ }
610
+ ) }) });
611
+ };
612
+ var InlineEdit = ({
613
+ value,
614
+ onSubmit,
615
+ onChange,
616
+ onCancel,
617
+ variant = "input",
618
+ placeholder,
619
+ fontSize = "md",
620
+ fontWeight,
621
+ maxW,
622
+ disabled,
623
+ allowEmpty = false,
624
+ rows = 3,
625
+ editLabel = "Edit"
626
+ }) => {
627
+ const cancelRef = useRef(null);
628
+ const handleSubmit = (details) => {
629
+ const trimmed = details.value.trim();
630
+ if (!allowEmpty && trimmed === "") {
631
+ cancelRef.current?.();
632
+ return;
633
+ }
634
+ onSubmit?.(trimmed);
635
+ };
636
+ return /* @__PURE__ */ jsxs(
637
+ Editable.Root,
638
+ {
639
+ fontSize,
640
+ fontWeight,
641
+ maxW,
642
+ value: String(value ?? ""),
643
+ onValueChange: (d) => onChange?.(d.value),
644
+ onValueRevert: (d) => onCancel?.(d.value),
645
+ onValueCommit: handleSubmit,
646
+ disabled,
647
+ placeholder,
648
+ children: [
649
+ /* @__PURE__ */ jsx(CancelRefCapture, { cancelRef }),
650
+ /* @__PURE__ */ jsx(Editable.Preview, {}),
651
+ variant === "textarea" ? /* @__PURE__ */ jsx(Editable.Textarea, { minH: `${rows * 1.5}em` }) : /* @__PURE__ */ jsx(Editable.Input, {}),
652
+ /* @__PURE__ */ jsx(EditControls, { editLabel })
653
+ ]
654
+ }
655
+ );
656
+ };
657
+ InlineEdit.displayName = "InlineEdit";
632
658
  function InputField({
633
659
  ref,
634
660
  ...props
@@ -781,7 +807,7 @@ NumberInputField2.displayName = "NumberInputField";
781
807
  function RadioGroupField(props) {
782
808
  const { name, label, options, radioGroupProps, stackProps, ...rest } = props;
783
809
  return /* @__PURE__ */ jsx(FormField, { name, label, ...rest, children: (field) => /* @__PURE__ */ jsx(
784
- RadioGroup.Root,
810
+ RadioGroup,
785
811
  {
786
812
  value: String(field.value ?? ""),
787
813
  onValueChange: (e) => field.onChange(e.value),
@@ -904,6 +930,6 @@ function TextareaField({
904
930
  }
905
931
  TextareaField.displayName = "TextareaField";
906
932
 
907
- export { ArrayField, CheckboxField, CodeField, ColorPickerField, ControlledFormField, DatePickerField, DirtyFormGuard, EditableHeading, FileField, FormField, InputField, MarkdownField, NumberInputField2 as NumberInputField, RadioGroupField, SelectField, SwitchField, TextareaField };
933
+ export { ArrayField, CheckboxField, CodeField, ColorPickerField, ControlledFormField, DatePickerField, DirtyFormGuard, FileField, FormField, InlineEdit, InputField, MarkdownField, NumberInputField2 as NumberInputField, RadioGroupField, SelectField, SwitchField, TextareaField };
908
934
  //# sourceMappingURL=index.js.map
909
935
  //# sourceMappingURL=index.js.map