sheerly 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/lib/accordion.d.ts +13 -4
  2. package/lib/alert.d.ts +22 -7
  3. package/lib/avatar.css +1 -1
  4. package/lib/avatar.d.ts +21 -8
  5. package/lib/badge.d.ts +14 -4
  6. package/lib/breadcrumb.d.ts +18 -3
  7. package/lib/button.css +1 -1
  8. package/lib/button.d.ts +13 -4
  9. package/lib/card.d.ts +32 -12
  10. package/lib/carousel.d.ts +13 -7
  11. package/lib/checkbox.d.ts +6 -0
  12. package/lib/dialog.d.ts +20 -8
  13. package/lib/dropdown-menu.d.ts +30 -13
  14. package/lib/hover-card.d.ts +15 -6
  15. package/lib/index.css +1 -1
  16. package/lib/index.d.ts +1 -1
  17. package/lib/index.js +245 -237
  18. package/lib/input.css +1 -1
  19. package/lib/input.d.ts +6 -0
  20. package/lib/kbd.d.ts +10 -3
  21. package/lib/label.css +1 -1
  22. package/lib/label.d.ts +6 -0
  23. package/lib/pagination.d.ts +16 -2
  24. package/lib/popover.d.ts +15 -6
  25. package/lib/progress.d.ts +6 -0
  26. package/lib/radio.d.ts +13 -3
  27. package/lib/scrollbar.css +1 -0
  28. package/lib/scrollbar.d.ts +17 -0
  29. package/lib/select.css +1 -1
  30. package/lib/select.d.ts +6 -0
  31. package/lib/separator.d.ts +14 -4
  32. package/lib/sheet.d.ts +19 -6
  33. package/lib/skeleton.d.ts +12 -3
  34. package/lib/slider.d.ts +6 -0
  35. package/lib/spinner.d.ts +10 -4
  36. package/lib/switch.d.ts +6 -0
  37. package/lib/table.css +1 -1
  38. package/lib/table.d.ts +14 -3
  39. package/lib/tabs.d.ts +31 -8
  40. package/lib/textarea.d.ts +6 -0
  41. package/lib/toggle.d.ts +7 -0
  42. package/lib/tooltip.d.ts +15 -6
  43. package/lib/typography.d.ts +12 -4
  44. package/lib/utils/polymorphic.d.ts +14 -0
  45. package/package.json +12 -12
  46. package/src/accordion.tsx +20 -6
  47. package/src/alert.tsx +52 -14
  48. package/src/avatar.css +0 -1
  49. package/src/avatar.tsx +44 -15
  50. package/src/badge.tsx +34 -16
  51. package/src/breadcrumb.tsx +32 -8
  52. package/src/button.css +1 -0
  53. package/src/button.tsx +44 -27
  54. package/src/card.tsx +82 -23
  55. package/src/carousel.tsx +28 -11
  56. package/src/checkbox.tsx +7 -1
  57. package/src/dialog.tsx +55 -16
  58. package/src/dropdown-menu.tsx +94 -25
  59. package/src/hover-card.tsx +28 -9
  60. package/src/index.css +1 -0
  61. package/src/index.ts +1 -1
  62. package/src/input.css +1 -0
  63. package/src/input.tsx +7 -1
  64. package/src/kbd.tsx +17 -5
  65. package/src/label.css +1 -0
  66. package/src/label.tsx +7 -1
  67. package/src/pagination.tsx +23 -10
  68. package/src/popover.tsx +28 -9
  69. package/src/progress.tsx +7 -1
  70. package/src/radio.tsx +20 -5
  71. package/src/scrollbar.css +56 -0
  72. package/src/scrollbar.tsx +28 -0
  73. package/src/select.css +24 -0
  74. package/src/select.tsx +7 -1
  75. package/src/separator.tsx +23 -7
  76. package/src/sheet.tsx +53 -13
  77. package/src/skeleton.tsx +19 -5
  78. package/src/slider.tsx +7 -1
  79. package/src/spinner.tsx +21 -8
  80. package/src/switch.tsx +7 -1
  81. package/src/table.css +0 -1
  82. package/src/table.tsx +21 -5
  83. package/src/tabs.tsx +50 -17
  84. package/src/textarea.tsx +7 -1
  85. package/src/toggle.tsx +8 -1
  86. package/src/tooltip.tsx +28 -9
  87. package/src/typography.tsx +19 -5
  88. package/src/utils/polymorphic.ts +19 -0
  89. /package/lib/{cn.d.ts → utils/cn.d.ts} +0 -0
  90. /package/src/{cn.ts → utils/cn.ts} +0 -0
