pixelize-design-library 2.4.1-beta.1 → 2.4.1-beta.2

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.
Files changed (70) hide show
  1. package/.cursor/modules/account-management/MODULE.md +8 -1
  2. package/.cursor/modules/feedback/MODULE.md +6 -0
  3. package/.cursor/modules/inputs-date-file/MODULE.md +12 -1
  4. package/.cursor/modules/inputs-select/MODULE.md +64 -2
  5. package/.cursor/modules/inputs-toggle/MODULE.md +6 -0
  6. package/.cursor/modules/layout-navigation/MODULE.md +55 -5
  7. package/.cursor/modules/overlays/MODULE.md +29 -16
  8. package/.cursor/modules/table/MODULE.md +6 -0
  9. package/.cursor/modules/theme/MODULE.md +117 -0
  10. package/dist/Assets/defaultLogo.d.ts.map +1 -1
  11. package/dist/Assets/defaultLogo.js +1 -3
  12. package/dist/Assets/defaultLogo.tsx +4 -8
  13. package/dist/Components/DatePicker/CalendarPanel.d.ts.map +1 -1
  14. package/dist/Components/DatePicker/CalendarPanel.js +12 -3
  15. package/dist/Components/DatePicker/SingleDatePicker.d.ts.map +1 -1
  16. package/dist/Components/DatePicker/SingleDatePicker.js +11 -9
  17. package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -2
  18. package/dist/Components/DatePicker/TimePicker.d.ts.map +1 -1
  19. package/dist/Components/DatePicker/TimePicker.js +14 -2
  20. package/dist/Components/DatePicker/TimePickerInput.d.ts.map +1 -1
  21. package/dist/Components/DatePicker/TimePickerInput.js +9 -1
  22. package/dist/Components/SelectV2/SelectV2.d.ts +3 -0
  23. package/dist/Components/SelectV2/SelectV2.d.ts.map +1 -0
  24. package/dist/Components/SelectV2/SelectV2.js +185 -0
  25. package/dist/Components/SelectV2/SelectV2Props.d.ts +67 -0
  26. package/dist/Components/SelectV2/SelectV2Props.d.ts.map +1 -0
  27. package/dist/Components/SelectV2/SelectV2Props.js +2 -0
  28. package/dist/Components/SideBar/SideBar.js +1 -1
  29. package/dist/Components/WorkspaceWindow/WorkspaceTrayPreview.js +2 -1
  30. package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts +2 -2
  31. package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts.map +1 -1
  32. package/dist/Components/WorkspaceWindow/WorkspaceWindow.js +25 -4
  33. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts +18 -0
  34. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts.map +1 -1
  35. package/dist/Theme/chakra/Avatar.styles.d.ts +33 -0
  36. package/dist/Theme/chakra/Avatar.styles.d.ts.map +1 -0
  37. package/dist/Theme/chakra/Avatar.styles.js +28 -0
  38. package/dist/Theme/chakra/Drawer.styles.d.ts +32 -0
  39. package/dist/Theme/chakra/Drawer.styles.d.ts.map +1 -0
  40. package/dist/Theme/chakra/Drawer.styles.js +26 -0
  41. package/dist/Theme/chakra/Menu.styles.d.ts +70 -0
  42. package/dist/Theme/chakra/Menu.styles.d.ts.map +1 -0
  43. package/dist/Theme/chakra/Menu.styles.js +50 -0
  44. package/dist/Theme/chakra/Modal.styles.d.ts +32 -0
  45. package/dist/Theme/chakra/Modal.styles.d.ts.map +1 -0
  46. package/dist/Theme/chakra/Modal.styles.js +26 -0
  47. package/dist/Theme/chakra/Popover.styles.d.ts +37 -0
  48. package/dist/Theme/chakra/Popover.styles.d.ts.map +1 -0
  49. package/dist/Theme/chakra/Popover.styles.js +30 -0
  50. package/dist/Theme/chakra/Slider.styles.d.ts +31 -0
  51. package/dist/Theme/chakra/Slider.styles.d.ts.map +1 -0
  52. package/dist/Theme/chakra/Slider.styles.js +25 -0
  53. package/dist/Theme/chakra/Switch.styles.d.ts +31 -0
  54. package/dist/Theme/chakra/Switch.styles.d.ts.map +1 -0
  55. package/dist/Theme/chakra/Switch.styles.js +24 -0
  56. package/dist/Theme/chakra/Tabs.styles.d.ts +43 -0
  57. package/dist/Theme/chakra/Tabs.styles.d.ts.map +1 -0
  58. package/dist/Theme/chakra/Tabs.styles.js +41 -0
  59. package/dist/Theme/chakra/componentStyles.d.ts +228 -1
  60. package/dist/Theme/chakra/componentStyles.d.ts.map +1 -1
  61. package/dist/Theme/chakra/componentStyles.js +62 -0
  62. package/dist/Theme/provider/PixelizeThemeProvider.d.ts +11 -1
  63. package/dist/Theme/provider/PixelizeThemeProvider.d.ts.map +1 -1
  64. package/dist/Theme/provider/PixelizeThemeProvider.js +35 -2
  65. package/dist/Theme/provider/ThemeSwitcher.d.ts.map +1 -1
  66. package/dist/Theme/provider/ThemeSwitcher.js +23 -11
  67. package/dist/index.d.ts +3 -1
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4 -2
  70. package/package.json +1 -1
@@ -22,9 +22,16 @@ Account/admin-facing components: UserDetails, RolesPermission, CustomModulesTabl
22
22
  - `surface` reads `background[50]`, never `colors.white` — white is a foreground token and stays white in dark
23
23
  - Remaining hex literals are `??` fallbacks, not live values: a hand-built palette may omit rungs (tests `jest.mock` a partial one), so keep the fallback when adding a token read
24
24
  - Fixed by design, not palette-following: `avatarColor()`'s `AVATAR_COLORS` (OrgSwitcher — deterministic identity fill seeded by org name, white label on top) and `UpgradeButton`'s `iconColor` default (icon on a gradient fill). Colored fills/foregrounds, not canvas surfaces
25
- - **OrgSwitcher popover bg bug (same class as the ButtonGroupIcon menu bug in `buttons`):** `PopoverContent` had no `bg=`, so it fell through to Chakra's baseStyle `var(--popper-bg)` — hardcoded to `colors.white`, gated behind Chakra's own `_dark` which this app's palette-swap dark mode never triggers — rendering a white popover in dark mode regardless of theme. Fixed with an explicit `bg={theme.colors.backgroundColor.light}`
25
+ - **OrgSwitcher popover bg bug (same class as the ButtonGroupIcon menu bug in `buttons`):** `PopoverContent` had no `bg=`, so it fell through to Chakra's baseStyle `var(--popper-bg)` — hardcoded to `colors.white`, gated behind Chakra's own `_dark` which this app's palette-swap dark mode never triggers — rendering a white popover in dark mode regardless of theme. Fixed with an explicit `bg={theme.colors.backgroundColor.light}`; now also covered app-wide by the theme-level `Popover` style override (`Theme/chakra/Popover.styles.ts`, overlays module / theme module Wave H)
26
26
  - OrgSwitcher trigger border: `borderColor` switched from `gray[200]` to `boxborder?.[800] ?? gray[200]` — it styles a real `<button>`, so its border is a control boundary needing WCAG 1.4.11 (>=3.0 non-text contrast) against any surface up to `muted`, which `gray[200]` failed in dark. Org name/role text switched from `gray[800]`/`gray[500]` to `text[900]`/`text[500]` — mode-adaptive text tokens, the correct choice over mode-invariant gray literals for body text
