@invopop/popui 0.1.3 → 0.1.4-beta.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 (180) hide show
  1. package/dist/AlertDialog.svelte +10 -11
  2. package/dist/BaseButton.svelte +29 -104
  3. package/dist/BaseCard.svelte +35 -30
  4. package/dist/BaseCounter.svelte +11 -8
  5. package/dist/BaseDropdown.svelte +5 -5
  6. package/dist/BaseFlag.svelte +5 -3
  7. package/dist/BaseFlag.svelte.d.ts +1 -0
  8. package/dist/BaseTable.svelte +16 -16
  9. package/dist/BaseTable.svelte.d.ts +1 -1
  10. package/dist/BaseTableActions.svelte +4 -6
  11. package/dist/BaseTableCellContent.svelte +9 -21
  12. package/dist/BaseTableCheckbox.svelte +9 -11
  13. package/dist/BaseTableHeaderContent.svelte +4 -4
  14. package/dist/BaseTableHeaderOrderBy.svelte +23 -12
  15. package/dist/BaseTableRow.svelte +12 -10
  16. package/dist/Breadcrumb.svelte +40 -0
  17. package/dist/Breadcrumb.svelte.d.ts +4 -0
  18. package/dist/Breadcrumbs.svelte +5 -30
  19. package/dist/ButtonFile.svelte +40 -30
  20. package/dist/ButtonUuidCopy.svelte +6 -3
  21. package/dist/CardCheckbox.svelte +45 -32
  22. package/dist/CardCheckbox.svelte.d.ts +1 -1
  23. package/dist/CardRelation.svelte +12 -13
  24. package/dist/CompanySelector.svelte +35 -7
  25. package/dist/CounterWidget.svelte +52 -0
  26. package/dist/CounterWidget.svelte.d.ts +4 -0
  27. package/dist/DataListItem.svelte +14 -10
  28. package/dist/DatePicker.svelte +20 -17
  29. package/dist/DrawerContext.svelte +207 -15
  30. package/dist/DrawerContextItem.svelte +50 -50
  31. package/dist/DrawerContextSeparator.svelte +1 -1
  32. package/dist/DropdownSelect.svelte +81 -22
  33. package/dist/DropdownSelectGroup.svelte +15 -0
  34. package/dist/DropdownSelectGroup.svelte.d.ts +7 -0
  35. package/dist/EmptyState.svelte +42 -0
  36. package/dist/EmptyState.svelte.d.ts +4 -0
  37. package/dist/FeedEvents.svelte +9 -5
  38. package/dist/FeedIconEvent.svelte +2 -2
  39. package/dist/FeedIconStatus.svelte +4 -4
  40. package/dist/FeedItem.svelte +10 -11
  41. package/dist/FeedItemDetail.svelte +32 -6
  42. package/dist/FeedViewer.svelte +1 -1
  43. package/dist/GlobalSearch.svelte +13 -12
  44. package/dist/InputCheckbox.svelte +2 -5
  45. package/dist/InputError.svelte +4 -9
  46. package/dist/InputLabel.svelte +3 -1
  47. package/dist/InputRadio.svelte +29 -13
  48. package/dist/InputRadio.svelte.d.ts +1 -1
  49. package/dist/InputSearch.svelte +8 -8
  50. package/dist/InputSelect.svelte +32 -31
  51. package/dist/InputText.svelte +32 -24
  52. package/dist/InputTextarea.svelte +25 -19
  53. package/dist/InputToggle.svelte +24 -18
  54. package/dist/MenuItem.svelte +16 -11
  55. package/dist/MenuItemCollapsible.svelte +7 -7
  56. package/dist/Notification.svelte +60 -25
  57. package/dist/ProfileAvatar.svelte +43 -14
  58. package/dist/ProgressBar.svelte +42 -0
  59. package/dist/ProgressBar.svelte.d.ts +4 -0
  60. package/dist/ProgressBarCircle.svelte +46 -0
  61. package/dist/ProgressBarCircle.svelte.d.ts +4 -0
  62. package/dist/SeparatorHorizontal.svelte +2 -2
  63. package/dist/ShortcutWrapper.svelte +14 -5
  64. package/dist/StatusLabel.svelte +4 -5
  65. package/dist/StepIconList.svelte +11 -9
  66. package/dist/TagBeta.svelte +26 -14
  67. package/dist/TagProgress.svelte +28 -0
  68. package/dist/TagProgress.svelte.d.ts +4 -0
  69. package/dist/TagSearch.svelte +4 -4
  70. package/dist/TagStatus.svelte +32 -34
  71. package/dist/TitleMain.svelte +1 -1
  72. package/dist/TitleSection.svelte +1 -1
  73. package/dist/UuidCopy.svelte +4 -4
  74. package/dist/alert-dialog/alert-dialog-action.svelte +8 -4
  75. package/dist/alert-dialog/alert-dialog-cancel.svelte +7 -3
  76. package/dist/alert-dialog/alert-dialog-content.svelte +1 -1
  77. package/dist/alert-dialog/alert-dialog-description.svelte +1 -1
  78. package/dist/alert-dialog/alert-dialog-footer.svelte +1 -1
  79. package/dist/alert-dialog/alert-dialog-header.svelte +1 -1
  80. package/dist/alert-dialog/alert-dialog-overlay.svelte +1 -1
  81. package/dist/alert-dialog/alert-dialog-title.svelte +1 -1
  82. package/dist/alert-dialog/alert-dialog-trigger.svelte +4 -2
  83. package/dist/button/button.svelte +224 -24
  84. package/dist/button/button.svelte.d.ts +77 -26
  85. package/dist/clickOutside.d.ts +5 -2
  86. package/dist/clickOutside.js +9 -3
  87. package/dist/data-table/cells/boolean-cell.svelte +16 -0
  88. package/dist/data-table/cells/boolean-cell.svelte.d.ts +8 -0
  89. package/dist/data-table/cells/currency-cell.svelte +10 -0
  90. package/dist/data-table/cells/currency-cell.svelte.d.ts +8 -0
  91. package/dist/data-table/cells/date-cell.svelte +10 -0
  92. package/dist/data-table/cells/date-cell.svelte.d.ts +8 -0
  93. package/dist/data-table/cells/tag-cell.svelte +12 -0
  94. package/dist/data-table/cells/tag-cell.svelte.d.ts +8 -0
  95. package/dist/data-table/cells/text-cell.svelte +10 -0
  96. package/dist/data-table/cells/text-cell.svelte.d.ts +8 -0
  97. package/dist/data-table/column-definitions.d.ts +12 -0
  98. package/dist/data-table/column-definitions.js +42 -0
  99. package/dist/data-table/column-sizing-helpers.d.ts +6 -0
  100. package/dist/data-table/column-sizing-helpers.js +24 -0
  101. package/dist/data-table/create-columns.d.ts +3 -0
  102. package/dist/data-table/create-columns.js +50 -0
  103. package/dist/data-table/data-table-pagination.svelte +173 -0
  104. package/dist/data-table/data-table-pagination.svelte.d.ts +4 -0
  105. package/dist/data-table/data-table-svelte.svelte.d.ts +40 -0
  106. package/dist/data-table/data-table-svelte.svelte.js +111 -0
  107. package/dist/data-table/data-table-toolbar.svelte +16 -0
  108. package/dist/data-table/data-table-toolbar.svelte.d.ts +29 -0
  109. package/dist/data-table/data-table-types.d.ts +75 -0
  110. package/dist/data-table/data-table-types.js +1 -0
  111. package/dist/data-table/data-table-view-options.svelte +88 -0
  112. package/dist/data-table/data-table-view-options.svelte.d.ts +27 -0
  113. package/dist/data-table/data-table.svelte +323 -0
  114. package/dist/data-table/data-table.svelte.d.ts +25 -0
  115. package/dist/data-table/flex-render.svelte +40 -0
  116. package/dist/data-table/flex-render.svelte.d.ts +33 -0
  117. package/dist/data-table/index.d.ts +13 -0
  118. package/dist/data-table/index.js +13 -0
  119. package/dist/data-table/render-helpers.d.ts +90 -0
  120. package/dist/data-table/render-helpers.js +99 -0
  121. package/dist/data-table/table-setup.d.ts +36 -0
  122. package/dist/data-table/table-setup.js +130 -0
  123. package/dist/data-table/table-styles.d.ts +17 -0
  124. package/dist/data-table/table-styles.js +49 -0
  125. package/dist/helpers.d.ts +1 -0
  126. package/dist/helpers.js +3 -0
  127. package/dist/index.d.ts +16 -7
  128. package/dist/index.js +33 -14
  129. package/dist/range-calendar/range-calendar-cell.svelte +1 -1
  130. package/dist/range-calendar/range-calendar-day.svelte +11 -12
  131. package/dist/range-calendar/range-calendar-head-cell.svelte +1 -1
  132. package/dist/range-calendar/range-calendar-header.svelte +1 -1
  133. package/dist/range-calendar/range-calendar-month-select.svelte +1 -1
  134. package/dist/range-calendar/range-calendar-next-button.svelte +3 -3
  135. package/dist/range-calendar/range-calendar-prev-button.svelte +3 -3
  136. package/dist/range-calendar/range-calendar.svelte +1 -1
  137. package/dist/sonner/index.d.ts +1 -0
  138. package/dist/sonner/index.js +1 -0
  139. package/dist/sonner/sonner.svelte +44 -0
  140. package/dist/sonner/sonner.svelte.d.ts +4 -0
  141. package/dist/svg/CheckBadge.svelte +18 -0
  142. package/dist/svg/CheckBadge.svelte.d.ts +26 -0
  143. package/dist/svg/IconDelivery.svelte +86 -0
  144. package/dist/svg/IconDelivery.svelte.d.ts +20 -0
  145. package/dist/svg/IconEmpty.svelte +113 -121
  146. package/dist/svg/IconOrder.svelte +81 -0
  147. package/dist/svg/IconOrder.svelte.d.ts +20 -0
  148. package/dist/svg/IconPayment.svelte +86 -0
  149. package/dist/svg/IconPayment.svelte.d.ts +20 -0
  150. package/dist/table/table-body.svelte +5 -1
  151. package/dist/table/table-cell.svelte +4 -2
  152. package/dist/table/table-footer.svelte +1 -1
  153. package/dist/table/table-head.svelte +4 -2
  154. package/dist/table/table-header.svelte +1 -1
  155. package/dist/table/table-row.svelte +4 -2
  156. package/dist/table/table.svelte +2 -2
  157. package/dist/tabs/tabs-list.svelte +8 -2
  158. package/dist/tabs/tabs-list.svelte.d.ts +4 -1
  159. package/dist/tabs/tabs-trigger.svelte +5 -3
  160. package/dist/tabs/tabs-trigger.svelte.d.ts +4 -1
  161. package/dist/tailwind.theme.css +998 -0
  162. package/dist/tooltip/tooltip-content.svelte +2 -2
  163. package/dist/types.d.ts +76 -50
  164. package/package.json +20 -10
  165. package/dist/CounterWorkflow.svelte +0 -19
  166. package/dist/CounterWorkflow.svelte.d.ts +0 -4
  167. package/dist/DrawerContextWorkspace.svelte +0 -126
  168. package/dist/DrawerContextWorkspace.svelte.d.ts +0 -4
  169. package/dist/EmptyStateIcon.svelte +0 -52
  170. package/dist/EmptyStateIcon.svelte.d.ts +0 -4
  171. package/dist/EmptyStateIllustration.svelte +0 -66
  172. package/dist/EmptyStateIllustration.svelte.d.ts +0 -4
  173. package/dist/FormLayoutModal.svelte +0 -14
  174. package/dist/FormLayoutModal.svelte.d.ts +0 -4
  175. package/dist/ProfileSelector.svelte +0 -41
  176. package/dist/ProfileSelector.svelte.d.ts +0 -4
  177. package/dist/SectionLayout.svelte +0 -13
  178. package/dist/SectionLayout.svelte.d.ts +0 -4
  179. package/dist/tw.theme.d.ts +0 -171
  180. package/dist/tw.theme.js +0 -188
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import clsx from 'clsx'
3
+ import ProgressBarCircle from './ProgressBarCircle.svelte'
4
+ import type { TagProgressProps } from './types'
5
+
6
+ let { progress, variant = 'default' }: TagProgressProps = $props()
7
+
8
+ let percentage = $derived(Math.round(progress * 100))
9
+
10
+ let containerStyles = $derived(
11
+ clsx('inline-flex items-center gap-1 rounded-full overflow-hidden pl-0.5 pr-1 py-0.5', {
12
+ 'bg-background-selected-inverse': variant === 'dark',
13
+ 'bg-background-default-secondary': variant === 'default'
14
+ })
15
+ )
16
+
17
+ let textStyles = $derived(
18
+ clsx('text-sm font-medium leading-4 whitespace-nowrap', {
19
+ 'text-foreground-inverse-default': variant === 'dark',
20
+ 'text-foreground-default-default': variant === 'default'
21
+ })
22
+ )
23
+ </script>
24
+
25
+ <div class={containerStyles}>
26
+ <ProgressBarCircle {progress} size={16} {variant} />
27
+ <span class={textStyles}>{percentage}%</span>
28
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { TagProgressProps } from './types';
2
+ declare const TagProgress: import("svelte").Component<TagProgressProps, {}, "">;
3
+ type TagProgress = ReturnType<typeof TagProgress>;
4
+ export default TagProgress;
@@ -20,15 +20,15 @@
20
20
  <span
21
21
  class:pl-2={icon}
22
22
  class:pl-3={!icon}
23
- class="border rounded pr-1.5 text-sm inline-flex items-center border-workspace-accent-100 bg-workspace-accent-50"
23
+ class="border rounded pr-1.5 text-sm inline-flex items-center border-border-selected bg-background-selected"
24
24
  >
25
25
  {#if resolvedIcon}
26
- <Icon src={resolvedIcon} theme={iconTheme} class="h-4 w-4 mr-1 text-workspace-accent" />
26
+ <Icon src={resolvedIcon} theme={iconTheme} class="h-4 w-4 mr-1 text-foreground-selected" />
27
27
  {/if}
28
- <span class="py-1 pr-2 text-workspace-accent tracking-normal">{label}</span>
28
+ <span class="py-1 pr-2 text-foreground-selected tracking-normal">{label}</span>
29
29
  <button
30
30
  aria-label="Clear"
31
- class="py-1 border-l border-workspace-accent-100 pl-1 text-neutral-500"
31
+ class="cursor-pointer py-1 border-l border-border-selected pl-1 text-foreground-default-secondary"
32
32
  onclick={handleClear}
33
33
  >
34
34
  <svg
@@ -5,50 +5,48 @@
5
5
  let { label = '', status = 'grey', dot = false }: TagStatusProps = $props()
6
6
 
7
7
  let tagStyles = $derived(
8
- clsx({
9
- 'bg-positive-100 text-positive-500': status === 'green',
10
- 'border border-positive-200': status === 'green' && dot,
11
- 'bg-yellow-100 text-yellow-500': status === 'yellow',
12
- 'border border-yellow-200': status === 'yellow' && dot,
13
- 'bg-danger-100 text-danger-500': status === 'red',
14
- 'border border-danger-200': status === 'red' && dot,
15
- 'bg-warning-100 text-warning-500': status === 'orange',
16
- 'border border-warning-200': status === 'orange' && dot,
17
- 'bg-blue-100 text-blue-500': status === 'blue',
18
- 'border border-blue-200': status === 'blue' && dot,
19
- 'bg-purple-100 text-purple-500': status === 'purple',
20
- 'border border-purple-200': status === 'purple' && dot,
21
- 'border border-dashed border-neutral-200 text-neutral-400': status === 'empty',
22
- 'bg-neutral-100 text-neutral-500': status === 'grey',
23
- 'border border-neutral-200': status === 'grey' && dot,
24
- 'pl-1.5 pr-[5px] py-0.5': dot && label,
25
- 'p-0.5': dot && !label,
26
- 'px-1 py-0.5': !dot
8
+ clsx('rounded inline-flex items-center text-sm font-medium gap-1 box-border leading-4 py-0.5', {
9
+ 'bg-background-status-paid text-foreground-status-paid': status === 'green',
10
+ 'bg-background-status-processing text-foreground-status-processing': status === 'yellow',
11
+ 'bg-background-status-error text-foreground-status-error': status === 'red',
12
+ 'bg-background-status-draft text-foreground-status-draft': status === 'orange',
13
+ 'bg-background-status-sent text-foreground-status-sent': status === 'blue',
14
+ 'bg-background-status-registered text-foreground-status-registered': status === 'purple',
15
+ 'bg-background-status-completed text-foreground-status-completed': status === 'teal',
16
+ 'bg-background-status-received text-foreground-status-received': status === 'steelBlue',
17
+ 'bg-background-status-rejected text-foreground-status-rejected': status === 'crimson',
18
+ 'bg-sherwood-alpha-10 text-sherwood-60': status === 'olive',
19
+ 'bg-background-status-void text-foreground-default-secondary': status === 'grey',
20
+ 'shadow-avatar text-foreground-default-secondary': status === 'empty',
21
+ 'px-1.5': dot,
22
+ 'p-0!': dot && !label,
23
+ 'px-1': !dot
27
24
  })
28
25
  )
29
26
 
30
27
  let dotStyles = $derived(
31
- clsx({
32
- 'bg-positive-500': status === 'green',
33
- 'bg-yellow-500': status === 'yellow',
34
- 'bg-danger-500': status === 'red',
35
- 'bg-warning-500': status === 'orange',
36
- 'bg-blue-500': status === 'blue',
37
- 'bg-purple-500': status === 'purple',
38
- 'bg-neutral-300': status === 'empty',
39
- 'bg-neutral-500': status === 'grey'
28
+ clsx('rounded-[2px] shrink-0', {
29
+ 'bg-icon-status-paid': status === 'green',
30
+ 'bg-icon-status-processing': status === 'yellow',
31
+ 'bg-icon-status-error': status === 'red',
32
+ 'bg-icon-status-draft': status === 'orange',
33
+ 'bg-icon-status-sent': status === 'blue',
34
+ 'bg-icon-status-registered': status === 'purple',
35
+ 'bg-icon-status-completed': status === 'teal',
36
+ 'bg-icon-status-received': status === 'steelBlue',
37
+ 'bg-icon-status-rejected': status === 'crimson',
38
+ 'bg-sherwood-50': status === 'olive',
39
+ 'bg-icon-status-void': status === 'grey',
40
+ 'bg-icon-default-secondary': status === 'empty'
40
41
  })
41
42
  )
42
43
  </script>
43
44
 
44
- <span
45
- class:h-5={Boolean(label)}
46
- class="{tagStyles} rounded text-sm inline-flex items-center font-medium gap-1 box-border"
47
- >
45
+ <span class={tagStyles}>
48
46
  {#if dot}
49
- <span class="{dotStyles} w-2 h-2 rounded-sm"></span>
47
+ <span class="{dotStyles} size-2"></span>
50
48
  {/if}
51
49
  {#if label}
52
- <span>{label}</span>
50
+ <span class="whitespace-nowrap">{label}</span>
53
51
  {/if}
54
52
  </span>
@@ -4,7 +4,7 @@
4
4
  let { title = '', children }: TitleMainProps = $props()
5
5
  </script>
6
6
 
7
- <h1 class="text-neutral-800 font-medium text-lg font-sans tracking-tightest">
7
+ <h1 class="text-foreground font-medium text-lg">
8
8
  {#if children}
9
9
  {@render children()}
10
10
  {:else}
@@ -4,7 +4,7 @@
4
4
  let { title = '', children }: TitleSectionProps = $props()
5
5
  </script>
6
6
 
7
- <h1 class="text-neutral-800 font-medium text-lg font-sans tracking-tighter">
7
+ <h1 class="text-foreground font-medium text-lg">
8
8
  {#if children}
9
9
  {@render children()}
10
10
  {:else}
@@ -35,11 +35,11 @@
35
35
  'justify-end': rightAlign,
36
36
  'text-sm': small,
37
37
  'text-base': !small,
38
- 'text-neutral-800': dark,
39
- 'text-neutral-500': !dark,
38
+ 'text-foreground': dark,
39
+ 'text-foreground-default-secondary': !dark,
40
40
  'justify-between': !compact,
41
41
  'w-full': full,
42
- 'border border-neutral-800/10 rounded-md pl-2.5 pr-2 py-[5px]': !full
42
+ 'border border-border rounded-md pl-2.5 pr-2 py-[5px]': !full
43
43
  })
44
44
  )
45
45
 
@@ -65,6 +65,6 @@
65
65
  {formattedUuid}
66
66
  </button>
67
67
  <button class="p-1 cursor-pointer" onclick={handleIconClick}>
68
- <Icon src={link ? ExternalLink : Duplicate} class="w-4 h-4 text-neutral-500" />
68
+ <Icon src={link ? ExternalLink : Duplicate} class="w-4 h-4 text-foreground-default-secondary" />
69
69
  </button>
70
70
  </div>
@@ -6,16 +6,20 @@
6
6
  ref = $bindable(null),
7
7
  class: className,
8
8
  destructive = false,
9
- children
9
+ children,
10
+ ...restProps
10
11
  }: AlertDialogPrimitive.ActionProps & { destructive: boolean } = $props()
11
12
 
12
- let variant = $derived((destructive ? 'destructive' : 'primary') as ButtonVariant)
13
+ let variant = $derived((destructive ? 'danger' : 'primary') as ButtonVariant)
13
14
  </script>
14
15
 
15
16
  <AlertDialogPrimitive.Action
16
17
  bind:ref
17
18
  data-slot="alert-dialog-action"
18
- class={cn(buttonVariants({ variant }), className)}
19
+ class={cn(buttonVariants({ variant }), 'group', className)}
20
+ {...restProps}
19
21
  >
20
- {@render children?.()}
22
+ <div class="inline-flex items-center transition-transform group-active:translate-y-px">
23
+ {@render children?.()}
24
+ </div>
21
25
  </AlertDialogPrimitive.Action>
@@ -5,15 +5,19 @@
5
5
  let {
6
6
  ref = $bindable(null),
7
7
  class: className,
8
- children
8
+ children,
9
+ ...restProps
9
10
  }: AlertDialogPrimitive.CancelProps = $props()
10
11
  </script>
11
12
 
12
13
  <AlertDialogPrimitive.Cancel
13
14
  bind:ref
14
15
  data-slot="alert-dialog-cancel"
15
- class={cn(buttonVariants({ variant: 'secondary' }), 'mt-2 sm:mt-0', className)}
16
+ class={cn(buttonVariants({ variant: 'secondary' }), 'group mt-2 sm:mt-0', className)}
16
17
  {onkeydown}
18
+ {...restProps}
17
19
  >
18
- {@render children?.()}
20
+ <div class="inline-flex items-center transition-transform group-active:translate-y-px">
21
+ {@render children?.()}
22
+ </div>
19
23
  </AlertDialogPrimitive.Cancel>
@@ -18,7 +18,7 @@
18
18
  bind:ref
19
19
  data-slot="alert-dialog-content"
20
20
  class={cn(
21
- 'bg-white fixed left-[50%] top-[50%] z-[1002] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-5 pt-3 px-4 pb-4 sm:rounded-lg md:w-full',
21
+ 'bg-background fixed left-1/2 top-1/2 z-[1002] flex flex-col w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-xl overflow-clip',
22
22
  className
23
23
  )}
24
24
  >
@@ -12,7 +12,7 @@
12
12
  bind:ref
13
13
  data-slot="alert-dialog-description"
14
14
  class={cn(
15
- 'text-neutral-500 text-base flex flex-col space-y-2 justify-start items-start !mt-2',
15
+ 'text-base font-normal leading-5 tracking-tight text-foreground-default-secondary',
16
16
  className
17
17
  )}
18
18
  >
@@ -11,7 +11,7 @@
11
11
  <div
12
12
  bind:this={ref}
13
13
  data-slot="alert-dialog-footer"
14
- class={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-3', className)}
14
+ class={cn('flex gap-3 justify-end px-3 pb-3', className)}
15
15
  >
16
16
  {@render children?.()}
17
17
  </div>
@@ -11,7 +11,7 @@
11
11
  <div
12
12
  bind:this={ref}
13
13
  data-slot="alert-dialog-header"
14
- class={cn('flex flex-col space-y-1 text-center sm:text-left', className)}
14
+ class={cn('flex flex-col gap-1 px-4 py-3', className)}
15
15
  >
16
16
  {@render children?.()}
17
17
  </div>
@@ -8,7 +8,7 @@
8
8
  bind:ref
9
9
  data-slot="alert-dialog-overlay"
10
10
  class={cn(
11
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-neutral-800/30 fixed inset-0 z-[1001]',
11
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-neutral-80/30 fixed inset-0 z-[1001]',
12
12
  className
13
13
  )}
14
14
  />
@@ -11,7 +11,7 @@
11
11
  <AlertDialogPrimitive.Title
12
12
  bind:ref
13
13
  data-slot="alert-dialog-title"
14
- class={cn('text-lg font-semibold text-neutral-800', className)}
14
+ class={cn('text-lg font-semibold leading-6 tracking-tight text-foreground', className)}
15
15
  >
16
16
  {@render children?.()}
17
17
  </AlertDialogPrimitive.Title>
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
3
- let { ref = $bindable(null) }: AlertDialogPrimitive.TriggerProps = $props()
3
+ let { ref = $bindable(null), children }: AlertDialogPrimitive.TriggerProps = $props()
4
4
  </script>
5
5
 
6
- <AlertDialogPrimitive.Trigger bind:ref data-slot="alert-dialog-trigger" />
6
+ <AlertDialogPrimitive.Trigger bind:ref data-slot="alert-dialog-trigger">
7
+ {@render children?.()}
8
+ </AlertDialogPrimitive.Trigger>
@@ -2,77 +2,277 @@
2
2
  import { cn, type WithElementRef } from '../utils.js'
3
3
  import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements'
4
4
  import { type VariantProps, tv } from 'tailwind-variants'
5
+ import type { IconSource } from '@steeze-ui/svelte-icon'
6
+
5
7
  export const buttonVariants = tv({
6
- base: 'ring-workspace-accent-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 flex items-center justify-center font-medium font-sans relative group tracking-tight rounded-md text-base text-neutral-800 box-border',
8
+ base: 'inline-flex items-center justify-center font-medium text-base whitespace-nowrap focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-selected focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-30 relative overflow-hidden box-border cursor-pointer',
7
9
  variants: {
8
10
  variant: {
9
- default: 'bg-white text-neutral-800 hover:bg-primary/90',
10
- destructive:
11
- 'ring-danger-200 bg-danger-500 border border-danger-500 hover:bg-danger-600 hover:border-danger-600 active:bg-danger-700 active:border-danger-700 text-white',
12
- outline:
13
- 'border-neutral-200 bg-white hover:border-neutral-300 border shadow-button active:shadow-button-active',
14
11
  primary:
15
- 'bg-workspace-accent-500 hover:bg-workspace-accent-600 active:bg-workspace-accent-700 text-white',
12
+ 'bg-background-accent text-foreground-inverse border border-border shadow-button-primary hover:bg-background-accent-hover active:bg-background-accent-hover active:shadow-button-pressed [&_svg]:text-icon-inverse',
13
+ warning:
14
+ 'bg-background-warning-inverse text-foreground-inverse border border-border shadow-button-primary hover:bg-background-warning-bold active:bg-background-warning-bold active:shadow-button-pressed [&_svg]:text-icon-inverse',
15
+ danger:
16
+ 'bg-background-default-tertiary text-foreground-critical border border-border shadow-button-default hover:bg-background-critical-bold hover:text-foreground-inverse hover:border-background-critical-bold active:bg-background-critical-bold active:text-foreground-inverse active:border-background-critical-bold active:shadow-[0px_4px_4px_-1px_inset_rgba(11,11,16,0.16)] [&_svg]:text-icon-critical hover:[&_svg]:text-icon-inverse active:[&_svg]:text-icon-inverse',
17
+ outline:
18
+ 'bg-background text-foreground border border-border-default-secondary shadow-button-default hover:border-border-default-secondary-hover active:shadow-button-pressed [&_svg]:text-icon',
19
+ ghost:
20
+ 'bg-transparent text-foreground hover:shadow-button-default active:shadow-button-pressed hover:bg-background-default-tertiary-hover active:bg-background-default-tertiary-hover [&_svg]:text-icon',
16
21
  secondary:
17
- 'bg-neutral-100 border border-neutral-100 hover:bg-neutral-200 hover:border-neutral-200 active:bg-neutral-300 active:border-neutral-300',
18
- ghost: 'hover:bg-accent hover:text-accent-foreground',
19
- link: 'text-primary underline-offset-4 hover:underline'
22
+ 'bg-background-default-tertiary text-foreground shadow-button-default hover:bg-background-default-tertiary-hover active:bg-background-default-tertiary-hover active:shadow-button-pressed [&_svg]:text-icon',
23
+ dark: 'bg-transparent text-foreground-inverse border border-border-inverse-secondary hover:bg-background-selected-inverse active:bg-background-inverse-tertiary active:shadow-button-dark-pressed [&_svg]:text-icon-inverse',
24
+ 'dark-ghost':
25
+ 'bg-transparent text-foreground-inverse hover:bg-background-selected-inverse active:bg-background-inverse-tertiary active:shadow-button-dark-pressed [&_svg]:text-icon-inverse'
20
26
  },
21
27
  size: {
22
- default: 'h-7 px-2 py-1',
23
- sm: 'h-9 rounded-md px-3',
24
- lg: 'h-11 rounded-md px-8',
25
- icon: 'h-7 p-1.5',
26
- 'icon-sm': 'size-6 p-1 active:pt-[5px] active:pb-[3px]'
28
+ sm: 'h-6 rounded-sm',
29
+ md: 'h-7 rounded-md',
30
+ lg: 'h-8 rounded-lg'
31
+ },
32
+ iconOnly: {
33
+ true: '',
34
+ false: ''
35
+ },
36
+ hasIcon: {
37
+ true: '',
38
+ false: ''
39
+ },
40
+ stackedLeft: {
41
+ true: '',
42
+ false: ''
43
+ },
44
+ stackedRight: {
45
+ true: '',
46
+ false: ''
27
47
  }
28
48
  },
49
+ compoundVariants: [
50
+ // Icon-only padding (varies by size) - must come first to avoid conflicts
51
+ {
52
+ size: 'sm',
53
+ iconOnly: true,
54
+ class: '!p-1'
55
+ },
56
+ {
57
+ size: 'md',
58
+ iconOnly: true,
59
+ class: '!p-1.5'
60
+ },
61
+ {
62
+ size: 'lg',
63
+ iconOnly: true,
64
+ class: '!p-2'
65
+ },
66
+ // Vertical padding for buttons with text
67
+ {
68
+ size: ['sm', 'md'],
69
+ iconOnly: false,
70
+ class: 'py-1'
71
+ },
72
+ {
73
+ size: 'lg',
74
+ iconOnly: false,
75
+ class: 'py-1.5'
76
+ },
77
+ // No icon - symmetric padding
78
+ {
79
+ size: ['sm', 'md'],
80
+ iconOnly: false,
81
+ hasIcon: false,
82
+ class: 'px-2'
83
+ },
84
+ {
85
+ size: 'lg',
86
+ iconOnly: false,
87
+ hasIcon: false,
88
+ class: 'px-3'
89
+ },
90
+ // Icon-left - asymmetric padding (less on icon side)
91
+ {
92
+ size: ['sm', 'md'],
93
+ iconOnly: false,
94
+ hasIcon: true,
95
+ class: 'pl-1.5 pr-2'
96
+ },
97
+ {
98
+ size: 'lg',
99
+ iconOnly: false,
100
+ hasIcon: true,
101
+ class: 'pl-2 pr-3'
102
+ },
103
+ // Icon-only uses bold icon variants
104
+ {
105
+ variant: ['secondary', 'outline', 'ghost'],
106
+ iconOnly: true,
107
+ class: '[&_svg]:!text-icon-default-bold'
108
+ },
109
+ {
110
+ variant: ['primary', 'warning', 'dark-ghost'],
111
+ iconOnly: true,
112
+ class: '[&_svg]:!text-icon-inverse-bold'
113
+ },
114
+ {
115
+ variant: 'dark',
116
+ iconOnly: true,
117
+ class: '[&_svg]:!text-icon-inverse-bold'
118
+ },
119
+ {
120
+ size: 'sm',
121
+ iconOnly: true,
122
+ class: 'w-6'
123
+ },
124
+ {
125
+ size: 'md',
126
+ iconOnly: true,
127
+ class: 'w-7'
128
+ },
129
+ {
130
+ size: 'lg',
131
+ iconOnly: true,
132
+ class: 'w-8'
133
+ },
134
+ {
135
+ stackedLeft: true,
136
+ class:
137
+ '!rounded-l-none hover:!bg-background-default-secondary active:!bg-background-default-secondary'
138
+ },
139
+ {
140
+ stackedRight: true,
141
+ class:
142
+ '!rounded-r-none hover:!bg-background-default-secondary active:!bg-background-default-secondary'
143
+ }
144
+ ],
29
145
  defaultVariants: {
30
- variant: 'default',
31
- size: 'default'
146
+ variant: 'primary',
147
+ size: 'md',
148
+ iconOnly: false,
149
+ hasIcon: false,
150
+ stackedLeft: false,
151
+ stackedRight: false
32
152
  }
33
153
  })
154
+
34
155
  export type ButtonVariant = VariantProps<typeof buttonVariants>['variant']
35
156
  export type ButtonSize = VariantProps<typeof buttonVariants>['size']
36
157
  export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
37
158
  WithElementRef<HTMLAnchorAttributes> & {
38
159
  variant?: ButtonVariant
39
160
  size?: ButtonSize
161
+ icon?: IconSource
162
+ iconPosition?: 'left' | 'right'
163
+ iconClass?: string
164
+ stackedLeft?: boolean
165
+ stackedRight?: boolean
40
166
  }
41
167
  </script>
42
168
 
43
169
  <script lang="ts">
170
+ import { Icon } from '@steeze-ui/svelte-icon'
171
+
44
172
  let {
45
173
  class: className,
46
- variant = 'default',
47
- size = 'default',
174
+ variant = 'primary',
175
+ size = 'lg',
176
+ icon,
177
+ iconPosition = 'left',
178
+ iconClass = '',
179
+ stackedLeft = false,
180
+ stackedRight = false,
48
181
  ref = $bindable(null),
49
182
  href = undefined,
50
183
  type = 'button',
51
184
  disabled,
52
- children
185
+ children,
186
+ onclick,
187
+ ...rest
53
188
  }: ButtonProps = $props()
189
+
190
+ let iconOnly = $derived(!children)
191
+ let hasIcon = $derived(!!icon && !iconOnly)
192
+
193
+ let iconSize = $derived(
194
+ {
195
+ sm: 'size-3',
196
+ md: 'size-4',
197
+ lg: 'size-4'
198
+ }[size]
199
+ )
200
+
201
+ // For icon-right, we need to reverse the padding
202
+ let paddingClass = $derived(
203
+ iconPosition === 'right' && hasIcon ? (size === 'lg' ? 'pl-3 pr-2' : 'pl-2 pr-1.5') : ''
204
+ )
54
205
  </script>
55
206
 
207
+ {#snippet iconContent()}
208
+ {#if icon}
209
+ <div class={cn('relative z-10', iconClass && `[&_svg]:${iconClass}`)}>
210
+ <Icon src={icon} class={iconSize} />
211
+ </div>
212
+ {/if}
213
+ {/snippet}
214
+
215
+ {#snippet buttonContent()}
216
+ <div
217
+ class={cn(
218
+ 'inline-flex items-center transition-transform group-active:translate-y-px',
219
+ !iconOnly && 'gap-1'
220
+ )}
221
+ >
222
+ {#if icon && !children}
223
+ {@render iconContent()}
224
+ {:else if iconPosition === 'right'}
225
+ {#if children}
226
+ <span class="z-10">{@render children()}</span>
227
+ {/if}
228
+ {#if icon}
229
+ {@render iconContent()}
230
+ {/if}
231
+ {:else}
232
+ {#if icon}
233
+ {@render iconContent()}
234
+ {/if}
235
+ {#if children}
236
+ <span class="z-10">{@render children()}</span>
237
+ {/if}
238
+ {/if}
239
+ </div>
240
+ {/snippet}
241
+
56
242
  {#if href}
57
243
  <a
58
244
  bind:this={ref}
59
245
  data-slot="button"
60
- class={cn(buttonVariants({ variant, size }), className)}
246
+ class={cn(
247
+ buttonVariants({ variant, size, iconOnly, hasIcon, stackedLeft, stackedRight }),
248
+ iconPosition === 'right' && 'flex-row-reverse',
249
+ paddingClass,
250
+ className
251
+ )}
61
252
  href={disabled ? undefined : href}
62
253
  aria-disabled={disabled}
63
254
  role={disabled ? 'link' : undefined}
64
255
  tabindex={disabled ? -1 : undefined}
256
+ {...rest}
65
257
  >
66
- {@render children?.()}
258
+ {@render buttonContent()}
67
259
  </a>
68
260
  {:else}
69
261
  <button
70
262
  bind:this={ref}
71
263
  data-slot="button"
72
- class={cn(buttonVariants({ variant, size }), className)}
264
+ class={cn(
265
+ buttonVariants({ variant, size, iconOnly, hasIcon, stackedLeft, stackedRight }),
266
+ 'group',
267
+ iconPosition === 'right' && 'flex-row-reverse',
268
+ paddingClass,
269
+ className
270
+ )}
73
271
  {type}
74
272
  {disabled}
273
+ {onclick}
274
+ {...rest}
75
275
  >
76
- {@render children?.()}
276
+ {@render buttonContent()}
77
277
  </button>
78
278
  {/if}