@qoretechnologies/reqraft 0.10.65 → 0.10.66-pr.145.g32331ea

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 (85) hide show
  1. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  2. package/dist/components/form/engine/CompactRow.js +128 -24
  3. package/dist/components/form/engine/CompactRow.js.map +1 -1
  4. package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
  5. package/dist/components/form/engine/CompactToolbar.js +78 -15
  6. package/dist/components/form/engine/CompactToolbar.js.map +1 -1
  7. package/dist/components/form/engine/FormEngine.d.ts +48 -1
  8. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  9. package/dist/components/form/engine/FormEngine.js +243 -85
  10. package/dist/components/form/engine/FormEngine.js.map +1 -1
  11. package/dist/components/form/engine/OptionFieldMessages.d.ts +18 -2
  12. package/dist/components/form/engine/OptionFieldMessages.d.ts.map +1 -1
  13. package/dist/components/form/engine/OptionFieldMessages.js +22 -3
  14. package/dist/components/form/engine/OptionFieldMessages.js.map +1 -1
  15. package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
  16. package/dist/components/form/engine/_structuredData/SchemaDataView.js +27 -1
  17. package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
  18. package/dist/components/form/engine/compactRowContext.d.ts +5 -0
  19. package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
  20. package/dist/components/form/engine/compactRowContext.js.map +1 -1
  21. package/dist/components/form/engine/compactRowStyles.d.ts +12 -0
  22. package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
  23. package/dist/components/form/engine/compactRowStyles.js +72 -39
  24. package/dist/components/form/engine/compactRowStyles.js.map +1 -1
  25. package/dist/components/form/engine/compactToolbarContext.d.ts +3 -0
  26. package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
  27. package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
  28. package/dist/components/form/engine/formAppearance.d.ts +48 -0
  29. package/dist/components/form/engine/formAppearance.d.ts.map +1 -0
  30. package/dist/components/form/engine/formAppearance.js +50 -0
  31. package/dist/components/form/engine/formAppearance.js.map +1 -0
  32. package/dist/components/form/engine/readFirst.d.ts +14 -2
  33. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  34. package/dist/components/form/engine/readFirst.js +6 -2
  35. package/dist/components/form/engine/readFirst.js.map +1 -1
  36. package/dist/components/form/engine/rowFocus.d.ts +9 -1
  37. package/dist/components/form/engine/rowFocus.d.ts.map +1 -1
  38. package/dist/components/form/engine/rowFocus.js +17 -5
  39. package/dist/components/form/engine/rowFocus.js.map +1 -1
  40. package/dist/components/form/fields/ChoiceGroupHeading.d.ts +21 -0
  41. package/dist/components/form/fields/ChoiceGroupHeading.d.ts.map +1 -0
  42. package/dist/components/form/fields/ChoiceGroupHeading.js +33 -0
  43. package/dist/components/form/fields/ChoiceGroupHeading.js.map +1 -0
  44. package/dist/components/form/fields/Field.d.ts.map +1 -1
  45. package/dist/components/form/fields/Field.js +5 -3
  46. package/dist/components/form/fields/Field.js.map +1 -1
  47. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
  48. package/dist/components/form/fields/allowed-values/AllowedValues.js +4 -2
  49. package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
  50. package/dist/components/form/fields/radio-group/RadioGroup.d.ts.map +1 -1
  51. package/dist/components/form/fields/radio-group/RadioGroup.js +13 -7
  52. package/dist/components/form/fields/radio-group/RadioGroup.js.map +1 -1
  53. package/dist/components/form/index.d.ts +1 -0
  54. package/dist/components/form/index.d.ts.map +1 -1
  55. package/dist/components/form/index.js +1 -0
  56. package/dist/components/form/index.js.map +1 -1
  57. package/dist/components/supportTicket/TicketHeader.d.ts.map +1 -1
  58. package/dist/components/supportTicket/TicketHeader.js +4 -1
  59. package/dist/components/supportTicket/TicketHeader.js.map +1 -1
  60. package/dist/components/supportTicket/TicketReplyBox.d.ts.map +1 -1
  61. package/dist/components/supportTicket/TicketReplyBox.js +29 -10
  62. package/dist/components/supportTicket/TicketReplyBox.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/components/form/engine/CompactRow.tsx +141 -22
  65. package/src/components/form/engine/CompactToolbar.tsx +85 -16
  66. package/src/components/form/engine/FormEngine.stories.tsx +25 -13
  67. package/src/components/form/engine/FormEngine.tsx +358 -77
  68. package/src/components/form/engine/FormEngineAppearance.stories.tsx +540 -0
  69. package/src/components/form/engine/FormEngineStickyHeaders.stories.tsx +5 -1
  70. package/src/components/form/engine/OptionFieldMessages.tsx +73 -2
  71. package/src/components/form/engine/_structuredData/SchemaDataView.tsx +17 -4
  72. package/src/components/form/engine/compactRowContext.ts +5 -0
  73. package/src/components/form/engine/compactRowStyles.ts +218 -38
  74. package/src/components/form/engine/compactToolbarContext.ts +3 -0
  75. package/src/components/form/engine/formAppearance.ts +78 -0
  76. package/src/components/form/engine/readFirst.ts +16 -3
  77. package/src/components/form/engine/rowFocus.ts +17 -6
  78. package/src/components/form/fields/ChoiceGroupHeading.tsx +38 -0
  79. package/src/components/form/fields/Field.tsx +6 -5
  80. package/src/components/form/fields/allowed-values/AllowedValues.tsx +7 -4
  81. package/src/components/form/fields/radio-group/RadioGroup.tsx +13 -7
  82. package/src/components/form/index.tsx +1 -0
  83. package/src/components/supportTicket/TicketHeader.tsx +2 -1
  84. package/src/components/supportTicket/TicketReplyBox.stories.tsx +17 -2
  85. package/src/components/supportTicket/TicketReplyBox.tsx +27 -5
