@vadem/ui 0.0.3 → 0.2.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.
@@ -0,0 +1,604 @@
1
+ /* Schedule - spec: specs/schedule.md */
2
+ @layer vd.components {
3
+ .vd-schedule {
4
+ --vd-schedule-gap: var(--vd-space-3);
5
+ --vd-schedule-border: var(--vd-color-border);
6
+ --vd-schedule-bg: var(--vd-color-surface);
7
+ --vd-schedule-muted: var(--vd-color-text-muted);
8
+ --vd-schedule-radius: var(--vd-radius-surface);
9
+ --vd-schedule-cell-height: 7rem;
10
+ --vd-schedule-hour-height: 3rem;
11
+ --vd-schedule-gutter: 3.5rem;
12
+ --vd-schedule-max-height: 36rem;
13
+ --vd-schedule-agenda-time: 9rem;
14
+ --vd-schedule-now-size: var(--vd-space-0-5);
15
+ --vd-schedule-event-radius: var(--vd-radius-sm);
16
+ --vd-schedule-today-bg: var(--vd-color-action);
17
+ --vd-schedule-today-fg: var(--vd-color-on-action);
18
+ --vd-schedule-now: var(--vd-color-danger);
19
+ --vd-schedule-marker: var(--vd-color-focus);
20
+
21
+ display: grid;
22
+ gap: var(--vd-schedule-gap);
23
+ min-inline-size: 0;
24
+ color: var(--vd-color-text);
25
+ container-type: inline-size;
26
+ }
27
+
28
+ /* ------------------------------------------------------------- toolbar */
29
+
30
+ .vd-schedule__toolbar {
31
+ display: flex;
32
+ flex-wrap: wrap;
33
+ align-items: center;
34
+ justify-content: space-between;
35
+ gap: var(--vd-space-2) var(--vd-space-4);
36
+ }
37
+
38
+ .vd-schedule__nav,
39
+ .vd-schedule__views {
40
+ display: flex;
41
+ flex-wrap: wrap;
42
+ align-items: center;
43
+ gap: var(--vd-space-1);
44
+ }
45
+
46
+ .vd-schedule__title {
47
+ margin: 0;
48
+ margin-inline-start: var(--vd-space-2);
49
+ font-size: var(--vd-text-lg);
50
+ font-weight: var(--vd-weight-semibold);
51
+ }
52
+
53
+ .vd-schedule__title::first-letter {
54
+ text-transform: uppercase;
55
+ }
56
+
57
+ /* ---------------------------------------------------------- event chips */
58
+
59
+ .vd-schedule__event,
60
+ .vd-schedule__block,
61
+ .vd-schedule__agenda-event {
62
+ --vd-schedule-event-bg: var(--vd-color-action-subtle);
63
+ --vd-schedule-event-fg: var(--vd-color-text);
64
+ --vd-schedule-event-edge: var(--vd-color-action);
65
+ }
66
+
67
+ [data-color='success'] {
68
+ --vd-schedule-event-bg: var(--vd-color-success-subtle);
69
+ --vd-schedule-event-edge: var(--vd-color-success);
70
+ }
71
+ [data-color='warning'] {
72
+ --vd-schedule-event-bg: var(--vd-color-warning-subtle);
73
+ --vd-schedule-event-edge: var(--vd-color-warning);
74
+ }
75
+ [data-color='danger'] {
76
+ --vd-schedule-event-bg: var(--vd-color-danger-subtle);
77
+ --vd-schedule-event-edge: var(--vd-color-danger);
78
+ }
79
+ [data-color='info'] {
80
+ --vd-schedule-event-bg: var(--vd-color-info-subtle);
81
+ --vd-schedule-event-edge: var(--vd-color-info);
82
+ }
83
+ [data-color='neutral'] {
84
+ --vd-schedule-event-bg: var(--vd-color-surface-raised);
85
+ --vd-schedule-event-edge: var(--vd-color-border-strong);
86
+ }
87
+
88
+ .vd-schedule__event,
89
+ .vd-schedule__block {
90
+ display: flex;
91
+ gap: var(--vd-space-1);
92
+ min-inline-size: 0;
93
+ margin: 0;
94
+ padding: var(--vd-space-1) var(--vd-space-2);
95
+ border: 0;
96
+ border-inline-start: var(--vd-space-1) solid var(--vd-schedule-event-edge);
97
+ border-radius: var(--vd-schedule-event-radius);
98
+ background: var(--vd-schedule-event-bg);
99
+ color: var(--vd-schedule-event-fg);
100
+ font: inherit;
101
+ font-size: var(--vd-text-xs);
102
+ line-height: var(--vd-leading-snug);
103
+ text-align: start;
104
+ cursor: pointer;
105
+ }
106
+
107
+ .vd-schedule__event {
108
+ inline-size: 100%;
109
+ align-items: baseline;
110
+ white-space: nowrap;
111
+ }
112
+
113
+ .vd-schedule__event .vd-schedule__name {
114
+ overflow: hidden;
115
+ text-overflow: ellipsis;
116
+ }
117
+
118
+ .vd-schedule__time {
119
+ color: var(--vd-schedule-muted);
120
+ font-variant-numeric: tabular-nums;
121
+ }
122
+
123
+ .vd-schedule__name {
124
+ min-inline-size: 0;
125
+ font-weight: var(--vd-weight-medium);
126
+ }
127
+
128
+ @media (hover: hover) {
129
+ .vd-schedule__event:hover,
130
+ .vd-schedule__block:hover,
131
+ .vd-schedule__agenda-event:hover {
132
+ background: color-mix(
133
+ in oklch,
134
+ var(--vd-schedule-event-bg),
135
+ var(--vd-schedule-event-edge) 14%
136
+ );
137
+ }
138
+ }
139
+
140
+ .vd-schedule button:focus-visible {
141
+ outline: var(--vd-focus-ring-width) solid var(--vd-color-focus);
142
+ outline-offset: var(--vd-focus-ring-offset);
143
+ }
144
+
145
+ [data-dragging].vd-schedule__event,
146
+ [data-dragging].vd-schedule__block {
147
+ opacity: var(--vd-opacity-disabled);
148
+ }
149
+
150
+ .vd-schedule[data-state='dragging'] {
151
+ cursor: grabbing;
152
+ }
153
+
154
+ /* ---------------------------------------------------------------- month */
155
+
156
+ .vd-schedule__month {
157
+ inline-size: 100%;
158
+ table-layout: fixed;
159
+ border-collapse: separate;
160
+ border-spacing: 0;
161
+ border: var(--vd-border-width) solid var(--vd-schedule-border);
162
+ border-radius: var(--vd-schedule-radius);
163
+ background: var(--vd-schedule-bg);
164
+ overflow: hidden;
165
+ }
166
+
167
+ .vd-schedule__month th {
168
+ padding: var(--vd-space-2);
169
+ border-block-end: var(--vd-border-width) solid var(--vd-schedule-border);
170
+ color: var(--vd-schedule-muted);
171
+ font-family: var(--vd-font-mono);
172
+ font-size: var(--vd-text-xs);
173
+ font-weight: var(--vd-weight-medium);
174
+ letter-spacing: var(--vd-tracking-caps);
175
+ text-align: start;
176
+ text-transform: uppercase;
177
+ }
178
+
179
+ .vd-schedule__month abbr {
180
+ text-decoration: none;
181
+ }
182
+
183
+ .vd-schedule__cell {
184
+ min-inline-size: 0;
185
+ overflow: hidden;
186
+ block-size: var(--vd-schedule-cell-height);
187
+ padding: var(--vd-space-1);
188
+ border-block-end: var(--vd-border-width) solid var(--vd-schedule-border);
189
+ border-inline-end: var(--vd-border-width) solid var(--vd-schedule-border);
190
+ vertical-align: top;
191
+ }
192
+
193
+ .vd-schedule__month tr > .vd-schedule__cell:last-child {
194
+ border-inline-end: 0;
195
+ }
196
+
197
+ .vd-schedule__month tbody tr:last-child > .vd-schedule__cell {
198
+ border-block-end: 0;
199
+ }
200
+
201
+ .vd-schedule__cell[data-outside] {
202
+ background: var(--vd-color-surface-sunken);
203
+ }
204
+
205
+ .vd-schedule__cell[data-outside] .vd-schedule__day {
206
+ color: var(--vd-schedule-muted);
207
+ }
208
+
209
+ .vd-schedule__cell[data-drop-target],
210
+ .vd-schedule__allday-cell[data-drop-target] {
211
+ outline: var(--vd-focus-ring-width) solid var(--vd-schedule-marker);
212
+ outline-offset: calc(-1 * var(--vd-focus-ring-width));
213
+ }
214
+
215
+ .vd-schedule__day {
216
+ display: inline-grid;
217
+ place-items: center;
218
+ min-inline-size: var(--vd-control-height-sm);
219
+ block-size: var(--vd-control-height-sm);
220
+ margin: 0;
221
+ padding-inline: var(--vd-space-1);
222
+ border: 0;
223
+ border-radius: var(--vd-radius-pill);
224
+ background: transparent;
225
+ color: inherit;
226
+ font: inherit;
227
+ font-size: var(--vd-text-sm);
228
+ font-variant-numeric: tabular-nums;
229
+ cursor: pointer;
230
+ }
231
+
232
+ @media (hover: hover) {
233
+ .vd-schedule__day:hover {
234
+ background: var(--vd-color-action-subtle);
235
+ }
236
+ }
237
+
238
+ .vd-schedule__day[aria-current='date'] {
239
+ background: var(--vd-schedule-today-bg);
240
+ color: var(--vd-schedule-today-fg);
241
+ font-weight: var(--vd-weight-semibold);
242
+ }
243
+
244
+ .vd-schedule__chips {
245
+ display: grid;
246
+ /* Chips shrink to the cell: long titles end with an ellipsis, never spill into the next day. */
247
+ grid-template-columns: minmax(0, 1fr);
248
+ gap: var(--vd-space-0-5);
249
+ margin: var(--vd-space-1) 0 0;
250
+ padding: 0;
251
+ list-style: none;
252
+ }
253
+
254
+ .vd-schedule__more {
255
+ margin: 0;
256
+ padding: 0 var(--vd-space-2);
257
+ border: 0;
258
+ background: transparent;
259
+ color: var(--vd-schedule-muted);
260
+ font: inherit;
261
+ font-size: var(--vd-text-xs);
262
+ font-weight: var(--vd-weight-medium);
263
+ cursor: pointer;
264
+ }
265
+
266
+ @media (hover: hover) {
267
+ .vd-schedule__more:hover {
268
+ color: var(--vd-color-text);
269
+ text-decoration: underline;
270
+ }
271
+ }
272
+
273
+ /* ---------------------------------------------------------------- agenda */
274
+
275
+ .vd-schedule__agenda {
276
+ display: grid;
277
+ gap: var(--vd-space-4);
278
+ }
279
+
280
+ .vd-schedule__agenda-day {
281
+ display: grid;
282
+ gap: var(--vd-space-2);
283
+ }
284
+
285
+ .vd-schedule__agenda-date {
286
+ margin: 0;
287
+ padding-block-end: var(--vd-space-1);
288
+ border-block-end: var(--vd-border-width) solid var(--vd-schedule-border);
289
+ font-weight: var(--vd-weight-semibold);
290
+ }
291
+
292
+ .vd-schedule__agenda-date[data-today] {
293
+ color: var(--vd-color-text-accent);
294
+ }
295
+
296
+ .vd-schedule__agenda-list {
297
+ display: grid;
298
+ gap: var(--vd-space-1);
299
+ margin: 0;
300
+ padding: 0;
301
+ list-style: none;
302
+ }
303
+
304
+ .vd-schedule__agenda-event {
305
+ display: grid;
306
+ grid-template-columns: var(--vd-schedule-agenda-time) minmax(0, 1fr);
307
+ gap: var(--vd-space-3);
308
+ inline-size: 100%;
309
+ margin: 0;
310
+ padding: var(--vd-space-2) var(--vd-space-3);
311
+ border: 0;
312
+ border-inline-start: var(--vd-space-1) solid var(--vd-schedule-event-edge);
313
+ border-radius: var(--vd-schedule-event-radius);
314
+ background: var(--vd-schedule-event-bg);
315
+ color: inherit;
316
+ font: inherit;
317
+ text-align: start;
318
+ cursor: pointer;
319
+ }
320
+
321
+ .vd-schedule__agenda-time {
322
+ color: var(--vd-schedule-muted);
323
+ font-size: var(--vd-text-sm);
324
+ font-variant-numeric: tabular-nums;
325
+ }
326
+
327
+ .vd-schedule__agenda-event .vd-schedule__name {
328
+ overflow-wrap: anywhere;
329
+ }
330
+
331
+ .vd-schedule__empty,
332
+ .vd-schedule__invalid {
333
+ margin: 0;
334
+ padding: var(--vd-space-6);
335
+ border: var(--vd-border-width) dashed var(--vd-schedule-border);
336
+ border-radius: var(--vd-schedule-radius);
337
+ color: var(--vd-schedule-muted);
338
+ text-align: center;
339
+ }
340
+
341
+ /* ------------------------------------------------------------ time grid */
342
+
343
+ .vd-schedule__timegrid {
344
+ --vd-schedule-columns: var(--vd-schedule-gutter) repeat(var(--vd-schedule-days), minmax(0, 1fr));
345
+ border: var(--vd-border-width) solid var(--vd-schedule-border);
346
+ border-radius: var(--vd-schedule-radius);
347
+ background: var(--vd-schedule-bg);
348
+ overflow: hidden;
349
+ }
350
+
351
+ .vd-schedule__head,
352
+ .vd-schedule__allday,
353
+ .vd-schedule__grid {
354
+ display: grid;
355
+ grid-template-columns: var(--vd-schedule-columns);
356
+ }
357
+
358
+ .vd-schedule__colhead {
359
+ display: grid;
360
+ justify-items: center;
361
+ margin: 0;
362
+ padding: var(--vd-space-2) var(--vd-space-1);
363
+ border: 0;
364
+ border-inline-start: var(--vd-border-width) solid var(--vd-schedule-border);
365
+ background: transparent;
366
+ color: inherit;
367
+ font: inherit;
368
+ cursor: pointer;
369
+ }
370
+
371
+ @media (hover: hover) {
372
+ .vd-schedule__colhead:hover {
373
+ background: var(--vd-color-action-subtle);
374
+ }
375
+ }
376
+
377
+ .vd-schedule__weekday {
378
+ color: var(--vd-schedule-muted);
379
+ font-family: var(--vd-font-mono);
380
+ font-size: var(--vd-text-xs);
381
+ letter-spacing: var(--vd-tracking-caps);
382
+ text-transform: uppercase;
383
+ }
384
+
385
+ .vd-schedule__date {
386
+ font-size: var(--vd-text-lg);
387
+ font-weight: var(--vd-weight-semibold);
388
+ font-variant-numeric: tabular-nums;
389
+ }
390
+
391
+ .vd-schedule__colhead[data-today] .vd-schedule__date {
392
+ color: var(--vd-color-text-accent);
393
+ }
394
+
395
+ .vd-schedule__allday {
396
+ border-block: var(--vd-border-width) solid var(--vd-schedule-border);
397
+ }
398
+
399
+ .vd-schedule__allday-label {
400
+ align-self: center;
401
+ padding-inline: var(--vd-space-1);
402
+ color: var(--vd-schedule-muted);
403
+ font-size: var(--vd-text-xs);
404
+ text-align: end;
405
+ }
406
+
407
+ .vd-schedule__allday-cell {
408
+ display: grid;
409
+ align-content: start;
410
+ gap: var(--vd-space-0-5);
411
+ min-block-size: var(--vd-control-height-md);
412
+ padding: var(--vd-space-1);
413
+ border-inline-start: var(--vd-border-width) solid var(--vd-schedule-border);
414
+ }
415
+
416
+ .vd-schedule__scroll {
417
+ max-block-size: var(--vd-schedule-max-height);
418
+ overflow-y: auto;
419
+ overscroll-behavior: contain;
420
+ }
421
+
422
+ .vd-schedule__grid {
423
+ position: relative;
424
+ block-size: calc(var(--vd-schedule-hours) * var(--vd-schedule-hour-height));
425
+ }
426
+
427
+ .vd-schedule__hours {
428
+ display: grid;
429
+ grid-auto-rows: var(--vd-schedule-hour-height);
430
+ }
431
+
432
+ .vd-schedule__hour {
433
+ padding-inline: var(--vd-space-1);
434
+ color: var(--vd-schedule-muted);
435
+ font-size: var(--vd-text-xs);
436
+ font-variant-numeric: tabular-nums;
437
+ text-align: end;
438
+ translate: 0 calc(-0.5lh);
439
+ }
440
+
441
+ .vd-schedule__hour:first-child {
442
+ translate: none;
443
+ }
444
+
445
+ .vd-schedule__column {
446
+ position: relative;
447
+ border-inline-start: var(--vd-border-width) solid var(--vd-schedule-border);
448
+ /* Hour lines and fainter half-hour lines. */
449
+ background-image:
450
+ linear-gradient(var(--vd-schedule-border) var(--vd-border-width), transparent 0),
451
+ linear-gradient(
452
+ color-mix(in oklch, var(--vd-schedule-border) 45%, transparent) var(--vd-border-width),
453
+ transparent 0
454
+ );
455
+ background-size:
456
+ 100% var(--vd-schedule-hour-height),
457
+ 100% calc(var(--vd-schedule-hour-height) / 2);
458
+ }
459
+
460
+ .vd-schedule__column[data-today] {
461
+ background-color: color-mix(in oklch, var(--vd-color-action-subtle) 35%, transparent);
462
+ }
463
+
464
+ .vd-schedule__block {
465
+ position: absolute;
466
+ inset-block-start: calc(var(--vd-schedule-top) * var(--vd-schedule-hour-height) / 60);
467
+ inset-inline-start: calc(100% * var(--vd-schedule-col) / var(--vd-schedule-cols));
468
+ inline-size: calc(100% / var(--vd-schedule-cols) - var(--vd-space-0-5));
469
+ block-size: calc(
470
+ var(--vd-schedule-span) * var(--vd-schedule-hour-height) / 60 - var(--vd-space-0-5)
471
+ );
472
+ flex-direction: column;
473
+ overflow: hidden;
474
+ box-shadow: var(--vd-shadow-sm);
475
+ }
476
+
477
+ .vd-schedule__block[data-short] {
478
+ white-space: nowrap;
479
+ }
480
+
481
+ .vd-schedule__block[data-short] .vd-schedule__name {
482
+ overflow: hidden;
483
+ text-overflow: ellipsis;
484
+ }
485
+
486
+ .vd-schedule__block[data-short] .vd-schedule__time {
487
+ display: none;
488
+ }
489
+
490
+ .vd-schedule__block[data-clipped-start] {
491
+ border-start-start-radius: 0;
492
+ border-start-end-radius: 0;
493
+ }
494
+
495
+ .vd-schedule__block[data-clipped-end] {
496
+ border-end-start-radius: 0;
497
+ border-end-end-radius: 0;
498
+ }
499
+
500
+ .vd-schedule__block .vd-schedule__name {
501
+ overflow-wrap: break-word;
502
+ hyphens: auto;
503
+ }
504
+
505
+ .vd-schedule__resize {
506
+ position: absolute;
507
+ inset-inline: 0;
508
+ inset-block-end: 0;
509
+ block-size: var(--vd-space-2);
510
+ cursor: ns-resize;
511
+ }
512
+
513
+ .vd-schedule__preview {
514
+ position: absolute;
515
+ inset-inline: 0;
516
+ inset-block-start: calc(var(--vd-schedule-top) * var(--vd-schedule-hour-height) / 60);
517
+ block-size: calc(var(--vd-schedule-span) * var(--vd-schedule-hour-height) / 60);
518
+ padding: var(--vd-space-1) var(--vd-space-2);
519
+ border: var(--vd-focus-ring-width) dashed var(--vd-schedule-marker);
520
+ border-radius: var(--vd-schedule-event-radius);
521
+ color: var(--vd-schedule-marker);
522
+ font-size: var(--vd-text-xs);
523
+ font-variant-numeric: tabular-nums;
524
+ pointer-events: none;
525
+ }
526
+
527
+ .vd-schedule__now {
528
+ position: absolute;
529
+ inset-inline: 0;
530
+ inset-block-start: calc(var(--vd-schedule-top) * var(--vd-schedule-hour-height) / 60);
531
+ block-size: var(--vd-schedule-now-size);
532
+ background: var(--vd-schedule-now);
533
+ pointer-events: none;
534
+ }
535
+
536
+ .vd-schedule__now::before {
537
+ content: '';
538
+ position: absolute;
539
+ inset-inline-start: calc(-1 * var(--vd-space-1));
540
+ inset-block-start: 50%;
541
+ inline-size: var(--vd-space-2);
542
+ block-size: var(--vd-space-2);
543
+ border-radius: var(--vd-radius-pill);
544
+ background: var(--vd-schedule-now);
545
+ translate: 0 -50%;
546
+ }
547
+
548
+ .vd-schedule__dot {
549
+ display: none;
550
+ }
551
+
552
+ /* Narrow month: days show a dot instead of unreadable chips; a day opens the day view. */
553
+ @container (width < 36rem) {
554
+ .vd-schedule__chips {
555
+ display: none;
556
+ }
557
+ .vd-schedule__cell {
558
+ block-size: auto;
559
+ text-align: center;
560
+ }
561
+ .vd-schedule__day {
562
+ position: relative;
563
+ }
564
+ .vd-schedule__dot {
565
+ display: block;
566
+ position: absolute;
567
+ inset-block-end: calc(-1 * var(--vd-space-1));
568
+ inset-inline-start: 50%;
569
+ inline-size: var(--vd-space-1);
570
+ block-size: var(--vd-space-1);
571
+ border-radius: var(--vd-radius-pill);
572
+ background: var(--vd-color-action);
573
+ /* Logical centring (translate is physical and would drift in RTL). */
574
+ margin-inline-start: calc(var(--vd-space-1) / -2);
575
+ }
576
+ .vd-schedule__day[aria-current='date'] .vd-schedule__dot {
577
+ background: var(--vd-schedule-today-bg);
578
+ }
579
+ }
580
+
581
+ /* Narrow containers: agenda stacks the time over the title. */
582
+ @container (width < 40rem) {
583
+ .vd-schedule__agenda-event {
584
+ grid-template-columns: minmax(0, 1fr);
585
+ gap: 0;
586
+ }
587
+ }
588
+
589
+ @media (forced-colors: active) {
590
+ .vd-schedule__event,
591
+ .vd-schedule__block,
592
+ .vd-schedule__agenda-event {
593
+ border: var(--vd-border-width) solid CanvasText;
594
+ border-inline-start-width: var(--vd-space-1);
595
+ }
596
+ .vd-schedule__day[aria-current='date'] {
597
+ outline: var(--vd-border-width) solid Highlight;
598
+ }
599
+ .vd-schedule__now,
600
+ .vd-schedule__now::before {
601
+ background: Highlight;
602
+ }
603
+ }
604
+ }
@@ -128,5 +128,11 @@
128
128
  .vd-slider {
129
129
  appearance: auto;
130
130
  }
