tamga-ui 0.4.4 → 0.5.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/CHANGELOG.md +893 -0
- package/README.md +3 -5
- package/dist/blocks/count-row.d.ts +3 -8
- package/dist/blocks/count-row.d.ts.map +1 -1
- package/dist/blocks/count-row.js +3 -8
- package/dist/blocks/filter-bar.d.ts +42 -28
- package/dist/blocks/filter-bar.d.ts.map +1 -1
- package/dist/blocks/filter-bar.js +13 -5
- package/dist/blocks/index.d.ts +4 -17
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +4 -17
- package/dist/blocks/save-bar.d.ts +4 -12
- package/dist/blocks/save-bar.d.ts.map +1 -1
- package/dist/blocks/save-bar.js +4 -12
- package/dist/components/a11y.d.ts.map +1 -1
- package/dist/components/a11y.js +13 -18
- package/dist/components/advanced-input.d.ts +54 -48
- package/dist/components/advanced-input.d.ts.map +1 -1
- package/dist/components/advanced-input.js +64 -59
- package/dist/components/announcement.d.ts +34 -0
- package/dist/components/announcement.d.ts.map +1 -0
- package/dist/components/announcement.js +12 -0
- package/dist/components/appearance.d.ts +33 -1
- package/dist/components/appearance.d.ts.map +1 -1
- package/dist/components/appearance.js +78 -7
- package/dist/components/avatar.d.ts +28 -21
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +46 -22
- package/dist/components/badge.d.ts +54 -4
- package/dist/components/badge.d.ts.map +1 -1
- package/dist/components/badge.js +42 -9
- package/dist/components/bar.d.ts.map +1 -1
- package/dist/components/bar.js +4 -20
- package/dist/components/button.d.ts +15 -7
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +54 -8
- package/dist/components/chart.d.ts +5 -0
- package/dist/components/chart.d.ts.map +1 -1
- package/dist/components/chart.js +18 -11
- package/dist/components/checkbox.d.ts +23 -1
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +3 -4
- package/dist/components/chrome.d.ts +38 -54
- package/dist/components/chrome.d.ts.map +1 -1
- package/dist/components/chrome.js +55 -63
- package/dist/components/combobox.d.ts.map +1 -1
- package/dist/components/combobox.js +19 -3
- package/dist/components/data-table.d.ts +4 -4
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +15 -16
- package/dist/components/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker.js +11 -4
- package/dist/components/disclosure.d.ts +17 -2
- package/dist/components/disclosure.d.ts.map +1 -1
- package/dist/components/disclosure.js +4 -8
- package/dist/components/display.d.ts +119 -94
- package/dist/components/display.d.ts.map +1 -1
- package/dist/components/display.js +103 -106
- package/dist/components/empty-state.d.ts +70 -52
- package/dist/components/empty-state.d.ts.map +1 -1
- package/dist/components/empty-state.js +40 -52
- package/dist/components/error-state.d.ts +21 -4
- package/dist/components/error-state.d.ts.map +1 -1
- package/dist/components/error-state.js +16 -6
- package/dist/components/file-upload.d.ts +45 -2
- package/dist/components/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload.js +32 -7
- package/dist/components/gauge.d.ts +72 -9
- package/dist/components/gauge.d.ts.map +1 -1
- package/dist/components/gauge.js +52 -49
- package/dist/components/icons.d.ts +1 -1
- package/dist/components/icons.d.ts.map +1 -1
- package/dist/components/icons.js +4 -0
- package/dist/components/input.d.ts +21 -0
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +15 -1
- package/dist/components/layout.d.ts +47 -70
- package/dist/components/layout.d.ts.map +1 -1
- package/dist/components/layout.js +31 -73
- package/dist/components/link.d.ts +5 -10
- package/dist/components/link.d.ts.map +1 -1
- package/dist/components/live-scope.d.ts.map +1 -1
- package/dist/components/live-scope.js +5 -8
- package/dist/components/log-view.d.ts +32 -1
- package/dist/components/log-view.d.ts.map +1 -1
- package/dist/components/log-view.js +42 -15
- package/dist/components/number-input.d.ts +20 -2
- package/dist/components/number-input.d.ts.map +1 -1
- package/dist/components/number-input.js +32 -9
- package/dist/components/overlay.d.ts +69 -61
- package/dist/components/overlay.d.ts.map +1 -1
- package/dist/components/overlay.js +129 -78
- package/dist/components/pagination.d.ts.map +1 -1
- package/dist/components/pagination.js +12 -7
- package/dist/components/pie.d.ts.map +1 -1
- package/dist/components/pie.js +8 -7
- package/dist/components/primitives.d.ts +136 -6
- package/dist/components/primitives.d.ts.map +1 -1
- package/dist/components/primitives.js +73 -20
- package/dist/components/progress.d.ts +44 -9
- package/dist/components/progress.d.ts.map +1 -1
- package/dist/components/progress.js +21 -9
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js +11 -12
- package/dist/components/rail-link.d.ts +17 -1
- package/dist/components/rail-link.d.ts.map +1 -1
- package/dist/components/rail-link.js +3 -3
- package/dist/components/rich-text.d.ts +8 -1
- package/dist/components/rich-text.d.ts.map +1 -1
- package/dist/components/rich-text.js +13 -19
- package/dist/components/says-bubble.d.ts +38 -0
- package/dist/components/says-bubble.d.ts.map +1 -0
- package/dist/components/says-bubble.js +6 -0
- package/dist/components/scroll-x.d.ts +23 -0
- package/dist/components/scroll-x.d.ts.map +1 -0
- package/dist/components/scroll-x.js +27 -0
- package/dist/components/section.d.ts +18 -1
- package/dist/components/section.d.ts.map +1 -1
- package/dist/components/section.js +12 -1
- package/dist/components/segmented.d.ts +17 -1
- package/dist/components/segmented.d.ts.map +1 -1
- package/dist/components/segmented.js +26 -6
- package/dist/components/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton.js +1 -1
- package/dist/components/slider.d.ts +16 -2
- package/dist/components/slider.d.ts.map +1 -1
- package/dist/components/slider.js +12 -5
- package/dist/components/sparkline.d.ts +9 -2
- package/dist/components/sparkline.d.ts.map +1 -1
- package/dist/components/sparkline.js +9 -5
- package/dist/components/spinner.d.ts +16 -1
- package/dist/components/spinner.d.ts.map +1 -1
- package/dist/components/spinner.js +24 -1
- package/dist/components/square-picker.d.ts +4 -20
- package/dist/components/square-picker.d.ts.map +1 -1
- package/dist/components/square-picker.js +4 -20
- package/dist/components/stacked-bar.d.ts.map +1 -1
- package/dist/components/stacked-bar.js +5 -4
- package/dist/components/surface.d.ts +32 -3
- package/dist/components/surface.d.ts.map +1 -1
- package/dist/components/surface.js +11 -4
- package/dist/components/switch.d.ts +14 -1
- package/dist/components/switch.d.ts.map +1 -1
- package/dist/components/switch.js +2 -3
- package/dist/components/tabs.d.ts +35 -11
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +48 -5
- package/dist/components/timeline-strip.d.ts +28 -3
- package/dist/components/timeline-strip.d.ts.map +1 -1
- package/dist/components/timeline-strip.js +19 -8
- package/dist/components/tone.d.ts +51 -19
- package/dist/components/tone.d.ts.map +1 -1
- package/dist/components/tone.js +69 -15
- package/dist/components/tree-select.d.ts.map +1 -1
- package/dist/components/tree-select.js +10 -3
- package/dist/fonts/LICENSE-jetbrains-mono.txt +93 -0
- package/dist/fonts/LICENSE-onest.txt +93 -0
- package/dist/fonts/LICENSE-red-hat-display.txt +93 -0
- package/dist/fonts/jetbrains-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/onest-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/onest-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-display-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-display-latin-wght-normal.woff2 +0 -0
- package/dist/fonts.css +54 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -6
- package/dist/kit.css +3153 -652
- package/dist/lib/color.d.ts +8 -19
- package/dist/lib/color.d.ts.map +1 -1
- package/dist/lib/color.js +8 -19
- package/dist/lib/data-props.d.ts +4 -15
- package/dist/lib/data-props.d.ts.map +1 -1
- package/dist/lib/data-props.js +4 -15
- package/dist/lib/image.d.ts +4 -20
- package/dist/lib/image.d.ts.map +1 -1
- package/dist/lib/image.js +4 -20
- package/dist/lib/palette.d.ts +16 -20
- package/dist/lib/palette.d.ts.map +1 -1
- package/dist/lib/palette.js +136 -71
- package/dist/lib/scroll-lock.d.ts +4 -14
- package/dist/lib/scroll-lock.d.ts.map +1 -1
- package/dist/lib/scroll-lock.js +4 -14
- package/dist/patterns/app-shell.d.ts.map +1 -1
- package/dist/patterns/app-shell.js +4 -13
- package/dist/patterns/appearance-template.d.ts +20 -15
- package/dist/patterns/appearance-template.d.ts.map +1 -1
- package/dist/patterns/appearance-template.js +29 -8
- package/dist/patterns/list-template.d.ts.map +1 -1
- package/dist/patterns/list-template.js +1 -1
- package/dist/patterns/overview-template.d.ts.map +1 -1
- package/dist/patterns/overview-template.js +1 -1
- package/dist/patterns/settings-template.d.ts +1 -12
- package/dist/patterns/settings-template.d.ts.map +1 -1
- package/dist/patterns/settings-template.js +2 -2
- package/dist/patterns/shared.d.ts.map +1 -1
- package/dist/patterns/shared.js +8 -1
- package/dist/styles.css +2 -1
- package/dist/theme.css +94 -261
- package/package.json +3 -1
- package/dist/components/control-base.d.ts +0 -7
- package/dist/components/control-base.d.ts.map +0 -1
- package/dist/components/control-base.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,899 @@ Versions follow [semver](https://semver.org/). Through `0.x`, breaking changes m
|
|
|
5
5
|
|
|
6
6
|
> 🇹🇷 Türkçe için [tamga.org.tr/tr](https://tamga.org.tr/tr).
|
|
7
7
|
|
|
8
|
+
## 0.5.1
|
|
9
|
+
|
|
10
|
+
> Three corrections the 0.5.0 port left behind: a menu that stole the page's scroll, and the
|
|
11
|
+
> rail's hover, lift and press.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **The rail's hover is a wash again, and the current row lifts.** Hovering a row had it grow a
|
|
16
|
+
border and a base, turning every row into its own button: a rail is a list of eight, and eight
|
|
17
|
+
controls under the pointer is not navigation. Hover is now only the wash the kit already had a
|
|
18
|
+
token for (`--color-nav-hover-bg`), and the current row — which never takes that wash — lifts by
|
|
19
|
+
a pixel over its 3px base, so "you are here" is the one thing standing up. Law 2 is untouched:
|
|
20
|
+
it binds the FILL to an action, not the height, and the current row still speaks with an
|
|
21
|
+
outline. The pressed row travels 2px, which is the 3px of its base measured from where it
|
|
22
|
+
actually rests.
|
|
23
|
+
|
|
24
|
+
- **A pressed segment no longer sinks below its own ground.** The selected tab rests a pixel up so
|
|
25
|
+
its shadow has room, which puts its ground at 1px; it was travelling 2px. The physics gate could
|
|
26
|
+
not see this because it measured the ARRIVAL, not the travel, and every family with a shadow
|
|
27
|
+
used to rest flat — that is fixed too, and the gate found this the moment it could.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **A menu that starts open no longer steals the focus.** `DropdownMenu` with `defaultOpen`
|
|
32
|
+
focused its first option on mount, and the browser scrolls whatever it focuses into view: a page
|
|
33
|
+
carrying such a menu opened thousands of pixels down, past its own heading. The rule is no
|
|
34
|
+
longer "is it open" but "was it just opened" — the focus belongs to whoever performed the
|
|
35
|
+
opening. A menu the visitor opens still focuses its first option, so the arrow keys have
|
|
36
|
+
somewhere to start. Covered by a test.
|
|
37
|
+
|
|
38
|
+
## 0.5.0
|
|
39
|
+
|
|
40
|
+
> The Soft Neo Brutalism port: every component, every token and the physics behind them. The
|
|
41
|
+
> renames are under "Breaking", each with the line that moves you across.
|
|
42
|
+
|
|
43
|
+
### Removed
|
|
44
|
+
|
|
45
|
+
- **A dead layer of unprefixed classes is gone.** `theme.css` still carried `.press-surface`,
|
|
46
|
+
`.seated-surface`, `.card-surface`, `.sunk-surface`, `.app-surface`, `.gutter`, `.rail-link` and
|
|
47
|
+
a second copy of the skeleton and beacon keyframes (`.animate-skeleton-breath`,
|
|
48
|
+
`.animate-beacon-breath`). All of it predates the `tamga-` rename: the real physics lives in
|
|
49
|
+
`kit.css` as the `.tamga-*` family, and nothing in the kit, the docs site or either consuming
|
|
50
|
+
panel referenced a single one of these. One comment beside them even claimed a block had been
|
|
51
|
+
deleted while the block sat eight lines below it. 210 lines.
|
|
52
|
+
|
|
53
|
+
- **27 token names the kit itself never read.** `--shadow-raised`, `--shadow-pressed`,
|
|
54
|
+
`--shadow-seated-pressed`, `--shadow-overlay`, `--shadow-ambient`, `--shadow-rim`, the ten
|
|
55
|
+
`-foreground` pairs, `--primary`, `--secondary`, `--muted`, `--popover`, `--beacon`, `--input`,
|
|
56
|
+
`--duration-instant`, `--table-min-wide`, `--table-min-widest`, `--color-danger-solid` and
|
|
57
|
+
`--radius-lg`. They were printed on the token page, so a consumer could reasonably read them as
|
|
58
|
+
part of the kit's vocabulary, and the vocabulary was stale: the page listed `--shadow-raised` as
|
|
59
|
+
`2px 2px 0 0 var(--shadow-color)` while the kit actually paints
|
|
60
|
+
`2px 2px 0 var(--color-edge-strong)`. A name the kit does not read is a name nothing keeps
|
|
61
|
+
honest. The token page goes from 162 entries to 136, and every entry left is one the kit uses.
|
|
62
|
+
|
|
63
|
+
Migration: each has an equivalent in the kit's own family, and in most cases the same value
|
|
64
|
+
(`--primary-foreground` and `--color-accent-ink` were both `#fdfcfa` light / `#12245c` dark).
|
|
65
|
+
Kept: the raw brand ramp (`--color-brand-50/100/400/600`), which is documented as raw material
|
|
66
|
+
that the semantic tokens derive from rather than something the interface consumes.
|
|
67
|
+
|
|
68
|
+
- **19 `@theme inline` bridges nobody could reach.** `--color-background`, `--color-foreground`,
|
|
69
|
+
`--color-primary`, `--color-muted`, `--color-popover`, `--color-border`, `--color-input`, the
|
|
70
|
+
`-foreground` pairs and the rest of the shadcn-compat naming existed only to generate Tailwind
|
|
71
|
+
utilities (`bg-background`, `text-muted-foreground`, …). Nothing used them, and they were not on
|
|
72
|
+
the token page either, so they were not an offering to consumers, just weight: **266 fewer
|
|
73
|
+
generated utilities** (1401 → 1135). The raw tokens behind them are untouched, so a product that
|
|
74
|
+
writes `var(--primary)` in its own CSS still works.
|
|
75
|
+
|
|
76
|
+
Kept on purpose: `--font-sans`. No rule in the kit reads it, but Tailwind's preflight does, so
|
|
77
|
+
removing it would have quietly changed the typeface of every consumer.
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- **`DropdownMenu` takes `defaultOpen`.** A documentation surface has to be able to show the open
|
|
82
|
+
panel; until now the only way was a click, so a menu on a poster page was an empty button. Not
|
|
83
|
+
for a product screen: a menu that is open before anyone asked for it covers what is under it.
|
|
84
|
+
|
|
85
|
+
### Changed
|
|
86
|
+
|
|
87
|
+
- **`FileUpload`'s drop zone is no longer squared paper.** It reused `.tamga-art-well`, a ground
|
|
88
|
+
designed for ILLUSTRATIONS ("an instrument on paper"); behind a sentence and two lines of hint
|
|
89
|
+
text the 8px ruling competes with the words. The well now has its own class
|
|
90
|
+
(`.tamga-drop-well`): a dashed edge on the accent's palest ground, which is the quietest way to
|
|
91
|
+
say "you can drop something here". `.tamga-art-well` is unchanged and still draws illustrations.
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
|
|
95
|
+
- **`Calendar` now opens on the month of its `value`.** It always opened on the current month, so
|
|
96
|
+
a date handed to it from another month left the grid showing today with no selection anywhere in
|
|
97
|
+
sight: the caller had given a date and the calendar appeared to have ignored it. With no `value`
|
|
98
|
+
it still opens on today.
|
|
99
|
+
|
|
100
|
+
### Changed
|
|
101
|
+
|
|
102
|
+
- **`ColorSwatches`: the free-colour square now carries an eyedropper.** Its empty state was a
|
|
103
|
+
checkered ground and nothing else. The ground says "no colour here" but not what the square is
|
|
104
|
+
FOR, and this square does something none of the other six do: it opens a colour picker. The
|
|
105
|
+
glyph says that. Once a free colour is chosen the eyedropper gives way to the check mark the
|
|
106
|
+
presets use, so the "which one is selected" reading stays the same across all seven.
|
|
107
|
+
|
|
108
|
+
- **The chart family now matches the design reference.** Eight components changed, all of them
|
|
109
|
+
visual: the bar chart's rows fade to 0.4 around the one you point at (a painted row background
|
|
110
|
+
turned five rows into five boxes), the pie's first series takes the accent instead of the
|
|
111
|
+
categorical palette's olive, the score ring is a filled arc rather than a 32-segment dial, the
|
|
112
|
+
score meter became a five-band scale with a pointer rather than a filling bar, and progress
|
|
113
|
+
moved its label and number above the track and dropped the ticks that used to stand in for the
|
|
114
|
+
number.
|
|
115
|
+
|
|
116
|
+
Two rules came out of it and they hold across the family: **the first series is the accent**
|
|
117
|
+
(`seriRenk`), because most charts have one series and it is the page's real information; and
|
|
118
|
+
**emphasis is opacity, never a painted ground**.
|
|
119
|
+
|
|
120
|
+
The sparkline lost its area fill and baseline: both gave an axis-less line the look of an axis,
|
|
121
|
+
promising a scale it cannot deliver. It also lost its end marker by default (`mark` turns it
|
|
122
|
+
back on), because in a column of sparklines it repeats on every row.
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
- **The form family now matches the design reference.** Nine components, and each change answers a
|
|
126
|
+
complaint someone actually had: the combobox now **bolds the matched letters** in each option, so
|
|
127
|
+
a long list shows you why a row is in it; the date picker's cells are a 36px grid with a framed
|
|
128
|
+
today instead of text in a table; multi select shows **four chips and then `+N`**, because a field
|
|
129
|
+
holding eleven selections used to grow taller than the form; tags input asks twice before
|
|
130
|
+
destroying — the first Backspace marks the last tag, the second removes it; and tree select draws
|
|
131
|
+
a **mixed** parent when only some children are picked, instead of an unchecked one that lies.
|
|
132
|
+
|
|
133
|
+
Two of them are rebuilds rather than edits. **Rich text's active button is a wash, not a fill**:
|
|
134
|
+
three formats can be on at once, and three filled buttons broke the one-primary-action rule and
|
|
135
|
+
made the toolbar read like a warning. **Schedule input** is described under Breaking.
|
|
136
|
+
|
|
137
|
+
Number input keeps its own rule: while the field has focus it shows **what you typed**, and
|
|
138
|
+
formats only on blur. Formatting mid-keystroke moves the caret out from under the cursor, which is
|
|
139
|
+
how "1.500" becomes "1.5001" — measured, not imagined.
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
- **The table and list family now matches the design reference.** `SortHeader` draws a neutral
|
|
143
|
+
two-way glyph on sortable columns that are not sorted, and keeps the **direction** arrow for the
|
|
144
|
+
sorted one, now in the accent colour. Before this, an unsorted header carried nothing at all, so
|
|
145
|
+
nothing on screen said the header was clickable and sorting was found by accident.
|
|
146
|
+
|
|
147
|
+
`SelectAll` stopped drawing its own box. It was a `role="checkbox"` span that painted a plain
|
|
148
|
+
square when checked, while the row boxes beside it painted `Checkbox`'s tick: two different
|
|
149
|
+
marks in one column, visible only when everything was selected. It is a `Checkbox` with
|
|
150
|
+
`indeterminate` now — same component, same size, same keyboard.
|
|
151
|
+
|
|
152
|
+
`ListRow` highlights on `--color-hover`, the token the table already used (it was on
|
|
153
|
+
`--color-sunk`, so a list beside a table showed two different greys), and it takes `min-height`
|
|
154
|
+
rather than `height`, because a row with a title *and* a sub-line was overflowing its box.
|
|
155
|
+
|
|
156
|
+
`LogView` gained level badges and dashed row rules: 13px mono at a 1.7 line height, a fixed
|
|
157
|
+
78px timestamp column, and a badge whose **slot** is fixed width while the badge hugs its text,
|
|
158
|
+
so the message column starts at the same place on every line.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
- **The overlay family now matches the design reference.** `Dialog` enters instead of appearing:
|
|
162
|
+
160ms, opacity plus a scale from .98 (it settles, it does not grow), with the scrim fading
|
|
163
|
+
alongside it, and `prefers-reduced-motion` turning both off while leaving the dialog open.
|
|
164
|
+
|
|
165
|
+
**The scrim is the ink at 45%**, not a warm brown at 32%. The dialog page states the rule —
|
|
166
|
+
everything behind it becomes unreachable — and at 32% the page behind stayed comfortably
|
|
167
|
+
readable, so the dialog read as a card rather than as a gate. Same hue as the ink, so the dim
|
|
168
|
+
is one colour deepening rather than a second colour cast over the page.
|
|
169
|
+
|
|
170
|
+
`Popover` grew an arrow, drawn as two stacked triangles (edge colour under, surface colour 2px
|
|
171
|
+
down), aligned 22px from the trigger's side rather than centred on the 288px panel, because an
|
|
172
|
+
arrow leaving the middle points at empty space instead of at what opened it. `Tooltip` keeps
|
|
173
|
+
its own arrow: that bubble is `fixed` and measured in JS, so it is detached from the trigger's
|
|
174
|
+
box and the arrow is its only tie.
|
|
175
|
+
|
|
176
|
+
`Tooltip` also waits now: **400ms on hover, nothing on keyboard focus**, `Esc` closes it, and
|
|
177
|
+
the label is bound with `aria-describedby` to a copy that is always in the DOM — a screen
|
|
178
|
+
reader reads the description the moment focus lands, while the bubble may not be open yet.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
- **The shell family now matches the design reference.** `Tabs` underlines the active tab with
|
|
182
|
+
**3px** sitting on the strip's own rule rather than a 1px line the same weight as it. The rail's
|
|
183
|
+
active row takes an accent **wash**: hover and active were both the surface colour, so the only
|
|
184
|
+
thing separating them was 3px of shadow against 4px, which the eye does not read. It is still a
|
|
185
|
+
wash and not a fill, so "you are here" is still not painted as an action.
|
|
186
|
+
|
|
187
|
+
`LogoTile`'s letter is the display face at its heaviest, in the accent colour. Drawn in muted
|
|
188
|
+
mono it read as a *code* rather than as a brand, and this tile stands in for an image.
|
|
189
|
+
|
|
190
|
+
**Keyboard, and it is a promise.** `role="tablist"` and `role="radiogroup"` announce "move with
|
|
191
|
+
the arrows"; while the arrows did nothing, that role was a lie. Both strips now move with ←/→,
|
|
192
|
+
jump with Home/End, carry focus along with the selection, skip disabled tabs, and expose a
|
|
193
|
+
**single tab stop** — an eight-tab strip used to cost eight presses to get past.
|
|
194
|
+
|
|
195
|
+
**`Segmented` is a radio group**, not a group of pressed buttons: as buttons, a screen reader
|
|
196
|
+
did not say how many choices there were or which one was chosen, because pressed buttons count
|
|
197
|
+
as independent of each other. `RadioGroup` stays a separate component for a separate job — it
|
|
198
|
+
is a form field, with a label, help text and an error line; this is a toolbar control.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
- **The design's own kit was read section by section — all 96 of them.** Six reference files
|
|
202
|
+
(actions, form, data, feedback, layout, extras), each section compared against its page and its
|
|
203
|
+
component. What came out of it is in the entries above and below; the ones that changed
|
|
204
|
+
behaviour rather than measurements are marked as such.
|
|
205
|
+
|
|
206
|
+
The appearance screen's five parts (`ColorSwatches`, `ThemeCards`, `RailCards`, `ImageField`,
|
|
207
|
+
`SquarePicker`) were documented in prose with no live example on the page — the one thing a
|
|
208
|
+
screen built out of **pictures instead of words** cannot be explained without. Its page opens
|
|
209
|
+
with the real thing now.
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
- **An accordion is a stack of cards, and the open one rises.** Every section used to be a row
|
|
213
|
+
inside one surface, separated by rules, and which one was open could only be read from the
|
|
214
|
+
direction of its caret. Each is its own card now (1.5px edge, r7); open, it takes a 3px base
|
|
215
|
+
and a washed head, and its body indents to the title's text column.
|
|
216
|
+
|
|
217
|
+
`SectionHead` grew a second size. `base` stays the card's own strip; **`lg` is a section of a
|
|
218
|
+
PAGE** — a 30px title, an eyebrow above it **in the accent** (in a quiet grey it read as a
|
|
219
|
+
separate line rather than part of the title), a line under it, and no closing rule, because
|
|
220
|
+
the container sets the page's rhythm.
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
- **Avatars are brand tiles now.** They were grey-on-grey with one 3px corner at every size. The
|
|
224
|
+
**corner grows with the size** (4 · 5 · 7 · 8) — at 24px an 8px corner turns the square towards
|
|
225
|
+
a circle, and at 56 a 4px corner leaves it sharp — the edge is 1.5px like every other pressed
|
|
226
|
+
thing, and **only the large ones (40 up) carry a base**, because a 24px tile lives inside a row
|
|
227
|
+
and a base there crowds it. Two fills, `solid` and `soft`; not a palette, because an avatar is
|
|
228
|
+
not a status.
|
|
229
|
+
|
|
230
|
+
`ErrorState` is **centred** and its retry is the primary button: the block replaces a section
|
|
231
|
+
rather than being pinned to its left edge, and in that state the screen offers nothing else.
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
- **`Code` is the dark block it was drawn as.** It was a light surface with a copy button parked
|
|
235
|
+
in its corner, over the first line. It is now the inverse surface in both themes, with a strip
|
|
236
|
+
carrying the **filename** and the copy button, and **line numbers** that cannot be selected —
|
|
237
|
+
someone dragging to copy the code was taking the numbers with it. The reference puts an accent
|
|
238
|
+
shadow under it; Law 1 says the edge and the offset are one colour, and the law comes first.
|
|
239
|
+
|
|
240
|
+
`Alert` carries the **tone's glyph in its own tile** (the four feedback marks derive from the
|
|
241
|
+
tone, so the same tone cannot be a triangle on one screen and a circle on the next). Its 3px
|
|
242
|
+
left border is gone: the comment above it had said "the tone is the wash, not the left rule"
|
|
243
|
+
for a long time while the rule kept drawing it.
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
- **The form family, the same way.** A failing field is **washed**, not only outlined: with four
|
|
247
|
+
fields in a form the eye was hunting for the bad one along the edges. Its error line carries a
|
|
248
|
+
filled warning glyph, because colour alone is not a mark. And **disabled is a different object,
|
|
249
|
+
not a faded one** — a dashed edge on a sunk ground, the rule already written for buttons and
|
|
250
|
+
applied only there; checkbox, radio and switch were fading to 45% opacity instead.
|
|
251
|
+
|
|
252
|
+
`Select` options can carry a `hint`, the quiet second value on the right of a row ("2-3 days",
|
|
253
|
+
"₺49"): under the label it doubles the list's height, and what is being read is still one
|
|
254
|
+
choice.
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
- **The action family went through the reference one section at a time.** `IconButton` has three
|
|
258
|
+
sizes — 30, 40 and 50 — and **the corner grows with the size** (5 · 7 · 8), because one radius
|
|
259
|
+
across three sizes makes the small one look round and the large one sharp; its base is 3px, not
|
|
260
|
+
2, which had left it sitting at the same height as the mini button beside it. `MiniButton` is
|
|
261
|
+
28px, the reference's own measure.
|
|
262
|
+
|
|
263
|
+
Both gained the fills they were missing (`primary`, `soft`, `danger`, `ghost` / `quiet`), and
|
|
264
|
+
**`ghost` is not an object at rest**: no edge, no base, it appears under the pointer. Thirty
|
|
265
|
+
rows each carrying a three-dot button would otherwise be thirty objects.
|
|
266
|
+
|
|
267
|
+
`Steps` marks the current step with a **light accent fill** rather than an outline: the done
|
|
268
|
+
ones are filled dark, and an outlined current step read as one of the empty ones ahead of it.
|
|
269
|
+
`Kbd` is layered now (1.5px edge, 2px base) — in this kit depth is the mark of what can be
|
|
270
|
+
pressed, and a shortcut describes something to press.
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
- **Measured against the reference, component by component.** `Segmented` is 7px around the well
|
|
274
|
+
and 5px around each button (it was 6 and 4), pads 6×14, and keeps **full ink on the unselected
|
|
275
|
+
options**: a faded option read as *disabled*, while what separates them is the seat. It also
|
|
276
|
+
gained the **6px gap between a glyph and its word** that it never had, which is why every
|
|
277
|
+
icon-bearing segment glued the two together.
|
|
278
|
+
|
|
279
|
+
`Tabs` underlines the **body** of a tab, not the word: 4px between tabs with 8×12 padding
|
|
280
|
+
inside each, rather than 24px between bare words. `Kpi` follows the reference's two shapes (see
|
|
281
|
+
Added), and `StackedBarChart` draws its slices in **one hue's ramp** instead of the categorical
|
|
282
|
+
palette: stacked slices are parts of ONE measure, and in four different colours each slice
|
|
283
|
+
reads as a measure of its own while the total disappears. Each slice keeps a 1px edge with no
|
|
284
|
+
bottom border, so two slices share one line.
|
|
285
|
+
|
|
286
|
+
**`KpiGrid` asks its container, not the screen.** The rule was three media queries plus a count
|
|
287
|
+
of the tiles, and the measured failure was this: on a 1494px screen, inside a 790px column, it
|
|
288
|
+
opened four columns, each tile fell to 190px and the number was clipped. It is now
|
|
289
|
+
`auto-fit` with a 210px floor. `SkeletonKpi`'s bars gained `max-w-full` for the same reason: a
|
|
290
|
+
skeleton that overflows its card is not carrying the geometry it stands in for.
|
|
291
|
+
|
|
292
|
+
**The slider's handle sits on its rail.** WebKit aligns the thumb to the TOP of a track with an
|
|
293
|
+
explicit height rather than centring it, so the square hung below the rail by half its height.
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
- **The default brand is `#1E4FD8`.** The palette generator's reference brand was already this
|
|
297
|
+
blue, but the default theme still shipped the older, greyer `#2069c9` — so a product that picked
|
|
298
|
+
the very colour the kit is built around got a different palette than the kit's own default. The
|
|
299
|
+
accent family moves with it in both themes; in dark the hue shifts to match while every value
|
|
300
|
+
keeps its lightness, because each of those lightness numbers has a written argument beside it.
|
|
301
|
+
|
|
302
|
+
The selected-row ground moves with it and this one is worth saying out loud: `#ecedf3` had a
|
|
303
|
+
chroma of 0.008 — all but colourless — so a selected row sat one step lighter than a hovered one
|
|
304
|
+
and the two did not read apart. It is `#dce9fb` now: what separates them is hue, not lightness.
|
|
305
|
+
White ink on the primary fill goes from 5.22:1 to 6.47:1.
|
|
306
|
+
|
|
307
|
+
### Added
|
|
308
|
+
|
|
309
|
+
- **`Announcement`, the strip across the top of a page.** The design's `page-band` section is an
|
|
310
|
+
announcement strip; this kit's `PageBand` is the page's own title block (eyebrow, `h1`,
|
|
311
|
+
subtitle, actions). Two different things under one name, so the strip became its own component.
|
|
312
|
+
Two looks, and the difference is a sentence rather than a style: `loud` is the filled accent and
|
|
313
|
+
it LIFTS, because the reader is meant to act on it and in this kit a fill already means action;
|
|
314
|
+
`quiet` is a wash with no base, because a standing condition ("you are in test mode") only asks
|
|
315
|
+
to be read. Its ink is `--color-accent-ink` in both themes rather than the design's light blue:
|
|
316
|
+
`--color-accent-soft` is fixed across themes while `--color-accent` lightens at night, and the
|
|
317
|
+
pair measures 4.03 in light but **1.61** in dark. Hierarchy comes from size and weight instead.
|
|
318
|
+
|
|
319
|
+
- **`Spinner` gained the two looks the design shows and the kit was missing:** `dots`, three equal
|
|
320
|
+
squares blinking in turn for the side of a line of text, and `square`, a raised box turning on
|
|
321
|
+
its own axis with its shadow, for a wait that owns the view. `bars`, `pixels` and `ring` are
|
|
322
|
+
unchanged, and `bars` stays the default.
|
|
323
|
+
|
|
324
|
+
- **`Avatar` takes a `status` mark.** A square in the tile's bottom-right corner in the tone's own
|
|
325
|
+
colour, with a ring in the ground behind it. It is the one place colour is allowed on an avatar:
|
|
326
|
+
the tile stays monochrome because identity is text, and this mark is not identity but health.
|
|
327
|
+
No default · a mark on every avatar would be a legend nobody wrote.
|
|
328
|
+
|
|
329
|
+
- **`Dot` takes a `size`** (`sm` · `base` · `lg`). The large one carries an edge and a base,
|
|
330
|
+
because at 14px a flat square reads as a swatch rather than a status; the small one drops them,
|
|
331
|
+
because at 6px an edge swallows the square.
|
|
332
|
+
|
|
333
|
+
- **`RichText` takes `hint`**, the quiet mono note at the end of the toolbar saying what the
|
|
334
|
+
editor accepts ("Markdown supported"). The toolbar also moved onto the header strip's ground
|
|
335
|
+
and took the box's own edge weight under it: on the sunk ground it read as a second box inside
|
|
336
|
+
the editor.
|
|
337
|
+
|
|
338
|
+
- **`TimelineStrip` takes `steps`**, the second shape of the same question. The buckets measure a
|
|
339
|
+
RUN (24 hours, one health each); the steps name the STATIONS (an order's history): icon tiles
|
|
340
|
+
on a line, with the line drawn twice · a quiet one end to end and an accent one up to where it
|
|
341
|
+
stands now. Only the steps that happened are raised, because a base under something that has
|
|
342
|
+
not happened read as if it had.
|
|
343
|
+
|
|
344
|
+
- **`ThemeToggle variant="segmented"` can offer two.** It demanded all three labels and threw
|
|
345
|
+
otherwise. The three-way stays the recommendation and the reason stands (see `preference`:
|
|
346
|
+
"system" is the absence of a choice, not a third shade), but offering two is a legitimate
|
|
347
|
+
product decision, so the step now follows the label: no `system` label, no `system` step. With
|
|
348
|
+
two the labels are visible; with three only the glyph is, because three words stretch the
|
|
349
|
+
control past any toolbar.
|
|
350
|
+
|
|
351
|
+
- **`TimelineStrip` takes `className`**, like every other surface in the kit.
|
|
352
|
+
|
|
353
|
+
- **`Progress` takes two more looks.** `blocks` is a row of cells for a COUNTABLE capacity, where
|
|
354
|
+
the real sentence is "7 of 10" and a smooth bar would claim a precision that does not exist;
|
|
355
|
+
the last filled cell takes the light tone, the one mark that says where we are. `split` is one
|
|
356
|
+
track cut into shares, for a distribution that adds up to a whole, with its legend underneath.
|
|
357
|
+
The caller writes the legend line · the kit formats no percentages, because the sign and its
|
|
358
|
+
place are a locale.
|
|
359
|
+
|
|
360
|
+
- **`PasswordInput` takes `strength`**, the meter under the field: so many bars lit out of four,
|
|
361
|
+
and a line saying what is still missing. The kit LIGHTS the bars and does not judge the
|
|
362
|
+
password: what counts as strong is a policy, and a policy belongs to the product.
|
|
363
|
+
|
|
364
|
+
- **`NumberInput` takes `look="quantity"`**, the joined control with the buttons flanking the
|
|
365
|
+
value, for a count that is CLICKED into place. The value there is not an editable field: with
|
|
366
|
+
two buttons doing the whole job, a typed invalid value has nothing to gain. `field` (the text
|
|
367
|
+
field with the stepper on its edge) stays the default, for numbers that are typed.
|
|
368
|
+
|
|
369
|
+
- **`LogView` takes `filters`**, the level bar over the stream. The kit draws the bar and marks
|
|
370
|
+
the chosen one; which levels exist, what they are called and the filtering itself stay with the
|
|
371
|
+
caller · a log view that filtered its own lines would have to know what a level means.
|
|
372
|
+
|
|
373
|
+
- **`FileUpload` takes `files`**, the transfer rows under the well: one going up (a bar and a
|
|
374
|
+
percentage), one that arrived (its size, written by the caller · the kit formats no bytes), one
|
|
375
|
+
refused (the row turns critical and carries the reason beside the file name, not under it).
|
|
376
|
+
`labels.hint` adds the quiet line about accepted types, and the well's glyph now sits in a
|
|
377
|
+
raised tile: a bare glyph in the middle of a dashed area sinks into it.
|
|
378
|
+
|
|
379
|
+
- **`EmptyNote` takes `icon`**, and with it the note collapses to a single line: a card that is
|
|
380
|
+
empty inside an otherwise full screen deserves a sentence, not a picture.
|
|
381
|
+
|
|
382
|
+
- **`EmptyTile` takes `icon`**, which turns the tile into the grid's empty cell · dashed and
|
|
383
|
+
groundless while it waits, solid and raised under the pointer. The dashed edge says "not
|
|
384
|
+
content yet", the lift says "this is a control".
|
|
385
|
+
|
|
386
|
+
- **`Label` takes `look="section"`**, the heading over a group of fields: letter-spaced and
|
|
387
|
+
heavier, because it names a region rather than annotating a number.
|
|
388
|
+
|
|
389
|
+
- **`Select` options take a `label`**, for when the stored value is not the text to show: a locale
|
|
390
|
+
is kept as `tr` and read as "Türkçe".
|
|
391
|
+
|
|
392
|
+
- **`StatusChip` takes a `look`.** `wash` (the default, unchanged) has no edge, because in a
|
|
393
|
+
table of thirty rows an edge on every chip turns the status column into a column of boxes.
|
|
394
|
+
`outline` carries the tone as a line on the surface, for a chip standing alone. `solid` is the
|
|
395
|
+
tone's plate with its own ink, for a TERMINAL state that ends the row's story ("delivered",
|
|
396
|
+
"returned"); it stands in tension with Law 2, a fill means action, which is exactly why it is
|
|
397
|
+
opt-in and not the default.
|
|
398
|
+
|
|
399
|
+
- **`Beacon` takes `edged`**, for a mark that sits ON a control: it grows a step (12 → 14) and
|
|
400
|
+
takes the pressed edge, and its fill turns into the tone's wash. A solid square touching a
|
|
401
|
+
button's own edge reads as part of that edge. The beacon's own size also went from 8px to 12px
|
|
402
|
+
· 8 is the measure of a dot beside a line of text, not of a mark that has to be found across a
|
|
403
|
+
screen.
|
|
404
|
+
|
|
405
|
+
- **`Beacon` takes `look="ping"` and a `state`.** `pulse` (the existing breath) says a STATE: it
|
|
406
|
+
is live, it is streaming. `ping`, a ring expanding out of the mark and fading, says a CALL:
|
|
407
|
+
"there is something new here" · which is what the design attaches to a control's corner. The
|
|
408
|
+
core stays under the ring, otherwise the mark disappears at the faint end of the beat.
|
|
409
|
+
|
|
410
|
+
- **`Badge` takes `dot`**, a mark with no number, for when the answer is "there is something new"
|
|
411
|
+
rather than "there are four". `count` is now optional, since a dot has none to show.
|
|
412
|
+
|
|
413
|
+
- **`Separator` takes `look` and `label`.** `plain` is the quiet rule, `dashed` a provisional one,
|
|
414
|
+
`strong` the one that separates two SECTIONS and therefore takes the edge colour rather than the
|
|
415
|
+
line colour, and `label` carries a word in the middle ("or"), which turns the separator into a
|
|
416
|
+
choice rather than a break.
|
|
417
|
+
|
|
418
|
+
- **`SectionHead` takes `size="sub"`**, the row that opens a sub-section INSIDE a card: no band
|
|
419
|
+
behind it, a rule under it, and `meta` becomes a count chip beside the title instead of a label.
|
|
420
|
+
|
|
421
|
+
- **`Button` takes `size="lg"`** (52px, one step up the shadow ladder at 5px). A screen's single
|
|
422
|
+
action: an empty state's call, a wizard's next.
|
|
423
|
+
|
|
424
|
+
- **`Alert` takes `onDismiss` and `dismissLabel`.** Without them an alert is a standing condition
|
|
425
|
+
the reader cannot clear; with them, a message they have finished with. The control is a ghost
|
|
426
|
+
icon button: inside a washed box, a second bordered object competes with the message itself.
|
|
427
|
+
|
|
428
|
+
- **A tone now carries `markInk`, the glyph that reads ON its `mark`** · and it is not one colour
|
|
429
|
+
for all six. See Fixed below for what it repairs.
|
|
430
|
+
|
|
431
|
+
### Fixed
|
|
432
|
+
|
|
433
|
+
- **`LineChart`'s hover marker rendered as a pill, and the chart showed a stray tooltip.** Two
|
|
434
|
+
costs of the same decision: the `viewBox` is 100×100 with `preserveAspectRatio="none"` so that
|
|
435
|
+
coordinates behave like percentages. A `<rect width={14} height={14}>` drawn inside it measured
|
|
436
|
+
**252 × 22 px** on a 1800×160 chart, and the comment beside it claimed `vectorEffect` kept the
|
|
437
|
+
size — that property preserves stroke width, not geometry. The marker now sits in the HTML layer
|
|
438
|
+
(`.tamga-chart-mark`), positioned in percentages and sized in pixels, so it is square at every
|
|
439
|
+
width. Separately, the accessible name was given with `<title>`, which browsers render as a
|
|
440
|
+
native tooltip: hovering the chart popped a box reading "Kayıt: 14" — with the wrong number, as
|
|
441
|
+
the title always names the LAST value rather than the hovered one. The name is now `aria-label`:
|
|
442
|
+
same sentence for a screen reader, no bubble on screen.
|
|
443
|
+
|
|
444
|
+
- **Eight tokens were declared but never published.** `--font-sans`, `--font-display`,
|
|
445
|
+
`--font-mono`, `--tracking-label` and four radii (`-sm`, `-md`, `-xl`, `-full`) all exist in
|
|
446
|
+
`theme.css`, all are used, and all generate Tailwind utilities — and none of them appeared in the
|
|
447
|
+
token reference. They sit in the bridge `@theme inline` block, which the extractor read only for
|
|
448
|
+
`var(--x)` aliases. The typography page describes three faces; the token page's typography group
|
|
449
|
+
did not carry their names. For a consumer, a name that is not published does not exist. A gate
|
|
450
|
+
now diffs every declaration in a `:root`/`@theme` body against the published list.
|
|
451
|
+
|
|
452
|
+
- **Twenty-two tokens carried no rationale at all**, and the cause was a pattern rather than
|
|
453
|
+
twenty-two oversights: one comment sits above a RUN of declarations (the six `--color-*-inverse`,
|
|
454
|
+
`--chart-2..5`, `--mark-dot` and its radius) and the parser correctly binds it to the first name
|
|
455
|
+
only. All twenty-two are written; the extractor now stops on a token with no rationale. Every one
|
|
456
|
+
of the 145 tokens carries a bilingual one.
|
|
457
|
+
|
|
458
|
+
- **Three token comments described a kit that no longer exists**, and they are published: the
|
|
459
|
+
token page is generated from them. `--font-display` said "headings are the same face, heavier:
|
|
460
|
+
never a separate display cut" while the token itself reads `"Red Hat Display"`, two lines under
|
|
461
|
+
a `--font-sans` comment that already describes three faces. `--font-mono` said "Mono is the same
|
|
462
|
+
face too" and went on to explain that Red Hat Mono was *not* taken "because it would make the kit
|
|
463
|
+
a two-family system" — the token reads `"JetBrains Mono"` and the kit has been a three-family
|
|
464
|
+
system since the port. `--radius-full` said "avatars and the live dot ONLY"; it is read by the
|
|
465
|
+
score ring alone, and fully round lives in three places (`check:yuvarlak` says so in its own
|
|
466
|
+
output). All three rewritten to what the code does.
|
|
467
|
+
|
|
468
|
+
- **`Segmented` was two pixels taller than every control beside it.** `--control` is 40px and the
|
|
469
|
+
input, the button, the select and the icon button all read it; the segment took its height from
|
|
470
|
+
padding and measured 42. On a toolbar the input and the button lined up and the segment did not,
|
|
471
|
+
which is exactly what the measure page promises cannot happen. A fixed height had been tried once
|
|
472
|
+
and rolled back for a good reason: it was given to the button INSIDE the well, and the well then
|
|
473
|
+
added its own 3px padding and 1px edge on top of it and came out at 46. The height belongs to the
|
|
474
|
+
well itself, with the items stretching into it. `-sm` and the icon segment take `height: auto` and
|
|
475
|
+
are unchanged, because standing under 40px on a toolbar is their whole reason to exist. Found by
|
|
476
|
+
the measure page's own rhythm demo; held by a new gate, `check:olcu-hizasi`, which requires all
|
|
477
|
+
eight base controls to declare `height: var(--control)`.
|
|
478
|
+
|
|
479
|
+
- **Every number input turned into an 18px chip.** A class rename landed on a name that was
|
|
480
|
+
already taken: the tab counter became `.tamga-sayi`, which is what `NumberInput` uses for the
|
|
481
|
+
numeral's FACE. Two definitions of the same class, the later one winning, and the field
|
|
482
|
+
inherited the chip's box · 18px tall, chip padding, chip background. Nothing errored: both
|
|
483
|
+
names were defined, so the class-name gate passed too. The counter is `.tamga-sayac` now, and
|
|
484
|
+
`check-css` gained the question that catches this shape: is this class defined twice in the
|
|
485
|
+
same context? It immediately found four more, all real:
|
|
486
|
+
|
|
487
|
+
- `.tamga-collapsible-head` and `-body` existed twice (a row-shaped port and a card-shaped one)
|
|
488
|
+
and the later pair had quietly dropped the header's `font-weight` and its background
|
|
489
|
+
transition. The design writes 700; the accordion had been shipping unbolded headers.
|
|
490
|
+
- `.tamga-sheet-end` was split across two blocks (mirrored shadow in one, animation in the
|
|
491
|
+
other); they are one block now.
|
|
492
|
+
- `.tamga-eyebrow` was pasted twice, identically.
|
|
493
|
+
- the docs' `.docs-search-btn` carried its radius and height in a second block below itself.
|
|
494
|
+
|
|
495
|
+
- **The popover was drawn as a card, and it showed.** It carried a header strip with its own
|
|
496
|
+
background, a rule under it, a second rule over the footer and a boxed close button · three
|
|
497
|
+
horizontal lines inside a 288px panel, so the eye read the box instead of what was in it. The
|
|
498
|
+
design's popover is one padded surface: a bold title line, the content, a right-aligned footer,
|
|
499
|
+
and nothing else. `closeLabel` is optional now and draws a quiet corner control when given:
|
|
500
|
+
a popover is dismissed with Escape or by clicking away, and the thing that must be closed
|
|
501
|
+
deliberately is a dialog.
|
|
502
|
+
|
|
503
|
+
- **`SecretField` hid its actions inside the field.** Two mini buttons crammed against the right
|
|
504
|
+
edge made copying look like trim. A secret is read, not typed: the value now sits in a sunk
|
|
505
|
+
read-only plate with a key glyph, and reveal and copy are two real buttons beside it, the copy
|
|
506
|
+
one carrying its label as the design writes it.
|
|
507
|
+
|
|
508
|
+
- **A selected radio card only changed its edge.** The design fills it with the soft accent, and
|
|
509
|
+
the note that said "selection by edge, not by the accent colour" was about a different token
|
|
510
|
+
(`--color-accent-line`, which collapses into `--color-edge` on a light brand).
|
|
511
|
+
`--color-accent-soft` is fixed in both themes and carries its own ink, so the wash joins the
|
|
512
|
+
edge and the lift rather than replacing them. `look="card"` also stopped forcing a three-column
|
|
513
|
+
grid: three priced shipping options read down a column, and the container's layout is the
|
|
514
|
+
caller's decision.
|
|
515
|
+
|
|
516
|
+
- **A rising sparkline was grey.** `positive` fell into the muted stroke, which contradicted the
|
|
517
|
+
decision already written on the `Delta` chip: good news is the accent, not green, because a
|
|
518
|
+
rising trend is a movement rather than a state. Neutral stays quiet; a trend line only takes a
|
|
519
|
+
colour when it is carrying good or bad news.
|
|
520
|
+
|
|
521
|
+
- **The number input's operator glyphs were duotone.** `Icon`'s default weight is duotone, which
|
|
522
|
+
is right for an icon that carries the brand and wrong for a control's operator: duotone draws
|
|
523
|
+
its second layer quieter, and a single-stroke mark like a plus or a minus turns into a faded
|
|
524
|
+
sketch of itself. The plus, the minus and the two stepper carets are `bold` now, which is what
|
|
525
|
+
the design writes for them.
|
|
526
|
+
|
|
527
|
+
- **`LocaleSwitcher` drew the browser's `<select>`, not the kit's.** Above two locales it fell
|
|
528
|
+
back to a native control: the OS arrow, the OS dropdown, and none of the kit's rules. It uses
|
|
529
|
+
the kit's `Select` now.
|
|
530
|
+
|
|
531
|
+
- **The separator family was drawn one step off, because the design's token names collide with
|
|
532
|
+
this kit's.** In the design's own file `--edge` is `#0A1F3D`, a near-black navy · this kit's
|
|
533
|
+
`--color-edge` is `#c3c9d3`, a pale grey, and the near-black one is `--color-edge-strong`. Its
|
|
534
|
+
`--line` is our `--color-edge`, and its `--dash` is our `--color-line`. Read as if the names
|
|
535
|
+
matched, the ladder came out flat: the section rule was drawn in pale grey where the design
|
|
536
|
+
asks for near-black. The four rules now sit where they belong · plain `--color-div`, dashed
|
|
537
|
+
`--color-line`, strong `--color-edge-strong` at 1.5px, vertical `--color-edge`. The same
|
|
538
|
+
mis-mapping had reached three more places from this cycle, all corrected: the announcement
|
|
539
|
+
strip's border and base, the spinner's `square`, and the large `Dot`.
|
|
540
|
+
|
|
541
|
+
- **The announcement strip's title was navy on blue.** The kit's base layer paints every
|
|
542
|
+
`strong` with `--color-ink`, which is right for page copy and wrong on a surface carrying its
|
|
543
|
+
own ink: the title measured about 1.9 against the accent ground while the line under it was
|
|
544
|
+
readable. Inside the strip, `strong` inherits now (6.47).
|
|
545
|
+
|
|
546
|
+
- **The `+N` tile in an `AvatarStack` was raised in a different colour from the faces beside
|
|
547
|
+
it.** The avatar tiles lift with `--color-edge-strong`; the summary tile had a pale base, so
|
|
548
|
+
it read as being made of another material.
|
|
549
|
+
|
|
550
|
+
- **In dark, the glyph inside an alert's tile sank into its own plate.** The tile is painted in
|
|
551
|
+
the tone's `mark`, which is a fixed plate in both themes, and the glyph was `--color-page`,
|
|
552
|
+
which is not: near-white in light, near-black at night. On critical it measured **2.96**, under
|
|
553
|
+
the 3.0 floor that applies to a graphical object. One ink cannot fix six plates, so each tone
|
|
554
|
+
now carries its own, picked by measurement: critical takes white (5.89), `info` follows the page
|
|
555
|
+
(7.38 / 8.61) because its plate is the one that flips too, and the rest take the fixed dark
|
|
556
|
+
plate (4.27-7.59). `check-token-contrast` measures these six pairs at the 3.0 glyph floor, and
|
|
557
|
+
it reads the pairs out of `tone.ts` rather than from a list of its own: written by hand, the
|
|
558
|
+
gate passed a deliberate sabotage of the mapping, because what it measured was its own list.
|
|
559
|
+
|
|
560
|
+
- **The `+N` tile in an `AvatarStack` now carries its own base.** It is the one tile in the row
|
|
561
|
+
that is not a person but a summary, and the offset is what steps it out of the row of faces.
|
|
562
|
+
|
|
563
|
+
- **The dropdown menu's group heading was a row-sized label.** It is the name of a GROUP, not of a
|
|
564
|
+
row: caption size, heavy, letter-spaced, with the tighter padding the design gives it (10px
|
|
565
|
+
rather than 16px, which had left a second misalignment down the menu's left edge). Casing stays
|
|
566
|
+
with the caller · the kit does not touch text, and `text-transform` would hand Turkish's i/İ to
|
|
567
|
+
the browser.
|
|
568
|
+
|
|
569
|
+
### Breaking
|
|
570
|
+
|
|
571
|
+
- **`ScoreMatrix` is a density grid now, not a waffle of one score.** The design's 03.15 is a
|
|
572
|
+
two-dimensional heatmap · rows for one band (a weekday), columns for the other (an hour), and a
|
|
573
|
+
cell's colour reporting the amount at their crossing. What stood under that name here was a
|
|
574
|
+
10×10 waffle rendering a single 0-100 score, which `ScoreRing` and `ScoreMeter` already answer.
|
|
575
|
+
The new props are `rows`, `columns`, `levels`, `legend` and `cellTitle`; colour comes from the
|
|
576
|
+
brand ramp rather than the tone family, because a cell reports an AMOUNT and not a state, and
|
|
577
|
+
the step is computed against the grid's own maximum · an absolute threshold would make one grid
|
|
578
|
+
impossible to compare with another week's numbers.
|
|
579
|
+
|
|
580
|
+
- **`.tamga-tab-sayi` is now `.tamga-sayac`.** The count chip stopped belonging to tabs when
|
|
581
|
+
`SectionHead size="sub"` started carrying one beside its title, and a class named after tabs in
|
|
582
|
+
that position would have made the name a lie. It was briefly `.tamga-sayi`, which was already
|
|
583
|
+
taken by the numeral face `NumberInput` wears · see the Fixed entry. The `count` prop on `Tabs`
|
|
584
|
+
is unchanged; only a consumer styling the kit's internals by class name is affected.
|
|
585
|
+
|
|
586
|
+
- **In dark, a sunk surface was the page.** `--color-sunk` is the ground for content that sits *in*
|
|
587
|
+
the page rather than on it: filter bars, table headers, code blocks, sub-panels, skeleton
|
|
588
|
+
placeholders. In light it sits ΔL* 7.3 under the page; in dark it sat **1.1** under it, which is
|
|
589
|
+
to say nowhere. The skeleton made it visible: its base is `--color-sunk` and the bar you actually
|
|
590
|
+
see is a breathing `::after` (opacity 0.78 ↔ 0.06), so at the bottom of every breath only the
|
|
591
|
+
base was left, and against the page it measured a ratio of 1.02. The placeholder vanished and
|
|
592
|
+
came back, once per breath. Dark cannot fix this by going lighter (`--color-band` carries that
|
|
593
|
+
measurement: lightening dark surfaces collapsed the card to ΔL* 0.4), so sunk went down instead,
|
|
594
|
+
`#0e1829` → `#020c21`, ΔL* 5.8 under the page. The number is the ramp's own compression, not a
|
|
595
|
+
taste call: dark holds every other surface pair at ~0.8 of light's separation, and 7.3 × 0.79 =
|
|
596
|
+
5.8. Chroma does not drop with it (14.5 against the page's 13.7, same 280° hue).
|
|
597
|
+
|
|
598
|
+
- **`makePalette` generated the same invisible surface for every brand.** The kit's dark half is
|
|
599
|
+
written by hand and the generator runs its own ladder, and the generated ladder had the same
|
|
600
|
+
missing rung: dark `sunk` sat at `l 0.209`, ΔL* 1.0 under the `l 0.218` page it is supposed to sit
|
|
601
|
+
under, and it is now `l 0.168`.
|
|
602
|
+
A product generating a palette from its own brand colour inherited the invisible filter bar. The
|
|
603
|
+
rung now sits below the rail, which is also its order in light, and measures ΔL* 4.9–5.2 across
|
|
604
|
+
the ten brand colours the suite covers.
|
|
605
|
+
|
|
606
|
+
- **Two gates were silent on it, so both now measure it.** Surface separation was only ever asked
|
|
607
|
+
of `--color-edge` and `--color-line` (`check-token-contrast`) and of `navHoverBg · rail`
|
|
608
|
+
(`measurePalette`). Both now carry the sunk/page and sunk/shell pairs against the same 2.0 floor
|
|
609
|
+
that already stood for "a second ground on top of a ground must read as changed". Verified by
|
|
610
|
+
putting the old value back: the gate names ΔL* 1.1 and fails.
|
|
611
|
+
|
|
612
|
+
- **The danger icon button's glyph nearly disappeared in dark.** `.tamga-icon-btn-danger` fills with
|
|
613
|
+
`--color-critical-mark`, which is the same wine red in both themes, and painted its glyph with
|
|
614
|
+
`--color-page`, which is not: near-white in light (5.26) and near-black in dark (2.96). The design
|
|
615
|
+
writes this pair as fixed (`#fff` on `#9E2A3A`), and the ink is now `--color-inverse-ink`, white in
|
|
616
|
+
both themes, 5.89 on the plate either way. The pair is measured by `check-token-contrast` now.
|
|
617
|
+
|
|
618
|
+
- **A new gate measures the whole class: a theme-fixed ground under a theme-flipping ink.**
|
|
619
|
+
`check-tema-cifti` resolves every kit rule that sets both `background` and `color` down to hex in
|
|
620
|
+
both themes, and fails when exactly one side is theme-fixed and either theme falls under AA. This
|
|
621
|
+
same shape had already been fixed three times by hand this cycle (the selection bar, the marked
|
|
622
|
+
link at 1.36, and the danger icon button), each time without anything to stop the fourth. It
|
|
623
|
+
measures 12 mixed pairs today. What it deliberately does not see: a ground and an ink split across
|
|
624
|
+
two rules, which needs real CSS resolution rather than a per-rule read.
|
|
625
|
+
|
|
626
|
+
- **A comment claimed `--color-hover` was sunk's value; it is not, in either theme.** Light hover
|
|
627
|
+
is `#f7f5ef` and sunk `#e1ddd3`; dark hover is `#1a2842` and sunk `#020c21`. The two had drifted
|
|
628
|
+
apart long before, on both sides, and the comment was still asserting the old identity.
|
|
629
|
+
|
|
630
|
+
- **A tall `Dialog` cut off its own close button.** The panel had no bound: content taller than the
|
|
631
|
+
window made a `wide` dialog 1014px tall inside a 783px viewport, and since the shell centres its
|
|
632
|
+
child, 116px was clipped off the top and 116px off the bottom. The title and the close control
|
|
633
|
+
live in that top 116px. Escape still worked; the mouse had no way out. The body scroll that
|
|
634
|
+
fixes this had been written for `size="full"` only, and the other three sizes overflowed in
|
|
635
|
+
silence. The panel is now bounded and the body scrolls, with the header and footer held in
|
|
636
|
+
place.
|
|
637
|
+
|
|
638
|
+
- **Nine things the port had skipped.** Comparing `kit.css` class by class against the last commit
|
|
639
|
+
turned up 58 untouched classes; most are layout utilities and the mascot's furniture and were
|
|
640
|
+
right to leave alone, but nine were still speaking the old language:
|
|
641
|
+
|
|
642
|
+
- `Button size="sm"` carried the full-size 4px layer and 4px press, so the only thing "small"
|
|
643
|
+
about it was its width. It now steps down to 3px, like every other reduced control.
|
|
644
|
+
- A selected `RadioGroup` card or chip was marked with the accent colour and a 2px layer, while
|
|
645
|
+
every other selection in the kit — swatch, theme card, rail row, segment — is marked with the
|
|
646
|
+
edge and a lift. On a light brand the accent and the edge fall close enough together that the
|
|
647
|
+
selection disappeared.
|
|
648
|
+
- An invalid field sat at 2px while focus moved to 3px, so clicking into a field with an error
|
|
649
|
+
RAISED it.
|
|
650
|
+
- `Progress` had a 1px edge and a flat ink fill. It takes the 1.5px edge, a 3px layer, and a
|
|
651
|
+
striped accent fill with a hard right edge, so where the fill stops is exact at any brand.
|
|
652
|
+
- `Slider` was round — both the track and the thumb — against the kit's own written rule that
|
|
653
|
+
only the radio, the score ring and the ring spinner are circles. The thumb is now a 24px
|
|
654
|
+
square that can actually be grabbed.
|
|
655
|
+
- `RichText`'s toolbar buttons were flat, and an active one filled with plain ink, a colour the
|
|
656
|
+
kit uses nowhere else. They are boxed now, and an active one fills with the accent and sits on
|
|
657
|
+
its own base.
|
|
658
|
+
- `ImageField` was a thin 1px box; empty, it was a dashed rectangle with a normal surface
|
|
659
|
+
inside, so a filled field and an empty one read at the same weight. Empty is now hatched, the
|
|
660
|
+
same hatch the custom colour swatch uses.
|
|
661
|
+
- `LogoTile` took the 1.5px edge and the button radius.
|
|
662
|
+
- `Surface` drew its edge with `--color-edge`, the colour reserved for an object's own rule, so
|
|
663
|
+
the screen's ground read as heavily as the cards standing on it. It uses `--color-line`.
|
|
664
|
+
|
|
665
|
+
### Added
|
|
666
|
+
|
|
667
|
+
- **A gate for the roundness rule** (`check:yuvarlak`). The rule was written down in two places
|
|
668
|
+
and enforced nowhere, which is why the slider stayed round for months without anyone noticing —
|
|
669
|
+
on its own it does not look wrong; what is wrong is that it disagrees with everything beside it.
|
|
670
|
+
The gate reads `kit.css` and allows `border-radius: 50%` only on a named list of selectors, so
|
|
671
|
+
adding a circle is now a decision someone has to write down.
|
|
672
|
+
|
|
673
|
+
### Breaking
|
|
674
|
+
|
|
675
|
+
- **`LogView` takes a `labels` object.** New required prop: `labels={{ newLines: (n) => … }}`,
|
|
676
|
+
the text of the button described under Added. It is required rather than optional because a kit
|
|
677
|
+
that silently drops a behaviour when a string is missing is worse than one that asks for the
|
|
678
|
+
string.
|
|
679
|
+
|
|
680
|
+
- **Two names went back to the design's vocabulary.** The kit had invented both, and in the
|
|
681
|
+
design each name belongs to a different component:
|
|
682
|
+
|
|
683
|
+
`Rise` was a block sliding in from below; in the design it is **the number climbing from zero
|
|
684
|
+
to its target**. The animation is now **`Reveal`** (class `.tamga-rise` → `.tamga-reveal`), and
|
|
685
|
+
`Rise` is the change indicator. Our own docs page for it opened with "the name may be
|
|
686
|
+
misleading", which was the warning.
|
|
687
|
+
|
|
688
|
+
`SaysBubble` was the bubble over an empty state's drawing; in the design it is **the
|
|
689
|
+
conversation bubble** (a customer message, our reply, an assistant's suggestion). The drawing's
|
|
690
|
+
bubble is now **`ArtSays`**, which `EmptyState` uses internally, and `SaysBubble` is the chat
|
|
691
|
+
bubble. With both under one name, whoever looked for an empty state and whoever looked for a
|
|
692
|
+
chat found the wrong component.
|
|
693
|
+
|
|
694
|
+
- **`Delta` is a chip, not an inline percentage.** A trend glyph plus the value, filled with the
|
|
695
|
+
tone's own ink: beside a KPI the old outline version was too quiet to read. Good news takes the
|
|
696
|
+
**accent**, not green — green is a STATE colour ("resolved") while a rising revenue is a
|
|
697
|
+
movement — bad news stays red, and a flat change has no colour at all. `mono` is gone; the chip
|
|
698
|
+
sets its own numerals.
|
|
699
|
+
|
|
700
|
+
- **`ScheduleInput` is now a weekly schedule, not an interval `<select>`.** It used to take
|
|
701
|
+
`value` (minutes), `onChange` and an `options` list and render a single `<select>` — a native
|
|
702
|
+
select wearing a component name, which is the one thing a kit should not ship. It now takes
|
|
703
|
+
`days` (0 Sunday to 6 Saturday), `from`, `to`, their change handlers, a `labels` object and a
|
|
704
|
+
ready `summary` sentence, and it draws seven day buttons over an hour range.
|
|
705
|
+
|
|
706
|
+
Migration: for choosing an interval use `Select` with your own options — that is literally what
|
|
707
|
+
the old component was. For a weekly window, the new props are on the
|
|
708
|
+
[Schedule input](https://tamga.org.tr/docs/schedule-input) page; the summary line is the
|
|
709
|
+
caller's sentence, because "Every weekday" and "Her hafta içi" are not a translation the kit can
|
|
710
|
+
make.
|
|
711
|
+
|
|
712
|
+
- **`FileUpload.onReorder` takes a target index, not a direction.** `(id, -1 | 1)` became
|
|
713
|
+
`(id, target)`. The first signature was enough for the two arrow buttons; dragging broke it,
|
|
714
|
+
because moving the fourth image to the front is not a step. Two callbacks would have told one
|
|
715
|
+
story from two places, so there is one meaning left: *put this item at this index*.
|
|
716
|
+
|
|
717
|
+
Migration: the arrow buttons now send `i - 1` / `i + 1`, so a handler that swapped two entries
|
|
718
|
+
keeps working for them — but for dragging it must **splice**, not swap, or making the fourth
|
|
719
|
+
image the cover flings the cover into fourth place. The docs page shows the splice form.
|
|
720
|
+
|
|
721
|
+
- **`SettingsPanel` no longer takes `accent`.** The brand-coloured left edge existed for one
|
|
722
|
+
screen — the appearance screen — and that screen stopped stacking panels (see below), so the
|
|
723
|
+
prop had no caller left and its documented reason no longer described anything. Drop the prop;
|
|
724
|
+
nothing replaces it. A product that wants a coloured edge on a panel is describing a different
|
|
725
|
+
component, not a variant of this one.
|
|
726
|
+
|
|
727
|
+
- **`AppearanceLabels.brand` gained four required strings** — `customName`, `preview`,
|
|
728
|
+
`previewAction` and `lightNote` — because the brand row now names the chosen colour, prints its
|
|
729
|
+
hex, and shows a sample of it. The kit does not write text, so all four come from the caller.
|
|
730
|
+
|
|
731
|
+
### Added
|
|
732
|
+
|
|
733
|
+
- **`Accordion.look`** — `cards` (the default) or `list`. The design draws both: sections as
|
|
734
|
+
their own raised cards, and the quiet stack inside one surface. The container decides, because
|
|
735
|
+
a prop on every section is the same decision taken again at every call site.
|
|
736
|
+
|
|
737
|
+
- **`ScrollX.controls` and `ScrollX.title`** — the two arrow buttons at the head of a strip, as
|
|
738
|
+
the design draws them. A click moves the strip by **one visible width** (90% of it, so the card
|
|
739
|
+
at the edge is not swallowed), never by "one card": that would need the strip to know what a
|
|
740
|
+
card is. The arrows do not replace the keyboard; the strip is focusable and scrolls with the
|
|
741
|
+
arrow keys already.
|
|
742
|
+
|
|
743
|
+
- **`Collapsible.icon`** — the glyph at the head of the row, in the accent: it says what kind of
|
|
744
|
+
section this is before the words are read.
|
|
745
|
+
|
|
746
|
+
- **`EmptyState` has a fourth layout, `plain`** — the dashed card the design draws: an icon tile
|
|
747
|
+
(`icon`, `tone`), a line and the first step, with no mascot. `art` is optional now. It is the
|
|
748
|
+
shape most screens need, and the dashed edge is the kit's own word for "not real content yet":
|
|
749
|
+
filled, the same place holds a solid card.
|
|
750
|
+
|
|
751
|
+
- **`Tag`** — the label badge: BETA, NEW, PRO. A sibling of `Badge` but not the same thing: a
|
|
752
|
+
counter carries a QUANTITY and disappears once read, a tag carries a STATE and stays. Three
|
|
753
|
+
looks — `dashed` for what is not real yet (a dashed edge says exactly that everywhere in the
|
|
754
|
+
kit), `solid` for what is new right now, `outline` for the quiet standing fact. The product
|
|
755
|
+
writes the word, the kit gives the shape.
|
|
756
|
+
|
|
757
|
+
- **`Spinner.look`** — `bars` (the default, the inline one that fits inside a control), `pixels`
|
|
758
|
+
(the mark's own 3×3 grid, pulsing along the diagonal, for a panel waiting on its first data)
|
|
759
|
+
and `ring` (the familiar circle, for a whole screen). The kit had only the bars, so every
|
|
760
|
+
screen-level wait borrowed a control-sized spinner.
|
|
761
|
+
|
|
762
|
+
- **`Descriptions.split`** — breaks the list into as many columns as fit (280px floor). At page
|
|
763
|
+
width a six-row list was leaving the right half empty; split, it reads as two short lists. Each
|
|
764
|
+
column keeps its own label column, so the values still line up.
|
|
765
|
+
|
|
766
|
+
- **`Code.filename`** — the name on the strip. Without it the strip still stands and holds the
|
|
767
|
+
copy button.
|
|
768
|
+
|
|
769
|
+
- **`InputGroup`** — the prefix/suffix box: a currency, a domain, a unit, a search glyph, a
|
|
770
|
+
shortcut key. The class for it had been in the kit with no component to draw it. A prefix is a
|
|
771
|
+
**piece**, not a string, so an `<Icon />` fits where "₺" fits, and the focus ring wraps the
|
|
772
|
+
whole box: one object, not two.
|
|
773
|
+
|
|
774
|
+
- **`Field.required`, `Field.note`, `Field.info` and `Field.count`.** The asterisk is a glyph
|
|
775
|
+
rather than a word (a word is a translation, and the kit makes none), `note` is the caller's
|
|
776
|
+
quiet word at the far end of the label row, `info` a mark that sits outside the `<label>` so
|
|
777
|
+
clicking it does not focus the control, and `count` the character counter under the control —
|
|
778
|
+
on the FIELD, because a textarea knows how many characters it holds, not how many it is
|
|
779
|
+
allowed.
|
|
780
|
+
|
|
781
|
+
- **`Button.variant="soft"`** — a step between primary and secondary, filled in the accent's
|
|
782
|
+
light tone. The action that says "you can also do this" without competing with the page's one
|
|
783
|
+
filled button.
|
|
784
|
+
|
|
785
|
+
- **`Link.look`** — `inline` (the default), `standalone` with an arrow that steps forward under
|
|
786
|
+
the pointer, `quiet` for a footer where twenty links cannot all be in the accent, and `marked`
|
|
787
|
+
for the one address in a paragraph that has to be found.
|
|
788
|
+
|
|
789
|
+
- **`Kbd.inline`** — the quieter key for a row in a shortcut list, where twenty layered boxes
|
|
790
|
+
would turn the list into a keypad.
|
|
791
|
+
|
|
792
|
+
- **`Card` can lead somewhere.** `href` (with `linkComponent`) or `onClick` makes the card a real
|
|
793
|
+
`<a>` or `<button>` and gives it the raised physics: it lifts under the pointer and presses
|
|
794
|
+
flat. A product card was being hand-rolled as a clickable `div`, which is invisible to the
|
|
795
|
+
keyboard and silent to a screen reader.
|
|
796
|
+
|
|
797
|
+
- **`SaysBubble`** — the conversation bubble, in three sides: `them` (left, quiet surface),
|
|
798
|
+
`me` (right, accent fill with a base) and `assistant` (a dashed, washed suggestion). The corner
|
|
799
|
+
facing the speaker is the small one; there is no tail, because a tail means a rotated square
|
|
800
|
+
and the kit has none. Time and delivery state live inside the bubble, where they do not break
|
|
801
|
+
the rhythm of a long thread.
|
|
802
|
+
|
|
803
|
+
- **`Kpi.look`** — `tile` (the default) is what a KPI grid is built from: a 40px icon box on the
|
|
804
|
+
left, the label over the number. `detail` is the taller card for a number that carries a curve
|
|
805
|
+
beside it and a change under it, the delta now drawn as a chip rather than an inline
|
|
806
|
+
percentage. The two are separate because of room: a card that fits a curve is taller than a
|
|
807
|
+
tile four of which stand side by side.
|
|
808
|
+
|
|
809
|
+
- **`Tabs.look="folder"` and `TabPanel`.** The design has two kinds of tab and the kit had one.
|
|
810
|
+
The line separates views of the page; the folder separates sections of one surface, sitting ON
|
|
811
|
+
its panel — the active tab's bottom edge is transparent and the tab drops by the panel's 1.5px
|
|
812
|
+
border, so the two read as one body.
|
|
813
|
+
|
|
814
|
+
- **`Segmented.size="sm"`** — the strip that lives in a toolbar. At the base size a segment
|
|
815
|
+
stands taller than the row it sits in; the docs example box's bar was 55px against the
|
|
816
|
+
reference's 45.
|
|
817
|
+
|
|
818
|
+
- **`yiginRenk` / `yiginRenkleri`** (from `tamga-ui/tone`) — the brand ramp a stacked chart's
|
|
819
|
+
slices step through, beside `seriRenk` for separate measures. Two names, so the two cases
|
|
820
|
+
cannot be confused.
|
|
821
|
+
|
|
822
|
+
- **`RailLink.badge`** (with `badgeLabel`) — how many things wait behind an entry. On a wide rail
|
|
823
|
+
it is the number; on a narrow one only a square, because a two-digit number sits on top of the
|
|
824
|
+
icon in a 40px box, and an unreadable number says no more than "there is something". The number
|
|
825
|
+
itself goes to the screen reader through `badgeLabel`, which is why that one is required.
|
|
826
|
+
|
|
827
|
+
- **`TabItem.count`** — the mono chip beside a tab's label: how many rows are in that tab. Mono,
|
|
828
|
+
because it is a number compared with the other tabs' numbers rather than a word to be read.
|
|
829
|
+
|
|
830
|
+
- **`Tooltip.bind`** — turns off the `aria-describedby` tie. On for everything except a trigger
|
|
831
|
+
whose accessible name is already the tooltip's text: a narrow rail item is labelled
|
|
832
|
+
"Orders" and its tip says "Orders", and a screen reader read it twice.
|
|
833
|
+
|
|
834
|
+
- **`Toast` has its own lifetime.** "It comes, and it goes" was the component's one sentence and
|
|
835
|
+
the going was left to the caller: every product wrote its own `setTimeout`, and the ones that
|
|
836
|
+
did not left notifications on screen. It is **5 seconds now, 8 with an `action`** ("Undo" has
|
|
837
|
+
to be readable *and* reachable before it leaves), `duration={0}` keeps it until dismissed, and
|
|
838
|
+
**the timer pauses while the pointer or keyboard focus is on it** — the hand reaching for
|
|
839
|
+
"Undo" travels straight across the toast.
|
|
840
|
+
|
|
841
|
+
`role` follows the tone: **`alert` only for `danger`**, because an assertive region cuts into
|
|
842
|
+
the sentence a screen reader is reading. Everything else stays `status`.
|
|
843
|
+
|
|
844
|
+
- **`MenuItem.shortcut`** — the keyboard shortcut drawn on the right of a menu row as a `Kbd`. It
|
|
845
|
+
does not bind the key: a menu that binds a global shortcut would fight the page that already
|
|
846
|
+
has one.
|
|
847
|
+
|
|
848
|
+
- **`LogView` says how many lines you missed.** Following only when you are already at the bottom
|
|
849
|
+
is the right behaviour, but it has a price: a line that arrives while you are reading further up
|
|
850
|
+
is out of sight, and without a word about it the stream looks stopped. A "↓ 12 new lines" button
|
|
851
|
+
now appears in that case and takes you down; the counter resets the moment you reach the bottom.
|
|
852
|
+
|
|
853
|
+
- **`LogLine.level`** — the level badge's word ("INFO", "WARN", "UYARI"). The kit draws the badge
|
|
854
|
+
and colours it from `tone`; the product writes the word, because a log level is not a string the
|
|
855
|
+
kit can translate.
|
|
856
|
+
|
|
857
|
+
- **`FileUpload` reorders by dragging** as well as with the arrow buttons. The dragged card fades
|
|
858
|
+
to 0.45 (lower reads as deleted) and the card it would land on takes the accent edge — the kit's
|
|
859
|
+
existing "this is the target" mark, not a new line invented for it. The arrows stay, because
|
|
860
|
+
drag-and-drop does not exist for someone on a keyboard.
|
|
861
|
+
|
|
862
|
+
- **`Checkbox.indeterminate`** — renders `aria-checked="mixed"` with a minus glyph. A parent row
|
|
863
|
+
whose children are partly selected had to be drawn either checked or unchecked, and both were
|
|
864
|
+
false; `TreeSelect` and any "select all" header need this third state.
|
|
865
|
+
|
|
866
|
+
- **`NumberInput.locale`** — which thousands separator and decimal mark to draw. It was hardcoded
|
|
867
|
+
to the browser's locale, so a Turkish panel viewed in an English browser showed `1,500.50` in a
|
|
868
|
+
form that submits `1.500,50`.
|
|
869
|
+
|
|
870
|
+
- **`RailCards`.** The sidebar width was a three-word `Segmented`: "Always narrow · Always wide ·
|
|
871
|
+
Let the user choose". On the same screen the theme was asked with pictures and this with words,
|
|
872
|
+
and how much room a menu takes is something you see rather than read. Three miniatures now, and
|
|
873
|
+
the third carries a collapse button at the foot of the rail because that is where it sits in the
|
|
874
|
+
panel.
|
|
875
|
+
|
|
876
|
+
- **`ThemeCards` takes a one-line note under each name** (`lightNote`, `darkNote`, `systemNote`),
|
|
877
|
+
and "System" is drawn as one panel cut on a diagonal rather than two rectangles side by side.
|
|
878
|
+
Two rectangles say "there are two themes"; the diagonal says "same panel, the device decides".
|
|
879
|
+
|
|
880
|
+
- **`PageBand` takes an `eyebrow`.** A short line above the title, for the question a title leaves
|
|
881
|
+
open — whether a setting applies to everyone or only to the person reading it.
|
|
882
|
+
|
|
883
|
+
### Changed
|
|
884
|
+
|
|
885
|
+
- **The appearance screen is one card with dashed rows, not five stacked cards.** Five cards said
|
|
886
|
+
"a new subject starts here" five times, for five parts of one subject; and with the title above
|
|
887
|
+
the control in each, the eye zigzagged down the screen. Titles now sit in one column and
|
|
888
|
+
controls in another, split by the card's own width rather than the viewport, so the breakpoint
|
|
889
|
+
is right whether the rail is open or shut.
|
|
890
|
+
|
|
891
|
+
- **A colour swatch is the colour.** It was a white box holding a 20px square, with the check mark
|
|
892
|
+
deliberately left out because "its contrast changes with the chosen colour and disappears on a
|
|
893
|
+
light one". The reason was right and the remedy was not: the ink is now taken from the palette
|
|
894
|
+
that colour generates, so a light swatch gets dark ink and a dark one white. The square is 44px
|
|
895
|
+
and the check sits inside it.
|
|
896
|
+
|
|
897
|
+
The swatch no longer lifts on hover or sits on press. Its resting height is two different
|
|
898
|
+
numbers (0 unselected, 4 selected) and one hover ladder cannot serve both — tuned for the
|
|
899
|
+
unselected box, hover LOWERED the selected one. Law 1 · E and F caught it.
|
|
900
|
+
|
|
8
901
|
## 0.4.4
|
|
9
902
|
|
|
10
903
|
### Added
|