@sakaniui/react 0.8.7 → 0.8.8

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/AGENTS.md CHANGED
@@ -16,8 +16,14 @@ import manifest from '@sakaniui/react/manifest.json';
16
16
  const button = manifest.components.find((c) => c.name === 'Button'); // props[], contract.requiredProps
17
17
  ```
18
18
  Editors can query the same data through the bundled MCP server
19
- (`npx -y -p @sakaniui/react sakaniui-mcp`): `get_component`, `check_usage`, `get_tokens`, `get_guide`.
20
- If it is connected, call `check_usage` on every component you write.
19
+ (`npx -y -p @sakaniui/react sakaniui-mcp`): `get_component`, `check_usage`, `get_tokens`, `get_guide`,
20
+ `check_compatibility`, `get_changelog`. If it is connected, call `check_usage` on every component you write.
21
+
22
+ **Versions.** Every component has `since`, the first release that contained it. The project may have an
23
+ older `@sakaniui/react` installed than the one the manifest describes: if an entry is marked
24
+ `availableInInstalled: false`, or `check_compatibility` lists it under `missingInInstalled`, it does not
25
+ exist in that project, so do not use it without upgrading. The server reads the project's installed
26
+ version itself; if it cannot, run `npm ls @sakaniui/react` and pass the result as `installedVersion`.
21
27
  If a prop, value or token is not in the manifest, it does not exist. If `contract.requiresAccessibleName`
22
28
  is true, the required `aria-label` / alt prop is the only thing that names the control. Do not drop it.
23
29
 
package/CHANGELOG.md ADDED
@@ -0,0 +1,472 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@sakaniui/react` are documented here.
4
+
5
+ ## 0.8.8
6
+
7
+ Audit of the agent contract and MCP server (accuracy, security, versioning).
8
+
9
+ - **Manifest accuracy.** `FaqBlock.columns` is now `1 | 2` (numbers), not `"1" | "2"`; prop `values`
10
+ keep their real type. All 231 design tokens are listed (the 49 `glass-*`, `surface-*` and `liquid-*`
11
+ tokens were missing). `LiquidGlass`, `LiquidBackdrop` and `HoverGroup` are described, and hooks and
12
+ helpers are listed under `utilities`. Defaults that are code (`createIcon(...)`, arrow functions) are
13
+ no longer shown. The build now fails if a public component is exported but not described, so the
14
+ manifest cannot silently fall behind.
15
+ - **Manifest content.** Design-tool (Figma) notes, source paths and a sample e-mail address are no longer
16
+ shipped in the manifest.
17
+ - **Versioning.** Every component has `since`, the first release that contained it. `CHANGELOG.md` now
18
+ ships in the package. The MCP server finds the project's own installed `@sakaniui/react` (working
19
+ directory, or `--project <dir>`) and answers from that copy; when the project is older it flags
20
+ components it does not have yet. New tools `check_compatibility` and `get_changelog`.
21
+ - **Summaries.** Component summaries were rewritten where the source notes were maintainer-only text
22
+ (garbled or empty summaries, design-tool node ids); blocks get a name-and-group summary.
23
+ - **Verified on every build.** `npm run build:lib` now also runs `scripts/manifest/verify.mjs`, which fails
24
+ the build (and so `npm publish`) if an entry is not a real export, a prop is not in the type
25
+ definitions, a token disagrees with `tokens.css`, `since` is newer than the package, or anything that
26
+ looks like a private reference (design-file link or node id, e-mail address, local path, key) or any
27
+ write / network / exec code in the server appears.
28
+ - **Server hardening.** Every tool argument is type- and length-checked, tools are marked read-only, and
29
+ the server reads only four fixed files from an install (package.json, manifest, AGENTS.md, CHANGELOG.md).
30
+
31
+ ## 0.8.7
32
+
33
+ - **Machine-readable contract for AI agents and tooling.** The package now ships
34
+ `@sakaniui/react/manifest.json`: every exported component and block (123 + 42) with its import
35
+ path, summary, props, types, enum values, defaults, required props and a
36
+ `requiresAccessibleName` flag, plus all 182 design tokens. It is generated from the TypeScript
37
+ source on every `build:lib` (react-docgen-typescript), so it cannot drift from the code, and it only
38
+ lists names that are really exported. AGENTS.md now points agents at it first.
39
+ - **MCP server.** `npx -y -p @sakaniui/react sakaniui-mcp` starts a local, dependency-free Model
40
+ Context Protocol server over stdio that answers from the shipped manifest and AGENTS.md. Tools:
41
+ `search_components`, `get_component`, `list_components`, `get_tokens`, `check_usage` (reports
42
+ missing required props, values outside an enum and props that do not exist) and `get_guide`.
43
+ - `IconButton`'s `icon` prop description no longer says "Lucide icon component" (it takes Tabler or Lucide).
44
+
45
+ ## 0.8.6
46
+
47
+ - **Social icons are now exported.** The glyphs the Figma ProfileCard and TeamCard use --
48
+ `XIcon`, `GithubIcon` (ProfileCard) and `InstagramIcon`, `FacebookIcon`, `LinkedinIcon`
49
+ (TeamCard) -- can be imported from `@sakaniui/react`, so an app's `socialLinks` can use the exact
50
+ same icons as the design system instead of copying them. They draw in `currentColor`.
51
+
52
+ ## 0.8.5
53
+
54
+ - **Sidebar: 8px corners.** To match the Figma file (where the sidebar components now use
55
+ `radius/md`), `SidebarItem`, `SidebarSubItem`, `SidebarSearch` (field, command and collapsed),
56
+ `SidebarHeader` (workspace card and brand button) and the `SidebarFooter` action button go from
57
+ 6px to 8px. Small icon buttons (the header toggle and footer menu) and the keyboard-shortcut
58
+ badge keep their size, as in Figma.
59
+
60
+ ## 0.8.4
61
+
62
+ - **Switch: new `stretch` variant.** `<Switch variant="stretch" />` adds a liquid motion: on every
63
+ toggle the thumb stretches (16 -> about 22px) as it travels -- the edge it is heading toward moves
64
+ first, the tail follows a beat later -- then relaxes into a circle. One smooth motion with no
65
+ overshoot, it stays inside the track, a click mid-travel reverses from where the thumb visibly is,
66
+ and it is off with reduced motion. `variant="default"` (the default) is the plain switch,
67
+ unchanged. Figma: Switch gains a *Type* axis (Default | Stretch).
68
+
69
+ ## 0.8.3
70
+
71
+ - **SakaniUI.** The design system is now called SakaniUI, and the GitHub repository moved to
72
+ github.com/samzydd/Sakaniui (the old URL redirects). The package name, `@sakaniui/react`, is
73
+ unchanged; this release updates the repository, homepage and issues links shown on npm.
74
+
75
+ ## 0.8.2
76
+
77
+ - **Kanban Board: calmer motion.** The dragged card's tilt and its settle on drop are now
78
+ near-critically damped (overshoot down from about 30% to 2%), and the cards that slide out of the
79
+ way ease in without overshooting.
80
+
81
+ ## 0.8.1
82
+
83
+ - **Kanban Board: smooth drag and drop.** The block's native HTML5 drag is replaced by pointer-based
84
+ dragging (mouse, pen and touch). While you drag, the card lifts and swings from the grab point
85
+ with its movement; a drop slot -- the card itself at 20% with a 12/4 dashed outline -- opens
86
+ exactly where it will land and the other cards slide out of the way; on release the card glides
87
+ into place. Drops land at the slot's position instead of the end of the column. Touch drags start
88
+ with a press-and-hold, the board auto-scrolls at its edges, a card dropped outside every column
89
+ springs back, and reduced motion turns off the swing and glide.
90
+ - The sample board has photo avatars and five or six cards per column. Figma: Board Column gains a
91
+ *Drop target* variant, and the Kanban *Dragging* state shows the new slot.
92
+
93
+ ## 0.8.0
94
+
95
+ - **Removed:** Glass Icons (`@sakaniui/react/glass-icons`). The glass versions couldn't stay faithful
96
+ to every Tabler icon, so the set is gone from the package, the docs and the Figma file (with its
97
+ `glass-icon/*` variables and `--glass-icon-*` tokens). Use the regular icons from
98
+ `@sakaniui/react/icons` instead (`GlassHeart` -> `IconHeart`). Glass and liquid glass *surfaces*
99
+ are unchanged.
100
+ - `lucide-react` is gone entirely, and so is its licence notice: every icon is Tabler (MIT).
101
+
102
+ ## 0.7.0
103
+
104
+ - **Tabler Icons is now the icon set.** New entry point `@sakaniui/react/icons` with all 5,184 Tabler
105
+ outline icons (`IconHome`, `IconCalendar` ...) and 1,054 filled ones (`IconHomeFilled` ...),
106
+ generated from `@tabler/icons` and matching the Figma *↳ Icons (Tabler)* page. One component per
107
+ icon, tree-shaken individually (one icon is about 1 kB). Props follow lucide-react (`size`,
108
+ `color`, `strokeWidth`, `absoluteStrokeWidth`) plus `title`; default stroke 1.5, the Figma stroke.
109
+ - **Every component now renders Tabler icons.** The 125 Lucide icons used inside components and
110
+ blocks were swapped for their Tabler equivalents, with the same mapping as the Figma file (house
111
+ -> home, triangle-alert -> alert-triangle, panel-left -> layout-sidebar ...). `lucide-react` is no
112
+ longer a dependency of the package.
113
+ - Icon props are typed `IconComponent` (exported from the main entry) instead of Lucide's
114
+ `LucideIcon`; Lucide and Tabler React icons still fit, so existing apps keep working.
115
+ - **Removed:** `@sakaniui/react/sicons` (the rounded Lucide set from 0.6.x), replaced by
116
+ `@sakaniui/react/icons`. Swap `SiconHeart` for `IconHeart`; names follow Tabler.
117
+ - `THIRD_PARTY_NOTICES.md` now carries Tabler's MIT licence (icons) as well as Lucide's ISC licence
118
+ (Glass Icons, still Lucide-based).
119
+
120
+ ## 0.6.1
121
+
122
+ - **Sicons: crisp chevrons and checks.** Icons with short, sharp corners (chevrons, checks, small
123
+ arrows, list ticks) now use a 1px corner radius instead of 3.7 or 4; a 4px radius blunted their
124
+ points into curves. The rule: if a 4px radius would use more than 30% of the shorter edge at the
125
+ icon's tightest corner, the whole icon gets 1px (274 icons); every other icon keeps 4px. The
126
+ Figma Sicons set uses the same rule (307 icons there, where Figma joins some lines differently).
127
+
128
+ ## 0.6.0
129
+
130
+ - **Sicons: Sakani's own icon set, `@sakaniui/react/sicons`.** The same 1,626 icons as the Figma
131
+ *Icons* component set: Lucide's shapes at a 1.5 stroke with softened corners (a 4px radius, 3.7px
132
+ on icons whose short corners can't take 4). One component per icon (`SiconHeart`,
133
+ `SiconCalendar`, ...), each tree-shaken on its own (one icon is under 1 kB).
134
+ - Props follow lucide-react (`size`, `color`, `strokeWidth`, `absoluteStrokeWidth`), plus `title`,
135
+ so swapping a Lucide icon is a find-and-replace. Colour is `currentColor`.
136
+ - Figma first: the *Icons* set itself has the same rounded corners, so every icon instance in the
137
+ file matches.
138
+ - Corner rounding is baked into the path data at build time (`scripts/sicons/`), with the same
139
+ rule the Figma set was built with. A few percent of icons can get the 3.7 radius in one and the
140
+ 4 in the other where Figma joins lines differently. Where two lines meet at a shared point (an
141
+ arrow head on its shaft) the corner is left as is, as in Figma.
142
+ - Naming: the icon set is now called Sicons everywhere (Figma page *↳ Sicons*, component set
143
+ *Sicons*), credited as based on Lucide. The package now ships `THIRD_PARTY_NOTICES.md` with
144
+ Lucide's ISC licence, which covers Sicons and Glass Icons.
145
+ - Storybook: *Foundations -> Sicons* (overview, close-up, props, searchable gallery).
146
+ - Not changed: the built-in components still render lucide-react icons; moving them onto Sicons is
147
+ a separate step.
148
+
149
+ ## 0.5.0
150
+
151
+ - **Glass icons: all 1,626 icons in the Sakani icon set, as monochrome frosted glass.** New entry
152
+ point `@sakaniui/react/glass-icons`, one component per icon (`GlassHeart`, `GlassCalendar`, ...),
153
+ each tree-shaken on its own. Each icon's main shape is one charcoal glass solid (top-to-bottom
154
+ gradient, bright rim, soft shadow), a disc tucked behind its corner glows through the glass
155
+ blurred, and inner lines sit on the glass in white (lines off the glass stay solid). Line-only
156
+ icons (arrows, a checkmark) become a single thick glass stroke. Props: `size` (default 24, any CSS
157
+ length), `surface`, `title`.
158
+ - Charcoal on purpose: brand-neutral, so any team can use them. Colours are the new
159
+ `--glass-icon-*` tokens on `:root` and `.dark` (accent, glass-top, glass-bottom, rim, detail,
160
+ detail-off), so light and dark follow the nearest theme scope.
161
+ - Figma first: the file has the matching *Glass Icons* component set (page *↳ Glass Icons*, 1,626
162
+ 24x24 `type=` variants mirroring *Icons*, layers scale with the instance), coloured by the
163
+ `glass-icon/*` variables in the Semantic collection (Light/Dark).
164
+ - Which parts are glass and which are lines is decided at build time
165
+ (`scripts/glass-icons/decompose.mjs`), with the same rules the Figma set was built with.
166
+ - The set: 1,603 icons from lucide-react's shape data, 23 from the Figma file (brand logos Lucide
167
+ removed, plus icons Lucide merged into a sibling).
168
+ - Pure SVG on a 24x24 grid (masks, gradients, blur), no backdrop-filter: sharp at any size and the
169
+ same in every browser.
170
+ - `<GlassIcon icon={AnyLucideIcon} />` covers Lucide icons added later (drawn as one glass stroke).
171
+ - Storybook: *Foundations -> Glass Icons* (overview light/dark, sizes, searchable gallery).
172
+
173
+ ## 0.4.11
174
+
175
+ - **ProductCard matches Figma to the pixel.** Measured against the Figma set (320 x 536), the code
176
+ card was 546px tall and its text column 294px instead of 296px. Fixed: the title-to-description
177
+ gap is 8px (it was the body's 12px), the swatches are the 28px Figma uses (circle 21, check 10)
178
+ instead of 32px, the five stars are 91px wide (2.68px apart, not 4px), and the 1px border is taken
179
+ out of the padding and the image height so the stroke sits "inside" the frame as in Figma. The
180
+ standalone `ColorSwatch` is unchanged: it now sizes from `--swatch-size` (default 32px), which
181
+ the card sets to 28px.
182
+
183
+ ## 0.4.10
184
+
185
+ - **CRMDashboardBlock is responsive.** It was hard-wired to the viewport (`100vw` x `100vh`) with
186
+ media queries, so inside a frame, a split view or a phone it overflowed and clipped. It now fills
187
+ its container (`--crm-block-height` sets the height; default `100vh`) and its breakpoints are
188
+ container queries. Tablet (<= 880px): the filter panel steps aside and the toolbar wraps. Phone
189
+ (<= 640px): the icon rail becomes a slide-in navigation drawer opened from the top bar's menu
190
+ button (Escape or the scrim closes it), the toolbar stacks, tabs scroll, and padding tightens. The
191
+ table now stacks into cards based on its own width (<= 720px) instead of the window's, so it never
192
+ crams eight columns into a narrow frame. No prop changes.
193
+ - **TeamCard matches Figma's text width.** The card's 1px border was added on top of Figma's 12px
194
+ padding (Figma's stroke sits inside the frame), leaving a 378px text column instead of 380px. That
195
+ was enough to wrap the *Card details* bio onto a third line, making the card 20px taller than
196
+ Figma's. The border is now taken out of the padding, so the column is 380px and the bio wraps
197
+ exactly as in Figma.
198
+ - **KanbanBoardBlock works on phones.** The toolbar was one non-wrapping row, so the search field,
199
+ filter chips and buttons overlapped below ~700px. The block is now a size container: below 760px
200
+ the toolbar stacks (search, filters, then the actions sharing the row), and the board scrolls edge to
201
+ edge with columns snapping into place as you swipe. Wider layouts are unchanged.
202
+
203
+ ## 0.4.9
204
+
205
+ - **ProgressItem titles line up with their numbers.** In the vertical layout a title with no
206
+ description sat at the top of the 32px circle, 6px above its centre; it is now centred on the circle.
207
+ A title with a description stays top-aligned so the pair reads as one block. The horizontal layout
208
+ is left-aligned on purpose (the label starts at the circle's left edge) and that is now explicit in
209
+ the CSS.
210
+
211
+ ## 0.4.8
212
+
213
+ - **AI-readable design system.** The package now ships `AGENTS.md`: the *why* behind the system for
214
+ AI agents and new teammates — setup that must be right, eight principles, what to do when nothing
215
+ fits, when to use (and not use) each component and why it behaves as it does, glass/liquid usage rules,
216
+ the behaviour you must supply yourself, and recipes for AI-product moments (uncertain answers, sources,
217
+ declined requests, partial responses). The docs site serves an index at `/llms.txt` and the full
218
+ text at `/llms-full.txt`.
219
+
220
+ ## 0.4.7
221
+
222
+ - **SidebarPromo uses the real Button.** Its CTA was a hand-styled `<button>` too. It now renders
223
+ `<Button variant="primary" size="sm">` stretched full width, so it gets the updated hover,
224
+ press and focus effects. Liquid surfaces keep the outlined, see-through look. No prop changes.
225
+
226
+ ## 0.4.6
227
+
228
+ - **EmptyState uses the real Button.** The action was a hand-styled `<button>` that missed the
229
+ updated Button's hover, press and focus effects. It now renders `<Button variant="outline"
230
+ size="sm">`, so it stays in step with every Button change. No prop changes.
231
+
232
+ ## 0.4.5
233
+
234
+ - **BlogListingFeaturedCard is responsive.** The horizontal card (a fixed 400px image plus
235
+ text) squeezed its text column to a sliver whenever its container was narrower than ~640px.
236
+ It now measures its own container: side by side when there's room, stacked (image on top,
237
+ full width) below 640px, with the footer wrapping below 360px. Nothing changes at the
238
+ card's designed width (874px), and `BlogListingBlock` is unchanged. New story:
239
+ *Marketing → Blog Listing Featured Card → Responsive*.
240
+
241
+ ## 0.4.4
242
+
243
+ - **Stepper: the bar animates between steps.** Going forward, the connector fills from the
244
+ step you leave toward the next one and that circle activates when the bar arrives (its ring
245
+ ripples once and the previous circle's check draws in). Going back plays it in reverse,
246
+ draining the bar. Jumping several steps hands the fill from bar to bar. Horizontal and
247
+ vertical. No animation on first render; `prefers-reduced-motion` makes every change
248
+ instant. New stories: *Composite / Stepper → Animated* and *Animated vertical*.
249
+
250
+ ## 0.4.3
251
+
252
+ - **Faster sidebar toggle in the dashboard.** Collapsing or expanding the sidebar used
253
+ to drop frames (a 367ms frame and 200ms+ tasks on expand): the main glass panel
254
+ rebuilt its megapixel displacement map on every animation frame and the charts
255
+ re-rendered with it. Lens maps are now built only along the edges, big lenses settle
256
+ before re-measuring, and the dashboard content is memoized. Worst frame: 33ms, no
257
+ long tasks. Output is pixel-identical.
258
+ - **Collapsed rail:** hovering anywhere on the rail turns the logo into the "open
259
+ sidebar" button (it cross-fades), not only hovering the logo itself.
260
+
261
+ ## 0.4.2
262
+
263
+ **Liquid glass speaks Figma: the same Glass properties, the same values, the same result.**
264
+
265
+ - **`LiquidGlass` now takes Figma's Glass effect properties directly**, in
266
+ Figma's units: refraction, depth, dispersion, frost, light intensity and
267
+ light angle. The tokens are the liquid/regular and liquid/clear effect
268
+ styles as they are in Figma:
269
+ `--liquid-refraction-regular|clear` (0.55 | 0.8), `--liquid-depth-*`
270
+ (16 | 20), `--liquid-dispersion-*` (0.3 | 0.4), `--liquid-frost-*` (4 | 1),
271
+ `--liquid-light-intensity-*` (0.7 | 0.8) and `--liquid-light-angle` (-45).
272
+ Per element: `<LiquidGlass effect={{ refraction: 0.8, depth: 20, dispersion: 0.4, frost: 1 }}>`.
273
+ - **Measured, property by property.** Each Figma property was swept on its
274
+ own over gradient, step and flat-grey backdrops, and the code reproduces
275
+ every probe: the bend within 0.3px on average (all refraction, depth and
276
+ dispersion values), the frost blur within 0.3px, the light within half a
277
+ brightness level. How each property behaves:
278
+ - Refraction × depth sets the bend; depth also sets how far in it reaches
279
+ (0.8 × depth px). The steep fall near the rim folds the content just
280
+ inside into the magnified band along the edges and round the corners.
281
+ - Dispersion splits the color: red bends more, blue less.
282
+ - Frost blurs the backdrop before it is bent.
283
+ - Light is added on top: a 1px rim, strongest on edges that face the
284
+ light (none on edges side-on to it), plus a shade inside the lit edges
285
+ and a glow inside the far ones. It is drawn in the filter now, so it adds
286
+ light like Figma instead of laying white over the backdrop.
287
+ - **Correction to 0.4.1:** Figma's lens never samples outside the element, and
288
+ every edge bends the same way (with the light off). The 0.4.1 note about an
289
+ approximate clear rim no longer applies.
290
+ - **Breaking (tokens published in 0.4.1):** `--liquid-bezel-*`,
291
+ `--liquid-shift-*`, `--liquid-profile-*` and `--liquid-saturate-*` are gone
292
+ (Figma has no such properties); `--liquid-depth` is now Figma's Depth, and the
293
+ old inset-shadow token is `--liquid-edge-shade` (Safari/Firefox fallback
294
+ only). `--liquid-light-angle` is Figma's angle in degrees (-45), not a CSS
295
+ gradient angle.
296
+ - **New: `LiquidBackdrop`.** Wrap a liquid-glass UI in
297
+ `<LiquidBackdrop src={photo}>` and every lens inside refracts the photo itself
298
+ (an aligned copy, kept aligned while lenses glide, scroll or squish) instead of
299
+ whatever the browser painted below it. Like Figma, glass stacked on glass now
300
+ bends the sharp original: real refraction and color fringing on nested lenses,
301
+ not a blur of the lens below. `veil` lays a color over the image for every lens
302
+ (Figma's 5% overlay fill; a scrim in dark mode). `source={false}` on a lens
303
+ bends the UI below instead (slider knobs, selection droplets).
304
+ - **Fast at full-screen sizes.** A live SVG filter over a full-screen lens is
305
+ re-evaluated whenever anything near it repaints (the dashboard ran at ~15fps
306
+ while hovering the sidebar). Inside a `LiquidBackdrop`, lenses bigger than
307
+ 300×300 now run the same filter once into a canvas and re-bake only when their
308
+ size, position, theme or properties change: 60fps, pixel-identical. Small
309
+ lenses that move stay live; `bake={false}` keeps a big moving lens live.
310
+ - **`LiquidDashboardBlock`** sits on a `LiquidBackdrop`: the promo card and the
311
+ sidebar lenses refract the sharp photo like the Figma frame; the active lens
312
+ springs and stretches as it glides; item labels are fg/default as in Figma.
313
+ - **`LiquidDashboardBlock` is responsive.** It reflows to the width of its panel
314
+ (container queries): four stat cards become 2×2, then a column; the charts go
315
+ from three across to two, then one; Recent orders and Recent activity stack.
316
+ Below 900px the sidebar collapses to its rail by itself (until you toggle it).
317
+ The collapsed rail is fixed: lenses hug the 32px buttons, items are centered,
318
+ groups are separated by a hairline, and the lens lands exactly where the
319
+ rail's width animation ends. Search closes on Esc and shows a focus ring.
320
+ Collapsed tooltips are portaled to the page (the rail clipped them and the main
321
+ panel covered them), and hovering a nav item changes nothing but the glass: the
322
+ library's own icon darkening, which fired before the lens faded in, is off.
323
+ The opened search field is a glass pill: its icon and text were white on a white
324
+ box (the top bar is in on-photo mode), so they vanished.
325
+ - **Storybook:** *Foundations / Liquid Glass* is now a showcase (sidebar, tab bar
326
+ with a sliding droplet, Now Playing card whose slider knobs turn into lenses,
327
+ a lens you can drag over the photo), a dark version, and a Playground with
328
+ Figma's six Glass properties as controls. The calibration and measurement
329
+ tools moved to *Foundations / Liquid Glass / Lab*.
330
+
331
+ ## 0.4.1
332
+
333
+ **Liquid glass matches the Figma file.**
334
+
335
+ - **`tint` prop on `LiquidGlass`** — `"regular" | "clear" | "subtle" | "none"`.
336
+ `subtle` is Figma's `glass/bg-subtle` (5% ink; 8% white in dark), the fill of
337
+ a full-bleed overlay over a photo. Defaults to the variant's own tint.
338
+ - **One lens per variant.** `--liquid-refraction`, `-shift`, `-bezel`, `-profile`,
339
+ `-dispersion`, `-frost` and `-saturate` now have `-regular` and `-clear`
340
+ versions (Figma's two `liquid/*` effect styles), fitted against Figma's own
341
+ render. Set the unprefixed name on one element to override just that one.
342
+ - **Directional lens, rim and depth.** The bend, the rim light and the inner
343
+ shading follow `--liquid-light-angle` (Figma's light, -45 degrees), so the lit
344
+ edges differ from the far edges as in Figma. New `--liquid-shift-*`
345
+ and `--liquid-profile-*` tokens.
346
+ - **Figma's shadows** for both variants (`--liquid-shadow-regular|clear`) and
347
+ Figma's glass tint values (`.64 / .76 / .52`).
348
+ - **New `--surface-fg-muted` token** (solid, glass and liquid), and
349
+ `data-on-photo`: light text for any subtree that sits straight on a photo.
350
+ - Liquid scope defaults: the `Menu` is frosted, the active `SidebarItem` is flat
351
+ and `SidebarPromo` is transparent with an outlined button, so the dashboard
352
+ block no longer needs overrides for them.
353
+ - Known difference: Figma's clear lens samples *outside* the element at its lit
354
+ edges. CSS `backdrop-filter` cannot read outside its own box, so the clear
355
+ variant's rim is an approximation.
356
+
357
+ ## 0.4.0
358
+
359
+ **Glass and liquid glass.**
360
+
361
+ - **New theme axis: Surface (Solid · Glass · Liquid).** Components read
362
+ `--surface-*` tokens; `data-surface="glass" | "liquid" | "solid"` on any
363
+ ancestor re-themes everything inside it. Solid is pixel-identical to
364
+ before (checked story by story). Menus, modals and selects carry the
365
+ setting through their portals. `prefers-reduced-transparency` falls back
366
+ to opaque surfaces.
367
+ - **New: `LiquidGlass` and `useLiquidGlass`.** Apple-style liquid glass: an
368
+ SVG displacement filter bends the backdrop at the element's edge (with a
369
+ per-channel color fringe), plus tint, rim light, depth and a pointer-
370
+ following glare. Chromium renders the refraction; Safari and Firefox get
371
+ a frosted fallback with the same rim. Tunable through `--liquid-*` tokens
372
+ (tint, refraction, bezel, dispersion, frost, saturate, overlay and panel tints).
373
+ - **New block: `LiquidDashboardBlock`** (`@sakaniui/react/blocks`, Storybook
374
+ *Blocks / Application / Liquid Glass Dashboard*). A full dashboard on a
375
+ photo: one glass overlay, transparent chrome, solid data cards, an active
376
+ sidebar lens that only moves on click and a softer hover lens.
377
+ - Interaction polish: Switch spring, Slider fling bounce, chip/tag fade-out,
378
+ ListItem hover glide, ghost Button without shadow, Menu radius 8px,
379
+ `Switch` `description` prop, `bg/canvas` hover fill on surface components.
380
+ - Fix: the swatch checkmark could render invisible on light swatches in
381
+ server-rendered pages.
382
+
383
+ ## 0.3.5
384
+
385
+ - Replaces the Sakani mark (`PlaceholderLogo`'s default fill) with the new
386
+ logo, brand-orange background.
387
+ - Fix: `vite.lib.config.ts` has no `publicDir` override, so Vite's default
388
+ behaviour was copying this repo's `public/` folder into the published
389
+ package as a side effect — `dist/favicon.svg` shipped inside every install
390
+ of `@sakaniui/react` for no reason connected to the library itself. Still
391
+ ships (removing it isn't this release's job), but now carries the current
392
+ brand mark rather than a leftover unrelated asset.
393
+
394
+ ## 0.3.4
395
+
396
+ 0.3.3 was never actually published — a publish got stuck mid-flight on the
397
+ registry (staged but never finalized) and had to be abandoned rather than
398
+ retried, so this carries everything that would have shipped as 0.3.3:
399
+
400
+ - **Fix: `Popover` and `Modal` had no entrance/exit animation at all.** They
401
+ appeared and vanished on a single frame, unlike `Select` and `Combobox`,
402
+ which already ease their panels in and out. Both now animate over 180ms on
403
+ the same curve, kept mounted past `open` so the exit has something to play
404
+ on, and fall back to a timeout if `animationend` never fires (a
405
+ backgrounded tab, or anything suppressing animations) — without it, a
406
+ dismissed popover, or worse a full-screen modal backdrop, could be left
407
+ mounted and invisible over the page while still able to take focus.
408
+ - **Fix: charts read colour tokens from `document.documentElement`, ignoring
409
+ any `.dark`/`.force-light` scope between it and the chart.** A chart
410
+ rendered inside a themed container painted the *outer* theme's colours on
411
+ the *inner* theme's background. Tokens now resolve from the chart's own
412
+ element, and the reader re-renders when any ancestor's class changes, not
413
+ just `<html>`'s.
414
+ - **Fix: server-rendered charts never picked up real tokens at all.**
415
+ `useThemeTick` only bumped on theme *changes*; under SSR there is no
416
+ `getComputedStyle`, so a server-rendered chart kept its hardcoded fallback
417
+ colours forever once hydrated (React won't patch a hydration mismatch). It
418
+ now also bumps once on mount. Several of those fallbacks were themselves
419
+ stale values from an older palette and are corrected.
420
+ - **Fix: `Select`'s floating listbox and `Modal`'s backdrop ignored the
421
+ `.dark`/`.force-light` scope of whatever they were opened from.** Both
422
+ portal to `<body>` to position with `fixed`, which moves them out from
423
+ under any themed container; they now carry that container's theme class
424
+ onto the portaled element.
425
+ - `Table` gained a drag handle: a grip icon at the left edge of a
426
+ `reorderable` row, hidden until hover, and the sole drag origin (dragging
427
+ no longer starts from clicking anywhere in the row).
428
+ - `CRMDashboardBlock`, `KanbanBoardBlock` and `DataTableBlock` gained
429
+ `fillPlaceholders`, which extends the table to fill a taller container with
430
+ placeholder rows instead of leaving blank canvas below it.
431
+ - `Calendar` now exports its `DateRange` type.
432
+
433
+ ## 0.3.2
434
+
435
+ - **Fix: `@sakaniui/react/tokens.css` was never actually published.** The `exports` map pointed it at `./src/styles/tokens.css`, but `files: ["dist"]` only ever publishes the `dist` folder — so that path never existed in the installed package, and `import '@sakaniui/react/tokens.css'` (exactly as documented in the README) failed to resolve for every consumer. Without it, every component would have rendered completely unstyled: the CSS ships only the `var(--color-fg-default)` *references*, not the `:root { --color-fg-default: ... }` *definitions*. Fixed by copying `tokens.css` into `dist/` as part of the build and pointing the export there instead.
436
+
437
+ ## 0.3.1
438
+
439
+ - Fix: `Combobox`'s `loading` prop (the panel's loading state) was declared on `ComboboxOption` instead of `ComboboxProps`, so passing it to `<Combobox loading />` as documented was a type error and the prop was unreachable in a type-checked consumer. Moved to `ComboboxProps`, where the component was already reading it from at runtime.
440
+
441
+ ## 0.3.0
442
+
443
+ The library has grown substantially since the last published release —
444
+ five new categories of primitives and dozens of new blocks, all matching
445
+ their Figma source 1:1 and shipping with full light/dark support.
446
+
447
+ **New component categories:**
448
+ - **E-commerce** — Cart Item, Checkout Steps, Color Swatch, Price Display, Product Card, Product Gallery, Quantity Selector, Size Selector, Star Rating, Stock Status, Wishlist Button
449
+ - **Marketing** — Blog Blockquote, Blog Feature Text, Blog Image, Blog Listing Card, Blog Listing Featured Card, Featured Icon, First Page Heading, Job Listing, List, Location Dot, Marquee, Metric, Mobile Navigation Menu, Placeholder Logo, Profile Card, Rich Text Heading, Rich Text Paragraph, Section Heading, Sub Feature, Team Card
450
+
451
+ **New blocks:**
452
+ - **Authentication** — Email Verification, Forgot Password, Login, Reset Password, Sign Up, Two-Factor Authentication
453
+ - **Billing** — Add Card Form, Billing Address, Billing History, Current Plan, Payment Method
454
+ - **E-commerce** — Checkout Flow, Order Confirmation, Product Detail, Product Grid, Shopping Cart
455
+ - **Marketing** — Blog Listing, Careers, CTA Banner, FAQ, Feature Grid, Hero, Logo Cloud, Pricing Table, Team Section, Testimonial
456
+ - **Application** — Account Overview, Activity Log, App Header, Data Table + Toolbar, File Upload Panel, Form Modal, Inline CTA, Multistep Modal, Notification Panel, Onboarding Progress, Profile Settings, Section Footer
457
+
458
+ **Other:**
459
+ - `StarRating` gained a full `orientation` axis (horizontal / horizontal-reverse / vertical), shared between the E-commerce Product Detail block and Marketing's own Star Rating usage.
460
+ - Every component and block's Storybook Docs page now renders a real, written explanation (previously blank) — what it does, what it maps to in Figma, and key implementation notes, sourced from each component's own doc comments.
461
+ - The Storybook landing page now introduces the Sakani Design System itself instead of Storybook's generic default onboarding content.
462
+ - README's component/block inventory brought up to date with the actual library (114+ components, 41 blocks).
463
+
464
+ ## 0.2.0
465
+
466
+ - Blocks are now published from a separate subpath, `@sakaniui/react/blocks`, kept out of the main `@sakaniui/react` entry point so importing them is a deliberate choice.
467
+ - Added Funnel and Heatmap charts.
468
+ - The library now auto-builds (`prepare` script) on install.
469
+
470
+ ## 0.1.0
471
+
472
+ - First published release of `@sakaniui/react`.
package/README.md CHANGED
@@ -116,8 +116,17 @@ up instead of guessing prop names.
116
116
  Claude Code: `claude mcp add sakaniui -- npx -y -p @sakaniui/react sakaniui-mcp`
117
117
 
118
118
  Tools: `search_components`, `get_component`, `list_components`, `get_tokens`, `check_usage`
119
- (validates props against the contract) and `get_guide`. It runs locally, has no dependencies and
120
- answers from the installed version.
119
+ (validates props against the contract), `get_guide`, `check_compatibility` and `get_changelog`.
120
+
121
+ - **Read-only.** It reads four fixed files from a `@sakaniui/react` install (package.json, the
122
+ manifest, AGENTS.md, CHANGELOG.md). It writes nothing, runs nothing, opens no network connection and
123
+ takes no file paths. Every tool is marked read-only.
124
+ - **Matches your version.** It finds the `@sakaniui/react` installed in your project (working directory,
125
+ or `--project <dir>`) and flags components your version does not have yet, with the release notes for
126
+ the versions in between (`get_changelog`).
127
+ - **Accurate by construction.** `npm run build:lib` fails if the manifest disagrees with the real build:
128
+ an export that is not described, a prop that is not declared, a token that is not defined, or anything
129
+ that looks like a private reference.
121
130
 
122
131
  ## Glass & liquid glass
123
132