@qoretechnologies/reqore 0.38.0 → 0.38.1

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 (59) hide show
  1. package/__tests__/dropdown.test.tsx +10 -8
  2. package/__tests__/table.test.tsx +0 -1
  3. package/dist/components/Dropdown/index.d.ts +2 -2
  4. package/dist/components/Dropdown/index.d.ts.map +1 -1
  5. package/dist/components/Dropdown/index.js +5 -5
  6. package/dist/components/Dropdown/index.js.map +1 -1
  7. package/dist/components/Dropdown/item.d.ts +6 -5
  8. package/dist/components/Dropdown/item.d.ts.map +1 -1
  9. package/dist/components/Dropdown/item.js +14 -6
  10. package/dist/components/Dropdown/item.js.map +1 -1
  11. package/dist/components/Dropdown/list.d.ts +4 -2
  12. package/dist/components/Dropdown/list.d.ts.map +1 -1
  13. package/dist/components/Dropdown/list.js +33 -7
  14. package/dist/components/Dropdown/list.js.map +1 -1
  15. package/dist/components/Menu/index.js +4 -4
  16. package/dist/components/Menu/index.js.map +1 -1
  17. package/dist/components/Menu/item.d.ts +1 -1
  18. package/dist/components/Menu/item.d.ts.map +1 -1
  19. package/dist/components/Menu/item.js +6 -6
  20. package/dist/components/Menu/item.js.map +1 -1
  21. package/dist/components/Message/index.d.ts.map +1 -1
  22. package/dist/components/Message/index.js +3 -4
  23. package/dist/components/Message/index.js.map +1 -1
  24. package/dist/components/MultiSelect/index.js +2 -2
  25. package/dist/components/MultiSelect/index.js.map +1 -1
  26. package/dist/components/Notifications/notification.d.ts +1 -0
  27. package/dist/components/Notifications/notification.d.ts.map +1 -1
  28. package/dist/components/Notifications/notification.js +10 -21
  29. package/dist/components/Notifications/notification.js.map +1 -1
  30. package/dist/components/Panel/LabelEditor.d.ts.map +1 -1
  31. package/dist/components/Panel/LabelEditor.js +1 -1
  32. package/dist/components/Panel/LabelEditor.js.map +1 -1
  33. package/dist/components/Panel/index.d.ts.map +1 -1
  34. package/dist/components/Panel/index.js +22 -16
  35. package/dist/components/Panel/index.js.map +1 -1
  36. package/dist/components/Textarea/index.d.ts +4 -0
  37. package/dist/components/Textarea/index.d.ts.map +1 -1
  38. package/dist/components/Textarea/index.js +20 -5
  39. package/dist/components/Textarea/index.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/components/Dropdown/index.tsx +16 -14
  42. package/src/components/Dropdown/item.tsx +26 -10
  43. package/src/components/Dropdown/list.tsx +80 -30
  44. package/src/components/Menu/index.tsx +2 -2
  45. package/src/components/Menu/item.tsx +93 -85
  46. package/src/components/Message/index.tsx +39 -35
  47. package/src/components/MultiSelect/index.tsx +2 -2
  48. package/src/components/Notifications/notification.tsx +34 -30
  49. package/src/components/Panel/LabelEditor.tsx +1 -0
  50. package/src/components/Panel/index.tsx +24 -17
  51. package/src/components/Textarea/index.tsx +77 -27
  52. package/src/stories/Dropdown/Dropdown.stories.tsx +58 -0
  53. package/src/stories/Dropdown/DropdownTests.stories.tsx +78 -0
  54. package/src/stories/Message/Message.stories.tsx +13 -5
  55. package/src/stories/MultiSelect/MultiSelect.stories.tsx +2 -2
  56. package/src/stories/Panel/Panel.stories.tsx +86 -0
  57. package/src/stories/TextArea/TextArea.stories.tsx +49 -0
  58. package/src/stories/TextArea/TextAreaTests.stories.tsx +103 -0
  59. package/tests.json +1 -1
@@ -273,11 +273,9 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
273
273
  2 +