27
27
  - UserDetails avatar initials color: replaced the fixed `primary[600]` rung with `accentTextOnCanvas(colors.primary, avatarBg)` (guarded `colors?.primary ? accentTextOnCanvas(...) : "#4F46E5"` fallback) — picks contrast dynamically against the avatar bg instead of assuming one fixed rung clears AA 4.5 for every brand's dark palette
28
+ - **Avatar badge/container ring bug (theme-level fix):** Chakra's own `Avatar` baseStyle
29
+ hardcodes the badge/container cutout border to `colors.white` (a ring meant to match the
30
+ surface the avatar sits on), behind `_dark`, same never-triggered gate as Modal/Menu — every
31
+ bare `<Avatar>`/`<AvatarBadge>` (used here in `UserDetails`, `OrgSwitcher`,
32
+ `OrganizationDetails`, plus `NavigationBar`/`Notification`/`SelectSearch` elsewhere) rendered a
33
+ white ring on the dark canvas. Fixed centrally in `Theme/chakra/Avatar.styles.ts` (registered
34
+ in `componentStyles.ts`), not per-component.
28
35
  - **Modal surface bug (QA-caught, blocking) — 6 action modals:** `AddUserModal`,
29
36
  `DeactivateConfirmModal`, `ChangeRoleModal` (UserDetails), `DeleteRoleModal` (RolesPermission),
30
37
  `CreateOrgModal`, `DeleteOrgModal` (OrganizationDetails) all rendered a raw Chakra `ModalContent`
@@ -15,6 +15,12 @@ Loading, Skeletons, ProgressBar, Notification, FeedbackForm.
15
15
 
16
16
  ## Dark mode
17
17
 
18
+ - **Skeleton** (`Components/Skeletons/`) — Chakra's own baseStyle hardcodes
19
+ `--skeleton-start-color`/`--skeleton-end-color` to `gray.100`/`gray.400` behind `_dark`, same
20
+ never-triggered gate as Modal/Menu (theme module). Fixed centrally in `componentStyles.ts`
21
+ (`Skeleton` entry, rungs `gray[100]`/`gray[300]`) rather than in `Skeletons.tsx` — a
22
+ caller-supplied `startColor`/`endColor` prop still wins exactly as before; this only supplies
23
+ the default the base style already owns.
18
24
  - **Notification**: default `bgColor` switched `theme.colors.white` → `theme.colors.background[50]`
19
25
  — `white` is a foreground token (label ink, stays white in dark) and was being used as the card
