@studiocms/ui 1.0.0-beta.0 → 1.0.0-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 (56) hide show
  1. package/dist/components/Accordion/accordion.css +6 -6
  2. package/dist/components/Badge/Badge.astro +12 -3
  3. package/dist/components/Badge/badge.css +15 -45
  4. package/dist/components/Breadcrumbs/breadcrumbs.css +2 -2
  5. package/dist/components/Center/Center.astro +1 -1
  6. package/dist/components/Checkbox/Checkbox.astro +6 -5
  7. package/dist/components/Checkbox/checkbox.css +9 -9
  8. package/dist/components/Checkbox/checkbox.js +1 -0
  9. package/dist/components/Dropdown/dropdown.css +12 -12
  10. package/dist/components/Footer/footer.css +4 -0
  11. package/dist/components/Group/group.css +12 -6
  12. package/dist/components/Icon/Icon.astro +14 -6
  13. package/dist/components/Icon/IconBase.astro +2 -0
  14. package/dist/components/Input/Input.astro +57 -13
  15. package/dist/components/Input/input.css +30 -4
  16. package/dist/components/Modal/modal.css +4 -4
  17. package/dist/components/Progress/Progress.astro +3 -2
  18. package/dist/components/Progress/progress.css +1 -1
  19. package/dist/components/RadioGroup/RadioGroup.astro +1 -1
  20. package/dist/components/RadioGroup/radiogroup.css +9 -9
  21. package/dist/components/RadioGroup/radiogroup.js +0 -2
  22. package/dist/components/Row/row.css +1 -1
  23. package/dist/components/SearchSelect/SearchSelect.astro +8 -4
  24. package/dist/components/SearchSelect/searchselect.css +3 -7
  25. package/dist/components/SearchSelect/searchselect.js +13 -6
  26. package/dist/components/Select/select.css +1 -5
  27. package/dist/components/Select/select.js +3 -3
  28. package/dist/components/Skeleton/skeleton.d.ts +6 -70
  29. package/dist/components/Tabs/TabItem.astro +8 -2
  30. package/dist/components/Tabs/Tabs.astro +8 -2
  31. package/dist/components/Tabs/tabs.css +2 -2
  32. package/dist/components/Textarea/textarea.css +4 -4
  33. package/dist/components/Toast/Toaster.astro +4 -4
  34. package/dist/components/Toast/toaster.css +9 -9
  35. package/dist/components/Toast/toaster.js +2 -2
  36. package/dist/components/Toggle/Toggle.astro +2 -2
  37. package/dist/components/Toggle/toggle.css +7 -7
  38. package/dist/components/Toggle/toggle.js +1 -0
  39. package/dist/components/User/User.astro +1 -1
  40. package/dist/components/User/user.css +2 -2
  41. package/dist/css/colors.css +63 -53
  42. package/dist/index.d.ts +7 -0
  43. package/dist/index.js +31 -41
  44. package/dist/toolbar/ColorPicker.js +4 -64
  45. package/dist/toolbar/icon.js +1 -1
  46. package/dist/toolbar/index.js +4 -4
  47. package/dist/utils/headers.d.ts +54 -8
  48. package/dist/utils/headers.js +8 -1
  49. package/dist/utils/stubs/icons-d-ts.stub +9 -0
  50. package/dist/utils/typegen.d.ts +6 -0
  51. package/dist/utils/typegen.js +14 -0
  52. package/package.json +16 -5
  53. package/dist/events.d.js +0 -0
  54. package/dist/utils/integration-utils.d.ts +0 -130
  55. package/dist/utils/integration-utils.js +0 -161
  56. package/dist/virtuals.d.js +0 -0
@@ -3,7 +3,7 @@
3
3
  border-radius: var(--radius-md);
4
4
  padding: 1.5rem;
5
5
  box-shadow: 0px 4px 8px var(--shadow);
6
- animation: hide .25s ease;
6
+ animation: hide 0.25s ease;
7
7
  overflow: visible;
8
8
  margin: auto;
9
9
  z-index: 50;
@@ -19,7 +19,7 @@
19
19
  width: 608px;
20
20
  }
