@kwtv/components 0.3.0 → 0.4.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 (49) hide show
  1. package/README.md +35 -0
  2. package/package.json +2 -2
  3. package/src/astro/Accordion.astro +10 -6
  4. package/src/astro/AccordionItem.astro +47 -43
  5. package/src/astro/ActiveFilterTags.astro +29 -25
  6. package/src/astro/Alert.astro +45 -41
  7. package/src/astro/Badge.astro +80 -76
  8. package/src/astro/Band.astro +104 -58
  9. package/src/astro/Breadcrumb.astro +33 -29
  10. package/src/astro/Button.astro +132 -128
  11. package/src/astro/Card.astro +64 -60
  12. package/src/astro/CartLine.astro +59 -55
  13. package/src/astro/Checkbox.astro +36 -32
  14. package/src/astro/Chip.astro +68 -64
  15. package/src/astro/DotGrid.astro +50 -46
  16. package/src/astro/EmptyState.astro +26 -22
  17. package/src/astro/FilterGroup.astro +29 -25
  18. package/src/astro/Filters.astro +50 -46
  19. package/src/astro/Footer.astro +179 -175
  20. package/src/astro/FooterColumn.astro +39 -35
  21. package/src/astro/Header.astro +67 -63
  22. package/src/astro/Icon.astro +1 -1
  23. package/src/astro/IconButton.astro +64 -60
  24. package/src/astro/Marquee.astro +33 -29
  25. package/src/astro/NavDropdown.astro +120 -116
  26. package/src/astro/NavLink.astro +59 -55
  27. package/src/astro/Newsletter.astro +58 -54
  28. package/src/astro/Pager.astro +43 -39
  29. package/src/astro/PickCard.astro +72 -68
  30. package/src/astro/ProductCard.astro +120 -116
  31. package/src/astro/Radio.astro +36 -32
  32. package/src/astro/Skeleton.astro +43 -39
  33. package/src/astro/Social.astro +26 -22
  34. package/src/astro/StepIndicator.astro +55 -51
  35. package/src/astro/Sticker.astro +50 -46
  36. package/src/astro/Swatch.astro +44 -40
  37. package/src/astro/Table.astro +58 -54
  38. package/src/astro/TableCard.astro +39 -35
  39. package/src/astro/TextField.astro +92 -88
  40. package/src/astro/Totals.astro +39 -35
  41. package/src/react/Drawer.css +60 -56
  42. package/src/react/Modal.css +97 -93
  43. package/src/react/NewsCarousel.css +108 -104
  44. package/src/react/QuantityStepper.css +84 -80
  45. package/src/react/Select.css +159 -155
  46. package/src/react/Toast.css +128 -124
  47. package/src/styles/base.css +30 -26
  48. package/src/styles/controls.css +183 -179
  49. package/src/styles/motion.css +203 -199
@@ -1,93 +1,97 @@
1
1
  /* Quantity stepper. All values from the design-system tokens. */
2
2
 
3
- .ui-qty {
4
- display: inline-flex;
5
- align-items: center;
6
- border: 1px solid var(--border);
7
- border-radius: var(--radius-md);
8
- background: var(--surface);
9
- overflow: hidden;
10
- }
3
+ @layer reset, tokens, base, components, motion, utilities;
11
4
 
