@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
@@ -1,18 +1,15 @@
1
- import { LayoutCanvasView } from './chunk-CKCXQBHQ.js';
1
+ import { LayoutCanvasView } 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 { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './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 { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './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 { cn } from './chunk-DMPSQ22Q.js';
18
15
  import { Layers } from 'lucide-react';
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/booking/booking-space-layout-picker.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAgBO,SAAS,wBAAA,CAAyB;AAAA,EACvC,MAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EASG;AACD,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,aAAa,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA;AAErE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,sGAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,IAAA;AAAA,UACA,gBAAA;AAAA,UACA,WAAA;AAAA,UACA,aAAA,EAAe,KAAA;AAAA,UACf,SAAA,EAAU,uBAAA;AAAA,UACV,cACE,MAAA,CAAO,MAAA,GAAS,oBACd,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iCAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAO,IAAA,EAAM,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAiC,eAAW,IAAA,EAAC,CAAA;AAAA,iCACxE,MAAA,EAAA,EAAO,KAAA,EAAO,QAAQ,EAAA,IAAM,aAAA,EAAe,eAAe,aAAA,EACzD,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,iBAAc,SAAA,EAAU,4EAAA,EACvB,8BAAC,WAAA,EAAA,EAAY,WAAA,EAAY,gBAAe,CAAA,EAC1C,CAAA;AAAA,8BACA,GAAA,CAAC,aAAA,EAAA,EACE,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,0BACX,IAAA,CAAC,UAAA,EAAA,EAA0B,KAAA,EAAO,KAAA,CAAM,EAAA,EACrC,QAAA,EAAA;AAAA,gBAAA,KAAA,CAAM,IAAA;AAAA,gBAAK,QAAA;AAAA,gBAAI,KAAA,CAAM,SAAA;AAAA,gBAAU;AAAA,eAAA,EAAA,EADjB,KAAA,CAAM,EAEvB,CACD,CAAA,EACH;AAAA,aAAA,EACF;AAAA,WAAA,EACF,CAAA,GACE;AAAA;AAAA;AAER;AAAA,GACF;AAEJ","file":"booking-space-layout-picker.js","sourcesContent":["\"use client\";\n\nimport { Layers } from \"lucide-react\";\nimport {\n LayoutCanvasView,\n type LayoutCanvasViewRow,\n} from \"../live-space/layout-canvas-view\";\nimport type { LayoutCanvasFloorLayout } from \"../live-space/layout-canvas-types\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, cn } from \"../ui\";\n\nexport type BookingSpaceFloorOption = {\n id: string;\n name: string;\n freeCount: number;\n};\n\nexport function BookingSpaceLayoutPicker({\n floors,\n activeFloorId,\n onFloorChange,\n layout,\n rows,\n selectedIds,\n onResourceSelect,\n className,\n}: {\n floors: BookingSpaceFloorOption[];\n activeFloorId: string;\n onFloorChange: (floorId: string) => void;\n layout: LayoutCanvasFloorLayout;\n rows: LayoutCanvasViewRow[];\n selectedIds: string[];\n onResourceSelect: (id: string) => void;\n className?: string;\n}) {\n const active = floors.find((f) => f.id === activeFloorId) ?? floors[0];\n\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full min-w-0 flex-col overflow-hidden rounded-2xl border border-border bg-card\",\n className,\n )}\n >\n <LayoutCanvasView\n layout={layout}\n rows={rows}\n onResourceSelect={onResourceSelect}\n selectedIds={selectedIds}\n showStatusDot={false}\n className=\"h-full min-h-0 flex-1\"\n toolbarStart={\n floors.length > 0 ? (\n <div className=\"flex min-w-0 items-center gap-2\">\n <Layers size={14} className=\"shrink-0 text-muted-foreground\" aria-hidden />\n <Select value={active?.id ?? activeFloorId} onValueChange={onFloorChange}>\n <SelectTrigger className=\"h-8 min-w-0 max-w-full flex-1 rounded-lg border-border bg-card sm:max-w-xs\">\n <SelectValue placeholder=\"Select floor\" />\n </SelectTrigger>\n <SelectContent>\n {floors.map((floor) => (\n <SelectItem key={floor.id} value={floor.id}>\n {floor.name} · {floor.freeCount} free\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null\n }\n />\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/booking/booking-space-layout-picker.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAuBO,SAAS,wBAAA,CAAyB;AAAA,EACvC,MAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EASG;AACD,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,aAAa,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA;AAErE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,sGAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,IAAA;AAAA,UACA,gBAAA;AAAA,UACA,WAAA;AAAA,UACA,aAAA,EAAe,KAAA;AAAA,UACf,SAAA,EAAU,uBAAA;AAAA,UACV,cACE,MAAA,CAAO,MAAA,GAAS,oBACd,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iCAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAO,IAAA,EAAM,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAiC,eAAW,IAAA,EAAC,CAAA;AAAA,iCACxE,MAAA,EAAA,EAAO,KAAA,EAAO,QAAQ,EAAA,IAAM,aAAA,EAAe,eAAe,aAAA,EACzD,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,iBAAc,SAAA,EAAU,4EAAA,EACvB,8BAAC,WAAA,EAAA,EAAY,WAAA,EAAY,gBAAe,CAAA,EAC1C,CAAA;AAAA,8BACA,GAAA,CAAC,aAAA,EAAA,EACE,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,0BACX,IAAA,CAAC,UAAA,EAAA,EAA0B,KAAA,EAAO,KAAA,CAAM,EAAA,EACrC,QAAA,EAAA;AAAA,gBAAA,KAAA,CAAM,IAAA;AAAA,gBAAK,QAAA;AAAA,gBAAI,KAAA,CAAM,SAAA;AAAA,gBAAU;AAAA,eAAA,EAAA,EADjB,KAAA,CAAM,EAEvB,CACD,CAAA,EACH;AAAA,aAAA,EACF;AAAA,WAAA,EACF,CAAA,GACE;AAAA;AAAA;AAER;AAAA,GACF;AAEJ","file":"booking-space-layout-picker.js","sourcesContent":["\"use client\";\n\nimport { Layers } from \"lucide-react\";\nimport {\n LayoutCanvasView,\n type LayoutCanvasViewRow,\n} from \"../live-space/layout-canvas-view\";\nimport type { LayoutCanvasFloorLayout } from \"../live-space/layout-canvas-types\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport { cn } from \"../ui/utils\";\n\nexport type BookingSpaceFloorOption = {\n id: string;\n name: string;\n freeCount: number;\n};\n\nexport function BookingSpaceLayoutPicker({\n floors,\n activeFloorId,\n onFloorChange,\n layout,\n rows,\n selectedIds,\n onResourceSelect,\n className,\n}: {\n floors: BookingSpaceFloorOption[];\n activeFloorId: string;\n onFloorChange: (floorId: string) => void;\n layout: LayoutCanvasFloorLayout;\n rows: LayoutCanvasViewRow[];\n selectedIds: string[];\n onResourceSelect: (id: string) => void;\n className?: string;\n}) {\n const active = floors.find((f) => f.id === activeFloorId) ?? floors[0];\n\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full min-w-0 flex-col overflow-hidden rounded-2xl border border-border bg-card\",\n className,\n )}\n >\n <LayoutCanvasView\n layout={layout}\n rows={rows}\n onResourceSelect={onResourceSelect}\n selectedIds={selectedIds}\n showStatusDot={false}\n className=\"h-full min-h-0 flex-1\"\n toolbarStart={\n floors.length > 0 ? (\n <div className=\"flex min-w-0 items-center gap-2\">\n <Layers size={14} className=\"shrink-0 text-muted-foreground\" aria-hidden />\n <Select value={active?.id ?? activeFloorId} onValueChange={onFloorChange}>\n <SelectTrigger className=\"h-8 min-w-0 max-w-full flex-1 rounded-lg border-border bg-card sm:max-w-xs\">\n <SelectValue placeholder=\"Select floor\" />\n </SelectTrigger>\n <SelectContent>\n {floors.map((floor) => (\n <SelectItem key={floor.id} value={floor.id}>\n {floor.name} · {floor.freeCount} free\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null\n }\n />\n </div>\n );\n}\n"]}
@@ -0,0 +1,16 @@
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
+
5
+ declare const buttonVariants: (props?: ({
6
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
7
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
8
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
9
+ declare const Button: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
10
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
11
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
12
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
+ asChild?: boolean;
14
+ }, "ref"> & React.RefAttributes<HTMLButtonElement>>;
15
+
16
+ export { Button as B, buttonVariants as b };
@@ -1,14 +1,4 @@
1
- import './chunk-F7MU5T46.js';
2
- import './chunk-RV5PMZYZ.js';
3
- import './chunk-L65F4EMK.js';
4
- import './chunk-PBNBLCC2.js';
5
- import './chunk-VVXGQKN7.js';
6
- import './chunk-7YCAAP43.js';
7
- import './chunk-DC4QH6W2.js';
8
- import './chunk-LUB7QWGU.js';
9
1
  import { Button } from './chunk-VHINHHZQ.js';
10
- import './chunk-FCY5FYJB.js';
11
- import './chunk-OWNUMPUC.js';
12
2
  import { cn } from './chunk-DMPSQ22Q.js';
13
3
  import { useRef, useState, useCallback, useEffect, useLayoutEffect } from 'react';
14
4
  import { ChevronDown } from 'lucide-react';
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/support/chat-stick-to-bottom.tsx"],"names":[],"mappings":"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","file":"chat-stick-to-bottom.js","sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Button, cn } from \"../ui\";\n\nconst NEAR_BOTTOM_PX = 80;\n\nfunction isNearBottom(el: HTMLElement): boolean {\n return el.scrollHeight - el.scrollTop - el.clientHeight <= NEAR_BOTTOM_PX;\n}\n\nexport function useChatStickToBottom(opts: {\n conversationId: string | null;\n itemCount: number;\n lastItemId?: string | null;\n pinToLatest?: boolean;\n layoutKey?: string | number | null;\n}) {\n const scrollerRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const stuckRef = useRef(true);\n const prevConversationId = useRef<string | null>(null);\n const prevItemCount = useRef(0);\n const prevLastItemId = useRef<string | null | undefined>(undefined);\n const [unseenCount, setUnseenCount] = useState(0);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const el = scrollerRef.current;\n if (!el) return;\n stuckRef.current = true;\n setUnseenCount(0);\n const run = () => {\n el.scrollTo({ top: el.scrollHeight, behavior });\n bottomRef.current?.scrollIntoView({ block: \"end\", behavior });\n };\n run();\n requestAnimationFrame(() => {\n run();\n requestAnimationFrame(run);\n });\n window.setTimeout(() => {\n if (!stuckRef.current) return;\n el.scrollTop = el.scrollHeight;\n }, 120);\n }, []);\n\n const syncStuckFromScroll = useCallback(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const atBottom = isNearBottom(el);\n stuckRef.current = atBottom;\n if (atBottom) setUnseenCount(0);\n }, []);\n\n useEffect(() => {\n const root = scrollerRef.current;\n const target = bottomRef.current;\n if (!root || !target) return;\n const io = new IntersectionObserver(\n ([entry]) => {\n if (entry?.isIntersecting) {\n stuckRef.current = true;\n setUnseenCount(0);\n }\n },\n { root, threshold: 0, rootMargin: `0px 0px ${NEAR_BOTTOM_PX}px 0px` },\n );\n io.observe(target);\n return () => io.disconnect();\n }, [opts.conversationId, opts.itemCount]);\n\n useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const onScroll = () => syncStuckFromScroll();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n const ro = new ResizeObserver(() => {\n if (!stuckRef.current) return;\n el.scrollTop = el.scrollHeight;\n });\n ro.observe(el);\n const inner = el.firstElementChild;\n if (inner) ro.observe(inner);\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n ro.disconnect();\n };\n }, [opts.conversationId, opts.itemCount, syncStuckFromScroll]);\n\n useLayoutEffect(() => {\n const conversationChanged = prevConversationId.current !== opts.conversationId;\n const lastIdChanged = prevLastItemId.current !== opts.lastItemId;\n const countDelta = opts.itemCount - prevItemCount.current;\n\n if (conversationChanged) {\n stuckRef.current = true;\n setUnseenCount(0);\n prevConversationId.current = opts.conversationId;\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n if (opts.conversationId) scrollToBottom(\"auto\");\n return;\n }\n\n if (!opts.conversationId) {\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n return;\n }\n\n if (lastIdChanged || countDelta > 0) {\n const added = Math.max(countDelta, lastIdChanged ? 1 : 0);\n if (opts.pinToLatest || stuckRef.current) {\n scrollToBottom(\"smooth\");\n } else if (added > 0) {\n setUnseenCount((n) => n + added);\n }\n }\n\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n }, [opts.conversationId, opts.itemCount, opts.lastItemId, opts.pinToLatest, scrollToBottom]);\n\n useLayoutEffect(() => {\n if (!opts.conversationId || !stuckRef.current) return;\n const el = scrollerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [opts.layoutKey, opts.conversationId]);\n\n return {\n scrollerRef,\n bottomRef,\n unseenCount,\n scrollToBottom: () => scrollToBottom(\"smooth\"),\n };\n}\n\nexport function ChatNewMessagesButton({\n count,\n onClick,\n className,\n}: {\n count: number;\n onClick: () => void;\n className?: string;\n}) {\n if (count <= 0) return null;\n const label = count === 1 ? \"1 new message\" : `${count} new messages`;\n return (\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={onClick}\n className={cn(\"pointer-events-auto h-8 rounded-full px-3 shadow-md\", className)}\n aria-label={label}\n >\n <ChevronDown size={14} strokeWidth={2} />\n {label}\n </Button>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/support/chat-stick-to-bottom.tsx"],"names":[],"mappings":"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","file":"chat-stick-to-bottom.js","sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../ui/utils\";\n\nconst NEAR_BOTTOM_PX = 80;\n\nfunction isNearBottom(el: HTMLElement): boolean {\n return el.scrollHeight - el.scrollTop - el.clientHeight <= NEAR_BOTTOM_PX;\n}\n\nexport function useChatStickToBottom(opts: {\n conversationId: string | null;\n itemCount: number;\n lastItemId?: string | null;\n pinToLatest?: boolean;\n layoutKey?: string | number | null;\n}) {\n const scrollerRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const stuckRef = useRef(true);\n const prevConversationId = useRef<string | null>(null);\n const prevItemCount = useRef(0);\n const prevLastItemId = useRef<string | null | undefined>(undefined);\n const [unseenCount, setUnseenCount] = useState(0);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const el = scrollerRef.current;\n if (!el) return;\n stuckRef.current = true;\n setUnseenCount(0);\n const run = () => {\n el.scrollTo({ top: el.scrollHeight, behavior });\n bottomRef.current?.scrollIntoView({ block: \"end\", behavior });\n };\n run();\n requestAnimationFrame(() => {\n run();\n requestAnimationFrame(run);\n });\n window.setTimeout(() => {\n if (!stuckRef.current) return;\n el.scrollTop = el.scrollHeight;\n }, 120);\n }, []);\n\n const syncStuckFromScroll = useCallback(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const atBottom = isNearBottom(el);\n stuckRef.current = atBottom;\n if (atBottom) setUnseenCount(0);\n }, []);\n\n useEffect(() => {\n const root = scrollerRef.current;\n const target = bottomRef.current;\n if (!root || !target) return;\n const io = new IntersectionObserver(\n ([entry]) => {\n if (entry?.isIntersecting) {\n stuckRef.current = true;\n setUnseenCount(0);\n }\n },\n { root, threshold: 0, rootMargin: `0px 0px ${NEAR_BOTTOM_PX}px 0px` },\n );\n io.observe(target);\n return () => io.disconnect();\n }, [opts.conversationId, opts.itemCount]);\n\n useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const onScroll = () => syncStuckFromScroll();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n const ro = new ResizeObserver(() => {\n if (!stuckRef.current) return;\n el.scrollTop = el.scrollHeight;\n });\n ro.observe(el);\n const inner = el.firstElementChild;\n if (inner) ro.observe(inner);\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n ro.disconnect();\n };\n }, [opts.conversationId, opts.itemCount, syncStuckFromScroll]);\n\n useLayoutEffect(() => {\n const conversationChanged = prevConversationId.current !== opts.conversationId;\n const lastIdChanged = prevLastItemId.current !== opts.lastItemId;\n const countDelta = opts.itemCount - prevItemCount.current;\n\n if (conversationChanged) {\n stuckRef.current = true;\n setUnseenCount(0);\n prevConversationId.current = opts.conversationId;\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n if (opts.conversationId) scrollToBottom(\"auto\");\n return;\n }\n\n if (!opts.conversationId) {\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n return;\n }\n\n if (lastIdChanged || countDelta > 0) {\n const added = Math.max(countDelta, lastIdChanged ? 1 : 0);\n if (opts.pinToLatest || stuckRef.current) {\n scrollToBottom(\"smooth\");\n } else if (added > 0) {\n setUnseenCount((n) => n + added);\n }\n }\n\n prevItemCount.current = opts.itemCount;\n prevLastItemId.current = opts.lastItemId;\n }, [opts.conversationId, opts.itemCount, opts.lastItemId, opts.pinToLatest, scrollToBottom]);\n\n useLayoutEffect(() => {\n if (!opts.conversationId || !stuckRef.current) return;\n const el = scrollerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [opts.layoutKey, opts.conversationId]);\n\n return {\n scrollerRef,\n bottomRef,\n unseenCount,\n scrollToBottom: () => scrollToBottom(\"smooth\"),\n };\n}\n\nexport function ChatNewMessagesButton({\n count,\n onClick,\n className,\n}: {\n count: number;\n onClick: () => void;\n className?: string;\n}) {\n if (count <= 0) return null;\n const label = count === 1 ? \"1 new message\" : `${count} new messages`;\n return (\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={onClick}\n className={cn(\"pointer-events-auto h-8 rounded-full px-3 shadow-md\", className)}\n aria-label={label}\n >\n <ChevronDown size={14} strokeWidth={2} />\n {label}\n </Button>\n );\n}\n"]}
@@ -0,0 +1,116 @@
1
+ import { Label } from './chunk-IBGGQXTH.js';
2
+ import { cn } from './chunk-DMPSQ22Q.js';
3
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
4
+ import { CheckIcon } from 'lucide-react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+ import * as React from 'react';
7
+
8
+ function Checkbox({ className, ...props }) {
9
+ return /* @__PURE__ */ jsx(
10
+ CheckboxPrimitive.Root,
11
+ {
12
+ "data-slot": "checkbox",
13
+ className: cn(
14
+ "peer size-4 shrink-0 cursor-pointer rounded-[4px] border border-border bg-background shadow-xs outline-none transition-colors",
15
+ "hover:border-ring/60 hover:bg-muted/40",
16
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
17
+ "dark:bg-input/30 dark:data-[state=checked]:bg-primary",
18
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
19
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
20
+ "disabled:cursor-not-allowed disabled:opacity-50",
21
+ className
22
+ ),
23
+ ...props,
24
+ children: /* @__PURE__ */ jsx(
25
+ CheckboxPrimitive.Indicator,
26
+ {
27
+ "data-slot": "checkbox-indicator",
28
+ className: "flex items-center justify-center text-current transition-none",
29
+ children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
30
+ }
31
+ )
32
+ }
33
+ );
34
+ }
35
+ function CheckboxField({
36
+ id: idProp,
37
+ label,
38
+ description,
39
+ checked,
40
+ onCheckedChange,
41
+ layout = "inline",
42
+ size = "default",
43
+ className,
44
+ labelClassName,
45
+ disabled,
46
+ ...checkboxProps
47
+ }) {
48
+ const autoId = React.useId();
49
+ const id = idProp ?? autoId;
50
+ const handleChange = (value) => {
51
+ onCheckedChange?.(value === true);
52
+ };
53
+ const labelText = size === "sm" ? "text-xs" : "text-sm";
54
+ if (layout === "between") {
55
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4", className), children: [
56
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
57
+ /* @__PURE__ */ jsx(
58
+ Label,
59
+ {
60
+ htmlFor: id,
61
+ className: cn(
62
+ "cursor-pointer font-medium text-foreground leading-snug",
63
+ labelText,
64
+ labelClassName
65
+ ),
66
+ children: label
67
+ }
68
+ ),
69
+ description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground leading-relaxed", children: description }) : null
70
+ ] }),
71
+ /* @__PURE__ */ jsx(
72
+ Checkbox,
73
+ {
74
+ id,
75
+ checked,
76
+ onCheckedChange: handleChange,
77
+ disabled,
78
+ className: cn(size === "sm" && "size-3.5"),
79
+ ...checkboxProps
80
+ }
81
+ )
82
+ ] });
83
+ }
84
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-start gap-2.5", className), children: [
85
+ /* @__PURE__ */ jsx(
86
+ Checkbox,
87
+ {
88
+ id,
89
+ checked,
90
+ onCheckedChange: handleChange,
91
+ disabled,
92
+ className: cn("shrink-0", size === "default" && "mt-0.5", size === "sm" && "size-3.5"),
93
+ ...checkboxProps
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 grid gap-0.5 pt-px leading-none", children: [
97
+ /* @__PURE__ */ jsx(
98
+ Label,
99
+ {
100
+ htmlFor: id,
101
+ className: cn(
102
+ "cursor-pointer font-normal text-foreground leading-snug",
103
+ labelText,
104
+ labelClassName
105
+ ),
106
+ children: label
107
+ }
108
+ ),
109
+ description ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: description }) : null
110
+ ] })
111
+ ] });
112
+ }
113
+
114
+ export { Checkbox, CheckboxField };
115
+ //# sourceMappingURL=chunk-2IZODKTR.js.map
116
+ //# sourceMappingURL=chunk-2IZODKTR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/checkbox.tsx","../src/ui/checkbox-field.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-2IZODKTR.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { CheckIcon } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"peer size-4 shrink-0 cursor-pointer rounded-[4px] border border-border bg-background shadow-xs outline-none transition-colors\",\n \"hover:border-ring/60 hover:bg-muted/40\",\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"dark:bg-input/30 dark:data-[state=checked]:bg-primary\",\n \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { Checkbox } from \"./checkbox\";\nimport { Label } from \"./label\";\nimport { cn } from \"./utils\";\n\ntype CheckboxFieldProps = Omit<\n React.ComponentProps<typeof Checkbox>,\n \"onCheckedChange\" | \"checked\"\n> & {\n label: React.ReactNode;\n description?: React.ReactNode;\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Checkbox + label (default) or label left / checkbox right. */\n layout?: \"inline\" | \"between\";\n size?: \"default\" | \"sm\";\n className?: string;\n labelClassName?: string;\n};\n\nfunction CheckboxField({\n id: idProp,\n label,\n description,\n checked,\n onCheckedChange,\n layout = \"inline\",\n size = \"default\",\n className,\n labelClassName,\n disabled,\n ...checkboxProps\n}: CheckboxFieldProps) {\n const autoId = React.useId();\n const id = idProp ?? autoId;\n\n const handleChange = (value: boolean | \"indeterminate\") => {\n onCheckedChange?.(value === true);\n };\n\n const labelText = size === \"sm\" ? \"text-xs\" : \"text-sm\";\n\n if (layout === \"between\") {\n return (\n <div className={cn(\"flex items-center justify-between gap-4\", className)}>\n <div className=\"min-w-0\">\n <Label\n htmlFor={id}\n className={cn(\n \"cursor-pointer font-medium text-foreground leading-snug\",\n labelText,\n labelClassName,\n )}\n >\n {label}\n </Label>\n {description ? (\n <p className=\"mt-0.5 text-xs text-muted-foreground leading-relaxed\">{description}</p>\n ) : null}\n </div>\n <Checkbox\n id={id}\n checked={checked}\n onCheckedChange={handleChange}\n disabled={disabled}\n className={cn(size === \"sm\" && \"size-3.5\")}\n {...checkboxProps}\n />\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex items-start gap-2.5\", className)}>\n <Checkbox\n id={id}\n checked={checked}\n onCheckedChange={handleChange}\n disabled={disabled}\n className={cn(\"shrink-0\", size === \"default\" && \"mt-0.5\", size === \"sm\" && \"size-3.5\")}\n {...checkboxProps}\n />\n <div className=\"min-w-0 grid gap-0.5 pt-px leading-none\">\n <Label\n htmlFor={id}\n className={cn(\n \"cursor-pointer font-normal text-foreground leading-snug\",\n labelText,\n labelClassName,\n )}\n >\n {label}\n </Label>\n {description ? (\n <p className=\"text-xs text-muted-foreground leading-relaxed\">{description}</p>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport { CheckboxField };\n"]}
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+
3
+ // src/ui/use-mobile.ts
4
+ var MOBILE_BREAKPOINT = 768;
5
+ function useIsMobile() {
6
+ const [isMobile, setIsMobile] = React.useState(void 0);
7
+ React.useEffect(() => {
8
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
9
+ const onChange = () => {
10
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
11
+ };
12
+ mql.addEventListener("change", onChange);
13
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
14
+ return () => mql.removeEventListener("change", onChange);
15
+ }, []);
16
+ return !!isMobile;
17
+ }
18
+
19
+ export { useIsMobile };
20
+ //# sourceMappingURL=chunk-2TT2ZGMT.js.map
21
+ //# sourceMappingURL=chunk-2TT2ZGMT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/use-mobile.ts"],"names":[],"mappings":";;;AAEA,IAAM,iBAAA,GAAoB,GAAA;AAEnB,SAAS,WAAA,GAAc;AAC5B,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAA8B,MAAS,CAAA;AAE7E,EAAM,gBAAU,MAAM;AACpB,IAAA,MAAM,MAAM,MAAA,CAAO,UAAA,CAAW,CAAA,YAAA,EAAe,iBAAA,GAAoB,CAAC,CAAA,GAAA,CAAK,CAAA;AACvE,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,WAAA,CAAY,MAAA,CAAO,aAAa,iBAAiB,CAAA;AAAA,IACnD,CAAA;AACA,IAAA,GAAA,CAAI,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AACvC,IAAA,WAAA,CAAY,MAAA,CAAO,aAAa,iBAAiB,CAAA;AACjD,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,CAAC,CAAC,QAAA;AACX","file":"chunk-2TT2ZGMT.js","sourcesContent":["import * as React from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener(\"change\", onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return !!isMobile;\n}\n"]}
@@ -0,0 +1,192 @@
1
+ import { cn } from './chunk-DMPSQ22Q.js';
2
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
3
+ import { CheckIcon, CircleIcon, ChevronRightIcon } from 'lucide-react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function DropdownMenu({ ...props }) {
7
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
8
+ }
9
+ function DropdownMenuPortal({
10
+ ...props
11
+ }) {
12
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
13
+ }
14
+ function DropdownMenuTrigger({
15
+ ...props
16
+ }) {
17
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
18
+ }
19
+ function DropdownMenuContent({
20
+ className,
21
+ sideOffset = 4,
22
+ ...props
23
+ }) {
24
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
25
+ DropdownMenuPrimitive.Content,
26
+ {
27
+ "data-slot": "dropdown-menu-content",
28
+ sideOffset,
29
+ className: cn(
30
+ "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-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-white/10 p-1 shadow-md",
31
+ className
32
+ ),
33
+ ...props
34
+ }
35
+ ) });
36
+ }
37
+ function DropdownMenuGroup({ ...props }) {
38
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
39
+ }
40
+ function DropdownMenuItem({
41
+ className,
42
+ inset,
43
+ variant = "default",
44
+ ...props
45
+ }) {
46
+ return /* @__PURE__ */ jsx(
47
+ DropdownMenuPrimitive.Item,
48
+ {
49
+ "data-slot": "dropdown-menu-item",
50
+ "data-inset": inset,
51
+ "data-variant": variant,
52
+ className: cn(
53
+ "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",
54
+ className
55
+ ),
56
+ ...props
57
+ }
58
+ );
59
+ }
60
+ function DropdownMenuCheckboxItem({
61
+ className,
62
+ children,
63
+ checked,
64
+ ...props
65
+ }) {
66
+ return /* @__PURE__ */ jsxs(
67
+ DropdownMenuPrimitive.CheckboxItem,
68
+ {
69
+ "data-slot": "dropdown-menu-checkbox-item",
70
+ className: cn(
71
+ "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",
72
+ className
73
+ ),
74
+ checked,
75
+ ...props,
76
+ children: [
77
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
78
+ children
79
+ ]
80
+ }
81
+ );
82
+ }
83
+ function DropdownMenuRadioGroup({
84
+ ...props
85
+ }) {
86
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
87
+ }
88
+ function DropdownMenuRadioItem({
89
+ className,
90
+ children,
91
+ ...props
92
+ }) {
93
+ return /* @__PURE__ */ jsxs(
94
+ DropdownMenuPrimitive.RadioItem,
95
+ {
96
+ "data-slot": "dropdown-menu-radio-item",
97
+ className: cn(
98
+ "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",
99
+ className
100
+ ),
101
+ ...props,
102
+ children: [
103
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
104
+ children
105
+ ]
106
+ }
107
+ );
108
+ }
109
+ function DropdownMenuLabel({
110
+ className,
111
+ inset,
112
+ ...props
113
+ }) {
114
+ return /* @__PURE__ */ jsx(
115
+ DropdownMenuPrimitive.Label,
116
+ {
117
+ "data-slot": "dropdown-menu-label",
118
+ "data-inset": inset,
119
+ className: cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className),
120
+ ...props
121
+ }
122
+ );
123
+ }
124
+ function DropdownMenuSeparator({
125
+ className,
126
+ ...props
127
+ }) {
128
+ return /* @__PURE__ */ jsx(
129
+ DropdownMenuPrimitive.Separator,
130
+ {
131
+ "data-slot": "dropdown-menu-separator",
132
+ className: cn("bg-card/10 -mx-1 my-1 h-px", className),
133
+ ...props
134
+ }
135
+ );
136
+ }
137
+ function DropdownMenuShortcut({ className, ...props }) {
138
+ return /* @__PURE__ */ jsx(
139
+ "span",
140
+ {
141
+ "data-slot": "dropdown-menu-shortcut",
142
+ className: cn("text-muted-foreground ml-auto text-xs tracking-widest", className),
143
+ ...props
144
+ }
145
+ );
146
+ }
147
+ function DropdownMenuSub({ ...props }) {
148
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
149
+ }
150
+ function DropdownMenuSubTrigger({
151
+ className,
152
+ inset,
153
+ children,
154
+ ...props
155
+ }) {
156
+ return /* @__PURE__ */ jsxs(
157
+ DropdownMenuPrimitive.SubTrigger,
158
+ {
159
+ "data-slot": "dropdown-menu-sub-trigger",
160
+ "data-inset": inset,
161
+ className: cn(
162
+ "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",
163
+ className
164
+ ),
165
+ ...props,
166
+ children: [
167
+ children,
168
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
169
+ ]
170
+ }
171
+ );
172
+ }
173
+ function DropdownMenuSubContent({
174
+ className,
175
+ ...props
176
+ }) {
177
+ return /* @__PURE__ */ jsx(
178
+ DropdownMenuPrimitive.SubContent,
179
+ {
180
+ "data-slot": "dropdown-menu-sub-content",
181
+ className: cn(
182
+ "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-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg border border-white/10 p-1 shadow-md",
183
+ className
184
+ ),
185
+ ...props
186
+ }
187
+ );
188
+ }
189
+
190
+ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
191
+ //# sourceMappingURL=chunk-3MAGTCCN.js.map
192
+ //# sourceMappingURL=chunk-3MAGTCCN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/dropdown-menu.tsx"],"names":[],"mappings":"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","file":"chunk-3MAGTCCN.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\n\nimport { cn } from \"./utils\";\n\nfunction DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\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-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-white/10 p-1 shadow-md\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-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 DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-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 <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-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 <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-card/10 -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-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\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-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-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg border border-white/10 p-1 shadow-md\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n"]}