@boyernick/standard-ui-react 0.1.1-canary.2 → 0.1.1-canary.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boyernick/standard-ui-react",
3
- "version": "0.1.1-canary.2",
3
+ "version": "0.1.1-canary.4",
4
4
  "description": "React components for StandardUI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/accordion.tsx CHANGED
@@ -79,6 +79,6 @@ export const AccordionPanel = ({
79
79
  )}
80
80
  {...props}
81
81
  >
82
- <div className="px-4 pt-0 pb-4 leading-relaxed">{children}</div>
82
+ <div className="px-4 pt-2 pb-4 leading-relaxed">{children}</div>
83
83
  </BaseAccordion.Panel>
84
84
  )
@@ -66,8 +66,7 @@ export const AutocompleteInputGroup = ({
66
66
  }: AutocompleteInputGroupProps) => (
67
67
  <BaseAutocomplete.InputGroup
68
68
  className={cn(
69
- "relative flex min-h-9 w-full items-center rounded-md border border-border-secondary bg-surface inset-shadow-outline-top outline-none transition-[color,box-shadow]",
70
- "has-[[data-popup-open]]:bg-background-tertiary/60",
69
+ "relative flex min-h-9 w-full items-center rounded-xl border border-border-secondary bg-surface inset-shadow-outline-top outline-none transition-[color,box-shadow]",
71
70
  "focus-within:border-ring focus-within:ring-[3px] focus-within:ring-offset-1 focus-within:ring-offset-background-primary focus-within:ring-ring/20",
72
71
  "aria-invalid:border-destructive aria-invalid:focus-within:border-destructive aria-invalid:focus-within:ring-destructive/20",
73
72
  "has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:focus-within:border-destructive has-[[aria-invalid=true]]:focus-within:ring-destructive/20",
@@ -84,7 +83,7 @@ export const AutocompleteInput = ({
84
83
  }: AutocompleteInputProps) => (
85
84
  <BaseAutocomplete.Input
86
85
  className={cn(
87
- "h-9 min-w-0 flex-1 cursor-text rounded-md bg-transparent px-3 text-sm text-fg-primary outline-none placeholder:text-fg-quaternary focus-visible:ring-0",
86
+ "h-9 min-w-0 flex-1 cursor-text rounded-xl bg-transparent px-3 text-sm text-fg-primary outline-none placeholder:text-fg-quaternary focus-visible:ring-0",
88
87
  className,
89
88
  )}
90
89
  {...props}
@@ -134,7 +133,7 @@ export const AutocompleteClear = ({
134
133
  {...props}
135
134
  >
136
135
  {children ?? (
137
- <IconCrossSmall size={14} className="size-3.5" aria-hidden />
136
+ <IconCrossSmall size={16} className="size-4" aria-hidden />
138
137
  )}
139
138
  </BaseAutocomplete.Clear>
140
139
  )
@@ -151,7 +150,7 @@ export const AutocompleteBackdrop = ({
151
150
  )
152
151
 
153
152
  export const AutocompletePositioner = ({
154
- sideOffset = 4,
153
+ sideOffset = 6,
155
154
  className,
156
155
  ...props
157
156
  }: AutocompletePositionerProps) => (
@@ -168,7 +167,7 @@ export const AutocompletePopup = ({
168
167
  }: AutocompletePopupProps) => (
169
168
  <BaseAutocomplete.Popup
170
169
  className={cn(
171
- "z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden rounded-md border border-border-primary bg-surface shadow-md outline-none",
170
+ "z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden rounded-xl border border-border-primary-solid bg-surface shadow-lg outline-none",
172
171
  motion.popupAnchor,
173
172
  className,
174
173
  )}
@@ -199,7 +198,7 @@ export const AutocompleteList = ({
199
198
  ...props
200
199
  }: AutocompleteListProps) => (
201
200
  <BaseAutocomplete.List
202
- className={cn("max-h-[inherit] overflow-y-auto p-1 outline-none", className)}
201
+ className={cn("max-h-[inherit] overflow-y-auto p-1.5 outline-none empty:p-0", className)}
203
202
  {...props}
204
203
  />
205
204
  )
@@ -210,7 +209,7 @@ export const AutocompleteItem = ({
210
209
  }: AutocompleteItemProps) => (
211
210
  <BaseAutocomplete.Item
212
211
  className={cn(
213
- "flex min-h-8 cursor-default items-center gap-2 rounded-xs px-2.5 py-1.5 text-sm text-fg-primary outline-none select-none",
212
+ "flex min-h-9 cursor-default items-center gap-2 rounded-sm px-3 py-2 text-sm text-fg-primary outline-none select-none",
214
213
  motion.colors,
215
214
  "data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-background-tertiary data-highlighted:text-fg-primary",
216
215
  className,
@@ -224,7 +223,7 @@ export const AutocompleteEmpty = ({
224
223
  ...props
225
224
  }: AutocompleteEmptyProps) => (
226
225
  <BaseAutocomplete.Empty
227
- className={cn("px-2.5 py-2 text-sm text-fg-tertiary empty:hidden", className)}
226
+ className={cn("px-3 py-2 text-sm text-fg-tertiary empty:hidden", className)}
228
227
  {...props}
229
228
  />
230
229
  )
@@ -234,7 +233,7 @@ export const AutocompleteStatus = ({
234
233
  ...props
235
234
  }: AutocompleteStatusProps) => (
236
235
  <BaseAutocomplete.Status
237
- className={cn("px-2.5 py-2 text-sm text-fg-tertiary", className)}
236
+ className={cn("px-3 py-2 text-sm text-fg-tertiary", className)}
238
237
  {...props}
239
238
  />
240
239
  )
@@ -251,7 +250,7 @@ export const AutocompleteGroupLabel = ({
251
250
  ...props
252
251
  }: AutocompleteGroupLabelProps) => (
253
252
  <BaseAutocomplete.GroupLabel
254
- className={cn("px-2.5 py-1.5 text-xs text-fg-tertiary", className)}
253
+ className={cn("px-3 py-1.5 text-xs text-fg-tertiary", className)}
255
254
  {...props}
256
255
  />
257
256
  )
package/src/badge.tsx CHANGED
@@ -1,28 +1,92 @@
1
1
  import { cva, type VariantProps } from "class-variance-authority"
2
- import type { HTMLAttributes } from "react"
2
+ import type { HTMLAttributes, ReactNode } from "react"
3
3
  import { cn } from "./lib/cn"
4
4
 
5
5
  const badgeVariants = cva(
6
- "text-xs-strong inline-flex items-center rounded-full py-0.5",
6
+ "inline-flex shrink-0 items-center justify-center whitespace-nowrap align-middle [&>[data-badge-label]]:min-w-0 [&>[data-badge-label]]:truncate [&>[data-badge-slot]]:inline-flex [&>[data-badge-slot]]:shrink-0 [&>[data-badge-slot]]:items-center [&>[data-badge-slot]]:justify-center [&>[data-badge-slot]>svg]:size-full",
7
7
  {
8
8
  variants: {
9
9
  variant: {
10
- default: "bg-background-tertiary px-3 text-fg-primary",
11
- outline: "border border-border-primary px-2 text-fg-secondary",
12
- destructive: "bg-destructive/10 px-2 text-destructive",
10
+ default: "bg-background-tertiary text-fg-primary",
11
+ outline: "border border-border-primary text-fg-secondary",
12
+ info: "bg-status-info-background text-status-info",
13
+ success: "bg-status-success-background text-status-success",
14
+ warning: "bg-status-warning-background text-status-warning",
15
+ critical: "bg-status-critical-background text-status-critical",
16
+ destructive: "bg-status-critical-background text-status-critical",
17
+ },
18
+ size: {
19
+ xxs: "text-2xs-strong h-4 gap-0.5 px-1.5 [&>[data-badge-slot]]:size-2.5",
20
+ xs: "text-2xs-strong h-5 gap-1 px-1.5 [&>[data-badge-slot]]:size-3",
21
+ sm: "text-xs-strong h-6 gap-1 px-2 [&>[data-badge-slot]]:size-3.5",
22
+ md: "text-xs-strong h-7 gap-1.5 px-2.5 [&>[data-badge-slot]]:size-3.5",
23
+ lg: "text-sm-strong h-8 gap-1.5 px-3 [&>[data-badge-slot]]:size-4",
24
+ },
25
+ rounded: {
26
+ true: "rounded-full",
27
+ false: "rounded-sm",
28
+ },
29
+ iconOnly: {
30
+ true: "p-0",
31
+ false: "",
13
32
  },
14
33
  },
34
+ compoundVariants: [
35
+ { iconOnly: true, size: "xxs", class: "size-4" },
36
+ { iconOnly: true, size: "xs", class: "size-5" },
37
+ { iconOnly: true, size: "sm", class: "size-6" },
38
+ { iconOnly: true, size: "md", class: "size-7" },
39
+ { iconOnly: true, size: "lg", class: "size-8" },
40
+ ],
15
41
  defaultVariants: {
16
42
  variant: "default",
43
+ size: "sm",
44
+ rounded: false,
45
+ iconOnly: false,
17
46
  },
18
47
  },
19
48
  )
20
49
 
21
- export type BadgeProps = HTMLAttributes<HTMLSpanElement> &
22
- VariantProps<typeof badgeVariants>
50
+ export type BadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "prefix"> &
51
+ VariantProps<typeof badgeVariants> & {
52
+ /** Square badge sized to the height of `size`. */
53
+ iconOnly?: boolean
54
+ /** Pill shape (`rounded-full`) instead of the default light radius. */
55
+ rounded?: boolean
56
+ /** Icon or element before the label. */
57
+ prefix?: ReactNode
58
+ /** Icon or element after the label. */
59
+ suffix?: ReactNode
60
+ }
23
61
 
24
- export const Badge = ({ className, variant, ...props }: BadgeProps) => (
25
- <span className={cn(badgeVariants({ variant }), className)} {...props} />
62
+ export const Badge = ({
63
+ className,
64
+ variant,
65
+ size,
66
+ rounded,
67
+ iconOnly,
68
+ prefix,
69
+ suffix,
70
+ children,
71
+ ...props
72
+ }: BadgeProps) => (
73
+ <span
74
+ className={cn(
75
+ badgeVariants({ variant, size, rounded, iconOnly }),
76
+ className,
77
+ )}
78
+ {...props}
79
+ >
80
+ {iconOnly ? (
81
+ <span data-badge-slot="icon">{children}</span>
82
+ ) : (
83
+ <>
84
+ {prefix ? <span data-badge-slot="prefix">{prefix}</span> : null}
85
+ {children != null ? <span data-badge-label>{children}</span> : null}
86
+ {suffix ? <span data-badge-slot="suffix">{suffix}</span> : null}
87
+ </>
88
+ )}
89
+ </span>
26
90
  )
27
91
 
28
92
  export { badgeVariants }
@@ -1,16 +1,30 @@
1
- import type { ComponentProps, ReactNode } from "react";
2
- import { IconChevronRightSmall } from "./icons";
3
- import { cn } from "./lib/cn";
4
- import { motion } from "./lib/motion";
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+ import type { ComponentProps, ReactNode } from "react"
3
+ import { IconChevronRightSmall } from "./icons"
4
+ import { cn } from "./lib/cn"
5
+ import { motion } from "./lib/motion"
6
+
7
+ export type BreadcrumbProps = ComponentProps<"nav">
8
+ export type BreadcrumbListProps = ComponentProps<"ol">
9
+ export type BreadcrumbItemProps = ComponentProps<"li">
10
+ export type BreadcrumbLinkProps = ComponentProps<"a">
11
+ export type BreadcrumbPageProps = ComponentProps<"span">
12
+
13
+ const breadcrumbSeparatorVariants = cva("text-fg-tertiary", {
14
+ variants: {
15
+ variant: {
16
+ chevron: "[&_svg]:size-3.5",
17
+ slash: "px-0.5",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: "chevron",
22
+ },
23
+ })
5
24
 
6
- export type BreadcrumbProps = ComponentProps<"nav">;
7
- export type BreadcrumbListProps = ComponentProps<"ol">;
8
- export type BreadcrumbItemProps = ComponentProps<"li">;
9
- export type BreadcrumbLinkProps = ComponentProps<"a">;
10
- export type BreadcrumbPageProps = ComponentProps<"span">;
11
25
  export type BreadcrumbSeparatorProps = ComponentProps<"li"> & {
12
- children?: ReactNode;
13
- };
26
+ children?: ReactNode
27
+ } & VariantProps<typeof breadcrumbSeparatorVariants>
14
28
 
15
29
  export const Breadcrumb = ({ className, ...props }: BreadcrumbProps) => (
16
30
  <nav
@@ -18,27 +32,27 @@ export const Breadcrumb = ({ className, ...props }: BreadcrumbProps) => (
18
32
  className={cn("text-sm text-fg-secondary", className)}
19
33
  {...props}
20
34
  />
21
- );
35
+ )
22
36
 
23
37
  export const BreadcrumbList = ({
24
38
  className,
25
39
  ...props
26
40
  }: BreadcrumbListProps) => (
27
41
  <ol
28
- className={cn("flex flex-wrap items-center gap-1.5", className)}
42
+ className={cn("flex flex-wrap items-center gap-0.5", className)}
29
43
  {...props}
30
44
  />
31
- );
45
+ )
32
46
 
33
47
  export const BreadcrumbItem = ({
34
48
  className,
35
49
  ...props
36
50
  }: BreadcrumbItemProps) => (
37
51
  <li
38
- className={cn("inline-flex items-center gap-1.5", className)}
52
+ className={cn("inline-flex items-center gap-1.5 px-1", className)}
39
53
  {...props}
40
54
  />
41
- );
55
+ )
42
56
 
43
57
  export const BreadcrumbLink = ({
44
58
  className,
@@ -52,7 +66,7 @@ export const BreadcrumbLink = ({
52
66
  )}
53
67
  {...props}
54
68
  />
55
- );
69
+ )
56
70
 
57
71
  export const BreadcrumbPage = ({
58
72
  className,
@@ -63,19 +77,23 @@ export const BreadcrumbPage = ({
63
77
  className={cn("font-medium text-fg-primary", className)}
64
78
  {...props}
65
79
  />
66
- );
80
+ )
67
81
 
68
82
  export const BreadcrumbSeparator = ({
69
83
  className,
70
84
  children,
85
+ variant,
71
86
  ...props
72
87
  }: BreadcrumbSeparatorProps) => (
73
88
  <li
74
89
  role="presentation"
75
90
  aria-hidden
76
- className={cn("text-fg-tertiary [&_svg]:size-3.5", className)}
91
+ className={cn(breadcrumbSeparatorVariants({ variant }), className)}
77
92
  {...props}
78
93
  >
79
- {children ?? <IconChevronRightSmall />}
94
+ {children ??
95
+ (variant === "slash" ? "/" : <IconChevronRightSmall aria-hidden />)}
80
96
  </li>
81
- );
97
+ )
98
+
99
+ export { breadcrumbSeparatorVariants }
package/src/button.tsx CHANGED
@@ -3,7 +3,7 @@ import type { ButtonHTMLAttributes, ReactNode } from "react"
3
3
  import { cn } from "./lib/cn"
4
4
 
5
5
  const buttonVariants = cva(
6
- "text-sm inline-flex cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap transition-all duration-150 ease-out outline-none focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary disabled:cursor-not-allowed disabled:opacity-50 disabled:active:translate-y-0 active:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
6
+ "text-sm inline-flex cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap transition-all duration-[var(--duration-sm)] ease-enter outline-none focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary disabled:cursor-not-allowed disabled:opacity-50 disabled:active:translate-y-0 active:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
7
7
  {
8
8
  variants: {
9
9
  variant: {
@@ -25,7 +25,7 @@ const buttonVariants = cva(
25
25
  },
26
26
  rounded: {
27
27
  true: "rounded-full",
28
- false: "rounded-md",
28
+ false: "rounded-lg",
29
29
  },
30
30
  iconOnly: {
31
31
  true: "px-0",
package/src/calendar.tsx CHANGED
@@ -8,9 +8,9 @@ import { motion } from "./lib/motion"
8
8
  export type CalendarProps = DayPickerProps
9
9
 
10
10
  const navButtonClassName = cn(
11
- "inline-flex size-8 items-center justify-center rounded-md text-fg-tertiary",
11
+ "inline-flex size-6 items-center justify-center rounded-md border border-transparent text-fg-tertiary",
12
12
  motion.colors,
13
- "hover:bg-background-tertiary hover:text-fg-primary outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50",
13
+ "hover:bg-background-tertiary hover:text-fg-primary outline-none focus-visible:border-ring focus-visible:bg-background-tertiary focus-visible:text-fg-primary focus-visible:ring-2 focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50",
14
14
  )
15
15
 
16
16
  const CalendarChevron = ({
@@ -40,34 +40,45 @@ export const Calendar = ({
40
40
  className,
41
41
  classNames,
42
42
  showOutsideDays = true,
43
+ weekStartsOn = 1,
43
44
  components,
44
45
  ...props
45
46
  }: CalendarProps) => (
46
47
  <DayPicker
47
48
  showOutsideDays={showOutsideDays}
48
- className={cn("w-fit p-3", className)}
49
+ weekStartsOn={weekStartsOn}
50
+ className={cn(
51
+ "w-64 rounded-xl border border-border-primary bg-surface p-3",
52
+ className,
53
+ )}
49
54
  classNames={{
50
55
  months: "relative flex flex-col gap-4 sm:flex-row",
51
- month: "flex w-full flex-col gap-3",
52
- month_caption: "relative flex h-8 items-center justify-center px-8",
56
+ month: "flex w-full flex-col",
57
+ month_caption: "flex h-8 items-start justify-start",
53
58
  caption_label: "text-sm-strong text-fg-primary",
54
- nav: "absolute inset-x-0 top-0 flex items-center justify-between",
59
+ nav: "absolute top-0 right-0 flex items-center",
55
60
  button_previous: navButtonClassName,
56
61
  button_next: navButtonClassName,
57
62
  month_grid: "w-full border-collapse",
58
63
  weekdays: "flex",
59
64
  weekday:
60
- "flex size-8 items-center justify-center text-xs font-normal text-fg-tertiary",
61
- weeks: "flex flex-col",
62
- week: "mt-0.5 flex w-full",
65
+ "flex w-8 items-center justify-center pb-1 text-xs font-normal text-fg-tertiary select-none",
66
+ weeks: "flex flex-col gap-1",
67
+ week: "flex w-full",
63
68
  day: "relative p-0 text-center",
64
69
  day_button: cn(
65
- "inline-flex size-8 items-center justify-center rounded-md text-sm text-fg-primary",
70
+ "inline-flex size-8 items-center justify-center rounded-lg text-sm text-fg-primary tabular-nums",
66
71
  motion.colors,
67
- "hover:bg-background-tertiary outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 aria-selected:opacity-100",
72
+ "hover:bg-background-tertiary outline-none focus-visible:z-10 focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-selected:opacity-100",
68
73
  ),
69
74
  selected:
70
75
  "[&>button]:bg-brand-primary [&>button]:text-brand-foreground [&>button]:ring-0 [&>button]:hover:bg-brand-primary-hover [&>button]:hover:text-brand-foreground",
76
+ range_start:
77
+ "rounded-l-lg bg-brand-primary/10 last:rounded-r-lg [&>button]:relative [&>button]:z-[1]",
78
+ range_middle:
79
+ "bg-brand-primary/10 first:rounded-l-lg last:rounded-r-lg [&>button]:!rounded-none [&>button]:!bg-transparent [&>button]:!text-fg-primary [&>button]:hover:!bg-brand-primary/15",
80
+ range_end:
81
+ "rounded-r-lg bg-brand-primary/10 first:rounded-l-lg [&>button]:relative [&>button]:z-[1]",
71
82
  today:
72
83
  "[&>button]:font-medium [&>button]:ring-1 [&>button]:ring-inset [&>button]:ring-border-secondary",
73
84
  outside: "[&>button]:text-fg-quaternary",
package/src/card.tsx CHANGED
@@ -1,32 +1,59 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
1
2
  import type { HTMLAttributes } from "react"
2
3
  import { cn } from "./lib/cn"
3
4
 
4
- export type CardProps = HTMLAttributes<HTMLDivElement>
5
+ const cardVariants = cva("flex flex-col rounded-xl bg-surface text-fg-primary", {
6
+ variants: {
7
+ variant: {
8
+ elevated: "shadow-lg",
9
+ outline: "border border-border-primary",
10
+ ghost: "",
11
+ },
12
+ padding: {
13
+ md: "gap-6 py-6",
14
+ none: "",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: "elevated",
19
+ padding: "md",
20
+ },
21
+ })
22
+
23
+ export type CardProps = HTMLAttributes<HTMLDivElement> &
24
+ VariantProps<typeof cardVariants>
5
25
  export type CardHeaderProps = HTMLAttributes<HTMLDivElement>
6
26
  export type CardTitleProps = HTMLAttributes<HTMLHeadingElement>
7
27
  export type CardDescriptionProps = HTMLAttributes<HTMLParagraphElement>
28
+ export type CardActionProps = HTMLAttributes<HTMLDivElement>
8
29
  export type CardContentProps = HTMLAttributes<HTMLDivElement>
9
30
  export type CardFooterProps = HTMLAttributes<HTMLDivElement>
10
31
 
11
- export const Card = ({ className, ...props }: CardProps) => (
32
+ export const Card = ({ className, variant, padding, ...props }: CardProps) => (
12
33
  <div
13
- className={cn(
14
- "flex flex-col overflow-hidden rounded-xl border border-border-primary bg-surface",
15
- className,
16
- )}
17
34
  {...props}
35
+ data-slot="card"
36
+ className={cn(cardVariants({ variant, padding }), className)}
18
37
  />
19
38
  )
20
39
 
21
40
  export const CardHeader = ({ className, ...props }: CardHeaderProps) => (
22
41
  <div
23
- className={cn("flex flex-col gap-1 px-5 pt-5 pb-3", className)}
24
42
  {...props}
43
+ data-slot="card-header"
44
+ className={cn(
45
+ "grid auto-rows-min items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto]",
46
+ className,
47
+ )}
25
48
  />
26
49
  )
27
50
 
28
51
  export const CardTitle = ({ className, ...props }: CardTitleProps) => (
29
- <h3 className={cn("text-sm-strong text-fg-primary", className)} {...props} />
52
+ <h3
53
+ {...props}
54
+ data-slot="card-title"
55
+ className={cn("text-sm-strong leading-none text-fg-primary", className)}
56
+ />
30
57
  )
31
58
 
32
59
  export const CardDescription = ({
@@ -34,21 +61,37 @@ export const CardDescription = ({
34
61
  ...props
35
62
  }: CardDescriptionProps) => (
36
63
  <p
37
- className={cn("text-sm leading-relaxed text-fg-secondary", className)}
38
64
  {...props}
65
+ data-slot="card-description"
66
+ className={cn("text-sm text-fg-secondary", className)}
67
+ />
68
+ )
69
+
70
+ export const CardAction = ({ className, ...props }: CardActionProps) => (
71
+ <div
72
+ {...props}
73
+ data-slot="card-action"
74
+ className={cn(
75
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
76
+ className,
77
+ )}
39
78
  />
40
79
  )
41
80
 
42
81
  export const CardContent = ({ className, ...props }: CardContentProps) => (
43
- <div className={cn("px-5 pb-5", className)} {...props} />
82
+ <div
83
+ {...props}
84
+ data-slot="card-content"
85
+ className={cn("px-6", className)}
86
+ />
44
87
  )
45
88
 
46
89
  export const CardFooter = ({ className, ...props }: CardFooterProps) => (
47
90
  <div
48
- className={cn(
49
- "flex items-center gap-2 border-t border-border-primary px-5 py-4",
50
- className,
51
- )}
52
91
  {...props}
92
+ data-slot="card-footer"
93
+ className={cn("flex items-center gap-2 px-6", className)}
53
94
  />
54
95
  )
96
+
97
+ export { cardVariants }