@spacesync/client 0.1.0 → 0.1.2
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 +7 -4
- package/dist/image-picker-field.js +17 -60
- 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/shell/page-list-sticky-columns.ts","../src/shell/shell-top-bar-chrome.ts","../src/ui/button.tsx","../src/ui/input.tsx","../src/ui/search-field.tsx","../src/ui/pagination.tsx","../src/ui/select.tsx","../src/shell/page-list-chrome.tsx"],"names":["Button","cva","React2","Input","jsx","jsxs"],"mappings":"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","file":"page-list-chrome.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 { cn } from \"../ui/utils\";\n\nexport type PageListColumnFixed = \"left\" | \"right\";\n\nexport type PageListStickyColumnOptions = {\n side: PageListColumnFixed;\n layer: \"head\" | \"body\";\n sortActive?: boolean;\n};\n\nconst leftEdgeShadow = cn(\n \"after:pointer-events-none after:absolute after:inset-y-0 after:right-0 after:w-3 after:translate-x-full\",\n \"after:bg-gradient-to-r after:from-black/[0.06] after:to-transparent dark:after:from-black/20\",\n \"after:opacity-0 after:transition-opacity\",\n \"group-data-[scrolled-x=true]/table-scroll:after:opacity-100\",\n);\n\nconst rightEdgeShadow = cn(\n \"before:pointer-events-none before:absolute before:inset-y-0 before:left-0 before:w-3 before:-translate-x-full\",\n \"before:bg-gradient-to-l before:from-black/[0.06] before:to-transparent dark:before:from-black/20\",\n \"before:opacity-0 before:transition-opacity\",\n \"group-data-[scrolled-x-end=false]/table-scroll:before:opacity-100\",\n);\n\n/** Sticky left/right column classes for horizontally scrollable list tables (antd-style). */\nexport function pageListStickyColumnClass({\n side,\n layer,\n sortActive = false,\n}: PageListStickyColumnOptions): string {\n const isHead = layer === \"head\";\n const pin = side === \"left\" ? \"left-0\" : \"right-0\";\n const edgeShadow = side === \"left\" ? leftEdgeShadow : rightEdgeShadow;\n\n return cn(\n \"relative sticky\",\n pin,\n isHead ? \"top-0 z-[3]\" : \"z-[1]\",\n sortActive\n ? \"bg-blue-50/80 dark:bg-blue-950/40\"\n : isHead\n ? \"bg-card\"\n : \"bg-card group-hover:bg-accent\",\n edgeShadow,\n );\n}\n\n/** Use on tables with fixed columns instead of border-collapse. */\nexport const pageListTableWithFixedColumnsClass = \"border-separate border-spacing-0\";\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 * 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 * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"./utils\";\n\nconst inputVariants = cva(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground border-border bg-card text-foreground flex w-full min-w-0 rounded-md border px-3 py-1 text-base transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:border-blue-400 focus-visible:ring-[3px] focus-visible:ring-blue-500/25 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-red-400 aria-invalid:ring-red-500/20 md:text-sm\",\n {\n variants: {\n size: {\n sm: \"h-8 text-sm\",\n default: \"h-9\",\n lg: \"h-10\",\n xl: \"h-11\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n },\n);\n\nconst Input = React.forwardRef<\n HTMLInputElement,\n Omit<React.ComponentProps<\"input\">, \"size\"> & VariantProps<typeof inputVariants>\n>(function Input({ className, type, size, ...props }, ref) {\n return (\n <input\n ref={ref}\n type={type}\n data-slot=\"input\"\n className={cn(inputVariants({ size }), className)}\n {...props}\n />\n );\n});\n\nexport { Input, inputVariants };\n","import { Search } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\nimport { Input } from \"./input\";\n\nexport function SearchField({\n value,\n onChange,\n placeholder,\n className,\n size = \"default\",\n \"aria-label\": ariaLabel,\n}: {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n className?: string;\n size?: \"default\" | \"lg\";\n \"aria-label\"?: string;\n}) {\n const heightClass = size === \"lg\" ? \"h-11\" : \"h-10\";\n const iconSize = size === \"lg\" ? 16 : 16;\n\n return (\n <div\n className={cn(\n \"flex items-center gap-2 rounded-md border border-border bg-card px-3 w-full focus-within:border-blue-400 focus-within:ring-[3px] focus-within:ring-blue-500/25 transition-all\",\n heightClass,\n className,\n )}\n >\n <Search size={iconSize} className=\"text-muted-foreground shrink-0\" strokeWidth={2.25} />\n <Input\n type=\"search\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n aria-label={ariaLabel}\n className=\"flex-1 border-0 bg-transparent shadow-none focus-visible:ring-0 px-0 min-w-0 h-auto\"\n />\n </div>\n );\n}\n","import * as React from \"react\";\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\nimport { Button, buttonVariants } from \"./button\";\n\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationContent({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">;\n\nfunction PaginationLink({ className, isActive, size = \"icon\", ...props }: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">Previous</span>\n </PaginationLink>\n );\n}\n\nfunction PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pr-2.5\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">Next</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"border border-border bg-card data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground hover:border-border focus-visible:border-blue-400 focus-visible:ring-blue-500/25 aria-invalid:border-red-400 aria-invalid:ring-red-500/20 dark:bg-input/30 dark:hover:bg-input/50 flex w-full items-center justify-between gap-2 rounded-md px-3 py-2 text-sm whitespace-nowrap transition-[color,box-shadow,border-color] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"popper\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-white/10 shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-card/10 focus:text-popover-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"bg-card/10 pointer-events-none -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","import { useEffect, useRef, type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronUp, ChevronsUpDown } from \"lucide-react\";\nimport type { SortDirection } from \"../hooks/use-client-sort\";\nimport {\n pageListStickyColumnClass,\n pageListTableWithFixedColumnsClass,\n type PageListColumnFixed,\n} from \"./page-list-sticky-columns\";\nexport {\n pageListStickyColumnClass,\n pageListTableWithFixedColumnsClass,\n type PageListColumnFixed,\n} from \"./page-list-sticky-columns\";\nimport {\n shellTopBarNeutralActionDataAttr,\n shellTopBarOutlineButtonClass,\n shellTopBarPrimaryButtonClass,\n} from \"./shell-top-bar-chrome\";\nimport { cn } from \"../ui/utils\";\nimport { Button } from \"../ui/button\";\nimport { SearchField } from \"../ui/search-field\";\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"../ui/pagination\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport type { UseClientPaginationResult } from \"../hooks/use-client-pagination\";\n\n/** Fills the app main pane (white card on grey chrome). */\nexport function PageListRoot({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div className={cn(\"h-full flex flex-col min-h-0 bg-card\", className)} {...props} />\n );\n}\n\n/** White header block under the app chrome. */\nexport function PageListHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"shrink-0 bg-card border-b border-border px-5 pt-4 pb-4\", className)}\n {...props}\n />\n );\n}\n\nexport function PageListTitleRow({\n title,\n subtitle,\n actions,\n titleAddon,\n}: {\n title: ReactNode;\n subtitle?: string;\n actions?: ReactNode;\n /** Rendered before the title (e.g. live indicator). */\n titleAddon?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div>\n {titleAddon ? (\n <div className=\"flex items-center gap-2 mb-1\">\n {titleAddon}\n <h1 className=\"text-base font-semibold text-foreground\">{title}</h1>\n </div>\n ) : (\n <h1 className=\"text-base font-semibold text-foreground\">{title}</h1>\n )}\n {subtitle ? <p className=\"text-xs text-muted-foreground mt-1\">{subtitle}</p> : null}\n </div>\n {actions ? (\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">{actions}</div>\n ) : null}\n </div>\n );\n}\n\n/** Primary CTA in a page list header (e.g. New announcement). */\nexport function PageListPrimaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n className={cn(\n \"h-9 gap-1.5 rounded-xl bg-blue-500 px-4 text-sm font-medium text-white hover:bg-blue-600\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Secondary CTA for empty states and alternate actions. */\nexport function PageListSecondaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\n \"h-9 gap-1.5 rounded-xl border-border bg-card px-4 text-sm font-medium text-foreground hover:bg-accent\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Primary CTA rendered in {@link ShellTopBar} actions on the dark shell. */\nexport function ShellTopBarPrimaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button type=\"button\" size=\"sm\" className={cn(shellTopBarPrimaryButtonClass, className)} {...props} />\n );\n}\n\n/** Secondary / outline CTA in {@link ShellTopBar} — same chrome as detail header actions (Edit member, Add adjustment). */\nexport function ShellTopBarSecondaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className={cn(shellTopBarOutlineButtonClass, className)}\n {...props}\n />\n );\n}\n\nexport { shellTopBarNeutralActionDataAttr };\n\n/** Search, filters, or secondary controls (spacing matches Live space). */\nexport function PageListToolbar({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"mt-4 flex flex-col gap-3 items-start\", className)} {...props} />;\n}\n\n/** Compact KPI tiles (Live space stat row). */\nexport function PageListStatGrid({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"mt-4 grid grid-cols-2 gap-2 sm:grid-cols-4\", className)}\n {...props}\n />\n );\n}\n\nexport type PageListStatTone = \"default\" | \"danger\" | \"success\";\n\nexport function PageListStatCard({\n label,\n value,\n tone = \"default\",\n}: {\n label: string;\n value: ReactNode;\n tone?: PageListStatTone;\n}) {\n const shell =\n tone === \"danger\"\n ? \"border-red-100 bg-red-50/80\"\n : tone === \"success\"\n ? \"border-emerald-100 bg-emerald-50/80\"\n : \"border-border bg-muted\";\n const labelClass =\n tone === \"danger\"\n ? \"text-red-600/80\"\n : tone === \"success\"\n ? \"text-emerald-700/80\"\n : \"text-muted-foreground\";\n const valueClass =\n tone === \"danger\" ? \"text-red-700\" : tone === \"success\" ? \"text-emerald-800\" : \"text-foreground\";\n\n return (\n <div className={cn(\"rounded-lg border px-3 py-2\", shell)}>\n <p className={cn(\"text-[11px] mb-0.5\", labelClass)}>{label}</p>\n <p className={cn(\"text-sm font-semibold tabular-nums\", valueClass)}>{value}</p>\n </div>\n );\n}\n\n/** Scrollable white region for tables / lists. Stay flush horizontally; table cells provide inset (same as Live space). */\nexport function PageListTableArea({ className, ...props }: React.ComponentProps<\"div\">) {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const syncScrollState = () => {\n if (el.scrollLeft > 0) {\n el.dataset.scrolledX = \"true\";\n } else {\n delete el.dataset.scrolledX;\n }\n\n const atRightEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;\n if (!atRightEnd && el.scrollWidth > el.clientWidth) {\n el.dataset.scrolledXEnd = \"false\";\n } else {\n delete el.dataset.scrolledXEnd;\n }\n };\n\n syncScrollState();\n el.addEventListener(\"scroll\", syncScrollState, { passive: true });\n const resizeObserver = new ResizeObserver(syncScrollState);\n resizeObserver.observe(el);\n if (el.firstElementChild) {\n resizeObserver.observe(el.firstElementChild);\n }\n\n return () => {\n el.removeEventListener(\"scroll\", syncScrollState);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <div\n ref={ref}\n className={cn(\n \"group/table-scroll flex-1 min-h-0 overflow-auto bg-card border-t border-border\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Search input styling shared with Live space. */\nexport function PageListSearchField({\n value,\n onChange,\n placeholder,\n className,\n}: {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n className?: string;\n}) {\n return (\n <SearchField\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n className={className}\n />\n );\n}\n\n/** Sticky table header row (Live space). */\nexport function PageListStickyThead({ children }: { children: ReactNode }) {\n return (\n <thead className=\"sticky top-0 z-[2] bg-card shadow-[0_1px_0_0_var(--border)]\">\n {children}\n </thead>\n );\n}\n\n/** Non-sticky thead for embedded detail tables. */\nexport function PageListThead({ className, ...props }: React.ComponentProps<\"thead\">) {\n return <thead className={cn(\"border-b border-border\", className)} {...props} />;\n}\n\n/** Standard `<table>` shell for list and detail tables. */\nexport function PageListTable({\n minWidth,\n fixedColumns = false,\n compact = false,\n className,\n style,\n ...props\n}: React.ComponentProps<\"table\"> & {\n minWidth?: number;\n fixedColumns?: boolean;\n compact?: boolean;\n}) {\n return (\n <table\n className={cn(\n \"w-full text-left text-sm\",\n fixedColumns ? pageListTableWithFixedColumnsClass : \"border-collapse\",\n compact && \"border-collapse\",\n className,\n )}\n style={minWidth != null ? { ...style, minWidth: `${minWidth}px` } : style}\n {...props}\n />\n );\n}\n\n/** Standard header row styling for column labels. */\nexport function PageListHeaderRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n className={cn(\"text-[10px] uppercase tracking-wide text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport type PageListTdTone = \"default\" | \"primary\" | \"muted\" | \"mono\";\nexport type PageListCellSize = \"default\" | \"comfortable\";\n\nconst pageListTdToneClass: Record<PageListTdTone, string> = {\n default: \"text-xs text-foreground\",\n primary: \"text-xs font-medium text-foreground\",\n muted: \"text-xs text-muted-foreground\",\n mono: \"text-xs font-mono text-muted-foreground\",\n};\n\nconst pageListTdSizeClass: Record<PageListCellSize, string> = {\n default: \"px-2 py-2.5 first:pl-5 last:pr-5\",\n comfortable: \"px-5 py-3.5 first:pl-5 last:pr-5\",\n};\n\n/** Standard data row — border, hover, optional click navigation. */\nexport function PageListTr({\n onClick,\n selected = false,\n className,\n onKeyDown,\n ...props\n}: React.ComponentProps<\"tr\"> & {\n onClick?: () => void;\n selected?: boolean;\n}) {\n const clickable = Boolean(onClick);\n\n return (\n <tr\n role={clickable ? \"link\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n clickable && onClick\n ? (e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : onKeyDown\n }\n className={cn(\n \"border-b border-border last:border-0 transition-colors\",\n clickable &&\n \"group cursor-pointer hover:bg-accent outline-none focus-visible:ring-2 focus-visible:ring-blue-400 focus-visible:ring-inset\",\n selected && \"bg-accent/60\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport const pageListThClass =\n \"font-medium py-2.5 px-2 text-left text-[10px] uppercase tracking-wide text-muted-foreground first:pl-5 last:pr-5\";\n\nexport const pageListTdClass = pageListTdSizeClass.default;\n\nexport function PageListTh({\n children,\n columnFixed,\n align = \"left\",\n className,\n ...props\n}: React.ComponentProps<\"th\"> & {\n columnFixed?: PageListColumnFixed;\n align?: \"left\" | \"right\";\n}) {\n return (\n <th\n className={cn(\n pageListThClass,\n align === \"right\" && \"text-right\",\n columnFixed &&\n pageListStickyColumnClass({ side: columnFixed, layer: \"head\" }),\n className,\n )}\n {...props}\n >\n {children}\n </th>\n );\n}\n\nexport function PageListTd({\n children,\n columnFixed,\n align = \"left\",\n tone = \"default\",\n size = \"default\",\n className,\n ...props\n}: React.ComponentProps<\"td\"> & {\n columnFixed?: PageListColumnFixed;\n align?: \"left\" | \"right\";\n tone?: PageListTdTone;\n size?: PageListCellSize;\n}) {\n return (\n <td\n className={cn(\n pageListTdSizeClass[size],\n pageListTdToneClass[tone],\n tone === \"mono\" && align === \"right\" && \"font-medium text-foreground\",\n align === \"right\" && \"text-right\",\n columnFixed &&\n pageListStickyColumnClass({ side: columnFixed, layer: \"body\" }),\n className,\n )}\n {...props}\n >\n {children}\n </td>\n );\n}\n\nexport function PageListSortableTh<K extends string>({\n label,\n columnKey,\n sortKey,\n direction,\n onSort,\n align = \"left\",\n columnFixed,\n className,\n}: {\n label: ReactNode;\n columnKey: K;\n sortKey: K;\n direction: SortDirection;\n onSort: (key: K) => void;\n align?: \"left\" | \"right\";\n columnFixed?: PageListColumnFixed;\n className?: string;\n}) {\n const active = sortKey === columnKey;\n const ariaSort = active ? (direction === \"asc\" ? \"ascending\" : \"descending\") : undefined;\n const DirectionIcon = direction === \"asc\" ? ChevronUp : ChevronDown;\n\n return (\n <th\n className={cn(\n pageListThClass,\n align === \"right\" && \"text-right\",\n active &&\n \"text-blue-700 shadow-[inset_0_-2px_0_0_rgb(59,130,246)] dark:text-blue-300\",\n columnFixed &&\n pageListStickyColumnClass({\n side: columnFixed,\n layer: \"head\",\n sortActive: active,\n }),\n !columnFixed &&\n active &&\n \"bg-blue-50/80 dark:bg-blue-950/40\",\n className,\n )}\n aria-sort={ariaSort}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => onSort(columnKey)}\n className={cn(\n \"group inline-flex h-auto w-full gap-1 rounded-none border-0 p-0 shadow-none\",\n \"text-[10px] font-medium uppercase tracking-wide\",\n \"hover:bg-transparent\",\n active\n ? \"text-blue-700 dark:text-blue-300\"\n : \"text-muted-foreground hover:text-foreground\",\n align === \"right\" ? \"justify-end\" : \"justify-start\",\n )}\n >\n <span>{label}</span>\n {active ? (\n <DirectionIcon\n size={12}\n strokeWidth={2}\n className=\"shrink-0 text-blue-600 dark:text-blue-400\"\n aria-hidden\n />\n ) : (\n <ChevronsUpDown\n size={12}\n strokeWidth={2}\n className=\"shrink-0 opacity-40 transition-opacity group-hover:opacity-70\"\n aria-hidden\n />\n )}\n </Button>\n </th>\n );\n}\n\nfunction getVisiblePages(page: number, totalPages: number): (number | \"ellipsis\")[] {\n if (totalPages <= 5) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages = new Set<number>([1, totalPages, page - 1, page, page + 1]);\n const sorted = [...pages].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const result: (number | \"ellipsis\")[] = [];\n for (let i = 0; i < sorted.length; i += 1) {\n const current = sorted[i]!;\n const prev = sorted[i - 1];\n if (prev !== undefined && current - prev > 1) {\n result.push(\"ellipsis\");\n }\n result.push(current);\n }\n return result;\n}\n\nfunction paginationLinkClick(page: number, setPage: (page: number) => void) {\n return (event: MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n setPage(page);\n };\n}\n\nexport type PageListPaginationProps = Pick<\n UseClientPaginationResult<unknown>,\n | \"page\"\n | \"setPage\"\n | \"pageSize\"\n | \"setPageSize\"\n | \"pageSizeOptions\"\n | \"totalItems\"\n | \"totalPages\"\n | \"rangeStart\"\n | \"rangeEnd\"\n | \"canPrev\"\n | \"canNext\"\n>;\n\n/** Footer bar for paginated list tables — count, page-size selector, and page controls. */\nexport function PageListPagination({\n page,\n setPage,\n pageSize,\n setPageSize,\n pageSizeOptions,\n totalItems,\n totalPages,\n rangeStart,\n rangeEnd,\n canPrev,\n canNext,\n}: PageListPaginationProps) {\n if (totalItems === 0) return null;\n\n const visiblePages = getVisiblePages(page, totalPages);\n const showPageControls = totalPages > 1;\n\n return (\n <div\n className=\"shrink-0 flex flex-col gap-3 border-t border-border bg-card px-5 py-3 sm:flex-row sm:items-center sm:justify-between\"\n >\n <p className=\"text-sm text-muted-foreground tabular-nums\">\n Showing <span className=\"font-medium text-foreground\">{rangeStart}</span>\n {\"–\"}\n <span className=\"font-medium text-foreground\">{rangeEnd}</span> of{\" \"}\n <span className=\"font-medium text-foreground\">{totalItems}</span>\n </p>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground whitespace-nowrap\">Rows per page</span>\n <Select\n value={String(pageSize)}\n onValueChange={(value) => setPageSize(Number(value))}\n >\n <SelectTrigger className=\"h-8 w-[72px] rounded-lg border-border bg-card text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((option) => (\n <SelectItem key={option} value={String(option)}>\n {option}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {showPageControls ? (\n <Pagination className=\"mx-0 w-auto justify-end\">\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious\n href=\"#\"\n aria-disabled={!canPrev}\n className={cn(!canPrev && \"pointer-events-none opacity-50\")}\n onClick={\n canPrev\n ? paginationLinkClick(page - 1, setPage)\n : (event) => event.preventDefault()\n }\n />\n </PaginationItem>\n {visiblePages.map((pageNum, index) =>\n pageNum === \"ellipsis\" ? (\n <PaginationItem key={`ellipsis-${index}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={pageNum}>\n <PaginationLink\n href=\"#\"\n isActive={pageNum === page}\n onClick={paginationLinkClick(pageNum, setPage)}\n >\n {pageNum}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n <PaginationItem>\n <PaginationNext\n href=\"#\"\n aria-disabled={!canNext}\n className={cn(!canNext && \"pointer-events-none opacity-50\")}\n onClick={\n canNext\n ? paginationLinkClick(page + 1, setPage)\n : (event) => event.preventDefault()\n }\n />\n </PaginationItem>\n </PaginationContent>\n </Pagination>\n ) : null}\n </div>\n </div>\n );\n}\n\n/** Empty state for list pages inside PageListTableArea. */\nexport function PageListEmptyState({\n title,\n description,\n icon,\n action,\n variant = \"minimal\",\n className,\n}: {\n title: string;\n description?: string;\n icon?: ReactNode;\n action?: ReactNode;\n variant?: \"minimal\" | \"illustrated\";\n className?: string;\n}) {\n if (variant === \"minimal\") {\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center py-24 gap-2\",\n className,\n )}\n >\n <span className=\"text-sm text-muted-foreground\">{title}</span>\n {description ? (\n <span className=\"text-xs text-muted-foreground\">{description}</span>\n ) : null}\n {action}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center py-20 gap-3 border-2 border-dashed border-border rounded-2xl bg-muted/50\",\n className,\n )}\n >\n {icon ? (\n <div className=\"w-10 h-10 rounded-2xl bg-muted flex items-center justify-center\">\n {icon}\n </div>\n ) : null}\n <div className=\"flex flex-col items-center gap-1 text-center px-4\">\n <p className=\"text-sm text-muted-foreground font-medium\">{title}</p>\n {description ? (\n <p className=\"text-xs text-muted-foreground max-w-sm\">{description}</p>\n ) : null}\n </div>\n {action}\n </div>\n );\n}\n\n/** Bordered scroll wrapper for embedded detail tables. */\nexport function DetailTableFrame({\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"overflow-x-auto rounded-xl border border-border\", className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/** Flat content section for detail pages — title + optional description + optional header action, separated by a thin divider. */\nexport function DetailSection({\n title,\n description,\n headerMeta,\n headerAction,\n children,\n}: {\n title: string;\n description?: string;\n /** Right-aligned non-interactive meta (counts, tax note). */\n headerMeta?: ReactNode;\n headerAction?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <div className=\"border-b border-border px-6 py-6 last:border-0\">\n <div className=\"flex items-start justify-between gap-4 mb-4\">\n <div>\n <h2 className=\"text-sm font-semibold text-foreground\">{title}</h2>\n {description && <p className=\"text-xs text-muted-foreground mt-0.5\">{description}</p>}\n </div>\n {headerAction ? (\n headerAction\n ) : headerMeta ? (\n <div className=\"shrink-0 text-xs text-muted-foreground\">{headerMeta}</div>\n ) : null}\n </div>\n {children}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"page-list-chrome.js"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
/** Same shape as platform support attachments from the API. */
|
|
4
4
|
interface SupportAttachment {
|
|
@@ -15,11 +15,11 @@ interface SupportAttachment {
|
|
|
15
15
|
declare function PlatformSupportAttachmentChip({ attachment, onRemove, }: {
|
|
16
16
|
attachment: SupportAttachment;
|
|
17
17
|
onRemove?: () => void;
|
|
18
|
-
}):
|
|
18
|
+
}): React.JSX.Element;
|
|
19
19
|
declare function PlatformSupportAttachmentPreview({ attachment, className, }: {
|
|
20
20
|
attachment: SupportAttachment;
|
|
21
21
|
className?: string;
|
|
22
|
-
}):
|
|
22
|
+
}): React.JSX.Element;
|
|
23
23
|
type PlatformSupportMessageComposerProps = {
|
|
24
24
|
value: string;
|
|
25
25
|
onChange: (value: string) => void;
|
|
@@ -33,6 +33,6 @@ type PlatformSupportMessageComposerProps = {
|
|
|
33
33
|
compact?: boolean;
|
|
34
34
|
className?: string;
|
|
35
35
|
};
|
|
36
|
-
declare function PlatformSupportMessageComposer({ value, onChange, attachments, onAttachmentsChange, onSend, onUploadFile, onTyping, placeholder, disabled, compact, className, }: PlatformSupportMessageComposerProps):
|
|
36
|
+
declare function PlatformSupportMessageComposer({ value, onChange, attachments, onAttachmentsChange, onSend, onUploadFile, onTyping, placeholder, disabled, compact, className, }: PlatformSupportMessageComposerProps): React.JSX.Element;
|
|
37
37
|
|
|
38
38
|
export { PlatformSupportAttachmentChip, PlatformSupportAttachmentPreview, PlatformSupportMessageComposer, type PlatformSupportMessageComposerProps, type SupportAttachment };
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { FilePickerField } from './chunk-OMSJWTSZ.js';
|
|
2
|
+
import { Tooltip, TooltipTrigger, TooltipContent, Textarea } from './chunk-4A6RCBB5.js';
|
|
3
|
+
import './chunk-RV5PMZYZ.js';
|
|
4
|
+
import './chunk-L65F4EMK.js';
|
|
5
|
+
import './chunk-PBNBLCC2.js';
|
|
6
|
+
import './chunk-VVXGQKN7.js';
|
|
7
|
+
import './chunk-7YCAAP43.js';
|
|
8
|
+
import './chunk-LUB7QWGU.js';
|
|
9
|
+
import { Button } from './chunk-VHINHHZQ.js';
|
|
10
|
+
import './chunk-FCY5FYJB.js';
|
|
11
|
+
import './chunk-OWNUMPUC.js';
|
|
12
|
+
import { cn } from './chunk-DMPSQ22Q.js';
|
|
13
|
+
import { useState, useCallback } from 'react';
|
|
14
|
+
import { Paperclip, X, Image, FileText, Plus, Send } from 'lucide-react';
|
|
4
15
|
import { toast } from 'sonner';
|
|
5
|
-
import {
|
|
6
|
-
import { cva } from 'class-variance-authority';
|
|
7
|
-
import { clsx } from 'clsx';
|
|
8
|
-
import { twMerge } from 'tailwind-merge';
|
|
9
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
11
|
-
|
|
12
|
-
// src/support/platform-support-message-composer.tsx
|
|
16
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
13
17
|
|
|
14
18
|
// src/lib/support-attachments.ts
|
|
15
19
|
var MAX_ATTACHMENTS_PER_MESSAGE = 5;
|
|
@@ -40,213 +44,6 @@ function describeSupportAttachmentError(err) {
|
|
|
40
44
|
}
|
|
41
45
|
return "Unsupported file type.";
|
|
42
46
|
}
|
|
43
|
-
function cn(...inputs) {
|
|
44
|
-
return twMerge(clsx(inputs));
|
|
45
|
-
}
|
|
46
|
-
var buttonVariants = cva(
|
|
47
|
-
"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",
|
|
48
|
-
{
|
|
49
|
-
variants: {
|
|
50
|
-
variant: {
|
|
51
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]",
|
|
52
|
-
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",
|
|
53
|
-
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",
|
|
54
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]",
|
|
55
|
-
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",
|
|
56
|
-
link: "text-primary underline-offset-4 hover:underline active:text-primary/80"
|
|
57
|
-
},
|
|
58
|
-
size: {
|
|
59
|
-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
60
|
-
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
61
|
-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
62
|
-
icon: "size-9 rounded-md"
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
defaultVariants: {
|
|
66
|
-
variant: "default",
|
|
67
|
-
size: "default"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
);
|
|
71
|
-
var Button = React.forwardRef(function Button2({ className, variant, size, asChild = false, ...props }, ref) {
|
|
72
|
-
const Comp = asChild ? Slot : "button";
|
|
73
|
-
return /* @__PURE__ */ jsx(
|
|
74
|
-
Comp,
|
|
75
|
-
{
|
|
76
|
-
ref,
|
|
77
|
-
"data-slot": "button",
|
|
78
|
-
className: cn(buttonVariants({ variant, size }), className),
|
|
79
|
-
...props
|
|
80
|
-
}
|
|
81
|
-
);
|
|
82
|
-
});
|
|
83
|
-
Button.displayName = "Button";
|
|
84
|
-
function FilePickerField({
|
|
85
|
-
label,
|
|
86
|
-
actionLabel,
|
|
87
|
-
description,
|
|
88
|
-
selectedLabel,
|
|
89
|
-
accept,
|
|
90
|
-
multiple = false,
|
|
91
|
-
disabled = false,
|
|
92
|
-
variant = "card",
|
|
93
|
-
icon,
|
|
94
|
-
className,
|
|
95
|
-
triggerClassName,
|
|
96
|
-
inputClassName,
|
|
97
|
-
title,
|
|
98
|
-
onFilesSelected
|
|
99
|
-
}) {
|
|
100
|
-
const inputRef = useRef(null);
|
|
101
|
-
const triggerLabel = selectedLabel ?? actionLabel ?? (multiple ? "Choose files" : "Choose file");
|
|
102
|
-
const fallbackIcon = variant === "card" ? /* @__PURE__ */ jsx(Upload, { size: 16, className: "text-muted-foreground" }) : /* @__PURE__ */ jsx(Paperclip, { size: 13 });
|
|
103
|
-
const handleFiles = (files) => {
|
|
104
|
-
if (disabled) return;
|
|
105
|
-
onFilesSelected(files);
|
|
106
|
-
if (inputRef.current) inputRef.current.value = "";
|
|
107
|
-
};
|
|
108
|
-
const input = /* @__PURE__ */ jsx(
|
|
109
|
-
"input",
|
|
110
|
-
{
|
|
111
|
-
ref: inputRef,
|
|
112
|
-
type: "file",
|
|
113
|
-
accept,
|
|
114
|
-
multiple,
|
|
115
|
-
disabled,
|
|
116
|
-
className: cn("hidden", inputClassName),
|
|
117
|
-
onChange: (event) => handleFiles(event.target.files)
|
|
118
|
-
}
|
|
119
|
-
);
|
|
120
|
-
if (variant === "button") {
|
|
121
|
-
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
122
|
-
input,
|
|
123
|
-
/* @__PURE__ */ jsxs(
|
|
124
|
-
Button,
|
|
125
|
-
{
|
|
126
|
-
type: "button",
|
|
127
|
-
variant: "outline",
|
|
128
|
-
disabled,
|
|
129
|
-
title,
|
|
130
|
-
className: triggerClassName,
|
|
131
|
-
onClick: () => inputRef.current?.click(),
|
|
132
|
-
children: [
|
|
133
|
-
icon ?? fallbackIcon,
|
|
134
|
-
triggerLabel
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
)
|
|
138
|
-
] });
|
|
139
|
-
}
|
|
140
|
-
if (variant === "inline") {
|
|
141
|
-
return /* @__PURE__ */ jsxs("span", { className, children: [
|
|
142
|
-
input,
|
|
143
|
-
/* @__PURE__ */ jsxs(
|
|
144
|
-
"button",
|
|
145
|
-
{
|
|
146
|
-
type: "button",
|
|
147
|
-
disabled,
|
|
148
|
-
title,
|
|
149
|
-
className: cn(
|
|
150
|
-
"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",
|
|
151
|
-
triggerClassName
|
|
152
|
-
),
|
|
153
|
-
onClick: () => inputRef.current?.click(),
|
|
154
|
-
children: [
|
|
155
|
-
icon ?? fallbackIcon,
|
|
156
|
-
triggerLabel
|
|
157
|
-
]
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
] });
|
|
161
|
-
}
|
|
162
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
163
|
-
label ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-widest text-muted-foreground", children: label }) : null,
|
|
164
|
-
input,
|
|
165
|
-
/* @__PURE__ */ jsxs(
|
|
166
|
-
"button",
|
|
167
|
-
{
|
|
168
|
-
type: "button",
|
|
169
|
-
disabled,
|
|
170
|
-
title,
|
|
171
|
-
className: cn(
|
|
172
|
-
"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",
|
|
173
|
-
triggerClassName
|
|
174
|
-
),
|
|
175
|
-
onClick: () => inputRef.current?.click(),
|
|
176
|
-
onDragOver: (event) => {
|
|
177
|
-
if (disabled) return;
|
|
178
|
-
event.preventDefault();
|
|
179
|
-
},
|
|
180
|
-
onDrop: (event) => {
|
|
181
|
-
if (disabled) return;
|
|
182
|
-
event.preventDefault();
|
|
183
|
-
handleFiles(event.dataTransfer.files);
|
|
184
|
-
},
|
|
185
|
-
children: [
|
|
186
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 flex size-8 items-center justify-center rounded-lg bg-muted", children: icon ?? fallbackIcon }),
|
|
187
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: triggerLabel }),
|
|
188
|
-
description ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-[10px] text-muted-foreground", children: description }) : null
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
)
|
|
192
|
-
] });
|
|
193
|
-
}
|
|
194
|
-
function TooltipProvider({
|
|
195
|
-
delayDuration = 0,
|
|
196
|
-
...props
|
|
197
|
-
}) {
|
|
198
|
-
return /* @__PURE__ */ jsx(
|
|
199
|
-
TooltipPrimitive.Provider,
|
|
200
|
-
{
|
|
201
|
-
"data-slot": "tooltip-provider",
|
|
202
|
-
delayDuration,
|
|
203
|
-
...props
|
|
204
|
-
}
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
function Tooltip({ ...props }) {
|
|
208
|
-
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
|
|
209
|
-
}
|
|
210
|
-
function TooltipTrigger({ ...props }) {
|
|
211
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
212
|
-
}
|
|
213
|
-
function TooltipContent({
|
|
214
|
-
className,
|
|
215
|
-
sideOffset = 0,
|
|
216
|
-
children,
|
|
217
|
-
...props
|
|
218
|
-
}) {
|
|
219
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
220
|
-
TooltipPrimitive.Content,
|
|
221
|
-
{
|
|
222
|
-
"data-slot": "tooltip-content",
|
|
223
|
-
sideOffset,
|
|
224
|
-
className: cn(
|
|
225
|
-
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
226
|
-
className
|
|
227
|
-
),
|
|
228
|
-
...props,
|
|
229
|
-
children: [
|
|
230
|
-
children,
|
|
231
|
-
/* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
232
|
-
]
|
|
233
|
-
}
|
|
234
|
-
) });
|
|
235
|
-
}
|
|
236
|
-
var Textarea = React.forwardRef(function Textarea2({ className, ...props }, ref) {
|
|
237
|
-
return /* @__PURE__ */ jsx(
|
|
238
|
-
"textarea",
|
|
239
|
-
{
|
|
240
|
-
ref,
|
|
241
|
-
"data-slot": "textarea",
|
|
242
|
-
className: cn(
|
|
243
|
-
"resize-none border-border bg-card text-foreground placeholder:text-muted-foreground focus-visible:border-blue-400 focus-visible:ring-blue-500/25 aria-invalid:border-red-400 aria-invalid:ring-red-500/20 flex field-sizing-content min-h-16 w-full rounded-md border px-3 py-2 text-base transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
244
|
-
className
|
|
245
|
-
),
|
|
246
|
-
...props
|
|
247
|
-
}
|
|
248
|
-
);
|
|
249
|
-
});
|
|
250
47
|
function PlatformSupportAttachmentChip({
|
|
251
48
|
attachment,
|
|
252
49
|
onRemove
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/support-attachments.ts","../src/ui/utils.ts","../src/ui/button.tsx","../src/files/file-picker-field.tsx","../src/ui/tooltip.tsx","../src/ui/textarea.tsx","../src/support/platform-support-message-composer.tsx"],"names":["Button","jsx","jsxs","React2","Textarea","Paperclip","ImageIcon"],"mappings":"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","file":"platform-support-message-composer.js","sourcesContent":["/**\n * Support attachment helpers for the shared message composer.\n * Copied from `@spacesync/client/domain` so the client has no package dependency.\n */\n\nexport const MAX_ATTACHMENTS_PER_MESSAGE = 5;\n\nexport const MAX_SUPPORT_ATTACHMENT_BYTES = 5 * 1024 * 1024;\n\nconst ALLOWED_MIME_PREFIXES = [\"image/\", \"application/pdf\", \"text/\"];\nconst ALLOWED_MIME_EXACT = new Set([\n \"application/zip\",\n \"application/json\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n]);\n\nexport type SupportAttachmentValidationError =\n | { kind: \"too_big\"; max: number }\n | { kind: \"unsupported_type\" };\n\n/** Same shape as platform support attachments from the API. */\nexport interface SupportAttachment {\n id: string;\n name: string;\n mimeType: string;\n sizeBytes: number;\n storageKey: string;\n uploadedAt: string;\n /** Short-lived signed URL, populated by the API on read — not stored in Mongo. */\n readUrl?: string;\n}\n\nexport function validateSupportAttachmentFile(file: {\n size: number;\n type: string;\n}): SupportAttachmentValidationError | null {\n if (file.size > MAX_SUPPORT_ATTACHMENT_BYTES) {\n return { kind: \"too_big\", max: MAX_SUPPORT_ATTACHMENT_BYTES };\n }\n const mime = file.type || \"application/octet-stream\";\n const allowed =\n ALLOWED_MIME_EXACT.has(mime) || ALLOWED_MIME_PREFIXES.some((prefix) => mime.startsWith(prefix));\n if (!allowed) {\n return { kind: \"unsupported_type\" };\n }\n return null;\n}\n\nexport function describeSupportAttachmentError(err: SupportAttachmentValidationError): string {\n if (err.kind === \"too_big\") {\n const mb = (err.max / (1024 * 1024)).toFixed(1);\n return `File too large (max ${mb} MB).`;\n }\n return \"Unsupported file type.\";\n}\n","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","\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"./utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","import * as React from \"react\";\n\nimport { cn } from \"./utils\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(function Textarea({ className, ...props }, ref) {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n \"resize-none border-border bg-card text-foreground placeholder:text-muted-foreground focus-visible:border-blue-400 focus-visible:ring-blue-500/25 aria-invalid:border-red-400 aria-invalid:ring-red-500/20 flex field-sizing-content min-h-16 w-full rounded-md border px-3 py-2 text-base transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport { Textarea };\n","import { useCallback, useState } from \"react\";\nimport { FileText, Image as ImageIcon, Paperclip, Plus, Send, X } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport {\n MAX_ATTACHMENTS_PER_MESSAGE,\n describeSupportAttachmentError,\n validateSupportAttachmentFile,\n type SupportAttachment,\n} from \"../lib/support-attachments\";\nimport { FilePickerField } from \"../files/file-picker-field\";\nimport { Button, Textarea, Tooltip, TooltipContent, TooltipTrigger, cn } from \"../ui\";\n\nexport type { SupportAttachment };\n\nexport function PlatformSupportAttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: SupportAttachment;\n onRemove?: () => void;\n}) {\n return (\n <li className=\"inline-flex items-center gap-1.5 rounded-lg border border-border bg-card px-2.5 py-1 text-xs text-muted-foreground\">\n <Paperclip size={11} className=\"shrink-0 text-muted-foreground\" />\n <span className=\"max-w-[140px] truncate\">{attachment.name}</span>\n {onRemove ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onRemove}\n className=\"size-5 text-muted-foreground hover:text-red-500\"\n aria-label={`Remove ${attachment.name}`}\n >\n <X size={11} />\n </Button>\n ) : null}\n </li>\n );\n}\n\nexport function PlatformSupportAttachmentPreview({\n attachment,\n className,\n}: {\n attachment: SupportAttachment;\n className?: string;\n}) {\n const href = attachment.readUrl;\n const isImage = attachment.mimeType.startsWith(\"image/\");\n const inner = (\n <>\n {isImage ? (\n <ImageIcon size={12} className=\"shrink-0 text-muted-foreground\" />\n ) : (\n <FileText size={12} className=\"shrink-0 text-muted-foreground\" />\n )}\n <span className=\"min-w-0 flex-1 truncate font-medium\">{attachment.name}</span>\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n {Math.round(attachment.sizeBytes / 1024)} KB\n </span>\n </>\n );\n if (!href) {\n return (\n <span\n className={cn(\n \"flex max-w-[220px] items-center gap-2 rounded-lg border border-border bg-card px-2.5 py-1.5 text-xs text-muted-foreground\",\n className,\n )}\n title={attachment.name}\n >\n {inner}\n </span>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n download={attachment.name}\n className={cn(\n \"flex max-w-[220px] items-center gap-2 rounded-lg border border-border bg-card px-2.5 py-1.5 text-xs text-muted-foreground hover:bg-accent\",\n className,\n )}\n title={attachment.name}\n >\n {inner}\n </a>\n );\n}\n\nexport type PlatformSupportMessageComposerProps = {\n value: string;\n onChange: (value: string) => void;\n attachments: SupportAttachment[];\n onAttachmentsChange: (attachments: SupportAttachment[]) => void;\n onSend: () => void;\n onUploadFile: (file: File) => Promise<SupportAttachment>;\n onTyping?: () => void;\n placeholder?: string;\n disabled?: boolean;\n compact?: boolean;\n className?: string;\n};\n\nexport function PlatformSupportMessageComposer({\n value,\n onChange,\n attachments,\n onAttachmentsChange,\n onSend,\n onUploadFile,\n onTyping,\n placeholder = \"Write a message…\",\n disabled = false,\n compact = false,\n className,\n}: PlatformSupportMessageComposerProps) {\n const [busy, setBusy] = useState(false);\n\n const canSend = !disabled && (value.trim().length > 0 || attachments.length > 0);\n\n const handleFiles = useCallback(\n async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n const remaining = MAX_ATTACHMENTS_PER_MESSAGE - attachments.length;\n if (remaining <= 0) {\n toast.error(`Maximum ${MAX_ATTACHMENTS_PER_MESSAGE} attachments per message`);\n return;\n }\n setBusy(true);\n try {\n const next = [...attachments];\n for (const file of Array.from(files).slice(0, remaining)) {\n const err = validateSupportAttachmentFile(file);\n if (err) {\n toast.error(describeSupportAttachmentError(err));\n continue;\n }\n next.push(await onUploadFile(file));\n }\n onAttachmentsChange(next);\n } catch {\n toast.error(\"Could not upload file\");\n } finally {\n setBusy(false);\n }\n },\n [attachments, onAttachmentsChange, onUploadFile],\n );\n\n const removeAttachment = (id: string) => {\n onAttachmentsChange(attachments.filter((a) => a.id !== id));\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (canSend) onSend();\n }\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n {attachments.length > 0 ? (\n <ul className=\"flex flex-wrap gap-1.5\">\n {attachments.map((attachment) => (\n <PlatformSupportAttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={() => removeAttachment(attachment.id)}\n />\n ))}\n </ul>\n ) : null}\n\n <div\n className={cn(\n \"rounded-xl border border-border bg-card px-2.5 py-2 shadow-sm\",\n disabled && \"opacity-60\",\n )}\n >\n <div className=\"flex items-end gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex shrink-0\">\n <FilePickerField\n variant=\"inline\"\n multiple\n disabled={disabled || busy || attachments.length >= MAX_ATTACHMENTS_PER_MESSAGE}\n actionLabel=\"\"\n icon={<Plus size={compact ? 16 : 18} strokeWidth={1.75} />}\n triggerClassName={cn(\n \"inline-flex items-center justify-center rounded-lg border border-transparent text-muted-foreground transition-colors hover:border-border hover:bg-muted hover:text-foreground\",\n compact ? \"size-8\" : \"size-9\",\n )}\n title=\"Attach files\"\n onFilesSelected={(files) => void handleFiles(files)}\n />\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">Attach</TooltipContent>\n </Tooltip>\n <Textarea\n value={value}\n onChange={(e) => {\n onChange(e.target.value);\n onTyping?.();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || busy}\n rows={1}\n className={cn(\n \"max-h-28 min-h-[36px] flex-1 resize-none border-0 bg-transparent px-0.5 py-1.5 text-sm shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n compact && \"min-h-[32px] text-xs\",\n )}\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n size=\"icon\"\n onClick={onSend}\n disabled={!canSend || busy}\n aria-label=\"Send message\"\n className={cn(\n \"shrink-0 rounded-lg bg-blue-500 text-white hover:bg-blue-600 disabled:bg-muted disabled:text-muted-foreground\",\n compact ? \"size-8\" : \"size-9\",\n )}\n >\n <Send size={compact ? 14 : 16} strokeWidth={2} />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">Send</TooltipContent>\n </Tooltip>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/support-attachments.ts","../src/support/platform-support-message-composer.tsx"],"names":["ImageIcon"],"mappings":"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","file":"platform-support-message-composer.js","sourcesContent":["/**\n * Support attachment helpers for the shared message composer.\n * Copied from `@spacesync/client/domain` so the client has no package dependency.\n */\n\nexport const MAX_ATTACHMENTS_PER_MESSAGE = 5;\n\nexport const MAX_SUPPORT_ATTACHMENT_BYTES = 5 * 1024 * 1024;\n\nconst ALLOWED_MIME_PREFIXES = [\"image/\", \"application/pdf\", \"text/\"];\nconst ALLOWED_MIME_EXACT = new Set([\n \"application/zip\",\n \"application/json\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n]);\n\nexport type SupportAttachmentValidationError =\n | { kind: \"too_big\"; max: number }\n | { kind: \"unsupported_type\" };\n\n/** Same shape as platform support attachments from the API. */\nexport interface SupportAttachment {\n id: string;\n name: string;\n mimeType: string;\n sizeBytes: number;\n storageKey: string;\n uploadedAt: string;\n /** Short-lived signed URL, populated by the API on read — not stored in Mongo. */\n readUrl?: string;\n}\n\nexport function validateSupportAttachmentFile(file: {\n size: number;\n type: string;\n}): SupportAttachmentValidationError | null {\n if (file.size > MAX_SUPPORT_ATTACHMENT_BYTES) {\n return { kind: \"too_big\", max: MAX_SUPPORT_ATTACHMENT_BYTES };\n }\n const mime = file.type || \"application/octet-stream\";\n const allowed =\n ALLOWED_MIME_EXACT.has(mime) || ALLOWED_MIME_PREFIXES.some((prefix) => mime.startsWith(prefix));\n if (!allowed) {\n return { kind: \"unsupported_type\" };\n }\n return null;\n}\n\nexport function describeSupportAttachmentError(err: SupportAttachmentValidationError): string {\n if (err.kind === \"too_big\") {\n const mb = (err.max / (1024 * 1024)).toFixed(1);\n return `File too large (max ${mb} MB).`;\n }\n return \"Unsupported file type.\";\n}\n","import { useCallback, useState } from \"react\";\nimport { FileText, Image as ImageIcon, Paperclip, Plus, Send, X } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport {\n MAX_ATTACHMENTS_PER_MESSAGE,\n describeSupportAttachmentError,\n validateSupportAttachmentFile,\n type SupportAttachment,\n} from \"../lib/support-attachments\";\nimport { FilePickerField } from \"../files/file-picker-field\";\nimport { Button, Textarea, Tooltip, TooltipContent, TooltipTrigger, cn } from \"../ui\";\n\nexport type { SupportAttachment };\n\nexport function PlatformSupportAttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: SupportAttachment;\n onRemove?: () => void;\n}) {\n return (\n <li className=\"inline-flex items-center gap-1.5 rounded-lg border border-border bg-card px-2.5 py-1 text-xs text-muted-foreground\">\n <Paperclip size={11} className=\"shrink-0 text-muted-foreground\" />\n <span className=\"max-w-[140px] truncate\">{attachment.name}</span>\n {onRemove ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onRemove}\n className=\"size-5 text-muted-foreground hover:text-red-500\"\n aria-label={`Remove ${attachment.name}`}\n >\n <X size={11} />\n </Button>\n ) : null}\n </li>\n );\n}\n\nexport function PlatformSupportAttachmentPreview({\n attachment,\n className,\n}: {\n attachment: SupportAttachment;\n className?: string;\n}) {\n const href = attachment.readUrl;\n const isImage = attachment.mimeType.startsWith(\"image/\");\n const inner = (\n <>\n {isImage ? (\n <ImageIcon size={12} className=\"shrink-0 text-muted-foreground\" />\n ) : (\n <FileText size={12} className=\"shrink-0 text-muted-foreground\" />\n )}\n <span className=\"min-w-0 flex-1 truncate font-medium\">{attachment.name}</span>\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n {Math.round(attachment.sizeBytes / 1024)} KB\n </span>\n </>\n );\n if (!href) {\n return (\n <span\n className={cn(\n \"flex max-w-[220px] items-center gap-2 rounded-lg border border-border bg-card px-2.5 py-1.5 text-xs text-muted-foreground\",\n className,\n )}\n title={attachment.name}\n >\n {inner}\n </span>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n download={attachment.name}\n className={cn(\n \"flex max-w-[220px] items-center gap-2 rounded-lg border border-border bg-card px-2.5 py-1.5 text-xs text-muted-foreground hover:bg-accent\",\n className,\n )}\n title={attachment.name}\n >\n {inner}\n </a>\n );\n}\n\nexport type PlatformSupportMessageComposerProps = {\n value: string;\n onChange: (value: string) => void;\n attachments: SupportAttachment[];\n onAttachmentsChange: (attachments: SupportAttachment[]) => void;\n onSend: () => void;\n onUploadFile: (file: File) => Promise<SupportAttachment>;\n onTyping?: () => void;\n placeholder?: string;\n disabled?: boolean;\n compact?: boolean;\n className?: string;\n};\n\nexport function PlatformSupportMessageComposer({\n value,\n onChange,\n attachments,\n onAttachmentsChange,\n onSend,\n onUploadFile,\n onTyping,\n placeholder = \"Write a message…\",\n disabled = false,\n compact = false,\n className,\n}: PlatformSupportMessageComposerProps) {\n const [busy, setBusy] = useState(false);\n\n const canSend = !disabled && (value.trim().length > 0 || attachments.length > 0);\n\n const handleFiles = useCallback(\n async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n const remaining = MAX_ATTACHMENTS_PER_MESSAGE - attachments.length;\n if (remaining <= 0) {\n toast.error(`Maximum ${MAX_ATTACHMENTS_PER_MESSAGE} attachments per message`);\n return;\n }\n setBusy(true);\n try {\n const next = [...attachments];\n for (const file of Array.from(files).slice(0, remaining)) {\n const err = validateSupportAttachmentFile(file);\n if (err) {\n toast.error(describeSupportAttachmentError(err));\n continue;\n }\n next.push(await onUploadFile(file));\n }\n onAttachmentsChange(next);\n } catch {\n toast.error(\"Could not upload file\");\n } finally {\n setBusy(false);\n }\n },\n [attachments, onAttachmentsChange, onUploadFile],\n );\n\n const removeAttachment = (id: string) => {\n onAttachmentsChange(attachments.filter((a) => a.id !== id));\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (canSend) onSend();\n }\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n {attachments.length > 0 ? (\n <ul className=\"flex flex-wrap gap-1.5\">\n {attachments.map((attachment) => (\n <PlatformSupportAttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={() => removeAttachment(attachment.id)}\n />\n ))}\n </ul>\n ) : null}\n\n <div\n className={cn(\n \"rounded-xl border border-border bg-card px-2.5 py-2 shadow-sm\",\n disabled && \"opacity-60\",\n )}\n >\n <div className=\"flex items-end gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex shrink-0\">\n <FilePickerField\n variant=\"inline\"\n multiple\n disabled={disabled || busy || attachments.length >= MAX_ATTACHMENTS_PER_MESSAGE}\n actionLabel=\"\"\n icon={<Plus size={compact ? 16 : 18} strokeWidth={1.75} />}\n triggerClassName={cn(\n \"inline-flex items-center justify-center rounded-lg border border-transparent text-muted-foreground transition-colors hover:border-border hover:bg-muted hover:text-foreground\",\n compact ? \"size-8\" : \"size-9\",\n )}\n title=\"Attach files\"\n onFilesSelected={(files) => void handleFiles(files)}\n />\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">Attach</TooltipContent>\n </Tooltip>\n <Textarea\n value={value}\n onChange={(e) => {\n onChange(e.target.value);\n onTyping?.();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || busy}\n rows={1}\n className={cn(\n \"max-h-28 min-h-[36px] flex-1 resize-none border-0 bg-transparent px-0.5 py-1.5 text-sm shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n compact && \"min-h-[32px] text-xs\",\n )}\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n size=\"icon\"\n onClick={onSend}\n disabled={!canSend || busy}\n aria-label=\"Send message\"\n className={cn(\n \"shrink-0 rounded-lg bg-blue-500 text-white hover:bg-blue-600 disabled:bg-muted disabled:text-muted-foreground\",\n compact ? \"size-8\" : \"size-9\",\n )}\n >\n <Send size={compact ? 14 : 16} strokeWidth={2} />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">Send</TooltipContent>\n </Tooltip>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
// src/theme/shell-theme.ts
|
|
5
|
-
function getShellTheme() {
|
|
6
|
-
return "light";
|
|
7
|
-
}
|
|
8
|
-
function cn(...inputs) {
|
|
9
|
-
return twMerge(clsx(inputs));
|
|
10
|
-
}
|
|
1
|
+
import { getShellTheme } from './chunk-OWNUMPUC.js';
|
|
2
|
+
import { cn } from './chunk-DMPSQ22Q.js';
|
|
11
3
|
|
|
12
4
|
// src/shell/shell-sidebar-nav.ts
|
|
13
5
|
var shellSidebarButtonReset = "font-normal shadow-none hover:bg-sidebar-accent hover:text-sidebar-foreground [&_svg]:size-[18px]";
|
|
14
6
|
function shellSidebarNavItemClass(isActive, collapsed) {
|
|
7
|
+
const isDarkShell = getShellTheme() === "dark";
|
|
15
8
|
return cn(
|
|
16
9
|
"relative flex w-full items-center rounded-lg border text-left text-sm transition-colors",
|
|
17
10
|
shellSidebarButtonReset,
|
|
18
11
|
collapsed ? "h-9 justify-center px-0 has-[>svg]:px-0" : "justify-start gap-3 px-2.5 py-2 has-[>svg]:px-2.5",
|
|
19
|
-
isActive ? "border-blue-200/60 bg-blue-50 text-blue-700" : "border-transparent text-sidebar-foreground/65 hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
|
12
|
+
isActive ? isDarkShell ? "border-blue-500/25 bg-blue-500/15 text-blue-300" : "border-blue-200/60 bg-blue-50 text-blue-700" : "border-transparent text-sidebar-foreground/65 hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
|
20
13
|
);
|
|
21
14
|
}
|
|
22
15
|
function shellSidebarNavIconClass(isActive) {
|
|
@@ -31,11 +24,12 @@ function shellSidebarCollapseButtonClass(collapsed) {
|
|
|
31
24
|
);
|
|
32
25
|
}
|
|
33
26
|
function shellSidebarNavSubItemClass(isActive) {
|
|
27
|
+
const isDarkShell = getShellTheme() === "dark";
|
|
34
28
|
return cn(
|
|
35
29
|
"relative flex w-full items-center rounded-md border text-left text-sm transition-colors",
|
|
36
30
|
shellSidebarButtonReset,
|
|
37
31
|
"justify-start gap-2 py-1.5 pl-9 pr-2.5",
|
|
38
|
-
isActive ? "border-blue-200/60 bg-blue-50 text-blue-700" : "border-transparent text-sidebar-foreground/60 hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
|
32
|
+
isActive ? isDarkShell ? "border-blue-500/25 bg-blue-500/15 text-blue-300" : "border-blue-200/60 bg-blue-50 text-blue-700" : "border-transparent text-sidebar-foreground/60 hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
|
39
33
|
);
|
|
40
34
|
}
|
|
41
35
|
function shellSidebarNavGroupHeaderClass(isSectionActive, collapsed, isOpen) {
|
|
@@ -57,10 +51,11 @@ function shellSidebarNavSubItemsContainerClass(isOpen) {
|
|
|
57
51
|
);
|
|
58
52
|
}
|
|
59
53
|
function shellSidebarNavCountBadgeClass(collapsedIcon = false) {
|
|
54
|
+
const isDarkShell = getShellTheme() === "dark";
|
|
60
55
|
return cn(
|
|
61
56
|
"pointer-events-none flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1 text-[10px] font-semibold tabular-nums",
|
|
62
57
|
collapsedIcon ? "absolute right-0.5 top-0.5" : "ml-auto",
|
|
63
|
-
"bg-amber-100 text-amber-700"
|
|
58
|
+
isDarkShell ? "bg-amber-500/20 text-amber-300" : "bg-amber-100 text-amber-700"
|
|
64
59
|
);
|
|
65
60
|
}
|
|
66
61
|
|