@vritti/quantum-ui 0.5.3 → 0.5.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vritti AI Platforms Private Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { c as createLucideIcon } from './createLucideIcon.js';
3
3
  import { A as ArrowDown, j as ArrowDownToLine, f as ArrowLeft, a as ArrowUp, i as ArrowUpFromLine, B as BookmarkPlus, C as ChevronsLeft, b as ChevronsRight, c as Columns2, E as EllipsisVertical, e as Equal, d as FilePlusCorner, F as FileUp, h as Funnel, I as Inbox, L as LayoutList, P as Pin, R as RefreshCw, S as Settings, g as Settings2, T as TableProperties } from './table-properties.js';
4
- import { z as Baseline, B as Bold, j as CircleUserRound, C as Clipboard, c as ClipboardType, f as Code, p as Columns3, E as Eraser, s as Heading1, r as Heading2, H as Heading3, t as Image, I as Italic, g as Link, a as Link2Off, n as List, w as ListIndentDecrease, x as ListIndentIncrease, u as ListOrdered, o as ListTodo, L as LockOpen, M as Mic, q as Minus, y as PaintBucket, P as Pipette, Q as Quote, R as Redo, b as Scissors, S as Send, e as Strikethrough, h as Subscript, i as Superscript, v as Table, l as TextAlignCenter, k as TextAlignEnd, m as TextAlignStart, d as Trash, T as Twitter, A as Type, U as Underline, D as Undo, Y as Youtube } from './youtube.js';
4
+ import { y as Baseline, B as Bold, j as CircleUserRound, C as Clipboard, c as ClipboardType, f as Code, p as Columns3, E as Eraser, s as Heading1, r as Heading2, H as Heading3, I as Italic, g as Link, a as Link2Off, n as List, v as ListIndentDecrease, w as ListIndentIncrease, t as ListOrdered, o as ListTodo, L as LockOpen, M as Mic, q as Minus, x as PaintBucket, P as Pipette, Q as Quote, R as Redo, b as Scissors, S as Send, e as Strikethrough, h as Subscript, i as Superscript, u as Table, l as TextAlignCenter, k as TextAlignEnd, m as TextAlignStart, d as Trash, T as Twitter, z as Type, U as Underline, A as Undo, Y as Youtube } from './youtube.js';
5
5
  import { C as Calendar } from './calendar.js';
6
6
  import { C as Camera, U as User } from './user.js';
7
7
  import { C as CheckCheck } from './check-check.js';
