svelte-comp 1.3.3 → 1.3.6

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 (138) hide show
  1. package/LICENSE.md +21 -21
  2. package/README.md +101 -100
  3. package/dist/App.svelte +507 -507
  4. package/dist/Container.svelte +59 -59
  5. package/dist/app.css +234 -235
  6. package/dist/app.d.ts +10 -0
  7. package/dist/lib/Accordion.svelte +155 -155
  8. package/dist/lib/Badge.svelte +44 -44
  9. package/dist/lib/Button.svelte +185 -170
  10. package/dist/lib/Calendar.svelte +384 -384
  11. package/dist/lib/Card.svelte +103 -103
  12. package/dist/lib/Carousel.svelte +293 -293
  13. package/dist/lib/Carousel.svelte.d.ts +1 -1
  14. package/dist/lib/CheckBox.svelte +210 -210
  15. package/dist/lib/CodeView.svelte +308 -307
  16. package/dist/lib/ColorPicker.svelte +159 -159
  17. package/dist/lib/ContextMenu.svelte +328 -322
  18. package/dist/lib/DatePicker.svelte +246 -246
  19. package/dist/lib/Dialog.svelte +233 -233
  20. package/dist/lib/Field.svelte +299 -299
  21. package/dist/lib/FilePicker.svelte +295 -240
  22. package/dist/lib/FilePicker.svelte.d.ts +6 -1
  23. package/dist/lib/Form.svelte +438 -438
  24. package/dist/lib/Hamburger.svelte +217 -217
  25. package/dist/lib/InstallPWA.svelte +94 -94
  26. package/dist/lib/Menu.svelte +623 -623
  27. package/dist/lib/NoticeBase.svelte +140 -140
  28. package/dist/lib/PaginatedCard.svelte +73 -73
  29. package/dist/lib/Pagination.svelte +119 -119
  30. package/dist/lib/PrimaryColorSelect.svelte +111 -111
  31. package/dist/lib/ProgressBar.svelte +141 -141
  32. package/dist/lib/ProgressCircle.svelte +190 -190
  33. package/dist/lib/Radio.svelte +189 -189
  34. package/dist/lib/SearchInput.svelte +104 -104
  35. package/dist/lib/Select.svelte +524 -524
  36. package/dist/lib/Slider.svelte +253 -253
  37. package/dist/lib/Splitter.svelte +159 -150
  38. package/dist/lib/Switch.svelte +168 -167
  39. package/dist/lib/Table.svelte +299 -299
  40. package/dist/lib/Tabs.svelte +213 -213
  41. package/dist/lib/ThemeToggle.svelte +128 -127
  42. package/dist/lib/TimePicker.svelte +312 -312
  43. package/dist/lib/TimePickerNew.svelte +634 -0
  44. package/dist/lib/TimePickerNew.svelte.d.ts +49 -0
  45. package/dist/lib/Toast.svelte +123 -123
  46. package/dist/lib/Tooltip.svelte +110 -110
  47. package/dist/lib/Topbar.svelte +107 -107
  48. package/dist/lib/__tests__/Accordion.test.d.ts +1 -0
  49. package/dist/lib/__tests__/Accordion.test.js +171 -0
  50. package/dist/lib/__tests__/Badge.test.d.ts +1 -0
  51. package/dist/lib/__tests__/Badge.test.js +41 -0
  52. package/dist/lib/__tests__/Button.test.d.ts +1 -0
  53. package/dist/lib/__tests__/Button.test.js +269 -0
  54. package/dist/lib/__tests__/Calendar.test.d.ts +1 -0
  55. package/dist/lib/__tests__/Calendar.test.js +171 -0
  56. package/dist/lib/__tests__/Card.test.d.ts +1 -0
  57. package/dist/lib/__tests__/Card.test.js +148 -0
  58. package/dist/lib/__tests__/Carousel.test.d.ts +1 -0
  59. package/dist/lib/__tests__/Carousel.test.js +439 -0
  60. package/dist/lib/__tests__/CheckBox.test.d.ts +1 -0
  61. package/dist/lib/__tests__/CheckBox.test.js +152 -0
  62. package/dist/lib/__tests__/CodeView.test.d.ts +1 -0
  63. package/dist/lib/__tests__/CodeView.test.js +157 -0
  64. package/dist/lib/__tests__/ColorPicker.test.d.ts +1 -0
  65. package/dist/lib/__tests__/ColorPicker.test.js +93 -0
  66. package/dist/lib/__tests__/ContextMenu.test.d.ts +1 -0
  67. package/dist/lib/__tests__/ContextMenu.test.js +67 -0
  68. package/dist/lib/__tests__/DatePicker.test.d.ts +1 -0
  69. package/dist/lib/__tests__/DatePicker.test.js +108 -0
  70. package/dist/lib/__tests__/Dialog.test.d.ts +1 -0
  71. package/dist/lib/__tests__/Dialog.test.js +183 -0
  72. package/dist/lib/__tests__/Field.test.d.ts +1 -0
  73. package/dist/lib/__tests__/Field.test.js +190 -0
  74. package/dist/lib/__tests__/FilePicker.test.d.ts +1 -0
  75. package/dist/lib/__tests__/FilePicker.test.js +179 -0
  76. package/dist/lib/__tests__/Form.integration.test.d.ts +1 -0
  77. package/dist/lib/__tests__/Form.integration.test.js +158 -0
  78. package/dist/lib/__tests__/Form.test.d.ts +1 -0
  79. package/dist/lib/__tests__/Form.test.js +463 -0
  80. package/dist/lib/__tests__/Hamburger.test.d.ts +1 -0
  81. package/dist/lib/__tests__/Hamburger.test.js +161 -0
  82. package/dist/lib/__tests__/InstallPWA.test.d.ts +1 -0
  83. package/dist/lib/__tests__/InstallPWA.test.js +15 -0
  84. package/dist/lib/__tests__/Menu.test.d.ts +1 -0
  85. package/dist/lib/__tests__/Menu.test.js +285 -0
  86. package/dist/lib/__tests__/NoticeBase.test.d.ts +1 -0
  87. package/dist/lib/__tests__/NoticeBase.test.js +60 -0
  88. package/dist/lib/__tests__/PaginatedCard.test.d.ts +1 -0
  89. package/dist/lib/__tests__/PaginatedCard.test.js +89 -0
  90. package/dist/lib/__tests__/Pagination.test.d.ts +1 -0
  91. package/dist/lib/__tests__/Pagination.test.js +168 -0
  92. package/dist/lib/__tests__/PrimaryColorSelect.test.d.ts +1 -0
  93. package/dist/lib/__tests__/PrimaryColorSelect.test.js +92 -0
  94. package/dist/lib/__tests__/ProgressBar.test.d.ts +1 -0
  95. package/dist/lib/__tests__/ProgressBar.test.js +69 -0
  96. package/dist/lib/__tests__/ProgressCircle.test.d.ts +1 -0
  97. package/dist/lib/__tests__/ProgressCircle.test.js +71 -0
  98. package/dist/lib/__tests__/Radio.test.d.ts +1 -0
  99. package/dist/lib/__tests__/Radio.test.js +127 -0
  100. package/dist/lib/__tests__/SearchInput.test.d.ts +1 -0
  101. package/dist/lib/__tests__/SearchInput.test.js +80 -0
  102. package/dist/lib/__tests__/Select.test.d.ts +1 -0
  103. package/dist/lib/__tests__/Select.test.js +408 -0
  104. package/dist/lib/__tests__/Slider.test.d.ts +1 -0
  105. package/dist/lib/__tests__/Slider.test.js +213 -0
  106. package/dist/lib/__tests__/Splitter.test.d.ts +1 -0
  107. package/dist/lib/__tests__/Splitter.test.js +87 -0
  108. package/dist/lib/__tests__/Switch.test.d.ts +1 -0
  109. package/dist/lib/__tests__/Switch.test.js +97 -0
  110. package/dist/lib/__tests__/Table.test.d.ts +1 -0
  111. package/dist/lib/__tests__/Table.test.js +349 -0
  112. package/dist/lib/__tests__/Tabs.test.d.ts +1 -0
  113. package/dist/lib/__tests__/Tabs.test.js +262 -0
  114. package/dist/lib/__tests__/ThemeToggle.test.d.ts +1 -0
  115. package/dist/lib/__tests__/ThemeToggle.test.js +84 -0
  116. package/dist/lib/__tests__/TimePicker.test.d.ts +1 -0
  117. package/dist/lib/__tests__/TimePicker.test.js +146 -0
  118. package/dist/lib/__tests__/TimePickerNew.test.d.ts +1 -0
  119. package/dist/lib/__tests__/TimePickerNew.test.js +322 -0
  120. package/dist/lib/__tests__/Toast.test.d.ts +1 -0
  121. package/dist/lib/__tests__/Toast.test.js +135 -0
  122. package/dist/lib/__tests__/Tooltip.test.d.ts +1 -0
  123. package/dist/lib/__tests__/Tooltip.test.js +171 -0
  124. package/dist/lib/__tests__/Topbar.test.d.ts +1 -0
  125. package/dist/lib/__tests__/Topbar.test.js +25 -0
  126. package/dist/lib/__tests__/setupLangContext.d.ts +1 -0
  127. package/dist/lib/__tests__/setupLangContext.js +65 -0
  128. package/dist/lib/__tests__/storage.test.d.ts +1 -0
  129. package/dist/lib/__tests__/storage.test.js +124 -0
  130. package/dist/lib/__tests__/utils.test.d.ts +1 -0
  131. package/dist/lib/__tests__/utils.test.js +11 -0
  132. package/dist/lib/index.d.ts +1 -0
  133. package/dist/lib/index.js +1 -0
  134. package/dist/lib/lang.d.ts +4 -0
  135. package/dist/lib/lang.js +4 -0
  136. package/dist/styles.css +234 -232
  137. package/dist/utils/index.js +15 -4
  138. package/package.json +52 -52
