@qoretechnologies/reqore 0.37.9 → 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.
- package/__tests__/dropdown.test.tsx +10 -8
- package/__tests__/table.test.tsx +0 -1
- package/dist/components/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/components/Breadcrumbs/index.js +6 -4
- package/dist/components/Breadcrumbs/index.js.map +1 -1
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +5 -5
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/ControlGroup/index.d.ts.map +1 -1
- package/dist/components/ControlGroup/index.js +1 -1
- package/dist/components/ControlGroup/index.js.map +1 -1
- package/dist/components/Drawer/index.d.ts +1 -1
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Dropdown/index.d.ts +2 -2
- package/dist/components/Dropdown/index.d.ts.map +1 -1
- package/dist/components/Dropdown/index.js +5 -5
- package/dist/components/Dropdown/index.js.map +1 -1
- package/dist/components/Dropdown/item.d.ts +6 -5
- package/dist/components/Dropdown/item.d.ts.map +1 -1
- package/dist/components/Dropdown/item.js +14 -6
- package/dist/components/Dropdown/item.js.map +1 -1
- package/dist/components/Dropdown/list.d.ts +4 -2
- package/dist/components/Dropdown/list.d.ts.map +1 -1
- package/dist/components/Dropdown/list.js +33 -7
- package/dist/components/Dropdown/list.js.map +1 -1
- package/dist/components/Effect/index.d.ts +1 -0
- package/dist/components/Effect/index.d.ts.map +1 -1
- package/dist/components/Effect/index.js +39 -24
- package/dist/components/Effect/index.js.map +1 -1
- package/dist/components/InternalPopover/index.d.ts.map +1 -1
- package/dist/components/InternalPopover/index.js +21 -1
- package/dist/components/InternalPopover/index.js.map +1 -1
- package/dist/components/Menu/index.js +4 -4
- package/dist/components/Menu/index.js.map +1 -1
- package/dist/components/Menu/item.d.ts +1 -1
- package/dist/components/Menu/item.d.ts.map +1 -1
- package/dist/components/Menu/item.js +6 -6
- package/dist/components/Menu/item.js.map +1 -1
- package/dist/components/Message/index.d.ts.map +1 -1
- package/dist/components/Message/index.js +3 -4
- package/dist/components/Message/index.js.map +1 -1
- package/dist/components/MultiSelect/index.js +2 -2
- package/dist/components/MultiSelect/index.js.map +1 -1
- package/dist/components/Notifications/notification.d.ts +1 -0
- package/dist/components/Notifications/notification.d.ts.map +1 -1
- package/dist/components/Notifications/notification.js +10 -21
- package/dist/components/Notifications/notification.js.map +1 -1
- package/dist/components/Panel/LabelEditor.d.ts +12 -0
- package/dist/components/Panel/LabelEditor.d.ts.map +1 -0
- package/dist/components/Panel/LabelEditor.js +61 -0
- package/dist/components/Panel/LabelEditor.js.map +1 -0
- package/dist/components/Panel/index.d.ts +11 -1
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +65 -22
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/components/Tabs/content.d.ts +4 -2
- package/dist/components/Tabs/content.d.ts.map +1 -1
- package/dist/components/Tabs/content.js +22 -5
- package/dist/components/Tabs/content.js.map +1 -1
- package/dist/components/Textarea/index.d.ts +4 -0
- package/dist/components/Textarea/index.d.ts.map +1 -1
- package/dist/components/Textarea/index.js +20 -5
- package/dist/components/Textarea/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Breadcrumbs/index.tsx +19 -5
- package/src/components/Button/index.tsx +12 -11
- package/src/components/ControlGroup/index.tsx +1 -0
- package/src/components/Drawer/index.tsx +1 -1
- package/src/components/Dropdown/index.tsx +16 -14
- package/src/components/Dropdown/item.tsx +26 -10
- package/src/components/Dropdown/list.tsx +80 -30
- package/src/components/Effect/index.tsx +46 -15
- package/src/components/InternalPopover/index.tsx +24 -1
- package/src/components/Menu/index.tsx +2 -2
- package/src/components/Menu/item.tsx +93 -85
- package/src/components/Message/index.tsx +39 -35
- package/src/components/MultiSelect/index.tsx +2 -2
- package/src/components/Notifications/notification.tsx +34 -30
- package/src/components/Panel/LabelEditor.tsx +67 -0
- package/src/components/Panel/index.tsx +99 -25
- package/src/components/Tabs/content.tsx +44 -7
- package/src/components/Textarea/index.tsx +77 -27
- package/src/mock/breadcrumbs.ts +12 -1
- package/src/stories/Dropdown/Dropdown.stories.tsx +58 -0
- package/src/stories/Dropdown/DropdownTests.stories.tsx +78 -0
- package/src/stories/Message/Message.stories.tsx +13 -5
- package/src/stories/MultiSelect/MultiSelect.stories.tsx +2 -2
- package/src/stories/Panel/Panel.stories.tsx +123 -0
- package/src/stories/Popover/Popover.stories.tsx +41 -0
- package/src/stories/TextArea/TextArea.stories.tsx +49 -0
- package/src/stories/TextArea/TextAreaTests.stories.tsx +103 -0
- package/tests.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
|
-
import { isArray, size } from 'lodash';
|
|
2
|
+
import { isArray, omit, size } from 'lodash';
|
|
3
3
|
import { darken, rgba } from 'polished';
|
|
4
|
+
import { Resizable, ResizableProps } from 're-resizable';
|
|
4
5
|
import { ReactElement, forwardRef, useCallback, useMemo, useState } from 'react';
|
|
5
6
|
import { useMeasure, useUpdateEffect } from 'react-use';
|
|
6
7
|
import styled, { css } from 'styled-components';
|
|
@@ -44,8 +45,9 @@ import ReqoreControlGroup from '../ControlGroup';
|
|
|
44
45
|
import ReqoreDropdown from '../Dropdown';
|
|
45
46
|
import { IReqoreDropdownItem } from '../Dropdown/list';
|
|
46
47
|
import { IReqoreEffect, StyledEffect, TReqoreEffectColor } from '../Effect';
|
|
47
|
-
import {
|
|
48
|
+
import { StyledHeader } from '../Header';
|
|
48
49
|
import ReqoreIcon, { IReqoreIconProps, StyledIconWrapper } from '../Icon';
|
|
50
|
+
import { LabelEditor } from './LabelEditor';
|
|
49
51
|
import { ReqorePanelNonResponsiveActions } from './NonResponsiveActions';
|
|
50
52
|
|
|
51
53
|
export interface IReqorePanelSubAction extends Omit<IReqoreDropdownItem, 'value'> {}
|
|
@@ -92,6 +94,9 @@ export interface IReqorePanelProps
|
|
|
92
94
|
collapseButtonProps?: IReqoreButtonProps;
|
|
93
95
|
disabled?: boolean;
|
|
94
96
|
|
|
97
|
+
onLabelEdit?: (label: string | number) => void;
|
|
98
|
+
resizable?: ResizableProps;
|
|
99
|
+
|
|
95
100
|
breadcrumbs?: IReqoreBreadcrumbsProps;
|
|
96
101
|
|
|
97
102
|
onClose?: () => void;
|
|
@@ -164,7 +169,17 @@ export const StyledPanelTitleHeaderContent = styled.div`
|
|
|
164
169
|
}
|
|
165
170
|
`;
|
|
166
171
|
|
|
167
|
-
export
|
|
172
|
+
export type TPanelStyle = React.FC<
|
|
173
|
+
Omit<IReqorePanelProps, 'onResize' | 'size'> &
|
|
174
|
+
ResizableProps & {
|
|
175
|
+
ref?: any;
|
|
176
|
+
theme: IReqoreTheme;
|
|
177
|
+
effect: IReqoreEffect;
|
|
178
|
+
interactive?: boolean;
|
|
179
|
+
}
|
|
180
|
+
>;
|
|
181
|
+
|
|
182
|
+
export const StyledPanel: TPanelStyle = styled(StyledEffect)<IStyledPanel>`
|
|
168
183
|
background-color: ${({ theme, opacity = 1 }: IStyledPanel) =>
|
|
169
184
|
rgba(changeDarkness(getMainBackgroundColor(theme), 0.03), opacity)};
|
|
170
185
|
border-radius: ${({ rounded }) => (rounded ? RADIUS_FROM_SIZE.normal : 0)}px;
|
|
@@ -181,7 +196,6 @@ export const StyledPanel = styled(StyledEffect)<IStyledPanel>`
|
|
|
181
196
|
flex-flow: column;
|
|
182
197
|
position: relative;
|
|
183
198
|
backdrop-filter: ${({ blur, opacity }) => (blur && opacity < 1 ? `blur(${blur}px)` : undefined)};
|
|
184
|
-
transition: 0.2s ease-in-out;
|
|
185
199
|
width: ${({ fluid }) => (fluid ? '100%' : undefined)};
|
|
186
200
|
max-width: 100%;
|
|
187
201
|
flex: ${({ fluid }) => (fluid ? '1 auto' : '0 0 auto')};
|
|
@@ -255,10 +269,14 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
|
|
|
255
269
|
rgba(changeLightness(getMainBackgroundColor(theme), 0.03), opacity)};
|
|
256
270
|
justify-content: space-between;
|
|
257
271
|
// 2 is border that has to be added to the size + the button size + padding
|
|
258
|
-
min-height: ${({ size }) =>
|
|
272
|
+
min-height: ${({ size, transparent, flat, minimal }) =>
|
|
273
|
+
2 +
|
|
274
|
+
(SIZE_TO_PX[size] + ((transparent && flat) || minimal ? 0 : PADDING_FROM_SIZE[size]) * 2)}px;
|
|
259
275
|
align-items: center;
|
|
260
|
-
padding: ${({ noHorizontalPadding, size }: IStyledPanel) =>
|
|
261
|
-
`${
|
|
276
|
+
padding: ${({ noHorizontalPadding, size, transparent, flat, intent }: IStyledPanel) =>
|
|
277
|
+
`${transparent && flat && !intent ? 0 : PADDING_FROM_SIZE[size]}px ${
|
|
278
|
+
noHorizontalPadding ? 0 : `${PADDING_FROM_SIZE[size]}px`
|
|
279
|
+
}`};
|
|
262
280
|
border-bottom: ${({ theme, isCollapsed, flat, opacity = 1 }) =>
|
|
263
281
|
!isCollapsed && !flat
|
|
264
282
|
? `1px solid ${rgba(changeLightness(getMainBackgroundColor(theme), 0.2), opacity)}`
|
|
@@ -287,9 +305,18 @@ export const StyledPanelTitle = styled.div<IStyledPanel>`
|
|
|
287
305
|
`}
|
|
288
306
|
`;
|
|
289
307
|
|
|
308
|
+
export const StyledPanelTopBar = styled(StyledPanelTitle)`
|
|
309
|
+
padding-bottom: ${({ minimal, padded, size, transparent }: IStyledPanel) =>
|
|
310
|
+
!padded ? `${PADDING_FROM_SIZE[size]}px` : minimal || transparent ? 0 : undefined};
|
|
311
|
+
padding-top: ${({ minimal, size }: IStyledPanel) =>
|
|
312
|
+
minimal ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
313
|
+
`;
|
|
314
|
+
|
|
290
315
|
export const StyledPanelBottomActions = styled(StyledPanelTitle)`
|
|
291
|
-
padding: ${({
|
|
292
|
-
`${PADDING_FROM_SIZE[size]}px
|
|
316
|
+
padding-top: ${({ minimal, padded, size, transparent }: IStyledPanel) =>
|
|
317
|
+
!padded ? `${PADDING_FROM_SIZE[size]}px` : minimal || transparent ? 0 : undefined};
|
|
318
|
+
padding-bottom: ${({ minimal, size }: IStyledPanel) =>
|
|
319
|
+
minimal ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
293
320
|
border-bottom: 0;
|
|
294
321
|
border-top: ${({ theme, flat, opacity = 1 }) =>
|
|
295
322
|
!flat
|
|
@@ -299,18 +326,26 @@ export const StyledPanelBottomActions = styled(StyledPanelTitle)`
|
|
|
299
326
|
|
|
300
327
|
export const StyledPanelContent = styled.div<IStyledPanel>`
|
|
301
328
|
display: ${({ isCollapsed }) => (isCollapsed ? 'none !important' : undefined)};
|
|
302
|
-
padding: ${({ padded, size, noHorizontalPadding }) =>
|
|
329
|
+
padding: ${({ padded, size, noHorizontalPadding, minimal }) =>
|
|
303
330
|
!padded
|
|
304
331
|
? undefined
|
|
305
332
|
: noHorizontalPadding
|
|
306
333
|
? `${PADDING_FROM_SIZE[size]}px 0`
|
|
307
|
-
: `${PADDING_FROM_SIZE[size]}px`};
|
|
334
|
+
: `${PADDING_FROM_SIZE[size] / (minimal ? 2 : 1)}px ${PADDING_FROM_SIZE[size]}px`};
|
|
308
335
|
// The padding is not needed when the panel is minimal and has title, since
|
|
309
336
|
// the title already has padding and is transparent
|
|
310
337
|
padding-top: ${({ minimal, hasLabel, padded, size }) =>
|
|
311
|
-
minimal && hasLabel && padded
|
|
312
|
-
|
|
313
|
-
|
|
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};
|
|
314
349
|
flex: 1;
|
|
315
350
|
overflow: auto;
|
|
316
351
|
overflow-wrap: anywhere;
|
|
@@ -359,6 +394,8 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
359
394
|
breadcrumbs,
|
|
360
395
|
showActionsWhenCollapsed = true,
|
|
361
396
|
showHeaderTooltip,
|
|
397
|
+
resizable,
|
|
398
|
+
onLabelEdit,
|
|
362
399
|
...rest
|
|
363
400
|
}: IReqorePanelProps,
|
|
364
401
|
ref
|
|
@@ -382,6 +419,27 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
382
419
|
setIsCollapsed(!!isCollapsed);
|
|
383
420
|
}, [isCollapsed]);
|
|
384
421
|
|
|
422
|
+
const _resizable: ResizableProps = useMemo(() => {
|
|
423
|
+
const disabledProps: ResizableProps = {
|
|
424
|
+
enable: {
|
|
425
|
+
top: false,
|
|
426
|
+
right: false,
|
|
427
|
+
bottom: false,
|
|
428
|
+
left: false,
|
|
429
|
+
topRight: false,
|
|
430
|
+
bottomRight: false,
|
|
431
|
+
bottomLeft: false,
|
|
432
|
+
topLeft: false,
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
if (isCollapsed || disabled) {
|
|
437
|
+
return disabledProps;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return resizable || disabledProps;
|
|
441
|
+
}, [resizable, isCollapsed, disabled]);
|
|
442
|
+
|
|
385
443
|
// Return true if the card has a title bar, otherwise return false.
|
|
386
444
|
const hasTitleBar: boolean = useMemo(
|
|
387
445
|
() =>
|
|
@@ -626,11 +684,18 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
626
684
|
|
|
627
685
|
return (
|
|
628
686
|
<StyledPanel
|
|
629
|
-
{...rest}
|
|
630
|
-
|
|
687
|
+
{...omit(rest, ['onResize'])}
|
|
688
|
+
{..._resizable}
|
|
689
|
+
as={rest.as || !!resizable ? Resizable : 'div'}
|
|
631
690
|
ref={(ref) => {
|
|
632
|
-
|
|
633
|
-
|
|
691
|
+
let _ref = ref;
|
|
692
|
+
|
|
693
|
+
if (ref?.resizable) {
|
|
694
|
+
_ref = ref.resizable;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
targetRef.current = _ref;
|
|
698
|
+
setItemRef(_ref);
|
|
634
699
|
}}
|
|
635
700
|
isCollapsed={_isCollapsed}
|
|
636
701
|
rounded={rounded}
|
|
@@ -645,19 +710,23 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
645
710
|
disabled={disabled}
|
|
646
711
|
>
|
|
647
712
|
{hasTitleBar && (
|
|
648
|
-
<
|
|
713
|
+
<StyledPanelTopBar
|
|
649
714
|
flat={flat}
|
|
650
715
|
isCollapsed={_isCollapsed}
|
|
651
716
|
collapsible={collapsible}
|
|
652
717
|
className='reqore-panel-title'
|
|
653
718
|
onClick={handleCollapseClick}
|
|
654
719
|
theme={theme}
|
|
720
|
+
minimal={minimal}
|
|
655
721
|
size={contentSize || panelSize}
|
|
656
722
|
opacity={opacity ?? (minimal ? 0 : 1)}
|
|
657
723
|
noHorizontalPadding={noHorizontalPadding}
|
|
658
724
|
responsive={responsiveTitle}
|
|
659
725
|
isMobile={isMobile || isSmall}
|
|
660
726
|
ref={measureRef}
|
|
727
|
+
padded={padded}
|
|
728
|
+
transparent={rest.transparent || opacity === 0}
|
|
729
|
+
intent={intent}
|
|
661
730
|
>
|
|
662
731
|
{hasTitleHeader && (
|
|
663
732
|
<StyledPanelTitleHeader>
|
|
@@ -693,17 +762,17 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
693
762
|
/>
|
|
694
763
|
) : null}
|
|
695
764
|
{typeof label === 'string' ? (
|
|
696
|
-
<
|
|
765
|
+
<LabelEditor
|
|
697
766
|
size={headerSize || panelSize}
|
|
698
767
|
customTheme={theme}
|
|
699
768
|
effect={{
|
|
700
769
|
noWrap: true,
|
|
701
770
|
...headerEffect,
|
|
702
771
|
}}
|
|
772
|
+
label={label}
|
|
773
|
+
onSubmit={onLabelEdit}
|
|
703
774
|
tooltip={showHeaderTooltip ? label : undefined}
|
|
704
|
-
|
|
705
|
-
{label}
|
|
706
|
-
</ReqoreHeading>
|
|
775
|
+
/>
|
|
707
776
|
) : (
|
|
708
777
|
label
|
|
709
778
|
)}
|
|
@@ -761,13 +830,14 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
761
830
|
>
|
|
762
831
|
{actions.map(renderNonResponsiveActions())}
|
|
763
832
|
</ReqorePanelNonResponsiveActions>
|
|
764
|
-
</
|
|
833
|
+
</StyledPanelTopBar>
|
|
765
834
|
)}
|
|
766
835
|
{!_isCollapsed || (_isCollapsed && !unMountContentOnCollapse) ? (
|
|
767
836
|
<StyledPanelContent
|
|
768
837
|
as={'div'}
|
|
769
838
|
className='reqore-panel-content'
|
|
770
|
-
hasLabel={!!
|
|
839
|
+
hasLabel={!!hasTitleBar}
|
|
840
|
+
hasBottomActions={hasBottomActions}
|
|
771
841
|
isCollapsed={_isCollapsed}
|
|
772
842
|
style={contentStyle}
|
|
773
843
|
padded={padded}
|
|
@@ -784,6 +854,10 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
|
|
|
784
854
|
flat={flat}
|
|
785
855
|
className='reqore-panel-bottom-actions'
|
|
786
856
|
theme={theme}
|
|
857
|
+
padded={padded}
|
|
858
|
+
intent={intent}
|
|
859
|
+
minimal={minimal}
|
|
860
|
+
transparent={rest.transparent || opacity === 0}
|
|
787
861
|
opacity={opacity ?? (minimal ? 0 : 1)}
|
|
788
862
|
size={contentSize || panelSize}
|
|
789
863
|
noHorizontalPadding={noHorizontalPadding}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
|
+
import { PADDING_FROM_SIZE, TSizes } from '../../constants/sizes';
|
|
3
4
|
|
|
4
|
-
export type TReqoreTabsContentPadding =
|
|
5
|
+
export type TReqoreTabsContentPadding =
|
|
6
|
+
| 'horizontal'
|
|
7
|
+
| 'vertical'
|
|
8
|
+
| 'none'
|
|
9
|
+
| 'both'
|
|
10
|
+
| 'top'
|
|
11
|
+
| 'bottom'
|
|
12
|
+
| 'left'
|
|
13
|
+
| 'right'
|
|
14
|
+
| true
|
|
15
|
+
| false;
|
|
5
16
|
|
|
6
17
|
export interface IReqoreTabsContent extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
18
|
children?: any;
|
|
8
19
|
tabId: string | number;
|
|
9
20
|
padded?: TReqoreTabsContentPadding;
|
|
21
|
+
size?: TSizes;
|
|
10
22
|
}
|
|
11
23
|
|
|
12
24
|
const StyledTabsContent = styled.div`
|
|
@@ -14,16 +26,41 @@ const StyledTabsContent = styled.div`
|
|
|
14
26
|
flex-flow: column;
|
|
15
27
|
overflow: hidden;
|
|
16
28
|
flex: 1;
|
|
17
|
-
padding: ${({ padded }: IReqoreTabsContent) =>
|
|
29
|
+
padding: ${({ padded, size }: IReqoreTabsContent) =>
|
|
18
30
|
padded === 'none' || padded === false
|
|
19
31
|
? undefined
|
|
20
|
-
: `${
|
|
21
|
-
padded === 'both' || padded === true || padded === '
|
|
22
|
-
|
|
32
|
+
: `${
|
|
33
|
+
padded === 'both' || padded === true || padded === 'vertical'
|
|
34
|
+
? `${PADDING_FROM_SIZE[size]}px`
|
|
35
|
+
: 0
|
|
36
|
+
} ${
|
|
37
|
+
padded === 'both' || padded === true || padded === 'horizontal'
|
|
38
|
+
? `${PADDING_FROM_SIZE[size]}px`
|
|
39
|
+
: 0
|
|
40
|
+
}`};
|
|
41
|
+
padding-top: ${({ padded, size }: IReqoreTabsContent) =>
|
|
42
|
+
padded === 'top' ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
43
|
+
padding-bottom: ${({ padded, size }: IReqoreTabsContent) =>
|
|
44
|
+
padded === 'bottom' ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
45
|
+
padding-left: ${({ padded, size }: IReqoreTabsContent) =>
|
|
46
|
+
padded === 'left' ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
47
|
+
padding-right: ${({ padded, size }: IReqoreTabsContent) =>
|
|
48
|
+
padded === 'right' ? `${PADDING_FROM_SIZE[size]}px` : undefined};
|
|
23
49
|
`;
|
|
24
50
|
|
|
25
|
-
const ReqoreTabsContent = ({
|
|
26
|
-
|
|
51
|
+
const ReqoreTabsContent = ({
|
|
52
|
+
children,
|
|
53
|
+
className,
|
|
54
|
+
padded = true,
|
|
55
|
+
size = 'normal',
|
|
56
|
+
...rest
|
|
57
|
+
}: IReqoreTabsContent) => (
|
|
58
|
+
<StyledTabsContent
|
|
59
|
+
{...rest}
|
|
60
|
+
size={size}
|
|
61
|
+
padded={padded}
|
|
62
|
+
className={`${className || ''} reqore-tabs-content`}
|
|
63
|
+
>
|
|
27
64
|
{children}
|
|
28
65
|
</StyledTabsContent>
|
|
29
66
|
);
|
|
@@ -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
|
-
|
|
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
|
}
|
package/src/mock/breadcrumbs.ts
CHANGED
|
@@ -17,9 +17,20 @@ export default [
|
|
|
17
17
|
props: {
|
|
18
18
|
href: 'https://google.com',
|
|
19
19
|
},
|
|
20
|
-
|
|
20
|
+
leftIconProps: {
|
|
21
|
+
image:
|
|
22
|
+
'https://avatars.githubusercontent.com/u/44835090?s=400&u=371120ce0755102d2e432f11ad9aa0378c871b45&v=4',
|
|
23
|
+
},
|
|
21
24
|
flat: false,
|
|
22
25
|
intent: 'info',
|
|
26
|
+
effect: {
|
|
27
|
+
glow: {
|
|
28
|
+
color: 'info',
|
|
29
|
+
size: 1,
|
|
30
|
+
blur: 10,
|
|
31
|
+
when: 'hover',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
23
34
|
},
|
|
24
35
|
{
|
|
25
36
|
icon: Icons.Services,
|
|
@@ -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
|
-
|
|
43
|
-
|
|
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
|
|