rei-kit 2.24.0 → 2.25.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.
package/dist/styles.css CHANGED
@@ -342,16 +342,16 @@
342
342
  background: linear-gradient(to right, var(--rk-scroll-fade), transparent);
343
343
  }
344
344
 
345
- .rk-listbox[data-v-7f8cd788] {
345
+ .rk-listbox[data-v-3cd5a3c6] {
346
346
  overflow-y: auto;
347
347
  border-radius: var(--radius-card);
348
348
  padding: 0.25rem;
349
349
  }
350
- .rk-listbox[data-v-7f8cd788]:focus-visible {
350
+ .rk-listbox[data-v-3cd5a3c6]:focus-visible {
351
351
  outline: 2px solid var(--color-primary);
352
352
  outline-offset: 1px;
353
353
  }
354
- .rk-listbox-option[data-v-7f8cd788] {
354
+ .rk-listbox-option[data-v-3cd5a3c6] {
355
355
  display: flex;
356
356
  cursor: pointer;
357
357
  align-items: center;
@@ -365,38 +365,43 @@
365
365
  /* The current row shows only while the list has focus. A list that is not
366
366
  being used has no "current" row, and a highlight left behind on one reads
367
367
  as a selection — which is exactly what it is not. */
368
- .rk-listbox:focus-within .rk-listbox-option.is-active[data-v-7f8cd788] {
368
+ .rk-listbox:focus-within .rk-listbox-option.is-active[data-v-3cd5a3c6] {
369
369
  background: var(--color-muted);
370
370
  }
371
- .rk-listbox-option.is-chosen[data-v-7f8cd788] {
372
- color: var(--color-primary);
371
+
372
+ /* The chosen row is its tinted ground, its weight and its tick — not a
373
+ primary-coloured label on a ten per cent tint of primary, which is the
374
+ same fault `BaseBadge` had: a faint wash of a colour is still nearly that
375
+ colour, and the pair measured 4.16:1. */
376
+ .rk-listbox-option.is-chosen[data-v-3cd5a3c6] {
377
+ color: var(--color-ink);
373
378
  font-weight: 500;
374
379
  }
375
380
 
376
381
  /* Chosen is the tick and the tint, and it holds whether the list is in use
377
382
  or not: the current option and the chosen one are different things. */
378
- .rk-listbox-option.is-chosen[data-v-7f8cd788] {
383
+ .rk-listbox-option.is-chosen[data-v-3cd5a3c6] {
379
384
  background: color-mix(in oklab, var(--color-primary) 10%, transparent);
380
385
  }
381
- .rk-listbox:focus-within .rk-listbox-option.is-chosen.is-active[data-v-7f8cd788] {
386
+ .rk-listbox:focus-within .rk-listbox-option.is-chosen.is-active[data-v-3cd5a3c6] {
382
387
  background: color-mix(in oklab, var(--color-primary) 20%, transparent);
383
388
  }
384
- .rk-listbox-option.is-disabled[data-v-7f8cd788] {
389
+ .rk-listbox-option.is-disabled[data-v-3cd5a3c6] {
385
390
  cursor: not-allowed;
386
391
  opacity: 0.45;
387
392
  }
388
- .rk-listbox-label[data-v-7f8cd788] {
393
+ .rk-listbox-label[data-v-3cd5a3c6] {
389
394
  display: block;
390
395
  overflow: hidden;
391
396
  text-overflow: ellipsis;
392
397
  white-space: nowrap;
393
398
  }
394
- .rk-listbox-description[data-v-7f8cd788] {
399
+ .rk-listbox-description[data-v-3cd5a3c6] {
395
400
  display: block;
396
401
  font-size: 0.75rem;
397
402
  color: var(--color-ink-soft);
398
403
  }
399
- .rk-listbox-empty[data-v-7f8cd788] {
404
+ .rk-listbox-empty[data-v-3cd5a3c6] {
400
405
  padding: 1rem;
401
406
  }
402
407
 
@@ -1073,7 +1078,7 @@ to {
1073
1078
  gap: var(--spacing, .25rem);
1074
1079
  min-height: 52px;
1075
1080
  padding-block: calc(var(--spacing, .25rem) * 1.5);
1076
- color: var(--color-ink-soft, #5c7480);
1081
+ color: var(--color-ink-soft, #586f7b);
1077
1082
  flex-direction: column;
1078
1083
  flex: 1;
1079
1084
  display: flex;
@@ -1406,20 +1411,20 @@ to {
1406
1411
  font-size: 0.8125rem;
1407
1412
  }
1408
1413
 
1409
- .rk-cal[data-v-d682f18a] {
1414
+ .rk-cal[data-v-36cbc7fd] {
1410
1415
  display: flex;
1411
1416
  width: 100%;
1412
1417
  max-width: 19rem;
1413
1418
  flex-direction: column;
1414
1419
  gap: 0.5rem;
1415
1420
  }
1416
- .rk-cal-head[data-v-d682f18a] {
1421
+ .rk-cal-head[data-v-36cbc7fd] {
1417
1422
  display: flex;
1418
1423
  align-items: center;
1419
1424
  justify-content: space-between;
1420
1425
  gap: 0.25rem;
1421
1426
  }
1422
- .rk-cal-arrow[data-v-d682f18a] {
1427
+ .rk-cal-arrow[data-v-36cbc7fd] {
1423
1428
  display: grid;
1424
1429
  width: 2rem;
1425
1430
  height: 2rem;
@@ -1428,40 +1433,40 @@ to {
1428
1433
  color: var(--color-ink);
1429
1434
  transition: background-color var(--duration-fast) var(--ease-standard);
1430
1435
  }
1431
- .rk-cal-arrow[data-v-d682f18a]:hover {
1436
+ .rk-cal-arrow[data-v-36cbc7fd]:hover {
1432
1437
  background: var(--color-muted);
1433
1438
  }
1434
- .rk-cal-title[data-v-d682f18a] {
1439
+ .rk-cal-title[data-v-36cbc7fd] {
1435
1440
  border-radius: var(--radius-cell);
1436
1441
  padding: 0.25rem 0.625rem;
1437
1442
  font-size: 0.875rem;
1438
1443
  font-weight: 600;
1439
1444
  color: var(--color-ink);
1440
1445
  }
1441
- .rk-cal-title[data-v-d682f18a]:hover {
1446
+ .rk-cal-title[data-v-36cbc7fd]:hover {
1442
1447
  background: var(--color-muted);
1443
1448
  }
1444
- .rk-cal-weekdays[data-v-d682f18a],
1445
- .rk-cal-week[data-v-d682f18a] {
1449
+ .rk-cal-weekdays[data-v-36cbc7fd],
1450
+ .rk-cal-week[data-v-36cbc7fd] {
1446
1451
  display: grid;
1447
1452
  grid-template-columns: repeat(7, minmax(0, 1fr));
1448
1453
  }
1449
- .rk-cal-weekdays[data-v-d682f18a] {
1454
+ .rk-cal-weekdays[data-v-36cbc7fd] {
1450
1455
  gap: 2px;
1451
1456
  font-size: 0.6875rem;
1452
1457
  font-weight: 600;
1453
1458
  text-align: center;
1454
1459
  color: var(--color-ink-soft);
1455
1460
  }
1456
- .rk-cal-grid[data-v-d682f18a] {
1461
+ .rk-cal-grid[data-v-36cbc7fd] {
1457
1462
  display: grid;
1458
1463
  gap: 2px;
1459
1464
  }
1460
- .rk-cal-cell[data-v-d682f18a] {
1465
+ .rk-cal-cell[data-v-36cbc7fd] {
1461
1466
  display: grid;
1462
1467
  place-items: center;
1463
1468
  }
1464
- .rk-cal-day[data-v-d682f18a] {
1469
+ .rk-cal-day[data-v-36cbc7fd] {
1465
1470
  display: grid;
1466
1471
  width: 100%;
1467
1472
  height: 2.25rem;
@@ -1474,53 +1479,57 @@ to {
1474
1479
  background-color var(--duration-fast) var(--ease-standard),
1475
1480
  color var(--duration-fast) var(--ease-standard);
1476
1481
  }
1477
- .rk-cal-day[data-v-d682f18a]:hover:not(:disabled) {
1482
+ .rk-cal-day[data-v-36cbc7fd]:hover:not(:disabled) {
1478
1483
  background: var(--color-muted);
1479
1484
  }
1480
- .rk-cal-day[data-v-d682f18a]:focus-visible {
1485
+ .rk-cal-day[data-v-36cbc7fd]:focus-visible {
1481
1486
  outline: 2px solid var(--color-primary);
1482
1487
  outline-offset: -2px;
1483
1488
  }
1484
1489
 
1485
1490
  /* A day from the month either side: still reachable, visibly not this month. */
1486
- .rk-cal-day.is-outside[data-v-d682f18a] {
1491
+ /* `ink-soft` and nothing else. It used to carry `opacity: 0.55` on top,
1492
+ which took a colour that clears AA down to 2.2:1 — and these are real
1493
+ buttons with real labels, reachable by script and read out by name, not
1494
+ decoration. The softer ink is already the difference between this month
1495
+ and the next. */
1496
+ .rk-cal-day.is-outside[data-v-36cbc7fd] {
1487
1497
  color: var(--color-ink-soft);
1488
- opacity: 0.55;
1489
1498
  }
1490
- .rk-cal-day.is-inside[data-v-d682f18a] {
1499
+ .rk-cal-day.is-inside[data-v-36cbc7fd] {
1491
1500
  background: color-mix(in oklab, var(--color-primary) 14%, transparent);
1492
1501
  border-radius: 0;
1493
1502
  }
1494
- .rk-cal-day.is-selected[data-v-d682f18a] {
1503
+ .rk-cal-day.is-selected[data-v-36cbc7fd] {
1495
1504
  background: var(--color-primary);
1496
1505
  color: var(--color-on-primary);
1497
1506
  font-weight: 600;
1498
1507
  opacity: 1;
1499
1508
  }
1500
- .rk-cal-day[aria-current='date'][data-v-d682f18a]:not(.is-selected) {
1509
+ .rk-cal-day[aria-current='date'][data-v-36cbc7fd]:not(.is-selected) {
1501
1510
  box-shadow: inset 0 0 0 1px var(--color-primary);
1502
1511
  }
1503
- .rk-cal-day[data-v-d682f18a]:disabled {
1512
+ .rk-cal-day[data-v-36cbc7fd]:disabled {
1504
1513
  cursor: not-allowed;
1505
1514
  opacity: 0.3;
1506
1515
  }
1507
- .rk-cal-blocks[data-v-d682f18a] {
1516
+ .rk-cal-blocks[data-v-36cbc7fd] {
1508
1517
  display: grid;
1509
1518
  grid-template-columns: repeat(3, minmax(0, 1fr));
1510
1519
  gap: 0.375rem;
1511
1520
  }
1512
- .rk-cal-block[data-v-d682f18a] {
1521
+ .rk-cal-block[data-v-36cbc7fd] {
1513
1522
  height: 2.5rem;
1514
1523
  border-radius: var(--radius-cell);
1515
1524
  font-size: 0.8125rem;
1516
1525
  color: var(--color-ink);
1517
1526
  transition: background-color var(--duration-fast) var(--ease-standard);
1518
1527
  }
1519
- .rk-cal-block[data-v-d682f18a]:hover {
1528
+ .rk-cal-block[data-v-36cbc7fd]:hover {
1520
1529
  background: var(--color-muted);
1521
1530
  }
1522
1531
 
1523
- .rk-chip[data-v-c94a820d] {
1532
+ .rk-chip[data-v-7939c4e0] {
1524
1533
  display: inline-flex;
1525
1534
  max-width: 100%;
1526
1535
  align-items: center;
@@ -1533,7 +1542,7 @@ to {
1533
1542
  background: var(--color-muted);
1534
1543
  color: var(--color-ink);
1535
1544
  }
1536
- .rk-chip-body[data-v-c94a820d] {
1545
+ .rk-chip-body[data-v-7939c4e0] {
1537
1546
  display: inline-flex;
1538
1547
  min-width: 0;
1539
1548
  align-items: center;
@@ -1541,42 +1550,49 @@ to {
1541
1550
  border-radius: 9999px;
1542
1551
  color: inherit;
1543
1552
  }
1544
- .rk-chip-body.is-button[data-v-c94a820d] {
1553
+ .rk-chip-body.is-button[data-v-7939c4e0] {
1545
1554
  cursor: pointer;
1546
1555
  }
1547
- .rk-chip.is-selected[data-v-c94a820d] {
1556
+ .rk-chip.is-selected[data-v-7939c4e0] {
1548
1557
  background: var(--color-primary);
1549
1558
  color: var(--color-on-primary);
1550
1559
  }
1551
- .rk-chip.is-disabled[data-v-c94a820d] {
1560
+ .rk-chip.is-disabled[data-v-7939c4e0] {
1552
1561
  cursor: not-allowed;
1553
1562
  opacity: 0.5;
1554
1563
  }
1555
1564
 
1556
1565
  /* The tones tint rather than fill: a row of chips in five solid colours is a
1557
1566
  row where nothing stands out. The selected one fills, and that is the point
1558
- of it. */
1559
- .rk-chip.tone-primary[data-v-c94a820d] {
1567
+ of it.
1568
+
1569
+ The ground and the edge carry the role; `ink` carries the words. Two of
1570
+ these used to write the role straight onto a tint of itself and the other
1571
+ two mixed it most of the way there, which is the same fault by degrees —
1572
+ a browser measured the warning chip at 4.13:1. There is one answer to
1573
+ this in the kit now, and `BaseBadge`, `BaseAlert` and `BaseListbox` give
1574
+ the same one. */
1575
+ .rk-chip.tone-primary[data-v-7939c4e0] {
1560
1576
  background: color-mix(in oklab, var(--color-primary) 12%, transparent);
1561
1577
  border-color: color-mix(in oklab, var(--color-primary) 25%, transparent);
1562
- color: var(--color-primary);
1578
+ color: var(--color-ink);
1563
1579
  }
1564
- .rk-chip.tone-success[data-v-c94a820d] {
1580
+ .rk-chip.tone-success[data-v-7939c4e0] {
1565
1581
  background: color-mix(in oklab, var(--color-positive) 14%, transparent);
1566
1582
  border-color: color-mix(in oklab, var(--color-positive) 28%, transparent);
1567
- color: color-mix(in oklab, var(--color-positive) 80%, var(--color-ink));
1583
+ color: var(--color-ink);
1568
1584
  }
1569
- .rk-chip.tone-warning[data-v-c94a820d] {
1585
+ .rk-chip.tone-warning[data-v-7939c4e0] {
1570
1586
  background: color-mix(in oklab, var(--color-warning) 16%, transparent);
1571
1587
  border-color: color-mix(in oklab, var(--color-warning) 30%, transparent);
1572
- color: color-mix(in oklab, var(--color-warning) 75%, var(--color-ink));
1588
+ color: var(--color-ink);
1573
1589
  }
1574
- .rk-chip.tone-danger[data-v-c94a820d] {
1590
+ .rk-chip.tone-danger[data-v-7939c4e0] {
1575
1591
  background: color-mix(in oklab, var(--color-negative) 12%, transparent);
1576
1592
  border-color: color-mix(in oklab, var(--color-negative) 26%, transparent);
1577
- color: var(--color-negative);
1593
+ color: var(--color-ink);
1578
1594
  }
1579
- .rk-chip-remove[data-v-c94a820d] {
1595
+ .rk-chip-remove[data-v-7939c4e0] {
1580
1596
  display: grid;
1581
1597
  width: 1.125rem;
1582
1598
  height: 1.125rem;
@@ -1587,7 +1603,7 @@ to {
1587
1603
  opacity: 0.7;
1588
1604
  transition: opacity var(--duration-fast) var(--ease-standard);
1589
1605
  }
1590
- .rk-chip-remove[data-v-c94a820d]:hover {
1606
+ .rk-chip-remove[data-v-7939c4e0]:hover {
1591
1607
  opacity: 1;
1592
1608
  background: color-mix(in oklab, currentColor 15%, transparent);
1593
1609
  }
package/dist/tokens.css CHANGED
@@ -22,7 +22,7 @@
22
22
  --color-surface: #ffffff;
23
23
  --color-muted: #ddf4e7;
24
24
  --color-ink: #0f2229;
25
- --color-ink-soft: #5c7480;
25
+ --color-ink-soft: #586f7b;
26
26
  --color-hair: #e1edea;
27
27
 
28
28
  /* ---------------------------------------------------------------------
@@ -72,7 +72,7 @@
72
72
  --color-primary: #26667f;
73
73
  --color-accent: #124170;
74
74
  --color-positive: #67c090;
75
- --color-negative: #c9463b;
75
+ --color-negative: #c7453a;
76
76
  --color-warning: #d89a3e;
77
77
 
78
78
  --color-on-primary: #ffffff;
@@ -87,7 +87,7 @@
87
87
  --color-primary: #26667f;
88
88
  --color-accent: #124170;
89
89
  --color-positive: #67c090;
90
- --color-negative: #c9463b;
90
+ --color-negative: #c7453a;
91
91
  --color-warning: #d89a3e;
92
92
 
93
93
  --color-on-primary: #ffffff;
@@ -15,6 +15,7 @@
15
15
  */
16
16
  export { default as BaseAccordion } from './BaseAccordion.vue';
17
17
  export type { AccordionItem } from './BaseAccordion.vue';
18
+ /** Where this page sits, and the way back up. */
18
19
  export { default as BaseBreadcrumb } from './BaseBreadcrumb.vue';
19
20
  export type { Crumb } from './BaseBreadcrumb.vue';
20
21
  /**
@@ -29,6 +30,7 @@ export type { Crumb } from './BaseBreadcrumb.vue';
29
30
  * Menu key, or it is a set of actions a keyboard cannot reach at all.
30
31
  */
31
32
  export { default as BaseContextMenu } from './BaseContextMenu.vue';
33
+ /** One section that opens and closes. */
32
34
  export { default as BaseDisclosure } from './BaseDisclosure.vue';
33
35
  /**
34
36
  * `BaseHoverCard`, for when the answer is a thing rather than a sentence —
@@ -48,6 +50,7 @@ export { default as BaseDrawer } from './BaseDrawer.vue';
48
50
  * to make somebody reaching for one notice the other exists.
49
51
  */
50
52
  export { default as BaseModal } from './BaseModal.vue';
53
+ /** Moving between pages of a list. */
51
54
  export { default as BasePagination } from './BasePagination.vue';
52
55
  /**
53
56
  * Everything the app can do, behind ⌘K. In the wide entry because it is a
@@ -67,9 +70,18 @@ export type { DataColumn, TableSort } from './DataTable.vue';
67
70
  * a desk-sized screen is arranged with, and that a phone never shows.
68
71
  */
69
72
  export { default as BaseSplitter } from './BaseSplitter.vue';
73
+ /**
74
+ * A row of controls that belong together: a formatting bar, a row of view
75
+ * switches, the actions over a table.
76
+ */
70
77
  export { default as BaseToolbar } from './BaseToolbar.vue';
78
+ /**
79
+ * A tree of things that contain things: folders, a category list, a table
80
+ * of contents.
81
+ */
71
82
  export { default as BaseTree } from './BaseTree.vue';
72
83
  export type { TreeNode } from './BaseTree.vue';
84
+ /** Two lists and the way between them: what is available, what is chosen. */
73
85
  export { default as TransferList } from './TransferList.vue';
74
86
  /**
75
87
  * One question, asked the way the screen expects: a modal on a wide screen,
@@ -77,11 +89,18 @@ export { default as TransferList } from './TransferList.vue';
77
89
  * app that only ever shows the sheet should reach for `BaseSheet` itself.
78
90
  */
79
91
  export { default as ResponsiveDialog } from './ResponsiveDialog.vue';
92
+ /** Sections of one page, one visible at a time. */
80
93
  export { default as BaseTabs } from './BaseTabs.vue';
81
94
  export type { TabPanel } from './BaseTabs.vue';
95
+ /** A short label that appears beside a control. */
82
96
  export { default as BaseTooltip } from './BaseTooltip.vue';
97
+ /**
98
+ * A wide site's navigation, where a section has more in it than a row can
99
+ * hold: columns of links under a heading, opened from the bar.
100
+ */
83
101
  export { default as MegaMenu } from './MegaMenu.vue';
84
102
  export type { MegaMenuColumn, MegaMenuItem, MegaMenuLink } from './MegaMenu.vue';
103
+ /** The primary navigation of a wide site. */
85
104
  export { default as NavLinks } from './NavLinks.vue';
86
105
  export type { NavLinkItem } from './NavLinks.vue';
87
106
  /**
package/dist/web.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as BaseCheckbox_default, c as useBoundValue, d as ensureSheetRoot, n as elementDirection, o as BaseSheet_default, r as horizontalStep, s as inertOutside, t as focusTarget } from "./focus-target-DRgd8UnQ.js";
2
- import { a as BaseSkeleton_default, c as useMediaQuery, i as focusableWithin, n as ScrollArea_default, o as useMenuKeys, s as useAnchoredPanel, t as BaseListbox_default } from "./BaseListbox-BQoSwYdJ.js";
2
+ import { a as BaseSkeleton_default, c as useMediaQuery, i as focusableWithin, n as ScrollArea_default, o as useMenuKeys, s as useAnchoredPanel, t as BaseListbox_default } from "./BaseListbox-DvZ7IhNn.js";
3
3
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
4
4
  import { t as BaseButton_default } from "./BaseButton-RN2an975.js";
5
5
  import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, mergeModels, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, unref, useId, useModel, useTemplateRef, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rei-kit",
3
- "version": "2.24.0",
3
+ "version": "2.25.0",
4
4
  "description": "One kit, every look. 105 accessible Vue 3 + Tailwind 4 components, four materials (quiet, glass, brutal, soft) and ten WCAG-checked palettes, each switched with one attribute.",
5
5
  "keywords": [
6
6
  "vue",
@@ -107,7 +107,8 @@
107
107
  "size": "node scripts/size.mjs",
108
108
  "palettes:check": "node scripts/build-palettes.mjs --check",
109
109
  "type-check:showcase": "vue-tsc -p tsconfig.showcase.json --noEmit",
110
- "type-check:strict": "vue-tsc -p tsconfig.strict.json --noEmit"
110
+ "type-check:strict": "vue-tsc -p tsconfig.strict.json --noEmit",
111
+ "test:browser": "pnpm showcase:build && playwright test"
111
112
  },
112
113
  "peerDependencies": {
113
114
  "@supabase/supabase-js": "^2.0.0",
@@ -129,6 +130,8 @@
129
130
  }
130
131
  },
131
132
  "devDependencies": {
133
+ "@axe-core/playwright": "^4.13.0",
134
+ "@playwright/test": "^1.63.0",
132
135
  "@supabase/supabase-js": "^2.112.4",
133
136
  "@tailwindcss/vite": "^4.3.3",
134
137
  "@tsconfig/node24": "^24.0.5",