@adea-ai/ui 0.89.1 → 0.93.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/dist/NOTICE +19 -0
- package/dist/components/composites/list-row/index.d.ts +1 -0
- package/dist/components/composites/list-row/index.d.ts.map +1 -1
- package/dist/components/composites/list-row/index.js +2 -1
- package/dist/components/composites/list-row/list-row-control.d.ts +20 -0
- package/dist/components/composites/list-row/list-row-control.d.ts.map +1 -0
- package/dist/components/composites/list-row/list-row-control.js +96 -0
- package/dist/components/composites/list-row/list-row-control.js.map +1 -0
- package/dist/components/composites/list-row/list-row.d.ts +15 -35
- package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
- package/dist/components/composites/list-row/list-row.js +88 -135
- package/dist/components/composites/list-row/list-row.js.map +1 -1
- package/dist/components/composites/tree/index.d.ts +4 -0
- package/dist/components/composites/tree/index.d.ts.map +1 -0
- package/dist/components/composites/tree/index.js +2 -0
- package/dist/components/composites/tree/tree-navigation.d.ts +46 -0
- package/dist/components/composites/tree/tree-navigation.d.ts.map +1 -0
- package/dist/components/composites/tree/tree-navigation.js +95 -0
- package/dist/components/composites/tree/tree-navigation.js.map +1 -0
- package/dist/components/composites/tree/tree.d.ts +64 -0
- package/dist/components/composites/tree/tree.d.ts.map +1 -0
- package/dist/components/composites/tree/tree.js +311 -0
- package/dist/components/composites/tree/tree.js.map +1 -0
- package/dist/components/conversation/message-composer.d.ts +18 -3
- package/dist/components/conversation/message-composer.d.ts.map +1 -1
- package/dist/components/conversation/message-composer.js +93 -27
- package/dist/components/conversation/message-composer.js.map +1 -1
- package/dist/components/layout/sidebar-nav/index.d.ts +1 -1
- package/dist/components/layout/sidebar-nav/index.d.ts.map +1 -1
- package/dist/components/layout/sidebar-nav/index.js +2 -2
- package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts +19 -1
- package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts.map +1 -1
- package/dist/components/layout/sidebar-nav/sidebar-nav.js +83 -17
- package/dist/components/layout/sidebar-nav/sidebar-nav.js.map +1 -1
- package/dist/components/layout/top-bar/top-bar.d.ts +6 -5
- package/dist/components/layout/top-bar/top-bar.d.ts.map +1 -1
- package/dist/components/layout/top-bar/top-bar.js +30 -7
- package/dist/components/layout/top-bar/top-bar.js.map +1 -1
- package/dist/components/ui/dialog/dialog.d.ts +2 -0
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.js +4 -3
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/modal-dialog/modal-dialog.d.ts +5 -2
- package/dist/components/ui/modal-dialog/modal-dialog.d.ts.map +1 -1
- package/dist/components/ui/modal-dialog/modal-dialog.js +33 -24
- package/dist/components/ui/modal-dialog/modal-dialog.js.map +1 -1
- package/dist/components/ui/textarea/index.d.ts +1 -1
- package/dist/components/ui/textarea/index.d.ts.map +1 -1
- package/dist/components/ui/textarea/index.js +2 -2
- package/dist/components/ui/textarea/textarea.d.ts +15 -2
- package/dist/components/ui/textarea/textarea.d.ts.map +1 -1
- package/dist/components/ui/textarea/textarea.js +47 -3
- package/dist/components/ui/textarea/textarea.js.map +1 -1
- package/dist/components/ui/tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip/tooltip.js +239 -17
- package/dist/components/ui/tooltip/tooltip.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/lib/variants.js +2 -2
- package/dist/r/conversation.json +1 -0
- package/dist/r/list-row.json +5 -0
- package/dist/r/registry.json +41 -2
- package/dist/r/src/components/composites/list-row/index.ts +1 -0
- package/dist/r/src/components/composites/list-row/list-row-control.tsx +108 -0
- package/dist/r/src/components/composites/list-row/list-row.tsx +60 -127
- package/dist/r/src/components/composites/tree/index.ts +3 -0
- package/dist/r/src/components/composites/tree/tree-navigation.ts +114 -0
- package/dist/r/src/components/composites/tree/tree.tsx +405 -0
- package/dist/r/src/components/conversation/message-composer.tsx +103 -22
- package/dist/r/src/components/layout/sidebar-nav/index.ts +3 -0
- package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
- package/dist/r/src/components/layout/top-bar/top-bar.tsx +34 -11
- package/dist/r/src/components/ui/dialog/dialog.tsx +4 -2
- package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
- package/dist/r/src/components/ui/textarea/index.ts +1 -1
- package/dist/r/src/components/ui/textarea/textarea.tsx +52 -10
- package/dist/r/src/components/ui/tooltip/tooltip.tsx +305 -10
- package/dist/r/src/styles/base.css +40 -0
- package/dist/r/textarea.json +3 -1
- package/dist/r/top-bar.json +3 -1
- package/dist/r/tree.json +29 -0
- package/package.json +4 -1
- package/registry.json +41 -2
- package/src/components/composites/list-row/index.ts +1 -0
- package/src/components/composites/list-row/list-row-control.tsx +108 -0
- package/src/components/composites/list-row/list-row.tsx +60 -127
- package/src/components/composites/tree/index.ts +3 -0
- package/src/components/composites/tree/tree-navigation.ts +114 -0
- package/src/components/composites/tree/tree.tsx +405 -0
- package/src/components/conversation/message-composer.tsx +103 -22
- package/src/components/layout/sidebar-nav/index.ts +3 -0
- package/src/components/layout/sidebar-nav/sidebar-nav.tsx +75 -6
- package/src/components/layout/top-bar/top-bar.tsx +34 -11
- package/src/components/ui/dialog/dialog.tsx +4 -2
- package/src/components/ui/modal-dialog/modal-dialog.tsx +20 -4
- package/src/components/ui/textarea/index.ts +1 -1
- package/src/components/ui/textarea/textarea.tsx +52 -10
- package/src/components/ui/tooltip/tooltip.tsx +305 -10
- package/src/index.ts +1 -0
- package/src/styles/base.css +40 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-nav.js","names":["PolymorphicProps","Polymorphic","ChevronRight","ComponentProps","JSX","ValidComponent","Show","createSignal","splitProps","cn","invokeEventHandler","handler","event","Event","Array","isArray","callback","data","SidebarNavProps","T","class","SidebarNav","props","local","rest","_$createComponent","_$mergeProps","as","aria-label","children","SidebarNavHeader","_el$","_tmpl$","_$spread","SidebarNavTitleProps","SidebarNavTitle","SidebarNavContent","_el$2","_tmpl$2","SidebarNavFooter","_el$3","_tmpl$3","SidebarNavSectionTriggerProps","Omit","onReorder","direction","onClick","onKeyDown","SidebarNavSectionProps","label","collapsible","defaultOpen","open","onOpenChange","triggerProps","count","action","Element","headingAs","SidebarNavSection","uncontrolledOpen","setUncontrolledOpen","setOpen","next","undefined","trigger","triggerRest","heading","when","_el$4","_tmpl$4","_$insert","_el$5","_tmpl$5","_el$6","_tmpl$9","_el$7","firstChild","_$memo","fallback","_el$8","_tmpl$6","aria-expanded","defaultPrevented","altKey","key","preventDefault","stopPropagation","_el$9","_tmpl$7","_el$0","_tmpl$8","SidebarNavItemProps","active","nested","trailing","sidebarNavItemClass","join","sidebarNavItemStateClass","idle","SidebarNavItem","aria-current","data-active","_el$1","_tmpl$0","SidebarNavButton","_el$10","_tmpl$1","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/layout/sidebar-nav/sidebar-nav.tsx"],"sourcesContent":["import type { PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { Polymorphic } from '@kobalte/core/polymorphic'\nimport { ChevronRight } from 'lucide-solid'\nimport type { ComponentProps, JSX, ValidComponent } from 'solid-js'\nimport { Show, createSignal, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\nfunction invokeEventHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n ;(handler as (event: Event) => void)(event)\n }\n}\n\n/**\n * SidebarNav.\n *\n * The secondary navigation column: the list of things inside the destination\n * the rail selected — projects, sessions, files, threads. It is a different\n * object from the rail, not a wider version of it, which is why it is a separate\n * component rather than the rail with labels on.\n *\n * Rows share one recipe with the rail's, so a row in a sidebar and a row in a\n * rail read as the same kind of thing at the same density. That recipe is\n * exactly KiroCrew's nav row: `text-sm font-medium`, `gap-2.5`, `px-3 py-2`,\n * `rounded-md`, `transition-colors`.\n *\n * The width comes from `--sidebar-width`. Sections collapse by default only when\n * the caller says so, because a section that starts collapsed and holds the\n * user's own work is a hidden default.\n */\nexport type SidebarNavProps<T extends ValidComponent = 'nav'> = PolymorphicProps<\n T,\n { class?: string; 'aria-label'?: string }\n>\n\nexport function SidebarNav<T extends ValidComponent = 'nav'>(props: SidebarNavProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavProps, ['class', 'aria-label', 'children'])\n\n return (\n <Polymorphic\n as=\"nav\"\n aria-label={local['aria-label'] ?? 'Section'}\n class={cn(\n 'bg-sidebar text-sidebar-foreground flex h-full w-sidebar shrink-0 flex-col border-e border-sidebar-border',\n local.class\n )}\n {...(rest as ComponentProps<'nav'>)}\n >\n {local.children}\n </Polymorphic>\n )\n}\n\nexport function SidebarNavHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-header\"\n class={cn('flex h-topbar shrink-0 items-center justify-between gap-2 px-3', local.class)}\n {...rest}\n />\n )\n}\n\nexport type SidebarNavTitleProps<T extends ValidComponent = 'div'> = PolymorphicProps<\n T,\n { class?: string }\n>\n\nexport function SidebarNavTitle<T extends ValidComponent = 'div'>(props: SidebarNavTitleProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavTitleProps, ['class'])\n return (\n <Polymorphic\n as=\"div\"\n data-slot=\"sidebar-nav-title\"\n class={cn('truncate text-sm font-semibold tracking-tight', local.class)}\n {...(rest as ComponentProps<'div'>)}\n />\n )\n}\n\n/** The scrolling middle of the sidebar. */\nexport function SidebarNavContent(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-content\"\n class={cn('flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto px-2 py-2', local.class)}\n {...rest}\n />\n )\n}\n\nexport function SidebarNavFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-footer\"\n class={cn('flex shrink-0 items-center gap-1 border-t border-sidebar-border p-2', local.class)}\n {...rest}\n />\n )\n}\n\n/** Props forwarded to a collapsible section's disclosure button. */\nexport type SidebarNavSectionTriggerProps = Omit<\n ComponentProps<'button'>,\n 'type' | 'aria-expanded' | 'onClick' | 'onKeyDown' | 'children' | 'class' | 'style'\n> & {\n /** Called for Alt+ArrowUp/Down; the host owns ordering and row identity. */\n onReorder?: (direction: 'up' | 'down') => void\n /** Runs before the section toggle and may cancel it with `preventDefault()`. */\n onClick?: ComponentProps<'button'>['onClick']\n /** Runs before shared Alt+Arrow handling and may cancel it with `preventDefault()`. */\n onKeyDown?: ComponentProps<'button'>['onKeyDown']\n}\n\n/**\n * A titled, collapsible group. Collapsible because a list of projects\n * inevitably outgrows the column, and the user needs to put the ones they are\n * not using away *without* them disappearing into a menu.\n */\nexport type SidebarNavSectionProps = ComponentProps<'div'> & {\n label: string\n /** Render a disclosure control instead of a plain heading. */\n collapsible?: boolean\n defaultOpen?: boolean\n /** Controlled disclosure state. When supplied, the host owns changes. */\n open?: boolean\n /** Called for user-initiated disclosure changes. */\n onOpenChange?: (open: boolean) => void\n /** Native props and reorder callbacks for the disclosure control. */\n triggerProps?: SidebarNavSectionTriggerProps\n /** Count shown beside the label. */\n count?: number\n /** A control at the trailing edge of the heading row. */\n action?: JSX.Element\n /** Semantic heading element for a host's section hierarchy. */\n headingAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n}\n\nexport function SidebarNavSection(props: SidebarNavSectionProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'collapsible',\n 'defaultOpen',\n 'open',\n 'onOpenChange',\n 'triggerProps',\n 'count',\n 'action',\n 'headingAs',\n 'children',\n ])\n const [uncontrolledOpen, setUncontrolledOpen] = createSignal(local.defaultOpen ?? true)\n const open = () => local.open ?? uncontrolledOpen()\n const setOpen = (next: boolean) => {\n if (local.open === undefined) setUncontrolledOpen(next)\n local.onOpenChange?.(next)\n }\n\n const [trigger, triggerRest] = splitProps(local.triggerProps ?? {}, [\n 'onClick',\n 'onKeyDown',\n 'onReorder',\n ])\n\n const heading = (\n <>\n <Show when={local.collapsible}>\n <ChevronRight\n aria-hidden=\"true\"\n class={cn('size-3.5 shrink-0 text-muted-foreground transition-transform ease-out', {\n 'rotate-90': open(),\n })}\n />\n </Show>\n <span class=\"min-w-0 flex-1 truncate\">{local.label}</span>\n <Show when={local.count !== undefined}>\n <span class=\"shrink-0 tabular-nums text-muted-foreground\">{local.count}</span>\n </Show>\n </>\n )\n\n return (\n <div data-slot=\"sidebar-nav-section\" class={cn('flex flex-col gap-0.5', local.class)} {...rest}>\n <div class=\"group/section-header flex items-center gap-1 rounded-md px-2 py-1.5 hover:bg-sidebar-accent/60\">\n <Polymorphic\n as={local.headingAs ?? 'div'}\n aria-label={local.headingAs ? local.label : undefined}\n class=\"flex min-w-0 flex-1 items-center gap-1.5 text-2xs font-medium tracking-wide text-sidebar-muted-foreground uppercase\"\n >\n <Show when={local.collapsible} fallback={heading}>\n <button\n {...(triggerRest as ComponentProps<'button'>)}\n type=\"button\"\n aria-expanded={open()}\n onClick={(event) => {\n invokeEventHandler(trigger.onClick, event)\n if (event.defaultPrevented) return\n setOpen(!open())\n }}\n onKeyDown={(event) => {\n invokeEventHandler(trigger.onKeyDown, event)\n if (event.defaultPrevented || !event.altKey) return\n if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') return\n event.preventDefault()\n event.stopPropagation()\n trigger.onReorder?.(event.key === 'ArrowUp' ? 'up' : 'down')\n }}\n class=\"flex min-w-0 flex-1 items-center gap-1.5 rounded-sm text-2xs font-medium tracking-wide text-sidebar-muted-foreground uppercase outline-none transition-colors ease-out hover:text-sidebar-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle\"\n >\n {heading}\n </button>\n </Show>\n </Polymorphic>\n <Show when={local.action}>\n <span class=\"shrink-0 opacity-0 transition-opacity ease-out group-hover/section-header:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100\">\n {local.action}\n </span>\n </Show>\n </div>\n <Show when={!local.collapsible || open()}>\n <div class=\"flex flex-col gap-0.5\">{local.children}</div>\n </Show>\n </div>\n )\n}\n\nexport type SidebarNavItemProps<T extends ValidComponent = 'a'> = PolymorphicProps<\n T,\n {\n class?: string\n active?: boolean\n /** Indent one level, for a child row such as a branch under a project. */\n nested?: boolean\n /** Trailing slot: a count, a status dot, a hover action. */\n trailing?: JSX.Element\n }\n>\n\n/** A sidebar row. Exported classes, so a caller's own element can match it. */\nexport const sidebarNavItemClass = [\n 'group/nav-item relative flex min-w-0 items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium',\n 'whitespace-nowrap transition-colors ease-out outline-none select-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n '[&_svg]:size-4 [&_svg]:shrink-0',\n].join(' ')\n\nexport const sidebarNavItemStateClass = {\n active: 'bg-primary-subtle text-foreground',\n idle: 'text-muted-foreground hover:bg-surface-hover hover:text-foreground',\n}\n\nexport function SidebarNavItem<T extends ValidComponent = 'a'>(props: SidebarNavItemProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavItemProps, [\n 'class',\n 'active',\n 'nested',\n 'trailing',\n 'children',\n ])\n\n return (\n <Polymorphic\n as=\"a\"\n aria-current={local.active ? 'page' : undefined}\n data-active={local.active ? '' : undefined}\n class={cn(\n sidebarNavItemClass,\n local.active ? sidebarNavItemStateClass.active : sidebarNavItemStateClass.idle,\n { 'ps-8': local.nested },\n local.class\n )}\n {...(rest as ComponentProps<'a'>)}\n >\n {local.children}\n <Show when={local.trailing}>\n <span class=\"ms-auto flex shrink-0 items-center gap-1\">{local.trailing}</span>\n </Show>\n </Polymorphic>\n )\n}\n\n/** A row that is a button rather than a destination — \"New project\". */\nexport function SidebarNavButton(props: ComponentProps<'button'>) {\n const [local, rest] = splitProps(props, ['class', 'children'])\n\n return (\n <button\n type=\"button\"\n class={cn(\n sidebarNavItemClass,\n sidebarNavItemStateClass.idle,\n 'w-full disabled:pointer-events-none disabled:opacity-50',\n local.class\n )}\n {...rest}\n >\n {local.children}\n </button>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sidebar-nav.js","names":["PolymorphicProps","Polymorphic","ChevronRight","ComponentProps","JSX","ValidComponent","Show","createSignal","splitProps","cn","invokeEventHandler","handler","event","Event","Array","isArray","callback","data","SidebarNavProps","T","class","SidebarNav","props","local","rest","_$createComponent","_$mergeProps","as","aria-label","children","SidebarNavHeader","_el$","_tmpl$","_$spread","SidebarNavTitleProps","SidebarNavTitle","SidebarNavContent","_el$2","_tmpl$2","SidebarNavFooter","_el$3","_tmpl$3","SidebarNavSectionTriggerProps","Omit","onReorder","direction","onClick","onKeyDown","SidebarNavSectionProps","label","collapsible","defaultOpen","active","open","onOpenChange","triggerProps","count","action","Element","headingAs","SidebarNavSection","uncontrolledOpen","setUncontrolledOpen","setOpen","next","undefined","trigger","triggerRest","heading","when","_el$4","_tmpl$4","_$insert","_el$5","_tmpl$5","_el$6","_tmpl$9","_el$7","firstChild","_$memo","fallback","_el$8","_tmpl$6","aria-expanded","aria-current","defaultPrevented","altKey","key","preventDefault","stopPropagation","_el$9","_tmpl$7","_el$0","_tmpl$8","_$effect","_p$","_v$","_v$2","e","_$setAttribute","t","_$className","SidebarNavRowProps","actions","SidebarNavRow","_el$1","_tmpl$1","_el$10","_tmpl$0","SidebarNavLabel","_el$11","_tmpl$10","SidebarNavItemProps","nested","trailing","sidebarNavItemClass","join","sidebarNavItemStateClass","idle","SidebarNavItem","data-active","_el$12","_tmpl$11","SidebarNavButton","_el$13","_tmpl$12","_$createComponent","_$mergeProps","_$memo","_$setAttribute","_$className"],"sources":["../../../../src/components/layout/sidebar-nav/sidebar-nav.tsx"],"sourcesContent":["import type { PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { Polymorphic } from '@kobalte/core/polymorphic'\nimport { ChevronRight } from 'lucide-solid'\nimport type { ComponentProps, JSX, ValidComponent } from 'solid-js'\nimport { Show, createSignal, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\nfunction invokeEventHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n ;(handler as (event: Event) => void)(event)\n }\n}\n\n/**\n * SidebarNav.\n *\n * The secondary navigation column: the list of things inside the destination\n * the rail selected — projects, sessions, files, threads. It is a different\n * object from the rail, not a wider version of it, which is why it is a separate\n * component rather than the rail with labels on.\n *\n * Rows share one recipe with the rail's, so a row in a sidebar and a row in a\n * rail read as the same kind of thing at the same density. That recipe is\n * exactly KiroCrew's nav row: `text-sm font-medium`, `gap-2.5`, `px-3 py-2`,\n * `rounded-md`, `transition-colors`.\n *\n * The width comes from `--sidebar-width`. Sections collapse by default only when\n * the caller says so, because a section that starts collapsed and holds the\n * user's own work is a hidden default.\n */\nexport type SidebarNavProps<T extends ValidComponent = 'nav'> = PolymorphicProps<\n T,\n { class?: string; 'aria-label'?: string }\n>\n\nexport function SidebarNav<T extends ValidComponent = 'nav'>(props: SidebarNavProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavProps, ['class', 'aria-label', 'children'])\n\n return (\n <Polymorphic\n as=\"nav\"\n aria-label={local['aria-label'] ?? 'Section'}\n class={cn(\n 'bg-sidebar text-sidebar-foreground flex h-full w-sidebar min-w-0 max-w-full shrink-0 flex-col border-e border-sidebar-border',\n local.class\n )}\n {...(rest as ComponentProps<'nav'>)}\n >\n {local.children}\n </Polymorphic>\n )\n}\n\nexport function SidebarNavHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-header\"\n class={cn('flex h-topbar shrink-0 items-center justify-between gap-2 px-3', local.class)}\n {...rest}\n />\n )\n}\n\nexport type SidebarNavTitleProps<T extends ValidComponent = 'div'> = PolymorphicProps<\n T,\n { class?: string }\n>\n\nexport function SidebarNavTitle<T extends ValidComponent = 'div'>(props: SidebarNavTitleProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavTitleProps, ['class'])\n return (\n <Polymorphic\n as=\"div\"\n data-slot=\"sidebar-nav-title\"\n class={cn('truncate text-sm font-semibold tracking-tight', local.class)}\n {...(rest as ComponentProps<'div'>)}\n />\n )\n}\n\n/** The scrolling middle of the sidebar. */\nexport function SidebarNavContent(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-content\"\n class={cn('flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto px-2 py-2', local.class)}\n {...rest}\n />\n )\n}\n\nexport function SidebarNavFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"sidebar-nav-footer\"\n class={cn('flex shrink-0 items-center gap-1 border-t border-sidebar-border p-2', local.class)}\n {...rest}\n />\n )\n}\n\n/** Props forwarded to a collapsible section's disclosure button. */\nexport type SidebarNavSectionTriggerProps = Omit<\n ComponentProps<'button'>,\n 'type' | 'aria-expanded' | 'onClick' | 'onKeyDown' | 'children' | 'class' | 'style'\n> & {\n /** Called for Alt+ArrowUp/Down; the host owns ordering and row identity. */\n onReorder?: (direction: 'up' | 'down') => void\n /** Runs before the section toggle and may cancel it with `preventDefault()`. */\n onClick?: ComponentProps<'button'>['onClick']\n /** Runs before shared Alt+Arrow handling and may cancel it with `preventDefault()`. */\n onKeyDown?: ComponentProps<'button'>['onKeyDown']\n}\n\n/**\n * A titled, collapsible group. Collapsible because a list of projects\n * inevitably outgrows the column, and the user needs to put the ones they are\n * not using away *without* them disappearing into a menu.\n */\nexport type SidebarNavSectionProps = ComponentProps<'div'> & {\n label: string\n /** Render a disclosure control instead of a plain heading. */\n collapsible?: boolean\n defaultOpen?: boolean\n /** Mark the current project/group without changing its disclosure state. */\n active?: boolean\n /** Controlled disclosure state. When supplied, the host owns changes. */\n open?: boolean\n /** Called for user-initiated disclosure changes. */\n onOpenChange?: (open: boolean) => void\n /** Native props and reorder callbacks for the disclosure control. */\n triggerProps?: SidebarNavSectionTriggerProps\n /** Count shown beside the label. */\n count?: number\n /** A control at the trailing edge of the heading row. */\n action?: JSX.Element\n /** Semantic heading element for a host's section hierarchy. */\n headingAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n}\n\nexport function SidebarNavSection(props: SidebarNavSectionProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'collapsible',\n 'defaultOpen',\n 'active',\n 'open',\n 'onOpenChange',\n 'triggerProps',\n 'count',\n 'action',\n 'headingAs',\n 'children',\n ])\n const [uncontrolledOpen, setUncontrolledOpen] = createSignal(local.defaultOpen ?? true)\n const open = () => local.open ?? uncontrolledOpen()\n const setOpen = (next: boolean) => {\n if (local.open === undefined) setUncontrolledOpen(next)\n local.onOpenChange?.(next)\n }\n\n const [trigger, triggerRest] = splitProps(local.triggerProps ?? {}, [\n 'onClick',\n 'onKeyDown',\n 'onReorder',\n ])\n\n const heading = (\n <>\n <Show when={local.collapsible}>\n <ChevronRight\n aria-hidden=\"true\"\n class={cn('size-3.5 shrink-0 text-muted-foreground transition-transform ease-out', {\n 'rotate-90': open(),\n })}\n />\n </Show>\n <span class=\"min-w-0 flex-1 truncate\">{local.label}</span>\n <Show when={local.count !== undefined}>\n <span class=\"shrink-0 tabular-nums text-muted-foreground\">{local.count}</span>\n </Show>\n </>\n )\n\n return (\n <div data-slot=\"sidebar-nav-section\" class={cn('flex flex-col gap-0.5', local.class)} {...rest}>\n <div\n data-slot=\"sidebar-nav-section-header\"\n data-active={local.active ? '' : undefined}\n class={cn(\n 'group/section-header flex items-center gap-1 rounded-md px-2 py-1.5',\n { '[@media(pointer:coarse)]:py-0': local.collapsible },\n local.active ? 'bg-primary-subtle text-foreground' : 'hover:bg-sidebar-accent/60'\n )}\n >\n <Polymorphic\n as={local.headingAs ?? 'div'}\n aria-label={local.headingAs ? local.label : undefined}\n class={cn(\n 'flex min-w-0 flex-1 items-center gap-1.5 text-2xs font-medium tracking-wide uppercase',\n local.active ? 'text-foreground' : 'text-sidebar-muted-foreground'\n )}\n >\n <Show when={local.collapsible} fallback={heading}>\n <button\n {...(triggerRest as ComponentProps<'button'>)}\n type=\"button\"\n aria-expanded={open()}\n aria-current={local.active ? 'page' : triggerRest['aria-current']}\n onClick={(event) => {\n invokeEventHandler(trigger.onClick, event)\n if (event.defaultPrevented) return\n setOpen(!open())\n }}\n onKeyDown={(event) => {\n invokeEventHandler(trigger.onKeyDown, event)\n if (event.defaultPrevented || !event.altKey) return\n if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') return\n event.preventDefault()\n event.stopPropagation()\n trigger.onReorder?.(event.key === 'ArrowUp' ? 'up' : 'down')\n }}\n class={cn(\n 'flex min-w-0 flex-1 items-center gap-1.5 rounded-sm text-2xs font-medium tracking-wide uppercase outline-none transition-colors ease-out hover:text-sidebar-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle [@media(pointer:coarse)]:min-h-11',\n local.active ? 'text-foreground' : 'text-sidebar-muted-foreground'\n )}\n >\n {heading}\n </button>\n </Show>\n </Polymorphic>\n <Show when={local.action}>\n <span class=\"shrink-0 opacity-0 transition-opacity ease-out group-hover/section-header:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100\">\n {local.action}\n </span>\n </Show>\n </div>\n <Show when={!local.collapsible || open()}>\n <div class=\"flex flex-col gap-0.5\">{local.children}</div>\n </Show>\n </div>\n )\n}\n\nexport type SidebarNavRowProps = ComponentProps<'div'> & {\n /** Adjacent controls, outside the navigation item's interactive element. */\n actions?: JSX.Element\n}\n\n/**\n * A navigation item and its adjacent controls. Actions stay outside the item\n * to avoid nested buttons; touch, keyboard focus, and expanded menus expose\n * them without requiring a pointer hover. A narrow lane or enlarged text\n * may move actions onto a second line rather than clipping the label or controls.\n */\nexport function SidebarNavRow(props: SidebarNavRowProps) {\n const [local, rest] = splitProps(props, ['class', 'children', 'actions'])\n return (\n <div\n data-slot=\"sidebar-nav-row\"\n class={cn(\n 'group/sidebar-nav-row flex min-w-0 flex-wrap items-center gap-0.5 [&>[data-slot=sidebar-nav-item]]:flex-1 [&>[data-slot=sidebar-nav-item]]:basis-36',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.actions}>\n <span\n data-slot=\"sidebar-nav-row-actions\"\n class=\"ms-auto flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity ease-out group-hover/sidebar-nav-row:opacity-100 group-focus-within/sidebar-nav-row:opacity-100 has-[[aria-haspopup=menu][aria-expanded=true]]:opacity-100 has-[[aria-haspopup=true][aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100\"\n >\n {local.actions}\n </span>\n </Show>\n </div>\n )\n}\n\n/** Row text may truncate visually; its complete content remains the accessible name. */\nexport function SidebarNavLabel(props: ComponentProps<'span'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <span\n data-slot=\"sidebar-nav-label\"\n class={cn('min-w-0 flex-1 truncate', local.class)}\n {...rest}\n />\n )\n}\n\nexport type SidebarNavItemProps<T extends ValidComponent = 'a'> = PolymorphicProps<\n T,\n {\n class?: string\n active?: boolean\n /** Indent one level, for a child row such as a branch under a project. */\n nested?: boolean\n /** Trailing slot: a count, a status dot, a hover action. */\n trailing?: JSX.Element\n }\n>\n\n/**\n * A sidebar row. Exported classes, so a caller's own element can match it.\n * Coarse pointers get a 44px target without changing Kiro's desktop density.\n */\nexport const sidebarNavItemClass = [\n 'group/nav-item relative flex min-w-0 items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium',\n 'whitespace-nowrap transition-colors ease-out outline-none select-none [@media(pointer:coarse)]:min-h-11',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n '[&_svg]:size-4 [&_svg]:shrink-0',\n].join(' ')\n\nexport const sidebarNavItemStateClass = {\n active: 'bg-primary-subtle text-foreground',\n idle: 'text-muted-foreground hover:bg-surface-hover hover:text-foreground',\n}\n\nexport function SidebarNavItem<T extends ValidComponent = 'a'>(props: SidebarNavItemProps<T>) {\n const [local, rest] = splitProps(props as SidebarNavItemProps, [\n 'class',\n 'active',\n 'nested',\n 'trailing',\n 'children',\n ])\n\n return (\n <Polymorphic\n as=\"a\"\n data-slot=\"sidebar-nav-item\"\n aria-current={local.active ? 'page' : undefined}\n data-active={local.active ? '' : undefined}\n class={cn(\n sidebarNavItemClass,\n local.active ? sidebarNavItemStateClass.active : sidebarNavItemStateClass.idle,\n { 'ps-8': local.nested },\n local.class\n )}\n {...(rest as ComponentProps<'a'>)}\n >\n {local.children}\n <Show when={local.trailing}>\n <span class=\"ms-auto flex shrink-0 items-center gap-1\">{local.trailing}</span>\n </Show>\n </Polymorphic>\n )\n}\n\n/** A row that is a button rather than a destination — \"New project\". */\nexport function SidebarNavButton(props: ComponentProps<'button'>) {\n const [local, rest] = splitProps(props, ['class', 'children'])\n\n return (\n <button\n type=\"button\"\n class={cn(\n sidebarNavItemClass,\n sidebarNavItemStateClass.idle,\n 'w-full disabled:pointer-events-none disabled:opacity-50',\n local.class\n )}\n {...rest}\n >\n {local.children}\n </button>\n )\n}\n"],"mappings":"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"}
|
|
@@ -3,10 +3,10 @@ import type { ComponentProps } from 'solid-js';
|
|
|
3
3
|
* TopBar.
|
|
4
4
|
*
|
|
5
5
|
* The window's title row and primary toolbar. Three tracks: a leading group, a
|
|
6
|
-
* centred search, and a trailing group.
|
|
7
|
-
* window width and the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* centred search, and a trailing group. On wide screens the search is a fixed
|
|
7
|
+
* function of the window width and the side groups are equal remainders. On
|
|
8
|
+
* narrow screens the middle track yields space to the controls, and each side
|
|
9
|
+
* group scrolls when necessary so keyboard focus can reveal every action.
|
|
10
10
|
*
|
|
11
11
|
* On a frameless desktop window this row is also the drag region, so it carries
|
|
12
12
|
* `window-drag` and the controls inside it opt back out. `macos-inset` and
|
|
@@ -25,11 +25,12 @@ export type TopBarProps = ComponentProps<'header'> & {
|
|
|
25
25
|
glass?: boolean;
|
|
26
26
|
};
|
|
27
27
|
export declare function TopBar(props: TopBarProps): import("solid-js").JSX.Element;
|
|
28
|
-
/** A side group
|
|
28
|
+
/** A scrollable side group; equal wide-screen tracks centre the search. */
|
|
29
29
|
export declare function TopBarSection(props: ComponentProps<'div'> & {
|
|
30
30
|
align?: 'start' | 'end';
|
|
31
31
|
}): import("solid-js").JSX.Element;
|
|
32
32
|
export declare function TopBarTitle(props: ComponentProps<'div'> & {
|
|
33
|
+
/** Aligns text within this slot; it does not position the slot. */
|
|
33
34
|
align?: 'start' | 'center';
|
|
34
35
|
}): import("solid-js").JSX.Element;
|
|
35
36
|
/** A breadcrumb or path readout that yields to the actions when space runs out. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-bar.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"top-bar.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAK9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG;IACnD,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,kCAuBxC;AAYD,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;CAAE,kCAqBvF;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAC7B,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAC3B,kCAcF;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,kCAS5D;AAED,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG;IACzD,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,kCA0BpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,kCAqB7E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
-
import { createComponent, insert, mergeProps, spread, template } from "solid-js/web";
|
|
2
|
+
import { createComponent, delegateEvents, insert, mergeProps, spread, template } from "solid-js/web";
|
|
3
|
+
import { Search } from "lucide-solid";
|
|
3
4
|
import { Show, splitProps } from "solid-js";
|
|
4
5
|
//#region src/components/layout/top-bar/top-bar.tsx
|
|
5
6
|
var _tmpl$ = /*#__PURE__*/ template(`<header data-slot=top-bar>`);
|
|
@@ -7,7 +8,7 @@ var _tmpl$2 = /*#__PURE__*/ template(`<div data-slot=top-bar-section>`);
|
|
|
7
8
|
var _tmpl$3 = /*#__PURE__*/ template(`<div data-slot=top-bar-title>`);
|
|
8
9
|
var _tmpl$4 = /*#__PURE__*/ template(`<div data-slot=top-bar-breadcrumb>`);
|
|
9
10
|
var _tmpl$5 = /*#__PURE__*/ template(`<kbd class="bg-muted ms-auto hidden h-5 shrink-0 items-center rounded-sm border border-border px-1.5 font-mono text-2xs sm:flex">`);
|
|
10
|
-
var _tmpl$6 = /*#__PURE__*/ template(`<button type=button data-slot=top-bar-search><span class=truncate>`);
|
|
11
|
+
var _tmpl$6 = /*#__PURE__*/ template(`<button type=button data-slot=top-bar-search><span class="sr-only sm:not-sr-only sm:truncate">`);
|
|
11
12
|
var _tmpl$7 = /*#__PURE__*/ template(`<button type=button data-slot=top-bar-pill><span>`);
|
|
12
13
|
function TopBar(props) {
|
|
13
14
|
const [local, rest] = splitProps(props, [
|
|
@@ -20,18 +21,35 @@ function TopBar(props) {
|
|
|
20
21
|
return (() => {
|
|
21
22
|
var _el$ = _tmpl$();
|
|
22
23
|
spread(_el$, mergeProps({ get ["class"]() {
|
|
23
|
-
return cn("h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[
|
|
24
|
+
return cn("h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3 border-b border-border bg-card text-card-foreground px-3 md:grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)]", local.glass && "glass-panel", local.draggable && "window-drag", local.macosInset && "window-inset-macos", local.windowsInset && "window-inset-windows", local.class);
|
|
24
25
|
} }, rest), false, false);
|
|
25
26
|
return _el$;
|
|
26
27
|
})();
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
function invokeFocusHandler(handler, event) {
|
|
30
|
+
if (Array.isArray(handler)) {
|
|
31
|
+
const [callback, data] = handler;
|
|
32
|
+
callback(data, event);
|
|
33
|
+
} else if (typeof handler === "function") handler(event);
|
|
34
|
+
}
|
|
35
|
+
/** A scrollable side group; equal wide-screen tracks centre the search. */
|
|
29
36
|
function TopBarSection(props) {
|
|
30
|
-
const [local, rest] = splitProps(props, [
|
|
37
|
+
const [local, rest] = splitProps(props, [
|
|
38
|
+
"class",
|
|
39
|
+
"align",
|
|
40
|
+
"onFocusIn"
|
|
41
|
+
]);
|
|
31
42
|
return (() => {
|
|
32
43
|
var _el$2 = _tmpl$2();
|
|
44
|
+
_el$2.$$focusin = (event) => {
|
|
45
|
+
if (event.target instanceof HTMLElement) event.target.scrollIntoView({
|
|
46
|
+
block: "nearest",
|
|
47
|
+
inline: "nearest"
|
|
48
|
+
});
|
|
49
|
+
invokeFocusHandler(local.onFocusIn, event);
|
|
50
|
+
};
|
|
33
51
|
spread(_el$2, mergeProps({ get ["class"]() {
|
|
34
|
-
return cn("window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden", local.align === "end" && "justify-end", local.align !== "end" && "justify-start", local.class);
|
|
52
|
+
return cn("window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden", local.align === "end" && "md:justify-end", local.align !== "end" && "justify-start", local.class);
|
|
35
53
|
} }, rest), false, false);
|
|
36
54
|
return _el$2;
|
|
37
55
|
})();
|
|
@@ -75,8 +93,12 @@ function TopBarSearch(props) {
|
|
|
75
93
|
return (() => {
|
|
76
94
|
var _el$5 = _tmpl$6(), _el$6 = _el$5.firstChild;
|
|
77
95
|
spread(_el$5, mergeProps({ get ["class"]() {
|
|
78
|
-
return cn("text-muted-foreground flex h-control-md w-full items-center gap-2 rounded-md border border-input px-3 text-sm", "transition-colors ease-out outline-none", "hover:bg-surface-hover hover:text-foreground", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", "window-no-drag", local.class);
|
|
96
|
+
return cn("text-muted-foreground flex h-control-md w-full min-w-(--control-height-md) items-center justify-center gap-2 rounded-md border border-input px-3 text-sm sm:justify-start", "transition-colors ease-out outline-none", "hover:bg-surface-hover hover:text-foreground", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", "window-no-drag", local.class);
|
|
79
97
|
} }, rest), false, true);
|
|
98
|
+
insert(_el$5, createComponent(Search, {
|
|
99
|
+
"aria-hidden": "true",
|
|
100
|
+
"class": "size-4 shrink-0 sm:hidden"
|
|
101
|
+
}), _el$6);
|
|
80
102
|
insert(_el$6, () => local.placeholder ?? "Search");
|
|
81
103
|
insert(_el$5, createComponent(Show, {
|
|
82
104
|
get when() {
|
|
@@ -112,6 +134,7 @@ function TopBarPill(props) {
|
|
|
112
134
|
return _el$8;
|
|
113
135
|
})();
|
|
114
136
|
}
|
|
137
|
+
delegateEvents(["focusin"]);
|
|
115
138
|
//#endregion
|
|
116
139
|
export { TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle };
|
|
117
140
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-bar.js","names":["ComponentProps","Show","splitProps","cn","TopBarProps","draggable","macosInset","windowsInset","glass","TopBar","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","TopBarSection","align","_el$2","_tmpl$2","TopBarTitle","_el$3","_tmpl$3","TopBarBreadcrumb","_el$4","_tmpl$4","TopBarSearchProps","placeholder","shortcut","TopBarSearch","_el$5","_tmpl$6","_el$6","firstChild","_$insert","_$createComponent","when","children","_el$7","_tmpl$5","TopBarPill","label","_el$8","_tmpl$7","_el$9","_$mergeProps","_$createComponent"],"sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * TopBar.\n *\n * The window's title row and primary toolbar. Three tracks: a leading group, a\n * centred search, and a trailing group. The search is a fixed function of the\n * window width and the two side groups are equal remainders, which is what\n * makes the search *exactly* window-centred by construction — no measurement,\n * no observer, no absolutely-positioned overlay to keep clear of.\n *\n * On a frameless desktop window this row is also the drag region, so it carries\n * `window-drag` and the controls inside it opt back out. `macos-inset` and\n * `windows-inset` reserve the space the native window controls occupy, which is\n * why the row can look off-centre in a frameless window and be correct: it is\n * centred in the space the user can actually see.\n */\nexport type TopBarProps = ComponentProps<'header'> & {\n /** Make the row draggable, for a frameless window. */\n draggable?: boolean\n /** Reserve space for the macOS traffic lights. */\n macosInset?: boolean\n /** Reserve space for the Windows caption buttons. */\n windowsInset?: boolean\n /** Blur the content scrolling under the bar. */\n glass?: boolean\n}\n\nexport function TopBar(props: TopBarProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'draggable',\n 'macosInset',\n 'windowsInset',\n 'glass',\n ])\n\n return (\n <header\n data-slot=\"top-bar\"\n class={cn(\n 'h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border-b border-border bg-card text-card-foreground px-3 md:grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)]',\n local.glass && 'glass-panel',\n local.draggable && 'window-drag',\n local.macosInset && 'window-inset-macos',\n local.windowsInset && 'window-inset-windows',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A side group. Both sides are equal remainders, which centres the search. */\nexport function TopBarSection(props: ComponentProps<'div'> & { align?: 'start' | 'end' }) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n\n return (\n <div\n data-slot=\"top-bar-section\"\n class={cn(\n 'window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden',\n local.align === 'end' && 'justify-end',\n local.align !== 'end' && 'justify-start',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function TopBarTitle(props: ComponentProps<'div'> & { align?: 'start' | 'center' }) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n return (\n <div\n data-slot=\"top-bar-title\"\n class={cn(\n 'truncate text-sm font-medium',\n local.align === 'center' && 'text-center',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A breadcrumb or path readout that yields to the actions when space runs out. */\nexport function TopBarBreadcrumb(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"top-bar-breadcrumb\"\n class={cn('flex min-w-0 items-center gap-1.5 text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport type TopBarSearchProps = ComponentProps<'button'> & {\n /** The hint shown inside the field, e.g. \"Search projects and files\". */\n placeholder?: string\n /** The shortcut chip drawn at the trailing edge, e.g. \"⌘K\". */\n shortcut?: string\n}\n\n/**\n * The search affordance in the middle track.\n *\n * It is a button, not an input, and that is deliberate: clicking it opens the\n * command palette, which already owns the input, the ranking and the keyboard\n * handling. A second live input here would be a second source of truth for the\n * same query. It is styled to read as a field because that is what it behaves\n * like from the user's side.\n */\nexport function TopBarSearch(props: TopBarSearchProps) {\n const [local, rest] = splitProps(props, ['class', 'placeholder', 'shortcut'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-search\"\n class={cn(\n 'text-muted-foreground flex h-control-md w-full items-center gap-2 rounded-md border border-input px-3 text-sm',\n 'transition-colors ease-out outline-none',\n 'hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag',\n local.class\n )}\n {...rest}\n >\n <span class=\"truncate\">{local.placeholder ?? 'Search'}</span>\n <Show when={local.shortcut}>\n <kbd class=\"bg-muted ms-auto hidden h-5 shrink-0 items-center rounded-sm border border-border px-1.5 font-mono text-2xs sm:flex\">\n {local.shortcut}\n </kbd>\n </Show>\n </button>\n )\n}\n\n/**\n * A labelled top-bar control — the readouts KiroCrew puts in the trailing\n * group. Container queries on the group decide which of these survive a narrow\n * window; a caller marks the cheap-to-drop ones and the group handles the rest.\n */\nexport function TopBarPill(props: ComponentProps<'button'> & { label: string }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'children'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-pill\"\n class={cn(\n 'text-muted-foreground inline-flex h-control-sm shrink-0 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium',\n 'transition-colors ease-out outline-none',\n 'hover:border-input hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag [&_svg]:size-3.5 [&_svg]:shrink-0',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <span>{local.label}</span>\n </button>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"top-bar.js","names":["ComponentProps","Show","splitProps","Search","cn","TopBarProps","draggable","macosInset","windowsInset","glass","TopBar","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","invokeFocusHandler","handler","event","Event","Array","isArray","callback","data","TopBarSection","align","_el$2","_tmpl$2","$$focusin","target","HTMLElement","scrollIntoView","block","inline","onFocusIn","TopBarTitle","_el$3","_tmpl$3","TopBarBreadcrumb","_el$4","_tmpl$4","TopBarSearchProps","placeholder","shortcut","TopBarSearch","_el$5","_tmpl$6","_el$6","firstChild","_$insert","_$createComponent","when","children","_el$7","_tmpl$5","TopBarPill","label","_el$8","_tmpl$7","_el$9","_$delegateEvents","_$mergeProps","_$createComponent","_$delegateEvents"],"sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { Search } from 'lucide-solid'\nimport { cn } from '#lib/utils'\n\n/**\n * TopBar.\n *\n * The window's title row and primary toolbar. Three tracks: a leading group, a\n * centred search, and a trailing group. On wide screens the search is a fixed\n * function of the window width and the side groups are equal remainders. On\n * narrow screens the middle track yields space to the controls, and each side\n * group scrolls when necessary so keyboard focus can reveal every action.\n *\n * On a frameless desktop window this row is also the drag region, so it carries\n * `window-drag` and the controls inside it opt back out. `macos-inset` and\n * `windows-inset` reserve the space the native window controls occupy, which is\n * why the row can look off-centre in a frameless window and be correct: it is\n * centred in the space the user can actually see.\n */\nexport type TopBarProps = ComponentProps<'header'> & {\n /** Make the row draggable, for a frameless window. */\n draggable?: boolean\n /** Reserve space for the macOS traffic lights. */\n macosInset?: boolean\n /** Reserve space for the Windows caption buttons. */\n windowsInset?: boolean\n /** Blur the content scrolling under the bar. */\n glass?: boolean\n}\n\nexport function TopBar(props: TopBarProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'draggable',\n 'macosInset',\n 'windowsInset',\n 'glass',\n ])\n\n return (\n <header\n data-slot=\"top-bar\"\n class={cn(\n 'h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3 border-b border-border bg-card text-card-foreground px-3 md:grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)]',\n local.glass && 'glass-panel',\n local.draggable && 'window-drag',\n local.macosInset && 'window-inset-macos',\n local.windowsInset && 'window-inset-windows',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nfunction invokeFocusHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\n/** A scrollable side group; equal wide-screen tracks centre the search. */\nexport function TopBarSection(props: ComponentProps<'div'> & { align?: 'start' | 'end' }) {\n const [local, rest] = splitProps(props, ['class', 'align', 'onFocusIn'])\n\n return (\n <div\n data-slot=\"top-bar-section\"\n class={cn(\n 'window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden',\n local.align === 'end' && 'md:justify-end',\n local.align !== 'end' && 'justify-start',\n local.class\n )}\n onFocusIn={(event) => {\n if (event.target instanceof HTMLElement) {\n event.target.scrollIntoView({ block: 'nearest', inline: 'nearest' })\n }\n invokeFocusHandler(local.onFocusIn, event)\n }}\n {...rest}\n />\n )\n}\n\nexport function TopBarTitle(\n props: ComponentProps<'div'> & {\n /** Aligns text within this slot; it does not position the slot. */\n align?: 'start' | 'center'\n }\n) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n return (\n <div\n data-slot=\"top-bar-title\"\n class={cn(\n 'truncate text-sm font-medium',\n local.align === 'center' && 'text-center',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A breadcrumb or path readout that yields to the actions when space runs out. */\nexport function TopBarBreadcrumb(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"top-bar-breadcrumb\"\n class={cn('flex min-w-0 items-center gap-1.5 text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport type TopBarSearchProps = ComponentProps<'button'> & {\n /** The hint shown inside the field, e.g. \"Search projects and files\". */\n placeholder?: string\n /** The shortcut chip drawn at the trailing edge, e.g. \"⌘K\". */\n shortcut?: string\n}\n\n/**\n * The search affordance in the middle track.\n *\n * It is a button, not an input, and that is deliberate: clicking it opens the\n * command palette, which already owns the input, the ranking and the keyboard\n * handling. A second live input here would be a second source of truth for the\n * same query. It is styled to read as a field because that is what it behaves\n * like from the user's side.\n */\nexport function TopBarSearch(props: TopBarSearchProps) {\n const [local, rest] = splitProps(props, ['class', 'placeholder', 'shortcut'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-search\"\n class={cn(\n 'text-muted-foreground flex h-control-md w-full min-w-(--control-height-md) items-center justify-center gap-2 rounded-md border border-input px-3 text-sm sm:justify-start',\n 'transition-colors ease-out outline-none',\n 'hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag',\n local.class\n )}\n {...rest}\n >\n <Search aria-hidden=\"true\" class=\"size-4 shrink-0 sm:hidden\" />\n <span class=\"sr-only sm:not-sr-only sm:truncate\">{local.placeholder ?? 'Search'}</span>\n <Show when={local.shortcut}>\n <kbd class=\"bg-muted ms-auto hidden h-5 shrink-0 items-center rounded-sm border border-border px-1.5 font-mono text-2xs sm:flex\">\n {local.shortcut}\n </kbd>\n </Show>\n </button>\n )\n}\n\n/**\n * A labelled top-bar control — the readouts KiroCrew puts in the trailing\n * group. Container queries on the group decide which of these survive a narrow\n * window; a caller marks the cheap-to-drop ones and the group handles the rest.\n */\nexport function TopBarPill(props: ComponentProps<'button'> & { label: string }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'children'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-pill\"\n class={cn(\n 'text-muted-foreground inline-flex h-control-sm shrink-0 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium',\n 'transition-colors ease-out outline-none',\n 'hover:border-input hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag [&_svg]:size-3.5 [&_svg]:shrink-0',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <span>{local.label}</span>\n </button>\n )\n}\n"],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ export type DialogContentProps = ComponentProps<typeof KobalteDialogContent> & {
|
|
|
38
38
|
* user can escape from needs the button.
|
|
39
39
|
*/
|
|
40
40
|
closeButton?: JSX.Element | false;
|
|
41
|
+
/** Use a 1rem inset as the positioner bounds for tall, viewport-filling surfaces. */
|
|
42
|
+
positioner?: 'default' | 'inset';
|
|
41
43
|
};
|
|
42
44
|
export declare function DialogContent(props: DialogContentProps): JSX.Element;
|
|
43
45
|
export declare function DialogHeader(props: ComponentProps<'div'>): JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,aAAa,EACvB,OAAO,IAAI,oBAAoB,EAC/B,OAAO,IAAI,oBAAoB,EAChC,MAAM,sBAAsB,CAAA;AAG7B,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAwC7D,KAAK,6BAA6B,GAAG;IACnC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvB,eAAe,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;IACnD,eAAe,CAAC,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAChF,gBAAgB,CAAC,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC,kBAAkB,CAAC,CAAA;CACnF,CAAA;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,eAAe,EACf,eAAe,EAAE,qBAAqB,EACtC,gBAAgB,EAAE,sBAAsB,GACzC,EAAE,6BAA6B;6BA6DE,KAAK;8BAyCJ,KAAK;EA8CvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,eAEjE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,eAEhF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,eAE9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,eAY/E;AAED,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,GAAG;IAC7E;;;;OAIG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,aAAa,EACvB,OAAO,IAAI,oBAAoB,EAC/B,OAAO,IAAI,oBAAoB,EAChC,MAAM,sBAAsB,CAAA;AAG7B,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAwC7D,KAAK,6BAA6B,GAAG;IACnC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvB,eAAe,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;IACnD,eAAe,CAAC,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAChF,gBAAgB,CAAC,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC,kBAAkB,CAAC,CAAA;CACnF,CAAA;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,eAAe,EACf,eAAe,EAAE,qBAAqB,EACtC,gBAAgB,EAAE,sBAAsB,GACzC,EAAE,6BAA6B;6BA6DE,KAAK;8BAyCJ,KAAK;EA8CvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,eAEjE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,eAEhF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,eAE9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,eAY/E;AAED,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,GAAG;IAC7E;;;;OAIG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;IACjC,qFAAqF;IACrF,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;CACjC,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,eAiCtD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASxD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASxD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,KAAK,CAAC,eAQ5E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,WAAW,CAAC,eAKxF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,WAAW,CAAC,eAGxF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,WAAW,CAAC,eAGlF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
2
|
import { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from "../../../lib/overlay.js";
|
|
3
|
-
import { className, createComponent, insert, memo, mergeProps, spread, template } from "solid-js/web";
|
|
3
|
+
import { className, createComponent, effect, insert, memo, mergeProps, spread, template } from "solid-js/web";
|
|
4
4
|
import { X } from "lucide-solid";
|
|
5
5
|
import { Show, createRenderEffect, onCleanup, splitProps } from "solid-js";
|
|
6
6
|
import { Content, Dialog, Overlay } from "@kobalte/core/dialog";
|
|
@@ -157,12 +157,12 @@ function DialogContent(props) {
|
|
|
157
157
|
const [local, rest] = splitProps(props, [
|
|
158
158
|
"class",
|
|
159
159
|
"children",
|
|
160
|
-
"closeButton"
|
|
160
|
+
"closeButton",
|
|
161
|
+
"positioner"
|
|
161
162
|
]);
|
|
162
163
|
return createComponent(Dialog.Portal, { get children() {
|
|
163
164
|
return [createComponent(DialogOverlay, {}), (() => {
|
|
164
165
|
var _el$ = _tmpl$();
|
|
165
|
-
className(_el$, overlayPositioner);
|
|
166
166
|
insert(_el$, createComponent(Content, mergeProps({ get ["class"]() {
|
|
167
167
|
return cn(overlaySurface, overlayMotion, "relative grid w-full max-w-lg gap-4 p-5", local.class);
|
|
168
168
|
} }, rest, { get children() {
|
|
@@ -183,6 +183,7 @@ function DialogContent(props) {
|
|
|
183
183
|
}
|
|
184
184
|
})];
|
|
185
185
|
} })));
|
|
186
|
+
effect(() => className(_el$, cn(overlayPositioner, local.positioner === "inset" && "inset-4 grid-rows-1 p-0")));
|
|
186
187
|
return _el$;
|
|
187
188
|
})()];
|
|
188
189
|
} });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.js","names":["Dialog","KobalteDialog","Content","KobalteDialogContent","Overlay","KobalteDialogOverlay","X","Accessor","ComponentProps","JSX","createRenderEffect","onCleanup","Show","splitProps","overlayMotion","overlayPositioner","overlayScrim","overlaySurface","cn","FocusCycle","content","HTMLElement","opener","openerEligible","closed","focusMovedOutside","closeAutoFocusScheduled","frame","fallbackTimer","observer","MutationObserver","onFocusIn","event","FocusEvent","canRestoreFocus","target","isConnected","document","body","documentElement","closest","matches","getClientRects","length","hasOtherOverlay","querySelectorAll","some","overlay","contains","DialogFocusRestorationOptions","open","restoreFocusRef","onOpenAutoFocus","onCloseAutoFocus","createDialogFocusRestoration","callerOnOpenAutoFocus","callerOnCloseAutoFocus","focusCycles","WeakMap","activeFocusCycle","pendingOpener","pendingOpenerEligible","active","activeElement","finishFocusCycle","cycle","undefined","window","cancelAnimationFrame","clearTimeout","disconnect","removeEventListener","scheduleFocusRestore","requestAnimationFrame","focusIsAvailable","Node","focus","preventScroll","Event","element","currentTarget","openerWasCaptured","focusEvent","set","addEventListener","get","defaultPrevented","observe","attributes","attributeFilter","childList","subtree","queueMicrotask","setTimeout","props","_$createComponent","DialogTrigger","Trigger","DialogPortal","Portal","DialogOverlay","local","rest","_$mergeProps","class","DialogContentProps","closeButton","Element","DialogContent","children","_el$","_tmpl$","_$className","_$insert","_$memo","when","CloseButton","DialogHeader","_el$2","_tmpl$2","_$spread","DialogFooter","_el$3","_tmpl$3","DialogTitle","Title","DialogDescription","Description","DialogCloseButton","DialogClose","Dialog","_$createComponent","KobalteDialog","KobalteDialogOverlay","_$mergeProps","KobalteDialogContent","_$memo"],"sources":["../../../../src/components/ui/dialog/dialog.tsx"],"sourcesContent":["import {\n Dialog as KobalteDialog,\n Content as KobalteDialogContent,\n Overlay as KobalteDialogOverlay,\n} from '@kobalte/core/dialog'\n// AlertDialog assigns to the shared DialogRoot.Content object, so these named exports stay role-stable.\nimport { X } from 'lucide-solid'\nimport type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { createRenderEffect, onCleanup, Show, splitProps } from 'solid-js'\nimport { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'\nimport { cn } from '#lib/utils'\n\ntype FocusCycle = {\n content: HTMLElement\n opener: HTMLElement | null\n openerEligible: boolean\n closed: boolean\n focusMovedOutside: boolean\n closeAutoFocusScheduled: boolean\n frame?: number\n fallbackTimer?: number\n observer?: MutationObserver\n onFocusIn: (event: FocusEvent) => void\n}\n\nfunction canRestoreFocus(target: HTMLElement): boolean {\n return (\n target.isConnected &&\n target !== document.body &&\n target !== document.documentElement &&\n !target.closest('[inert], [aria-hidden=\"true\"]') &&\n !target.matches(':disabled') &&\n target.getClientRects().length > 0\n )\n}\n\nfunction hasOtherOverlay(content: HTMLElement, opener: HTMLElement): boolean {\n return [...document.querySelectorAll<HTMLElement>('[role=\"dialog\"], [role=\"alertdialog\"]')].some(\n (overlay) =>\n overlay !== content &&\n !content.contains(overlay) &&\n !overlay.contains(opener) &&\n !overlay.closest('[aria-hidden=\"true\"], [inert]') &&\n overlay.getClientRects().length > 0\n )\n}\n\ntype DialogFocusRestorationOptions = {\n open: Accessor<boolean>\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n onOpenAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onOpenAutoFocus']\n onCloseAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onCloseAutoFocus']\n}\n\n/**\n * Adds guarded opener capture and restoration to a Kobalte dialog content.\n * Composed surfaces use this internal helper; it is omitted from the public\n * dialog barrel so the restoration policy stays with the dialog components.\n */\nexport function createDialogFocusRestoration({\n open,\n restoreFocusRef,\n onOpenAutoFocus: callerOnOpenAutoFocus,\n onCloseAutoFocus: callerOnCloseAutoFocus,\n}: DialogFocusRestorationOptions) {\n const focusCycles = new WeakMap<HTMLElement, FocusCycle>()\n let activeFocusCycle: FocusCycle | undefined\n let pendingOpener: HTMLElement | null = null\n let pendingOpenerEligible = false\n\n createRenderEffect(() => {\n if (!open() || typeof document === 'undefined') {\n pendingOpener = null\n pendingOpenerEligible = false\n return\n }\n const active = restoreFocusRef?.() ?? document.activeElement\n pendingOpener = active instanceof HTMLElement ? active : null\n pendingOpenerEligible = active instanceof HTMLElement && canRestoreFocus(active)\n })\n\n const finishFocusCycle = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) window.cancelAnimationFrame(cycle.frame)\n if (cycle.fallbackTimer !== undefined) window.clearTimeout(cycle.fallbackTimer)\n cycle.observer?.disconnect()\n document.removeEventListener('focusin', cycle.onFocusIn)\n if (activeFocusCycle === cycle) activeFocusCycle = undefined\n }\n\n const scheduleFocusRestore = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) return\n cycle.frame = window.requestAnimationFrame(() => {\n cycle.frame = undefined\n const opener = cycle.opener\n const active = document.activeElement\n const focusIsAvailable =\n active === document.body ||\n active === document.documentElement ||\n active === cycle.content ||\n (active instanceof Node && cycle.content.contains(active))\n if (\n activeFocusCycle !== cycle ||\n !cycle.closed ||\n cycle.focusMovedOutside ||\n !opener ||\n !opener.isConnected ||\n opener.matches(':disabled') ||\n opener.getClientRects().length === 0 ||\n !focusIsAvailable ||\n hasOtherOverlay(cycle.content, opener)\n ) {\n finishFocusCycle(cycle)\n return\n }\n\n // Inert and aria-hidden are removed by the dialog's containment cleanup.\n // Wait for that cleanup before returning focus to the original control.\n if (opener.closest('[inert], [aria-hidden=\"true\"]')) return\n if (cycle.openerEligible && canRestoreFocus(opener)) {\n opener.focus({ preventScroll: true })\n }\n finishFocusCycle(cycle)\n })\n }\n\n const onOpenAutoFocus = (event: Event) => {\n const element = event.currentTarget\n if (element instanceof HTMLElement) {\n if (activeFocusCycle) finishFocusCycle(activeFocusCycle)\n\n const openerWasCaptured = pendingOpener !== null\n const opener = pendingOpener ?? document.activeElement\n const openerEligible = openerWasCaptured\n ? pendingOpenerEligible\n : opener instanceof HTMLElement && canRestoreFocus(opener)\n pendingOpener = null\n pendingOpenerEligible = false\n const cycle: FocusCycle = {\n content: element,\n opener: opener instanceof HTMLElement ? opener : null,\n openerEligible,\n closed: false,\n focusMovedOutside: false,\n closeAutoFocusScheduled: false,\n onFocusIn: (focusEvent) => {\n const target = focusEvent.target\n if (\n !(target instanceof HTMLElement) ||\n target === document.body ||\n target === document.documentElement ||\n target === element ||\n element.contains(target) ||\n target === (opener instanceof HTMLElement ? opener : null)\n ) {\n return\n }\n cycle.focusMovedOutside = true\n },\n }\n focusCycles.set(element, cycle)\n activeFocusCycle = cycle\n document.addEventListener('focusin', cycle.onFocusIn)\n }\n callerOnOpenAutoFocus?.(event)\n }\n\n const onCloseAutoFocus = (event: Event) => {\n const element = event.currentTarget\n const cycle = element instanceof HTMLElement ? focusCycles.get(element) : undefined\n callerOnCloseAutoFocus?.(event)\n\n if (!cycle) return\n cycle.closed = true\n\n // A caller that prevents Kobalte's close autofocus owns the focus decision.\n if (event.defaultPrevented) {\n finishFocusCycle(cycle)\n return\n }\n\n if (cycle.fallbackTimer !== undefined) {\n window.clearTimeout(cycle.fallbackTimer)\n cycle.fallbackTimer = undefined\n }\n cycle.closeAutoFocusScheduled = true\n cycle.observer = new MutationObserver(() => scheduleFocusRestore(cycle))\n cycle.observer.observe(document.body, {\n attributes: true,\n attributeFilter: ['aria-hidden', 'inert'],\n childList: true,\n subtree: true,\n })\n scheduleFocusRestore(cycle)\n }\n\n onCleanup(() => {\n const cycle = activeFocusCycle\n if (!cycle) return\n cycle.closed = true\n\n // Kobalte dispatches unmount autofocus from a timer. This fallback only\n // releases the scoped focus listener if the content did not dispatch it.\n queueMicrotask(() => {\n if (cycle.closeAutoFocusScheduled) return\n cycle.fallbackTimer = window.setTimeout(() => {\n cycle.fallbackTimer = undefined\n if (!cycle.closeAutoFocusScheduled) finishFocusCycle(cycle)\n }, 0)\n })\n })\n\n return { onOpenAutoFocus, onCloseAutoFocus }\n}\n\n/**\n * Dialog.\n *\n * A modal surface for a decision or a short task. `Dialog.Portal` keeps the\n * panel out of the app's stacking and overflow contexts, `Dialog.Overlay`\n * dims what is behind it, and Kobalte handles the focus trap, the escape key,\n * scroll locking and returning focus to the trigger on close.\n *\n * The close button is part of the content rather than optional, because every\n * modal needs a way out that is not the keyboard. A dialog whose only exit is\n * Escape is a trap for anyone using a pointer.\n */\nexport function Dialog(props: ComponentProps<typeof KobalteDialog>) {\n return <KobalteDialog {...props} />\n}\n\nexport function DialogTrigger(props: ComponentProps<typeof KobalteDialog.Trigger>) {\n return <KobalteDialog.Trigger {...props} />\n}\n\nexport function DialogPortal(props: ComponentProps<typeof KobalteDialog.Portal>) {\n return <KobalteDialog.Portal {...props} />\n}\n\nexport function DialogOverlay(props: ComponentProps<typeof KobalteDialogOverlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialogOverlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type DialogContentProps = ComponentProps<typeof KobalteDialogContent> & {\n /**\n * Replaces the default close button. Pass `false` to remove it — only for a\n * dialog that cannot be dismissed (an update that must finish); anything the\n * user can escape from needs the button.\n */\n closeButton?: JSX.Element | false\n}\n\nexport function DialogContent(props: DialogContentProps) {\n const [local, rest] = splitProps(props, ['class', 'children', 'closeButton'])\n\n return (\n <KobalteDialog.Portal>\n <DialogOverlay />\n <div class={overlayPositioner}>\n <KobalteDialogContent\n class={cn(\n overlaySurface,\n overlayMotion,\n 'relative grid w-full max-w-lg gap-4 p-5',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.closeButton !== false}>\n <KobalteDialog.CloseButton\n aria-label=\"Close\"\n class={cn(\n 'absolute top-3.5 end-3.5 rounded-md p-1 text-muted-foreground',\n 'transition-colors ease-out hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle outline-none'\n )}\n >\n {local.closeButton ?? <X class=\"size-4\" />}\n </KobalteDialog.CloseButton>\n </Show>\n </KobalteDialogContent>\n </div>\n </KobalteDialog.Portal>\n )\n}\n\nexport function DialogHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-header\"\n class={cn('flex flex-col gap-1.5 pe-6 text-start', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogTitle(props: ComponentProps<typeof KobalteDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Title\n class={cn('text-base leading-none font-semibold tracking-tight', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogDescription(props: ComponentProps<typeof KobalteDialog.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function DialogCloseButton(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n\n/**\n * The close control, unstyled and polymorphic — for a footer's text \"Cancel\" or\n * \"Close\", which is a different control from the corner icon `DialogCloseButton`\n * draws. Take it as `as={Button}` so it carries the button's variants rather than\n * a copied class string.\n */\nexport function DialogClose(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dialog.js","names":["Dialog","KobalteDialog","Content","KobalteDialogContent","Overlay","KobalteDialogOverlay","X","Accessor","ComponentProps","JSX","createRenderEffect","onCleanup","Show","splitProps","overlayMotion","overlayPositioner","overlayScrim","overlaySurface","cn","FocusCycle","content","HTMLElement","opener","openerEligible","closed","focusMovedOutside","closeAutoFocusScheduled","frame","fallbackTimer","observer","MutationObserver","onFocusIn","event","FocusEvent","canRestoreFocus","target","isConnected","document","body","documentElement","closest","matches","getClientRects","length","hasOtherOverlay","querySelectorAll","some","overlay","contains","DialogFocusRestorationOptions","open","restoreFocusRef","onOpenAutoFocus","onCloseAutoFocus","createDialogFocusRestoration","callerOnOpenAutoFocus","callerOnCloseAutoFocus","focusCycles","WeakMap","activeFocusCycle","pendingOpener","pendingOpenerEligible","active","activeElement","finishFocusCycle","cycle","undefined","window","cancelAnimationFrame","clearTimeout","disconnect","removeEventListener","scheduleFocusRestore","requestAnimationFrame","focusIsAvailable","Node","focus","preventScroll","Event","element","currentTarget","openerWasCaptured","focusEvent","set","addEventListener","get","defaultPrevented","observe","attributes","attributeFilter","childList","subtree","queueMicrotask","setTimeout","props","_$createComponent","DialogTrigger","Trigger","DialogPortal","Portal","DialogOverlay","local","rest","_$mergeProps","class","DialogContentProps","closeButton","Element","positioner","DialogContent","children","_el$","_tmpl$","_$insert","_$memo","when","CloseButton","_$effect","_$className","DialogHeader","_el$2","_tmpl$2","_$spread","DialogFooter","_el$3","_tmpl$3","DialogTitle","Title","DialogDescription","Description","DialogCloseButton","DialogClose","Dialog","_$createComponent","KobalteDialog","KobalteDialogOverlay","_$mergeProps","KobalteDialogContent","_$memo","_$className"],"sources":["../../../../src/components/ui/dialog/dialog.tsx"],"sourcesContent":["import {\n Dialog as KobalteDialog,\n Content as KobalteDialogContent,\n Overlay as KobalteDialogOverlay,\n} from '@kobalte/core/dialog'\n// AlertDialog assigns to the shared DialogRoot.Content object, so these named exports stay role-stable.\nimport { X } from 'lucide-solid'\nimport type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { createRenderEffect, onCleanup, Show, splitProps } from 'solid-js'\nimport { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'\nimport { cn } from '#lib/utils'\n\ntype FocusCycle = {\n content: HTMLElement\n opener: HTMLElement | null\n openerEligible: boolean\n closed: boolean\n focusMovedOutside: boolean\n closeAutoFocusScheduled: boolean\n frame?: number\n fallbackTimer?: number\n observer?: MutationObserver\n onFocusIn: (event: FocusEvent) => void\n}\n\nfunction canRestoreFocus(target: HTMLElement): boolean {\n return (\n target.isConnected &&\n target !== document.body &&\n target !== document.documentElement &&\n !target.closest('[inert], [aria-hidden=\"true\"]') &&\n !target.matches(':disabled') &&\n target.getClientRects().length > 0\n )\n}\n\nfunction hasOtherOverlay(content: HTMLElement, opener: HTMLElement): boolean {\n return [...document.querySelectorAll<HTMLElement>('[role=\"dialog\"], [role=\"alertdialog\"]')].some(\n (overlay) =>\n overlay !== content &&\n !content.contains(overlay) &&\n !overlay.contains(opener) &&\n !overlay.closest('[aria-hidden=\"true\"], [inert]') &&\n overlay.getClientRects().length > 0\n )\n}\n\ntype DialogFocusRestorationOptions = {\n open: Accessor<boolean>\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n onOpenAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onOpenAutoFocus']\n onCloseAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onCloseAutoFocus']\n}\n\n/**\n * Adds guarded opener capture and restoration to a Kobalte dialog content.\n * Composed surfaces use this internal helper; it is omitted from the public\n * dialog barrel so the restoration policy stays with the dialog components.\n */\nexport function createDialogFocusRestoration({\n open,\n restoreFocusRef,\n onOpenAutoFocus: callerOnOpenAutoFocus,\n onCloseAutoFocus: callerOnCloseAutoFocus,\n}: DialogFocusRestorationOptions) {\n const focusCycles = new WeakMap<HTMLElement, FocusCycle>()\n let activeFocusCycle: FocusCycle | undefined\n let pendingOpener: HTMLElement | null = null\n let pendingOpenerEligible = false\n\n createRenderEffect(() => {\n if (!open() || typeof document === 'undefined') {\n pendingOpener = null\n pendingOpenerEligible = false\n return\n }\n const active = restoreFocusRef?.() ?? document.activeElement\n pendingOpener = active instanceof HTMLElement ? active : null\n pendingOpenerEligible = active instanceof HTMLElement && canRestoreFocus(active)\n })\n\n const finishFocusCycle = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) window.cancelAnimationFrame(cycle.frame)\n if (cycle.fallbackTimer !== undefined) window.clearTimeout(cycle.fallbackTimer)\n cycle.observer?.disconnect()\n document.removeEventListener('focusin', cycle.onFocusIn)\n if (activeFocusCycle === cycle) activeFocusCycle = undefined\n }\n\n const scheduleFocusRestore = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) return\n cycle.frame = window.requestAnimationFrame(() => {\n cycle.frame = undefined\n const opener = cycle.opener\n const active = document.activeElement\n const focusIsAvailable =\n active === document.body ||\n active === document.documentElement ||\n active === cycle.content ||\n (active instanceof Node && cycle.content.contains(active))\n if (\n activeFocusCycle !== cycle ||\n !cycle.closed ||\n cycle.focusMovedOutside ||\n !opener ||\n !opener.isConnected ||\n opener.matches(':disabled') ||\n opener.getClientRects().length === 0 ||\n !focusIsAvailable ||\n hasOtherOverlay(cycle.content, opener)\n ) {\n finishFocusCycle(cycle)\n return\n }\n\n // Inert and aria-hidden are removed by the dialog's containment cleanup.\n // Wait for that cleanup before returning focus to the original control.\n if (opener.closest('[inert], [aria-hidden=\"true\"]')) return\n if (cycle.openerEligible && canRestoreFocus(opener)) {\n opener.focus({ preventScroll: true })\n }\n finishFocusCycle(cycle)\n })\n }\n\n const onOpenAutoFocus = (event: Event) => {\n const element = event.currentTarget\n if (element instanceof HTMLElement) {\n if (activeFocusCycle) finishFocusCycle(activeFocusCycle)\n\n const openerWasCaptured = pendingOpener !== null\n const opener = pendingOpener ?? document.activeElement\n const openerEligible = openerWasCaptured\n ? pendingOpenerEligible\n : opener instanceof HTMLElement && canRestoreFocus(opener)\n pendingOpener = null\n pendingOpenerEligible = false\n const cycle: FocusCycle = {\n content: element,\n opener: opener instanceof HTMLElement ? opener : null,\n openerEligible,\n closed: false,\n focusMovedOutside: false,\n closeAutoFocusScheduled: false,\n onFocusIn: (focusEvent) => {\n const target = focusEvent.target\n if (\n !(target instanceof HTMLElement) ||\n target === document.body ||\n target === document.documentElement ||\n target === element ||\n element.contains(target) ||\n target === (opener instanceof HTMLElement ? opener : null)\n ) {\n return\n }\n cycle.focusMovedOutside = true\n },\n }\n focusCycles.set(element, cycle)\n activeFocusCycle = cycle\n document.addEventListener('focusin', cycle.onFocusIn)\n }\n callerOnOpenAutoFocus?.(event)\n }\n\n const onCloseAutoFocus = (event: Event) => {\n const element = event.currentTarget\n const cycle = element instanceof HTMLElement ? focusCycles.get(element) : undefined\n callerOnCloseAutoFocus?.(event)\n\n if (!cycle) return\n cycle.closed = true\n\n // A caller that prevents Kobalte's close autofocus owns the focus decision.\n if (event.defaultPrevented) {\n finishFocusCycle(cycle)\n return\n }\n\n if (cycle.fallbackTimer !== undefined) {\n window.clearTimeout(cycle.fallbackTimer)\n cycle.fallbackTimer = undefined\n }\n cycle.closeAutoFocusScheduled = true\n cycle.observer = new MutationObserver(() => scheduleFocusRestore(cycle))\n cycle.observer.observe(document.body, {\n attributes: true,\n attributeFilter: ['aria-hidden', 'inert'],\n childList: true,\n subtree: true,\n })\n scheduleFocusRestore(cycle)\n }\n\n onCleanup(() => {\n const cycle = activeFocusCycle\n if (!cycle) return\n cycle.closed = true\n\n // Kobalte dispatches unmount autofocus from a timer. This fallback only\n // releases the scoped focus listener if the content did not dispatch it.\n queueMicrotask(() => {\n if (cycle.closeAutoFocusScheduled) return\n cycle.fallbackTimer = window.setTimeout(() => {\n cycle.fallbackTimer = undefined\n if (!cycle.closeAutoFocusScheduled) finishFocusCycle(cycle)\n }, 0)\n })\n })\n\n return { onOpenAutoFocus, onCloseAutoFocus }\n}\n\n/**\n * Dialog.\n *\n * A modal surface for a decision or a short task. `Dialog.Portal` keeps the\n * panel out of the app's stacking and overflow contexts, `Dialog.Overlay`\n * dims what is behind it, and Kobalte handles the focus trap, the escape key,\n * scroll locking and returning focus to the trigger on close.\n *\n * The close button is part of the content rather than optional, because every\n * modal needs a way out that is not the keyboard. A dialog whose only exit is\n * Escape is a trap for anyone using a pointer.\n */\nexport function Dialog(props: ComponentProps<typeof KobalteDialog>) {\n return <KobalteDialog {...props} />\n}\n\nexport function DialogTrigger(props: ComponentProps<typeof KobalteDialog.Trigger>) {\n return <KobalteDialog.Trigger {...props} />\n}\n\nexport function DialogPortal(props: ComponentProps<typeof KobalteDialog.Portal>) {\n return <KobalteDialog.Portal {...props} />\n}\n\nexport function DialogOverlay(props: ComponentProps<typeof KobalteDialogOverlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialogOverlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type DialogContentProps = ComponentProps<typeof KobalteDialogContent> & {\n /**\n * Replaces the default close button. Pass `false` to remove it — only for a\n * dialog that cannot be dismissed (an update that must finish); anything the\n * user can escape from needs the button.\n */\n closeButton?: JSX.Element | false\n /** Use a 1rem inset as the positioner bounds for tall, viewport-filling surfaces. */\n positioner?: 'default' | 'inset'\n}\n\nexport function DialogContent(props: DialogContentProps) {\n const [local, rest] = splitProps(props, ['class', 'children', 'closeButton', 'positioner'])\n\n return (\n <KobalteDialog.Portal>\n <DialogOverlay />\n <div class={cn(overlayPositioner, local.positioner === 'inset' && 'inset-4 grid-rows-1 p-0')}>\n <KobalteDialogContent\n class={cn(\n overlaySurface,\n overlayMotion,\n 'relative grid w-full max-w-lg gap-4 p-5',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.closeButton !== false}>\n <KobalteDialog.CloseButton\n aria-label=\"Close\"\n class={cn(\n 'absolute top-3.5 end-3.5 rounded-md p-1 text-muted-foreground',\n 'transition-colors ease-out hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle outline-none'\n )}\n >\n {local.closeButton ?? <X class=\"size-4\" />}\n </KobalteDialog.CloseButton>\n </Show>\n </KobalteDialogContent>\n </div>\n </KobalteDialog.Portal>\n )\n}\n\nexport function DialogHeader(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-header\"\n class={cn('flex flex-col gap-1.5 pe-6 text-start', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogTitle(props: ComponentProps<typeof KobalteDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Title\n class={cn('text-base leading-none font-semibold tracking-tight', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogDescription(props: ComponentProps<typeof KobalteDialog.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function DialogCloseButton(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n\n/**\n * The close control, unstyled and polymorphic — for a footer's text \"Cancel\" or\n * \"Close\", which is a different control from the corner icon `DialogCloseButton`\n * draws. Take it as `as={Button}` so it carries the button's variants rather than\n * a copied class string.\n */\nexport function DialogClose(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n"],"mappings":"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"}
|
|
@@ -25,9 +25,12 @@ import { DialogContent } from '../dialog/dialog';
|
|
|
25
25
|
* cannot be inferred from the focused element.
|
|
26
26
|
*
|
|
27
27
|
* Use `Dialog` directly when you need its composition; use this when you want a
|
|
28
|
-
* dialog that is correct by default.
|
|
28
|
+
* dialog that is correct by default. `size="settings"` supplies a wide, bounded
|
|
29
|
+
* shell for a shared settings layout; ordinary dialogs keep their compact default.
|
|
29
30
|
*/
|
|
30
|
-
export type ModalDialogProps = Omit<ComponentProps<typeof DialogContent>, 'children' | 'aria-label' | 'aria-labelledby'> & {
|
|
31
|
+
export type ModalDialogProps = Omit<ComponentProps<typeof DialogContent>, 'children' | 'aria-label' | 'aria-labelledby' | 'positioner'> & {
|
|
32
|
+
/** Selects the bounded, scrollable shell used for grouped workspace settings. */
|
|
33
|
+
size?: 'default' | 'settings';
|
|
31
34
|
open: boolean;
|
|
32
35
|
onClose: () => void;
|
|
33
36
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/modal-dialog/modal-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAG7D,OAAO,EAGL,aAAa,EAId,MAAM,kBAAkB,CAAA;AAEzB
|
|
1
|
+
{"version":3,"file":"modal-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/modal-dialog/modal-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAG7D,OAAO,EAGL,aAAa,EAId,MAAM,kBAAkB,CAAA;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,cAAc,CAAC,OAAO,aAAa,CAAC,EACpC,UAAU,GAAG,YAAY,GAAG,iBAAiB,GAAG,YAAY,CAC7D,GAAG;IACF,iFAAiF;IACjF,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IAC3B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;IACnD,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,eAsFlD"}
|
|
@@ -9,6 +9,7 @@ function ModalDialog(props) {
|
|
|
9
9
|
"onClose",
|
|
10
10
|
"title",
|
|
11
11
|
"modal",
|
|
12
|
+
"size",
|
|
12
13
|
"description",
|
|
13
14
|
"headerLeading",
|
|
14
15
|
"class",
|
|
@@ -53,8 +54,11 @@ function ModalDialog(props) {
|
|
|
53
54
|
get children() {
|
|
54
55
|
return createComponent(DialogContent, mergeProps({
|
|
55
56
|
ref: setContent,
|
|
57
|
+
get positioner() {
|
|
58
|
+
return local.size === "settings" ? "inset" : "default";
|
|
59
|
+
},
|
|
56
60
|
get ["class"]() {
|
|
57
|
-
return cn("gap-4", local.class);
|
|
61
|
+
return cn("gap-4", local.size === "settings" && "flex h-208 max-h-full min-h-0 max-w-6xl flex-col gap-0 overflow-hidden p-0", local.class);
|
|
58
62
|
},
|
|
59
63
|
get ["aria-label"]() {
|
|
60
64
|
return local["aria-label"] ?? local.title;
|
|
@@ -70,30 +74,35 @@ function ModalDialog(props) {
|
|
|
70
74
|
return focusRestoration.onCloseAutoFocus;
|
|
71
75
|
},
|
|
72
76
|
get children() {
|
|
73
|
-
return [createComponent(DialogHeader, {
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
return [createComponent(DialogHeader, {
|
|
78
|
+
get ["class"]() {
|
|
79
|
+
return local.size === "settings" ? "shrink-0 gap-1 border-b border-border px-5 pt-4 pb-3 pe-14" : void 0;
|
|
80
|
+
},
|
|
81
|
+
get children() {
|
|
82
|
+
return [createComponent(DialogTitle, {
|
|
83
|
+
"class": "flex items-center gap-2",
|
|
84
|
+
get children() {
|
|
85
|
+
return [createComponent(Show, {
|
|
86
|
+
get when() {
|
|
87
|
+
return local.headerLeading;
|
|
88
|
+
},
|
|
89
|
+
get children() {
|
|
90
|
+
return local.headerLeading;
|
|
91
|
+
}
|
|
92
|
+
}), memo(() => local.title)];
|
|
93
|
+
}
|
|
94
|
+
}), createComponent(Show, {
|
|
95
|
+
get when() {
|
|
92
96
|
return local.description;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
},
|
|
98
|
+
get children() {
|
|
99
|
+
return createComponent(DialogDescription, { get children() {
|
|
100
|
+
return local.description;
|
|
101
|
+
} });
|
|
102
|
+
}
|
|
103
|
+
})];
|
|
104
|
+
}
|
|
105
|
+
}), memo(() => local.children)];
|
|
97
106
|
}
|
|
98
107
|
}));
|
|
99
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal-dialog.js","names":["Accessor","ComponentProps","JSX","Show","createEffect","createSignal","onCleanup","splitProps","cn","createDialogFocusRestoration","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","ModalDialogProps","Omit","open","onClose","title","modal","description","headerLeading","Element","restoreFocusRef","HTMLElement","children","ModalDialog","props","local","rest","content","setContent","focusRestoration","onOpenAutoFocus","onCloseAutoFocus","element","background","document","body","filter","child","contains","wasInert","map","node","hasAttribute","setAttribute","forEach","index","removeAttribute","_$createComponent","when","onOpenChange","next","_$mergeProps","ref","class","aria-label","aria-labelledby","undefined","_$memo","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/modal-dialog/modal-dialog.tsx"],"sourcesContent":["import type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { Show, createEffect, createSignal, onCleanup, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport {\n createDialogFocusRestoration,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../dialog/dialog'\n\n/**\n * ModalDialog.\n *\n * A dialog that owns four things `Dialog` leaves to its caller, each of which is a\n * real defect when it is missed:\n *\n * 1. **It unmounts while closed.** An always-mounted dialog that closes as a side\n * effect of an async action can leave Kobalte's `aria-hidden` bookkeeping behind,\n * which hides the rest of the application from assistive technology. Unmounting\n * the whole owner makes cleanup the only way the layer can end.\n * 2. **It marks the background `inert`.** `inert` keeps the background out of the\n * tab order and the accessibility tree without depending on that bookkeeping, and\n * it restores exactly the elements that did not already have it — so a nested\n * dialog does not un-inert its parent.\n * 3. **It sets an explicit accessible name.** The content receives `aria-label`\n * from `title`, so its name does not depend on the title id registration effect.\n * Pass `aria-label` to use a different name while keeping the visible title;\n * pass `aria-labelledby` when another visible label should take precedence.\n * 4. **It returns focus to the opener.** The opener is captured before the dialog\n * autofocuses and restored after the owner closes, unless a close-autofocus\n * handler takes control or focus has moved to another layer. For controlled\n * dialogs without a composed trigger, pass `restoreFocusRef` when the opener\n * cannot be inferred from the focused element.\n *\n * Use `Dialog` directly when you need its composition; use this when you want a\n * dialog that is correct by default.\n */\nexport type ModalDialogProps = Omit<\n ComponentProps<typeof DialogContent>,\n 'children' | 'aria-label' | 'aria-labelledby'\n> & {\n open: boolean\n onClose: () => void\n title: string\n /**\n * Controls Kobalte's focus, scroll and accessibility modality. Defaults to `true`;\n * background body children remain inert in either mode.\n */\n modal?: boolean\n description?: string\n /** A mark or icon drawn before the title. */\n headerLeading?: JSX.Element\n /** Replaces `title` as the accessible name while keeping the visible title. */\n 'aria-label'?: string\n /** Names the dialog from a visible element; ARIA gives it precedence over `aria-label`. */\n 'aria-labelledby'?: string\n /**\n * Supplies the external control to focus when this controlled dialog closes.\n * Defaults to the element focused immediately before the dialog opens.\n */\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n children?: JSX.Element\n}\n\nexport function ModalDialog(props: ModalDialogProps) {\n const [local, rest] = splitProps(props, [\n 'open',\n 'onClose',\n 'title',\n 'modal',\n 'description',\n 'headerLeading',\n 'class',\n 'children',\n 'aria-label',\n 'aria-labelledby',\n 'restoreFocusRef',\n 'onOpenAutoFocus',\n 'onCloseAutoFocus',\n ])\n\n const [content, setContent] = createSignal<HTMLElement>()\n const focusRestoration = createDialogFocusRestoration({\n open: () => local.open,\n restoreFocusRef: local.restoreFocusRef,\n onOpenAutoFocus: local.onOpenAutoFocus,\n onCloseAutoFocus: local.onCloseAutoFocus,\n })\n\n createEffect(() => {\n if (!local.open) return\n const element = content()\n if (!element) return\n\n const background = [...document.body.children].filter(\n (child): child is HTMLElement => child instanceof HTMLElement && !child.contains(element)\n )\n const wasInert = background.map((node) => node.hasAttribute('inert'))\n for (const node of background) node.setAttribute('inert', '')\n\n onCleanup(() => {\n background.forEach((node, index) => {\n // Only the elements that were not already inert are restored, so a nested\n // dialog closing does not undo its parent's containment.\n if (!wasInert[index]) node.removeAttribute('inert')\n })\n })\n })\n\n return (\n <Show when={local.open}>\n <Dialog open modal={local.modal ?? true} onOpenChange={(next) => !next && local.onClose()}>\n <DialogContent\n ref={setContent}\n class={cn('gap-4'
|
|
1
|
+
{"version":3,"file":"modal-dialog.js","names":["Accessor","ComponentProps","JSX","Show","createEffect","createSignal","onCleanup","splitProps","cn","createDialogFocusRestoration","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","ModalDialogProps","Omit","size","open","onClose","title","modal","description","headerLeading","Element","restoreFocusRef","HTMLElement","children","ModalDialog","props","local","rest","content","setContent","focusRestoration","onOpenAutoFocus","onCloseAutoFocus","element","background","document","body","filter","child","contains","wasInert","map","node","hasAttribute","setAttribute","forEach","index","removeAttribute","_$createComponent","when","onOpenChange","next","_$mergeProps","ref","positioner","class","aria-label","aria-labelledby","undefined","_$memo","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/modal-dialog/modal-dialog.tsx"],"sourcesContent":["import type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { Show, createEffect, createSignal, onCleanup, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport {\n createDialogFocusRestoration,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../dialog/dialog'\n\n/**\n * ModalDialog.\n *\n * A dialog that owns four things `Dialog` leaves to its caller, each of which is a\n * real defect when it is missed:\n *\n * 1. **It unmounts while closed.** An always-mounted dialog that closes as a side\n * effect of an async action can leave Kobalte's `aria-hidden` bookkeeping behind,\n * which hides the rest of the application from assistive technology. Unmounting\n * the whole owner makes cleanup the only way the layer can end.\n * 2. **It marks the background `inert`.** `inert` keeps the background out of the\n * tab order and the accessibility tree without depending on that bookkeeping, and\n * it restores exactly the elements that did not already have it — so a nested\n * dialog does not un-inert its parent.\n * 3. **It sets an explicit accessible name.** The content receives `aria-label`\n * from `title`, so its name does not depend on the title id registration effect.\n * Pass `aria-label` to use a different name while keeping the visible title;\n * pass `aria-labelledby` when another visible label should take precedence.\n * 4. **It returns focus to the opener.** The opener is captured before the dialog\n * autofocuses and restored after the owner closes, unless a close-autofocus\n * handler takes control or focus has moved to another layer. For controlled\n * dialogs without a composed trigger, pass `restoreFocusRef` when the opener\n * cannot be inferred from the focused element.\n *\n * Use `Dialog` directly when you need its composition; use this when you want a\n * dialog that is correct by default. `size=\"settings\"` supplies a wide, bounded\n * shell for a shared settings layout; ordinary dialogs keep their compact default.\n */\nexport type ModalDialogProps = Omit<\n ComponentProps<typeof DialogContent>,\n 'children' | 'aria-label' | 'aria-labelledby' | 'positioner'\n> & {\n /** Selects the bounded, scrollable shell used for grouped workspace settings. */\n size?: 'default' | 'settings'\n open: boolean\n onClose: () => void\n title: string\n /**\n * Controls Kobalte's focus, scroll and accessibility modality. Defaults to `true`;\n * background body children remain inert in either mode.\n */\n modal?: boolean\n description?: string\n /** A mark or icon drawn before the title. */\n headerLeading?: JSX.Element\n /** Replaces `title` as the accessible name while keeping the visible title. */\n 'aria-label'?: string\n /** Names the dialog from a visible element; ARIA gives it precedence over `aria-label`. */\n 'aria-labelledby'?: string\n /**\n * Supplies the external control to focus when this controlled dialog closes.\n * Defaults to the element focused immediately before the dialog opens.\n */\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n children?: JSX.Element\n}\n\nexport function ModalDialog(props: ModalDialogProps) {\n const [local, rest] = splitProps(props, [\n 'open',\n 'onClose',\n 'title',\n 'modal',\n 'size',\n 'description',\n 'headerLeading',\n 'class',\n 'children',\n 'aria-label',\n 'aria-labelledby',\n 'restoreFocusRef',\n 'onOpenAutoFocus',\n 'onCloseAutoFocus',\n ])\n\n const [content, setContent] = createSignal<HTMLElement>()\n const focusRestoration = createDialogFocusRestoration({\n open: () => local.open,\n restoreFocusRef: local.restoreFocusRef,\n onOpenAutoFocus: local.onOpenAutoFocus,\n onCloseAutoFocus: local.onCloseAutoFocus,\n })\n\n createEffect(() => {\n if (!local.open) return\n const element = content()\n if (!element) return\n\n const background = [...document.body.children].filter(\n (child): child is HTMLElement => child instanceof HTMLElement && !child.contains(element)\n )\n const wasInert = background.map((node) => node.hasAttribute('inert'))\n for (const node of background) node.setAttribute('inert', '')\n\n onCleanup(() => {\n background.forEach((node, index) => {\n // Only the elements that were not already inert are restored, so a nested\n // dialog closing does not undo its parent's containment.\n if (!wasInert[index]) node.removeAttribute('inert')\n })\n })\n })\n\n return (\n <Show when={local.open}>\n <Dialog open modal={local.modal ?? true} onOpenChange={(next) => !next && local.onClose()}>\n <DialogContent\n ref={setContent}\n positioner={local.size === 'settings' ? 'inset' : 'default'}\n class={cn(\n 'gap-4',\n local.size === 'settings' &&\n 'flex h-208 max-h-full min-h-0 max-w-6xl flex-col gap-0 overflow-hidden p-0',\n local.class\n )}\n aria-label={local['aria-label'] ?? local.title}\n aria-labelledby={\n local['aria-labelledby'] ?? (local['aria-label'] !== undefined ? '' : undefined)\n }\n {...rest}\n onOpenAutoFocus={focusRestoration.onOpenAutoFocus}\n onCloseAutoFocus={focusRestoration.onCloseAutoFocus}\n >\n <DialogHeader\n class={\n local.size === 'settings'\n ? 'shrink-0 gap-1 border-b border-border px-5 pt-4 pb-3 pe-14'\n : undefined\n }\n >\n <DialogTitle class=\"flex items-center gap-2\">\n <Show when={local.headerLeading}>{local.headerLeading}</Show>\n {local.title}\n </DialogTitle>\n <Show when={local.description}>\n <DialogDescription>{local.description}</DialogDescription>\n </Show>\n </DialogHeader>\n {local.children}\n </DialogContent>\n </Dialog>\n </Show>\n )\n}\n"],"mappings":";;;;;AAqEA,SAAgB4B,YAAYC,OAAyB;CACnD,MAAM,CAACC,OAAOC,QAAQxB,WAAWsB,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAkB,CACnB;CAED,MAAM,CAACG,SAASC,cAAc5B,aAA0B;CACxD,MAAM6B,mBAAmBzB,6BAA6B;EACpDS,YAAYY,MAAMZ;EAClBO,iBAAiBK,MAAML;EACvBU,iBAAiBL,MAAMK;EACvBC,kBAAkBN,MAAMM;CAC1B,CAAC;CAEDhC,mBAAmB;EACjB,IAAI,CAAC0B,MAAMZ,MAAM;EACjB,MAAMmB,UAAUL,QAAQ;EACxB,IAAI,CAACK,SAAS;EAEd,MAAMC,aAAa,CAAC,GAAGC,SAASC,KAAKb,QAAQ,CAAC,CAACc,QAC5CC,UAAgCA,iBAAiBhB,eAAe,CAACgB,MAAMC,SAASN,OAAO,CAC1F;EACA,MAAMO,WAAWN,WAAWO,KAAKC,SAASA,KAAKC,aAAa,OAAO,CAAC;EACpE,KAAK,MAAMD,QAAQR,YAAYQ,KAAKE,aAAa,SAAS,EAAE;EAE5D1C,gBAAgB;GACdgC,WAAWW,SAASH,MAAMI,UAAU;IAGlC,IAAI,CAACN,SAASM,QAAQJ,KAAKK,gBAAgB,OAAO;GACpD,CAAC;EACH,CAAC;CACH,CAAC;CAED,OAAAC,gBACGjD,MAAI;EAAA,IAACkD,OAAI;GAAA,OAAEvB,MAAMZ;EAAI;EAAA,IAAAS,WAAA;GAAA,OAAAyB,gBACnB1C,QAAM;IAACQ,MAAI;IAAA,IAACG,QAAK;KAAA,OAAES,MAAMT,SAAS;IAAI;IAAEiC,eAAeC,SAAS,CAACA,QAAQzB,MAAMX,QAAQ;IAAC,IAAAQ,WAAA;KAAA,OAAAyB,gBACtFzC,eAAa6C,WAAA;MAAAC,KACPxB;MAAU,IACfyB,aAAU;OAAA,OAAE5B,MAAMb,SAAS,aAAa,UAAU;MAAS;MAAA,KAAA,WAAA;OAAA,OACpDT,GACL,SACAsB,MAAMb,SAAS,cACb,8EACFa,MAAM6B,KACR;MAAC;MAAA,KAAA,gBAAA;OAAA,OACW7B,MAAM,iBAAiBA,MAAMV;MAAK;MAAA,KAAA,qBAAA;OAAA,OAE5CU,MAAM,uBAAuBA,MAAM,kBAAkBgC,KAAAA,IAAY,KAAKA,KAAAA;MAAU;KAAA,GAE9E/B,MAAI;MAAA,IACRI,kBAAe;OAAA,OAAED,iBAAiBC;MAAe;MAAA,IACjDC,mBAAgB;OAAA,OAAEF,iBAAiBE;MAAgB;MAAA,IAAAT,WAAA;OAAA,OAAA,CAAAyB,gBAElDvC,cAAY;QAAA,KAAA,WAAA;SAAA,OAETiB,MAAMb,SAAS,aACX,+DACA6C,KAAAA;QAAS;QAAA,IAAAnC,WAAA;SAAA,OAAA,CAAAyB,gBAGdtC,aAAW;UAAA,SAAA;UAAA,IAAAa,WAAA;WAAA,OAAA,CAAAyB,gBACTjD,MAAI;YAAA,IAACkD,OAAI;aAAA,OAAEvB,MAAMP;YAAa;YAAA,IAAAI,WAAA;aAAA,OAAGG,MAAMP;YAAa;WAAA,CAAA,GAAAwC,WACpDjC,MAAMV,KAAK,CAAA;UAAA;SAAA,CAAA,GAAAgC,gBAEbjD,MAAI;UAAA,IAACkD,OAAI;WAAA,OAAEvB,MAAMR;UAAW;UAAA,IAAAK,WAAA;WAAA,OAAAyB,gBAC1BxC,mBAAiB,EAAA,IAAAe,WAAA;YAAA,OAAEG,MAAMR;WAAW,EAAA,CAAA;UAAA;SAAA,CAAA,CAAA;QAAA;OAAA,CAAA,GAAAyC,WAGxCjC,MAAMH,QAAQ,CAAA;MAAA;KAAA,CAAA,CAAA;IAAA;GAAA,CAAA;EAAA;CAAA,CAAA;AAKzB"}
|