@dodlhuat/basix 1.2.0 → 1.2.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 (93) hide show
  1. package/README.md +266 -6
  2. package/css/accordion.scss +86 -87
  3. package/css/alert.scss +137 -137
  4. package/css/button.scss +48 -0
  5. package/css/calendar.scss +957 -0
  6. package/css/card.scss +65 -65
  7. package/css/chart.scss +270 -157
  8. package/css/chat-bubbles.scss +134 -68
  9. package/css/chips.scss +109 -19
  10. package/css/colors.scss +32 -32
  11. package/css/datepicker.scss +336 -336
  12. package/css/defaults.scss +90 -90
  13. package/css/docs.scss +529 -0
  14. package/css/editor.scss +36 -0
  15. package/css/file-uploader.scss +1 -1
  16. package/css/flyout-menu.scss +361 -361
  17. package/css/form.scss +0 -15
  18. package/css/gallery.scss +65 -6
  19. package/css/grid.scss +41 -40
  20. package/css/group-picker.scss +345 -0
  21. package/css/guitar-chords.css +250 -250
  22. package/css/icons.scss +330 -330
  23. package/css/parameters.scss +3 -3
  24. package/css/placeholder.scss +33 -33
  25. package/css/popover.scss +206 -0
  26. package/css/progress.scss +76 -32
  27. package/css/properties.scss +51 -36
  28. package/css/push-menu.scss +302 -174
  29. package/css/reset.scss +39 -39
  30. package/css/scrollbar.scss +62 -5
  31. package/css/sidebar-nav.scss +92 -0
  32. package/css/spinner.scss +65 -65
  33. package/css/stepper.scss +48 -12
  34. package/css/style.css +3155 -254
  35. package/css/style.css.map +1 -1
  36. package/css/style.min.css +1 -1
  37. package/css/style.scss +51 -45
  38. package/css/table.scss +199 -199
  39. package/css/tabs.scss +154 -123
  40. package/css/timeline.scss +83 -38
  41. package/css/timepicker.scss +100 -5
  42. package/css/toast.scss +81 -81
  43. package/css/virtual-dropdown.scss +35 -29
  44. package/js/calendar.js +532 -0
  45. package/js/calendar.ts +706 -0
  46. package/js/chart.js +573 -257
  47. package/js/chart.ts +692 -0
  48. package/js/code-viewer.js +10 -10
  49. package/js/code-viewer.ts +188 -188
  50. package/js/datepicker.ts +627 -627
  51. package/js/docs-nav.js +204 -0
  52. package/js/dropdown.ts +179 -179
  53. package/js/editor.js +50 -6
  54. package/js/editor.ts +483 -444
  55. package/js/file-uploader.js +1 -0
  56. package/js/file-uploader.ts +1 -0
  57. package/js/flyout-menu.js +14 -14
  58. package/js/flyout-menu.ts +249 -249
  59. package/js/form-builder.js +106 -106
  60. package/js/gallery.js +14 -8
  61. package/js/gallery.ts +245 -236
  62. package/js/group-picker.js +342 -0
  63. package/js/group-picker.ts +447 -0
  64. package/js/guitar-chords.js +268 -268
  65. package/js/lazy-loader.js +121 -121
  66. package/js/modal.ts +166 -166
  67. package/js/popover.js +163 -0
  68. package/js/popover.ts +219 -0
  69. package/js/position.js +108 -0
  70. package/js/position.ts +111 -0
  71. package/js/push-menu.js +113 -0
  72. package/js/push-menu.ts +284 -145
  73. package/js/request.js +50 -50
  74. package/js/scroll.ts +47 -47
  75. package/js/scrollbar.js +13 -0
  76. package/js/scrollbar.ts +324 -307
  77. package/js/select.ts +216 -216
  78. package/js/sidebar-nav.js +41 -0
  79. package/js/sidebar-nav.ts +66 -0
  80. package/js/table.ts +452 -452
  81. package/js/tabs.ts +279 -279
  82. package/js/theme.js +17 -6
  83. package/js/theme.ts +234 -224
  84. package/js/toast.ts +137 -137
  85. package/js/tooltip.js +6 -60
  86. package/js/tooltip.ts +184 -251
  87. package/js/tsconfig.json +18 -18
  88. package/js/utils.ts +83 -83
  89. package/js/virtual-dropdown.js +25 -25
  90. package/js/virtual-dropdown.ts +365 -365
  91. package/package.json +37 -39
  92. package/js/index.js +0 -816
  93. package/js/index.ts +0 -987