274
274
  (SIZE_TO_PX[size] + ((transparent && flat) || minimal ? 0 : PADDING_FROM_SIZE[size]) * 2)}px;
275
275
  align-items: center;
276
- padding: ${({ noHorizontalPadding, size, transparent, flat, minimal, intent }: IStyledPanel) =>
276
+ padding: ${({ noHorizontalPadding, size, transparent, flat, intent }: IStyledPanel) =>
277
277
  `${transparent && flat && !intent ? 0 : PADDING_FROM_SIZE[size]}px ${
278
- noHorizontalPadding
279
- ? 0
280
- : `${minimal ? PADDING_FROM_SIZE[size] / 2 : PADDING_FROM_SIZE[size]}px`
278
+ noHorizontalPadding ? 0 : `${PADDING_FROM_SIZE[size]}px`
281
279
  }`};
282
280
  border-bottom: ${({ theme, isCollapsed, flat, opacity = 1 }) =>
283
281
  !isCollapsed && !flat
@@ -308,17 +306,17 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
308
306
  `;
309
307
 
310
308
  export const StyledPanelTopBar = styled(StyledPanelTitle)`
311
- padding-bottom: ${({ minimal, padded, size }: IStyledPanel) =>
312
- !padded ? `${PADDING_FROM_SIZE[size] / (minimal ? 2 : 1)}px` : minimal ? 0 : undefined};
309
+ padding-bottom: ${({ minimal, padded, size, transparent }: IStyledPanel) =>
310
+ !padded ? `${PADDING_FROM_SIZE[size]}px` : minimal || transparent ? 0 : undefined};
313
311
  padding-top: ${({ minimal, size }: IStyledPanel) =>
314
- minimal ? `${PADDING_FROM_SIZE[size] / 2}px` : undefined};
312
+ minimal ? `${PADDING_FROM_SIZE[size]}px` : undefined};
315
313
  `;
316
314
 
317
315
  export const StyledPanelBottomActions = styled(StyledPanelTitle)`
318
- padding-top: ${({ minimal, padded, size }: IStyledPanel) =>
319
- !padded ? `${PADDING_FROM_SIZE[size] / (minimal ? 2 : 1)}px` : minimal ? 0 : undefined};
316
+ padding-top: ${({ minimal, padded, size, transparent }: IStyledPanel) =>
317
+ !padded ? `${PADDING_FROM_SIZE[size]}px` : minimal || transparent ? 0 : undefined};
320
318
  padding-bottom: ${({ minimal, size }: IStyledPanel) =>
321
- minimal ? `${PADDING_FROM_SIZE[size] / 2}px` : undefined};
319
+ minimal ? `${PADDING_FROM_SIZE[size]}px` : undefined};
322
320
  border-bottom: 0;
