sv5ui 1.1.2 → 1.2.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.
Files changed (155) hide show
  1. package/README.md +6 -0
  2. package/dist/Alert/Alert.svelte +33 -22
  3. package/dist/Alert/Alert.svelte.d.ts +1 -1
  4. package/dist/Alert/alert.types.d.ts +4 -0
  5. package/dist/Avatar/Avatar.svelte +72 -46
  6. package/dist/Avatar/avatar.types.d.ts +36 -3
  7. package/dist/Avatar/avatar.variants.d.ts +138 -0
  8. package/dist/Avatar/avatar.variants.js +23 -12
  9. package/dist/Avatar/index.d.ts +1 -1
  10. package/dist/AvatarGroup/AvatarGroup.svelte +11 -6
  11. package/dist/AvatarGroup/AvatarGroup.svelte.d.ts +1 -1
  12. package/dist/AvatarGroup/avatar-group.types.d.ts +18 -3
  13. package/dist/AvatarGroup/avatar-group.variants.d.ts +85 -0
  14. package/dist/AvatarGroup/avatar-group.variants.js +19 -29
  15. package/dist/Badge/Badge.svelte +4 -3
  16. package/dist/Badge/Badge.svelte.d.ts +1 -1
  17. package/dist/Badge/badge.types.d.ts +9 -0
  18. package/dist/Breadcrumb/Breadcrumb.svelte +20 -7
  19. package/dist/Breadcrumb/Breadcrumb.svelte.d.ts +1 -1
  20. package/dist/Breadcrumb/breadcrumb.types.d.ts +5 -1
  21. package/dist/Breadcrumb/breadcrumb.variants.d.ts +15 -5
  22. package/dist/Breadcrumb/breadcrumb.variants.js +7 -3
  23. package/dist/Button/Button.svelte +71 -16
  24. package/dist/Button/Button.svelte.d.ts +0 -1
  25. package/dist/Button/button.types.d.ts +61 -2
  26. package/dist/Calendar/Calendar.svelte +4 -0
  27. package/dist/Calendar/Calendar.svelte.d.ts +1 -1
  28. package/dist/Calendar/calendar.types.d.ts +4 -0
  29. package/dist/Card/Card.svelte +5 -4
  30. package/dist/Card/Card.svelte.d.ts +1 -1
  31. package/dist/Card/card.types.d.ts +5 -1
  32. package/dist/Checkbox/Checkbox.svelte +37 -11
  33. package/dist/Checkbox/Checkbox.svelte.d.ts +1 -1
  34. package/dist/Checkbox/checkbox.types.d.ts +16 -1
  35. package/dist/Checkbox/checkbox.variants.d.ts +90 -0
  36. package/dist/Checkbox/checkbox.variants.js +73 -4
  37. package/dist/Chip/Chip.svelte +3 -2
  38. package/dist/Chip/Chip.svelte.d.ts +1 -1
  39. package/dist/Chip/chip.types.d.ts +5 -1
  40. package/dist/Chip/chip.variants.d.ts +135 -45
  41. package/dist/Chip/chip.variants.js +9 -9
  42. package/dist/ContextMenu/ContextMenu.svelte +87 -77
  43. package/dist/ContextMenu/ContextMenu.svelte.d.ts +1 -1
  44. package/dist/ContextMenu/context-menu.types.d.ts +9 -3
  45. package/dist/ContextMenu/context-menu.types.js +1 -1
  46. package/dist/ContextMenu/context-menu.variants.d.ts +74 -160
  47. package/dist/ContextMenu/context-menu.variants.js +63 -95
  48. package/dist/DropdownMenu/DropdownMenu.svelte +37 -43
  49. package/dist/DropdownMenu/DropdownMenu.svelte.d.ts +1 -1
  50. package/dist/DropdownMenu/dropdown-menu.types.d.ts +9 -3
  51. package/dist/DropdownMenu/dropdown-menu.types.js +1 -1
  52. package/dist/DropdownMenu/dropdown-menu.variants.d.ts +79 -230
  53. package/dist/DropdownMenu/dropdown-menu.variants.js +68 -111
  54. package/dist/DropdownMenu/index.d.ts +1 -1
  55. package/dist/Empty/Empty.svelte +68 -33
  56. package/dist/Empty/Empty.svelte.d.ts +1 -1
  57. package/dist/Empty/empty.types.d.ts +26 -9
  58. package/dist/Empty/empty.variants.d.ts +150 -130
  59. package/dist/Empty/empty.variants.js +33 -324
  60. package/dist/FieldGroup/FieldGroup.svelte +11 -6
  61. package/dist/FieldGroup/FieldGroup.svelte.d.ts +1 -1
  62. package/dist/FieldGroup/field-group.types.d.ts +4 -0
  63. package/dist/FormField/FormField.svelte +17 -18
  64. package/dist/FormField/FormField.svelte.d.ts +1 -1
  65. package/dist/FormField/form-field.types.d.ts +4 -0
  66. package/dist/Icon/Icon.svelte +13 -7
  67. package/dist/Icon/icon.types.d.ts +18 -9
  68. package/dist/Input/Input.svelte +30 -29
  69. package/dist/Kbd/Kbd.svelte +13 -3
  70. package/dist/Kbd/Kbd.svelte.d.ts +1 -1
  71. package/dist/Kbd/index.d.ts +1 -1
  72. package/dist/Kbd/kbd.types.d.ts +15 -1
  73. package/dist/Kbd/kbd.variants.d.ts +92 -30
  74. package/dist/Kbd/kbd.variants.js +55 -35
  75. package/dist/Kbd/useKbd.svelte.d.ts +2 -2
  76. package/dist/Kbd/useKbd.svelte.js +34 -41
  77. package/dist/Link/Link.svelte +69 -24
  78. package/dist/Link/Link.svelte.d.ts +1 -1
  79. package/dist/Link/link.types.d.ts +26 -8
  80. package/dist/Link/link.variants.d.ts +35 -60
  81. package/dist/Link/link.variants.js +8 -110
  82. package/dist/Modal/Modal.svelte +9 -1
  83. package/dist/Modal/modal.types.d.ts +5 -0
  84. package/dist/Modal/modal.variants.d.ts +5 -0
  85. package/dist/Modal/modal.variants.js +1 -0
  86. package/dist/Pagination/Pagination.svelte +143 -94
  87. package/dist/Pagination/Pagination.svelte.d.ts +1 -1
  88. package/dist/Pagination/index.d.ts +1 -1
  89. package/dist/Pagination/pagination.types.d.ts +21 -2
  90. package/dist/Pagination/pagination.variants.d.ts +21 -387
  91. package/dist/Pagination/pagination.variants.js +63 -59
  92. package/dist/Popover/Popover.svelte +9 -12
  93. package/dist/Popover/Popover.svelte.d.ts +1 -1
  94. package/dist/Popover/popover.types.d.ts +4 -0
  95. package/dist/Popover/popover.variants.d.ts +5 -75
  96. package/dist/Popover/popover.variants.js +6 -16
  97. package/dist/Progress/Progress.svelte +58 -30
  98. package/dist/Progress/progress.types.d.ts +9 -1
  99. package/dist/Progress/progress.variants.d.ts +55 -25
  100. package/dist/Progress/progress.variants.js +34 -28
  101. package/dist/RadioGroup/RadioGroup.svelte +105 -61
  102. package/dist/RadioGroup/RadioGroup.svelte.d.ts +1 -1
  103. package/dist/RadioGroup/radio-group.types.d.ts +16 -1
  104. package/dist/RadioGroup/radio-group.variants.d.ts +90 -0
  105. package/dist/RadioGroup/radio-group.variants.js +73 -4
  106. package/dist/Select/Select.svelte +9 -6
  107. package/dist/Select/Select.svelte.d.ts +1 -1
  108. package/dist/Select/select.types.d.ts +4 -0
  109. package/dist/SelectMenu/SelectMenu.svelte +436 -0
  110. package/dist/SelectMenu/SelectMenu.svelte.d.ts +5 -0
  111. package/dist/SelectMenu/index.d.ts +2 -0
  112. package/dist/SelectMenu/index.js +1 -0
  113. package/dist/SelectMenu/select-menu.types.d.ts +262 -0
  114. package/dist/SelectMenu/select-menu.types.js +1 -0
  115. package/dist/SelectMenu/select-menu.variants.d.ts +759 -0
  116. package/dist/SelectMenu/select-menu.variants.js +33 -0
  117. package/dist/Separator/Separator.svelte +1 -2
  118. package/dist/Separator/separator.variants.d.ts +1 -5
  119. package/dist/Separator/separator.variants.js +2 -2
  120. package/dist/Skeleton/Skeleton.svelte +18 -2
  121. package/dist/Skeleton/Skeleton.svelte.d.ts +1 -1
  122. package/dist/Skeleton/skeleton.types.d.ts +10 -1
  123. package/dist/Slideover/Slideover.svelte +9 -1
  124. package/dist/Slideover/slideover.types.d.ts +5 -0
  125. package/dist/Slideover/slideover.variants.d.ts +20 -5
  126. package/dist/Slideover/slideover.variants.js +4 -29
  127. package/dist/Switch/Switch.svelte +32 -31
  128. package/dist/Switch/Switch.svelte.d.ts +1 -1
  129. package/dist/Switch/switch.types.d.ts +6 -1
  130. package/dist/Switch/switch.variants.js +6 -6
  131. package/dist/Tabs/Tabs.svelte +6 -9
  132. package/dist/Tabs/Tabs.svelte.d.ts +1 -1
  133. package/dist/Tabs/tabs.types.d.ts +4 -0
  134. package/dist/Tabs/tabs.variants.js +2 -0
  135. package/dist/Textarea/Textarea.svelte +26 -25
  136. package/dist/ThemeModeButton/theme-mode-button.types.d.ts +7 -2
  137. package/dist/Timeline/Timeline.svelte +62 -19
  138. package/dist/Timeline/Timeline.svelte.d.ts +1 -1
  139. package/dist/Timeline/index.d.ts +1 -1
  140. package/dist/Timeline/timeline.types.d.ts +8 -0
  141. package/dist/Tooltip/Tooltip.svelte +12 -10
  142. package/dist/Tooltip/Tooltip.svelte.d.ts +1 -1
  143. package/dist/Tooltip/tooltip.types.d.ts +8 -4
  144. package/dist/Tooltip/tooltip.variants.d.ts +10 -75
  145. package/dist/Tooltip/tooltip.variants.js +8 -17
  146. package/dist/User/User.svelte +13 -9
  147. package/dist/User/User.svelte.d.ts +1 -1
  148. package/dist/User/user.types.d.ts +4 -0
  149. package/dist/User/user.variants.d.ts +60 -0
  150. package/dist/User/user.variants.js +13 -1
  151. package/dist/config.d.ts +4 -0
  152. package/dist/config.js +4 -0
  153. package/dist/index.d.ts +1 -1
  154. package/dist/index.js +1 -1
  155. package/package.json +2 -2
