@kinetixui/ui 0.7.0 → 0.9.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
@@ -1217,7 +1217,85 @@ interface TableOfContentsProps extends React$1.HTMLAttributes<HTMLElement> {
1217
1217
  }
1218
1218
  declare const TableOfContents: React$1.ForwardRefExoticComponent<TableOfContentsProps & React$1.RefAttributes<HTMLElement>>;
1219
1219
 
1220
+ /**
1221
+ * Kbd — a single keyboard key glyph, e.g. `<Kbd>⌘</Kbd>`. Wrap several in
1222
+ * `KbdGroup` for a shortcut combo (`⌘` `K`). Gap-fill addition (not in the
1223
+ * original Figma source) — matches the shadcn/ui Kbd/KbdGroup API shape.
1224
+ */
1225
+ interface KbdProps extends React$1.HTMLAttributes<HTMLElement> {
1226
+ /** render as the single child element (Radix Slot) instead of <kbd> */
1227
+ asChild?: boolean;
1228
+ }
1229
+ declare const Kbd: React$1.ForwardRefExoticComponent<KbdProps & React$1.RefAttributes<HTMLElement>>;
1230
+ interface KbdGroupProps extends React$1.HTMLAttributes<HTMLElement> {
1231
+ }
1232
+ /** Lays out multiple `Kbd` for a shortcut combo — `<KbdGroup><Kbd>⌘</Kbd><Kbd>K</Kbd></KbdGroup>` */
1233
+ declare const KbdGroup: React$1.ForwardRefExoticComponent<KbdGroupProps & React$1.RefAttributes<HTMLElement>>;
1234
+
1235
+ /**
1236
+ * Empty — a placeholder for a zero-results state (an empty table, an empty
1237
+ * search, a fresh workspace with nothing in it yet). Composition-based, like
1238
+ * Card: `Empty` is an unstyled-beyond-layout root so it composes cleanly
1239
+ * inside whatever already has a border (a Table cell, a Card, a bare page
1240
+ * section) instead of forcing its own. Gap-fill addition (not in the
1241
+ * original Figma source) — matches the shadcn/ui Empty API shape.
1242
+ */
1243
+ declare const Empty: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
1244
+ declare const EmptyHeader: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
1245
+ declare const emptyMediaVariants: (props?: ({
1246
+ variant?: "icon" | "default" | null | undefined;
1247
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1248
+ interface EmptyMediaProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof emptyMediaVariants> {
1249
+ }
1250
+ declare const EmptyMedia: React$1.ForwardRefExoticComponent<EmptyMediaProps & React$1.RefAttributes<HTMLDivElement>>;
1251
+ declare const EmptyTitle: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
1252
+ declare const EmptyDescription: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
1253
+ declare const EmptyContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
1254
+
1255
+ /**
1256
+ * ButtonGroup — visually joins adjacent buttons into a connected cluster
1257
+ * (segmented-control style): inner corners squared off, shared borders
1258
+ * overlapped by 1px so they don't double up, the focused child raised
1259
+ * above its neighbours so its ring isn't clipped. Gap-fill addition (not
1260
+ * in the original Figma source) — matches the shadcn/ui ButtonGroup API
1261
+ * shape. Works with any child that renders its own border/radius (Button,
1262
+ * ButtonGroupText, a Select trigger, …), not just `<Button>`.
1263
+ */
1264
+ interface ButtonGroupProps extends React$1.HTMLAttributes<HTMLDivElement> {
1265
+ orientation?: "horizontal" | "vertical";
1266
+ }
1267
+ declare const ButtonGroup: React$1.ForwardRefExoticComponent<ButtonGroupProps & React$1.RefAttributes<HTMLDivElement>>;
1268
+ interface ButtonGroupSeparatorProps extends React$1.HTMLAttributes<HTMLDivElement> {
1269
+ orientation?: "horizontal" | "vertical";
1270
+ }
1271
+ /** A thin divider between segments — useful between non-outline buttons, where the group's own overlap trick has no shared border to lean on. */
1272
+ declare const ButtonGroupSeparator: React$1.ForwardRefExoticComponent<ButtonGroupSeparatorProps & React$1.RefAttributes<HTMLDivElement>>;
1273
+ /** A static, non-interactive label segment inside a group — e.g. a unit or a prefix next to steppers. */
1274
+ declare const ButtonGroupText: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLSpanElement> & React$1.RefAttributes<HTMLSpanElement>>;
1275
+
1276
+ /**
1277
+ * NativeSelect — a styled wrapper around the native `<select>` element,
1278
+ * for when a form should submit synchronously without JS (or just prefers
1279
+ * the OS-native picker on mobile) instead of Select's Radix popover.
1280
+ * Matches Input's `inputVariants` styling 1:1 so the two are drop-in
1281
+ * interchangeable in a Field. Gap-fill addition (not in the original
1282
+ * Figma source) — matches the shadcn/ui Native Select API shape.
1283
+ */
1284
+ declare const nativeSelectVariants: (props?: ({
1285
+ state?: "Default" | "Focus" | "Disabled" | "Error" | null | undefined;
1286
+ corners?: "sharp" | "default" | "pill" | "rounded" | null | undefined;
1287
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1288
+ interface NativeSelectProps extends Omit<React$1.SelectHTMLAttributes<HTMLSelectElement>, "size">, VariantProps<typeof nativeSelectVariants> {
1289
+ }
1290
+ declare const NativeSelect: React$1.ForwardRefExoticComponent<NativeSelectProps & React$1.RefAttributes<HTMLSelectElement>>;
1291
+ interface NativeSelectOptionProps extends React$1.OptionHTMLAttributes<HTMLOptionElement> {
1292
+ }
1293
+ declare const NativeSelectOption: React$1.ForwardRefExoticComponent<NativeSelectOptionProps & React$1.RefAttributes<HTMLOptionElement>>;
1294
+ interface NativeSelectOptGroupProps extends React$1.OptgroupHTMLAttributes<HTMLOptGroupElement> {
1295
+ }
1296
+ declare const NativeSelectOptGroup: React$1.ForwardRefExoticComponent<NativeSelectOptGroupProps & React$1.RefAttributes<HTMLOptGroupElement>>;
1297
+
1220
1298
  /** Merges Tailwind class names, resolving conflicts (clsx + tailwind-merge). */
1221
1299
  declare function cn(...inputs: ClassValue[]): string;
1222
1300
 
1223
- 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, 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, 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, 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, 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, fabVariants, formatBytes, informVariants, inputVariants, messageVariants, navigationMenuTriggerStyle, spinnerVariants, tagVariants, textareaVariants, toggleVariants, useAppBar, useFormField, useSidebar };
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 };
package/dist/index.js CHANGED
@@ -3867,6 +3867,182 @@ var TableOfContents = React65.forwardRef(
3867
3867
  }) })
3868
3868
  );
