@infonomic/uikit 5.3.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/astro.d.ts +51 -0
  2. package/dist/astro.js +51 -0
  3. package/dist/components/accordion/accordion.module.css +60 -0
  4. package/dist/components/avatar/avatar.module.css +54 -0
  5. package/dist/components/badge/badge.module.css +61 -0
  6. package/dist/components/button/button-group.module.css +19 -0
  7. package/dist/components/button/button.astro +86 -0
  8. package/dist/components/button/button.module.css +431 -0
  9. package/dist/components/button/control-buttons.module.css +132 -0
  10. package/dist/components/button/copy-button.module.css +56 -0
  11. package/dist/components/button/icon-button.astro +47 -0
  12. package/dist/components/card/card-content.astro +14 -0
  13. package/dist/components/card/card-description.astro +14 -0
  14. package/dist/components/card/card-footer.astro +14 -0
  15. package/dist/components/card/card-header.astro +14 -0
  16. package/dist/components/card/card-title.astro +14 -0
  17. package/dist/components/card/card.astro +41 -0
  18. package/dist/components/card/card.module.css +77 -0
  19. package/dist/components/container/container.astro +13 -0
  20. package/dist/components/container/container.module.css +36 -0
  21. package/dist/components/dropdown/dropdown.module.css +120 -0
  22. package/dist/components/forms/calendar.module.css +269 -0
  23. package/dist/components/forms/checkbox.astro +129 -0
  24. package/dist/components/forms/checkbox.js +1 -1
  25. package/dist/components/forms/checkbox.module.css +211 -0
  26. package/dist/components/forms/error-text.astro +14 -0
  27. package/dist/components/forms/error-text.module.css +9 -0
  28. package/dist/components/forms/help-text.astro +13 -0
  29. package/dist/components/forms/help-text.module.css +9 -0
  30. package/dist/components/forms/input-adornment.astro +26 -0
  31. package/dist/components/forms/input-adornment.module.css +21 -0
  32. package/dist/components/forms/input.astro +99 -0
  33. package/dist/components/forms/input.module.css +278 -0
  34. package/dist/components/forms/label.astro +24 -0
  35. package/dist/components/forms/label.module.css +15 -0
  36. package/dist/components/forms/radio-group.module.css +163 -0
  37. package/dist/components/forms/select.module.css +68 -0
  38. package/dist/components/forms/text-area.astro +77 -0
  39. package/dist/components/forms/text-area.module.css +10 -0
  40. package/dist/components/hamburger/hamburger.astro +30 -0
  41. package/dist/components/notifications/alert.module.css +110 -0
  42. package/dist/components/notifications/toast.module.css +237 -0
  43. package/dist/components/overlay/overlay.module.css +41 -0
  44. package/dist/components/pager/pagination.module.css +149 -0
  45. package/dist/components/scroll-area/scroll-area.module.css +64 -0
  46. package/dist/components/scroll-to-top/scroll-to-top.astro +75 -0
  47. package/dist/components/scroll-to-top/scroll-to-top.module.css +86 -0
  48. package/dist/components/section/section.astro +13 -0
  49. package/dist/components/section/section.module.css +9 -0
  50. package/dist/components/shimmer/shimmer.module.css +53 -0
  51. package/dist/components/table/table.module.css +100 -0
  52. package/dist/components/tabs/tabs.module.css +66 -0
  53. package/dist/components/tooltip/tooltip.module.css +45 -0
  54. package/dist/icons/check-icon.astro +37 -0
  55. package/dist/icons/close-icon.astro +38 -0
  56. package/dist/icons/icon-element.astro +27 -0
  57. package/dist/icons/icons.module.css +155 -0
  58. package/dist/icons/light-icon.astro +36 -0
  59. package/dist/icons/moon-icon.astro +38 -0
  60. package/dist/icons/search-icon.astro +40 -0
  61. package/dist/widgets/datepicker/datepicker.module.css +189 -0
  62. package/dist/widgets/drawer/drawer.module.css +112 -0
  63. package/dist/widgets/modal/modal.module.css +81 -0
  64. package/dist/widgets/timeline/timeline.module.css +87 -0
  65. package/package.json +5 -4
  66. package/src/astro.js +6 -0
  67. package/src/components/forms/checkbox.astro +129 -0
  68. package/src/components/forms/checkbox.tsx +1 -1
  69. package/src/components/forms/text-area.astro +77 -0
  70. package/src/icons/check-icon.astro +37 -0