package/README.md CHANGED
@@ -9,10 +9,16 @@
9
9
  Built with Tailwind CSS 4, OKLCH color tokens, and accessible headless primitives.
10
10
  </p>
11
11
 
12
+ <p align="center">
13
+ <a href="https://sv5ui.vercel.app/docs"><strong>Documentation</strong></a> · <a href="https://sv5ui.vercel.app"><strong>Live Demo</strong></a>
14
+ </p>
15
+
12
16
  <p align="center">
13
17
  <a href="https://www.npmjs.com/package/sv5ui"><img src="https://img.shields.io/npm/v/sv5ui.svg?style=flat-square&colorA=18181b&colorB=ff3e00" alt="npm version" /></a>
14
18
  <a href="https://github.com/ndlabdev/sv5ui/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/sv5ui.svg?style=flat-square&colorA=18181b&colorB=ff3e00" alt="license" /></a>
15
19
  <a href="https://www.npmjs.com/package/sv5ui"><img src="https://img.shields.io/npm/dm/sv5ui.svg?style=flat-square&colorA=18181b&colorB=ff3e00" alt="downloads" /></a>
20
+ <a href="https://svelte.dev"><img src="https://img.shields.io/badge/svelte-5-ff3e00?style=flat-square&logo=svelte&logoColor=white" alt="Svelte 5" /></a>
21
+ <a href="https://www.typescriptlang.org"><img src="https://img.shields.io/badge/types-TypeScript-blue?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" /></a>
16
22
  </p>