3869
3869
  TableOfContents.displayName = "TableOfContents";
3870
+
3871
+ // src/components/kbd.tsx
3872
+ import * as React66 from "react";
3873
+ import { Slot as Slot10 } from "@radix-ui/react-slot";
3874
+ import { jsx as jsx71 } from "react/jsx-runtime";
3875
+ var Kbd = React66.forwardRef(({ className, asChild = false, ...props }, ref) => {
3876
+ const Comp = asChild ? Slot10 : "kbd";
3877
+ return /* @__PURE__ */ jsx71(
3878
+ Comp,
3879
+ {
3880
+ ref,
3881
+ className: cn(
3882
+ "inline-flex h-5 min-w-5 items-center justify-center rounded-sm border border-input bg-muted px-1.5 font-sans text-[11px] font-medium text-muted-foreground",
3883
+ className
3884
+ ),
3885
+ ...props
3886
+ }
3887
+ );
3888
+ });
3889
+ Kbd.displayName = "Kbd";
3890
+ var KbdGroup = React66.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx71("kbd", { ref, className: cn("inline-flex items-center gap-1", className), ...props }));
3891
+ KbdGroup.displayName = "KbdGroup";
3892
+
3893
+ // src/components/empty.tsx
3894
+ import * as React67 from "react";
3895
+ import { cva as cva18 } from "class-variance-authority";
3896
+ import { jsx as jsx72 } from "react/jsx-runtime";
3897
+ var Empty = React67.forwardRef(
3898
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx72(
3899
+ "div",
3900
+ {
3901
+ ref,
3902
+ className: cn("flex min-w-0 flex-1 flex-col items-center justify-center gap-6 p-10 text-center font-sans", className),
3903
+ ...props
3904
+ }
3905
+ )
3906
+ );
3907
+ Empty.displayName = "Empty";
3908
+ var EmptyHeader = React67.forwardRef(
3909
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx72("div", { ref, className: cn("flex max-w-sm flex-col items-center gap-2", className), ...props })
3910
+ );
3911
+ EmptyHeader.displayName = "EmptyHeader";
3912
+ var emptyMediaVariants = cva18("flex shrink-0 items-center justify-center", {
3913
+ variants: {
3914
+ /** `icon` gives a muted circular badge behind the icon; `default` renders the child as-is (an illustration, an avatar, …) */
3915
+ variant: {
3916
+ default: "",
3917
+ icon: "size-10 rounded-full bg-muted text-muted-foreground [&_svg]:size-5"
3918
+ }
3919
+ },
3920
+ defaultVariants: { variant: "default" }
3921
+ });
3922
+ var EmptyMedia = React67.forwardRef(
3923
+ ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx72("div", { ref, className: cn(emptyMediaVariants({ variant }), className), ...props })
3924
+ );
3925
+ EmptyMedia.displayName = "EmptyMedia";
3926
+ var EmptyTitle = React67.forwardRef(
3927
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx72("p", { ref, className: cn("text-title-sm font-medium text-foreground", className), ...props })
3928
+ );
3929
+ EmptyTitle.displayName = "EmptyTitle";
3930
+ var EmptyDescription = React67.forwardRef(
3931
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx72("p", { ref, className: cn("text-body-sm text-muted-foreground", className), ...props })
3932
+ );
3933
+ EmptyDescription.displayName = "EmptyDescription";
3934
+ var EmptyContent = React67.forwardRef(
3935
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx72("div", { ref, className: cn("flex flex-col items-center gap-3", className), ...props })
3936
+ );
3937
+ EmptyContent.displayName = "EmptyContent";
3938
+
3939
+ // src/components/button-group.tsx
3940
+ import * as React68 from "react";
3941
+ import { jsx as jsx73 } from "react/jsx-runtime";
3942
+ var ButtonGroup = React68.forwardRef(
3943
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx73(
3944
+ "div",
3945
+ {
3946
+ ref,
3947
+ role: "group",
3948
+ "data-orientation": orientation,
3949
+ className: cn(
3950
+ "flex w-fit items-stretch [&>*]:relative [&>*]:focus-visible:z-10",
3951
+ orientation === "horizontal" ? "flex-row [&>*:not(:first-child)]:-ml-px [&>*:not(:first-child)]:rounded-l-none [&>*:not(:last-child)]:rounded-r-none" : "flex-col [&>*:not(:first-child)]:-mt-px [&>*:not(:first-child)]:rounded-t-none [&>*:not(:last-child)]:rounded-b-none",
3952
+ className
3953
+ ),
3954
+ ...props
3955
+ }
3956
+ )
3957
+ );
3958
+ ButtonGroup.displayName = "ButtonGroup";
3959
+ var ButtonGroupSeparator = React68.forwardRef(
3960
+ ({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx73(
3961
+ "div",
3962
+ {
3963
+ ref,
3964
+ role: "separator",
3965
+ "aria-orientation": orientation,
3966
+ className: cn("shrink-0 self-stretch bg-border", orientation === "vertical" ? "my-1.5 w-px" : "mx-1.5 h-px", className),
3967
+ ...props
3968
+ }
3969
+ )
3970
+ );
3971
+ ButtonGroupSeparator.displayName = "ButtonGroupSeparator";
3972
+ var ButtonGroupText = React68.forwardRef(
3973
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx73(
3974
+ "span",
3975
+ {
3976
+ ref,
3977
+ className: cn(
3978
+ "flex items-center gap-1.5 rounded-md border border-input bg-muted px-3 text-label-md text-foreground",
3979
+ className
3980
+ ),
3981
+ ...props
3982
+ }
3983
+ )
3984
+ );
3985
+ ButtonGroupText.displayName = "ButtonGroupText";
3986
+
3987
+ // src/components/native-select.tsx
3988
+ import * as React69 from "react";
3989
+ import { ChevronDown as ChevronDown4 } from "lucide-react";
3990
+ import { cva as cva19 } from "class-variance-authority";
3991
+ import { jsx as jsx74, jsxs as jsxs41 } from "react/jsx-runtime";
3992
+ var nativeSelectVariants = cva19(
3993
+ [
3994
+ "flex w-full appearance-none border border-input bg-background px-3 py-3 pr-9",
3995
+ "font-sans text-[14px] leading-5 tracking-[0.25px] text-foreground",
3996
+ "outline-none transition-colors",
3997
+ "focus-visible:border-primary focus-visible:shadow-focus",
3998
+ "disabled:cursor-not-allowed disabled:opacity-disabled",
3999
+ "aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive aria-[invalid=true]:focus-visible:shadow-focus-destructive"
4000
+ ],
4001
+ {
4002
+ variants: {
4003
+ state: {
4004
+ Default: "",
4005
+ Focus: "border-primary shadow-focus",
4006
+ Error: "border-destructive",
4007
+ Disabled: "opacity-disabled pointer-events-none"
4008
+ },
4009
+ corners: {
4010
+ sharp: "rounded-none",
4011
+ default: "rounded-sm",
4012
+ rounded: "rounded-md",
4013
+ pill: "rounded-full px-4"
4014
+ }
4015
+ },
4016
+ defaultVariants: { state: "Default", corners: "default" }
4017
+ }
4018
+ );
4019
+ var NativeSelect = React69.forwardRef(
4020
+ ({ className, state, corners, disabled, "aria-invalid": ariaInvalid, children, ...props }, ref) => /* @__PURE__ */ jsxs41("div", { className: "relative", children: [
4021
+ /* @__PURE__ */ jsx74(
4022
+ "select",
4023
+ {
4024
+ ref,
4025
+ "data-slot": "native-select",
4026
+ "data-state": state ? state.toLowerCase() : void 0,
4027
+ "aria-invalid": ariaInvalid ?? (state === "Error" || void 0),
4028
+ disabled: disabled || state === "Disabled",
4029
+ className: cn(nativeSelectVariants({ state, corners }), className),
4030
+ ...props,
4031
+ children
4032
+ }
4033
+ ),
4034
+ /* @__PURE__ */ jsx74(ChevronDown4, { className: "pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" })
4035
+ ] })
4036
+ );
4037
+ NativeSelect.displayName = "NativeSelect";
4038
+ var NativeSelectOption = React69.forwardRef(
4039
+ ({ ...props }, ref) => /* @__PURE__ */ jsx74("option", { ref, ...props })
4040
+ );
4041
+ NativeSelectOption.displayName = "NativeSelectOption";
4042
+ var NativeSelectOptGroup = React69.forwardRef(
4043
+ ({ ...props }, ref) => /* @__PURE__ */ jsx74("optgroup", { ref, ...props })
4044
+ );
4045
+ NativeSelectOptGroup.displayName = "NativeSelectOptGroup";
3870
4046
  export {
3871
4047
  Accordion,
3872
4048
  AccordionContent,
@@ -3906,6 +4082,9 @@ export {
3906
4082
  BreadcrumbPage,
3907
4083
  BreadcrumbSeparator,
3908
4084
  Button,
4085
+ ButtonGroup,
4086
+ ButtonGroupSeparator,
4087
+ ButtonGroupText,
3909
4088
  Calendar,
3910
4089
  Card,
3911
4090
  CardContent,
@@ -3991,6 +4170,12 @@ export {
3991
4170
  DropdownMenuSubContent,
3992
4171
  DropdownMenuSubTrigger,
3993
4172
  DropdownMenuTrigger,
4173
+ Empty,
4174
+ EmptyContent,
4175
+ EmptyDescription,
4176
+ EmptyHeader,
4177
+ EmptyMedia,
4178
+ EmptyTitle,
3994
4179
  Fab,
3995
4180
  Field,
3996
4181
  FieldControl,
@@ -4025,6 +4210,8 @@ export {
4025
4210
  InputOTPGroup,
4026
4211
  InputOTPSeparator,
4027
4212
  InputOTPSlot,
4213
+ Kbd,
4214
+ KbdGroup,
4028
4215
  Label2 as Label,
4029
4216
  List3 as List,
4030
4217
  ListItem,
@@ -4046,6 +4233,9 @@ export {
4046
4233
  MenubarTrigger,
4047
4234
  Metric,
4048
4235
  Modal,
4236
+ NativeSelect,
4237
+ NativeSelectOptGroup,
4238
+ NativeSelectOption,
4049
4239
  NavigationBar,
4050
4240
  NavigationMenu,
4051
4241
  NavigationMenuContent,
@@ -4146,11 +4336,13 @@ export {
4146
4336
  badgeVariants,
4147
4337
  buttonVariants,
4148
4338
  cn,
4339
+ emptyMediaVariants,
4149
4340
  fabVariants,
4150
4341
  formatBytes,
4151
4342
  informVariants,
4152
4343
  inputVariants,
4153
4344
  messageVariants,
4345
+ nativeSelectVariants,
4154
4346
  navigationMenuTriggerStyle,
4155
4347
  spinnerVariants,
4156
4348
  tagVariants,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kinetixui/ui",
3
- "version": "0.7.0",
3
+ "version": "0.9.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.7.0",
93
+ "@kinetixui/tokens": "0.9.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,71 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cn } from "../lib/utils";
5
+
6
+ /**
7
+ * ButtonGroup — visually joins adjacent buttons into a connected cluster
8
+ * (segmented-control style): inner corners squared off, shared borders
9
+ * overlapped by 1px so they don't double up, the focused child raised
10
+ * above its neighbours so its ring isn't clipped. Gap-fill addition (not
11
+ * in the original Figma source) — matches the shadcn/ui ButtonGroup API
12
+ * shape. Works with any child that renders its own border/radius (Button,
13
+ * ButtonGroupText, a Select trigger, …), not just `<Button>`.
14
+ */
15
+ export interface ButtonGroupProps extends React.HTMLAttributes<HTMLDivElement> {
16
+ orientation?: "horizontal" | "vertical";
17
+ }
18
+
19
+ const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(
20
+ ({ className, orientation = "horizontal", ...props }, ref) => (
21
+ <div
22
+ ref={ref}
23
+ role="group"
24
+ data-orientation={orientation}
25
+ className={cn(
26
+ "flex w-fit items-stretch [&>*]:relative [&>*]:focus-visible:z-10",
27
+ orientation === "horizontal"
28
+ ? "flex-row [&>*:not(:first-child)]:-ml-px [&>*:not(:first-child)]:rounded-l-none [&>*:not(:last-child)]:rounded-r-none"
29
+ : "flex-col [&>*:not(:first-child)]:-mt-px [&>*:not(:first-child)]:rounded-t-none [&>*:not(:last-child)]:rounded-b-none",
30
+ className,
31
+ )}
32
+ {...props}
33
+ />
34
+ ),
35
+ );
36
+ ButtonGroup.displayName = "ButtonGroup";
37
+
38
+ export interface ButtonGroupSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {
39
+ orientation?: "horizontal" | "vertical";
40
+ }
41
+
42
+ /** A thin divider between segments — useful between non-outline buttons, where the group's own overlap trick has no shared border to lean on. */
43
+ const ButtonGroupSeparator = React.forwardRef<HTMLDivElement, ButtonGroupSeparatorProps>(
44
+ ({ className, orientation = "vertical", ...props }, ref) => (
45
+ <div
46
+ ref={ref}
47
+ role="separator"
48
+ aria-orientation={orientation}
49
+ className={cn("shrink-0 self-stretch bg-border", orientation === "vertical" ? "my-1.5 w-px" : "mx-1.5 h-px", className)}
50
+ {...props}
51
+ />
52
+ ),
53
+ );
54
+ ButtonGroupSeparator.displayName = "ButtonGroupSeparator";
55
+
56
+ /** A static, non-interactive label segment inside a group — e.g. a unit or a prefix next to steppers. */
57
+ const ButtonGroupText = React.forwardRef<HTMLSpanElement, React.HTMLAttributes<HTMLSpanElement>>(
58
+ ({ className, ...props }, ref) => (
59
+ <span
60
+ ref={ref}
61
+ className={cn(
62
+ "flex items-center gap-1.5 rounded-md border border-input bg-muted px-3 text-label-md text-foreground",
63
+ className,
64
+ )}
65
+ {...props}
66
+ />
67
+ ),
68
+ );
69
+ ButtonGroupText.displayName = "ButtonGroupText";
70
+
71
+ export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText };
@@ -0,0 +1,76 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import { cn } from "../lib/utils";
6
+
7
+ /**
8
+ * Empty — a placeholder for a zero-results state (an empty table, an empty
9
+ * search, a fresh workspace with nothing in it yet). Composition-based, like
10
+ * Card: `Empty` is an unstyled-beyond-layout root so it composes cleanly
11
+ * inside whatever already has a border (a Table cell, a Card, a bare page
12
+ * section) instead of forcing its own. Gap-fill addition (not in the
13
+ * original Figma source) — matches the shadcn/ui Empty API shape.
14
+ */
15
+ const Empty = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
16
+ ({ className, ...props }, ref) => (
17
+ <div
18
+ ref={ref}
19
+ className={cn("flex min-w-0 flex-1 flex-col items-center justify-center gap-6 p-10 text-center font-sans", className)}
20
+ {...props}
21
+ />
22
+ ),
23
+ );
24
+ Empty.displayName = "Empty";
25
+
26
+ const EmptyHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
27
+ ({ className, ...props }, ref) => (
28
+ <div ref={ref} className={cn("flex max-w-sm flex-col items-center gap-2", className)} {...props} />
29
+ ),
30
+ );
31
+ EmptyHeader.displayName = "EmptyHeader";
32
+
33
+ const emptyMediaVariants = cva("flex shrink-0 items-center justify-center", {
34
+ variants: {
35
+ /** `icon` gives a muted circular badge behind the icon; `default` renders the child as-is (an illustration, an avatar, …) */
36
+ variant: {
37
+ default: "",
38
+ icon: "size-10 rounded-full bg-muted text-muted-foreground [&_svg]:size-5",
39
+ },
40
+ },
41
+ defaultVariants: { variant: "default" },
42
+ });
43
+
44
+ export interface EmptyMediaProps
45
+ extends React.HTMLAttributes<HTMLDivElement>,
46
+ VariantProps<typeof emptyMediaVariants> {}
47
+
48
+ const EmptyMedia = React.forwardRef<HTMLDivElement, EmptyMediaProps>(
49
+ ({ className, variant, ...props }, ref) => (
50
+ <div ref={ref} className={cn(emptyMediaVariants({ variant }), className)} {...props} />
51
+ ),
52
+ );
53
+ EmptyMedia.displayName = "EmptyMedia";
54
+
55
+ const EmptyTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
56
+ ({ className, ...props }, ref) => (
57
+ <p ref={ref} className={cn("text-title-sm font-medium text-foreground", className)} {...props} />
58
+ ),
59
+ );
60
+ EmptyTitle.displayName = "EmptyTitle";
61
+
62
+ const EmptyDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
63
+ ({ className, ...props }, ref) => (
64
+ <p ref={ref} className={cn("text-body-sm text-muted-foreground", className)} {...props} />
65
+ ),
66
+ );
67
+ EmptyDescription.displayName = "EmptyDescription";
68
+
69
+ const EmptyContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
70
+ ({ className, ...props }, ref) => (
71
+ <div ref={ref} className={cn("flex flex-col items-center gap-3", className)} {...props} />
72
+ ),
73
+ );
74
+ EmptyContent.displayName = "EmptyContent";
75
+
76
+ export { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent, emptyMediaVariants };
@@ -0,0 +1,40 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { cn } from "../lib/utils";
6
+
7
+ /**
8
+ * Kbd — a single keyboard key glyph, e.g. `<Kbd>⌘</Kbd>`. Wrap several in
9
+ * `KbdGroup` for a shortcut combo (`⌘` `K`). Gap-fill addition (not in the
10
+ * original Figma source) — matches the shadcn/ui Kbd/KbdGroup API shape.
11
+ */
12
+ export interface KbdProps extends React.HTMLAttributes<HTMLElement> {
13
+ /** render as the single child element (Radix Slot) instead of <kbd> */
14
+ asChild?: boolean;
15
+ }
16
+
17
+ const Kbd = React.forwardRef<HTMLElement, KbdProps>(({ className, asChild = false, ...props }, ref) => {
18
+ const Comp = asChild ? Slot : "kbd";
19
+ return (
20
+ <Comp
21
+ ref={ref}
22
+ className={cn(
23
+ "inline-flex h-5 min-w-5 items-center justify-center rounded-sm border border-input bg-muted px-1.5 font-sans text-[11px] font-medium text-muted-foreground",
24
+ className,
25
+ )}
26
+ {...props}
27
+ />
28
+ );
29
+ });
30
+ Kbd.displayName = "Kbd";
31
+
32
+ export interface KbdGroupProps extends React.HTMLAttributes<HTMLElement> {}
33
+
34
+ /** Lays out multiple `Kbd` for a shortcut combo — `<KbdGroup><Kbd>⌘</Kbd><Kbd>K</Kbd></KbdGroup>` */
35
+ const KbdGroup = React.forwardRef<HTMLElement, KbdGroupProps>(({ className, ...props }, ref) => (
36
+ <kbd ref={ref} className={cn("inline-flex items-center gap-1", className)} {...props} />
37
+ ));
38
+ KbdGroup.displayName = "KbdGroup";
39
+
40
+ export { Kbd, KbdGroup };
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { ChevronDown } from "lucide-react";
5
+ import { cva, type VariantProps } from "class-variance-authority";
6
+ import { cn } from "../lib/utils";
7
+
8
+ /**
9
+ * NativeSelect — a styled wrapper around the native `<select>` element,
10
+ * for when a form should submit synchronously without JS (or just prefers
11
+ * the OS-native picker on mobile) instead of Select's Radix popover.
12
+ * Matches Input's `inputVariants` styling 1:1 so the two are drop-in
13
+ * interchangeable in a Field. Gap-fill addition (not in the original
14
+ * Figma source) — matches the shadcn/ui Native Select API shape.
15
+ */
16
+ const nativeSelectVariants = cva(
17
+ [
18
+ "flex w-full appearance-none border border-input bg-background px-3 py-3 pr-9",
19
+ "font-sans text-[14px] leading-5 tracking-[0.25px] text-foreground",
20
+ "outline-none transition-colors",
21
+ "focus-visible:border-primary focus-visible:shadow-focus",
22
+ "disabled:cursor-not-allowed disabled:opacity-disabled",
23
+ "aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive aria-[invalid=true]:focus-visible:shadow-focus-destructive",
24
+ ],
25
+ {
26
+ variants: {
27
+ state: {
28
+ Default: "",
29
+ Focus: "border-primary shadow-focus",
30
+ Error: "border-destructive",
31
+ Disabled: "opacity-disabled pointer-events-none",
32
+ },
33
+ corners: {
34
+ sharp: "rounded-none",
35
+ default: "rounded-sm",
36
+ rounded: "rounded-md",
37
+ pill: "rounded-full px-4",
38
+ },
39
+ },
40
+ defaultVariants: { state: "Default", corners: "default" },
41
+ },
42
+ );
43
+
44
+ export interface NativeSelectProps
45
+ extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "size">,
46
+ VariantProps<typeof nativeSelectVariants> {}
47
+
48
+ const NativeSelect = React.forwardRef<HTMLSelectElement, NativeSelectProps>(
49
+ ({ className, state, corners, disabled, "aria-invalid": ariaInvalid, children, ...props }, ref) => (
50
+ <div className="relative">
51
+ <select
52
+ ref={ref}
53
+ data-slot="native-select"
54
+ data-state={state ? state.toLowerCase() : undefined}
55
+ aria-invalid={ariaInvalid ?? (state === "Error" || undefined)}
56
+ disabled={disabled || state === "Disabled"}
57
+ className={cn(nativeSelectVariants({ state, corners }), className)}
58
+ {...props}
59
+ >
60
+ {children}
61
+ </select>
62
+ <ChevronDown className="pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
63
+ </div>
64
+ ),
65
+ );
66
+ NativeSelect.displayName = "NativeSelect";
67
+
68
+ export interface NativeSelectOptionProps extends React.OptionHTMLAttributes<HTMLOptionElement> {}
69
+
70
+ const NativeSelectOption = React.forwardRef<HTMLOptionElement, NativeSelectOptionProps>(
71
+ ({ ...props }, ref) => <option ref={ref} {...props} />,
72
+ );
73
+ NativeSelectOption.displayName = "NativeSelectOption";
74
+
75
+ export interface NativeSelectOptGroupProps extends React.OptgroupHTMLAttributes<HTMLOptGroupElement> {}
76
+
77
+ const NativeSelectOptGroup = React.forwardRef<HTMLOptGroupElement, NativeSelectOptGroupProps>(
78
+ ({ ...props }, ref) => <optgroup ref={ref} {...props} />,
79
+ );
80
+ NativeSelectOptGroup.displayName = "NativeSelectOptGroup";
81
+
82
+ export { NativeSelect, NativeSelectOption, NativeSelectOptGroup, nativeSelectVariants };
package/src/index.ts CHANGED
@@ -311,4 +311,33 @@ export { Quote, type QuoteProps } from "./components/quote";
311
311
  export { Footer, FooterColumn, FooterLink, FooterBottom, type FooterColumnProps } from "./components/footer";
312
312
  export { TableOfContents, type TableOfContentsProps, type TocItem } from "./components/table-of-contents";
313
313
 
314
+ /* Batch 6 — infra/design-system audit gap-fill components */
315
+ export { Kbd, KbdGroup, type KbdProps, type KbdGroupProps } from "./components/kbd";
316
+ export {
317
+ Empty,
318
+ EmptyHeader,
319
+ EmptyMedia,
320
+ EmptyTitle,
321
+ EmptyDescription,
322
+ EmptyContent,
323
+ emptyMediaVariants,
324
+ type EmptyMediaProps,
325
+ } from "./components/empty";
326
+ export {
327
+ ButtonGroup,
328
+ ButtonGroupSeparator,
329
+ ButtonGroupText,
330
+ type ButtonGroupProps,
331
+ type ButtonGroupSeparatorProps,
332
+ } from "./components/button-group";
333
+ export {
334
+ NativeSelect,
335
+ NativeSelectOption,
336
+ NativeSelectOptGroup,
337
+ nativeSelectVariants,
338
+ type NativeSelectProps,
339
+ type NativeSelectOptionProps,
340
+ type NativeSelectOptGroupProps,
341
+ } from "./components/native-select";
342
+
314
343
  export { cn } from "./lib/utils";
@@ -0,0 +1,32 @@
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 { Button, ButtonGroup } from "@kinetixui/ui";
6
+ import { Bold, Italic, Underline } from "lucide-react";
7
+
8
+ const Demo = () => (
9
+ <ButtonGroup>
10
+ <Button variant="Outline" size="icon" aria-label="Bold">
11
+ <Bold />
12
+ </Button>
13
+ <Button variant="Outline" size="icon" aria-label="Italic">
14
+ <Italic />
15
+ </Button>
16
+ <Button variant="Outline" size="icon" aria-label="Underline">
17
+ <Underline />
18
+ </Button>
19
+ </ButtonGroup>
20
+ );
21
+
22
+ const meta = {
23
+ title: "Controls & Actions/ButtonGroup",
24
+ parameters: {
25
+ layout: "centered",
26
+ docs: { source: { code: "<ButtonGroup>\\n <Button variant=\"Outline\" size=\"icon\"><Bold /></Button>\\n <Button variant=\"Outline\" size=\"icon\"><Italic /></Button>\\n <Button variant=\"Outline\" size=\"icon\"><Underline /></Button>\\n</ButtonGroup>", language: "tsx" } },
27
+ },
28
+ } satisfies Meta;
29
+
30
+ export default meta;
31
+
32
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,35 @@
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 { Button, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@kinetixui/ui";
6
+ import { Search } from "lucide-react";
7
+
8
+ const Demo = () => (
9
+ <Empty className="w-full max-w-sm rounded-lg border border-dashed">
10
+ <EmptyHeader>
11
+ <EmptyMedia variant="icon">
12
+ <Search />
13
+ </EmptyMedia>
14
+ <EmptyTitle>No results found</EmptyTitle>
15
+ <EmptyDescription>Try adjusting your search or filters.</EmptyDescription>
16
+ </EmptyHeader>
17
+ <EmptyContent>
18
+ <Button variant="Outline" size="sm">
19
+ Clear filters
20
+ </Button>
21
+ </EmptyContent>
22
+ </Empty>
23
+ );
24
+
25
+ const meta = {
26
+ title: "Feedback/Empty",
27
+ parameters: {
28
+ layout: "centered",
29
+ docs: { source: { code: "<Empty>\\n <EmptyHeader>\\n <EmptyMedia variant=\"icon\"><Search /></EmptyMedia>\\n <EmptyTitle>No results found</EmptyTitle>\\n <EmptyDescription>Try adjusting your search or filters.</EmptyDescription>\\n </EmptyHeader>\\n <EmptyContent>\\n <Button variant=\"Outline\" size=\"sm\">Clear filters</Button>\\n </EmptyContent>\\n</Empty>", language: "tsx" } },
30
+ },
31
+ } satisfies Meta;
32
+
33
+ export default meta;
34
+
35
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,27 @@
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 { Kbd, KbdGroup } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <div className="flex items-center gap-4">
9
+ <Kbd>⏎</Kbd>
10
+ <KbdGroup>
11
+ <Kbd>⌘</Kbd>
12
+ <Kbd>K</Kbd>
13
+ </KbdGroup>
14
+ </div>
15
+ );
16
+
17
+ const meta = {
18
+ title: "Foundations/Kbd",
19
+ parameters: {
20
+ layout: "centered",
21
+ docs: { source: { code: "<Kbd>⏎</Kbd>\\n<KbdGroup>\\n <Kbd>⌘</Kbd>\\n <Kbd>K</Kbd>\\n</KbdGroup>", language: "tsx" } },
22
+ },
23
+ } satisfies Meta;
24
+
25
+ export default meta;
26
+
27
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };
@@ -0,0 +1,33 @@
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 { NativeSelect, NativeSelectOptGroup, NativeSelectOption, Select } from "@kinetixui/ui";
6
+
7
+ const Demo = () => (
8
+ <NativeSelect className="max-w-xs" defaultValue="">
9
+ <NativeSelectOption value="" disabled>
10
+ Select a fruit…
11
+ </NativeSelectOption>
12
+ <NativeSelectOptGroup label="Citrus">
13
+ <NativeSelectOption value="orange">Orange</NativeSelectOption>
14
+ <NativeSelectOption value="lemon">Lemon</NativeSelectOption>
15
+ </NativeSelectOptGroup>
16
+ <NativeSelectOptGroup label="Stone fruit">
17
+ <NativeSelectOption value="peach">Peach</NativeSelectOption>
18
+ <NativeSelectOption value="plum">Plum</NativeSelectOption>
19
+ </NativeSelectOptGroup>
20
+ </NativeSelect>
21
+ );
22
+
23
+ const meta = {
24
+ title: "Form Inputs/NativeSelect",
25
+ parameters: {
26
+ layout: "centered",
27
+ docs: { source: { code: "<NativeSelect defaultValue=\"\">\\n <NativeSelectOption value=\"\" disabled>Select a fruit…</NativeSelectOption>\\n <NativeSelectOptGroup label=\"Citrus\">\\n <NativeSelectOption value=\"orange\">Orange</NativeSelectOption>\\n </NativeSelectOptGroup>\\n</NativeSelect>", language: "tsx" } },
28
+ },
29
+ } satisfies Meta;
30
+
31
+ export default meta;
32
+
33
+ export const Default: StoryObj<typeof meta> = { render: () => <Demo /> };