@@ -25,6 +25,7 @@ import { e as File, c as FileArchive, d as FileCode, a as FileHeadphone, F as Fi
25
25
  import { F as FileText } from './file-text.js';
26
26
  import { G as Globe } from './globe.js';
27
27
  import { G as GripVertical } from './grip-vertical.js';
28
+ import { I as Image, U as Upload } from './upload.js';
28
29
  import { I as Info, T as TriangleAlert } from './triangle-alert.js';
29
30
  import { L as LoaderCircle } from './loader-circle.js';
30
31
  import { L as LockKeyhole } from './lock-keyhole.js';
@@ -36,7 +37,6 @@ import { P as Pencil, a as Plus, T as Trash2 } from './trash-2.js';
36
37
  import { S as Save, a as Share2 } from './share-2.js';
37
38
  import { S as ScanBarcode } from './scan-barcode.js';
38
39
  import { S as Search } from './search.js';
39
- import { U as Upload } from './upload.js';
40
40
  import { X } from './x.js';
41
41
  import { forwardRef, useState, useMemo, useEffect } from 'react';
42
42
  import { u as useInView } from './index18.js';
@@ -4,7 +4,7 @@ import { c as cn } from './utils.js';
4
4
  import { B as Button } from './Button.js';
5
5
  import { F as FilePreview } from './FilePreview.js';
6
6
  import { F as Field, e as FieldLabel, c as FieldError } from './field.js';
7
- import { U as Upload } from './upload.js';
7
+ import { U as Upload, I as Image } from './upload.js';
8
8
  import { C as Camera, U as User } from './user.js';
9
9
  import { X } from './x.js';
10
10
 
@@ -37,7 +37,8 @@ const UploadFile = ({
37
37
  const firstFile = files[0];
38
38
  const selectedImageUrl = useImageObjectUrl(firstFile);
39
39
  const imageSrc = hasFiles ? selectedImageUrl : previewUrl ?? null;
40
- const isPreset = anchor === "dropzone" || anchor === "button" || anchor === "avatar";
40
+ const isPreset = anchor === "dropzone" || anchor === "button" || anchor === "avatar" || anchor === "logo";
41
+ const isTile = anchor === "avatar" || anchor === "logo";
41
42
  function handleClick() {
42
43
  if (disabled) return;
43
44
  inputRef.current?.click();
@@ -103,8 +104,11 @@ const UploadFile = ({
103
104
  placeholder ?? "Upload file"
104
105
  ] });
105
106
  }
106
- if (anchor === "avatar") {
107
+ if (isTile) {
107
108
  const avatarSize = 80;
109
+ const isLogo = anchor === "logo";
110
+ const shape = isLogo ? "rounded-lg" : "rounded-full";
111
+ const Placeholder = isLogo ? Image : User;
108
112
  return (
109
113
  // Wrapper provides positioning context for the badge outside overflow-hidden
110
114
  /* @__PURE__ */ jsxs("div", { className: "relative inline-block", style: { width: avatarSize, height: avatarSize }, children: [
@@ -115,7 +119,8 @@ const UploadFile = ({
115
119
  onClick: handleClick,
116
120
  disabled,
117
121
  className: cn(
118
- "group relative h-full w-full overflow-hidden rounded-full bg-muted",
122
+ "group relative h-full w-full overflow-hidden bg-muted",
123
+ shape,
119
124
  disabled ? "cursor-default" : "cursor-pointer",
120
125
  // A shown image is content, not an affordance — only dim the empty placeholder
121
126
  disabled && !imageSrc && "opacity-50"
@@ -126,12 +131,21 @@ const UploadFile = ({
126
131
  {
127
132
  src: imageSrc,
128
133
  alt: firstFile?.name ?? "",
129
- className: "rounded-full object-cover w-full h-full",
134
+ className: cn("w-full h-full", shape, isLogo ? "object-contain" : "object-cover"),
130
135
  style: { width: avatarSize, height: avatarSize }
131
136
  }
132
137
  ),
133
- !disabled && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-black/40 opacity-0 transition-opacity group-hover:opacity-100", children: /* @__PURE__ */ jsx(Camera, { className: "h-5 w-5 text-white" }) })
134
- ] }) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx(User, { className: "h-8 w-8 text-muted-foreground" }) })
138
+ !disabled && /* @__PURE__ */ jsx(
139
+ "div",
140
+ {
141
+ className: cn(
142
+ "absolute inset-0 flex items-center justify-center bg-black/40 opacity-0 transition-opacity group-hover:opacity-100",
143
+ shape
144
+ ),
145
+ children: /* @__PURE__ */ jsx(Camera, { className: "h-5 w-5 text-white" })
146
+ }
147
+ )
148
+ ] }) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx(Placeholder, { className: "h-8 w-8 text-muted-foreground" }) })
135
149
  }
136
150
  ),
137
151
  !imageSrc && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute -bottom-0.5 -right-0.5 flex h-6 w-6 items-center justify-center rounded-full bg-primary ring-2 ring-background", children: /* @__PURE__ */ jsx(Upload, { className: "h-3 w-3 text-primary-foreground" }) })
