@tangle-network/ui 11.27.0 → 11.28.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 +6 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/lib/control-presentation.js +33 -1
- package/dist/primitives/button.d.ts +3 -2
- package/dist/primitives/button.js +9 -6
- package/dist/primitives/help-text.d.ts +14 -0
- package/dist/primitives/help-text.js +18 -0
- package/dist/primitives/input.d.ts +3 -3
- package/dist/primitives/input.js +16 -15
- package/dist/primitives/label.js +1 -1
- package/dist/primitives/select.d.ts +2 -2
- package/dist/primitives/select.js +2 -2
- package/dist/primitives.d.ts +2 -1
- package/dist/primitives.js +2 -1
- package/package.json +2 -2
- package/src/lib/control-presentation.ts +49 -2
- package/src/primitives/button.tsx +14 -7
- package/src/primitives/control-presentation.stories.tsx +10 -1
- package/src/primitives/control-presentation.test.tsx +51 -6
- package/src/primitives/help-text.tsx +30 -0
- package/src/primitives/index.ts +3 -0
- package/src/primitives/input.tsx +21 -13
- package/src/primitives/label.tsx +2 -1
- package/src/primitives/select.tsx +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5f50a1b: Put `Button`, `Input`, `Textarea` and `SelectTrigger` on one control scale: `sm` 32px/12px text, `md` (default) 36px/14px, `lg` 44px/16px, read from Brand's control tokens with pixel fallbacks. Visible changes: a default `Input` is now 36px (was 44px) with 12px side padding (was 16px), matching the default `Button` and `SelectTrigger`; `Input` `sm` is 32px (was 36px) and `lg` 44px (was 48px); `SelectTrigger` uses the `rounded-lg` corner at md and gains `sm|md|lg`; `Button` `lg` text is 16px (was 14px); fields render 16px text on a coarse pointer so iOS does not zoom on focus. `Button` adds `md`, `icon-sm` (32px) and `icon-lg` (44px). New `HelpText` (`tone="hint" | "error"`, 12px) renders `Input` and `Textarea` hints and errors (were 14px); `Label` reads `--font-size-label`. `compact`, `touch` and `xl` are unchanged.
|
|
8
|
+
|
|
3
9
|
## 11.27.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ import { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGr
|
|
|
53
53
|
import { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from "./primitives/popover.js";
|
|
54
54
|
import { Slider } from "./primitives/slider.js";
|
|
55
55
|
import { Input, InputProps, Textarea, TextareaProps } from "./primitives/input.js";
|
|
56
|
+
import { HelpText, HelpTextProps } from "./primitives/help-text.js";
|
|
56
57
|
import { Badge, BadgeProps, badgeVariants } from "./primitives/badge.js";
|
|
57
58
|
import { Avatar, AvatarFallback, AvatarImage } from "./primitives/avatar.js";
|
|
58
59
|
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "./primitives/dropdown-menu.js";
|
|
@@ -119,4 +120,4 @@ import { QuestionPreview, QuestionPreviewProps } from "./tool-previews/question-
|
|
|
119
120
|
import { DiffPreview, DiffPreviewProps } from "./tool-previews/diff-preview.js";
|
|
120
121
|
import { RedactedDocSegment, RedactedDocument, RedactedDocumentData, RedactedDocumentProps, RevealResult } from "./redaction/redacted-document.js";
|
|
121
122
|
import "./redaction.js";
|
|
122
|
-
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, 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, 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, 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, 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 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, 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, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TaskStreamEvent, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TerminalStreamEvent, TextPart, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, ThinkingIndicator, type ThinkingIndicatorProps, 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, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, messagesAtom, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, 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 };
|
|
123
|
+
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, 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, 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, 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 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, 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, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TaskStreamEvent, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TerminalStreamEvent, TextPart, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, ThinkingIndicator, type ThinkingIndicatorProps, 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, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, messagesAtom, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, 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
|
@@ -9,6 +9,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./primitive
|
|
|
9
9
|
import { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger } from "./primitives/context-menu.js";
|
|
10
10
|
import { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from "./primitives/popover.js";
|
|
11
11
|
import { Slider } from "./primitives/slider.js";
|
|
12
|
+
import { HelpText } from "./primitives/help-text.js";
|
|
12
13
|
import { Label } from "./primitives/label.js";
|
|
13
14
|
import { Input, Textarea } from "./primitives/input.js";
|
|
14
15
|
import { Badge, badgeVariants } from "./primitives/badge.js";
|
|
@@ -103,4 +104,4 @@ import { addMessage, addParts, clearChat, isStreamingAtom, messagesAtom, partMap
|
|
|
103
104
|
import { copyText } from "./utils/copy-text.js";
|
|
104
105
|
import { timeAgo } from "./utils/time-ago.js";
|
|
105
106
|
import { RedactedDocument } from "./redaction/redacted-document.js";
|
|
106
|
-
export { AgentTimeline, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, AuthHeader, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, 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, 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, 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, RealtimeSessionRegistry, RedactedDocument, RichFileTree, RunGroup, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ThinkingIndicator, ToastContainer, ToastProvider, ToolCallFeed, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, UserMenu, UserMessage, WebSearchPreview, WriteFilePreview, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, messagesAtom, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, 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 };
|
|
107
|
+
export { AgentTimeline, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, AuthHeader, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, CSV_PREVIEW_ROW_LIMIT, 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, 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, RealtimeSessionRegistry, RedactedDocument, RichFileTree, RunGroup, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ThinkingIndicator, ToastContainer, ToastProvider, ToolCallFeed, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, UserMenu, UserMessage, WebSearchPreview, WriteFilePreview, activeSessionsAtom, addMessage, addParts, badgeVariants, bumpActiveSessionActivity, buttonVariants, clearChat, cn, configurePdfViewer, copyText, createAuthFetcher, detectFileFormat, fileExtension, filterFileTree, findUnsupportedOpenUINode, focusField, focusFieldInvalid, focusFieldWithin, focusRing, focusRingInset, formatBytes, formatDuration, formatUptime, getActiveSession, getAllActiveSessions, getAllProjectActivity, getCodeLanguage, getFormatLabel, getSanitizedMarkdownHeadingIdFromRawFragment, getSessionsByActivity, getSessionsForNavbar, getSessionsForProject, getSyntaxLanguage, getToolCategory, getToolDisplayMetadata, getToolErrorText, getTotalRunningSessionCount, hasBackgroundRunningSessions, initialsOf, isStreamingAtom, isViewerMessage, messagesAtom, parseCsv, parseToolEvent, partMapAtom, registerActiveSession, resetActiveSessions, resolveFilePreviewKind, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, 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 };
|
|
@@ -2,10 +2,42 @@ import { focusField } from "./focus.js";
|
|
|
2
2
|
import { cn } from "./utils.js";
|
|
3
3
|
//#region src/lib/control-presentation.ts
|
|
4
4
|
const controlMotion = "duration-[var(--duration-fast)] ease-[var(--ease-standard)] motion-reduce:transition-none motion-reduce:duration-0";
|
|
5
|
+
const controlHeight = {
|
|
6
|
+
sm: "h-[var(--control-height-sm,2rem)]",
|
|
7
|
+
md: "h-[var(--control-height,2.25rem)]",
|
|
8
|
+
lg: "h-[var(--control-height-lg,2.75rem)]"
|
|
9
|
+
};
|
|
10
|
+
const controlText = {
|
|
11
|
+
sm: "text-[length:var(--control-text-sm,0.75rem)]",
|
|
12
|
+
md: "text-[length:var(--control-text-md,0.875rem)]",
|
|
13
|
+
lg: "text-[length:var(--control-text-lg,1rem)]"
|
|
14
|
+
};
|
|
15
|
+
const controlRadius = {
|
|
16
|
+
sm: "rounded-md",
|
|
17
|
+
md: "rounded-lg",
|
|
18
|
+
lg: "rounded-lg"
|
|
19
|
+
};
|
|
20
|
+
/** Square icon-only controls on the same heights. */
|
|
21
|
+
const controlSquare = {
|
|
22
|
+
sm: "size-[var(--control-height-sm,2rem)]",
|
|
23
|
+
md: "size-[var(--control-height,2.25rem)]",
|
|
24
|
+
lg: "size-[var(--control-height-lg,2.75rem)]"
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Field text never drops below 16px on a coarse pointer: iOS Safari zooms the
|
|
28
|
+
* page on focus for anything smaller.
|
|
29
|
+
*/
|
|
30
|
+
const fieldTouchText = "pointer-coarse:text-base";
|
|
31
|
+
/** Field sizes: the control scale with field padding. */
|
|
32
|
+
const fieldSizes = {
|
|
33
|
+
sm: cn(controlHeight.sm, controlText.sm, controlRadius.sm, "px-2.5"),
|
|
34
|
+
md: cn(controlHeight.md, controlText.md, controlRadius.md, "px-3"),
|
|
35
|
+
lg: cn(controlHeight.lg, controlText.lg, controlRadius.lg, "px-4")
|
|
36
|
+
};
|
|
5
37
|
const controlSizes = {
|
|
6
38
|
compact: "h-[var(--control-height)] px-3 py-1 text-sm",
|
|
7
39
|
touch: "h-11 min-h-11 min-w-11 px-4 py-2 text-base"
|
|
8
40
|
};
|
|
9
41
|
const fieldPresentation = cn(focusField, controlMotion, "min-w-0 bg-[var(--bg-input)] 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(--bg-input)] autofill:[-webkit-text-fill-color:var(--text-primary)] autofill:caret-[var(--text-primary)]");
|
|
10
42
|
//#endregion
|
|
11
|
-
export { controlMotion, controlSizes, fieldPresentation };
|
|
43
|
+
export { controlHeight, controlMotion, controlRadius, controlSizes, controlSquare, controlText, fieldPresentation, fieldSizes, fieldTouchText };
|
|
@@ -2,11 +2,12 @@ import * as React from "react";
|
|
|
2
2
|
//#region src/primitives/button.d.ts
|
|
3
3
|
declare const buttonVariants: (props?: ({
|
|
4
4
|
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "sandbox" | "secondary" | null | undefined;
|
|
5
|
-
size?: "compact" | "default" | "icon" | "lg" | "sm" | "touch" | "xl" | null | undefined;
|
|
5
|
+
size?: "compact" | "default" | "icon" | "icon-lg" | "icon-sm" | "lg" | "md" | "sm" | "touch" | "xl" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
8
8
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "sandbox" | null;
|
|
9
|
-
|
|
9
|
+
/** sm 32px, default/md 36px (`--control-height`), lg 44px; icon sizes are squares on the same heights. */
|
|
10
|
+
size?: "default" | "md" | "sm" | "lg" | "xl" | "icon" | "icon-sm" | "icon-lg" | "compact" | "touch" | null;
|
|
10
11
|
asChild?: boolean;
|
|
11
12
|
loading?: boolean;
|
|
12
13
|
children?: React.ReactNode;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { focusRing } from "../lib/focus.js";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
-
import { controlMotion, controlSizes } from "../lib/control-presentation.js";
|
|
3
|
+
import { controlHeight, controlMotion, controlRadius, controlSizes, controlSquare, controlText } from "../lib/control-presentation.js";
|
|
4
4
|
import { Slot } from "@radix-ui/react-slot";
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/primitives/button.tsx
|
|
9
|
-
const buttonVariants = cva(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium
|
|
9
|
+
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
10
|
variants: {
|
|
11
11
|
variant: {
|
|
12
12
|
default: "bg-primary text-primary-foreground hover:bg-primary/90 active:scale-[0.97]",
|
|
@@ -18,11 +18,14 @@ const buttonVariants = cva(`inline-flex items-center justify-center gap-2 whites
|
|
|
18
18
|
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]"
|
|
19
19
|
},
|
|
20
20
|
size: {
|
|
21
|
-
default:
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
default: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
22
|
+
md: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
23
|
+
sm: `${controlHeight.sm} ${controlText.sm} ${controlRadius.sm} px-3`,
|
|
24
|
+
lg: `${controlHeight.lg} ${controlText.lg} ${controlRadius.lg} px-7`,
|
|
24
25
|
xl: "h-13 rounded-xl px-9 text-base",
|
|
25
|
-
icon:
|
|
26
|
+
icon: `${controlSquare.md} ${controlText.md} ${controlRadius.md}`,
|
|
27
|
+
"icon-sm": `${controlSquare.sm} ${controlText.sm} ${controlRadius.sm}`,
|
|
28
|
+
"icon-lg": `${controlSquare.lg} ${controlText.lg} ${controlRadius.lg}`,
|
|
26
29
|
...controlSizes
|
|
27
30
|
}
|
|
28
31
|
},
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/help-text.d.ts
|
|
3
|
+
export interface HelpTextProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
4
|
+
/** `hint` describes a field; `error` reports what is wrong with its value. */
|
|
5
|
+
tone?: "hint" | "error";
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Text under a field. One size (`--font-size-help`, 12px) for every field, so
|
|
9
|
+
* forms across products read the same. Point the field's `aria-describedby` at
|
|
10
|
+
* its `id`; Input and Textarea do this for their `hint` and `error` props.
|
|
11
|
+
*/
|
|
12
|
+
declare const HelpText: React.ForwardRefExoticComponent<HelpTextProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { HelpText };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/primitives/help-text.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Text under a field. One size (`--font-size-help`, 12px) for every field, so
|
|
7
|
+
* forms across products read the same. Point the field's `aria-describedby` at
|
|
8
|
+
* its `id`; Input and Textarea do this for their `hint` and `error` props.
|
|
9
|
+
*/
|
|
10
|
+
const HelpText = React.forwardRef(({ className, tone = "hint", ...props }, ref) => /* @__PURE__ */ jsx("p", {
|
|
11
|
+
ref,
|
|
12
|
+
"data-tone": tone,
|
|
13
|
+
className: cn("text-[length:var(--font-size-help,0.75rem)] leading-4", tone === "error" ? "font-medium text-[var(--surface-danger-text)]" : "text-[var(--text-dim)]", className),
|
|
14
|
+
...props
|
|
15
|
+
}));
|
|
16
|
+
HelpText.displayName = "HelpText";
|
|
17
|
+
//#endregion
|
|
18
|
+
export { HelpText };
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
//#region src/primitives/input.d.ts
|
|
4
4
|
declare const inputVariants: (props?: ({
|
|
5
5
|
variant?: "default" | "error" | "sandbox" | null | undefined;
|
|
6
|
-
size?: "compact" | "default" | "lg" | "sm" | "touch" | null | undefined;
|
|
6
|
+
size?: "compact" | "default" | "lg" | "md" | "sm" | "touch" | null | undefined;
|
|
7
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
8
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
|
|
9
9
|
label?: string;
|
|
@@ -14,8 +14,8 @@ declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttri
|
|
|
14
14
|
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
15
15
|
/** Both values render the same field. */
|
|
16
16
|
variant?: "default" | "sandbox";
|
|
17
|
-
/**
|
|
18
|
-
size?: "default" | "compact" | "touch";
|
|
17
|
+
/** Text, padding and corner from the control scale; the 120px well is unchanged. compact and touch remain. */
|
|
18
|
+
size?: "default" | "sm" | "md" | "lg" | "compact" | "touch";
|
|
19
19
|
label?: string;
|
|
20
20
|
error?: string;
|
|
21
21
|
hint?: string;
|
package/dist/primitives/input.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { focusFieldInvalid } from "../lib/focus.js";
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
|
-
import { controlSizes, fieldPresentation } from "../lib/control-presentation.js";
|
|
4
|
+
import { controlRadius, controlSizes, controlText, fieldPresentation, fieldSizes, fieldTouchText } from "../lib/control-presentation.js";
|
|
5
|
+
import { HelpText } from "./help-text.js";
|
|
5
6
|
import { Label } from "./label.js";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
7
8
|
import * as React from "react";
|
|
8
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
//#region src/primitives/input.tsx
|
|
10
|
-
const inputVariants = cva(cn("flex w-full
|
|
11
|
+
const inputVariants = cva(cn("flex w-full border py-1 placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium file:text-sm", fieldPresentation, fieldTouchText), {
|
|
11
12
|
variants: {
|
|
12
13
|
variant: {
|
|
13
14
|
default: "",
|
|
@@ -15,10 +16,12 @@ const inputVariants = cva(cn("flex w-full rounded-lg border px-4 py-2 text-sm pl
|
|
|
15
16
|
error: focusFieldInvalid
|
|
16
17
|
},
|
|
17
18
|
size: {
|
|
18
|
-
default:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
default: fieldSizes.md,
|
|
20
|
+
md: fieldSizes.md,
|
|
21
|
+
sm: fieldSizes.sm,
|
|
22
|
+
lg: fieldSizes.lg,
|
|
23
|
+
compact: cn(fieldSizes.md, controlSizes.compact),
|
|
24
|
+
touch: cn(fieldSizes.md, controlSizes.touch)
|
|
22
25
|
}
|
|
23
26
|
},
|
|
24
27
|
defaultVariants: {
|
|
@@ -57,14 +60,13 @@ const Input = React.forwardRef(({ className, type, variant, size, label, error,
|
|
|
57
60
|
children: label
|
|
58
61
|
}),
|
|
59
62
|
input,
|
|
60
|
-
error && /* @__PURE__ */ jsx(
|
|
63
|
+
error && /* @__PURE__ */ jsx(HelpText, {
|
|
61
64
|
id: errorId,
|
|
62
|
-
|
|
65
|
+
tone: "error",
|
|
63
66
|
children: error
|
|
64
67
|
}),
|
|
65
|
-
hint && /* @__PURE__ */ jsx(
|
|
68
|
+
hint && /* @__PURE__ */ jsx(HelpText, {
|
|
66
69
|
id: hintId,
|
|
67
|
-
className: "text-[var(--text-dim)] text-sm",
|
|
68
70
|
children: hint
|
|
69
71
|
})
|
|
70
72
|
]
|
|
@@ -78,7 +80,7 @@ const Textarea = React.forwardRef(({ className, variant: _variant, size = "defau
|
|
|
78
80
|
const errorId = error ? `${textareaId}-error` : void 0;
|
|
79
81
|
const textarea = /* @__PURE__ */ jsx("textarea", {
|
|
80
82
|
id: textareaId,
|
|
81
|
-
className: cn("flex min-h-[120px] w-full resize-y
|
|
83
|
+
className: cn("flex min-h-[120px] w-full resize-y border px-3 py-2", "placeholder:text-[var(--text-dim)]", "disabled:cursor-not-allowed disabled:opacity-50", fieldPresentation, fieldTouchText, size === "sm" ? cn(controlText.sm, controlRadius.sm, "px-2.5") : size === "lg" ? cn(controlText.lg, controlRadius.lg, "px-4 py-3") : cn(controlText.md, controlRadius.md), error && "border-[var(--surface-danger-border)] hover:border-[var(--surface-danger-border)] focus:border-[var(--focus-border-danger)] focus:ring-[var(--focus-halo-danger)]", size === "compact" && "min-h-24 px-3 py-2", size === "touch" && "text-base", className),
|
|
82
84
|
ref,
|
|
83
85
|
...props,
|
|
84
86
|
"aria-describedby": descriptionIds(describedBy, hintId, errorId),
|
|
@@ -94,14 +96,13 @@ const Textarea = React.forwardRef(({ className, variant: _variant, size = "defau
|
|
|
94
96
|
children: label
|
|
95
97
|
}),
|
|
96
98
|
textarea,
|
|
97
|
-
error && /* @__PURE__ */ jsx(
|
|
99
|
+
error && /* @__PURE__ */ jsx(HelpText, {
|
|
98
100
|
id: errorId,
|
|
99
|
-
|
|
101
|
+
tone: "error",
|
|
100
102
|
children: error
|
|
101
103
|
}),
|
|
102
|
-
hint && /* @__PURE__ */ jsx(
|
|
104
|
+
hint && /* @__PURE__ */ jsx(HelpText, {
|
|
103
105
|
id: hintId,
|
|
104
|
-
className: "text-[var(--text-dim)] text-sm",
|
|
105
106
|
children: hint
|
|
106
107
|
})
|
|
107
108
|
]
|
package/dist/primitives/label.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as React from "react";
|
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
7
7
|
//#region src/primitives/label.tsx
|
|
8
|
-
const labelVariants = cva("font-medium text-
|
|
8
|
+
const labelVariants = cva("font-medium text-[length:var(--font-size-label,0.875rem)] leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
|
|
9
9
|
const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, {
|
|
10
10
|
ref,
|
|
11
11
|
className: cn(labelVariants(), className),
|
|
@@ -5,8 +5,8 @@ declare const Select: React.FC<SelectPrimitive.SelectProps>;
|
|
|
5
5
|
declare const SelectGroup: React.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
6
6
|
declare const SelectValue: React.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>>;
|
|
7
7
|
declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & {
|
|
8
|
-
/**
|
|
9
|
-
size?: "default" | "compact" | "touch";
|
|
8
|
+
/** The shared control scale: sm 32px, default/md 36px, lg 44px. compact follows density, touch is at least 44px. */
|
|
9
|
+
size?: "default" | "sm" | "md" | "lg" | "compact" | "touch";
|
|
10
10
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
11
11
|
declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
-
import { controlSizes, fieldPresentation } from "../lib/control-presentation.js";
|
|
3
|
+
import { controlSizes, fieldPresentation, fieldSizes, fieldTouchText } from "../lib/control-presentation.js";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
@@ -11,7 +11,7 @@ const SelectGroup = SelectPrimitive.Group;
|
|
|
11
11
|
const SelectValue = SelectPrimitive.Value;
|
|
12
12
|
const SelectTrigger = React.forwardRef(({ className, children, size = "default", ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
|
|
13
13
|
ref,
|
|
14
|
-
className: cn("flex
|
|
14
|
+
className: cn("flex w-full items-center justify-between whitespace-nowrap border py-1 shadow-sm placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", fieldPresentation, fieldTouchText, "data-[placeholder]:text-[var(--text-dim)] [&>span]:min-w-0 [&>span]:text-left", "data-[state=open]:border-primary data-[state=open]:bg-[var(--accent-surface-strong)] [&[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
15
|
...props,
|
|
16
16
|
children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
|
|
17
17
|
asChild: true,
|
package/dist/primitives.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGr
|
|
|
10
10
|
import { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from "./primitives/popover.js";
|
|
11
11
|
import { Slider } from "./primitives/slider.js";
|
|
12
12
|
import { Input, InputProps, Textarea, TextareaProps } from "./primitives/input.js";
|
|
13
|
+
import { HelpText, HelpTextProps } from "./primitives/help-text.js";
|
|
13
14
|
import { Badge, BadgeProps, badgeVariants } from "./primitives/badge.js";
|
|
14
15
|
import { Avatar, AvatarFallback, AvatarImage } from "./primitives/avatar.js";
|
|
15
16
|
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "./primitives/dropdown-menu.js";
|
|
@@ -47,4 +48,4 @@ import { Chip, ChipProps } from "./primitives/chip.js";
|
|
|
47
48
|
import { Metric, MetricProps, MetricStrip, MetricStripProps } from "./primitives/metric-strip.js";
|
|
48
49
|
import { FilterField, FilterFieldProps, Toolbar, ToolbarProps } from "./primitives/toolbar.js";
|
|
49
50
|
import { Logo, LogoProps, TangleKnot } from "@tangle-network/brand";
|
|
50
|
-
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, ArtifactPane, type ArtifactPaneProps, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Button, type ButtonProps, CATEGORY_TONES, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FilterField, type FilterFieldProps, Heading, type HeadingProps, type HeadingVariant, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, Input, type InputProps, Label, Logo, type LogoProps, Metric, type MetricProps, MetricStrip, type MetricStripProps, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, badgeVariants, buttonVariants, initialsOf, toneFor, useTheme, useToast };
|
|
51
|
+
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, ArtifactPane, type ArtifactPaneProps, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Button, type ButtonProps, CATEGORY_TONES, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FilterField, type FilterFieldProps, Heading, type HeadingProps, type HeadingVariant, HelpText, type HelpTextProps, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, Input, type InputProps, Label, Logo, type LogoProps, Metric, type MetricProps, MetricStrip, type MetricStripProps, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, badgeVariants, buttonVariants, initialsOf, toneFor, useTheme, useToast };
|
package/dist/primitives.js
CHANGED
|
@@ -7,6 +7,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./primitive
|
|
|
7
7
|
import { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger } from "./primitives/context-menu.js";
|
|
8
8
|
import { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from "./primitives/popover.js";
|
|
9
9
|
import { Slider } from "./primitives/slider.js";
|
|
10
|
+
import { HelpText } from "./primitives/help-text.js";
|
|
10
11
|
import { Label } from "./primitives/label.js";
|
|
11
12
|
import { Input, Textarea } from "./primitives/input.js";
|
|
12
13
|
import { Badge, badgeVariants } from "./primitives/badge.js";
|
|
@@ -47,4 +48,4 @@ import { IconTile, initialsOf } from "./primitives/icon-tile.js";
|
|
|
47
48
|
import { Metric, MetricStrip } from "./primitives/metric-strip.js";
|
|
48
49
|
import { FilterField, Toolbar } from "./primitives/toolbar.js";
|
|
49
50
|
import { Logo, TangleKnot } from "@tangle-network/brand";
|
|
50
|
-
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FilterField, Heading, IconTile, InlineCode, Input, Label, Logo, Metric, MetricStrip, PageHeader, PageShell, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ToastContainer, ToastProvider, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, badgeVariants, buttonVariants, initialsOf, toneFor, useTheme, useToast };
|
|
51
|
+
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, Avatar, AvatarFallback, AvatarImage, Badge, Button, CATEGORY_TONES, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FilterField, Heading, HelpText, IconTile, InlineCode, Input, Label, Logo, Metric, MetricStrip, PageHeader, PageShell, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, 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, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, ToastContainer, ToastProvider, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, badgeVariants, buttonVariants, initialsOf, toneFor, useTheme, useToast };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/ui",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.28.0",
|
|
4
4
|
"description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"peerDependencies": {
|
|
150
150
|
"@hocuspocus/provider": ">=2.15.0 <5.0.0",
|
|
151
151
|
"@nanostores/react": ">=0.8.4 <3.0.0",
|
|
152
|
-
"@tangle-network/brand": "^1.
|
|
152
|
+
"@tangle-network/brand": "^1.18.0",
|
|
153
153
|
"@tiptap/core": ">=3.20.4 <4.0.0",
|
|
154
154
|
"@tiptap/extension-collaboration": ">=3.20.4 <4.0.0",
|
|
155
155
|
"@tiptap/extension-collaboration-caret": ">=3.7.0 <4.0.0",
|
|
@@ -6,8 +6,55 @@ import { cn } from "./utils";
|
|
|
6
6
|
export const controlMotion =
|
|
7
7
|
"duration-[var(--duration-fast)] ease-[var(--ease-standard)] motion-reduce:transition-none motion-reduce:duration-0";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The control scale. Button, Input, Textarea and SelectTrigger take the same
|
|
11
|
+
* `sm | md | lg` sizes and read the same Brand tokens, so any row of controls
|
|
12
|
+
* at one size shares a height, a text size and a corner. md follows the
|
|
13
|
+
* `--control-height` density knob. The fallbacks keep an app on an older
|
|
14
|
+
* Brand stylesheet at the same pixels.
|
|
15
|
+
*/
|
|
16
|
+
export type ControlSize = "sm" | "md" | "lg";
|
|
17
|
+
|
|
18
|
+
export const controlHeight = {
|
|
19
|
+
sm: "h-[var(--control-height-sm,2rem)]",
|
|
20
|
+
md: "h-[var(--control-height,2.25rem)]",
|
|
21
|
+
lg: "h-[var(--control-height-lg,2.75rem)]",
|
|
22
|
+
} as const satisfies Record<ControlSize, string>;
|
|
23
|
+
|
|
24
|
+
export const controlText = {
|
|
25
|
+
sm: "text-[length:var(--control-text-sm,0.75rem)]",
|
|
26
|
+
md: "text-[length:var(--control-text-md,0.875rem)]",
|
|
27
|
+
lg: "text-[length:var(--control-text-lg,1rem)]",
|
|
28
|
+
} as const satisfies Record<ControlSize, string>;
|
|
29
|
+
|
|
30
|
+
export const controlRadius = {
|
|
31
|
+
sm: "rounded-md",
|
|
32
|
+
md: "rounded-lg",
|
|
33
|
+
lg: "rounded-lg",
|
|
34
|
+
} as const satisfies Record<ControlSize, string>;
|
|
35
|
+
|
|
36
|
+
/** Square icon-only controls on the same heights. */
|
|
37
|
+
export const controlSquare = {
|
|
38
|
+
sm: "size-[var(--control-height-sm,2rem)]",
|
|
39
|
+
md: "size-[var(--control-height,2.25rem)]",
|
|
40
|
+
lg: "size-[var(--control-height-lg,2.75rem)]",
|
|
41
|
+
} as const satisfies Record<ControlSize, string>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Field text never drops below 16px on a coarse pointer: iOS Safari zooms the
|
|
45
|
+
* page on focus for anything smaller.
|
|
46
|
+
*/
|
|
47
|
+
export const fieldTouchText = "pointer-coarse:text-base";
|
|
48
|
+
|
|
49
|
+
/** Field sizes: the control scale with field padding. */
|
|
50
|
+
export const fieldSizes = {
|
|
51
|
+
sm: cn(controlHeight.sm, controlText.sm, controlRadius.sm, "px-2.5"),
|
|
52
|
+
md: cn(controlHeight.md, controlText.md, controlRadius.md, "px-3"),
|
|
53
|
+
lg: cn(controlHeight.lg, controlText.lg, controlRadius.lg, "px-4"),
|
|
54
|
+
} as const satisfies Record<ControlSize, string>;
|
|
55
|
+
|
|
56
|
+
// Explicit opt-in sizes kept for existing callers. Compact follows the
|
|
57
|
+
// consumer's density token (md); touch is lg with a guaranteed 44px minimum.
|
|
11
58
|
export const controlSizes = {
|
|
12
59
|
compact: "h-[var(--control-height)] px-3 py-1 text-sm",
|
|
13
60
|
touch: "h-11 min-h-11 min-w-11 px-4 py-2 text-base",
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { Slot } from "@radix-ui/react-slot";
|
|
2
2
|
import { cva } from "class-variance-authority";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { controlMotion, controlSizes } from "../lib/control-presentation";
|
|
4
|
+
import { controlHeight, controlMotion, controlRadius, controlSizes, controlSquare, controlText } from "../lib/control-presentation";
|
|
5
5
|
import { focusRing } from "../lib/focus";
|
|
6
6
|
import { cn } from "../lib/utils";
|
|
7
7
|
|
|
8
|
+
// Sizes follow the shared control scale (control-presentation.ts): sm, md and
|
|
9
|
+
// lg match Input, Textarea and SelectTrigger at the same size. xl is a display
|
|
10
|
+
// call to action outside that scale.
|
|
8
11
|
const buttonVariants = cva(
|
|
9
|
-
`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium
|
|
12
|
+
`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
13
|
{
|
|
11
14
|
variants: {
|
|
12
15
|
variant: {
|
|
@@ -25,11 +28,14 @@ const buttonVariants = cva(
|
|
|
25
28
|
"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]",
|
|
26
29
|
},
|
|
27
30
|
size: {
|
|
28
|
-
default:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
default: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
32
|
+
md: `${controlHeight.md} ${controlText.md} ${controlRadius.md} px-4 py-2`,
|
|
33
|
+
sm: `${controlHeight.sm} ${controlText.sm} ${controlRadius.sm} px-3`,
|
|
34
|
+
lg: `${controlHeight.lg} ${controlText.lg} ${controlRadius.lg} px-7`,
|
|
31
35
|
xl: "h-13 rounded-xl px-9 text-base",
|
|
32
|
-
icon:
|
|
36
|
+
icon: `${controlSquare.md} ${controlText.md} ${controlRadius.md}`,
|
|
37
|
+
"icon-sm": `${controlSquare.sm} ${controlText.sm} ${controlRadius.sm}`,
|
|
38
|
+
"icon-lg": `${controlSquare.lg} ${controlText.lg} ${controlRadius.lg}`,
|
|
33
39
|
...controlSizes,
|
|
34
40
|
},
|
|
35
41
|
},
|
|
@@ -43,7 +49,8 @@ const buttonVariants = cva(
|
|
|
43
49
|
export interface ButtonProps
|
|
44
50
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
45
51
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "sandbox" | null;
|
|
46
|
-
|
|
52
|
+
/** sm 32px, default/md 36px (`--control-height`), lg 44px; icon sizes are squares on the same heights. */
|
|
53
|
+
size?: "default" | "md" | "sm" | "lg" | "xl" | "icon" | "icon-sm" | "icon-lg" | "compact" | "touch" | null;
|
|
47
54
|
asChild?: boolean;
|
|
48
55
|
loading?: boolean;
|
|
49
56
|
children?: React.ReactNode;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
3
|
import { Button } from "./button";
|
|
4
|
+
import { HelpText } from "./help-text";
|
|
4
5
|
import { Input, Textarea } from "./input";
|
|
6
|
+
import { Label } from "./label";
|
|
5
7
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select";
|
|
6
8
|
import { Metric, MetricStrip } from "./metric-strip";
|
|
7
9
|
|
|
@@ -11,7 +13,7 @@ function Contract() {
|
|
|
11
13
|
return (
|
|
12
14
|
<main className="mx-auto max-w-5xl space-y-6 bg-background p-4 text-foreground" data-presentation-contract>
|
|
13
15
|
<h1 className="text-xl font-semibold">Field and metric presentation</h1>
|
|
14
|
-
{(["
|
|
16
|
+
{(["sm", "md", "lg", "compact", "touch"] as const).map((size) => (
|
|
15
17
|
<section key={size} data-size-row={size} className="space-y-2">
|
|
16
18
|
<h2 className="font-semibold">{size}</h2>
|
|
17
19
|
<div className="flex flex-wrap items-end gap-3">
|
|
@@ -24,10 +26,17 @@ function Contract() {
|
|
|
24
26
|
</SelectContent>
|
|
25
27
|
</Select>
|
|
26
28
|
<Button size={size} onClick={() => setActions((value) => value + 1)}>Save</Button>
|
|
29
|
+
<Button size={size} variant="outline">Cancel</Button>
|
|
27
30
|
</div>
|
|
28
31
|
<Textarea size={size} aria-label={`${size} notes`} placeholder="Details" />
|
|
29
32
|
</section>
|
|
30
33
|
))}
|
|
34
|
+
<section className="max-w-sm space-y-1.5" data-form-text>
|
|
35
|
+
<Label htmlFor="workspace-name">Workspace name</Label>
|
|
36
|
+
<Input id="workspace-name" aria-describedby="workspace-name-hint" placeholder="Acme" />
|
|
37
|
+
<HelpText id="workspace-name-hint">Shown to everyone you invite.</HelpText>
|
|
38
|
+
<HelpText tone="error">This name is already taken.</HelpText>
|
|
39
|
+
</section>
|
|
31
40
|
<section className="space-y-2" data-state-controls>
|
|
32
41
|
<h2 className="font-semibold">States and actions</h2>
|
|
33
42
|
<Input label="Email" autoComplete="email" name="email" defaultValue="reader@example.test" />
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { cleanup, render, screen } from "@testing-library/react";
|
|
3
3
|
import { afterEach, describe, expect, it } from "vitest";
|
|
4
|
-
import { controlMotion, fieldPresentation } from "../lib/control-presentation";
|
|
4
|
+
import { controlHeight, controlText, controlMotion, fieldPresentation } from "../lib/control-presentation";
|
|
5
|
+
import { HelpText } from "./help-text";
|
|
6
|
+
import { Label } from "./label";
|
|
5
7
|
import { Button, buttonVariants } from "./button";
|
|
6
8
|
import { Input, Textarea } from "./input";
|
|
7
9
|
import { Select, SelectTrigger, SelectValue } from "./select";
|
|
@@ -21,16 +23,39 @@ describe("shared control presentation", () => {
|
|
|
21
23
|
expect(controlMotion).toContain("motion-reduce:duration-0");
|
|
22
24
|
});
|
|
23
25
|
|
|
24
|
-
it("
|
|
25
|
-
const
|
|
26
|
-
|
|
26
|
+
it("puts Button, Input, Textarea and SelectTrigger on one height and text scale", () => {
|
|
27
|
+
const classes = (name: string) => screen.getByLabelText(name).className.split(" ");
|
|
28
|
+
const { rerender } = render(<><Input aria-label="Input" /><Textarea aria-label="Textarea" /><Button aria-label="Action">Action</Button><Select><SelectTrigger aria-label="Select"><SelectValue /></SelectTrigger></Select></>);
|
|
29
|
+
// The default is md for every control: one 36px height, one 14px text size, one corner.
|
|
30
|
+
for (const name of ["Input", "Action", "Select"]) {
|
|
31
|
+
expect(classes(name)).toContain(controlHeight.md);
|
|
32
|
+
expect(classes(name)).toContain(controlText.md);
|
|
33
|
+
expect(classes(name)).toContain("rounded-lg");
|
|
34
|
+
}
|
|
35
|
+
expect(classes("Textarea")).toContain(controlText.md);
|
|
27
36
|
expect(screen.getByLabelText("Textarea").className).toContain("min-h-[120px]");
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
for (const size of ["sm", "md", "lg"] as const) {
|
|
38
|
+
rerender(<><Input size={size} aria-label="Input" /><Textarea size={size} aria-label="Textarea" /><Button size={size} aria-label="Action">Action</Button><Select><SelectTrigger size={size} aria-label="Select"><SelectValue /></SelectTrigger></Select></>);
|
|
39
|
+
for (const name of ["Input", "Action", "Select"]) {
|
|
40
|
+
expect(classes(name), `${name} ${size}`).toContain(controlHeight[size]);
|
|
41
|
+
expect(classes(name), `${name} ${size}`).toContain(controlText[size]);
|
|
42
|
+
expect(classes(name), `${name} ${size}`).toContain(size === "sm" ? "rounded-md" : "rounded-lg");
|
|
43
|
+
expect(screen.getByLabelText(name)).not.toHaveAttribute("size");
|
|
44
|
+
}
|
|
45
|
+
expect(classes("Textarea")).toContain(controlText[size]);
|
|
46
|
+
}
|
|
47
|
+
// Fields never drop below 16px on a coarse pointer (iOS zooms on focus otherwise).
|
|
48
|
+
for (const name of ["Input", "Textarea", "Select"]) expect(classes(name)).toContain("pointer-coarse:text-base");
|
|
49
|
+
expect(classes("Action")).not.toContain("pointer-coarse:text-base");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("keeps the explicit compact and touch sizes", () => {
|
|
53
|
+
const { rerender } = render(<><Input size="compact" aria-label="Input" /><Button size="compact">Action</Button><Select><SelectTrigger size="compact" aria-label="Select"><SelectValue /></SelectTrigger></Select></>);
|
|
30
54
|
for (const size of ["compact", "touch"] as const) {
|
|
31
55
|
rerender(<><Input size={size} aria-label="Input" /><Textarea size={size} aria-label="Textarea" /><Button size={size}>Action</Button><Select><SelectTrigger size={size} aria-label="Select"><SelectValue /></SelectTrigger></Select></>);
|
|
32
56
|
for (const name of ["Input", "Select"]) {
|
|
33
57
|
expect(screen.getByLabelText(name).className).toContain(size === "compact" ? "h-[var(--control-height)]" : "min-h-11");
|
|
58
|
+
expect(screen.getByLabelText(name).className.split(" ")).toContain("rounded-lg");
|
|
34
59
|
expect(screen.getByLabelText(name)).not.toHaveAttribute("size");
|
|
35
60
|
}
|
|
36
61
|
expect(screen.getByText("Action").className).toContain(size === "compact" ? "h-[var(--control-height)]" : "min-h-11");
|
|
@@ -38,6 +63,26 @@ describe("shared control presentation", () => {
|
|
|
38
63
|
}
|
|
39
64
|
});
|
|
40
65
|
|
|
66
|
+
it("gives icon buttons squares on the same heights", () => {
|
|
67
|
+
render(<><Button size="icon-sm" aria-label="Small" /><Button size="icon" aria-label="Medium" /><Button size="icon-lg" aria-label="Large" /></>);
|
|
68
|
+
expect(screen.getByLabelText("Small").className).toContain("size-[var(--control-height-sm,2rem)]");
|
|
69
|
+
expect(screen.getByLabelText("Medium").className).toContain("size-[var(--control-height,2.25rem)]");
|
|
70
|
+
expect(screen.getByLabelText("Large").className).toContain("size-[var(--control-height-lg,2.75rem)]");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("renders labels and help text at one size each, and wires hint and error to the field", () => {
|
|
74
|
+
render(<><Label htmlFor="x">Name</Label><HelpText>Plain</HelpText><Input label="Email" hint="We never share it" error="Enter an address" /></>);
|
|
75
|
+
expect(screen.getByText("Name").className).toContain("text-[length:var(--font-size-label,0.875rem)]");
|
|
76
|
+
for (const text of ["Plain", "We never share it", "Enter an address"]) {
|
|
77
|
+
expect(screen.getByText(text).className).toContain("text-[length:var(--font-size-help,0.75rem)]");
|
|
78
|
+
}
|
|
79
|
+
expect(screen.getByText("Enter an address")).toHaveAttribute("data-tone", "error");
|
|
80
|
+
const field = screen.getByLabelText("Email");
|
|
81
|
+
const described = field.getAttribute("aria-describedby")!.split(" ");
|
|
82
|
+
expect(described).toContain(screen.getByText("We never share it").id);
|
|
83
|
+
expect(described).toContain(screen.getByText("Enter an address").id);
|
|
84
|
+
});
|
|
85
|
+
|
|
41
86
|
it("preserves field and trigger refs, caller overrides, invalid/disabled and autofill attributes", () => {
|
|
42
87
|
const input = React.createRef<HTMLInputElement>();
|
|
43
88
|
const textarea = React.createRef<HTMLTextAreaElement>();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../lib/utils";
|
|
3
|
+
|
|
4
|
+
export interface HelpTextProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
5
|
+
/** `hint` describes a field; `error` reports what is wrong with its value. */
|
|
6
|
+
tone?: "hint" | "error";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Text under a field. One size (`--font-size-help`, 12px) for every field, so
|
|
11
|
+
* forms across products read the same. Point the field's `aria-describedby` at
|
|
12
|
+
* its `id`; Input and Textarea do this for their `hint` and `error` props.
|
|
13
|
+
*/
|
|
14
|
+
const HelpText = React.forwardRef<HTMLParagraphElement, HelpTextProps>(
|
|
15
|
+
({ className, tone = "hint", ...props }, ref) => (
|
|
16
|
+
<p
|
|
17
|
+
ref={ref}
|
|
18
|
+
data-tone={tone}
|
|
19
|
+
className={cn(
|
|
20
|
+
"text-[length:var(--font-size-help,0.75rem)] leading-4",
|
|
21
|
+
tone === "error" ? "font-medium text-[var(--surface-danger-text)]" : "text-[var(--text-dim)]",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
),
|
|
27
|
+
);
|
|
28
|
+
HelpText.displayName = "HelpText";
|
|
29
|
+
|
|
30
|
+
export { HelpText };
|
package/src/primitives/index.ts
CHANGED
|
@@ -65,6 +65,9 @@ export { Slider } from "./slider";
|
|
|
65
65
|
export { Input, Textarea } from "./input";
|
|
66
66
|
export type { InputProps, TextareaProps } from "./input";
|
|
67
67
|
|
|
68
|
+
export { HelpText } from "./help-text";
|
|
69
|
+
export type { HelpTextProps } from "./help-text";
|
|
70
|
+
|
|
68
71
|
export { Badge, badgeVariants } from "./badge";
|
|
69
72
|
export type { BadgeProps } from "./badge";
|
|
70
73
|
|
package/src/primitives/input.tsx
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { controlSizes, fieldPresentation } from "../lib/control-presentation";
|
|
4
|
+
import { controlRadius, controlSizes, controlText, fieldPresentation, fieldSizes, fieldTouchText } from "../lib/control-presentation";
|
|
5
5
|
import { focusFieldInvalid } from "../lib/focus";
|
|
6
6
|
import { cn } from "../lib/utils";
|
|
7
|
+
import { HelpText } from "./help-text";
|
|
7
8
|
import { Label } from "./label";
|
|
8
9
|
|
|
9
10
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
10
11
|
|
|
12
|
+
// Sizes follow the shared control scale (control-presentation.ts), so an Input
|
|
13
|
+
// and a Button at the same size share a height, text size and corner.
|
|
11
14
|
const inputVariants = cva(
|
|
12
15
|
cn(
|
|
13
|
-
"flex w-full
|
|
16
|
+
"flex w-full border py-1 placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium file:text-sm",
|
|
14
17
|
fieldPresentation,
|
|
18
|
+
fieldTouchText,
|
|
15
19
|
),
|
|
16
20
|
{
|
|
17
21
|
variants: {
|
|
@@ -22,10 +26,12 @@ const inputVariants = cva(
|
|
|
22
26
|
error: focusFieldInvalid,
|
|
23
27
|
},
|
|
24
28
|
size: {
|
|
25
|
-
default:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
default: fieldSizes.md,
|
|
30
|
+
md: fieldSizes.md,
|
|
31
|
+
sm: fieldSizes.sm,
|
|
32
|
+
lg: fieldSizes.lg,
|
|
33
|
+
compact: cn(fieldSizes.md, controlSizes.compact),
|
|
34
|
+
touch: cn(fieldSizes.md, controlSizes.touch),
|
|
29
35
|
}
|
|
30
36
|
},
|
|
31
37
|
defaultVariants: {
|
|
@@ -79,8 +85,8 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
79
85
|
<div className="w-full space-y-1.5">
|
|
80
86
|
{label && <Label htmlFor={inputId} className="block">{label}</Label>}
|
|
81
87
|
{input}
|
|
82
|
-
{error && <
|
|
83
|
-
{hint && <
|
|
88
|
+
{error && <HelpText id={errorId} tone="error">{error}</HelpText>}
|
|
89
|
+
{hint && <HelpText id={hintId}>{hint}</HelpText>}
|
|
84
90
|
</div>
|
|
85
91
|
);
|
|
86
92
|
},
|
|
@@ -91,8 +97,8 @@ export interface TextareaProps
|
|
|
91
97
|
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
92
98
|
/** Both values render the same field. */
|
|
93
99
|
variant?: "default" | "sandbox";
|
|
94
|
-
/**
|
|
95
|
-
size?: "default" | "compact" | "touch";
|
|
100
|
+
/** Text, padding and corner from the control scale; the 120px well is unchanged. compact and touch remain. */
|
|
101
|
+
size?: "default" | "sm" | "md" | "lg" | "compact" | "touch";
|
|
96
102
|
label?: string;
|
|
97
103
|
error?: string;
|
|
98
104
|
hint?: string;
|
|
@@ -116,10 +122,12 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
116
122
|
<textarea
|
|
117
123
|
id={textareaId}
|
|
118
124
|
className={cn(
|
|
119
|
-
"flex min-h-[120px] w-full resize-y
|
|
125
|
+
"flex min-h-[120px] w-full resize-y border px-3 py-2",
|
|
120
126
|
"placeholder:text-[var(--text-dim)]",
|
|
121
127
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
122
128
|
fieldPresentation,
|
|
129
|
+
fieldTouchText,
|
|
130
|
+
size === "sm" ? cn(controlText.sm, controlRadius.sm, "px-2.5") : size === "lg" ? cn(controlText.lg, controlRadius.lg, "px-4 py-3") : cn(controlText.md, controlRadius.md),
|
|
123
131
|
error && focusFieldInvalid,
|
|
124
132
|
size === "compact" && "min-h-24 px-3 py-2",
|
|
125
133
|
size === "touch" && "text-base",
|
|
@@ -138,8 +146,8 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
138
146
|
<div className="w-full space-y-1.5">
|
|
139
147
|
{label && <Label htmlFor={textareaId} className="block">{label}</Label>}
|
|
140
148
|
{textarea}
|
|
141
|
-
{error && <
|
|
142
|
-
{hint && <
|
|
149
|
+
{error && <HelpText id={errorId} tone="error">{error}</HelpText>}
|
|
150
|
+
{hint && <HelpText id={hintId}>{hint}</HelpText>}
|
|
143
151
|
</div>
|
|
144
152
|
);
|
|
145
153
|
},
|
package/src/primitives/label.tsx
CHANGED
|
@@ -5,8 +5,9 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { cn } from "../lib/utils";
|
|
7
7
|
|
|
8
|
+
// One label size (`--font-size-label`, 14px) for every field size.
|
|
8
9
|
const labelVariants = cva(
|
|
9
|
-
"font-medium text-
|
|
10
|
+
"font-medium text-[length:var(--font-size-label,0.875rem)] leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
10
11
|
);
|
|
11
12
|
|
|
12
13
|
const Label = React.forwardRef<
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
4
4
|
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
5
5
|
import * as React from "react";
|
|
6
|
-
import { controlSizes, fieldPresentation } from "../lib/control-presentation";
|
|
6
|
+
import { controlSizes, fieldPresentation, fieldSizes, fieldTouchText } from "../lib/control-presentation";
|
|
7
7
|
import { cn } from "../lib/utils";
|
|
8
8
|
|
|
9
9
|
const Select = SelectPrimitive.Root;
|
|
@@ -15,19 +15,20 @@ const SelectValue = SelectPrimitive.Value;
|
|
|
15
15
|
const SelectTrigger = React.forwardRef<
|
|
16
16
|
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
|
17
17
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
|
|
18
|
-
/**
|
|
19
|
-
size?: "default" | "compact" | "touch";
|
|
18
|
+
/** The shared control scale: sm 32px, default/md 36px, lg 44px. compact follows density, touch is at least 44px. */
|
|
19
|
+
size?: "default" | "sm" | "md" | "lg" | "compact" | "touch";
|
|
20
20
|
}
|
|
21
21
|
>(({ className, children, size = "default", ...props }, ref) => (
|
|
22
22
|
<SelectPrimitive.Trigger
|
|
23
23
|
ref={ref}
|
|
24
24
|
className={cn(
|
|
25
|
-
"flex
|
|
25
|
+
"flex w-full items-center justify-between whitespace-nowrap border py-1 shadow-sm placeholder:text-[var(--text-dim)] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
26
26
|
fieldPresentation,
|
|
27
|
+
fieldTouchText,
|
|
27
28
|
"data-[placeholder]:text-[var(--text-dim)] [&>span]:min-w-0 [&>span]:text-left",
|
|
28
29
|
// The designed open state: accent border and surface while the menu is up.
|
|
29
30
|
"data-[state=open]:border-primary data-[state=open]:bg-[var(--accent-surface-strong)] [&[data-state=open]>svg]:rotate-180 [&>svg]:transition-transform",
|
|
30
|
-
size
|
|
31
|
+
size === "compact" || size === "touch" ? cn(fieldSizes.md, controlSizes[size]) : fieldSizes[size === "default" ? "md" : size],
|
|
31
32
|
className,
|
|
32
33
|
)}
|
|
33
34
|
{...props}
|