package/src/alert.tsx CHANGED
@@ -1,25 +1,63 @@
1
- import type { HTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
- export interface AlertProps extends HTMLAttributes<HTMLDivElement> {
5
- 'data-variant'?: 'default' | 'destructive' | 'success' | 'info' | 'warning'
6
- }
5
+ export type AlertProps<T extends ElementType = 'div'> = PolymorphicProps<
6
+ T,
7
+ { 'data-variant'?: 'default' | 'destructive' | 'success' | 'info' | 'warning' }
8
+ >
7
9
 
8
- export function Alert({ className, role = 'alert', ...props }: AlertProps) {
9
- return <div role={role} className={cn('sheerly-alert', className)} {...props} />
10
+ /**
11
+ * A callout. The leading icon is embedded in CSS and swaps per `data-variant`.
12
+ *
13
+ * Polymorphic: pass `as` to change the rendered tag (defaults to `div`).
14
+ *
15
+ * @example
16
+ * <Alert data-variant="warning">
17
+ * <AlertTitle>Heads up</AlertTitle>
18
+ * <AlertDescription>Your session expires soon.</AlertDescription>
19
+ * </Alert>
20
+ */
21
+ export function Alert<T extends ElementType = 'div'>({
22
+ as,
23
+ className,
24
+ ...props
25
+ }: AlertProps<T>) {
26
+ const Tag = as ?? 'div'
27
+ return (
28
+ <Tag role="alert" className={cn('sheerly-alert', className)} {...props} />
29
+ )
10
30
  }
11
31
 
12
- export function AlertTitle({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
13
- return <div className={cn('sheerly-alert-title', className)} {...props} />
32
+ export type AlertTitleProps<T extends ElementType = 'div'> = PolymorphicProps<T>
33
+
34
+ export function AlertTitle<T extends ElementType = 'div'>({
35
+ as,
36
+ className,
37
+ ...props
38
+ }: AlertTitleProps<T>) {
39
+ const Tag = as ?? 'div'
40
+ return <Tag className={cn('sheerly-alert-title', className)} {...props} />
14
41
  }
15
42
 
16
- export function AlertDescription({
43
+ export type AlertDescriptionProps<T extends ElementType = 'div'> = PolymorphicProps<T>
44
+
45
+ export function AlertDescription<T extends ElementType = 'div'>({
46
+ as,
17
47
  className,
18
48
  ...props
19
- }: HTMLAttributes<HTMLDivElement>) {
20
- return <div className={cn('sheerly-alert-description', className)} {...props} />
49
+ }: AlertDescriptionProps<T>) {
50
+ const Tag = as ?? 'div'
51
+ return <Tag className={cn('sheerly-alert-description', className)} {...props} />
21
52
  }
22
53
 
23
- export function AlertAction({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
24
- return <div className={cn('sheerly-alert-action', className)} {...props} />
54
+ export type AlertActionProps<T extends ElementType = 'div'> = PolymorphicProps<T>
55
+
56
+ export function AlertAction<T extends ElementType = 'div'>({
57
+ as,
58
+ className,
59
+ ...props
60
+ }: AlertActionProps<T>) {
61
+ const Tag = as ?? 'div'
62
+ return <Tag className={cn('sheerly-alert-action', className)} {...props} />
25
63
  }
package/src/avatar.css CHANGED
@@ -1,6 +1,5 @@
1
1
  /* Avatar — circular image with initials fallback */
2
2
  .sheerly-avatar {
3
- position: relative;
4
3
  display: flex;
5
4
  flex-shrink: 0;
6
5
  overflow: hidden;
package/src/avatar.tsx CHANGED
@@ -1,12 +1,31 @@
1
- import type { HTMLAttributes, ImgHTMLAttributes } from 'react'
2
- import { cn } from './cn'
3
-
4
- export interface AvatarProps extends HTMLAttributes<HTMLDivElement> {
5
- 'data-size'?: 'sm' | 'default' | 'lg' | 'xl'
6
- }
7
-
8
- export function Avatar({ className, ...props }: AvatarProps) {
9
- return <div className={cn('sheerly-avatar', className)} {...props} />
1
+ import type { ElementType, ImgHTMLAttributes } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
4
+
5
+ export type AvatarProps<T extends ElementType = 'div'> = PolymorphicProps<
6
+ T,
7
+ { 'data-size'?: 'sm' | 'default' | 'lg' | 'xl' }
8
+ >
9
+
10
+ /**
11
+ * A circular avatar. Nest an <AvatarImage> with an <AvatarFallback> for initials.
12
+ *
13
+ * Polymorphic: pass `as` to change the rendered tag (defaults to `div`, e.g.
14
+ * `as="a"` for a linkable avatar).
15
+ *
16
+ * @example
17
+ * <Avatar>
18
+ * <AvatarImage src="/me.jpg" alt="Ada" />
19
+ * <AvatarFallback>AL</AvatarFallback>
20
+ * </Avatar>
21
+ */
22
+ export function Avatar<T extends ElementType = 'div'>({
23
+ as,
24
+ className,
25
+ ...props
26
+ }: AvatarProps<T>) {
27
+ const Tag = as ?? 'div'
28
+ return <Tag className={cn('sheerly-avatar', className)} {...props} />
10
29
  }
11
30
 
12
31
  export interface AvatarImageProps extends ImgHTMLAttributes<HTMLImageElement> {
@@ -17,14 +36,24 @@ export function AvatarImage(props: AvatarImageProps) {
17
36
  return <img {...props} />
18
37
  }
19
38
 
20
- export type AvatarFallbackProps = HTMLAttributes<HTMLSpanElement>
39
+ export type AvatarFallbackProps<T extends ElementType = 'span'> = PolymorphicProps<T>
21
40
 
22
- export function AvatarFallback({ className, ...props }: AvatarFallbackProps) {
23
- return <span className={cn('sheerly-avatar-fallback', className)} {...props} />
41
+ export function AvatarFallback<T extends ElementType = 'span'>({
42
+ as,
43
+ className,
44
+ ...props
45
+ }: AvatarFallbackProps<T>) {
46
+ const Tag = as ?? 'span'
47
+ return <Tag className={cn('sheerly-avatar-fallback', className)} {...props} />
24
48
  }
25
49
 
26
- export type AvatarGroupProps = HTMLAttributes<HTMLDivElement>
50
+ export type AvatarGroupProps<T extends ElementType = 'div'> = PolymorphicProps<T>
27
51
 
28
- export function AvatarGroup({ className, ...props }: AvatarGroupProps) {
29
- return <div className={cn('sheerly-avatar-group', className)} {...props} />
52
+ export function AvatarGroup<T extends ElementType = 'div'>({
53
+ as,
54
+ className,
55
+ ...props
56
+ }: AvatarGroupProps<T>) {
57
+ const Tag = as ?? 'div'
58
+ return <Tag className={cn('sheerly-avatar-group', className)} {...props} />
30
59
  }
package/src/badge.tsx CHANGED
@@ -1,19 +1,37 @@
1
- import type { HTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
- export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
5
- 'data-variant'?:
6
- | 'default'
7
- | 'secondary'
8
- | 'destructive'
9
- | 'outline'
10
- | 'ghost'
11
- | 'success'
12
- | 'warning'
13
- | 'error'
14
- | 'blue'
15
- }
5
+ export type BadgeProps<T extends ElementType = 'span'> = PolymorphicProps<
6
+ T,
7
+ {
8
+ 'data-variant'?:
9
+ | 'default'
10
+ | 'secondary'
11
+ | 'destructive'
12
+ | 'outline'
13
+ | 'ghost'
14
+ | 'success'
15
+ | 'warning'
16
+ | 'error'
17
+ | 'blue'
18
+ }
19
+ >
16
20
 
17
- export function Badge({ className, ...props }: BadgeProps) {
18
- return <span className={cn('sheerly-badge', className)} {...props} />
21
+ /**
22
+ * A pill-shaped label. Set `data-variant` for color.
23
+ *
24
+ * Polymorphic: pass `as` to change the rendered tag (defaults to `span`, e.g.
25
+ * `as="a"` for a linkable badge).
26
+ *
27
+ * @example
28
+ * <Badge data-variant="success">Active</Badge>
29
+ */
30
+ export function Badge<T extends ElementType = 'span'>({
31
+ as,
32
+ className,
33
+ ...props
34
+ }: BadgeProps<T>) {
35
+ const Tag = as ?? 'span'
36
+ return <Tag className={cn('sheerly-badge', className)} {...props} />
19
37
  }
@@ -1,6 +1,19 @@
1
- import type { AnchorHTMLAttributes, HTMLAttributes, OlHTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { AnchorHTMLAttributes, ElementType, HTMLAttributes, OlHTMLAttributes } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
5
+ /**
6
+ * A path hierarchy of links.
7
+ *
8
+ * @example
9
+ * <Breadcrumb>
10
+ * <BreadcrumbList>
11
+ * <BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
12
+ * <BreadcrumbSeparator />
13
+ * <BreadcrumbItem><BreadcrumbPage>Docs</BreadcrumbPage></BreadcrumbItem>
14
+ * </BreadcrumbList>
15
+ * </Breadcrumb>
16
+ */
4
17
  export function Breadcrumb({ className, ...props }: HTMLAttributes<HTMLElement>) {
5
18
  return (
6
19
  <nav
@@ -23,9 +36,16 @@ export function BreadcrumbLink({ className, ...props }: AnchorHTMLAttributes<HTM
23
36
  return <a className={cn('sheerly-breadcrumb-link', className)} {...props} />
24
37
  }
25
38
 
26
- export function BreadcrumbPage({ className, ...props }: HTMLAttributes<HTMLSpanElement>) {
39
+ export type BreadcrumbPageProps<T extends ElementType = 'span'> = PolymorphicProps<T>
40
+
41
+ export function BreadcrumbPage<T extends ElementType = 'span'>({
42
+ as,
43
+ className,
44
+ ...props
45
+ }: BreadcrumbPageProps<T>) {
46
+ const Tag = as ?? 'span'
27
47
  return (
28
- <span
48
+ <Tag
29
49
  role="link"
30
50
  aria-disabled="true"
31
51
  aria-current="page"
@@ -52,13 +72,17 @@ export function BreadcrumbSeparator({
52
72
  )
53
73
  }
54
74
 
55
- export function BreadcrumbEllipsis({
75
+ export type BreadcrumbEllipsisProps<T extends ElementType = 'span'> = PolymorphicProps<T>
76
+
77
+ export function BreadcrumbEllipsis<T extends ElementType = 'span'>({
78
+ as,
56
79
  className,
57
80
  children,
58
81
  ...props
59
- }: HTMLAttributes<HTMLSpanElement>) {
82
+ }: BreadcrumbEllipsisProps<T>) {
83
+ const Tag = as ?? 'span'
60
84
  return (
61
- <span
85
+ <Tag
62
86
  role="presentation"
63
87
  aria-hidden="true"
64
88
  aria-label="More"
@@ -66,6 +90,6 @@ export function BreadcrumbEllipsis({
66
90
  {...props}
67
91
  >
68
92
  {children}
69
- </span>
93
+ </Tag>
70
94
  )
71
95
  }
package/src/button.css CHANGED
@@ -15,6 +15,7 @@
15
15
  outline: none;
16
16
  cursor: pointer;
17
17
  border: 1px solid transparent;
18
+ box-sizing: border-box;
18
19
  text-decoration: none;
19
20
  user-select: none;
20
21
 
package/src/button.tsx CHANGED
@@ -1,30 +1,47 @@
1
- import type { ButtonHTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
5
- 'data-variant'?:
6
- | 'default'
7
- | 'primary'
8
- | 'secondary'
9
- | 'tertiary'
10
- | 'ghost'
11
- | 'muted'
12
- | 'destructive'
13
- | 'error'
14
- | 'outline'
15
- | 'link'
16
- 'data-size'?:
17
- | 'xs'
18
- | 'sm'
19
- | 'default'
20
- | 'lg'
21
- | 'icon'
22
- | 'icon-xs'
23
- | 'icon-sm'
24
- | 'icon-lg'
25
- 'data-rounded'?: 'full'
26
- }
5
+ export type ButtonProps<T extends ElementType = 'button'> = PolymorphicProps<
6
+ T,
7
+ {
8
+ 'data-variant'?:
9
+ | 'default'
10
+ | 'primary'
11
+ | 'secondary'
12
+ | 'tertiary'
13
+ | 'ghost'
14
+ | 'muted'
15
+ | 'destructive'
16
+ | 'error'
17
+ | 'outline'
18
+ | 'link'
19
+ 'data-size'?:
20
+ | 'xs'
21
+ | 'sm'
22
+ | 'default'
23
+ | 'lg'
24
+ | 'icon'
25
+ | 'icon-xs'
26
+ | 'icon-sm'
27
+ | 'icon-lg'
28
+ 'data-rounded'?: 'full'
29
+ }
30
+ >
27
31
 
28
- export function Button({ className, ...props }: ButtonProps) {
29
- return <button className={cn('sheerly-button', className)} {...props} />
32
+ /**
33
+ * A button. Defaults to the primary variant; set `data-variant` / `data-size`
34
+ * to change it.
35
+ *
36
+ * @example
37
+ * <Button data-variant="secondary">Save</Button>
38
+ * <Button as="a" role="button" href="/settings">Settings</Button>
39
+ */
40
+ export function Button<T extends ElementType = 'button'>({
41
+ as,
42
+ className,
43
+ ...props
44
+ }: ButtonProps<T>) {
45
+ const Tag = as ?? 'button'
46
+ return <Tag className={cn('sheerly-button', className)} {...props} />
30
47
  }
package/src/card.tsx CHANGED
@@ -1,41 +1,100 @@
1
- import type { HTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
- export interface CardProps extends HTMLAttributes<HTMLDivElement> {
5
- 'data-size'?: 'default' | 'sm'
6
- }
5
+ export type CardProps<T extends ElementType = 'div'> = PolymorphicProps<
6
+ T,
7
+ { 'data-size'?: 'default' | 'sm' }
8
+ >
7
9
 
8
- export function Card({ className, ...props }: CardProps) {
9
- return <div className={cn('sheerly-card', className)} {...props} />
10
+ /**
11
+ * A surface container. Compose with the sub-parts below.
12
+ *
13
+ * Polymorphic: pass `as` to change the rendered tag (defaults to `div`).
14
+ *
15
+ * @example
16
+ * <Card as="article">
17
+ * <CardHeader>
18
+ * <CardTitle>Notifications</CardTitle>
19
+ * <CardDescription>You have 3 unread.</CardDescription>
20
+ * </CardHeader>
21
+ * <CardContent>…</CardContent>
22
+ * </Card>
23
+ */
24
+ export function Card<T extends ElementType = 'div'>({
25
+ as,
26
+ className,
27
+ ...props
28
+ }: CardProps<T>) {
29
+ const Tag = as ?? 'div'
30
+ return <Tag className={cn('sheerly-card', className)} {...props} />
10
31
  }
11
32
 
12
- export function CardHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
13
- return <div className={cn('sheerly-card-header', className)} {...props} />
14
- }
33
+ export type CardHeaderProps<T extends ElementType = 'div'> = PolymorphicProps<T>
15
34
 
16
- export function CardTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>) {
17
- return <h3 className={cn('sheerly-card-title', className)} {...props} />
35
+ export function CardHeader<T extends ElementType = 'div'>({
36
+ as,
37
+ className,
38
+ ...props
39
+ }: CardHeaderProps<T>) {
40
+ const Tag = as ?? 'div'
41
+ return <Tag className={cn('sheerly-card-header', className)} {...props} />
18
42
  }
19
43
 
20
- export function CardDescription({
44
+ export type CardTitleProps<T extends ElementType = 'h3'> = PolymorphicProps<T>
45
+
46
+ export function CardTitle<T extends ElementType = 'h3'>({
47
+ as,
21
48
  className,
22
49
  ...props
23
- }: HTMLAttributes<HTMLParagraphElement>) {
24
- return <p className={cn('sheerly-card-description', className)} {...props} />
50
+ }: CardTitleProps<T>) {
51
+ const Tag = as ?? 'h3'
52
+ return <Tag className={cn('sheerly-card-title', className)} {...props} />
25
53
  }
26
54
 
27
- export function CardAction({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
28
- return <div className={cn('sheerly-card-action', className)} {...props} />
55
+ export type CardDescriptionProps<T extends ElementType = 'p'> = PolymorphicProps<T>
56
+
57
+ export function CardDescription<T extends ElementType = 'p'>({
58
+ as,
59
+ className,
60
+ ...props
61
+ }: CardDescriptionProps<T>) {
62
+ const Tag = as ?? 'p'
63
+ return <Tag className={cn('sheerly-card-description', className)} {...props} />
29
64
  }
30
65
 
31
- export function CardContent({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
32
- return <div className={cn('sheerly-card-content', className)} {...props} />
66
+ export type CardActionProps<T extends ElementType = 'div'> = PolymorphicProps<T>
67
+
68
+ export function CardAction<T extends ElementType = 'div'>({
69
+ as,
70
+ className,
71
+ ...props
72
+ }: CardActionProps<T>) {
73
+ const Tag = as ?? 'div'
74
+ return <Tag className={cn('sheerly-card-action', className)} {...props} />
33
75
  }
34
76
 
35
- export interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
36
- 'data-direction'?: 'column'
77
+ export type CardContentProps<T extends ElementType = 'div'> = PolymorphicProps<T>
78
+
79
+ export function CardContent<T extends ElementType = 'div'>({
80
+ as,
81
+ className,
82
+ ...props
83
+ }: CardContentProps<T>) {
84
+ const Tag = as ?? 'div'
85
+ return <Tag className={cn('sheerly-card-content', className)} {...props} />
37
86
  }
38
87
 
39
- export function CardFooter({ className, ...props }: CardFooterProps) {
40
- return <div className={cn('sheerly-card-footer', className)} {...props} />
88
+ export type CardFooterProps<T extends ElementType = 'div'> = PolymorphicProps<
89
+ T,
90
+ { 'data-direction'?: 'column' }
91
+ >
92
+
93
+ export function CardFooter<T extends ElementType = 'div'>({
94
+ as,
95
+ className,
96
+ ...props
97
+ }: CardFooterProps<T>) {
98
+ const Tag = as ?? 'div'
99
+ return <Tag className={cn('sheerly-card-footer', className)} {...props} />
41
100
  }
package/src/carousel.tsx CHANGED
@@ -1,7 +1,8 @@
1
- import type { HTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
- export type CarouselProps = HTMLAttributes<HTMLDivElement>
5
+ export type CarouselProps<T extends ElementType = 'div'> = PolymorphicProps<T>
5
6
 
6
7
  /**
7
8
  * Pure-CSS carousel. The element itself is the scroll container — put
@@ -14,17 +15,33 @@ export type CarouselProps = HTMLAttributes<HTMLDivElement>
14
15
  * component sets no gap on purpose (a fixed basis + gap breaks first/last
15
16
  * snapping, so the prev/next buttons wouldn't disable and end dots wouldn't
16
17
  * highlight).
18
+ *
19
+ * @example
20
+ * <Carousel>
21
+ * <CarouselItem data-name="Slide 1">…</CarouselItem>
22
+ * <CarouselItem data-name="Slide 2">…</CarouselItem>
23
+ * </Carousel>
17
24
  */
18
- export function Carousel({ className, ...props }: CarouselProps) {
19
- return <div className={cn('sheerly-carousel', className)} {...props} />
25
+ export function Carousel<T extends ElementType = 'div'>({
26
+ as,
27
+ className,
28
+ ...props
29
+ }: CarouselProps<T>) {
30
+ const Tag = as ?? 'div'
31
+ return <Tag className={cn('sheerly-carousel', className)} {...props} />
20
32
  }
21
33
 
22
- export interface CarouselItemProps extends HTMLAttributes<HTMLDivElement> {
23
- /** Accessible name for this slide's generated scroll marker (WCAG). */
24
- 'data-name'?: string
25
- }
34
+ export type CarouselItemProps<T extends ElementType = 'div'> = PolymorphicProps<
35
+ T,
36
+ { /** Accessible name for this slide's generated scroll marker (WCAG). */ 'data-name'?: string }
37
+ >
26
38
 
27
39
  /** A slide. Defaults to `width: 100%` (one per page); override via `style`/`className`. */
28
- export function CarouselItem({ className, ...props }: CarouselItemProps) {
29
- return <div className={cn('sheerly-carousel-item', className)} {...props} />
40
+ export function CarouselItem<T extends ElementType = 'div'>({
41
+ as,
42
+ className,
43
+ ...props
44
+ }: CarouselItemProps<T>) {
45
+ const Tag = as ?? 'div'
46
+ return <Tag className={cn('sheerly-carousel-item', className)} {...props} />
30
47
  }
package/src/checkbox.tsx CHANGED
@@ -1,8 +1,14 @@
1
1
  import type { InputHTMLAttributes } from 'react'
2
- import { cn } from './cn'
2
+ import { cn } from './utils/cn'
3
3
 
4
4
  export type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>
5
5
 
6
+ /**
7
+ * A checkbox `<input>`. Pair with a <Label> for a clickable target.
8
+ *
9
+ * @example
10
+ * <Checkbox id="terms" defaultChecked />
11
+ */
6
12
  export function Checkbox({ className, ...props }: CheckboxProps) {
7
13
  return (
8
14
  <input type="checkbox" className={cn('sheerly-checkbox', className)} {...props} />
package/src/dialog.tsx CHANGED
@@ -1,39 +1,78 @@
1
- import type { ButtonHTMLAttributes, DialogHTMLAttributes, HTMLAttributes } from 'react'
2
- import { cn } from './cn'
1
+ import type { ButtonHTMLAttributes, DialogHTMLAttributes, ElementType } from 'react'
2
+ import { cn } from './utils/cn'
3
+ import type { PolymorphicProps } from './utils/polymorphic'
3
4
 
4
5
  /**
5
6
  * Native <dialog>. Open via invoker command (`command="show-modal"`) or
6
7
  * `.showModal()`. Add `closedby="any"` for light-dismiss.
8
+ *
9
+ * @example
10
+ * <button commandfor="d" command="show-modal">Open</button>
11
+ * <Dialog id="d" closedby="any">
12
+ * <DialogHeader><DialogTitle>Confirm</DialogTitle></DialogHeader>
13
+ * <DialogFooter><DialogClose command="close" commandfor="d">Cancel</DialogClose></DialogFooter>
14
+ * </Dialog>
7
15
  */
8
16
  export function Dialog({ className, ...props }: DialogHTMLAttributes<HTMLDialogElement>) {
9
17
  return <dialog className={cn('sheerly-dialog', className)} {...props} />
10
18
  }
11
19
 
12
- export function DialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
13
- return <div className={cn('sheerly-dialog-header', className)} {...props} />
14
- }
20
+ export type DialogHeaderProps<T extends ElementType = 'div'> = PolymorphicProps<T>
15
21
 
16
- export function DialogTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>) {
17
- return <h3 className={cn('sheerly-dialog-title', className)} {...props} />
22
+ export function DialogHeader<T extends ElementType = 'div'>({
23
+ as,
24
+ className,
25
+ ...props
26
+ }: DialogHeaderProps<T>) {
27
+ const Tag = as ?? 'div'
28
+ return <Tag className={cn('sheerly-dialog-header', className)} {...props} />
18
29
  }
19
30
 
20
- export function DialogDescription({
31
+ export type DialogTitleProps<T extends ElementType = 'h3'> = PolymorphicProps<T>
32
+
33
+ export function DialogTitle<T extends ElementType = 'h3'>({
34
+ as,
21
35
  className,
22
36
  ...props
23
- }: HTMLAttributes<HTMLParagraphElement>) {
24
- return <p className={cn('sheerly-dialog-description', className)} {...props} />
37
+ }: DialogTitleProps<T>) {
38
+ const Tag = as ?? 'h3'
39
+ return <Tag className={cn('sheerly-dialog-title', className)} {...props} />
25
40
  }
26
41
 
27
- export function DialogBody({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
28
- return <div className={cn('sheerly-dialog-body', className)} {...props} />
42
+ export type DialogDescriptionProps<T extends ElementType = 'p'> = PolymorphicProps<T>
43
+
44
+ export function DialogDescription<T extends ElementType = 'p'>({
45
+ as,
46
+ className,
47
+ ...props
48
+ }: DialogDescriptionProps<T>) {
49
+ const Tag = as ?? 'p'
50
+ return <Tag className={cn('sheerly-dialog-description', className)} {...props} />
29
51
  }
30
52
 
31
- export interface DialogFooterProps extends HTMLAttributes<HTMLDivElement> {
32
- 'data-direction'?: 'column'
53
+ export type DialogBodyProps<T extends ElementType = 'div'> = PolymorphicProps<T>
54
+
55
+ export function DialogBody<T extends ElementType = 'div'>({
56
+ as,
57
+ className,
58
+ ...props
59
+ }: DialogBodyProps<T>) {
60
+ const Tag = as ?? 'div'
61
+ return <Tag className={cn('sheerly-dialog-body', className)} {...props} />
33
62
  }
34
63
 
35
- export function DialogFooter({ className, ...props }: DialogFooterProps) {
36
- return <div className={cn('sheerly-dialog-footer', className)} {...props} />
64
+ export type DialogFooterProps<T extends ElementType = 'div'> = PolymorphicProps<
65
+ T,
66
+ { 'data-direction'?: 'column' }
67
+ >
68
+
69
+ export function DialogFooter<T extends ElementType = 'div'>({
70
+ as,
71
+ className,
72
+ ...props
73
+ }: DialogFooterProps<T>) {
74
+ const Tag = as ?? 'div'
75
+ return <Tag className={cn('sheerly-dialog-footer', className)} {...props} />
37
76
  }
38
77
 
39
78
  export function DialogClose({