@@ -0,0 +1,14 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ interface Props extends HTMLAttributes<'div'> {
4
+ class?: string
5
+ }
6
+
7
+ import styles from './card.module.css'
8
+
9
+ const { class: className, ...rest } = Astro.props as Props
10
+ ---
11
+
12
+ <div class:list={[styles['card-header'], className]} {...rest}>
13
+ <slot />
14
+ </div>
@@ -0,0 +1,14 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ interface Props extends HTMLAttributes<'div'> {
4
+ class?: string
5
+ }
6
+
7
+ import styles from './card.module.css'
8
+
9
+ const { class: className, ...rest } = Astro.props as Props
10
+ ---
11
+
12
+ <div class:list={[styles['card-title'], className]} {...rest}>
13
+ <slot />
14
+ </div>
@@ -0,0 +1,41 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+
4
+ interface Props extends HTMLAttributes<'button'>, Omit<HTMLAttributes<'a'>, 'type'> {
5
+ class?: string
6
+ hover?: boolean
7
+ href?: string
8
+ target?: string
9
+ as?: 'div' | 'a'
10
+ }
11
+
12
+ import styles from './card.module.css'
13
+
14
+ const {
15
+ class: className,
16
+ hover,
17
+ as = 'div',
18
+ href,
19
+ target = href?.startsWith('http') ? '_blank' : undefined,
20
+ ...rest
21
+ } = Astro.props as Props
22
+
23
+ const componentType = href != null ? 'a' : as
24
+ ---
25
+
26
+ {
27
+ componentType === 'a' ? (
28
+ <a
29
+ href={href}
30
+ target={target}
31
+ class:list={[styles.card, { [styles['card-hover']]: hover }, className]}
32
+ {...rest}
33
+ >
34
+ <slot />
35
+ </a>
36
+ ) : (
37
+ <div class:list={[styles.card, { [styles['card-hover']]: hover }, className]} {...rest}>
38
+ <slot />
39
+ </div>
40
+ )
41
+ }
@@ -0,0 +1,77 @@
1
+ @layer infonomic-base, infonomic-functional, infonomic-utilities, infonomic-theme, infonomic-typography, infonomic-components;
2
+
3
+ @layer infonomic-components {
4
+ .card,
5
+ :global(.card) {
6
+ display: flex;
7
+ flex-direction: column;
8
+ text-decoration: none;
9
+ width: 100%;
10
+ max-width: 100%;
11
+ color: var(--foreground);
12
+ background: var(--canvas-25);
13
+ border-width: var(--border-width-thin);
14
+ border-color: var(--border-color);
15
+ border-style: var(--border-style-solid);
16
+ border-radius: var(--border-radius-md);
17
+ box-shadow: var(--shadow-sm)
18
+ }
19
+
20
+ .card:is(:global(.dark) *),
21
+ :global(.card):is(:global(.dark) *) {
22
+ background: var(--canvas-800);
23
+ }
24
+
25
+ .card-hover,
26
+ :global(.card-hover) {
27
+ transition: background 0.2s ease-in-out;
28
+ }
29
+
30
+ .card-hover:hover,
31
+ :global(.card-hover):hover {
32
+ background: oklch(from var(--theme-50) 1 0.03 h);
33
+ }
34
+
35
+ .card-hover:hover:is(:global(.dark) *),
36
+ :global(.card-hover):hover:is(:global(.dark) *) {
37
+ background: oklch(from var(--canvas-800) 0.2 c h);
38
+ }
39
+
40
+ .card-header,
41
+ :global(.card-header) {
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: 0.5rem;
45
+ padding: 1rem;
46
+ }
47
+
48
+ .card-title,
49
+ :global(.card-title) {
50
+ color: var(--headings);
51
+ font-size: 1.8rem;
52
+ font-weight: bold;
53
+ line-height: 1;
54
+ letter-spacing: -0.015em;
55
+ }
56
+
57
+ .card-description,
58
+ :global(.card-description) {
59
+ font-size: 0.875rem;
60
+ color: var(--muted);
61
+ }
62
+
63
+ .card-content,
64
+ :global(.card-content) {
65
+ flex: 1;
66
+ padding: 1rem;
67
+ padding-top: 0;
68
+ }
69
+
70
+ .card-footer,
71
+ :global(.card-footer) {
72
+ display: flex;
73
+ align-items: center;
74
+ padding: 1rem;
75
+ padding-top: 0;
76
+ }
77
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ interface Props {
3
+ class?: string
4
+ }
5
+
6
+ import styles from './container.module.css'
7
+
8
+ const { class: className, ...rest } = Astro.props as Props
9
+ ---
10
+
11
+ <div class:list={[styles.container, className]} {...rest}>
12
+ <slot />
13
+ </div>
@@ -0,0 +1,36 @@
1
+ @layer infonomic-base, infonomic-functional, infonomic-utilities, infonomic-theme, infonomic-typography, infonomic-components;
2
+
3
+ @layer infonomic-components {
4
+ .container,
5
+ :global(.container) {
6
+ width: 100%;
7
+ padding: 0 1rem;
8
+ margin: 0 auto;
9
+ max-width: 60rem;
10
+ }
11
+
12
+ /* Shy edges */
13
+ /* Large */
14
+ @media (min-width: 66rem) {
15
+ .container,
16
+ :global(.container) {
17
+ max-width: 64rem;
18
+ }
19
+ }
20
+
21
+ /* X-Large */
22
+ @media (min-width: 77rem) {
23
+ .container,
24
+ :global(.container) {
25
+ max-width: 74.375rem;
26
+ }
27
+ }
28
+
29
+ /* 2X-Large */
30
+ @media (min-width: 94rem) {
31
+ .container,
32
+ :global(.container) {
33
+ max-width: 87.5rem;
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,120 @@
1
+ @layer infonomic-base, infonomic-functional, infonomic-utilities, infonomic-theme, infonomic-typography, infonomic-components;
2
+
3
+ @layer infonomic-components {
4
+
5
+ .dropdown-content,
6
+ .dropdown-subcontent {
7
+ z-index: 20;
8
+ background-color: var(--surface-panel-elevated);
9
+ padding: 4px;
10
+ animation-duration: 400ms;
11
+ animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
12
+ will-change: transform, opacity;
13
+ border-width: var(--border-width-thin);
14
+ border-color: var(--surface-panel-border);
15
+ border-style: var(--border-style-solid);
16
+ border-radius: var(--border-radius-md);
17
+ box-shadow: var(--shadow-sm);
18
+
19
+ &[data-side="top"] {
20
+ animation-name: slideDownAndFade;
21
+ }
22
+
23
+ &[data-side="right"] {
24
+ animation-name: slideLeftAndFade;
25
+ }
26
+
27
+ &[data-side="bottom"] {
28
+ animation-name: slideUpAndFade;
29
+ }
30
+
31
+ &[data-side="left"] {
32
+ animation-name: slideRightAndFade;
33
+ }
34
+ }
35
+
36
+
37
+ .dropdown-item {
38
+ display: flex;
39
+ align-items: center;
40
+ gap: var(--gap-1);
41
+ width: 100%;
42
+ padding: 5px 2px;
43
+ font-size: var(--font-size-sm);
44
+ color: var(--surface-item-text);
45
+ background-color: var(--surface-item);
46
+ transition: background-color 0.2s;
47
+ cursor: default;
48
+ outline: none;
49
+ border-radius: var(--border-radius-sm);
50
+ }
51
+
52
+ /* Updated to also cover data-highlighted presence */
53
+ .dropdown-item:hover,
54
+ .dropdown-item:focus,
55
+ .dropdown-item[data-highlighted] {
56
+ background-color: var(--surface-item-hover);
57
+ color: var(--surface-item-text-hover);
58
+ }
59
+
60
+ .dropdown-separator {
61
+ margin: 0 auto;
62
+ width: 90%;
63
+ background-color: var(--surface-panel-border);
64
+ margin: var(--spacing-4) 0;
65
+ border-top-width: var(--border-width-thin);
66
+ border-top-color: var(--surface-panel-border);
67
+ border-top-style: var(--border-style-solid);
68
+ }
69
+
70
+ /* Dark mode handled by surface tokens in theme layer */
71
+
72
+ @keyframes slideUpAndFade {
73
+ from {
74
+ opacity: 0;
75
+ transform: translateY(2px);
76
+ }
77
+
78
+ to {
79
+ opacity: 1;
80
+ transform: translateY(0);
81
+ }
82
+ }
83
+
84
+ @keyframes slideRightAndFade {
85
+ from {
86
+ opacity: 0;
87
+ transform: translateX(-2px);
88
+ }
89
+
90
+ to {
91
+ opacity: 1;
92
+ transform: translateX(0);
93
+ }
94
+ }
95
+
96
+ @keyframes slideDownAndFade {
97
+ from {
98
+ opacity: 0;
99
+ transform: translateY(-2px);
100
+ }
101
+
102
+ to {
103
+ opacity: 1;
104
+ transform: translateY(0);
105
+ }
106
+ }
107
+
108
+ @keyframes slideLeftAndFade {
109
+ from {
110
+ opacity: 0;
111
+ transform: translateX(2px);
112
+ }
113
+
114
+ to {
115
+ opacity: 1;
116
+ transform: translateX(0);
117
+ }
118
+ }
119
+
120
+ }
@@ -0,0 +1,269 @@
1
+ @layer infonomic-base, infonomic-functional, infonomic-utilities, infonomic-theme, infonomic-typography, infonomic-components;
2
+
3
+ @layer infonomic-components {
4
+ .day-picker {
5
+ padding: var(--spacing-12)
6
+ }
7
+
8
+ /* relative flex flex-col gap-4 sm:flex-row */
9
+ .months {
10
+ position: relative;
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: var(--spacing-16);
14
+ }
15
+
16
+ /* 'relative flex h-7 items-center justify-center', */
17
+ .months-caption {
18
+ position: relative;
19
+ display: flex;
20
+ height: 1.75rem;
21
+ /* 28px */
22
+ align-items: center;
23
+ justify-content: center;
24
+ }
25
+
26
+ /* 'flex items-center justify-center gap-2 w-full',_dropdownsClassName */
27
+ .dropdowns {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ gap: var(--spacing-8);
32
+ width: 100%;
33
+ }
34
+
35
+ .select-trigger {
36
+ width: 100%;
37
+ height: 2.25rem;
38
+ /* 36px */
39
+ font-size: 0.875rem;
40
+ /* 14px */
41
+ }
42
+
43
+ .select-content {
44
+ z-index: 100;
45
+ background-color: var(--background);
46
+ color: var(--foreground);
47
+ }
48
+
49
+ .select-item {
50
+ display: flex;
51
+ align-items: center;
52
+ width: 100%;
53
+ justify-content: center;
54
+ padding: 0.25rem 0.5rem;
55
+ font-size: 0.875rem;
56
+ cursor: pointer;
57
+ border: none;
58
+ /* 14px */
59
+ }
60
+
61
+ .select-item:hover {
62
+ background-color: var(--gray-50);
63
+ color: var(--foreground);
64
+ }
65
+
66
+ .select-chevrons {
67
+ stroke: var(--primary-400);
68
+ opacity: 0.7
69
+ }
70
+
71
+ .scroll-area {
72
+ border: 1px solid var(--border-color);
73
+ height: 240px;
74
+ width: 120px;
75
+ background-color: var(--background);
76
+ text-align: center;
77
+ }
78
+
79
+ .disabled {
80
+ color: var(--muted);
81
+ opacity: 0.5;
82
+ }
83
+
84
+ /* 'invisible flex-1' */
85
+ /* This is used to hide the month when the calendar is in single mode */
86
+ /* and the month is not selected */
87
+ .hidden {
88
+ visibility: hidden;
89
+ flex: 1;
90
+ }
91
+
92
+
93
+ /* 'text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30', */
94
+ .outside {
95
+ color: var(--muted);
96
+ opacity: 0.5;
97
+ }
98
+
99
+ .outside[aria-selected='true'] {
100
+ color: var(--muted);
101
+ opacity: 0.3;
102
+ }
103
+
104
+ /* 'pt-3 text-sm' */
105
+ .footer {
106
+ padding-top: var(--spacing-12);
107
+ font-size: 0.875rem;
108
+ /* 14px */
109
+ }
110
+
111
+ .weekdays {
112
+ display: flex;
113
+ }
114
+
115
+ /* 'w-9 text-sm font-normal text-muted-foreground', */
116
+ .weekday {
117
+ width: 2.25rem;
118
+ /* 36px */
119
+ font-size: 0.875rem;
120
+ /* 14px */
121
+ font-weight: normal;
122
+ color: var(--muted);
123
+ }
124
+
125
+ /* 'truncate text-sm font-medium' */
126
+ .caption-label {
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ white-space: nowrap;
130
+ font-size: 0.875rem;
131
+ /* 14px */
132
+ font-weight: 500;
133
+ }
134
+
135
+ /* 'mx-auto mt-4' */
136
+ .month-grid {
137
+ margin-left: auto;
138
+ margin-right: auto;
139
+ margin-top: var(--spacing-16);
140
+ }
141
+
142
+ /* 'mt-2 flex w-max items-start' */
143
+ .week {
144
+ margin-top: var(--spacing-8);
145
+ display: flex;
146
+ width: max-content;
147
+ align-items: flex-start;
148
+ }
149
+
150
+ /* 'flex size-9 flex-1 items-center justify-center p-0 text-sm', */
151
+ .day {
152
+ display: flex;
153
+ width: 2.25rem;
154
+ /* 36px */
155
+ height: 2.25rem;
156
+ /* 36px */
157
+ flex: 1;
158
+ align-items: center;
159
+ justify-content: center;
160
+ padding: 0;
161
+ font-size: 0.875rem;
162
+ /* 14px */
163
+ }
164
+
165
+ /* '[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground', */
166
+ .day>button {
167
+ color: var(--foreground);
168
+ }
169
+
170
+ /* '[&>button]:bg-accent [&>button]:text-accent-foreground', */
171
+ .today>button {
172
+ /* background-color: var(--gray-50); */
173
+ border: solid 1px var(--stroke-primary);
174
+ color: var(--foreground);
175
+ }
176
+
177
+ .day>button:hover,
178
+ .day-selected>button {
179
+ background-color: var(--fill-primary-strong);
180
+ color: white;
181
+ }
182
+
183
+ /* 'size-9 rounded-md p-0 font-normal transition-none aria-selected:opacity-100', */
184
+ .day-button {
185
+ width: 2.25rem;
186
+ /* 36px */
187
+ height: 2.25rem;
188
+ /* 36px */
189
+ border-radius: var(--border-radius-md);
190
+ padding: 0;
191
+ font-weight: normal;
192
+ transition: none;
193
+ }
194
+
195
+ .day-button[aria-selected='true'] {
196
+ opacity: 1;
197
+ }
198
+
199
+ /* 'bg-accent [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground' */
200
+ .button-range {
201
+ background-color: var(--fill-primary-weak);
202
+ color: var(--foreground);
203
+ }
204
+
205
+ .button-range>button {
206
+ background-color: var(--fill-primary-strong);
207
+ color: white;
208
+ }
209
+
210
+ .button-range>button:hover {
211
+ background-color: var(--fill-primary-strong);
212
+ color: var(--foreground);
213
+ }
214
+
215
+ .range-start {
216
+ border-top-left-radius: var(--border-radius-md);
217
+ border-bottom-left-radius: var(--border-radius-md);
218
+ }
219
+
220
+ .range-end {
221
+ border-top-right-radius: var(--border-radius-md);
222
+ border-bottom-right-radius: var(--border-radius-md);
223
+ }
224
+
225
+ /* 'bg-accent !text-foreground [&>button]:bg-transparent [&>button]:!text-foreground [&>button]:hover:bg-transparent [&>button]:hover:!text-foreground', */
226
+ .range-middle {
227
+ background-color: var(--fill-primary-weak);
228
+ color: var(--foreground);
229
+ }
230
+
231
+ .range-middle>button,
232
+ .range-middle>button:hover {
233
+ background-color: transparent;
234
+ color: var(--foreground);
235
+ }
236
+
237
+ @media (min-width: 40rem) {
238
+ .months {
239
+ flex-direction: row;
240
+ }
241
+ }
242
+
243
+ /* 🌙 Dark via `.dark` class. We rely on the
244
+ * consuming application to detect a user's preferred
245
+ * color scheme - either by header or cookie, and set
246
+ * a root html class accordingly
247
+ */
248
+ :global(.dark) {
249
+ .select-content {
250
+ background-color: var(--canvas-800);
251
+ color: var(--foreground);
252
+ }
253
+
254
+ .scroll-area {
255
+ background-color: var(--canvas-800);
256
+ color: var(--foreground);
257
+ }
258
+
259
+ .select-item:hover {
260
+ background-color: var(--primary-400);
261
+ color: var(--foreground);
262
+ }
263
+
264
+ .select-chevrons {
265
+ stroke: var(--primary-200);
266
+ opacity: 0.7;
267
+ }
268
+ }
269
+ }
@@ -0,0 +1,129 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ import type { Intent, Size, Variant } from './@types/checkbox.js'
4
+ import CheckIcon from '../../icons/check-icon.astro'
5
+ import ErrorText from './error-text.astro'
6
+ import HelpText from './help-text.astro'
7
+ import styles from './checkbox.module.css'
8
+
9
+ interface Props extends HTMLAttributes<'input'> {
10
+ id: string
11
+ name: string
12
+ label: string
13
+ variant?: Variant
14
+ size?: Size
15
+ intent?: Intent
16
+ reverse?: boolean
17
+ checked?: boolean
18
+ class?: string
19
+ checkBoxClasses?: string
20
+ containerClasses?: string
21
+ componentClasses?: string
22
+ labelClasses?: string
23
+ error?: boolean
24
+ helpText?: string
25
+ errorText?: string
26
+ }
27
+
28
+ const {
29
+ id,
30
+ name,
31
+ label,
32
+ variant = 'outlined',
33
+ size = 'md',
34
+ intent = 'primary',
35
+ reverse = false,
36
+ checked = false,
37
+ class: className,
38
+ checkBoxClasses,
39
+ containerClasses,
40
+ componentClasses,
41
+ labelClasses,
42
+ error = false,
43
+ helpText = '',
44
+ errorText = '',
45
+ ...rest
46
+ } = Astro.props
47
+ ---
48
+
49
+ <div class:list={['checkbox-container', containerClasses]}>
50
+ <div
51
+ class:list={[
52
+ 'checkbox-component',
53
+ styles.container,
54
+ componentClasses,
55
+ { [styles.reverse]: reverse }
56
+ ]}
57
+ >
58
+ <input type="checkbox" id={id} name={name} checked={checked} class="sr-only peer" {...rest} />
59
+
60
+ <label
61
+ for={id}
62
+ class:list={[
63
+ 'checkbox',
64
+ variant,
65
+ size,
66
+ intent,
67
+ styles.checkbox,
68
+ styles[variant],
69
+ styles[size],
70
+ styles[intent],
71
+ checkBoxClasses,
72
+ className
73
+ ]}
74
+ data-state={checked ? 'checked' : 'unchecked'}
75
+ >
76
+ <span
77
+ class:list={['checkbox-indicator', styles.indicator]}
78
+ data-state={checked ? 'checked' : 'unchecked'}
79
+ >
80
+ <CheckIcon class={styles.icon} />
81
+ </span>
82
+ </label>
83
+
84
+ <label for={id} class:list={[styles.label, labelClasses]}>
85
+ {label}
86
+ </label>
87
+ </div>
88
+ {
89
+ error ? (
90
+ <ErrorText id={`error-for-${id}`} text={errorText ?? helpText} />
91
+ ) : (
92
+ helpText?.length > 0 && <HelpText text={helpText} />
93
+ )
94
+ }
95
+ </div>
96
+
97
+ <script>
98
+ function setupCheckboxes() {
99
+ const inputs = document.querySelectorAll('input[type="checkbox"].peer')
100
+
101
+ inputs.forEach((input) => {
102
+ const checkboxInput = input as HTMLInputElement
103
+ const id = checkboxInput.id
104
+ // Find the visual checkbox label associated with this input
105
+ const visualCheckbox = document.querySelector(`label.checkbox[for="${id}"]`)
106
+ const indicator = visualCheckbox?.querySelector('.checkbox-indicator')
107
+
108
+ if (visualCheckbox && indicator) {
109
+ // Update state on change
110
+ checkboxInput.addEventListener('change', () => {
111
+ const state = checkboxInput.checked ? 'checked' : 'unchecked'
112
+ visualCheckbox.setAttribute('data-state', state)
113
+ indicator.setAttribute('data-state', state)
114
+ })
115
+
116
+ // Ensure initial state is correct
117
+ const state = checkboxInput.checked ? 'checked' : 'unchecked'
118
+ visualCheckbox.setAttribute('data-state', state)
119
+ indicator.setAttribute('data-state', state)
120
+ }
121
+ })
122
+ }
123
+
124
+ // Run on initial load
125
+ setupCheckboxes()
126
+
127
+ // Support Astro View Transitions
128
+ document.addEventListener('astro:page-load', setupCheckboxes)
129
+ </script>