package/css/form.scss CHANGED
@@ -181,25 +181,10 @@ select {
181
181
  }
182
182
 
183
183
  .form-hint {
184
- display: flex;
185
- align-items: flex-start;
186
- gap: 0.3rem;
187
184
  font-size: 0.75rem;
188
185
  line-height: 1.45;
189
186
  color: var(--secondary-text);
190
187
  margin-top: 0.125rem;
191
-
192
- &::before {
193
- content: '';
194
- display: block;
195
- width: 4px;
196
- height: 4px;
197
- border-radius: 50%;
198
- background: currentColor;
199
- flex-shrink: 0;
200
- margin-top: 0.38em;
201
- opacity: 0.55;
202
- }
203
188
  }
204
189
 
205
190
  &.error {
package/css/gallery.scss CHANGED
@@ -22,9 +22,31 @@
22
22
  overflow: hidden;
23
23
  box-shadow: $shadow;
24
24
  transition:
25
- transform 0.3s ease,
26
- box-shadow 0.3s ease;
25
+ transform 0.3s cubic-bezier(0.2, 0, 0, 1),
26
+ box-shadow 0.3s cubic-bezier(0.2, 0, 0, 1);
27
27
  position: relative;
28
+ cursor: pointer;
29
+
30
+ &:hover {
31
+ transform: translateY(-4px);
32
+ box-shadow:
33
+ 0 8px 24px rgba(0, 0, 0, 0.1),
34
+ 0 2px 8px rgba(0, 0, 0, 0.06);
35
+
36
+ img.loaded {
37
+ transform: scale(1.03);
38
+ }
39
+ }
40
+
41
+ &:active {
42
+ transform: translateY(-1px);
43
+ transition-duration: 0.1s;
44
+ }
45
+
46
+ &:focus-visible {
47
+ outline: 2px solid var(--accent-color);
48
+ outline-offset: 2px;
49
+ }
28
50
  }
29
51
 
30
52
  .masonry-item img {
@@ -33,30 +55,67 @@
33
55
  display: block;
34
56
  object-fit: cover;
35
57
  opacity: 0;
36
- transition: opacity 0.5s ease-in;
58
+ transform: scale(1.06);
59
+ filter: blur(4px);
60
+ transition:
61
+ opacity 0.5s ease,
62
+ transform 0.6s cubic-bezier(0.2, 0, 0, 1),
63
+ filter 0.5s ease;
37
64
  }
38
65
 
39
66
  .masonry-item img.loaded {
40
67
  opacity: 1;
68
+ transform: scale(1);
69
+ filter: blur(0);
41
70
  }
42
71
 
43
72
  .masonry-item-info {
44
- padding: $spacing;
73
+ padding: calc($spacing * 0.75) $spacing;
74
+ border-top: 1px solid var(--divider);
45
75
  }
46
76
 
47
77
  .masonry-item-title {
48
78
  margin: 0 0 calc($spacing / 4);
49
- font-size: $spacing;
79
+ font-size: 0.9375rem;
50
80
  font-weight: 600;
81
+ color: var(--primary-text);
82
+ line-height: 1.3;
51
83
  }
52
84
 
53
85
  .masonry-item-desc {
54
86
  margin: 0;
55
- font-size: 0.9rem;
87
+ font-size: 0.8125rem;
56
88
  color: var(--secondary-text);
89
+ line-height: 1.5;
57
90
  }
58
91
 
59
92
  .loader {
60
93
  text-align: center;
61
94
  padding: calc($spacing * 2.5);
95
+ color: var(--secondary-text);
96
+ font-size: 0.8125rem;
97
+ }
98
+
99
+ // Staggered entrance for items
100
+ @media (prefers-reduced-motion: no-preference) {
101
+ .masonry-item {
102
+ animation: masonry-in 0.4s cubic-bezier(0.2, 0, 0, 1) both;
103
+ }
104
+
105
+ @for $i from 1 through 20 {
106
+ .masonry-column .masonry-item:nth-child(#{$i}) {
107
+ animation-delay: #{0.04s * $i};
108
+ }
109
+ }
110
+ }
111
+
112
+ @keyframes masonry-in {
113
+ from {
114
+ opacity: 0;
115
+ transform: translateY(16px) scale(0.97);
116
+ }
117
+ to {
118
+ opacity: 1;
119
+ transform: translateY(0) scale(1);
120
+ }
62
121
  }
