@humain/ui 2.1.63 → 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 +7 -339
- 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 +79 -78
- 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 +58 -57
- 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/index195.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index195.js","names":[],"sources":["../src/components/organisms/content/History/History.tsx"],"sourcesContent":["import {\n ArrowDown,\n ArrowUp,\n ChevronsUp,\n Filter,\n type LucideIcon,\n Maximize2,\n MessageSquare,\n Minus,\n Paperclip,\n Pencil,\n Plus,\n Tag,\n Trash2,\n UserRound,\n X,\n} from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { Badge } from '@/components/atoms/display/Badge';\nimport { Avatar } from '@/components/molecules/data/Avatar';\nimport { FileTypeIcon } from '@/components/molecules/files/FileTypeIcon';\nimport { assertNever, cn } from '@/lib/utils';\n\n/* -------------------------------------------------------------------------------------------------\n * History Types\n * -------------------------------------------------------------------------------------------------*/\n\nexport type HistoryEventType =\n | 'create'\n | 'update-fields'\n | 'reassign'\n | 'tags'\n | 'attachment'\n | 'comment'\n | 'delete-comment'\n | 'delete-record';\n\nexport type HistoryActorKind = 'person' | 'external' | 'bot';\nexport type HistoryTone =\n | 'primary'\n | 'success'\n | 'info'\n | 'warning'\n | 'destructive'\n | 'muted';\nexport type HistoryPriority = 'low' | 'medium' | 'important' | 'urgent';\nexport type HistoryValueState = 'current' | 'previous' | 'added' | 'removed';\nexport type HistoryHeaderActionId = 'filter' | 'expand' | 'close';\n\nexport interface HistoryActor {\n id: string;\n name: string;\n avatarSrc?: string;\n fallback?: string;\n kind?: HistoryActorKind;\n}\n\nexport interface HistoryPersonValue {\n id: string;\n name: string;\n avatarSrc?: string;\n fallback?: string;\n}\n\nexport type HistoryValueToken =\n | {\n type: 'status';\n label: string;\n tone?: Exclude<HistoryTone, 'primary'>;\n }\n | {\n type: 'priority';\n label: string;\n priority?: HistoryPriority;\n }\n | {\n type: 'person';\n person: HistoryPersonValue;\n }\n | {\n type: 'date';\n value: string;\n }\n | {\n type: 'number';\n value: number | string;\n unit?: string;\n }\n | {\n type: 'tag';\n label: string;\n tone?: HistoryTone;\n }\n | {\n type: 'boolean';\n value: boolean;\n trueLabel?: string;\n falseLabel?: string;\n }\n | {\n type: 'file';\n name: string;\n extension?: string;\n }\n | {\n type: 'text';\n value: string;\n }\n | {\n type: 'empty';\n label?: string;\n };\n\nexport interface HistoryFieldChange {\n id: string;\n label: string;\n from?: HistoryValueToken;\n to?: HistoryValueToken;\n added?: HistoryValueToken[];\n removed?: HistoryValueToken[];\n}\n\ninterface HistoryEventBase {\n id: string;\n actor: HistoryActor;\n timestamp: string;\n dateTime?: string;\n actorFlags?: string[];\n defaultExpanded?: boolean;\n}\n\nexport interface HistoryCreateEvent extends HistoryEventBase {\n type: 'create';\n actionLabel?: string;\n target: string;\n}\n\nexport interface HistoryDeleteRecordEvent extends HistoryEventBase {\n type: 'delete-record';\n actionLabel?: string;\n target: string;\n}\n\nexport interface HistoryUpdateFieldsEvent extends HistoryEventBase {\n type: 'update-fields';\n summaryLabel?: string;\n changes: HistoryFieldChange[];\n}\n\nexport interface HistoryReassignEvent extends HistoryEventBase {\n type: 'reassign';\n fieldLabel?: string;\n from?: HistoryPersonValue[];\n to: HistoryPersonValue[];\n}\n\nexport interface HistoryTagsEvent extends HistoryEventBase {\n type: 'tags';\n fieldLabel?: string;\n added?: HistoryValueToken[];\n removed?: HistoryValueToken[];\n}\n\nexport interface HistoryAttachmentEvent extends HistoryEventBase {\n type: 'attachment';\n fieldLabel?: string;\n added?: HistoryValueToken[];\n removed?: HistoryValueToken[];\n}\n\nexport interface HistoryCommentEvent extends HistoryEventBase {\n type: 'comment';\n comment: string;\n}\n\nexport interface HistoryDeleteCommentEvent extends HistoryEventBase {\n type: 'delete-comment';\n commentAuthor: HistoryPersonValue;\n originalText?: string;\n actionLabel?: string;\n}\n\nexport type HistoryEvent =\n | HistoryCreateEvent\n | HistoryUpdateFieldsEvent\n | HistoryReassignEvent\n | HistoryTagsEvent\n | HistoryAttachmentEvent\n | HistoryCommentEvent\n | HistoryDeleteCommentEvent\n | HistoryDeleteRecordEvent;\n\nexport interface HistoryGroup {\n id: string;\n label: string;\n events: HistoryEvent[];\n}\n\nexport interface HistoryHeaderAction {\n id: HistoryHeaderActionId;\n label?: string;\n onClick?: () => void;\n disabled?: boolean;\n}\n\nexport interface HistoryProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n title?: string;\n groups: HistoryGroup[];\n actions?: HistoryHeaderAction[];\n loading?: boolean;\n ariaLabel?: string;\n emptyMessage?: string;\n collapsibleChangeThreshold?: number;\n autoExpandNewestLargeEdit?: boolean;\n expandedEventIds?: string[];\n defaultExpandedEventIds?: string[];\n onExpandedEventIdsChange?: (ids: string[]) => void;\n}\n\ninterface HistoryEventCategoryConfig {\n label: string;\n Icon: LucideIcon;\n badgeClassName: string;\n actionClassName: string;\n}\n\nconst historyEventCategoryConfig = {\n create: {\n label: 'Create',\n Icon: Plus,\n badgeClassName: 'bg-success/10 text-success ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n 'update-fields': {\n label: 'Update fields',\n Icon: Pencil,\n badgeClassName: 'bg-info/10 text-info ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n reassign: {\n label: 'Reassign people',\n Icon: UserRound,\n badgeClassName: 'bg-primary/10 text-primary ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n tags: {\n label: 'Tags',\n Icon: Tag,\n badgeClassName: 'bg-info/10 text-info ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n attachment: {\n label: 'Attachment',\n Icon: Paperclip,\n badgeClassName: 'bg-info/10 text-info ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n comment: {\n label: 'Comment',\n Icon: MessageSquare,\n badgeClassName: 'bg-warning/10 text-warning ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n 'delete-comment': {\n label: 'Delete comment',\n Icon: Trash2,\n badgeClassName:\n 'bg-destructive/10 text-destructive ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n 'delete-record': {\n label: 'Delete record',\n Icon: Trash2,\n badgeClassName:\n 'bg-destructive/10 text-destructive ring-background dark:ring-card',\n actionClassName: 'text-card-foreground',\n },\n} satisfies Record<HistoryEventType, HistoryEventCategoryConfig>;\n\nconst historyHeaderActionConfig = {\n filter: { label: 'Filter history', Icon: Filter },\n expand: { label: 'Expand history panel', Icon: Maximize2 },\n close: { label: 'Close history panel', Icon: X },\n} satisfies Record<HistoryHeaderActionId, { label: string; Icon: LucideIcon }>;\n\nconst toneTextClass = {\n primary: 'text-card-foreground',\n success: 'text-card-foreground',\n info: 'text-card-foreground',\n warning: 'text-card-foreground',\n destructive: 'text-card-foreground',\n muted: 'text-card-foreground',\n} satisfies Record<HistoryTone, string>;\n\nconst toneDotClass = {\n primary: 'bg-primary',\n success: 'bg-success',\n info: 'bg-info',\n warning: 'bg-warning',\n destructive: 'bg-destructive',\n muted: 'bg-muted-foreground',\n} satisfies Record<HistoryTone, string>;\n\nconst priorityConfig = {\n low: { Icon: ArrowDown, className: 'text-card-foreground' },\n medium: { Icon: Minus, className: 'text-card-foreground' },\n important: { Icon: ChevronsUp, className: 'text-card-foreground' },\n urgent: { Icon: ArrowUp, className: 'text-card-foreground' },\n} satisfies Record<HistoryPriority, { Icon: LucideIcon; className: string }>;\n\nconst historyDisclosureRevealClassName =\n 'motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-top-1 motion-safe:duration-150';\n\n/* -------------------------------------------------------------------------------------------------\n * Helpers\n * -------------------------------------------------------------------------------------------------*/\n\nfunction getActorFallback(actor: HistoryActor | HistoryPersonValue) {\n return actor.fallback ?? actor.name;\n}\n\nfunction getEventCount(groups: HistoryGroup[]) {\n return groups.reduce((count, group) => count + group.events.length, 0);\n}\n\nfunction getEventPositions(groups: HistoryGroup[]) {\n const positions = new Map<string, number>();\n let position = 1;\n\n for (const group of groups) {\n for (const event of group.events) {\n positions.set(event.id, position);\n position += 1;\n }\n }\n\n return positions;\n}\n\nfunction getCollectionEventValueCount(\n event: HistoryTagsEvent | HistoryAttachmentEvent,\n) {\n return (event.added?.length ?? 0) + (event.removed?.length ?? 0);\n}\n\nfunction getCollapsibleSummary(\n event: HistoryEvent,\n threshold: number,\n): string | null {\n switch (event.type) {\n case 'update-fields':\n return event.changes.length >= threshold\n ? `${event.changes.length} Fields`\n : null;\n case 'tags': {\n const total = getCollectionEventValueCount(event);\n return total >= threshold\n ? getDeltaSummary(event.added, event.removed)\n : null;\n }\n case 'attachment': {\n const total = getCollectionEventValueCount(event);\n return total >= threshold\n ? getDeltaSummary(event.added, event.removed)\n : null;\n }\n case 'delete-comment':\n return event.originalText ? 'deleted comment' : null;\n case 'create':\n case 'reassign':\n case 'comment':\n case 'delete-record':\n return null;\n default:\n return assertNever(event);\n }\n}\n\nfunction isCollapsibleEvent(event: HistoryEvent, threshold: number) {\n return getCollapsibleSummary(event, threshold) !== null;\n}\n\nfunction getDefaultExpandedEventIds(\n groups: HistoryGroup[],\n threshold: number,\n autoExpandNewestLargeEdit: boolean,\n) {\n const ids = new Set<string>();\n let didAutoExpandLargeEdit = false;\n\n for (const group of groups) {\n for (const event of group.events) {\n if (\n event.defaultExpanded === true &&\n isCollapsibleEvent(event, threshold)\n ) {\n ids.add(event.id);\n }\n\n if (\n autoExpandNewestLargeEdit &&\n !didAutoExpandLargeEdit &&\n event.defaultExpanded !== false &&\n event.type === 'update-fields' &&\n event.changes.length >= threshold\n ) {\n ids.add(event.id);\n didAutoExpandLargeEdit = true;\n }\n }\n }\n\n return Array.from(ids);\n}\n\nfunction getDeltaSummary(\n added: HistoryValueToken[] | undefined,\n removed: HistoryValueToken[] | undefined,\n) {\n const parts: string[] = [];\n\n if (added?.length) {\n parts.push(`+${added.length}`);\n }\n\n if (removed?.length) {\n parts.push(`-${removed.length}`);\n }\n\n return parts.join(' ');\n}\n\nfunction useExpandedEventIds({\n groups,\n threshold,\n autoExpandNewestLargeEdit,\n expandedEventIds,\n defaultExpandedEventIds,\n onExpandedEventIdsChange,\n}: {\n groups: HistoryGroup[];\n threshold: number;\n autoExpandNewestLargeEdit: boolean;\n expandedEventIds?: string[];\n defaultExpandedEventIds?: string[];\n onExpandedEventIdsChange?: (ids: string[]) => void;\n}) {\n const computedDefaultIds = React.useMemo(\n () =>\n defaultExpandedEventIds ??\n getDefaultExpandedEventIds(groups, threshold, autoExpandNewestLargeEdit),\n [autoExpandNewestLargeEdit, defaultExpandedEventIds, groups, threshold],\n );\n const [internalIds, setInternalIds] = React.useState(computedDefaultIds);\n const isControlled = expandedEventIds !== undefined;\n const activeIds = isControlled ? expandedEventIds : internalIds;\n\n const setExpanded = React.useCallback(\n (eventId: string, nextExpanded: boolean) => {\n const next = new Set(activeIds);\n\n if (nextExpanded) {\n next.add(eventId);\n } else {\n next.delete(eventId);\n }\n\n const nextIds = Array.from(next);\n\n if (!isControlled) {\n setInternalIds(nextIds);\n }\n\n onExpandedEventIdsChange?.(nextIds);\n },\n [activeIds, isControlled, onExpandedEventIdsChange],\n );\n\n return {\n expandedIdSet: React.useMemo(() => new Set(activeIds), [activeIds]),\n setExpanded,\n };\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Value Tokens\n * -------------------------------------------------------------------------------------------------*/\n\ninterface HistoryValueProps {\n value: HistoryValueToken;\n state?: HistoryValueState;\n className?: string;\n}\n\nfunction HistoryMiniPerson({ person }: { person: HistoryPersonValue }) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n <span\n data-slot=\"history-mini-person-avatar\"\n aria-hidden=\"true\"\n className=\"shrink-0\"\n >\n <Avatar\n src={person.avatarSrc}\n fallback={getActorFallback(person)}\n alt=\"\"\n size=\"xs\"\n shape=\"circle\"\n className=\"size-4\"\n />\n </span>\n <span className=\"truncate\">{person.name}</span>\n </span>\n );\n}\n\nfunction HistoryValue({\n value,\n state = 'current',\n className,\n}: HistoryValueProps) {\n const isPrevious = state === 'previous' || state === 'removed';\n const stateClassName = cn(\n isPrevious &&\n 'text-secondary-foreground line-through decoration-current/60',\n state === 'added' && 'text-card-foreground',\n state === 'removed' && 'text-secondary-foreground',\n );\n\n switch (value.type) {\n case 'status': {\n const tone = value.tone ?? 'info';\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center gap-1 font-medium',\n toneTextClass[tone],\n stateClassName,\n className,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn('size-1.5 rounded-full', toneDotClass[tone])}\n />\n <span className=\"truncate\">{value.label}</span>\n </span>\n );\n }\n\n case 'priority': {\n const priority = value.priority ?? 'medium';\n const { Icon, className: priorityClassName } = priorityConfig[priority];\n\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center gap-1 font-medium',\n priorityClassName,\n stateClassName,\n className,\n )}\n >\n <Icon aria-hidden=\"true\" className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{value.label}</span>\n </span>\n );\n }\n\n case 'person':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center font-medium text-card-foreground',\n stateClassName,\n className,\n )}\n >\n <HistoryMiniPerson person={value.person} />\n </span>\n );\n\n case 'date':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-block min-w-0 truncate font-mono text-card-foreground',\n stateClassName,\n className,\n )}\n >\n {value.value}\n </span>\n );\n\n case 'number':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-baseline gap-1 font-mono text-card-foreground',\n stateClassName,\n className,\n )}\n >\n <span>{value.value}</span>\n {value.unit && (\n <span className=\"text-secondary-foreground\">{value.unit}</span>\n )}\n </span>\n );\n\n case 'tag': {\n const tone = value.tone ?? 'primary';\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center gap-0.5 font-medium',\n toneTextClass[tone],\n stateClassName,\n className,\n )}\n >\n <span aria-hidden=\"true\">#</span>\n <span className=\"truncate\">{value.label}</span>\n </span>\n );\n }\n\n case 'boolean': {\n const label = value.value\n ? (value.trueLabel ?? 'On')\n : (value.falseLabel ?? 'Off');\n const tone: HistoryTone = value.value ? 'success' : 'muted';\n\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center gap-1 font-medium',\n toneTextClass[tone],\n stateClassName,\n className,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn('size-1.5 rounded-full', toneDotClass[tone])}\n />\n <span>{label}</span>\n </span>\n );\n }\n\n case 'file':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-flex min-w-0 items-center gap-1 font-medium text-card-foreground',\n stateClassName,\n className,\n )}\n >\n <span aria-hidden=\"true\" className=\"shrink-0\">\n <FileTypeIcon\n extension={value.extension}\n fileType={value.extension ? undefined : 'document'}\n size=\"xs\"\n />\n </span>\n <span className=\"truncate\">{value.name}</span>\n </span>\n );\n\n case 'text':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-block min-w-0 truncate text-card-foreground',\n stateClassName,\n className,\n )}\n >\n {value.value}\n </span>\n );\n\n case 'empty':\n return (\n <span\n data-slot=\"history-value\"\n className={cn(\n 'inline-block min-w-0 truncate italic text-secondary-foreground',\n className,\n )}\n >\n {value.label ?? 'Empty'}\n </span>\n );\n\n default:\n return assertNever(value);\n }\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Body Renderers\n * -------------------------------------------------------------------------------------------------*/\n\nfunction HistoryFieldChangeRow({ change }: { change: HistoryFieldChange }) {\n const hasDelta =\n (change.added?.length ?? 0) + (change.removed?.length ?? 0) > 0;\n\n return (\n <div\n data-slot=\"history-field-change\"\n className=\"flex min-w-0 items-start gap-2 text-sm leading-5\"\n >\n <span className=\"min-w-[72px] shrink-0 font-semibold text-secondary-foreground\">\n {change.label}\n </span>\n <span className=\"flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1\">\n {hasDelta ? (\n <>\n {change.added?.map((value, index) => (\n <span\n key={`added:${change.id}:${index}`}\n className=\"inline-flex min-w-0 items-center gap-1\"\n >\n <span className=\"font-mono font-semibold text-secondary-foreground\">\n +\n </span>\n <HistoryValue value={value} state=\"added\" />\n </span>\n ))}\n {change.removed?.map((value, index) => (\n <span\n key={`removed:${change.id}:${index}`}\n className=\"inline-flex min-w-0 items-center gap-1\"\n >\n <span className=\"font-mono font-semibold text-secondary-foreground\">\n -\n </span>\n <HistoryValue value={value} state=\"removed\" />\n </span>\n ))}\n </>\n ) : (\n <>\n {change.from && (\n <HistoryValue value={change.from} state=\"previous\" />\n )}\n {change.to && <HistoryValue value={change.to} />}\n </>\n )}\n </span>\n </div>\n );\n}\n\nfunction HistoryCollectionChange({\n label,\n added,\n removed,\n}: {\n label: string;\n added?: HistoryValueToken[];\n removed?: HistoryValueToken[];\n}) {\n const change: HistoryFieldChange = {\n id: label.toLowerCase().replace(/\\s+/g, '-'),\n label,\n added,\n removed,\n };\n\n return <HistoryFieldChangeRow change={change} />;\n}\n\nfunction HistoryCollapsedSummaryButton({\n event,\n expanded,\n summary,\n controlsId,\n onToggle,\n}: {\n event: HistoryEvent;\n expanded: boolean;\n summary: string;\n controlsId: string;\n onToggle: () => void;\n}) {\n const isDeleteComment = event.type === 'delete-comment';\n const buttonLabel = isDeleteComment\n ? expanded\n ? 'Hide'\n : 'View'\n : expanded\n ? 'Show less'\n : 'Show all';\n\n return (\n <button\n type=\"button\"\n data-slot=\"history-collapse-trigger\"\n aria-expanded={expanded}\n aria-controls={controlsId}\n onClick={onToggle}\n className={cn(\n 'group/history-collapse flex min-h-11 w-full min-w-0 items-center gap-2 rounded-lg border border-border px-2.5 py-2 text-left text-sm leading-5 sm:min-h-0 sm:py-1',\n 'transition-[background-color,border-color,box-shadow,transform] duration-150 ease-out motion-reduce:transition-none',\n 'hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-[0.99] motion-reduce:active:scale-100',\n isDeleteComment\n ? 'hover:border-destructive/30'\n : 'hover:border-primary/30',\n isDeleteComment && 'border-dashed py-3',\n )}\n >\n {isDeleteComment ? (\n <Trash2\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 text-destructive motion-safe:transition-transform motion-safe:duration-150 motion-safe:group-hover/history-collapse:scale-105\"\n />\n ) : (\n <ChevronIndicator expanded={expanded} />\n )}\n <span className=\"min-w-0 flex-1 text-secondary-foreground\">\n {isDeleteComment ? summary : event.type === 'tags' ? 'Tags' : 'Updated'}\n </span>\n {!isDeleteComment && (\n <span className=\"min-w-0 flex-1 truncate font-semibold text-foreground\">\n {summary}\n </span>\n )}\n <span className=\"shrink-0 text-xs font-medium text-secondary-foreground motion-safe:transition-transform motion-safe:duration-150 motion-safe:group-hover/history-collapse:translate-x-0.5\">\n {buttonLabel}\n </span>\n </button>\n );\n}\n\nfunction ChevronIndicator({ expanded }: { expanded: boolean }) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 16 16\"\n className={cn(\n 'size-4 shrink-0 text-muted-foreground transition-[color,transform] duration-150 ease-out motion-reduce:transition-none group-hover/history-collapse:text-primary',\n expanded && 'rotate-180',\n )}\n >\n <path\n d=\"M4 6l4 4 4-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n );\n}\n\ninterface HistoryEventBodyProps {\n event: HistoryEvent;\n threshold: number;\n expanded: boolean;\n contentId: string;\n onToggleExpanded: () => void;\n}\n\nfunction HistoryEventBody({\n event,\n threshold,\n expanded,\n contentId,\n onToggleExpanded,\n}: HistoryEventBodyProps) {\n const category = historyEventCategoryConfig[event.type];\n const summary = getCollapsibleSummary(event, threshold);\n\n switch (event.type) {\n case 'create':\n return (\n <p className=\"min-w-0 text-sm font-medium leading-5\">\n <span className={category.actionClassName}>\n {event.actionLabel ?? 'Created the project'}\n </span>{' '}\n <span className=\"text-card-foreground\">\"{event.target}\"</span>\n </p>\n );\n\n case 'delete-record':\n return (\n <p className=\"min-w-0 text-sm font-medium leading-5\">\n <span className={category.actionClassName}>\n {event.actionLabel ?? 'Deleted the record'}\n </span>{' '}\n <span className=\"text-card-foreground\">\"{event.target}\"</span>\n </p>\n );\n\n case 'update-fields':\n if (summary !== null) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <HistoryCollapsedSummaryButton\n event={event}\n expanded={expanded}\n summary={summary}\n controlsId={contentId}\n onToggle={onToggleExpanded}\n />\n <div\n id={contentId}\n hidden={!expanded}\n className={cn(\n 'flex min-w-0 flex-col gap-2 ps-2',\n historyDisclosureRevealClassName,\n )}\n >\n {expanded &&\n event.changes.map((change) => (\n <HistoryFieldChangeRow key={change.id} change={change} />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n {event.changes.map((change) => (\n <HistoryFieldChangeRow key={change.id} change={change} />\n ))}\n </div>\n );\n\n case 'reassign':\n return (\n <HistoryFieldChangeRow\n change={{\n id: `${event.id}:reassign`,\n label: event.fieldLabel ?? 'Assignee',\n removed: event.from?.map((person) => ({ type: 'person', person })),\n added: event.to.map((person) => ({ type: 'person', person })),\n }}\n />\n );\n\n case 'tags':\n if (summary !== null) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <HistoryCollapsedSummaryButton\n event={event}\n expanded={expanded}\n summary={summary}\n controlsId={contentId}\n onToggle={onToggleExpanded}\n />\n <div\n id={contentId}\n hidden={!expanded}\n className={historyDisclosureRevealClassName}\n >\n {expanded && (\n <HistoryCollectionChange\n label={event.fieldLabel ?? 'Tags'}\n added={event.added}\n removed={event.removed}\n />\n )}\n </div>\n </div>\n );\n }\n\n return (\n <HistoryCollectionChange\n label={event.fieldLabel ?? 'Tags'}\n added={event.added}\n removed={event.removed}\n />\n );\n\n case 'attachment':\n if (summary !== null) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <HistoryCollapsedSummaryButton\n event={event}\n expanded={expanded}\n summary={summary}\n controlsId={contentId}\n onToggle={onToggleExpanded}\n />\n <div\n id={contentId}\n hidden={!expanded}\n className={historyDisclosureRevealClassName}\n >\n {expanded && (\n <HistoryCollectionChange\n label={event.fieldLabel ?? 'Attachment'}\n added={event.added}\n removed={event.removed}\n />\n )}\n </div>\n </div>\n );\n }\n\n return (\n <HistoryCollectionChange\n label={event.fieldLabel ?? 'Attachment'}\n added={event.added}\n removed={event.removed}\n />\n );\n\n case 'comment':\n return (\n <blockquote className=\"rounded-xl border border-warning/20 bg-warning/10 px-3 py-2 text-sm leading-5 text-card-foreground\">\n {event.comment}\n </blockquote>\n );\n\n case 'delete-comment': {\n const summaryText =\n event.actionLabel ??\n `Comment by ${event.commentAuthor.name} was deleted`;\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <HistoryCollapsedSummaryButton\n event={event}\n expanded={expanded}\n summary={summaryText}\n controlsId={contentId}\n onToggle={onToggleExpanded}\n />\n <div\n id={contentId}\n hidden={!expanded}\n className={historyDisclosureRevealClassName}\n >\n {expanded && event.originalText && (\n <blockquote className=\"rounded-lg border border-dashed border-border bg-muted/40 px-3 py-2 text-sm leading-5 text-secondary-foreground\">\n {event.originalText}\n </blockquote>\n )}\n </div>\n </div>\n );\n }\n\n default:\n return assertNever(event);\n }\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Structure\n * -------------------------------------------------------------------------------------------------*/\n\nfunction HistoryActorNode({\n actor,\n type,\n showConnector,\n}: {\n actor: HistoryActor;\n type: HistoryEventType;\n showConnector: boolean;\n}) {\n const category = historyEventCategoryConfig[type];\n const Icon = category.Icon;\n\n return (\n <div\n data-slot=\"history-event-node\"\n aria-hidden=\"true\"\n className=\"relative flex w-8 shrink-0 self-stretch justify-center\"\n >\n <Avatar\n src={actor.avatarSrc}\n fallback={getActorFallback(actor)}\n alt=\"\"\n size=\"sm\"\n shape=\"circle\"\n className=\"relative z-10\"\n />\n <span\n aria-hidden=\"true\"\n className={cn(\n 'absolute left-[22px] top-[21px] z-20 flex size-4 items-center justify-center rounded-full ring-1 motion-safe:transition-[box-shadow,transform] motion-safe:duration-150 motion-safe:group-hover/history-event:scale-105 group-hover/history-event:shadow-sm',\n category.badgeClassName,\n )}\n >\n <Icon className=\"size-3\" />\n </span>\n {showConnector && (\n <span\n aria-hidden=\"true\"\n className=\"absolute bottom-[-12px] top-9 w-px rounded-full bg-border\"\n />\n )}\n </div>\n );\n}\n\nfunction HistoryActorFlags({ flags }: { flags?: string[] }) {\n if (!flags?.length) {\n return null;\n }\n\n return (\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n {flags.map((flag) => (\n <Badge key={flag} variant=\"soft\" color=\"purple\" size=\"xs\">\n {flag}\n </Badge>\n ))}\n </span>\n );\n}\n\ninterface HistoryItemProps {\n event: HistoryEvent;\n threshold: number;\n isLastInGroup: boolean;\n position: number;\n total: number;\n expanded: boolean;\n onExpandedChange: (expanded: boolean) => void;\n}\n\nfunction HistoryItem({\n event,\n threshold,\n isLastInGroup,\n position,\n total,\n expanded,\n onExpandedChange,\n}: HistoryItemProps) {\n const category = historyEventCategoryConfig[event.type];\n const headerId = React.useId();\n const contentId = React.useId();\n\n return (\n <article\n data-slot=\"history-event\"\n aria-labelledby={headerId}\n aria-setsize={total}\n aria-posinset={position}\n className=\"group/history-event flex min-w-0 gap-4 rounded-lg py-1 transition-colors duration-150 ease-out motion-reduce:transition-none hover:bg-muted/20\"\n >\n <HistoryActorNode\n actor={event.actor}\n type={event.type}\n showConnector={!isLastInGroup}\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <div\n id={headerId}\n className=\"flex min-w-0 items-center gap-1.5 font-bold text-sm leading-5 text-card-foreground\"\n >\n <span className=\"truncate\">{event.actor.name}</span>\n <HistoryActorFlags flags={event.actorFlags} />\n <span className=\"sr-only\">{category.label}</span>\n </div>\n {event.dateTime ? (\n <time\n dateTime={event.dateTime}\n className=\"ms-auto shrink-0 text-xs leading-4 text-secondary-foreground\"\n >\n {event.timestamp}\n </time>\n ) : (\n <span className=\"ms-auto shrink-0 text-xs leading-4 text-secondary-foreground\">\n {event.timestamp}\n </span>\n )}\n </div>\n <HistoryEventBody\n event={event}\n threshold={threshold}\n expanded={expanded}\n contentId={contentId}\n onToggleExpanded={() => onExpandedChange(!expanded)}\n />\n </div>\n </article>\n );\n}\n\nfunction HistoryGroupSeparator({ label }: { label: string }) {\n return (\n <div\n data-slot=\"history-group-separator\"\n className=\"flex w-full items-center gap-2 text-sm font-medium leading-5 text-secondary-foreground\"\n >\n <span>{label}</span>\n <span aria-hidden=\"true\" className=\"h-px min-w-0 flex-1 bg-border\" />\n </div>\n );\n}\n\nfunction HistoryHeader({\n title,\n actions,\n}: {\n title: string;\n actions?: HistoryHeaderAction[];\n}) {\n return (\n <div\n data-slot=\"history-header\"\n className=\"flex min-w-0 items-start gap-3 pb-2\"\n >\n <h2 className=\"min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground\">\n {title}\n </h2>\n {actions?.length ? (\n <div className=\"flex shrink-0 items-center gap-1\">\n {actions.map((action) => {\n const config = historyHeaderActionConfig[action.id];\n const Icon = config.Icon;\n\n return (\n <Button\n key={action.id}\n type=\"button\"\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"icon-xs\"\n shape=\"rounded\"\n iconOnly\n disabled={action.disabled}\n aria-label={action.label ?? config.label}\n onClick={action.onClick}\n className=\"size-11 text-secondary-foreground hover:text-foreground sm:size-6\"\n >\n <Icon aria-hidden=\"true\" className=\"size-4\" />\n </Button>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * History\n * -------------------------------------------------------------------------------------------------*/\n\nconst History = React.forwardRef<HTMLDivElement, HistoryProps>(\n (\n {\n title = 'History',\n groups,\n actions,\n loading,\n ariaLabel,\n emptyMessage = 'No history events',\n collapsibleChangeThreshold = 5,\n autoExpandNewestLargeEdit = true,\n expandedEventIds,\n defaultExpandedEventIds,\n onExpandedEventIdsChange,\n className,\n ...props\n },\n ref,\n ) => {\n const totalEvents = React.useMemo(() => getEventCount(groups), [groups]);\n const eventPositions = React.useMemo(\n () => getEventPositions(groups),\n [groups],\n );\n const { expandedIdSet, setExpanded } = useExpandedEventIds({\n groups,\n threshold: collapsibleChangeThreshold,\n autoExpandNewestLargeEdit,\n expandedEventIds,\n defaultExpandedEventIds,\n onExpandedEventIdsChange,\n });\n\n return (\n <div\n ref={ref}\n data-slot=\"history\"\n role=\"feed\"\n aria-label={ariaLabel ?? title}\n aria-busy={loading || undefined}\n className={cn(\n 'flex w-full max-w-[400px] min-w-0 flex-col gap-4 overflow-hidden rounded-[var(--borderradius-rounded-box,12px)] border border-border bg-background p-6 shadow-lg',\n className,\n )}\n {...props}\n >\n <HistoryHeader title={title} actions={actions} />\n {loading && totalEvents === 0 ? (\n <p\n role=\"status\"\n aria-live=\"polite\"\n className=\"text-sm leading-5 text-secondary-foreground\"\n >\n Loading history\n </p>\n ) : totalEvents === 0 ? (\n <p className=\"text-sm leading-5 text-secondary-foreground\">\n {emptyMessage}\n </p>\n ) : (\n <div\n data-slot=\"history-groups\"\n className=\"flex min-w-0 flex-col gap-4\"\n >\n {groups.map((group) => (\n <section\n key={group.id}\n data-slot=\"history-group\"\n aria-label={group.label}\n className=\"flex min-w-0 flex-col gap-2\"\n >\n <HistoryGroupSeparator label={group.label} />\n <div className=\"flex min-w-0 flex-col gap-4\">\n {group.events.map((event, index) => (\n <HistoryItem\n key={event.id}\n event={event}\n threshold={collapsibleChangeThreshold}\n isLastInGroup={index === group.events.length - 1}\n position={eventPositions.get(event.id) ?? 1}\n total={totalEvents}\n expanded={expandedIdSet.has(event.id)}\n onExpandedChange={(nextExpanded) =>\n setExpanded(event.id, nextExpanded)\n }\n />\n ))}\n </div>\n </section>\n ))}\n </div>\n )}\n </div>\n );\n },\n);\n\nHistory.displayName = 'History';\n\nexport {\n History,\n HistoryValue,\n historyEventCategoryConfig,\n historyHeaderActionConfig,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index195.js","names":[],"sources":["../src/components/organisms/content/GroupingControls/GroupingControls.tsx"],"sourcesContent":["'use client';\n\nimport type { Column, Table } from '@tanstack/react-table';\nimport { Check, ChevronDown, Plus } from 'lucide-react';\nimport * as React from 'react';\nimport { Tag } from '@/components/molecules/data/Tag';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandList,\n} from '@/components/ui/command';\nimport { Popover, PopoverPopup, PopoverTrigger } from '@/components/ui/popover';\nimport { cn } from '@/lib/utils';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface GroupingControlsProps<TData> {\n /** The TanStack Table instance */\n table: Table<TData>;\n /** List of column IDs that can be grouped. If not provided, uses columns with enableGrouping: true */\n groupableColumns?: string[];\n /** Placeholder text when no grouping is selected */\n placeholder?: string;\n /** Maximum number of grouping levels allowed */\n maxLevels?: number;\n /** Visual variant of the control */\n variant: 'dropdown' | 'chips';\n /** Size variant */\n size?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n}\n\ninterface GroupableColumn {\n id: string;\n label: string;\n}\n\n// ============================================\n// GroupingControls Component\n// ============================================\n\nfunction GroupingControls<TData>({\n table,\n groupableColumns: groupableColumnsProp,\n placeholder = 'Group by...',\n maxLevels,\n variant,\n size = 'md',\n className,\n}: GroupingControlsProps<TData>) {\n const [open, setOpen] = React.useState(false);\n\n // Get current grouping state from table\n const grouping = table.getState().grouping;\n\n // Get all groupable columns from the table\n const allGroupableColumns = React.useMemo((): GroupableColumn[] => {\n const columns = table.getAllColumns();\n\n // Filter to columns that can be grouped\n const groupable = columns.filter((col: Column<TData, unknown>) => {\n // If groupableColumns prop is provided, use that\n if (groupableColumnsProp) {\n return groupableColumnsProp.includes(col.id);\n }\n // Otherwise, use column's enableGrouping setting\n return col.getCanGroup();\n });\n\n return groupable.map((col: Column<TData, unknown>) => ({\n id: col.id,\n label:\n typeof col.columnDef.header === 'string'\n ? col.columnDef.header\n : col.id.charAt(0).toUpperCase() + col.id.slice(1),\n }));\n }, [table, groupableColumnsProp]);\n\n // Check if max levels reached\n const isMaxLevelsReached =\n maxLevels !== undefined && grouping.length >= maxLevels;\n\n // Get display label for selected columns\n const displayLabel = React.useMemo(() => {\n if (grouping.length === 0) return placeholder;\n\n return grouping\n .map((id) => {\n const col = allGroupableColumns.find((c) => c.id === id);\n return col?.label || id;\n })\n .join(', ');\n }, [grouping, allGroupableColumns, placeholder]);\n\n // Handle column selection/deselection\n const handleSelect = React.useCallback(\n (columnId: string) => {\n const currentIndex = grouping.indexOf(columnId);\n\n if (currentIndex >= 0) {\n // Deselect: remove from grouping\n const newGrouping = grouping.filter((id) => id !== columnId);\n table.setGrouping(newGrouping);\n } else {\n // Select: add to grouping (respecting maxLevels)\n if (maxLevels !== undefined && grouping.length >= maxLevels) {\n return; // Don't add if max levels reached\n }\n const newGrouping = [...grouping, columnId];\n table.setGrouping(newGrouping);\n }\n },\n [grouping, table, maxLevels],\n );\n\n // Get selection order for a column (1-indexed)\n const getSelectionOrder = (columnId: string): number | null => {\n const index = grouping.indexOf(columnId);\n return index >= 0 ? index + 1 : null;\n };\n\n // Get available columns (not yet in grouping)\n const availableColumns = React.useMemo(() => {\n return allGroupableColumns.filter((col) => !grouping.includes(col.id));\n }, [allGroupableColumns, grouping]);\n\n // Handle removing a column from grouping\n const handleRemove = React.useCallback(\n (columnId: string) => {\n const newGrouping = grouping.filter((id) => id !== columnId);\n table.setGrouping(newGrouping);\n },\n [grouping, table],\n );\n\n // Handle adding a column via the add button dropdown\n const handleAddColumn = React.useCallback(\n (columnId: string) => {\n if (maxLevels !== undefined && grouping.length >= maxLevels) {\n return;\n }\n const newGrouping = [...grouping, columnId];\n table.setGrouping(newGrouping);\n setOpen(false);\n },\n [grouping, table, maxLevels],\n );\n\n if (variant === 'chips') {\n const showAddButton = availableColumns.length > 0 && !isMaxLevelsReached;\n\n const addColumnPopover = showAddButton ? (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n className={cn(\n 'inline-flex items-center justify-center rounded-md',\n 'border border-dashed border-input bg-background',\n 'hover:bg-accent hover:border-solid',\n 'transition-[background-color,border-color] duration-150 ease-out motion-reduce:transition-none',\n size === 'sm' ? 'h-6 px-2 text-xs' : 'h-7 px-2 text-sm',\n )}\n aria-label=\"Add grouping\"\n >\n <Plus\n className={cn(\n 'size-3.5 transition-transform duration-200 motion-reduce:transition-none',\n open && 'rotate-45',\n )}\n />\n </PopoverTrigger>\n <PopoverPopup\n side=\"bottom\"\n align=\"start\"\n className=\"min-w-[180px] w-max max-w-[280px] p-0\"\n >\n <Command>\n <CommandList>\n <CommandEmpty>No columns available</CommandEmpty>\n <CommandGroup>\n {availableColumns.map((column) => (\n <CommandItem\n key={column.id}\n value={column.id}\n onSelect={() => handleAddColumn(column.id)}\n className=\"cursor-pointer\"\n >\n {column.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverPopup>\n </Popover>\n ) : null;\n\n return (\n <div\n data-slot=\"grouping-controls\"\n role=\"toolbar\"\n aria-label=\"Grouping controls\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n {grouping.length === 0 ? (\n <span className=\"text-sm text-muted-foreground\">{placeholder}</span>\n ) : (\n grouping.map((columnId) => {\n const column = allGroupableColumns.find((c) => c.id === columnId);\n if (!column) return null;\n\n return (\n <Tag\n key={columnId}\n size={size === 'sm' ? 'sm' : 'md'}\n removable\n onRemove={() => handleRemove(columnId)}\n >\n {column.label}\n </Tag>\n );\n })\n )}\n {addColumnPopover}\n </div>\n );\n }\n\n // Dropdown variant\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n data-slot=\"grouping-controls\"\n aria-label=\"Group by column\"\n className={cn(\n 'inline-flex items-center justify-between gap-2 whitespace-nowrap',\n 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n 'rounded-md font-medium',\n 'transition-[color,background-color,border-color,transform] duration-150 ease-out motion-reduce:transition-none',\n 'active:translate-y-px',\n size === 'sm' ? 'h-8 px-3 text-sm' : 'h-9 px-3.5 py-2.5 text-sm',\n className,\n )}\n >\n <span\n className={cn(\n 'truncate',\n grouping.length === 0 && 'text-muted-foreground',\n )}\n >\n {displayLabel}\n </span>\n <ChevronDown\n className={cn(\n 'size-4 shrink-0 opacity-50 transition-transform duration-200 motion-reduce:transition-none',\n open && 'rotate-180',\n )}\n />\n </PopoverTrigger>\n <PopoverPopup\n side=\"bottom\"\n align=\"start\"\n className=\"min-w-[200px] w-max max-w-[300px] p-0\"\n >\n <Command>\n <CommandList>\n <CommandEmpty>No groupable columns</CommandEmpty>\n <CommandGroup>\n {allGroupableColumns.map((column) => {\n const isSelected = grouping.includes(column.id);\n const order = getSelectionOrder(column.id);\n const isDisabled = !isSelected && isMaxLevelsReached;\n\n return (\n <CommandItem\n key={column.id}\n value={column.id}\n onSelect={() => handleSelect(column.id)}\n disabled={isDisabled}\n data-disabled={isDisabled}\n data-slot=\"combobox-item\"\n className={cn(\n 'flex items-center justify-between gap-2 px-2 py-1.5 cursor-pointer',\n isSelected && 'bg-accent',\n )}\n >\n <div className=\"flex items-center gap-2\">\n {isSelected && (\n <Check\n className=\"size-4 text-primary motion-safe:animate-in motion-safe:zoom-in-75 motion-safe:duration-150\"\n aria-hidden=\"true\"\n />\n )}\n <span>{column.label}</span>\n </div>\n {order !== null && (\n <span className=\"inline-flex size-5 items-center justify-center rounded-full bg-primary/10 text-[11px] font-semibold text-primary motion-safe:animate-in motion-safe:zoom-in-75 motion-safe:duration-150\">\n {order}\n </span>\n )}\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverPopup>\n </Popover>\n );\n}\n\nGroupingControls.displayName = 'GroupingControls';\n\nexport type { GroupableColumn };\nexport { GroupingControls };\n"],"mappings":"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"}
|