@@ -8,7 +8,7 @@
8
8
  // - `ConnectionManagement` per-item actions — dropped (actions omitted).
9
9
  // - `Select` → reqraft `SelectFormField` (`items` instead of `defaultItems`,
10
10
  // single-arg `onChange`; `type`/`closeCollectionOnUnMount` not forwarded).
11
- import { ReqoreCheckbox, ReqoreControlGroup, ReqoreSpan } from '@qoretechnologies/reqore';
11
+ import { ReqoreCheckbox, ReqoreControlGroup } from '@qoretechnologies/reqore';
12
12
  import { IReqoreButtonProps } from '@qoretechnologies/reqore/dist/components/Button';
13
13
  import { IQorusAllowedValue, TQorusType } from '@qoretechnologies/ts-toolkit';
14
14
  import { size as count, isEqual } from 'lodash';
@@ -20,6 +20,7 @@ import {
20
20
  } from '../select/SelectCollection';
21
21
  import { ISelectFormFieldItem, SelectFormField as Select } from '../select/Select';
22
22
  import { useAllowedValueAvailability } from '../../engine/OptionFieldMessages';
23
+ import { ChoiceGroupHeading, useSelectedChoiceIntent } from '../ChoiceGroupHeading';
23
24
  import type { IReqraftAllowedValue } from '../Field';
24
25
 
25
26
  export interface IFieldAllowedValuesProps extends Pick<
