@spacesync/client 0.1.0 → 0.1.1
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/README.md +9 -14
- package/dist/analog-clock-picker.d.ts +2 -2
- package/dist/analog-clock-picker.js +12 -406
- package/dist/analog-clock-picker.js.map +1 -1
- package/dist/api.js +7 -87
- package/dist/api.js.map +1 -1
- package/dist/app-modal.d.ts +7 -8
- package/dist/app-modal.js +3 -74
- package/dist/app-modal.js.map +1 -1
- package/dist/app-shell-mobile-nav.d.ts +1 -2
- package/dist/app-shell-mobile-nav.js +2 -66
- package/dist/app-shell-mobile-nav.js.map +1 -1
- package/dist/app-web-shell.d.ts +2 -2
- package/dist/app-web-shell.js +1 -4
- package/dist/app-web-shell.js.map +1 -1
- package/dist/booking-schedule-calendars.d.ts +12 -12
- package/dist/booking-schedule-calendars.js +13 -402
- package/dist/booking-schedule-calendars.js.map +1 -1
- package/dist/chat-stick-to-bottom.d.ts +1 -2
- package/dist/chat-stick-to-bottom.js +12 -48
- package/dist/chat-stick-to-bottom.js.map +1 -1
- package/dist/chunk-4A6RCBB5.js +4925 -0
- package/dist/chunk-4A6RCBB5.js.map +1 -0
- package/dist/chunk-4NNK5IXY.js +79 -0
- package/dist/chunk-4NNK5IXY.js.map +1 -0
- package/dist/chunk-4Y5DBM6Z.js +6 -0
- package/dist/chunk-4Y5DBM6Z.js.map +1 -0
- package/dist/chunk-7YCAAP43.js +107 -0
- package/dist/chunk-7YCAAP43.js.map +1 -0
- package/dist/chunk-DMPSQ22Q.js +11 -0
- package/dist/chunk-DMPSQ22Q.js.map +1 -0
- package/dist/chunk-FCY5FYJB.js +104 -0
- package/dist/chunk-FCY5FYJB.js.map +1 -0
- package/dist/chunk-H7EX6B6N.js +580 -0
- package/dist/chunk-H7EX6B6N.js.map +1 -0
- package/dist/chunk-HCHASUB6.js +13 -0
- package/dist/chunk-HCHASUB6.js.map +1 -0
- package/dist/chunk-L65F4EMK.js +34 -0
- package/dist/chunk-L65F4EMK.js.map +1 -0
- package/dist/chunk-LUB7QWGU.js +301 -0
- package/dist/chunk-LUB7QWGU.js.map +1 -0
- package/dist/chunk-OMSJWTSZ.js +120 -0
- package/dist/chunk-OMSJWTSZ.js.map +1 -0
- package/dist/chunk-OWNUMPUC.js +9 -0
- package/dist/chunk-OWNUMPUC.js.map +1 -0
- package/dist/chunk-P65TMY3D.js +87 -0
- package/dist/chunk-P65TMY3D.js.map +1 -0
- package/dist/chunk-PBNBLCC2.js +84 -0
- package/dist/chunk-PBNBLCC2.js.map +1 -0
- package/dist/chunk-RV5PMZYZ.js +63 -0
- package/dist/chunk-RV5PMZYZ.js.map +1 -0
- package/dist/chunk-VHINHHZQ.js +48 -0
- package/dist/chunk-VHINHHZQ.js.map +1 -0
- package/dist/chunk-VVXGQKN7.js +107 -0
- package/dist/chunk-VVXGQKN7.js.map +1 -0
- package/dist/chunk-XU3EFSQX.js +22 -0
- package/dist/chunk-XU3EFSQX.js.map +1 -0
- package/dist/chunk-YAVEMXXV.js +381 -0
- package/dist/chunk-YAVEMXXV.js.map +1 -0
- package/dist/chunk-ZIJQ7BXU.js +27 -0
- package/dist/chunk-ZIJQ7BXU.js.map +1 -0
- package/dist/detail-page-header.d.ts +3 -3
- package/dist/detail-page-header.js +5 -149
- package/dist/detail-page-header.js.map +1 -1
- package/dist/{dialog-CIdvylPK.d.ts → dialog-CPkbi5N3.d.ts} +10 -11
- package/dist/file-picker-field.d.ts +2 -2
- package/dist/file-picker-field.js +3 -163
- package/dist/file-picker-field.js.map +1 -1
- package/dist/file-viewer-dialog.d.ts +2 -2
- package/dist/file-viewer-dialog.js +12 -223
- package/dist/file-viewer-dialog.js.map +1 -1
- package/dist/floor-switcher.d.ts +2 -2
- package/dist/floor-switcher.js +13 -323
- package/dist/floor-switcher.js.map +1 -1
- package/dist/forms.js +1 -23
- package/dist/forms.js.map +1 -1
- package/dist/image-picker-field.d.ts +2 -2
- package/dist/image-picker-field.js +3 -48
- package/dist/image-picker-field.js.map +1 -1
- package/dist/layout-canvas-view.d.ts +2 -2
- package/dist/layout-canvas-view.js +17 -220
- package/dist/layout-canvas-view.js.map +1 -1
- package/dist/lib/dateDisplay.js +1 -82
- package/dist/lib/dateDisplay.js.map +1 -1
- package/dist/live-resource-meta.js +1 -25
- package/dist/live-resource-meta.js.map +1 -1
- package/dist/live-space-pulse-dot.d.ts +2 -2
- package/dist/live-space-pulse-dot.js +2 -16
- package/dist/live-space-pulse-dot.js.map +1 -1
- package/dist/notification-sidebar-preview.d.ts +3 -3
- package/dist/notification-sidebar-preview.js +3 -61
- package/dist/notification-sidebar-preview.js.map +1 -1
- package/dist/page-list-chrome.d.ts +25 -25
- package/dist/page-list-chrome.js +6 -968
- package/dist/page-list-chrome.js.map +1 -1
- package/dist/platform-support-message-composer.d.ts +4 -4
- package/dist/platform-support-message-composer.js +15 -218
- package/dist/platform-support-message-composer.js.map +1 -1
- package/dist/shell-sidebar-nav.js +8 -13
- package/dist/shell-sidebar-nav.js.map +1 -1
- package/dist/shell-theme.js +1 -7
- package/dist/shell-theme.js.map +1 -1
- package/dist/shell-top-bar-chrome.js +3 -103
- package/dist/shell-top-bar-chrome.js.map +1 -1
- package/dist/shell-top-bar.d.ts +3 -3
- package/dist/shell-top-bar.js +1 -69
- package/dist/shell-top-bar.js.map +1 -1
- package/dist/support-presence-status.d.ts +2 -2
- package/dist/support-presence-status.js +3 -41
- package/dist/support-presence-status.js.map +1 -1
- package/dist/theme-appearance-control.d.ts +2 -2
- package/dist/theme-appearance-control.js +4 -63
- package/dist/theme-appearance-control.js.map +1 -1
- package/dist/theme-boot-script.js +1 -2
- package/dist/theme-boot-script.js.map +1 -1
- package/dist/theme-provider.d.ts +2 -2
- package/dist/theme-provider.js +2 -23
- package/dist/theme-provider.js.map +1 -1
- package/dist/ui.d.ts +261 -262
- package/dist/ui.js +11 -5635
- package/dist/ui.js.map +1 -1
- package/package.json +11 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/utils.ts","../src/ui/button.tsx","../src/shell/shell-top-bar.tsx","../src/shell/shell-top-bar-chrome.ts","../src/shell/detail-page-header.tsx"],"names":["Button","jsxs","jsx"],"mappings":"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","file":"detail-page-header.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"./utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-all disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 active:bg-destructive/80 active:scale-[0.98] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 dark:active:bg-destructive/70\",\n outline:\n \"border bg-background text-foreground hover:bg-accent hover:text-accent-foreground active:bg-accent/80 active:scale-[0.98] dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:active:bg-input/60\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:scale-[0.98] dark:hover:bg-accent/50 dark:active:bg-accent/40\",\n link: \"text-primary underline-offset-4 hover:underline active:text-primary/80\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9 rounded-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }\n>(function Button({ className, variant, size, asChild = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n});\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import {\n createContext,\n useContext,\n useEffect,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\n\ntype ShellTopBarState = {\n title?: ReactNode;\n icon?: ReactNode;\n actions?: ReactNode;\n};\n\ntype ShellTopBarStore = {\n getSnapshot: () => ShellTopBarState;\n subscribe: (listener: () => void) => () => void;\n setState: (next: ShellTopBarState) => void;\n};\n\nconst EMPTY_TOP_BAR_STATE: ShellTopBarState = {};\n\nfunction createShellTopBarStore(): ShellTopBarStore {\n let state = EMPTY_TOP_BAR_STATE;\n const listeners = new Set<() => void>();\n\n return {\n getSnapshot: () => state,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n setState: (next) => {\n state = next;\n listeners.forEach((listener) => listener());\n },\n };\n}\n\nconst ShellTopBarStoreContext = createContext<ShellTopBarStore | null>(null);\n\nexport function ShellTopBarProvider({ children }: { children: ReactNode }) {\n const [store] = useState(createShellTopBarStore);\n\n return (\n <ShellTopBarStoreContext.Provider value={store}>\n {children}\n </ShellTopBarStoreContext.Provider>\n );\n}\n\nfunction useShellTopBarStore() {\n const store = useContext(ShellTopBarStoreContext);\n if (!store) {\n throw new Error(\"ShellTopBar components must be used within ShellTopBarProvider\");\n }\n return store;\n}\n\n/** Pages render a title and optional actions for the app shell top bar. */\nexport function ShellTopBar({\n title,\n icon,\n actions,\n}: {\n title: ReactNode;\n icon?: ReactNode;\n actions?: ReactNode;\n}) {\n const store = useShellTopBarStore();\n\n useEffect(() => {\n store.setState({ title, icon, actions });\n return () => store.setState(EMPTY_TOP_BAR_STATE);\n }, [title, icon, actions, store]);\n\n return null;\n}\n\n/** Renders registered page title and actions inside AppWebShell topBar. */\nexport function ShellTopBarFrame() {\n const store = useShellTopBarStore();\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { title, icon, actions } = state;\n\n if (title == null && actions == null) {\n return <div className=\"flex flex-1 items-center\" />;\n }\n\n const titleIsPlainText = typeof title === \"string\";\n\n return (\n <>\n <div className=\"flex min-w-0 flex-1 items-center\">\n {title != null ? (\n <div\n data-slot=\"shell-top-bar-title\"\n className=\"flex min-w-0 flex-1 items-center gap-2 text-sidebar-foreground\"\n >\n {titleIsPlainText ? (\n <>\n {icon != null ? (\n <span className=\"flex shrink-0 items-center text-sidebar-foreground/60\">{icon}</span>\n ) : null}\n <h1 className=\"truncate text-sm font-normal\">{title}</h1>\n </>\n ) : (\n title\n )}\n </div>\n ) : null}\n </div>\n {actions != null ? (\n <div data-slot=\"shell-top-bar-actions\" className=\"flex shrink-0 items-center gap-1.5\">\n {actions}\n </div>\n ) : null}\n </>\n );\n}\n","import { getShellTheme } from \"../theme/shell-theme\";\nimport { cn } from \"../ui/utils\";\n\nexport const shellTopBarMutedIconClass = \"text-sidebar-foreground/60\";\nexport const shellTopBarTitleTextClass = \"text-sidebar-foreground\";\n\n/** Shared sizing and corner radius for shell top bar actions. */\nconst shellTopBarActionSize = cn(\n \"inline-flex !h-7 min-h-0 items-center justify-center gap-1 px-2.5 text-xs font-medium\",\n \"[&_svg:not([class*='size-'])]:size-3.5\",\n);\nconst shellTopBarRadius = \"rounded-md\";\n\nfunction isDarkShell() {\n return getShellTheme() === \"dark\";\n}\n\n/** Resting surface for neutral shell controls (secondary, outline, icon). */\nconst shellTopBarNeutralRest =\n \"border border-sidebar-border bg-sidebar-accent text-sidebar-foreground shadow-none transition-colors\";\n\n/** Visible hover — lighten fill on dark shell, darken on light shell. */\nconst shellTopBarNeutralHover = isDarkShell()\n ? \"hover:!border-sidebar-foreground/25 hover:!bg-sidebar-foreground/12 hover:!text-sidebar-foreground\"\n : \"hover:!border-sidebar-foreground/14 hover:!bg-sidebar-foreground/6 hover:!text-sidebar-foreground\";\n\nconst shellTopBarNeutralActive = isDarkShell()\n ? \"active:!border-sidebar-foreground/20 active:!bg-sidebar-foreground/8 active:!text-sidebar-foreground\"\n : \"active:!border-sidebar-foreground/10 active:!bg-sidebar-foreground/4 active:!text-sidebar-foreground\";\n\n/** Apply to native shell actions (links, ticket buttons) so they share the same hover treatment as {@link ShellTopBarSecondaryActionButton}. */\nexport const shellTopBarNeutralActionDataAttr = {\n \"data-shell-top-bar-action\": \"\",\n} as const;\n\n/** Compact back control in the shell top bar (detail pages). */\nexport const shellTopBarBackButtonClass = cn(\n \"inline-flex !h-6 !w-6 shrink-0 items-center justify-center text-sidebar-foreground/70\",\n shellTopBarRadius,\n shellTopBarNeutralRest,\n shellTopBarNeutralHover,\n shellTopBarNeutralActive,\n);\n\n/** Icon-only control (e.g. overflow menu) in the shell top bar. */\nexport const shellTopBarIconButtonClass = cn(\n \"inline-flex !h-7 !w-7 shrink-0 items-center justify-center text-sidebar-foreground/70\",\n shellTopBarRadius,\n shellTopBarNeutralRest,\n shellTopBarNeutralHover,\n shellTopBarNeutralActive,\n \"[&_svg:not([class*='size-'])]:size-3.5\",\n);\n\n/**\n * Neutral secondary / outline action in the shell top bar.\n * Uses `!` on hover so shadcn `Button variant=\"outline\"` cannot win.\n */\nexport const shellTopBarSecondaryButtonClass = cn(\n shellTopBarActionSize,\n shellTopBarRadius,\n \"!border-sidebar-border !bg-sidebar-accent !text-sidebar-foreground shadow-none transition-colors\",\n \"!py-0\",\n shellTopBarNeutralHover,\n shellTopBarNeutralActive,\n \"disabled:pointer-events-none disabled:!border-sidebar-border/60 disabled:!bg-sidebar-accent/60 disabled:!text-sidebar-foreground/40\",\n);\n\n/** Primary CTA in the shell top bar (New invoice, Add staff, etc.). */\nexport const shellTopBarPrimaryButtonClass = cn(\n shellTopBarActionSize,\n shellTopBarRadius,\n \"bg-blue-500 text-white transition-colors hover:bg-blue-600\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n);\n\n/** Positive / payment emphasis in the shell top bar (e.g. Mark as paid). */\nexport const shellTopBarAccentButtonClass = cn(\n shellTopBarActionSize,\n shellTopBarRadius,\n \"bg-emerald-600 text-white transition-colors hover:bg-emerald-700\",\n);\n\n/** Positive status action in the shell top bar (e.g. Mark resolved). */\nexport const shellTopBarSuccessButtonClass = cn(\n shellTopBarActionSize,\n shellTopBarRadius,\n isDarkShell()\n ? \"border border-emerald-500/35 bg-emerald-500/15 text-emerald-300 transition-colors hover:border-emerald-400/45 hover:bg-emerald-500/25\"\n : \"border border-emerald-200 bg-emerald-50 text-emerald-700 transition-colors hover:border-emerald-300 hover:bg-emerald-100\",\n);\n\n/** Informative / reopen action in the shell top bar. */\nexport const shellTopBarInfoButtonClass = cn(\n shellTopBarActionSize,\n shellTopBarRadius,\n isDarkShell()\n ? \"border border-blue-500/35 bg-blue-500/15 text-blue-300 transition-colors hover:border-blue-400/45 hover:bg-blue-500/25\"\n : \"border border-blue-200 bg-blue-50 text-blue-700 transition-colors hover:border-blue-300 hover:bg-blue-100\",\n);\n\n/** Outline-style action — same neutral chrome as {@link shellTopBarSecondaryButtonClass}. */\nexport const shellTopBarOutlineButtonClass = shellTopBarSecondaryButtonClass;\n\n/** Wrapper for segmented toggles (2D / list, etc.) in the shell top bar. */\nexport const shellTopBarSegmentedShellClass = cn(\n \"flex items-center gap-0.5 border border-sidebar-border bg-sidebar-accent p-0.5\",\n shellTopBarRadius,\n);\n\nexport function shellTopBarSegmentedItemClass(active: boolean) {\n const dark = isDarkShell();\n return cn(\n shellTopBarActionSize,\n \"!h-6 px-2\",\n \"rounded-sm\",\n active\n ? dark\n ? \"bg-sidebar text-sidebar-foreground shadow-sm\"\n : \"bg-white text-sidebar-foreground shadow-sm\"\n : dark\n ? \"text-sidebar-foreground/60 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground\"\n : \"text-sidebar-foreground/60 hover:bg-sidebar-foreground/6 hover:text-sidebar-foreground\",\n );\n}\n\n/** Grouped field shell (month picker, etc.) in the top bar. */\nexport const shellTopBarControlGroupClass = cn(\n \"flex h-7 items-center gap-1.5 border border-sidebar-border bg-sidebar-accent pl-2.5 pr-1 text-sidebar-foreground\",\n shellTopBarRadius,\n);\n\nexport const shellTopBarControlLabelClass =\n \"m-0 shrink-0 text-[11px] font-normal text-sidebar-foreground/60\";\n\n/** Select trigger embedded in {@link shellTopBarControlGroupClass}. */\nexport const shellTopBarSelectTriggerClass =\n \"h-6 min-w-[140px] flex-1 border-0 bg-transparent px-1 text-xs text-sidebar-foreground shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 [&_svg]:text-sidebar-foreground/60\";\n\n/** Square control for date steppers and similar compact actions. */\nexport const shellTopBarCompactIconButtonClass = cn(\n \"inline-flex !h-6 !w-6 items-center justify-center text-sidebar-foreground/70\",\n shellTopBarRadius,\n shellTopBarNeutralRest,\n shellTopBarNeutralHover,\n shellTopBarNeutralActive,\n \"[&_svg:not([class*='size-'])]:size-3.5\",\n);\n\n/** Center label in a date stepper (shows “Today” or a formatted date). */\nexport const shellTopBarDateLabelButtonClass = cn(\n shellTopBarActionSize,\n \"min-w-[72px]\",\n shellTopBarNeutralRest,\n shellTopBarNeutralHover,\n shellTopBarNeutralActive,\n);\n","import type { ReactNode } from \"react\";\nimport { ChevronLeft } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { ShellTopBar } from \"./shell-top-bar\";\nimport {\n shellTopBarBackButtonClass,\n shellTopBarMutedIconClass,\n shellTopBarTitleTextClass,\n} from \"./shell-top-bar-chrome\";\n\nexport type DetailPageHeaderProps = {\n onBack: () => void;\n backAriaLabel: string;\n icon: ReactNode;\n title: ReactNode;\n /** Defaults to `title` when it is a plain string */\n mobileTitle?: ReactNode;\n actions?: ReactNode;\n};\n\nconst mobileBackClass =\n \"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground transition-colors hover:bg-muted/80 hover:text-foreground\";\n\nfunction DetailTitleRow({\n onBack,\n backAriaLabel,\n icon,\n title,\n backClassName,\n backIconSize,\n}: DetailPageHeaderProps & { backClassName: string; backIconSize: number }) {\n return (\n <span className=\"flex min-w-0 items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onBack}\n aria-label={backAriaLabel}\n className={backClassName}\n >\n <ChevronLeft size={backIconSize} strokeWidth={2} />\n </Button>\n <span className={`flex shrink-0 items-center ${shellTopBarMutedIconClass}`}>{icon}</span>\n {typeof title === \"string\" ? (\n <span className={`truncate text-sm font-normal ${shellTopBarTitleTextClass}`}>{title}</span>\n ) : (\n <span className={`min-w-0 flex-1 truncate text-sm font-normal ${shellTopBarTitleTextClass}`}>\n {title}\n </span>\n )}\n </span>\n );\n}\n\nexport function DetailPageShellHeader(props: DetailPageHeaderProps) {\n return (\n <ShellTopBar\n title={<DetailTitleRow {...props} backClassName={shellTopBarBackButtonClass} backIconSize={14} />}\n actions={props.actions}\n />\n );\n}\n\nexport function DetailPageMobileHeader({\n onBack,\n backAriaLabel,\n icon,\n title,\n mobileTitle,\n actions,\n}: DetailPageHeaderProps) {\n const resolvedMobileTitle =\n mobileTitle ??\n (typeof title === \"string\" ? (\n <h1 className=\"truncate text-sm font-semibold text-foreground\">{title}</h1>\n ) : (\n <div className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">{title}</div>\n ));\n\n return (\n <div className=\"flex shrink-0 items-center justify-between gap-3 border-b border-border px-5 py-3 md:hidden\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onBack}\n aria-label={backAriaLabel}\n className={mobileBackClass}\n >\n <ChevronLeft size={18} strokeWidth={2} />\n </Button>\n <span className=\"flex shrink-0 items-center text-muted-foreground\">{icon}</span>\n {resolvedMobileTitle}\n </div>\n {actions ? <div className=\"flex shrink-0 items-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shell/detail-page-header.tsx"],"names":[],"mappings":"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","file":"detail-page-header.js","sourcesContent":["import type { ReactNode } from \"react\";\nimport { ChevronLeft } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { ShellTopBar } from \"./shell-top-bar\";\nimport {\n shellTopBarBackButtonClass,\n shellTopBarMutedIconClass,\n shellTopBarTitleTextClass,\n} from \"./shell-top-bar-chrome\";\n\nexport type DetailPageHeaderProps = {\n onBack: () => void;\n backAriaLabel: string;\n icon: ReactNode;\n title: ReactNode;\n /** Defaults to `title` when it is a plain string */\n mobileTitle?: ReactNode;\n actions?: ReactNode;\n};\n\nconst mobileBackClass =\n \"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground transition-colors hover:bg-muted/80 hover:text-foreground\";\n\nfunction DetailTitleRow({\n onBack,\n backAriaLabel,\n icon,\n title,\n backClassName,\n backIconSize,\n}: DetailPageHeaderProps & { backClassName: string; backIconSize: number }) {\n return (\n <span className=\"flex min-w-0 items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onBack}\n aria-label={backAriaLabel}\n className={backClassName}\n >\n <ChevronLeft size={backIconSize} strokeWidth={2} />\n </Button>\n <span className={`flex shrink-0 items-center ${shellTopBarMutedIconClass}`}>{icon}</span>\n {typeof title === \"string\" ? (\n <span className={`truncate text-sm font-normal ${shellTopBarTitleTextClass}`}>{title}</span>\n ) : (\n <span className={`min-w-0 flex-1 truncate text-sm font-normal ${shellTopBarTitleTextClass}`}>\n {title}\n </span>\n )}\n </span>\n );\n}\n\nexport function DetailPageShellHeader(props: DetailPageHeaderProps) {\n return (\n <ShellTopBar\n title={<DetailTitleRow {...props} backClassName={shellTopBarBackButtonClass} backIconSize={14} />}\n actions={props.actions}\n />\n );\n}\n\nexport function DetailPageMobileHeader({\n onBack,\n backAriaLabel,\n icon,\n title,\n mobileTitle,\n actions,\n}: DetailPageHeaderProps) {\n const resolvedMobileTitle =\n mobileTitle ??\n (typeof title === \"string\" ? (\n <h1 className=\"truncate text-sm font-semibold text-foreground\">{title}</h1>\n ) : (\n <div className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">{title}</div>\n ));\n\n return (\n <div className=\"flex shrink-0 items-center justify-between gap-3 border-b border-border px-5 py-3 md:hidden\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onBack}\n aria-label={backAriaLabel}\n className={mobileBackClass}\n >\n <ChevronLeft size={18} strokeWidth={2} />\n </Button>\n <span className=\"flex shrink-0 items-center text-muted-foreground\">{icon}</span>\n {resolvedMobileTitle}\n </div>\n {actions ? <div className=\"flex shrink-0 items-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
4
3
|
|
|
5
|
-
declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>):
|
|
6
|
-
declare function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>):
|
|
7
|
-
declare function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>):
|
|
8
|
-
declare function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>):
|
|
9
|
-
declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>):
|
|
10
|
-
declare function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>):
|
|
11
|
-
declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">):
|
|
12
|
-
declare function DialogFooter({ className, ...props }: React.ComponentProps<"div">):
|
|
13
|
-
declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>):
|
|
14
|
-
declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>):
|
|
4
|
+
declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
|
|
5
|
+
declare function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element;
|
|
6
|
+
declare function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
|
|
7
|
+
declare function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element;
|
|
8
|
+
declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element;
|
|
9
|
+
declare function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>): React.JSX.Element;
|
|
10
|
+
declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
11
|
+
declare function DialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
12
|
+
declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element;
|
|
13
|
+
declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): React.JSX.Element;
|
|
15
14
|
|
|
16
15
|
export { DialogContent as D, DialogFooter as a, DialogHeader as b, Dialog as c, DialogClose as d, DialogDescription as e, DialogTitle as f, DialogTrigger as g, DialogOverlay as h, DialogPortal as i };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
type FilePickerFieldVariant = "card" | "button" | "inline";
|
|
@@ -18,6 +18,6 @@ interface FilePickerFieldProps {
|
|
|
18
18
|
title?: string;
|
|
19
19
|
onFilesSelected: (files: FileList | null) => void;
|
|
20
20
|
}
|
|
21
|
-
declare function FilePickerField({ label, actionLabel, description, selectedLabel, accept, multiple, disabled, variant, icon, className, triggerClassName, inputClassName, title, onFilesSelected, }: FilePickerFieldProps):
|
|
21
|
+
declare function FilePickerField({ label, actionLabel, description, selectedLabel, accept, multiple, disabled, variant, icon, className, triggerClassName, inputClassName, title, onFilesSelected, }: FilePickerFieldProps): React.JSX.Element;
|
|
22
22
|
|
|
23
23
|
export { FilePickerField, type FilePickerFieldProps, type FilePickerFieldVariant };
|
|
@@ -1,165 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
-
import { cva } from 'class-variance-authority';
|
|
6
|
-
import { clsx } from 'clsx';
|
|
7
|
-
import { twMerge } from 'tailwind-merge';
|
|
8
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
9
|
-
|
|
10
|
-
// src/files/file-picker-field.tsx
|
|
11
|
-
function cn(...inputs) {
|
|
12
|
-
return twMerge(clsx(inputs));
|
|
13
|
-
}
|
|
14
|
-
var buttonVariants = cva(
|
|
15
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-all disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
16
|
-
{
|
|
17
|
-
variants: {
|
|
18
|
-
variant: {
|
|
19
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]",
|
|
20
|
-
destructive: "bg-destructive text-white hover:bg-destructive/90 active:bg-destructive/80 active:scale-[0.98] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 dark:active:bg-destructive/70",
|
|
21
|
-
outline: "border bg-background text-foreground hover:bg-accent hover:text-accent-foreground active:bg-accent/80 active:scale-[0.98] dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:active:bg-input/60",
|
|
22
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]",
|
|
23
|
-
ghost: "hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:scale-[0.98] dark:hover:bg-accent/50 dark:active:bg-accent/40",
|
|
24
|
-
link: "text-primary underline-offset-4 hover:underline active:text-primary/80"
|
|
25
|
-
},
|
|
26
|
-
size: {
|
|
27
|
-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
28
|
-
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
29
|
-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
30
|
-
icon: "size-9 rounded-md"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
defaultVariants: {
|
|
34
|
-
variant: "default",
|
|
35
|
-
size: "default"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
var Button = React.forwardRef(function Button2({ className, variant, size, asChild = false, ...props }, ref) {
|
|
40
|
-
const Comp = asChild ? Slot : "button";
|
|
41
|
-
return /* @__PURE__ */ jsx(
|
|
42
|
-
Comp,
|
|
43
|
-
{
|
|
44
|
-
ref,
|
|
45
|
-
"data-slot": "button",
|
|
46
|
-
className: cn(buttonVariants({ variant, size }), className),
|
|
47
|
-
...props
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
});
|
|
51
|
-
Button.displayName = "Button";
|
|
52
|
-
function FilePickerField({
|
|
53
|
-
label,
|
|
54
|
-
actionLabel,
|
|
55
|
-
description,
|
|
56
|
-
selectedLabel,
|
|
57
|
-
accept,
|
|
58
|
-
multiple = false,
|
|
59
|
-
disabled = false,
|
|
60
|
-
variant = "card",
|
|
61
|
-
icon,
|
|
62
|
-
className,
|
|
63
|
-
triggerClassName,
|
|
64
|
-
inputClassName,
|
|
65
|
-
title,
|
|
66
|
-
onFilesSelected
|
|
67
|
-
}) {
|
|
68
|
-
const inputRef = useRef(null);
|
|
69
|
-
const triggerLabel = selectedLabel ?? actionLabel ?? (multiple ? "Choose files" : "Choose file");
|
|
70
|
-
const fallbackIcon = variant === "card" ? /* @__PURE__ */ jsx(Upload, { size: 16, className: "text-muted-foreground" }) : /* @__PURE__ */ jsx(Paperclip, { size: 13 });
|
|
71
|
-
const handleFiles = (files) => {
|
|
72
|
-
if (disabled) return;
|
|
73
|
-
onFilesSelected(files);
|
|
74
|
-
if (inputRef.current) inputRef.current.value = "";
|
|
75
|
-
};
|
|
76
|
-
const input = /* @__PURE__ */ jsx(
|
|
77
|
-
"input",
|
|
78
|
-
{
|
|
79
|
-
ref: inputRef,
|
|
80
|
-
type: "file",
|
|
81
|
-
accept,
|
|
82
|
-
multiple,
|
|
83
|
-
disabled,
|
|
84
|
-
className: cn("hidden", inputClassName),
|
|
85
|
-
onChange: (event) => handleFiles(event.target.files)
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
-
if (variant === "button") {
|
|
89
|
-
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
90
|
-
input,
|
|
91
|
-
/* @__PURE__ */ jsxs(
|
|
92
|
-
Button,
|
|
93
|
-
{
|
|
94
|
-
type: "button",
|
|
95
|
-
variant: "outline",
|
|
96
|
-
disabled,
|
|
97
|
-
title,
|
|
98
|
-
className: triggerClassName,
|
|
99
|
-
onClick: () => inputRef.current?.click(),
|
|
100
|
-
children: [
|
|
101
|
-
icon ?? fallbackIcon,
|
|
102
|
-
triggerLabel
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
)
|
|
106
|
-
] });
|
|
107
|
-
}
|
|
108
|
-
if (variant === "inline") {
|
|
109
|
-
return /* @__PURE__ */ jsxs("span", { className, children: [
|
|
110
|
-
input,
|
|
111
|
-
/* @__PURE__ */ jsxs(
|
|
112
|
-
"button",
|
|
113
|
-
{
|
|
114
|
-
type: "button",
|
|
115
|
-
disabled,
|
|
116
|
-
title,
|
|
117
|
-
className: cn(
|
|
118
|
-
"inline-flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-blue-600 disabled:pointer-events-none disabled:text-muted-foreground/60 dark:text-blue-400",
|
|
119
|
-
triggerClassName
|
|
120
|
-
),
|
|
121
|
-
onClick: () => inputRef.current?.click(),
|
|
122
|
-
children: [
|
|
123
|
-
icon ?? fallbackIcon,
|
|
124
|
-
triggerLabel
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
] });
|
|
129
|
-
}
|
|
130
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
131
|
-
label ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-widest text-muted-foreground", children: label }) : null,
|
|
132
|
-
input,
|
|
133
|
-
/* @__PURE__ */ jsxs(
|
|
134
|
-
"button",
|
|
135
|
-
{
|
|
136
|
-
type: "button",
|
|
137
|
-
disabled,
|
|
138
|
-
title,
|
|
139
|
-
className: cn(
|
|
140
|
-
"flex cursor-pointer flex-col items-center justify-center rounded-lg border border-dashed border-border bg-muted/80 px-4 py-6 text-center transition-colors hover:border-border hover:bg-accent disabled:pointer-events-none disabled:opacity-60",
|
|
141
|
-
triggerClassName
|
|
142
|
-
),
|
|
143
|
-
onClick: () => inputRef.current?.click(),
|
|
144
|
-
onDragOver: (event) => {
|
|
145
|
-
if (disabled) return;
|
|
146
|
-
event.preventDefault();
|
|
147
|
-
},
|
|
148
|
-
onDrop: (event) => {
|
|
149
|
-
if (disabled) return;
|
|
150
|
-
event.preventDefault();
|
|
151
|
-
handleFiles(event.dataTransfer.files);
|
|
152
|
-
},
|
|
153
|
-
children: [
|
|
154
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 flex size-8 items-center justify-center rounded-lg bg-muted", children: icon ?? fallbackIcon }),
|
|
155
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: triggerLabel }),
|
|
156
|
-
description ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-[10px] text-muted-foreground", children: description }) : null
|
|
157
|
-
]
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
] });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export { FilePickerField };
|
|
1
|
+
export { FilePickerField } from './chunk-OMSJWTSZ.js';
|
|
2
|
+
import './chunk-VHINHHZQ.js';
|
|
3
|
+
import './chunk-DMPSQ22Q.js';
|
|
164
4
|
//# sourceMappingURL=file-picker-field.js.map
|
|
165
5
|
//# sourceMappingURL=file-picker-field.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/utils.ts","../src/ui/button.tsx","../src/files/file-picker-field.tsx"],"names":["Button","jsx"],"mappings":"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","file":"file-picker-field.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"./utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-all disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 active:bg-destructive/80 active:scale-[0.98] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 dark:active:bg-destructive/70\",\n outline:\n \"border bg-background text-foreground hover:bg-accent hover:text-accent-foreground active:bg-accent/80 active:scale-[0.98] dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:active:bg-input/60\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:scale-[0.98] dark:hover:bg-accent/50 dark:active:bg-accent/40\",\n link: \"text-primary underline-offset-4 hover:underline active:text-primary/80\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9 rounded-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }\n>(function Button({ className, variant, size, asChild = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n});\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import { useRef, type ReactNode } from \"react\";\nimport { Paperclip, Upload } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../ui/utils\";\n\nexport type FilePickerFieldVariant = \"card\" | \"button\" | \"inline\";\n\nexport interface FilePickerFieldProps {\n label?: string;\n actionLabel?: string;\n description?: string;\n selectedLabel?: string;\n accept?: string;\n multiple?: boolean;\n disabled?: boolean;\n variant?: FilePickerFieldVariant;\n icon?: ReactNode;\n className?: string;\n triggerClassName?: string;\n inputClassName?: string;\n title?: string;\n onFilesSelected: (files: FileList | null) => void;\n}\n\nexport function FilePickerField({\n label,\n actionLabel,\n description,\n selectedLabel,\n accept,\n multiple = false,\n disabled = false,\n variant = \"card\",\n icon,\n className,\n triggerClassName,\n inputClassName,\n title,\n onFilesSelected,\n}: FilePickerFieldProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const triggerLabel = selectedLabel ?? actionLabel ?? (multiple ? \"Choose files\" : \"Choose file\");\n const fallbackIcon = variant === \"card\" ? (\n <Upload size={16} className=\"text-muted-foreground\" />\n ) : (\n <Paperclip size={13} />\n );\n\n const handleFiles = (files: FileList | null) => {\n if (disabled) return;\n onFilesSelected(files);\n if (inputRef.current) inputRef.current.value = \"\";\n };\n\n const input = (\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className={cn(\"hidden\", inputClassName)}\n onChange={(event) => handleFiles(event.target.files)}\n />\n );\n\n if (variant === \"button\") {\n return (\n <div className={className}>\n {input}\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={disabled}\n title={title}\n className={triggerClassName}\n onClick={() => inputRef.current?.click()}\n >\n {icon ?? fallbackIcon}\n {triggerLabel}\n </Button>\n </div>\n );\n }\n\n if (variant === \"inline\") {\n return (\n <span className={className}>\n {input}\n <button\n type=\"button\"\n disabled={disabled}\n title={title}\n className={cn(\n \"inline-flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-blue-600 disabled:pointer-events-none disabled:text-muted-foreground/60 dark:text-blue-400\",\n triggerClassName,\n )}\n onClick={() => inputRef.current?.click()}\n >\n {icon ?? fallbackIcon}\n {triggerLabel}\n </button>\n </span>\n );\n }\n\n return (\n <div className={cn(\"flex flex-col gap-1.5\", className)}>\n {label ? (\n <span className=\"text-[10px] font-medium uppercase tracking-widest text-muted-foreground\">\n {label}\n </span>\n ) : null}\n {input}\n <button\n type=\"button\"\n disabled={disabled}\n title={title}\n className={cn(\n \"flex cursor-pointer flex-col items-center justify-center rounded-lg border border-dashed border-border bg-muted/80 px-4 py-6 text-center transition-colors hover:border-border hover:bg-accent disabled:pointer-events-none disabled:opacity-60\",\n triggerClassName,\n )}\n onClick={() => inputRef.current?.click()}\n onDragOver={(event) => {\n if (disabled) return;\n event.preventDefault();\n }}\n onDrop={(event) => {\n if (disabled) return;\n event.preventDefault();\n handleFiles(event.dataTransfer.files);\n }}\n >\n <span className=\"mb-1 flex size-8 items-center justify-center rounded-lg bg-muted\">\n {icon ?? fallbackIcon}\n </span>\n <span className=\"text-xs font-medium text-muted-foreground\">{triggerLabel}</span>\n {description ? (\n <span className=\"mt-0.5 text-[10px] text-muted-foreground\">{description}</span>\n ) : null}\n </button>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"file-picker-field.js"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
interface FileViewerFile {
|
|
4
4
|
name: string;
|
|
@@ -10,6 +10,6 @@ declare function FileViewerDialog({ file, open, onOpenChange, }: {
|
|
|
10
10
|
file: FileViewerFile | null;
|
|
11
11
|
open: boolean;
|
|
12
12
|
onOpenChange: (open: boolean) => void;
|
|
13
|
-
}):
|
|
13
|
+
}): React.JSX.Element;
|
|
14
14
|
|
|
15
15
|
export { FileViewerDialog, type FileViewerFile };
|
|
@@ -1,229 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ResponsiveDialog, ResponsiveDialogContent, ResponsiveDialogTitle } from './chunk-4A6RCBB5.js';
|
|
2
|
+
import './chunk-RV5PMZYZ.js';
|
|
3
|
+
import './chunk-L65F4EMK.js';
|
|
4
|
+
import './chunk-PBNBLCC2.js';
|
|
5
|
+
import './chunk-VVXGQKN7.js';
|
|
6
|
+
import './chunk-7YCAAP43.js';
|
|
7
|
+
import './chunk-LUB7QWGU.js';
|
|
8
|
+
import { Button } from './chunk-VHINHHZQ.js';
|
|
9
|
+
import './chunk-FCY5FYJB.js';
|
|
10
|
+
import './chunk-OWNUMPUC.js';
|
|
11
|
+
import './chunk-DMPSQ22Q.js';
|
|
2
12
|
import { useState, useRef, useEffect, useMemo } from 'react';
|
|
3
|
-
import { Minus, Plus, RotateCcw, Download, ExternalLink, FileText
|
|
4
|
-
import { clsx } from 'clsx';
|
|
5
|
-
import { twMerge } from 'tailwind-merge';
|
|
6
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
7
|
-
import { cva } from 'class-variance-authority';
|
|
13
|
+
import { Minus, Plus, RotateCcw, Download, ExternalLink, FileText } from 'lucide-react';
|
|
8
14
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
9
|
-
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
10
|
-
import { Drawer as Drawer$1 } from 'vaul';
|
|
11
15
|
|
|
12
|
-
// src/files/file-viewer-dialog.tsx
|
|
13
|
-
function cn(...inputs) {
|
|
14
|
-
return twMerge(clsx(inputs));
|
|
15
|
-
}
|
|
16
|
-
var buttonVariants = cva(
|
|
17
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-all disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
18
|
-
{
|
|
19
|
-
variants: {
|
|
20
|
-
variant: {
|
|
21
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]",
|
|
22
|
-
destructive: "bg-destructive text-white hover:bg-destructive/90 active:bg-destructive/80 active:scale-[0.98] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 dark:active:bg-destructive/70",
|
|
23
|
-
outline: "border bg-background text-foreground hover:bg-accent hover:text-accent-foreground active:bg-accent/80 active:scale-[0.98] dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:active:bg-input/60",
|
|
24
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]",
|
|
25
|
-
ghost: "hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:scale-[0.98] dark:hover:bg-accent/50 dark:active:bg-accent/40",
|
|
26
|
-
link: "text-primary underline-offset-4 hover:underline active:text-primary/80"
|
|
27
|
-
},
|
|
28
|
-
size: {
|
|
29
|
-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
30
|
-
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
31
|
-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
32
|
-
icon: "size-9 rounded-md"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
defaultVariants: {
|
|
36
|
-
variant: "default",
|
|
37
|
-
size: "default"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
var Button = React3.forwardRef(function Button2({ className, variant, size, asChild = false, ...props }, ref) {
|
|
42
|
-
const Comp = asChild ? Slot : "button";
|
|
43
|
-
return /* @__PURE__ */ jsx(
|
|
44
|
-
Comp,
|
|
45
|
-
{
|
|
46
|
-
ref,
|
|
47
|
-
"data-slot": "button",
|
|
48
|
-
className: cn(buttonVariants({ variant, size }), className),
|
|
49
|
-
...props
|
|
50
|
-
}
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
Button.displayName = "Button";
|
|
54
|
-
function Dialog({ ...props }) {
|
|
55
|
-
return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
56
|
-
}
|
|
57
|
-
function DialogPortal({ ...props }) {
|
|
58
|
-
return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
59
|
-
}
|
|
60
|
-
function DialogOverlay({
|
|
61
|
-
className,
|
|
62
|
-
...props
|
|
63
|
-
}) {
|
|
64
|
-
return /* @__PURE__ */ jsx(
|
|
65
|
-
DialogPrimitive.Overlay,
|
|
66
|
-
{
|
|
67
|
-
"data-slot": "dialog-overlay",
|
|
68
|
-
className: cn(
|
|
69
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
70
|
-
className
|
|
71
|
-
),
|
|
72
|
-
...props
|
|
73
|
-
}
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
function DialogContent({
|
|
77
|
-
className,
|
|
78
|
-
children,
|
|
79
|
-
...props
|
|
80
|
-
}) {
|
|
81
|
-
return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
82
|
-
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
83
|
-
/* @__PURE__ */ jsxs(
|
|
84
|
-
DialogPrimitive.Content,
|
|
85
|
-
{
|
|
86
|
-
"data-slot": "dialog-content",
|
|
87
|
-
className: cn(
|
|
88
|
-
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
89
|
-
className
|
|
90
|
-
),
|
|
91
|
-
...props,
|
|
92
|
-
children: [
|
|
93
|
-
children,
|
|
94
|
-
/* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
|
|
95
|
-
/* @__PURE__ */ jsx(XIcon, {}),
|
|
96
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
97
|
-
] })
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
)
|
|
101
|
-
] });
|
|
102
|
-
}
|
|
103
|
-
function DialogTitle({ className, ...props }) {
|
|
104
|
-
return /* @__PURE__ */ jsx(
|
|
105
|
-
DialogPrimitive.Title,
|
|
106
|
-
{
|
|
107
|
-
"data-slot": "dialog-title",
|
|
108
|
-
className: cn("text-lg leading-none font-semibold", className),
|
|
109
|
-
...props
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
function Drawer({ ...props }) {
|
|
114
|
-
return /* @__PURE__ */ jsx(Drawer$1.Root, { "data-slot": "drawer", ...props });
|
|
115
|
-
}
|
|
116
|
-
function DrawerPortal({ ...props }) {
|
|
117
|
-
return /* @__PURE__ */ jsx(Drawer$1.Portal, { "data-slot": "drawer-portal", ...props });
|
|
118
|
-
}
|
|
119
|
-
function DrawerOverlay({
|
|
120
|
-
className,
|
|
121
|
-
...props
|
|
122
|
-
}) {
|
|
123
|
-
return /* @__PURE__ */ jsx(
|
|
124
|
-
Drawer$1.Overlay,
|
|
125
|
-
{
|
|
126
|
-
"data-slot": "drawer-overlay",
|
|
127
|
-
className: cn(
|
|
128
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
129
|
-
className
|
|
130
|
-
),
|
|
131
|
-
...props
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
function DrawerContent({
|
|
136
|
-
className,
|
|
137
|
-
children,
|
|
138
|
-
...props
|
|
139
|
-
}) {
|
|
140
|
-
return /* @__PURE__ */ jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [
|
|
141
|
-
/* @__PURE__ */ jsx(DrawerOverlay, {}),
|
|
142
|
-
/* @__PURE__ */ jsxs(
|
|
143
|
-
Drawer$1.Content,
|
|
144
|
-
{
|
|
145
|
-
"data-slot": "drawer-content",
|
|
146
|
-
className: cn(
|
|
147
|
-
"group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
|
|
148
|
-
"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
|
|
149
|
-
"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
|
|
150
|
-
"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
|
|
151
|
-
"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
|
|
152
|
-
className
|
|
153
|
-
),
|
|
154
|
-
...props,
|
|
155
|
-
children: [
|
|
156
|
-
/* @__PURE__ */ jsx("div", { className: "bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
|
|
157
|
-
children
|
|
158
|
-
]
|
|
159
|
-
}
|
|
160
|
-
)
|
|
161
|
-
] });
|
|
162
|
-
}
|
|
163
|
-
function DrawerTitle({ className, ...props }) {
|
|
164
|
-
return /* @__PURE__ */ jsx(
|
|
165
|
-
Drawer$1.Title,
|
|
166
|
-
{
|
|
167
|
-
"data-slot": "drawer-title",
|
|
168
|
-
className: cn("text-foreground font-semibold", className),
|
|
169
|
-
...props
|
|
170
|
-
}
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
var MOBILE_BREAKPOINT = 768;
|
|
174
|
-
function useIsMobile() {
|
|
175
|
-
const [isMobile, setIsMobile] = React3.useState(void 0);
|
|
176
|
-
React3.useEffect(() => {
|
|
177
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
178
|
-
const onChange = () => {
|
|
179
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
180
|
-
};
|
|
181
|
-
mql.addEventListener("change", onChange);
|
|
182
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
183
|
-
return () => mql.removeEventListener("change", onChange);
|
|
184
|
-
}, []);
|
|
185
|
-
return !!isMobile;
|
|
186
|
-
}
|
|
187
|
-
var ResponsiveDialogContext = React3.createContext({
|
|
188
|
-
drawer: false
|
|
189
|
-
});
|
|
190
|
-
var drawerContentShell = "w-full min-w-0 !max-w-none left-0 right-0 gap-0 border-border bg-card p-0 rounded-t-xl text-foreground shadow-xl pb-[max(1rem,env(safe-area-inset-bottom))] max-h-[min(90vh,90dvh)] z-[60] overflow-hidden";
|
|
191
|
-
function ResponsiveDialog({ children, ...props }) {
|
|
192
|
-
const drawer = useIsMobile();
|
|
193
|
-
return /* @__PURE__ */ jsx(ResponsiveDialogContext.Provider, { value: { drawer }, children: drawer ? /* @__PURE__ */ jsx(
|
|
194
|
-
Drawer,
|
|
195
|
-
{
|
|
196
|
-
repositionInputs: false,
|
|
197
|
-
open: props.open,
|
|
198
|
-
onOpenChange: props.onOpenChange,
|
|
199
|
-
defaultOpen: props.defaultOpen,
|
|
200
|
-
children
|
|
201
|
-
}
|
|
202
|
-
) : /* @__PURE__ */ jsx(Dialog, { ...props, children }) });
|
|
203
|
-
}
|
|
204
|
-
function ResponsiveDialogContent({ className, children, ...props }) {
|
|
205
|
-
const { drawer } = React3.useContext(ResponsiveDialogContext);
|
|
206
|
-
if (drawer) {
|
|
207
|
-
const {
|
|
208
|
-
onOpenAutoFocus,
|
|
209
|
-
onCloseAutoFocus,
|
|
210
|
-
onEscapeKeyDown,
|
|
211
|
-
onPointerDownOutside,
|
|
212
|
-
onInteractOutside,
|
|
213
|
-
forceMount,
|
|
214
|
-
...drawerRest
|
|
215
|
-
} = props;
|
|
216
|
-
return /* @__PURE__ */ jsx(DrawerContent, { className: cn(drawerContentShell, className, "!w-full"), ...drawerRest, children });
|
|
217
|
-
}
|
|
218
|
-
return /* @__PURE__ */ jsx(DialogContent, { className, ...props, children });
|
|
219
|
-
}
|
|
220
|
-
function ResponsiveDialogTitle({ className, ...props }) {
|
|
221
|
-
const { drawer } = React3.useContext(ResponsiveDialogContext);
|
|
222
|
-
if (drawer) {
|
|
223
|
-
return /* @__PURE__ */ jsx(DrawerTitle, { className: cn("text-lg leading-none font-semibold", className), ...props });
|
|
224
|
-
}
|
|
225
|
-
return /* @__PURE__ */ jsx(DialogTitle, { className, ...props });
|
|
226
|
-
}
|
|
227
16
|
function FileViewerDialog({
|
|
228
17
|
file,
|
|
229
18
|
open,
|