@@ -141,7 +155,7 @@ const UploadFile = ({
141
155
  return null;
142
156
  }
143
157
  function renderFileList() {
144
- if (!isPreset || !hasFiles || anchor === "avatar") return null;
158
+ if (!isPreset || !hasFiles || isTile) return null;
145
159
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsxs(
146
160
  "div",
147
161
  {
@@ -176,9 +190,9 @@ const UploadFile = ({
176
190
  )) });
177
191
  }
178
192
  return (
179
- // Field is w-full by default; the avatar is a fixed 80px circle, so it hugs its content
193
+ // Field is w-full by default; a tile is a fixed 80px square or circle, so it hugs its content
180
194
  // instead of claiming the whole row and pushing sibling content to the far edge
181
- /* @__PURE__ */ jsxs(Field, { "data-disabled": disabled, className: cn(anchor === "avatar" && "w-fit", className), children: [
195
+ /* @__PURE__ */ jsxs(Field, { "data-disabled": disabled, className: cn(isTile && "w-fit", className), children: [
182
196
  label && /* @__PURE__ */ jsx(FieldLabel, { children: label }),
183
197
  renderAnchor(),
184
198
  renderFileList(),
@@ -1 +1 @@
1
- {"version":3,"file":"UploadFile.js","sources":["../lib/components/UploadFile/UploadFile.tsx"],"sourcesContent":["import { Camera, Upload, User, X } from 'lucide-react';\nimport type React from 'react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { cn } from '../../../shadcn/utils';\nimport { Button } from '../Button';\nimport { Field, FieldError, FieldLabel } from '../Field';\nimport { FilePreview } from '../FilePreview';\n\ntype AnchorPreset = 'dropzone' | 'button' | 'avatar';\n\ninterface UploadFileBaseProps {\n anchor?: AnchorPreset | React.ReactNode;\n multiple?: boolean;\n accept?: string;\n className?: string;\n disabled?: boolean;\n label?: string;\n error?: string;\n placeholder?: string;\n hint?: string;\n value?: File | File[] | null;\n /** URL of an already-persisted file (e.g. a saved avatar). Shown as the preview until a new file is picked. */\n previewUrl?: string;\n isLoading?: boolean;\n}\n\ninterface UploadFileStandaloneProps extends UploadFileBaseProps {\n name?: never;\n onChange: (files: File | File[] | undefined) => void;\n}\n\ninterface UploadFileFormProps extends UploadFileBaseProps {\n name: string;\n onChange?: (files: File | File[] | undefined) => void;\n}\n\nexport type UploadFileProps = UploadFileStandaloneProps | UploadFileFormProps;\n\n// Creates a revocable object URL for an image File; null for non-images or no file.\n// Built during render, not in an effect, so the preview never flashes a placeholder first.\nfunction useImageObjectUrl(file: File | undefined): string | null {\n const objectUrl = useMemo(() => (file?.type.startsWith('image/') ? URL.createObjectURL(file) : null), [file]);\n\n useEffect(() => {\n if (!objectUrl) return;\n return () => URL.revokeObjectURL(objectUrl);\n }, [objectUrl]);\n\n return objectUrl;\n}\n\n// File upload trigger with optional preset anchors and built-in file preview\nexport const UploadFile: React.FC<UploadFileProps> = ({\n anchor = 'dropzone',\n multiple = false,\n accept,\n className,\n disabled,\n label,\n error,\n placeholder,\n hint,\n value,\n previewUrl,\n onChange,\n isLoading,\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Normalize value to an array for consistent handling\n const files: File[] = !value ? [] : Array.isArray(value) ? value : [value];\n const hasFiles = files.length > 0;\n\n const firstFile: File | undefined = files[0];\n const selectedImageUrl = useImageObjectUrl(firstFile);\n // A picked file always wins; previewUrl only fills in when nothing is selected, so\n // picking a non-image never falls back to the stale remote image\n const imageSrc = hasFiles ? selectedImageUrl : (previewUrl ?? null);\n\n // True when using a preset string anchor (not a custom ReactNode)\n const isPreset = anchor === 'dropzone' || anchor === 'button' || anchor === 'avatar';\n\n // Opens the native file picker\n function handleClick() {\n if (disabled) return;\n inputRef.current?.click();\n }\n\n // Forwards selected files to consumer and resets input\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const fileList = event.target.files;\n if (!fileList || fileList.length === 0) return;\n\n if (multiple) {\n // Merge with existing files, avoiding duplicates by name+size\n const incoming = Array.from(fileList);\n const merged = [...files, ...incoming.filter((f) => !files.some((e) => e.name === f.name && e.size === f.size))];\n onChange?.(merged);\n } else {\n onChange?.(fileList[0]);\n }\n\n // Reset so the same file can be re-selected\n event.target.value = '';\n }\n\n // Removes a specific file from the selection\n function handleRemove(file: File) {\n if (multiple) {\n const remaining = files.filter((f) => f !== file);\n onChange?.(remaining.length ? remaining : undefined);\n } else {\n onChange?.(undefined);\n }\n }\n\n // Renders the clickable anchor element based on the anchor prop\n function renderAnchor() {\n // Custom ReactNode — preserve original headless behaviour\n if (!isPreset) {\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n style={{ all: 'unset', display: 'inline-block', cursor: disabled ? 'default' : 'pointer' }}\n >\n {anchor as React.ReactNode}\n </button>\n );\n }\n\n if (anchor === 'dropzone') {\n // In single mode with a file selected, the file row replaces the dropzone\n if (!multiple && hasFiles) return null;\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n 'flex w-full flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-8 transition-colors',\n error ? 'border-destructive' : 'border-border',\n disabled ? 'cursor-default opacity-50' : 'cursor-pointer hover:bg-muted/50',\n )}\n >\n {imageSrc ? (\n <img src={imageSrc} alt=\"\" className=\"h-16 w-16 rounded object-cover\" />\n ) : (\n <Upload className=\"h-6 w-6 text-muted-foreground\" />\n )}\n <p className=\"text-sm text-muted-foreground\">{placeholder ?? 'Click or drag to upload'}</p>\n {hint && <p className=\"text-xs text-muted-foreground\">{hint}</p>}\n </button>\n );\n }\n\n if (anchor === 'button') {\n // In single mode with a file selected, the file row replaces the button\n if (!multiple && hasFiles) return null;\n\n return (\n <Button type=\"button\" variant=\"outline\" onClick={handleClick} disabled={disabled}>\n <Upload className=\"h-4 w-4\" />\n {placeholder ?? 'Upload file'}\n </Button>\n );\n }\n\n if (anchor === 'avatar') {\n const avatarSize = 80;\n\n return (\n // Wrapper provides positioning context for the badge outside overflow-hidden\n <div className=\"relative inline-block\" style={{ width: avatarSize, height: avatarSize }}>\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n 'group relative h-full w-full overflow-hidden rounded-full bg-muted',\n disabled ? 'cursor-default' : 'cursor-pointer',\n // A shown image is content, not an affordance — only dim the empty placeholder\n disabled && !imageSrc && 'opacity-50',\n )}\n >\n {imageSrc ? (\n <>\n <img\n src={imageSrc}\n alt={firstFile?.name ?? ''}\n className=\"rounded-full object-cover w-full h-full\"\n style={{ width: avatarSize, height: avatarSize }}\n />\n {/* Camera overlay on hover — omitted when read-only, since nothing can be picked */}\n {!disabled && (\n <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-black/40 opacity-0 transition-opacity group-hover:opacity-100\">\n <Camera className=\"h-5 w-5 text-white\" />\n </div>\n )}\n </>\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <User className=\"h-8 w-8 text-muted-foreground\" />\n </div>\n )}\n </button>\n\n {/* Badge sits outside overflow-hidden so it's never clipped */}\n {!imageSrc && (\n <div className=\"pointer-events-none absolute -bottom-0.5 -right-0.5 flex h-6 w-6 items-center justify-center rounded-full bg-primary ring-2 ring-background\">\n <Upload className=\"h-3 w-3 text-primary-foreground\" />\n </div>\n )}\n </div>\n );\n }\n\n return null;\n }\n\n // Renders the file list below the anchor for preset anchors (not avatar)\n function renderFileList() {\n if (!isPreset || !hasFiles || anchor === 'avatar') return null;\n\n return (\n <div className=\"flex flex-col gap-2\">\n {files.map((file) => (\n <div\n key={`${file.name}-${file.size}`}\n className={cn(\n 'relative overflow-hidden flex items-center gap-3 rounded-lg border border-dashed p-3',\n isLoading ? 'border-primary/40 animate-pulse' : 'border-border',\n )}\n >\n {isLoading && <div className=\"absolute inset-0 bg-primary/5\" />}\n <div className=\"relative flex items-center gap-3 flex-1 min-w-0\">\n <FilePreview file={file} size={40} />\n <div className=\"flex-1 min-w-0\">\n <span className=\"block truncate text-sm\">{file.name}</span>\n {isLoading && <span className=\"text-xs text-muted-foreground\">Uploading...</span>}\n </div>\n {!isLoading && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n onClick={() => handleRemove(file)}\n disabled={disabled}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n\n return (\n // Field is w-full by default; the avatar is a fixed 80px circle, so it hugs its content\n // instead of claiming the whole row and pushing sibling content to the far edge\n <Field data-disabled={disabled} className={cn(anchor === 'avatar' && 'w-fit', className)}>\n {label && <FieldLabel>{label}</FieldLabel>}\n\n {renderAnchor()}\n {renderFileList()}\n\n <input\n ref={inputRef}\n type=\"file\"\n multiple={multiple}\n accept={accept}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n tabIndex={-1}\n />\n\n {error && <FieldError>{error}</FieldError>}\n </Field>\n );\n};\n\nUploadFile.displayName = 'UploadFile';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UploadFile.js","sources":["../lib/components/UploadFile/UploadFile.tsx"],"sourcesContent":["import { Camera, Image, Upload, User, X } from 'lucide-react';\nimport type React from 'react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { cn } from '../../../shadcn/utils';\nimport { Button } from '../Button';\nimport { Field, FieldError, FieldLabel } from '../Field';\nimport { FilePreview } from '../FilePreview';\n\ntype AnchorPreset = 'dropzone' | 'button' | 'avatar' | 'logo';\n\ninterface UploadFileBaseProps {\n anchor?: AnchorPreset | React.ReactNode;\n multiple?: boolean;\n accept?: string;\n className?: string;\n disabled?: boolean;\n label?: string;\n error?: string;\n placeholder?: string;\n hint?: string;\n value?: File | File[] | null;\n /** URL of an already-persisted file (e.g. a saved avatar). Shown as the preview until a new file is picked. */\n previewUrl?: string;\n isLoading?: boolean;\n}\n\ninterface UploadFileStandaloneProps extends UploadFileBaseProps {\n name?: never;\n onChange: (files: File | File[] | undefined) => void;\n}\n\ninterface UploadFileFormProps extends UploadFileBaseProps {\n name: string;\n onChange?: (files: File | File[] | undefined) => void;\n}\n\nexport type UploadFileProps = UploadFileStandaloneProps | UploadFileFormProps;\n\n// Creates a revocable object URL for an image File; null for non-images or no file.\n// Built during render, not in an effect, so the preview never flashes a placeholder first.\nfunction useImageObjectUrl(file: File | undefined): string | null {\n const objectUrl = useMemo(() => (file?.type.startsWith('image/') ? URL.createObjectURL(file) : null), [file]);\n\n useEffect(() => {\n if (!objectUrl) return;\n return () => URL.revokeObjectURL(objectUrl);\n }, [objectUrl]);\n\n return objectUrl;\n}\n\n// File upload trigger with optional preset anchors and built-in file preview\nexport const UploadFile: React.FC<UploadFileProps> = ({\n anchor = 'dropzone',\n multiple = false,\n accept,\n className,\n disabled,\n label,\n error,\n placeholder,\n hint,\n value,\n previewUrl,\n onChange,\n isLoading,\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Normalize value to an array for consistent handling\n const files: File[] = !value ? [] : Array.isArray(value) ? value : [value];\n const hasFiles = files.length > 0;\n\n const firstFile: File | undefined = files[0];\n const selectedImageUrl = useImageObjectUrl(firstFile);\n // A picked file always wins; previewUrl only fills in when nothing is selected, so\n // picking a non-image never falls back to the stale remote image\n const imageSrc = hasFiles ? selectedImageUrl : (previewUrl ?? null);\n\n // True when using a preset string anchor (not a custom ReactNode)\n const isPreset = anchor === 'dropzone' || anchor === 'button' || anchor === 'avatar' || anchor === 'logo';\n // Both tile presets share one 80px picker; avatar crops to a circle, logo keeps the whole image in a square\n const isTile = anchor === 'avatar' || anchor === 'logo';\n\n // Opens the native file picker\n function handleClick() {\n if (disabled) return;\n inputRef.current?.click();\n }\n\n // Forwards selected files to consumer and resets input\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const fileList = event.target.files;\n if (!fileList || fileList.length === 0) return;\n\n if (multiple) {\n // Merge with existing files, avoiding duplicates by name+size\n const incoming = Array.from(fileList);\n const merged = [...files, ...incoming.filter((f) => !files.some((e) => e.name === f.name && e.size === f.size))];\n onChange?.(merged);\n } else {\n onChange?.(fileList[0]);\n }\n\n // Reset so the same file can be re-selected\n event.target.value = '';\n }\n\n // Removes a specific file from the selection\n function handleRemove(file: File) {\n if (multiple) {\n const remaining = files.filter((f) => f !== file);\n onChange?.(remaining.length ? remaining : undefined);\n } else {\n onChange?.(undefined);\n }\n }\n\n // Renders the clickable anchor element based on the anchor prop\n function renderAnchor() {\n // Custom ReactNode — preserve original headless behaviour\n if (!isPreset) {\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n style={{ all: 'unset', display: 'inline-block', cursor: disabled ? 'default' : 'pointer' }}\n >\n {anchor as React.ReactNode}\n </button>\n );\n }\n\n if (anchor === 'dropzone') {\n // In single mode with a file selected, the file row replaces the dropzone\n if (!multiple && hasFiles) return null;\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n 'flex w-full flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-8 transition-colors',\n error ? 'border-destructive' : 'border-border',\n disabled ? 'cursor-default opacity-50' : 'cursor-pointer hover:bg-muted/50',\n )}\n >\n {imageSrc ? (\n <img src={imageSrc} alt=\"\" className=\"h-16 w-16 rounded object-cover\" />\n ) : (\n <Upload className=\"h-6 w-6 text-muted-foreground\" />\n )}\n <p className=\"text-sm text-muted-foreground\">{placeholder ?? 'Click or drag to upload'}</p>\n {hint && <p className=\"text-xs text-muted-foreground\">{hint}</p>}\n </button>\n );\n }\n\n if (anchor === 'button') {\n // In single mode with a file selected, the file row replaces the button\n if (!multiple && hasFiles) return null;\n\n return (\n <Button type=\"button\" variant=\"outline\" onClick={handleClick} disabled={disabled}>\n <Upload className=\"h-4 w-4\" />\n {placeholder ?? 'Upload file'}\n </Button>\n );\n }\n\n if (isTile) {\n const avatarSize = 80;\n const isLogo = anchor === 'logo';\n const shape = isLogo ? 'rounded-lg' : 'rounded-full';\n const Placeholder = isLogo ? Image : User;\n\n return (\n // Wrapper provides positioning context for the badge outside overflow-hidden\n <div className=\"relative inline-block\" style={{ width: avatarSize, height: avatarSize }}>\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n 'group relative h-full w-full overflow-hidden bg-muted',\n shape,\n disabled ? 'cursor-default' : 'cursor-pointer',\n // A shown image is content, not an affordance — only dim the empty placeholder\n disabled && !imageSrc && 'opacity-50',\n )}\n >\n {imageSrc ? (\n <>\n <img\n src={imageSrc}\n alt={firstFile?.name ?? ''}\n // A logo must stay whole, so it is contained; an avatar fills its circle\n className={cn('w-full h-full', shape, isLogo ? 'object-contain' : 'object-cover')}\n style={{ width: avatarSize, height: avatarSize }}\n />\n {/* Camera overlay on hover — omitted when read-only, since nothing can be picked */}\n {!disabled && (\n <div\n className={cn(\n 'absolute inset-0 flex items-center justify-center bg-black/40 opacity-0 transition-opacity group-hover:opacity-100',\n shape,\n )}\n >\n <Camera className=\"h-5 w-5 text-white\" />\n </div>\n )}\n </>\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <Placeholder className=\"h-8 w-8 text-muted-foreground\" />\n </div>\n )}\n </button>\n\n {/* Badge sits outside overflow-hidden so it's never clipped */}\n {!imageSrc && (\n <div className=\"pointer-events-none absolute -bottom-0.5 -right-0.5 flex h-6 w-6 items-center justify-center rounded-full bg-primary ring-2 ring-background\">\n <Upload className=\"h-3 w-3 text-primary-foreground\" />\n </div>\n )}\n </div>\n );\n }\n\n return null;\n }\n\n // Renders the file list below the anchor for preset anchors (not the tile presets, which preview inline)\n function renderFileList() {\n if (!isPreset || !hasFiles || isTile) return null;\n\n return (\n <div className=\"flex flex-col gap-2\">\n {files.map((file) => (\n <div\n key={`${file.name}-${file.size}`}\n className={cn(\n 'relative overflow-hidden flex items-center gap-3 rounded-lg border border-dashed p-3',\n isLoading ? 'border-primary/40 animate-pulse' : 'border-border',\n )}\n >\n {isLoading && <div className=\"absolute inset-0 bg-primary/5\" />}\n <div className=\"relative flex items-center gap-3 flex-1 min-w-0\">\n <FilePreview file={file} size={40} />\n <div className=\"flex-1 min-w-0\">\n <span className=\"block truncate text-sm\">{file.name}</span>\n {isLoading && <span className=\"text-xs text-muted-foreground\">Uploading...</span>}\n </div>\n {!isLoading && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n onClick={() => handleRemove(file)}\n disabled={disabled}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n\n return (\n // Field is w-full by default; a tile is a fixed 80px square or circle, so it hugs its content\n // instead of claiming the whole row and pushing sibling content to the far edge\n <Field data-disabled={disabled} className={cn(isTile && 'w-fit', className)}>\n {label && <FieldLabel>{label}</FieldLabel>}\n\n {renderAnchor()}\n {renderFileList()}\n\n <input\n ref={inputRef}\n type=\"file\"\n multiple={multiple}\n accept={accept}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n tabIndex={-1}\n />\n\n {error && <FieldError>{error}</FieldError>}\n </Field>\n );\n};\n\nUploadFile.displayName = 'UploadFile';\n"],"names":[],"mappings":"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"}
@@ -3834,6 +3834,10 @@ select:-webkit-autofill:active {
3834
3834
  fill: var(--primary);
3835
3835
  }
3836
3836
 
3837
+ .object-contain {
3838
+ object-fit: contain;
3839
+ }
3840
+
3837
3841
  .object-cover {
3838
3842
  object-fit: cover;
3839
3843
  }
package/dist/field.js CHANGED
@@ -29,7 +29,7 @@ function FieldLegend({
29
29
  {
30
30
  "data-slot": "field-legend",
31
31
  "data-variant": variant,
32
- className: cn("mb-3 font-medium", "data-[variant=legend]:text-base", "data-[variant=label]:text-sm", className),
32
+ className: cn("font-medium", "data-[variant=legend]:text-base", "data-[variant=label]:text-sm", className),
33
33
  ...props
34
34
  }
35
35
  );
package/dist/field.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","sources":["../shadcn/shadcnField/field.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useMemo } from 'react';\nimport { Label } from '../shadcnLabel';\nimport { Separator } from '../shadcnSeparator';\nimport { cn } from '../utils';\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-4',\n 'has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn('mb-3 font-medium', 'data-[variant=legend]:text-base', 'data-[variant=label]:text-sm', className)}\n {...props}\n />\n );\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group @container/field-group flex w-full flex-col gap-2 data-[slot=checkbox-group]:gap-1 [&>[data-slot=field-group]]:gap-2',\n className,\n )}\n {...props}\n />\n );\n}\n\nconst fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-destructive', {\n variants: {\n orientation: {\n vertical: ['flex-col [&>*]:w-full [&>.sr-only]:w-auto'],\n horizontal: [\n 'flex-row items-center',\n '[&>[data-slot=field-label]]:flex-auto',\n 'has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n responsive: [\n 'flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto',\n '@md/field-group:[&>[data-slot=field-label]]:flex-auto',\n '@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\nfunction Field({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(fieldVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn('group/field-content flex flex-1 flex-col gap-1.5 leading-snug', className)}\n {...props}\n />\n );\n}\n\nfunction FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n 'group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-70',\n 'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4',\n 'has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-70',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n 'text-muted-foreground text-xs leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance',\n 'last:-mt-1 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5',\n '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'> & {\n children?: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"bg-background text-muted-foreground relative mx-auto block w-fit px-2\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n );\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>;\n}) {\n const content = useMemo(() => {\n if (children) {\n return children;\n }\n\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return errors[0]?.message;\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {errors.map((error) => error?.message && <li key={error.message}>{error.message}</li>)}\n </ul>\n );\n }, [children, errors]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn('text-destructive text-sm font-normal', className)}\n {...props}\n >\n {content}\n </div>\n );\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldTitle,\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"field.js","sources":["../shadcn/shadcnField/field.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useMemo } from 'react';\nimport { Label } from '../shadcnLabel';\nimport { Separator } from '../shadcnSeparator';\nimport { cn } from '../utils';\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-4',\n 'has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn('font-medium', 'data-[variant=legend]:text-base', 'data-[variant=label]:text-sm', className)}\n {...props}\n />\n );\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group @container/field-group flex w-full flex-col gap-2 data-[slot=checkbox-group]:gap-1 [&>[data-slot=field-group]]:gap-2',\n className,\n )}\n {...props}\n />\n );\n}\n\nconst fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-destructive', {\n variants: {\n orientation: {\n vertical: ['flex-col [&>*]:w-full [&>.sr-only]:w-auto'],\n horizontal: [\n 'flex-row items-center',\n '[&>[data-slot=field-label]]:flex-auto',\n 'has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n responsive: [\n 'flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto',\n '@md/field-group:[&>[data-slot=field-label]]:flex-auto',\n '@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\nfunction Field({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(fieldVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn('group/field-content flex flex-1 flex-col gap-1.5 leading-snug', className)}\n {...props}\n />\n );\n}\n\nfunction FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n 'group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-70',\n 'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4',\n 'has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-70',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n 'text-muted-foreground text-xs leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance',\n 'last:-mt-1 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5',\n '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'> & {\n children?: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"bg-background text-muted-foreground relative mx-auto block w-fit px-2\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n );\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>;\n}) {\n const content = useMemo(() => {\n if (children) {\n return children;\n }\n\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return errors[0]?.message;\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {errors.map((error) => error?.message && <li key={error.message}>{error.message}</li>)}\n </ul>\n );\n }, [children, errors]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn('text-destructive text-sm font-normal', className)}\n {...props}\n >\n {content}\n </div>\n );\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldTitle,\n};\n"],"names":[],"mappings":"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"}