@humain/ui 2.1.62 → 2.1.65
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/dist/components/organisms/ai/AIToolCall/AIToolCall.d.ts +9 -3
- package/dist/components/organisms/ai/AIToolRun/index.d.ts +1 -1
- package/dist/components/organisms/ai/AIToolRun/validation.d.ts +24 -3
- package/dist/components/organisms/ai/_shared/format-ai-duration.d.ts +1 -0
- package/dist/components/organisms/ai/_shared/workflow-step-renderer.d.ts +1 -0
- package/dist/index.js +52 -52
- package/dist/index151.js +1 -1
- package/dist/index174.js +10 -333
- package/dist/index174.js.map +1 -1
- package/dist/index175.js +310 -137
- package/dist/index175.js.map +1 -1
- package/dist/index176.js +148 -174
- package/dist/index176.js.map +1 -1
- package/dist/index177.js +186 -78
- package/dist/index177.js.map +1 -1
- package/dist/index178.js +74 -124
- package/dist/index178.js.map +1 -1
- package/dist/index179.js +133 -1
- package/dist/index179.js.map +1 -0
- package/dist/index180.js +2 -201
- package/dist/index181.js +201 -0
- package/dist/{index180.js.map → index181.js.map} +1 -1
- package/dist/index183.js +130 -166
- package/dist/index183.js.map +1 -1
- package/dist/index184.js +195 -983
- package/dist/index184.js.map +1 -1
- package/dist/index185.js +1069 -369
- package/dist/index185.js.map +1 -1
- package/dist/index186.js +395 -197
- package/dist/index186.js.map +1 -1
- package/dist/index187.js +198 -243
- package/dist/index187.js.map +1 -1
- package/dist/index188.js +263 -3
- package/dist/index188.js.map +1 -1
- package/dist/index189.js +3 -209
- package/dist/index189.js.map +1 -1
- package/dist/index190.js +190 -777
- package/dist/index190.js.map +1 -1
- package/dist/index191.js +771 -252
- package/dist/index191.js.map +1 -1
- package/dist/index192.js +250 -65
- package/dist/index192.js.map +1 -1
- package/dist/index193.js +72 -523
- package/dist/index193.js.map +1 -1
- package/dist/index194.js +537 -144
- package/dist/index194.js.map +1 -1
- package/dist/index195.js +139 -720
- package/dist/index195.js.map +1 -1
- package/dist/index196.js +707 -167
- package/dist/index196.js.map +1 -1
- package/dist/index197.js +175 -151
- package/dist/index197.js.map +1 -1
- package/dist/index198.js +152 -487
- package/dist/index198.js.map +1 -1
- package/dist/index199.js +472 -225
- package/dist/index199.js.map +1 -1
- package/dist/index200.js +236 -260
- package/dist/index200.js.map +1 -1
- package/dist/index201.js +265 -215
- package/dist/index201.js.map +1 -1
- package/dist/index202.js +207 -307
- package/dist/index202.js.map +1 -1
- package/dist/index203.js +302 -135
- package/dist/index203.js.map +1 -1
- package/dist/index204.js +140 -271
- package/dist/index204.js.map +1 -1
- package/dist/index205.js +263 -253
- package/dist/index205.js.map +1 -1
- package/dist/index206.js +244 -137
- package/dist/index206.js.map +1 -1
- package/dist/index207.js +100 -238
- package/dist/index207.js.map +1 -1
- package/dist/index208.js +278 -74
- package/dist/index208.js.map +1 -1
- package/dist/index209.js +56 -97
- package/dist/index209.js.map +1 -1
- package/dist/index210.js +142 -47
- package/dist/index210.js.map +1 -1
- package/dist/index211.js +38 -84
- package/dist/index211.js.map +1 -1
- package/dist/index212.js +72 -252
- package/dist/index212.js.map +1 -1
- package/dist/index213.js +274 -26
- package/dist/index213.js.map +1 -1
- package/dist/index214.js +29 -94
- package/dist/index214.js.map +1 -1
- package/dist/index215.js +98 -25
- package/dist/index215.js.map +1 -1
- package/dist/index216.js +20 -565
- package/dist/index216.js.map +1 -1
- package/dist/index217.js +564 -17
- package/dist/index217.js.map +1 -1
- package/dist/index218.js +20 -23
- package/dist/index218.js.map +1 -1
- package/dist/index219.js +20 -95
- package/dist/index219.js.map +1 -1
- package/dist/index220.js +92 -88
- package/dist/index220.js.map +1 -1
- package/dist/index221.js +97 -29
- package/dist/index221.js.map +1 -1
- package/dist/index222.js +24 -470
- package/dist/index222.js.map +1 -1
- package/dist/index223.js +446 -196
- package/dist/index223.js.map +1 -1
- package/dist/index224.js +199 -729
- package/dist/index224.js.map +1 -1
- package/dist/index225.js +750 -61
- package/dist/index225.js.map +1 -1
- package/dist/index226.js +58 -181
- package/dist/index226.js.map +1 -1
- package/dist/index227.js +175 -259
- package/dist/index227.js.map +1 -1
- package/dist/index228.js +246 -172
- package/dist/index228.js.map +1 -1
- package/dist/index229.js +195 -32
- package/dist/index229.js.map +1 -1
- package/dist/index230.js +12 -40
- package/dist/index230.js.map +1 -1
- package/dist/index231.js +23 -26
- package/dist/index231.js.map +1 -1
- package/dist/index232.js +45 -22
- package/dist/index232.js.map +1 -1
- package/dist/index233.js +27 -48
- package/dist/index233.js.map +1 -1
- package/dist/index234.js +52 -26
- package/dist/index234.js.map +1 -1
- package/dist/index235.js +40 -225
- package/dist/index235.js.map +1 -1
- package/dist/index236.js +217 -39
- package/dist/index236.js.map +1 -1
- package/dist/index237.js +50 -0
- package/dist/index237.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/wc/AIToolCall.js +218 -0
- package/dist/wc/AIToolCall.js.map +1 -0
- package/dist/wc/hf-ai-tool-call.js +34 -219
- package/dist/wc/hf-ai-tool-call.js.map +1 -1
- package/dist/wc/hf-ai-tool-run.js +673 -576
- package/dist/wc/hf-ai-tool-run.js.map +1 -1
- package/dist/wc/workflow-step-renderer.js +94 -86
- package/dist/wc/workflow-step-renderer.js.map +1 -1
- package/dist/wc-react/AIToolCall.js +218 -0
- package/dist/wc-react/AIToolCall.js.map +1 -0
- package/dist/wc-react/hf-ai-tool-call.js +32 -217
- package/dist/wc-react/hf-ai-tool-call.js.map +1 -1
- package/dist/wc-react/hf-ai-tool-run.js +698 -601
- package/dist/wc-react/hf-ai-tool-run.js.map +1 -1
- package/dist/wc-react/workflow-step-renderer.js +76 -68
- package/dist/wc-react/workflow-step-renderer.js.map +1 -1
- package/package.json +1 -1
- package/skills/humain-ui/SKILL.md +1 -1
- package/skills/humain-ui-wc/SKILL.md +1 -1
- package/skills/humain-ui-wc.skill +0 -0
- package/skills/humain-ui.skill +0 -0
- package/dist/index182.js +0 -143
- package/dist/index182.js.map +0 -1
- package/dist/wc/wrench.js +0 -10
- package/dist/wc/wrench.js.map +0 -1
- package/dist/wc-react/wrench.js +0 -10
- package/dist/wc-react/wrench.js.map +0 -1
package/dist/index203.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index203.js","names":[],"sources":["../src/components/organisms/layout/SectionHeader/SectionHeader.tsx"],"sourcesContent":["'use client';\n\nimport { Search } from 'lucide-react';\nimport * as React from 'react';\nimport { Button, type ButtonProps } from '@/components/atoms/buttons/Button';\nimport { ButtonGroup } from '@/components/atoms/buttons/ButtonGroup';\nimport { Input, type InputProps } from '@/components/atoms/forms/Input';\nimport { Separator } from '@/components/atoms/layout/Separator';\nimport { Tabs } from '@/components/molecules/navigation/Tabs';\nimport { cn } from '@/lib/utils';\n\nexport type SectionHeaderSize = 'sm' | 'md';\nexport type SectionHeaderHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\ntype SectionHeaderHeadingTag = `h${SectionHeaderHeadingLevel}`;\n\nexport interface SectionHeaderAction\n extends Omit<ButtonProps, 'children' | 'render'> {\n label: React.ReactNode;\n}\n\nexport interface SectionHeaderTab {\n label: React.ReactNode;\n value?: string;\n active?: boolean;\n leadingIcon?: React.ReactNode;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n}\n\nexport interface SectionHeaderSearchProps\n extends Omit<\n InputProps,\n 'size' | 'shape' | 'startIcon' | 'endIcon' | 'appearance'\n > {\n placeholder?: string;\n ariaLabel?: string;\n /** Optional interactive filter control rendered beside the search input */\n filterButton?: React.ReactNode;\n}\n\nexport interface SectionHeaderProps\n extends Omit<React.ComponentPropsWithoutRef<'header'>, 'title'> {\n /** Section title */\n title: React.ReactNode;\n /** Supporting text below the title */\n supportingText?: React.ReactNode;\n /** Heading/text size from the Figma variants */\n size?: SectionHeaderSize;\n /** Semantic heading level for the section title */\n headingLevel?: SectionHeaderHeadingLevel;\n /** Action buttons rendered to the right of the title block */\n actions?: SectionHeaderAction[];\n /** Optional grouped actions rendered as a segmented control */\n buttonGroup?: SectionHeaderAction[];\n /** Optional search input rendered to the right of the title block */\n search?: SectionHeaderSearchProps;\n /** Optional tabs row rendered below the header controls */\n tabs?: SectionHeaderTab[];\n /** Trailing menu control rendered after the action buttons */\n menuButton?: React.ReactNode;\n /** Show the bottom divider */\n showDivider?: boolean;\n}\n\ntype SectionHeaderControlProps = Pick<\n SectionHeaderProps,\n 'actions' | 'buttonGroup' | 'search'\n>;\n\nconst controlTouchTargetClassName = 'min-h-11 min-w-11 shrink-0';\n\nfunction getHeadingTag(\n headingLevel: SectionHeaderHeadingLevel,\n): SectionHeaderHeadingTag {\n return `h${headingLevel}` as SectionHeaderHeadingTag;\n}\n\nfunction SectionHeaderTouchTargetControl({\n control,\n}: {\n control: React.ReactNode;\n}): React.ReactNode {\n if (React.isValidElement<{ className?: string }>(control)) {\n return React.cloneElement(control, {\n className: cn(control.props.className, controlTouchTargetClassName),\n });\n }\n\n return (\n <span\n className={cn(\n 'inline-flex items-center justify-center',\n controlTouchTargetClassName,\n )}\n >\n {control}\n </span>\n );\n}\n\nfunction getSectionHeaderActionKey(\n action: SectionHeaderAction,\n index: number,\n prefix = 'section-header-action',\n): React.Key {\n return typeof action.label === 'string'\n ? `${action.label}-${index}`\n : `${prefix}-${index}`;\n}\n\nfunction SectionHeaderActionButton({\n action,\n className,\n}: {\n action: SectionHeaderAction;\n className?: string;\n}): React.JSX.Element {\n const { label, className: actionClassName, ...buttonProps } = action;\n\n return (\n <Button\n appearance=\"solid\"\n size=\"default\"\n shape=\"rounded\"\n className={cn(\n 'h-10 rounded-xl px-2 text-xs font-medium',\n actionClassName,\n className,\n )}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n}\n\nfunction SectionHeaderButtonGroup({\n actions,\n}: {\n actions: SectionHeaderAction[];\n}): React.JSX.Element {\n return (\n <ButtonGroup\n aria-label=\"Section header controls\"\n shape=\"rounded\"\n className=\"overflow-hidden rounded-xl\"\n >\n {actions.map((action, index) => {\n const { label, className, ...buttonProps } = action;\n\n return (\n <Button\n key={getSectionHeaderActionKey(\n action,\n index,\n 'section-header-group-action',\n )}\n appearance={\n (buttonProps.appearance as ButtonProps['appearance']) ?? 'soft'\n }\n variant={\n (buttonProps.variant as ButtonProps['variant']) ?? 'primary'\n }\n size=\"md\"\n shape=\"rounded\"\n className={cn(\n 'border-transparent px-3 text-xs font-medium shadow-none',\n className,\n )}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n}\n\nfunction getTabValue(tab: SectionHeaderTab, index: number): string {\n if (tab.value !== undefined) {\n return tab.value;\n }\n\n if (typeof tab.label === 'string') {\n return `${tab.label}-${index}`;\n }\n\n return `section-header-tab-${index}`;\n}\n\nfunction SectionHeaderTabs({\n tabs,\n}: {\n tabs: SectionHeaderTab[];\n}): React.JSX.Element {\n const tabValues = tabs.map((tab, index) => getTabValue(tab, index));\n const tabListKey = JSON.stringify(tabValues);\n const activeIndex = tabs.findIndex((tab) => tab.active);\n const activeValue = activeIndex >= 0 ? tabValues[activeIndex] : undefined;\n\n return (\n <Tabs\n key={tabListKey}\n value={activeValue}\n defaultValue={activeValue ?? tabValues[0]}\n className=\"w-full\"\n >\n <Tabs.List\n variant=\"boxed\"\n size=\"sm\"\n align=\"stretch\"\n aria-label=\"Section header tabs\"\n className=\"w-full overflow-x-auto overflow-y-hidden rounded-[8px] border border-border bg-card p-1 shadow-sm\"\n >\n {tabs.map((tab, index) => {\n const value = tabValues[index];\n return (\n <Tabs.Trigger\n key={value}\n value={value}\n icon={tab.leadingIcon}\n className=\"min-w-max flex-1 rounded-[10px] px-3 py-1\"\n onClick={tab.onClick}\n >\n <span className=\"whitespace-nowrap\">{tab.label}</span>\n </Tabs.Trigger>\n );\n })}\n </Tabs.List>\n </Tabs>\n );\n}\n\nfunction SectionHeaderControls({\n actions,\n buttonGroup,\n search,\n}: SectionHeaderControlProps): React.JSX.Element {\n return (\n <React.Fragment>\n {search ? <SectionHeaderSearchField search={search} /> : null}\n {buttonGroup?.length ? (\n <SectionHeaderButtonGroup actions={buttonGroup} />\n ) : null}\n {actions?.length ? (\n <div className=\"flex flex-wrap items-center gap-3 md:flex-nowrap\">\n {actions.map((action, index) => (\n <SectionHeaderActionButton\n key={getSectionHeaderActionKey(action, index)}\n action={action}\n />\n ))}\n </div>\n ) : null}\n </React.Fragment>\n );\n}\n\nfunction SectionHeaderSearchField({\n search,\n}: {\n search: SectionHeaderSearchProps;\n}): React.JSX.Element {\n const {\n className: searchClassName,\n placeholder,\n ariaLabel,\n filterButton,\n ...searchProps\n } = search;\n const searchInput = (\n <Input\n size=\"md\"\n shape=\"rounded\"\n aria-label={ariaLabel ?? 'Search'}\n placeholder={placeholder ?? 'Search'}\n startIcon={<Search className=\"size-4\" />}\n className={cn(\n filterButton ? 'min-w-0 flex-1' : 'w-full max-w-[320px]',\n searchClassName,\n )}\n {...searchProps}\n />\n );\n\n if (filterButton) {\n return (\n <div\n data-slot=\"section-header-search\"\n className=\"flex w-full max-w-[376px] items-center gap-2\"\n >\n {searchInput}\n <SectionHeaderTouchTargetControl control={filterButton} />\n </div>\n );\n }\n\n return searchInput;\n}\n\nconst SectionHeader = React.forwardRef<HTMLElement, SectionHeaderProps>(\n (\n {\n title,\n supportingText,\n size = 'md',\n headingLevel = 2,\n actions,\n buttonGroup,\n search,\n tabs,\n menuButton = null,\n showDivider = true,\n className,\n ...props\n },\n ref,\n ) => {\n const hasSearch = Boolean(search);\n const hasButtonGroup = Boolean(buttonGroup?.length);\n const hasActions = Boolean(actions?.length);\n const hasInlineControls = hasSearch || hasButtonGroup || hasActions;\n const hasHeaderControls = hasInlineControls || Boolean(menuButton);\n const HeadingTag = getHeadingTag(headingLevel);\n\n return (\n <header\n ref={ref}\n data-slot=\"section-header\"\n className={cn('relative flex w-full flex-col gap-4', className)}\n {...props}\n >\n <div className=\"grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-x-4 gap-y-3\">\n <div\n className={cn(\n 'col-start-1 row-start-1 flex min-w-0 flex-col justify-center gap-0.5',\n menuButton ? 'pe-8 md:pe-0' : null,\n )}\n >\n <HeadingTag\n className={cn(\n 'line-clamp-2 w-full break-words font-semibold text-foreground',\n size === 'sm'\n ? 'text-[14px] leading-5'\n : 'text-[18px] leading-7',\n )}\n >\n {title}\n </HeadingTag>\n {supportingText ? (\n <p className=\"line-clamp-2 w-full break-words text-sm leading-5 text-secondary-foreground\">\n {supportingText}\n </p>\n ) : null}\n </div>\n\n {hasHeaderControls ? (\n <div\n className={cn(\n 'col-span-2 row-start-2 flex flex-wrap items-center gap-3 md:col-span-1 md:col-start-2 md:row-start-1 md:flex-nowrap md:justify-end',\n !hasInlineControls && 'contents md:flex',\n )}\n >\n <SectionHeaderControls\n actions={actions}\n buttonGroup={buttonGroup}\n search={search}\n />\n {menuButton ? (\n <div className=\"absolute end-0 top-0 md:static\">\n <SectionHeaderTouchTargetControl control={menuButton} />\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n\n {tabs?.length ? <SectionHeaderTabs tabs={tabs} /> : null}\n\n {showDivider ? <Separator aria-hidden=\"true\" /> : null}\n </header>\n );\n },\n);\n\nSectionHeader.displayName = 'SectionHeader';\n\nexport { SectionHeader };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index203.js","names":[],"sources":["../src/components/organisms/layout/PageHeader/PageHeader.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { ArrowLeft, MoreHorizontal, Search } from 'lucide-react';\nimport * as React from 'react';\nimport { Button, type ButtonProps } from '@/components/atoms/buttons/Button';\nimport { Separator } from '@/components/atoms/layout/Separator';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { Kbd } from '@/components/molecules/data/Kbd';\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbHomeLink,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/components/molecules/navigation/Breadcrumb';\nimport {\n DropdownMenu,\n type DropdownMenuItemProps,\n} from '@/components/organisms/menus/DropdownMenu';\nimport { cn } from '@/lib/utils';\n\n/* -----------------------------------------------------------------------------\n * Types\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbItemType {\n /** Display label for the breadcrumb */\n label: string;\n /** URL for the breadcrumb link */\n href?: string;\n /** Whether this is the current/active page */\n isCurrent?: boolean;\n}\n\nexport type PageHeaderActionButtonProps = Omit<\n ButtonProps,\n 'variant' | 'onClick' | 'children'\n>;\n\nexport type PageHeaderOverflowActionProps = Pick<\n DropdownMenuItemProps,\n | 'aria-describedby'\n | 'aria-label'\n | 'className'\n | 'disabled'\n | 'icon'\n | 'id'\n | 'title'\n> &\n Partial<Record<`data-${string}`, unknown>>;\n\nexport interface PageHeaderAction {\n /** Button label */\n label: string;\n /** Button variant */\n variant?: ButtonProps['variant'];\n /** Click handler */\n onClick?: () => void;\n /**\n * Additional props applied only when the action renders as a visible Button.\n * Use overflowProps for actions that move into the More actions menu.\n */\n buttonProps?: PageHeaderActionButtonProps;\n /**\n * Additional props applied only when the action renders as an overflow menu item.\n * Menu icons are intentionally explicit so button endIcon values do not become\n * misleading leading menu icons.\n */\n overflowProps?: PageHeaderOverflowActionProps;\n}\n\n/* -----------------------------------------------------------------------------\n * Variants\n * -------------------------------------------------------------------------- */\n\nconst pageHeaderVariants = cva('flex flex-col w-full', {\n variants: {\n variant: {\n simple: 'gap-5',\n avatar: 'gap-5',\n 'banner-avatar': 'gap-0',\n 'banner-simple': 'gap-0',\n 'banner-avatar-centered': 'gap-0',\n 'banner-simple-centered': 'gap-0',\n },\n },\n defaultVariants: {\n variant: 'simple',\n },\n});\n\nconst contentVariants = cva('flex flex-wrap items-start w-full', {\n variants: {\n variant: {\n simple: 'gap-4',\n avatar: 'gap-4 md:gap-5',\n 'banner-avatar': 'gap-4 md:gap-6',\n 'banner-simple': 'gap-4 md:gap-6',\n 'banner-avatar-centered':\n 'flex-col items-center text-center gap-4 md:gap-6',\n 'banner-simple-centered':\n 'flex-col items-center text-center gap-4 md:gap-6',\n },\n },\n defaultVariants: {\n variant: 'simple',\n },\n});\n\nconst bannerVariants = cva(\n 'relative w-full overflow-hidden bg-gradient-to-br from-secondary to-muted',\n {\n variants: {\n variant: {\n default: 'h-40 md:h-60', // 160px mobile, 240px desktop\n centered: 'h-40 md:h-60',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst MAX_VISIBLE_HEADER_ACTIONS = 2;\n\ntype IndexedPageHeaderAction = PageHeaderAction & {\n originalIndex: number;\n};\n\nfunction getPageHeaderActionVariant(\n action: PageHeaderAction,\n index: number,\n actionCount: number,\n): ButtonProps['variant'] {\n return (\n action.variant ?? (index === actionCount - 1 ? 'primary' : 'secondary')\n );\n}\n\nfunction isPriorityHeaderAction(\n action: IndexedPageHeaderAction,\n actionCount: number,\n): boolean {\n return (\n getPageHeaderActionVariant(action, action.originalIndex, actionCount) ===\n 'primary'\n );\n}\n\nfunction splitPageHeaderActions(actions: PageHeaderAction[]): {\n visibleActions: IndexedPageHeaderAction[];\n overflowActions: IndexedPageHeaderAction[];\n} {\n const indexedActions = actions.map((action, originalIndex) => ({\n ...action,\n originalIndex,\n }));\n\n if (indexedActions.length <= MAX_VISIBLE_HEADER_ACTIONS) {\n return {\n visibleActions: indexedActions,\n overflowActions: [],\n };\n }\n\n const defaultVisibleActions = indexedActions.slice(\n 0,\n MAX_VISIBLE_HEADER_ACTIONS,\n );\n\n if (\n defaultVisibleActions.some((action) =>\n isPriorityHeaderAction(action, indexedActions.length),\n )\n ) {\n return {\n visibleActions: defaultVisibleActions,\n overflowActions: indexedActions.slice(MAX_VISIBLE_HEADER_ACTIONS),\n };\n }\n\n const priorityAction = [...indexedActions]\n .reverse()\n .find((action) => isPriorityHeaderAction(action, indexedActions.length));\n\n if (!priorityAction) {\n return {\n visibleActions: defaultVisibleActions,\n overflowActions: indexedActions.slice(MAX_VISIBLE_HEADER_ACTIONS),\n };\n }\n\n const visibleActions = [indexedActions[0], priorityAction].sort(\n (left, right) => left.originalIndex - right.originalIndex,\n );\n const visibleIndexes = new Set(\n visibleActions.map((action) => action.originalIndex),\n );\n\n return {\n visibleActions,\n overflowActions: indexedActions.filter(\n (action) => !visibleIndexes.has(action.originalIndex),\n ),\n };\n}\n\nfunction getOverflowActionItemProps(\n action: PageHeaderAction,\n): Partial<PageHeaderOverflowActionProps> {\n const disabled = Boolean(\n action.overflowProps?.disabled ||\n action.buttonProps?.disabled ||\n action.buttonProps?.loading,\n );\n\n return {\n ...action.overflowProps,\n disabled,\n };\n}\n\n/* -----------------------------------------------------------------------------\n * PageHeader Component\n * -------------------------------------------------------------------------- */\n\nexport interface PageHeaderProps\n extends VariantProps<typeof pageHeaderVariants> {\n /** Page title */\n title: string;\n /** Supporting text/description */\n supportingText?: string;\n /** Breadcrumb items for desktop navigation */\n breadcrumbs?: BreadcrumbItemType[];\n /** Action buttons */\n actions?: PageHeaderAction[];\n /** Search placeholder text - enables search input when provided */\n searchPlaceholder?: string;\n /** Keyboard shortcut to display in search input */\n searchShortcut?: string;\n /** Search callback */\n onSearch?: (value: string) => void;\n /** Show bottom divider */\n showDivider?: boolean;\n /** Avatar props for avatar variants */\n avatarSrc?: string;\n /** Avatar fallback text (e.g., name for initials) */\n avatarFallback?: string;\n /** Avatar indicator */\n avatarStatusIcon?: AvatarProps['indicator'];\n /** Back button click handler (mobile) */\n onBackClick?: () => void;\n /** Back button label (mobile) */\n backLabel?: string;\n /** Additional className */\n className?: string;\n}\n\nfunction PageHeaderBreadcrumbs({\n breadcrumbs,\n}: {\n breadcrumbs: PageHeaderProps['breadcrumbs'];\n}) {\n if (!breadcrumbs || breadcrumbs.length === 0) return null;\n\n return (\n <Breadcrumb className=\"hidden md:flex delight-fade-in motion-reduce:!animate-none\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbHomeLink href=\"/\" />\n </BreadcrumbItem>\n {breadcrumbs.map((item, index) => {\n const isLast = index === breadcrumbs.length - 1;\n const hasEllipsis = breadcrumbs.length > 3;\n\n if (hasEllipsis && index === 1) {\n return (\n <React.Fragment key={`ellipsis-${index}`}>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbEllipsis />\n </BreadcrumbItem>\n </React.Fragment>\n );\n }\n\n if (hasEllipsis && index > 1 && !isLast) {\n return null;\n }\n\n return (\n <React.Fragment key={item.label}>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n {isLast || item.isCurrent ? (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n ) : (\n <BreadcrumbLink href={item.href}>{item.label}</BreadcrumbLink>\n )}\n </BreadcrumbItem>\n </React.Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n\nfunction PageHeaderBackButton({\n breadcrumbs,\n onBackClick,\n backLabel,\n}: {\n breadcrumbs: PageHeaderProps['breadcrumbs'];\n onBackClick?: () => void;\n backLabel: string;\n}) {\n if (!onBackClick || !breadcrumbs || breadcrumbs.length === 0) return null;\n\n return (\n <Button\n appearance=\"link\"\n variant=\"primary\"\n size=\"sm\"\n startIcon={<ArrowLeft className=\"size-5\" />}\n onClick={onBackClick}\n aria-label={`Go back: ${backLabel}`}\n className=\"md:hidden text-secondary-foreground px-0 hover:no-underline\"\n >\n {backLabel}\n </Button>\n );\n}\n\nfunction PageHeaderActions({\n actions,\n}: {\n actions: PageHeaderProps['actions'];\n}) {\n if (!actions || actions.length === 0) return null;\n\n const { visibleActions, overflowActions } = splitPageHeaderActions(actions);\n\n return (\n <div\n className=\"flex items-center gap-3 delight-stagger motion-reduce:!animate-none\"\n style={{ '--delight-delay': '120ms' } as React.CSSProperties}\n >\n {visibleActions.map((action) => (\n <Button\n key={`${action.label}-${action.originalIndex}`}\n variant={\n action.variant ??\n getPageHeaderActionVariant(\n action,\n action.originalIndex,\n actions.length,\n )\n }\n onClick={action.onClick}\n {...action.buttonProps}\n >\n {action.label}\n </Button>\n ))}\n {overflowActions.length > 0 && (\n <DropdownMenu>\n <DropdownMenu.Trigger\n render={\n <Button appearance=\"ghost\" size=\"icon\" aria-label=\"More actions\">\n <MoreHorizontal className=\"size-5\" />\n </Button>\n }\n />\n <DropdownMenu.Popup align=\"end\" sideOffset={4}>\n <DropdownMenu.Items>\n {overflowActions.map((action) => (\n <DropdownMenu.Item\n key={`${action.label}-${action.originalIndex}`}\n {...getOverflowActionItemProps(action)}\n onClick={action.onClick}\n variant={\n action.variant === 'destructive' ? 'destructive' : 'default'\n }\n >\n {action.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Items>\n </DropdownMenu.Popup>\n </DropdownMenu>\n )}\n </div>\n );\n}\n\nfunction PageHeaderSearch({\n searchId,\n searchPlaceholder,\n searchShortcut,\n onSearch,\n}: {\n searchId: string;\n searchPlaceholder?: string;\n searchShortcut?: string;\n onSearch?: (query: string) => void;\n}) {\n if (!searchPlaceholder) return null;\n\n return (\n <search\n className=\"relative flex-1 min-w-0 max-w-xs delight-stagger motion-reduce:!animate-none\"\n style={{ '--delight-delay': '180ms' } as React.CSSProperties}\n >\n <div className=\"group/search relative\">\n <Search\n className=\"absolute start-3 top-1/2 -translate-y-1/2 size-5 text-text-quaternary pointer-events-none transition-colors duration-150 group-focus-within/search:text-primary motion-reduce:transition-none\"\n aria-hidden=\"true\"\n />\n <input\n id={searchId}\n type=\"text\"\n placeholder={searchPlaceholder}\n aria-label={searchPlaceholder}\n onChange={(e) => onSearch?.(e.target.value)}\n className={cn(\n 'peer w-full rounded-lg border border-border bg-background py-2.5 pe-10 ps-10',\n 'text-base text-foreground placeholder:text-muted-foreground',\n 'shadow-xs transition-[border-color,box-shadow] duration-150 motion-reduce:transition-none',\n 'focus-visible:border-primary focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-primary',\n )}\n />\n {searchShortcut && (\n <Kbd\n variant=\"outline\"\n size=\"xs\"\n className=\"absolute end-3 top-1/2 -translate-y-1/2 transition-opacity duration-150 peer-focus-visible:opacity-0 motion-reduce:transition-none\"\n aria-hidden=\"true\"\n >\n {searchShortcut}\n </Kbd>\n )}\n </div>\n </search>\n );\n}\n\nfunction getPageHeaderInitials(name?: string) {\n if (!name) return '';\n const words = name.split(' ').filter(Boolean);\n if (words.length >= 2) {\n return `${words[0][0]}${words[1][0]}`.toUpperCase();\n }\n return name.slice(0, 2).toUpperCase();\n}\n\nfunction PageHeaderAvatar({\n hasAvatar,\n isBanner,\n avatarSrc,\n avatarFallback,\n avatarStatusIcon,\n}: {\n hasAvatar: boolean;\n isBanner: boolean;\n avatarSrc?: string;\n avatarFallback?: string;\n avatarStatusIcon: PageHeaderProps['avatarStatusIcon'];\n}) {\n if (!hasAvatar) return null;\n\n if (isBanner) {\n return (\n <div\n className={cn(\n 'relative shrink-0 rounded-full ring-4 ring-bg-primary shadow-lg',\n 'size-24 md:size-40',\n 'delight-fade-in motion-reduce:!animate-none',\n )}\n >\n {avatarSrc ? (\n <img\n src={avatarSrc}\n alt={avatarFallback || ''}\n className=\"size-full rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex size-full items-center justify-center rounded-full bg-accent text-2xl font-semibold text-muted-foreground md:text-4xl\">\n {getPageHeaderInitials(avatarFallback)}\n </div>\n )}\n {avatarStatusIcon === 'verified' && (\n <div className=\"absolute bottom-0 end-0 flex size-6 items-center justify-center rounded-full border-2 border-primary bg-primary/10 md:size-10\">\n <svg\n className=\"size-3 text-primary md:size-5\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <title>Verified</title>\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <Avatar\n src={avatarSrc}\n fallback={avatarFallback}\n alt={avatarFallback}\n size=\"xl\"\n indicator={avatarStatusIcon}\n />\n );\n}\n\nfunction PageHeaderTextContent({\n title,\n supportingText,\n isCentered,\n}: {\n title: React.ReactNode;\n supportingText?: string;\n isCentered: boolean;\n}) {\n return (\n <div\n className={cn(\n 'flex flex-col min-w-0',\n isCentered ? 'items-center' : 'flex-1',\n )}\n >\n <h1\n className=\"text-xl font-semibold text-foreground leading-relaxed delight-stagger motion-reduce:!animate-none\"\n style={{ '--delight-delay': '0ms' } as React.CSSProperties}\n >\n {title}\n </h1>\n {supportingText && (\n <p\n className=\"text-base text-muted-foreground leading-6 max-w-prose delight-stagger motion-reduce:!animate-none\"\n style={{ '--delight-delay': '60ms' } as React.CSSProperties}\n >\n {supportingText}\n </p>\n )}\n </div>\n );\n}\n\nconst PageHeader = React.forwardRef<HTMLElement, PageHeaderProps>(\n (\n {\n variant = 'simple',\n title,\n supportingText,\n breadcrumbs,\n actions,\n searchPlaceholder,\n searchShortcut = '⌘K',\n onSearch,\n showDivider = true,\n avatarSrc,\n avatarFallback,\n avatarStatusIcon = 'verified',\n onBackClick,\n backLabel = 'Back',\n className,\n },\n ref,\n ) => {\n const searchId = React.useId();\n const resolvedVariant = variant ?? 'simple';\n const isBanner = resolvedVariant.startsWith('banner');\n const isCentered = resolvedVariant.includes('centered');\n const hasAvatar = resolvedVariant.includes('avatar');\n\n // Banner variants\n if (isBanner) {\n return (\n <header\n ref={ref}\n data-slot=\"page-header\"\n className={cn(\n pageHeaderVariants({ variant: resolvedVariant }),\n className,\n )}\n >\n {/* Banner image area with avatar overlap */}\n <div className=\"relative\">\n <div\n className={bannerVariants({\n variant: isCentered ? 'centered' : 'default',\n })}\n aria-hidden=\"true\"\n />\n\n {/* Avatar positioned to overlap banner bottom */}\n {hasAvatar && (\n <div\n className={cn(\n 'absolute inset-x-0 px-4 md:px-8',\n // Position avatar to overlap banner: -48px mobile, -40px desktop from bottom\n '-bottom-12 md:-bottom-20',\n isCentered && 'flex justify-center',\n )}\n >\n <PageHeaderAvatar\n hasAvatar={hasAvatar}\n isBanner={isBanner}\n avatarSrc={avatarSrc}\n avatarFallback={avatarFallback}\n avatarStatusIcon={avatarStatusIcon}\n />\n </div>\n )}\n </div>\n\n {/* Main content below banner */}\n <div\n className={cn(\n 'px-4 md:px-8',\n // Padding top to account for avatar overlap: 64px mobile, 96px desktop\n hasAvatar ? 'pt-16 md:pt-24' : 'pt-6',\n isCentered && 'flex flex-col items-center',\n )}\n >\n {/* Back button for mobile */}\n <div className=\"md:hidden mb-4\">\n <PageHeaderBackButton\n breadcrumbs={breadcrumbs}\n onBackClick={onBackClick}\n backLabel={backLabel}\n />\n </div>\n\n {/* Breadcrumbs for desktop */}\n {!isCentered && (\n <div className=\"hidden md:block\">\n <PageHeaderBreadcrumbs breadcrumbs={breadcrumbs} />\n </div>\n )}\n\n <div\n className={cn(\n contentVariants({ variant: resolvedVariant }),\n 'mt-4 md:mt-6',\n )}\n >\n {/* Text content */}\n <PageHeaderTextContent\n title={title}\n supportingText={supportingText}\n isCentered={isCentered}\n />\n\n {/* Actions */}\n <PageHeaderActions actions={actions} />\n\n {/* Search */}\n <PageHeaderSearch\n searchId={searchId}\n searchPlaceholder={searchPlaceholder}\n searchShortcut={searchShortcut}\n onSearch={onSearch}\n />\n </div>\n </div>\n\n {/* Divider */}\n {showDivider && (\n <Separator className=\"mt-5 delight-connector-fill motion-reduce:!animate-none\" />\n )}\n </header>\n );\n }\n\n // Non-banner variants (simple, avatar)\n return (\n <header\n ref={ref}\n data-slot=\"page-header\"\n className={cn(\n pageHeaderVariants({ variant: resolvedVariant }),\n className,\n )}\n >\n {/* Navigation: Breadcrumbs (desktop) / Back button (mobile) */}\n {breadcrumbs && breadcrumbs.length > 0 && (\n <div>\n <PageHeaderBreadcrumbs breadcrumbs={breadcrumbs} />\n <PageHeaderBackButton\n breadcrumbs={breadcrumbs}\n onBackClick={onBackClick}\n backLabel={backLabel}\n />\n </div>\n )}\n\n {/* Main content */}\n <div className={cn(contentVariants({ variant: resolvedVariant }))}>\n {/* Avatar + Text group */}\n <div\n className={cn(\n 'flex gap-4 items-center flex-1 min-w-0',\n hasAvatar && 'flex-row',\n )}\n >\n <PageHeaderAvatar\n hasAvatar={hasAvatar}\n isBanner={isBanner}\n avatarSrc={avatarSrc}\n avatarFallback={avatarFallback}\n avatarStatusIcon={avatarStatusIcon}\n />\n <PageHeaderTextContent\n title={title}\n supportingText={supportingText}\n isCentered={isCentered}\n />\n </div>\n\n {/* Actions */}\n <PageHeaderActions actions={actions} />\n\n {/* Search */}\n <PageHeaderSearch\n searchId={searchId}\n searchPlaceholder={searchPlaceholder}\n searchShortcut={searchShortcut}\n onSearch={onSearch}\n />\n </div>\n\n {/* Divider */}\n {showDivider && (\n <Separator className=\"delight-connector-fill motion-reduce:!animate-none\" />\n )}\n </header>\n );\n },\n);\n\nPageHeader.displayName = 'PageHeader';\n\nexport { bannerVariants, contentVariants, PageHeader, pageHeaderVariants };\n"],"mappings":"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"}
|
package/dist/index204.js
CHANGED
|
@@ -1,296 +1,165 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "./index2.js";
|
|
3
|
-
import { Button
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
3
|
+
import { Button } from "./index5.js";
|
|
4
|
+
import { ButtonGroup as ButtonGroupCompound } from "./index8.js";
|
|
5
|
+
import { Input } from "./index33.js";
|
|
6
|
+
import { Separator } from "./index51.js";
|
|
7
|
+
import { Tabs } from "./index137.js";
|
|
8
|
+
import { Search } from "lucide-react";
|
|
8
9
|
import * as React from "react";
|
|
9
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
-
//#region src/components/organisms/
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
function getCommandMenuMaxHeight(maxHeight) {
|
|
15
|
-
return Number.isFinite(maxHeight) && maxHeight >= 0 ? maxHeight : DEFAULT_COMMAND_MENU_MAX_HEIGHT;
|
|
11
|
+
//#region src/components/organisms/layout/SectionHeader/SectionHeader.tsx
|
|
12
|
+
var controlTouchTargetClassName = "min-h-11 min-w-11 shrink-0";
|
|
13
|
+
function getHeadingTag(headingLevel) {
|
|
14
|
+
return `h${headingLevel}`;
|
|
16
15
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return shortcut;
|
|
23
|
-
}
|
|
24
|
-
function CommandShortcutBadge({ children, className }) {
|
|
25
|
-
return /* @__PURE__ */ jsx(Kbd, {
|
|
26
|
-
variant: "solid",
|
|
27
|
-
size: "sm",
|
|
28
|
-
className: cn("shadow-xs", className),
|
|
29
|
-
children
|
|
16
|
+
function SectionHeaderTouchTargetControl({ control }) {
|
|
17
|
+
if (React.isValidElement(control)) return React.cloneElement(control, { className: cn(control.props.className, controlTouchTargetClassName) });
|
|
18
|
+
return /* @__PURE__ */ jsx("span", {
|
|
19
|
+
className: cn("inline-flex items-center justify-center", controlTouchTargetClassName),
|
|
20
|
+
children: control
|
|
30
21
|
});
|
|
31
22
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return /* @__PURE__ */ jsx(Kbd, {
|
|
35
|
-
variant: "footer",
|
|
36
|
-
size: "sm",
|
|
37
|
-
className: cn("p-1.5", className),
|
|
38
|
-
children
|
|
39
|
-
});
|
|
23
|
+
function getSectionHeaderActionKey(action, index, prefix = "section-header-action") {
|
|
24
|
+
return typeof action.label === "string" ? `${action.label}-${index}` : `${prefix}-${index}`;
|
|
40
25
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return /* @__PURE__ */ jsx(
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
function SectionHeaderActionButton({ action, className }) {
|
|
27
|
+
const { label, className: actionClassName, ...buttonProps } = action;
|
|
28
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
29
|
+
appearance: "solid",
|
|
30
|
+
size: "default",
|
|
31
|
+
shape: "rounded",
|
|
32
|
+
className: cn("h-10 rounded-xl px-2 text-xs font-medium", actionClassName, className),
|
|
33
|
+
...buttonProps,
|
|
34
|
+
children: label
|
|
46
35
|
});
|
|
47
36
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
className: "text-xs font-semibold text-text-quaternary",
|
|
66
|
-
children: "esc"
|
|
67
|
-
})
|
|
68
|
-
}),
|
|
69
|
-
label: "to close"
|
|
70
|
-
}
|
|
71
|
-
];
|
|
72
|
-
function CommandMenuFooter({ hints = defaultFooterHints, showSettingsButton = false, onSettingsClick, className }) {
|
|
73
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
74
|
-
"data-slot": "command-menu-footer",
|
|
75
|
-
className: cn("flex items-center gap-3 border-t border-border bg-card/80 py-2 pe-2 ps-[18px] supports-backdrop-filter:backdrop-blur", className),
|
|
76
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
77
|
-
className: "hidden flex-1 items-start gap-4 [@media(hover:hover)]:flex",
|
|
78
|
-
children: hints.map((hint) => /* @__PURE__ */ jsxs("div", {
|
|
79
|
-
className: "flex items-center gap-2",
|
|
80
|
-
children: [hint.keys, /* @__PURE__ */ jsx(FooterNavText, { children: hint.label })]
|
|
81
|
-
}, hint.label))
|
|
82
|
-
}), showSettingsButton && /* @__PURE__ */ jsx(Button, {
|
|
83
|
-
appearance: "ghost",
|
|
84
|
-
variant: "secondary",
|
|
85
|
-
size: "icon",
|
|
86
|
-
className: "group ms-auto rounded-full bg-muted",
|
|
87
|
-
onClick: onSettingsClick,
|
|
88
|
-
"aria-label": "Settings",
|
|
89
|
-
children: /* @__PURE__ */ jsx(Settings, { className: "size-5 text-muted-foreground transition-transform duration-300 ease-out group-hover:rotate-90 motion-reduce:transition-none" })
|
|
90
|
-
})]
|
|
37
|
+
function SectionHeaderButtonGroup({ actions }) {
|
|
38
|
+
return /* @__PURE__ */ jsx(ButtonGroupCompound, {
|
|
39
|
+
"aria-label": "Section header controls",
|
|
40
|
+
shape: "rounded",
|
|
41
|
+
className: "overflow-hidden rounded-xl",
|
|
42
|
+
children: actions.map((action, index) => {
|
|
43
|
+
const { label, className, ...buttonProps } = action;
|
|
44
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
45
|
+
appearance: buttonProps.appearance ?? "soft",
|
|
46
|
+
variant: buttonProps.variant ?? "primary",
|
|
47
|
+
size: "md",
|
|
48
|
+
shape: "rounded",
|
|
49
|
+
className: cn("border-transparent px-3 text-xs font-medium shadow-none", className),
|
|
50
|
+
...buttonProps,
|
|
51
|
+
children: label
|
|
52
|
+
}, getSectionHeaderActionKey(action, index, "section-header-group-action"));
|
|
53
|
+
})
|
|
91
54
|
});
|
|
92
55
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
children:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
children: option.shortcut
|
|
56
|
+
function getTabValue(tab, index) {
|
|
57
|
+
if (tab.value !== void 0) return tab.value;
|
|
58
|
+
if (typeof tab.label === "string") return `${tab.label}-${index}`;
|
|
59
|
+
return `section-header-tab-${index}`;
|
|
60
|
+
}
|
|
61
|
+
function SectionHeaderTabs({ tabs }) {
|
|
62
|
+
const tabValues = tabs.map((tab, index) => getTabValue(tab, index));
|
|
63
|
+
const tabListKey = JSON.stringify(tabValues);
|
|
64
|
+
const activeIndex = tabs.findIndex((tab) => tab.active);
|
|
65
|
+
const activeValue = activeIndex >= 0 ? tabValues[activeIndex] : void 0;
|
|
66
|
+
return /* @__PURE__ */ jsx(Tabs, {
|
|
67
|
+
value: activeValue,
|
|
68
|
+
defaultValue: activeValue ?? tabValues[0],
|
|
69
|
+
className: "w-full",
|
|
70
|
+
children: /* @__PURE__ */ jsx(Tabs.List, {
|
|
71
|
+
variant: "boxed",
|
|
72
|
+
size: "sm",
|
|
73
|
+
align: "stretch",
|
|
74
|
+
"aria-label": "Section header tabs",
|
|
75
|
+
className: "w-full overflow-x-auto overflow-y-hidden rounded-[8px] border border-border bg-card p-1 shadow-sm",
|
|
76
|
+
children: tabs.map((tab, index) => {
|
|
77
|
+
const value = tabValues[index];
|
|
78
|
+
return /* @__PURE__ */ jsx(Tabs.Trigger, {
|
|
79
|
+
value,
|
|
80
|
+
icon: tab.leadingIcon,
|
|
81
|
+
className: "min-w-max flex-1 rounded-[10px] px-3 py-1",
|
|
82
|
+
onClick: tab.onClick,
|
|
83
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
84
|
+
className: "whitespace-nowrap",
|
|
85
|
+
children: tab.label
|
|
86
|
+
})
|
|
87
|
+
}, value);
|
|
126
88
|
})
|
|
127
|
-
|
|
128
|
-
});
|
|
89
|
+
})
|
|
90
|
+
}, tabListKey);
|
|
129
91
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
92
|
+
function SectionHeaderControls({ actions, buttonGroup, search }) {
|
|
93
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
94
|
+
search ? /* @__PURE__ */ jsx(SectionHeaderSearchField, { search }) : null,
|
|
95
|
+
buttonGroup?.length ? /* @__PURE__ */ jsx(SectionHeaderButtonGroup, { actions: buttonGroup }) : null,
|
|
96
|
+
actions?.length ? /* @__PURE__ */ jsx("div", {
|
|
97
|
+
className: "flex flex-wrap items-center gap-3 md:flex-nowrap",
|
|
98
|
+
children: actions.map((action, index) => /* @__PURE__ */ jsx(SectionHeaderActionButton, { action }, getSectionHeaderActionKey(action, index)))
|
|
99
|
+
}) : null
|
|
100
|
+
] });
|
|
138
101
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
className: "flex flex-col",
|
|
150
|
-
children: group.options.map(optionRenderer)
|
|
151
|
-
})]
|
|
102
|
+
function SectionHeaderSearchField({ search }) {
|
|
103
|
+
const { className: searchClassName, placeholder, ariaLabel, filterButton, ...searchProps } = search;
|
|
104
|
+
const searchInput = /* @__PURE__ */ jsx(Input, {
|
|
105
|
+
size: "md",
|
|
106
|
+
shape: "rounded",
|
|
107
|
+
"aria-label": ariaLabel ?? "Search",
|
|
108
|
+
placeholder: placeholder ?? "Search",
|
|
109
|
+
startIcon: /* @__PURE__ */ jsx(Search, { className: "size-4" }),
|
|
110
|
+
className: cn(filterButton ? "min-w-0 flex-1" : "w-full max-w-[320px]", searchClassName),
|
|
111
|
+
...searchProps
|
|
152
112
|
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (groups.length > 0) return groups.map((group, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [index > 0 && /* @__PURE__ */ jsx(CommandSeparator, { className: "mx-0" }), /* @__PURE__ */ jsx(CommandMenuGroupSection, {
|
|
158
|
-
group,
|
|
159
|
-
optionRenderer
|
|
160
|
-
})] }, group.id));
|
|
161
|
-
return /* @__PURE__ */ jsx("div", {
|
|
162
|
-
className: "flex flex-col p-2",
|
|
163
|
-
children: options.map(optionRenderer)
|
|
113
|
+
if (filterButton) return /* @__PURE__ */ jsxs("div", {
|
|
114
|
+
"data-slot": "section-header-search",
|
|
115
|
+
className: "flex w-full max-w-[376px] items-center gap-2",
|
|
116
|
+
children: [searchInput, /* @__PURE__ */ jsx(SectionHeaderTouchTargetControl, { control: filterButton })]
|
|
164
117
|
});
|
|
118
|
+
return searchInput;
|
|
165
119
|
}
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
"data-slot": "
|
|
120
|
+
var SectionHeader = React.forwardRef(({ title, supportingText, size = "md", headingLevel = 2, actions, buttonGroup, search, tabs, menuButton = null, showDivider = true, className, ...props }, ref) => {
|
|
121
|
+
const hasSearch = Boolean(search);
|
|
122
|
+
const hasButtonGroup = Boolean(buttonGroup?.length);
|
|
123
|
+
const hasActions = Boolean(actions?.length);
|
|
124
|
+
const hasInlineControls = hasSearch || hasButtonGroup || hasActions;
|
|
125
|
+
const hasHeaderControls = hasInlineControls || Boolean(menuButton);
|
|
126
|
+
const HeadingTag = getHeadingTag(headingLevel);
|
|
127
|
+
return /* @__PURE__ */ jsxs("header", {
|
|
128
|
+
ref,
|
|
129
|
+
"data-slot": "section-header",
|
|
130
|
+
className: cn("relative flex w-full flex-col gap-4", className),
|
|
131
|
+
...props,
|
|
176
132
|
children: [
|
|
177
|
-
/* @__PURE__ */
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
...inputProps,
|
|
200
|
-
value,
|
|
201
|
-
placeholder,
|
|
202
|
-
"aria-label": placeholder,
|
|
203
|
-
className: "min-w-0 flex-1 bg-transparent text-sm leading-5 text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
204
|
-
}),
|
|
205
|
-
showShortcut && /* @__PURE__ */ jsx(CommandShortcutBadge, { children: shortcutText }),
|
|
206
|
-
/* @__PURE__ */ jsx(ClearButton, {
|
|
207
|
-
size: "icon-xs",
|
|
208
|
-
className: "-me-1 rounded-sm p-0 opacity-50 hover:opacity-80 focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4",
|
|
209
|
-
disabled: !value && !canClose,
|
|
210
|
-
"aria-label": value ? "Clear search" : canClose ? "Close command menu" : "Clear search",
|
|
211
|
-
onClick: clearOrClose
|
|
212
|
-
})
|
|
213
|
-
]
|
|
214
|
-
});
|
|
215
|
-
} })
|
|
216
|
-
}),
|
|
217
|
-
/* @__PURE__ */ jsxs(CommandList, {
|
|
218
|
-
style: { maxHeight: safeMaxHeight },
|
|
219
|
-
className: "overflow-y-auto p-0",
|
|
220
|
-
children: [/* @__PURE__ */ jsx(CommandEmpty, {
|
|
221
|
-
className: "py-6 text-center text-sm text-muted-foreground animate-in fade-in-0 duration-200 motion-reduce:animate-none",
|
|
222
|
-
children: emptyState || emptyText
|
|
223
|
-
}), /* @__PURE__ */ jsx(CommandMenuBodyContent, {
|
|
224
|
-
groups,
|
|
225
|
-
options,
|
|
226
|
-
optionRenderer: renderOption,
|
|
227
|
-
children
|
|
228
|
-
})]
|
|
133
|
+
/* @__PURE__ */ jsxs("div", {
|
|
134
|
+
className: "grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-x-4 gap-y-3",
|
|
135
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
136
|
+
className: cn("col-start-1 row-start-1 flex min-w-0 flex-col justify-center gap-0.5", menuButton ? "pe-8 md:pe-0" : null),
|
|
137
|
+
children: [/* @__PURE__ */ jsx(HeadingTag, {
|
|
138
|
+
className: cn("line-clamp-2 w-full break-words font-semibold text-foreground", size === "sm" ? "text-[14px] leading-5" : "text-[18px] leading-7"),
|
|
139
|
+
children: title
|
|
140
|
+
}), supportingText ? /* @__PURE__ */ jsx("p", {
|
|
141
|
+
className: "line-clamp-2 w-full break-words text-sm leading-5 text-secondary-foreground",
|
|
142
|
+
children: supportingText
|
|
143
|
+
}) : null]
|
|
144
|
+
}), hasHeaderControls ? /* @__PURE__ */ jsxs("div", {
|
|
145
|
+
className: cn("col-span-2 row-start-2 flex flex-wrap items-center gap-3 md:col-span-1 md:col-start-2 md:row-start-1 md:flex-nowrap md:justify-end", !hasInlineControls && "contents md:flex"),
|
|
146
|
+
children: [/* @__PURE__ */ jsx(SectionHeaderControls, {
|
|
147
|
+
actions,
|
|
148
|
+
buttonGroup,
|
|
149
|
+
search
|
|
150
|
+
}), menuButton ? /* @__PURE__ */ jsx("div", {
|
|
151
|
+
className: "absolute end-0 top-0 md:static",
|
|
152
|
+
children: /* @__PURE__ */ jsx(SectionHeaderTouchTargetControl, { control: menuButton })
|
|
153
|
+
}) : null]
|
|
154
|
+
}) : null]
|
|
229
155
|
}),
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
showSettingsButton,
|
|
233
|
-
onSettingsClick
|
|
234
|
-
})
|
|
156
|
+
tabs?.length ? /* @__PURE__ */ jsx(SectionHeaderTabs, { tabs }) : null,
|
|
157
|
+
showDivider ? /* @__PURE__ */ jsx(Separator, { "aria-hidden": "true" }) : null
|
|
235
158
|
]
|
|
236
159
|
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function CommandMenu({ open, onOpenChange, placeholder = DEFAULT_COMMAND_MENU_PLACEHOLDER, emptyText = "No results found.", emptyState, options = [], groups = [], onSelect, showShortcut = false, shortcutText, showFooter = false, footerHints, showSettingsButton = false, onSettingsClick, className, maxHeight = DEFAULT_COMMAND_MENU_MAX_HEIGHT, filter, children }) {
|
|
240
|
-
const platformShortcut = usePlatformShortcut();
|
|
241
|
-
const resolvedShortcut = shortcutText ?? platformShortcut;
|
|
242
|
-
return /* @__PURE__ */ jsx(CommandDialog, {
|
|
243
|
-
open,
|
|
244
|
-
onOpenChange,
|
|
245
|
-
className: cn("max-w-[508px] sm:max-w-[508px]", className),
|
|
246
|
-
children: /* @__PURE__ */ jsx(CommandMenuBody, {
|
|
247
|
-
placeholder,
|
|
248
|
-
emptyText,
|
|
249
|
-
emptyState,
|
|
250
|
-
options,
|
|
251
|
-
groups,
|
|
252
|
-
onSelect,
|
|
253
|
-
onClose: () => onOpenChange?.(false),
|
|
254
|
-
showShortcut,
|
|
255
|
-
shortcutText: resolvedShortcut,
|
|
256
|
-
showFooter,
|
|
257
|
-
footerHints,
|
|
258
|
-
showSettingsButton,
|
|
259
|
-
onSettingsClick,
|
|
260
|
-
maxHeight,
|
|
261
|
-
filter,
|
|
262
|
-
children
|
|
263
|
-
})
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
CommandMenu.displayName = "CommandMenu";
|
|
267
|
-
function CommandMenuPanel({ placeholder = DEFAULT_COMMAND_MENU_PLACEHOLDER, emptyText = "No results found.", emptyState, options = [], groups = [], onSelect, showShortcut = false, shortcutText, showFooter = false, footerHints, showSettingsButton = false, onSettingsClick, className, maxHeight = DEFAULT_COMMAND_MENU_MAX_HEIGHT, filter, children }) {
|
|
268
|
-
const platformShortcut = usePlatformShortcut();
|
|
269
|
-
const resolvedShortcut = shortcutText ?? platformShortcut;
|
|
270
|
-
return /* @__PURE__ */ jsx("div", {
|
|
271
|
-
"data-slot": "command-menu-panel",
|
|
272
|
-
className: cn(COMMAND_MENU_SHELL_CLASS_NAME, className),
|
|
273
|
-
children: /* @__PURE__ */ jsx(CommandMenuBody, {
|
|
274
|
-
placeholder,
|
|
275
|
-
emptyText,
|
|
276
|
-
emptyState,
|
|
277
|
-
options,
|
|
278
|
-
groups,
|
|
279
|
-
onSelect,
|
|
280
|
-
showShortcut,
|
|
281
|
-
shortcutText: resolvedShortcut,
|
|
282
|
-
showFooter,
|
|
283
|
-
footerHints,
|
|
284
|
-
showSettingsButton,
|
|
285
|
-
onSettingsClick,
|
|
286
|
-
maxHeight,
|
|
287
|
-
filter,
|
|
288
|
-
children
|
|
289
|
-
})
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
CommandMenuPanel.displayName = "CommandMenu.Panel";
|
|
160
|
+
});
|
|
161
|
+
SectionHeader.displayName = "SectionHeader";
|
|
293
162
|
//#endregion
|
|
294
|
-
export {
|
|
163
|
+
export { SectionHeader };
|
|
295
164
|
|
|
296
165
|
//# sourceMappingURL=index204.js.map
|