@qoretechnologies/reqore 0.70.15 → 0.70.17
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 +209 -190
- package/dist/components/DatePicker/index.d.ts +5 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/DatePicker/index.js +66 -4
- package/dist/components/DatePicker/index.js.map +1 -1
- package/package.json +1 -1
- package/tests.json +1 -1
package/.claude/CLAUDE.md
CHANGED
|
@@ -1,86 +1,105 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
45
|
+
- **State:** zustand + React Context (use-context-selector)
|
|
13
46
|
- **Testing:** Jest + React Testing Library (tests in `__tests__/`)
|
|
14
|
-
- **
|
|
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
|
-
|
|
50
|
+
## Perf conventions that OVERRIDE the frontend default
|
|
21
51
|
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
- **Pattern:**
|
|
51
|
-
- **Exports:**
|
|
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
|
-
|
|
56
|
-
- **Dynamic theming:**
|
|
57
|
-
- **Intents:**
|
|
58
|
-
|
|
59
|
-
- **Custom
|
|
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
|
-
- **
|
|
64
|
-
|
|
65
|
-
- **Usage:**
|
|
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
|
-
- **
|
|
70
|
-
- **
|
|
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
|
-
|
|
76
|
-
- **Methods:** `addModal()`, `removeModal()`, `addNotification()`, `confirmAction()
|
|
77
|
-
- **Mobile detection:** `isMobile`, `isTablet`, `isMobileOrTablet`
|
|
78
|
-
- **ESC handling:**
|
|
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
|
-
- `
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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`, …)
|
|
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
|
|
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
|
-
|
|
126
|
-
- **New prop on an existing component, bug fix, refactor, test-only, story-only** →
|
|
127
|
-
|
|
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
|
-
|
|
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
|
-
- **
|
|
140
|
-
|
|
141
|
-
- **Selectors:**
|
|
142
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- **NEVER set `QLIP_UPLOAD_TOKEN` locally.** `vitest.config.ts` attaches qlip's `upload`
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
176
|
-
- **Naming:**
|
|
177
|
-
|
|
178
|
-
- **
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
- **
|
|
201
|
-
- **
|
|
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
|
-
- **
|
|
206
|
-
- **
|
|
207
|
-
- **
|
|
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
|
-
- **
|
|
213
|
-
- **
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
-
- **
|
|
228
|
-
- **
|
|
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
|
-
- **
|
|
234
|
-
- **
|
|
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
|
-
- **
|
|
240
|
-
- **
|
|
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
|
|
246
|
-
|
|
|
247
|
-
| Styled component props not typed
|
|
248
|
-
| Theme not applying
|
|
249
|
-
| ESC key ignored in modal
|
|
250
|
-
| Icon not rendering
|
|
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
|
|
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
|
|
257
|
-
|
|
|
258
|
-
| `src/index.tsx`
|
|
259
|
-
| `src/constants/`
|
|
260
|
-
| `src/helpers/`
|
|
261
|
-
| `src/hooks/`
|
|
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/`
|
|
264
|
-
| `src/types/`
|
|
265
|
-
| `__tests__/`
|
|
266
|
-
| `src/stories/`
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
5. **Propagate theme to children:**
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
- **
|
|
282
|
-
- **
|
|
283
|
-
- **
|
|
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.
|
|
@@ -41,6 +41,10 @@ export interface IDatePickerProps<T extends TDateValue> extends Omit<DatePickerP
|
|
|
41
41
|
placeholder?: string;
|
|
42
42
|
/** Props for the button trigger. Only used when `selectOnly` is true. */
|
|
43
43
|
buttonProps?: IReqoreButtonProps;
|
|
44
|
+
/** Overrides the locale-provided punctuation between the date and time.
|
|
45
|
+
* Pass a single space to render an ISO-style date and time without a comma.
|
|
46
|
+
* The locale-provided separator is preserved when this prop is undefined. */
|
|
47
|
+
dateTimeSeparator?: string;
|
|
44
48
|
}
|
|
45
|
-
export declare const DatePicker: <T extends TDateValue>({ value: _value, onChange, fluid, flat, rounded, minimal, size, pill, intent, customTheme, inheritCustomTheme, granularity, hourCycle, hideTimeZone, shouldForceLeadingZeros, onClearClick, closeOnSelect, isClearable, tooltip, popoverProps, inputProps, pickerProps, timeInputProps, timeFieldProps, pickerActiveDayProps, pickerDayProps, yearMonthPickerProps, minValue, maxValue, readOnlyInputOnTouch, dateType, errorBoundaryOptions, locale, selectOnly, placeholder, buttonProps, ...props }: IDatePickerProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
export declare const DatePicker: <T extends TDateValue>({ value: _value, onChange, fluid, flat, rounded, minimal, size, pill, intent, customTheme, inheritCustomTheme, granularity, hourCycle, hideTimeZone, shouldForceLeadingZeros, onClearClick, closeOnSelect, isClearable, tooltip, popoverProps, inputProps, pickerProps, timeInputProps, timeFieldProps, pickerActiveDayProps, pickerDayProps, yearMonthPickerProps, minValue, maxValue, readOnlyInputOnTouch, dateType, errorBoundaryOptions, locale, selectOnly, placeholder, buttonProps, dateTimeSeparator, ...props }: IDatePickerProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
46
50
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DatePicker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,IAAI,EAGJ,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAgE,MAAM,OAAO,CAAC;AACrF,OAAO,EAEL,QAAQ,EAIR,eAAe,EAIf,SAAS,EACV,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAoB,WAAW,EAAU,MAAM,qBAAqB,CAAC;AAI5E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAqB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAoB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,CACpD,SACE,IAAI,CACF,eAAe,CAAC,aAAa,CAAC,EAC9B,OAAO,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,CAChE,EACD,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,gBAAgB;IAClB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEzB,QAAQ,CAAC,EAAE,WAAW,CAAC;IAEvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,IAAI,IAAI,CAAC;IAEtB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,YAAY,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAE1C,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;kEAE8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;qFACiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;+CAC2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DatePicker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,IAAI,EAGJ,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAgE,MAAM,OAAO,CAAC;AACrF,OAAO,EAEL,QAAQ,EAIR,eAAe,EAIf,SAAS,EACV,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAoB,WAAW,EAAU,MAAM,qBAAqB,CAAC;AAI5E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAqB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAoB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,CACpD,SACE,IAAI,CACF,eAAe,CAAC,aAAa,CAAC,EAC9B,OAAO,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,CAChE,EACD,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,gBAAgB;IAClB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEzB,QAAQ,CAAC,EAAE,WAAW,CAAC;IAEvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,IAAI,IAAI,CAAC;IAEtB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,YAAY,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAE1C,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;kEAE8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;qFACiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;+CAC2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC;;iFAE6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA0KD,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,UAAU,EAAE,2fAuC9C,gBAAgB,CAAC,CAAC,CAAC,4CA2WrB,CAAC"}
|