sv5ui 1.1.3 → 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 -0
  154. package/dist/index.js +1 -0
  155. package/package.json +2 -2
@@ -1,12 +1,57 @@
1
1
  import { tv } from 'tailwind-variants';
2
- const navButton = [
3
- 'inline-flex items-center justify-center rounded-md',
4
- 'cursor-pointer select-none transition-colors',
5
- 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
6
- 'disabled:cursor-not-allowed disabled:opacity-50',
7
- 'hover:bg-surface-container-high text-on-surface-variant'
8
- ];
9
2
  const navIcon = 'shrink-0';
3
+ export const activeVariantColorClasses = {
4
+ solid: {
5
+ primary: 'data-[selected]:bg-primary data-[selected]:text-on-primary data-[selected]:hover:bg-primary/90',
6
+ secondary: 'data-[selected]:bg-secondary data-[selected]:text-on-secondary data-[selected]:hover:bg-secondary/90',
7
+ tertiary: 'data-[selected]:bg-tertiary data-[selected]:text-on-tertiary data-[selected]:hover:bg-tertiary/90',
8
+ success: 'data-[selected]:bg-success data-[selected]:text-on-success data-[selected]:hover:bg-success/90',
9
+ warning: 'data-[selected]:bg-warning data-[selected]:text-on-warning data-[selected]:hover:bg-warning/90',
10
+ error: 'data-[selected]:bg-error data-[selected]:text-on-error data-[selected]:hover:bg-error/90',
11
+ info: 'data-[selected]:bg-info data-[selected]:text-on-info data-[selected]:hover:bg-info/90',
12
+ surface: 'data-[selected]:bg-surface-container-highest data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest/90'
13
+ },
14
+ outline: {
15
+ primary: 'data-[selected]:ring-2 data-[selected]:ring-primary data-[selected]:text-primary data-[selected]:hover:bg-primary/10',
16
+ secondary: 'data-[selected]:ring-2 data-[selected]:ring-secondary data-[selected]:text-secondary data-[selected]:hover:bg-secondary/10',
17
+ tertiary: 'data-[selected]:ring-2 data-[selected]:ring-tertiary data-[selected]:text-tertiary data-[selected]:hover:bg-tertiary/10',
18
+ success: 'data-[selected]:ring-2 data-[selected]:ring-success data-[selected]:text-success data-[selected]:hover:bg-success/10',
19
+ warning: 'data-[selected]:ring-2 data-[selected]:ring-warning data-[selected]:text-warning data-[selected]:hover:bg-warning/10',
20
+ error: 'data-[selected]:ring-2 data-[selected]:ring-error data-[selected]:text-error data-[selected]:hover:bg-error/10',
21
+ info: 'data-[selected]:ring-2 data-[selected]:ring-info data-[selected]:text-info data-[selected]:hover:bg-info/10',
22
+ surface: 'data-[selected]:ring-2 data-[selected]:ring-outline-variant data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest'
23
+ },
24
+ soft: {
25
+ primary: 'data-[selected]:bg-primary-container data-[selected]:text-on-primary-container data-[selected]:hover:bg-primary-container/90',
26
+ secondary: 'data-[selected]:bg-secondary-container data-[selected]:text-on-secondary-container data-[selected]:hover:bg-secondary-container/90',
27
+ tertiary: 'data-[selected]:bg-tertiary-container data-[selected]:text-on-tertiary-container data-[selected]:hover:bg-tertiary-container/90',
28
+ success: 'data-[selected]:bg-success-container data-[selected]:text-on-success-container data-[selected]:hover:bg-success-container/90',
29
+ warning: 'data-[selected]:bg-warning-container data-[selected]:text-on-warning-container data-[selected]:hover:bg-warning-container/90',
30
+ error: 'data-[selected]:bg-error-container data-[selected]:text-on-error-container data-[selected]:hover:bg-error-container/90',
31
+ info: 'data-[selected]:bg-info-container data-[selected]:text-on-info-container data-[selected]:hover:bg-info-container/90',
32
+ surface: 'data-[selected]:bg-surface-container-highest data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest/90'
33
+ },
34
+ subtle: {
35
+ primary: 'data-[selected]:bg-primary-container/50 data-[selected]:text-primary data-[selected]:hover:bg-primary-container/70',
36
+ secondary: 'data-[selected]:bg-secondary-container/50 data-[selected]:text-secondary data-[selected]:hover:bg-secondary-container/70',
37
+ tertiary: 'data-[selected]:bg-tertiary-container/50 data-[selected]:text-tertiary data-[selected]:hover:bg-tertiary-container/70',
38
+ success: 'data-[selected]:bg-success-container/50 data-[selected]:text-success data-[selected]:hover:bg-success-container/70',
39
+ warning: 'data-[selected]:bg-warning-container/50 data-[selected]:text-warning data-[selected]:hover:bg-warning-container/70',
40
+ error: 'data-[selected]:bg-error-container/50 data-[selected]:text-error data-[selected]:hover:bg-error-container/70',
41
+ info: 'data-[selected]:bg-info-container/50 data-[selected]:text-info data-[selected]:hover:bg-info-container/70',
42
+ surface: 'data-[selected]:bg-surface-container-highest/50 data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest/70'
43
+ },
44
+ ghost: {
45
+ primary: 'data-[selected]:text-primary data-[selected]:hover:bg-primary/10',
46
+ secondary: 'data-[selected]:text-secondary data-[selected]:hover:bg-secondary/10',
47
+ tertiary: 'data-[selected]:text-tertiary data-[selected]:hover:bg-tertiary/10',
48
+ success: 'data-[selected]:text-success data-[selected]:hover:bg-success/10',
49
+ warning: 'data-[selected]:text-warning data-[selected]:hover:bg-warning/10',
50
+ error: 'data-[selected]:text-error data-[selected]:hover:bg-error/10',
51
+ info: 'data-[selected]:text-info data-[selected]:hover:bg-info/10',
52
+ surface: 'data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest'
53
+ }
54
+ };
10
55
  export const paginationVariants = tv({
11
56
  slots: {
12
57
  root: '',
@@ -19,10 +64,10 @@ export const paginationVariants = tv({
19
64
  'hover:bg-surface-container-high text-on-surface'
20
65
  ],
21
66
  ellipsis: 'inline-flex items-center justify-center pointer-events-none text-on-surface-variant',
22
- first: navButton,
23
- prev: navButton,
24
- next: navButton,
25
- last: navButton,
67
+ first: '',
68
+ prev: '',
69
+ next: '',
70
+ last: '',
26
71
  ellipsisIcon: navIcon,
27
72
  firstIcon: navIcon,
28
73
  prevIcon: navIcon,
@@ -30,41 +75,11 @@ export const paginationVariants = tv({
30
75
  lastIcon: navIcon
31
76
  },
32
77
  variants: {
33
- activeColor: {
34
- primary: {
35
- item: 'data-[selected]:bg-primary data-[selected]:text-on-primary data-[selected]:hover:bg-primary/90'
36
- },
37
- secondary: {
38
- item: 'data-[selected]:bg-secondary data-[selected]:text-on-secondary data-[selected]:hover:bg-secondary/90'
39
- },
40
- tertiary: {
41
- item: 'data-[selected]:bg-tertiary data-[selected]:text-on-tertiary data-[selected]:hover:bg-tertiary/90'
42
- },
43
- success: {
44
- item: 'data-[selected]:bg-success data-[selected]:text-on-success data-[selected]:hover:bg-success/90'
45
- },
46
- warning: {
47
- item: 'data-[selected]:bg-warning data-[selected]:text-on-warning data-[selected]:hover:bg-warning/90'
48
- },
49
- error: {
50
- item: 'data-[selected]:bg-error data-[selected]:text-on-error data-[selected]:hover:bg-error/90'
51
- },
52
- info: {
53
- item: 'data-[selected]:bg-info data-[selected]:text-on-info data-[selected]:hover:bg-info/90'
54
- },
55
- surface: {
56
- item: 'data-[selected]:bg-surface-container-highest data-[selected]:text-on-surface data-[selected]:hover:bg-surface-container-highest/90'
57
- }
58
- },
59
78
  size: {
60
79
  xs: {
61
80
  list: 'gap-0.5',
62
81
  item: 'size-7 text-xs',
63
82
  ellipsis: 'size-7 text-xs',
64
- first: 'size-7',
65
- prev: 'size-7',
66
- next: 'size-7',
67
- last: 'size-7',
68
83
  ellipsisIcon: 'size-3',
69
84
  firstIcon: 'size-3',
70
85
  prevIcon: 'size-3',
@@ -75,10 +90,6 @@ export const paginationVariants = tv({
75
90
  list: 'gap-0.5',
76
91
  item: 'size-8 text-xs',
77
92
  ellipsis: 'size-8 text-xs',
78
- first: 'size-8',
79
- prev: 'size-8',
80
- next: 'size-8',
81
- last: 'size-8',
82
93
  ellipsisIcon: 'size-3.5',
83
94
  firstIcon: 'size-3.5',
84
95
  prevIcon: 'size-3.5',
@@ -89,10 +100,6 @@ export const paginationVariants = tv({
89
100
  list: 'gap-1',
90
101
  item: 'size-9 text-sm',
91
102
  ellipsis: 'size-9 text-sm',
92
- first: 'size-9',
93
- prev: 'size-9',
94
- next: 'size-9',
95
- last: 'size-9',
96
103
  ellipsisIcon: 'size-4',
97
104
  firstIcon: 'size-4',
98
105
  prevIcon: 'size-4',
@@ -103,10 +110,6 @@ export const paginationVariants = tv({
103
110
  list: 'gap-1',
104
111
  item: 'size-10 text-sm',
105
112
  ellipsis: 'size-10 text-sm',
106
- first: 'size-10',
107
- prev: 'size-10',
108
- next: 'size-10',
109
- last: 'size-10',
110
113
  ellipsisIcon: 'size-5',
111
114
  firstIcon: 'size-5',
112
115
  prevIcon: 'size-5',
@@ -117,10 +120,6 @@ export const paginationVariants = tv({
117
120
  list: 'gap-1.5',
118
121
  item: 'size-11 text-base',
119
122
  ellipsis: 'size-11 text-base',
120
- first: 'size-11',
121
- prev: 'size-11',
122
- next: 'size-11',
123
- last: 'size-11',
124
123
  ellipsisIcon: 'size-5',
125
124
  firstIcon: 'size-5',
126
125
  prevIcon: 'size-5',
@@ -135,11 +134,16 @@ export const paginationVariants = tv({
135
134
  }
136
135
  },
137
136
  defaultVariants: {
138
- activeColor: 'primary',
139
137
  size: 'md'
140
138
  }
141
139
  });
142
140
  export const paginationDefaults = {
143
- defaultVariants: paginationVariants.defaultVariants,
141
+ defaultVariants: {
142
+ ...paginationVariants.defaultVariants,
143
+ variant: 'ghost',
144
+ color: 'surface',
145
+ activeColor: 'primary',
146
+ activeVariant: 'solid'
147
+ },
144
148
  slots: {}
145
149
  };
@@ -12,10 +12,11 @@
12
12
  const config = getComponentConfig('popover', popoverDefaults)
13
13
 
14
14
  let {
15
+ ref = $bindable(null),
15
16
  open = $bindable(false),
16
17
  onOpenChange,
17
18
  onOpenChangeComplete,
18
- side = config.defaultVariants.side ?? 'bottom',
19
+ side = 'bottom',
19
20
  sideOffset = 8,
20
21
  align = 'center',
21
22
  alignOffset = 0,
@@ -38,12 +39,11 @@
38
39
  ui,
39
40
  class: className,
40
41
  children,
41
- content: contentSlot
42
+ content: contentSlot,
43
+ ...restProps
42
44
  }: Props = $props()
43
45
 
44
- const showArrow = $derived(!!arrow)
45
-
46
- const variantSlots = $derived(popoverVariants({ side, transition }))
46
+ const variantSlots = $derived(popoverVariants({ transition }))
47
47
  const classes = $derived({
48
48
  content: variantSlots.content({ class: [config.slots.content, ui?.content] }),
49
49
  arrow: variantSlots.arrow({ class: [config.slots.arrow, ui?.arrow] })
@@ -61,15 +61,11 @@
61
61
  function close() {
62
62
  open = false
63
63
  }
64
-
65
- function handleOpenChange(value: boolean) {
66
- open = value
67
- onOpenChange?.(value)
68
- }
69
64
  </script>
70
65
 
71
66
  {#snippet popoverContentEl()}
72
67
  <Popover.Content
68
+ bind:ref
73
69
  {side}
74
70
  {sideOffset}
75
71
  {align}
@@ -89,12 +85,13 @@
89
85
  {onInteractOutside}
90
86
  {forceMount}
91
87
  class={[classes.content, !children ? className : undefined]}
88
+ {...restProps}
92
89
  >
93
90
  {#if contentSlot}
94
91
  {@render contentSlot({ open, close })}
95
92
  {/if}
96
93
 
97
- {#if showArrow}
94
+ {#if arrow}
98
95
  <Popover.Arrow
99
96
  width={arrowProps.width}
100
97
  height={arrowProps.height}
@@ -104,7 +101,7 @@
104
101
  </Popover.Content>
105
102
  {/snippet}
106
103
 
107
- <Popover.Root bind:open onOpenChange={handleOpenChange} {onOpenChangeComplete}>
104
+ <Popover.Root bind:open {onOpenChange} {onOpenChangeComplete}>
108
105
  {#if children}
109
106
  <Popover.Trigger>
110
107
  {#snippet child({ props })}
@@ -1,6 +1,6 @@
1
1
  import type { PopoverProps } from './popover.types.js';
2
2
  export type Props = PopoverProps;
3
3
  import { Popover } from 'bits-ui';
4
- declare const Popover: import("svelte").Component<PopoverProps, {}, "open">;
4
+ declare const Popover: import("svelte").Component<PopoverProps, {}, "ref" | "open">;
5
5
  type Popover = ReturnType<typeof Popover>;
6
6
  export default Popover;
@@ -5,6 +5,10 @@ import type { PopoverRootPropsWithoutHTML, PopoverContentPropsWithoutHTML, Popov
5
5
  type RootProps = Pick<PopoverRootPropsWithoutHTML, 'open' | 'onOpenChange' | 'onOpenChangeComplete'>;
6
6
  type ContentProps = Pick<PopoverContentPropsWithoutHTML, 'side' | 'sideOffset' | 'align' | 'alignOffset' | 'avoidCollisions' | 'collisionBoundary' | 'collisionPadding' | 'sticky' | 'hideWhenDetached' | 'trapFocus' | 'preventScroll' | 'onOpenAutoFocus' | 'onCloseAutoFocus' | 'onEscapeKeydown' | 'onInteractOutside' | 'forceMount'>;
7
7
  export interface PopoverProps extends RootProps, ContentProps {
8
+ /**
9
+ * Bindable reference to the content DOM element.
10
+ */
11
+ ref?: HTMLElement | null;
8
12
  /**
9
13
  * Display an arrow alongside the popover.
10
14
  * Can be a boolean or arrow props for customization.
@@ -1,68 +1,26 @@
1
1
  import { type VariantProps } from 'tailwind-variants';
2
2
  export declare const popoverVariants: import("tailwind-variants").TVReturnType<{
3
- side: {
4
- top: {
5
- content: string;
6
- };
7
- right: {
8
- content: string;
9
- };
10
- bottom: {
11
- content: string;
12
- };
13
- left: {
14
- content: string;
15
- };
16
- };
17
3
  transition: {
18
4
  true: {
19
- content: string;
5
+ content: string[];
20
6
  };
21
7
  };
22
8
  }, {
23
9
  content: string[];
24
10
  arrow: string;
25
11
  }, undefined, {
26
- side: {
27
- top: {
28
- content: string;
29
- };
30
- right: {
31
- content: string;
32
- };
33
- bottom: {
34
- content: string;
35
- };
36
- left: {
37
- content: string;
38
- };
39
- };
40
12
  transition: {
41
13
  true: {
42
- content: string;
14
+ content: string[];
43
15
  };
44
16
  };
45
17
  }, {
46
18
  content: string[];
47
19
  arrow: string;
48
20
  }, import("tailwind-variants").TVReturnType<{
49
- side: {
50
- top: {
51
- content: string;
52
- };
53
- right: {
54
- content: string;
55
- };
56
- bottom: {
57
- content: string;
58
- };
59
- left: {
60
- content: string;
61
- };
62
- };
63
21
  transition: {
64
22
  true: {
65
- content: string;
23
+ content: string[];
66
24
  };
67
25
  };
68
26
  }, {
@@ -73,46 +31,18 @@ export type PopoverVariantProps = VariantProps<typeof popoverVariants>;
73
31
  export type PopoverSlots = keyof ReturnType<typeof popoverVariants>;
74
32
  export declare const popoverDefaults: {
75
33
  defaultVariants: import("tailwind-variants").TVDefaultVariants<{
76
- side: {
77
- top: {
78
- content: string;
79
- };
80
- right: {
81
- content: string;
82
- };
83
- bottom: {
84
- content: string;
85
- };
86
- left: {
87
- content: string;
88
- };
89
- };
90
34
  transition: {
91
35
  true: {
92
- content: string;
36
+ content: string[];
93
37
  };
94
38
  };
95
39
  }, {
96
40
  content: string[];
97
41
  arrow: string;
98
42
  }, {
99
- side: {
100
- top: {
101
- content: string;
102
- };
103
- right: {
104
- content: string;
105
- };
106
- bottom: {
107
- content: string;
108
- };
109
- left: {
110
- content: string;
111
- };
112
- };
113
43
  transition: {
114
44
  true: {
115
- content: string;
45
+ content: string[];
116
46
  };
117
47
  };
118
48
  }, {
@@ -10,28 +10,18 @@ export const popoverVariants = tv({
10
10
  arrow: ''
11
11
  },
12
12
  variants: {
13
- side: {
14
- top: {
15
- content: 'data-[state=open]:animate-[slide-in-from-bottom_150ms_ease-out] data-[state=closed]:animate-[slide-in-from-top_100ms_ease-in_reverse]'
16
- },
17
- right: {
18
- content: 'data-[state=open]:animate-[slide-in-from-left_150ms_ease-out] data-[state=closed]:animate-[slide-in-from-right_100ms_ease-in_reverse]'
19
- },
20
- bottom: {
21
- content: 'data-[state=open]:animate-[slide-in-from-top_150ms_ease-out] data-[state=closed]:animate-[slide-in-from-bottom_100ms_ease-in_reverse]'
22
- },
23
- left: {
24
- content: 'data-[state=open]:animate-[slide-in-from-right_150ms_ease-out] data-[state=closed]:animate-[slide-in-from-left_100ms_ease-in_reverse]'
25
- }
26
- },
27
13
  transition: {
28
14
  true: {
29
- content: 'data-[state=open]:animate-[fade-in_150ms_ease-out,scale-in_150ms_ease-out] data-[state=closed]:animate-[fade-out_100ms_ease-in,scale-out_100ms_ease-in]'
15
+ content: [
16
+ 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
17
+ 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
18
+ 'data-[side=top]:slide-in-from-bottom-2 data-[side=right]:slide-in-from-left-2',
19
+ 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2'
20
+ ]
30
21
  }
31
22
  }
32
23
  },
33
24
  defaultVariants: {
34
- side: 'bottom',
35
25
  transition: true
36
26
  }
37
27
  });
@@ -24,30 +24,51 @@
24
24
  ui,
25
25
  class: className,
26
26
  statusSlot,
27
+ stepSlot,
27
28
  ...restProps
28
29
  }: Props = $props()
29
30
 
30
- const maxValue = $derived(Array.isArray(max) ? max.length - 1 : max)
31
- const percent = $derived(
32
- value !== null ? Math.round((Math.min(value, maxValue) / maxValue) * 100) : 0
33
- )
34
31
  const isIndeterminate = $derived(value === null)
35
- const state = $derived(isIndeterminate ? 'indeterminate' : 'determinate')
32
+ const hasSteps = $derived(Array.isArray(max))
33
+
34
+ const realMax = $derived.by(() => {
35
+ if (isIndeterminate || !max) return undefined
36
+ if (Array.isArray(max)) return max.length - 1
37
+ return Number(max)
38
+ })
39
+
40
+ const percent = $derived.by(() => {
41
+ if (isIndeterminate) return undefined
42
+ if (value! < 0) return 0
43
+ if (value! > (realMax ?? 100)) return 100
44
+ return Math.round((value! / (realMax ?? 100)) * 100)
45
+ })
36
46
 
37
47
  const indicatorStyle = $derived.by(() => {
38
- if (isIndeterminate) return ''
48
+ if (percent === undefined) return ''
39
49
  const offset = 100 - percent
40
- if (orientation === 'horizontal') {
41
- return inverted
42
- ? `transform: translateX(${offset}%);`
43
- : `transform: translateX(-${offset}%);`
50
+ if (orientation === 'vertical') {
51
+ return `transform: translateY(${inverted ? '' : '-'}${offset}%);`
44
52
  }
45
- // Vertical: fill from bottom to top (positive Y = down)
46
- return inverted
47
- ? `transform: translateY(-${offset}%);`
48
- : `transform: translateY(${offset}%);`
53
+ return `transform: translateX(${inverted ? '' : '-'}${offset}%);`
49
54
  })
50
55
 
56
+ const statusStyle = $derived.by(() => {
57
+ const val = `${Math.max(percent ?? 0, 0)}%`
58
+ return orientation === 'vertical' ? `height: ${val};` : `width: ${val};`
59
+ })
60
+
61
+ function stepVariant(index: number): 'active' | 'first' | 'last' | 'other' {
62
+ const isActive = index === Number(value)
63
+ const isFirst = index === 0
64
+ const isLast = index === realMax
65
+
66
+ if (isActive && !isFirst) return 'active'
67
+ if (isFirst && isActive) return 'first'
68
+ if (isLast && isActive) return 'last'
69
+ return 'other'
70
+ }
71
+
51
72
  const classes = $derived.by(() => {
52
73
  const slots = progressVariants({ animation, color, size, orientation, inverted })
53
74
  return {
@@ -55,24 +76,25 @@
55
76
  base: slots.base({ class: [config.slots.base, ui?.base] }),
56
77
  indicator: slots.indicator({ class: [config.slots.indicator, ui?.indicator] }),
57
78
  status: slots.status({ class: [config.slots.status, ui?.status] }),
58
- stepsBase: slots.steps({ class: [config.slots.steps, ui?.steps] }),
59
- stepActive: progressVariants({ size, step: 'active' }).steps(),
60
- stepOther: progressVariants({ size, step: 'other' }).steps()
79
+ steps: slots.steps({ class: [config.slots.steps, ui?.steps] })
61
80
  }
62
81
  })
82
+
83
+ const state = $derived(isIndeterminate ? 'indeterminate' : 'determinate')
63
84
  </script>
64
85
 
65
86
  <Progress.Root
66
87
  bind:ref
67
88
  value={value ?? undefined}
68
- max={maxValue}
89
+ max={realMax}
69
90
  class={classes.root}
91
+ data-orientation={orientation}
70
92
  {...restProps}
71
93
  >
72
- {#if status && !Array.isArray(max)}
73
- <div class={classes.status} style={isIndeterminate ? '' : `width: ${percent}%;`}>
94
+ {#if !isIndeterminate && status}
95
+ <div class={classes.status} style={statusStyle}>
74
96
  {#if statusSlot}
75
- {@render statusSlot({ percent })}
97
+ {@render statusSlot({ percent: percent ?? 0 })}
76
98
  {:else}
77
99
  {percent}%
78
100
  {/if}
@@ -83,16 +105,22 @@
83
105
  <div class={classes.indicator} data-state={state} style={indicatorStyle}></div>
84
106
  </div>
85
107
 
86
- {#if Array.isArray(max)}
87
- <div class={classes.stepsBase}>
108
+ {#if hasSteps && Array.isArray(max)}
109
+ <div class={classes.steps}>
88
110
  {#each max as step, index (index)}
89
- <span
90
- class={value !== null && index <= value
91
- ? classes.stepActive
92
- : classes.stepOther}
93
- >
94
- {step}
95
- </span>
111
+ {@const stepClass = progressVariants({
112
+ size,
113
+ orientation,
114
+ inverted,
115
+ step: stepVariant(index)
116
+ }).step({ class: [config.slots.step, ui?.step] })}
117
+ <div class={stepClass}>
118
+ {#if stepSlot}
119
+ {@render stepSlot({ step, index })}
120
+ {:else}
121
+ {step}
122
+ {/if}
123
+ </div>
96
124
  {/each}
97
125
  </div>
98
126
  {/if}
@@ -46,7 +46,7 @@ export type ProgressProps = Omit<Progress.RootProps, 'max'> & {
46
46
  animation?: NonNullable<ProgressVariantProps['animation']>;
47
47
  /**
48
48
  * Override styles for specific progress slots.
49
- * Available slots: root, base, indicator, status, steps.
49
+ * Available slots: root, base, indicator, status, steps, step.
50
50
  */
51
51
  ui?: Partial<Record<ProgressSlots, ClassNameValue>>;
52
52
  /**
@@ -60,4 +60,12 @@ export type ProgressProps = Omit<Progress.RootProps, 'max'> & {
60
60
  statusSlot?: Snippet<[{
61
61
  percent: number;
62
62
  }]>;
63
+ /**
64
+ * Custom content rendered for each step label.
65
+ * Takes precedence over the default step text.
66
+ */
67
+ stepSlot?: Snippet<[{
68
+ step: string;
69
+ index: number;
70
+ }]>;
63
71
  };