17
23
 
18
24
  ---
@@ -15,6 +15,7 @@
15
15
  const icons = getComponentConfig('icons', iconsDefaults)
16
16
 
17
17
  let {
18
+ ref = $bindable(null),
18
19
  as = 'div',
19
20
  ui,
20
21
  title,
@@ -24,7 +25,7 @@
24
25
  color = config.defaultVariants.color,
25
26
  variant = config.defaultVariants.variant,
26
27
  orientation = config.defaultVariants.orientation,
27
- open = true,
28
+ open = $bindable(true),
28
29
  close = false,
29
30
  closeIcon,
30
31
  actions,
@@ -41,7 +42,7 @@
41
42
  const resolvedCloseIcon = $derived(closeIcon ?? icons.close)
42
43
 
43
44
  const classes = $derived.by(() => {
44
- const slots = alertVariants({ variant, color, orientation })
45
+ const slots = alertVariants({ variant, color, orientation, title: !!title })
45
46
  return {
46
47
  root: slots.root({ class: [config.slots.root, className, ui?.root] }),
47
48
  wrapper: slots.wrapper({ class: [config.slots.wrapper, ui?.wrapper] }),
@@ -54,19 +55,31 @@
54
55
  }
55
56
  })
56
57
 
57
- const closeButtonProps = $derived.by(() => {
58
- if (!close) return null
59
- if (close === true) return {}
60
- return close
61
- })
58
+ const closeButtonProps = $derived(!close ? null : close === true ? {} : close)
59
+
60
+ const isVertical = $derived(orientation === 'vertical')
61
+ const hasActions = $derived(!!actionsSlot || (actions && actions.length > 0))
62
62
 
63
63
  function handleClose() {
64
+ open = false
64
65
  onClose?.()
65
66
  }
66
67
  </script>
67
68
 
69
+ {#snippet actionsContent()}
70
+ {#if actionsSlot}
71
+ {@render actionsSlot()}
72
+ {:else if actions && actions.length > 0}
73
+ <div class={classes.actions}>
74
+ {#each actions as action, index (index)}
75
+ <Button size="xs" {...action} />
76
+ {/each}
77
+ </div>
78
+ {/if}
79
+ {/snippet}
80
+
68
81
  {#if open}
69
- <svelte:element this={as} class={classes.root} role="alert" {...restProps}>
82
+ <svelte:element this={as} bind:this={ref} class={classes.root} role="alert" {...restProps}>
70
83
  {#if leading}
71
84
  {@render leading()}
72
85
  {:else if icon}
@@ -75,7 +88,7 @@
75
88
  <Avatar {...avatar} class={classes.avatar} />
76
89
  {/if}
77
90
 
78
- {#if title || description || titleSlot || descriptionSlot}
91
+ {#if title || description || titleSlot || descriptionSlot || (isVertical && hasActions)}
79
92
  <div class={classes.wrapper}>
80
93
  {#if titleSlot}
81
94
  {@render titleSlot()}
@@ -88,17 +101,15 @@
88
101
  {:else if description}
89
102
  <div class={classes.description}>{description}</div>
90
103
  {/if}
104
+
105
+ {#if isVertical}
106
+ {@render actionsContent()}
107
+ {/if}
91
108
  </div>
92
109
  {/if}
93
110
 
94
- {#if actionsSlot}
95
- {@render actionsSlot()}
96
- {:else if actions && actions.length > 0}
97
- <div class={classes.actions}>
98
- {#each actions as action, index (index)}
99
- <Button size="xs" {...action} />
100
- {/each}
101
- </div>
111
+ {#if !isVertical}
112
+ {@render actionsContent()}
102
113
  {/if}
103
114
 
104
115
  {#if closeSlot}
@@ -107,13 +118,13 @@
107
118
  </div>
108
119
  {:else if closeButtonProps}
109
120
  <Button
110
- icon={resolvedCloseIcon}
111
- variant="link"
112
- color="surface"
121
+ {...closeButtonProps}
122
+ icon={closeButtonProps.icon ?? resolvedCloseIcon}
123
+ variant={closeButtonProps.variant ?? 'link'}
124
+ color={closeButtonProps.color ?? 'surface'}
113
125
  class={classes.close}
114
126
  onclick={handleClose}
115
- aria-label="Close alert"
116
- {...closeButtonProps}
127
+ aria-label={closeButtonProps['aria-label'] ?? 'Close alert'}
117
128
  />
118
129
  {/if}
119
130
  </svelte:element>
@@ -1,5 +1,5 @@
1
1
  import type { AlertProps } from './alert.types.js';
2
2
  export type Props = AlertProps;
3
- declare const Alert: import("svelte").Component<AlertProps, {}, "">;
3
+ declare const Alert: import("svelte").Component<AlertProps, {}, "ref" | "open">;
4
4
  type Alert = ReturnType<typeof Alert>;
5
5
  export default Alert;
@@ -5,6 +5,10 @@ import type { AlertVariantProps, AlertSlots } from './alert.variants.js';
5
5
  import type { AvatarProps } from '../Avatar/avatar.types.js';
6
6
  import type { ButtonProps } from '../Button/button.types.js';
7
7
  export type AlertProps = Omit<HTMLAttributes<HTMLDivElement>, 'class' | 'title'> & {
8
+ /**
9
+ * Bindable reference to the root DOM element.
10
+ */
11
+ ref?: HTMLElement | null;
8
12
  /**
9
13
  * The HTML element to render as.
10
14
  * @default 'div'
@@ -1,26 +1,16 @@
1
1
  <script lang="ts" module>
2
- import type { AvatarProps, AvatarSize } from './avatar.types.js'
2
+ import type { AvatarProps, AvatarSize, AvatarRounded } from './avatar.types.js'
3
3
 
4
4
  export type Props = AvatarProps
5
-
6
- const SIZE_PX: Record<AvatarSize, number> = {
7
- '3xs': 16,
8
- '2xs': 20,
9
- xs: 24,
10
- sm: 28,
11
- md: 32,
12
- lg: 36,
13
- xl: 40,
14
- '2xl': 44,
15
- '3xl': 48
16
- }
17
5
  </script>
18
6
 
19
7
  <script lang="ts">
20
8
  import { Avatar } from 'bits-ui'
21
- import { avatarVariants, avatarDefaults } from './avatar.variants.js'
9
+ import { avatarVariants, avatarDefaults, avatarSizePx } from './avatar.variants.js'
22
10
  import { getComponentConfig } from '../config.js'
23
11
  import { getContext } from 'svelte'
12
+ import Icon from '../Icon/Icon.svelte'
13
+ import Chip from '../Chip/Chip.svelte'
24
14
 
25
15
  const config = getComponentConfig('avatar', avatarDefaults)
26
16
 
@@ -29,60 +19,96 @@
29
19
  src,
30
20
  alt,
31
21
  size,
22
+ rounded,
32
23
  text,
24
+ icon,
25
+ chip,
26
+ loading,
33
27
  delayMs = 0,
34
28
  class: className,
35
29
  ui,
30
+ fallback: fallbackSnippet,
36
31
  children,
37
32
  ...restProps
38
33
  }: Props = $props()
39
34
 
40
- const groupContext = getContext<{ size: AvatarSize; baseClass: string } | undefined>(
41
- 'avatarGroup'
42
- )
35
+ const groupContext = getContext<
36
+ { size: AvatarSize; rounded: AvatarRounded; baseClass: string } | undefined
37
+ >('avatarGroup')
43
38
 
44
39
  const resolvedSize = $derived(size ?? groupContext?.size ?? config.defaultVariants.size ?? 'md')
45
- const sizePx = $derived(SIZE_PX[resolvedSize])
40
+ const resolvedRounded = $derived(
41
+ rounded ?? groupContext?.rounded ?? config.defaultVariants.rounded ?? 'full'
42
+ )
43
+ const sizePx = $derived(avatarSizePx[resolvedSize])
46
44
 
47
45
  const initials = $derived(
48
- text ||
49
- (alt
50
- ? alt
51
- .split(' ')
52
- .slice(0, 2)
53
- .map((w) => w[0])
54
- .join('')
55
- .toUpperCase()
56
- : '')
46
+ text !== undefined
47
+ ? text
48
+ : alt
49
+ ? alt
50
+ .split(' ')
51
+ .filter(Boolean)
52
+ .slice(0, 2)
53
+ .map((w) => w[0])
54
+ .join('')
55
+ .toUpperCase()
56
+ : ''
57
+ )
58
+
59
+ const chipProps = $derived(
60
+ chip === true
61
+ ? { inset: true as const }
62
+ : chip
63
+ ? { inset: true as const, ...chip }
64
+ : undefined
57
65
  )
58
66
 
59
67
  const classes = $derived.by(() => {
60
- const slots = avatarVariants({ size: resolvedSize })
68
+ const slots = avatarVariants({ size: resolvedSize, rounded: resolvedRounded })
61
69
  return {
62
70
  root: slots.root({
63
71
  class: [config.slots.root, groupContext?.baseClass, className, ui?.root]
64
72
  }),
65
73
  image: slots.image({ class: [config.slots.image, ui?.image] }),
66
- fallback: slots.fallback({ class: [config.slots.fallback, ui?.fallback] })
74
+ fallback: slots.fallback({ class: [config.slots.fallback, ui?.fallback] }),
75
+ icon: slots.icon({ class: [config.slots.icon, ui?.icon] })
67
76
  }
68
77
  })
69
78
  </script>
70
79
 
71
- <Avatar.Root bind:ref class={classes.root} {delayMs} {...restProps}>
72
- {#if children}
73
- {@render children()}
74
- {:else}
75
- {#if src}
76
- <Avatar.Image
77
- {src}
78
- alt={alt ?? ''}
79
- class={classes.image}
80
- width={sizePx}
81
- height={sizePx}
82
- />
80
+ {#snippet avatarContent()}
81
+ <Avatar.Root {...restProps} bind:ref class={classes.root} {delayMs}>
82
+ {#if children}
83
+ {@render children()}
84
+ {:else}
85
+ {#if src}
86
+ <Avatar.Image
87
+ {src}
88
+ alt={alt ?? ''}
89
+ class={classes.image}
90
+ width={sizePx}
91
+ height={sizePx}
92
+ {loading}
93
+ />
94
+ {/if}
95
+ <Avatar.Fallback class={classes.fallback}>
96
+ {#if fallbackSnippet}
97
+ {@render fallbackSnippet()}
98
+ {:else if initials}
99
+ {initials}
100
+ {:else if icon}
101
+ <Icon name={icon} class={classes.icon} />
102
+ {/if}
103
+ </Avatar.Fallback>
83
104
  {/if}
84
- <Avatar.Fallback class={classes.fallback}>
85
- {initials}
86
- </Avatar.Fallback>
87
- {/if}
88
- </Avatar.Root>
105
+ </Avatar.Root>
106
+ {/snippet}
107
+
108
+ {#if chipProps}
109
+ <Chip {...chipProps}>
110
+ {@render avatarContent()}
111
+ </Chip>
112
+ {:else}
113
+ {@render avatarContent()}
114
+ {/if}
@@ -1,14 +1,23 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { Avatar } from 'bits-ui';
3
3
  import type { ClassNameValue } from 'tailwind-merge';
4
- import type { AvatarVariantProps, AvatarSlots } from './avatar.variants.js';
5
- export type AvatarSize = NonNullable<AvatarVariantProps['size']>;
4
+ import type { AvatarVariantProps, AvatarSize, AvatarSlots } from './avatar.variants.js';
5
+ import type { ChipProps } from '../Chip/chip.types.js';
6
+ export type { AvatarSize };
7
+ export type AvatarRounded = NonNullable<AvatarVariantProps['rounded']>;
8
+ export type AvatarChipProps = Pick<ChipProps, 'color' | 'size' | 'position' | 'inset' | 'show' | 'text'>;
6
9
  export type AvatarProps = Omit<Avatar.RootProps, 'children'> & {
7
10
  /**
8
11
  * Controls the dimensions of the avatar.
9
12
  * @default 'md'
10
13
  */
11
14
  size?: AvatarSize;
15
+ /**
16
+ * Controls the border radius of the avatar.
17
+ * Use `'lg'`, `'md'`, `'sm'` for square-ish avatars (e.g. organization logos).
18
+ * @default 'full'
19
+ */
20
+ rounded?: AvatarRounded;
12
21
  /**
13
22
  * URL of the image to display.
14
23
  * The image will be shown once it loads successfully.
@@ -24,6 +33,25 @@ export type AvatarProps = Omit<Avatar.RootProps, 'children'> & {
24
33
  * Overrides auto-generated initials from `alt`.
25
34
  */
26
35
  text?: string;
36
+ /**
37
+ * Iconify icon name to display as fallback when no image or text is available.
38
+ * @example 'lucide:user', 'mdi:account'
39
+ */
40
+ icon?: string;
41
+ /**
42
+ * Renders a Chip indicator on the avatar.
43
+ * Pass `true` for default chip, or an object to customize.
44
+ * @example true
45
+ * @example { color: 'success' }
46
+ * @example { color: 'error', position: 'bottom-right' }
47
+ */
48
+ chip?: boolean | AvatarChipProps;
49
+ /**
50
+ * Image loading strategy.
51
+ * Use `'lazy'` for avatars below the fold to improve page load performance.
52
+ * @default 'eager'
53
+ */
54
+ loading?: 'lazy' | 'eager';
27
55
  /**
28
56
  * Additional CSS classes for the root element.
29
57
  */
@@ -32,9 +60,14 @@ export type AvatarProps = Omit<Avatar.RootProps, 'children'> & {
32
60
  * Override styles for specific avatar slots.
33
61
  */
34
62
  ui?: Partial<Record<AvatarSlots, ClassNameValue>>;
63
+ /**
64
+ * Custom fallback content to render when the image is unavailable.
65
+ * Overrides text, initials, and icon fallback.
66
+ */
67
+ fallback?: Snippet;
35
68
  /**
36
69
  * Custom content to render inside the avatar.
37
- * When provided, overrides image, text, and icon.
70
+ * When provided, overrides the entire avatar content (image + fallback).
38
71
  */
39
72
  children?: Snippet;
40
73
  };
@@ -3,176 +3,314 @@ export declare const avatarVariants: import("tailwind-variants").TVReturnType<{
3
3
  size: {
4
4
  '3xs': {
5
5
  root: string;
6
+ icon: string;
6
7
  };
7
8
  '2xs': {
8
9
  root: string;
10
+ icon: string;
9
11
  };
10
12
  xs: {
11
13
  root: string;
14
+ icon: string;
12
15
  };
13
16
  sm: {
14
17
  root: string;
18
+ icon: string;
15
19
  };
16
20
  md: {
17
21
  root: string;
22
+ icon: string;
18
23
  };
19
24
  lg: {
20
25
  root: string;
26
+ icon: string;
21
27
  };
22
28
  xl: {
23
29
  root: string;
30
+ icon: string;
24
31
  };
25
32
  '2xl': {
26
33
  root: string;
34
+ icon: string;
27
35
  };
28
36
  '3xl': {
29
37
  root: string;
38
+ icon: string;
39
+ };
40
+ };
41
+ rounded: {
42
+ full: {
43
+ root: string;
44
+ };
45
+ lg: {
46
+ root: string;
47
+ };
48
+ md: {
49
+ root: string;
50
+ };
51
+ sm: {
52
+ root: string;
53
+ };
54
+ none: {
55
+ root: string;
30
56
  };
31
57
  };
32
58
  }, {
33
59
  root: string;
34
60
  image: string;
35
61
  fallback: string;
62
+ icon: string;
36
63
  }, undefined, {
37
64
  size: {
38
65
  '3xs': {
39
66
  root: string;
67
+ icon: string;
40
68
  };
41
69
  '2xs': {
42
70
  root: string;
71
+ icon: string;
43
72
  };
44
73
  xs: {
45
74
  root: string;
75
+ icon: string;
46
76
  };
47
77
  sm: {
48
78
  root: string;
79
+ icon: string;
49
80
  };
50
81
  md: {
51
82
  root: string;
83
+ icon: string;
52
84
  };
53
85
  lg: {
54
86
  root: string;
87
+ icon: string;
55
88
  };
56
89
  xl: {
57
90
  root: string;
91
+ icon: string;
58
92
  };
59
93
  '2xl': {
60
94
  root: string;
95
+ icon: string;
61
96
  };
62
97
  '3xl': {
63
98
  root: string;
99
+ icon: string;
100
+ };
101
+ };
102
+ rounded: {
103
+ full: {
104
+ root: string;
105
+ };
106
+ lg: {
107
+ root: string;
108
+ };
109
+ md: {
110
+ root: string;
111
+ };
112
+ sm: {
113
+ root: string;
114
+ };
115
+ none: {
116
+ root: string;
64
117
  };
65
118
  };
66
119
  }, {
67
120
  root: string;
68
121
  image: string;
69
122
  fallback: string;
123
+ icon: string;
70
124
  }, import("tailwind-variants").TVReturnType<{
71
125
  size: {
72
126
  '3xs': {
73
127
  root: string;
128
+ icon: string;
74
129
  };
75
130
  '2xs': {
76
131
  root: string;
132
+ icon: string;
77
133
  };
78
134
  xs: {
79
135
  root: string;
136
+ icon: string;
80
137
  };
81
138
  sm: {
82
139
  root: string;
140
+ icon: string;
83
141
  };
84
142
  md: {
85
143
  root: string;
144
+ icon: string;
86
145
  };
87
146
  lg: {
88
147
  root: string;
148
+ icon: string;
89
149
  };
90
150
  xl: {
91
151
  root: string;
152
+ icon: string;
92
153
  };
93
154
  '2xl': {
94
155
  root: string;
156
+ icon: string;
95
157
  };
96
158
  '3xl': {
97
159
  root: string;
160
+ icon: string;
161
+ };
162
+ };
163
+ rounded: {
164
+ full: {
165
+ root: string;
166
+ };
167
+ lg: {
168
+ root: string;
169
+ };
170
+ md: {
171
+ root: string;
172
+ };
173
+ sm: {
174
+ root: string;
175
+ };
176
+ none: {
177
+ root: string;
98
178
  };
99
179
  };
100
180
  }, {
101
181
  root: string;
102
182
  image: string;
103
183
  fallback: string;
184
+ icon: string;
104
185
  }, undefined, unknown, unknown, undefined>>;
105
186
  export type AvatarVariantProps = VariantProps<typeof avatarVariants>;
187
+ export type AvatarSize = NonNullable<AvatarVariantProps['size']>;
106
188
  export type AvatarSlots = keyof ReturnType<typeof avatarVariants>;
189
+ /** Tailwind size-4 through size-12 → (4 + index) × 4 pixels */
190
+ export declare const avatarSizePx: Record<AvatarSize, number>;
107
191
  export declare const avatarDefaults: {
108
192
  defaultVariants: import("tailwind-variants").TVDefaultVariants<{
109
193
  size: {
110
194
  '3xs': {
111
195
  root: string;
196
+ icon: string;
112
197
  };
113
198
  '2xs': {
114
199
  root: string;
200
+ icon: string;
115
201
  };
116
202
  xs: {
117
203
  root: string;
204
+ icon: string;
118
205
  };
119
206
  sm: {
120
207
  root: string;
208
+ icon: string;
121
209
  };
122
210
  md: {
123
211
  root: string;
212
+ icon: string;
124
213
  };
125
214
  lg: {
126
215
  root: string;
216
+ icon: string;
127
217
  };
128
218
  xl: {
129
219
  root: string;
220
+ icon: string;
130
221
  };
131
222
  '2xl': {
132
223
  root: string;
224
+ icon: string;
133
225
  };
134
226
  '3xl': {
135
227
  root: string;
228
+ icon: string;
229
+ };
230
+ };
231
+ rounded: {
232
+ full: {
233
+ root: string;
234
+ };
235
+ lg: {
236
+ root: string;
237
+ };
238
+ md: {
239
+ root: string;
240
+ };
241
+ sm: {
242
+ root: string;
243
+ };
244
+ none: {
245
+ root: string;
136
246
  };
137
247
  };
138
248
  }, {
139
249
  root: string;
140
250
  image: string;
141
251
  fallback: string;
252
+ icon: string;
142
253
  }, {
143
254
  size: {
144
255
  '3xs': {
145
256
  root: string;
257
+ icon: string;
146
258
  };
147
259
  '2xs': {
148
260
  root: string;
261
+ icon: string;
149
262
  };
150
263
  xs: {
151
264
  root: string;
265
+ icon: string;
152
266
  };
153
267
  sm: {
154
268
  root: string;
269
+ icon: string;
155
270
  };
156
271
  md: {
157
272
  root: string;
273
+ icon: string;
158
274
  };
159
275
  lg: {
160
276
  root: string;
277
+ icon: string;
161
278
  };
162
279
  xl: {
163
280
  root: string;
281
+ icon: string;
164
282
  };
165
283
  '2xl': {
166
284
  root: string;
285
+ icon: string;
167
286
  };
168
287
  '3xl': {
169
288
  root: string;
289
+ icon: string;
290
+ };
291
+ };
292
+ rounded: {
293
+ full: {
294
+ root: string;
295
+ };
296
+ lg: {
297
+ root: string;
298
+ };
299
+ md: {
300
+ root: string;
301
+ };
302
+ sm: {
303
+ root: string;
304
+ };
305
+ none: {
306
+ root: string;
170
307
  };
171
308
  };
172
309
  }, {
173
310
  root: string;
174
311
  image: string;
175
312
  fallback: string;
313
+ icon: string;
176
314
  }>;
177
315
  slots: Partial<Record<AvatarSlots, string>>;
178
316
  };