131
+
132
+ /* The native control's own indicator is removed by `outline: none` above. */
133
+ .vd-slider:focus-visible {
134
+ outline: var(--vd-focus-ring-width) solid var(--vd-color-focus);
135
+ outline-offset: var(--vd-focus-ring-offset);
136
+ }
131
137
  }
132
138
  }
@@ -13,9 +13,9 @@ export interface VdLinearScale {
13
13
  range: readonly [number, number];
14
14
  (value: number): number;
15
15
  }
16
- export declare function linearScale(domain: readonly [number, number], range: readonly [number, number]): VdLinearScale;
16
+ export declare function vdLinearScale(domain: readonly [number, number], range: readonly [number, number]): VdLinearScale;
17
17
  /** Round numbers for an axis: 1, 2, 2.5 or 5 times a power of ten. Always includes zero. */
18
- export declare function niceTicks(min: number, max: number, target?: number): number[];
18
+ export declare function vdNiceTicks(min: number, max: number, target?: number): number[];
19
19
  export interface VdBand {
20
20
  /** Start of each band. */
21
21
  start: number;
@@ -25,27 +25,27 @@ export interface VdBand {
25
25
  step: number;
26
26
  }
27
27
  /** Evenly spaced bands across `range` for `count` categories. */
28
- export declare function bands(count: number, range: readonly [number, number]): VdBand[];
28
+ export declare function vdBands(count: number, range: readonly [number, number]): VdBand[];
29
29
  /** Index of the band nearest to `position` (pointer or keyboard), clamped. */
30
- export declare function nearestIndex(position: number, count: number, range: readonly [number, number]): number;
30
+ export declare function vdNearestIndex(position: number, count: number, range: readonly [number, number]): number;
31
31
  export interface VdStackSegment {
32
32
  from: number;
33
33
  to: number;
34
34
  }
35
35
  /** Stacks positive values upward and negative values downward from zero, per category. */
36
- export declare function stack(series: readonly VdChartSeries[], count: number): VdStackSegment[][];
36
+ export declare function vdStack(series: readonly VdChartSeries[], count: number): VdStackSegment[][];
37
37
  /** [min, max] over all values (stacked totals when `stacked`). */
38
- export declare function extent(series: readonly VdChartSeries[], count: number, stacked: boolean): readonly [number, number];
38
+ export declare function vdExtent(series: readonly VdChartSeries[], count: number, stacked: boolean): readonly [number, number];
39
39
  /**
40
40
  * A bar from `base` to `end` along the value axis, `thickness` wide, centred at `center` on the
41
41
  * category axis. The data end is rounded (`radius`), the baseline end square.
42
42
  */
43
- export declare function barPath(center: number, thickness: number, base: number, end: number, radius: number, orientation: 'vertical' | 'horizontal'): string;
43
+ export declare function vdBarPath(center: number, thickness: number, base: number, end: number, radius: number, orientation: 'vertical' | 'horizontal'): string;
44
44
  export type VdPoint = readonly [x: number, y: number] | null;
45
45
  /** Polyline through points; a `null` starts a new segment (missing data is a gap). */
46
- export declare function linePath(points: readonly VdPoint[]): string;
46
+ export declare function vdLinePath(points: readonly VdPoint[]): string;
47
47
  /** Closed area between each continuous run of points and the baseline. */
48
- export declare function areaPath(points: readonly VdPoint[], baseline: number): string;
48
+ export declare function vdAreaPath(points: readonly VdPoint[], baseline: number): string;
49
49
  type VdChartKind = 'bar' | 'line';
50
50
  /** Formats a value for tooltips and the table (full precision, locale-aware). */
51
51
  type VdChartFormat = (value: number) => string;
@@ -136,6 +136,9 @@ export declare abstract class VdFieldControlBase implements OnInit {
136
136
  /** Mirrored Reactive/Template forms state; set once the control is resolved (ngOnInit). */
137
137
  private readonly ngSource;
138
138
  private readonly ngState;
139
+ protected readonly isRadio: boolean;
140
+ /** Required by a Reactive/Template validator while the `required` input is unset. */
141
+ protected readonly requiredByValidator: Signal<boolean>;
139
142
  /** Invalid as displayed: forced, or form-invalid after the user has touched the control. */
140
143
  readonly showInvalid: Signal<boolean>;
141
144
  private readonly fieldControl;