@qoretechnologies/reqore 0.70.16 → 0.70.18

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/.claude/CLAUDE.md CHANGED
@@ -1,86 +1,105 @@
1
- # ReQore AI Coding Agent Instructions
2
-
3
- ## Project Overview
4
-
5
- ReQore is a **themeable React component library** for the Qorus platform. It provides 40+ UI components (Button, Table, Modal, Drawer, etc.) that share a unified design system with consistent theming, sizing, and effect systems.
6
-
7
- **Key Facts:**
1
+ @~/Projects/instruction-files/CLAUDE.md
2
+ @~/Projects/instruction-files/stacks/frontend/FRONTEND.md
3
+
4
+ # ReQore — Claude entry point
5
+
6
+ ## Shared Qore rules (READ FIRST)
7
+
8
+ The two `@`-imports above load the shared rules from the **instruction-files**
9
+ repo: the org-wide baseline (`CLAUDE.md`) and the frontend ruleset
10
+ (`stacks/frontend/FRONTEND.md`) — git safety, commit conventions, CI
11
+ monitoring, `/audit`, the Reqore-first rule, the Storybook + Qlip visual-change
12
+ flow, story descriptions, and more. Those files point on to
13
+ `stacks/frontend/BRAND_DESIGN.md` for brand / UI-design decisions (read it
14
+ before building any visual surface). **Everything below this section is
15
+ specific to ReQore.**
16
+
17
+ **If the imports above did not load** — you don't see the shared rules because
18
+ this repo is cloned somewhere other than `~/Projects/instruction-files` — find
19
+ the shared repo before doing any frontend work:
20
+
21
+ 1. Check for a gitignored **`.instruction-files-path`** file at this repo's
22
+ root. If it exists, read the path `P` from it, then read `P/CLAUDE.md` and
23
+ `P/stacks/frontend/FRONTEND.md` (+ `P/stacks/frontend/BRAND_DESIGN.md` for
24
+ UI work) and follow them.
25
+ 2. Otherwise locate the `instruction-files` repo on disk (try
26
+ `~/Projects/instruction-files`, then your other project roots). If found at
27
+ `P`, write `P` into `.instruction-files-path` (create it — it's gitignored)
28
+ so future sessions skip the search, then read the files above.
29
+ 3. If it isn't cloned anywhere, **STOP and ask the user to clone it**:
30
+ `git clone git@github.com:qoretechnologies/instruction-files.git ~/Projects/instruction-files`
31
+ Do not proceed with frontend work until the shared rules are loaded.
32
+
33
+ # ReQore — project-specific rules
34
+
35
+ ReQore is a **themeable React component library** for the Qorus platform. It provides
36
+ 40+ UI components (Button, Table, Modal, Drawer, etc.) sharing one design system with
37
+ consistent theming, sizing, and effect systems. **reqore is the UI primitive library
38
+ itself** — rules here are about how to build and publish reqore's own components.
39
+
40
+ ## Key Facts
8
41
 
9
42
  - **Framework:** React 18 + TypeScript (strict mode)
10
43
  - **Build:** TypeScript compilation to `/dist`, exports both `.js` and `.d.ts`
11
44
  - **Styling:** styled-components with theme-driven values (no CSS modules)
12
- - **State Management:** zustand + React Context (use-context-selector)
45
+ - **State:** zustand + React Context (use-context-selector)
13
46
  - **Testing:** Jest + React Testing Library (tests in `__tests__/`)
14
- - **Documentation:** Storybook (dev stories in `src/stories/`) + Docusaurus (docs site)
15
-
16
- ## Architecture Essentials
17
-
18
- ### General Development Practices
47
+ - **Docs:** Storybook (dev stories in `src/stories/`) + Docusaurus (docs site)
48
+ - **Priority:** user experience and performance first; complexity/tech debt secondary.
19
49
 
20
- # General
50
+ ## Perf conventions that OVERRIDE the frontend default
21
51
 
22
- - Focus is first on user experience and performance, complexity and tech debt secondary
23
- - Follow existing code patterns for new components; refer to similar components for guidance
24
- - Check if a helper or utility already exists before writing a new one
52
+ Reqore is a hot-path primitive library, so it inverts the general
53
+ "don't memoize by default" guidance:
25
54
 
26
- # TypeScript
55
+ - Always wrap components in `memo()` unless there's a specific reason not to.
56
+ - Always wrap callbacks in `useCallback()` unless there's a specific reason not to.
57
+ - Always memoize computed values in `useMemo()` unless there's a specific reason not to.
27
58
 
28
- - Use TypeScript with strict typing; define prop interfaces for each component with `I` prefix for interfaces and `T` prefix for types
29
-
30
- # UI / UX
31
-
32
- - Always make sure to create reusable components
33
- - Always use named exports for React components
34
- - There can be multiple React components in one file if it makes sense
35
- - Use styled-components for styling; define style interfaces for styled components
36
- - Always componentize styles with styled-components; avoid inline styles except for dynamic cases
37
- - Use functional components with React hooks
38
- - For React, always wrap components in `memo()` unless there's a specific reason not to
39
- - For React, always wrap callbacks in `useCallback()` unless there's a specific reason not to
40
- - For React, always memoize computed values in `useMemo()` unless there's a specific reason not to
41
-
42
- # Testing
43
-
44
- - Run tests after changes, run `yarn precheck` after feature completions
45
- - Write a unit test if it makes sense for the change you have made, but Storybook tests will always have higher priority
59
+ ## Architecture Essentials
46
60
 
47
61
  ### Component Structure
48
-
49
- - **Folder:** `src/components/{ComponentName}/` contains only `index.tsx` (and occasionally `backdrop.tsx` for overlay components)
50
- - **Pattern:** Each component is a `memo()` wrapped functional component with TypeScript interfaces
51
- - **Exports:** Named exports (e.g., `export const ReqoreButton`) from component files; re-exported in `src/index.tsx`
62
+ - **Folder:** `src/components/{ComponentName}/` contains only `index.tsx` (and
63
+ occasionally `backdrop.tsx` for overlay components).
64
+ - **Pattern:** each component is a `memo()`-wrapped functional component with TS interfaces.
65
+ - **Exports:** named exports (e.g. `export const ReqoreButton`); re-exported in `src/index.tsx`.
52
66
 
53
67
  ### Theme System (`src/constants/theme.ts` + hooks)
54
-
55
- - **Global theming:** `useReqoreTheme()` hook provides `IReqoreTheme` (colors, text, main background, intents)
56
- - **Dynamic theming:** Components read theme via hooks, enabling runtime theme switching
57
- - **Intents:** Type-safe intent system (e.g., `'primary' | 'secondary' | 'success' | 'danger'`) maps to theme colors
58
- - **Custom themes:** Merge with `DEFAULT_THEME`; see `ThemeProvider.tsx`
59
- - **Custom theme inheritance:** Components automatically inherit `customTheme` from ancestor components via `CustomThemeContext`. The `useReqoreTheme()` hook checks this context when no explicit `customTheme` prop is passed. Components can opt out with `inheritCustomTheme={false}` (available on components extending `IWithReqoreCustomTheme`). Components that wrap children and set a custom theme must pass `customTheme` to `ReqoreThemeProvider` so descendants can inherit it.
68
+ - **Global theming:** `useReqoreTheme()` provides `IReqoreTheme` (colors, text, main
69
+ background, intents).
70
+ - **Dynamic theming:** components read theme via hooks, enabling runtime switching.
71
+ - **Intents:** type-safe intent system (`'primary' | 'secondary' | 'success' | 'danger'`)
72
+ maps to theme colors.
73
+ - **Custom themes:** merge with `DEFAULT_THEME`; see `ThemeProvider.tsx`.
74
+ - **Custom theme inheritance:** components inherit `customTheme` from ancestors via
75
+ `CustomThemeContext`. `useReqoreTheme()` checks this context when no explicit
76
+ `customTheme` prop is passed. Opt out with `inheritCustomTheme={false}` (on components
77
+ extending `IWithReqoreCustomTheme`). Components that wrap children and set a custom theme
78
+ must pass `customTheme` to `ReqoreThemeProvider` so descendants can inherit it.
60
79
 
61
80
  ### Sizing System (`src/constants/sizes.ts`)
62
-
63
- - **Size types:** `'micro' | 'tiny' | 'small' | 'normal' | 'big' | 'huge' | 'massive'`
64
- - **Pattern:** Maps like `SIZE_TO_PX`, `SIZE_TO_NUMBER`, `CONTROL_TEXT_FROM_SIZE` convert size enums to pixel/CSS values
65
- - **Usage:** Most interactive components accept `size?: TSizes` prop; pass through to nested styled components
81
+ - **Size types:** `'micro' | 'tiny' | 'small' | 'normal' | 'big' | 'huge' | 'massive'`.
82
+ - **Pattern:** maps like `SIZE_TO_PX`, `SIZE_TO_NUMBER`, `CONTROL_TEXT_FROM_SIZE` convert
83
+ size enums to pixel/CSS values.
84
+ - **Usage:** most interactive components accept `size?: TSizes`; pass through to nested
85
+ styled components.
66
86
 
67
87
  ### Effect System (`src/components/Effect/`)
68
-
69
- - **Purpose:** Provides gradient, blur, shadow effects applied via `StyledTextEffect`
70
- - **Props:** `IWithReqoreEffect` mixin (gradient, blur, shadow, opacity) on interactive components
71
- - **Color types:** `TReqoreHexColor`, `TReqoreRgbaColor`, `TReqoreMultiTypeColor` used consistently
88
+ - **Purpose:** gradient, blur, shadow effects applied via `StyledTextEffect`.
89
+ - **Props:** `IWithReqoreEffect` mixin (gradient, blur, shadow, opacity).
90
+ - **Color types:** `TReqoreHexColor`, `TReqoreRgbaColor`, `TReqoreMultiTypeColor`.
72
91
 
73
92
  ### Global Context (`src/context/ReqoreContext.tsx` + `ReqoreProvider.tsx`)
74
-
75
- - **Manages:** Modals, notifications, z-index stack, mobile breakpoints, animations toggle, tooltips
76
- - **Methods:** `addModal()`, `removeModal()`, `addNotification()`, `confirmAction()` (confirmation dialog)
77
- - **Mobile detection:** `isMobile`, `isTablet`, `isMobileOrTablet` flags from `useMedia()` hook
78
- - **ESC handling:** Modals/popovers close on ESC via `escClosableModals` stack; `closeModalsOnEscPress` toggle
93
+ - **Manages:** modals, notifications, z-index stack, mobile breakpoints, animations toggle,
94
+ tooltips.
95
+ - **Methods:** `addModal()`, `removeModal()`, `addNotification()`, `confirmAction()`.
96
+ - **Mobile detection:** `isMobile`, `isTablet`, `isMobileOrTablet` from `useMedia()`.
97
+ - **ESC handling:** modals/popovers close on ESC via `escClosableModals` stack;
98
+ `closeModalsOnEscPress` toggle.
79
99
 
80
100
  ## Development Workflows
81
101
 
82
102
  ### Quick Start
83
-
84
103
  ```bash
85
104
  yarn install
86
105
  yarn storybook # Dev mode on http://localhost:6007
@@ -91,100 +110,107 @@ yarn build # TypeScript compilation
91
110
  ```
92
111
 
93
112
  ### Pre-commit Checks
94
-
95
- - `yarn precheck` runs: lint test build (production)
96
- - `pre-push` hook enforces same checks before push (see `package.json`)
97
- - Line length: 100 characters (enforced by eslint)
98
-
99
- ### Pre-commit / pre-push audit (`/audit`)
100
-
101
- When the user asks the agent to commit OR push changes, the agent MUST first run the `/audit` skill on the pending diff and show the report UNLESS `/audit` has already been run on the exact same set of changes in the current conversation (no new edits since). The audit catches the regressions `yarn precheck` cannot:
102
-
103
- - Standard prop contract declared but never wired (the headline bug — `intent` extended on the interface but never read, so `intent='danger'` paints nothing).
113
+ - `yarn precheck` runs: lint → test → build (production).
114
+ - `pre-push` hook enforces the same checks before push (see `package.json`).
115
+ - Line length: 100 characters (enforced by eslint).
116
+
117
+ ### What reqore's `/audit` uniquely catches
118
+ (The general "run `/audit` before every commit/push, show the report, pause for
119
+ fix-or-waive" flow is the frontend baseline — this is what reqore's audit adds on top.)
120
+ - Standard prop contract declared but never wired (the headline bug — `intent` extended on
121
+ the interface but never read, so `intent='danger'` paints nothing).
104
122
  - One-off raw HTML or styled wrappers where a Reqore primitive fits.
105
- - Matrix stories (`Sizes`, `Intents`, …) that render identical-looking rows because the prop isn't wired OR the matrix isn't constrained on a wide viewport.
123
+ - Matrix stories (`Sizes`, `Intents`, …) rendering identical-looking rows because the prop
124
+ isn't wired OR the matrix isn't constrained on a wide viewport.
106
125
  - Test coverage gaps against the standard prop matrix.
107
126
  - Helper duplication vs `src/helpers/`.
108
127
  - Appendix A drift vs `.tasks/NEW_COMPONENT.md`.
109
128
 
110
- Order of operations on a commit/push request:
111
-
112
- 1. Run `/audit` (if not already clean for this exact diff).
113
- 2. Show the report.
114
- 3. Pause for the user to either fix findings or explicitly waive them.
115
- 4. Only then proceed to `git commit` / `git push`.
116
-
117
- The audit never edits files and never invokes git — it reports; the user/agent decides what to fix. Skipping the audit on commit/push is a hard violation: the report is what makes the silent regressions visible.
118
-
119
129
  ### Version bumps (required on every PR)
120
130
 
121
- Every PR to `develop` MUST bump `package.json`'s `version` field before it merges. This is load-bearing: `.github/workflows/beta_release.yml` runs on every push to `develop` and publishes to NPM using whatever version is in `package.json` at push time. If two PRs merge back-to-back without bumps, the second silently no-ops or fails (NPM refuses to re-publish an existing version).
131
+ Every PR to `develop` MUST bump `package.json`'s `version` field before it merges. This is
132
+ load-bearing: `.github/workflows/beta_release.yml` runs on every push to `develop` and
133
+ publishes to NPM using whatever version is in `package.json` at push time. If two PRs merge
134
+ back-to-back without bumps, the second silently no-ops or fails (NPM refuses to re-publish
135
+ an existing version).
122
136
 
123
137
  **Bump size rules:**
124
-
125
- - **New component** (a whole new `Reqore{Name}` in `src/components/` exported from `src/index.tsx`) → minor: `0.70.6` → `0.71.0`
126
- - **New prop on an existing component, bug fix, refactor, test-only, story-only** → patch: `0.70.6` → `0.70.7`
127
- - **Breaking change** (removed export, changed default behaviour, renamed prop without alias) → major: `0.70.6` → `1.0.0` — coordinate with the maintainer first; Reqore stays 0.x until 1.0 is intentional.
138
+ - **New component** (a whole new `Reqore{Name}` in `src/components/` exported from
139
+ `src/index.tsx`) → minor: `0.70.6` → `0.71.0`
140
+ - **New prop on an existing component, bug fix, refactor, test-only, story-only** →
141
+ patch: `0.70.6` → `0.70.7`
142
+ - **Breaking change** (removed export, changed default behaviour, renamed prop without
143
+ alias) → major: `0.70.6` → `1.0.0` — coordinate with the maintainer first; Reqore stays
144
+ 0.x until 1.0 is intentional.
128
145
 
129
146
  **How to bump:**
147
+ 1. Edit `package.json` directly (`"version": "0.70.7"`) as part of the same PR. Don't leave
148
+ it for a post-merge follow-up — the workflow can't wait for a second push.
149
+ 2. Commit it in a dedicated `chore(release): bump version to X.Y.Z` commit OR fold the line
150
+ into the feature commit; both are fine.
151
+ 3. If another PR bumps to the same version before yours merges, rebase and bump again — the
152
+ version in `develop` on merge must be strictly greater than the previous merged version.
130
153
 
131
- 1. Edit `package.json` directly (`"version": "0.70.7"`) as part of the same PR as the change. Don't leave it for a post-merge follow-up — the workflow can't wait for a second push.
132
- 2. Commit it in a dedicated `chore(release): bump version to X.Y.Z` commit OR fold the line into the feature commit; both are fine.
133
- 3. If another PR bumps to the same version before yours merges, rebase and bump again — the version in `develop` on merge must be strictly greater than the previous merged version.
134
-
135
- **Where to look if you're not sure:** `git log --oneline -20 -- package.json` — every recent commit touching it shows the bump pattern.
154
+ **Where to look if unsure:** `git log --oneline -20 -- package.json`.
136
155
 
137
156
  ### Testing Patterns
138
-
139
- - **Setup:** `__tests__/setup.js` disables console debug/info/error
140
- - **Wrapper:** Always wrap tests with `<ReqoreUIProvider><ReqoreLayoutContent><ReqoreContent>...</ReqoreContent></ReqoreLayoutContent></ReqoreUIProvider>`
141
- - **Selectors:** Use CSS classes like `.reqore-button`, `.reqore-icon` (added via `className` prop)
142
- - **Example:** See [button.test.tsx](__tests__/button.test.tsx)
157
+ - **Setup:** `__tests__/setup.js` disables console debug/info/error.
158
+ - **Wrapper:** always wrap tests with
159
+ `<ReqoreUIProvider><ReqoreLayoutContent><ReqoreContent>...</ReqoreContent></ReqoreLayoutContent></ReqoreUIProvider>`.
160
+ - **Selectors:** use CSS classes like `.reqore-button`, `.reqore-icon` (added via
161
+ `className` prop).
162
+ - **Example:** see `__tests__/button.test.tsx`.
143
163
 
144
164
  ### Storybook Stories
165
+ - **Location:** `src/stories/` (e.g. `Collection.stories.tsx`).
166
+ - **Pattern:** ArgTypes for props, canvas controls, visual testing via Chromatic.
167
+ - **Command:** `yarn build-storybook` builds the static site.
145
168
 
146
- - **Location:** `src/stories/` (e.g., `Collection.stories.tsx`)
147
- - **Pattern:** ArgTypes for props, canvas controls, visual testing via Chromatic
148
- - **Command:** `yarn build-storybook` builds static site
149
-
150
- ### Verifying a visual fix locally with Qlip (IMPORTANT)
151
-
152
- Before claiming a Qlip-flagged snapshot is fixed, **capture the story locally with Qlip and Read the PNG**. Text-based "the code says X" reasoning has repeatedly missed cases where the code change didn't actually reach the pixels (a prop that turned out to be a no-op, a rule beaten on specificity, a styled override the component ignored). The reviewer has ~870 snapshots per build to review; do not waste that time on "fixed" claims that didn't actually change the render.
169
+ ### Verifying a visual fix locally with Qlip — reqore mechanics
153
170
 
154
- **How to capture one story locally without triggering upload:**
171
+ (The principle capture the story locally and Read the PNG before claiming a Qlip-flagged
172
+ snapshot is fixed — is the frontend baseline. These are reqore's specific mechanics and
173
+ guardrails.)
155
174
 
175
+ Capture one story without triggering upload:
156
176
  ```bash
157
177
  yarn test:stories src/stories/Tabs/Tabs.stories.tsx > /tmp/qlip-verify.log 2>&1
158
178
  ```
159
-
160
- Then `Read` the specific PNG under `qlip/screenshots/<timestamp>/stories/auto/<Story__Id>.png` and inspect it as an image (Read supports PNGs). To prove the fix actually moved the pixels, compare the `md5` of that PNG against the same story in the previous capture directory — identical hashes mean the render did not change, whatever the diff says.
161
-
162
- **Rules of the road (violate these and you'll publish local screenshots to the shared review dashboard or mislead yourself with a stale capture):**
163
-
164
- - **NEVER set `QLIP_UPLOAD_TOKEN` locally.** `vitest.config.ts` attaches qlip's `upload` block only when that variable is present, and CI supplies it from the repository secret in `.github/workflows/tests.yml`. With it set, **every** `yarn test:stories` publishes a build the whole team then sees in review. This is not hypothetical: the token was hardcoded here until July 2026 and local runs posted four unwanted builds in a single session.
165
- - **Check for the upload line.** qlip prints `[qlip] uploaded build <id> … → https://qlip.qoretechnologies.com` when it publishes. If a local run prints that, the gate is broken — stop and fix it before continuing.
166
- - **NEVER run `yarn vitest run` with no `--project`** — it includes the storybook project and captures the whole ~870-snapshot suite, which will slow the machine to a crawl (and upload it, if the gate is broken). For unit tests use `yarn test` (`--project unit`), which captures nothing; for stories, one story file at a time.
167
- - **Delete the previous capture directory BEFORE you re-capture.** Qlip's file naming is `<StoryId>.png` — a re-capture overwrites, but a story that no longer exists (renamed, deleted, skipped) leaves its old PNG behind and will mislead you into reviewing a render that is no longer produced.
168
-
169
- Attempts that don't include a Qlip capture + PNG read are "I *think* I fixed it" — not "I fixed it". For visual reviews, the render is the source of truth.
179
+ Then `Read` the PNG under `qlip/screenshots/<timestamp>/stories/auto/<Story__Id>.png`.
180
+ To prove the fix moved the pixels, compare the `md5` of that PNG against the same story in
181
+ the previous capture directory — identical hashes mean the render did not change.
182
+
183
+ **Guardrails:**
184
+ - **NEVER set `QLIP_UPLOAD_TOKEN` locally.** `vitest.config.ts` attaches qlip's `upload`
185
+ block only when that variable is present, and CI supplies it from the repo secret in
186
+ `.github/workflows/tests.yml`. With it set, **every** `yarn test:stories` publishes a
187
+ build the whole team then sees in review (the token was hardcoded here until July 2026 and
188
+ local runs posted four unwanted builds in one session).
189
+ - **Check for the upload line.** qlip prints
190
+ `[qlip] uploaded build <id> … → https://qlip.qoretechnologies.com` when it publishes. If a
191
+ local run prints that, the gate is broken — stop and fix it before continuing.
192
+ - **NEVER run `yarn vitest run` with no `--project`** — it includes the storybook project
193
+ and captures the whole ~870-snapshot suite (and uploads it if the gate is broken). Use
194
+ `yarn test` (`--project unit`) for unit tests; one story file at a time for stories.
195
+ - **Delete the previous capture directory BEFORE re-capturing.** Qlip names files
196
+ `<StoryId>.png`; a renamed/deleted/skipped story leaves its old PNG behind and will
197
+ mislead you into reviewing a render that is no longer produced.
170
198
 
171
199
  ## Code Patterns & Conventions
172
200
 
173
201
  ### Component Prop Interfaces
174
-
175
- - **Extend mixins:** `IWithReqoreSize`, `IWithReqoreEffect`, `IWithReqoreLoading`, `IWithReqoreReadOnly`, `IWithReqoreCustomTheme`
176
- - **Naming:** Props interface is `IReqore{ComponentName}Props`; style interface is `IReqore{ComponentName}Style`
177
- - **Optional theme:** Style interfaces accept `theme: IReqoreTheme` for styled-components access
178
- - **Readonly context:** Use `readonly` keyword on context properties (immutability)
202
+ - **Extend mixins:** `IWithReqoreSize`, `IWithReqoreEffect`, `IWithReqoreLoading`,
203
+ `IWithReqoreReadOnly`, `IWithReqoreCustomTheme`.
204
+ - **Naming:** props interface is `IReqore{ComponentName}Props`; style interface is
205
+ `IReqore{ComponentName}Style`.
206
+ - **Optional theme:** style interfaces accept `theme: IReqoreTheme` for styled-components access.
207
+ - **Readonly context:** use the `readonly` keyword on context properties (immutability).
179
208
 
180
209
  ### Styled Components Pattern
181
-
182
210
  ```tsx
183
211
  const StyledButton = styled.button<IReqoreButtonStyle>`
184
- // Use props.theme from ReqoreTheme
185
212
  background: ${({ theme, intent }) => theme.intents?.[intent]?.color};
186
213
  color: ${({ theme }) => getReadableColor(theme)};
187
- // Conditional styles via css helper
188
214
  ${({ disabled }) =>
189
215
  disabled &&
190
216
  css`
@@ -194,96 +220,89 @@ const StyledButton = styled.button<IReqoreButtonStyle>`
194
220
  ```
195
221
 
196
222
  ### Hooks Usage
197
-
198
- - **Theme:** `useReqoreTheme(element?, customTheme?, intent?, intentsKey?, inheritCustomTheme?)` returns `IReqoreTheme`. Pass `customTheme` and `inheritCustomTheme` from component props to support custom theme inheritance.
199
- - **Context props:** `useReqoreProperty('propertyName')` for context values (avoids consuming entire context)
200
- - **Local refs:** `useCombinedRefs()` for forwarding + internal refs; `useOutsideClick()` for popover clicks
201
- - **Auto-focus:** `useAutoFocus()` for modal/drawer focus management
223
+ - **Theme:** `useReqoreTheme(element?, customTheme?, intent?, intentsKey?, inheritCustomTheme?)`
224
+ returns `IReqoreTheme`. Pass `customTheme` and `inheritCustomTheme` from props to support
225
+ custom theme inheritance.
226
+ - **Context props:** `useReqoreProperty('propertyName')` (avoids consuming the whole context).
227
+ - **Local refs:** `useCombinedRefs()` for forwarding + internal refs; `useOutsideClick()`
228
+ for popover clicks.
229
+ - **Auto-focus:** `useAutoFocus()` for modal/drawer focus management.
202
230
 
203
231
  ### Color Helpers (`src/helpers/colors.ts`)
204
-
205
- - **Text contrast:** `getReadableColor(theme)` returns light or dark based on theme.main
206
- - **Gradients:** `getGradientMix()` blends multiple colors for effect gradients
207
- - **Hex↔RGBA:** `hexAToRGBA()`, `getRGBAFromHex()` for color space conversions
208
- - **Lightness:** `changeLightness()`, `changeDarkness()` for theme-aware color adjustments
232
+ - **Text contrast:** `getReadableColor(theme)` returns light or dark based on `theme.main`.
233
+ - **Gradients:** `getGradientMix()` blends multiple colors for effect gradients.
234
+ - **Hex↔RGBA:** `hexAToRGBA()`, `getRGBAFromHex()`.
235
+ - **Lightness:** `changeLightness()`, `changeDarkness()` for theme-aware adjustments.
209
236
 
210
237
  ### Animation Config
211
-
212
- - **Spring:** `SPRING_CONFIG` for bounce/smooth animations (via `@react-spring/web`)
213
- - **Disabled:** `SPRING_CONFIG_NO_ANIMATIONS` when `animations.buttons: false`
214
- - **Usage:** Wrap animated components with `<animated>` from react-spring
238
+ - **Spring:** `SPRING_CONFIG` for bounce/smooth animations (via `@react-spring/web`).
239
+ - **Disabled:** `SPRING_CONFIG_NO_ANIMATIONS` when `animations.buttons: false`.
240
+ - **Usage:** wrap animated components with `<animated>` from react-spring.
215
241
 
216
242
  ## Key Integration Points
217
243
 
218
244
  ### Modal & Notification Flow
219
-
220
- 1. **Add modal:** `context.addModal(modalElement, id?)` returns modal ID
221
- 2. **Close:** `context.removeModal(id)` + optional confirmation dialog
222
- 3. **Notifications:** `context.addNotification({...})` queues toast; auto-removes after `duration`
223
- 4. **Portal:** All modals/notifications render via `customPortalId` or default DOM portal
245
+ 1. **Add modal:** `context.addModal(modalElement, id?)` returns modal ID.
246
+ 2. **Close:** `context.removeModal(id)` + optional confirmation dialog.
247
+ 3. **Notifications:** `context.addNotification({...})` queues a toast; auto-removes after `duration`.
248
+ 4. **Portal:** modals/notifications render via `customPortalId` or default DOM portal.
224
249
 
225
250
  ### Responsive Breakpoints
226
-
227
- - **Mobile:** `isMobile` (width ≤ 480px)
228
- - **Tablet:** `isTablet` (width 1024px)
229
- - **Usage:** Conditional rendering in components; affects dropdown/menu positioning
251
+ - **Mobile:** `isMobile` (width ≤ 480px).
252
+ - **Tablet:** `isTablet` (width ≤ 1024px).
253
+ - **Usage:** conditional rendering; affects dropdown/menu positioning.
230
254
 
231
255
  ### Icon System (`src/types/icons.ts`)
232
-
233
- - **Type:** `IReqoreIconName` (string literal of all icon names)
234
- - **Render:** `<ReqoreIcon name="iconNameHere" />` or component prop `icon="iconNameHere"`
235
- - **Sizing:** Icon size auto-scales with component size via `ICON_FROM_SIZE`
256
+ - **Type:** `IReqoreIconName` (string literal of all icon names).
257
+ - **Render:** `<ReqoreIcon name="iconNameHere" />` or component prop `icon="iconNameHere"`.
258
+ - **Sizing:** icon size auto-scales with component size via `ICON_FROM_SIZE`.
236
259
 
237
260
  ### Collections & Paging
238
-
239
- - **Collection:** Renders arrays with optional sorting/filtering; used in Table, MultiSelect
240
- - **Paging:** `useReqorePaging()` hook handles offset/limit; `<ReqorePaging>` component for controls
241
- - **Pattern:** See [Collection.tsx](src/components/Collection/) and [Paging.tsx](src/containers/Paging.tsx)
261
+ - **Collection:** renders arrays with optional sorting/filtering; used in Table, MultiSelect.
262
+ - **Paging:** `useReqorePaging()` handles offset/limit; `<ReqorePaging>` for controls.
263
+ - **Pattern:** see `src/components/Collection/` and `src/containers/Paging.tsx`.
242
264
 
243
265
  ## Common Pitfalls & Solutions
244
266
 
245
- | Issue | Solution |
246
- | -------------------------------------- | -------------------------------------------------------------------------------------------- |
247
- | Styled component props not typed | Add `<IComponentStyle>` generic; ensure mixin interfaces extend properly |
248
- | Theme not applying | Verify `ReqoreUIProvider` wraps component tree; check `useReqoreTheme()` call |
249
- | ESC key ignored in modal | Ensure `closeModalsOnEscPress: true` in provider; modal must be in `escClosableModals` stack |
250
- | Icon not rendering | Verify icon name in `IReqoreIconName`; check icon imports in `Icon/` component |
251
- | Tests fail with "React is not defined" | Verify `setup.js` is loaded; jsx: "react-jsx" in tsconfig.json |
252
- | Animation janky on slow devices | Offer `animations.buttons: false` toggle in theme/context; use `SPRING_CONFIG_NO_ANIMATIONS` |
267
+ | Issue | Solution |
268
+ | --- | --- |
269
+ | Styled component props not typed | Add `<IComponentStyle>` generic; ensure mixin interfaces extend properly |
270
+ | Theme not applying | Verify `ReqoreUIProvider` wraps the tree; check `useReqoreTheme()` call |
271
+ | ESC key ignored in modal | Ensure `closeModalsOnEscPress: true`; modal must be in `escClosableModals` stack |
272
+ | Icon not rendering | Verify icon name in `IReqoreIconName`; check icon imports in `Icon/` |
273
+ | Tests fail with "React is not defined" | Verify `setup.js` is loaded; `jsx: "react-jsx"` in tsconfig.json |
274
+ | Animation janky on slow devices | Offer `animations.buttons: false`; use `SPRING_CONFIG_NO_ANIMATIONS` |
253
275
 
254
276
  ## File Reference
255
277
 
256
- | Path | Purpose |
257
- | ----------------- | --------------------------------------------------------------- |
258
- | `src/index.tsx` | Main export barrel; re-exports all public components |
259
- | `src/constants/` | Global enums, size maps, theme defaults, animation configs |
260
- | `src/helpers/` | Color math, utility functions (no React) |
261
- | `src/hooks/` | Custom React hooks (theme, context, DOM utilities) |
278
+ | Path | Purpose |
279
+ | --- | --- |
280
+ | `src/index.tsx` | Main export barrel; re-exports all public components |
281
+ | `src/constants/` | Global enums, size maps, theme defaults, animation configs |
282
+ | `src/helpers/` | Color math, utility functions (no React) |
283
+ | `src/hooks/` | Custom React hooks (theme, context, DOM utilities) |
262
284
  | `src/containers/` | Provider components (ReqoreProvider, ThemeProvider, UIProvider) |
263
- | `src/context/` | Context definitions (ReqoreContext, ThemeContext) |
264
- | `src/types/` | Global TypeScript interfaces (icons, global prop mixins) |
265
- | `__tests__/` | Jest tests; mirrors `src/` structure |
266
- | `src/stories/` | Storybook stories for visual development |
285
+ | `src/context/` | Context definitions (ReqoreContext, ThemeContext) |
286
+ | `src/types/` | Global TypeScript interfaces (icons, global prop mixins) |
287
+ | `__tests__/` | Jest tests; mirrors `src/` structure |
288
+ | `src/stories/` | Storybook stories for visual development |
267
289
 
268
290
  ## When Adding New Components
269
-
270
- 1. **Create folder:** `src/components/{ComponentName}/index.tsx`
271
- 2. **Define interfaces:** `IReqore{ComponentName}Props` + `IReqore{ComponentName}Style`
272
- 3. **Use mixins:** Extend `IWithReqoreEffect`, `IWithReqoreSize`, `IWithReqoreCustomTheme` as needed
273
- 4. **Apply theme:** Use `useReqoreTheme('main', customTheme, intent, undefined, inheritCustomTheme)` — destructure both `customTheme` and `inheritCustomTheme` from props so the component supports custom theme inheritance from ancestor components
274
- 5. **Propagate theme to children:** If the component wraps children with `ReqoreThemeProvider`, pass both the resolved `theme` and raw `customTheme` prop: `<ReqoreThemeProvider theme={theme} customTheme={customTheme}>` — this enables descendant components to inherit the custom theme via `CustomThemeContext`
275
- 6. **Export:** Add named export to `src/index.tsx`
276
- 7. **Test:** Add test file in `__tests__/{ComponentName}.test.tsx` with UIProvider wrapper
277
- 8. **Story:** Create `src/stories/{ComponentName}.stories.tsx` with argTypes
291
+ 1. **Create folder:** `src/components/{ComponentName}/index.tsx`.
292
+ 2. **Define interfaces:** `IReqore{ComponentName}Props` + `IReqore{ComponentName}Style`.
293
+ 3. **Use mixins:** extend `IWithReqoreEffect`, `IWithReqoreSize`, `IWithReqoreCustomTheme` as needed.
294
+ 4. **Apply theme:** `useReqoreTheme('main', customTheme, intent, undefined, inheritCustomTheme)`
295
+ — destructure both `customTheme` and `inheritCustomTheme` from props.
296
+ 5. **Propagate theme to children:** if wrapping children with `ReqoreThemeProvider`, pass
297
+ both the resolved `theme` and raw `customTheme` prop so descendants inherit via
298
+ `CustomThemeContext`.
299
+ 6. **Export:** add named export to `src/index.tsx`.
300
+ 7. **Test:** add `__tests__/{ComponentName}.test.tsx` with the UIProvider wrapper.
301
+ 8. **Story:** create `src/stories/{ComponentName}.stories.tsx` with argTypes.
302
+ (Also follow `.tasks/NEW_COMPONENT.md` — Appendix A is what `/audit` checks against.)
278
303
 
279
304
  ## Documentation
280
-
281
- - **Storybook:** Run `yarn storybook` for interactive component playground
282
- - **Docusaurus:** Run `yarn docs:dev` for user guides + API docs
283
- - **TypeDoc:** `yarn docs:api` generates API reference from JSDoc comments
284
- - **Inline:** Use JSDoc comments on public props/methods for IDE tooltips
285
-
286
- ## Other
287
-
288
- - You may need to source zsh to get some commands (like gh) working
289
- - If there is an issue, always start the branch with the issue number e.g. `feature/1234_new-component`
305
+ - **Storybook:** `yarn storybook` for the interactive playground.
306
+ - **Docusaurus:** `yarn docs:dev` for user guides + API docs.
307
+ - **TypeDoc:** `yarn docs:api` generates API reference from JSDoc comments.
308
+ - **Inline:** JSDoc comments on public props/methods for IDE tooltips.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qoretechnologies/reqore",
3
- "version": "0.70.16",
3
+ "version": "0.70.18",
4
4
  "description": "ReQore is a highly theme-able and modular UI library for React",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",