@spacesync/client 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -14
- package/dist/analog-clock-picker.d.ts +2 -2
- package/dist/analog-clock-picker.js +12 -406
- package/dist/analog-clock-picker.js.map +1 -1
- package/dist/api.js +7 -87
- package/dist/api.js.map +1 -1
- package/dist/app-modal.d.ts +7 -8
- package/dist/app-modal.js +3 -74
- package/dist/app-modal.js.map +1 -1
- package/dist/app-shell-mobile-nav.d.ts +1 -2
- package/dist/app-shell-mobile-nav.js +2 -66
- package/dist/app-shell-mobile-nav.js.map +1 -1
- package/dist/app-web-shell.d.ts +2 -2
- package/dist/app-web-shell.js +1 -4
- package/dist/app-web-shell.js.map +1 -1
- package/dist/booking-schedule-calendars.d.ts +12 -12
- package/dist/booking-schedule-calendars.js +13 -402
- package/dist/booking-schedule-calendars.js.map +1 -1
- package/dist/chat-stick-to-bottom.d.ts +1 -2
- package/dist/chat-stick-to-bottom.js +12 -48
- package/dist/chat-stick-to-bottom.js.map +1 -1
- package/dist/chunk-4A6RCBB5.js +4925 -0
- package/dist/chunk-4A6RCBB5.js.map +1 -0
- package/dist/chunk-4NNK5IXY.js +79 -0
- package/dist/chunk-4NNK5IXY.js.map +1 -0
- package/dist/chunk-4Y5DBM6Z.js +6 -0
- package/dist/chunk-4Y5DBM6Z.js.map +1 -0
- package/dist/chunk-7YCAAP43.js +107 -0
- package/dist/chunk-7YCAAP43.js.map +1 -0
- package/dist/chunk-DMPSQ22Q.js +11 -0
- package/dist/chunk-DMPSQ22Q.js.map +1 -0
- package/dist/chunk-FCY5FYJB.js +104 -0
- package/dist/chunk-FCY5FYJB.js.map +1 -0
- package/dist/chunk-H7EX6B6N.js +580 -0
- package/dist/chunk-H7EX6B6N.js.map +1 -0
- package/dist/chunk-HCHASUB6.js +13 -0
- package/dist/chunk-HCHASUB6.js.map +1 -0
- package/dist/chunk-L65F4EMK.js +34 -0
- package/dist/chunk-L65F4EMK.js.map +1 -0
- package/dist/chunk-LUB7QWGU.js +301 -0
- package/dist/chunk-LUB7QWGU.js.map +1 -0
- package/dist/chunk-OMSJWTSZ.js +120 -0
- package/dist/chunk-OMSJWTSZ.js.map +1 -0
- package/dist/chunk-OWNUMPUC.js +9 -0
- package/dist/chunk-OWNUMPUC.js.map +1 -0
- package/dist/chunk-P65TMY3D.js +87 -0
- package/dist/chunk-P65TMY3D.js.map +1 -0
- package/dist/chunk-PBNBLCC2.js +84 -0
- package/dist/chunk-PBNBLCC2.js.map +1 -0
- package/dist/chunk-RV5PMZYZ.js +63 -0
- package/dist/chunk-RV5PMZYZ.js.map +1 -0
- package/dist/chunk-VHINHHZQ.js +48 -0
- package/dist/chunk-VHINHHZQ.js.map +1 -0
- package/dist/chunk-VVXGQKN7.js +107 -0
- package/dist/chunk-VVXGQKN7.js.map +1 -0
- package/dist/chunk-XU3EFSQX.js +22 -0
- package/dist/chunk-XU3EFSQX.js.map +1 -0
- package/dist/chunk-YAVEMXXV.js +381 -0
- package/dist/chunk-YAVEMXXV.js.map +1 -0
- package/dist/chunk-ZIJQ7BXU.js +27 -0
- package/dist/chunk-ZIJQ7BXU.js.map +1 -0
- package/dist/detail-page-header.d.ts +3 -3
- package/dist/detail-page-header.js +5 -149
- package/dist/detail-page-header.js.map +1 -1
- package/dist/{dialog-CIdvylPK.d.ts → dialog-CPkbi5N3.d.ts} +10 -11
- package/dist/file-picker-field.d.ts +2 -2
- package/dist/file-picker-field.js +3 -163
- package/dist/file-picker-field.js.map +1 -1
- package/dist/file-viewer-dialog.d.ts +2 -2
- package/dist/file-viewer-dialog.js +12 -223
- package/dist/file-viewer-dialog.js.map +1 -1
- package/dist/floor-switcher.d.ts +2 -2
- package/dist/floor-switcher.js +13 -323
- package/dist/floor-switcher.js.map +1 -1
- package/dist/forms.js +1 -23
- package/dist/forms.js.map +1 -1
- package/dist/image-picker-field.d.ts +2 -2
- package/dist/image-picker-field.js +3 -48
- package/dist/image-picker-field.js.map +1 -1
- package/dist/layout-canvas-view.d.ts +2 -2
- package/dist/layout-canvas-view.js +17 -220
- package/dist/layout-canvas-view.js.map +1 -1
- package/dist/lib/dateDisplay.js +1 -82
- package/dist/lib/dateDisplay.js.map +1 -1
- package/dist/live-resource-meta.js +1 -25
- package/dist/live-resource-meta.js.map +1 -1
- package/dist/live-space-pulse-dot.d.ts +2 -2
- package/dist/live-space-pulse-dot.js +2 -16
- package/dist/live-space-pulse-dot.js.map +1 -1
- package/dist/notification-sidebar-preview.d.ts +3 -3
- package/dist/notification-sidebar-preview.js +3 -61
- package/dist/notification-sidebar-preview.js.map +1 -1
- package/dist/page-list-chrome.d.ts +25 -25
- package/dist/page-list-chrome.js +6 -968
- package/dist/page-list-chrome.js.map +1 -1
- package/dist/platform-support-message-composer.d.ts +4 -4
- package/dist/platform-support-message-composer.js +15 -218
- package/dist/platform-support-message-composer.js.map +1 -1
- package/dist/shell-sidebar-nav.js +8 -13
- package/dist/shell-sidebar-nav.js.map +1 -1
- package/dist/shell-theme.js +1 -7
- package/dist/shell-theme.js.map +1 -1
- package/dist/shell-top-bar-chrome.js +3 -103
- package/dist/shell-top-bar-chrome.js.map +1 -1
- package/dist/shell-top-bar.d.ts +3 -3
- package/dist/shell-top-bar.js +1 -69
- package/dist/shell-top-bar.js.map +1 -1
- package/dist/support-presence-status.d.ts +2 -2
- package/dist/support-presence-status.js +3 -41
- package/dist/support-presence-status.js.map +1 -1
- package/dist/theme-appearance-control.d.ts +2 -2
- package/dist/theme-appearance-control.js +4 -63
- package/dist/theme-appearance-control.js.map +1 -1
- package/dist/theme-boot-script.js +1 -2
- package/dist/theme-boot-script.js.map +1 -1
- package/dist/theme-provider.d.ts +2 -2
- package/dist/theme-provider.js +2 -23
- package/dist/theme-provider.js.map +1 -1
- package/dist/ui.d.ts +261 -262
- package/dist/ui.js +11 -5635
- package/dist/ui.js.map +1 -1
- package/package.json +11 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/utils.ts","../src/ui/button.tsx","../src/support/chat-stick-to-bottom.tsx"],"names":["Button","jsx"],"mappings":"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","file":"chat-stick-to-bottom.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"./utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-all disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 active:scale-[0.98]\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 active:bg-destructive/80 active:scale-[0.98] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 dark:active:bg-destructive/70\",\n outline:\n \"border bg-background text-foreground hover:bg-accent hover:text-accent-foreground active:bg-accent/80 active:scale-[0.98] dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:active:bg-input/60\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70 active:scale-[0.98]\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:scale-[0.98] dark:hover:bg-accent/50 dark:active:bg-accent/40\",\n link: \"text-primary underline-offset-4 hover:underline active:text-primary/80\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9 rounded-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }\n>(function Button({ className, variant, size, asChild = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n});\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import { 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, 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"]}
|