323
321
  border-top: ${({ theme, flat, opacity = 1 }) =>
324
322
  !flat
@@ -333,13 +331,21 @@ export const StyledPanelContent = styled.div<IStyledPanel>`
333
331
  ? undefined
334
332
  : noHorizontalPadding
335
333
  ? `${PADDING_FROM_SIZE[size]}px 0`
336
- : `${minimal ? PADDING_FROM_SIZE[size] / 2 : PADDING_FROM_SIZE[size]}px`};
334
+ : `${PADDING_FROM_SIZE[size] / (minimal ? 2 : 1)}px ${PADDING_FROM_SIZE[size]}px`};
337
335
  // The padding is not needed when the panel is minimal and has title, since
338
336
  // the title already has padding and is transparent
339
337
  padding-top: ${({ minimal, hasLabel, padded, size }) =>
340
- minimal && hasLabel && padded ? `${PADDING_FROM_SIZE[size] / 2}px` : undefined};
341
- padding-bottom: ${({ minimal, padded, size }) =>
342
- minimal && padded ? `${PADDING_FROM_SIZE[size] / 2}px` : undefined};
338
+ minimal && hasLabel && padded
339
+ ? `${PADDING_FROM_SIZE[size] / 2}px`
340
+ : padded
341
+ ? `${PADDING_FROM_SIZE[size]}px`
342
+ : undefined};
343
+ padding-bottom: ${({ minimal, padded, size, hasBottomActions }) =>
344
+ minimal && hasBottomActions && padded
345
+ ? `${PADDING_FROM_SIZE[size] / 2}px`
346
+ : padded
347
+ ? `${PADDING_FROM_SIZE[size]}px`
348
+ : undefined};
343
349
  flex: 1;
344
350
  overflow: auto;
345
351
  overflow-wrap: anywhere;
@@ -719,7 +725,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
719
725
  isMobile={isMobile || isSmall}
720
726
  ref={measureRef}
721
727
  padded={padded}
722
- transparent={rest.transparent}
728
+ transparent={rest.transparent || opacity === 0}
723
729
  intent={intent}
724
730
  >
725
731
  {hasTitleHeader && (
@@ -830,7 +836,8 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
830
836
  <StyledPanelContent
831
837
  as={'div'}
832
838
  className='reqore-panel-content'
833
- hasLabel={!!label}
839
+ hasLabel={!!hasTitleBar}
840
+ hasBottomActions={hasBottomActions}
834
841
  isCollapsed={_isCollapsed}
835
842
  style={contentStyle}
836
843
  padded={padded}
@@ -850,7 +857,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
850
857
  padded={padded}
851
858
  intent={intent}
852
859
  minimal={minimal}
853
- transparent={rest.transparent}
860
+ transparent={rest.transparent || opacity === 0}
854
861
  opacity={opacity ?? (minimal ? 0 : 1)}
855
862
  size={contentSize || panelSize}
856
863
  noHorizontalPadding={noHorizontalPadding}
@@ -1,6 +1,7 @@
1
1
  import { rgba } from 'polished';
2
- import React, { forwardRef, useEffect, useState } from 'react';
2
+ import React, { forwardRef, useCallback, useEffect, useState } from 'react';
3
3
  import styled, { css } from 'styled-components';
4
+ import { ReqoreDropdown } from '../..';
4
5
  import { RADIUS_FROM_SIZE, SIZE_TO_PX, TEXT_FROM_SIZE, TSizes } from '../../constants/sizes';
5
6
  import { IReqoreTheme } from '../../constants/theme';
6
7
  import { changeLightness, getReadableColor } from '../../helpers/colors';
@@ -18,10 +19,13 @@ import {
18
19
  IWithReqoreEffect,
19
20
  IWithReqoreTooltip,
20
21
  } from '../../types/global';
22
+ import { IReqoreDropdownProps } from '../Dropdown';
21
23
  import { StyledEffect } from '../Effect';
22
24
  import { IReqoreInputStyle } from '../Input';
23
25
  import ReqoreInputClearButton from '../InputClearButton';
24
26
 
27
+ export interface IReqoreFormTemplates extends IReqoreDropdownProps {}
28
+
25
29
  export interface IReqoreTextareaProps
26
30
  extends React.HTMLAttributes<HTMLTextAreaElement>,
27
31
  IReqoreReadOnly,
@@ -46,6 +50,7 @@ export interface IReqoreTextareaProps
46
50
  onClearClick?: () => any;
47
51
  wrapperStyle?: React.CSSProperties;
48
52
  focusRules?: IReqoreAutoFocusRules;
53
+ templates?: IReqoreFormTemplates;
49
54
  }
50
55
 
51
56
  export interface IReqoreTextareaStyle extends IReqoreTextareaProps {
@@ -141,6 +146,7 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
141
146
  onChange,
142
147
  fixed,
143
148
  focusRules,
149
+ templates,
144
150
  ...rest
145
151
  }: IReqoreTextareaProps,
146
152
  ref
@@ -158,6 +164,75 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
158
164
  useAutosizeTextArea(inputRef, _value, scaleWithContent);
159
165
  useAutoFocus(inputRef, rest.readOnly || rest.disabled ? undefined : focusRules, onChange);
160
166
 
167
+ const handleItemSelect = useCallback(
168
+ (item) => {
169
+ if (!inputRef || !item || !item.value) {
170
+ return;
171
+ }
172
+ // Add the value of the selected item to the current value at the cursor position
173
+ const value = `${_value.slice(0, inputRef.selectionStart)}${item.value}${_value.slice(
174
+ inputRef.selectionEnd
175
+ )}`;
176
+
177
+ setValue(value);
178
+ },
179
+ [inputRef, _value]
180
+ );
181
+
182
+ const renderChildren = () => {
183
+ return (
184
+ <>
185
+ <StyledTextarea
186
+ {...rest}
187
+ effect={{
188
+ interactive: !rest?.disabled && !rest.readOnly,
189
+ ...rest?.effect,
190
+ }}
191
+ onChange={(e) => {
192
+ setValue(e.target.value);
193
+ onChange?.(e);
194
+ }}
195
+ as='textarea'
196
+ className={`${className || ''} reqore-control reqore-textarea`}
197
+ _size={size}
198
+ ref={(ref) => setInputRef(ref)}
199
+ theme={theme}
200
+ rounded={rounded}
201
+ rows={1}
202
+ value={_value}
203
+ readonly={rest?.readOnly}
204
+ />
205
+ <ReqoreInputClearButton
206
+ enabled={!rest?.readOnly && !rest?.disabled && !!(onClearClick && onChange)}
207
+ show={_value && _value !== ''}
208
+ onClick={onClearClick}
209
+ size={size}
210
+ />
211
+ </>
212
+ );
213
+ };
214
+
215
+ if (templates) {
216
+ return (
217
+ <ReqoreDropdown<Omit<IReqoreTextareaStyle & { ref: any }, 'content'>>
218
+ component={StyledTextareaWrapper}
219
+ className={`${className || ''} reqore-control-wrapper`}
220
+ width={width}
221
+ height={height}
222
+ fluid={fluid}
223
+ fixed={fixed}
224
+ _size={size}
225
+ theme={theme}
226
+ style={wrapperStyle}
227
+ ref={targetRef}
228
+ onItemSelect={handleItemSelect}
229
+ {...templates}
230
+ >
231
+ {renderChildren()}
232
+ </ReqoreDropdown>
233
+ );
234
+ }
235
+
161
236
  return (
162
237
  <StyledTextareaWrapper
163
238
  className={`${className || ''} reqore-control-wrapper`}
@@ -170,32 +245,7 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
170
245
  style={wrapperStyle}
171
246
  ref={targetRef}
172
247
  >
173
- <StyledTextarea
174
- {...rest}
175
- effect={{
176
- interactive: !rest?.disabled && !rest.readOnly,
177
- ...rest?.effect,
178
- }}
179
- onChange={(e) => {
180
- setValue(e.target.value);
181
- onChange?.(e);
182
- }}
183
- as='textarea'
184
- className={`${className || ''} reqore-control reqore-textarea`}
185
- _size={size}
186
- ref={(ref) => setInputRef(ref)}
187
- theme={theme}
188
- rounded={rounded}
189
- rows={1}
190
- value={_value}
191
- readonly={rest?.readOnly}
192
- />
193
- <ReqoreInputClearButton
194
- enabled={!rest?.readOnly && !rest?.disabled && !!(onClearClick && onChange)}
195
- show={_value && _value !== ''}
196
- onClick={onClearClick}
197
- size={size}
198
- />
248
+ {renderChildren()}
199
249
  </StyledTextareaWrapper>
200
250
  );
201
251
  }
@@ -1,6 +1,8 @@
1
1
  import { StoryFn, StoryObj } from '@storybook/react';
2
+ import { fireEvent, within } from '@storybook/testing-library';
2
3
  import ReqoreButton, { IReqoreButtonProps } from '../../components/Button';
3
4
  import { IReqoreDropdownProps } from '../../components/Dropdown';
5
+ import { sleep } from '../../helpers/utils';
4
6
  import { ReqoreControlGroup, ReqoreDropdown, ReqoreInput } from '../../index';
5
7
  import { StoryMeta } from '../utils';
6
8
  import { argManager } from '../utils/args';
@@ -315,3 +317,59 @@ export const WithCustomPaging: Story = {
315
317
 
316
318
  play: () => {},
317
319
  };
320
+
321
+ export const WithChildItems: Story = {
322
+ render: (args) => <ReqoreDropdown {...args} />,
323
+ args: {
324
+ label: 'Dropdown with child items',
325
+ items: [
326
+ {
327
+ label: 'Test',
328
+ description: 'I have children',
329
+ rightIcon: 'MenuLine',
330
+ rightIconColor: 'info:lighten:2',
331
+ items: [
332
+ {
333
+ label: 'Test child 1',
334
+ },
335
+ {
336
+ label: 'Test child 2',
337
+ },
338
+ {
339
+ label: 'Test child 3',
340
+ description: 'I have children too',
341
+ items: [
342
+ {
343
+ label: 'Test deep child 1',
344
+ },
345
+ {
346
+ label: 'Test deep child 2',
347
+ },
348
+ {
349
+ label: 'Test deep child 3',
350
+ },
351
+ ],
352
+ },
353
+ {
354
+ label: 'Test child 4',
355
+ },
356
+ ],
357
+ },
358
+ {
359
+ label: 'Normal item',
360
+ description: 'I have no children',
361
+ },
362
+ ],
363
+ },
364
+ play: async ({ canvasElement }) => {
365
+ const canvas = within(canvasElement);
366
+
367
+ await sleep(200);
368
+
369
+ await fireEvent.click(canvas.getAllByText('Dropdown with child items')[0]);
370
+
371
+ await sleep(200);
372
+
373
+ await fireEvent.click(canvas.getAllByText('Test')[0]);
374
+ },
375
+ };
@@ -0,0 +1,78 @@
1
+ import { expect } from '@storybook/jest';
2
+ import { StoryObj } from '@storybook/react';
3
+ import { fireEvent, waitFor, within } from '@storybook/testing-library';
4
+ import ReqoreButton, { IReqoreButtonProps } from '../../components/Button';
5
+ import { IReqoreDropdownProps } from '../../components/Dropdown';
6
+ import { ReqoreDropdown } from '../../index';
7
+ import { StoryMeta } from '../utils';
8
+ import { argManager } from '../utils/args';
9
+ import { WithChildItems } from './Dropdown.stories';
10
+
11
+ const { createArg, disableArg } = argManager<IReqoreDropdownProps>();
12
+
13
+ const meta = {
14
+ title: 'Form/Dropdown/Tests',
15
+ component: ReqoreDropdown,
16
+ parameters: {
17
+ chromatic: {
18
+ delay: 1500,
19
+ },
20
+ },
21
+ argTypes: {
22
+ ...disableArg('multiSelect'),
23
+ ...createArg('component', {
24
+ defaultValue: ReqoreButton,
25
+ table: {
26
+ disable: true,
27
+ },
28
+ }),
29
+ ...createArg('filterable', {
30
+ defaultValue: true,
31
+ name: 'Filterable',
32
+ type: 'boolean',
33
+ }),
34
+ ...createArg('items', {
35
+ table: {
36
+ disable: true,
37
+ },
38
+ }),
39
+ },
40
+ args: {
41
+ component: ReqoreButton,
42
+ filterable: true,
43
+ },
44
+ } as StoryMeta<typeof ReqoreDropdown<IReqoreButtonProps>>;
45
+
46
+ export default meta;
47
+
48
+ type Story = StoryObj<typeof meta>;
49
+
50
+ export const ItemsCanBeTraversed: Story = {
51
+ ...WithChildItems,
52
+ play: async ({ canvasElement, ...rest }) => {
53
+ const canvas = within(canvasElement);
54
+
55
+ await WithChildItems.play({ canvasElement, ...rest });
56
+
57
+ await waitFor(() => expect(canvas.getAllByText('Test child 3')[0]).toBeTruthy(), {
58
+ timeout: 5000,
59
+ });
60
+
61
+ await fireEvent.click(canvas.getAllByText('Test child 3')[0]);
62
+
63
+ await expect(canvas.getAllByText('Test deep child 3')[0]).toBeTruthy();
64
+ },
65
+ };
66
+
67
+ export const BackButtonsWork: Story = {
68
+ ...ItemsCanBeTraversed,
69
+ play: async ({ canvasElement, ...rest }) => {
70
+ const canvas = within(canvasElement);
71
+
72
+ await ItemsCanBeTraversed.play({ canvasElement, ...rest });
73
+
74
+ await fireEvent.click(document.querySelector('.reqore-dropdown-back-button'));
75
+
76
+ await expect(canvas.getAllByText('Test child 3')[0]).toBeTruthy();
77
+ },
78
+ };
@@ -39,11 +39,8 @@ const Template: StoryFn<IReqoreMessageProps> = (args: IReqoreMessageProps) => {
39
39
  return (
40
40
  <>
41
41
  <ReqoreMessage {...args} onClick={noop}>
42
- In to am attended desirous raptures declared diverted confined at. Collected instantly
43
- remaining up certainly to necessary as. Over walk dull into son boy door went new. At or
44
- happiness commanded daughters as. Is handsome an declared at received in extended vicinity
45
- subjects. Into miss on he over been late pain an. Only week bore boy what fat case left use.
46
- Match round scale now sex style far times. Your me past an much.
42
+ {args.children ||
43
+ 'In to am attended desirous raptures declared diverted confined at. Collected instantly remaining up certainly to necessary as. Over walk dull into son boy door went new. At or happiness commanded daughters as. Is handsome an declared at received in extended vicinity subjects. Into miss on he over been late pain an. Only week bore boy what fat case left use. Match round scale now sex style far times. Your me past an much.'}
47
44
  </ReqoreMessage>
48
45
  </>
49
46
  );
@@ -53,6 +50,16 @@ export const Basic: Story = {
53
50
  render: Template,
54
51
  };
55
52
 
53
+ export const NoTitle: Story = {
54
+ render: Template,
55
+ args: {
56
+ icon: 'InformationFill',
57
+ flat: true,
58
+ title: undefined,
59
+ children: 'This is a test',
60
+ },
61
+ };
62
+
56
63
  export const Flat: Story = {
57
64
  render: Template,
58
65
 
@@ -68,6 +75,7 @@ export const Minimal: Story = {
68
75
  args: {
69
76
  minimal: true,
70
77
  intent: 'danger',
78
+ size: 'small',
71
79
  },
72
80
  };
73
81
 
@@ -43,13 +43,13 @@ type Story = StoryObj<typeof meta>;
43
43
 
44
44
  const Template: StoryFn<IReqoreMultiSelectProps> = (args: IReqoreMultiSelectProps) => {
45
45
  const [selected, setSelected] = useState<string[]>([
46
- 'Existing item 1',
47
46
  'Existing item 3',
48
47
  'Disabled item',
49
- 'Minimal item with border',
50
48
  'itemWithNoLabel',
51
49
  ]);
52
50
 
51
+ console.log({ selected });
52
+
53
53
  return (
54
54
  <ReqoreMultiSelect
55
55
  value={selected}
@@ -359,6 +359,84 @@ export const Minimal: Story = {
359
359
  },
360
360
  };
361
361
 
362
+ export const MinimalOnlyContent: Story = {
363
+ render: Template,
364
+
365
+ args: {
366
+ label: undefined,
367
+ badge: undefined,
368
+ icon: undefined,
369
+ minimal: true,
370
+ actions: [
371
+ { label: 'test', show: false },
372
+ {
373
+ show: false,
374
+ group: [
375
+ { label: 'test 2', show: true },
376
+ { label: 'test 3', show: true },
377
+ ],
378
+ },
379
+ ],
380
+ bottomActions: [
381
+ { label: 'test', show: false, position: 'left' },
382
+ {
383
+ position: 'right',
384
+ show: false,
385
+ group: [
386
+ { label: 'test 2', show: true },
387
+ { label: 'test 3', show: true },
388
+ ],
389
+ },
390
+ ],
391
+ collapsible: false,
392
+ },
393
+ };
394
+
395
+ export const MinimalOnlyTopBar: Story = {
396
+ render: Template,
397
+
398
+ args: {
399
+ label: undefined,
400
+ badge: undefined,
401
+ icon: undefined,
402
+ minimal: true,
403
+ bottomActions: [
404
+ { label: 'test', show: false, position: 'left' },
405
+ {
406
+ position: 'right',
407
+ show: false,
408
+ group: [
409
+ { label: 'test 2', show: true },
410
+ { label: 'test 3', show: true },
411
+ ],
412
+ },
413
+ ],
414
+ collapsible: false,
415
+ },
416
+ };
417
+
418
+ export const MinimalOnlyBottomBar: Story = {
419
+ render: Template,
420
+
421
+ args: {
422
+ label: undefined,
423
+ badge: undefined,
424
+ icon: undefined,
425
+ minimal: true,
426
+ actions: [
427
+ { label: 'test', show: false },
428
+ {
429
+ show: false,
430
+ group: [
431
+ { label: 'test 2', show: true },
432
+ { label: 'test 3', show: true },
433
+ ],
434
+ },
435
+ ],
436
+ collapsible: false,
437
+ },
438
+ };
439
+
362
440
  export const MinimalWithIntent: Story = {
363
441
  render: Template,
364
442
 
@@ -370,6 +448,14 @@ export const MinimalWithIntent: Story = {
370
448
  },
371
449
  };
372
450
 
451
+ export const WithOpacity: Story = {
452
+ render: Template,
453
+
454
+ args: {
455
+ opacity: 0.5,
456
+ },
457
+ };
458
+
373
459
  export const Disabled: Story = {
374
460
  render: Template,
375
461
 
@@ -1,6 +1,9 @@
1
+ import { expect } from '@storybook/jest';
1
2
  import { StoryFn, StoryObj } from '@storybook/react';
3
+ import { fireEvent } from '@storybook/testing-library';
2
4
  import { useState } from 'react';
3
5
  import { IReqoreTextareaProps } from '../../components/Textarea';
6
+ import { sleep } from '../../helpers/utils';
4
7
  import { ReqoreControlGroup, ReqoreTextarea } from '../../index';
5
8
  import { StoryMeta } from '../utils';
6
9
  import { DisabledArg, MinimalArg, SizeArg, argManager } from '../utils/args';
@@ -236,3 +239,49 @@ export const Effect: Story = {
236
239
  },
237
240
  },
238
241
  };
242
+
243
+ export const WithTemplates: Story = {
244
+ render: (args) => <ReqoreTextarea {...args} />,
245
+
246
+ args: {
247
+ templates: {
248
+ handler: 'focus',
249
+ useTargetWidth: true,
250
+ noWrapper: true,
251
+ items: [
252
+ {
253
+ label: 'New message in discord',
254
+ icon: 'DiscordLine',
255
+ description: 'When a new message in discord is received',
256
+ items: [
257
+ {
258
+ divider: true,
259
+ label: 'Discord',
260
+ },
261
+ {
262
+ label: 'Author',
263
+ description: 'Author of the message',
264
+ value: '$state:{1.field.author}',
265
+ },
266
+ {
267
+ label: 'Content',
268
+ description: 'Content of the message',
269
+ value: '$state:{1.field.content}',
270
+ },
271
+ ],
272
+ },
273
+ {
274
+ label: 'New event in Google Calendar',
275
+ icon: 'Calendar2Fill',
276
+ description: 'When a new event is created in Google Calendar',
277
+ },
278
+ ],
279
+ },
280
+ },
281
+
282
+ play: async () => {
283
+ await sleep(200);
284
+ await fireEvent.focusIn(document.querySelector('textarea'));
285
+ await expect(document.querySelector('.reqore-popover-content')).toBeTruthy();
286
+ },
287
+ };