package/css/grid.scss CHANGED
@@ -1,40 +1,41 @@
1
- @use "parameters" as *;
2
-
3
- .row {
4
- display: flex;
5
- flex-direction: row;
6
- gap: $spacing;
7
- margin-bottom: $spacing;
8
-
9
- &.spacing-top {
10
- padding-top: calc($spacing / 2);
11
- }
12
-
13
- .column {
14
- flex: 1;
15
- padding: $spacing;
16
-
17
- @for $i from 2 through 6 {
18
- &.grow-#{$i} {
19
- flex-grow: $i;
20
- }
21
- }
22
-
23
- .column {
24
- padding: 0;
25
- }
26
-
27
- .row {
28
- margin-bottom: 0;
29
- }
30
- }
31
- }
32
-
33
- @media screen and (max-width:768px) {
34
- .row {
35
- flex-wrap: wrap;
36
- .column {
37
- flex-basis: 100%;
38
- }
39
- }
40
- }
1
+ @use "parameters" as *;
2
+
3
+ .row {
4
+ display: flex;
5
+ flex-direction: row;
6
+ gap: $spacing;
7
+ margin-bottom: $spacing;
8
+
9
+ &.spacing-top {
10
+ padding-top: calc($spacing / 2);
11
+ }
12
+
13
+ .column {
14
+ flex: 1;
15
+ min-width: 0;
16
+ padding: $spacing;
17
+
18
+ @for $i from 2 through 6 {
19
+ &.grow-#{$i} {
20
+ flex-grow: $i;
21
+ }
22
+ }
23
+
24
+ .column {
25
+ padding: 0;
26
+ }
27
+
28
+ .row {
29
+ margin-bottom: 0;
30
+ }
31
+ }
32
+ }
33
+
34
+ @media screen and (max-width:768px) {
35
+ .row {
36
+ flex-wrap: wrap;
37
+ .column {
38
+ flex-basis: 100%;
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,345 @@
1
+ @use "properties";
2
+ @use "parameters" as *;
3
+
4
+ .group-picker {
5
+ position: relative;
6
+ width: 100%;
7
+ color: var(--primary-text);
8
+
9
+ // ─── Selection summary ─────────────────────────────────────────────────────
10
+
11
+ &__selection {
12
+ display: flex;
13
+ flex-wrap: wrap;
14
+ align-items: center;
15
+ gap: calc($spacing * 0.35);
16
+ min-height: $form-height;
17
+ padding: calc($spacing * 0.35) calc($spacing * 0.6);
18
+ background: var(--background);
19
+ border: 1px solid var(--divider);
20
+ border-radius: calc($border-radius / 2);
21
+ margin-bottom: calc($spacing * 0.75);
22
+ box-shadow: $shadow;
23
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
24
+
25
+ // Chips inside use gap — suppress their own margins
26
+ .chip {
27
+ margin: 0;
28
+ animation: gp-chip-in 0.2s cubic-bezier(0.34, 1.56, 0.64, 1) both;
29
+ }
30
+
31
+ // Fix font icon centering inside the absolute close button
32
+ .chip.closeable button {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+
37
+ .icon {
38
+ font-size: 0.7rem;
39
+ top: 0;
40
+ }
41
+ }
42
+
43
+ &:empty::before {
44
+ content: attr(data-placeholder);
45
+ color: var(--secondary-text);
46
+ font-size: 0.875rem;
47
+ }
48
+
49
+ &:focus-within {
50
+ border-color: var(--accent-color);
51
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-color) 15%, transparent);
52
+ }
53
+ }
54
+
55
+ // Parent chip — solid accent fill
56
+ // Specificity 0,3,0 via .chip.group-picker__chip--parent → beats .chips .chip (0,2,0)
57
+ &__selection .chip.group-picker__chip--parent {
58
+ background: var(--accent-color);
59
+ color: var(--background); // same pattern as button.scss button-variant
60
+
61
+ button {
62
+ background: color-mix(in srgb, var(--accent-color) 78%, black);
63
+ color: var(--background);
64
+ }
65
+ }
66
+
67
+ // ─── Search ────────────────────────────────────────────────────────────────
68
+ // Basix <input> handles border, focus ring, shadow — we only position the icon
69
+
70
+ &__search {
71
+ position: relative;
72
+ margin-bottom: calc($spacing * 0.5);
73
+
74
+ input {
75
+ padding-left: calc($spacing * 2.2);
76
+ }
77
+ }
78
+
79
+ &__search-icon {
80
+ position: absolute;
81
+ left: calc($spacing * 0.55);
82
+ top: 50%;
83
+ transform: translateY(-50%);
84
+ font-size: 1rem;
85
+ color: var(--secondary-text);
86
+ pointer-events: none;
87
+ opacity: 0.45;
88
+ z-index: 1;
89
+ }
90
+
91
+ // ─── List container ────────────────────────────────────────────────────────
92
+
93
+ &__list {
94
+ max-height: 420px;
95
+ overflow-y: auto;
96
+ overflow-x: hidden;
97
+ -webkit-overflow-scrolling: touch;
98
+ border: 1px solid var(--divider);
99
+ border-radius: calc($border-radius / 2);
100
+ background: var(--background);
101
+ box-shadow: $shadow;
102
+ }
103
+
104
+ // ─── Empty state ───────────────────────────────────────────────────────────
105
+
106
+ &__empty {
107
+ display: flex;
108
+ flex-direction: column;
109
+ align-items: center;
110
+ justify-content: center;
111
+ padding: calc($spacing * 2.5) $spacing;
112
+ color: var(--secondary-text);
113
+ font-size: 0.875rem;
114
+ text-align: center;
115
+ gap: calc($spacing * 0.5);
116
+
117
+ .icon {
118
+ font-size: 2rem;
119
+ opacity: 0.2;
120
+ }
121
+ }
122
+
123
+ // ─── Group row ─────────────────────────────────────────────────────────────
124
+
125
+ &__group {
126
+ border-bottom: 1px solid var(--divider);
127
+
128
+ &:last-child {
129
+ border-bottom: none;
130
+ }
131
+
132
+ // Expanded state: tint the header and accent the label
133
+ &.is-expanded > .group-picker__group-header {
134
+ background: color-mix(in srgb, var(--accent-color) 4%, transparent);
135
+
136
+ .group-picker__group-label {
137
+ color: var(--accent-color);
138
+ }
139
+ }
140
+ }
141
+
142
+ &__group-header {
143
+ display: flex;
144
+ align-items: center;
145
+ gap: calc($spacing * 0.5);
146
+ padding: calc($spacing * 0.75) calc($spacing * 0.85);
147
+ cursor: pointer;
148
+ user-select: none;
149
+ -webkit-tap-highlight-color: transparent;
150
+ transition: background 0.15s ease;
151
+
152
+ &:hover {
153
+ background: var(--hover);
154
+ }
155
+
156
+ &:active {
157
+ background: var(--secondary-background);
158
+ }
159
+ }
160
+
161
+ // Chevron — accent color when expanded, eased rotation
162
+ &__chevron {
163
+ flex-shrink: 0;
164
+ font-size: 1rem;
165
+ color: var(--secondary-text);
166
+ opacity: 0.5;
167
+ transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
168
+ color 0.15s ease,
169
+ opacity 0.15s ease;
170
+
171
+ .group-picker__group.is-expanded & {
172
+ transform: rotate(90deg);
173
+ color: var(--accent-color);
174
+ opacity: 1;
175
+ }
176
+ }
177
+
178
+ &__group-label {
179
+ flex: 1;
180
+ font-size: 0.875rem;
181
+ font-weight: 600;
182
+ color: var(--primary-text);
183
+ transition: color 0.15s ease;
184
+
185
+ mark {
186
+ background: color-mix(in srgb, var(--warning) 22%, transparent);
187
+ color: inherit;
188
+ border-radius: 2px;
189
+ padding: 0 2px;
190
+ }
191
+ }
192
+
193
+ // Action button — pill style, overrides Basix <button> base where needed
194
+ &__group-action {
195
+ flex-shrink: 0;
196
+ font-size: 0.6875rem;
197
+ font-weight: 500;
198
+ letter-spacing: 0.025em;
199
+ text-transform: uppercase;
200
+ padding: calc($spacing * 0.15) calc($spacing * 0.6);
201
+ border-radius: calc($border-radius * 3);
202
+ border: 1px solid var(--divider);
203
+ background: transparent;
204
+ color: var(--secondary-text);
205
+ line-height: 1.5;
206
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease,
207
+ transform 0.1s ease;
208
+
209
+ &:hover:not(.button-primary):not(:disabled) {
210
+ border-color: var(--accent-color);
211
+ color: var(--accent-color);
212
+ background: color-mix(in srgb, var(--accent-color) 6%, transparent);
213
+ transform: none;
214
+ }
215
+
216
+ &:active:not(:disabled) {
217
+ transform: scale(0.94);
218
+ }
219
+
220
+ // When button-primary is added by JS — keep pill shape
221
+ &.button-primary {
222
+ border-radius: calc($border-radius * 3);
223
+ font-size: 0.6875rem;
224
+ font-weight: 500;
225
+ letter-spacing: 0.025em;
226
+ text-transform: uppercase;
227
+ padding: calc($spacing * 0.15) calc($spacing * 0.6);
228
+ border: 1px solid transparent;
229
+ line-height: 1.5;
230
+ }
231
+ }
232
+
233
+ // ─── Leaf group ────────────────────────────────────────────────────────────
234
+
235
+ &__group.is-leaf {
236
+ cursor: pointer;
237
+
238
+ &.is-selected > .group-picker__group-header {
239
+ background: color-mix(in srgb, var(--accent-color) 6%, transparent);
240
+
241
+ .group-picker__group-label {
242
+ color: var(--accent-color);
243
+ }
244
+ }
245
+
246
+ &.is-selected .group-picker__leaf-check {
247
+ opacity: 1;
248
+ transform: scale(1);
249
+ }
250
+ }
251
+
252
+ // Leaf check icon — springs in on select
253
+ &__leaf-check {
254
+ flex-shrink: 0;
255
+ font-size: 1.1rem;
256
+ color: var(--accent-color);
257
+ opacity: 0;
258
+ transform: scale(0.3);
259
+ transition: opacity 0.18s ease,
260
+ transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1);
261
+ }
262
+
263
+ // ─── Subgroups accordion ───────────────────────────────────────────────────
264
+
265
+ &__subgroups {
266
+ height: 0;
267
+ overflow: hidden;
268
+ opacity: 0;
269
+ transition: height 0.28s cubic-bezier(0.16, 1, 0.3, 1),
270
+ opacity 0.2s ease;
271
+
272
+ .group-picker__group.is-expanded & {
273
+ opacity: 1;
274
+ }
275
+ }
276
+
277
+ // Subgroup chip list — indented to align with label, not chevron
278
+ &__subgroup-list {
279
+ display: flex;
280
+ flex-wrap: wrap;
281
+ gap: calc($spacing * 0.3);
282
+ padding: calc($spacing * 0.3) calc($spacing * 0.85) calc($spacing * 0.75) calc($spacing * 2.35);
283
+
284
+ // Chips use gap — suppress their own margins
285
+ .chip {
286
+ margin: 0;
287
+ }
288
+ }
289
+
290
+ // Subgroup chip — selected/disabled states on top of .chip.clickable
291
+ &__subgroup {
292
+ transition: background 0.15s ease, color 0.15s ease, outline-color 0.15s ease;
293
+
294
+ &.is-selected {
295
+ background: color-mix(in srgb, var(--accent-color) 12%, var(--background));
296
+ color: var(--accent-color);
297
+ outline: 1px solid color-mix(in srgb, var(--accent-color) 35%, transparent);
298
+ font-weight: 500;
299
+ }
300
+
301
+ &.is-disabled {
302
+ opacity: 0.35;
303
+ cursor: not-allowed;
304
+ pointer-events: none;
305
+ }
306
+
307
+ mark {
308
+ background: color-mix(in srgb, var(--warning) 22%, transparent);
309
+ color: inherit;
310
+ border-radius: 2px;
311
+ padding: 0 2px;
312
+ }
313
+ }
314
+ }
315
+
316
+ // ─── Chip entrance animation ─────────────────────────────────────────────────
317
+
318
+ @keyframes gp-chip-in {
319
+ from {
320
+ opacity: 0;
321
+ transform: scale(0.7) translateY(4px);
322
+ }
323
+ to {
324
+ opacity: 1;
325
+ transform: scale(1) translateY(0);
326
+ }
327
+ }
328
+
329
+ // ─── Responsive ──────────────────────────────────────────────────────────────
330
+
331
+ @media (max-width: 768px) {
332
+ .group-picker {
333
+ &__list {
334
+ max-height: 55vh;
335
+ }
336
+
337
+ &__group-header {
338
+ padding: calc($spacing * 0.9) calc($spacing * 0.85);
339
+ }
340
+
341
+ &__subgroup-list {
342
+ padding-left: calc($spacing * 2);
343
+ }
344
+ }
345
+ }