@devalok/shilp-sutra 0.53.0 → 0.54.0
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/AGENTS.md +7 -1
- package/BREAKING.json +29 -0
- package/MIGRATION.md +55 -0
- package/dist/composed/avatar-group.d.ts +11 -9
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +108 -140
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +19 -11
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +81 -110
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/error-boundary.d.ts +15 -3
- package/dist/composed/error-boundary.d.ts.map +1 -1
- package/dist/composed/error-boundary.js +43 -26
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/loading-skeleton.d.ts +2 -0
- package/dist/composed/loading-skeleton.d.ts.map +1 -1
- package/dist/composed/loading-skeleton.js +79 -56
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/master-detail.d.ts +21 -8
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js +91 -77
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/page-skeletons.d.ts +6 -0
- package/dist/composed/page-skeletons.d.ts.map +1 -1
- package/dist/composed/page-skeletons.js +93 -71
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/shell/index.d.ts +5 -3
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +2 -3
- package/dist/shell/notification-preferences.d.ts.map +1 -1
- package/dist/shell/notification-preferences.js +2 -0
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/ui/combobox.d.ts +1 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +133 -128
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +124 -138
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.d.ts +7 -0
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +4 -2
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/icon-button.d.ts +2 -1
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/label.d.ts.map +1 -1
- package/dist/ui/label.js +7 -6
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/spinner.d.ts.map +1 -1
- package/dist/ui/spinner.js +50 -44
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +24 -24
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table.js +1 -1
- package/dist/ui/table.js.map +1 -1
- package/docs/components/composed/bulk-action-bar.md +9 -3
- package/docs/components/composed/error-boundary.md +18 -2
- package/docs/components/composed/master-detail.md +12 -2
- package/docs/components/composed/page-skeletons.md +2 -2
- package/docs/components/composed/rich-chat-input.md +18 -6
- package/docs/components/composed/simple-tooltip.md +1 -1
- package/docs/components/shell/app-command-palette.md +2 -1
- package/docs/components/shell/bottom-navbar.md +4 -4
- package/docs/components/shell/command-registry.md +2 -2
- package/docs/components/shell/link-context.md +2 -2
- package/docs/components/shell/top-bar.md +1 -1
- package/docs/components/ui/search-input.md +2 -2
- package/docs/components/ui/slider.md +2 -2
- package/docs/components/ui/split-button.md +3 -3
- package/llms.txt +2 -2
- package/make-kit/Guidelines.md +1 -1
- package/make-kit/components/overview.md +2 -2
- package/make-kit/foundations/surfaces.md +1 -1
- package/mcp-manifest.json +403 -147
- package/package.json +1 -6
- package/skill/SKILL.md +1 -1
- package/skill/chat-skill/README.md +18 -0
- package/skill/chat-skill/SKILL.md +78 -0
- package/skill/chat-skill/chatgpt-instructions.md +26 -0
- package/skill/chat-skill/gemini-instructions.md +25 -0
- package/skill/references/components.md +2 -2
- package/dist/shell/sidebar.d.ts +0 -113
- package/dist/shell/sidebar.d.ts.map +0 -1
- package/dist/shell/sidebar.js +0 -293
- package/dist/shell/sidebar.js.map +0 -1
- package/docs/components/shell/sidebar.md +0 -103
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"master-detail.js","names":[],"sources":["../../src/composed/master-detail.tsx"],"sourcesContent":["'use client'\n\nimport { IconArrowLeft } from '@tabler/icons-react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * A responsive master-detail layout. On desktop, shows a fixed-width list panel\n * alongside a detail panel. Below the breakpoint, switches to a stacked view\n * with animated transitions and a back button.\n */\nexport interface MasterDetailProps extends React.HTMLAttributes<HTMLDivElement> {\n /** ID of currently selected item. null = no selection (show list on mobile). */\n selected?: string | null\n /** Called when mobile back button is pressed. */\n onBack?: () => void\n /** Master panel width on desktop. @default '280px' */\n masterWidth?: string\n /** Breakpoint below which stacked mode activates. @default 'md' */\n breakpoint?: 'sm' | 'md' | 'lg'\n /** Content to show in the detail pane when nothing is selected. */\n emptyState?: React.ReactNode\n /** Called when user presses ArrowUp/ArrowDown while the list has focus. */\n onNavigate?: (direction: 'up' | 'down') => void\n}\n\ninterface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\ninterface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {}\n\ninterface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n active?: boolean\n}\n\n// ============================================================\n// Breakpoint values\n// ============================================================\n\nconst breakpoints: Record<string, string> = {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n}\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false)\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return\n const mql = window.matchMedia(query)\n setMatches(mql.matches)\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches)\n mql.addEventListener('change', handler)\n return () => mql.removeEventListener('change', handler)\n }, [query])\n\n return matches\n}\n\n// ============================================================\n// Context\n// ============================================================\n\ninterface MasterDetailContextValue {\n selected: string | null\n isMobile: boolean\n onBack?: () => void\n emptyState?: React.ReactNode\n onNavigate?: (direction: 'up' | 'down') => void\n activeIndex: number\n setActiveIndex: (index: number) => void\n registerItemRef: (index: number, el: HTMLButtonElement | null) => void\n itemCount: number\n setItemCount: (count: number) => void\n}\n\nconst MasterDetailContext = React.createContext<MasterDetailContextValue>({\n selected: null,\n isMobile: false,\n activeIndex: 0,\n setActiveIndex: () => {},\n registerItemRef: () => {},\n itemCount: 0,\n setItemCount: () => {},\n})\n\n// ============================================================\n// Compound Components\n// ============================================================\n\nfunction MasterDetailList({ children, className, ...props }: MasterDetailListProps) {\n const { selected, isMobile, onNavigate, activeIndex, setActiveIndex, registerItemRef, setItemCount } = React.useContext(MasterDetailContext)\n const itemRefsLocal = React.useRef<(HTMLButtonElement | null)[]>([])\n\n // Count children and register with context\n const childCount = React.Children.count(children)\n React.useEffect(() => {\n setItemCount(childCount)\n }, [childCount, setItemCount])\n\n // Keep roving focus in sync with the active/selected item, so keyboard nav\n // starts on the current selection instead of always the first row.\n const activeChildIndex = React.useMemo(() => {\n let idx = -1\n React.Children.forEach(children, (child, i) => {\n if (\n React.isValidElement(child) &&\n (child.props as { active?: boolean }).active\n ) {\n idx = i\n }\n })\n return idx\n }, [children])\n React.useEffect(() => {\n if (activeChildIndex >= 0) setActiveIndex(activeChildIndex)\n }, [activeChildIndex, setActiveIndex])\n\n // On mobile, hide list when something is selected\n if (isMobile && selected) return null\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n const next = Math.min(activeIndex + 1, childCount - 1)\n setActiveIndex(next)\n itemRefsLocal.current[next]?.focus()\n onNavigate?.('down')\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n const prev = Math.max(activeIndex - 1, 0)\n setActiveIndex(prev)\n itemRefsLocal.current[prev]?.focus()\n onNavigate?.('up')\n } else if (e.key === 'Home') {\n e.preventDefault()\n setActiveIndex(0)\n itemRefsLocal.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = childCount - 1\n setActiveIndex(last)\n itemRefsLocal.current[last]?.focus()\n }\n }\n\n return (\n <div\n role=\"listbox\"\n tabIndex={-1}\n className={cn(\n 'overflow-y-auto focus-visible:outline-hidden',\n !isMobile && 'border-r border-surface-border',\n className,\n )}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {React.Children.map(children, (child, i) => {\n if (!React.isValidElement(child)) return child\n return React.cloneElement(child as React.ReactElement<any>, {\n ref: (el: HTMLButtonElement | null) => {\n itemRefsLocal.current[i] = el\n registerItemRef(i, el)\n },\n tabIndex: i === activeIndex ? 0 : -1,\n })\n })}\n </div>\n )\n}\n\nfunction MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps) {\n const { selected, isMobile, onBack, emptyState } = React.useContext(MasterDetailContext)\n\n // On mobile, hide detail when nothing selected\n if (isMobile && !selected) return null\n\n return (\n <div className={cn('flex-1 overflow-y-auto', className)} {...props}>\n {isMobile && onBack && (\n <div className=\"border-b border-surface-border px-ds-04 py-ds-03\">\n <Button variant=\"ghost\" size=\"xs\" onClick={onBack} startIcon={<Icon icon={IconArrowLeft} />}>\n Back\n </Button>\n </div>\n )}\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={selected ?? 'empty'}\n initial={isMobile ? { x: 20, opacity: 0 } : false}\n animate={{ x: 0, opacity: 1 }}\n exit={isMobile ? { x: -20, opacity: 0 } : undefined}\n transition={springs.snappy}\n >\n {selected ? children : (emptyState ?? children)}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nconst MasterDetailListItem = React.forwardRef<HTMLButtonElement, MasterDetailListItemProps>(\n function MasterDetailListItem({ active = false, children, className, onKeyDown, ...props }, ref) {\n function handleKeyDown(e: React.KeyboardEvent<HTMLButtonElement>) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ;(e.target as HTMLButtonElement).click()\n }\n onKeyDown?.(e)\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n data-active={active || undefined}\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-raised-hover',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset',\n active && 'bg-accent-2 text-accent-11 font-medium',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n },\n)\n\n// ============================================================\n// MasterDetail Root\n// ============================================================\n\nfunction MasterDetailRoot({\n selected = null,\n onBack,\n masterWidth = '280px',\n breakpoint = 'md',\n emptyState,\n onNavigate,\n children,\n className,\n style,\n ...props\n}: MasterDetailProps) {\n const isMobile = useMediaQuery(`(max-width: ${breakpoints[breakpoint]})`)\n const [activeIndex, setActiveIndex] = React.useState(0)\n const [itemCount, setItemCount] = React.useState(0)\n const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([])\n\n const registerItemRef = React.useCallback((index: number, el: HTMLButtonElement | null) => {\n itemRefs.current[index] = el\n }, [])\n\n return (\n <MasterDetailContext.Provider value={{ selected, isMobile, onBack, emptyState, onNavigate, activeIndex, setActiveIndex, registerItemRef, itemCount, setItemCount }}>\n <div\n className={cn(\n 'flex h-full',\n !isMobile && 'grid',\n className,\n )}\n style={{\n ...style,\n ...(isMobile ? {} : { gridTemplateColumns: `${masterWidth} 1fr` }),\n }}\n {...props}\n >\n {children}\n </div>\n </MasterDetailContext.Provider>\n )\n}\n\nconst MasterDetail = Object.assign(MasterDetailRoot, {\n List: MasterDetailList,\n Detail: MasterDetailDetail,\n ListItem: MasterDetailListItem,\n})\n\nexport { MasterDetail }\nexport type { MasterDetailListItemProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"master-detail.js","names":[],"sources":["../../src/composed/master-detail.tsx"],"sourcesContent":["'use client'\n\nimport { IconArrowLeft } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n/**\n * A responsive master-detail layout. Desktop: fixed-width list panel + detail\n * panel. Below the breakpoint: stacked view with a back button. The list is an\n * ARIA `listbox` with roving keyboard nav (Arrow/Home/End + Enter/Space).\n *\n * Selection can be **controlled** (`selected`) or **owned** by the component\n * (`defaultSelected` + `onSelect`, deriving each row's active state from its\n * `value` — no hand-wiring `active` + `onClick` per row).\n */\nexport interface MasterDetailProps\n // Replaces the rarely-used native text-selection `onSelect` with our row-select callback.\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /** Controlled selected item id. `null` = no selection. Omit for uncontrolled. */\n selected?: string | null\n /** Uncontrolled initial selection. */\n defaultSelected?: string | null\n /** Called with a row's `value` when it's chosen (click or Enter/Space). */\n onSelect?: (value: string) => void\n /** Accessible name for the list (the `listbox`). @default 'Items' */\n label?: string\n /** Called when mobile back button is pressed. */\n onBack?: () => void\n /** Master panel width on desktop. @default '280px' */\n masterWidth?: string\n /** Breakpoint below which stacked mode activates. @default 'md' */\n breakpoint?: 'sm' | 'md' | 'lg'\n /** Content to show in the detail pane when nothing is selected. */\n emptyState?: React.ReactNode\n /** Called when the user presses ArrowUp/ArrowDown while the list has focus. */\n onNavigate?: (direction: 'up' | 'down') => void\n}\n\ninterface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Explicit active state. Omit to derive from `value` === the selected id. */\n active?: boolean\n /** Row id — enables derived selection + auto-fires `onSelect` on activate. */\n value?: string\n}\n\nconst breakpoints: Record<string, string> = { sm: '640px', md: '768px', lg: '1024px' }\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false)\n React.useEffect(() => {\n if (typeof window === 'undefined') return\n const mql = window.matchMedia(query)\n setMatches(mql.matches)\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches)\n mql.addEventListener('change', handler)\n return () => mql.removeEventListener('change', handler)\n }, [query])\n return matches\n}\n\ninterface MasterDetailContextValue {\n selected: string | null\n onSelect?: (value: string) => void\n label: string\n isMobile: boolean\n onBack?: () => void\n emptyState?: React.ReactNode\n onNavigate?: (direction: 'up' | 'down') => void\n activeIndex: number\n setActiveIndex: (index: number) => void\n registerItemRef: (index: number, el: HTMLButtonElement | null) => void\n}\n\nconst MasterDetailContext = React.createContext<MasterDetailContextValue>({\n selected: null,\n label: 'Items',\n isMobile: false,\n activeIndex: 0,\n setActiveIndex: () => {},\n registerItemRef: () => {},\n})\n\nfunction itemIsActive(child: React.ReactNode, selected: string | null): boolean {\n if (!React.isValidElement(child)) return false\n const p = child.props as { active?: boolean; value?: string }\n return p.active ?? (p.value != null && p.value === selected)\n}\n\nfunction MasterDetailList({ children, className, 'aria-label': ariaLabel, ...props }: MasterDetailListProps) {\n const { selected, label, isMobile, onNavigate, activeIndex, setActiveIndex, registerItemRef } =\n React.useContext(MasterDetailContext)\n const itemRefsLocal = React.useRef<(HTMLButtonElement | null)[]>([])\n const childCount = React.Children.count(children)\n\n // Roving focus starts on the active/selected row (derived from `active` or `value`).\n const activeChildIndex = React.useMemo(() => {\n let idx = -1\n React.Children.forEach(children, (child, i) => {\n if (itemIsActive(child, selected)) idx = i\n })\n return idx\n }, [children, selected])\n React.useEffect(() => {\n if (activeChildIndex >= 0) setActiveIndex(activeChildIndex)\n }, [activeChildIndex, setActiveIndex])\n\n if (isMobile && selected) return null\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n const next = Math.min(activeIndex + 1, childCount - 1)\n setActiveIndex(next); itemRefsLocal.current[next]?.focus(); onNavigate?.('down')\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n const prev = Math.max(activeIndex - 1, 0)\n setActiveIndex(prev); itemRefsLocal.current[prev]?.focus(); onNavigate?.('up')\n } else if (e.key === 'Home') {\n e.preventDefault(); setActiveIndex(0); itemRefsLocal.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = childCount - 1\n setActiveIndex(last); itemRefsLocal.current[last]?.focus()\n }\n }\n\n return (\n <div\n role=\"listbox\"\n aria-label={ariaLabel ?? label}\n tabIndex={-1}\n className={cn('overflow-y-auto focus-visible:outline-hidden', !isMobile && 'border-e border-surface-border', className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {React.Children.map(children, (child, i) => {\n if (!React.isValidElement(child)) return child\n return React.cloneElement(child as React.ReactElement<any>, {\n ref: (el: HTMLButtonElement | null) => {\n itemRefsLocal.current[i] = el\n registerItemRef(i, el)\n },\n tabIndex: i === activeIndex ? 0 : -1,\n })\n })}\n </div>\n )\n}\n\nfunction MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps) {\n const { selected, isMobile, onBack, emptyState } = React.useContext(MasterDetailContext)\n const reduced = useReducedMotion()\n if (isMobile && !selected) return null\n\n return (\n // aria-live so AT users are told the detail changed when the selection swaps.\n <div role=\"region\" aria-label=\"Detail\" aria-live=\"polite\" className={cn('flex-1 overflow-y-auto', className)} {...props}>\n {isMobile && onBack && (\n <div className=\"border-b border-surface-border px-ds-04 py-ds-03\">\n <Button variant=\"ghost\" size=\"xs\" onClick={onBack} startIcon={<Icon icon={IconArrowLeft} className=\"rtl:-scale-x-100\" />}>\n Back\n </Button>\n </div>\n )}\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={selected ?? 'empty'}\n initial={isMobile && !reduced ? { x: 20, opacity: 0 } : false}\n animate={{ x: 0, opacity: 1 }}\n exit={isMobile && !reduced ? { x: -20, opacity: 0 } : undefined}\n transition={reduced ? { duration: 0 } : springs.snappy}\n >\n {selected ? children : (emptyState ?? children)}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nconst MasterDetailListItem = React.forwardRef<HTMLButtonElement, MasterDetailListItemProps>(\n function MasterDetailListItem({ active, value, children, className, onKeyDown, onClick, ...props }, ref) {\n const { selected, onSelect } = React.useContext(MasterDetailContext)\n const isActive = active ?? (value != null && value === selected)\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLButtonElement>) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ;(e.currentTarget as HTMLButtonElement).click()\n }\n onKeyDown?.(e)\n }\n function handleClick(e: React.MouseEvent<HTMLButtonElement>) {\n if (value != null) onSelect?.(value)\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-active={isActive || undefined}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n className={cn(\n 'flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-raised-hover',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset',\n isActive && 'bg-accent-2 text-accent-11 font-medium',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n },\n)\n\nfunction MasterDetailRoot({\n selected,\n defaultSelected = null,\n onSelect,\n label = 'Items',\n onBack,\n masterWidth = '280px',\n breakpoint = 'md',\n emptyState,\n onNavigate,\n children,\n className,\n style,\n ...props\n}: MasterDetailProps) {\n const isMobile = useMediaQuery(`(max-width: ${breakpoints[breakpoint]})`)\n const [activeIndex, setActiveIndex] = React.useState(0)\n const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([])\n\n // Controlled when `selected` is provided; otherwise own the selection.\n const isControlled = selected !== undefined\n const [internalSelected, setInternalSelected] = React.useState<string | null>(defaultSelected)\n const resolvedSelected = isControlled ? selected ?? null : internalSelected\n\n const handleSelect = React.useCallback(\n (value: string) => {\n if (!isControlled) setInternalSelected(value)\n onSelect?.(value)\n },\n [isControlled, onSelect],\n )\n\n const registerItemRef = React.useCallback((index: number, el: HTMLButtonElement | null) => {\n itemRefs.current[index] = el\n }, [])\n\n return (\n <MasterDetailContext.Provider\n value={{ selected: resolvedSelected, onSelect: handleSelect, label, isMobile, onBack, emptyState, onNavigate, activeIndex, setActiveIndex, registerItemRef }}\n >\n <div\n className={cn('flex h-full', !isMobile && 'grid', className)}\n style={{ ...style, ...(isMobile ? {} : { gridTemplateColumns: `${masterWidth} 1fr` }) }}\n {...props}\n >\n {children}\n </div>\n </MasterDetailContext.Provider>\n )\n}\n\nconst MasterDetail = Object.assign(MasterDetailRoot, {\n List: MasterDetailList,\n Detail: MasterDetailDetail,\n ListItem: MasterDetailListItem,\n})\n\nexport { MasterDetail }\nexport type { MasterDetailListItemProps }\n"],"mappings":"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"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export interface DashboardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
3
|
+
/** Accessible label for the loading region. @default 'Loading' */
|
|
4
|
+
label?: string;
|
|
3
5
|
}
|
|
4
6
|
declare const DashboardSkeleton: React.ForwardRefExoticComponent<DashboardSkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
5
7
|
export interface ProjectListSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
8
|
+
/** Accessible label for the loading region. @default 'Loading' */
|
|
9
|
+
label?: string;
|
|
6
10
|
}
|
|
7
11
|
declare const ProjectListSkeleton: React.ForwardRefExoticComponent<ProjectListSkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
8
12
|
export interface TaskDetailSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
13
|
+
/** Accessible label for the loading region. @default 'Loading' */
|
|
14
|
+
label?: string;
|
|
9
15
|
}
|
|
10
16
|
declare const TaskDetailSkeleton: React.ForwardRefExoticComponent<TaskDetailSkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
17
|
export { DashboardSkeleton, ProjectListSkeleton, TaskDetailSkeleton, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-skeletons.d.ts","sourceRoot":"","sources":["../../src/composed/page-skeletons.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"page-skeletons.d.ts","sourceRoot":"","sources":["../../src/composed/page-skeletons.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAgB9B,MAAM,WAAW,sBAAuB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IACnF,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,iBAAiB,+FAmDtB,CAAA;AAMD,MAAM,WAAW,wBAAyB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IACrF,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,mBAAmB,iGA4DxB,CAAA;AAMD,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IACpF,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,kBAAkB,gGA+CvB,CAAA;AAID,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,CAAA"}
|
|
@@ -3,142 +3,164 @@ import { Skeleton as t } from "../ui/skeleton.js";
|
|
|
3
3
|
import * as n from "react";
|
|
4
4
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
5
|
//#region src/composed/page-skeletons.tsx
|
|
6
|
-
|
|
6
|
+
function a(e) {
|
|
7
|
+
return {
|
|
8
|
+
role: "status",
|
|
9
|
+
"aria-busy": !0,
|
|
10
|
+
"aria-label": e ?? "Loading"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function o({ label: e }) {
|
|
14
|
+
return /* @__PURE__ */ i("span", {
|
|
15
|
+
className: "sr-only",
|
|
16
|
+
children: [e ?? "Loading", "…"]
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
var s = n.forwardRef(function({ className: n, label: s, ...c }, l) {
|
|
7
20
|
return /* @__PURE__ */ i("div", {
|
|
8
|
-
ref:
|
|
9
|
-
...
|
|
21
|
+
ref: l,
|
|
22
|
+
...a(s),
|
|
23
|
+
...c,
|
|
10
24
|
className: e("flex flex-col gap-ds-06", n),
|
|
11
|
-
children: [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
className: "
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ r(o, { label: s }),
|
|
27
|
+
/* @__PURE__ */ r("div", {
|
|
28
|
+
className: "grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-4",
|
|
29
|
+
children: Array.from({ length: 4 }).map((e, n) => /* @__PURE__ */ i("div", {
|
|
30
|
+
className: "flex flex-col gap-ds-04 rounded-surface border border-card bg-surface-raised p-ds-05b",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ i("div", {
|
|
33
|
+
className: "flex items-center justify-between",
|
|
34
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-11" }), /* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-sm rounded-surface" })]
|
|
35
|
+
}),
|
|
36
|
+
/* @__PURE__ */ r(t, { className: "h-ds-xs-plus w-ds-10" }),
|
|
37
|
+
/* @__PURE__ */ r(t, { className: "h-ds-03 w-[112px]" })
|
|
38
|
+
]
|
|
39
|
+
}, `stat-${n}`))
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ i("div", {
|
|
42
|
+
className: "rounded-surface border border-card bg-surface-raised p-ds-06",
|
|
15
43
|
children: [
|
|
16
44
|
/* @__PURE__ */ i("div", {
|
|
17
|
-
className: "flex items-center justify-between",
|
|
18
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
45
|
+
className: "mb-ds-06 flex items-center justify-between",
|
|
46
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-05b w-[128px]" }), /* @__PURE__ */ i("div", {
|
|
47
|
+
className: "flex items-center gap-ds-03",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-sm rounded-surface" }),
|
|
50
|
+
/* @__PURE__ */ r(t, { className: "h-ds-05 w-[112px]" }),
|
|
51
|
+
/* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-sm rounded-surface" })
|
|
52
|
+
]
|
|
53
|
+
})]
|
|
19
54
|
}),
|
|
20
|
-
/* @__PURE__ */ r(
|
|
21
|
-
|
|
55
|
+
/* @__PURE__ */ r("div", {
|
|
56
|
+
className: "mb-ds-03 grid grid-cols-7 gap-ds-03",
|
|
57
|
+
children: Array.from({ length: 7 }).map((e, n) => /* @__PURE__ */ r(t, { className: "mx-auto h-ds-04 w-ds-07" }, `wh-${n}`))
|
|
58
|
+
}),
|
|
59
|
+
/* @__PURE__ */ r("div", {
|
|
60
|
+
className: "grid grid-cols-7 gap-ds-03",
|
|
61
|
+
children: Array.from({ length: 35 }).map((e, n) => /* @__PURE__ */ r(t, { className: "mx-auto h-ds-md w-ds-md rounded-pill" }, `cal-${n}`))
|
|
62
|
+
})
|
|
22
63
|
]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
className: "rounded-overlay-lg border border-card-strong bg-surface-raised p-ds-06",
|
|
26
|
-
children: [
|
|
27
|
-
/* @__PURE__ */ i("div", {
|
|
28
|
-
className: "mb-ds-06 flex items-center justify-between",
|
|
29
|
-
children: [/* @__PURE__ */ r(t, { className: e("h-ds-05b w-[128px]", a) }), /* @__PURE__ */ i("div", {
|
|
30
|
-
className: "flex items-center gap-ds-03",
|
|
31
|
-
children: [
|
|
32
|
-
/* @__PURE__ */ r(t, { className: e("h-ds-sm w-ds-sm rounded-surface", a) }),
|
|
33
|
-
/* @__PURE__ */ r(t, { className: e("h-ds-05 w-[112px]", a) }),
|
|
34
|
-
/* @__PURE__ */ r(t, { className: e("h-ds-sm w-ds-sm rounded-surface", a) })
|
|
35
|
-
]
|
|
36
|
-
})]
|
|
37
|
-
}),
|
|
38
|
-
/* @__PURE__ */ r("div", {
|
|
39
|
-
className: "mb-ds-03 grid grid-cols-7 gap-ds-03",
|
|
40
|
-
children: Array.from({ length: 7 }).map((n, i) => /* @__PURE__ */ r(t, { className: e("mx-auto h-ds-04 w-ds-07", a) }, `wh-${i}`))
|
|
41
|
-
}),
|
|
42
|
-
/* @__PURE__ */ r("div", {
|
|
43
|
-
className: "grid grid-cols-7 gap-ds-03",
|
|
44
|
-
children: Array.from({ length: 35 }).map((n, i) => /* @__PURE__ */ r(t, { className: e("mx-auto h-ds-md w-ds-md rounded-pill", a) }, `cal-${i}`))
|
|
45
|
-
})
|
|
46
|
-
]
|
|
47
|
-
})]
|
|
64
|
+
})
|
|
65
|
+
]
|
|
48
66
|
});
|
|
49
67
|
});
|
|
50
|
-
|
|
51
|
-
var
|
|
68
|
+
s.displayName = "DashboardSkeleton";
|
|
69
|
+
var c = n.forwardRef(function({ className: n, label: s, ...c }, l) {
|
|
52
70
|
return /* @__PURE__ */ i("div", {
|
|
53
|
-
ref:
|
|
54
|
-
...
|
|
71
|
+
ref: l,
|
|
72
|
+
...a(s),
|
|
73
|
+
...c,
|
|
55
74
|
className: e("flex flex-col gap-ds-06", n),
|
|
56
75
|
children: [
|
|
76
|
+
/* @__PURE__ */ r(o, { label: s }),
|
|
57
77
|
/* @__PURE__ */ i("div", {
|
|
58
78
|
className: "flex flex-col gap-ds-05 sm:flex-row sm:items-center sm:justify-between",
|
|
59
79
|
children: [/* @__PURE__ */ i("div", {
|
|
60
80
|
className: "flex flex-col gap-ds-03",
|
|
61
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
62
|
-
}), /* @__PURE__ */ r(t, { className:
|
|
81
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-06 w-[112px]" }), /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-13" })]
|
|
82
|
+
}), /* @__PURE__ */ r(t, { className: "h-ds-sm-plus w-[128px] rounded-surface" })]
|
|
63
83
|
}),
|
|
64
84
|
/* @__PURE__ */ i("div", {
|
|
65
85
|
className: "flex flex-col gap-ds-04 sm:flex-row sm:items-center",
|
|
66
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
86
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-sm-plus flex-1 rounded-surface" }), /* @__PURE__ */ r("div", {
|
|
67
87
|
className: "flex gap-ds-02b",
|
|
68
|
-
children: Array.from({ length: 4 }).map((
|
|
88
|
+
children: Array.from({ length: 4 }).map((e, n) => /* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-10 rounded-surface" }, `f-${n}`))
|
|
69
89
|
})]
|
|
70
90
|
}),
|
|
71
91
|
/* @__PURE__ */ r("div", {
|
|
72
92
|
className: "grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-3",
|
|
73
|
-
children: Array.from({ length: 6 }).map((
|
|
74
|
-
className: "flex flex-col gap-ds-05 rounded-
|
|
93
|
+
children: Array.from({ length: 6 }).map((e, n) => /* @__PURE__ */ i("div", {
|
|
94
|
+
className: "flex flex-col gap-ds-05 rounded-surface border border-card bg-surface-raised p-ds-05b",
|
|
75
95
|
children: [
|
|
76
96
|
/* @__PURE__ */ i("div", {
|
|
77
97
|
className: "flex items-center justify-between",
|
|
78
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
98
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-05b w-ds-10 rounded-pill" }), /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-11 rounded-control" })]
|
|
79
99
|
}),
|
|
80
100
|
/* @__PURE__ */ i("div", {
|
|
81
101
|
className: "flex flex-col gap-ds-03",
|
|
82
102
|
children: [
|
|
83
|
-
/* @__PURE__ */ r(t, { className:
|
|
84
|
-
/* @__PURE__ */ r(t, { className:
|
|
85
|
-
/* @__PURE__ */ r(t, { className:
|
|
103
|
+
/* @__PURE__ */ r(t, { className: "h-ds-05 w-3/4" }),
|
|
104
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-full" }),
|
|
105
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-2/3" })
|
|
86
106
|
]
|
|
87
107
|
}),
|
|
88
108
|
/* @__PURE__ */ i("div", {
|
|
89
109
|
className: "flex items-center justify-between pt-ds-02",
|
|
90
110
|
children: [/* @__PURE__ */ r("div", {
|
|
91
111
|
className: "flex -space-x-ds-03",
|
|
92
|
-
children: Array.from({ length: 3 }).map((
|
|
93
|
-
}), /* @__PURE__ */ r(t, { className:
|
|
112
|
+
children: Array.from({ length: 3 }).map((e, i) => /* @__PURE__ */ r(t, { className: "h-ds-xs-plus w-ds-xs-plus rounded-pill" }, `av-${n}-${i}`))
|
|
113
|
+
}), /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-md" })]
|
|
94
114
|
})
|
|
95
115
|
]
|
|
96
|
-
}, `proj-${
|
|
116
|
+
}, `proj-${n}`))
|
|
97
117
|
})
|
|
98
118
|
]
|
|
99
119
|
});
|
|
100
120
|
});
|
|
101
|
-
|
|
102
|
-
var
|
|
121
|
+
c.displayName = "ProjectListSkeleton";
|
|
122
|
+
var l = n.forwardRef(function({ className: n, label: s, ...c }, l) {
|
|
103
123
|
return /* @__PURE__ */ i("div", {
|
|
104
|
-
ref:
|
|
105
|
-
...
|
|
106
|
-
|
|
124
|
+
ref: l,
|
|
125
|
+
...a(s),
|
|
126
|
+
...c,
|
|
127
|
+
className: e("flex h-full flex-col gap-0 rounded-surface border border-card bg-surface-raised", n),
|
|
107
128
|
children: [
|
|
129
|
+
/* @__PURE__ */ r(o, { label: s }),
|
|
108
130
|
/* @__PURE__ */ i("div", {
|
|
109
131
|
className: "flex items-center justify-between border-b border-surface-border-strong px-ds-05b py-ds-05",
|
|
110
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
132
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-05b w-[192px]" }), /* @__PURE__ */ i("div", {
|
|
111
133
|
className: "flex items-center gap-ds-03",
|
|
112
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
134
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-xs-plus w-ds-xs-plus rounded-surface" }), /* @__PURE__ */ r(t, { className: "h-ds-xs-plus w-ds-xs-plus rounded-surface" })]
|
|
113
135
|
})]
|
|
114
136
|
}),
|
|
115
137
|
/* @__PURE__ */ r("div", {
|
|
116
138
|
className: "flex flex-col gap-0 border-b border-surface-border-strong px-ds-05b py-ds-05",
|
|
117
|
-
children: Array.from({ length: 5 }).map((
|
|
139
|
+
children: Array.from({ length: 5 }).map((e, n) => /* @__PURE__ */ i("div", {
|
|
118
140
|
className: "flex items-center gap-ds-05 py-ds-03",
|
|
119
|
-
children: [/* @__PURE__ */ r(t, { className:
|
|
120
|
-
}, `prop-${
|
|
141
|
+
children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-12 shrink-0" }), /* @__PURE__ */ r(t, { className: "h-ds-06 w-[128px] rounded-control" })]
|
|
142
|
+
}, `prop-${n}`))
|
|
121
143
|
}),
|
|
122
144
|
/* @__PURE__ */ r("div", {
|
|
123
145
|
className: "border-b border-surface-border-strong px-ds-05b",
|
|
124
146
|
children: /* @__PURE__ */ r("div", {
|
|
125
147
|
className: "flex gap-ds-05 py-ds-04",
|
|
126
|
-
children: Array.from({ length: 3 }).map((
|
|
148
|
+
children: Array.from({ length: 3 }).map((e, n) => /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-10" }, `tab-${n}`))
|
|
127
149
|
})
|
|
128
150
|
}),
|
|
129
151
|
/* @__PURE__ */ i("div", {
|
|
130
152
|
className: "flex flex-1 flex-col gap-ds-04 px-ds-05b py-ds-05",
|
|
131
153
|
children: [
|
|
132
|
-
/* @__PURE__ */ r(t, { className:
|
|
133
|
-
/* @__PURE__ */ r(t, { className:
|
|
134
|
-
/* @__PURE__ */ r(t, { className:
|
|
135
|
-
/* @__PURE__ */ r(t, { className:
|
|
136
|
-
/* @__PURE__ */ r(t, { className:
|
|
154
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-full" }),
|
|
155
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-4/5" }),
|
|
156
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-3/5" }),
|
|
157
|
+
/* @__PURE__ */ r(t, { className: "mt-ds-03 h-ds-04 w-full" }),
|
|
158
|
+
/* @__PURE__ */ r(t, { className: "h-ds-04 w-2/3" })
|
|
137
159
|
]
|
|
138
160
|
})
|
|
139
161
|
]
|
|
140
162
|
});
|
|
141
163
|
});
|
|
142
|
-
|
|
164
|
+
l.displayName = "TaskDetailSkeleton";
|
|
143
165
|
//#endregion
|
|
144
|
-
export {
|
|
166
|
+
export { s as DashboardSkeleton, c as ProjectListSkeleton, l as TaskDetailSkeleton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-skeletons.js","names":[],"sources":["../../src/composed/page-skeletons.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\nconst shimmer = 'bg-surface-raised-hover'\n\n// --- Dashboard Skeleton ---\n\nexport interface DashboardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {}\n\nconst DashboardSkeleton = React.forwardRef<HTMLDivElement, DashboardSkeletonProps>(\n function DashboardSkeleton({ className, ...props }, ref) {\n return (\n <div ref={ref} {...props} className={cn(\"flex flex-col gap-ds-06\", className)}>\n {/* Stat cards grid */}\n <div className=\"grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div\n key={`stat-${i}`}\n className=\"flex flex-col gap-ds-04 rounded-overlay-lg border border-card-strong bg-surface-raised p-ds-05b\"\n >\n <div className=\"flex items-center justify-between\">\n <Skeleton className={cn('h-ds-04 w-ds-11', shimmer)} />\n <Skeleton className={cn('h-ds-sm w-ds-sm rounded-surface', shimmer)} />\n </div>\n <Skeleton className={cn('h-ds-xs-plus w-ds-10', shimmer)} />\n <Skeleton className={cn('h-ds-03 w-[112px]', shimmer)} />\n </div>\n ))}\n </div>\n\n {/* Attendance calendar placeholder */}\n <div className=\"rounded-overlay-lg border border-card-strong bg-surface-raised p-ds-06\">\n <div className=\"mb-ds-06 flex items-center justify-between\">\n <Skeleton className={cn('h-ds-05b w-[128px]', shimmer)} />\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className={cn('h-ds-sm w-ds-sm rounded-surface', shimmer)} />\n <Skeleton className={cn('h-ds-05 w-[112px]', shimmer)} />\n <Skeleton className={cn('h-ds-sm w-ds-sm rounded-surface', shimmer)} />\n </div>\n </div>\n {/* Weekday headers */}\n <div className=\"mb-ds-03 grid grid-cols-7 gap-ds-03\">\n {Array.from({ length: 7 }).map((_, i) => (\n <Skeleton key={`wh-${i}`} className={cn('mx-auto h-ds-04 w-ds-07', shimmer)} />\n ))}\n </div>\n {/* Calendar grid */}\n <div className=\"grid grid-cols-7 gap-ds-03\">\n {Array.from({ length: 35 }).map((_, i) => (\n <Skeleton\n key={`cal-${i}`}\n className={cn('mx-auto h-ds-md w-ds-md rounded-pill', shimmer)}\n />\n ))}\n </div>\n </div>\n </div>\n )\n},\n)\n\nDashboardSkeleton.displayName = 'DashboardSkeleton'\n\n// --- Project List Skeleton ---\n\nexport interface ProjectListSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {}\n\nconst ProjectListSkeleton = React.forwardRef<HTMLDivElement, ProjectListSkeletonProps>(\n function ProjectListSkeleton({ className, ...props }, ref) {\n return (\n <div ref={ref} {...props} className={cn(\"flex flex-col gap-ds-06\", className)}>\n {/* Header */}\n <div className=\"flex flex-col gap-ds-05 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-col gap-ds-03\">\n <Skeleton className={cn('h-ds-06 w-[112px]', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-ds-13', shimmer)} />\n </div>\n <Skeleton className={cn('h-ds-sm-plus w-[128px] rounded-surface', shimmer)} />\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-ds-04 sm:flex-row sm:items-center\">\n <Skeleton className={cn('h-ds-sm-plus flex-1 rounded-surface', shimmer)} />\n <div className=\"flex gap-ds-02b\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={`f-${i}`} className={cn('h-ds-sm w-ds-10 rounded-surface', shimmer)} />\n ))}\n </div>\n </div>\n\n {/* Project cards grid */}\n <div className=\"grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div\n key={`proj-${i}`}\n className=\"flex flex-col gap-ds-05 rounded-overlay-lg border border-card-strong bg-surface-raised p-ds-05b\"\n >\n {/* Top row: status + org */}\n <div className=\"flex items-center justify-between\">\n <Skeleton className={cn('h-ds-05b w-ds-10 rounded-pill', shimmer)} />\n <Skeleton className={cn('h-ds-05 w-ds-11 rounded-control', shimmer)} />\n </div>\n {/* Title + description */}\n <div className=\"flex flex-col gap-ds-03\">\n <Skeleton className={cn('h-ds-05 w-3/4', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-full', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-2/3', shimmer)} />\n </div>\n {/* Bottom row: members + count */}\n <div className=\"flex items-center justify-between pt-ds-02\">\n <div className=\"flex -space-x-ds-03\">\n {Array.from({ length: 3 }).map((_, j) => (\n <Skeleton\n key={`av-${i}-${j}`}\n className={cn('h-ds-xs-plus w-ds-xs-plus rounded-pill', shimmer)}\n />\n ))}\n </div>\n <Skeleton className={cn('h-ds-04 w-ds-md', shimmer)} />\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n},\n)\n\nProjectListSkeleton.displayName = 'ProjectListSkeleton'\n\n// --- Task Detail Skeleton ---\n\nexport interface TaskDetailSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {}\n\nconst TaskDetailSkeleton = React.forwardRef<HTMLDivElement, TaskDetailSkeletonProps>(\n function TaskDetailSkeleton({ className, ...props }, ref) {\n return (\n <div ref={ref} {...props} className={cn(\"flex h-full flex-col gap-0 rounded-overlay-lg border border-card-strong bg-surface-raised\", className)}>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-surface-border-strong px-ds-05b py-ds-05\">\n <Skeleton className={cn('h-ds-05b w-[192px]', shimmer)} />\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className={cn('h-ds-xs-plus w-ds-xs-plus rounded-surface', shimmer)} />\n <Skeleton className={cn('h-ds-xs-plus w-ds-xs-plus rounded-surface', shimmer)} />\n </div>\n </div>\n\n {/* Property rows */}\n <div className=\"flex flex-col gap-0 border-b border-surface-border-strong px-ds-05b py-ds-05\">\n {Array.from({ length: 5 }).map((_, i) => (\n <div\n key={`prop-${i}`}\n className=\"flex items-center gap-ds-05 py-ds-03\"\n >\n <Skeleton className={cn('h-ds-04 w-ds-12 shrink-0', shimmer)} />\n <Skeleton className={cn('h-ds-06 w-[128px] rounded-control', shimmer)} />\n </div>\n ))}\n </div>\n\n {/* Tabs */}\n <div className=\"border-b border-surface-border-strong px-ds-05b\">\n <div className=\"flex gap-ds-05 py-ds-04\">\n {Array.from({ length: 3 }).map((_, i) => (\n <Skeleton key={`tab-${i}`} className={cn('h-ds-05 w-ds-10', shimmer)} />\n ))}\n </div>\n </div>\n\n {/* Tab content */}\n <div className=\"flex flex-1 flex-col gap-ds-04 px-ds-05b py-ds-05\">\n <Skeleton className={cn('h-ds-04 w-full', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-4/5', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-3/5', shimmer)} />\n <Skeleton className={cn('mt-ds-03 h-ds-04 w-full', shimmer)} />\n <Skeleton className={cn('h-ds-04 w-2/3', shimmer)} />\n </div>\n </div>\n )\n},\n)\n\nTaskDetailSkeleton.displayName = 'TaskDetailSkeleton'\n\nexport {\n DashboardSkeleton,\n ProjectListSkeleton,\n TaskDetailSkeleton,\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"page-skeletons.js","names":[],"sources":["../../src/composed/page-skeletons.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\n// role=status + aria-busy so AT announces the loading region (child Skeletons are\n// aria-hidden). The sr-only label carries the announcement text.\nfunction statusProps(label?: string) {\n return { role: 'status' as const, 'aria-busy': true, 'aria-label': label ?? 'Loading' }\n}\nfunction SrLabel({ label }: { label?: string }) {\n return <span className=\"sr-only\">{label ?? 'Loading'}…</span>\n}\n\n// --- Dashboard Skeleton ---\n\nexport interface DashboardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst DashboardSkeleton = React.forwardRef<HTMLDivElement, DashboardSkeletonProps>(\n function DashboardSkeleton({ className, label, ...props }, ref) {\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn(\"flex flex-col gap-ds-06\", className)}>\n <SrLabel label={label} />\n {/* Stat cards grid */}\n <div className=\"grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div\n key={`stat-${i}`}\n className=\"flex flex-col gap-ds-04 rounded-surface border border-card bg-surface-raised p-ds-05b\"\n >\n <div className=\"flex items-center justify-between\">\n <Skeleton className={'h-ds-04 w-ds-11'} />\n <Skeleton className={'h-ds-sm w-ds-sm rounded-surface'} />\n </div>\n <Skeleton className={'h-ds-xs-plus w-ds-10'} />\n <Skeleton className={'h-ds-03 w-[112px]'} />\n </div>\n ))}\n </div>\n\n {/* Attendance calendar placeholder */}\n <div className=\"rounded-surface border border-card bg-surface-raised p-ds-06\">\n <div className=\"mb-ds-06 flex items-center justify-between\">\n <Skeleton className={'h-ds-05b w-[128px]'} />\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className={'h-ds-sm w-ds-sm rounded-surface'} />\n <Skeleton className={'h-ds-05 w-[112px]'} />\n <Skeleton className={'h-ds-sm w-ds-sm rounded-surface'} />\n </div>\n </div>\n {/* Weekday headers */}\n <div className=\"mb-ds-03 grid grid-cols-7 gap-ds-03\">\n {Array.from({ length: 7 }).map((_, i) => (\n <Skeleton key={`wh-${i}`} className={'mx-auto h-ds-04 w-ds-07'} />\n ))}\n </div>\n {/* Calendar grid */}\n <div className=\"grid grid-cols-7 gap-ds-03\">\n {Array.from({ length: 35 }).map((_, i) => (\n <Skeleton\n key={`cal-${i}`}\n className={'mx-auto h-ds-md w-ds-md rounded-pill'}\n />\n ))}\n </div>\n </div>\n </div>\n )\n},\n)\n\nDashboardSkeleton.displayName = 'DashboardSkeleton'\n\n// --- Project List Skeleton ---\n\nexport interface ProjectListSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst ProjectListSkeleton = React.forwardRef<HTMLDivElement, ProjectListSkeletonProps>(\n function ProjectListSkeleton({ className, label, ...props }, ref) {\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn(\"flex flex-col gap-ds-06\", className)}>\n <SrLabel label={label} />\n {/* Header */}\n <div className=\"flex flex-col gap-ds-05 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-col gap-ds-03\">\n <Skeleton className={'h-ds-06 w-[112px]'} />\n <Skeleton className={'h-ds-04 w-ds-13'} />\n </div>\n <Skeleton className={'h-ds-sm-plus w-[128px] rounded-surface'} />\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-ds-04 sm:flex-row sm:items-center\">\n <Skeleton className={'h-ds-sm-plus flex-1 rounded-surface'} />\n <div className=\"flex gap-ds-02b\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={`f-${i}`} className={'h-ds-sm w-ds-10 rounded-surface'} />\n ))}\n </div>\n </div>\n\n {/* Project cards grid */}\n <div className=\"grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div\n key={`proj-${i}`}\n className=\"flex flex-col gap-ds-05 rounded-surface border border-card bg-surface-raised p-ds-05b\"\n >\n {/* Top row: status + org */}\n <div className=\"flex items-center justify-between\">\n <Skeleton className={'h-ds-05b w-ds-10 rounded-pill'} />\n <Skeleton className={'h-ds-05 w-ds-11 rounded-control'} />\n </div>\n {/* Title + description */}\n <div className=\"flex flex-col gap-ds-03\">\n <Skeleton className={'h-ds-05 w-3/4'} />\n <Skeleton className={'h-ds-04 w-full'} />\n <Skeleton className={'h-ds-04 w-2/3'} />\n </div>\n {/* Bottom row: members + count */}\n <div className=\"flex items-center justify-between pt-ds-02\">\n <div className=\"flex -space-x-ds-03\">\n {Array.from({ length: 3 }).map((_, j) => (\n <Skeleton\n key={`av-${i}-${j}`}\n className={'h-ds-xs-plus w-ds-xs-plus rounded-pill'}\n />\n ))}\n </div>\n <Skeleton className={'h-ds-04 w-ds-md'} />\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n},\n)\n\nProjectListSkeleton.displayName = 'ProjectListSkeleton'\n\n// --- Task Detail Skeleton ---\n\nexport interface TaskDetailSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst TaskDetailSkeleton = React.forwardRef<HTMLDivElement, TaskDetailSkeletonProps>(\n function TaskDetailSkeleton({ className, label, ...props }, ref) {\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn(\"flex h-full flex-col gap-0 rounded-surface border border-card bg-surface-raised\", className)}>\n <SrLabel label={label} />\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-surface-border-strong px-ds-05b py-ds-05\">\n <Skeleton className={'h-ds-05b w-[192px]'} />\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className={'h-ds-xs-plus w-ds-xs-plus rounded-surface'} />\n <Skeleton className={'h-ds-xs-plus w-ds-xs-plus rounded-surface'} />\n </div>\n </div>\n\n {/* Property rows */}\n <div className=\"flex flex-col gap-0 border-b border-surface-border-strong px-ds-05b py-ds-05\">\n {Array.from({ length: 5 }).map((_, i) => (\n <div\n key={`prop-${i}`}\n className=\"flex items-center gap-ds-05 py-ds-03\"\n >\n <Skeleton className={'h-ds-04 w-ds-12 shrink-0'} />\n <Skeleton className={'h-ds-06 w-[128px] rounded-control'} />\n </div>\n ))}\n </div>\n\n {/* Tabs */}\n <div className=\"border-b border-surface-border-strong px-ds-05b\">\n <div className=\"flex gap-ds-05 py-ds-04\">\n {Array.from({ length: 3 }).map((_, i) => (\n <Skeleton key={`tab-${i}`} className={'h-ds-05 w-ds-10'} />\n ))}\n </div>\n </div>\n\n {/* Tab content */}\n <div className=\"flex flex-1 flex-col gap-ds-04 px-ds-05b py-ds-05\">\n <Skeleton className={'h-ds-04 w-full'} />\n <Skeleton className={'h-ds-04 w-4/5'} />\n <Skeleton className={'h-ds-04 w-3/5'} />\n <Skeleton className={'mt-ds-03 h-ds-04 w-full'} />\n <Skeleton className={'h-ds-04 w-2/3'} />\n </div>\n </div>\n )\n},\n)\n\nTaskDetailSkeleton.displayName = 'TaskDetailSkeleton'\n\nexport {\n DashboardSkeleton,\n ProjectListSkeleton,\n TaskDetailSkeleton,\n}\n"],"mappings":"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"}
|
package/dist/shell/index.d.ts
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @module @devalok/shilp-sutra/shell
|
|
4
4
|
*
|
|
5
|
-
* Application shell components:
|
|
5
|
+
* Application shell components: top bar, bottom nav, notifications, and command palette.
|
|
6
6
|
* All shell components require client-side React ("use client").
|
|
7
7
|
*
|
|
8
|
+
* For sidebars, compose the `Sidebar` primitives from `@devalok/shilp-sutra/ui/sidebar`,
|
|
9
|
+
* or start from a ready-made preset (e.g. `sidebar-app`) at
|
|
10
|
+
* https://shilp-sutra.devalok.in/presets.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
|
-
* import { AppSidebar } from '@devalok/shilp-sutra/shell/sidebar'
|
|
10
13
|
* import { TopBar } from '@devalok/shilp-sutra/shell/top-bar'
|
|
11
14
|
*/
|
|
12
15
|
export { AppCommandPalette, type AppCommandPaletteProps, type AppCommandPaletteUser, type SearchResult, type SearchResultGroup, } from './app-command-palette';
|
|
@@ -15,6 +18,5 @@ export { type CommandPageItem, type CommandRegistry, CommandRegistryProvider, ty
|
|
|
15
18
|
export { LinkProvider, type LinkProviderProps, useLink } from './link-context';
|
|
16
19
|
export { type Notification, NotificationCenter, type NotificationCenterProps, } from './notification-center';
|
|
17
20
|
export { type NotificationPreference, NotificationPreferences, type NotificationPreferencesProps, type NotificationProject, } from './notification-preferences';
|
|
18
|
-
export { AppSidebar, type AppSidebarProps, type NavGroup, type NavItem, type SidebarUser, } from './sidebar';
|
|
19
21
|
export { TopBar, type TopBarProps, type TopBarUser, type UserMenuItem, } from './top-bar';
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,iBAAiB,GACvB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,uBAAuB,EACvB,KAAK,4BAA4B,EACjC,kBAAkB,GACnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAC,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAC7E,OAAO,EACL,KAAK,YAAY,EACjB,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,KAAK,sBAAsB,EAC3B,uBAAuB,EACvB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,WAAW,CAAA"}
|
package/dist/shell/index.js
CHANGED
|
@@ -6,6 +6,5 @@ import "./link-context.js";
|
|
|
6
6
|
import { BottomNavbar as a } from "./bottom-navbar.js";
|
|
7
7
|
import { NotificationCenter as o } from "./notification-center.js";
|
|
8
8
|
import { NotificationPreferences as s } from "./notification-preferences.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
export { i as AppCommandPalette, c as AppSidebar, a as BottomNavbar, n as CommandRegistryProvider, e as LinkProvider, o as NotificationCenter, s as NotificationPreferences, l as TopBar, r as useCommandRegistry, t as useLink };
|
|
9
|
+
import { TopBar as c } from "./top-bar.js";
|
|
10
|
+
export { i as AppCommandPalette, a as BottomNavbar, n as CommandRegistryProvider, e as LinkProvider, o as NotificationCenter, s as NotificationPreferences, c as TopBar, r as useCommandRegistry, t as useLink };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-preferences.d.ts","sourceRoot":"","sources":["../../src/shell/notification-preferences.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA6B9B,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC1D,+BAA+B;IAC/B,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAA;IACtC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAA;IAChC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE;QACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;QACxB,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,OAAO,CAAA;KACf,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3E,gDAAgD;IAChD,YAAY,CAAC,EAAE,CACb,UAAU,EAAE,sBAAsB,EAClC,OAAO,EAAE,MAAM,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqBD,QAAA,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"notification-preferences.d.ts","sourceRoot":"","sources":["../../src/shell/notification-preferences.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA6B9B,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC1D,+BAA+B;IAC/B,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAA;IACtC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAA;IAChC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE;QACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;QACxB,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,OAAO,CAAA;KACf,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3E,gDAAgD;IAChD,YAAY,CAAC,EAAE,CACb,UAAU,EAAE,sBAAsB,EAClC,OAAO,EAAE,MAAM,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqBD,QAAA,MAAM,uBAAuB,kHAgQ5B,CAAA;AAID,OAAO,EAAE,uBAAuB,EAAE,CAAA"}
|
|
@@ -109,6 +109,7 @@ var k = {
|
|
|
109
109
|
value: t.minTier,
|
|
110
110
|
onValueChange: (e) => N?.(t, e),
|
|
111
111
|
children: [/* @__PURE__ */ C(_, {
|
|
112
|
+
"aria-label": `Minimum notification tier for ${i.label} on ${Q(t.projectId)}`,
|
|
112
113
|
className: "h-ds-xs-plus w-[130px] text-body-sm",
|
|
113
114
|
children: /* @__PURE__ */ C(v, {})
|
|
114
115
|
}), /* @__PURE__ */ C(h, { children: Object.entries(A).map(([e, t]) => /* @__PURE__ */ C(g, {
|
|
@@ -122,6 +123,7 @@ var k = {
|
|
|
122
123
|
className: "text-body-sm text-surface-fg-subtle",
|
|
123
124
|
children: t.muted ? "Muted" : "Active"
|
|
124
125
|
}), /* @__PURE__ */ C(y, {
|
|
126
|
+
"aria-label": `${t.muted ? "Unmute" : "Mute"} ${i.label} for ${Q(t.projectId)}`,
|
|
125
127
|
checked: !t.muted,
|
|
126
128
|
onCheckedChange: () => M?.(t)
|
|
127
129
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-preferences.js","names":[],"sources":["../../src/shell/notification-preferences.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationPreferences -- Manage notification rules per channel/project.\n *\n * Props-driven: accepts preferences array, projects, and callbacks.\n * No internal fetching -- the consumer is responsible for data loading.\n */\nimport { IconBell, IconMessage,IconPlus, IconTrash } from '@tabler/icons-react'\nimport * as React from 'react'\nimport { useState } from 'react'\n\nimport { Button } from '../ui/button'\nimport { Card, CardContent,CardHeader, CardTitle } from '../ui/card'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconButton } from '../ui/icon-button'\nimport { cn } from '../ui/lib/utils'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { Spinner } from '../ui/spinner'\nimport { Switch } from '../ui/switch'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NotificationPreference {\n id: string\n userId?: string\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n}\n\nexport interface NotificationProject {\n id: string\n title: string\n}\n\nexport interface NotificationPreferencesProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'onSave'> {\n /** Current preference rules */\n preferences?: NotificationPreference[]\n /** Available projects for scoping rules */\n projects?: NotificationProject[]\n /** Whether data is loading */\n isLoading?: boolean\n /** Called to add or update a preference */\n onSave?: (preference: {\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n }) => void | Promise<void>\n /** Called to toggle mute on a preference */\n onToggleMute?: (preference: NotificationPreference) => void | Promise<void>\n /** Called to update the tier on a preference */\n onUpdateTier?: (\n preference: NotificationPreference,\n newTier: string,\n ) => void | Promise<void>\n /** Called to delete a preference */\n onDelete?: (preferenceId: string) => void | Promise<void>\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Constants\n// -----------------------------------------------------------------------\n\nconst CHANNEL_LABELS: Record<string, { label: string; icon: React.ReactNode }> = {\n IN_APP: { label: 'In-App', icon: <Icon icon={IconBell} size=\"sm\" /> },\n GOOGLE_CHAT: { label: 'Google Chat', icon: <Icon icon={IconMessage} size=\"sm\" /> },\n}\n\nconst TIER_LABELS: Record<string, string> = {\n INFO: 'All (Info+)',\n IMPORTANT: 'Important+',\n CRITICAL: 'Critical only',\n}\n\n// -----------------------------------------------------------------------\n// NotificationPreferences\n// -----------------------------------------------------------------------\n\nconst NotificationPreferences = React.forwardRef<HTMLDivElement, NotificationPreferencesProps>(\n function NotificationPreferences(\n {\n preferences = [],\n projects = [],\n isLoading = false,\n onSave,\n onToggleMute,\n onUpdateTier,\n onDelete,\n className,\n ...props\n },\n ref,\n ) {\n const [showAddDialog, setShowAddDialog] = useState(false)\n const [newProjectId, setNewProjectId] = useState<string>('global')\n const [newChannel, setNewChannel] = useState<string>('IN_APP')\n const [newMinTier, setNewMinTier] = useState<string>('INFO')\n const [newMuted, setNewMuted] = useState(false)\n const [isSaving, setIsSaving] = useState(false)\n\n const handleAdd = async () => {\n if (!onSave) return\n setIsSaving(true)\n try {\n await onSave({\n projectId: newProjectId === 'global' ? null : newProjectId,\n channel: newChannel,\n minTier: newMinTier,\n muted: newMuted,\n })\n setShowAddDialog(false)\n resetForm()\n } catch (error) {\n console.error('[Preferences] Failed to save:', error)\n } finally {\n setIsSaving(false)\n }\n }\n\n const resetForm = () => {\n setNewProjectId('global')\n setNewChannel('IN_APP')\n setNewMinTier('INFO')\n setNewMuted(false)\n }\n\n const getProjectName = (projectId: string | null) => {\n if (!projectId) return 'Global (all projects)'\n const project = projects.find((p) => p.id === projectId)\n return project?.title || 'Unknown project'\n }\n\n return (\n <>\n <Card ref={ref} className={className} {...(props as Omit<typeof props, 'color'>)}>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle className=\"text-body-md font-semibold\">\n Notification Preferences\n </CardTitle>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setShowAddDialog(true)}\n >\n <Icon icon={IconPlus} size=\"sm\" className=\"mr-ds-02b\" />\n Add Rule\n </Button>\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <div className=\"flex items-center justify-center py-ds-07\">\n <Spinner />\n </div>\n ) : preferences.length === 0 ? (\n <div className=\"py-ds-07 text-center\">\n <p className=\"text-body-md text-surface-fg-subtle\">\n No custom preferences set. All notifications are delivered by\n default.\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {preferences.map((pref, i) => {\n const channelInfo =\n CHANNEL_LABELS[pref.channel] || CHANNEL_LABELS.IN_APP\n return (\n <div\n key={pref.id}\n className={cn(\n 'flex items-center gap-ds-05 py-ds-04',\n i < preferences.length - 1 &&\n 'border-b border-surface-border-strong',\n )}\n >\n {/* Channel icon */}\n <div className=\"flex h-ds-sm w-ds-sm shrink-0 items-center justify-center rounded-surface bg-surface-raised\">\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm text-surface-fg-muted\" aria-hidden=\"true\">{channelInfo.icon}</span>\n </div>\n\n {/* Info */}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-body-md font-medium text-surface-fg\">\n {channelInfo.label}\n </p>\n <p className=\"text-body-sm text-surface-fg-subtle\">\n {getProjectName(pref.projectId)}\n </p>\n </div>\n\n {/* Min tier */}\n <Select\n value={pref.minTier}\n onValueChange={(v) => onUpdateTier?.(pref, v)}\n >\n <SelectTrigger className=\"h-ds-xs-plus w-[130px] text-body-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* Muted toggle */}\n <div className=\"flex items-center gap-ds-02b\">\n <span className=\"text-body-sm text-surface-fg-subtle\">\n {pref.muted ? 'Muted' : 'Active'}\n </span>\n <Switch\n checked={!pref.muted}\n onCheckedChange={() => onToggleMute?.(pref)}\n />\n </div>\n\n {/* Delete */}\n <IconButton\n aria-label={`Delete ${channelInfo.label} notification rule`}\n icon={<Icon icon={IconTrash} />}\n variant=\"ghost\"\n color=\"error\"\n size=\"sm\"\n onClick={() => onDelete?.(pref.id)}\n className=\"shrink-0\"\n />\n </div>\n )\n })}\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Add Preference Dialog */}\n <Dialog open={showAddDialog} onOpenChange={setShowAddDialog}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Add Notification Rule</DialogTitle>\n <DialogDescription>\n Customize how you receive notifications for a specific channel\n and project.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-ds-05 pt-ds-03\">\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-scope\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Scope\n </label>\n <Select value={newProjectId} onValueChange={setNewProjectId}>\n <SelectTrigger id=\"pref-scope\">\n <SelectValue placeholder=\"Select scope\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"global\">\n Global (all projects)\n </SelectItem>\n {projects.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-channel\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Channel\n </label>\n <Select value={newChannel} onValueChange={setNewChannel}>\n <SelectTrigger id=\"pref-channel\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"IN_APP\">In-App</SelectItem>\n <SelectItem value=\"GOOGLE_CHAT\">Google Chat</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-min-tier\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Minimum Tier\n </label>\n <Select value={newMinTier} onValueChange={setNewMinTier}>\n <SelectTrigger id=\"pref-min-tier\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <label htmlFor=\"pref-muted\" className=\"text-body-md text-surface-fg\">\n Mute this channel\n </label>\n <Switch id=\"pref-muted\" checked={newMuted} onCheckedChange={setNewMuted} />\n </div>\n\n <div className=\"flex justify-end gap-ds-03 pt-ds-03\">\n <Button\n variant=\"ghost\"\n onClick={() => {\n setShowAddDialog(false)\n resetForm()\n }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleAdd}\n disabled={isSaving}\n >\n {isSaving ? 'Saving...' : 'Save Rule'}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </>\n )\n },\n)\n\nNotificationPreferences.displayName = 'NotificationPreferences'\n\nexport { NotificationPreferences }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"notification-preferences.js","names":[],"sources":["../../src/shell/notification-preferences.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationPreferences -- Manage notification rules per channel/project.\n *\n * Props-driven: accepts preferences array, projects, and callbacks.\n * No internal fetching -- the consumer is responsible for data loading.\n */\nimport { IconBell, IconMessage,IconPlus, IconTrash } from '@tabler/icons-react'\nimport * as React from 'react'\nimport { useState } from 'react'\n\nimport { Button } from '../ui/button'\nimport { Card, CardContent,CardHeader, CardTitle } from '../ui/card'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconButton } from '../ui/icon-button'\nimport { cn } from '../ui/lib/utils'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { Spinner } from '../ui/spinner'\nimport { Switch } from '../ui/switch'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NotificationPreference {\n id: string\n userId?: string\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n}\n\nexport interface NotificationProject {\n id: string\n title: string\n}\n\nexport interface NotificationPreferencesProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'onSave'> {\n /** Current preference rules */\n preferences?: NotificationPreference[]\n /** Available projects for scoping rules */\n projects?: NotificationProject[]\n /** Whether data is loading */\n isLoading?: boolean\n /** Called to add or update a preference */\n onSave?: (preference: {\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n }) => void | Promise<void>\n /** Called to toggle mute on a preference */\n onToggleMute?: (preference: NotificationPreference) => void | Promise<void>\n /** Called to update the tier on a preference */\n onUpdateTier?: (\n preference: NotificationPreference,\n newTier: string,\n ) => void | Promise<void>\n /** Called to delete a preference */\n onDelete?: (preferenceId: string) => void | Promise<void>\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Constants\n// -----------------------------------------------------------------------\n\nconst CHANNEL_LABELS: Record<string, { label: string; icon: React.ReactNode }> = {\n IN_APP: { label: 'In-App', icon: <Icon icon={IconBell} size=\"sm\" /> },\n GOOGLE_CHAT: { label: 'Google Chat', icon: <Icon icon={IconMessage} size=\"sm\" /> },\n}\n\nconst TIER_LABELS: Record<string, string> = {\n INFO: 'All (Info+)',\n IMPORTANT: 'Important+',\n CRITICAL: 'Critical only',\n}\n\n// -----------------------------------------------------------------------\n// NotificationPreferences\n// -----------------------------------------------------------------------\n\nconst NotificationPreferences = React.forwardRef<HTMLDivElement, NotificationPreferencesProps>(\n function NotificationPreferences(\n {\n preferences = [],\n projects = [],\n isLoading = false,\n onSave,\n onToggleMute,\n onUpdateTier,\n onDelete,\n className,\n ...props\n },\n ref,\n ) {\n const [showAddDialog, setShowAddDialog] = useState(false)\n const [newProjectId, setNewProjectId] = useState<string>('global')\n const [newChannel, setNewChannel] = useState<string>('IN_APP')\n const [newMinTier, setNewMinTier] = useState<string>('INFO')\n const [newMuted, setNewMuted] = useState(false)\n const [isSaving, setIsSaving] = useState(false)\n\n const handleAdd = async () => {\n if (!onSave) return\n setIsSaving(true)\n try {\n await onSave({\n projectId: newProjectId === 'global' ? null : newProjectId,\n channel: newChannel,\n minTier: newMinTier,\n muted: newMuted,\n })\n setShowAddDialog(false)\n resetForm()\n } catch (error) {\n console.error('[Preferences] Failed to save:', error)\n } finally {\n setIsSaving(false)\n }\n }\n\n const resetForm = () => {\n setNewProjectId('global')\n setNewChannel('IN_APP')\n setNewMinTier('INFO')\n setNewMuted(false)\n }\n\n const getProjectName = (projectId: string | null) => {\n if (!projectId) return 'Global (all projects)'\n const project = projects.find((p) => p.id === projectId)\n return project?.title || 'Unknown project'\n }\n\n return (\n <>\n <Card ref={ref} className={className} {...(props as Omit<typeof props, 'color'>)}>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle className=\"text-body-md font-semibold\">\n Notification Preferences\n </CardTitle>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setShowAddDialog(true)}\n >\n <Icon icon={IconPlus} size=\"sm\" className=\"mr-ds-02b\" />\n Add Rule\n </Button>\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <div className=\"flex items-center justify-center py-ds-07\">\n <Spinner />\n </div>\n ) : preferences.length === 0 ? (\n <div className=\"py-ds-07 text-center\">\n <p className=\"text-body-md text-surface-fg-subtle\">\n No custom preferences set. All notifications are delivered by\n default.\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {preferences.map((pref, i) => {\n const channelInfo =\n CHANNEL_LABELS[pref.channel] || CHANNEL_LABELS.IN_APP\n return (\n <div\n key={pref.id}\n className={cn(\n 'flex items-center gap-ds-05 py-ds-04',\n i < preferences.length - 1 &&\n 'border-b border-surface-border-strong',\n )}\n >\n {/* Channel icon */}\n <div className=\"flex h-ds-sm w-ds-sm shrink-0 items-center justify-center rounded-surface bg-surface-raised\">\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm text-surface-fg-muted\" aria-hidden=\"true\">{channelInfo.icon}</span>\n </div>\n\n {/* Info */}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-body-md font-medium text-surface-fg\">\n {channelInfo.label}\n </p>\n <p className=\"text-body-sm text-surface-fg-subtle\">\n {getProjectName(pref.projectId)}\n </p>\n </div>\n\n {/* Min tier */}\n <Select\n value={pref.minTier}\n onValueChange={(v) => onUpdateTier?.(pref, v)}\n >\n <SelectTrigger\n aria-label={`Minimum notification tier for ${channelInfo.label} on ${getProjectName(pref.projectId)}`}\n className=\"h-ds-xs-plus w-[130px] text-body-sm\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* Muted toggle */}\n <div className=\"flex items-center gap-ds-02b\">\n <span className=\"text-body-sm text-surface-fg-subtle\">\n {pref.muted ? 'Muted' : 'Active'}\n </span>\n <Switch\n aria-label={`${pref.muted ? 'Unmute' : 'Mute'} ${channelInfo.label} for ${getProjectName(pref.projectId)}`}\n checked={!pref.muted}\n onCheckedChange={() => onToggleMute?.(pref)}\n />\n </div>\n\n {/* Delete */}\n <IconButton\n aria-label={`Delete ${channelInfo.label} notification rule`}\n icon={<Icon icon={IconTrash} />}\n variant=\"ghost\"\n color=\"error\"\n size=\"sm\"\n onClick={() => onDelete?.(pref.id)}\n className=\"shrink-0\"\n />\n </div>\n )\n })}\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Add Preference Dialog */}\n <Dialog open={showAddDialog} onOpenChange={setShowAddDialog}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Add Notification Rule</DialogTitle>\n <DialogDescription>\n Customize how you receive notifications for a specific channel\n and project.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-ds-05 pt-ds-03\">\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-scope\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Scope\n </label>\n <Select value={newProjectId} onValueChange={setNewProjectId}>\n <SelectTrigger id=\"pref-scope\">\n <SelectValue placeholder=\"Select scope\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"global\">\n Global (all projects)\n </SelectItem>\n {projects.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-channel\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Channel\n </label>\n <Select value={newChannel} onValueChange={setNewChannel}>\n <SelectTrigger id=\"pref-channel\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"IN_APP\">In-App</SelectItem>\n <SelectItem value=\"GOOGLE_CHAT\">Google Chat</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-min-tier\" className=\"text-body-sm font-medium text-surface-fg-muted\">\n Minimum Tier\n </label>\n <Select value={newMinTier} onValueChange={setNewMinTier}>\n <SelectTrigger id=\"pref-min-tier\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <label htmlFor=\"pref-muted\" className=\"text-body-md text-surface-fg\">\n Mute this channel\n </label>\n <Switch id=\"pref-muted\" checked={newMuted} onCheckedChange={setNewMuted} />\n </div>\n\n <div className=\"flex justify-end gap-ds-03 pt-ds-03\">\n <Button\n variant=\"ghost\"\n onClick={() => {\n setShowAddDialog(false)\n resetForm()\n }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleAdd}\n disabled={isSaving}\n >\n {isSaving ? 'Saving...' : 'Save Rule'}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </>\n )\n },\n)\n\nNotificationPreferences.displayName = 'NotificationPreferences'\n\nexport { NotificationPreferences }\n"],"mappings":"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"}
|
package/dist/ui/combobox.d.ts
CHANGED
|
@@ -98,6 +98,6 @@ interface ComboboxMultipleProps extends ComboboxBaseProps {
|
|
|
98
98
|
onValueChange: (value: string[]) => void;
|
|
99
99
|
}
|
|
100
100
|
export type ComboboxProps = ComboboxSingleProps | ComboboxMultipleProps;
|
|
101
|
-
declare const Combobox: React.ForwardRefExoticComponent<ComboboxProps & React.RefAttributes<
|
|
101
|
+
declare const Combobox: React.ForwardRefExoticComponent<ComboboxProps & React.RefAttributes<HTMLDivElement>>;
|
|
102
102
|
export { Combobox };
|
|
103
103
|
//# sourceMappingURL=combobox.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAYjD,eAAO,MAAM,uBAAuB;;
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAYjD,eAAO,MAAM,uBAAuB;;8EAsBnC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AA0B5F;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,UAAU,iBAAkB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACxF,+CAA+C;IAC/C,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oGAAoG;IACpG,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC7E,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,8GAA8G;IAC9G,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC;AAED,UAAU,qBAAsB,SAAQ,iBAAiB;IACvD,QAAQ,EAAE,IAAI,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAQvE,QAAA,MAAM,QAAQ,sFAyab,CAAA;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|