@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.
Files changed (38) hide show
  1. package/.claude/CLAUDE.md +39 -18
  2. package/package.json +1 -1
  3. package/src/components/dpqlEditor/DpqlEditor.stories.tsx +74 -2
  4. package/src/components/form/engine/FormEngine.stories.tsx +654 -32
  5. package/src/components/form/engine/FormEngineRemote.stories.tsx +48 -0
  6. package/src/components/form/engine/_structuredData/StructuredDataView.stories.tsx +8 -0
  7. package/src/components/form/engine/variants/FormEngineVariants.stories.tsx +40 -0
  8. package/src/components/form/expressions/ExpressionField.stories.tsx +74 -2
  9. package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +187 -0
  10. package/src/components/form/fields/Field.stories.tsx +40 -0
  11. package/src/components/form/fields/array/ArrayAutoField.stories.tsx +64 -0
  12. package/src/components/form/fields/auto/AutoFormField.stories.tsx +136 -0
  13. package/src/components/form/fields/binary/Binary.stories.tsx +32 -0
  14. package/src/components/form/fields/boolean/Boolean.stories.tsx +24 -0
  15. package/src/components/form/fields/byte-size/ByteSize.stories.tsx +24 -0
  16. package/src/components/form/fields/color/Color.stories.tsx +30 -0
  17. package/src/components/form/fields/cron/Cron.stories.tsx +8 -0
  18. package/src/components/form/fields/date/Date.stories.tsx +22 -0
  19. package/src/components/form/fields/file/File.stories.tsx +48 -0
  20. package/src/components/form/fields/long-string/LongString.stories.tsx +24 -0
  21. package/src/components/form/fields/markdown/Markdown.stories.tsx +8 -0
  22. package/src/components/form/fields/number/Number.stories.tsx +31 -0
  23. package/src/components/form/fields/object/Object.stories.tsx +88 -0
  24. package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +24 -0
  25. package/src/components/form/fields/rich-text/RichText.stories.tsx +23 -0
  26. package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +72 -0
  27. package/src/components/form/fields/select/Select.stories.tsx +104 -0
  28. package/src/components/form/fields/string/String.stories.tsx +16 -0
  29. package/src/components/form/fields/template/TemplateField.stories.tsx +160 -0
  30. package/src/components/form/fields/url/Url.stories.tsx +24 -0
  31. package/src/components/log/Log.stories.tsx +96 -0
  32. package/src/components/menu/Menu.stories.tsx +54 -0
  33. package/src/components/qonsoleSmartInput/QonsoleSmartInput.stories.tsx +14 -0
  34. package/src/components/smartEditor/SmartEditor.stories.tsx +32 -0
  35. package/src/hooks/useFetch/useFetch.stories.tsx +30 -0
  36. package/src/hooks/useStorage/useStorage.stories.tsx +30 -0
  37. package/src/hooks/useWebSocket/useWebsocket.stories.tsx +127 -1
  38. package/src/stores/currentUser/currentUser.stories.tsx +17 -0
package/.claude/CLAUDE.md CHANGED
@@ -1,4 +1,36 @@
1
- # ReQraft AI Coding Agent Instructions
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
- - The package is in **beta** (pre-1.0): bump the **patch** for a PR — e.g. `0.10.4` → `0.10.5`. Do NOT bump minor/major for ordinary feature/fix PRs while in beta.
151
- - Bump in `package.json` only (no git tag): `npm version patch --no-git-tag-version`, and include it in the PR's commit.
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.9",
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: { chromatic: { disable: true } },
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' />