@adres/mgda-ui 0.0.0-stage → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/brand-knowledge.json +451 -0
- package/knowledge/accordion.md +135 -0
- package/knowledge/activity-rings.md +123 -0
- package/knowledge/alert.md +184 -0
- package/knowledge/answer-actions.md +217 -0
- package/knowledge/aspect-ratio.md +82 -0
- package/knowledge/avatar.md +158 -0
- package/knowledge/badge.md +172 -0
- package/knowledge/bar-graph.md +167 -0
- package/knowledge/bento-grid.md +115 -0
- package/knowledge/blockquote.md +153 -0
- package/knowledge/box-list.md +177 -0
- package/knowledge/bullet-list.md +128 -0
- package/knowledge/button-group.md +179 -0
- package/knowledge/button.md +231 -0
- package/knowledge/calendar.md +168 -0
- package/knowledge/card.md +321 -0
- package/knowledge/cards-nav.md +170 -0
- package/knowledge/chain-of-thought.md +164 -0
- package/knowledge/chat-container.md +135 -0
- package/knowledge/chat-message.md +224 -0
- package/knowledge/checkbox-card.md +172 -0
- package/knowledge/checkbox.md +111 -0
- package/knowledge/citations.md +241 -0
- package/knowledge/combobox.md +265 -0
- package/knowledge/countdown-pill.md +153 -0
- package/knowledge/cta.md +118 -0
- package/knowledge/data-list.md +173 -0
- package/knowledge/data-table.md +220 -0
- package/knowledge/dialog.md +249 -0
- package/knowledge/drawer.md +236 -0
- package/knowledge/dropdown-menu.md +238 -0
- package/knowledge/dropzone.md +153 -0
- package/knowledge/email-chips-input.md +161 -0
- package/knowledge/empty-state.md +106 -0
- package/knowledge/entity-header.md +166 -0
- package/knowledge/feature-grid.md +120 -0
- package/knowledge/feedback-bar.md +127 -0
- package/knowledge/footer.md +116 -0
- package/knowledge/heading.md +189 -0
- package/knowledge/hero.md +361 -0
- package/knowledge/input-button.md +187 -0
- package/knowledge/input-group.md +185 -0
- package/knowledge/input.md +256 -0
- package/knowledge/inset.md +177 -0
- package/knowledge/kpi-card.md +206 -0
- package/knowledge/list-nav.md +181 -0
- package/knowledge/logo-cloud.md +102 -0
- package/knowledge/media-gallery.md +158 -0
- package/knowledge/message-actions.md +175 -0
- package/knowledge/nav-sidebar.md +225 -0
- package/knowledge/number-stepper.md +159 -0
- package/knowledge/page-header.md +109 -0
- package/knowledge/pagination.md +225 -0
- package/knowledge/popover.md +159 -0
- package/knowledge/pricing.md +132 -0
- package/knowledge/progress.md +156 -0
- package/knowledge/prompt-input.md +337 -0
- package/knowledge/prompt-suggestions.md +168 -0
- package/knowledge/quota-bar.md +160 -0
- package/knowledge/quote.md +116 -0
- package/knowledge/radio-card.md +172 -0
- package/knowledge/radio-group.md +135 -0
- package/knowledge/reasoning.md +142 -0
- package/knowledge/search.md +131 -0
- package/knowledge/section-nav.md +162 -0
- package/knowledge/segmented-control.md +181 -0
- package/knowledge/select-button.md +205 -0
- package/knowledge/select.md +210 -0
- package/knowledge/separator.md +75 -0
- package/knowledge/shimmer-text.md +140 -0
- package/knowledge/sidebar.md +227 -0
- package/knowledge/skeleton.md +142 -0
- package/knowledge/slider.md +133 -0
- package/knowledge/slideshow.md +159 -0
- package/knowledge/source.md +156 -0
- package/knowledge/spinner.md +120 -0
- package/knowledge/stat-strip.md +128 -0
- package/knowledge/stats.md +117 -0
- package/knowledge/step-indicator.md +157 -0
- package/knowledge/switch.md +88 -0
- package/knowledge/table.md +190 -0
- package/knowledge/tabs.md +169 -0
- package/knowledge/testimonials.md +115 -0
- package/knowledge/text-link.md +192 -0
- package/knowledge/text.md +194 -0
- package/knowledge/thinking-bar.md +115 -0
- package/knowledge/thinking-steps.md +140 -0
- package/knowledge/toaster.md +127 -0
- package/knowledge/toggle.md +113 -0
- package/knowledge/tool-call-card.md +241 -0
- package/knowledge/tooltip.md +120 -0
- package/knowledge/top-nav.md +138 -0
- package/knowledge.json +19854 -0
- package/package.json +94 -4
- package/src/components/accordion.stories.tsx +46 -0
- package/src/components/accordion.tsx +74 -0
- package/src/components/activity-rings.stories.tsx +73 -0
- package/src/components/activity-rings.tsx +121 -0
- package/src/components/alert.stories.tsx +43 -0
- package/src/components/alert.tsx +132 -0
- package/src/components/answer-actions.stories.tsx +54 -0
- package/src/components/answer-actions.test.tsx +37 -0
- package/src/components/answer-actions.tsx +313 -0
- package/src/components/aspect-ratio.stories.tsx +32 -0
- package/src/components/aspect-ratio.tsx +5 -0
- package/src/components/avatar.stories.tsx +40 -0
- package/src/components/avatar.tsx +154 -0
- package/src/components/badge.stories.tsx +27 -0
- package/src/components/badge.tsx +63 -0
- package/src/components/bar-graph.stories.tsx +28 -0
- package/src/components/bar-graph.tsx +204 -0
- package/src/components/bento-grid.stories.tsx +23 -0
- package/src/components/bento-grid.tsx +67 -0
- package/src/components/blockquote.stories.tsx +28 -0
- package/src/components/blockquote.tsx +88 -0
- package/src/components/box-list.stories.tsx +25 -0
- package/src/components/box-list.tsx +108 -0
- package/src/components/bullet-list.stories.tsx +22 -0
- package/src/components/bullet-list.tsx +101 -0
- package/src/components/button-group.stories.tsx +31 -0
- package/src/components/button-group.tsx +156 -0
- package/src/components/button.stories.tsx +66 -0
- package/src/components/button.test.ts +17 -0
- package/src/components/button.tsx +139 -0
- package/src/components/calendar.stories.tsx +25 -0
- package/src/components/calendar.tsx +367 -0
- package/src/components/card.stories.tsx +44 -0
- package/src/components/card.tsx +392 -0
- package/src/components/cards-nav.stories.tsx +35 -0
- package/src/components/cards-nav.tsx +115 -0
- package/src/components/chain-of-thought.stories.tsx +67 -0
- package/src/components/chain-of-thought.test.tsx +50 -0
- package/src/components/chain-of-thought.tsx +170 -0
- package/src/components/chat-container.stories.tsx +47 -0
- package/src/components/chat-container.test.tsx +49 -0
- package/src/components/chat-container.tsx +222 -0
- package/src/components/chat-message.stories.tsx +52 -0
- package/src/components/chat-message.test.tsx +36 -0
- package/src/components/chat-message.tsx +163 -0
- package/src/components/checkbox-card.stories.tsx +27 -0
- package/src/components/checkbox-card.tsx +200 -0
- package/src/components/checkbox.stories.tsx +26 -0
- package/src/components/checkbox.tsx +61 -0
- package/src/components/citations.stories.tsx +64 -0
- package/src/components/citations.test.tsx +61 -0
- package/src/components/citations.tsx +220 -0
- package/src/components/combobox.stories.tsx +184 -0
- package/src/components/combobox.test.tsx +82 -0
- package/src/components/combobox.tsx +407 -0
- package/src/components/countdown-pill.stories.tsx +24 -0
- package/src/components/countdown-pill.tsx +129 -0
- package/src/components/cta.stories.tsx +29 -0
- package/src/components/cta.tsx +52 -0
- package/src/components/data-list.stories.tsx +50 -0
- package/src/components/data-list.test.tsx +35 -0
- package/src/components/data-list.tsx +181 -0
- package/src/components/data-table.stories.tsx +29 -0
- package/src/components/data-table.tsx +200 -0
- package/src/components/dialog.stories.tsx +42 -0
- package/src/components/dialog.tsx +200 -0
- package/src/components/drawer.stories.tsx +48 -0
- package/src/components/drawer.tsx +385 -0
- package/src/components/dropdown-menu.stories.tsx +41 -0
- package/src/components/dropdown-menu.tsx +252 -0
- package/src/components/dropzone.stories.tsx +19 -0
- package/src/components/dropzone.tsx +250 -0
- package/src/components/email-chips-input.stories.tsx +135 -0
- package/src/components/email-chips-input.tsx +210 -0
- package/src/components/empty-state.stories.tsx +22 -0
- package/src/components/empty-state.tsx +35 -0
- package/src/components/entity-header.stories.tsx +43 -0
- package/src/components/entity-header.test.tsx +35 -0
- package/src/components/entity-header.tsx +92 -0
- package/src/components/feature-grid.stories.tsx +25 -0
- package/src/components/feature-grid.tsx +87 -0
- package/src/components/feedback-bar.stories.tsx +25 -0
- package/src/components/feedback-bar.test.tsx +24 -0
- package/src/components/feedback-bar.tsx +62 -0
- package/src/components/footer.stories.tsx +23 -0
- package/src/components/footer.tsx +78 -0
- package/src/components/heading.stories.tsx +45 -0
- package/src/components/heading.test.tsx +22 -0
- package/src/components/heading.tsx +77 -0
- package/src/components/hero.stories.tsx +38 -0
- package/src/components/hero.tsx +498 -0
- package/src/components/input-button.stories.tsx +19 -0
- package/src/components/input-button.tsx +112 -0
- package/src/components/input-group.stories.tsx +38 -0
- package/src/components/input-group.tsx +157 -0
- package/src/components/input.stories.tsx +31 -0
- package/src/components/input.tsx +284 -0
- package/src/components/inset.stories.tsx +29 -0
- package/src/components/inset.tsx +70 -0
- package/src/components/kpi-card.stories.tsx +29 -0
- package/src/components/kpi-card.tsx +284 -0
- package/src/components/list-nav.stories.tsx +22 -0
- package/src/components/list-nav.tsx +145 -0
- package/src/components/logo-cloud.stories.tsx +23 -0
- package/src/components/logo-cloud.tsx +42 -0
- package/src/components/media-gallery.stories.tsx +25 -0
- package/src/components/media-gallery.tsx +347 -0
- package/src/components/message-actions.stories.tsx +45 -0
- package/src/components/message-actions.test.tsx +32 -0
- package/src/components/message-actions.tsx +119 -0
- package/src/components/nav-sidebar.stories.tsx +58 -0
- package/src/components/nav-sidebar.test.tsx +54 -0
- package/src/components/nav-sidebar.tsx +462 -0
- package/src/components/number-stepper.stories.tsx +19 -0
- package/src/components/number-stepper.tsx +158 -0
- package/src/components/page-header.stories.tsx +25 -0
- package/src/components/page-header.tsx +64 -0
- package/src/components/pagination.stories.tsx +110 -0
- package/src/components/pagination.test.tsx +46 -0
- package/src/components/pagination.tsx +144 -0
- package/src/components/popover.stories.tsx +26 -0
- package/src/components/popover.tsx +62 -0
- package/src/components/pricing.stories.tsx +42 -0
- package/src/components/pricing.tsx +130 -0
- package/src/components/progress.stories.tsx +22 -0
- package/src/components/progress.tsx +189 -0
- package/src/components/prompt-input.stories.tsx +62 -0
- package/src/components/prompt-input.test.tsx +106 -0
- package/src/components/prompt-input.tsx +343 -0
- package/src/components/prompt-suggestions.stories.tsx +53 -0
- package/src/components/prompt-suggestions.test.tsx +37 -0
- package/src/components/prompt-suggestions.tsx +122 -0
- package/src/components/quota-bar.stories.tsx +19 -0
- package/src/components/quota-bar.tsx +191 -0
- package/src/components/quote.stories.tsx +18 -0
- package/src/components/quote.tsx +43 -0
- package/src/components/radio-card.stories.tsx +27 -0
- package/src/components/radio-card.tsx +225 -0
- package/src/components/radio-group.stories.tsx +32 -0
- package/src/components/radio-group.tsx +68 -0
- package/src/components/reasoning.stories.tsx +50 -0
- package/src/components/reasoning.test.tsx +48 -0
- package/src/components/reasoning.tsx +143 -0
- package/src/components/search.stories.tsx +18 -0
- package/src/components/search.tsx +133 -0
- package/src/components/section-nav.stories.tsx +59 -0
- package/src/components/section-nav.test.tsx +36 -0
- package/src/components/section-nav.tsx +146 -0
- package/src/components/segmented-control.stories.tsx +22 -0
- package/src/components/segmented-control.tsx +301 -0
- package/src/components/select-button.stories.tsx +27 -0
- package/src/components/select-button.tsx +174 -0
- package/src/components/select.stories.tsx +27 -0
- package/src/components/select.tsx +198 -0
- package/src/components/separator.stories.tsx +22 -0
- package/src/components/separator.tsx +23 -0
- package/src/components/shimmer-text.stories.tsx +23 -0
- package/src/components/shimmer-text.test.tsx +35 -0
- package/src/components/shimmer-text.tsx +43 -0
- package/src/components/sidebar.stories.tsx +25 -0
- package/src/components/sidebar.tsx +234 -0
- package/src/components/skeleton.stories.tsx +22 -0
- package/src/components/skeleton.tsx +96 -0
- package/src/components/slider.stories.tsx +20 -0
- package/src/components/slider.tsx +176 -0
- package/src/components/slideshow.stories.tsx +30 -0
- package/src/components/slideshow.tsx +291 -0
- package/src/components/source.stories.tsx +32 -0
- package/src/components/source.test.tsx +40 -0
- package/src/components/source.tsx +161 -0
- package/src/components/spinner.stories.tsx +19 -0
- package/src/components/spinner.tsx +76 -0
- package/src/components/stat-strip.stories.tsx +36 -0
- package/src/components/stat-strip.test.tsx +25 -0
- package/src/components/stat-strip.tsx +85 -0
- package/src/components/stats.stories.tsx +24 -0
- package/src/components/stats.tsx +83 -0
- package/src/components/step-indicator.stories.tsx +18 -0
- package/src/components/step-indicator.test.tsx +18 -0
- package/src/components/step-indicator.tsx +286 -0
- package/src/components/switch.stories.tsx +26 -0
- package/src/components/switch.tsx +32 -0
- package/src/components/table.stories.tsx +38 -0
- package/src/components/table.tsx +220 -0
- package/src/components/tabs.stories.tsx +25 -0
- package/src/components/tabs.tsx +276 -0
- package/src/components/testimonials.stories.tsx +22 -0
- package/src/components/testimonials.tsx +109 -0
- package/src/components/text-link.stories.tsx +47 -0
- package/src/components/text-link.test.tsx +18 -0
- package/src/components/text-link.tsx +88 -0
- package/src/components/text.stories.tsx +49 -0
- package/src/components/text.tsx +105 -0
- package/src/components/thinking-bar.stories.tsx +19 -0
- package/src/components/thinking-bar.test.tsx +27 -0
- package/src/components/thinking-bar.tsx +64 -0
- package/src/components/thinking-steps.stories.tsx +44 -0
- package/src/components/thinking-steps.test.tsx +42 -0
- package/src/components/thinking-steps.tsx +92 -0
- package/src/components/toaster.stories.tsx +80 -0
- package/src/components/toaster.tsx +36 -0
- package/src/components/toggle.stories.tsx +21 -0
- package/src/components/toggle.tsx +103 -0
- package/src/components/tool-call-card.stories.tsx +97 -0
- package/src/components/tool-call-card.test.tsx +88 -0
- package/src/components/tool-call-card.tsx +231 -0
- package/src/components/tooltip.stories.tsx +25 -0
- package/src/components/tooltip.tsx +43 -0
- package/src/components/top-nav.stories.tsx +20 -0
- package/src/components/top-nav.tsx +76 -0
- package/src/docs/Colors.stories.tsx +192 -0
- package/src/docs/GettingStarted.mdx +72 -0
- package/src/docs/Mcp.mdx +52 -0
- package/src/docs/Typography.stories.tsx +114 -0
- package/src/hooks/use-in-view.ts +32 -0
- package/src/hooks/use-reduced-motion.ts +26 -0
- package/src/index.ts +343 -0
- package/src/lib/cn.test.ts +67 -0
- package/src/lib/cn.ts +81 -0
- package/src/lib/motion.ts +109 -0
- package/src/lib/prefix-utilities.test.ts +56 -0
- package/src/lib/prefix-utilities.ts +50 -0
- package/src/styles/base.css +489 -0
- package/src/styles/motion.css +69 -0
- package/src/styles/overrides.css +44 -0
- package/src/styles/typography.css +173 -0
- package/src/theme/theme.css +391 -0
- package/src/theme/tokens.ts +29 -0
- package/src/theme/types.ts +26 -0
- package/README.md +0 -3
package/src/index.ts
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
// ─── Web App - Layout & Navigation ───────────────────────────────────────────
|
|
2
|
+
export {
|
|
3
|
+
Sidebar, SidebarItem, SidebarSection, SidebarUserCard,
|
|
4
|
+
type SidebarProps, type SidebarItemProps, type SidebarUserCardProps,
|
|
5
|
+
} from "./components/sidebar"
|
|
6
|
+
export {
|
|
7
|
+
NavSidebar,
|
|
8
|
+
type NavSidebarProps, type NavSection, type NavItem, type NavSubItem,
|
|
9
|
+
} from "./components/nav-sidebar"
|
|
10
|
+
export { ListNav, ListNavItem, type ListNavProps, type ListNavItemProps, type ListNavSize } from "./components/list-nav"
|
|
11
|
+
export { SectionNav, type SectionNavProps, type SectionNavItem } from "./components/section-nav"
|
|
12
|
+
export { CardsNav, type CardsNavItem, type CardsNavProps, type CardsNavSize } from "./components/cards-nav"
|
|
13
|
+
export {
|
|
14
|
+
BulletList, BulletListItem,
|
|
15
|
+
type BulletListProps, type BulletListItemProps, type BulletListSize,
|
|
16
|
+
} from "./components/bullet-list"
|
|
17
|
+
export { BoxList, type BoxListItem, type BoxListProps, type BoxListSize } from "./components/box-list"
|
|
18
|
+
export { TopNav, Breadcrumbs, type TopNavProps, type BreadcrumbsProps } from "./components/top-nav"
|
|
19
|
+
export { PageHeader, type PageHeaderProps } from "./components/page-header"
|
|
20
|
+
export { EntityHeader, entityHeaderVariants, entityInitials, type EntityHeaderProps, type EntityHeaderSize } from "./components/entity-header"
|
|
21
|
+
export { StatStrip, statStripVariants, type StatStripProps, type StatStripItem, type StatStripTone } from "./components/stat-strip"
|
|
22
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, type TabsProps, type TabsSize } from "./components/tabs"
|
|
23
|
+
|
|
24
|
+
// ─── Web App - Core Primitives ────────────────────────────────────────────────
|
|
25
|
+
export { Button, buttonVariants, type ButtonProps } from "./components/button"
|
|
26
|
+
export {
|
|
27
|
+
ButtonGroup, ButtonGroupItem,
|
|
28
|
+
type ButtonGroupProps, type ButtonGroupItemProps,
|
|
29
|
+
type ButtonGroupSize, type ButtonGroupVariant, type ButtonGroupSelected,
|
|
30
|
+
} from "./components/button-group"
|
|
31
|
+
export {
|
|
32
|
+
Input, TextFieldRoot, TextFieldSlot,
|
|
33
|
+
Textarea,
|
|
34
|
+
Label, Field,
|
|
35
|
+
type InputProps, type InputSize,
|
|
36
|
+
type TextFieldRootProps, type TextFieldSlotProps,
|
|
37
|
+
type TextareaProps, type TextareaResize, type TextareaSize,
|
|
38
|
+
type LabelProps, type FieldProps,
|
|
39
|
+
} from "./components/input"
|
|
40
|
+
export { Search, type SearchProps } from "./components/search"
|
|
41
|
+
export { Combobox, type ComboboxProps, type ComboboxItem, type ComboboxSize } from "./components/combobox"
|
|
42
|
+
export { Card, CardHeader, CardBanner, CardTitle, CardDescription, CardContent, CardFooter, cardCn, type CardProps, type CardHeaderProps, type CardBannerProps, type CardHeaderSize, type CardVariant, type CardPadding, type CardGap, type CardElevation } from "./components/card"
|
|
43
|
+
export { Calendar, type CalendarProps, type CalendarMode, type CalendarValue, type DateRange } from "./components/calendar"
|
|
44
|
+
export { Inset, type InsetProps, type InsetSide, type InsetClip } from "./components/inset"
|
|
45
|
+
export { Badge, badgeVariants, type BadgeProps } from "./components/badge"
|
|
46
|
+
export { Alert, AlertTitle, AlertDescription, type AlertProps } from "./components/alert"
|
|
47
|
+
export { Separator } from "./components/separator"
|
|
48
|
+
export {
|
|
49
|
+
Avatar, AvatarImage, AvatarFallback, AvatarStack,
|
|
50
|
+
type AvatarProps, type AvatarImageProps, type AvatarFallbackProps, type AvatarStackProps,
|
|
51
|
+
type AvatarSize,
|
|
52
|
+
} from "./components/avatar"
|
|
53
|
+
export {
|
|
54
|
+
Skeleton, SkeletonText,
|
|
55
|
+
type SkeletonProps, type SkeletonTextProps, type SkeletonVariant,
|
|
56
|
+
} from "./components/skeleton"
|
|
57
|
+
export { EmptyState, type EmptyStateProps } from "./components/empty-state"
|
|
58
|
+
export { AspectRatio } from "./components/aspect-ratio"
|
|
59
|
+
export {
|
|
60
|
+
Blockquote, BlockquoteCaption, BlockquoteFigure,
|
|
61
|
+
type BlockquoteProps, type BlockquoteCaptionProps, type BlockquoteFigureProps,
|
|
62
|
+
type BlockquoteSize, type BlockquoteColor,
|
|
63
|
+
} from "./components/blockquote"
|
|
64
|
+
export { Quote, quoteVariants, type QuoteProps } from "./components/quote"
|
|
65
|
+
export { Text, type TextProps, type TextAs, type TextSize, type TextWeight, type TextAlign, type TextColor, type TextWrap } from "./components/text"
|
|
66
|
+
export { Heading, headingVariants, type HeadingProps, type HeadingAs, type HeadingSize, type HeadingColor, type HeadingAlign, type HeadingWrap } from "./components/heading"
|
|
67
|
+
export { TextLink, textLinkVariants, type TextLinkProps, type TextLinkColor, type TextLinkUnderline, type TextLinkSize } from "./components/text-link"
|
|
68
|
+
|
|
69
|
+
// ─── Web App - Overlays ───────────────────────────────────────────────────────
|
|
70
|
+
export {
|
|
71
|
+
Drawer,
|
|
72
|
+
DrawerTrigger,
|
|
73
|
+
DrawerClose,
|
|
74
|
+
DrawerContent,
|
|
75
|
+
DrawerHeader,
|
|
76
|
+
DrawerBody,
|
|
77
|
+
DrawerFooter,
|
|
78
|
+
DrawerTitle,
|
|
79
|
+
DrawerDescription,
|
|
80
|
+
type DrawerProps,
|
|
81
|
+
type DrawerContentProps,
|
|
82
|
+
type DrawerSide,
|
|
83
|
+
type DrawerSize,
|
|
84
|
+
} from "./components/drawer"
|
|
85
|
+
export {
|
|
86
|
+
Dialog,
|
|
87
|
+
DialogTrigger,
|
|
88
|
+
DialogPortal,
|
|
89
|
+
DialogClose,
|
|
90
|
+
DialogOverlay,
|
|
91
|
+
DialogContent,
|
|
92
|
+
DialogHeader,
|
|
93
|
+
DialogFooter,
|
|
94
|
+
DialogTitle,
|
|
95
|
+
DialogDescription,
|
|
96
|
+
type DialogContentProps,
|
|
97
|
+
type DialogSize,
|
|
98
|
+
} from "./components/dialog"
|
|
99
|
+
export {
|
|
100
|
+
Tooltip,
|
|
101
|
+
TooltipTrigger,
|
|
102
|
+
TooltipContent,
|
|
103
|
+
TooltipProvider,
|
|
104
|
+
type TooltipContentProps,
|
|
105
|
+
} from "./components/tooltip"
|
|
106
|
+
export {
|
|
107
|
+
Popover,
|
|
108
|
+
PopoverTrigger,
|
|
109
|
+
PopoverContent,
|
|
110
|
+
PopoverAnchor,
|
|
111
|
+
PopoverClose,
|
|
112
|
+
type PopoverContentProps,
|
|
113
|
+
type PopoverSize,
|
|
114
|
+
} from "./components/popover"
|
|
115
|
+
export {
|
|
116
|
+
DropdownMenu,
|
|
117
|
+
DropdownMenuTrigger,
|
|
118
|
+
DropdownMenuContent,
|
|
119
|
+
DropdownMenuItem,
|
|
120
|
+
DropdownMenuCheckboxItem,
|
|
121
|
+
DropdownMenuRadioItem,
|
|
122
|
+
DropdownMenuLabel,
|
|
123
|
+
DropdownMenuSeparator,
|
|
124
|
+
DropdownMenuGroup,
|
|
125
|
+
DropdownMenuPortal,
|
|
126
|
+
DropdownMenuSub,
|
|
127
|
+
DropdownMenuSubContent,
|
|
128
|
+
DropdownMenuSubTrigger,
|
|
129
|
+
DropdownMenuRadioGroup,
|
|
130
|
+
DropdownMenuShortcut,
|
|
131
|
+
type DropdownMenuContentProps,
|
|
132
|
+
type DropdownMenuItemProps,
|
|
133
|
+
} from "./components/dropdown-menu"
|
|
134
|
+
|
|
135
|
+
// ─── Web App - Form Controls ──────────────────────────────────────────────────
|
|
136
|
+
export {
|
|
137
|
+
SegmentedControl, SegmentedControlItem,
|
|
138
|
+
type SegmentedControlProps, type SegmentedControlItemProps, type SegmentedControlSize,
|
|
139
|
+
} from "./components/segmented-control"
|
|
140
|
+
export {
|
|
141
|
+
Select,
|
|
142
|
+
SelectGroup,
|
|
143
|
+
SelectValue,
|
|
144
|
+
SelectTrigger,
|
|
145
|
+
SelectContent,
|
|
146
|
+
SelectLabel,
|
|
147
|
+
SelectItem,
|
|
148
|
+
SelectSeparator,
|
|
149
|
+
SelectScrollUpButton,
|
|
150
|
+
SelectScrollDownButton,
|
|
151
|
+
type SelectTriggerProps,
|
|
152
|
+
type SelectTriggerSize,
|
|
153
|
+
} from "./components/select"
|
|
154
|
+
export {
|
|
155
|
+
SelectButton,
|
|
156
|
+
type SelectButtonProps,
|
|
157
|
+
type SelectButtonSize,
|
|
158
|
+
} from "./components/select-button"
|
|
159
|
+
export {
|
|
160
|
+
InputButton,
|
|
161
|
+
type InputButtonProps,
|
|
162
|
+
type InputButtonSize,
|
|
163
|
+
type InputButtonVariant,
|
|
164
|
+
} from "./components/input-button"
|
|
165
|
+
export { Toggle, type ToggleProps, type ToggleSize } from "./components/toggle"
|
|
166
|
+
export { Slider, type SliderProps, type SliderSize, type SliderValueLabel } from "./components/slider"
|
|
167
|
+
export { Checkbox, type CheckboxProps } from "./components/checkbox"
|
|
168
|
+
export {
|
|
169
|
+
CheckboxCardGroup, CheckboxCard, CheckboxCardTitle, CheckboxCardDescription,
|
|
170
|
+
type CheckboxCardGroupProps, type CheckboxCardProps,
|
|
171
|
+
type CheckboxCardSize, type CheckboxCardOrientation,
|
|
172
|
+
} from "./components/checkbox-card"
|
|
173
|
+
export { RadioGroup, RadioGroupItem, type RadioGroupItemProps } from "./components/radio-group"
|
|
174
|
+
export {
|
|
175
|
+
RadioCardGroup, RadioCard, RadioCardIcon, RadioCardTitle, RadioCardDescription,
|
|
176
|
+
type RadioCardGroupProps, type RadioCardProps, type RadioCardSize,
|
|
177
|
+
} from "./components/radio-card"
|
|
178
|
+
|
|
179
|
+
// ─── Web App - Data ───────────────────────────────────────────────────────────
|
|
180
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent, type AccordionProps } from "./components/accordion"
|
|
181
|
+
export {
|
|
182
|
+
DataTable,
|
|
183
|
+
rowStyle,
|
|
184
|
+
type DataTableProps, type ColumnDef,
|
|
185
|
+
type DataTableSize, type DataTableAlign,
|
|
186
|
+
} from "./components/data-table"
|
|
187
|
+
export {
|
|
188
|
+
DataList, DataListItem, DataListLabel, DataListValue,
|
|
189
|
+
type DataListProps, type DataListSize, type DataListOrientation, type DataListColumns,
|
|
190
|
+
} from "./components/data-list"
|
|
191
|
+
export {
|
|
192
|
+
Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption,
|
|
193
|
+
type TableProps, type TableSize, type TableVariant,
|
|
194
|
+
} from "./components/table"
|
|
195
|
+
|
|
196
|
+
// ─── Web App - Media ─────────────────────────────────────────────────────────
|
|
197
|
+
export {
|
|
198
|
+
Slideshow, SlideshowSlide,
|
|
199
|
+
type SlideshowProps, type SlideshowSlideProps, type SlideshowVariant,
|
|
200
|
+
} from "./components/slideshow"
|
|
201
|
+
export {
|
|
202
|
+
MediaGallery, Lightbox,
|
|
203
|
+
type MediaGalleryProps, type LightboxProps, type MediaItem, type MediaKind,
|
|
204
|
+
} from "./components/media-gallery"
|
|
205
|
+
|
|
206
|
+
// ─── Web App - Feedback ───────────────────────────────────────────────────────
|
|
207
|
+
export { Toaster, toast } from "./components/toaster"
|
|
208
|
+
export {
|
|
209
|
+
Progress,
|
|
210
|
+
type ProgressProps, type ProgressSize, type ProgressVariant, type ProgressShape,
|
|
211
|
+
} from "./components/progress"
|
|
212
|
+
export { Spinner, type SpinnerProps, type SpinnerSize } from "./components/spinner"
|
|
213
|
+
|
|
214
|
+
// ─── Web App - Patterns ──────────────────────────────────────────────────────
|
|
215
|
+
// Higher-level compositions built on top of the core primitives. Generic
|
|
216
|
+
// enough to be reused across brands; domain wording is parameterised.
|
|
217
|
+
export {
|
|
218
|
+
KpiCard, KpiCardGroup,
|
|
219
|
+
type KpiCardProps, type KpiCardGroupProps, type KpiCardSize,
|
|
220
|
+
} from "./components/kpi-card"
|
|
221
|
+
export {
|
|
222
|
+
CountdownPill,
|
|
223
|
+
getCountdownLabel,
|
|
224
|
+
type CountdownPillProps,
|
|
225
|
+
type CountdownTone,
|
|
226
|
+
type CountdownSize,
|
|
227
|
+
} from "./components/countdown-pill"
|
|
228
|
+
export {
|
|
229
|
+
StepIndicator,
|
|
230
|
+
type StepIndicatorProps, type StepIndicatorStep,
|
|
231
|
+
type StepIndicatorSize, type StepIndicatorOrientation,
|
|
232
|
+
} from "./components/step-indicator"
|
|
233
|
+
export { NumberStepper, type NumberStepperProps, type NumberStepperSize } from "./components/number-stepper"
|
|
234
|
+
export {
|
|
235
|
+
EmailChipsInput,
|
|
236
|
+
type EmailChipsInputProps,
|
|
237
|
+
type EmailChipsInputVariant,
|
|
238
|
+
type EmailChip,
|
|
239
|
+
} from "./components/email-chips-input"
|
|
240
|
+
export {
|
|
241
|
+
Dropzone,
|
|
242
|
+
type DropzoneProps, type DropzoneError, type DropzoneErrorReason,
|
|
243
|
+
} from "./components/dropzone"
|
|
244
|
+
export { QuotaBar, type QuotaBarProps, type QuotaBarShape } from "./components/quota-bar"
|
|
245
|
+
export {
|
|
246
|
+
Pagination, type PaginationProps,
|
|
247
|
+
PaginationContent,
|
|
248
|
+
PaginationItem,
|
|
249
|
+
PaginationLink, type PaginationLinkProps, paginationLinkVariants,
|
|
250
|
+
PaginationPrevious,
|
|
251
|
+
PaginationNext, type PaginationNavLinkProps,
|
|
252
|
+
PaginationEllipsis,
|
|
253
|
+
} from "./components/pagination"
|
|
254
|
+
export {
|
|
255
|
+
ActivityRings,
|
|
256
|
+
type ActivityRing,
|
|
257
|
+
type ActivityRingsProps,
|
|
258
|
+
} from "./components/activity-rings"
|
|
259
|
+
export {
|
|
260
|
+
BarGraph,
|
|
261
|
+
type BarGraphProps,
|
|
262
|
+
type BarGraphItem,
|
|
263
|
+
type BarGraphSize,
|
|
264
|
+
type BarGraphDirection,
|
|
265
|
+
} from "./components/bar-graph"
|
|
266
|
+
|
|
267
|
+
// ─── Web App - AI ────────────────────────────────────────────────────────────
|
|
268
|
+
// Parts for assistant and chat surfaces. Domain data stays with the caller.
|
|
269
|
+
export {
|
|
270
|
+
MessageAction, MessageActions,
|
|
271
|
+
type MessageActionProps, type MessageActionsProps, type MessageRating,
|
|
272
|
+
} from "./components/message-actions"
|
|
273
|
+
export {
|
|
274
|
+
ChatMessage, ChatAvatar, ChatDivider,
|
|
275
|
+
type ChatMessageProps, type ChatMessageFrom, type ChatMessageStatus,
|
|
276
|
+
type ChatAvatarProps, type ChatDividerProps,
|
|
277
|
+
} from "./components/chat-message"
|
|
278
|
+
export {
|
|
279
|
+
ChatContainerRoot, ChatContainerContent, ChatScrollButton, useChatContainer,
|
|
280
|
+
type ChatContainerRootProps, type ChatContainerContentProps, type ChatScrollButtonProps, type ChatContainerState,
|
|
281
|
+
} from "./components/chat-container"
|
|
282
|
+
export {
|
|
283
|
+
SuggestionChips, StarterPrompts,
|
|
284
|
+
type SuggestionChipsProps, type StarterPromptsProps, type StarterPromptItem,
|
|
285
|
+
} from "./components/prompt-suggestions"
|
|
286
|
+
export {
|
|
287
|
+
PromptInput, PromptInputAction, AttachmentChip, characterCountTone, formatFileSize,
|
|
288
|
+
type PromptInputProps, type PromptInputSize, type PromptInputActionProps, type AttachmentChipProps, type CharacterCountTone,
|
|
289
|
+
} from "./components/prompt-input"
|
|
290
|
+
export {
|
|
291
|
+
ThinkingSteps, StreamingCursor, thinkingStepsSummary,
|
|
292
|
+
type ThinkingStepsProps, type ThinkingStep, type ThinkingStepStatus,
|
|
293
|
+
} from "./components/thinking-steps"
|
|
294
|
+
export {
|
|
295
|
+
ShimmerText, shimmerGradient, type ShimmerTextProps, type ShimmerTextAs,
|
|
296
|
+
} from "./components/shimmer-text"
|
|
297
|
+
export { ThinkingBar, type ThinkingBarProps } from "./components/thinking-bar"
|
|
298
|
+
export {
|
|
299
|
+
ChainOfThought, ChainOfThoughtStep, ChainOfThoughtTrigger, ChainOfThoughtContent, ChainOfThoughtItem,
|
|
300
|
+
type ChainOfThoughtProps, type ChainOfThoughtStepProps, type ChainOfThoughtTriggerProps,
|
|
301
|
+
type ChainOfThoughtContentProps, type ChainOfThoughtItemProps,
|
|
302
|
+
} from "./components/chain-of-thought"
|
|
303
|
+
export {
|
|
304
|
+
Reasoning, ReasoningTrigger, ReasoningContent,
|
|
305
|
+
type ReasoningProps, type ReasoningTriggerProps, type ReasoningContentProps,
|
|
306
|
+
} from "./components/reasoning"
|
|
307
|
+
export {
|
|
308
|
+
ToolCallCard, TOOL_CALL_STATUS, toolCallNeedsAttention, toolPartToCallCard, formatToolValue,
|
|
309
|
+
type ToolCallCardProps, type ToolCallStatus, type ToolCallField, type ToolPart, type ToolPartCardProps,
|
|
310
|
+
} from "./components/tool-call-card"
|
|
311
|
+
export {
|
|
312
|
+
CitationMarker, UnsupportedClaim, SourceCard, SourceList, SourceAvatar, isStale, formatSourceDate,
|
|
313
|
+
type CitationSource, type CitationSourceKind, type CitationMarkerProps, type UnsupportedClaimProps,
|
|
314
|
+
type SourceCardProps, type SourceListProps, type SourceAvatarProps,
|
|
315
|
+
} from "./components/citations"
|
|
316
|
+
export {
|
|
317
|
+
Source, SourceTrigger, SourceContent, sourceDomain,
|
|
318
|
+
type SourceProps, type SourceTriggerProps, type SourceContentProps,
|
|
319
|
+
} from "./components/source"
|
|
320
|
+
export {
|
|
321
|
+
AnswerActions, FeedbackReasonChips,
|
|
322
|
+
type AnswerActionsProps, type AnswerFeedback, type AnswerReport, type FeedbackReasonChipsProps,
|
|
323
|
+
} from "./components/answer-actions"
|
|
324
|
+
export { FeedbackBar, type FeedbackBarProps } from "./components/feedback-bar"
|
|
325
|
+
|
|
326
|
+
// ─── Layout ───────────────────────────────────────────────────────────────────
|
|
327
|
+
export { BentoGrid, BentoItem, type BentoGridProps, type BentoItemProps } from "./components/bento-grid"
|
|
328
|
+
|
|
329
|
+
// ─── Marketing ────────────────────────────────────────────────────────────────
|
|
330
|
+
export { Hero, type HeroProps, type HeroLayout, type HeroStat } from "./components/hero"
|
|
331
|
+
export { CTA, type CTAProps } from "./components/cta"
|
|
332
|
+
export { FeatureGrid, type Feature, type FeatureGridProps } from "./components/feature-grid"
|
|
333
|
+
export { Pricing, type PricingProps, type PricingTier } from "./components/pricing"
|
|
334
|
+
export { Testimonials, type TestimonialsProps, type Testimonial } from "./components/testimonials"
|
|
335
|
+
export { Stats, type StatsProps, type Stat } from "./components/stats"
|
|
336
|
+
export { LogoCloud, type LogoCloudProps, type LogoCloudItem } from "./components/logo-cloud"
|
|
337
|
+
export { Footer, type FooterProps, type FooterColumn, type FooterLink } from "./components/footer"
|
|
338
|
+
|
|
339
|
+
// ─── Utilities & Hooks ────────────────────────────────────────────────────────
|
|
340
|
+
export { cn } from "./lib/cn"
|
|
341
|
+
export { useReducedMotion } from "./hooks/use-reduced-motion"
|
|
342
|
+
export { useInView } from "./hooks/use-in-view"
|
|
343
|
+
export { transitions, variants, stagger, viewport, hover } from "./lib/motion"
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import { cn } from "./cn"
|
|
3
|
+
|
|
4
|
+
describe("cn", () => {
|
|
5
|
+
it("joins plain class names", () => {
|
|
6
|
+
expect(cn("px-2", "py-1")).toBe("px-2 py-1")
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it("drops falsy conditional values", () => {
|
|
10
|
+
expect(cn("px-2", false && "hidden", undefined, null, "font-medium")).toBe(
|
|
11
|
+
"px-2 font-medium",
|
|
12
|
+
)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it("resolves conflicting Tailwind utilities with last wins", () => {
|
|
16
|
+
expect(cn("px-2", "px-4")).toBe("px-4")
|
|
17
|
+
expect(cn("text-foreground/60", "text-foreground")).toBe("text-foreground")
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("resolves conflicting ax-prefixed utilities with last wins", () => {
|
|
21
|
+
expect(cn("ax:px-2", "ax:px-4")).toBe("ax:px-4")
|
|
22
|
+
expect(cn("ax:text-foreground/60", "ax:text-foreground")).toBe("ax:text-foreground")
|
|
23
|
+
expect(cn("ax:hover:bg-primary", "ax:hover:bg-primary-strong")).toBe("ax:hover:bg-primary-strong")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("merges the DS named spacing tokens like built-in values", () => {
|
|
27
|
+
expect(cn("ax:px-sm", "ax:px-0")).toBe("ax:px-0")
|
|
28
|
+
expect(cn("ax:py-5xl", "ax:py-0")).toBe("ax:py-0")
|
|
29
|
+
expect(cn("ax:p-xl", "ax:p-md")).toBe("ax:p-md")
|
|
30
|
+
expect(cn("ax:gap-md", "ax:gap-2")).toBe("ax:gap-2")
|
|
31
|
+
expect(cn("ax:size-3xl", "ax:size-2xl")).toBe("ax:size-2xl")
|
|
32
|
+
expect(cn("ax:h-3xl", "ax:h-auto")).toBe("ax:h-auto")
|
|
33
|
+
expect(cn("ax:-mx-sm", "ax:-mx-md")).toBe("ax:-mx-md")
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("keeps an axis-specific spacing token that refines a shorthand", () => {
|
|
37
|
+
expect(cn("ax:p-xl", "ax:px-md")).toBe("ax:p-xl ax:px-md")
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("merges CSS-variable radius shorthand with other radius values", () => {
|
|
41
|
+
expect(cn("ax:rounded-(--button-radius)", "ax:rounded-full")).toBe("ax:rounded-full")
|
|
42
|
+
expect(cn("ax:rounded-full", "ax:rounded-(--input-radius)")).toBe("ax:rounded-(--input-radius)")
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("lets a later t-* utility replace an earlier one", () => {
|
|
46
|
+
expect(cn("ax:t-body-md", "ax:t-label-sm")).toBe("ax:t-label-sm")
|
|
47
|
+
expect(cn("ax:t-h1", "ax:t-display-md")).toBe("ax:t-display-md")
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("keeps weight and size utilities on either side of a t-* utility", () => {
|
|
51
|
+
expect(cn("ax:font-medium", "ax:t-body-sm")).toBe("ax:font-medium ax:t-body-sm")
|
|
52
|
+
expect(cn("ax:text-sm", "ax:t-body-md")).toBe("ax:text-sm ax:t-body-md")
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it("keeps a t-* utility when a later utility only refines it", () => {
|
|
56
|
+
expect(cn("ax:t-body-md", "ax:font-medium")).toBe("ax:t-body-md ax:font-medium")
|
|
57
|
+
expect(cn("ax:t-body-md", "ax:text-muted-foreground")).toBe("ax:t-body-md ax:text-muted-foreground")
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it("keeps an ax utility when an unprefixed class conflicts", () => {
|
|
61
|
+
expect(cn("ax:px-2", "px-4")).toBe("ax:px-2 px-4")
|
|
62
|
+
expect(cn("px-4", "ax:px-2")).toBe("px-4 ax:px-2")
|
|
63
|
+
expect(cn("ax:hover:bg-primary", "hover:bg-primary-strong")).toBe(
|
|
64
|
+
"ax:hover:bg-primary hover:bg-primary-strong",
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
})
|
package/src/lib/cn.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from "clsx"
|
|
2
|
+
import { extendTailwindMerge } from "tailwind-merge"
|
|
3
|
+
|
|
4
|
+
/** Named spacing tokens from `--spacing-*` in base.css (`ax:px-sm`, `ax:size-3xl`). */
|
|
5
|
+
const SPACING_TOKENS = ["2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl"]
|
|
6
|
+
|
|
7
|
+
/** The `@utility t-*` scale in typography.css. */
|
|
8
|
+
const TYPE_SCALE = [
|
|
9
|
+
"display-3xl", "display-2xl", "display-xl", "display-lg", "display-md", "display-sm",
|
|
10
|
+
"h1", "h2", "h3", "h4", "h5", "h6",
|
|
11
|
+
"body-2xl", "body-xl", "body-lg", "body-md", "body-sm", "body-xs",
|
|
12
|
+
"label-lg", "label-md", "label-sm", "label-xs", "label-2xs",
|
|
13
|
+
"caption", "overline", "code", "micro",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
/** Tailwind v4 CSS-variable shorthand, e.g. `rounded-(--button-radius)`. tailwind-merge v2 predates it. */
|
|
17
|
+
const isCssVariable = (value: string) => /^\(--[\w-]+\)$/.test(value)
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Tailwind v4 writes the library prefix as a leading variant (`ax:px-4`).
|
|
21
|
+
* Strip it before conflict detection so `ax:px-2` and `ax:px-4` collapse.
|
|
22
|
+
* Unprefixed classes are merged in their own group so `px-4` cannot remove `ax:px-2`.
|
|
23
|
+
*
|
|
24
|
+
* The DS's own tokens are registered so they merge like built-in values;
|
|
25
|
+
* without this, `ax:px-sm` and `ax:px-0` both survive and stylesheet order,
|
|
26
|
+
* not call order, decides which one applies.
|
|
27
|
+
*/
|
|
28
|
+
const twMerge = extendTailwindMerge<"ds-type">({
|
|
29
|
+
experimentalParseClassName({ className, parseClassName }) {
|
|
30
|
+
return parseClassName(className.startsWith("ax:") ? className.slice(3) : className)
|
|
31
|
+
},
|
|
32
|
+
extend: {
|
|
33
|
+
theme: {
|
|
34
|
+
spacing: [...SPACING_TOKENS, isCssVariable],
|
|
35
|
+
borderRadius: [isCssVariable],
|
|
36
|
+
},
|
|
37
|
+
// `t-*` classes only replace each other. They set different properties
|
|
38
|
+
// (body sizes set size and leading, headings also weight and tracking), and
|
|
39
|
+
// components layer `font-medium` on top of them on purpose, so a `t-*`
|
|
40
|
+
// class must not remove the size or weight utilities around it.
|
|
41
|
+
classGroups: {
|
|
42
|
+
"ds-type": [{ t: TYPE_SCALE }],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* `cn` - class-name composer.
|
|
49
|
+
*
|
|
50
|
+
* Combines `clsx` (conditional class lists) with `tailwind-merge`
|
|
51
|
+
* (last-wins resolution of conflicting Tailwind utilities).
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* cn("px-2", isLarge && "px-4") // → "px-4"
|
|
55
|
+
* cn("ax:px-2", "ax:px-4") // → "ax:px-4"
|
|
56
|
+
* cn("ax:px-sm", "ax:px-0") // → "ax:px-0"
|
|
57
|
+
* cn("ax:t-body-md", "ax:t-label-sm") // → "ax:t-label-sm"
|
|
58
|
+
* cn("ax:px-2", "px-4") // → "ax:px-2 px-4"
|
|
59
|
+
* cn("ax:text-foreground/60", className) // later `ax:` class wins
|
|
60
|
+
*/
|
|
61
|
+
export function cn(...inputs: ClassValue[]): string {
|
|
62
|
+
const tokens = clsx(inputs).split(/\s+/).filter(Boolean)
|
|
63
|
+
const plain: string[] = []
|
|
64
|
+
const prefixed: string[] = []
|
|
65
|
+
for (const token of tokens) {
|
|
66
|
+
if (token.startsWith("ax:")) prefixed.push(token)
|
|
67
|
+
else plain.push(token)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const plainKept = new Set(twMerge(plain).split(/\s+/).filter(Boolean))
|
|
71
|
+
const prefixedKept = new Set(twMerge(prefixed).split(/\s+/).filter(Boolean))
|
|
72
|
+
const seen = new Set<string>()
|
|
73
|
+
const kept: string[] = []
|
|
74
|
+
for (const token of tokens) {
|
|
75
|
+
const group = token.startsWith("ax:") ? prefixedKept : plainKept
|
|
76
|
+
if (!group.has(token) || seen.has(token)) continue
|
|
77
|
+
seen.add(token)
|
|
78
|
+
kept.push(token)
|
|
79
|
+
}
|
|
80
|
+
return kept.join(" ")
|
|
81
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Single source of truth for all motion primitives in the design system.
|
|
2
|
+
// Import from here; never hardcode animation values in components.
|
|
3
|
+
//
|
|
4
|
+
// Guiding principles
|
|
5
|
+
// ──────────────────
|
|
6
|
+
// • Enter with ease-out - fast start, smooth deceleration into place (feels responsive)
|
|
7
|
+
// • Exit with ease-in - gentle start, fast departure (gets out of the way)
|
|
8
|
+
// • State transitions use ease-in-out - balanced arc between two visible positions
|
|
9
|
+
// • Exits are ~70 % of the enter duration - exits should never overstay
|
|
10
|
+
// • Durations scale with surface size - micro < standard < large
|
|
11
|
+
|
|
12
|
+
// ─── Named easing curves (mirror the CSS custom properties in base.css) ───────
|
|
13
|
+
|
|
14
|
+
export const easing = {
|
|
15
|
+
/** Enter: fast start → smooth deceleration. Use when elements arrive on screen. */
|
|
16
|
+
out: [0.22, 1, 0.36, 1] as const,
|
|
17
|
+
/** Exit: gentle start → fast departure. Use when elements leave the screen. */
|
|
18
|
+
in: [0.55, 0, 1, 0.45] as const,
|
|
19
|
+
/** State: balanced arc. Use when an element moves between two visible positions. */
|
|
20
|
+
inOut: [0.45, 0, 0.55, 1] as const,
|
|
21
|
+
} as const
|
|
22
|
+
|
|
23
|
+
// ─── Duration + easing presets ────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
export const transitions = {
|
|
26
|
+
/** Micro-interactions: hover states, small feedbacks, icon swaps. */
|
|
27
|
+
snappy: { duration: 0.16, ease: easing.out },
|
|
28
|
+
|
|
29
|
+
/** Standard UI: dropdowns, tooltips, badges, small panels. */
|
|
30
|
+
smooth: { duration: 0.28, ease: easing.out },
|
|
31
|
+
|
|
32
|
+
/** Large surfaces: drawers, modals, marketing sections. */
|
|
33
|
+
slow: { duration: 0.42, ease: easing.out },
|
|
34
|
+
|
|
35
|
+
/** Exit counterpart of `smooth` - 70 % duration, ease-in so it leaves quickly. */
|
|
36
|
+
exit: { duration: 0.20, ease: easing.in },
|
|
37
|
+
|
|
38
|
+
/** Exit counterpart of `slow` - use for large surfaces leaving. */
|
|
39
|
+
exitSlow: { duration: 0.28, ease: easing.in },
|
|
40
|
+
|
|
41
|
+
/** Spring - bouncy interactive elements (cards on hover, spring pop). */
|
|
42
|
+
spring: { type: "spring" as const, stiffness: 260, damping: 28, mass: 0.9 },
|
|
43
|
+
|
|
44
|
+
/** Springy - snappier spring for rapid interactions. */
|
|
45
|
+
springy: { type: "spring" as const, stiffness: 380, damping: 22, mass: 0.7 },
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const T = transitions
|
|
49
|
+
|
|
50
|
+
// ─── Named variants ───────────────────────────────────────────────────────────
|
|
51
|
+
// Each `visible` state bakes in its transition so children work correctly inside
|
|
52
|
+
// stagger containers without needing a separate `transition` prop.
|
|
53
|
+
|
|
54
|
+
export const variants = {
|
|
55
|
+
fadeUp: {
|
|
56
|
+
hidden: { opacity: 0, y: 20 },
|
|
57
|
+
visible: { opacity: 1, y: 0, transition: T.slow },
|
|
58
|
+
},
|
|
59
|
+
fadeIn: {
|
|
60
|
+
hidden: { opacity: 0 },
|
|
61
|
+
visible: { opacity: 1, transition: T.smooth },
|
|
62
|
+
},
|
|
63
|
+
scaleIn: {
|
|
64
|
+
hidden: { opacity: 0, scale: 0.95 },
|
|
65
|
+
visible: { opacity: 1, scale: 1, transition: T.smooth },
|
|
66
|
+
},
|
|
67
|
+
springPop: {
|
|
68
|
+
hidden: { opacity: 0, scale: 0.8 },
|
|
69
|
+
visible: { opacity: 1, scale: 1, transition: T.springy },
|
|
70
|
+
},
|
|
71
|
+
slideLeft: {
|
|
72
|
+
hidden: { opacity: 0, x: -24 },
|
|
73
|
+
visible: { opacity: 1, x: 0, transition: T.slow },
|
|
74
|
+
},
|
|
75
|
+
slideRight: {
|
|
76
|
+
hidden: { opacity: 0, x: 24 },
|
|
77
|
+
visible: { opacity: 1, x: 0, transition: T.slow },
|
|
78
|
+
},
|
|
79
|
+
slideUp: {
|
|
80
|
+
hidden: { opacity: 0, y: 32 },
|
|
81
|
+
visible: { opacity: 1, y: 0, transition: T.slow },
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ─── Stagger container ────────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
// Returns a stagger container variant. Use on a parent `motion.*`; put `variants`
|
|
88
|
+
// on children: they'll animate with the correct stagger delay automatically.
|
|
89
|
+
export function stagger(delayChildren = 0, staggerChildren = 0.08) {
|
|
90
|
+
return {
|
|
91
|
+
hidden: {},
|
|
92
|
+
visible: { transition: { delayChildren, staggerChildren } },
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ─── Viewport config ──────────────────────────────────────────────────────────
|
|
97
|
+
|
|
98
|
+
// Default viewport config for whileInView animations.
|
|
99
|
+
export const viewport = { once: true, margin: "-60px 0px" } as const
|
|
100
|
+
|
|
101
|
+
// ─── Hover presets ────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
// whileHover target states. Pair with a `transition` on the same element.
|
|
104
|
+
// e.g. whileHover={hover.lift} transition={transitions.spring}
|
|
105
|
+
export const hover = {
|
|
106
|
+
lift: { y: -4 },
|
|
107
|
+
scale: { scale: 1.04 },
|
|
108
|
+
float: { y: -6, scale: 1.02 },
|
|
109
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import { prefixUtilities } from "./prefix-utilities"
|
|
3
|
+
|
|
4
|
+
describe("prefixUtilities", () => {
|
|
5
|
+
it("prefixes a single utility", () => {
|
|
6
|
+
expect(prefixUtilities("px-4").text).toBe("ax:px-4")
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it("puts ax before variants and arbitrary values", () => {
|
|
10
|
+
expect(prefixUtilities("sm:flex-row").text).toBe("ax:sm:flex-row")
|
|
11
|
+
expect(prefixUtilities("hover:bg-primary").text).toBe("ax:hover:bg-primary")
|
|
12
|
+
expect(prefixUtilities("dark:bg-black/40").text).toBe("ax:dark:bg-black/40")
|
|
13
|
+
expect(prefixUtilities("focus-visible:ring-2").text).toBe("ax:focus-visible:ring-2")
|
|
14
|
+
expect(prefixUtilities("rounded-(--input-radius)").text).toBe("ax:rounded-(--input-radius)")
|
|
15
|
+
expect(prefixUtilities("has-[input:disabled]:opacity-50").text).toBe(
|
|
16
|
+
"ax:has-[input:disabled]:opacity-50",
|
|
17
|
+
)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("leaves the dark theme hook and elevation classes unchanged", () => {
|
|
21
|
+
const result = prefixUtilities("px-4 dark elevation-0")
|
|
22
|
+
expect(result.text).toBe("ax:px-4 dark elevation-0")
|
|
23
|
+
expect(result.skipped).toEqual(["dark", "elevation-0"])
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("leaves the docs prose class unchanged", () => {
|
|
27
|
+
expect(prefixUtilities("prose-docs").text).toBe("prose-docs")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("leaves fumadocs utilities unchanged", () => {
|
|
31
|
+
expect(prefixUtilities("bg-fd-background text-fd-foreground").text).toBe(
|
|
32
|
+
"bg-fd-background text-fd-foreground",
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("prefixes utilities inside @apply and keeps the directive", () => {
|
|
37
|
+
expect(prefixUtilities("@apply t-label-sm;").text).toBe("@apply ax:t-label-sm;")
|
|
38
|
+
expect(
|
|
39
|
+
prefixUtilities(
|
|
40
|
+
"@apply font-display text-8xl font-semibold leading-24 tracking-tighter text-foreground-strong;",
|
|
41
|
+
).text,
|
|
42
|
+
).toBe(
|
|
43
|
+
"@apply ax:font-display ax:text-8xl ax:font-semibold ax:leading-24 ax:tracking-tighter ax:text-foreground-strong;",
|
|
44
|
+
)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it("does not double-prefix and keeps surrounding whitespace", () => {
|
|
48
|
+
expect(prefixUtilities(" ax:px-4\npx-2 ").text).toBe(" ax:px-4\nax:px-2 ")
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it("leaves a token it does not recognize and reports it", () => {
|
|
52
|
+
const result = prefixUtilities("px-4 {not-a-class}")
|
|
53
|
+
expect(result.text).toBe("ax:px-4 {not-a-class}")
|
|
54
|
+
expect(result.skipped).toEqual(["{not-a-class}"])
|
|
55
|
+
})
|
|
56
|
+
})
|