20
26
  surface; `background[50]` is the correct dark-mode-aware white-surface token. Real bug fix (was
@@ -12,7 +12,8 @@ ThemeDatePicker (Single/Range/Time variants), FileUpload, FileUploader, Editor (
12
12
  ## Key rules
13
13
 
14
14
  - DatePicker themed for brand tokens — `CalendarPanel` reads every color from `useCustomTheme()` (no hex literals), so it follows the active light/dark palette automatically.
15
- - The month/year `<select>` uses `colors.background[50]`, not `colors.white`: it is a white *surface* and must darken in dark mode. The one remaining `colors.white` (day label on the filled `primary[500]` circle — selected / range start / range end) is a *foreground* and correctly stays white. Don't "fix" it.
15
+ - The month/year `<select>` uses `colors.background[50]`, not `colors.white`: it is a white *surface* and must darken in dark mode.
16
+ - **Selected-day circle WCAG contrast (user-reported, fixed) — supersedes prior guidance below.** The filled day circle (selected / range start / range end) hardcoded `colors.white` text on `primary[500]`/`[600]` regardless of brand — the same class of gap `Button.styles.ts`'s solid variant already accounts for (white doesn't reliably clear AA against every brand's `[500]`, e.g. emerald/rosewood in dark, ~3.38/3.46). A previous pass here called this hardcoded white "correctly a foreground token, don't fix it" — that was wrong for the fill-contrast case specifically; foreground-vs-surface only tells you whether a token *inverts with mode*, not whether it *clears contrast against the fill it sits on*. Fixed via `onFilled(fill, theme.colors.white, theme.colors.black)` (`Theme/tokens/builders/accentText`) for both resting (`primary[500]`) and hover (`primary[600]`) fills.
16
17
  - **Calendar/time popover surface bug (user-reported, blocking):** `SingleDatePicker.tsx`, `RangeDatePicker.tsx`, `TimeOnlyPicker.tsx`, and the legacy `DatePicker.tsx` (still reachable — consumed directly by `Table/filters/LeftFilterPane.tsx`, not just via the unused commented-out playground import) each rendered a `PopoverContent` with no explicit `bg=` — the same Chakra-hardcoded-`colors.white`-behind-`_dark` bug as `Modal`/`AlertDialog`/`Drawer` (overlays module). Because `CalendarPanel`'s day/weekday text (`text[700]`/`gray[400]`/`gray[500]`) is computed against the *intended* dark canvas, the panel rendered on Chakra's un-migrated white default while its text was tuned for a dark background — producing exactly the washed-out, near-invisible day numbers reported. Fixed with `bg={theme.colors.background[50]}` on all four `PopoverContent`s (`TimeOnlyPicker.tsx` didn't previously call `useCustomTheme()` at all — added the hook). Verified live via Playwright across all four variants (date-only, date+time, range, time-only).
17
18
  - **FileUploader (QA-caught)** — its file-count and "Click here" text hardcoded `color="blue.500"`/
18
19
  `"blue.400"`, which fail AA against the component's canvas (same class as the Notification
@@ -47,6 +48,16 @@ ThemeDatePicker (Single/Range/Time variants), FileUpload, FileUploader, Editor (
47
48
  `.jodit-dialog_theme_dark` already hardcode `--jd-color-border: #6b6b6b` themselves (a Jodit-owned
48
49
  override we can't/don't need to touch), so this fix only had to cover panel/input backgrounds and
49
50
  the hover fill. Regression tests added to `joditThemeVars.test.ts`.
51
+ - **Date/time input control-boundary + surface pass (this session):** `SingleDatePicker`'s text
52
+ input, `TimePicker`'s hour/minute/AM-PM `<Select>`s, and `TimePickerInput`'s input all gained an
53
+ explicit `bg={theme.colors.gray?.[50]}` (was inheriting the ambient/transparent default) and
54
+ `borderColor={theme.colors.boxborder?.[800]}` (was `undefined`/unset outside the error state) —
55
+ same WCAG 1.4.11 control-boundary standard already applied to `MultiSelect`/`Select.styles`/
56
+ `SelectSearch` (see `inputs-select` MODULE.md). Hover now also resolves to
57
+ `theme.colors.primary[500]` (was `undefined`, i.e. no hover feedback at all) to match the
58
+ existing `_focus` treatment. `TimeOnlyPicker`'s footer divider `borderColor` switched from the
59
+ raw Chakra literal `gray.200` to the token `theme.colors.boxborder?.[300]`. `TimePicker` didn't
60
+ previously call `useCustomTheme()` — added the hook.
50
61
  - Masked-input blur must not discard a valid value. `isMaskComplete()` only recognises numeric/`a` tokens, so text month formats (e.g. `MMM d, yyyy`) never look "complete" — `handleInputBlur`/`handleInputFocus` therefore keep any value that `parseValidatedValue()` can parse to a valid date, and only `requestClose(null)` (clear) on empty/unparseable input. The Clear button and emptied-mask paths remain the explicit ways to clear. Regression: `SingleDatePicker.blur.test.tsx`.
51
62
 
52
63
  ## Migration notes
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- Select, SearchSelect, SelectSearch, MultiSelect, Dropdown, Search.
5
+ Select, SelectV2, SearchSelect, SelectSearch, MultiSelect, Dropdown, Search.
6
6
 
7
7
  ## Key paths
8
8
 
9
- - `src/Components/Select/`, `SearchSelect/`, `SelectSearch/`, `MultiSelect/`, `Dropdown/`, `Search/`
9
+ - `src/Components/Select/`, `SelectV2/`, `SearchSelect/`, `SelectSearch/`, `MultiSelect/`, `Dropdown/`, `Search/`
10
10
 
11
11
  ## Key rules
12
12
 
@@ -25,3 +25,65 @@ SearchSelect and SelectSearch source every color from `useCustomTheme()` or a pa
25
25
  - Control borders (`MultiSelect`, `Select.styles`, `SelectSearch`) bumped `boxborder` step [500]/[700] to **[800]**: WCAG 1.4.11 needs a 3:1 contrast ratio against any named surface up to `muted` (lightest) — [500]/[700] failed there, [800] clears all with margin (see inline comments at each call site)
26
26
  - Known behavior change: SearchSelect's inside-select placeholder text dropped the `theme.colors.placeholder?.[500] ?? theme.colors.gray[500]` fallback for a flat `theme.colors.gray[500]` — still a valid token, but only the lavender brand defines a distinct `placeholder` scale (other brands inherit it via spread), so lavender's placeholder text loses its tint and now renders plain gray
27
27
  - SearchSelect's "Remove All" tooltip dropped its explicit `bg`/`color` overrides, now rendering with ToolTip's own default styling instead of a forced `gray[600]`/`white`
28
+
29
+ ## SelectV2 — custom-popup dropdown (additive, new)
30
+
31
+ **Why it exists:** the existing `Select` (`src/Components/Select/`) wraps Chakra's `<Select>`, which
32
+ renders a **real native `<select>`/`<option>`** — the closed field is themeable, but the open dropdown
33
+ popup is painted by the browser's own UA stylesheet, not React. That means it can never get custom
34
+ option rendering, hover states beyond OS defaults, or type-ahead filtering — the popup is architecturally
35
+ outside Chakra/React's control (same class of gap as the native `color-scheme` bug documented in the
36
+ theme MODULE.md, Wave H). `SelectV2` is a MUI-style alternative: a fully React-rendered popup, so every
37
+ visual state (hover, selected, focus, disabled) is themeable via `useCustomTheme()`.
38
+
39
+ **This is purely additive.** `Select.tsx`/`SelectProps.ts`/`Select.styles.ts` were not touched — existing
40
+ consumer apps see **zero behavior change** on upgrading `pixelize-design-library`, whether or not they
41
+ ever adopt `SelectV2`. New work should prefer `SelectV2`; old call sites can keep using `Select`
42
+ indefinitely, with no forced migration.
43
+
44
+ - **Path:** `src/Components/SelectV2/` — `SelectV2.tsx`, `SelectV2Props.ts`, `SelectV2.test.tsx`.
45
+ - **Built from existing primitives only** — Chakra `Popover`/`PopoverTrigger`/`PopoverContent` (already
46
+ globally dark-mode-patched via `Theme/chakra/Popover.styles.ts`, Wave H) plus plain React state. No new
47
+ dependency added (no react-select/downshift/MUI) — bundle size and dependency surface are unchanged for
48
+ every consumer.
49
+ - **Prop shape mirrors `Select`** for easy future migration: `options: {id, label}[]`, `value`,
50
+ `onChange(option | undefined)`, `placeholder`, `label`, `error`, `errorMessage`, `helperText`,
51
+ `isDisabled`, `isRequired`, `size` (`sm`/`md`/`lg`, same px/height scale as `Select.styles.ts`). Not
52
+ identical — e.g. no `variant`/`colorScheme` passthrough — since it isn't a drop-in wrapper.
53
+ - **`data-testid`** is forwarded to the trigger button (same element as `role="combobox"`), so a
54
+ `Select` call site's existing `getByTestId(...)` query keeps working after switching to `SelectV2`.
55
+ - **Multi-select** via `isMulti` (discriminated union in `SelectV2Props`): `value` becomes
56
+ `(string|number)[]`, `onChange` receives the full `OptionProp[]` selection, each row renders a checkbox,
57
+ and the popup stays open across picks (`resetAndClose` skips closing on `isMulti`). Trigger shows the
58
+ joined labels, or `"N selected"` past `maxLabelsBeforeSummary` (default 2).
59
+ - **Custom option/row/trigger content**: `option.icon` + `option.description` give a built-in
60
+ icon+label+description row layout with no extra work; `renderOption(option, {isSelected, isActive})`
61
+ takes full control of a row (badges, avatars, arbitrary JSX) when that's not enough; `renderValue(selected)`
62
+ does the same for the trigger's content. All optional — omit for the original plain-text behavior.
63
+ - **`defaultOpen`**: opens the popover immediately on mount instead of waiting for a click — for
64
+ inline-edit patterns (a table cell that swaps to a select the instant it becomes editable, replacing a
65
+ native `<select autoFocus>`). Click-away still closes it via `Popover`'s own close-on-blur, firing `onBlur`.
66
+ - **Type-ahead filtering** built in (`isSearchable`, defaults `true`): a text input at the top of the
67
+ popup filters `options` client-side by substring match on `label`. Set `isSearchable={false}` to hide
68
+ it (still fully keyboard-navigable without it).
69
+ - **Keyboard/ARIA:** trigger is `role="combobox"` with `aria-haspopup="listbox"`/`aria-expanded`/
70
+ `aria-controls`; popup list is `role="listbox"` with `role="option"`/`aria-selected` items. ArrowDown/
71
+ ArrowUp move the active option (wraps at both ends), Enter selects, Escape closes without selecting,
72
+ Tab closes and lets focus move on. Reuses Chakra's `Popover` focus/outside-click handling rather than
73
+ reimplementing it.
74
+ - **Styling:** trigger box uses `Components/Common/fieldStyles.ts`'s `getFieldStateStyles()` — the same
75
+ shared border/focus/error visual standard as `Select`, `SearchSelect`, `MultiSelect` — so a `SelectV2`
76
+ sits visually consistent next to any of them. Popup surface/list follow the same token conventions as
77
+ `Dropdown`'s portaled menu (`background[50]`, `boxborder[200]`, `primary.opacity[8]` hover).
78
+ - **Known gap / fast-follow:** no virtualization — fine for typical option-list sizes (tens to low
79
+ hundreds); for very large lists prefer `SearchSelect`, which already has performance tests and
80
+ virtualizes.
81
+ - **Popup clipped inside `overflow:hidden` ancestors (user-reported, fixed).** `PopoverContent` wasn't
82
+ wrapped in Chakra's `<Portal>`, so it rendered inline in the DOM — any ancestor with
83
+ `overflow: hidden` (e.g. the library's own `Card variant="elevated"`, used throughout consumer
84
+ apps' settings/detail pages) visually clipped the open popup to whatever space was left below the
85
+ trigger. Symptom looked like a filtering bug (a 3-option list showing only the first option by
86
+ default, but showing correctly once typed down to 1 match) when it was actually the same content
87
+ height fitting inside the clipped region either way — the filter never changed. `Dropdown` and
88
+ `SearchSelect` already portal their menus for exactly this reason (see "Key rules" above); `SelectV2`
89
+ now does too.
@@ -16,3 +16,9 @@ Checkbox, RadioButton, Switch, Slider, Toggle/TableToggle.
16
16
 
17
17
  - `Checkbox`: label tooltip now uses the shared `ToolTip` component instead of raw Chakra `Tooltip` with hardcoded `gray[600]`/`white` — `ToolTip` resolves a dark-mode-aware surface itself.
18
18
  - `Toggle/TableToggle`: selected-tab label color changed from `theme.colors.black` (mode-invariant) to `theme.colors.text[900]` (mode-adaptive). Real bug fix: `black` was rendered on `background[50]`, which is near-black in dark mode — black-on-near-black was invisible; `text[900]` flips to near-white in dark mode.
19
+ - **`Slider`/`Switch` thumb bug (theme-level fix):** Chakra's own thumb baseStyle for both
20
+ hardcodes `bg: "white"` with **no** `_dark` gate at all (unlike most other components in this
21
+ sweep), so every bare `<SliderThumb>`/`<Switch>` rendered a literal white circle/knob on the
22
+ dark canvas regardless of mode. Fixed centrally in `Theme/chakra/Slider.styles.ts` and
23
+ `Switch.styles.ts` (registered in `componentStyles.ts`), each overriding the thumb part's `bg`
24
+ to `theme.colors.backgroundColor?.light ?? theme.colors.background?.[50]`.
@@ -26,6 +26,32 @@ WorkspaceWindow shell, WorkspaceTrayPreview popover).
26
26
  `WorkspaceWindow` calls `useCustomTheme()` **before** its `state === "minimized"` early
27
27
  return — after it, hook order would change when the window reopens.
28
28
 
29
+ **First real consumer: tickets (user-reported dark-mode gaps + first adoption).** `WorkspaceWindow`/
30
+ `WorkspaceTray`/`WorkspaceTrayPreview` existed but had no consumer yet; tickets' own hand-rolled
31
+ floating-ticket-window/tray/hover-preview (`core/workspace/`) was migrated onto these, and the
32
+ migration surfaced real gaps the "dark-mode checked" note above didn't cover — the control-bar
33
+ `bg="gray.50"`/`borderColor="gray.100"`/title `color="gray.700"` and the tray pill's
34
+ `bg/color/borderColor="blue.100/700/200"` were still **hardcoded literals**, not
35
+ `useCustomTheme()` tokens, so they didn't actually follow brand/dark-mode. Fixed to
36
+ `theme.colors.background?.[100]`/`boxborder?.[200]`/`text?.[700]` (window chrome, same pattern as
37
+ `AiLauncher`) and `theme.colors.primary?.[100/700/200]` (tray pill, matching tickets' own prior
38
+ token usage). `WorkspaceTrayPreview`'s card wrapper had the same gap (`borderColor="gray.200"`,
39
+ `color="gray.800"`) — same fix.
40
+ - **`onOverlayClick?: () => void`** added to `WorkspaceWindowProps` — with `size="full"` the
41
+ transparent `ModalContent` covers the viewport so Chakra's own `closeOnOverlayClick` never fires;
42
+ the parent needs its own "clicked the blurred backdrop" signal (tickets uses it to minimize
43
+ rather than close, preserving unsaved edits). `WorkspaceWindow` detects this itself
44
+ (`onMouseDown` + `e.target === e.currentTarget` on `ModalContent`) and also exposes
45
+ `${testId}-backdrop`.
46
+ - **`renderItem?: (item, {restore, close}) => ReactNode`** added to `WorkspaceTrayProps` — full
47
+ override for one tray item's pill markup, for a consumer that needs to wrap the pill in its own
48
+ logic (tickets wraps it in a ticket-fetching hover preview, `TrayTabPreview`) while still reusing
49
+ the tray's positioned/wrap-reverse container. Omit it for the plain built-in pill.
50
+ - Tickets' `TrayTabPreview` now delegates the hover-bridge timer/positioning entirely to
51
+ `WorkspaceTrayPreview` (`onOpenChange` gates the ticket fetch) and only supplies the ticket-specific
52
+ `preview` content — the timer/placement logic that used to be duplicated in the app is gone from
53
+ there now.
54
+
29
55
  ### Header, NavigationBar, FilterSidebar — WCAG/dark pass
30
56
 
31
57
  - **Header.tsx** — default (no explicit `colors` prop) styling changed: `bg` now
@@ -44,7 +70,9 @@ return — after it, hook order would change when the window reopens.
44
70
  `secondary[500]`). Its profile/account `MenuList` also sets
45
71
  `sx={{ "--menu-bg": theme.colors.backgroundColor.light }}` — same Chakra CSS-var fix as
46
72
  `ButtonGroupIcon` (buttons module): Chakra's `MenuItem` baseStyle hardcodes `--menu-bg` to
47
- white, gated behind `_dark`, which this app's theme-swap dark mode never triggers.
73
+ white, gated behind `_dark`, which this app's theme-swap dark mode never triggers. Now also
74
+ covered app-wide by the theme-level `Menu` style override (`Theme/chakra/Menu.styles.ts`, theme
75
+ module Wave G) — this per-call-site `sx` is redundant but harmless alongside it.
48
76
  - **FilterSidebar.tsx** — section-label tooltip swapped from raw Chakra `Tooltip` (hardcoded
49
77
  `bg={gray[600]}`/`color={white}`) to the library's `ToolTip` (token-driven); search-input
50
78
  `borderColor` now `theme.colors.boxborder?.[800] ?? gray[200]` — plain `gray[200]` fails
@@ -67,10 +95,12 @@ return — after it, hook order would change when the window reopens.
67
95
  The submenu row's label ink also switched from static `text[800]` (tuned for the `background[50]`
68
96
  canvas, not the `activeBg` fill the active row switches to) to `onFilled(activeBg, white, black)`,