@@ -97,13 +98,15 @@ export const FieldAllowedValuesCheckGroup = memo(
97
98
  */
98
99
  label?: string;
99
100
  }) => {
101
+ const selectedChoiceIntent = useSelectedChoiceIntent();
102
+
100
103
  return (
101
104
  <ReqoreControlGroup vertical size={rest.size || 'small'} gapSize='tiny'>
102
- <ReqoreSpan effect={{ opacity: 0.6, uppercase: true, weight: 'bold' }} size='tiny'>
105
+ <ChoiceGroupHeading>
103
106
  {label ? `${label}:`
104
107
  : multiSelect ? 'Select one or more:'
105
108
  : 'Select one:'}
106
- </ReqoreSpan>
109
+ </ChoiceGroupHeading>
107
110
  {items?.map((item) => {
108
111
  const unavailable = getSelectItemUnavailability(item);
109
112
 
@@ -134,7 +137,7 @@ export const FieldAllowedValuesCheckGroup = memo(
134
137
  which keeps the pointer events the tooltip is read through.
135
138
  It does not withhold `onClick` — the handler below does. */
136
139
  readOnly={rest.readOnly || !!unavailable}
137
- intent={item.value === value ? 'info' : undefined}
140
+ intent={selectedChoiceIntent(item.value === value)}
138
141
  // `isEqual`, and only once there is a value to match. The single
139
142
  // -select branch compared JSON.stringify(value) with
140
143
  // JSON.stringify(item.value), and JSON.stringify(undefined) is
@@ -1,6 +1,7 @@
1
1
  import { ReqoreRadioGroup } from '@qoretechnologies/reqore';
2
2
  import { IReqoreRadioGroupProps } from '@qoretechnologies/reqore/dist/components/RadioGroup';
3
3
  import { useMemo } from 'react';
4
+ import { useIsCalmForm } from '../../engine/formAppearance';
4
5
 
5
6
  export interface IRadioGroupFormFieldProps
6
7
  extends Omit<IReqoreRadioGroupProps, 'onChange' | 'onSelectClick' | 'selected'> {
@@ -16,20 +17,25 @@ export const RadioGroupFormField = ({
16
17
  value,
17
18
  ...rest
18
19
  }: IRadioGroupFormFieldProps) => {
20
+ const calm = useIsCalmForm();
19
21
  const items: IReqoreRadioGroupProps['items'] = useMemo(
20
22
  () =>
21
23
  _items.map((item) => ({
22
24
  margin: 'right',
23
- labelEffect: {
24
- spaced: 1,
25
- weight: 'bold',
26
- uppercase: true,
27
- textSize: 'small',
28
- },
25
+ // Calm: an option's name as written — a choice is read, not shouted.
26
+ labelEffect:
27
+ calm ?
28
+ { textSize: 'small' }
29
+ : {
30
+ spaced: 1,
31
+ weight: 'bold',
32
+ uppercase: true,
33
+ textSize: 'small',
34
+ },
29
35
  ...item,
30
36
  disabled: disabled || item.disabled,
31
37
  })),
32
- [_items]
38
+ [_items, calm]
33
39
  );
34
40
 
35
41
  return (
@@ -24,6 +24,7 @@ export * from './fields/string/String';
24
24
  export * from './fields/template/ExampleValueModal';
25
25
  export * from './fields/template/TemplateField';
26
26
  export * from './engine/FormEngine';
27
+ export * from './engine/formAppearance';
27
28
  export * from './engine/FormFieldsSkeleton';
28
29
  export * from './engine/optionActions';
29
30
  export * from './engine/rendererTypes';
@@ -201,7 +201,8 @@ export const TicketHeader = ({
201
201
  and the strip would no longer line up with them. */
202
202
  rowPadding='tiny'
203
203
  labelWidth={LABEL_WIDTH}
204
- uppercaseLabels
204
+ /* The labels' case is the theme's (`theme.uppercaseLabels`): an app that sets its
205
+ labels in sentence case gets "Opened by", not "OPENED BY". */
205
206
  flat
206
207
  transparent
207
208
  padded={false}
@@ -16,6 +16,19 @@ const meta = {
16
16
  export default meta;
17
17
  type Story = StoryObj<typeof meta>;
18
18
 
19
+ /**
20
+ * The reply is sent with the white primary, never the Qonsole purple: a ticket reply is not a
21
+ * hand-off to Qonsole (instruction-files decision 002). Read from the drawn button, so a theme
22
+ * or a default that brings the purple back fails here.
23
+ */
24
+ const expectWhiteSend = async (canvasElement: HTMLElement) => {
25
+ const send = within(canvasElement).getByText('Send reply').closest('button')!;
26
+ await waitFor(() => {
27
+ const [r, g, b] = getComputedStyle(send).backgroundColor.match(/\d+/g)!.map(Number);
28
+ expect(Math.min(r, g, b)).toBeGreaterThan(200);
29
+ });
30
+ };
31
+
19
32
  /**
20
33
  * The customer composer, plain-editor variant (used here for a deterministic
21
34
  * type→send test): an attach button (no extra menu → a plain button, not a
@@ -27,7 +40,7 @@ export const Default: Story = {
27
40
  docs: {
28
41
  description: {
29
42
  story:
30
- "Renders the customer composer's plain-editor variant — an attach button and Send, no internal-note toggle; typing a reply enables Send, which calls onSend with the body and internal: false.",
43
+ "Renders the customer composer's plain-editor variant — an attach button and Send, no internal-note toggle; typing a reply enables Send — the white primary, not the Qonsole purple — which calls onSend with the body and internal: false.",
31
44
  },
32
45
  },
33
46
  },
@@ -39,6 +52,7 @@ export const Default: Story = {
39
52
  await expect(canvas.queryByText('Internal note')).not.toBeInTheDocument();
40
53
 
41
54
  await userEvent.type(textarea!, 'Here is my reply');
55
+ await expectWhiteSend(canvasElement);
42
56
  await userEvent.click(canvas.getByText('Send reply'));
43
57
  await waitFor(() =>
44
58
  expect(args.onSend).toHaveBeenCalledWith(
@@ -59,7 +73,7 @@ export const StaffWithInternalNote: Story = {
59
73
  docs: {
60
74
  description: {
61
75
  story:
62
- "Renders the staff composer with a split send button — the primary action posts a public reply, while the caret opens 'Add internal note', which sends with internal: true.",
76
+ "Renders the staff composer with a split send button — the primary action (white, not the Qonsole purple) posts a public reply, while the caret opens 'Add internal note', which sends with internal: true.",
63
77
  },
64
78
  },
65
79
  },
@@ -72,6 +86,7 @@ export const StaffWithInternalNote: Story = {
72
86
 
73
87
  const textarea = canvasElement.querySelector('textarea');
74
88
  await userEvent.type(textarea!, 'internal context');
89
+ await expectWhiteSend(canvasElement);
75
90
 
76
91
  // "Add internal note" lives behind the split-send caret
77
92
  const caret = canvasElement.querySelector('.ticket-send-more');
@@ -1,9 +1,29 @@
1
1
  import type { TReqoreDropdownItems } from '@qoretechnologies/reqore/dist/components/Dropdown/list';
2
2
  import { ReactNode } from 'react';
3
- import { Composer, IComposerSendAction, TComposerEditor } from '../composer/Composer';
3
+ import {
4
+ Composer,
5
+ IComposerProps,
6
+ IComposerSendAction,
7
+ TComposerEditor,
8
+ } from '../composer/Composer';
4
9
  import { fileToAttachment as defaultFileToAttachment } from './fileToAttachment';
5
10
  import { IAttachmentUpload } from './meta';
6
11
 
12
+ /**
13
+ * A ticket reply is not a hand-off to Qonsole, so it does not wear Qonsole's look: no purple
14
+ * bar, no purple send (instruction-files decision 002 — a purple button means "this hands the
15
+ * work to Qonsole / AI" and nothing else). The bar keeps the composer's shape with the theme's
16
+ * own neutral edge (its `main`, a step lighter — how Reqore draws its dividers), and sending
17
+ * the reply is the surface's one primary action: white.
18
+ */
19
+ const REPLY_BOX_EFFECT: IComposerProps['effect'] = {
20
+ gradient: { direction: 'to bottom right', colors: 'main:lighten:3' },
21
+ };
22
+ const REPLY_SEND_STYLE: Pick<IComposerSendAction, 'intent' | 'minimal'> = {
23
+ intent: 'white',
24
+ minimal: false,
25
+ };
26
+
7
27
  /**
8
28
  * The `items` shape ReqoreDropdown accepts. Named, not derived: `ReqoreDropdown`
9
29
  * is a generic component, and `ComponentProps` of a generic resolves to `{}`
@@ -96,16 +116,15 @@ export const TicketReplyBox = ({
96
116
  : 'Send reply';
97
117
 
98
118
  // Staff surface splits the send button; customer surface is a single "Send reply".
99
- // Both use the Qonsole-style minimal `custom1` accent (the Composer default); the
100
- // internal note stays amber (`warning`) so it can't be mistaken for a public reply.
119
+ // Both send the reply as the white primary (`REPLY_SEND_STYLE`); the internal note
120
+ // stays amber (`warning`) so it can't be mistaken for a public reply.
101
121
  const sendActions: IComposerSendAction[] | undefined = allowInternalNote
102
122
  ? [
103
123
  {
104
124
  id: 'reply',
105
125
  label: labelFor(false),
106
126
  icon: 'SendPlane2Line',
107
- minimal: true,
108
- customTheme: { main: 'custom1' },
127
+ ...REPLY_SEND_STYLE,
109
128
  },
110
129
  {
111
130
  id: 'internal',
@@ -139,7 +158,10 @@ export const TicketReplyBox = ({
139
158
  disabledReason={disabledReason}
140
159
  onSend={handleSend}
141
160
  sendLabel={labelFor(false)}
161
+ sendIntent={REPLY_SEND_STYLE.intent}
162
+ sendMinimal={REPLY_SEND_STYLE.minimal}
142
163
  sendActions={sendActions}
164
+ effect={REPLY_BOX_EFFECT}
143
165
  sendMenuClassName='ticket-send-more'
144
166
  attachMenuItems={attachMenuItems}
145
167
  footerActions={footerActions}