@qoretechnologies/reqraft 0.10.9 → 0.10.11
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 +39 -18
- package/package.json +1 -1
- package/src/components/dpqlEditor/DpqlEditor.stories.tsx +74 -2
- package/src/components/form/engine/FormEngine.stories.tsx +654 -32
- package/src/components/form/engine/FormEngineRemote.stories.tsx +48 -0
- package/src/components/form/engine/_structuredData/StructuredDataView.stories.tsx +8 -0
- package/src/components/form/engine/variants/FormEngineVariants.stories.tsx +40 -0
- package/src/components/form/expressions/ExpressionField.stories.tsx +74 -2
- package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +187 -0
- package/src/components/form/fields/Field.stories.tsx +40 -0
- package/src/components/form/fields/array/ArrayAutoField.stories.tsx +64 -0
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +136 -0
- package/src/components/form/fields/binary/Binary.stories.tsx +32 -0
- package/src/components/form/fields/boolean/Boolean.stories.tsx +24 -0
- package/src/components/form/fields/byte-size/ByteSize.stories.tsx +24 -0
- package/src/components/form/fields/color/Color.stories.tsx +30 -0
- package/src/components/form/fields/cron/Cron.stories.tsx +8 -0
- package/src/components/form/fields/date/Date.stories.tsx +22 -0
- package/src/components/form/fields/file/File.stories.tsx +48 -0
- package/src/components/form/fields/long-string/LongString.stories.tsx +24 -0
- package/src/components/form/fields/markdown/Markdown.stories.tsx +8 -0
- package/src/components/form/fields/number/Number.stories.tsx +31 -0
- package/src/components/form/fields/object/Object.stories.tsx +88 -0
- package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +24 -0
- package/src/components/form/fields/rich-text/RichText.stories.tsx +23 -0
- package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +72 -0
- package/src/components/form/fields/select/Select.stories.tsx +104 -0
- package/src/components/form/fields/string/String.stories.tsx +16 -0
- package/src/components/form/fields/template/TemplateField.stories.tsx +160 -0
- package/src/components/form/fields/url/Url.stories.tsx +24 -0
- package/src/components/log/Log.stories.tsx +96 -0
- package/src/components/menu/Menu.stories.tsx +54 -0
- package/src/components/qonsoleSmartInput/QonsoleSmartInput.stories.tsx +14 -0
- package/src/components/smartEditor/SmartEditor.stories.tsx +32 -0
- package/src/hooks/useFetch/useFetch.stories.tsx +30 -0
- package/src/hooks/useStorage/useStorage.stories.tsx +30 -0
- package/src/hooks/useWebSocket/useWebsocket.stories.tsx +127 -1
- package/src/stores/currentUser/currentUser.stories.tsx +17 -0
package/.claude/CLAUDE.md
CHANGED
|
@@ -1,4 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
@~/Projects/instruction-files/CLAUDE.md
|
|
2
|
+
@~/Projects/instruction-files/stacks/frontend/FRONTEND.md
|
|
3
|
+
|
|
4
|
+
# ReQraft (toolkit-react) — 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 ReQraft (toolkit-react).**
|
|
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
|
+
# ReQraft (toolkit-react) — project-specific rules
|
|
2
34
|
|
|
3
35
|
## Project Overview
|
|
4
36
|
|
|
@@ -18,16 +50,6 @@ ReQraft (`@qoretechnologies/reqraft`) is a **React hooks and components toolkit*
|
|
|
18
50
|
|
|
19
51
|
## Architecture Essentials
|
|
20
52
|
|
|
21
|
-
### General Development Practices
|
|
22
|
-
|
|
23
|
-
- Focus on user experience and performance first; complexity and tech debt are secondary
|
|
24
|
-
- Follow existing code patterns; refer to similar hooks/components for guidance
|
|
25
|
-
- Check if a helper or utility already exists before writing a new one
|
|
26
|
-
- Use TypeScript with strict typing; prefix interfaces with `I` and types with `T`
|
|
27
|
-
- Always use named exports for React components and hooks
|
|
28
|
-
- Use functional components with React hooks; wrap in `memo()` unless there's a reason not to
|
|
29
|
-
- Wrap callbacks in `useCallback()` and computed values in `useMemo()` unless there's a reason not to
|
|
30
|
-
|
|
31
53
|
### Provider Stack (`src/providers/`)
|
|
32
54
|
|
|
33
55
|
The app must be wrapped in `ReqraftProvider` (or initialized via `initializeReqraft()`):
|
|
@@ -145,10 +167,13 @@ yarn build:test # Type-check without emit
|
|
|
145
167
|
- `pre-push` hook enforces: `build:test:prod`, `lint`, `test`
|
|
146
168
|
- Branch naming: always start with the issue number, e.g. `feature/49_pooled-connections`
|
|
147
169
|
|
|
148
|
-
### Versioning
|
|
170
|
+
### Versioning — every PR to `develop` MUST bump the version
|
|
171
|
+
|
|
172
|
+
`.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. A merge without a bump therefore tries to re-publish an already-published version and **fails** (NPM refuses to re-publish). This applies to **every** PR — features, fixes, chores, and docs-only changes alike. There is no exception.
|
|
149
173
|
|
|
150
|
-
-
|
|
151
|
-
- Bump in `package.json` only (no git tag): `npm version patch --no-git-tag-version`, and include
|
|
174
|
+
- Bump the **patch** for an ordinary PR while in beta (pre-1.0) — e.g. `0.10.9` → `0.10.10`. Do NOT bump minor/major for ordinary feature/fix PRs.
|
|
175
|
+
- Bump in `package.json` only (no git tag): `npm version patch --no-git-tag-version`, and include the bump in the PR's commit.
|
|
176
|
+
- If another PR bumps to the same version before yours merges, rebase and bump again — the version at merge time must be strictly greater than the last published one.
|
|
152
177
|
|
|
153
178
|
### Testing Patterns
|
|
154
179
|
|
|
@@ -167,8 +192,6 @@ yarn build:test # Type-check without emit
|
|
|
167
192
|
|
|
168
193
|
### Naming
|
|
169
194
|
|
|
170
|
-
- Interfaces: `I` prefix (e.g., `IReqraftUseFetch`)
|
|
171
|
-
- Types: `T` prefix (e.g., `TReqraftMenu`)
|
|
172
195
|
- Enums: PascalCase (e.g., `ReqraftWebSocketStatus`)
|
|
173
196
|
- Hooks: `useReqraft*` prefix
|
|
174
197
|
- Providers: `Reqraft*Provider`
|
|
@@ -249,7 +272,5 @@ yarn build:test # Type-check without emit
|
|
|
249
272
|
|
|
250
273
|
## Other
|
|
251
274
|
|
|
252
|
-
- You may need to source zsh to get some commands (like `gh`) working: `source ~/.zshrc`
|
|
253
|
-
- Branch naming convention: `feature/<issue-number>_<short-description>` (e.g., `feature/49_pooled-connections`)
|
|
254
275
|
- This library is a **peer-dependency consumer** of ReQore — do not copy ReQore internals here; import from `@qoretechnologies/reqore` instead
|
|
255
276
|
- `yarn update-reqore` updates ReQore to the latest beta
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoretechnologies/reqraft",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.11",
|
|
4
4
|
"description": "ReQraft is a collection of React components and hooks that are used across Qore Technologies' products made using the ReQore component library from Qore.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -511,7 +511,15 @@ const meta = {
|
|
|
511
511
|
export default meta;
|
|
512
512
|
export type Story = StoryObj<typeof meta>;
|
|
513
513
|
|
|
514
|
-
export const Empty: Story = {
|
|
514
|
+
export const Empty: Story = {
|
|
515
|
+
parameters: {
|
|
516
|
+
docs: {
|
|
517
|
+
description: {
|
|
518
|
+
story: 'Renders the DpqlEditor with no value — the editor mounts empty and ready for input.',
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
};
|
|
515
523
|
|
|
516
524
|
/**
|
|
517
525
|
* No chips / templates — just a valid DPQL literal expression so we can
|
|
@@ -524,18 +532,42 @@ export const WithPlainText: Story = {
|
|
|
524
532
|
args: {
|
|
525
533
|
value: '1 == 1 && "hello" != "world"',
|
|
526
534
|
},
|
|
535
|
+
parameters: {
|
|
536
|
+
docs: {
|
|
537
|
+
description: {
|
|
538
|
+
story:
|
|
539
|
+
'Renders the DpqlEditor with a plain DPQL literal expression — no field references or templates, so the editor mounts as plain text with no tag chips.',
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
},
|
|
527
543
|
};
|
|
528
544
|
|
|
529
545
|
export const WithFieldReference: Story = {
|
|
530
546
|
args: {
|
|
531
547
|
value: '@name == "Alice"',
|
|
532
548
|
},
|
|
549
|
+
parameters: {
|
|
550
|
+
docs: {
|
|
551
|
+
description: {
|
|
552
|
+
story:
|
|
553
|
+
'Renders the DpqlEditor with an @name field reference — the editor mounts with a tag chip for the field and the literal string operand.',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
533
557
|
};
|
|
534
558
|
|
|
535
559
|
export const WithTemplateVariable: Story = {
|
|
536
560
|
args: {
|
|
537
561
|
value: 'contains("$local:input", "es")',
|
|
538
562
|
},
|
|
563
|
+
parameters: {
|
|
564
|
+
docs: {
|
|
565
|
+
description: {
|
|
566
|
+
story:
|
|
567
|
+
'Renders the DpqlEditor with a contains() call whose first argument is a $local:input template — the template renders as a tag chip inside the call.',
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
},
|
|
539
571
|
};
|
|
540
572
|
|
|
541
573
|
export const WithMixedContent: Story = {
|
|
@@ -544,6 +576,14 @@ export const WithMixedContent: Story = {
|
|
|
544
576
|
// qore-2/design/dpql-syntax.md §"Logical Operators".
|
|
545
577
|
value: '@name == $data:{1.name} && @age > $config:min_age',
|
|
546
578
|
},
|
|
579
|
+
parameters: {
|
|
580
|
+
docs: {
|
|
581
|
+
description: {
|
|
582
|
+
story:
|
|
583
|
+
'Renders the DpqlEditor with mixed content — two @field references, two $data / $config templates and the DPQL "&&" logical operator between them, each rendered as its own chip or token.',
|
|
584
|
+
},
|
|
585
|
+
},
|
|
586
|
+
},
|
|
547
587
|
};
|
|
548
588
|
|
|
549
589
|
/**
|
|
@@ -1014,6 +1054,14 @@ export const ReadOnly: Story = {
|
|
|
1014
1054
|
value: '@name == "Alice"',
|
|
1015
1055
|
readOnly: true,
|
|
1016
1056
|
},
|
|
1057
|
+
parameters: {
|
|
1058
|
+
docs: {
|
|
1059
|
+
description: {
|
|
1060
|
+
story:
|
|
1061
|
+
'Renders the DpqlEditor with a valued expression but readOnly enabled — the field chip and literal render but the editor cannot be edited.',
|
|
1062
|
+
},
|
|
1063
|
+
},
|
|
1064
|
+
},
|
|
1017
1065
|
};
|
|
1018
1066
|
|
|
1019
1067
|
/**
|
|
@@ -1131,6 +1179,14 @@ export const CanTypeText: Story = {
|
|
|
1131
1179
|
value: '',
|
|
1132
1180
|
onChange: fn(),
|
|
1133
1181
|
},
|
|
1182
|
+
parameters: {
|
|
1183
|
+
docs: {
|
|
1184
|
+
description: {
|
|
1185
|
+
story:
|
|
1186
|
+
'Renders the empty DpqlEditor and types "hello" into it — the editor accepts the plain text and fires onChange.',
|
|
1187
|
+
},
|
|
1188
|
+
},
|
|
1189
|
+
},
|
|
1134
1190
|
play: async ({ canvasElement, args }) => {
|
|
1135
1191
|
const canvas = within(canvasElement);
|
|
1136
1192
|
|
|
@@ -1153,6 +1209,14 @@ export const LspCompletionRoundtrip: Story = {
|
|
|
1153
1209
|
value: '',
|
|
1154
1210
|
onChange: fn(),
|
|
1155
1211
|
},
|
|
1212
|
+
parameters: {
|
|
1213
|
+
docs: {
|
|
1214
|
+
description: {
|
|
1215
|
+
story:
|
|
1216
|
+
'Renders the empty DpqlEditor and types the "@" trigger — the LSP receives a textDocument/completion request against a dpql:// document URI and the dropdown mounts with the canned @name / @status / @age items.',
|
|
1217
|
+
},
|
|
1218
|
+
},
|
|
1219
|
+
},
|
|
1156
1220
|
play: async ({ canvasElement }) => {
|
|
1157
1221
|
const canvas = within(canvasElement);
|
|
1158
1222
|
|
|
@@ -1199,7 +1263,15 @@ export const LspCompletionRoundtrip: Story = {
|
|
|
1199
1263
|
* single physical connection and a single `initialize` handshake.
|
|
1200
1264
|
*/
|
|
1201
1265
|
export const TwoEditorsOneConnection: Story = {
|
|
1202
|
-
parameters: {
|
|
1266
|
+
parameters: {
|
|
1267
|
+
chromatic: { disable: true },
|
|
1268
|
+
docs: {
|
|
1269
|
+
description: {
|
|
1270
|
+
story:
|
|
1271
|
+
'Renders two DpqlEditor instances side by side — both share a single WebSocket via LspSharedConnection and each opens its own document URI, so the server sees one initialize but two didOpen notifications.',
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
},
|
|
1203
1275
|
render: () => (
|
|
1204
1276
|
<>
|
|
1205
1277
|
<DpqlEditorWithState value='name' />
|