@botiverse/raft-ui 0.22.0 → 0.23.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/CHANGELOG.md +121 -0
- package/dist/components/steps/steps.css +15 -10
- package/dist/components/timeline/timeline.css +2 -2
- package/dist/foundation.css +9 -3
- package/dist/{inbox-item.recipe-3j4DHKZ2.mjs → inbox-item-B-y7PxZ_.mjs} +625 -14
- package/dist/{index-DT1Hg5N-.d.mts → inbox-item-ChGeZBFb.d.mts} +263 -4
- package/dist/index.d.mts +40 -252
- package/dist/index.mjs +356 -640
- package/dist/style.css +7 -7
- package/dist/styles.css +80 -5
- package/dist/tokens.json +15 -2
- package/dist/wip.d.mts +65 -2
- package/dist/wip.mjs +140 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,124 @@
|
|
|
1
|
+
## [0.23.0](https://github.com/botiverse/raft-design/compare/v0.22.1...v0.23.0) (2026-10-22)
|
|
2
|
+
|
|
3
|
+
### Design System
|
|
4
|
+
|
|
5
|
+
- **Switch on the region's width**: a layout switches on the width of the region it sits in (a panel, a column, a card), not on the window's. A component that switches its own layout makes itself a container, so it lays out the same in a 360px panel on a wide window as on a phone; it then fills its row and needs a parent with a definite width. Only what the window itself sizes reads the window (the page shell, dialogs, sheets, toasts), and mouse or touch is read with `pointer` and `hover`, never with the width. Every row needs a way to give way: a row of controls that still doesn't fit wraps onto a second line, and a value such as an email truncates last. Whether a part's content fits is measured, not guessed from a width. It applies to DescriptionList, MessageActionCard, MessageImageGallery, MessageVideoPreview, MessageForwardedBundleGallery, Steps, the TasksPanel toolbar, ActivityInboxSelectionToolbar, ListRowMeta, SegmentedControl, SidebarSectionControls, SearchEntityResult and CodeBlockPre. ([#721](https://github.com/botiverse/raft-design/pull/721), [#733](https://github.com/botiverse/raft-design/pull/733))
|
|
6
|
+
- Why: the same component sits in a narrow panel on a wide window and fills a phone, so a layout that asked the window laid itself out for a screen it didn't have (a two-column list in a 360px panel, a step row that wrapped where it should stack); every layout that switched on the window was moved to its own region, or to the input where the switch is about touch.
|
|
7
|
+
- Affects: the switch points listed under Breaking Changes and Changed below.
|
|
8
|
+
- Docs: https://raft-design.botiverse.build/patterns/responsive/#switch-on-the-regions-width
|
|
9
|
+
- **Stacked buttons each take a frame**: when buttons stack full width (a dialog footer whose row doesn't fit, a bottom or top sheet's actions), a ghost button there takes the ink border of `default`, with its hover and press; it goes back to frameless when the row fits again. It applies to Button, DialogFooter, AlertDialogFooter and DrawerActions. ([#727](https://github.com/botiverse/raft-design/pull/727))
|
|
10
|
+
- Why: stretched to the full width, a frameless Cancel read as a line of text under the commit button, not as a button; once buttons stack, each needs its own box.
|
|
11
|
+
- Affects: a stacked ghost button: border `transparent` → `line-strong` on `layer-card`, hover and press `overlay-medium`, as `default`; text sizes `xs` to `xl` only, ghost icon buttons stay frameless.
|
|
12
|
+
- Docs: https://raft-design.botiverse.build/components/dialog/#the-footer
|
|
13
|
+
- **Text selection: its own token**: selected text (`::selection`) is painted with the new `selection` token and keeps its own text color. In light mode it is `brand-soft`, as before; in dark mode it is `brand` over the page at 22%, the same wash as a commented passage. `brand-soft` stays the menu highlight. It applies to MessageItem text. ([#730](https://github.com/botiverse/raft-design/pull/730))
|
|
14
|
+
- Why: in dark mode `brand-soft` left a selection at 1.23:1 against the canvas, so it was hard to see what was selected; a menu row's highlight and a selection need different values in dark mode, so they no longer share one.
|
|
15
|
+
- Affects: dark `selection` `brand-soft` (`oklch(0.5501 0.0999 91.5 / 0.2)`) → `color-mix(in oklch, var(--brand-400) 22%, transparent)`: 1.23:1 → 1.77:1 against the canvas, the selected text 7.7:1 (APCA Lc 80). Light mode is unchanged (1.14:1 against the canvas, the text 16.5:1, Lc 96).
|
|
16
|
+
- Docs: https://raft-design.botiverse.build/foundations/color/#text-selection
|
|
17
|
+
|
|
18
|
+
### Breaking Changes
|
|
19
|
+
|
|
20
|
+
- **MessageItem**: the header keeps no room for the hover toolbar, and `--mi-toolbar-reserve` is no longer read. At rest the sender line has the full width; while the toolbar shows (hover, focus inside the row, an open menu), the end of a sender line long enough to reach the corner fades out under it. `MessageItemToolbar` measures its own width onto the row as `--mi-toolbar-width`, so a toolbar with more or fewer buttons masks exactly its width. ([#726](https://github.com/botiverse/raft-design/pull/726))
|
|
21
|
+
- Why: keeping room for the toolbar cut the name to a few letters in a narrow column all the time, to protect a corner that is covered only while the pointer is on that message; the line now keeps its full width and nothing reflows on hover.
|
|
22
|
+
- Affects: with a mouse, header end padding `--mi-toolbar-reserve` (default 7rem) → 0. While the toolbar shows, the header is masked from 4px left of the toolbar's left edge to its end, after a 12px fade (`--mi-header-mask`); a row without a `MessageItemToolbar` masks nothing. The time's tooltip, when it fades out under the toolbar, can be pointed at once the pointer leaves the toolbar, and stays in the keyboard order.
|
|
23
|
+
- Migrate: remove `--mi-toolbar-reserve` wherever you set it; it has no effect. Render the toolbar with `MessageItemToolbar` inside the `MessageItem` row, which writes `--mi-toolbar-width`; a hover toolbar of your own gets no fade unless it sets `--mi-toolbar-width` (its width in px) on the row (`[data-message-item]`).
|
|
24
|
+
- Docs: https://raft-design.botiverse.build/components/message-item/#behavior
|
|
25
|
+
- **DescriptionList** `direction="horizontal"`, **MessageActionCardContent**, **MessageImageGallery**, **MessageForwardedBundleGallery**, **Steps** (without `vertical`) and **TasksPanelRoot** are size containers (`container-type: inline-size`) and switch their layout on their own width instead of the window's; the list, the galleries and the step row fill their row (`width: 100%`). ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
26
|
+
- Why: see Switch on the region's width, above.
|
|
27
|
+
- Affects: DescriptionList stacks below 24rem (384px) of its own width (was below a 640px window), the value right under its label (its 32px minimum row height dropped) and 10px between pairs (the 2px row gap plus 8px; was 2px). MessageActionCard properties stack below 24rem of the card's content (was below a 640px window) with the same spacing, the value's 6px padding above and below dropped; a card at its 440px cap keeps two columns. MessageImageGallery: at most `min(360px, 100%)` of its column (was `min(360px, 100vw − 112px)` below a 768px window); rows 8rem (7rem with three images) below 360px of the gallery's own width and 9rem (8rem) at it (was by a 640px window); three images stay two across and one under them. MessageForwardedBundleGallery: a row of three is three across from 360px of the gallery's own width (was from a 768px window) and two across below; its rows grow as above from 360px (was from a 640px window). Steps: below 40rem (640px) of the row's own width each step stacks its text under its marker (was below a 640px window), and from 40rem a row too long for its width wraps. TasksPanelToolbar: New Task and the view switch on one line and the filters on the next below 28rem (448px) of the panel's width (was below a 768px window), one wrapping row from 28rem; toolbar and viewport sides 16px below 28rem, 20px from it (was by a 768px window). The same window can now show a different layout: a narrow panel on a desktop takes the narrow layout, and a wide region on a small window keeps the wide one.
|
|
28
|
+
- Migrate: put each of these in a parent with a definite width: a block, a stretched flex or grid item, or anything with a width set. In a parent that shrinks to fit its content (`inline-block`, `w-fit` or `fit-content`, an absolutely positioned box or a floating layer with no width, a flex item with `flex-basis: auto` and no width) a size container takes no width from what it holds and collapses, its text one word to a line. Keep `TasksPanelToolbar` and `TasksPanelViewport` inside `TasksPanelRoot`, and `MessageActionCardProperties` inside `MessageActionCardContent`: outside them there is no container, so the tasks toolbar keeps its two-line layout with 20px sides and the properties stay in two columns at every width. Remove window breakpoint overrides (`sm:`, `md:`, `max-sm:`) you added to adjust these layouts, and check them in your narrowest panels.
|
|
29
|
+
- Docs: https://raft-design.botiverse.build/patterns/responsive/#switch-on-the-regions-width
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **SegmentedControl** `iconsOnlyBelow="auto"`: the segments show only their icons exactly when their labelled segments don't fit the width the control is given, and their labels again once they fit. It decides before the first frame paints, and again when the room, a label, a count, the selection or a web font changes, always against the labelled layout, so it doesn't flicker at the boundary. `iconsOnlyBelow` also takes any length in `px`, `rem` or `em` (`"18.5rem"`, `"296px"`), measured against the nearest `@container` (the control's parent when there is none), beside the presets `xs` to `2xl`, which stay CSS container queries. With `auto` or a length the track carries `data-icons-only` while it shows only icons. The presets' type is exported as `SegmentedControlIconsOnlyPreset`. ([#733](https://github.com/botiverse/raft-design/pull/733))
|
|
34
|
+
- Why: a width picked for one language, one count or one font was wrong for the others, and the room a control is given changes with what sits beside it; `auto` measures the labels against that room instead.
|
|
35
|
+
- Affects: with `auto`, the control is a shrinkable flex item (`min-w-0`); leave it free to shrink in its row (don't make it `shrink-0`). In development raft-ui warns when a segment has no icon, or when `iconsOnlyBelow` is neither a preset, `auto` nor a `px`, `rem` or `em` length (the segments then keep their labels).
|
|
36
|
+
- Docs: https://raft-design.botiverse.build/components/segmented-control/#behavior
|
|
37
|
+
- **`selection`** token: `--selection` in `foundation.css` and `tokens.json`, and the Tailwind color `selection` (`selection:bg-selection`). ([#730](https://github.com/botiverse/raft-design/pull/730))
|
|
38
|
+
- Why: see Text selection: its own token, above.
|
|
39
|
+
- Affects: light `var(--brand-soft)`; dark `color-mix(in oklch, var(--brand-400) 22%, transparent)`. Paint your own `::selection` with it in place of `brand-soft`.
|
|
40
|
+
- Docs: https://raft-design.botiverse.build/foundations/color/#text-selection
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- **SegmentedControl**: the track may shrink to its row. When the row is narrower than the track, its neighbors have given way and the segments can't show only their icons (or no `iconsOnlyBelow` is set), the segments scroll sideways inside the track, the checked one kept in view, instead of spilling onto the next control; the track sets `data-overflowing` while they do. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
45
|
+
- Why: the track never shrank below its segments, so in a narrow row it ran over its neighbor; scrolling inside it is the last way it gives way.
|
|
46
|
+
- Affects: track `shrink-0` → `min-w-0 max-w-full`; while overflowing, `overflow-x: auto` with no scrollbar. Segments still never shrink. A track you made `shrink-0` yourself still never shrinks.
|
|
47
|
+
- Docs: https://raft-design.botiverse.build/components/segmented-control/#behavior
|
|
48
|
+
- **SidebarSectionControls** and **SearchEntityResult**: decided by the input, not the window's width. The section controls show at rest wherever there is no fine pointer (a touch screen, a tablet at any width) and on hover, focus or an open menu with a mouse; a search result row is at least 64px tall on a touch screen at any width. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
49
|
+
- Why: a tablet is touch at 1024px and a narrow desktop window still has a mouse, so the width was the wrong question.
|
|
50
|
+
- Affects: section controls at rest: shown below a 768px window → shown without `pointer: fine`; a narrow desktop window with a mouse now shows them on hover only. Search result `min-height: 64px`: below a 768px window → `pointer: coarse`.
|
|
51
|
+
- Docs: https://raft-design.botiverse.build/patterns/responsive/#touch-screens
|
|
52
|
+
- **ActivityInboxSelectionToolbar**: one 44px row while its controls fit, and they wrap onto a second line in a narrow column, whatever the window. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
53
|
+
- Why: it wrapped only below a 768px window, so in a narrow column on a wide window its controls overflowed.
|
|
54
|
+
- Affects: `flex-wrap` at every width (was below a 768px window only); padding 6px above and 5px below (was 8px below a 768px window, 0 with a fixed 44px height from it).
|
|
55
|
+
- Docs: https://raft-design.botiverse.build/components/activity-inbox/
|
|
56
|
+
- **ListRowMeta**: stays whole while the title gives way first, then truncates when there is still no room, so a long value (an email beside a button in a 320px row) is cut instead of running under the button. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
57
|
+
- Why: the meta never shrank, so a long value overflowed the row.
|
|
58
|
+
- Affects: `shrink-0` → `min-w-0 truncate`.
|
|
59
|
+
- Docs: https://raft-design.botiverse.build/components/list-row/#content
|
|
60
|
+
- **MessageVideoPreview**: at most `min(360px, 100%)` of its column. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
61
|
+
- Why: its cap was the window less a guess at the message's chrome, which was wrong in a thread beside a conversation.
|
|
62
|
+
- Affects: `max-width` `min(360px, 100vw − 112px)` → `min(360px, 100%)`.
|
|
63
|
+
- Docs: https://raft-design.botiverse.build/components/message-attachment/#rules
|
|
64
|
+
- **Button** `variant="ghost"`, so **DialogFooter**, **AlertDialogFooter** (`AlertDialogCancel`) and **DrawerActions**: a ghost text button inside an element with `data-stacked` takes the ink frame of `default`. Dialog and alert dialog footers set `data-stacked` only while their buttons stack; `DrawerActions` sets it in a bottom or top sheet, where its buttons are always stacked, and not in a drawer from a side. Keep writing Cancel as `ghost`. ([#727](https://github.com/botiverse/raft-design/pull/727))
|
|
65
|
+
- Why: see Stacked buttons each take a frame, above.
|
|
66
|
+
- Affects: as above; a disabled ghost button keeps the disabled fill, and ghost icon buttons stay frameless. A stacked footer's buttons have no transition until the row has been measured and painted once (`data-measured`), so the frame doesn't fade in as a dialog opens.
|
|
67
|
+
- Docs: https://raft-design.botiverse.build/components/button/#which-color
|
|
68
|
+
- **MessageItem** text: selected text uses the `selection` token, so in dark mode a selection is deeper; light mode is unchanged. ([#730](https://github.com/botiverse/raft-design/pull/730))
|
|
69
|
+
- Why: see Text selection: its own token, above.
|
|
70
|
+
- Affects: `selection:bg-brand-soft` → `selection:bg-selection`.
|
|
71
|
+
- Docs: https://raft-design.botiverse.build/foundations/color/#text-selection
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- **TaskChip** (default and `size="sm"`): the chip's baseline is its text's, so its words sit on the line of the text beside it, such as a DescriptionList label; the status pixel and icons stay centered in the chip. ([#732](https://github.com/botiverse/raft-design/pull/732))
|
|
76
|
+
- Why: a centered flex box takes its baseline from its first item, so a chip that led with its status pixel sat on the pixel's bottom edge and its words stood a pixel off the label beside them.
|
|
77
|
+
- Affects: text laid out on the baseline inside the chip with 3px above and below (default, 22px) and 2px (`sm`, 20px), marks `self-center`; heights unchanged. `variant="inline"` is unchanged.
|
|
78
|
+
- Docs: https://raft-design.botiverse.build/foundations/alignment/#text-of-different-sizes-on-one-line
|
|
79
|
+
- **CodeBlockPre**: measures again whenever the `pre` resizes or its code changes (highlighting that arrives late, code that streams in), so a line that grows too long becomes the keyboard-reachable region (`tabindex="0"`, `role="region"`) it should be. ([#721](https://github.com/botiverse/raft-design/pull/721))
|
|
80
|
+
- Why: it measured once when it mounted, so code that changed later kept the first answer.
|
|
81
|
+
- Docs: https://raft-design.botiverse.build/components/code-block/#accessibility
|
|
82
|
+
|
|
83
|
+
## [0.22.1](https://github.com/botiverse/raft-design/compare/v0.22.0...v0.22.1) (2026-10-22)
|
|
84
|
+
|
|
85
|
+
### Design System
|
|
86
|
+
|
|
87
|
+
- **Located: one highlight for every jump**: the item a jump took someone to, such as a link to a message, a search result or Activity item that opens a message, Back to the list a result was opened from, a file comment's passage or the rows a bulk change touched, shows `info-soft` at once, holds it 1.2s and fades out with `ease-out`, gone at 2s. It is layered over the item's own fill and takes the item's corners; a stronger mark (selected, current, a search match, checked, an open menu) wins and the item isn't painted; a located item doesn't answer hover while it lasts, but a press still shows. With reduced motion it is held still for 2s and then goes off without a fade. It is only a look: a jump started from the keyboard also moves focus to the item. It applies to MessageItem. ([#719](https://github.com/botiverse/raft-design/pull/719))
|
|
88
|
+
- Why: the system had one line for a jumped-to message (`info-soft`, cleared after 2 seconds, listed under selection) and nothing shared to apply it, so each jump drew its own flash with its own timing and colour; every jump now shows one highlight that goes away by itself.
|
|
89
|
+
- Affects: `info-soft` cleared at 2s → held 0–1.2s, `ease-out` fade 1.2s–2s, gone at 2s (`LOCATED_MS` = 2000); the current match of a search inside a page is a selection and keeps `info-soft` while the search is open.
|
|
90
|
+
- Docs: https://raft-design.botiverse.build/foundations/states/#located
|
|
91
|
+
- **A status light beside text is 10px**: every status light and attention dot that sits beside text, in a chip, a badge, a panel header, a sidebar row or a list row, is 10px with a 1.5px ink edge and a 2px radius; none of them is 9px. A light on an avatar's corner still follows the avatar, and the 8px `Status` `sm` stays the attention dot on an icon's corner (the NotificationCenter bell's dot, a `Status` at the default size, is 10px). It applies to Status, Badge, PanelActivity, SidebarSectionAttention, LiveAgentActivityBarStatus, NotificationCenter and its trigger's dot, the task status icons (TaskStatusIcon, TaskChip, TaskCardStatus, TaskStatusBadge, TaskList, TaskBoard), InboxItem, MessageActionCard, Timeline and the `lead-dot` utility. ([#722](https://github.com/botiverse/raft-design/pull/722))
|
|
92
|
+
- Why: every line, chip and row a light sits in is an even number of pixels, so a 9px light had half a pixel left over and was drawn with one more device pixel above it than below (0.5px off center on a 1x screen, 0.17px on a 3x one); a 10px light centers on a whole pixel.
|
|
93
|
+
- Affects: light 9px → 10px, its colour 6px → 7px; the 1.5px ink edge and 2px radius are unchanged. Avatar corner badges (`AvatarBadge`) and `Status` `xs`, `sm` and `lg` are unchanged.
|
|
94
|
+
- Docs: https://raft-design.botiverse.build/foundations/alignment/#a-mark-that-leads-text
|
|
95
|
+
- **Link blue: a deeper, quieter blue**: `foreground-link`, the blue used only for links in running text, is a deep, quiet blue: in light mode about half the chroma of a bright link blue, so it sits beside black ink and yellow without being the loudest thing on a page full of links, and still reads as a link at a glance; dark mode uses the same blue, lightened to read on the dark canvas. It applies to Markdown links and anything colored with `foreground-link`. ([#725](https://github.com/botiverse/raft-design/pull/725))
|
|
96
|
+
- Why: with the bright blue, a page full of links looked loud against the black-and-yellow brand; links keep their blue and their underline, in a deeper, quieter shade.
|
|
97
|
+
- Affects: light `oklch(0.4878 0.2432 264.4)` (#1447e6) → `oklch(0.4327 0.1282 256.54)` (#184f95); dark `oklch(0.8071 0.1007 250.45)` (#8ec5ff) → `oklch(0.717 0.1183 253.58)` (#6da7ec). Against the canvas 6.83:1 → 8.11:1 in light mode and 9.51:1 → 6.89:1 in dark mode; against `foreground` 2.75:1 → 2.32:1 and 1.44:1 → 1.98:1, still under 3:1, so the underline at rest still marks the link.
|
|
98
|
+
- Docs: https://raft-design.botiverse.build/foundations/color/#meanings-of-color
|
|
99
|
+
|
|
100
|
+
### Added
|
|
101
|
+
|
|
102
|
+
- **useLocated**, **LOCATED_MS** and **LocatedRequest**, with the `data-located` highlight in `styles.css`: `useLocated(request)` returns `true` while an item should show the located highlight; set `data-located` on the item while it does. Pass a new `request` (a counter or token, a string or number, not the item's id) for each jump once the item is on screen. The hook turns the highlight on two frames later, so a second jump to the same item restarts it, and off after `LOCATED_MS`. ([#719](https://github.com/botiverse/raft-design/pull/719))
|
|
103
|
+
- Why: see Located: one highlight for every jump, above.
|
|
104
|
+
- Affects: `[data-located]` runs a 2s animation of the registered `--located-fill` colour (`info-soft` → transparent), painted as a `background-image` layer over the item's own fill; not painted while the item is `:active`, selected (`data-selected`, `data-active="true"`, `aria-selected="true"`), current (`aria-current`) or has `data-popup-open`. The `animation` shorthand replaces the item's own animation while it is located. Don't set `data-located` by hand: left on, it keeps hiding hover.
|
|
105
|
+
- Docs: https://raft-design.botiverse.build/foundations/states/#located
|
|
106
|
+
- **MessageItem** `located`: shows the located highlight on the message row; pass `useLocated(request)`. ([#719](https://github.com/botiverse/raft-design/pull/719))
|
|
107
|
+
- Why: see Located: one highlight for every jump, above.
|
|
108
|
+
- Affects: the row's resting fill is `--located-fill` (transparent unless located), so a search match, a checked row or an open menu keeps its own fill, and the ring around a delegated face matches the row; a located row doesn't take the `fill-subtle` hover while the highlight lasts. A row without `located` renders as before.
|
|
109
|
+
- Docs: https://raft-design.botiverse.build/components/message-item/#states
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
|
|
113
|
+
- **Status** `size="md"` (the default) and the `lead-dot` utility, so also **SidebarSectionAttention**, **LiveAgentActivityBarStatus** and the **NotificationCenterTrigger** dot; **TaskStatusIcon** and the per-status task icons, so the status pixel in **TaskChip**, **TaskCardStatus**, **TaskStatusBadge**, **TaskList** and **TaskBoard**; the unread dots of **InboxItem** and **NotificationCenter**, the **MessageActionCard** status dot and the **Timeline** default marker: 9px → 10px; props and markup are unchanged. ([#722](https://github.com/botiverse/raft-design/pull/722))
|
|
114
|
+
- Why: see A status light beside text is 10px, above.
|
|
115
|
+
- Affects: `--lead-dot` 9px → 10px, so Badge and PanelActivity hold a `Status` at 10px; the task status pixel svg 9×9 → 10×10; `--r-timeline-icon-size` default 9px → 10px. A chip that holds a status pixel is 1px wider, its height unchanged. The Timeline axis column is 1px wider and a horizontal Timeline 1px taller. The NotificationCenter unread dot sits centered on the title line: top 17.5px → 17px on a phone, 18px on a desktop. The NotificationCenterTrigger dot keeps its top-right anchor and grows 1px down and left. The InboxItem unread dot takes its extra pixel out of the gap below it, so rows keep their height.
|
|
116
|
+
- Docs: https://raft-design.botiverse.build/components/status/#sizes
|
|
117
|
+
- **`foreground-link`** token: light and dark values deepened to the quieter link blue, in `foundation.css` and `tokens.json`; the token name is unchanged. ([#725](https://github.com/botiverse/raft-design/pull/725))
|
|
118
|
+
- Why: see Link blue: a deeper, quieter blue, above.
|
|
119
|
+
- Affects: light #1447e6 → #184f95, dark #8ec5ff → #6da7ec (values above). Markdown links take the new blue, and so does their hover colour (the link blue mixed 20% toward `foreground`).
|
|
120
|
+
- Docs: https://raft-design.botiverse.build/foundations/color/#meanings-of-color
|
|
121
|
+
|
|
1
122
|
## [0.22.0](https://github.com/botiverse/raft-design/compare/v0.21.2...v0.22.0) (2026-10-22)
|
|
2
123
|
|
|
3
124
|
### Design System
|
|
@@ -296,18 +296,23 @@
|
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
299
|
+
/* A row of steps is its own container, so it switches on its own width, not
|
|
300
|
+
the window's: a dialog or a 400px panel on a wide window is as narrow as a
|
|
301
|
+
phone (design/patterns/responsive.md#switch-on-the-regions-width). Being a
|
|
302
|
+
container, it fills its row. A row too long for its width wraps its steps
|
|
303
|
+
onto a second line. */
|
|
304
|
+
.r-steps--horizontal {
|
|
305
|
+
container-type: inline-size;
|
|
306
|
+
flex-wrap: wrap;
|
|
307
|
+
row-gap: 8px;
|
|
308
|
+
inline-size: 100%;
|
|
304
309
|
}
|
|
305
310
|
|
|
306
|
-
/*
|
|
307
|
-
the steps share the width and each stacks its
|
|
308
|
-
titles wrapping. The marker and the connector
|
|
309
|
-
spans the step below. */
|
|
310
|
-
@
|
|
311
|
+
/* A narrow row (below 40rem of its own width): the titles beside their
|
|
312
|
+
markers would overflow it, so the steps share the width and each stacks its
|
|
313
|
+
text under the marker, the titles wrapping. The marker and the connector
|
|
314
|
+
share the top line; the text spans the step below. */
|
|
315
|
+
@container (width < 40rem) {
|
|
311
316
|
.r-steps--horizontal > .r-step {
|
|
312
317
|
--r-steps-connector-gap: 6px;
|
|
313
318
|
--r-steps-connector-min-width: 8px;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
- Local CSS variables (--r-timeline-*) declared on the list; items inherit them
|
|
3
3
|
- Modifier classes rebind local variables
|
|
4
4
|
- Component styles strictly consume local variables
|
|
5
|
-
- Every marker is a status pixel: a
|
|
5
|
+
- Every marker is a status pixel: a 10px square in the item's colour with a
|
|
6
6
|
1.5px sticker-ink edge, strung on a hairline. Titles are 14/20 ink,
|
|
7
7
|
details and times Space Mono 12 in ink-3, the time on the right of the
|
|
8
8
|
row. One scale for every size; `lg` only opens the title to 16/24.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
───────────────────────────────────────────────────────────────────────── */
|
|
14
14
|
|
|
15
15
|
.r-timeline {
|
|
16
|
-
--r-timeline-icon-size: var(--r-timeline-custom-icon-size,
|
|
16
|
+
--r-timeline-icon-size: var(--r-timeline-custom-icon-size, 10px);
|
|
17
17
|
/* The type scale's callout and mono meta, so a desktop gets its sizes too. */
|
|
18
18
|
--r-timeline-title-font-size: var(--text-callout);
|
|
19
19
|
--r-timeline-content-font-size: var(--text-mono-meta);
|
package/dist/foundation.css
CHANGED
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
--foreground-on-frame: var(--sticker-ink);
|
|
158
158
|
--foreground-on-frame-muted: oklch(0.4082 0.0679 93.96);
|
|
159
159
|
--foreground-on-frame-active: var(--sticker-ink);
|
|
160
|
-
--foreground-link: oklch(0.
|
|
160
|
+
--foreground-link: oklch(0.4327 0.1282 256.54);
|
|
161
161
|
--layer-canvas: oklch(1 0 0);
|
|
162
162
|
--layer-sidebar: oklch(0.986 0.0154 86.42);
|
|
163
163
|
--layer-popover: oklch(1 0 0);
|
|
@@ -287,6 +287,10 @@
|
|
|
287
287
|
empties it while the root carries data-input-modality="pointer", which
|
|
288
288
|
installInputModality sets after a click or a tap. */
|
|
289
289
|
--focus-ring: 0 0 0 2px oklch(1 0 0), 0 0 0 4px oklch(0.1813 0.005 17.62);
|
|
290
|
+
/* Selected text (::selection). brand-soft in light mode; in dark mode brand
|
|
291
|
+
over the page at 22%, the wash of a commented passage, because brand-soft
|
|
292
|
+
left a selection almost the same as the page. */
|
|
293
|
+
--selection: var(--brand-soft);
|
|
290
294
|
--field-font-size: 16px;
|
|
291
295
|
--field-font-weight: 400;
|
|
292
296
|
--field-line-height: 24px;
|
|
@@ -351,7 +355,7 @@
|
|
|
351
355
|
--foreground-on-hud-muted: var(--foreground-muted);
|
|
352
356
|
--foreground-on-frame: oklch(0.9211 0.004 106.48);
|
|
353
357
|
--foreground-on-frame-muted: oklch(0.6984 0.0043 106.51);
|
|
354
|
-
--foreground-link: oklch(0.
|
|
358
|
+
--foreground-link: oklch(0.717 0.1183 253.58);
|
|
355
359
|
--layer-canvas: oklch(0.2213 0.0038 106.71);
|
|
356
360
|
--layer-sidebar: oklch(0.1582 0.0041 106.86);
|
|
357
361
|
--layer-popover: oklch(0.2802 0.0036 106.63);
|
|
@@ -415,6 +419,7 @@
|
|
|
415
419
|
0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8);
|
|
416
420
|
--elevation-sticker: 4px 4px 0 oklch(0 0 0);
|
|
417
421
|
--focus-ring: 0 0 0 2px oklch(0.2213 0.0038 106.71), 0 0 0 4px oklch(0.9211 0.004 106.48);
|
|
422
|
+
--selection: color-mix(in oklch, var(--brand-400) 22%, transparent);
|
|
418
423
|
--sticker-edge: oklch(0.9843 0.004 106.47 / 0.349);
|
|
419
424
|
}
|
|
420
425
|
|
|
@@ -433,7 +438,7 @@
|
|
|
433
438
|
--foreground-on-hud-muted: var(--foreground-muted);
|
|
434
439
|
--foreground-on-frame: oklch(0.9211 0.004 106.48);
|
|
435
440
|
--foreground-on-frame-muted: oklch(0.6984 0.0043 106.51);
|
|
436
|
-
--foreground-link: oklch(0.
|
|
441
|
+
--foreground-link: oklch(0.717 0.1183 253.58);
|
|
437
442
|
--layer-canvas: oklch(0.2213 0.0038 106.71);
|
|
438
443
|
--layer-sidebar: oklch(0.1582 0.0041 106.86);
|
|
439
444
|
--layer-popover: oklch(0.2802 0.0036 106.63);
|
|
@@ -497,6 +502,7 @@
|
|
|
497
502
|
0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8);
|
|
498
503
|
--elevation-sticker: 4px 4px 0 oklch(0 0 0);
|
|
499
504
|
--focus-ring: 0 0 0 2px oklch(0.2213 0.0038 106.71), 0 0 0 4px oklch(0.9211 0.004 106.48);
|
|
505
|
+
--selection: color-mix(in oklch, var(--brand-400) 22%, transparent);
|
|
500
506
|
--sticker-edge: oklch(0.9843 0.004 106.47 / 0.349);
|
|
501
507
|
}
|
|
502
508
|
}
|