21
21
  .sui-modal[open] {
22
- animation: show .25s ease-in-out;
22
+ animation: show 0.25s ease-in-out;
23
23
  }
24
24
  html:has(.sui-modal[open]),
25
25
  body:has(.sui-modal[open]) {
@@ -27,7 +27,7 @@ body:has(.sui-modal[open]) {
27
27
  }
28
28
  .sui-modal[open]::backdrop {
29
29
  background-color: rgba(0, 0, 0, 0.75);
30
- animation: backdrop .3s ease-in-out forwards;
30
+ animation: backdrop 0.3s ease-in-out forwards;
31
31
  }
32
32
  .sui-modal-header:has(*) {
33
33
  margin-bottom: 1rem;
@@ -46,7 +46,7 @@ body:has(.sui-modal[open]) {
46
46
  display: flex;
47
47
  align-items: center;
48
48
  justify-content: center;
49
- transition: background-color .15s ease;
49
+ transition: background-color 0.15s ease;
50
50
  border-radius: var(--radius-sm);
51
51
  }
52
52
  .x-mark-container:hover {
@@ -5,15 +5,16 @@ import type { HTMLAttributes } from 'astro/types';
5
5
 
6
6
  type Props = {
7
7
  id: string;
8
+ label: string;
8
9
  value?: number;
9
10
  max?: number;
10
11
  color?: Omit<StudioCMSColorway, 'default'>;
11
12
  } & HTMLAttributes<'div'>;
12
13
 
13
- const { id, value = 0, max = 100, color = 'primary' } = Astro.props;
14
+ const { id, label, value = 0, max = 100, color = 'primary' } = Astro.props;
14
15
  ---
15
16
 
16
- <div class="sui-progress" class:list={[color]} role="progressbar" id={id} data-max={max} data-value={value}>
17
+ <div class="sui-progress" class:list={[color]} role="progressbar" aria-label={label} id={id} data-max={max} data-value={value}>
17
18
  <div class="sui-progress-slider" />
18
19
  </div>
19
20
  <script>
@@ -8,7 +8,7 @@
8
8
  .sui-progress-slider {
9
9
  height: 100%;
10
10
  width: 0;
11
- transition: all .75s ease;
11
+ transition: all 0.75s ease;
12
12
  border-radius: var(--radius-sm);
13
13
  background-color: var(--primary-base);
14
14
  }
@@ -94,7 +94,7 @@ const {
94
94
  for={value}
95
95
  class="sui-radio-label"
96
96
  class:list={[ individuallyDisabled && "disabled" ]}
97
- >
97
+ >
98
98
  <div class="sui-radio-box-container">
99
99
  <div
100
100
  class="sui-radio-box"
@@ -1,7 +1,7 @@
1
1
  .sui-radio-container {
2
2
  display: flex;
3
3
  flex-direction: column;
4
- gap: .5rem;
4
+ gap: 0.5rem;
5
5
  }
6
6
  .sui-radio-container.disabled {
7
7
  opacity: 0.5;
@@ -13,13 +13,13 @@
13
13
  pointer-events: none;
14
14
  }
15
15
  .req-star {
16
- color: var(--danger-base);
16
+ color: var(--danger-vibrant);
17
17
  font-weight: 700;
18
18
  }
19
19
  .sui-radio-inputs {
20
20
  display: flex;
21
21
  flex-direction: column;
22
- gap: .75rem;
22
+ gap: 0.75rem;
23
23
  }
24
24
  .sui-radio-container.horizontal .sui-radio-inputs {
25
25
  flex-direction: row;
@@ -27,7 +27,7 @@
27
27
  .sui-radio-label {
28
28
  display: flex;
29
29
  flex-direction: row;
30
- gap: .5rem;
30
+ gap: 0.5rem;
31
31
  position: relative;
32
32
  align-items: center;
33
33
  }
@@ -55,12 +55,12 @@
55
55
  outline-color: var(--warning-base);
56
56
  }
57
57
  .sui-radio-container.danger .sui-radio-label:has(.sui-radio-toggle:checked) .sui-radio-box {
58
- background-color: var(--danger-base);
59
- outline-color: var(--danger-base);
58
+ background-color: var(--danger-vibrant);
59
+ outline-color: var(--danger-vibrant);
60
60
  }
61
61
  .sui-radio-container.info .sui-radio-label:has(.sui-radio-toggle:checked) .sui-radio-box {
62
- background-color: var(--info-base);
63
- outline-color: var(--info-base);
62
+ background-color: var(--info-vibrant);
63
+ outline-color: var(--info-vibrant);
64
64
  }
65
65
  .sui-radio-container.mono .sui-radio-label:has(.sui-radio-toggle:checked) .sui-radio-box {
66
66
  background-color: var(--mono-base);
@@ -81,7 +81,7 @@
81
81
  border-radius: var(--radius-full);
82
82
  outline: 1px solid var(--default-base);
83
83
  outline-offset: 4px;
84
- transition: all .15s ease;
84
+ transition: all 0.15s ease;
85
85
  }
86
86
  .sui-radio-box:focus-visible {
87
87
  outline-color: var(--text-normal) !important;
@@ -4,7 +4,6 @@ function loadRadioGroups() {
4
4
  if (element.dataset.initialized) continue;
5
5
  element.dataset.initialized = "true";
6
6
  const radioBoxes = element.querySelectorAll(".sui-radio-box");
7
- let i = 0;
8
7
  for (const radioBox of radioBoxes) {
9
8
  radioBox.addEventListener("keydown", (e) => {
10
9
  if (e.key === "Enter" || e.key === " ") {
@@ -38,7 +37,6 @@ function loadRadioGroups() {
38
37
  previousRadioBox.click();
39
38
  }
40
39
  });
41
- i++;
42
40
  }
43
41
  element.addEventListener("keydown", (e) => {
44
42
  if (e.key !== "Enter") return;
@@ -8,7 +8,7 @@
8
8
  align-items: center;
9
9
  }
10
10
  .sui-row.sm {
11
- gap: .5rem;
11
+ gap: 0.5rem;
12
12
  }
13
13
  .sui-row.md {
14
14
  gap: 1rem;
@@ -151,8 +151,12 @@ const defaultLabel = selected
151
151
  tabindex={disabled ? -1 : 0}
152
152
  label={label || ''}
153
153
  isRequired={isRequired || false}
154
+ name={name ? `${name}-input` : undefined}
155
+ icon={{
156
+ name: "heroicons:chevron-up-down",
157
+ position: "right"
158
+ }}
154
159
  />
155
- <Icon name="heroicons:chevron-up-down" class="sui-search-select-indicator" width={24} height={24} />
156
160
  </div>
157
161
  <div class="sui-search-select-dropdown">
158
162
  <ul class="sui-search-select-dropdown-list" role="listbox" id={`${name}-dropdown`}>
@@ -189,7 +193,7 @@ const defaultLabel = selected
189
193
  const isSelected = Array.isArray(selected)
190
194
  ? selected.map((y) => y && y.value).includes(x.value)
191
195
  : selected?.value === x.value;
192
-
196
+
193
197
  return (
194
198
  <option
195
199
  value={x.value}
@@ -208,10 +212,10 @@ const defaultLabel = selected
208
212
  </span>
209
213
  )}
210
214
  {
211
- multiple && Array.isArray(selected ?? []) && (
215
+ multiple && Array.isArray(selected ?? []) && (
212
216
  <div class="sui-search-select-badge-container">
213
217
  {
214
- ((selected ?? []) as SearchSelectOption[]).map((s) => s &&
218
+ ((selected ?? []) as SearchSelectOption[]).map((s) => s &&
215
219
  <Badge class="sui-search-select-badge" data-value={s.value} size="sm" label={s.label} iconPosition="right" icon="heroicons:x-mark" />
216
220
  )
217
221
  }
@@ -18,7 +18,7 @@
18
18
  font-size: 14px;
19
19
  }
20
20
  .req-star {
21
- color: var(--danger-base);
21
+ color: var(--danger-vibrant);
22
22
  font-weight: 700;
23
23
  }
24
24
  .sui-search-select-dropdown-container {
@@ -32,13 +32,10 @@
32
32
  .sui-search-select-dropdown {
33
33
  position: absolute;
34
34
  width: 100%;
35
- border: 1px solid var(--border);
36
35
  list-style: none;
37
36
  margin: 0;
38
37
  padding: 0;
39
38
  flex-direction: column;
40
- border-radius: var(--radius-md);
41
- background-color: var(--background-step-2);
42
39
  overflow: hidden;
43
40
  top: calc(100% + 0.25rem);
44
41
  left: 0;
@@ -115,8 +112,8 @@
115
112
  }
116
113
  .sui-search-select-indicator {
117
114
  position: absolute;
118
- bottom: .675rem;
119
- right: .675rem;
115
+ bottom: 0.675rem;
116
+ right: 0.675rem;
120
117
  }
121
118
  .sui-search-input-wrapper:has(input:focus) + .sui-search-select-dropdown {
122
119
  display: flex;
@@ -141,7 +138,6 @@
141
138
  cursor: default;
142
139
  position: relative;
143
140
  padding-right: 2rem;
144
- border-block: 1.5px solid rgba(0, 0, 0, 0);
145
141
  }
146
142
  .sui-search-select-badge-container .sui-search-select-badge.sui-badge svg {
147
143
  position: absolute;
@@ -25,7 +25,14 @@ function loadSearchSelects() {
25
25
  };
26
26
  const createSelectBadge = (value, label) => {
27
27
  const badge = document.createElement("span");
28
- badge.classList.add("sui-badge", "primary", "sm", "default", "full", "sui-search-select-badge");
28
+ badge.classList.add(
29
+ "sui-badge",
30
+ "primary",
31
+ "sm",
32
+ "outlined",
33
+ "full",
34
+ "sui-search-select-badge"
35
+ );
29
36
  badge.setAttribute("data-value", value);
30
37
  badge.innerHTML = `${label} <svg style='min-width: 8px' xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 24 24' role="button" tabindex="0"><path fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 18L18 6M6 6l12 12'></path></svg>`;
31
38
  return badge;
@@ -41,8 +48,8 @@ function loadSearchSelects() {
41
48
  return;
42
49
  }
43
50
  for (const value of selectedValues.sort((a, b) => {
44
- const numA = Number.parseInt(a.match(/\d+/)?.[0] || "0");
45
- const numB = Number.parseInt(b.match(/\d+/)?.[0] || "0");
51
+ const numA = Number.parseInt(a.match(/\d+/)?.[0] || "0", 10);
52
+ const numB = Number.parseInt(b.match(/\d+/)?.[0] || "0", 10);
46
53
  return numA - numB;
47
54
  })) {
48
55
  const option = allOptions.find((opt) => opt.value === value);
@@ -71,7 +78,7 @@ function loadSearchSelects() {
71
78
  const updateOptionSelection = (value, container, state2, forceState) => {
72
79
  const currentSelected = state2.selectedOptionsMap[container.dataset.id] || [];
73
80
  const isCurrentlySelected = currentSelected.includes(value);
74
- const max = Number.parseInt(container.dataset.multipleMax);
81
+ const max = Number.parseInt(container.dataset.multipleMax, 10);
75
82
  if (!isCurrentlySelected && !Number.isNaN(max) && currentSelected.length >= max) {
76
83
  return false;
77
84
  }
@@ -105,7 +112,7 @@ function loadSearchSelects() {
105
112
  ".sui-search-select-option"
106
113
  );
107
114
  for (const entry of optionElements) {
108
- if (Number.parseInt(entry.dataset.optionIndex) === state2.focusIndex) {
115
+ if (Number.parseInt(entry.dataset.optionIndex, 10) === state2.focusIndex) {
109
116
  entry.classList.add("focused");
110
117
  } else {
111
118
  entry.classList.remove("focused");
@@ -279,7 +286,7 @@ function loadSearchSelects() {
279
286
  ".sui-search-select-option"
280
287
  );
281
288
  const focusedOption = Array.from(optionElements).find(
282
- (entry) => Number.parseInt(entry.dataset.optionIndex) === state2.focusIndex
289
+ (entry) => Number.parseInt(entry.dataset.optionIndex, 10) === state2.focusIndex
283
290
  );
284
291
  if (focusedOption && !focusedOption.classList.contains("disabled") && !focusedOption.hasAttribute("disabled")) {
285
292
  const value = focusedOption.dataset.value;
@@ -20,7 +20,7 @@
20
20
  font-size: 14px;
21
21
  }
22
22
  .req-star {
23
- color: var(--danger-base);
23
+ color: var(--danger-vibrant);
24
24
  font-weight: 700;
25
25
  }
26
26
  .sui-select-button {
@@ -70,13 +70,10 @@
70
70
  .sui-select-dropdown {
71
71
  position: absolute;
72
72
  width: 100%;
73
- border: 1px solid var(--border);
74
73
  list-style: none;
75
74
  margin: 0;
76
75
  padding: 0;
77
76
  flex-direction: column;
78
- border-radius: var(--radius-md);
79
- background-color: var(--background-step-2);
80
77
  overflow: hidden;
81
78
  top: calc(100% + 0.25rem);
82
79
  left: 0;
@@ -167,7 +164,6 @@
167
164
  cursor: default;
168
165
  position: relative;
169
166
  padding-right: 2rem;
170
- border-block: 1.5px solid rgba(0, 0, 0, 0);
171
167
  }
172
168
  .sui-select-badge-container .sui-select-badge.sui-badge svg {
173
169
  position: absolute;
@@ -62,7 +62,7 @@ function loadSelects() {
62
62
  };
63
63
  const createSelectBadge = (value, label) => {
64
64
  const badge = document.createElement("span");
65
- badge.classList.add("sui-badge", "primary", "sm", "default", "full", "sui-select-badge");
65
+ badge.classList.add("sui-badge", "primary", "sm", "outlined", "full", "sui-select-badge");
66
66
  badge.setAttribute("data-value", value);
67
67
  badge.innerHTML = `${label} <svg style='min-width: 8px' xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 24 24'><path fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 18L18 6M6 6l12 12'></path></svg>`;
68
68
  return badge;
@@ -139,7 +139,7 @@ function loadSelects() {
139
139
  const selectOpt = container?.dropdown?.querySelector(
140
140
  `.sui-select-option[value='${id}']`
141
141
  );
142
- const max = Number.parseInt(container?.dataset.multipleMax);
142
+ const max = Number.parseInt(container?.dataset.multipleMax, 10);
143
143
  const selectedCount = container?.querySelectorAll(".sui-select-option.selected").length ?? 0;
144
144
  const selectedCountEl = container?.querySelector(
145
145
  ".sui-select-max-span .sui-select-select-count"
@@ -164,7 +164,7 @@ function loadSelects() {
164
164
  ".sui-select-option"
165
165
  );
166
166
  for (const entry of optionElements) {
167
- if (Number.parseInt(entry.dataset.optionIndex) === state2.focusIndex) {
167
+ if (Number.parseInt(entry.dataset.optionIndex, 10) === state2.focusIndex) {
168
168
  entry.classList.add("focused");
169
169
  } else {
170
170
  entry.classList.remove("focused");
@@ -38,53 +38,19 @@ export declare const SkeletonSchema: z.ZodUnion<[z.ZodObject<{
38
38
  class?: string | undefined;
39
39
  radius?: "sm" | "none" | "md" | "lg" | undefined;
40
40
  animation?: "none" | "slide" | "pulse" | undefined;
41
- }>, z.ZodObject<z.objectUtil.extendShape<{
42
- /**
43
- * The variant of the skeleton.
44
- */
45
- variant: z.ZodLiteral<"text">;
46
- /**
47
- * The class of the skeleton. Defaults to `undefined`.
48
- */
41
+ }>, z.ZodObject<{
49
42
  class: z.ZodOptional<z.ZodString>;
50
- /**
51
- * The radius of the skeleton. Defaults to `lg`.
52
- */
53
43
  radius: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"none">, z.ZodLiteral<"sm">, z.ZodLiteral<"md">, z.ZodLiteral<"lg">]>>;
54
- /**
55
- * The animation of the skeleton. Defaults to `slide`.
56
- */
57
44
  animation: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"none">, z.ZodLiteral<"slide">, z.ZodLiteral<"pulse">]>>;
58
- /**
59
- * The width of the skeleton. Defaults to `100%`.
60
- */
61
45
  width: z.ZodOptional<z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>>;
62
- /**
63
- * The height of the skeleton. Defaults to `100%`.
64
- */
65
46
  height: z.ZodOptional<z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>>;
66
- }, {
67
- /**
68
- * The variant of the skeleton. `card` is used for cards which contain other Skeleton components.
69
- */
47
+ } & {
70
48
  variant: z.ZodLiteral<"card">;
71
- /**
72
- * The direction of the skeleton. Defaults to `column`.
73
- */
74
49
  direction: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"row">, z.ZodLiteral<"column">]>>;
75
- /**
76
- * The horizontal alignment of the skeleton. Defaults to `center`.
77
- */
78
50
  hAlign: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"start">, z.ZodLiteral<"center">, z.ZodLiteral<"end">]>>;
79
- /**
80
- * The vertical alignment of the skeleton. Defaults to `center`.
81
- */
82
51
  vAlign: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"start">, z.ZodLiteral<"center">, z.ZodLiteral<"end">]>>;
83
- /**
84
- * The gap between the skeletons. Defaults to `0.5rem`.
85
- */
86
52
  gap: z.ZodOptional<z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>>;
87
- }>, "strip", z.ZodTypeAny, {
53
+ }, "strip", z.ZodTypeAny, {
88
54
  variant: "card";
89
55
  width?: `${number}px` | `${number}rem` | `${number}%` | undefined;
90
56
  height?: `${number}px` | `${number}rem` | `${number}%` | undefined;
@@ -106,45 +72,15 @@ export declare const SkeletonSchema: z.ZodUnion<[z.ZodObject<{
106
72
  hAlign?: "center" | "start" | "end" | undefined;
107
73
  vAlign?: "center" | "start" | "end" | undefined;
108
74
  gap?: `${number}px` | `${number}rem` | `${number}%` | undefined;
109
- }>, z.ZodObject<z.objectUtil.extendShape<{
110
- /**
111
- * The variant of the skeleton.
112
- */
113
- variant: z.ZodLiteral<"text">;
114
- /**
115
- * The class of the skeleton. Defaults to `undefined`.
116
- */
75
+ }>, z.ZodObject<{
117
76
  class: z.ZodOptional<z.ZodString>;
118
- /**
119
- * The radius of the skeleton. Defaults to `lg`.
120
- */
121
77
  radius: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"none">, z.ZodLiteral<"sm">, z.ZodLiteral<"md">, z.ZodLiteral<"lg">]>>;
122
- /**
123
- * The animation of the skeleton. Defaults to `slide`.
124
- */
125
78
  animation: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"none">, z.ZodLiteral<"slide">, z.ZodLiteral<"pulse">]>>;
126
- /**
127
- * The width of the skeleton. Defaults to `100%`.
128
- */
129
- width: z.ZodOptional<z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>>;
130
- /**
131
- * The height of the skeleton. Defaults to `100%`.
132
- */
133
- height: z.ZodOptional<z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>>;
134
- }, {
135
- /**
136
- * The variant of the skeleton. `circle` is used for circles which contain other Skeleton components.
137
- */
79
+ } & {
138
80
  variant: z.ZodUnion<[z.ZodLiteral<"circle">, z.ZodLiteral<"block">]>;
139
- /**
140
- * The width of the skeleton.
141
- */
142
81
  width: z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>;
143
- /**
144
- * The height of the skeleton.
145
- */
146
82
  height: z.ZodUnion<[z.ZodType<`${number}px`, z.ZodTypeDef, `${number}px`>, z.ZodType<`${number}rem`, z.ZodTypeDef, `${number}rem`>, z.ZodType<`${number}%`, z.ZodTypeDef, `${number}%`>]>;
147
- }>, "strip", z.ZodTypeAny, {
83
+ }, "strip", z.ZodTypeAny, {
148
84
  width: `${number}px` | `${number}rem` | `${number}%`;
149
85
  height: `${number}px` | `${number}rem` | `${number}%`;
150
86
  variant: "circle" | "block";
@@ -23,17 +23,23 @@ interface Props {
23
23
  * Whether the tab should be active by default.
24
24
  */
25
25
  active?: boolean;
26
+
27
+ /**
28
+ * The unique ID of the tab. If not provided, a random ID will be generated.
29
+ */
30
+ id?: string;
26
31
  }
27
32
 
28
33
  const id = generateID('tab');
29
34
 
30
- const { icon, label, color = 'primary', active = false } = Astro.props;
35
+ const { icon, label, color = 'primary', active = false, id: customId } = Astro.props;
31
36
  ---
32
37
  <sui-tab-item
38
+ id={customId ?? id}
33
39
  data-icon={icon}
34
40
  data-label={label}
35
41
  data-color={color}
36
- data-tab-id={id}
42
+ data-tab-id={customId ?? id}
37
43
  data-active={active ? 'true' : undefined}
38
44
  >
39
45
  <slot />
@@ -34,6 +34,11 @@ interface Props {
34
34
  * The alignment of the tabs. Defaults to `left`.
35
35
  */
36
36
  align?: 'left' | 'center' | 'right';
37
+
38
+ /**
39
+ * The ID of the tab.
40
+ */
41
+ id?: string;
37
42
  }
38
43
 
39
44
  /**
@@ -133,6 +138,7 @@ const markTabAsActive = (tabId: string, html: string): string => {
133
138
  const uniqueId = generateID('sui-tabs-container');
134
139
 
135
140
  const {
141
+ id: customId,
136
142
  syncKey: originalSyncKey,
137
143
  storage = 'session',
138
144
  variant = 'default',
@@ -150,9 +156,9 @@ const containerId = generateID('sui-tabs-container');
150
156
 
151
157
  <div
152
158
  class="sui-tabs-container"
153
- id={containerId}
159
+ id={customId ?? containerId}
154
160
  data-sync-key={syncKey}
155
- data-unique-id={uniqueId}
161
+ data-unique-id={customId ?? uniqueId}
156
162
  data-storage-strategy={storage}
157
163
  class:list={[variant, align]}
158
164
  >
@@ -27,7 +27,7 @@
27
27
  margin-top: 0 !important;
28
28
  display: flex;
29
29
  flex-direction: row;
30
- gap: .5rem;
30
+ gap: 0.5rem;
31
31
  cursor: pointer;
32
32
  position: relative;
33
33
  min-width: fit-content;
@@ -36,7 +36,7 @@
36
36
  border-radius: var(--radius-md);
37
37
  height: 40px;
38
38
  padding: 0.5rem 0.75rem;
39
- transition: all .15s ease;
39
+ transition: all 0.15s ease;
40
40
  font-size: 0.875em;
41
41
  outline: 2px solid transparent;
42
42
  outline-offset: 2px;
@@ -1,7 +1,7 @@
1
1
  .sui-textarea-label {
2
2
  display: flex;
3
3
  flex-direction: column;
4
- gap: .25rem;
4
+ gap: 0.25rem;
5
5
  max-width: 80ch;
6
6
  }
7
7
  .sui-textarea-label.disabled {
@@ -20,12 +20,12 @@
20
20
  font-size: 14px;
21
21
  }
22
22
  .sui-textarea {
23
- padding: .65rem;
23
+ padding: 0.65rem;
24
24
  border-radius: var(--radius-md);
25
25
  border: 1px solid var(--border);
26
26
  background: var(--background-step-2);
27
27
  color: var(--text-normal);
28
- transition: all .15s ease;
28
+ transition: all 0.15s ease;
29
29
  resize: none;
30
30
  min-height: 12ch;
31
31
  width: 100%;
@@ -44,6 +44,6 @@
44
44
  background: var(--background-step-2);
45
45
  }
46
46
  .req-star {
47
- color: var(--danger-base);
47
+ color: var(--danger-vibrant);
48
48
  font-weight: 700;
49
49
  }
@@ -41,14 +41,14 @@ const {
41
41
  gap = 8,
42
42
  } = Astro.props;
43
43
  ---
44
- <div
45
- id="sui-toaster"
44
+ <div
45
+ id="sui-toaster"
46
46
  class:list={[
47
47
  closeButton && "closeable",
48
48
  position,
49
- ]},
49
+ ]}
50
50
  >
51
- <div
51
+ <div
52
52
  id="sui-toast-drawer"
53
53
  data-offset={offset}
54
54
  data-gap={gap}
@@ -30,11 +30,11 @@
30
30
  box-shadow: 0px 4px 8px var(--shadow);
31
31
  display: flex;
32
32
  flex-direction: column;
33
- gap: .5rem;
33
+ gap: 0.5rem;
34
34
  position: relative;
35
35
  overflow: hidden;
36
36
  margin-bottom: var(--gap);
37
- animation: toast-pop-in .25s ease forwards;
37
+ animation: toast-pop-in 0.25s ease forwards;
38
38
  z-index: 90;
39
39
  }
40
40
  .sui-toast-header {
@@ -46,7 +46,7 @@
46
46
  .sui-toast-header-left-side {
47
47
  display: flex;
48
48
  flex-direction: row;
49
- gap: .5rem;
49
+ gap: 0.5rem;
50
50
  align-items: center;
51
51
  font-weight: 500;
52
52
  font-size: 1.125em;
@@ -61,10 +61,10 @@
61
61
  color: var(--warning-base);
62
62
  }
63
63
  .sui-toast-container.danger .sui-toast-header-left-side svg {
64
- color: var(--danger-base);
64
+ color: var(--danger-vibrant);
65
65
  }
66
66
  .sui-toast-container.info .sui-toast-header-left-side svg {
67
- color: var(--info-base);
67
+ color: var(--info-vibrant);
68
68
  }
69
69
  .sui-toast-container.mono .sui-toast-header-left-side svg {
70
70
  color: var(--mono-base);
@@ -88,10 +88,10 @@
88
88
  background-color: var(--warning-base);
89
89
  }
90
90
  .sui-toast-container.danger .sui-toast-progress-bar {
91
- background-color: var(--danger-base);
91
+ background-color: var(--danger-vibrant);
92
92
  }
93
93
  .sui-toast-container.info .sui-toast-progress-bar {
94
- background-color: var(--info-base);
94
+ background-color: var(--info-vibrant);
95
95
  }
96
96
  .close-icon-container {
97
97
  cursor: pointer;
@@ -100,7 +100,7 @@
100
100
  display: flex;
101
101
  align-items: center;
102
102
  justify-content: center;
103
- transition: background-color .15s ease;
103
+ transition: background-color 0.15s ease;
104
104
  border-radius: var(--radius-sm);
105
105
  }
106
106
  .close-icon-container:hover {
@@ -111,7 +111,7 @@
111
111
  outline-offset: 2px;
112
112
  }
113
113
  .sui-toast-container.closing {
114
- animation: toast-closing .25s ease forwards;
114
+ animation: toast-closing 0.25s ease forwards;
115
115
  }
116
116
  .sui-toast-container.persistent {
117
117
  border: 1px solid var(--primary-base);
@@ -31,7 +31,7 @@ class Timer {
31
31
  if (!this.id || !this.started || !this.running) return;
32
32
  this.running = false;
33
33
  clearTimeout(this.id);
34
- this.remaining -= (/* @__PURE__ */ new Date()).getTime() - this.started.getTime();
34
+ this.remaining -= Date.now() - this.started.getTime();
35
35
  };
36
36
  getTimeLeft = () => {
37
37
  if (this.running) {
@@ -117,7 +117,7 @@ function createToast(props) {
117
117
  if (!props.persistent) {
118
118
  const timer = new Timer(
119
119
  () => removeToast(toastID),
120
- props.duration || (toastParent.dataset.duration ? Number.parseInt(toastParent.dataset.duration) : 4e3)
120
+ props.duration || (toastParent.dataset.duration ? Number.parseInt(toastParent.dataset.duration, 10) : 4e3)
121
121
  );
122
122
  const timerPauseWrapper = () => {
123
123
  toastContainer.classList.add("paused");