12
- .ui-qty button {
13
- display: inline-flex;
14
- align-items: center;
15
- justify-content: center;
16
- width: 40px;
17
- height: 40px;
18
- background: none;
19
- border: 0;
20
- color: var(--text);
21
- font-size: var(--text-lg);
22
- line-height: 1;
23
- cursor: pointer;
24
- transition: background-color var(--duration-fast) var(--ease-standard);
25
- }
5
+ @layer components {
6
+ .ui-qty {
7
+ display: inline-flex;
8
+ align-items: center;
9
+ border: 1px solid var(--border);
10
+ border-radius: var(--radius-md);
11
+ background: var(--surface);
12
+ overflow: hidden;
13
+ }
26
14
 
27
- .ui-qty button:hover:not(:disabled) {
28
- background: var(--surface-hover);
29
- }
15
+ .ui-qty button {
16
+ display: inline-flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ width: 40px;
20
+ height: 40px;
21
+ background: none;
22
+ border: 0;
23
+ color: var(--text);
24
+ font-size: var(--text-lg);
25
+ line-height: 1;
26
+ cursor: pointer;
27
+ transition: background-color var(--duration-fast) var(--ease-standard);
28
+ }
30
29
 
31
- .ui-qty button:focus-visible {
32
- outline: 2px solid var(--focus);
33
- outline-offset: -2px;
34
- }
30
+ .ui-qty button:hover:not(:disabled) {
31
+ background: var(--surface-hover);
32
+ }
35
33
 
36
- .ui-qty button:disabled {
37
- opacity: 0.4;
38
- cursor: not-allowed;
39
- }
34
+ .ui-qty button:focus-visible {
35
+ outline: 2px solid var(--focus);
36
+ outline-offset: -2px;
37
+ }
40
38
 
41
- /* The bin, shown instead of minus when the last one would be removed.
42
- --danger, because it destroys the line rather than decrementing it. The
43
- icon is not the only signal: the button carries an aria-label, and hover
44
- fills it so the intent is obvious before the click. */
45
- /* `.ui-qty button` is (0,1,1) and would otherwise win over a lone class, so
46
- these are scoped the same way rather than reaching for !important. */
47
- .ui-qty button.ui-qty__remove {
48
- color: var(--danger);
49
- }
50
- .ui-qty button.ui-qty__remove:hover:not(:disabled) {
51
- background: var(--danger-bg);
52
- }
53
- .ui-qty__remove svg {
54
- display: block;
55
- }
39
+ .ui-qty button:disabled {
40
+ opacity: 0.4;
41
+ cursor: not-allowed;
42
+ }
56
43
 
57
- .ui-qty__val {
58
- min-width: 40px;
59
- text-align: center;
60
- font-size: var(--text-sm);
61
- font-weight: var(--weight-semibold);
62
- font-variant-numeric: tabular-nums;
63
- color: var(--text);
64
- }
44
+ /* The bin, shown instead of minus when the last one would be removed.
45
+ --danger, because it destroys the line rather than decrementing it. The
46
+ icon is not the only signal: the button carries an aria-label, and hover
47
+ fills it so the intent is obvious before the click. */
48
+ /* `.ui-qty button` is (0,1,1) and would otherwise win over a lone class, so
49
+ these are scoped the same way rather than reaching for !important. */
50
+ .ui-qty button.ui-qty__remove {
51
+ color: var(--danger);
52
+ }
53
+ .ui-qty button.ui-qty__remove:hover:not(:disabled) {
54
+ background: var(--danger-bg);
55
+ }
56
+ .ui-qty__remove svg {
57
+ display: block;
58
+ }
65
59
 
66
- /* Large, 48 px, for the product page. */
67
- .ui-qty--lg button {
68
- width: 48px;
69
- height: 48px;
70
- font-size: var(--text-xl);
71
- }
72
- .ui-qty--lg .ui-qty__val {
73
- min-width: 48px;
74
- font-size: var(--text-base);
75
- }
60
+ .ui-qty__val {
61
+ min-width: 40px;
62
+ text-align: center;
63
+ font-size: var(--text-sm);
64
+ font-weight: var(--weight-semibold);
65
+ font-variant-numeric: tabular-nums;
66
+ color: var(--text);
67
+ }
76
68
 
77
- .ui-sr-only {
78
- position: absolute;
79
- width: 1px;
80
- height: 1px;
81
- padding: 0;
82
- margin: -1px;
83
- overflow: hidden;
84
- clip-path: inset(50%);
85
- white-space: nowrap;
86
- border: 0;
87
- }
69
+ /* Large, 48 px, for the product page. */
70
+ .ui-qty--lg button {
71
+ width: 48px;
72
+ height: 48px;
73
+ font-size: var(--text-xl);
74
+ }
75
+ .ui-qty--lg .ui-qty__val {
76
+ min-width: 48px;
77
+ font-size: var(--text-base);
78
+ }
88
79
 
89
- @media (prefers-reduced-motion: reduce) {
90
- .ui-qty button {
91
- transition: none;
80
+ .ui-sr-only {
81
+ position: absolute;
82
+ width: 1px;
83
+ height: 1px;
84
+ padding: 0;
85
+ margin: -1px;
86
+ overflow: hidden;
87
+ clip-path: inset(50%);
88
+ white-space: nowrap;
89
+ border: 0;
90
+ }
91
+
92
+ @media (prefers-reduced-motion: reduce) {
93
+ .ui-qty button {
94
+ transition: none;
95
+ }
92
96
  }
93
97
  }
@@ -1,183 +1,187 @@
1
1
  /* Select. Trigger plus listbox. All values from the design-system tokens. */
2
2
 
3
- .ui-field {
4
- display: flex;
5
- flex-direction: column;
6
- gap: var(--space-1-5);
7
- }
3
+ @layer reset, tokens, base, components, motion, utilities;
8
4
 
9
- .ui-field__label {
10
- font-size: var(--text-sm);
11
- font-weight: var(--weight-medium);
12
- color: var(--text);
13
- }
5
+ @layer components {
6
+ .ui-field {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--space-1-5);
10
+ }
14
11
 
15
- .ui-field__req {
16
- color: var(--danger);
17
- margin-inline-start: var(--space-0-5);
18
- }
12
+ .ui-field__label {
13
+ font-size: var(--text-sm);
14
+ font-weight: var(--weight-medium);
15
+ color: var(--text);
16
+ }
19
17
 
20
- .ui-field__hint {
21
- font-size: var(--text-xs);
22
- line-height: var(--leading-xs);
23
- color: var(--text-muted);
24
- }
18
+ .ui-field__req {
19
+ color: var(--danger);
20
+ margin-inline-start: var(--space-0-5);
21
+ }
25
22
 
26
- .ui-field__error {
27
- display: inline-flex;
28
- align-items: center;
29
- gap: var(--space-1-5);
30
- font-size: var(--text-xs);
31
- line-height: var(--leading-xs);
32
- color: var(--danger);
33
- }
23
+ .ui-field__hint {
24
+ font-size: var(--text-xs);
25
+ line-height: var(--leading-xs);
26
+ color: var(--text-muted);
27
+ }
34
28
 
35
- .ui-select {
36
- position: relative;
37
- display: block;
38
- }
29
+ .ui-field__error {
30
+ display: inline-flex;
31
+ align-items: center;
32
+ gap: var(--space-1-5);
33
+ font-size: var(--text-xs);
34
+ line-height: var(--leading-xs);
35
+ color: var(--danger);
36
+ }
39
37
 
40
- .ui-select__btn {
41
- display: flex;
42
- align-items: center;
43
- justify-content: space-between;
44
- gap: var(--space-2);
45
- width: 100%;
46
- min-height: 40px;
47
- padding: 0 var(--space-3);
48
- background: var(--surface);
49
- border: 1px solid var(--border-strong);
50
- border-radius: var(--radius-md);
51
- color: var(--text);
52
- font-family: var(--font-sans);
53
- font-size: var(--text-sm);
54
- text-align: start;
55
- cursor: pointer;
56
- transition: border-color var(--duration-fast) var(--ease-standard);
57
- }
38
+ .ui-select {
39
+ position: relative;
40
+ display: block;
41
+ }
58
42
 
59
- .ui-select__btn:hover,
60
- .ui-select__btn.is-hover {
61
- border-color: var(--border-strong);
62
- }
43
+ .ui-select__btn {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ gap: var(--space-2);
48
+ width: 100%;
49
+ min-height: 40px;
50
+ padding: 0 var(--space-3);
51
+ background: var(--surface);
52
+ border: 1px solid var(--border-strong);
53
+ border-radius: var(--radius-md);
54
+ color: var(--text);
55
+ font-family: var(--font-sans);
56
+ font-size: var(--text-sm);
57
+ text-align: start;
58
+ cursor: pointer;
59
+ transition: border-color var(--duration-fast) var(--ease-standard);
60
+ }
63
61
 
64
- .ui-select__btn:focus-visible,
65
- .ui-select__btn.is-focus {
66
- outline: 2px solid var(--focus);
67
- outline-offset: 2px;
68
- box-shadow: 0 0 0 4px var(--focus-outer);
69
- }
62
+ .ui-select__btn:hover,
63
+ .ui-select__btn.is-hover {
64
+ border-color: var(--border-strong);
65
+ }
70
66
 
71
- .ui-select__btn:disabled {
72
- opacity: 0.5;
73
- cursor: not-allowed;
74
- }
67
+ .ui-select__btn:focus-visible,
68
+ .ui-select__btn.is-focus {
69
+ outline: 2px solid var(--focus);
70
+ outline-offset: 2px;
71
+ box-shadow: 0 0 0 4px var(--focus-outer);
72
+ }
75
73
 
76
- .ui-select__value {
77
- overflow: hidden;
78
- text-overflow: ellipsis;
79
- white-space: nowrap;
80
- }
74
+ .ui-select__btn:disabled {
75
+ opacity: 0.5;
76
+ cursor: not-allowed;
77
+ }
81
78
 
82
- .ui-select__value--empty {
83
- color: var(--text-muted);
84
- }
79
+ .ui-select__value {
80
+ overflow: hidden;
81
+ text-overflow: ellipsis;
82
+ white-space: nowrap;
83
+ }
85
84
 
86
- .ui-select__chev {
87
- display: inline-flex;
88
- flex: none;
89
- color: var(--text-muted);
90
- }
85
+ .ui-select__value--empty {
86
+ color: var(--text-muted);
87
+ }
91
88
 
92
- /* Invalid: 2 px danger border. */
93
- .ui-select--invalid .ui-select__btn {
94
- border-width: 2px;
95
- border-color: var(--danger);
96
- padding-inline: calc(var(--space-3) - 1px);
97
- }
89
+ .ui-select__chev {
90
+ display: inline-flex;
91
+ flex: none;
92
+ color: var(--text-muted);
93
+ }
98
94
 
99
- /* The list. 6 px offset, 272 px max height, 36 px rows. */
100
- .ui-select__list {
101
- position: absolute;
102
- top: calc(100% + var(--space-1-5));
103
- left: 0;
104
- right: 0;
105
- z-index: var(--z-dropdown);
106
- max-height: 272px;
107
- overflow-y: auto;
108
- padding: var(--space-1);
109
- background: var(--surface);
110
- border: 1px solid var(--border);
111
- border-radius: var(--radius-md);
112
- box-shadow: var(--shadow-lg);
113
- }
95
+ /* Invalid: 2 px danger border. */
96
+ .ui-select--invalid .ui-select__btn {
97
+ border-width: 2px;
98
+ border-color: var(--danger);
99
+ padding-inline: calc(var(--space-3) - 1px);
100
+ }
114
101
 
115
- .ui-select__opt {
116
- display: flex;
117
- align-items: center;
118
- gap: var(--space-2);
119
- width: 100%;
120
- min-height: 36px;
121
- padding: 0 var(--space-2);
122
- background: transparent;
123
- border: 0;
124
- border-radius: var(--radius-sm);
125
- color: var(--text);
126
- font-family: var(--font-sans);
127
- font-size: var(--text-sm);
128
- text-align: start;
129
- cursor: pointer;
130
- }
102
+ /* The list. 6 px offset, 272 px max height, 36 px rows. */
103
+ .ui-select__list {
104
+ position: absolute;
105
+ top: calc(100% + var(--space-1-5));
106
+ left: 0;
107
+ right: 0;
108
+ z-index: var(--z-dropdown);
109
+ max-height: 272px;
110
+ overflow-y: auto;
111
+ padding: var(--space-1);
112
+ background: var(--surface);
113
+ border: 1px solid var(--border);
114
+ border-radius: var(--radius-md);
115
+ box-shadow: var(--shadow-lg);
116
+ }
131
117
 
132
- .ui-select__opt:hover,
133
- .ui-select__opt.is-hover,
134
- .ui-select__opt.is-focus {
135
- background: var(--surface-hover);
136
- }
118
+ .ui-select__opt {
119
+ display: flex;
120
+ align-items: center;
121
+ gap: var(--space-2);
122
+ width: 100%;
123
+ min-height: 36px;
124
+ padding: 0 var(--space-2);
125
+ background: transparent;
126
+ border: 0;
127
+ border-radius: var(--radius-sm);
128
+ color: var(--text);
129
+ font-family: var(--font-sans);
130
+ font-size: var(--text-sm);
131
+ text-align: start;
132
+ cursor: pointer;
133
+ }
137
134
 
138
- /* Selection marked by the tick and a weight change, not the fill alone. */
139
- .ui-select__opt[aria-selected="true"] {
140
- font-weight: var(--weight-semibold);
141
- }
135
+ .ui-select__opt:hover,
136
+ .ui-select__opt.is-hover,
137
+ .ui-select__opt.is-focus {
138
+ background: var(--surface-hover);
139
+ }
142
140
 
143
- .ui-select__tick {
144
- display: inline-flex;
145
- flex: none;
146
- width: 13px;
147
- color: var(--primary);
148
- visibility: hidden;
149
- }
141
+ /* Selection marked by the tick and a weight change, not the fill alone. */
142
+ .ui-select__opt[aria-selected="true"] {
143
+ font-weight: var(--weight-semibold);
144
+ }
150
145
 
151
- .ui-select__opt[aria-selected="true"] .ui-select__tick {
152
- visibility: visible;
153
- }
146
+ .ui-select__tick {
147
+ display: inline-flex;
148
+ flex: none;
149
+ width: 13px;
150
+ color: var(--primary);
151
+ visibility: hidden;
152
+ }
154
153
 
155
- .ui-select__opt.is-disabled,
156
- .ui-select__opt[aria-disabled="true"] {
157
- opacity: 0.5;
158
- cursor: not-allowed;
159
- }
154
+ .ui-select__opt[aria-selected="true"] .ui-select__tick {
155
+ visibility: visible;
156
+ }
160
157
 
161
- /* Group headings. Not selectable. */
162
- .ui-select__grouplabel {
163
- display: block;
164
- padding: var(--space-2) var(--space-2) var(--space-1);
165
- font-family: var(--font-mono);
166
- font-size: var(--text-2xs);
167
- font-weight: var(--weight-semibold);
168
- letter-spacing: var(--tracking-wider);
169
- text-transform: uppercase;
170
- color: var(--text-muted);
171
- }
158
+ .ui-select__opt.is-disabled,
159
+ .ui-select__opt[aria-disabled="true"] {
160
+ opacity: 0.5;
161
+ cursor: not-allowed;
162
+ }
172
163
 
173
- @media (max-width: 700px), (pointer: coarse) {
174
- .ui-select__opt {
175
- min-height: 40px;
164
+ /* Group headings. Not selectable. */
165
+ .ui-select__grouplabel {
166
+ display: block;
167
+ padding: var(--space-2) var(--space-2) var(--space-1);
168
+ font-family: var(--font-mono);
169
+ font-size: var(--text-2xs);
170
+ font-weight: var(--weight-semibold);
171
+ letter-spacing: var(--tracking-wider);
172
+ text-transform: uppercase;
173
+ color: var(--text-muted);
176
174
  }
177
- }
178
175
 
179
- @media (prefers-reduced-motion: reduce) {
180
- .ui-select__btn {
181
- transition: none;
176
+ @media (max-width: 700px), (pointer: coarse) {
177
+ .ui-select__opt {
178
+ min-height: 40px;
179
+ }
180
+ }
181
+
182
+ @media (prefers-reduced-motion: reduce) {
183
+ .ui-select__btn {
184
+ transition: none;
185
+ }
182
186
  }
183
187
  }