@clicktap/ui 1.0.3 → 1.1.1
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/components/Breadcrumbs/BreadcrumbLink.js +1 -1
- package/components/Breadcrumbs/BreadcrumbSeparator.js +1 -1
- package/docs/migrations/2026/08/ui-2026-08-11-peer-ranges-capped.md +30 -0
- package/docs/migrations/2026/08/ui-2026-08-14-breadcrumb-trail-fully-tokenised.md +80 -0
- package/docs/migrations/index.json +2 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as u}from"react/jsx-runtime";import{Link as o}from"react-aria-components";import{cn as i}from"../../utils/cn.js";function f({children:e,className:r,...t}){return u(o,{className:i("text-fg-muted no-underline cursor-pointer","focus-visible:outline-2 focus-visible:outline focus-visible:outline-border-subtle","hover:text-fg hover:underline","current:cursor-default current:text-fg current:font-semibold","disabled:cursor-default disabled:text-fg-subtle disabled:current:text-fg",r),...t,children:e})}export{f as BreadcrumbLink,f as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e}from"react/jsx-runtime";import{Breadcrumb as i}from"react-aria-components";import{cn as n}from"../../utils/cn.js";function
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{Breadcrumb as i}from"react-aria-components";import{cn as n}from"../../utils/cn.js";function d({children:r,className:t,...o}){return e(i,{className:n("flex items-center text-fg-muted","my-0 mx-2",t),...o,children:r??e("svg",{"aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",className:"w-4 h-4",children:e("path",{d:"M6 12L10 8L6 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})}export{d as BreadcrumbSeparator,d as default};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
**Affects:** every consumer — the peer ranges are the declaration your package manager installs against.
|
|
6
6
|
**Classification:** COMPATIBILITY
|
|
7
7
|
**Breaking:** Yes for a consumer already past a ceiling. No code change; the contract narrowed.
|
|
8
|
+
**Read before updating:** the capped ranges are the contract your install resolves against — decide before taking `@clicktap/ui` 1.x, not after
|
|
8
9
|
**Ticket:** CTAP-1241
|
|
9
10
|
|
|
10
11
|
## Summary
|
|
@@ -53,6 +54,35 @@ in your own app, confirm it matches what `@clicktap/ui` resolves. The split abov
|
|
|
53
54
|
without symptoms, and duplicate react-aria/stately instances surface as subtle focus and overlay bugs
|
|
54
55
|
rather than as an error.
|
|
55
56
|
|
|
57
|
+
### When the duplicate is transitive — nothing of yours to pin
|
|
58
|
+
|
|
59
|
+
The paragraph above assumes the second copy comes from a declaration you own. Often it does not:
|
|
60
|
+
crispi resolves `react-stately` 3.49.0 cleanly across every workspace member and still carries a
|
|
61
|
+
second copy at 3.46.0, arriving via `@adobe/react-spectrum` → `react-aria-components`. No manifest of
|
|
62
|
+
theirs names it, so there is no pin to correct.
|
|
63
|
+
|
|
64
|
+
Decide it in this order:
|
|
65
|
+
|
|
66
|
+
1. **Ask whether the two copies ever share a context.** The hazard is not two versions existing; it
|
|
67
|
+
is two versions of the same *provider* — `@react-aria/overlays`' focus scope and dismiss stack,
|
|
68
|
+
most of all — being live in one tree at once. Two design systems that each portal their own
|
|
69
|
+
overlays, never nesting one inside the other, can hold separate copies indefinitely. Two copies
|
|
70
|
+
reached through the same `OverlayProvider` cannot.
|
|
71
|
+
2. **If they do share one, force a single resolution with `pnpm.overrides`:**
|
|
72
|
+
```json
|
|
73
|
+
{ "pnpm": { "overrides": { "react-stately": "3.49.0" } } }
|
|
74
|
+
```
|
|
75
|
+
A bare-name override collapses every copy in the tree whatever any package declares. Verify with
|
|
76
|
+
`pnpm why react-stately` and then exercise the *other* library's overlays — you have moved it onto
|
|
77
|
+
a version it did not choose, which is the cost of this lever.
|
|
78
|
+
3. **If they do not, record the decision and move on.** `@clicktap/ui` externalizes `react-stately`
|
|
79
|
+
and `@react-stately/*`, so the copy under a foreign design system is never the copy this package
|
|
80
|
+
imports.
|
|
81
|
+
|
|
82
|
+
What you should not do is leave the check unresolved either way. A duplicate you have decided is
|
|
83
|
+
harmless is a different state from one you have not looked at, and only the first survives the next
|
|
84
|
+
person reading `pnpm why`.
|
|
85
|
+
|
|
56
86
|
## Verify
|
|
57
87
|
|
|
58
88
|
```bash
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# The breadcrumb trail is fully tokenised, so a dark-ground app can re-theme it
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-14
|
|
4
|
+
**Package:** `@clicktap/ui`
|
|
5
|
+
**Affects:** any consumer rendering `Breadcrumbs` — and, for the diagnosis below, any consumer on a
|
|
6
|
+
dark ground.
|
|
7
|
+
**Classification:** BUGFIX
|
|
8
|
+
**Breaking:** No. One small visual change in light mode: the ancestor crumbs and the chevron move
|
|
9
|
+
from `slate-600` to the `fg-muted` token (`slate-500`), one step lighter. The current crumb is
|
|
10
|
+
unchanged.
|
|
11
|
+
|
|
12
|
+
## What was wrong
|
|
13
|
+
|
|
14
|
+
`BreadcrumbLink` and `BreadcrumbSeparator` still carried a literal `text-slate-600` — residue from
|
|
15
|
+
the CTAP-1123 token sweep. A literal palette class cannot be re-themed at all: a consumer overriding
|
|
16
|
+
`--color-fg-muted` for a dark ground got no effect on the trail, because nothing in it read that
|
|
17
|
+
token.
|
|
18
|
+
|
|
19
|
+
Both now use `text-fg-muted`, so the whole trail re-themes with the rest of the library.
|
|
20
|
+
|
|
21
|
+
## The reported symptom, and what actually causes it
|
|
22
|
+
|
|
23
|
+
The report (CTAP-1304) was that the **current** crumb is illegible on a dark ground — roughly
|
|
24
|
+
1.2:1 against a black body. That crumb is styled `current:text-fg`, which is already a token, so
|
|
25
|
+
this fix does not change it. The cause is one level up:
|
|
26
|
+
|
|
27
|
+
> `@clicktap/ui` ships **light** token defaults and deliberately does not assume a ground. Re-theming
|
|
28
|
+
> is a runtime override of the tokens — see the top of `theme.css`.
|
|
29
|
+
|
|
30
|
+
An app that paints `body { background-color: #000 }` without overriding `--color-fg` gets
|
|
31
|
+
`slate-900` text on black. That is not specific to breadcrumbs: **`text-fg` appears 132 times across
|
|
32
|
+
39 components**, so the same app has the same problem everywhere. Breadcrumbs is simply where QA
|
|
33
|
+
noticed, because the current crumb is the item you most expect to stand out.
|
|
34
|
+
|
|
35
|
+
The fix on the consumer side is two lines, and it repairs all 39 components at once:
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
:root[data-theme='dark'] {
|
|
39
|
+
--color-fg: oklch(98% 0 0);
|
|
40
|
+
--color-fg-muted: oklch(70.4% 0.04 256.788);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The new `DarkGround` story shows exactly this. Delete the two custom properties from it and it
|
|
45
|
+
reproduces the reported bug.
|
|
46
|
+
|
|
47
|
+
## Overriding just the current crumb
|
|
48
|
+
|
|
49
|
+
If you are not re-theming globally and want to repaint one crumb, there is a sharp edge worth
|
|
50
|
+
knowing — it is why an override can look like it does nothing:
|
|
51
|
+
|
|
52
|
+
> tailwind-merge only drops a conflicting class when the **variant strings match**. `current:text-fg`
|
|
53
|
+
> (ours) and `data-[current]:text-white` (the natural guess) are different variants, so both survive
|
|
54
|
+
> the merge and stylesheet order decides the winner.
|
|
55
|
+
|
|
56
|
+
Claim the same variant and it resolves deterministically:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<BreadcrumbLink className="current:text-white">Product</BreadcrumbLink>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The `OverridingTheCurrentCrumb` story demonstrates it. This is also why a consumer override written
|
|
63
|
+
against `data-[disabled]` never affected the current crumb — `disabled` and `current` are different
|
|
64
|
+
states, so it was never going to match.
|
|
65
|
+
|
|
66
|
+
## Migration checklist
|
|
67
|
+
|
|
68
|
+
- [ ] Nothing required. The trail keeps working as-is.
|
|
69
|
+
- [ ] If you are on a dark ground, override `--color-fg` and `--color-fg-muted` rather than
|
|
70
|
+
restyling components — and check the rest of your app, since the same tokens drive 39 components.
|
|
71
|
+
- [ ] If you carry a local patch repainting breadcrumb colours, it can go; if you keep one, make
|
|
72
|
+
sure it claims the `current:` variant.
|
|
73
|
+
|
|
74
|
+
## Known residue
|
|
75
|
+
|
|
76
|
+
Twenty-six literal `text-slate-*` occurrences remain elsewhere in the library (CTAP-1123 residue,
|
|
77
|
+
across `FeatureGate`, `Collection`, `Pagination`, `EmptyResults` and others). They have the same
|
|
78
|
+
un-themeable problem as the two fixed here, but mapping them onto the token ladder is a visual
|
|
79
|
+
judgement per site rather than a mechanical swap — `slate-700` and `slate-800` have no exact token —
|
|
80
|
+
so they are deliberately not swept here. Tracked separately.
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"title": "`next` and `@heroui/*` peer ranges are capped; `react-stately` pinned",
|
|
8
8
|
"classification": "COMPATIBILITY",
|
|
9
9
|
"breaking": "Yes for a consumer already past a ceiling. No code change; the contract narrowed.",
|
|
10
|
-
"affects": "every consumer — the peer ranges are the declaration your package manager installs against."
|
|
10
|
+
"affects": "every consumer — the peer ranges are the declaration your package manager installs against.",
|
|
11
|
+
"read_before_updating": "the capped ranges are the contract your install resolves against — decide before taking `@clicktap/ui` 1.x, not after"
|
|
11
12
|
},
|
|
12
13
|
{
|
|
13
14
|
"path": "2026/08/ui-2026-08-11-password-reveal-toggle.md",
|