@kinetixui/ui 0.9.0 → 0.10.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/dist/index.d.ts CHANGED
@@ -1295,7 +1295,84 @@ interface NativeSelectOptGroupProps extends React$1.OptgroupHTMLAttributes<HTMLO
1295
1295
  }
1296
1296
  declare const NativeSelectOptGroup: React$1.ForwardRefExoticComponent<NativeSelectOptGroupProps & React$1.RefAttributes<HTMLOptGroupElement>>;
1297
1297
 
1298
+ /**
1299
+ * DescriptionList — `<dl>` term/detail rows with the site's own spec-sheet
1300
+ * skin (mono, uppercase, tracked term labels; a divided rounded shell).
1301
+ * Lifted out of two hand-rolled call sites — `ComponentMeta`'s doc-page
1302
+ * spec strip and the homepage's "spec" card — into a reusable component.
1303
+ * Gap-fill addition (not in the original Figma source).
1304
+ */
1305
+ declare const DescriptionList: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDListElement> & React$1.RefAttributes<HTMLDListElement>>;
1306
+ interface DescriptionListItemProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "children"> {
1307
+ term: React$1.ReactNode;
1308
+ children: React$1.ReactNode;
1309
+ /** `row` (default) puts the term and value side by side; `stacked` puts the value below a full-width term — better for long values. */
1310
+ layout?: "row" | "stacked";
1311
+ }
1312
+ declare const DescriptionListItem: React$1.ForwardRefExoticComponent<DescriptionListItemProps & React$1.RefAttributes<HTMLDivElement>>;
1313
+
1314
+ /**
1315
+ * Banner — a full-bleed, page-level notice (info/promo/maintenance),
1316
+ * optionally dismissible and stickied to the top of the viewport. Distinct
1317
+ * from `Alert` (in-flow, static) and `Sonner` (transient toast): Banner is
1318
+ * edge-to-edge and persistent until dismissed. Distinct from `Inform`
1319
+ * (contained, rounded inline card): Banner has no rounded corners or own
1320
+ * width — it spans whatever it's placed in, typically the full viewport.
1321
+ * Reuses `Inform`'s intent taxonomy and icon set for a consistent look.
1322
+ * Gap-fill addition (not in the original Figma source).
1323
+ */
1324
+ declare const bannerVariants: (props?: ({
1325
+ variant?: "success" | "warning" | "error" | "information" | "action" | null | undefined;
1326
+ sticky?: boolean | null | undefined;
1327
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1328
+ interface BannerProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof bannerVariants> {
1329
+ hideIcon?: boolean;
1330
+ onDismiss?: () => void;
1331
+ /** optional CTA rendered inline after the message */
1332
+ action?: {
1333
+ label: React$1.ReactNode;
1334
+ onClick?: () => void;
1335
+ };
1336
+ }
1337
+ declare const Banner: React$1.ForwardRefExoticComponent<BannerProps & React$1.RefAttributes<HTMLDivElement>>;
1338
+
1339
+ /**
1340
+ * SegmentedControl — an iOS-style single-select strip. Functionally
1341
+ * `ToggleGroup type="single"`: a thin, documented preset over the same
1342
+ * Radix primitive with the segmented look (`Tabs`' `TabsList`/
1343
+ * `TabsTrigger` visual treatment — filled track, raised active segment)
1344
+ * instead of `Toggle`'s individually-outlined-button look. `type="single"`
1345
+ * is fixed, not exposed — a segmented control that could go fully
1346
+ * unselected or multi-select isn't the pattern. Gap-fill addition (not in
1347
+ * the original Figma source).
1348
+ */
1349
+ type SegmentedControlProps = Omit<ToggleGroupPrimitive.ToggleGroupSingleProps, "type">;
1350
+ declare const SegmentedControl: React$1.ForwardRefExoticComponent<SegmentedControlProps & React$1.RefAttributes<HTMLDivElement>>;
1351
+ declare const SegmentedControlItem: React$1.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
1352
+
1353
+ /**
1354
+ * Timeline — ordered events down a rail (dot, connector, time, content).
1355
+ * `alternating` lays content left/right of a centered rail (desktop);
1356
+ * the default is a single left-aligned rail. Same rail/dot/connector
1357
+ * technique as `Stepper`, but for a history/activity log rather than a
1358
+ * progress indicator — no complete/current/upcoming states, an array of
1359
+ * arbitrary events instead. Gap-fill addition (not in the original Figma
1360
+ * source).
1361
+ */
1362
+ interface TimelineItem {
1363
+ time?: React$1.ReactNode;
1364
+ title: React$1.ReactNode;
1365
+ content?: React$1.ReactNode;
1366
+ /** custom dot content — defaults to a filled circle */
1367
+ icon?: React$1.ReactNode;
1368
+ }
1369
+ interface TimelineProps extends React$1.HTMLAttributes<HTMLOListElement> {
1370
+ items: TimelineItem[];
1371
+ alternating?: boolean;
1372
+ }
1373
+ declare const Timeline: React$1.ForwardRefExoticComponent<TimelineProps & React$1.RefAttributes<HTMLOListElement>>;
1374
+
1298
1375
  /** Merges Tailwind class names, resolving conflicts (clsx + tailwind-merge). */
1299
1376
  declare function cn(...inputs: ClassValue[]): string;
1300
1377
 
1301
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBar, AppBarActions, AppBarBrand, AppBarLink, type AppBarLinkProps, AppBarNav, AspectRatio, AudioPlayer, type AudioPlayerProps, Avatar, AvatarFallback, AvatarGroup, type AvatarGroupProps, AvatarImage, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, type ButtonGroupProps, ButtonGroupSeparator, type ButtonGroupSeparatorProps, ButtonGroupText, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, CircularProgress, type CircularProgressProps, CodeBlock, type CodeBlockFile, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DatePicker, type DatePickerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, type EmptyMediaProps, EmptyTitle, Fab, type FabProps, Field, FieldControl, FieldDescription, FieldLabel, FieldMessage, FileUpload, FileUploadItem, type FileUploadItemProps, type FileUploadProps, Footer, FooterBottom, FooterColumn, type FooterColumnProps, FooterLink, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Image, type ImageProps, Inform, type InformProps, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Kbd, KbdGroup, type KbdGroupProps, type KbdProps, Label, List, ListItem, type ListItemProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Metric, type MetricProps, Modal, type ModalProps, type ModalType, NativeSelect, NativeSelectOptGroup, type NativeSelectOptGroupProps, NativeSelectOption, type NativeSelectOptionProps, type NativeSelectProps, NavigationBar, type NavigationBarProps, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NumberInput, type NumberInputProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, Quote, type QuoteProps, RadioGroup, RadioGroupItem, Rating, type RatingProps, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarProvider, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, type SpinnerProps, Stepper, type StepperProps, type StepperStep, Switch, TabBar, TabBarItem, type TabBarItemProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableOfContents, type TableOfContentsProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, Textarea, type TextareaProps, Toaster, type TocItem, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, badgeVariants, buttonVariants, cn, emptyMediaVariants, fabVariants, formatBytes, informVariants, inputVariants, messageVariants, nativeSelectVariants, navigationMenuTriggerStyle, spinnerVariants, tagVariants, textareaVariants, toggleVariants, useAppBar, useFormField, useSidebar };
1378
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppBar, AppBarActions, AppBarBrand, AppBarLink, type AppBarLinkProps, AppBarNav, AspectRatio, AudioPlayer, type AudioPlayerProps, Avatar, AvatarFallback, AvatarGroup, type AvatarGroupProps, AvatarImage, Badge, type BadgeProps, Banner, type BannerProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, type ButtonGroupProps, ButtonGroupSeparator, type ButtonGroupSeparatorProps, ButtonGroupText, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, CircularProgress, type CircularProgressProps, CodeBlock, type CodeBlockFile, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DatePicker, type DatePickerProps, DescriptionList, DescriptionListItem, type DescriptionListItemProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, type EmptyMediaProps, EmptyTitle, Fab, type FabProps, Field, FieldControl, FieldDescription, FieldLabel, FieldMessage, FileUpload, FileUploadItem, type FileUploadItemProps, type FileUploadProps, Footer, FooterBottom, FooterColumn, type FooterColumnProps, FooterLink, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Image, type ImageProps, Inform, type InformProps, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Kbd, KbdGroup, type KbdGroupProps, type KbdProps, Label, List, ListItem, type ListItemProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Metric, type MetricProps, Modal, type ModalProps, type ModalType, NativeSelect, NativeSelectOptGroup, type NativeSelectOptGroupProps, NativeSelectOption, type NativeSelectOptionProps, type NativeSelectProps, NavigationBar, type NavigationBarProps, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NumberInput, type NumberInputProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, Quote, type QuoteProps, RadioGroup, RadioGroupItem, Rating, type RatingProps, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, SegmentedControl, SegmentedControlItem, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarProvider, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, type SpinnerProps, Stepper, type StepperProps, type StepperStep, Switch, TabBar, TabBarItem, type TabBarItemProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableOfContents, type TableOfContentsProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, Textarea, type TextareaProps, Timeline, type TimelineItem, type TimelineProps, Toaster, type TocItem, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, badgeVariants, bannerVariants, buttonVariants, cn, emptyMediaVariants, fabVariants, formatBytes, informVariants, inputVariants, messageVariants, nativeSelectVariants, navigationMenuTriggerStyle, spinnerVariants, tagVariants, textareaVariants, toggleVariants, useAppBar, useFormField, useSidebar };
package/dist/index.js CHANGED
@@ -4043,6 +4043,169 @@ var NativeSelectOptGroup = React69.forwardRef(
4043
4043
  ({ ...props }, ref) => /* @__PURE__ */ jsx74("optgroup", { ref, ...props })
4044
4044
  );
4045
4045
  NativeSelectOptGroup.displayName = "NativeSelectOptGroup";
4046
+
4047
+ // src/components/description-list.tsx
4048
+ import * as React70 from "react";
4049
+ import { jsx as jsx75, jsxs as jsxs42 } from "react/jsx-runtime";
4050
+ var DescriptionList = React70.forwardRef(
4051
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx75(
4052
+ "dl",
4053
+ {
4054
+ ref,
4055
+ className: cn("divide-y divide-border rounded-lg border border-border bg-muted/20", className),
4056
+ ...props
4057
+ }
4058
+ )
4059
+ );
4060
+ DescriptionList.displayName = "DescriptionList";
4061
+ var DescriptionListItem = React70.forwardRef(
4062
+ ({ className, term, children, layout = "row", ...props }, ref) => /* @__PURE__ */ jsxs42(
4063
+ "div",
4064
+ {
4065
+ ref,
4066
+ className: cn("gap-3 px-3.5 py-2.5", layout === "row" ? "flex items-baseline" : "flex flex-col", className),
4067
+ ...props,
4068
+ children: [
4069
+ /* @__PURE__ */ jsx75(
4070
+ "dt",
4071
+ {
4072
+ className: cn(
4073
+ "shrink-0 font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground",
4074
+ layout === "row" && "w-24"
4075
+ ),
4076
+ children: term
4077
+ }
4078
+ ),
4079
+ /* @__PURE__ */ jsx75("dd", { className: "min-w-0 text-body-sm text-foreground", children })
4080
+ ]
4081
+ }
4082
+ )
4083
+ );
4084
+ DescriptionListItem.displayName = "DescriptionListItem";
4085
+
4086
+ // src/components/banner.tsx
4087
+ import * as React71 from "react";
4088
+ import { cva as cva20 } from "class-variance-authority";
4089
+ import { CircleAlert as CircleAlert3, CircleCheck as CircleCheck3, Info as Info3, TriangleAlert as TriangleAlert4, X as X8 } from "lucide-react";
4090
+ import { jsx as jsx76, jsxs as jsxs43 } from "react/jsx-runtime";
4091
+ var bannerVariants = cva20(
4092
+ "flex w-full items-start gap-2.5 border-b px-4 py-3 text-body-sm font-sans [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0",
4093
+ {
4094
+ variants: {
4095
+ variant: {
4096
+ information: "border-info/20 bg-info/10 text-info",
4097
+ warning: "border-warning/25 bg-warning/15 text-warning",
4098
+ success: "border-success/25 bg-success/15 text-success",
4099
+ error: "border-destructive/20 bg-destructive/10 text-destructive",
4100
+ action: "border-transparent bg-foreground text-background"
4101
+ },
4102
+ sticky: {
4103
+ true: "sticky top-0 z-40",
4104
+ false: ""
4105
+ }
4106
+ },
4107
+ defaultVariants: { variant: "information", sticky: false }
4108
+ }
4109
+ );
4110
+ var ICON2 = {
4111
+ information: Info3,
4112
+ warning: TriangleAlert4,
4113
+ success: CircleCheck3,
4114
+ error: CircleAlert3,
4115
+ action: Info3
4116
+ };
4117
+ var Banner = React71.forwardRef(
4118
+ ({ className, variant = "information", sticky, hideIcon, onDismiss, action, children, ...props }, ref) => {
4119
+ const Icon2 = ICON2[variant ?? "information"];
4120
+ return /* @__PURE__ */ jsxs43("div", { ref, role: "banner", className: cn(bannerVariants({ variant, sticky }), className), ...props, children: [
4121
+ !hideIcon && /* @__PURE__ */ jsx76(Icon2, {}),
4122
+ /* @__PURE__ */ jsxs43("div", { className: "mx-auto flex min-w-0 max-w-4xl flex-1 flex-wrap items-center justify-center gap-x-3 gap-y-1 text-center", children: [
4123
+ /* @__PURE__ */ jsx76("span", { children }),
4124
+ action && /* @__PURE__ */ jsx76(
4125
+ "button",
4126
+ {
4127
+ type: "button",
4128
+ onClick: action.onClick,
4129
+ className: "inline-flex shrink-0 items-center gap-1.5 text-label-md font-medium underline-offset-2 outline-none hover:underline focus-visible:underline",
4130
+ children: action.label
4131
+ }
4132
+ )
4133
+ ] }),
4134
+ onDismiss && /* @__PURE__ */ jsx76(
4135
+ "button",
4136
+ {
4137
+ type: "button",
4138
+ onClick: onDismiss,
4139
+ "aria-label": "Dismiss",
4140
+ className: "-m-0.5 shrink-0 rounded-[2px] p-0.5 opacity-muted outline-none transition-opacity hover:opacity-visible focus-visible:opacity-visible focus-visible:ring-1 focus-visible:ring-current",
4141
+ children: /* @__PURE__ */ jsx76(X8, { className: "size-3.5" })
4142
+ }
4143
+ )
4144
+ ] });
4145
+ }
4146
+ );
4147
+ Banner.displayName = "Banner";
4148
+
4149
+ // src/components/segmented-control.tsx
4150
+ import * as React72 from "react";
4151
+ import * as ToggleGroupPrimitive2 from "@radix-ui/react-toggle-group";
4152
+ import { jsx as jsx77 } from "react/jsx-runtime";
4153
+ var SegmentedControl = React72.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx77(
4154
+ ToggleGroupPrimitive2.Root,
4155
+ {
4156
+ ref,
4157
+ type: "single",
4158
+ className: cn("inline-flex items-center rounded-lg bg-muted p-1 font-sans", className),
4159
+ ...props
4160
+ }
4161
+ ));
4162
+ SegmentedControl.displayName = "SegmentedControl";
4163
+ var SegmentedControlItem = React72.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx77(
4164
+ ToggleGroupPrimitive2.Item,
4165
+ {
4166
+ ref,
4167
+ className: cn(
4168
+ "inline-flex flex-1 items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-label-md font-medium text-muted-foreground transition-all",
4169
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring",
4170
+ "disabled:pointer-events-none disabled:opacity-disabled",
4171
+ "data-[state=on]:bg-background data-[state=on]:text-foreground data-[state=on]:shadow-sm",
4172
+ className
4173
+ ),
4174
+ ...props
4175
+ }
4176
+ ));
4177
+ SegmentedControlItem.displayName = "SegmentedControlItem";
4178
+
4179
+ // src/components/timeline.tsx
4180
+ import * as React73 from "react";
4181
+ import { jsx as jsx78, jsxs as jsxs44 } from "react/jsx-runtime";
4182
+ var Body = ({ item, align }) => /* @__PURE__ */ jsxs44("div", { className: cn("pb-6", align === "right" && "text-right"), children: [
4183
+ item.time && /* @__PURE__ */ jsx78("p", { className: "text-label-sm text-muted-foreground", children: item.time }),
4184
+ /* @__PURE__ */ jsx78("p", { className: "text-label-md font-medium text-foreground", children: item.title }),
4185
+ item.content && /* @__PURE__ */ jsx78("div", { className: "text-body-sm text-muted-foreground", children: item.content })
4186
+ ] });
4187
+ var Rail = ({ item, isLast }) => /* @__PURE__ */ jsxs44("div", { className: "flex flex-col items-center", children: [
4188
+ /* @__PURE__ */ jsx78("span", { className: "flex size-2.5 shrink-0 items-center justify-center rounded-full bg-primary", children: item.icon }),
4189
+ !isLast && /* @__PURE__ */ jsx78("span", { "aria-hidden": true, className: "my-1 w-px flex-1 bg-border" })
4190
+ ] });
4191
+ var Timeline = React73.forwardRef(
4192
+ ({ className, items, alternating = false, ...props }, ref) => /* @__PURE__ */ jsx78("ol", { ref, className: cn("flex flex-col font-sans", className), ...props, children: items.map((item, i) => {
4193
+ const isLast = i === items.length - 1;
4194
+ if (!alternating) {
4195
+ return /* @__PURE__ */ jsxs44("li", { className: "grid grid-cols-[auto_1fr] gap-x-3", children: [
4196
+ /* @__PURE__ */ jsx78(Rail, { item, isLast }),
4197
+ /* @__PURE__ */ jsx78(Body, { item, align: "left" })
4198
+ ] }, i);
4199
+ }
4200
+ const onRight = i % 2 === 0;
4201
+ return /* @__PURE__ */ jsxs44("li", { className: "grid grid-cols-[1fr_auto_1fr] gap-x-4", children: [
4202
+ onRight ? /* @__PURE__ */ jsx78("div", {}) : /* @__PURE__ */ jsx78(Body, { item, align: "right" }),
4203
+ /* @__PURE__ */ jsx78(Rail, { item, isLast }),
4204
+ onRight ? /* @__PURE__ */ jsx78(Body, { item, align: "left" }) : /* @__PURE__ */ jsx78("div", {})
4205
+ ] }, i);
4206
+ }) })
4207
+ );
4208
+ Timeline.displayName = "Timeline";
4046
4209
  export {
4047
4210
  Accordion,
4048
4211
  AccordionContent,
@@ -4074,6 +4237,7 @@ export {
4074
4237
  AvatarGroup,
4075
4238
  AvatarImage,
4076
4239
  Badge,
4240
+ Banner,
4077
4241
  Breadcrumb,
4078
4242
  BreadcrumbEllipsis,
4079
4243
  BreadcrumbItem,
@@ -4135,6 +4299,8 @@ export {
4135
4299
  ContextMenuTrigger,
4136
4300
  DataTable,
4137
4301
  DatePicker,
4302
+ DescriptionList,
4303
+ DescriptionListItem,
4138
4304
  Dialog,
4139
4305
  DialogClose,
4140
4306
  DialogContent,
@@ -4268,6 +4434,8 @@ export {
4268
4434
  ResizablePanelGroup,
4269
4435
  ScrollArea,
4270
4436
  ScrollBar,
4437
+ SegmentedControl,
4438
+ SegmentedControlItem,
4271
4439
  Select,
4272
4440
  SelectContent,
4273
4441
  SelectGroup,
@@ -4325,6 +4493,7 @@ export {
4325
4493
  TabsTrigger,
4326
4494
  Tag,
4327
4495
  Textarea,
4496
+ Timeline,
4328
4497
  Toaster,
4329
4498
  Toggle,
4330
4499
  ToggleGroup,
@@ -4334,6 +4503,7 @@ export {
4334
4503
  TooltipProvider,
4335
4504
  TooltipTrigger,
4336
4505
  badgeVariants,
4506
+ bannerVariants,
4337
4507
  buttonVariants,
4338
4508
  cn,
4339
4509
  emptyMediaVariants,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kinetixui/ui",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "private": false,
5
5
  "description": "KinetixUI React components — CVA + Radix + Tailwind on the KinetixUI token contract. Also distributed via the kinetixui CLI as a component registry.",
6
6
  "keywords": [
@@ -90,7 +90,7 @@
90
90
  "react-dom": ">=18"
91
91
  },
92
92
  "devDependencies": {
93
- "@kinetixui/tokens": "0.9.0",
93
+ "@kinetixui/tokens": "0.10.0",
94
94
  "@testing-library/jest-dom": "^7.0.1",
95
95
  "@testing-library/react": "^16.3.3",
96
96
  "@testing-library/user-event": "^14.6.7",
@@ -0,0 +1,89 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import { CircleAlert, CircleCheck, Info, TriangleAlert, X } from "lucide-react";
6
+ import { cn } from "../lib/utils";
7
+
8
+ /**
9
+ * Banner — a full-bleed, page-level notice (info/promo/maintenance),
10
+ * optionally dismissible and stickied to the top of the viewport. Distinct
11
+ * from `Alert` (in-flow, static) and `Sonner` (transient toast): Banner is
12
+ * edge-to-edge and persistent until dismissed. Distinct from `Inform`
13
+ * (contained, rounded inline card): Banner has no rounded corners or own
14
+ * width — it spans whatever it's placed in, typically the full viewport.
15
+ * Reuses `Inform`'s intent taxonomy and icon set for a consistent look.
16
+ * Gap-fill addition (not in the original Figma source).
17
+ */
18
+ const bannerVariants = cva(
19
+ "flex w-full items-start gap-2.5 border-b px-4 py-3 text-body-sm font-sans [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0",
20
+ {
21
+ variants: {
22
+ variant: {
23
+ information: "border-info/20 bg-info/10 text-info",
24
+ warning: "border-warning/25 bg-warning/15 text-warning",
25
+ success: "border-success/25 bg-success/15 text-success",
26
+ error: "border-destructive/20 bg-destructive/10 text-destructive",
27
+ action: "border-transparent bg-foreground text-background",
28
+ },
29
+ sticky: {
30
+ true: "sticky top-0 z-40",
31
+ false: "",
32
+ },
33
+ },
34
+ defaultVariants: { variant: "information", sticky: false },
35
+ },
36
+ );
37
+
38
+ const ICON = {
39
+ information: Info,
40
+ warning: TriangleAlert,
41
+ success: CircleCheck,
42
+ error: CircleAlert,
43
+ action: Info,
44
+ } as const;
45
+
46
+ export interface BannerProps
47
+ extends React.HTMLAttributes<HTMLDivElement>,
48
+ VariantProps<typeof bannerVariants> {
49
+ hideIcon?: boolean;
50
+ onDismiss?: () => void;
51
+ /** optional CTA rendered inline after the message */
52
+ action?: { label: React.ReactNode; onClick?: () => void };
53
+ }
54
+
55
+ const Banner = React.forwardRef<HTMLDivElement, BannerProps>(
56
+ ({ className, variant = "information", sticky, hideIcon, onDismiss, action, children, ...props }, ref) => {
57
+ const Icon = ICON[variant ?? "information"];
58
+ return (
59
+ <div ref={ref} role="banner" className={cn(bannerVariants({ variant, sticky }), className)} {...props}>
60
+ {!hideIcon && <Icon />}
61
+ <div className="mx-auto flex min-w-0 max-w-4xl flex-1 flex-wrap items-center justify-center gap-x-3 gap-y-1 text-center">
62
+ <span>{children}</span>
63
+ {action && (
64
+ <button
65
+ type="button"
66
+ onClick={action.onClick}
67
+ className="inline-flex shrink-0 items-center gap-1.5 text-label-md font-medium underline-offset-2 outline-none hover:underline focus-visible:underline"
68
+ >
69
+ {action.label}
70
+ </button>
71
+ )}
72
+ </div>
73
+ {onDismiss && (
74
+ <button
75
+ type="button"
76
+ onClick={onDismiss}
77
+ aria-label="Dismiss"
78
+ className="-m-0.5 shrink-0 rounded-[2px] p-0.5 opacity-muted outline-none transition-opacity hover:opacity-visible focus-visible:opacity-visible focus-visible:ring-1 focus-visible:ring-current"
79
+ >
80
+ <X className="size-3.5" />
81
+ </button>
82
+ )}
83
+ </div>
84
+ );
85
+ },
86
+ );
87
+ Banner.displayName = "Banner";
88
+
89
+ export { Banner, bannerVariants };
@@ -0,0 +1,52 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cn } from "../lib/utils";
5
+
6
+ /**
7
+ * DescriptionList — `<dl>` term/detail rows with the site's own spec-sheet
8
+ * skin (mono, uppercase, tracked term labels; a divided rounded shell).
9
+ * Lifted out of two hand-rolled call sites — `ComponentMeta`'s doc-page
10
+ * spec strip and the homepage's "spec" card — into a reusable component.
11
+ * Gap-fill addition (not in the original Figma source).
12
+ */
13
+ const DescriptionList = React.forwardRef<HTMLDListElement, React.HTMLAttributes<HTMLDListElement>>(
14
+ ({ className, ...props }, ref) => (
15
+ <dl
16
+ ref={ref}
17
+ className={cn("divide-y divide-border rounded-lg border border-border bg-muted/20", className)}
18
+ {...props}
19
+ />
20
+ ),
21
+ );
22
+ DescriptionList.displayName = "DescriptionList";
23
+
24
+ export interface DescriptionListItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
25
+ term: React.ReactNode;
26
+ children: React.ReactNode;
27
+ /** `row` (default) puts the term and value side by side; `stacked` puts the value below a full-width term — better for long values. */
28
+ layout?: "row" | "stacked";
29
+ }
30
+
31
+ const DescriptionListItem = React.forwardRef<HTMLDivElement, DescriptionListItemProps>(
32
+ ({ className, term, children, layout = "row", ...props }, ref) => (
33
+ <div
34
+ ref={ref}
35
+ className={cn("gap-3 px-3.5 py-2.5", layout === "row" ? "flex items-baseline" : "flex flex-col", className)}
36
+ {...props}
37
+ >
38
+ <dt
39
+ className={cn(
40
+ "shrink-0 font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground",
41
+ layout === "row" && "w-24",
42
+ )}
43
+ >
44
+ {term}
45
+ </dt>
46
+ <dd className="min-w-0 text-body-sm text-foreground">{children}</dd>
47
+ </div>
48
+ ),
49
+ );
50
+ DescriptionListItem.displayName = "DescriptionListItem";
51
+
52
+ export { DescriptionList, DescriptionListItem };
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
5
+ import { cn } from "../lib/utils";
6
+
7
+ /**
8
+ * SegmentedControl — an iOS-style single-select strip. Functionally
9
+ * `ToggleGroup type="single"`: a thin, documented preset over the same
10
+ * Radix primitive with the segmented look (`Tabs`' `TabsList`/
11
+ * `TabsTrigger` visual treatment — filled track, raised active segment)
12
+ * instead of `Toggle`'s individually-outlined-button look. `type="single"`
13
+ * is fixed, not exposed — a segmented control that could go fully
14
+ * unselected or multi-select isn't the pattern. Gap-fill addition (not in
15
+ * the original Figma source).
16
+ */
17
+ export type SegmentedControlProps = Omit<ToggleGroupPrimitive.ToggleGroupSingleProps, "type">;
18
+
19
+ const SegmentedControl = React.forwardRef<
20
+ React.ElementRef<typeof ToggleGroupPrimitive.Root>,
21
+ SegmentedControlProps
22
+ >(({ className, ...props }, ref) => (
23
+ <ToggleGroupPrimitive.Root
24
+ ref={ref}
25
+ type="single"
26
+ className={cn("inline-flex items-center rounded-lg bg-muted p-1 font-sans", className)}
27
+ {...props}
28
+ />
29
+ ));
30
+ SegmentedControl.displayName = "SegmentedControl";
31
+
32
+ const SegmentedControlItem = React.forwardRef<
33
+ React.ElementRef<typeof ToggleGroupPrimitive.Item>,
34
+ React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item>
35
+ >(({ className, ...props }, ref) => (
36
+ <ToggleGroupPrimitive.Item
37
+ ref={ref}
38
+ className={cn(
39
+ "inline-flex flex-1 items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-label-md font-medium text-muted-foreground transition-all",
40
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring",
41
+ "disabled:pointer-events-none disabled:opacity-disabled",
42
+ "data-[state=on]:bg-background data-[state=on]:text-foreground data-[state=on]:shadow-sm",
43
+ className,
44
+ )}
45
+ {...props}
46
+ />
47
+ ));
48
+ SegmentedControlItem.displayName = "SegmentedControlItem";
49
+
50
+ export { SegmentedControl, SegmentedControlItem };
@@ -0,0 +1,70 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cn } from "../lib/utils";
5
+
6
+ /**
7
+ * Timeline — ordered events down a rail (dot, connector, time, content).
8
+ * `alternating` lays content left/right of a centered rail (desktop);
9
+ * the default is a single left-aligned rail. Same rail/dot/connector
10
+ * technique as `Stepper`, but for a history/activity log rather than a
11
+ * progress indicator — no complete/current/upcoming states, an array of
12
+ * arbitrary events instead. Gap-fill addition (not in the original Figma
13
+ * source).
14
+ */
15
+ export interface TimelineItem {
16
+ time?: React.ReactNode;
17
+ title: React.ReactNode;
18
+ content?: React.ReactNode;
19
+ /** custom dot content — defaults to a filled circle */
20
+ icon?: React.ReactNode;
21
+ }
22
+
23
+ export interface TimelineProps extends React.HTMLAttributes<HTMLOListElement> {
24
+ items: TimelineItem[];
25
+ alternating?: boolean;
26
+ }
27
+
28
+ const Body = ({ item, align }: { item: TimelineItem; align: "left" | "right" }) => (
29
+ <div className={cn("pb-6", align === "right" && "text-right")}>
30
+ {item.time && <p className="text-label-sm text-muted-foreground">{item.time}</p>}
31
+ <p className="text-label-md font-medium text-foreground">{item.title}</p>
32
+ {item.content && <div className="text-body-sm text-muted-foreground">{item.content}</div>}
33
+ </div>
34
+ );
35
+
36
+ const Rail = ({ item, isLast }: { item: TimelineItem; isLast: boolean }) => (
37
+ <div className="flex flex-col items-center">
38
+ <span className="flex size-2.5 shrink-0 items-center justify-center rounded-full bg-primary">{item.icon}</span>
39
+ {!isLast && <span aria-hidden className="my-1 w-px flex-1 bg-border" />}
40
+ </div>
41
+ );
42
+
43
+ const Timeline = React.forwardRef<HTMLOListElement, TimelineProps>(
44
+ ({ className, items, alternating = false, ...props }, ref) => (
45
+ <ol ref={ref} className={cn("flex flex-col font-sans", className)} {...props}>
46
+ {items.map((item, i) => {
47
+ const isLast = i === items.length - 1;
48
+ if (!alternating) {
49
+ return (
50
+ <li key={i} className="grid grid-cols-[auto_1fr] gap-x-3">
51
+ <Rail item={item} isLast={isLast} />
52
+ <Body item={item} align="left" />
53
+ </li>
54
+ );
55
+ }
56
+ const onRight = i % 2 === 0;
57
+ return (
58
+ <li key={i} className="grid grid-cols-[1fr_auto_1fr] gap-x-4">
59
+ {onRight ? <div /> : <Body item={item} align="right" />}
60
+ <Rail item={item} isLast={isLast} />
61
+ {onRight ? <Body item={item} align="left" /> : <div />}
62
+ </li>
63
+ );
64
+ })}
65
+ </ol>
66
+ ),
67
+ );
68
+ Timeline.displayName = "Timeline";
69
+
70
+ export { Timeline };
package/src/index.ts CHANGED
@@ -339,5 +339,17 @@ export {
339
339
  type NativeSelectOptionProps,
340
340
  type NativeSelectOptGroupProps,
341
341
  } from "./components/native-select";
342
+ export {
343
+ DescriptionList,
344
+ DescriptionListItem,
345
+ type DescriptionListItemProps,
346
+ } from "./components/description-list";
347
+ export { Banner, bannerVariants, type BannerProps } from "./components/banner";
348
+ export {
349
+ SegmentedControl,
350
+ SegmentedControlItem,
351
+ type SegmentedControlProps,
352
+ } from "./components/segmented-control";
353
+ export { Timeline, type TimelineItem, type TimelineProps } from "./components/timeline";
342
354
 
343
355
  export { cn } from "./lib/utils";
@@ -0,0 +1,28 @@
1
+ /* AUTO-GENERATED by scripts/gen-stories.mjs — do not edit.
2
+ Source of truth: apps/web/src/registry/demos.tsx */
3
+ import * as React from "react";
4
+ import type { Meta, StoryObj } from "@storybook/react-vite";
5
+ import { Banner } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <div className="flex w-full flex-col gap-3">
9
+ <Banner variant="information" onDismiss={() => {}} action={{ label: "Learn more" }}>
10
+ A new version of KinetixUI is available.
11
+ </Banner>
12
+ <Banner variant="action" action={{ label: "Upgrade" }}>
13
+ You&rsquo;re on the free plan — upgrade for unlimited projects.
14
+ </Banner>
15
+ </div>
16
+ );
17
+
18
+ const meta = {
19
+ title: "Feedback/Banner",
20
+ parameters: {
21
+ layout: "centered",
22
+ docs: { source: { code: "<Banner variant=\"information\" onDismiss={close} action={{ label: \"Learn more\" }}>\\n A new version of KinetixUI is available.\\n</Banner>", language: "tsx" } },
23
+ },
24
+ } satisfies Meta;
25
+
26
+ export default meta;
27
+
28
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,26 @@
1
+ /* AUTO-GENERATED by scripts/gen-stories.mjs — do not edit.
2
+ Source of truth: apps/web/src/registry/demos.tsx */
3
+ import * as React from "react";
4
+ import type { Meta, StoryObj } from "@storybook/react-vite";
5
+ import { Avatar, DescriptionList, DescriptionListItem } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <DescriptionList className="w-full max-w-sm">
9
+ <DescriptionListItem term="Category">Data Display</DescriptionListItem>
10
+ <DescriptionListItem term="Built on">Radix Avatar</DescriptionListItem>
11
+ <DescriptionListItem term="Platforms">React, SwiftUI, Compose, Flutter</DescriptionListItem>
12
+ <DescriptionListItem term="CLI">npx @kinetixui/cli add avatar</DescriptionListItem>
13
+ </DescriptionList>
14
+ );
15
+
16
+ const meta = {
17
+ title: "Data Display/DescriptionList",
18
+ parameters: {
19
+ layout: "centered",
20
+ docs: { source: { code: "<DescriptionList>\\n <DescriptionListItem term=\"Category\">Data Display</DescriptionListItem>\\n <DescriptionListItem term=\"Built on\">Radix Avatar</DescriptionListItem>\\n</DescriptionList>", language: "tsx" } },
21
+ },
22
+ } satisfies Meta;
23
+
24
+ export default meta;
25
+
26
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,25 @@
1
+ /* AUTO-GENERATED by scripts/gen-stories.mjs — do not edit.
2
+ Source of truth: apps/web/src/registry/demos.tsx */
3
+ import * as React from "react";
4
+ import type { Meta, StoryObj } from "@storybook/react-vite";
5
+ import { List, SegmentedControl, SegmentedControlItem } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <SegmentedControl defaultValue="grid" className="w-full max-w-xs">
9
+ <SegmentedControlItem value="list">List</SegmentedControlItem>
10
+ <SegmentedControlItem value="grid">Grid</SegmentedControlItem>
11
+ <SegmentedControlItem value="board">Board</SegmentedControlItem>
12
+ </SegmentedControl>
13
+ );
14
+
15
+ const meta = {
16
+ title: "Controls & Actions/SegmentedControl",
17
+ parameters: {
18
+ layout: "centered",
19
+ docs: { source: { code: "<SegmentedControl defaultValue=\"grid\">\\n <SegmentedControlItem value=\"list\">List</SegmentedControlItem>\\n <SegmentedControlItem value=\"grid\">Grid</SegmentedControlItem>\\n <SegmentedControlItem value=\"board\">Board</SegmentedControlItem>\\n</SegmentedControl>", language: "tsx" } },
20
+ },
21
+ } satisfies Meta;
22
+
23
+ export default meta;
24
+
25
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,28 @@
1
+ /* AUTO-GENERATED by scripts/gen-stories.mjs — do not edit.
2
+ Source of truth: apps/web/src/registry/demos.tsx */
3
+ import * as React from "react";
4
+ import type { Meta, StoryObj } from "@storybook/react-vite";
5
+ import { SegmentedControl, Timeline } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <Timeline
9
+ className="w-full max-w-sm"
10
+ items={[
11
+ { time: "2 hours ago", title: "Deployed to production", content: "v0.9.0 shipped." },
12
+ { time: "Yesterday", title: "Opened PR #100", content: "feat(ui): add SegmentedControl" },
13
+ { time: "3 days ago", title: "Project created" },
14
+ ]}
15
+ />
16
+ );
17
+
18
+ const meta = {
19
+ title: "Data Display/Timeline",
20
+ parameters: {
21
+ layout: "centered",
22
+ docs: { source: { code: "<Timeline\\n items={[\\n { time: \"2 hours ago\", title: \"Deployed to production\", content: \"v0.9.0 shipped.\" },\\n { time: \"Yesterday\", title: \"Opened PR #100\" },\\n ]}\\n/>", language: "tsx" } },
23
+ },
24
+ } satisfies Meta;
25
+
26
+ export default meta;
27
+
28
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };