@aspect-ops/exon-ui 0.0.1 → 0.0.3

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 (178) hide show
  1. package/README.md +438 -0
  2. package/dist/components/ActionSheet/ActionSheet.svelte +270 -0
  3. package/dist/components/ActionSheet/ActionSheet.svelte.d.ts +12 -0
  4. package/dist/components/ActionSheet/ActionSheetItem.svelte +151 -0
  5. package/dist/components/ActionSheet/ActionSheetItem.svelte.d.ts +10 -0
  6. package/dist/components/ActionSheet/index.d.ts +3 -0
  7. package/dist/components/ActionSheet/index.js +2 -0
  8. package/dist/components/Alert/Alert.svelte +165 -0
  9. package/dist/components/Alert/Alert.svelte.d.ts +11 -0
  10. package/dist/components/Alert/index.d.ts +1 -0
  11. package/dist/components/Alert/index.js +1 -0
  12. package/dist/components/AspectRatio/AspectRatio.svelte +42 -0
  13. package/dist/components/AspectRatio/AspectRatio.svelte.d.ts +9 -0
  14. package/dist/components/AspectRatio/index.d.ts +1 -0
  15. package/dist/components/AspectRatio/index.js +1 -0
  16. package/dist/components/Avatar/Avatar.svelte +147 -0
  17. package/dist/components/Avatar/Avatar.svelte.d.ts +12 -0
  18. package/dist/components/Avatar/AvatarGroup.svelte +153 -0
  19. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +12 -0
  20. package/dist/components/Avatar/index.d.ts +2 -0
  21. package/dist/components/Avatar/index.js +2 -0
  22. package/dist/components/BottomSheet/BottomSheet.svelte +230 -0
  23. package/dist/components/BottomSheet/BottomSheet.svelte.d.ts +7 -0
  24. package/dist/components/BottomSheet/BottomSheetBody.svelte +20 -0
  25. package/dist/components/BottomSheet/BottomSheetBody.svelte.d.ts +7 -0
  26. package/dist/components/BottomSheet/BottomSheetHeader.svelte +27 -0
  27. package/dist/components/BottomSheet/BottomSheetHeader.svelte.d.ts +7 -0
  28. package/dist/components/BottomSheet/index.d.ts +3 -0
  29. package/dist/components/BottomSheet/index.js +3 -0
  30. package/dist/components/Box/Box.svelte +41 -0
  31. package/dist/components/Box/Box.svelte.d.ts +7 -0
  32. package/dist/components/Box/index.d.ts +1 -0
  33. package/dist/components/Box/index.js +1 -0
  34. package/dist/components/Card/Card.svelte +95 -0
  35. package/dist/components/Card/Card.svelte.d.ts +10 -0
  36. package/dist/components/Card/CardBody.svelte +32 -0
  37. package/dist/components/Card/CardBody.svelte.d.ts +7 -0
  38. package/dist/components/Card/CardFooter.svelte +34 -0
  39. package/dist/components/Card/CardFooter.svelte.d.ts +7 -0
  40. package/dist/components/Card/CardHeader.svelte +67 -0
  41. package/dist/components/Card/CardHeader.svelte.d.ts +9 -0
  42. package/dist/components/Card/index.d.ts +4 -0
  43. package/dist/components/Card/index.js +4 -0
  44. package/dist/components/Center/Center.svelte +28 -0
  45. package/dist/components/Center/Center.svelte.d.ts +8 -0
  46. package/dist/components/Center/index.d.ts +1 -0
  47. package/dist/components/Center/index.js +1 -0
  48. package/dist/components/Container/Container.svelte +58 -0
  49. package/dist/components/Container/Container.svelte.d.ts +10 -0
  50. package/dist/components/Container/index.d.ts +1 -0
  51. package/dist/components/Container/index.js +1 -0
  52. package/dist/components/Divider/Divider.svelte +38 -0
  53. package/dist/components/Divider/Divider.svelte.d.ts +9 -0
  54. package/dist/components/Divider/index.d.ts +1 -0
  55. package/dist/components/Divider/index.js +1 -0
  56. package/dist/components/EmptyState/EmptyState.svelte +164 -0
  57. package/dist/components/EmptyState/EmptyState.svelte.d.ts +12 -0
  58. package/dist/components/EmptyState/index.d.ts +1 -0
  59. package/dist/components/EmptyState/index.js +1 -0
  60. package/dist/components/FAB/FAB.svelte +242 -0
  61. package/dist/components/FAB/FAB.svelte.d.ts +9 -0
  62. package/dist/components/FAB/FABGroup.svelte +449 -0
  63. package/dist/components/FAB/FABGroup.svelte.d.ts +9 -0
  64. package/dist/components/FAB/index.d.ts +3 -0
  65. package/dist/components/FAB/index.js +2 -0
  66. package/dist/components/Grid/Grid.svelte +136 -0
  67. package/dist/components/Grid/Grid.svelte.d.ts +12 -0
  68. package/dist/components/Grid/GridItem.svelte +21 -0
  69. package/dist/components/Grid/GridItem.svelte.d.ts +7 -0
  70. package/dist/components/Grid/index.d.ts +2 -0
  71. package/dist/components/Grid/index.js +2 -0
  72. package/dist/components/List/List.svelte +42 -0
  73. package/dist/components/List/List.svelte.d.ts +18 -0
  74. package/dist/components/List/ListItem.svelte +139 -0
  75. package/dist/components/List/ListItem.svelte.d.ts +36 -0
  76. package/dist/components/List/index.d.ts +2 -0
  77. package/dist/components/List/index.js +2 -0
  78. package/dist/components/Modal/Modal.svelte +204 -0
  79. package/dist/components/Modal/Modal.svelte.d.ts +7 -0
  80. package/dist/components/Modal/ModalBody.svelte +50 -0
  81. package/dist/components/Modal/ModalBody.svelte.d.ts +7 -0
  82. package/dist/components/Modal/ModalFooter.svelte +37 -0
  83. package/dist/components/Modal/ModalFooter.svelte.d.ts +7 -0
  84. package/dist/components/Modal/ModalHeader.svelte +73 -0
  85. package/dist/components/Modal/ModalHeader.svelte.d.ts +7 -0
  86. package/dist/components/Modal/index.d.ts +4 -0
  87. package/dist/components/Modal/index.js +4 -0
  88. package/dist/components/Popover/Popover.svelte +14 -0
  89. package/dist/components/Popover/Popover.svelte.d.ts +7 -0
  90. package/dist/components/Popover/PopoverContent.svelte +63 -0
  91. package/dist/components/Popover/PopoverContent.svelte.d.ts +7 -0
  92. package/dist/components/Popover/PopoverTrigger.svelte +14 -0
  93. package/dist/components/Popover/PopoverTrigger.svelte.d.ts +7 -0
  94. package/dist/components/Popover/index.d.ts +3 -0
  95. package/dist/components/Popover/index.js +3 -0
  96. package/dist/components/Progress/ProgressBar.svelte +86 -0
  97. package/dist/components/Progress/ProgressBar.svelte.d.ts +11 -0
  98. package/dist/components/Progress/ProgressCircle.svelte +134 -0
  99. package/dist/components/Progress/ProgressCircle.svelte.d.ts +12 -0
  100. package/dist/components/Progress/Spinner.svelte +68 -0
  101. package/dist/components/Progress/Spinner.svelte.d.ts +8 -0
  102. package/dist/components/Progress/index.d.ts +3 -0
  103. package/dist/components/Progress/index.js +3 -0
  104. package/dist/components/PullToRefresh/PullToRefresh.svelte +304 -0
  105. package/dist/components/PullToRefresh/PullToRefresh.svelte.d.ts +20 -0
  106. package/dist/components/PullToRefresh/index.d.ts +1 -0
  107. package/dist/components/PullToRefresh/index.js +1 -0
  108. package/dist/components/SafeArea/SafeArea.svelte +33 -0
  109. package/dist/components/SafeArea/SafeArea.svelte.d.ts +7 -0
  110. package/dist/components/Select/Select.svelte +55 -12
  111. package/dist/components/Skeleton/Skeleton.svelte +59 -0
  112. package/dist/components/Skeleton/Skeleton.svelte.d.ts +10 -0
  113. package/dist/components/Skeleton/index.d.ts +1 -0
  114. package/dist/components/Skeleton/index.js +1 -0
  115. package/dist/components/Spacer/Spacer.svelte +56 -0
  116. package/dist/components/Spacer/Spacer.svelte.d.ts +6 -0
  117. package/dist/components/Spacer/index.d.ts +1 -0
  118. package/dist/components/Spacer/index.js +1 -0
  119. package/dist/components/Stack/Stack.svelte +117 -0
  120. package/dist/components/Stack/Stack.svelte.d.ts +13 -0
  121. package/dist/components/Stack/index.d.ts +1 -0
  122. package/dist/components/Stack/index.js +1 -0
  123. package/dist/components/SwipeActions/SwipeAction.svelte +43 -0
  124. package/dist/components/SwipeActions/SwipeAction.svelte.d.ts +8 -0
  125. package/dist/components/SwipeActions/SwipeActions.svelte +193 -0
  126. package/dist/components/SwipeActions/SwipeActions.svelte.d.ts +9 -0
  127. package/dist/components/SwipeActions/index.d.ts +2 -0
  128. package/dist/components/SwipeActions/index.js +2 -0
  129. package/dist/components/Switch/Switch.svelte +29 -9
  130. package/dist/components/Table/Table.svelte +175 -0
  131. package/dist/components/Table/Table.svelte.d.ts +38 -0
  132. package/dist/components/Table/TableBody.svelte +26 -0
  133. package/dist/components/Table/TableBody.svelte.d.ts +13 -0
  134. package/dist/components/Table/TableCell.svelte +85 -0
  135. package/dist/components/Table/TableCell.svelte.d.ts +28 -0
  136. package/dist/components/Table/TableHead.svelte +36 -0
  137. package/dist/components/Table/TableHead.svelte.d.ts +13 -0
  138. package/dist/components/Table/TableHeader.svelte +217 -0
  139. package/dist/components/Table/TableHeader.svelte.d.ts +32 -0
  140. package/dist/components/Table/TableRow.svelte +92 -0
  141. package/dist/components/Table/TableRow.svelte.d.ts +28 -0
  142. package/dist/components/Table/index.d.ts +6 -0
  143. package/dist/components/Table/index.js +6 -0
  144. package/dist/components/Tag/Tag.svelte +189 -0
  145. package/dist/components/Tag/Tag.svelte.d.ts +13 -0
  146. package/dist/components/Tag/index.d.ts +1 -0
  147. package/dist/components/Tag/index.js +1 -0
  148. package/dist/components/Toast/Toast.svelte +241 -0
  149. package/dist/components/Toast/Toast.svelte.d.ts +18 -0
  150. package/dist/components/Toast/ToastContainer.svelte +110 -0
  151. package/dist/components/Toast/ToastContainer.svelte.d.ts +8 -0
  152. package/dist/components/Toast/index.d.ts +3 -0
  153. package/dist/components/Toast/index.js +3 -0
  154. package/dist/components/Toast/toast.d.ts +13 -0
  155. package/dist/components/Toast/toast.js +55 -0
  156. package/dist/components/Tooltip/Tooltip.svelte +71 -0
  157. package/dist/components/Tooltip/Tooltip.svelte.d.ts +7 -0
  158. package/dist/components/Tooltip/index.d.ts +2 -0
  159. package/dist/components/Tooltip/index.js +1 -0
  160. package/dist/index.d.ts +29 -1
  161. package/dist/index.js +32 -0
  162. package/dist/styles/tokens.css +5 -0
  163. package/dist/types/data-display.d.ts +93 -0
  164. package/dist/types/data-display.js +1 -0
  165. package/dist/types/feedback.d.ts +92 -0
  166. package/dist/types/feedback.js +1 -0
  167. package/dist/types/index.d.ts +4 -0
  168. package/dist/types/layout.d.ts +57 -0
  169. package/dist/types/layout.js +1 -0
  170. package/dist/types/mobile.d.ts +91 -0
  171. package/dist/types/mobile.js +1 -0
  172. package/dist/utils/gestures.d.ts +219 -0
  173. package/dist/utils/gestures.js +492 -0
  174. package/dist/utils/haptics.d.ts +89 -0
  175. package/dist/utils/haptics.js +198 -0
  176. package/dist/utils/platform.d.ts +47 -0
  177. package/dist/utils/platform.js +156 -0
  178. package/package.json +1 -1
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import type { ModalFooterProps } from '../../types/index.js';
3
+
4
+ interface Props extends ModalFooterProps {
5
+ children?: import('svelte').Snippet;
6
+ }
7
+
8
+ let { class: className = '', children }: Props = $props();
9
+ </script>
10
+
11
+ <div class="modal-footer {className}">
12
+ {@render children?.()}
13
+ </div>
14
+
15
+ <style>
16
+ :global(.modal-footer) {
17
+ display: flex;
18
+ align-items: center;
19
+ justify-content: flex-end;
20
+ padding: var(--space-lg, 1rem) var(--space-xl, 1.5rem);
21
+ border-top: 1px solid var(--color-border, #e5e7eb);
22
+ gap: var(--space-md, 0.75rem);
23
+ flex-shrink: 0;
24
+ flex-wrap: wrap;
25
+ }
26
+
27
+ /* Mobile: Stack buttons vertically */
28
+ @media (max-width: 640px) {
29
+ :global(.modal-footer) {
30
+ flex-direction: column-reverse;
31
+ }
32
+
33
+ :global(.modal-footer > *) {
34
+ width: 100%;
35
+ }
36
+ }
37
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { ModalFooterProps } from '../../types/index.js';
2
+ interface Props extends ModalFooterProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const ModalFooter: import("svelte").Component<Props, {}, "">;
6
+ type ModalFooter = ReturnType<typeof ModalFooter>;
7
+ export default ModalFooter;
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ import type { ModalHeaderProps } from '../../types/index.js';
3
+ import { Dialog } from 'bits-ui';
4
+
5
+ interface Props extends ModalHeaderProps {
6
+ children?: import('svelte').Snippet;
7
+ }
8
+
9
+ let { class: className = '', children }: Props = $props();
10
+ </script>
11
+
12
+ <div class="modal-header {className}">
13
+ <Dialog.Title class="modal-title">
14
+ {@render children?.()}
15
+ </Dialog.Title>
16
+ <Dialog.Close class="modal-close" aria-label="Close modal">&times;</Dialog.Close>
17
+ </div>
18
+
19
+ <style>
20
+ :global(.modal-header) {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: space-between;
24
+ padding: var(--space-lg, 1rem) var(--space-xl, 1.5rem);
25
+ border-bottom: 1px solid var(--color-border, #e5e7eb);
26
+ gap: var(--space-md, 0.75rem);
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ :global(.modal-title) {
31
+ font-size: var(--font-size-lg, 1.125rem);
32
+ font-weight: var(--font-weight-semibold, 600);
33
+ color: var(--color-text, #1f2937);
34
+ line-height: var(--line-height-tight, 1.25);
35
+ margin: 0;
36
+ flex: 1;
37
+ }
38
+
39
+ :global(.modal-close) {
40
+ /* F20: Minimum 44x44px touch target */
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ min-width: 2.75rem;
45
+ min-height: 2.75rem;
46
+ width: 2.75rem;
47
+ height: 2.75rem;
48
+ border: none;
49
+ background: transparent;
50
+ color: var(--color-text-secondary, #6b7280);
51
+ font-size: var(--font-size-2xl, 1.5rem);
52
+ line-height: 1;
53
+ cursor: pointer;
54
+ border-radius: var(--radius-sm, 0.25rem);
55
+ transition: all 150ms ease;
56
+ flex-shrink: 0;
57
+ padding: 0;
58
+ }
59
+
60
+ :global(.modal-close:hover) {
61
+ background: var(--color-bg-secondary, #f3f4f6);
62
+ color: var(--color-text, #1f2937);
63
+ }
64
+
65
+ :global(.modal-close:focus-visible) {
66
+ outline: 2px solid var(--color-primary, #3b82f6);
67
+ outline-offset: 2px;
68
+ }
69
+
70
+ :global(.modal-close:active) {
71
+ transform: scale(0.95);
72
+ }
73
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { ModalHeaderProps } from '../../types/index.js';
2
+ interface Props extends ModalHeaderProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const ModalHeader: import("svelte").Component<Props, {}, "">;
6
+ type ModalHeader = ReturnType<typeof ModalHeader>;
7
+ export default ModalHeader;
@@ -0,0 +1,4 @@
1
+ export { default as Modal } from './Modal.svelte';
2
+ export { default as ModalHeader } from './ModalHeader.svelte';
3
+ export { default as ModalBody } from './ModalBody.svelte';
4
+ export { default as ModalFooter } from './ModalFooter.svelte';
@@ -0,0 +1,4 @@
1
+ export { default as Modal } from './Modal.svelte';
2
+ export { default as ModalHeader } from './ModalHeader.svelte';
3
+ export { default as ModalBody } from './ModalBody.svelte';
4
+ export { default as ModalFooter } from './ModalFooter.svelte';
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import type { PopoverProps } from '../../types/index.js';
3
+ import { Popover as BitsPopover } from 'bits-ui';
4
+
5
+ interface Props extends PopoverProps {
6
+ children?: import('svelte').Snippet;
7
+ }
8
+
9
+ let { class: className = '', children }: Props = $props();
10
+ </script>
11
+
12
+ <BitsPopover.Root>
13
+ {@render children?.()}
14
+ </BitsPopover.Root>
@@ -0,0 +1,7 @@
1
+ import type { PopoverProps } from '../../types/index.js';
2
+ interface Props extends PopoverProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const Popover: import("svelte").Component<Props, {}, "">;
6
+ type Popover = ReturnType<typeof Popover>;
7
+ export default Popover;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import type { PopoverContentProps } from '../../types/index.js';
3
+ import { Popover as BitsPopover } from 'bits-ui';
4
+
5
+ interface Props extends PopoverContentProps {
6
+ children?: import('svelte').Snippet;
7
+ }
8
+
9
+ let { side = 'bottom', class: className = '', children }: Props = $props();
10
+ </script>
11
+
12
+ <BitsPopover.Portal>
13
+ <BitsPopover.Content {side} class="popover-content {className}">
14
+ {@render children?.()}
15
+ </BitsPopover.Content>
16
+ </BitsPopover.Portal>
17
+
18
+ <style>
19
+ /* Popover content */
20
+ :global(.popover-content) {
21
+ /* MUST set font-family explicitly - portal doesn't inherit (F33) */
22
+ font-family: var(--exon-font-sans, var(--font-family, system-ui, -apple-system, sans-serif));
23
+ background: var(--exon-popover-bg, white);
24
+ border: 1px solid var(--exon-color-neutral-200, #e5e7eb);
25
+ border-radius: var(--exon-radius-lg, 0.5rem);
26
+ padding: 1rem;
27
+ box-shadow: var(--exon-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));
28
+ min-width: 12.5rem;
29
+ max-width: 20rem;
30
+ z-index: 150;
31
+ }
32
+
33
+ /* Fade-in animation */
34
+ :global(.popover-content[data-state='open']) {
35
+ animation: popover-fade-in 200ms ease-out;
36
+ }
37
+
38
+ :global(.popover-content[data-state='closed']) {
39
+ animation: popover-fade-out 150ms ease-in;
40
+ }
41
+
42
+ @keyframes -global-popover-fade-in {
43
+ from {
44
+ opacity: 0;
45
+ transform: scale(0.95);
46
+ }
47
+ to {
48
+ opacity: 1;
49
+ transform: scale(1);
50
+ }
51
+ }
52
+
53
+ @keyframes -global-popover-fade-out {
54
+ from {
55
+ opacity: 1;
56
+ transform: scale(1);
57
+ }
58
+ to {
59
+ opacity: 0;
60
+ transform: scale(0.95);
61
+ }
62
+ }
63
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { PopoverContentProps } from '../../types/index.js';
2
+ interface Props extends PopoverContentProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const PopoverContent: import("svelte").Component<Props, {}, "">;
6
+ type PopoverContent = ReturnType<typeof PopoverContent>;
7
+ export default PopoverContent;
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import type { PopoverTriggerProps } from '../../types/index.js';
3
+ import { Popover as BitsPopover } from 'bits-ui';
4
+
5
+ interface Props extends PopoverTriggerProps {
6
+ children?: import('svelte').Snippet;
7
+ }
8
+
9
+ let { class: className = '', children }: Props = $props();
10
+ </script>
11
+
12
+ <BitsPopover.Trigger class={className}>
13
+ {@render children?.()}
14
+ </BitsPopover.Trigger>
@@ -0,0 +1,7 @@
1
+ import type { PopoverTriggerProps } from '../../types/index.js';
2
+ interface Props extends PopoverTriggerProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const PopoverTrigger: import("svelte").Component<Props, {}, "">;
6
+ type PopoverTrigger = ReturnType<typeof PopoverTrigger>;
7
+ export default PopoverTrigger;
@@ -0,0 +1,3 @@
1
+ export { default as Popover } from './Popover.svelte';
2
+ export { default as PopoverTrigger } from './PopoverTrigger.svelte';
3
+ export { default as PopoverContent } from './PopoverContent.svelte';
@@ -0,0 +1,3 @@
1
+ export { default as Popover } from './Popover.svelte';
2
+ export { default as PopoverTrigger } from './PopoverTrigger.svelte';
3
+ export { default as PopoverContent } from './PopoverContent.svelte';
@@ -0,0 +1,86 @@
1
+ <script lang="ts">
2
+ import type { ProgressBarProps } from '../../types/index.js';
3
+
4
+ interface Props extends ProgressBarProps {
5
+ value?: number;
6
+ max?: number;
7
+ indeterminate?: boolean;
8
+ size?: 'sm' | 'md' | 'lg';
9
+ class?: string;
10
+ }
11
+
12
+ let {
13
+ value = 0,
14
+ max = 100,
15
+ indeterminate = false,
16
+ size = 'md',
17
+ class: className = ''
18
+ }: Props = $props();
19
+
20
+ // Calculate percentage for determinate mode
21
+ const percentage = $derived(indeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100)));
22
+ </script>
23
+
24
+ <div
25
+ class="progress-bar progress-bar--{size} {className}"
26
+ role="progressbar"
27
+ aria-valuemin="0"
28
+ aria-valuemax={max}
29
+ aria-valuenow={indeterminate ? undefined : value}
30
+ aria-label={indeterminate ? 'Loading' : `${Math.round(percentage)}% complete`}
31
+ >
32
+ <div
33
+ class="progress-bar__fill"
34
+ class:progress-bar__fill--indeterminate={indeterminate}
35
+ style="width: {indeterminate ? '30%' : `${percentage}%`}"
36
+ ></div>
37
+ </div>
38
+
39
+ <style>
40
+ .progress-bar {
41
+ position: relative;
42
+ width: 100%;
43
+ overflow: hidden;
44
+ background-color: var(--exon-progress-track, var(--color-neutral-200, #e5e7eb));
45
+ border-radius: var(--exon-radius-full, 9999px);
46
+ font-family: inherit;
47
+ }
48
+
49
+ /* Size variants */
50
+ .progress-bar--sm {
51
+ height: 0.25rem;
52
+ }
53
+
54
+ .progress-bar--md {
55
+ height: 0.5rem;
56
+ }
57
+
58
+ .progress-bar--lg {
59
+ height: 0.75rem;
60
+ }
61
+
62
+ /* Progress fill */
63
+ .progress-bar__fill {
64
+ height: 100%;
65
+ background-color: var(--exon-progress-fill, var(--color-primary, #3b82f6));
66
+ border-radius: var(--exon-radius-full, 9999px);
67
+ transition: width 0.3s ease;
68
+ }
69
+
70
+ /* Indeterminate animation */
71
+ .progress-bar__fill--indeterminate {
72
+ animation: progress-indeterminate 1.5s ease-in-out infinite;
73
+ }
74
+
75
+ @keyframes progress-indeterminate {
76
+ 0% {
77
+ transform: translateX(-100%);
78
+ }
79
+ 50% {
80
+ transform: translateX(350%);
81
+ }
82
+ 100% {
83
+ transform: translateX(-100%);
84
+ }
85
+ }
86
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { ProgressBarProps } from '../../types/index.js';
2
+ interface Props extends ProgressBarProps {
3
+ value?: number;
4
+ max?: number;
5
+ indeterminate?: boolean;
6
+ size?: 'sm' | 'md' | 'lg';
7
+ class?: string;
8
+ }
9
+ declare const ProgressBar: import("svelte").Component<Props, {}, "">;
10
+ type ProgressBar = ReturnType<typeof ProgressBar>;
11
+ export default ProgressBar;
@@ -0,0 +1,134 @@
1
+ <script lang="ts">
2
+ import type { ProgressCircleProps } from '../../types/index.js';
3
+
4
+ interface Props extends ProgressCircleProps {
5
+ value?: number;
6
+ max?: number;
7
+ indeterminate?: boolean;
8
+ size?: 'sm' | 'md' | 'lg';
9
+ strokeWidth?: number;
10
+ class?: string;
11
+ }
12
+
13
+ let {
14
+ value = 0,
15
+ max = 100,
16
+ indeterminate = false,
17
+ size = 'md',
18
+ strokeWidth = 4,
19
+ class: className = ''
20
+ }: Props = $props();
21
+
22
+ // SVG constants
23
+ const radius = 45;
24
+ const circumference = 2 * Math.PI * radius;
25
+
26
+ // Calculate percentage and stroke-dashoffset for determinate mode
27
+ const percentage = $derived(indeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100)));
28
+ const strokeDashoffset = $derived(circumference * (1 - percentage / 100));
29
+ </script>
30
+
31
+ <div
32
+ class="progress-circle progress-circle--{size} {className}"
33
+ role="progressbar"
34
+ aria-valuemin="0"
35
+ aria-valuemax={max}
36
+ aria-valuenow={indeterminate ? undefined : value}
37
+ aria-label={indeterminate ? 'Loading' : `${Math.round(percentage)}% complete`}
38
+ >
39
+ <svg class="progress-circle__svg" viewBox="0 0 100 100">
40
+ <!-- Track circle (background) -->
41
+ <circle
42
+ class="progress-circle__track"
43
+ cx="50"
44
+ cy="50"
45
+ r={radius}
46
+ fill="none"
47
+ stroke-width={strokeWidth}
48
+ />
49
+
50
+ <!-- Progress circle (foreground) -->
51
+ <circle
52
+ class="progress-circle__fill"
53
+ class:progress-circle__fill--indeterminate={indeterminate}
54
+ cx="50"
55
+ cy="50"
56
+ r={radius}
57
+ fill="none"
58
+ stroke-width={strokeWidth}
59
+ stroke-dasharray={circumference}
60
+ stroke-dashoffset={indeterminate ? circumference * 0.75 : strokeDashoffset}
61
+ stroke-linecap="round"
62
+ />
63
+ </svg>
64
+ </div>
65
+
66
+ <style>
67
+ .progress-circle {
68
+ display: inline-flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ font-family: inherit;
72
+ }
73
+
74
+ /* Size variants */
75
+ .progress-circle--sm {
76
+ width: 1.5rem;
77
+ height: 1.5rem;
78
+ }
79
+
80
+ .progress-circle--md {
81
+ width: 2.5rem;
82
+ height: 2.5rem;
83
+ }
84
+
85
+ .progress-circle--lg {
86
+ width: 3.5rem;
87
+ height: 3.5rem;
88
+ }
89
+
90
+ .progress-circle__svg {
91
+ width: 100%;
92
+ height: 100%;
93
+ transform: rotate(-90deg);
94
+ }
95
+
96
+ /* Track circle (background) */
97
+ .progress-circle__track {
98
+ stroke: var(--exon-progress-track, var(--color-neutral-200, #e5e7eb));
99
+ }
100
+
101
+ /* Progress circle (foreground fill) */
102
+ .progress-circle__fill {
103
+ stroke: var(--exon-progress-fill, var(--color-primary, #3b82f6));
104
+ transition: stroke-dashoffset 0.3s ease;
105
+ }
106
+
107
+ /* Indeterminate animation */
108
+ .progress-circle__fill--indeterminate {
109
+ animation:
110
+ progress-circle-rotate 1.5s linear infinite,
111
+ progress-circle-dash 1.5s ease-in-out infinite;
112
+ }
113
+
114
+ @keyframes progress-circle-rotate {
115
+ 0% {
116
+ transform: rotate(0deg);
117
+ }
118
+ 100% {
119
+ transform: rotate(360deg);
120
+ }
121
+ }
122
+
123
+ @keyframes progress-circle-dash {
124
+ 0% {
125
+ stroke-dashoffset: 282.74;
126
+ }
127
+ 50% {
128
+ stroke-dashoffset: 70.685;
129
+ }
130
+ 100% {
131
+ stroke-dashoffset: 282.74;
132
+ }
133
+ }
134
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { ProgressCircleProps } from '../../types/index.js';
2
+ interface Props extends ProgressCircleProps {
3
+ value?: number;
4
+ max?: number;
5
+ indeterminate?: boolean;
6
+ size?: 'sm' | 'md' | 'lg';
7
+ strokeWidth?: number;
8
+ class?: string;
9
+ }
10
+ declare const ProgressCircle: import("svelte").Component<Props, {}, "">;
11
+ type ProgressCircle = ReturnType<typeof ProgressCircle>;
12
+ export default ProgressCircle;
@@ -0,0 +1,68 @@
1
+ <script lang="ts">
2
+ import type { SpinnerProps } from '../../types/index.js';
3
+
4
+ interface Props extends SpinnerProps {
5
+ size?: 'sm' | 'md' | 'lg';
6
+ class?: string;
7
+ }
8
+
9
+ let { size = 'md', class: className = '' }: Props = $props();
10
+ </script>
11
+
12
+ <div class="spinner spinner--{size} {className}" role="status" aria-label="Loading">
13
+ <span class="spinner__visually-hidden">Loading...</span>
14
+ </div>
15
+
16
+ <style>
17
+ .spinner {
18
+ display: inline-block;
19
+ border-style: solid;
20
+ border-color: var(--exon-spinner-color, var(--color-primary, #3b82f6)) transparent transparent
21
+ transparent;
22
+ border-radius: 50%;
23
+ animation: spinner-rotate 0.75s linear infinite;
24
+ font-family: inherit;
25
+ }
26
+
27
+ /* Size variants - diameter and border-width */
28
+ .spinner--sm {
29
+ width: 1rem;
30
+ height: 1rem;
31
+ border-width: 2px;
32
+ }
33
+
34
+ .spinner--md {
35
+ width: 1.5rem;
36
+ height: 1.5rem;
37
+ border-width: 2px;
38
+ }
39
+
40
+ .spinner--lg {
41
+ width: 2rem;
42
+ height: 2rem;
43
+ border-width: 3px;
44
+ }
45
+
46
+ /* Visually hidden text for screen readers */
47
+ .spinner__visually-hidden {
48
+ position: absolute;
49
+ width: 1px;
50
+ height: 1px;
51
+ padding: 0;
52
+ margin: -1px;
53
+ overflow: hidden;
54
+ clip: rect(0, 0, 0, 0);
55
+ white-space: nowrap;
56
+ border-width: 0;
57
+ }
58
+
59
+ /* Rotation animation */
60
+ @keyframes spinner-rotate {
61
+ 0% {
62
+ transform: rotate(0deg);
63
+ }
64
+ 100% {
65
+ transform: rotate(360deg);
66
+ }
67
+ }
68
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { SpinnerProps } from '../../types/index.js';
2
+ interface Props extends SpinnerProps {
3
+ size?: 'sm' | 'md' | 'lg';
4
+ class?: string;
5
+ }
6
+ declare const Spinner: import("svelte").Component<Props, {}, "">;
7
+ type Spinner = ReturnType<typeof Spinner>;
8
+ export default Spinner;
@@ -0,0 +1,3 @@
1
+ export { default as ProgressBar } from './ProgressBar.svelte';
2
+ export { default as ProgressCircle } from './ProgressCircle.svelte';
3
+ export { default as Spinner } from './Spinner.svelte';
@@ -0,0 +1,3 @@
1
+ export { default as ProgressBar } from './ProgressBar.svelte';
2
+ export { default as ProgressCircle } from './ProgressCircle.svelte';
3
+ export { default as Spinner } from './Spinner.svelte';