@@ -1,111 +1,111 @@
1
- <!-- src/lib/PrimaryColorSelect.svelte -->
2
- <script lang="ts">
3
- /**
4
- * @component PrimaryColorSelect
5
- * @description Theme primary-color selector built on top of Select. Provides a fixed palette,
6
- * handles persistence, and updates the global <html> attribute.
7
- *
8
- * @prop sz {SizeKey} - Sizing preset passed directly to Select
9
- * @options xs|sm|md|lg|xl
10
- * @default sm
11
- *
12
- * @prop label {string} - Custom label text. Falls back to localized copy when omitted.
13
- *
14
- * @prop class {string} - Extra classes forwarded to the underlying Select component
15
- * @default ""
16
- *
17
- * @note The palette is predefined internally (`{ value, label, swatch }`).
18
- * @note Selected value is stored in localStorage under "primary".
19
- * @note The `html` element receives `data-primary="{value}"` for theme styling.
20
- * @note Uses the same onChange contract as Select and forwards palette options as-is.
21
- */
22
- import Select from "./Select.svelte";
23
- import type { PrimaryKey, PaletteOption, SizeKey } from "./types";
24
- import { getComponentText, getLangContext, getLangKey } from "./lang-context";
25
-
26
- type Props = {
27
- sz?: SizeKey;
28
- label?: string;
29
- class?: string;
30
- };
31
-
32
- let { sz = "sm", label, class: externalClass = "" }: Props = $props();
33
-
34
- const langCtx = getLangContext();
35
- const langKey = $derived(getLangKey(langCtx));
36
- const L = $derived(getComponentText("primaryColorSelect", langKey));
37
-
38
- const labelFinal = $derived(label ?? L.text);
39
-
40
- const palette: PaletteOption[] = [
41
- {
42
- value: "default",
43
- label: "Indigo",
44
- swatch: "oklch(62.3% 0.214 259.8deg)",
45
- },
46
- { value: "cyan", label: "Cyan", swatch: "oklch(71.5% 0.143 215.221)" },
47
- { value: "red", label: "Red", swatch: "oklch(58% 0.24 30deg)" },
48
- { value: "green", label: "Green", swatch: "oklch(65% 0.22 140deg)" },
49
- { value: "yellow", label: "Yellow", swatch: "oklch(75% 0.18 90deg)" },
50
- { value: "pink", label: "Pink", swatch: "oklch(70% 0.25 350deg)" },
51
- { value: "orange", label: "Orange", swatch: "oklch(72% 0.22 60deg)" },
52
- { value: "purple", label: "Purple", swatch: "oklch(55% 0.22 290deg)" },
53
- ];
54
-
55
- const paletteMap = palette.reduce<Record<PrimaryKey, PaletteOption>>(
56
- (acc, option) => {
57
- acc[option.value] = option;
58
- return acc;
59
- },
60
- {} as Record<PrimaryKey, PaletteOption>
61
- );
62
-
63
- let selected = $state<PrimaryKey>("default");
64
- let mounted = $state(false);
65
-
66
- function isPrimaryKey(value: unknown): value is PrimaryKey {
67
- return typeof value === "string" && value in paletteMap;
68
- }
69
-
70
- $effect(() => {
71
- if (!mounted) {
72
- try {
73
- if (typeof window !== "undefined") {
74
- const saved = localStorage.getItem("primary");
75
- if (isPrimaryKey(saved)) {
76
- selected = saved;
77
- }
78
- }
79
- } catch {
80
- // ignore unavailable storage/environment
81
- }
82
- mounted = true;
83
- }
84
- });
85
-
86
- $effect(() => {
87
- if (mounted) {
88
- try {
89
- if (typeof document !== "undefined") {
90
- document.documentElement.setAttribute("data-primary", selected);
91
- }
92
- if (typeof window !== "undefined") {
93
- localStorage.setItem("primary", selected);
94
- }
95
- } catch {
96
- // ignore unavailable storage/environment
97
- }
98
- }
99
- });
100
- </script>
101
-
102
- <Select
103
- {sz}
104
- label={labelFinal}
105
- options={palette}
106
- value={selected}
107
- onChange={(v) => {
108
- if (isPrimaryKey(v)) selected = v;
109
- }}
110
- class={externalClass}
111
- />
1
+ <!-- src/lib/PrimaryColorSelect.svelte -->
2
+ <script lang="ts">
3
+ /**
4
+ * @component PrimaryColorSelect
5
+ * @description Theme primary-color selector built on top of Select. Provides a fixed palette,
6
+ * handles persistence, and updates the global <html> attribute.
7
+ *
8
+ * @prop sz {SizeKey} - Sizing preset passed directly to Select
9
+ * @options xs|sm|md|lg|xl
10
+ * @default sm
11
+ *
12
+ * @prop label {string} - Custom label text. Falls back to localized copy when omitted.
13
+ *
14
+ * @prop class {string} - Extra classes forwarded to the underlying Select component
15
+ * @default ""
16
+ *
17
+ * @note The palette is predefined internally (`{ value, label, swatch }`).
18
+ * @note Selected value is stored in localStorage under "primary".
19
+ * @note The `html` element receives `data-primary="{value}"` for theme styling.
20
+ * @note Uses the same onChange contract as Select and forwards palette options as-is.
21
+ */
22
+ import Select from "./Select.svelte";
23
+ import type { PrimaryKey, PaletteOption, SizeKey } from "./types";
24
+ import { getComponentText, getLangContext, getLangKey } from "./lang-context";
25
+
26
+ type Props = {
27
+ sz?: SizeKey;
28
+ label?: string;
29
+ class?: string;
30
+ };
31
+
32
+ let { sz = "sm", label, class: externalClass = "" }: Props = $props();
33
+
34
+ const langCtx = getLangContext();
35
+ const langKey = $derived(getLangKey(langCtx));
36
+ const L = $derived(getComponentText("primaryColorSelect", langKey));
37
+
38
+ const labelFinal = $derived(label ?? L.text);
39
+
40
+ const palette: PaletteOption[] = [
41
+ {
42
+ value: "default",
43
+ label: "Indigo",
44
+ swatch: "oklch(62.3% 0.214 259.8deg)",
45
+ },
46
+ { value: "cyan", label: "Cyan", swatch: "oklch(71.5% 0.143 215.221)" },
47
+ { value: "red", label: "Red", swatch: "oklch(58% 0.24 30deg)" },
48
+ { value: "green", label: "Green", swatch: "oklch(65% 0.22 140deg)" },
49
+ { value: "yellow", label: "Yellow", swatch: "oklch(75% 0.18 90deg)" },
50
+ { value: "pink", label: "Pink", swatch: "oklch(70% 0.25 350deg)" },
51
+ { value: "orange", label: "Orange", swatch: "oklch(72% 0.22 60deg)" },
52
+ { value: "purple", label: "Purple", swatch: "oklch(55% 0.22 290deg)" },
53
+ ];
54
+
55
+ const paletteMap = palette.reduce<Record<PrimaryKey, PaletteOption>>(
56
+ (acc, option) => {
57
+ acc[option.value] = option;
58
+ return acc;
59
+ },
60
+ {} as Record<PrimaryKey, PaletteOption>
61
+ );
62
+
63
+ let selected = $state<PrimaryKey>("default");
64
+ let mounted = $state(false);
65
+
66
+ function isPrimaryKey(value: unknown): value is PrimaryKey {
67
+ return typeof value === "string" && value in paletteMap;
68
+ }
69
+
70
+ $effect(() => {
71
+ if (!mounted) {
72
+ try {
73
+ if (typeof window !== "undefined") {
74
+ const saved = localStorage.getItem("primary");
75
+ if (isPrimaryKey(saved)) {
76
+ selected = saved;
77
+ }
78
+ }
79
+ } catch {
80
+ // ignore unavailable storage/environment
81
+ }
82
+ mounted = true;
83
+ }
84
+ });
85
+
86
+ $effect(() => {
87
+ if (mounted) {
88
+ try {
89
+ if (typeof document !== "undefined") {
90
+ document.documentElement.setAttribute("data-primary", selected);
91
+ }
92
+ if (typeof window !== "undefined") {
93
+ localStorage.setItem("primary", selected);
94
+ }
95
+ } catch {
96
+ // ignore unavailable storage/environment
97
+ }
98
+ }
99
+ });
100
+ </script>
101
+
102
+ <Select
103
+ {sz}
104
+ label={labelFinal}
105
+ options={palette}
106
+ value={selected}
107
+ onChange={(v) => {
108
+ if (isPrimaryKey(v)) selected = v;
109
+ }}
110
+ class={externalClass}
111
+ />
@@ -1,141 +1,141 @@
1
- <!-- src/lib/ProgressBar.svelte -->
2
- <script lang="ts">
3
- /**
4
- * @component ProgressBar
5
- * @description A simple and accessible progress bar component that visually represents task completion.
6
- *
7
- * @prop value {number} - Current progress value from 0 to 100
8
- * @default 0
9
- *
10
- * @prop indeterminate {boolean} - Enables the animated indeterminate state
11
- * @default false
12
- *
13
- * @prop sz {SizeKey} - Controls the bar height
14
- * @options xs|sm|md|lg|xl
15
- * @default md
16
- *
17
- * @prop variant {ComponentVariant} - Visual style of the progress bar
18
- * @options default|neutral
19
- * @default default
20
- *
21
- * @prop class {string} - Additional CSS classes for the wrapper element
22
- * @default ""
23
- *
24
- * @prop label {string} - Optional text label displayed above the bar
25
- * @default ""
26
- *
27
- * @prop disabled {boolean} - Applies a muted inactive visual style
28
- * @default false
29
- *
30
- * @note Indeterminate animation for unknown progress.
31
- * @note Auto-clamping between 0 and 100.
32
- * @note Adaptive height based on size.
33
- * @note Theming support via CSS variables.
34
- * @note Fully accessible with proper `aria` roles.
35
- * @note No invalid ARIA attributes.
36
- */
37
- import type { HTMLAttributes } from "svelte/elements";
38
- import { type SizeKey, type ComponentVariant, TEXT } from "./types";
39
- import { cx, clamp } from "../utils";
40
-
41
- type Props = HTMLAttributes<HTMLDivElement> & {
42
- value?: number;
43
- indeterminate?: boolean;
44
- sz?: SizeKey;
45
- variant?: ComponentVariant;
46
- class?: string;
47
- label?: string;
48
- disabled?: boolean;
49
- };
50
-
51
- let {
52
- value = 0,
53
- indeterminate = false,
54
- sz = "md",
55
- variant = "default",
56
- class: externalClass = "",
57
- label = "",
58
- disabled = false,
59
- ...rest
60
- }: Props = $props();
61
-
62
- const pct = $derived(`${clamp(value, 0, 100)}%`);
63
-
64
- const sizeTrack = $derived(
65
- {
66
- xs: "h-[4px]",
67
- sm: "h-[5px]",
68
- md: "h-[6px]",
69
- lg: "h-[7px]",
70
- xl: "h-[8px]",
71
- }[sz]
72
- );
73
-
74
- const bar = $derived(
75
- variant === "neutral"
76
- ? "bg-[var(--color-bg-secondary)]"
77
- : "bg-[var(--color-bg-primary)]"
78
- );
79
-
80
- const rootClass = $derived(
81
- cx(
82
- "relative flex flex-col gap-1 w-full data-[disabled=true]:opacity-[var(--opacity-disabled)] data-[disabled=true]:cursor-not-allowed",
83
- externalClass
84
- )
85
- );
86
-
87
- const trackClass = $derived(
88
- cx(
89
- "absolute top-1/2 -translate-y-1/2 w-full bg-[var(--border-color-default)] rounded overflow-hidden",
90
- sizeTrack
91
- )
92
- );
93
-
94
- const barClass = $derived(cx("h-full", bar));
95
- </script>
96
-
97
- <div
98
- class={rootClass}
99
- role="progressbar"
100
- aria-valuemin="0"
101
- aria-valuemax="100"
102
- aria-valuenow={indeterminate ? undefined : Math.round(clamp(value, 0, 100))}
103
- data-disabled={disabled ? "true" : undefined}
104
- {...rest}
105
- >
106
- {#if label}
107
- <span class={cx("text-[var(--color-text-muted)] select-none", TEXT[sz])}>
108
- {label}
109
- </span>
110
- {/if}
111
-
112
- <div class="relative w-full h-10">
113
- <div class={trackClass}>
114
- {#if indeterminate}
115
- <div class={cx(barClass, "pb-indet")}></div>
116
- {:else}
117
- <div
118
- class={cx(barClass, "transition-[width]")}
119
- style={`width:${pct}`}
120
- ></div>
121
- {/if}
122
- </div>
123
- </div>
124
- </div>
125
-
126
- <style>
127
- :global {
128
- @keyframes pb-indeterminate {
129
- 0% {
130
- transform: translateX(-100%);
131
- }
132
- 100% {
133
- transform: translateX(250%);
134
- }
135
- }
136
- }
137
- .pb-indet {
138
- width: 40%;
139
- animation: pb-indeterminate 2s linear infinite;
140
- }
141
- </style>
1
+ <!-- src/lib/ProgressBar.svelte -->
2
+ <script lang="ts">
3
+ /**
4
+ * @component ProgressBar
5
+ * @description A simple and accessible progress bar component that visually represents task completion.
6
+ *
7
+ * @prop value {number} - Current progress value from 0 to 100
8
+ * @default 0
9
+ *
10
+ * @prop indeterminate {boolean} - Enables the animated indeterminate state
11
+ * @default false
12
+ *
13
+ * @prop sz {SizeKey} - Controls the bar height
14
+ * @options xs|sm|md|lg|xl
15
+ * @default md
16
+ *
17
+ * @prop variant {ComponentVariant} - Visual style of the progress bar
18
+ * @options default|neutral
19
+ * @default default
20
+ *
21
+ * @prop class {string} - Additional CSS classes for the wrapper element
22
+ * @default ""
23
+ *
24
+ * @prop label {string} - Optional text label displayed above the bar
25
+ * @default ""
26
+ *
27
+ * @prop disabled {boolean} - Applies a muted inactive visual style
28
+ * @default false
29
+ *
30
+ * @note Indeterminate animation for unknown progress.
31
+ * @note Auto-clamping between 0 and 100.
32
+ * @note Adaptive height based on size.
33
+ * @note Theming support via CSS variables.
34
+ * @note Fully accessible with proper `aria` roles.
35
+ * @note No invalid ARIA attributes.
36
+ */
37
+ import type { HTMLAttributes } from "svelte/elements";
38
+ import { type SizeKey, type ComponentVariant, TEXT } from "./types";
39
+ import { cx, clamp } from "../utils";
40
+
41
+ type Props = HTMLAttributes<HTMLDivElement> & {
42
+ value?: number;
43
+ indeterminate?: boolean;
44
+ sz?: SizeKey;
45
+ variant?: ComponentVariant;
46
+ class?: string;
47
+ label?: string;
48
+ disabled?: boolean;
49
+ };
50
+
51
+ let {
52
+ value = 0,
53
+ indeterminate = false,
54
+ sz = "md",
55
+ variant = "default",
56
+ class: externalClass = "",
57
+ label = "",
58
+ disabled = false,
59
+ ...rest
60
+ }: Props = $props();
61
+
62
+ const pct = $derived(`${clamp(value, 0, 100)}%`);
63
+
64
+ const sizeTrack = $derived(
65
+ {
66
+ xs: "h-[4px]",
67
+ sm: "h-[5px]",
68
+ md: "h-[6px]",
69
+ lg: "h-[7px]",
70
+ xl: "h-[8px]",
71
+ }[sz]
72
+ );
73
+
74
+ const bar = $derived(
75
+ variant === "neutral"
76
+ ? "bg-[var(--color-bg-secondary)]"
77
+ : "bg-[var(--color-bg-primary)]"
78
+ );
79
+
80
+ const rootClass = $derived(
81
+ cx(
82
+ "relative flex flex-col gap-1 w-full data-[disabled=true]:opacity-[var(--opacity-disabled)] data-[disabled=true]:cursor-not-allowed",
83
+ externalClass
84
+ )
85
+ );
86
+
87
+ const trackClass = $derived(
88
+ cx(
89
+ "absolute top-1/2 -translate-y-1/2 w-full bg-[var(--border-color-default)] rounded overflow-hidden",
90
+ sizeTrack
91
+ )
92
+ );
93
+
94
+ const barClass = $derived(cx("h-full", bar));
95
+ </script>
96
+
97
+ <div
98
+ class={rootClass}
99
+ role="progressbar"
100
+ aria-valuemin="0"
101
+ aria-valuemax="100"
102
+ aria-valuenow={indeterminate ? undefined : Math.round(clamp(value, 0, 100))}
103
+ data-disabled={disabled ? "true" : undefined}
104
+ {...rest}
105
+ >
106
+ {#if label}
107
+ <span class={cx("text-[var(--color-text-muted)] select-none", TEXT[sz])}>
108
+ {label}
109
+ </span>
110
+ {/if}
111
+
112
+ <div class="relative w-full h-10">
113
+ <div class={trackClass}>
114
+ {#if indeterminate}
115
+ <div class={cx(barClass, "pb-indet")}></div>
116
+ {:else}
117
+ <div
118
+ class={cx(barClass, "transition-[width]")}
119
+ style={`width:${pct}`}
120
+ ></div>
121
+ {/if}
122
+ </div>
123
+ </div>
124
+ </div>
125
+
126
+ <style>
127
+ :global {
128
+ @keyframes pb-indeterminate {
129
+ 0% {
130
+ transform: translateX(-100%);
131
+ }
132
+ 100% {
133
+ transform: translateX(250%);
134
+ }
135
+ }
136
+ }
137
+ .pb-indet {
138
+ width: 40%;
139
+ animation: pb-indeterminate 2s linear infinite;
140
+ }
141
+ </style>