@spacesync/client 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/analog-clock-picker.js +3 -11
  2. package/dist/analog-clock-picker.js.map +1 -1
  3. package/dist/booking-schedule-calendars.d.ts +1 -29
  4. package/dist/booking-schedule-calendars.js +6 -92
  5. package/dist/booking-schedule-calendars.js.map +1 -1
  6. package/dist/booking-schedule.d.ts +71 -0
  7. package/dist/booking-schedule.js +3 -0
  8. package/dist/booking-schedule.js.map +1 -0
  9. package/dist/booking-space-layout-picker.js +8 -11
  10. package/dist/booking-space-layout-picker.js.map +1 -1
  11. package/dist/button-Iem7kbk0.d.ts +16 -0
  12. package/dist/chat-stick-to-bottom.js +0 -10
  13. package/dist/chat-stick-to-bottom.js.map +1 -1
  14. package/dist/chunk-2IZODKTR.js +116 -0
  15. package/dist/chunk-2IZODKTR.js.map +1 -0
  16. package/dist/chunk-2TT2ZGMT.js +21 -0
  17. package/dist/chunk-2TT2ZGMT.js.map +1 -0
  18. package/dist/chunk-3MAGTCCN.js +192 -0
  19. package/dist/chunk-3MAGTCCN.js.map +1 -0
  20. package/dist/chunk-56H7UFAW.js +237 -0
  21. package/dist/chunk-56H7UFAW.js.map +1 -0
  22. package/dist/chunk-5HOK5JHR.js +60 -0
  23. package/dist/chunk-5HOK5JHR.js.map +1 -0
  24. package/dist/{chunk-H7EX6B6N.js → chunk-5NOKULX2.js} +5 -4
  25. package/dist/chunk-5NOKULX2.js.map +1 -0
  26. package/dist/chunk-6VJQIBC3.js +715 -0
  27. package/dist/chunk-6VJQIBC3.js.map +1 -0
  28. package/dist/chunk-BQVMO33N.js +133 -0
  29. package/dist/chunk-BQVMO33N.js.map +1 -0
  30. package/dist/chunk-CXXOKCLJ.js +37 -0
  31. package/dist/chunk-CXXOKCLJ.js.map +1 -0
  32. package/dist/chunk-FN4BWFDX.js +43 -0
  33. package/dist/chunk-FN4BWFDX.js.map +1 -0
  34. package/dist/chunk-HRHDOLWU.js +62 -0
  35. package/dist/chunk-HRHDOLWU.js.map +1 -0
  36. package/dist/chunk-HZB2EHEH.js +216 -0
  37. package/dist/chunk-HZB2EHEH.js.map +1 -0
  38. package/dist/chunk-IBGGQXTH.js +21 -0
  39. package/dist/chunk-IBGGQXTH.js.map +1 -0
  40. package/dist/chunk-JCEOU7BU.js +128 -0
  41. package/dist/chunk-JCEOU7BU.js.map +1 -0
  42. package/dist/{chunk-RV5PMZYZ.js → chunk-MBZAYH5D.js} +4 -18
  43. package/dist/chunk-MBZAYH5D.js.map +1 -0
  44. package/dist/chunk-NWVNYKND.js +153 -0
  45. package/dist/chunk-NWVNYKND.js.map +1 -0
  46. package/dist/chunk-OTSA5ROL.js +209 -0
  47. package/dist/chunk-OTSA5ROL.js.map +1 -0
  48. package/dist/chunk-OV5ODANJ.js +224 -0
  49. package/dist/chunk-OV5ODANJ.js.map +1 -0
  50. package/dist/chunk-PPMJZVR4.js +37 -0
  51. package/dist/chunk-PPMJZVR4.js.map +1 -0
  52. package/dist/{chunk-CKCXQBHQ.js → chunk-RC5SWZPB.js} +5 -4
  53. package/dist/chunk-RC5SWZPB.js.map +1 -0
  54. package/dist/chunk-SHMKDGFF.js +75 -0
  55. package/dist/chunk-SHMKDGFF.js.map +1 -0
  56. package/dist/chunk-T3SOBIYA.js +61 -0
  57. package/dist/chunk-T3SOBIYA.js.map +1 -0
  58. package/dist/chunk-TH5RASJS.js +97 -0
  59. package/dist/chunk-TH5RASJS.js.map +1 -0
  60. package/dist/{chunk-LUB7QWGU.js → chunk-VIJ2HWPZ.js} +5 -159
  61. package/dist/chunk-VIJ2HWPZ.js.map +1 -0
  62. package/dist/chunk-VQ63T7CJ.js +22 -0
  63. package/dist/chunk-VQ63T7CJ.js.map +1 -0
  64. package/dist/chunk-XDVGFHK4.js +50 -0
  65. package/dist/chunk-XDVGFHK4.js.map +1 -0
  66. package/dist/chunk-XI4BQY5T.js +188 -0
  67. package/dist/chunk-XI4BQY5T.js.map +1 -0
  68. package/dist/detail-page-header.js +1 -1
  69. package/dist/file-viewer-dialog.js +3 -9
  70. package/dist/file-viewer-dialog.js.map +1 -1
  71. package/dist/floor-switcher.js +5 -9
  72. package/dist/floor-switcher.js.map +1 -1
  73. package/dist/layout-canvas-view.js +8 -11
  74. package/dist/page-list-chrome.js +5 -3
  75. package/dist/page-list-loading.js +5 -3
  76. package/dist/page-list-loading.js.map +1 -1
  77. package/dist/platform-support-message-composer.js +2 -10
  78. package/dist/platform-support-message-composer.js.map +1 -1
  79. package/dist/sidebar-Dzvrjr69.d.ts +85 -0
  80. package/dist/styles/theme.css +52 -2
  81. package/dist/styles/theme.css.map +1 -1
  82. package/dist/theme-appearance-control.js +2 -1
  83. package/dist/theme-appearance-control.js.map +1 -1
  84. package/dist/ui/accordion.d.ts +9 -0
  85. package/dist/ui/accordion.js +4 -0
  86. package/dist/ui/accordion.js.map +1 -0
  87. package/dist/ui/calendar.d.ts +6 -0
  88. package/dist/ui/calendar.js +4 -0
  89. package/dist/ui/calendar.js.map +1 -0
  90. package/dist/ui/carousel.d.ts +22 -0
  91. package/dist/ui/carousel.js +5 -0
  92. package/dist/ui/carousel.js.map +1 -0
  93. package/dist/ui/chart.d.ts +42 -0
  94. package/dist/ui/chart.js +229 -0
  95. package/dist/ui/chart.js.map +1 -0
  96. package/dist/ui/command.d.ts +19 -0
  97. package/dist/ui/command.js +5 -0
  98. package/dist/ui/command.js.map +1 -0
  99. package/dist/ui/context-menu.d.ts +27 -0
  100. package/dist/ui/context-menu.js +4 -0
  101. package/dist/ui/context-menu.js.map +1 -0
  102. package/dist/ui/form.d.ts +27 -0
  103. package/dist/ui/form.js +5 -0
  104. package/dist/ui/form.js.map +1 -0
  105. package/dist/ui/input-otp.d.ts +13 -0
  106. package/dist/ui/input-otp.js +4 -0
  107. package/dist/ui/input-otp.js.map +1 -0
  108. package/dist/ui/menubar.d.ts +28 -0
  109. package/dist/ui/menubar.js +4 -0
  110. package/dist/ui/menubar.js.map +1 -0
  111. package/dist/ui/navigation-menu.d.ts +17 -0
  112. package/dist/ui/navigation-menu.js +4 -0
  113. package/dist/ui/navigation-menu.js.map +1 -0
  114. package/dist/ui/resizable.d.ts +10 -0
  115. package/dist/ui/resizable.js +4 -0
  116. package/dist/ui/resizable.js.map +1 -0
  117. package/dist/ui/sidebar.d.ts +7 -0
  118. package/dist/ui/sidebar.js +9 -0
  119. package/dist/ui/sidebar.js.map +1 -0
  120. package/dist/ui.d.ts +28 -272
  121. package/dist/ui.js +2427 -6
  122. package/dist/ui.js.map +1 -1
  123. package/package.json +9 -1
  124. package/dist/chunk-CKCXQBHQ.js.map +0 -1
  125. package/dist/chunk-F7MU5T46.js +0 -5146
  126. package/dist/chunk-F7MU5T46.js.map +0 -1
  127. package/dist/chunk-H7EX6B6N.js.map +0 -1
  128. package/dist/chunk-LUB7QWGU.js.map +0 -1
  129. package/dist/chunk-RV5PMZYZ.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/context-menu.tsx"],"names":[],"mappings":"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","file":"chunk-XI4BQY5T.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\n\nfunction ContextMenu({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nfunction ContextMenuGroup({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nfunction ContextMenuPortal({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {\n return <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />;\n}\n\nfunction ContextMenuSub({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nfunction ContextMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-card/10 focus:text-popover-foreground data-[state=open]:bg-card/10 data-[state=open]:text-popover-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nfunction ContextMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n return (\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-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 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border border-white/10 p-1 shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-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 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-white/10 p-1 shadow-md\",\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nfunction ContextMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-card/10 focus:text-popover-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(\n \"focus:bg-card/10 focus:text-popover-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction ContextMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(\n \"focus:bg-card/10 focus:text-popover-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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\",\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nfunction ContextMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset}\n className={cn(\"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn(\"bg-card/10 -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuGroup,\n ContextMenuPortal,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuRadioGroup,\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { ShellTopBar } from './chunk-4NNK5IXY.js';
2
- import { Button } from './chunk-VHINHHZQ.js';
3
2
  import { shellTopBarBackButtonClass, shellTopBarMutedIconClass, shellTopBarTitleTextClass } from './chunk-FCY5FYJB.js';
3
+ import { Button } from './chunk-VHINHHZQ.js';
4
4
  import './chunk-OWNUMPUC.js';
5
5
  import './chunk-DMPSQ22Q.js';
6
6
  import { ChevronLeft } from 'lucide-react';
@@ -1,14 +1,8 @@
1
- import { ResponsiveDialog, ResponsiveDialogContent, ResponsiveDialogTitle } from './chunk-F7MU5T46.js';
2
- import './chunk-RV5PMZYZ.js';
3
- import './chunk-L65F4EMK.js';
4
- import './chunk-PBNBLCC2.js';
1
+ import { ResponsiveDialog, ResponsiveDialogContent, ResponsiveDialogTitle } from './chunk-SHMKDGFF.js';
5
2
  import './chunk-VVXGQKN7.js';
6
- import './chunk-7YCAAP43.js';
7
- import './chunk-DC4QH6W2.js';
8
- import './chunk-LUB7QWGU.js';
3
+ import './chunk-2TT2ZGMT.js';
9
4
  import { Button } from './chunk-VHINHHZQ.js';
10
- import './chunk-FCY5FYJB.js';
11
- import './chunk-OWNUMPUC.js';
5
+ import './chunk-7YCAAP43.js';
12
6
  import { cn } from './chunk-DMPSQ22Q.js';
13
7
  import { useState, useRef, useEffect, useMemo } from 'react';
14
8
  import { Minus, Plus, RotateCcw, Download, ExternalLink, Loader2, FileText } from 'lucide-react';
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/files/file-viewer-dialog.tsx"],"names":[],"mappings":"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","file":"file-viewer-dialog.js","sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Download, ExternalLink, FileText, Loader2, Minus, Plus, RotateCcw } from \"lucide-react\";\nimport {\n Button,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogTitle,\n cn,\n} from \"../ui\";\n\nexport interface FileViewerFile {\n name: string;\n mimeType: string;\n sizeLabel?: string;\n url: string;\n}\n\nexport function FileViewerDialog({\n file,\n open,\n onOpenChange,\n}: {\n file: FileViewerFile | null;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n const [zoom, setZoom] = useState(1);\n const [dragging, setDragging] = useState(false);\n const [imageStatus, setImageStatus] = useState<\"loading\" | \"ready\" | \"error\">(\"loading\");\n const scrollRef = useRef<HTMLDivElement | null>(null);\n const dragStateRef = useRef<{\n pointerId: number;\n startX: number;\n startY: number;\n scrollLeft: number;\n scrollTop: number;\n } | null>(null);\n\n useEffect(() => {\n if (open) setZoom(1);\n setImageStatus(\"loading\");\n }, [open, file?.url]);\n\n const kind = useMemo(() => {\n if (!file) return \"other\";\n if (file.mimeType.startsWith(\"image/\")) return \"image\";\n if (file.mimeType === \"application/pdf\" || file.name.toLowerCase().endsWith(\".pdf\")) return \"pdf\";\n return \"other\";\n }, [file]);\n\n const zoomPercent = Math.round(zoom * 100);\n const isDraggable = kind === \"image\" && zoom > 1;\n\n const handleImagePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggable || !scrollRef.current) return;\n event.preventDefault();\n dragStateRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n scrollLeft: scrollRef.current.scrollLeft,\n scrollTop: scrollRef.current.scrollTop,\n };\n setDragging(true);\n event.currentTarget.setPointerCapture(event.pointerId);\n };\n\n const handleImagePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId || !scrollRef.current) return;\n scrollRef.current.scrollLeft = state.scrollLeft - (event.clientX - state.startX);\n scrollRef.current.scrollTop = state.scrollTop - (event.clientY - state.startY);\n };\n\n const handleImagePointerEnd = (event: React.PointerEvent<HTMLDivElement>) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId) return;\n dragStateRef.current = null;\n setDragging(false);\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"flex h-[min(88vh,900px)] w-[min(96vw,1100px)] max-w-none flex-col gap-0 overflow-hidden rounded-xl border-border bg-card p-0\">\n <div className=\"flex shrink-0 flex-col gap-3 border-b border-border py-3 pl-4 pr-14 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <ResponsiveDialogTitle className=\"truncate text-base font-semibold text-foreground\">\n {file?.name ?? \"File preview\"}\n </ResponsiveDialogTitle>\n {file?.sizeLabel ? (\n <p className=\"mt-1 text-xs text-muted-foreground\">{file.sizeLabel}</p>\n ) : null}\n </div>\n {file ? (\n <div className=\"flex shrink-0 flex-wrap items-center gap-1.5 lg:justify-end\">\n {kind === \"image\" ? (\n <div className=\"flex items-center gap-0.5 rounded-lg border border-border bg-background p-0.5\">\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-40\"\n onClick={() => setZoom((value) => Math.max(0.25, Number((value - 0.25).toFixed(2))))}\n disabled={zoom <= 0.25}\n aria-label=\"Zoom out\"\n >\n <Minus size={14} />\n </button>\n <span className=\"min-w-11 text-center text-xs font-medium tabular-nums text-muted-foreground\">\n {zoomPercent}%\n </span>\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-40\"\n onClick={() => setZoom((value) => Math.min(4, Number((value + 0.25).toFixed(2))))}\n disabled={zoom >= 4}\n aria-label=\"Zoom in\"\n >\n <Plus size={14} />\n </button>\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={() => setZoom(1)}\n aria-label=\"Reset zoom\"\n >\n <RotateCcw size={14} />\n </button>\n </div>\n ) : null}\n <Button\n asChild\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9\"\n title=\"Download\"\n >\n <a href={file.url} download={file.name}>\n <Download size={14} />\n <span className=\"sr-only\">Download</span>\n </a>\n </Button>\n <Button\n asChild\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9\"\n title=\"Open in new tab\"\n >\n <a href={file.url} target=\"_blank\" rel=\"noreferrer\">\n <ExternalLink size={14} />\n <span className=\"sr-only\">Open in new tab</span>\n </a>\n </Button>\n </div>\n ) : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-hidden bg-muted/60\">\n {!file ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n No file selected.\n </div>\n ) : kind === \"image\" ? (\n <div ref={scrollRef} className=\"h-full overflow-auto p-4\">\n <div\n className=\"flex min-h-full items-center justify-center\"\n style={{ minWidth: `${zoom * 100}%` }}\n onPointerDown={handleImagePointerDown}\n onPointerMove={handleImagePointerMove}\n onPointerUp={handleImagePointerEnd}\n onPointerCancel={handleImagePointerEnd}\n >\n <div className=\"relative flex min-h-[240px] w-full items-center justify-center\">\n {imageStatus !== \"ready\" ? (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label={imageStatus === \"error\" ? \"Couldn't load image\" : \"Loading image\"}\n >\n {imageStatus === \"error\" ? (\n <p className=\"text-sm text-muted-foreground\">Couldn't load image</p>\n ) : (\n <Loader2 size={28} className=\"animate-spin text-muted-foreground\" />\n )}\n </div>\n ) : null}\n <img\n src={file.url}\n alt={file.name}\n className={cn(\n \"block shrink-0 select-none rounded-lg border border-border bg-card shadow-sm\",\n imageStatus !== \"ready\" && \"opacity-0\",\n )}\n draggable={false}\n onLoad={() => setImageStatus(\"ready\")}\n onError={() => setImageStatus(\"error\")}\n style={{\n width: `${zoom * 100}%`,\n maxWidth: \"none\",\n cursor: isDraggable ? (dragging ? \"grabbing\" : \"grab\") : \"default\",\n touchAction: isDraggable ? \"none\" : \"auto\",\n }}\n />\n </div>\n </div>\n </div>\n ) : kind === \"pdf\" ? (\n <object data={file.url} type=\"application/pdf\" className=\"h-full w-full\">\n <div className=\"flex h-full flex-col items-center justify-center gap-3 p-6 text-center\">\n <FileText size={34} className=\"text-muted-foreground\" />\n <p className=\"max-w-md text-sm text-muted-foreground\">\n This browser cannot preview the PDF inline. You can still download or open it in a new tab.\n </p>\n </div>\n </object>\n ) : (\n <div className=\"flex h-full flex-col items-center justify-center gap-3 p-6 text-center\">\n <FileText size={34} className=\"text-muted-foreground\" />\n <p className=\"max-w-md text-sm text-muted-foreground\">\n Preview is not available for this file type. Download or open it in a new tab.\n </p>\n </div>\n )}\n </div>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/files/file-viewer-dialog.tsx"],"names":[],"mappings":"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","file":"file-viewer-dialog.js","sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Download, ExternalLink, FileText, Loader2, Minus, Plus, RotateCcw } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogTitle,\n} from \"../ui/responsive-dialog\";\nimport { cn } from \"../ui/utils\";\n\nexport interface FileViewerFile {\n name: string;\n mimeType: string;\n sizeLabel?: string;\n url: string;\n}\n\nexport function FileViewerDialog({\n file,\n open,\n onOpenChange,\n}: {\n file: FileViewerFile | null;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n const [zoom, setZoom] = useState(1);\n const [dragging, setDragging] = useState(false);\n const [imageStatus, setImageStatus] = useState<\"loading\" | \"ready\" | \"error\">(\"loading\");\n const scrollRef = useRef<HTMLDivElement | null>(null);\n const dragStateRef = useRef<{\n pointerId: number;\n startX: number;\n startY: number;\n scrollLeft: number;\n scrollTop: number;\n } | null>(null);\n\n useEffect(() => {\n if (open) setZoom(1);\n setImageStatus(\"loading\");\n }, [open, file?.url]);\n\n const kind = useMemo(() => {\n if (!file) return \"other\";\n if (file.mimeType.startsWith(\"image/\")) return \"image\";\n if (file.mimeType === \"application/pdf\" || file.name.toLowerCase().endsWith(\".pdf\")) return \"pdf\";\n return \"other\";\n }, [file]);\n\n const zoomPercent = Math.round(zoom * 100);\n const isDraggable = kind === \"image\" && zoom > 1;\n\n const handleImagePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggable || !scrollRef.current) return;\n event.preventDefault();\n dragStateRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n scrollLeft: scrollRef.current.scrollLeft,\n scrollTop: scrollRef.current.scrollTop,\n };\n setDragging(true);\n event.currentTarget.setPointerCapture(event.pointerId);\n };\n\n const handleImagePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId || !scrollRef.current) return;\n scrollRef.current.scrollLeft = state.scrollLeft - (event.clientX - state.startX);\n scrollRef.current.scrollTop = state.scrollTop - (event.clientY - state.startY);\n };\n\n const handleImagePointerEnd = (event: React.PointerEvent<HTMLDivElement>) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId) return;\n dragStateRef.current = null;\n setDragging(false);\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"flex h-[min(88vh,900px)] w-[min(96vw,1100px)] max-w-none flex-col gap-0 overflow-hidden rounded-xl border-border bg-card p-0\">\n <div className=\"flex shrink-0 flex-col gap-3 border-b border-border py-3 pl-4 pr-14 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <ResponsiveDialogTitle className=\"truncate text-base font-semibold text-foreground\">\n {file?.name ?? \"File preview\"}\n </ResponsiveDialogTitle>\n {file?.sizeLabel ? (\n <p className=\"mt-1 text-xs text-muted-foreground\">{file.sizeLabel}</p>\n ) : null}\n </div>\n {file ? (\n <div className=\"flex shrink-0 flex-wrap items-center gap-1.5 lg:justify-end\">\n {kind === \"image\" ? (\n <div className=\"flex items-center gap-0.5 rounded-lg border border-border bg-background p-0.5\">\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-40\"\n onClick={() => setZoom((value) => Math.max(0.25, Number((value - 0.25).toFixed(2))))}\n disabled={zoom <= 0.25}\n aria-label=\"Zoom out\"\n >\n <Minus size={14} />\n </button>\n <span className=\"min-w-11 text-center text-xs font-medium tabular-nums text-muted-foreground\">\n {zoomPercent}%\n </span>\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-40\"\n onClick={() => setZoom((value) => Math.min(4, Number((value + 0.25).toFixed(2))))}\n disabled={zoom >= 4}\n aria-label=\"Zoom in\"\n >\n <Plus size={14} />\n </button>\n <button\n type=\"button\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={() => setZoom(1)}\n aria-label=\"Reset zoom\"\n >\n <RotateCcw size={14} />\n </button>\n </div>\n ) : null}\n <Button\n asChild\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9\"\n title=\"Download\"\n >\n <a href={file.url} download={file.name}>\n <Download size={14} />\n <span className=\"sr-only\">Download</span>\n </a>\n </Button>\n <Button\n asChild\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9\"\n title=\"Open in new tab\"\n >\n <a href={file.url} target=\"_blank\" rel=\"noreferrer\">\n <ExternalLink size={14} />\n <span className=\"sr-only\">Open in new tab</span>\n </a>\n </Button>\n </div>\n ) : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-hidden bg-muted/60\">\n {!file ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n No file selected.\n </div>\n ) : kind === \"image\" ? (\n <div ref={scrollRef} className=\"h-full overflow-auto p-4\">\n <div\n className=\"flex min-h-full items-center justify-center\"\n style={{ minWidth: `${zoom * 100}%` }}\n onPointerDown={handleImagePointerDown}\n onPointerMove={handleImagePointerMove}\n onPointerUp={handleImagePointerEnd}\n onPointerCancel={handleImagePointerEnd}\n >\n <div className=\"relative flex min-h-[240px] w-full items-center justify-center\">\n {imageStatus !== \"ready\" ? (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label={imageStatus === \"error\" ? \"Couldn't load image\" : \"Loading image\"}\n >\n {imageStatus === \"error\" ? (\n <p className=\"text-sm text-muted-foreground\">Couldn't load image</p>\n ) : (\n <Loader2 size={28} className=\"animate-spin text-muted-foreground\" />\n )}\n </div>\n ) : null}\n <img\n src={file.url}\n alt={file.name}\n className={cn(\n \"block shrink-0 select-none rounded-lg border border-border bg-card shadow-sm\",\n imageStatus !== \"ready\" && \"opacity-0\",\n )}\n draggable={false}\n onLoad={() => setImageStatus(\"ready\")}\n onError={() => setImageStatus(\"error\")}\n style={{\n width: `${zoom * 100}%`,\n maxWidth: \"none\",\n cursor: isDraggable ? (dragging ? \"grabbing\" : \"grab\") : \"default\",\n touchAction: isDraggable ? \"none\" : \"auto\",\n }}\n />\n </div>\n </div>\n </div>\n ) : kind === \"pdf\" ? (\n <object data={file.url} type=\"application/pdf\" className=\"h-full w-full\">\n <div className=\"flex h-full flex-col items-center justify-center gap-3 p-6 text-center\">\n <FileText size={34} className=\"text-muted-foreground\" />\n <p className=\"max-w-md text-sm text-muted-foreground\">\n This browser cannot preview the PDF inline. You can still download or open it in a new tab.\n </p>\n </div>\n </object>\n ) : (\n <div className=\"flex h-full flex-col items-center justify-center gap-3 p-6 text-center\">\n <FileText size={34} className=\"text-muted-foreground\" />\n <p className=\"max-w-md text-sm text-muted-foreground\">\n Preview is not available for this file type. Download or open it in a new tab.\n </p>\n </div>\n )}\n </div>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"]}
@@ -1,14 +1,10 @@
1
- import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from './chunk-F7MU5T46.js';
2
- import { Label } from './chunk-RV5PMZYZ.js';
3
- import './chunk-L65F4EMK.js';
4
- import './chunk-PBNBLCC2.js';
5
- import './chunk-VVXGQKN7.js';
6
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-7YCAAP43.js';
7
- import './chunk-DC4QH6W2.js';
8
- import { Input } from './chunk-LUB7QWGU.js';
9
- import { Button } from './chunk-VHINHHZQ.js';
1
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from './chunk-3MAGTCCN.js';
10
2
  import { shellTopBarMutedIconClass, shellTopBarSecondaryButtonClass } from './chunk-FCY5FYJB.js';
3
+ import { Input } from './chunk-PPMJZVR4.js';
4
+ import { Button } from './chunk-VHINHHZQ.js';
11
5
  import './chunk-OWNUMPUC.js';
6
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-7YCAAP43.js';
7
+ import { Label } from './chunk-IBGGQXTH.js';
12
8
  import { cn } from './chunk-DMPSQ22Q.js';
13
9
  import { Layers, ChevronDown, Check, Plus, Trash2 } from 'lucide-react';
14
10
  import { useState, useEffect } from 'react';
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/live-space/floor-switcher.tsx"],"names":[],"mappings":"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","file":"floor-switcher.js","sourcesContent":["import { Check, ChevronDown, Layers, Plus, Trash2 } from \"lucide-react\";\nimport { shellTopBarMutedIconClass, shellTopBarSecondaryButtonClass } from \"../shell/shell-top-bar-chrome\";\nimport {\n Button,\n cn,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n Label,\n} from \"../ui\";\nimport { useEffect, useState } from \"react\";\n\nexport interface FloorSwitcherFloor {\n id: string;\n name: string;\n}\n\nexport function FloorSwitcher({\n floors,\n activeFloorId,\n onFloorChange,\n onAddFloor,\n onDeleteFloor,\n}: {\n floors: FloorSwitcherFloor[];\n activeFloorId: string;\n onFloorChange: (floorId: string) => void;\n onAddFloor?: (name: string) => void;\n onDeleteFloor?: (floorId: string) => void;\n}) {\n const activeFloor = floors.find((f) => f.id === activeFloorId) ?? floors[0];\n const [addOpen, setAddOpen] = useState(false);\n const [name, setName] = useState(\"\");\n const canDeleteFloor = Boolean(onDeleteFloor) && floors.length > 1;\n\n useEffect(() => {\n if (addOpen) {\n setName(`Floor ${floors.length + 1}`);\n }\n }, [addOpen, floors.length]);\n\n const handleAdd = () => {\n onAddFloor?.(name.trim() || `Floor ${floors.length + 1}`);\n setAddOpen(false);\n };\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className={cn(\n shellTopBarSecondaryButtonClass,\n \"min-w-0 max-w-[10rem] outline-none focus-visible:ring-2 focus-visible:ring-blue-500/30\",\n )}\n aria-label=\"Switch floor\"\n >\n <Layers size={12} className={cn(\"shrink-0\", shellTopBarMutedIconClass)} aria-hidden />\n <span className=\"truncate\">{activeFloor?.name ?? \"Floor\"}</span>\n <ChevronDown size={12} className={cn(\"shrink-0\", shellTopBarMutedIconClass)} aria-hidden />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n {floors.map((floor) => (\n <DropdownMenuItem\n key={floor.id}\n onClick={() => onFloorChange(floor.id)}\n className=\"flex items-center justify-between gap-2\"\n >\n <span className=\"truncate\">{floor.name}</span>\n {floor.id === activeFloorId ? (\n <Check size={14} className=\"shrink-0 text-blue-600\" aria-hidden />\n ) : (\n <span className=\"size-3.5 shrink-0\" aria-hidden />\n )}\n </DropdownMenuItem>\n ))}\n {onAddFloor || canDeleteFloor ? (\n <>\n <DropdownMenuSeparator />\n {onAddFloor ? (\n <DropdownMenuItem onClick={() => setAddOpen(true)}>\n <Plus size={14} className=\"mr-1.5\" />\n Add floor…\n </DropdownMenuItem>\n ) : null}\n {canDeleteFloor ? (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => onDeleteFloor?.(activeFloorId)}\n >\n <Trash2 size={14} className=\"mr-1.5\" />\n Delete floor…\n </DropdownMenuItem>\n ) : null}\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n\n {onAddFloor ? (\n <Dialog open={addOpen} onOpenChange={setAddOpen}>\n <DialogContent className=\"sm:max-w-md border-border\">\n <DialogHeader>\n <DialogTitle>Add floor</DialogTitle>\n <DialogDescription>\n Create a new floor with its own resources and 2D layout.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-1\">\n <Label htmlFor=\"new-floor-name\">Name</Label>\n <Input\n id=\"new-floor-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Floor 2\"\n className=\"mt-2 h-9\"\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleAdd();\n }}\n />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setAddOpen(false)}>\n Cancel\n </Button>\n <Button type=\"button\" onClick={handleAdd}>\n Add floor\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n ) : null}\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/live-space/floor-switcher.tsx"],"names":[],"mappings":"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","file":"floor-switcher.js","sourcesContent":["import { Check, ChevronDown, Layers, Plus, Trash2 } from \"lucide-react\";\nimport { shellTopBarMutedIconClass, shellTopBarSecondaryButtonClass } from \"../shell/shell-top-bar-chrome\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../ui/utils\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../ui/dialog\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { useEffect, useState } from \"react\";\n\nexport interface FloorSwitcherFloor {\n id: string;\n name: string;\n}\n\nexport function FloorSwitcher({\n floors,\n activeFloorId,\n onFloorChange,\n onAddFloor,\n onDeleteFloor,\n}: {\n floors: FloorSwitcherFloor[];\n activeFloorId: string;\n onFloorChange: (floorId: string) => void;\n onAddFloor?: (name: string) => void;\n onDeleteFloor?: (floorId: string) => void;\n}) {\n const activeFloor = floors.find((f) => f.id === activeFloorId) ?? floors[0];\n const [addOpen, setAddOpen] = useState(false);\n const [name, setName] = useState(\"\");\n const canDeleteFloor = Boolean(onDeleteFloor) && floors.length > 1;\n\n useEffect(() => {\n if (addOpen) {\n setName(`Floor ${floors.length + 1}`);\n }\n }, [addOpen, floors.length]);\n\n const handleAdd = () => {\n onAddFloor?.(name.trim() || `Floor ${floors.length + 1}`);\n setAddOpen(false);\n };\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className={cn(\n shellTopBarSecondaryButtonClass,\n \"min-w-0 max-w-[10rem] outline-none focus-visible:ring-2 focus-visible:ring-blue-500/30\",\n )}\n aria-label=\"Switch floor\"\n >\n <Layers size={12} className={cn(\"shrink-0\", shellTopBarMutedIconClass)} aria-hidden />\n <span className=\"truncate\">{activeFloor?.name ?? \"Floor\"}</span>\n <ChevronDown size={12} className={cn(\"shrink-0\", shellTopBarMutedIconClass)} aria-hidden />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n {floors.map((floor) => (\n <DropdownMenuItem\n key={floor.id}\n onClick={() => onFloorChange(floor.id)}\n className=\"flex items-center justify-between gap-2\"\n >\n <span className=\"truncate\">{floor.name}</span>\n {floor.id === activeFloorId ? (\n <Check size={14} className=\"shrink-0 text-blue-600\" aria-hidden />\n ) : (\n <span className=\"size-3.5 shrink-0\" aria-hidden />\n )}\n </DropdownMenuItem>\n ))}\n {onAddFloor || canDeleteFloor ? (\n <>\n <DropdownMenuSeparator />\n {onAddFloor ? (\n <DropdownMenuItem onClick={() => setAddOpen(true)}>\n <Plus size={14} className=\"mr-1.5\" />\n Add floor…\n </DropdownMenuItem>\n ) : null}\n {canDeleteFloor ? (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => onDeleteFloor?.(activeFloorId)}\n >\n <Trash2 size={14} className=\"mr-1.5\" />\n Delete floor…\n </DropdownMenuItem>\n ) : null}\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n\n {onAddFloor ? (\n <Dialog open={addOpen} onOpenChange={setAddOpen}>\n <DialogContent className=\"sm:max-w-md border-border\">\n <DialogHeader>\n <DialogTitle>Add floor</DialogTitle>\n <DialogDescription>\n Create a new floor with its own resources and 2D layout.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-1\">\n <Label htmlFor=\"new-floor-name\">Name</Label>\n <Input\n id=\"new-floor-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Floor 2\"\n className=\"mt-2 h-9\"\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleAdd();\n }}\n />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setAddOpen(false)}>\n Cancel\n </Button>\n <Button type=\"button\" onClick={handleAdd}>\n Add floor\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n ) : null}\n </>\n );\n}\n"]}
@@ -1,18 +1,15 @@
1
- export { LayoutCanvasView, matchesCanvasResourceSearch } from './chunk-CKCXQBHQ.js';
1
+ export { LayoutCanvasView, matchesCanvasResourceSearch } from './chunk-RC5SWZPB.js';
2
2
  import './chunk-XU3EFSQX.js';
3
3
  import './chunk-4Y5DBM6Z.js';
4
4
  import './chunk-ZIJQ7BXU.js';
5
- import './chunk-F7MU5T46.js';
6
- import './chunk-RV5PMZYZ.js';
7
- import './chunk-L65F4EMK.js';
8
- import './chunk-PBNBLCC2.js';
9
- import './chunk-VVXGQKN7.js';
10
- import './chunk-7YCAAP43.js';
11
- import './chunk-DC4QH6W2.js';
12
- import './chunk-H7EX6B6N.js';
13
- import './chunk-LUB7QWGU.js';
14
- import './chunk-VHINHHZQ.js';
5
+ import './chunk-5NOKULX2.js';
6
+ import './chunk-CXXOKCLJ.js';
7
+ import './chunk-BQVMO33N.js';
8
+ import './chunk-VIJ2HWPZ.js';
15
9
  import './chunk-FCY5FYJB.js';
10
+ import './chunk-XDVGFHK4.js';
11
+ import './chunk-PPMJZVR4.js';
12
+ import './chunk-VHINHHZQ.js';
16
13
  import './chunk-OWNUMPUC.js';
17
14
  import './chunk-DMPSQ22Q.js';
18
15
  //# sourceMappingURL=layout-canvas-view.js.map
@@ -1,7 +1,9 @@
1
- export { DetailSection, DetailTableFrame, PageListEmptyState, PageListHeader, PageListHeaderRow, PageListPagination, PageListPrimaryActionButton, PageListRoot, PageListSearchField, PageListSecondaryActionButton, PageListSortableTh, PageListStatCard, PageListStatGrid, PageListStickyThead, PageListTable, PageListTableArea, PageListTd, PageListTh, PageListThead, PageListTitleRow, PageListToolbar, PageListTr, ShellTopBarPrimaryActionButton, ShellTopBarSecondaryActionButton, pageListStickyColumnClass, pageListTableWithFixedColumnsClass, pageListTdClass, pageListThClass } from './chunk-H7EX6B6N.js';
2
- import './chunk-LUB7QWGU.js';
3
- import './chunk-VHINHHZQ.js';
1
+ export { DetailSection, DetailTableFrame, PageListEmptyState, PageListHeader, PageListHeaderRow, PageListPagination, PageListPrimaryActionButton, PageListRoot, PageListSearchField, PageListSecondaryActionButton, PageListSortableTh, PageListStatCard, PageListStatGrid, PageListStickyThead, PageListTable, PageListTableArea, PageListTd, PageListTh, PageListThead, PageListTitleRow, PageListToolbar, PageListTr, ShellTopBarPrimaryActionButton, ShellTopBarSecondaryActionButton, pageListStickyColumnClass, pageListTableWithFixedColumnsClass, pageListTdClass, pageListThClass } from './chunk-5NOKULX2.js';
2
+ import './chunk-BQVMO33N.js';
3
+ import './chunk-VIJ2HWPZ.js';
4
4
  export { shellTopBarNeutralActionDataAttr } from './chunk-FCY5FYJB.js';
5
+ import './chunk-PPMJZVR4.js';
6
+ import './chunk-VHINHHZQ.js';
5
7
  import './chunk-OWNUMPUC.js';
6
8
  import './chunk-DMPSQ22Q.js';
7
9
  //# sourceMappingURL=page-list-chrome.js.map
@@ -1,8 +1,10 @@
1
+ import { PageListTable, PageListStickyThead, PageListHeaderRow, PageListTh, PageListTr, PageListTd } from './chunk-5NOKULX2.js';
2
+ import './chunk-BQVMO33N.js';
3
+ import './chunk-VIJ2HWPZ.js';
4
+ import './chunk-FCY5FYJB.js';
1
5
  import { Skeleton } from './chunk-DC4QH6W2.js';
2
- import { PageListTable, PageListStickyThead, PageListHeaderRow, PageListTh, PageListTr, PageListTd } from './chunk-H7EX6B6N.js';
3
- import './chunk-LUB7QWGU.js';
6
+ import './chunk-PPMJZVR4.js';
4
7
  import './chunk-VHINHHZQ.js';
5
- import './chunk-FCY5FYJB.js';
6
8
  import './chunk-OWNUMPUC.js';
7
9
  import './chunk-DMPSQ22Q.js';
8
10
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shell/page-list-loading.tsx"],"names":[],"mappings":"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","file":"page-list-loading.js","sourcesContent":["import type { ReactNode } from \"react\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport {\n PageListHeaderRow,\n PageListStickyThead,\n PageListTable,\n PageListTd,\n PageListTh,\n PageListTr,\n} from \"./page-list-chrome\";\n\nexport type PageListSkeletonCell =\n | \"text\"\n | \"pill\"\n | \"avatar\"\n | \"actions\"\n | \"empty\"\n | \"checkbox\"\n | \"titleBody\";\n\nexport type PageListSkeletonColumn = {\n label?: ReactNode;\n align?: \"left\" | \"right\";\n cell: PageListSkeletonCell;\n className?: string;\n hidden?: boolean;\n};\n\nconst TEXT_WIDTHS = [\"w-28\", \"w-20\", \"w-24\", \"w-32\", \"w-16\"] as const;\n\nexport function StatValueSkeleton() {\n return (\n <span className=\"inline-flex h-5 items-center\" role=\"status\" aria-busy=\"true\" aria-label=\"Loading\">\n <Skeleton className=\"h-4 w-10\" />\n <span className=\"sr-only\">Loading</span>\n </span>\n );\n}\n\nfunction SkeletonCell({ cell, row, align }: { cell: PageListSkeletonCell; row: number; align?: \"left\" | \"right\" }) {\n switch (cell) {\n case \"checkbox\":\n return <Skeleton className=\"size-4 rounded\" />;\n case \"avatar\":\n return (\n <span className=\"inline-flex items-center gap-2.5\">\n <Skeleton className=\"size-7 shrink-0 rounded-full\" />\n <Skeleton className={`h-3.5 ${TEXT_WIDTHS[row % TEXT_WIDTHS.length]}`} />\n </span>\n );\n case \"pill\":\n return <Skeleton className=\"h-5 w-16 rounded-full\" />;\n case \"actions\":\n return (\n <div className={`inline-flex gap-2 ${align === \"right\" ? \"justify-end\" : \"\"}`}>\n <Skeleton className=\"h-7 w-16 rounded-lg\" />\n {row % 3 !== 0 ? <Skeleton className=\"h-7 w-14 rounded-lg\" /> : null}\n </div>\n );\n case \"titleBody\":\n return (\n <div className=\"flex items-start gap-3 min-w-0\">\n <Skeleton className=\"mt-1.5 h-2 w-2 shrink-0 rounded-full\" />\n <div className=\"min-w-0 space-y-1.5\">\n <Skeleton className={`h-3.5 ${row % 2 === 0 ? \"w-40\" : \"w-32\"}`} />\n <Skeleton className={`h-3 ${row % 3 === 0 ? \"w-56\" : \"w-44\"}`} />\n </div>\n </div>\n );\n case \"empty\":\n return null;\n default:\n return (\n <Skeleton\n className={`h-3.5 ${TEXT_WIDTHS[row % TEXT_WIDTHS.length]} ${align === \"right\" ? \"ml-auto\" : \"\"}`}\n />\n );\n }\n}\n\nexport function PageListTableSkeleton({\n columns,\n rows = 8,\n label = \"Loading\",\n minWidth,\n}: {\n columns: PageListSkeletonColumn[];\n rows?: number;\n label?: string;\n minWidth?: number;\n}) {\n const visible = columns.filter((column) => !column.hidden);\n\n return (\n <div role=\"status\" aria-busy=\"true\" aria-label={label}>\n <PageListTable minWidth={minWidth}>\n <PageListStickyThead>\n <PageListHeaderRow>\n {visible.map((column, i) => (\n <PageListTh\n key={i}\n align={column.align}\n className={column.className}\n aria-hidden={column.label == null ? true : undefined}\n >\n {column.label}\n </PageListTh>\n ))}\n </PageListHeaderRow>\n </PageListStickyThead>\n <tbody>\n {Array.from({ length: rows }, (_, row) => (\n <PageListTr key={row}>\n {visible.map((column, i) => (\n <PageListTd key={i} align={column.align} className={column.className}>\n <SkeletonCell cell={column.cell} row={row} align={column.align} />\n </PageListTd>\n ))}\n </PageListTr>\n ))}\n </tbody>\n </PageListTable>\n <span className=\"sr-only\">{label}</span>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/shell/page-list-loading.tsx"],"names":[],"mappings":"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","file":"page-list-loading.js","sourcesContent":["import type { ReactNode } from \"react\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport {\n PageListHeaderRow,\n PageListStickyThead,\n PageListTable,\n PageListTd,\n PageListTh,\n PageListTr,\n} from \"./page-list-chrome\";\n\nexport type PageListSkeletonCell =\n | \"text\"\n | \"pill\"\n | \"avatar\"\n | \"actions\"\n | \"empty\"\n | \"checkbox\"\n | \"titleBody\";\n\nexport type PageListSkeletonColumn = {\n label?: ReactNode;\n align?: \"left\" | \"right\";\n cell: PageListSkeletonCell;\n className?: string;\n hidden?: boolean;\n};\n\nconst TEXT_WIDTHS = [\"w-28\", \"w-20\", \"w-24\", \"w-32\", \"w-16\"] as const;\n\nexport function StatValueSkeleton() {\n return (\n <span className=\"inline-flex h-5 items-center\" role=\"status\" aria-busy=\"true\" aria-label=\"Loading\">\n <Skeleton className=\"h-4 w-10\" />\n <span className=\"sr-only\">Loading</span>\n </span>\n );\n}\n\nfunction SkeletonCell({ cell, row, align }: { cell: PageListSkeletonCell; row: number; align?: \"left\" | \"right\" }) {\n switch (cell) {\n case \"checkbox\":\n return <Skeleton className=\"size-4 rounded\" />;\n case \"avatar\":\n return (\n <span className=\"inline-flex items-center gap-2.5\">\n <Skeleton className=\"size-7 shrink-0 rounded-full\" />\n <Skeleton className={`h-3.5 ${TEXT_WIDTHS[row % TEXT_WIDTHS.length]}`} />\n </span>\n );\n case \"pill\":\n return <Skeleton className=\"h-5 w-16 rounded-full\" />;\n case \"actions\":\n return (\n <div className={`inline-flex gap-2 ${align === \"right\" ? \"justify-end\" : \"\"}`}>\n <Skeleton className=\"h-7 w-16 rounded-lg\" />\n {row % 3 !== 0 ? <Skeleton className=\"h-7 w-14 rounded-lg\" /> : null}\n </div>\n );\n case \"titleBody\":\n return (\n <div className=\"flex items-start gap-3 min-w-0\">\n <Skeleton className=\"mt-1.5 h-2 w-2 shrink-0 rounded-full\" />\n <div className=\"min-w-0 space-y-1.5\">\n <Skeleton className={`h-3.5 ${row % 2 === 0 ? \"w-40\" : \"w-32\"}`} />\n <Skeleton className={`h-3 ${row % 3 === 0 ? \"w-56\" : \"w-44\"}`} />\n </div>\n </div>\n );\n case \"empty\":\n return null;\n default:\n return (\n <Skeleton\n className={`h-3.5 ${TEXT_WIDTHS[row % TEXT_WIDTHS.length]} ${align === \"right\" ? \"ml-auto\" : \"\"}`}\n />\n );\n }\n}\n\nexport function PageListTableSkeleton({\n columns,\n rows = 8,\n label = \"Loading\",\n minWidth,\n}: {\n columns: PageListSkeletonColumn[];\n rows?: number;\n label?: string;\n minWidth?: number;\n}) {\n const visible = columns.filter((column) => !column.hidden);\n\n return (\n <div role=\"status\" aria-busy=\"true\" aria-label={label}>\n <PageListTable minWidth={minWidth}>\n <PageListStickyThead>\n <PageListHeaderRow>\n {visible.map((column, i) => (\n <PageListTh\n key={i}\n align={column.align}\n className={column.className}\n aria-hidden={column.label == null ? true : undefined}\n >\n {column.label}\n </PageListTh>\n ))}\n </PageListHeaderRow>\n </PageListStickyThead>\n <tbody>\n {Array.from({ length: rows }, (_, row) => (\n <PageListTr key={row}>\n {visible.map((column, i) => (\n <PageListTd key={i} align={column.align} className={column.className}>\n <SkeletonCell cell={column.cell} row={row} align={column.align} />\n </PageListTd>\n ))}\n </PageListTr>\n ))}\n </tbody>\n </PageListTable>\n <span className=\"sr-only\">{label}</span>\n </div>\n );\n}\n"]}
@@ -1,15 +1,7 @@
1
1
  import { FilePickerField } from './chunk-OMSJWTSZ.js';
2
- import { Tooltip, TooltipTrigger, TooltipContent, Textarea } from './chunk-F7MU5T46.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-DC4QH6W2.js';
9
- import './chunk-LUB7QWGU.js';
2
+ import { Textarea } from './chunk-VQ63T7CJ.js';
3
+ import { Tooltip, TooltipTrigger, TooltipContent } from './chunk-XDVGFHK4.js';
10
4
  import { Button } from './chunk-VHINHHZQ.js';
11
- import './chunk-FCY5FYJB.js';
12
- import './chunk-OWNUMPUC.js';
13
5
  import { cn } from './chunk-DMPSQ22Q.js';
14
6
  import { useState, useCallback } from 'react';
15
7
  import { Paperclip, X, Image, FileText, Plus, Send } from 'lucide-react';
@@ -1 +1 @@
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
+ {"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 } from \"../ui/button\";\nimport { Textarea } from \"../ui/textarea\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\";\nimport { cn } from \"../ui/utils\";\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"]}
@@ -0,0 +1,85 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { VariantProps } from 'class-variance-authority';
4
+ import { B as Button } from './button-Iem7kbk0.js';
5
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
6
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
7
+
8
+ declare const inputVariants: (props?: ({
9
+ size?: "default" | "sm" | "lg" | "xl" | null | undefined;
10
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
11
+ declare const Input: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "size"> & VariantProps<(props?: ({
12
+ size?: "default" | "sm" | "lg" | "xl" | null | undefined;
13
+ } & class_variance_authority_types.ClassProp) | undefined) => string>, "ref"> & React.RefAttributes<HTMLInputElement>>;
14
+
15
+ declare function Separator({ className, orientation, decorative, ...props }: React.ComponentProps<typeof SeparatorPrimitive.Root>): React.JSX.Element;
16
+
17
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): React.JSX.Element;
18
+ declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element;
19
+ declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element;
20
+ declare function TooltipContent({ className, sideOffset, children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content>): React.JSX.Element;
21
+
22
+ type SidebarContextProps = {
23
+ state: "expanded" | "collapsed";
24
+ open: boolean;
25
+ setOpen: (open: boolean) => void;
26
+ openMobile: boolean;
27
+ setOpenMobile: (open: boolean) => void;
28
+ isMobile: boolean;
29
+ toggleSidebar: () => void;
30
+ };
31
+ declare function useSidebar(): SidebarContextProps;
32
+ declare function SidebarProvider({ defaultOpen, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }: React.ComponentProps<"div"> & {
33
+ defaultOpen?: boolean;
34
+ open?: boolean;
35
+ onOpenChange?: (open: boolean) => void;
36
+ }): React.JSX.Element;
37
+ declare function Sidebar({ side, variant, collapsible, className, children, ...props }: React.ComponentProps<"div"> & {
38
+ side?: "left" | "right";
39
+ variant?: "sidebar" | "floating" | "inset";
40
+ collapsible?: "offcanvas" | "icon" | "none";
41
+ }): React.JSX.Element;
42
+ declare function SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>): React.JSX.Element;
43
+ declare function SidebarRail({ className, ...props }: React.ComponentProps<"button">): React.JSX.Element;
44
+ declare function SidebarInset({ className, ...props }: React.ComponentProps<"main">): React.JSX.Element;
45
+ declare function SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>): React.JSX.Element;
46
+ declare function SidebarHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
47
+ declare function SidebarFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
48
+ declare function SidebarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): React.JSX.Element;
49
+ declare function SidebarContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
50
+ declare function SidebarGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
51
+ declare function SidebarGroupLabel({ className, asChild, ...props }: React.ComponentProps<"div"> & {
52
+ asChild?: boolean;
53
+ }): React.JSX.Element;
54
+ declare function SidebarGroupAction({ className, asChild, ...props }: React.ComponentProps<"button"> & {
55
+ asChild?: boolean;
56
+ }): React.JSX.Element;
57
+ declare function SidebarGroupContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
58
+ declare function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
59
+ declare function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
60
+ declare const sidebarMenuButtonVariants: (props?: ({
61
+ variant?: "default" | "outline" | null | undefined;
62
+ size?: "default" | "sm" | "lg" | null | undefined;
63
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
64
+ declare function SidebarMenuButton({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<"button"> & {
65
+ asChild?: boolean;
66
+ isActive?: boolean;
67
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>;
68
+ } & VariantProps<typeof sidebarMenuButtonVariants>): React.JSX.Element;
69
+ declare function SidebarMenuAction({ className, asChild, showOnHover, ...props }: React.ComponentProps<"button"> & {
70
+ asChild?: boolean;
71
+ showOnHover?: boolean;
72
+ }): React.JSX.Element;
73
+ declare function SidebarMenuBadge({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
74
+ declare function SidebarMenuSkeleton({ className, showIcon, ...props }: React.ComponentProps<"div"> & {
75
+ showIcon?: boolean;
76
+ }): React.JSX.Element;
77
+ declare function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
78
+ declare function SidebarMenuSubItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
79
+ declare function SidebarMenuSubButton({ asChild, size, isActive, className, ...props }: React.ComponentProps<"a"> & {
80
+ asChild?: boolean;
81
+ size?: "sm" | "md";
82
+ isActive?: boolean;
83
+ }): React.JSX.Element;
84
+
85
+ export { TooltipTrigger as A, useSidebar as B, Input as I, Separator as S, TooltipContent as T, Sidebar as a, SidebarContent as b, SidebarFooter as c, SidebarGroup as d, SidebarGroupAction as e, SidebarGroupContent as f, SidebarGroupLabel as g, SidebarHeader as h, inputVariants as i, SidebarInput as j, SidebarInset as k, SidebarMenu as l, SidebarMenuAction as m, SidebarMenuBadge as n, SidebarMenuButton as o, SidebarMenuItem as p, SidebarMenuSkeleton as q, SidebarMenuSub as r, SidebarMenuSubButton as s, SidebarMenuSubItem as t, SidebarProvider as u, SidebarRail as v, SidebarSeparator as w, SidebarTrigger as x, Tooltip as y, TooltipProvider as z };
@@ -1,6 +1,56 @@
1
- @import "@fontsource-variable/inter";
2
-
3
1
  /* src/styles/theme.css */
2
+ @font-face {
3
+ font-family: "Inter Variable";
4
+ font-style: normal;
5
+ font-display: swap;
6
+ font-weight: 100 900;
7
+ src: url(@fontsource-variable/inter/files/inter-latin-wght-normal.woff2) format("woff2-variations");
8
+ unicode-range:
9
+ U+0000-00FF,
10
+ U+0131,
11
+ U+0152-0153,
12
+ U+02BB-02BC,
13
+ U+02C6,
14
+ U+02DA,
15
+ U+02DC,
16
+ U+0304,
17
+ U+0308,
18
+ U+0329,
19
+ U+2000-206F,
20
+ U+20AC,
21
+ U+2122,
22
+ U+2191,
23
+ U+2193,
24
+ U+2212,
25
+ U+2215,
26
+ U+FEFF,
27
+ U+FFFD;
28
+ }
29
+ @font-face {
30
+ font-family: "Inter Variable";
31
+ font-style: normal;
32
+ font-display: swap;
33
+ font-weight: 100 900;
34
+ src: url(@fontsource-variable/inter/files/inter-latin-ext-wght-normal.woff2) format("woff2-variations");
35
+ unicode-range:
36
+ U+0100-02BA,
37
+ U+02BD-02C5,
38
+ U+02C7-02CC,
39
+ U+02CE-02D7,
40
+ U+02DD-02FF,
41
+ U+0304,
42
+ U+0308,
43
+ U+0329,
44
+ U+1D00-1DBF,
45
+ U+1E00-1E9F,
46
+ U+1EF2-1EFF,
47
+ U+2020,
48
+ U+20A0-20AB,
49
+ U+20AD-20C0,
50
+ U+2113,
51
+ U+2C60-2C7F,
52
+ U+A720-A7FF;
53
+ }
4
54
  @custom-variant dark (&:is(.dark *));
5
55
  :root {
6
56
  --font-size: 16px;