69
97
  which is provably >=4.5 against any fill regardless of which rung `pickActiveAccent` picks.
70
- - **Drawer.tsx (QA-caught, blocking)**same `ModalContent` surface bug as `Modal`/`AlertDialog`
71
- (overlays module): `DrawerContent` had no explicit `bg=`, so it fell through to Chakra's
72
- hardcoded `colors.white` baseStyle, gated behind a `_dark` this app's theme-swap dark mode
73
- never triggers. Fixed with `bg={colors?.background?.[50]}`.
98
+ - **Drawer.tsx surface bugnow fixed at the theme level.** Same bug class as `Modal`/
99
+ `AlertDialog` (overlays module): Chakra's own `Drawer` baseStyle hardcodes `--drawer-bg` to
100
+ `colors.white` on the `dialog` part, gated behind a `_dark` this app's theme-swap dark mode
101
+ never triggers. Fixed centrally in `Theme/chakra/Drawer.styles.ts` (registered as `Drawer` in
102
+ `componentStyles.ts`), mirroring `Modal.styles.ts` — covers every `DrawerContent` app-wide. An
103
+ earlier pass's per-call-site `bg={colors?.background?.[50]}` fix is now redundant but harmless.
74
104
  - **FilterSidebar.tsx WCAG pass (Wave D, QA-driven)** — two real AA/graphical-object failures
75
105
  found beyond the surface bug above: the min/max price selected-row checkmark icon (`red[600]`
76
106
  on its own `red[100]` fill, ≈2.89:1, fails the 3:1 non-text bar) now uses
@@ -163,6 +193,26 @@ Regression tests: `sidebarAccentColors.test.ts` (lavender + rosewood) — light
163
193
  dark mode pins the light-mode rung (not the dark-inverted one), contrast ≥3:1 (icon) / ≥4.5:1
164
194
  (label) against the sidebar canvas, graceful fallback when `brand` is unknown.
165
195
 
