@clicktap/ui 2.0.3 → 2.0.5

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.
@@ -1 +1 @@
1
- "use client";import{jsxs as i,jsx as l}from"react/jsx-runtime";import{Option as p}from"../../Select/Option.js";import{Select as x}from"../../Select/Select.js";import{Button as h}from"../../Button/Button.js";import"../../../utils/cn.js";import{FilterIcon as d}from"../../Icon/FilterIcon.js";import"react-stately";import"react";import"../../Select/ButtonSelect.js";import"react-aria";import"@react-aria/interactions";import"../../Select/parts.js";import"react-aria-components";import"../../Select/ComboBoxSelect.js";import"../../Loader/Pulse.js";import"../../Select/MultiButtonSelect.js";function D({totalItems:o,startItem:s,endItem:r,setShowMobileFilters:m,availableSortOrders:a,appliedSortOrder:e,onSortChange:n}){const c=[...e?[e]:[],...a];return i("div",{className:"flex flex-col gap-y-5 mb-3",children:[i("div",{className:"flex items-center justify-between lg:justify-end gap-x-2",children:[i(h,{className:"lg:hidden grow-0 shrink-0 basis-auto gap-x-3 px-4",size:"sm",variant:"outline",onPress:()=>m(!0),"aria-details":"show filters",children:[l(d,{className:"w-3 h-3"}),"Filters"]}),l(x,{className:"w-44",selectedKey:e?`${e.code}_${e.direction}`:null,onSelectionChange:n,placeholder:"Sort by",label:"Sort By:",classNames:{input:"text-xs w-44 h-8 min-h-0",value:"text-xs",label:"hidden lg:block text-xs text-gray-600 whitespace-nowrap"},children:c.map(t=>l(p,{textValue:t.label,children:t.label},`${t.code}_${t.direction}`))})]}),o>0&&i("p",{className:"text-sm text-fg-muted",children:["Displaying ",s," - ",r," of ",o," items"]})]})}export{D as CollectionToolbar};
1
+ "use client";import{jsxs as i,jsx as l}from"react/jsx-runtime";import{Option as p}from"../../Select/Option.js";import{Select as x}from"../../Select/Select.js";import{Button as h}from"../../Button/Button.js";import"../../../utils/cn.js";import{FilterIcon as u}from"../../Icon/FilterIcon.js";import"react-stately";import"react";import"../../Select/ButtonSelect.js";import"react-aria";import"@react-aria/interactions";import"../../Select/parts.js";import"react-aria-components";import"../../Select/ComboBoxSelect.js";import"../../Loader/Pulse.js";import"../../Select/MultiButtonSelect.js";function D({totalItems:o,startItem:s,endItem:m,setShowMobileFilters:n,availableSortOrders:r,appliedSortOrder:e,onSortChange:a}){const c=[...e?[e]:[],...r];return i("div",{className:"flex flex-col gap-y-5 mb-3",children:[i("div",{className:"flex items-center justify-between lg:justify-end gap-x-2",children:[i(h,{className:"lg:hidden grow-0 shrink-0 basis-auto gap-x-3 px-4",size:"sm",variant:"outline",onPress:()=>n(!0),children:[l(u,{className:"w-3 h-3"}),"Filters"]}),l(x,{className:"w-44",selectedKey:e?`${e.code}_${e.direction}`:null,onSelectionChange:a,placeholder:"Sort by",label:"Sort By:",classNames:{input:"text-xs w-44 h-8 min-h-0",value:"text-xs",label:"hidden lg:block text-xs text-gray-600 whitespace-nowrap"},children:c.map(t=>l(p,{textValue:t.label,children:t.label},`${t.code}_${t.direction}`))})]}),o>0&&i("p",{className:"text-sm text-fg-muted",children:["Displaying ",s," - ",m," of ",o," items"]})]})}export{D as CollectionToolbar};
@@ -1 +1 @@
1
- "use client";import{jsx as c,jsxs as I,Fragment as R}from"react/jsx-runtime";import{Button as p}from"react-aria-components";import{cn as b}from"../../../utils/cn.js";import{CheckIcon as M}from"../../Icon/CheckIcon.js";import{isDevelopment as x}from"../../../utils/env.js";import{isValidHex as P,isVeryLight as j}from"../../../utils/color.js";import{isSwatchRenderer as y,SwatchRenderer as $,isValidImageUrl as _}from"../../../utils/swatch.js";function L(d){const s=new Map;for(const a of d)if("renderer"in a&&y(a.renderer)&&"options"in a)for(const r of a.options)r.swatch&&s.set(r.id,{...r.swatch,attributeCode:a.code,optionCode:r.code});return s}function T(d){const s=new Set;for(const a of d)if(a.simpleProduct?.saleability?.isSaleable!==!1)for(const r of a.attributes)s.add(`${r.attribute.code}:${r.option.code}`);return s}function V(d,s,a,r){const m=new Set,h=[];for(const l of d)for(const i of l.attributes){const f=s.get(i.option.id);f&&!m.has(i.option.id)&&a.has(i.attribute.code)&&(m.add(i.option.id),h.push({optionId:i.option.id,optionCode:f.optionCode,attributeCode:i.attribute.code,label:i.option.label,swatch:f,image:l.simpleProduct.image??null,isSaleable:r.has(`${i.attribute.code}:${i.option.code}`)}))}return h.sort((l,i)=>l.isSaleable===i.isSaleable?0:l.isSaleable?-1:1),h}function O({variants:d,availableFilters:s,attributeSwatchConfigs:a=[],matchedOptionIds:r,selectedOptionId:m,onSelect:h}){const l=new Map;for(const e of a)e.swatch?.listRenderer&&(x&&!y(e.swatch.listRenderer)&&console.warn(`[Swatch] Unknown listRenderer "${e.swatch.listRenderer}" for attribute "${e.code}" — skipping list swatches`),l.set(e.code,e.swatch.listRenderer));const i=L(s),f=T(d),u=V(d,i,l,f);if(u.length===0)return null;const U=new Set(u.map(e=>e.optionId)),k=r.find(e=>U.has(e)),N=m??k??u[0]?.optionId??null,S=u[0]?l.get(u[0].attributeCode)??null:null;return c("div",{className:"flex flex-row flex-wrap items-center gap-1.5 mt-1.5",children:u.map(e=>{const o=N===e.optionId,w=e.isSaleable?e.label:`${e.label} (out of stock)`;if(S===$.IMAGE)return c(p,{"aria-label":w,className:"cursor-pointer p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>c("span",{className:b("block w-8 aspect-[2.2/1] border bg-contain bg-center bg-no-repeat transition-all duration-150",o?"border-fg ring-1 ring-fg":"border-border-subtle",t&&!o&&"border-border-emphasis"),title:w,style:e.swatch.imageUrl?{backgroundImage:`url(${e.swatch.imageUrl})`}:void 0})},e.optionId);if(S===$.TEXT)return c(p,{"aria-label":w,className:"cursor-pointer p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>c("span",{className:b("inline-flex items-center px-1.5 py-0.5 text-[10px] font-medium border transition-colors duration-150",o?"bg-surface-inverse text-white border-fg":"bg-white text-slate-700 border-border",t&&!o&&"border-slate-500"),children:e.swatch.text??e.label})},e.optionId);const n=_(e.swatch.imageUrl),C=P(e.swatch.hex);if(!n&&!C){if(x){const t=[];e.swatch.hex&&!C&&t.push(`invalid hex "${e.swatch.hex}"`),e.swatch.imageUrl&&!n&&t.push(`invalid imageUrl "${e.swatch.imageUrl}"`),!e.swatch.hex&&!e.swatch.imageUrl&&t.push("missing hex and imageUrl"),console.warn(`[Swatch] Skipping list swatch for attribute "${e.attributeCode}" option "${e.optionCode}" — ${t.join("; ")}`)}return null}x&&e.swatch.imageUrl&&!n&&console.warn(`[Swatch] Falling back to SWATCH (hex) renderer for attribute "${e.attributeCode}" option "${e.optionCode}" — invalid imageUrl "${e.swatch.imageUrl}"`);const g=n?!1:j(e.swatch.hex??null),v=n?{backgroundImage:`url(${e.swatch.imageUrl})`}:{backgroundColor:e.swatch.hex??void 0};return c(p,{"aria-label":w,className:"cursor-pointer size-4 flex items-center justify-center p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>I("span",{className:b("relative inline-flex items-center justify-center size-4 rounded-full transition-all duration-150 overflow-hidden",n&&"bg-cover bg-center",n&&o&&"ring-2 ring-inset ring-white shadow-[0_0_0_2px_#222]",n&&t&&!o&&"ring-1 ring-border-emphasis",!n&&g&&"border border-border"),style:v,children:[!e.isSaleable&&I(R,{children:[c("span",{className:b("absolute top-1/2 left-1/2 w-[141%] h-[1.5px] -translate-x-1/2 -translate-y-1/2 -rotate-45",g?"bg-slate-400":"bg-white drop-shadow-sm",t&&!o&&"opacity-70")}),(o||t)&&c("span",{className:b("absolute top-1/2 left-1/2 w-[141%] h-[1.5px] -translate-x-1/2 -translate-y-1/2 rotate-45",g?"bg-slate-400":"bg-white drop-shadow-sm",t&&!o&&"opacity-70")})]}),!n&&e.isSaleable&&(o||t)&&c(M,{className:b("w-2.5 h-2.5 transition-opacity duration-150",g?"text-fg-subtle":"text-white drop-shadow-sm",t&&!o&&"opacity-70")})]})},e.optionId)})})}export{O as ProductCardSwatches};
1
+ "use client";import{jsx as c,jsxs as I,Fragment as R}from"react/jsx-runtime";import{Button as p}from"react-aria-components";import{cn as b}from"../../../utils/cn.js";import{CheckIcon as M}from"../../Icon/CheckIcon.js";import{isDevelopment as x}from"../../../utils/env.js";import{isValidHex as P,isVeryLight as j}from"../../../utils/color.js";import{isSwatchRenderer as y,SwatchRenderer as $,isValidImageUrl as _}from"../../../utils/swatch.js";function L(d){const s=new Map;for(const a of d)if("renderer"in a&&y(a.renderer)&&"options"in a)for(const r of a.options)r.swatch&&s.set(r.id,{...r.swatch,attributeCode:a.code,optionCode:r.code});return s}function T(d){const s=new Set;for(const a of d)if(a.simpleProduct?.saleability?.isSaleable!==!1)for(const r of a.attributes)s.add(`${r.attribute.code}:${r.option.code}`);return s}function V(d,s,a,r){const m=new Set,h=[];for(const l of d)for(const i of l.attributes){const f=s.get(i.option.id);f&&!m.has(i.option.id)&&a.has(i.attribute.code)&&(m.add(i.option.id),h.push({optionId:i.option.id,optionCode:f.optionCode,attributeCode:i.attribute.code,label:i.option.label,swatch:f,image:l.simpleProduct.image??null,isSaleable:r.has(`${i.attribute.code}:${i.option.code}`)}))}return h.sort((l,i)=>l.isSaleable===i.isSaleable?0:l.isSaleable?-1:1),h}function O({variants:d,availableFilters:s,attributeSwatchConfigs:a=[],matchedOptionIds:r,selectedOptionId:m,onSelect:h}){const l=new Map;for(const e of a)e.swatch?.listRenderer&&(x&&!y(e.swatch.listRenderer)&&console.warn(`[Swatch] Unknown listRenderer "${e.swatch.listRenderer}" for attribute "${e.code}" — skipping list swatches`),l.set(e.code,e.swatch.listRenderer));const i=L(s),f=T(d),u=V(d,i,l,f);if(u.length===0)return null;const U=new Set(u.map(e=>e.optionId)),k=r.find(e=>U.has(e)),N=m??k??u[0]?.optionId??null,S=u[0]?l.get(u[0].attributeCode)??null:null;return c("div",{className:"flex flex-row flex-wrap items-center gap-2 mt-1.5",children:u.map(e=>{const o=N===e.optionId,w=e.isSaleable?e.label:`${e.label} (out of stock)`;if(S===$.IMAGE)return c(p,{"aria-label":w,className:"cursor-pointer p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>c("span",{className:b("block w-8 aspect-[2.2/1] border bg-contain bg-center bg-no-repeat transition-all duration-150",o?"border-fg ring-1 ring-fg":"border-border-subtle",t&&!o&&"border-border-emphasis"),title:w,style:e.swatch.imageUrl?{backgroundImage:`url(${e.swatch.imageUrl})`}:void 0})},e.optionId);if(S===$.TEXT)return c(p,{"aria-label":w,className:"cursor-pointer p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>c("span",{className:b("inline-flex items-center px-1.5 py-0.5 text-[10px] font-medium border transition-colors duration-150",o?"bg-surface-inverse text-white border-fg":"bg-white text-slate-700 border-border",t&&!o&&"border-slate-500"),children:e.swatch.text??e.label})},e.optionId);const n=_(e.swatch.imageUrl),C=P(e.swatch.hex);if(!n&&!C){if(x){const t=[];e.swatch.hex&&!C&&t.push(`invalid hex "${e.swatch.hex}"`),e.swatch.imageUrl&&!n&&t.push(`invalid imageUrl "${e.swatch.imageUrl}"`),!e.swatch.hex&&!e.swatch.imageUrl&&t.push("missing hex and imageUrl"),console.warn(`[Swatch] Skipping list swatch for attribute "${e.attributeCode}" option "${e.optionCode}" — ${t.join("; ")}`)}return null}x&&e.swatch.imageUrl&&!n&&console.warn(`[Swatch] Falling back to SWATCH (hex) renderer for attribute "${e.attributeCode}" option "${e.optionCode}" — invalid imageUrl "${e.swatch.imageUrl}"`);const g=n?!1:j(e.swatch.hex??null),v=n?{backgroundImage:`url(${e.swatch.imageUrl})`}:{backgroundColor:e.swatch.hex??void 0};return c(p,{"aria-label":w,className:"cursor-pointer size-4 flex items-center justify-center p-0",onPress:()=>{h(e.optionId,e.optionCode,e.image,e.attributeCode)},children:({isHovered:t})=>I("span",{className:b("relative inline-flex items-center justify-center size-4 rounded-full transition-all duration-150 overflow-hidden",n&&"bg-cover bg-center",n&&o&&"ring-2 ring-inset ring-white shadow-[0_0_0_2px_#222]",n&&t&&!o&&"ring-1 ring-border-emphasis",!n&&g&&"border border-border"),style:v,children:[!e.isSaleable&&I(R,{children:[c("span",{className:b("absolute top-1/2 left-1/2 w-[141%] h-[1.5px] -translate-x-1/2 -translate-y-1/2 -rotate-45",g?"bg-slate-400":"bg-white drop-shadow-sm",t&&!o&&"opacity-70")}),(o||t)&&c("span",{className:b("absolute top-1/2 left-1/2 w-[141%] h-[1.5px] -translate-x-1/2 -translate-y-1/2 rotate-45",g?"bg-slate-400":"bg-white drop-shadow-sm",t&&!o&&"opacity-70")})]}),!n&&e.isSaleable&&(o||t)&&c(M,{className:b("w-2.5 h-2.5 transition-opacity duration-150",g?"text-fg-subtle":"text-white drop-shadow-sm",t&&!o&&"opacity-70")})]})},e.optionId)})})}export{O as ProductCardSwatches};
@@ -35,11 +35,38 @@ query text codegen started from.
35
35
 
36
36
  ## Migration
37
37
 
38
- 1. Switch codegen to string documents: `presetConfig`/`config` → `documentMode:
39
- 'string'` (client-preset ≥ 4 for `TypedDocumentString`), regenerate.
38
+ 1. Switch codegen to string documents. `documentMode: 'string'` goes under **`config`**, NOT
39
+ `presetConfig` — verified against `@graphql-codegen/client-preset` 4.8.3 and 6.1.3. Requires
40
+ client-preset >= 4 for `TypedDocumentString`. Regenerate.
41
+
42
+ ```ts
43
+ './generated/': {
44
+ preset: 'client',
45
+ presetConfig: { fragmentMasking: false },
46
+ config: { documentMode: 'string' }, // <- here
47
+ }
48
+ ```
49
+
50
+ **Verify the regeneration, because the wrong placement fails silently.** Under
51
+ `presetConfig`, codegen reports success and still emits AST documents — and since the new
52
+ client rejects an AST at runtime rather than at build time, both the build and the
53
+ typecheck stay green while every query goes out as the string `"[object Object]"`. A
54
+ consumer shipped exactly that and only caught it by counting emitted documents. After
55
+ regenerating, confirm the output contains `TypedDocumentString` and **zero**
56
+ `as unknown as DocumentNode`:
57
+
58
+ ```bash
59
+ grep -c 'TypedDocumentString' generated/graphql.ts # expect > 0
60
+ grep -c 'as unknown as DocumentNode' generated/graphql.ts # expect 0
61
+ ```
40
62
  2. Replace `TypedDocumentNode`/`RequestDocument` types at wrapper boundaries with
41
63
  `GraphqlDocument` / `GraphqlVariables` from this module; `GraphQLClientRequestHeaders`
42
64
  with the platform `HeadersInit`.
43
65
  3. Sites that imported `ClientError` from `graphql-request` import it from here.
44
- 4. A call that must send `FormData` or custom cors/credentials keeps using
45
- `createAuthAwareFetch()` (unchanged) and `String(document)` for the query text.
66
+ 4. Audit every site that turns a document into text itself, not just the `FormData` ones.
67
+ `createAuthAwareFetch()` is unchanged, and `String(document)` replaces `print(document)` —
68
+ but the class to search for is broader than uploads: **any hand-rolled
69
+ `fetch(url, { body: JSON.stringify({ query: print(Doc) }) })`**. A consumer found two
70
+ (`getCompanyCollection.ts`, `setCurrentCompanyCookie.ts`) that an inventory of upload call
71
+ sites did not anticipate, and they surfaced only after the codegen switch. Grep for
72
+ `print(` and for `from 'graphql'` across the app, not only for `FormData`.
@@ -22,16 +22,28 @@ base is react-aria-components; the rewrites cost nothing new:
22
22
  - **Pagination** → native boundary/sibling windowing.
23
23
  - **Badge** → the two wrapper elements, inline.
24
24
 
25
- ## Preserved API surface (inventoried from real call sites)
25
+ ## Same name, CHANGED signature — read this first
26
+
27
+ These kept their names, so a call site compiles, but the contract moved. A consumer had four
28
+ call sites break on props this document previously listed as simply preserved.
29
+
30
+ | Prop | Was (heroui) | Now |
31
+ | --- | --- | --- |
32
+ | `AccordionItem.onPress` | received a `PressEvent` | receives **no arguments**. A handler reading `e.target` type-checks anyway, because an extra declared parameter is accepted in some positions — it just gets `undefined` at runtime. |
33
+ | `Accordion.onSelectionChange` | could emit the string `'all'` | always emits `Set<string>`. A branch testing `keys === 'all'` is now dead code. |
34
+ | `Tooltip` `classNames.arrow` | slot existed | **removed** — the arrow is `OverlayArrow`; style it via `content`/`base` or the arrow element itself. |
35
+ | `Tooltip` `isOpen` | controlled open state | **not supported** — the RAC `TooltipTrigger` owns open state. Use `delay`/`isDisabled`, or drive visibility from the trigger. |
36
+
37
+ ## Same name, same behavior
26
38
 
27
39
  - Accordion: `selectionMode`, `defaultSelectedKeys` (incl. `"all"`),
28
- `defaultExpandedKeys`, controlled `selectedKeys` + `onSelectionChange`,
40
+ `defaultExpandedKeys`, controlled `selectedKeys`,
29
41
  `disallowEmptySelection`, `hideIndicator` (group and per-item),
30
42
  `showDivider`/`dividerProps` (an `<hr>` between items — `[&_hr]:hidden`
31
43
  keeps working), `itemClasses`/per-item `classNames` slots, per-item
32
44
  `title`/`subtitle`/`startContent`/`indicator` (a component still receives
33
45
  `{ isOpen }` — import `AccordionItemIndicatorProps` from HERE now),
34
- `disableIndicatorAnimation`, `onPress`, and the `data-open` attribute on
46
+ `disableIndicatorAnimation`, and the `data-open` attribute on
35
47
  heading/trigger/indicator that `data-[open=true]:` selectors style.
36
48
  - Tooltip: `content`, `offset`, `placement`, `showArrow`, `delay`,
37
49
  `isDisabled`, `classNames.base/content`, arbitrary child as trigger.
@@ -0,0 +1,28 @@
1
+ # CollectionToolbar and ProductCardSwatches Accessibility Fixes
2
+
3
+ **Date:** 2026-08-22
4
+ **Package:** `@clicktap/ui`
5
+ **Affects:** `Collection/CollectionToolbar`, `Collection/ProductCardSwatches`
6
+ **Classification:** BUGFIX (accessibility)
7
+ **Breaking:** No. Visual change is 2px of extra gap between card swatches.
8
+ **Ticket:** CTAP-1380
9
+
10
+ ## Changes
11
+
12
+ **`CollectionToolbar` — invalid `aria-details` removed.** The mobile filter button carried
13
+ `aria-details="show filters"`. `aria-details` takes an **ID reference**, not text, so axe
14
+ flags the value as invalid (`aria-valid-attr-value`). The button already has a visible
15
+ "Filters" label, so the attribute was redundant too.
16
+
17
+ **`ProductCardSwatches` — swatch spacing meets WCAG 2.5.8.** The swatches are 16px, under
18
+ the 24px minimum target size. The standard's spacing exception allows a smaller target
19
+ when no neighbouring target falls inside a 24px-diameter circle centred on it — centres
20
+ at least 24px apart. The row used `gap-1.5` (6px), leaving centres 22px apart, so every
21
+ swatch failed `target-size` (37 elements on a single collection page). Now `gap-2` (8px),
22
+ which puts centres at exactly 24px. The swatches themselves are unchanged.
23
+
24
+ ## What to check
25
+
26
+ Swatch rows are 2px wider per gap — confirm no wrapping regression at the narrowest
27
+ breakpoint. Consumers overriding the swatch container's spacing should re-check they
28
+ still satisfy the 24px centre-to-centre rule.
@@ -38,6 +38,25 @@ reference app pins the identical versions. When bumping, take the trio from the
38
38
  react-aria release announcement and re-run the production-bundle checks below —
39
39
  aligning to the coherent set fixed the Table failure outright with no code change.
40
40
 
41
+ ## If you still depend on `@heroui/*`, pinning is not enough
42
+
43
+ `@clicktap/ui` 2.x dropped heroui, so this case is invisible upstream — but a fork still carrying
44
+ it will install **both** trios no matter what it pins. heroui drags the old set in transitively:
45
+
46
+ ```
47
+ @heroui/badge -> @heroui/system -> @react-spectrum/provider -> @adobe/react-spectrum
48
+ -> react-aria-components (old)
49
+ ```
50
+
51
+ A consumer pinned one release *above* the verified set and ended up with two full trios and six
52
+ `@react-aria/*` subpackages at two versions each — precisely the skew this guide warns is invisible
53
+ outside production bundles. Aligning **down** to the verified set unified them.
54
+
55
+ So: pin to the verified set exactly (not "at least"), and if the duplicate persists, the remaining
56
+ copy is being pulled by a heroui/react-spectrum branch. Check with the instance-directory diff
57
+ below — and note that removing heroui is the only complete fix, since its transitive floor is not
58
+ something a pin can override.
59
+
41
60
  ## How to verify (jsdom cannot)
42
61
 
43
62
  Probe a production build in a real browser: open an uncontrolled DialogTrigger modal
@@ -10,6 +10,16 @@
10
10
  "affects": "every consumer of react-aria-components — dependency policy, not an API change",
11
11
  "read_before_updating": "never bump `react-aria`, `react-aria-components`, or `react-stately` independently — skewed internals fail silently, and only in production bundles."
12
12
  },
13
+ {
14
+ "path": "2026/08/ui-2026-08-22-collection-accessibility-fixes.md",
15
+ "module": "libs/frontend-modules/ui",
16
+ "package": "@clicktap/ui",
17
+ "date": "2026-08-22",
18
+ "title": "CollectionToolbar and ProductCardSwatches Accessibility Fixes",
19
+ "classification": "BUGFIX (accessibility)",
20
+ "breaking": "No. Visual change is 2px of extra gap between card swatches.",
21
+ "affects": "`Collection/CollectionToolbar`, `Collection/ProductCardSwatches`"
22
+ },
13
23
  {
14
24
  "path": "2026/08/ui-2026-08-22-accordion-divider-class-ownership.md",
15
25
  "module": "libs/frontend-modules/ui",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicktap/ui",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "private": false,
5
5
  "author": "Clicktap",
6
6
  "description": "A library of React UI components and low-level hooks.",