@tangle-network/ui 11.32.1 → 11.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/lib/control-presentation.js +2 -1
- package/dist/lib/focus.d.ts +5 -1
- package/dist/lib/focus.js +6 -1
- package/dist/lib/interaction.d.ts +41 -0
- package/dist/lib/interaction.js +42 -0
- package/dist/primitives/button.js +19 -18
- package/dist/primitives/card.d.ts +14 -1
- package/dist/primitives/card.js +15 -5
- package/dist/primitives/dropdown-menu.js +7 -6
- package/dist/primitives/segmented-control.d.ts +5 -1
- package/dist/primitives/segmented-control.js +12 -5
- package/dist/primitives/select.js +4 -3
- package/dist/primitives/tabs.js +4 -3
- package/dist/run/run-group.js +3 -2
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +2 -1
- package/package.json +2 -2
- package/src/files/file-artifact-pane.test.tsx +4 -2
- package/src/lib/control-presentation.ts +10 -4
- package/src/lib/focus.ts +7 -1
- package/src/lib/interaction.ts +64 -0
- package/src/primitives/button.tsx +29 -10
- package/src/primitives/card.tsx +23 -6
- package/src/primitives/control-presentation.test.tsx +6 -3
- package/src/primitives/date-picker.test.tsx +1 -1
- package/src/primitives/dropdown-menu.tsx +15 -10
- package/src/primitives/interaction-states.test.tsx +285 -0
- package/src/primitives/segmented-control.test.tsx +4 -2
- package/src/primitives/segmented-control.tsx +13 -14
- package/src/primitives/select.tsx +11 -5
- package/src/primitives/tabs.tsx +7 -3
- package/src/run/run-group.tsx +3 -2
- package/src/utils/index.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.33.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 03c7da0: Surface ladder and one interaction language.
|
|
8
|
+
|
|
9
|
+
Brand: Hospitality gets a stepped ladder (light page 91.6, white cards with a two-layer shadow, raised 95.6; dark page 16.9, card 31.1, raised 37.9 with a top highlight, popover 42.0), field wells that are always the opposite step from their parent, a 3:1 `--field-border`, darker muted text, and status fills retuned for its planes (success, warning, danger, neutral). Dark accent text (#b2dbc2) and the dark destructive red (0 80% 88%) are lifted so they keep 4.5:1 on the lighter raised and popover planes. New tokens `--hsl-raised`, `--hsl-raised-2`, `--well-page`, `--well-card`, `--well-raised`, `--well-raised-2`, `--well`, `--field-border`, `--shadow-raised`, `--shadow-well` and `--edge-highlight` default to the plain spine, so other themes look as before. Shared `--ix-hover`, `--ix-hover-border`, `--ix-press`, `--ix-after`, `--ix-sel-ring`, `--ix-sel-bg` and `--ix-hover-bg` derive from `--hsl-ring`. A `[data-slot="card"]` rule re-declares `--card` and `--well` per card level.
|
|
10
|
+
|
|
11
|
+
UI: new `ixControl`, `ixControlAfter`, `ixControlSoft`, `ixField`, `ixSelected`, `ixTabUnderline` and `ixRow` (exported from `@tangle-network/ui/utils`) give hover, press, after-click and selected states in the focus ring hue; the keyboard focus glow is unchanged. Button, Input, Textarea, `focusFieldWithin`, SelectTrigger/Item/Content, DropdownMenu content and items, Card, SegmentedControl and TabsTrigger apply them. Card renders `data-slot="card"` with `--edge-highlight` + `--shadow-card`, gains `interactive`, and CardDescription clamps at two lines. Select and DropdownMenu content paint the popover level. See docs/surfaces-and-states.md.
|
|
12
|
+
|
|
13
|
+
## 11.32.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 07e7a78: tangle-drift ignores CSS comments when counting header_height_literal and transcript_type_override, and no longer counts a step-progress bar (`.steps-bar`) as a header row. UI's RunGroup sets its Markdown with the shared TRANSCRIPT_TEXT instead of a fixed 15px / leading-7, so a run reads at the transcript scale.
|
|
18
|
+
|
|
3
19
|
## 11.32.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ import { timeAgo } from "./utils/time-ago.js";
|
|
|
120
120
|
import { TOOL_CATEGORY_ICONS, getToolCategory, getToolDisplayMetadata, getToolErrorText } from "./utils/tool-display.js";
|
|
121
121
|
import { cn } from "./lib/utils.js";
|
|
122
122
|
import { focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset } from "./lib/focus.js";
|
|
123
|
+
import { ixControl, ixControlAfter, ixControlSoft, ixField, ixRow, ixSelected, ixTabUnderline } from "./lib/interaction.js";
|
|
123
124
|
import "./utils.js";
|
|
124
125
|
import { CommandPreview, CommandPreviewProps } from "./tool-previews/command-preview.js";
|
|
125
126
|
import { WriteFilePreview, WriteFilePreviewProps } from "./tool-previews/write-file-preview.js";
|
|
@@ -130,4 +131,4 @@ import { QuestionPreview, QuestionPreviewProps } from "./tool-previews/question-
|
|
|
130
131
|
import { DiffPreview, DiffPreviewProps } from "./tool-previews/diff-preview.js";
|
|
131
132
|
import { RedactedDocSegment, RedactedDocument, RedactedDocumentData, RedactedDocumentProps, RevealResult } from "./redaction/redacted-document.js";
|
|
132
133
|
import "./redaction.js";
|
|
133
|
-
export { ActiveProjectActivity, ActiveSessionActivityOptions, ActiveSessionConnectionOptions, ActiveSessionConnectionState, ActiveSessionReconnectState, ActiveSessionRecord, ActiveSessionStatus, ActiveSessionTransportMode, ActiveSessionsState, AgentBranding, AgentStreamEvent, AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, AppendUserMessageOptions, ApplySdkEventOptions, ApprovalCard, type ApprovalCardProps, type ApprovalDiffFile, ApprovalDiffSummary, type ApprovalPlanStep, ArtifactPane, type ArtifactPaneProps, AuthHeader, type AuthHeaderProps, AuthUser, AutomationStreamEvent, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, BeginAssistantMessageOptions, BotStreamEvent, Button, type ButtonProps, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, Calendar, type CalendarDate, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, ChatAuthor, ChatContainer, type ChatContainerProps, ChatMessage, type ChatMessageProps, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, CommandPreview, type CommandPreviewProps, CompleteAssistantMessageOptions, ConnectionState, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CustomToolRenderer, DatePicker, type DatePickerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffPreview, type DiffPreviewProps, DisplayVariant, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, ExpandedToolDetail, type ExpandedToolDetailProps, type FeedSegment, FileArtifactPane, type FileArtifactPaneProps, FileCard, type FileCardProps, type FileDetails, type FileFormat, FileList, type FileListItem, type FileListProps, type FileNode, FilePreview, type FilePreviewKind, type FilePreviewProps, type FileTabData, FileTabs, type FileTabsProps, FileTree, type FileTreeProps, type FileTreeVisibilityOptions, type FileUploader, FilterField, type FilterFieldProps, FinalTextPart, GitHubLoginButton, type GitHubLoginButtonProps, GlobResultsPreview, type GlobResultsPreviewProps, GrepResultsPreview, type GrepResultsPreviewProps, GroupedMessage, Heading, type HeadingProps, type HeadingVariant, HelpText, type HelpTextProps, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, InlineThinkingItem, type InlineThinkingItemProps, InlineToolItem, type InlineToolItemProps, Input, type InputProps, Label, LiveDuration, LoginLayout, type LoginLayoutProps, Logo, type LogoProps, Markdown, type MarkdownLinkChip, type MarkdownLinkChipResolver, type MarkdownProps, MessageAuthor, type MessageAuthorProps, MessageList, type MessageListProps, type MessageRole, MessageRun, MessageUser, Metric, type MetricProps, MetricStrip, type MetricStripProps, OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES, type OpenUIAction, type OpenUIActionsNode, OpenUIArtifactRenderer, type OpenUIArtifactRendererProps, type OpenUIBadgeNode, type OpenUICardNode, type OpenUICodeNode, type OpenUIComponentNode, type OpenUIGridNode, type OpenUIHeadingNode, type OpenUIKeyValueNode, type OpenUIMarkdownNode, type OpenUIPrimitive, type OpenUISchemaIssue, type OpenUISchemaValidation, type OpenUISeparatorNode, type OpenUIStackNode, type OpenUIStatNode, type OpenUITableNode, type OpenUITextNode, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, PdfViewer, type PdfViewerConfig, type PdfViewerProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QuestionPreview, type QuestionPreviewProps, RadioGroup, RadioGroupItem, RealtimeSessionOptions, RealtimeSessionRegistry, RealtimeSessionRegistryProps, RealtimeSessionState, RealtimeSessionTarget, ReasoningPart, type RedactedDocSegment, RedactedDocument, type RedactedDocumentData, type RedactedDocumentProps, RegisterActiveSessionOptions, type RevealResult, RichFileTree, type RichFileTreeGitEntry, type RichFileTreeGitStatus, type RichFileTreeProps, type RichFileTreeThemeVars, Run, RunGroup, type RunGroupProps, type RunPhase, RunPhaseList, RunRowShell, type RunRowShellProps, type RunRowStatus, RunRowStatusDot, RunStats, SSEEvent, SdkSessionAttachment, SdkSessionEvent, SdkSessionSeed, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SessionMessage, SessionPart, SessionProjectKey, type SessionUser, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, type SidebarDropZoneProps, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, type StatCardProps, StatusPill, type StatusPillProps, type StatusTone, Switch, TONE_CLASSES, TOOL_CATEGORY_ICONS, TRANSCRIPT_TEXT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TaskList, type TaskListItem, type TaskListProps, type TaskStatus, TaskStreamEvent, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TerminalStreamEvent, TextPart, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, ThinkingIndicator, type ThinkingIndicatorProps, TimeSelect, type TimeSelectProps, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, type ToolCallData, ToolCallFeed, type ToolCallFeedProps, type ToolCallStatus, type ToolCallType, ToolCategory, ToolDisplayMetadata, ToolPart, ToolState, ToolStatus, ToolTime, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, UseAuthOptions, UseAuthResult, UseRunGroupsOptions, UseSSEStreamOptions, UseSSEStreamResult, UseSdkSessionOptions, UseSdkSessionReturn, UseToolCallStreamReturn, UserMenu, type UserMenuProps, UserMessage, type UserMessageProps, WebSearchPreview, type WebSearchPreviewProps, WriteFilePreview, type WriteFilePreviewProps, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, codeBlockGrammar, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fenceInfo, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatCalendarDate, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, localToday, messagesAtom, numericColumns, parseCalendarDate, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, showsTaskPriority, tableCsv, taskProgress, taskStatus, timeAgo, toneFor, truncateText, unregisterActiveSession, updateActiveSessionMeta, updatePart, useActiveSession, useActiveSessions, useActiveSessionsState, useApiKey, useAuth, useAutoScroll, useDropdownMenu, useHasBackgroundRunningSessions, useLiveTime, useNavbarSessions, useProjectActivity, useProjectSessions, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useSessionsByActivity, useTheme, useToast, useToolCallStream, useTotalRunningSessions, validateOpenUIJsonArtifact, validateOpenUIJsonNode };
|
|
134
|
+
export { ActiveProjectActivity, ActiveSessionActivityOptions, ActiveSessionConnectionOptions, ActiveSessionConnectionState, ActiveSessionReconnectState, ActiveSessionRecord, ActiveSessionStatus, ActiveSessionTransportMode, ActiveSessionsState, AgentBranding, AgentStreamEvent, AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, AppendUserMessageOptions, ApplySdkEventOptions, ApprovalCard, type ApprovalCardProps, type ApprovalDiffFile, ApprovalDiffSummary, type ApprovalPlanStep, ArtifactPane, type ArtifactPaneProps, AuthHeader, type AuthHeaderProps, AuthUser, AutomationStreamEvent, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, BeginAssistantMessageOptions, BotStreamEvent, Button, type ButtonProps, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, Calendar, type CalendarDate, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, ChatAuthor, ChatContainer, type ChatContainerProps, ChatMessage, type ChatMessageProps, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, CommandPreview, type CommandPreviewProps, CompleteAssistantMessageOptions, ConnectionState, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CustomToolRenderer, DatePicker, type DatePickerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffPreview, type DiffPreviewProps, DisplayVariant, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, ExpandedToolDetail, type ExpandedToolDetailProps, type FeedSegment, FileArtifactPane, type FileArtifactPaneProps, FileCard, type FileCardProps, type FileDetails, type FileFormat, FileList, type FileListItem, type FileListProps, type FileNode, FilePreview, type FilePreviewKind, type FilePreviewProps, type FileTabData, FileTabs, type FileTabsProps, FileTree, type FileTreeProps, type FileTreeVisibilityOptions, type FileUploader, FilterField, type FilterFieldProps, FinalTextPart, GitHubLoginButton, type GitHubLoginButtonProps, GlobResultsPreview, type GlobResultsPreviewProps, GrepResultsPreview, type GrepResultsPreviewProps, GroupedMessage, Heading, type HeadingProps, type HeadingVariant, HelpText, type HelpTextProps, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, InlineThinkingItem, type InlineThinkingItemProps, InlineToolItem, type InlineToolItemProps, Input, type InputProps, Label, LiveDuration, LoginLayout, type LoginLayoutProps, Logo, type LogoProps, Markdown, type MarkdownLinkChip, type MarkdownLinkChipResolver, type MarkdownProps, MessageAuthor, type MessageAuthorProps, MessageList, type MessageListProps, type MessageRole, MessageRun, MessageUser, Metric, type MetricProps, MetricStrip, type MetricStripProps, OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES, type OpenUIAction, type OpenUIActionsNode, OpenUIArtifactRenderer, type OpenUIArtifactRendererProps, type OpenUIBadgeNode, type OpenUICardNode, type OpenUICodeNode, type OpenUIComponentNode, type OpenUIGridNode, type OpenUIHeadingNode, type OpenUIKeyValueNode, type OpenUIMarkdownNode, type OpenUIPrimitive, type OpenUISchemaIssue, type OpenUISchemaValidation, type OpenUISeparatorNode, type OpenUIStackNode, type OpenUIStatNode, type OpenUITableNode, type OpenUITextNode, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, PdfViewer, type PdfViewerConfig, type PdfViewerProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QuestionPreview, type QuestionPreviewProps, RadioGroup, RadioGroupItem, RealtimeSessionOptions, RealtimeSessionRegistry, RealtimeSessionRegistryProps, RealtimeSessionState, RealtimeSessionTarget, ReasoningPart, type RedactedDocSegment, RedactedDocument, type RedactedDocumentData, type RedactedDocumentProps, RegisterActiveSessionOptions, type RevealResult, RichFileTree, type RichFileTreeGitEntry, type RichFileTreeGitStatus, type RichFileTreeProps, type RichFileTreeThemeVars, Run, RunGroup, type RunGroupProps, type RunPhase, RunPhaseList, RunRowShell, type RunRowShellProps, type RunRowStatus, RunRowStatusDot, RunStats, SSEEvent, SdkSessionAttachment, SdkSessionEvent, SdkSessionSeed, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SessionMessage, SessionPart, SessionProjectKey, type SessionUser, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, type SidebarDropZoneProps, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, type StatCardProps, StatusPill, type StatusPillProps, type StatusTone, Switch, TONE_CLASSES, TOOL_CATEGORY_ICONS, TRANSCRIPT_TEXT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TaskList, type TaskListItem, type TaskListProps, type TaskStatus, TaskStreamEvent, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TerminalStreamEvent, TextPart, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, ThinkingIndicator, type ThinkingIndicatorProps, TimeSelect, type TimeSelectProps, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, type ToolCallData, ToolCallFeed, type ToolCallFeedProps, type ToolCallStatus, type ToolCallType, ToolCategory, ToolDisplayMetadata, ToolPart, ToolState, ToolStatus, ToolTime, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, UseAuthOptions, UseAuthResult, UseRunGroupsOptions, UseSSEStreamOptions, UseSSEStreamResult, UseSdkSessionOptions, UseSdkSessionReturn, UseToolCallStreamReturn, UserMenu, type UserMenuProps, UserMessage, type UserMessageProps, WebSearchPreview, type WebSearchPreviewProps, WriteFilePreview, type WriteFilePreviewProps, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, codeBlockGrammar, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fenceInfo, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatCalendarDate, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, ixControl, ixControlAfter, ixControlSoft, ixField, ixRow, ixSelected, ixTabUnderline, localToday, messagesAtom, numericColumns, parseCalendarDate, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, showsTaskPriority, tableCsv, taskProgress, taskStatus, timeAgo, toneFor, truncateText, unregisterActiveSession, updateActiveSessionMeta, updatePart, useActiveSession, useActiveSessions, useActiveSessionsState, useApiKey, useAuth, useAutoScroll, useDropdownMenu, useHasBackgroundRunningSessions, useLiveTime, useNavbarSessions, useProjectActivity, useProjectSessions, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useSessionsByActivity, useTheme, useToast, useToolCallStream, useTotalRunningSessions, validateOpenUIJsonArtifact, validateOpenUIJsonNode };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixControl, ixControlAfter, ixControlSoft, ixField, ixRow, ixSelected, ixTabUnderline } from "./lib/interaction.js";
|
|
1
2
|
import { focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset } from "./lib/focus.js";
|
|
2
3
|
import { cn } from "./lib/utils.js";
|
|
3
4
|
import { Button, buttonVariants } from "./primitives/button.js";
|
|
@@ -77,8 +78,8 @@ import { InlineThinkingItem } from "./run/inline-thinking-item.js";
|
|
|
77
78
|
import { OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES } from "./openui/schema-data.js";
|
|
78
79
|
import { findUnsupportedOpenUINode, validateOpenUIJsonArtifact, validateOpenUIJsonNode } from "./openui-schema.js";
|
|
79
80
|
import { OpenUIArtifactRenderer } from "./openui/openui-artifact-renderer.js";
|
|
80
|
-
import { RunGroup } from "./run/run-group.js";
|
|
81
81
|
import { TRANSCRIPT_TEXT } from "./chat/transcript-text.js";
|
|
82
|
+
import { RunGroup } from "./run/run-group.js";
|
|
82
83
|
import { MessageAuthor, isViewerMessage } from "./chat/message-author.js";
|
|
83
84
|
import { UserMessage } from "./chat/user-message.js";
|
|
84
85
|
import { MessageList } from "./chat/message-list.js";
|
|
@@ -114,4 +115,4 @@ import { addMessage, addParts, clearChat, isStreamingAtom, messagesAtom, partMap
|
|
|
114
115
|
import { copyText } from "./utils/copy-text.js";
|
|
115
116
|
import { timeAgo } from "./utils/time-ago.js";
|
|
116
117
|
import { RedactedDocument } from "./redaction/redacted-document.js";
|
|
117
|
-
export { AgentTimeline, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ApprovalCard, ApprovalDiffSummary, ArtifactPane, AuthHeader, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatContainer, ChatMessage, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, CommandPreview, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffPreview, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ExpandedToolDetail, FileArtifactPane, FileCard, FileList, FilePreview, FileTabs, FileTree, FilterField, GitHubLoginButton, GlobResultsPreview, GrepResultsPreview, Heading, HelpText, IconTile, InlineCode, InlineThinkingItem, InlineToolItem, Input, Label, LiveDuration, LoginLayout, Logo, Markdown, MessageAuthor, MessageList, Metric, MetricStrip, OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES, OpenUIArtifactRenderer, PageHeader, PageShell, Pagination, PdfViewer, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QuestionPreview, RadioGroup, RadioGroupItem, RealtimeSessionRegistry, RedactedDocument, RichFileTree, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, StatusPill, Switch, TONE_CLASSES, TOOL_CATEGORY_ICONS, TRANSCRIPT_TEXT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TaskList, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ThinkingIndicator, TimeSelect, ToastContainer, ToastProvider, ToolCallFeed, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, UserMenu, UserMessage, WebSearchPreview, WriteFilePreview, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, codeBlockGrammar, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fenceInfo, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatCalendarDate, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, localToday, messagesAtom, numericColumns, parseCalendarDate, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, showsTaskPriority, tableCsv, taskProgress, taskStatus, timeAgo, toneFor, truncateText, unregisterActiveSession, updateActiveSessionMeta, updatePart, useActiveSession, useActiveSessions, useActiveSessionsState, useApiKey, useAuth, useAutoScroll, useDropdownMenu, useHasBackgroundRunningSessions, useLiveTime, useNavbarSessions, useProjectActivity, useProjectSessions, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useSessionsByActivity, useTheme, useToast, useToolCallStream, useTotalRunningSessions, validateOpenUIJsonArtifact, validateOpenUIJsonNode };
|
|
118
|
+
export { AgentTimeline, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ApprovalCard, ApprovalDiffSummary, ArtifactPane, AuthHeader, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatContainer, ChatMessage, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, CommandPreview, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffPreview, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ExpandedToolDetail, FileArtifactPane, FileCard, FileList, FilePreview, FileTabs, FileTree, FilterField, GitHubLoginButton, GlobResultsPreview, GrepResultsPreview, Heading, HelpText, IconTile, InlineCode, InlineThinkingItem, InlineToolItem, Input, Label, LiveDuration, LoginLayout, Logo, Markdown, MessageAuthor, MessageList, Metric, MetricStrip, OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES, OpenUIArtifactRenderer, PageHeader, PageShell, Pagination, PdfViewer, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QuestionPreview, RadioGroup, RadioGroupItem, RealtimeSessionRegistry, RedactedDocument, RichFileTree, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, StatusPill, Switch, TONE_CLASSES, TOOL_CATEGORY_ICONS, TRANSCRIPT_TEXT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TaskList, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ThinkingIndicator, TimeSelect, ToastContainer, ToastProvider, ToolCallFeed, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, UserMenu, UserMessage, WebSearchPreview, WriteFilePreview, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, codeBlockGrammar, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fenceInfo, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatCalendarDate, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, ixControl, ixControlAfter, ixControlSoft, ixField, ixRow, ixSelected, ixTabUnderline, localToday, messagesAtom, numericColumns, parseCalendarDate, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, showsTaskPriority, tableCsv, taskProgress, taskStatus, timeAgo, toneFor, truncateText, unregisterActiveSession, updateActiveSessionMeta, updatePart, useActiveSession, useActiveSessions, useActiveSessionsState, useApiKey, useAuth, useAutoScroll, useDropdownMenu, useHasBackgroundRunningSessions, useLiveTime, useNavbarSessions, useProjectActivity, useProjectSessions, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useSessionsByActivity, useTheme, useToast, useToolCallStream, useTotalRunningSessions, validateOpenUIJsonArtifact, validateOpenUIJsonNode };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixField } from "./interaction.js";
|
|
1
2
|
import { focusField } from "./focus.js";
|
|
2
3
|
import { cn } from "./utils.js";
|
|
3
4
|
//#region src/lib/control-presentation.ts
|
|
@@ -43,6 +44,6 @@ const controlSizes = {
|
|
|
43
44
|
compact: "h-[var(--control-height)] px-3 py-1 text-sm",
|
|
44
45
|
touch: "h-11 min-h-11 min-w-11 px-4 py-2 text-base"
|
|
45
46
|
};
|
|
46
|
-
const fieldPresentation = cn(focusField, controlMotion, "min-w-0
|
|
47
|
+
const fieldPresentation = cn(focusField, ixField, controlMotion, "min-w-0 text-foreground", "aria-invalid:border-[var(--surface-danger-border)] aria-invalid:hover:border-[var(--surface-danger-border)] aria-invalid:focus:border-[var(--focus-border-danger)] aria-invalid:focus:ring-[var(--focus-halo-danger)]", "autofill:shadow-[inset_0_0_0_1000px_var(--field-surface,var(--well))] autofill:[-webkit-text-fill-color:var(--text-primary)] autofill:caret-[var(--text-primary)]");
|
|
47
48
|
//#endregion
|
|
48
49
|
export { controlHeight, controlMotion, controlRadius, controlSizes, controlSquare, controlText, fieldPresentation, fieldSizes, fieldTouchText, touchTarget };
|
package/dist/lib/focus.d.ts
CHANGED
|
@@ -40,8 +40,12 @@ export declare const focusField = "border-border transition-[border-color,box-sh
|
|
|
40
40
|
* compose your own classes instead of this helper. The field selector is
|
|
41
41
|
* written out in full because Tailwind reads class names statically.
|
|
42
42
|
* Base styles use its marker class to clear the inner editor fallback outline.
|
|
43
|
+
*
|
|
44
|
+
* The container is the field, so it takes `ixField` (lib/interaction.ts): its
|
|
45
|
+
* own well fill, the `--field-border` hairline and the green hover edge. The
|
|
46
|
+
* borderless field inside stays transparent.
|
|
43
47
|
*/
|
|
44
|
-
export declare const focusFieldWithin = "focus-field-within
|
|
48
|
+
export declare const focusFieldWithin = "focus-field-within transition-[border-color,box-shadow] duration-150 ease-out bg-[var(--field-surface,var(--well))] border-[var(--field-border)] shadow-[var(--shadow-well)] hover:border-[var(--ix-hover-border)] hover:shadow-[var(--shadow-well),var(--ix-hover)] has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:border-[var(--focus-border)] has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:ring-3 has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:ring-[var(--focus-halo)]";
|
|
45
49
|
/** Error state for a field: a danger hairline and the same focus shape in danger. Compose after `focusField`. */
|
|
46
50
|
export declare const focusFieldInvalid = "border-[var(--surface-danger-border)] hover:border-[var(--surface-danger-border)] focus:border-[var(--focus-border-danger)] focus:ring-[var(--focus-halo-danger)]";
|
|
47
51
|
/** Keyboard-only focus for a control: a 1px focus line with the halo beyond it. */
|
package/dist/lib/focus.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixField } from "./interaction.js";
|
|
1
2
|
//#region src/lib/focus.ts
|
|
2
3
|
/**
|
|
3
4
|
* The focus treatment every control shares, in two shapes over one palette
|
|
@@ -40,8 +41,12 @@ const focusField = "border-border transition-[border-color,box-shadow] duration-
|
|
|
40
41
|
* compose your own classes instead of this helper. The field selector is
|
|
41
42
|
* written out in full because Tailwind reads class names statically.
|
|
42
43
|
* Base styles use its marker class to clear the inner editor fallback outline.
|
|
44
|
+
*
|
|
45
|
+
* The container is the field, so it takes `ixField` (lib/interaction.ts): its
|
|
46
|
+
* own well fill, the `--field-border` hairline and the green hover edge. The
|
|
47
|
+
* borderless field inside stays transparent.
|
|
43
48
|
*/
|
|
44
|
-
const focusFieldWithin =
|
|
49
|
+
const focusFieldWithin = `focus-field-within transition-[border-color,box-shadow] duration-150 ease-out ${ixField} has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:border-[var(--focus-border)] has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:ring-3 has-[:is(textarea,select,[contenteditable]:not([contenteditable=false]),input:not([type=button],[type=submit],[type=reset],[type=image],[type=checkbox],[type=radio],[type=range],[type=color],[type=file])):focus]:ring-[var(--focus-halo)]`;
|
|
45
50
|
/** Error state for a field: a danger hairline and the same focus shape in danger. Compose after `focusField`. */
|
|
46
51
|
const focusFieldInvalid = "border-[var(--surface-danger-border)] hover:border-[var(--surface-danger-border)] focus:border-[var(--focus-border-danger)] focus:ring-[var(--focus-halo-danger)]";
|
|
47
52
|
const focusRingBase = "focus-visible:outline-1 focus-visible:outline-[var(--focus-border)] focus-visible:ring-4 focus-visible:ring-[var(--focus-halo)]";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/lib/interaction.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The interaction states every control shares: one palette in five shapes, all
|
|
4
|
+
* read from `@tangle-network/brand`'s `--ix-*` tokens (tokens.css), which derive
|
|
5
|
+
* from the focus ring hue `--hsl-ring`. So hover, press, after-click and
|
|
6
|
+
* selected are the same green in Hospitality and the same indigo on the spine
|
|
7
|
+
* as the keyboard focus ring.
|
|
8
|
+
*
|
|
9
|
+
* hover 1px edge at .45 plus a 4px halo at .16 (`--ix-hover`)
|
|
10
|
+
* press 1px edge at .95 plus a 4px halo at .30 (`--ix-press`)
|
|
11
|
+
* after a control focused by a mouse click keeps a soft ring (`--ix-after`)
|
|
12
|
+
* selected a tint plus a 1px inset ring at .85 (`--ix-sel-bg`, `--ix-sel-ring`)
|
|
13
|
+
*
|
|
14
|
+
* The keyboard focus-visible glow stays exactly as `focusRing` / `focusField`
|
|
15
|
+
* (lib/focus.ts) draw it. Tailwind composes `--tw-ring-shadow` with
|
|
16
|
+
* `--tw-shadow`, so these shadows coexist with that ring, and
|
|
17
|
+
* `focus-visible:shadow-none` drops the hover glow while the keyboard ring shows.
|
|
18
|
+
*
|
|
19
|
+
* Every class is written out in full because Tailwind reads class names
|
|
20
|
+
* statically.
|
|
21
|
+
*/
|
|
22
|
+
/** Bordered or filled control: green edge on hover, deeper on press, a persistent soft ring after a mouse click. */
|
|
23
|
+
export declare const ixControl: string;
|
|
24
|
+
/** The after-click part of `ixControl` alone, for a field that opens a menu (SelectTrigger). */
|
|
25
|
+
export declare const ixControlAfter = "focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)]";
|
|
26
|
+
/** Ghost, icon, link and bare controls: a wash, never a glow (too noisy in sidebars and toolbars). */
|
|
27
|
+
export declare const ixControlSoft = "hover:bg-[var(--ix-hover-bg)] active:bg-[var(--ix-sel-bg)]";
|
|
28
|
+
/**
|
|
29
|
+
* Field: its own well and a visible border; hover replaces `focusField`'s
|
|
30
|
+
* neutral `--border-strong`. The well is the `--well` context variable, which a
|
|
31
|
+
* card re-declares for its descendants, so a field never takes its parent's
|
|
32
|
+
* colour. `--field-surface` still lets a context such as Toolbar pick the fill.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ixField: string;
|
|
35
|
+
/** Selected / on / current: tint plus a 1px inset green ring. */
|
|
36
|
+
export declare const ixSelected: string;
|
|
37
|
+
/** Underline tab: 2px green underline plus a faint tint, never a box; a faint underline on hover. */
|
|
38
|
+
export declare const ixTabUnderline: string;
|
|
39
|
+
/** List row / menu item: wash plus inset edge on hover or keyboard highlight; checked = selected. */
|
|
40
|
+
export declare const ixRow: string;
|
|
41
|
+
//#endregion
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region src/lib/interaction.ts
|
|
2
|
+
/**
|
|
3
|
+
* The interaction states every control shares: one palette in five shapes, all
|
|
4
|
+
* read from `@tangle-network/brand`'s `--ix-*` tokens (tokens.css), which derive
|
|
5
|
+
* from the focus ring hue `--hsl-ring`. So hover, press, after-click and
|
|
6
|
+
* selected are the same green in Hospitality and the same indigo on the spine
|
|
7
|
+
* as the keyboard focus ring.
|
|
8
|
+
*
|
|
9
|
+
* hover 1px edge at .45 plus a 4px halo at .16 (`--ix-hover`)
|
|
10
|
+
* press 1px edge at .95 plus a 4px halo at .30 (`--ix-press`)
|
|
11
|
+
* after a control focused by a mouse click keeps a soft ring (`--ix-after`)
|
|
12
|
+
* selected a tint plus a 1px inset ring at .85 (`--ix-sel-bg`, `--ix-sel-ring`)
|
|
13
|
+
*
|
|
14
|
+
* The keyboard focus-visible glow stays exactly as `focusRing` / `focusField`
|
|
15
|
+
* (lib/focus.ts) draw it. Tailwind composes `--tw-ring-shadow` with
|
|
16
|
+
* `--tw-shadow`, so these shadows coexist with that ring, and
|
|
17
|
+
* `focus-visible:shadow-none` drops the hover glow while the keyboard ring shows.
|
|
18
|
+
*
|
|
19
|
+
* Every class is written out in full because Tailwind reads class names
|
|
20
|
+
* statically.
|
|
21
|
+
*/
|
|
22
|
+
/** Bordered or filled control: green edge on hover, deeper on press, a persistent soft ring after a mouse click. */
|
|
23
|
+
const ixControl = "hover:border-[var(--ix-hover-border)] hover:shadow-[var(--ix-hover)] focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)] active:border-[hsl(var(--hsl-ring))] active:shadow-[var(--ix-press)] focus-visible:shadow-none";
|
|
24
|
+
/** The after-click part of `ixControl` alone, for a field that opens a menu (SelectTrigger). */
|
|
25
|
+
const ixControlAfter = "focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)]";
|
|
26
|
+
/** Ghost, icon, link and bare controls: a wash, never a glow (too noisy in sidebars and toolbars). */
|
|
27
|
+
const ixControlSoft = "hover:bg-[var(--ix-hover-bg)] active:bg-[var(--ix-sel-bg)]";
|
|
28
|
+
/**
|
|
29
|
+
* Field: its own well and a visible border; hover replaces `focusField`'s
|
|
30
|
+
* neutral `--border-strong`. The well is the `--well` context variable, which a
|
|
31
|
+
* card re-declares for its descendants, so a field never takes its parent's
|
|
32
|
+
* colour. `--field-surface` still lets a context such as Toolbar pick the fill.
|
|
33
|
+
*/
|
|
34
|
+
const ixField = "bg-[var(--field-surface,var(--well))] border-[var(--field-border)] shadow-[var(--shadow-well)] hover:border-[var(--ix-hover-border)] hover:shadow-[var(--shadow-well),var(--ix-hover)]";
|
|
35
|
+
/** Selected / on / current: tint plus a 1px inset green ring. */
|
|
36
|
+
const ixSelected = "aria-pressed:bg-[var(--ix-sel-bg)] aria-pressed:text-[var(--accent-text)] aria-pressed:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] aria-checked:bg-[var(--ix-sel-bg)] aria-checked:text-[var(--accent-text)] aria-checked:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] aria-[current=page]:bg-[var(--ix-sel-bg)] aria-[current=page]:text-[var(--accent-text)] aria-[current=page]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] data-[state=on]:bg-[var(--ix-sel-bg)] data-[state=on]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] data-[state=active]:bg-[var(--ix-sel-bg)] data-[state=active]:text-[var(--accent-text)] data-[state=active]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)]";
|
|
37
|
+
/** Underline tab: 2px green underline plus a faint tint, never a box; a faint underline on hover. */
|
|
38
|
+
const ixTabUnderline = "hover:shadow-[inset_0_-2px_0_hsl(var(--hsl-ring)/0.4)] data-[state=active]:bg-[hsl(var(--hsl-ring)/0.07)] data-[state=active]:text-[var(--accent-text)] data-[state=active]:shadow-[inset_0_-2px_0_var(--ix-sel-ring)] aria-checked:bg-[hsl(var(--hsl-ring)/0.07)] aria-checked:text-[var(--accent-text)] aria-checked:shadow-[inset_0_-2px_0_var(--ix-sel-ring)]";
|
|
39
|
+
/** List row / menu item: wash plus inset edge on hover or keyboard highlight; checked = selected. */
|
|
40
|
+
const ixRow = "hover:bg-[var(--ix-hover-bg)] hover:shadow-[inset_0_0_0_1px_var(--ix-hover-border)] data-[highlighted]:bg-[var(--ix-sel-bg)] data-[highlighted]:shadow-[inset_0_0_0_1px_var(--ix-hover-border)] focus:bg-[var(--ix-sel-bg)] data-[state=checked]:bg-[var(--ix-sel-bg)] data-[state=checked]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] active:shadow-[inset_0_0_0_1px_hsl(var(--hsl-ring))]";
|
|
41
|
+
//#endregion
|
|
42
|
+
export { ixControl, ixControlAfter, ixControlSoft, ixField, ixRow, ixSelected, ixTabUnderline };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixControl, ixControlSoft, ixSelected } from "../lib/interaction.js";
|
|
1
2
|
import { focusRing } from "../lib/focus.js";
|
|
2
3
|
import { cn } from "../lib/utils.js";
|
|
3
4
|
import { controlHeight, controlMotion, controlRadius, controlSizes, controlSquare, controlText } from "../lib/control-presentation.js";
|
|
@@ -9,13 +10,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
10
|
const buttonVariants = cva(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium transition-[color,background-color,border-color,box-shadow,transform,scale] ${controlMotion} ${focusRing} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0`, {
|
|
10
11
|
variants: {
|
|
11
12
|
variant: {
|
|
12
|
-
default:
|
|
13
|
-
destructive:
|
|
14
|
-
outline:
|
|
15
|
-
secondary:
|
|
16
|
-
ghost:
|
|
17
|
-
link:
|
|
18
|
-
sandbox:
|
|
13
|
+
default: `bg-primary text-primary-foreground hover:bg-primary/90 active:scale-[0.97] ${ixControl}`,
|
|
14
|
+
destructive: `bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.97] ${ixControl}`,
|
|
15
|
+
outline: `border border-border bg-card hover:bg-muted active:scale-[0.97] text-foreground ${ixControl}`,
|
|
16
|
+
secondary: `bg-muted border border-border text-foreground hover:bg-muted/80 active:scale-[0.97] ${ixControl}`,
|
|
17
|
+
ghost: `hover:text-foreground text-muted-foreground border border-transparent ${ixControlSoft}`,
|
|
18
|
+
link: `text-[var(--accent-text)] underline-offset-4 hover:underline ${ixControlSoft}`,
|
|
19
|
+
sandbox: `bg-[var(--btn-primary-bg)] text-[var(--btn-primary-text)] border border-[var(--border-accent)] hover:bg-[var(--btn-primary-hover)] active:scale-[0.97] ${ixControl}`
|
|
19
20
|
},
|
|
20
21
|
size: {
|
|
21
22
|
default: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
@@ -34,7 +35,15 @@ const buttonVariants = cva(`inline-flex items-center justify-center gap-2 whites
|
|
|
34
35
|
size: "default"
|
|
35
36
|
}
|
|
36
37
|
});
|
|
37
|
-
const bareButton = `${focusRing} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50`;
|
|
38
|
+
const bareButton = `${focusRing} ${ixControlSoft} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50`;
|
|
39
|
+
/** One Button render's classes: variant and size, the toggle states, then the caller's. */
|
|
40
|
+
function buttonClassName(variant, size, pressed, className) {
|
|
41
|
+
const toggle = pressed === void 0 ? void 0 : `${ixControl} ${ixSelected}`;
|
|
42
|
+
return variant === "bare" ? cn(bareButton, toggle, className) : cn(buttonVariants({
|
|
43
|
+
variant,
|
|
44
|
+
size
|
|
45
|
+
}), toggle, className);
|
|
46
|
+
}
|
|
38
47
|
function preventActivation(event) {
|
|
39
48
|
event.preventDefault();
|
|
40
49
|
event.stopPropagation();
|
|
@@ -61,11 +70,7 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, lo
|
|
|
61
70
|
const child = React.isValidElement(children) ? children : null;
|
|
62
71
|
const isDisabled = disabled || loading || child?.props.disabled;
|
|
63
72
|
return /* @__PURE__ */ jsx(Slot, {
|
|
64
|
-
className: variant
|
|
65
|
-
variant,
|
|
66
|
-
size,
|
|
67
|
-
className
|
|
68
|
-
})),
|
|
73
|
+
className: buttonClassName(variant, size, props["aria-pressed"], className),
|
|
69
74
|
ref,
|
|
70
75
|
...props,
|
|
71
76
|
...isDisabled ? disabledHandlers(props) : {},
|
|
@@ -84,11 +89,7 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, lo
|
|
|
84
89
|
});
|
|
85
90
|
}
|
|
86
91
|
return /* @__PURE__ */ jsxs("button", {
|
|
87
|
-
className: variant
|
|
88
|
-
variant,
|
|
89
|
-
size,
|
|
90
|
-
className
|
|
91
|
-
})),
|
|
92
|
+
className: buttonClassName(variant, size, props["aria-pressed"], className),
|
|
92
93
|
ref,
|
|
93
94
|
...props,
|
|
94
95
|
disabled: disabled || loading,
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
//#region src/primitives/card.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* A card is one level of the brand surface ladder. It carries
|
|
5
|
+
* `data-slot="card"`, and the brand's surface-context rule (tokens.css)
|
|
6
|
+
* re-declares `--card` and `--well` for everything inside it: a Card or a
|
|
7
|
+
* `bg-card` box inside a card paints the raised level, one inside that the
|
|
8
|
+
* raised-2 level, and a field in any of them takes the well that is the
|
|
9
|
+
* opposite step from its parent. Nesting needs no prop and no app selector.
|
|
10
|
+
*/
|
|
3
11
|
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
4
12
|
variant?: "default" | "glass" | "sandbox" | "elevated";
|
|
5
|
-
/** Decorative
|
|
13
|
+
/** Decorative hover feedback only (the shared green edge). Put actions in a native button or link. */
|
|
6
14
|
hover?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The card is itself the control, such as a card wrapped in a link: it takes
|
|
17
|
+
* the full control states (hover glow, press, the ring after a click).
|
|
18
|
+
*/
|
|
19
|
+
interactive?: boolean;
|
|
7
20
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
8
21
|
declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
9
22
|
export interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
|
package/dist/primitives/card.js
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
import "../lib/interaction.js";
|
|
1
2
|
import { cn } from "../lib/utils.js";
|
|
2
3
|
import { Heading } from "./heading.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
//#region src/primitives/card.tsx
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* A card is one level of the brand surface ladder. It carries
|
|
9
|
+
* `data-slot="card"`, and the brand's surface-context rule (tokens.css)
|
|
10
|
+
* re-declares `--card` and `--well` for everything inside it: a Card or a
|
|
11
|
+
* `bg-card` box inside a card paints the raised level, one inside that the
|
|
12
|
+
* raised-2 level, and a field in any of them takes the well that is the
|
|
13
|
+
* opposite step from its parent. Nesting needs no prop and no app selector.
|
|
14
|
+
*/
|
|
15
|
+
const Card = React.forwardRef(({ className, variant = "default", hover = false, interactive = false, ...props }, ref) => {
|
|
7
16
|
return /* @__PURE__ */ jsx("div", {
|
|
8
17
|
ref,
|
|
9
|
-
className: cn("rounded-[var(--radius-lg)] border text-card-foreground transition-[border-color,box-shadow]", "duration-[var(--transition-default)]", {
|
|
10
|
-
default: "bg-card border-border",
|
|
18
|
+
className: cn("rounded-[var(--radius-lg)] border text-card-foreground transition-[border-color,box-shadow,background-color]", "duration-[var(--transition-default)]", {
|
|
19
|
+
default: "bg-card border-border shadow-[var(--edge-highlight),var(--shadow-card)]",
|
|
11
20
|
elevated: "bg-muted/50 border-border shadow-[var(--shadow-card)]",
|
|
12
21
|
glass: "bg-card/80 backdrop-blur-xl border-border shadow-[var(--shadow-card)]",
|
|
13
22
|
sandbox: "bg-muted/50 border-primary/20 shadow-[var(--shadow-accent)]"
|
|
14
|
-
}[variant], hover && "hover:border-[var(--border-
|
|
23
|
+
}[variant], (hover || interactive) && "hover:border-[var(--ix-hover-border)] hover:shadow-[var(--ix-hover)] focus:not-focus-visible:border-[var(--ix-hover-border)] focus:not-focus-visible:shadow-[var(--ix-after)] active:border-[hsl(var(--hsl-ring))] active:shadow-[var(--ix-press)] focus-visible:shadow-none", className),
|
|
24
|
+
"data-slot": "card",
|
|
15
25
|
...props
|
|
16
26
|
});
|
|
17
27
|
});
|
|
@@ -32,7 +42,7 @@ const CardTitle = React.forwardRef(({ className, as = "h3", ...props }, ref) =>
|
|
|
32
42
|
CardTitle.displayName = "CardTitle";
|
|
33
43
|
const CardDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", {
|
|
34
44
|
ref,
|
|
35
|
-
className: cn("text-muted-foreground text-sm", className),
|
|
45
|
+
className: cn("text-muted-foreground text-sm line-clamp-2", className),
|
|
36
46
|
...props
|
|
37
47
|
}));
|
|
38
48
|
CardDescription.displayName = "CardDescription";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixRow } from "../lib/interaction.js";
|
|
1
2
|
import { cn } from "../lib/utils.js";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -12,33 +13,33 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
|
12
13
|
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
13
14
|
const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.SubTrigger, {
|
|
14
15
|
ref,
|
|
15
|
-
className: cn("flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none", "
|
|
16
|
+
className: cn("flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]", "data-[state=open]:bg-[var(--ix-sel-bg)]", ixRow, inset && "pl-8", className),
|
|
16
17
|
...props,
|
|
17
18
|
children: [children, /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })]
|
|
18
19
|
}));
|
|
19
20
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
20
21
|
const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, {
|
|
21
22
|
ref,
|
|
22
|
-
className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-
|
|
23
|
+
className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2", "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className),
|
|
23
24
|
...props
|
|
24
25
|
}));
|
|
25
26
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
26
27
|
const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
|
|
27
28
|
ref,
|
|
28
29
|
sideOffset,
|
|
29
|
-
className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-
|
|
30
|
+
className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2", "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className),
|
|
30
31
|
...props
|
|
31
32
|
}) }));
|
|
32
33
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
33
34
|
const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
|
|
34
35
|
ref,
|
|
35
|
-
className: cn("relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-
|
|
36
|
+
className: cn("relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", inset && "pl-8", className),
|
|
36
37
|
...props
|
|
37
38
|
}));
|
|
38
39
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
39
40
|
const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.CheckboxItem, {
|
|
40
41
|
ref,
|
|
41
|
-
className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-
|
|
42
|
+
className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
42
43
|
checked,
|
|
43
44
|
...props,
|
|
44
45
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -49,7 +50,7 @@ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checke
|
|
|
49
50
|
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
50
51
|
const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.RadioItem, {
|
|
51
52
|
ref,
|
|
52
|
-
className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-
|
|
53
|
+
className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
53
54
|
...props,
|
|
54
55
|
children: [/* @__PURE__ */ jsx("span", {
|
|
55
56
|
className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
@@ -12,7 +12,11 @@ import * as React from "react";
|
|
|
12
12
|
* console warning fires when both are omitted.
|
|
13
13
|
*
|
|
14
14
|
* Design rules baked into the default variant:
|
|
15
|
-
* -
|
|
15
|
+
* - The row track is a field well (`--well`, `--field-border`), so the
|
|
16
|
+
* control reads as one inset group on whatever plane it sits on.
|
|
17
|
+
* - Only the SELECTED segment shows a surface colour + accent text: the
|
|
18
|
+
* shared selected state (`ixSelected`: tint plus an inset ring). A tab
|
|
19
|
+
* shows it as an underline instead (`ixTabUnderline`).
|
|
16
20
|
* - Unselected segments have NO background — they're plain-text labels
|
|
17
21
|
* that darken on hover. This keeps the selected segment as the
|
|
18
22
|
* single visual anchor instead of the whole group competing with
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import "../lib/interaction.js";
|
|
2
3
|
import { focusRing, focusRingInset } from "../lib/focus.js";
|
|
3
4
|
import { cn } from "../lib/utils.js";
|
|
4
5
|
import "../lib/control-presentation.js";
|
|
@@ -83,7 +84,7 @@ function SegmentedControl({ value, onValueChange, options, variant = "row", clas
|
|
|
83
84
|
ref: stripRef,
|
|
84
85
|
onKeyDown: handleKeyDown,
|
|
85
86
|
onScroll: tabs ? measureOverflow : void 0,
|
|
86
|
-
className: cn("flex gap-1", variant === "row" && "flex-wrap items-center rounded-lg border border-border bg-
|
|
87
|
+
className: cn("flex gap-1", variant === "row" && "flex-wrap items-center rounded-lg border border-[var(--field-border)] bg-[var(--well)] p-1", variant === "tabs" && ["relative flex-nowrap items-end border-b border-border pb-0 overflow-x-auto", tabEdgeFade], className),
|
|
87
88
|
children: options.map((option, i) => {
|
|
88
89
|
const active = option.value === value;
|
|
89
90
|
const focusable = active || !hasMatch && i === 0;
|
|
@@ -100,11 +101,17 @@ function SegmentedControl({ value, onValueChange, options, variant = "row", clas
|
|
|
100
101
|
onClick: () => {
|
|
101
102
|
if (!active) onValueChange(option.value);
|
|
102
103
|
},
|
|
103
|
-
className: cn("relative inline-flex items-center gap-2 whitespace-nowrap text-sm font-medium transition-[color,background-color,border-color,box-shadow]", variant === "row" && [
|
|
104
|
-
"
|
|
104
|
+
className: cn("relative inline-flex items-center gap-2 whitespace-nowrap text-sm font-medium transition-[color,background-color,border-color,box-shadow]", variant === "row" && [
|
|
105
|
+
"rounded-md border border-transparent px-3 py-1.5",
|
|
106
|
+
focusRing,
|
|
107
|
+
"hover:bg-[var(--ix-hover-bg)] active:bg-[var(--ix-sel-bg)]",
|
|
108
|
+
"aria-pressed:bg-[var(--ix-sel-bg)] aria-pressed:text-[var(--accent-text)] aria-pressed:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] aria-checked:bg-[var(--ix-sel-bg)] aria-checked:text-[var(--accent-text)] aria-checked:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] aria-[current=page]:bg-[var(--ix-sel-bg)] aria-[current=page]:text-[var(--accent-text)] aria-[current=page]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] data-[state=on]:bg-[var(--ix-sel-bg)] data-[state=on]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)] data-[state=active]:bg-[var(--ix-sel-bg)] data-[state=active]:text-[var(--accent-text)] data-[state=active]:shadow-[inset_0_0_0_1px_var(--ix-sel-ring)]"
|
|
109
|
+
], variant === "tabs" && [
|
|
110
|
+
"shrink-0 rounded-none border-b-2 border-transparent -mb-px px-4 py-2",
|
|
105
111
|
"pointer-coarse:min-h-11",
|
|
106
|
-
focusRingInset
|
|
107
|
-
|
|
112
|
+
focusRingInset,
|
|
113
|
+
"hover:shadow-[inset_0_-2px_0_hsl(var(--hsl-ring)/0.4)] data-[state=active]:bg-[hsl(var(--hsl-ring)/0.07)] data-[state=active]:text-[var(--accent-text)] data-[state=active]:shadow-[inset_0_-2px_0_var(--ix-sel-ring)] aria-checked:bg-[hsl(var(--hsl-ring)/0.07)] aria-checked:text-[var(--accent-text)] aria-checked:shadow-[inset_0_-2px_0_var(--ix-sel-ring)]"
|
|
114
|
+
], active ? "text-[var(--accent-text)]" : "text-muted-foreground hover:text-foreground"),
|
|
108
115
|
children: [/* @__PURE__ */ jsx("span", { children: option.label }), option.adornment && /* @__PURE__ */ jsx("span", {
|
|
109
116
|
className: cn("text-xs", active ? "text-[var(--accent-text)]/80" : "text-muted-foreground"),
|
|
110
117
|
children: option.adornment
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { ixControlAfter, ixRow } from "../lib/interaction.js";
|
|
2
3
|
import { cn } from "../lib/utils.js";
|
|
3
4
|
import { controlSizes, fieldPresentation, fieldSizes, fieldTouchText } from "../lib/control-presentation.js";
|
|
4
5
|
import * as React from "react";
|
|
@@ -11,7 +12,7 @@ const SelectGroup = SelectPrimitive.Group;
|
|
|
11
12
|
const SelectValue = SelectPrimitive.Value;
|
|
12
13
|
const SelectTrigger = React.forwardRef(({ className, children, size = "default", ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
|
|
13
14
|
ref,
|
|
14
|
-
className: cn("flex w-full items-center justify-between gap-2 whitespace-nowrap border py-1
|
|
15
|
+
className: cn("flex w-full items-center justify-between gap-2 whitespace-nowrap border py-1 placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50", fieldPresentation, ixControlAfter, fieldTouchText, "data-[placeholder]:text-[var(--text-dim)] [&>span]:min-w-0 [&>span]:truncate [&>span]:text-left", "data-[state=open]:border-[var(--ix-hover-border)] data-[state=open]:shadow-[var(--ix-after)] [&[data-state=open]>svg]:rotate-180 [&>svg]:transition-transform", size === "compact" || size === "touch" ? cn(fieldSizes.md, controlSizes[size]) : fieldSizes[size === "default" ? "md" : size], className),
|
|
15
16
|
...props,
|
|
16
17
|
children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
|
|
17
18
|
asChild: true,
|
|
@@ -35,7 +36,7 @@ const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) =
|
|
|
35
36
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
36
37
|
const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
|
|
37
38
|
ref,
|
|
38
|
-
className: cn("data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-lg border border-border bg-
|
|
39
|
+
className: cn("data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)] data-[state=closed]:animate-out data-[state=open]:animate-in", position === "popper" && "data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1", className),
|
|
39
40
|
position,
|
|
40
41
|
...props,
|
|
41
42
|
children: [
|
|
@@ -56,7 +57,7 @@ const SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
56
57
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
57
58
|
const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
|
|
58
59
|
ref,
|
|
59
|
-
className: cn("relative flex w-full cursor-default select-none items-center rounded-md py-1.5 pr-8 pl-2 text-sm outline-none transition-
|
|
60
|
+
className: cn("relative flex w-full cursor-default select-none items-center rounded-md py-1.5 pr-8 pl-2 text-sm outline-none transition-[color,background-color,box-shadow] focus:text-foreground data-[state=checked]:font-medium data-[disabled]:pointer-events-none data-[disabled]:opacity-50", ixRow, className),
|
|
60
61
|
...props,
|
|
61
62
|
children: [/* @__PURE__ */ jsx("span", {
|
|
62
63
|
className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
|
package/dist/primitives/tabs.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ixControlSoft, ixSelected, ixTabUnderline } from "../lib/interaction.js";
|
|
1
2
|
import { focusRing } from "../lib/focus.js";
|
|
2
3
|
import { cn } from "../lib/utils.js";
|
|
3
4
|
import * as React from "react";
|
|
@@ -19,9 +20,9 @@ const TabsList = React.forwardRef(({ className, variant = "default", ...props },
|
|
|
19
20
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
20
21
|
const TabsTrigger = React.forwardRef(({ className, variant = "default", ...props }, ref) => {
|
|
21
22
|
const variants = {
|
|
22
|
-
default: `inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50
|
|
23
|
-
pills: `inline-flex items-center justify-center whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50 data-[state=
|
|
24
|
-
underline: `inline-flex items-center justify-center whitespace-nowrap rounded-t-md pb-3 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50 border-b-2 border-transparent data-[state=
|
|
23
|
+
default: `inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50 ${ixControlSoft} ${ixSelected}`,
|
|
24
|
+
pills: `inline-flex items-center justify-center whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50 data-[state=inactive]:text-muted-foreground ${ixControlSoft} ${ixSelected}`,
|
|
25
|
+
underline: `inline-flex items-center justify-center whitespace-nowrap rounded-t-md pb-3 text-sm font-medium transition-all ${focusRing} disabled:pointer-events-none disabled:opacity-50 border-b-2 border-transparent data-[state=inactive]:text-muted-foreground ${ixTabUnderline}`
|
|
25
26
|
};
|
|
26
27
|
return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, {
|
|
27
28
|
ref,
|
package/dist/run/run-group.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Markdown } from "../markdown/markdown.js";
|
|
|
5
5
|
import { InlineThinkingItem } from "./inline-thinking-item.js";
|
|
6
6
|
import { SyntheticText } from "../chat/synthetic-text.js";
|
|
7
7
|
import { OpenUIArtifactRenderer } from "../openui/openui-artifact-renderer.js";
|
|
8
|
+
import { TRANSCRIPT_TEXT } from "../chat/transcript-text.js";
|
|
8
9
|
import { memo, useMemo } from "react";
|
|
9
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
11
|
import { Bot, ChevronDown, ChevronRight, ClipboardList, FileEdit, FileSearch, Globe, Loader2, PencilLine, Search, Settings, Sparkles, Terminal } from "lucide-react";
|
|
@@ -254,7 +255,7 @@ const RunGroup = memo(({ run, partMap, collapsed, onToggle, branding = DEFAULT_B
|
|
|
254
255
|
if (part.type === "text" && !part.synthetic && part.text.trim()) return /* @__PURE__ */ jsx("div", {
|
|
255
256
|
className: "px-0.5",
|
|
256
257
|
children: /* @__PURE__ */ jsx(Markdown, {
|
|
257
|
-
className:
|
|
258
|
+
className: `tangle-prose ${TRANSCRIPT_TEXT} text-[var(--text-primary)]`,
|
|
258
259
|
children: part.text
|
|
259
260
|
})
|
|
260
261
|
}, key);
|
|
@@ -364,7 +365,7 @@ const RunGroup = memo(({ run, partMap, collapsed, onToggle, branding = DEFAULT_B
|
|
|
364
365
|
else if (part.type === "text" && part.text.trim()) node = part.synthetic ? /* @__PURE__ */ jsx(SyntheticText, { text: part.text }) : /* @__PURE__ */ jsx("div", {
|
|
365
366
|
className: "px-1 py-0.5",
|
|
366
367
|
children: /* @__PURE__ */ jsx(Markdown, {
|
|
367
|
-
className:
|
|
368
|
+
className: `tangle-prose ${TRANSCRIPT_TEXT}`,
|
|
368
369
|
children: part.text
|
|
369
370
|
})
|
|
370
371
|
});
|