196
+ ### SideBar default logo — hardcoded black fill invisible on dark-`primary[500]` brands (user-reported, fixed)
197
+
198
+ `SidebarHeader`'s fallback mark (no `logo` prop passed) wraps `Assets/defaultLogo.tsx` in a `Box`
199
+ with `bg={theme.colors.primary[500]}` + `color={theme.colors.white}` — but the SVG paths inside
200
+ `DefaultLogo` hardcoded `fill={theme.colors.black}` instead of inheriting that `color`. Most brands'
201
+ `primary[500]` is a mid-tone hue, so a black mark still read against it by accident; **zinc**'s
202
+ `primary[500]` is `#18181b` (near-black by design — see zinc's palette comment), so the black-on-
203
+ near-black logo was effectively invisible. Fixed by switching all three paths to `fill="currentColor"`
204
+ so the mark always matches whatever `color` its wrapper sets, regardless of brand — `DefaultLogo` no
205
+ longer needs `useCustomTheme()` at all.
206
+
207
+ That alone wasn't sufficient: the wrapper `Box` itself hardcoded `color={theme.colors.white}`
208
+ regardless of mode. Zinc **inverts** its dark palette — `primary[500]` is `#18181b` in light but
209
+ `#e4e4e7` (near-white) in dark — so a hardcoded-white icon on a hardcoded-white-in-dark-mode fill
210
+ went invisible again, this time in dark mode. Fixed with the same `onFilled(fill, white, black)`
211
+ WCAG-pick helper already used for the calendar's selected-day circle and `Button.styles.ts`'s solid
212
+ variant: `color={onFilled(theme.colors.primary[500], theme.colors.white, theme.colors.black)}`. Any
213
+ future "icon on a `primary[500]` fill" spot should use this same helper rather than assuming white
214
+ always clears — zinc dark is the proof case that it doesn't.
215
+
166
216
  ### Known gap — Header "Login" demo button (raw Chakra, wrong-canvas ghost ink)
167
217
 
168
218
  `Layout.tsx`'s `/header` playground route renders its `rightSlot` demo content with a **raw**
@@ -35,25 +35,30 @@ Toaster and ToolTip take all color from the theme (`useTheme()` / `useCustomThem
35
35
  so they follow the active light/dark palette; remaining hex literals are only `??`
36
36
  fallbacks for when no Pixelize palette is in context.
37
37
 
38
- - **Modal/AlertDialog surface bug (QA-caught, blocking):** `ModalContent`/`AlertDialogContent`
39
- had no explicit `bg=`, so both fell through to Chakra's own `baseStyle`, which hardcodes
40
- `[$bg.variable]: "colors.white"` gated behind `_dark` — this app's theme-swap dark mode
41
- (palette swapped, Chakra `colorMode` stays `"light"`) never triggers that `_dark` block, so
42
- every Modal/AlertDialog rendered a white panel with near-invisible text on the dark canvas.
43
- Same bug class as the `ButtonGroupIcon` menu-bg bug (buttons) and the `OrgSwitcher` popover
44
- bug (account-management) Chakra part-styles that hardcode a literal instead of reading a
45
- semantic token. `Card` was unaffected because it already used the patched
46
- `chakra-body-bg`/`chakra-body-text` semantic tokens (see theme module); Modal/AlertDialog
47
- bypass that layer entirely. Fixed with an explicit `bg={colors?.background?.[50]}` on both.
48
- `AlertDialog` has no separate Chakra theme key (it reuses Chakra's `Modal` style config
49
- internally), but still needed its own prop-level fix since this app's fix is component-level,
50
- not a Chakra `components.Modal` theme-config override.
38
+ - **Modal/AlertDialog surface bug — now fixed at the theme level, not per-component.**
39
+ Chakra's own `Modal` baseStyle hardcodes `[$bg.variable]: "colors.white"` on the `dialog`
40
+ part, gated behind `_dark` — this app's theme-swap dark mode (palette swapped, Chakra
41
+ `colorMode` stays `"light"`) never triggers that block, so every `ModalContent` rendered a
42
+ white panel with near-invisible text on the dark canvas. `AlertDialog` reuses Chakra's
43
+ `Modal` style config internally, so it inherits the same fix with no separate theme key.
44
+ Fixed centrally in `Theme/chakra/Modal.styles.ts` (`definePartsStyle` on the `dialog` part,
45
+ registered as `Modal` in `componentStyles.ts`) mirrors `Menu.styles.ts`/`Drawer.styles.ts`.
46
+ A prior pass fixed this per-call-site with an explicit `bg=` prop; that approach is
47
+ superseded by this theme-level override, which covers every `ModalContent`/`AlertDialogContent`
48
+ app-wide with zero per-call-site changes (an explicit `bg=` still wins if a caller sets one).
49
+ - **Popover surface bug** same bug class, fixed in `Theme/chakra/Popover.styles.ts`
50
+ (`--popper-bg` + `--popper-arrow-shadow-color`, registered as `Popover` in
51
+ `componentStyles.ts`) — see theme module Wave H. Every bare `<PopoverContent>` in the
52
+ library (this module doesn't own a dedicated Popover component folder — Popover is used
53
+ directly from Chakra by many components, e.g. `OrgSwitcher`, `MoreItems`, `SideBar`,
54
+ `DatePicker`) now gets a dark-aware surface for free.
51
55
 
52
56
  ## Dark mode — Modal/AlertDialog consumers
53
57
 
54
- `Drawer` (layout-navigation module) has the identical fix. Every other file in the library that
55
- renders a raw Chakra `ModalContent` needed the same explicit `bg=` — see the account-management,
56
- table, and cards MODULE.md sections for the specific consumer components fixed in this pass.
58
+ `Drawer` (layout-navigation module) has the identical theme-level fix (`Drawer.styles.ts`). Many
59
+ consumer components (see account-management, table, cards MODULE.md) additionally carry an
60
+ explicit per-call-site `bg=` from an earlier pass, predating the theme-level `Modal`/`Drawer`
61
+ style overrides above — now redundant but harmless (an explicit prop still wins, same value).
57
62
  `WorkspaceWindow` (layout-navigation) was checked and is **not** affected: its `ModalContent` is
58
63
  deliberately `bg="transparent"` with an inner `Box bg={theme.colors.background[50]}` as the real
59
64
  surface.
@@ -67,3 +72,11 @@ surface.
67
72
  passes through un-inverted (`sidebar: light.sidebar`), so it stays near-black in
68
73
  dark and the label stays legible; any other surface ramp would flip light and
69
74
  render the white label invisible. Callers overriding `bg` own that contrast.
75
+ - **Chakra's raw `Tooltip` baseStyle** hardcodes `--tooltip-bg`/`--tooltip-fg` to
76
+ `gray.700`/`whiteAlpha.900` behind `_dark`, same never-triggered gate — our reversed dark
77
+ gray ramp makes `gray.700` LIGHT, so a bare (non-`ToolTip`) Chakra `<Tooltip>` renders
78
+ near-white-on-near-white. Fixed with a `Tooltip` entry in `componentStyles.ts` pinning both
79
+ vars to `black`/`white` — the two tokens `buildDarkPalette` never remaps, so the chip stays a
80
+ stable dark-bg/white-text pair in both modes. This library's own `ToolTip` above already sets
81
+ its own `bg`/`color` explicitly and is unaffected; the fix targets consumer apps that render a
82
+ raw Chakra `Tooltip` directly instead of this component.
@@ -69,6 +69,12 @@ active palette: `Table` (pagination popover), `TableBody` (expanded-row panel),
69
69
  (`table.hover[300]`, same as before). Regression tests: `tableRowHoverStyle.test.ts` (lavender +
70
70
  rosewood). Scoped to the per-cell hover mechanism already in place — not restructured to a
71
71
  `<Tr>`-level highlight, since that wasn't the reported defect.
72
+ - **`TableSettings.tsx` enclosed-tab "cutout" bug (theme-level fix):** Chakra's own `Tabs`
73
+ baseStyle hardcodes the selected tab's cutout color to `colors.white` for the `enclosed`
74
+ (selected border) and `enclosed-colored` (selected background) variants, both behind `_dark`,
75
+ same never-triggered gate. `TableSettings.tsx` is this library's only consumer of Chakra's raw
76
+ `TabList`/`TabPanels`. Fixed centrally in `Theme/chakra/Tabs.styles.ts` (registered in
77
+ `componentStyles.ts`), overriding both variants' selected-tab cutout token.
72
78
  - **Known gap (found by code review, not fixed this pass):** `Table/filters/CompactSelect.tsx`,
73
79
  `Table/filters/TableFilters.tsx`, and `Table/components/TableActions.tsx` each render a raw
74
80
  Chakra `PopoverContent` with no `bg=` — the identical bug class just fixed in `Table.tsx`'s
@@ -296,6 +296,123 @@ shared-shape/shared-role values that would require restructuring the 10-step ram
296
296
  cross-brand `roles/bg.surface` mapping, not a zinc-only anchor swap — out of scope for a
297
297
  change scoped to "don't break anything."
298
298
 
299
+ **2026-07-20 — `PixelizeThemeProvider` gained an optional `themeOverrides` prop.** Found while
300
+ wiring dark mode into the **tickets** consumer app: it has its own font-stack/compact-control-size/
301
+ component-defaultProps customizations layered onto the brand theme (the old `withTheme(app, theme)`
302
+ pattern spread these onto `ThemesList[brand]` directly), and `PixelizeThemeProvider` had no
303
+ equivalent injection point — its internal `ChakraProvider` is hardcoded to
304
+ `brandThemes[brand][resolvedMode]`. Without this, every consumer app with its own theme
305
+ customizations would have had to build the same workaround (mount its own second `ChakraProvider`
306
+ inside the provider's tree, shadowing the internal one). `themeOverrides?: Record<string, unknown>`
307
+ is deep-merged via `extendTheme(brandThemes[brand][resolvedMode], themeOverrides)`, re-computed
308
+ whenever `brand`/`resolvedMode`/`themeOverrides` change so overrides always layer onto the *current*
309
+ palette. Safe post-resolution: `createBrandTheme` already fixes `config.initialColorMode` to
310
+ `"light"` on every palette, and `extendTheme` is a pure additive merge that doesn't re-derive
311
+ `_dark:` blocks — so this cannot reintroduce the double-adaptation bug the forced light
312
+ `colorModeManager` avoids. Optional, defaults to `undefined` — zero behavior change for existing
313
+ consumers that don't pass it.
314
+
315
+ **2026-07-20 — `PixelizeThemeProvider` re-syncs `brandState` when the `brand` prop changes post-mount.**
316
+ `brandProp` previously only seeded initial state (`useState(brandProp)`), so a consumer that
317
+ re-renders with a new `brand` after mount (e.g. persisting the pick through its own Redux store
318
+ instead of calling this provider's own `setBrand`) never saw it applied — the same gap `mode`
319
+ already had, worked around elsewhere by callers mirroring it in an effect. Fixed with a `useEffect`
320
+ on `brandProp` (skipping the first run, so it doesn't fight the rehydrate-from-storage effect) that
321
+ calls `setBrandState(brandProp)` only when the **prop itself** changes — not on every local
322
+ `setBrand()` call, so it doesn't fight the user's own in-session `ThemeSwitcher` picking.
323
+
324
+ **2026-07-20 — `ThemeSwitcher`'s brand menus gained a color swatch dot per brand.** `BrandMenu`
325
+ (icon variant) and `MenuVariant`'s brand submenu both previously showed only the brand name text.
326
+ Each option now renders a small (`0.625rem`) filled circle before the label, colored from that
327
+ brand's own `colors.primary[500]` in **light** mode (`brandThemes[brand].light...primary[500]`) —
328
+ always the light-mode anchor regardless of the switcher's current mode, so the dot is a stable
329
+ brand identifier rather than something that itself flips with dark mode. `ThemeSwitcher.tsx` also
330
+ stopped re-deriving `menuBg`/pushing it back via `sx` on every render (`useSwitcherColors()`) now
331
+ that `Menu.styles.ts` (Wave G) supplies `--menu-bg` centrally — removes a redundant Emotion style
332
+ recompute per render that showed up as flicker while hovering/scrolling the brand list.
333
+
334
+ ## Wave G — global `Menu` component style override (`--menu-bg`), found while auditing tickets
335
+
336
+ Same bug class as Wave E's `ThemeSwitcher` fix, but at the root instead of per-call-site: Chakra's
337
+ own `Menu` baseStyle hardcodes the `--menu-bg` CSS var to `"#fff"` (gated behind `_dark`, which this
338
+ app's theme-swap never triggers — `PixelizeThemeProvider`'s forced-light `colorModeManager`, Wave D
339
+ above). Every **bare** `<MenuList>` in every consuming app (tickets' board overflow menu,
340
+ `TicketOptionMenu`, rows-per-page menu, etc.) rendered a white dropdown on a dark canvas, and a
341
+ call-site `bg=` prop alone doesn't fix it — that only recolors the list's own box, not the CSS var
342
+ `MenuItem`'s `_focus`/`_active`/`_expanded` states read.
343
+
344
+ Added `src/Theme/chakra/Menu.styles.ts` (new file, registered in `componentStyles.ts`): a
345
+ `definePartsStyle` override on the `list` anatomy part that sets `--menu-bg` (via `cssVar`) to
346
+ `theme.colors.backgroundColor?.light ?? theme.colors.background?.[50] ?? "#fff"` and `color` to
347
+ `theme.colors.text?.[900]`. This fixes every consumer's bare `MenuList` app-wide with zero
348
+ per-call-site changes — `ThemeSwitcher`'s existing manual `bg=`/`sx={{"--menu-bg": ...}}` workaround
349
+ (Wave E) still works alongside it (an explicit call-site override still wins), it's just no longer
350
+ required for a plain `<MenuList>`. Verified: `tsc --noEmit` clean, lint clean, full `jest` suite
351
+ 905/905 (72 suites, up from 902/72 pre-fix — 3 new but this pass added no dedicated `Menu.styles`
352
+ test, the count reflects unrelated in-flight suite growth).
353
+
354
+ ## Wave H — `Popover`/`Skeleton` component-style overrides + native UI `color-scheme`, same audit as Wave G
355
+
356
+ Same bug class as Wave G's `Menu` fix, found while sweeping the rest of Chakra's own component
357
+ themes for the identical `_dark`-gated hardcoded-white pattern — plus one new bug *class* (native
358
+ browser chrome) the earlier waves never covered.
359
+
360
+ - **`Popover`** — Chakra's own Popover baseStyle hardcodes `--popper-bg` to `"colors.white"` and
361
+ `--popper-arrow-shadow-color` to `"colors.gray.200"`, both gated behind `_dark` (confirmed by
362
+ reading `@chakra-ui/theme`'s `popover.mjs` source directly — `content` is the anatomy part that
363
+ owns both vars; `--popper-arrow-bg` is untouched because Chakra's own baseStyle already points it
364
+ at `$popperBg`, so fixing `$popperBg` fixes the arrow fill for free). Every bare
365
+ `<PopoverContent>` rendered a white card with a light arrow shadow on the dark canvas. Added
366
+ `src/Theme/chakra/Popover.styles.ts` (new file, registered in `componentStyles.ts`) mirroring
367
+ `Menu.styles.ts` exactly: `createMultiStyleConfigHelpers(popoverAnatomy.keys)` +
368
+ `definePartsStyle` on the `content` part, `[$popperBg.variable]` sourced from
369
+ `theme.colors.backgroundColor?.light ?? theme.colors.background?.[50] ?? "#fff"` (identical
370
+ fallback chain to Menu) and `[$arrowShadowColor.variable]` from `theme.colors.border?.[200]`.
371
+ - **`Skeleton`** — Chakra's own Skeleton baseStyle hardcodes `--skeleton-start-color`/
372
+ `--skeleton-end-color` to `colors.gray.100`/`colors.gray.400`, same `_dark`-gated pattern.
373
+ Verified in `@chakra-ui/react`'s actual `skeleton.mjs` that Chakra's `Skeleton` is a
374
+ **single-part** style config (`defineStyleConfig`, not a multi-part anatomy like Menu/Popover),
375
+ and that its `startColor`/`endColor` are **props**, not style-config keys — but those props only
376
+ ever populate the same two CSS vars when a caller actually passes them (`useToken("colors", ["",
377
+ ""])` resolves to `undefined`, so `cssVarStyles` stays empty and the base style's vars pass
378
+ through untouched). That confirms Chakra's own prop-vs-style precedence already does the right
379
+ thing, so the fix was made at the `componentStyles.ts` level (a `Skeleton: ComponentStyleConfig`
380
+ entry, same file as `Badge`/`FormError`) rather than touching `Components/Skeletons/Skeletons.tsx`
381
+ — zero risk to the existing prop passthrough there; a caller-supplied `startColor`/`endColor`
382
+ still wins exactly as before. Rungs: `gray[100]`/`gray[300]` — `buildDarkPalette.ts`'s `gray`
383
+ ramp is already role-reversed for dark mode (low rungs go dark, high rungs go light there), so
384
+ the same two rung indices read as a light shimmer in light mode and a subtle dark-on-dark shimmer
385
+ in dark mode with no mode branching needed in the override itself.
386
+ - **`color-scheme` CSS property (new bug class)** — native browser UI (the `<select>` popup
387
+ chrome, the `<input type="date">` calendar picker) is painted by the browser's own UA stylesheet
388
+ keyed off the CSS `color-scheme` property, entirely outside Chakra/React theming — no component
389
+ style or palette swap can reach it, which is why this wasn't caught by any earlier wave's
390
+ component-by-component audit. Neither repo set it anywhere, so that native chrome always rendered
391
+ light regardless of the app's resolved mode. Fixed in `PixelizeThemeProvider.tsx` with a
392
+ `useEffect` that sets `document.documentElement.style.colorScheme = resolvedMode` whenever
393
+ `resolvedMode` changes. Scoped to the provider (not a global stylesheet or index.css rule) so
394
+ `withTheme` consumers — deliberately light-only per this doc's "Key rules" — see no change;
395
+ only `PixelizeThemeProvider`/`useThemeMode` consumers get mode-aware native chrome.
396
+ - Full gate green: `tsc --noEmit` clean, lint clean, `jest` 905/905 (72 suites, unchanged from
397
+ pre-Wave-H — no new dedicated test file added for these three, consistent with Wave G's Menu fix
398
+ which also shipped without one).
399
+
400
+ ## Wave I — remaining `_dark`-gated component overrides (Modal/Drawer/Avatar/Tabs/Slider/Switch/Tooltip)
401
+
402
+ Completes the Wave G/H sweep: every other Chakra component whose own baseStyle hardcodes a
403
+ literal behind the never-triggered `_dark` gate (or, for Slider/Switch, no gate at all), fixed
404
+ the same way — a `definePartsStyle`/`ComponentStyleConfig` override registered in
405
+ `componentStyles.ts`, sourcing color from `theme.colors.backgroundColor?.light ?? theme.colors
406
+ .background?.[50]` (or the relevant token) instead of Chakra's literal. See each domain
407
+ MODULE.md for the consumer-facing detail: `Modal`/`Drawer` (overlays, layout-navigation —
408
+ supersedes those modules' earlier per-call-site `bg=` fixes), `Avatar` (account-management),
409
+ `Tabs` (table), `Slider`/`Switch` (inputs-toggle), `Tooltip`/`Skeleton` (overlays, feedback —
410
+ `Tooltip` pins `black`/`white`, the two tokens `buildDarkPalette` never remaps, since a tooltip
411
+ must stay a stable dark chip in either mode rather than following the canvas).
412
+ `componentStyles.ts` now registers 10 chakra-native theme keys total (`Drawer`, `Menu`, `Modal`,
413
+ `Popover`, `Slider`, `Switch`, `Tabs`, `Avatar`, `Skeleton`, `Tooltip`) alongside the library's
414
+ own `Checkbox`/`Input`/`Button`/`Badge`/`FormError`/etc.
415
+
299
416
  ## Known gaps
300
417
 
301
418
  - `KanbanBoard.tsx` uses `var(--chakra-colors-gray-300)`, but `cssVarPrefix` is `"ck"` — that
@@ -1 +1 @@
1
- {"version":3,"file":"defaultLogo.d.ts","sourceRoot":"","sources":["../../src/Assets/defaultLogo.tsx"],"names":[],"mappings":"AAEA,QAAA,MAAM,WAAW,+CAyBhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"defaultLogo.d.ts","sourceRoot":"","sources":["../../src/Assets/defaultLogo.tsx"],"names":[],"mappings":"AAAA,QAAA,MAAM,WAAW,+CAuBhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("react/jsx-runtime");
4
- const useCustomTheme_1 = require("../Theme/useCustomTheme");
5
4
  const DefaultLogo = () => {
6
- const theme = (0, useCustomTheme_1.useCustomTheme)();
7
- return ((0, jsx_runtime_1.jsxs)("svg", { width: "12.09", height: "15.95", viewBox: "0 0 31 29", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M30.4999 6.26137V7.81058H15.9761H14.8787V22.8508V28.8862H12.5226C9.6824 28.8862 7.32632 26.4656 7.06812 23.3995C7.06812 23.2381 7.06812 23.0444 7.06812 22.8508V18.3323C7.06812 18.2677 7.06812 18.2032 7.06812 18.1063V15.5889V6.2291C7.06812 2.80793 9.84378 -5.72205e-06 13.2972 -5.72205e-06H24.8517C28.0147 0.355021 30.4676 3.00158 30.4676 6.2291L30.4999 6.26137Z", fill: theme.colors.black }), (0, jsx_runtime_1.jsx)("path", { d: "M7.10053 23.3672H7.03598C5.16402 23.2381 3.48571 22.4635 2.25926 21.3338C0.871428 20.0428 0 18.2677 0 16.3312V15.6211H7.06825V18.1386C7.06825 18.2032 7.06825 18.2677 7.06825 18.3645V22.883C7.06825 23.0767 7.06825 23.2381 7.06825 23.4317L7.10053 23.3672Z", fill: theme.colors.black }), (0, jsx_runtime_1.jsx)("path", { d: "M30.4678 12.0063V15.6211V17.1703C30.4678 20.6238 26.272 23.3994 21.0757 23.3994H14.8789V22.8508V15.6211H22.6572V7.81056C22.6895 7.81056 30.5001 7.81056 30.5001 7.81056V11.5868C30.5001 11.7159 30.5001 11.8772 30.5001 12.0063H30.4678Z", fill: theme.colors.black })] }));
5
+ return ((0, jsx_runtime_1.jsxs)("svg", { width: "12.09", height: "15.95", viewBox: "0 0 31 29", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M30.4999 6.26137V7.81058H15.9761H14.8787V22.8508V28.8862H12.5226C9.6824 28.8862 7.32632 26.4656 7.06812 23.3995C7.06812 23.2381 7.06812 23.0444 7.06812 22.8508V18.3323C7.06812 18.2677 7.06812 18.2032 7.06812 18.1063V15.5889V6.2291C7.06812 2.80793 9.84378 -5.72205e-06 13.2972 -5.72205e-06H24.8517C28.0147 0.355021 30.4676 3.00158 30.4676 6.2291L30.4999 6.26137Z", fill: "currentColor" }), (0, jsx_runtime_1.jsx)("path", { d: "M7.10053 23.3672H7.03598C5.16402 23.2381 3.48571 22.4635 2.25926 21.3338C0.871428 20.0428 0 18.2677 0 16.3312V15.6211H7.06825V18.1386C7.06825 18.2032 7.06825 18.2677 7.06825 18.3645V22.883C7.06825 23.0767 7.06825 23.2381 7.06825 23.4317L7.10053 23.3672Z", fill: "currentColor" }), (0, jsx_runtime_1.jsx)("path", { d: "M30.4678 12.0063V15.6211V17.1703C30.4678 20.6238 26.272 23.3994 21.0757 23.3994H14.8789V22.8508V15.6211H22.6572V7.81056C22.6895 7.81056 30.5001 7.81056 30.5001 7.81056V11.5868C30.5001 11.7159 30.5001 11.8772 30.5001 12.0063H30.4678Z", fill: "currentColor" })] }));
8
6
  };
9
7
  exports.default = DefaultLogo;
@@ -1,7 +1,4 @@
1
- import { useCustomTheme } from "../Theme/useCustomTheme";
2
-
3
1
  const DefaultLogo = () => {
4
- const theme = useCustomTheme();
5
2
  return (
6
3
  <svg
7
4
  width="12.09"
@@ -12,19 +9,18 @@ const DefaultLogo = () => {
12
9
  >
13
10
  <path
14
11
  d="M30.4999 6.26137V7.81058H15.9761H14.8787V22.8508V28.8862H12.5226C9.6824 28.8862 7.32632 26.4656 7.06812 23.3995C7.06812 23.2381 7.06812 23.0444 7.06812 22.8508V18.3323C7.06812 18.2677 7.06812 18.2032 7.06812 18.1063V15.5889V6.2291C7.06812 2.80793 9.84378 -5.72205e-06 13.2972 -5.72205e-06H24.8517C28.0147 0.355021 30.4676 3.00158 30.4676 6.2291L30.4999 6.26137Z"
15
- fill={theme.colors.black}
12
+ fill="currentColor"
16
13
  />
17
14
  <path
18
15
  d="M7.10053 23.3672H7.03598C5.16402 23.2381 3.48571 22.4635 2.25926 21.3338C0.871428 20.0428 0 18.2677 0 16.3312V15.6211H7.06825V18.1386C7.06825 18.2032 7.06825 18.2677 7.06825 18.3645V22.883C7.06825 23.0767 7.06825 23.2381 7.06825 23.4317L7.10053 23.3672Z"
19
- fill={theme.colors.black}
16
+ fill="currentColor"
20
17
  />
21
18
  <path
22
19
  d="M30.4678 12.0063V15.6211V17.1703C30.4678 20.6238 26.272 23.3994 21.0757 23.3994H14.8789V22.8508V15.6211H22.6572V7.81056C22.6895 7.81056 30.5001 7.81056 30.5001 7.81056V11.5868C30.5001 11.7159 30.5001 11.8772 30.5001 12.0063H30.4678Z"
23
- fill={theme.colors.black}
20
+ fill="currentColor"
24
21
  />
25
22
  </svg>
26
-
27
- )
23
+ );
28
24
  };
29
25
 
30
26
  export default DefaultLogo;
@@ -1 +1 @@
1
- {"version":3,"file":"CalendarPanel.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/CalendarPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,IAAI,CAAC;IACnB,eAAe,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC;IACzD,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACvC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC;IAE/B,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA8QtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"CalendarPanel.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/CalendarPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,IAAI,CAAC;IACnB,eAAe,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC;IACzD,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IACvC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC;IAE/B,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsRtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -10,6 +10,7 @@ const date_fns_1 = require("date-fns");
10
10
  const lucide_react_1 = require("lucide-react");
11
11
  const Button_1 = __importDefault(require("../Button/Button"));
12
12
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
13
+ const accentText_1 = require("../../Theme/tokens/builders/accentText");
13
14
  const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate, tempRangeStart, tempRangeEnd, isSameDay, isBefore, isAfter, minDate, maxDate, disablePastDates, disableFutureDates, disableToday, onDaySelect, hoveredDate, onDayHover, renderWeekdays, }) => {
14
15
  var _a;
15
16
  const theme = (0, useCustomTheme_1.useCustomTheme)();
@@ -86,11 +87,19 @@ const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate
86
87
  else if (isEnd)
87
88
  cellBg = `linear-gradient(to right, ${rangeBg} 50%, transparent 50%)`;
88
89
  }
90
+ // Solid fill (selected/range-endpoint) needs the ink checked against that
91
+ // specific fill — `primary[500]` doesn't reliably clear AA for white text on
92
+ // every brand/mode (same gap the solid Button variant already accounts for).
93
+ const solidFill = theme.colors.primary[500];
94
+ const solidHoverFill = theme.colors.primary[600];
89
95
  const circleColor = circleSolid
90
- ? theme.colors.white
96
+ ? (0, accentText_1.onFilled)(solidFill, theme.colors.white, theme.colors.black)
91
97
  : isInCurrentMonth
92
98
  ? theme.colors.text[700]
93
99
  : theme.colors.gray[400];
100
+ const circleHoverColor = circleSolid
101
+ ? (0, accentText_1.onFilled)(solidHoverFill, theme.colors.white, theme.colors.black)
102
+ : circleColor;
94
103
  const circleBorder = circleSolid
95
104
  ? "1px solid transparent"
96
105
  : isTentativeEnd
@@ -98,10 +107,10 @@ const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate
98
107
  : isToday
99
108
  ? `1px solid ${theme.colors.primary[300]}`
100
109
  : "1px solid transparent";
101
- days.push((0, jsx_runtime_1.jsx)(react_1.Box, { h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: (0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", disabled: disabled, onClick: () => !disabled && onDaySelect(new Date(thisDay)), onMouseEnter: () => !disabled && (onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(new Date(thisDay))), w: "1.75rem", h: "1.75rem", borderRadius: "full", display: "flex", alignItems: "center", justifyContent: "center", fontSize: "0.8125rem", fontWeight: circleSolid ? 600 : 500, lineHeight: "1", cursor: disabled ? "not-allowed" : "pointer", bg: circleSolid ? theme.colors.primary[500] : "transparent", color: circleColor, border: circleBorder, transition: "background 0.12s, color 0.12s", _hover: disabled
110
+ days.push((0, jsx_runtime_1.jsx)(react_1.Box, { h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: (0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", disabled: disabled, onClick: () => !disabled && onDaySelect(new Date(thisDay)), onMouseEnter: () => !disabled && (onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(new Date(thisDay))), w: "1.75rem", h: "1.75rem", borderRadius: "full", display: "flex", alignItems: "center", justifyContent: "center", fontSize: "0.8125rem", fontWeight: circleSolid ? 600 : 500, lineHeight: "1", cursor: disabled ? "not-allowed" : "pointer", bg: circleSolid ? solidFill : "transparent", color: circleColor, border: circleBorder, transition: "background 0.12s, color 0.12s", _hover: disabled
102
111
  ? {}
103
112
  : circleSolid
104
- ? { bg: theme.colors.primary[600] }
113
+ ? { bg: solidHoverFill, color: circleHoverColor }
105
114
  : { bg: rangeBg }, children: (0, date_fns_1.format)(thisDay, "d") }) }, thisDay.toString()));
106
115
  day = (0, date_fns_1.addDays)(day, 1);
107
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SingleDatePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/SingleDatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA6BlG,OAAO,EAAE,qBAAqB,EAAc,MAAM,mBAAmB,CAAC;AA2OtE,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA29B5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SingleDatePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/SingleDatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA6BlG,OAAO,EAAE,qBAAqB,EAAc,MAAM,mBAAmB,CAAC;AA2OtE,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAg+B5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}