@qoretechnologies/reqore 0.40.4 → 0.40.6
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__/helpers/colors.test.tsx +16 -0
- package/build-storybook.log +119 -117
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +32 -7
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Effect/index.d.ts +3 -0
- package/dist/components/Effect/index.d.ts.map +1 -1
- package/dist/components/Effect/index.js.map +1 -1
- package/dist/components/Tag/group.d.ts +2 -0
- package/dist/components/Tag/group.d.ts.map +1 -1
- package/dist/components/Tag/group.js +37 -3
- package/dist/components/Tag/group.js.map +1 -1
- package/dist/components/Tag/index.d.ts +1 -0
- package/dist/components/Tag/index.d.ts.map +1 -1
- package/dist/components/Tag/index.js +26 -15
- package/dist/components/Tag/index.js.map +1 -1
- package/dist/helpers/colors.d.ts +3 -2
- package/dist/helpers/colors.d.ts.map +1 -1
- package/dist/helpers/colors.js +25 -9
- package/dist/helpers/colors.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Button/index.tsx +63 -18
- package/src/components/Effect/index.tsx +3 -0
- package/src/components/Tag/group.tsx +20 -1
- package/src/components/Tag/index.tsx +21 -0
- package/src/helpers/colors.ts +35 -11
- package/src/stories/Button/Button.stories.tsx +28 -5
- package/src/stories/Message/Message.stories.tsx +9 -0
- package/src/stories/Tag/Tag.stories.tsx +275 -265
- package/src/stories/Tag/TagGroup.stories.tsx +13 -3
- package/tests.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { size } from 'lodash';
|
|
1
2
|
import { rgba } from 'polished';
|
|
2
3
|
import React, { forwardRef, memo, useCallback, useMemo, useState } from 'react';
|
|
3
4
|
import styled, { css } from 'styled-components';
|
|
@@ -73,6 +74,7 @@ export interface IReqoreButtonProps
|
|
|
73
74
|
customTheme?: IReqoreCustomTheme;
|
|
74
75
|
wrap?: boolean;
|
|
75
76
|
badge?: TReqoreBadge | TReqoreBadge[];
|
|
77
|
+
|
|
76
78
|
description?: string | number;
|
|
77
79
|
maxWidth?: string;
|
|
78
80
|
textAlign?: 'left' | 'center' | 'right';
|
|
@@ -315,28 +317,53 @@ export const ButtonBadge = memo(({ wrapGroup, compact, ...props }: IReqoreButton
|
|
|
315
317
|
[props]
|
|
316
318
|
);
|
|
317
319
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
320
|
+
const content = Array.isArray(props.content) ? props.content : [props.content];
|
|
321
|
+
|
|
322
|
+
const leftBadges = content.filter(
|
|
323
|
+
(badge) => typeof badge === 'string' || typeof badge === 'number' || !badge?.align
|
|
324
|
+
);
|
|
325
|
+
const rightBadges = content.filter(
|
|
326
|
+
(badge) => typeof badge !== 'string' && typeof badge !== 'number' && badge?.align === 'right'
|
|
327
|
+
);
|
|
328
|
+
const middleBadges = content.filter(
|
|
329
|
+
(badge) => typeof badge !== 'string' && typeof badge !== 'number' && badge?.align === 'center'
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
const buildContent = (badge: TReqoreBadge) => {
|
|
333
|
+
if (typeof badge === 'string' || typeof badge === 'number') {
|
|
334
|
+
return { label: badge, align: undefined };
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return { ...badge, align: undefined };
|
|
338
|
+
};
|
|
332
339
|
|
|
333
340
|
return (
|
|
334
341
|
<>
|
|
335
342
|
<ReqoreSpacer
|
|
336
|
-
width={props.wrap ? undefined : PADDING_FROM_SIZE[props.size]}
|
|
343
|
+
width={props.wrap ? undefined : PADDING_FROM_SIZE[props.size] / (compact ? 2 : 1)}
|
|
337
344
|
height={!props.wrap ? undefined : PADDING_FROM_SIZE[props.size] / 2}
|
|
338
345
|
/>
|
|
339
|
-
{
|
|
346
|
+
{size(leftBadges) ? (
|
|
347
|
+
<ReqoreTagGroup wrap={wrapGroup} align='left'>
|
|
348
|
+
{leftBadges.map((badge, index) =>
|
|
349
|
+
renderTag({ ...props, content: buildContent(badge), key: index })
|
|
350
|
+
)}
|
|
351
|
+
</ReqoreTagGroup>
|
|
352
|
+
) : null}
|
|
353
|
+
{size(middleBadges) ? (
|
|
354
|
+
<ReqoreTagGroup wrap={wrapGroup} fluid align='center'>
|
|
355
|
+
{middleBadges.map((badge, index) =>
|
|
356
|
+
renderTag({ ...props, content: buildContent(badge), key: index })
|
|
357
|
+
)}
|
|
358
|
+
</ReqoreTagGroup>
|
|
359
|
+
) : null}
|
|
360
|
+
{size(rightBadges) ? (
|
|
361
|
+
<ReqoreTagGroup wrap={wrapGroup} align='right'>
|
|
362
|
+
{rightBadges.map((badge, index) =>
|
|
363
|
+
renderTag({ ...props, content: buildContent(badge), key: index })
|
|
364
|
+
)}
|
|
365
|
+
</ReqoreTagGroup>
|
|
366
|
+
) : null}
|
|
340
367
|
</>
|
|
341
368
|
);
|
|
342
369
|
});
|
|
@@ -402,6 +429,17 @@ const ReqoreButton = memo(
|
|
|
402
429
|
const hasLeftIcon = icon || leftIconProps?.image;
|
|
403
430
|
const hasRightIcon = rightIcon || rightIconProps?.image;
|
|
404
431
|
|
|
432
|
+
const hasRightAlignedBadge = useMemo(() => {
|
|
433
|
+
if (Array.isArray(badge)) {
|
|
434
|
+
return badge.some(
|
|
435
|
+
(badge) =>
|
|
436
|
+
typeof badge !== 'string' && typeof badge !== 'number' && badge?.align === 'right'
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return typeof badge !== 'string' && typeof badge !== 'number' && badge?.align === 'right';
|
|
441
|
+
}, [badge]);
|
|
442
|
+
|
|
405
443
|
return (
|
|
406
444
|
<StyledButton
|
|
407
445
|
{...rest}
|
|
@@ -498,7 +536,11 @@ const ReqoreButton = memo(
|
|
|
498
536
|
_children ? (
|
|
499
537
|
<ReqoreHorizontalSpacer
|
|
500
538
|
width={1}
|
|
501
|
-
style={
|
|
539
|
+
style={
|
|
540
|
+
textAlign !== 'right' && !hasRightAlignedBadge
|
|
541
|
+
? { marginLeft: 'auto' }
|
|
542
|
+
: undefined
|
|
543
|
+
}
|
|
502
544
|
/>
|
|
503
545
|
) : null
|
|
504
546
|
) : (
|
|
@@ -515,7 +557,10 @@ const ReqoreButton = memo(
|
|
|
515
557
|
style={
|
|
516
558
|
textAlign !== 'right' || iconsAlign === 'center'
|
|
517
559
|
? {
|
|
518
|
-
marginLeft:
|
|
560
|
+
marginLeft:
|
|
561
|
+
!hasRightAlignedBadge && (iconsAlign !== 'center' || !_children)
|
|
562
|
+
? 'auto'
|
|
563
|
+
: undefined,
|
|
519
564
|
marginRight:
|
|
520
565
|
iconsAlign === 'center' || (textAlign === 'center' && !_children)
|
|
521
566
|
? 'auto'
|
|
@@ -28,6 +28,9 @@ export type TReqoreEffectColorManipulationAlpha =
|
|
|
28
28
|
| 0.9
|
|
29
29
|
| 1;
|
|
30
30
|
export type TReqoreHexColor = `#${string}`;
|
|
31
|
+
export type TReqoreRgbColor = `rgb(${number}, ${number}, ${number})`;
|
|
32
|
+
export type TReqoreRgbaColor = `rgba(${number}, ${number}, ${number}, ${string})`;
|
|
33
|
+
export type TReqoreMultiTypeColor = TReqoreHexColor | TReqoreRgbColor | TReqoreRgbaColor;
|
|
31
34
|
export type TReqoreColor = TReqoreHexColor | 'transparent';
|
|
32
35
|
export type TReqoreEffectColor =
|
|
33
36
|
| (TReqoreColor | TReqoreHexColor | 'main' | TReqoreIntent)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
3
|
import { GAP_FROM_SIZE, TSizes } from '../../constants/sizes';
|
|
4
4
|
import { IWithReqoreMinimal, IWithReqoreSize } from '../../types/global';
|
|
5
5
|
|
|
@@ -11,13 +11,32 @@ export interface IReqoreTagGroup
|
|
|
11
11
|
gapSize?: TSizes;
|
|
12
12
|
columns?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
13
13
|
wrap?: boolean;
|
|
14
|
+
fluid?: boolean;
|
|
15
|
+
align?: 'left' | 'center' | 'right';
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
const StyledTagGroup = styled.div`
|
|
17
19
|
flex-shrink: ${({ wrap }: IReqoreTagGroup) => (wrap ? 1 : 0)};
|
|
20
|
+
flex-grow: ${({ fluid }: IReqoreTagGroup) => (fluid ? 1 : undefined)};
|
|
18
21
|
display: flex;
|
|
19
22
|
flex-wrap: ${({ wrap }: IReqoreTagGroup) => (wrap ? 'wrap' : 'nowrap')};
|
|
20
23
|
gap: ${({ gapSize }: IReqoreTagGroup) => GAP_FROM_SIZE[gapSize]}px;
|
|
24
|
+
|
|
25
|
+
${({ align }) => {
|
|
26
|
+
if (align === 'right') {
|
|
27
|
+
return css`
|
|
28
|
+
margin-left: auto;
|
|
29
|
+
justify-content: flex-end;
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (align === 'center') {
|
|
34
|
+
return css`
|
|
35
|
+
margin: 0 auto;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
}}
|
|
21
40
|
`;
|
|
22
41
|
|
|
23
42
|
const ReqoreTagGroup = ({
|
|
@@ -56,6 +56,7 @@ export interface IReqoreTagProps
|
|
|
56
56
|
IWithReqoreEffect,
|
|
57
57
|
IWithReqoreCustomTheme {
|
|
58
58
|
fixed?: boolean | 'key' | 'label';
|
|
59
|
+
align?: 'left' | 'right' | 'center';
|
|
59
60
|
size?: TSizes;
|
|
60
61
|
label?: string | number;
|
|
61
62
|
labelKey?: string | number;
|
|
@@ -105,6 +106,26 @@ export const StyledTag = styled(StyledEffect)<IReqoreTagStyle>`
|
|
|
105
106
|
width: ${({ width }) => width || undefined};
|
|
106
107
|
transition: all 0.2s ease-out;
|
|
107
108
|
|
|
109
|
+
${({ align }) => {
|
|
110
|
+
if (align === 'left') {
|
|
111
|
+
return css`
|
|
112
|
+
margin-right: auto;
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (align === 'right') {
|
|
117
|
+
return css`
|
|
118
|
+
margin-left: auto;
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (align === 'center') {
|
|
123
|
+
return css`
|
|
124
|
+
margin: 0 auto;
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
}}
|
|
128
|
+
|
|
108
129
|
${InactiveIconScale};
|
|
109
130
|
|
|
110
131
|
${({ wrap, hasWidth }) =>
|
package/src/helpers/colors.ts
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
TReqoreEffectGradientColors,
|
|
7
7
|
TReqoreEffectGradientColorsObject,
|
|
8
8
|
TReqoreHexColor,
|
|
9
|
+
TReqoreMultiTypeColor,
|
|
10
|
+
TReqoreRgbaColor,
|
|
9
11
|
} from '../components/Effect';
|
|
10
12
|
import { Colors } from '../constants/colors';
|
|
11
13
|
import { DEFAULT_INTENTS, IReqoreTheme, TReqoreIntent } from '../constants/theme';
|
|
@@ -39,8 +41,9 @@ export const getReadableColorFrom = (
|
|
|
39
41
|
): TReqoreHexColor => {
|
|
40
42
|
const returnIfLight = ifLight || lighten(dim ? 0.05 : 0, Colors.DARK);
|
|
41
43
|
const returnIfDark = ifDark || darken(dim ? 0.05 : 0, Colors.LIGHT);
|
|
44
|
+
const fixedColor = hexAToRGBA(from);
|
|
42
45
|
|
|
43
|
-
return readableColor(
|
|
46
|
+
return readableColor(fixedColor, returnIfLight, returnIfDark, false) as TReqoreHexColor;
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
export const percentToHexAlpha = (p: number) => {
|
|
@@ -51,6 +54,22 @@ export const percentToHexAlpha = (p: number) => {
|
|
|
51
54
|
return hexValue.padStart(2, '0').toUpperCase(); // format with leading 0 and upper case characters
|
|
52
55
|
};
|
|
53
56
|
|
|
57
|
+
export const hexAToRGBA = (hex: TReqoreMultiTypeColor): TReqoreRgbaColor => {
|
|
58
|
+
// Check if this color is already in rgba format
|
|
59
|
+
if (hex.startsWith('rgb')) {
|
|
60
|
+
return hex as TReqoreRgbaColor;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const _hex = hex.length === 4 ? hex + hex.slice(1, 3) : hex;
|
|
64
|
+
|
|
65
|
+
const r = parseInt(_hex.slice(1, 3), 16);
|
|
66
|
+
const g = parseInt(_hex.slice(3, 5), 16);
|
|
67
|
+
const b = parseInt(_hex.slice(5, 7), 16);
|
|
68
|
+
const a = parseInt(_hex.slice(7, 9) || 'ff', 16) / 255;
|
|
69
|
+
|
|
70
|
+
return `rgba(${r}, ${g}, ${b}, ${a.toFixed(2)})`;
|
|
71
|
+
};
|
|
72
|
+
|
|
54
73
|
export const RGBAToHexA = (rgba, forceRemoveAlpha = false): TReqoreHexColor => {
|
|
55
74
|
if (isValidSixCharHex(rgba)) {
|
|
56
75
|
return rgba as TReqoreHexColor;
|
|
@@ -68,8 +87,8 @@ export const RGBAToHexA = (rgba, forceRemoveAlpha = false): TReqoreHexColor => {
|
|
|
68
87
|
.join('')) as TReqoreHexColor; // Puts the array to togehter to a string
|
|
69
88
|
};
|
|
70
89
|
|
|
71
|
-
export const shouldDarken = (mainColor:
|
|
72
|
-
return getLuminance(mainColor) > 0.2;
|
|
90
|
+
export const shouldDarken = (mainColor: TReqoreMultiTypeColor): boolean => {
|
|
91
|
+
return getLuminance(hexAToRGBA(mainColor)) > 0.2;
|
|
73
92
|
};
|
|
74
93
|
|
|
75
94
|
export const getMainColor: (theme: IReqoreTheme, component: string) => TReqoreHexColor = (
|
|
@@ -80,19 +99,24 @@ export const getMainColor: (theme: IReqoreTheme, component: string) => TReqoreHe
|
|
|
80
99
|
//export const changeBasedOnContrast = (color: string, lightness?: number): string =>
|
|
81
100
|
|
|
82
101
|
export const changeLightness = (color: TReqoreHexColor, lightness?: number): TReqoreHexColor => {
|
|
102
|
+
const fixedColor = hexAToRGBA(color);
|
|
103
|
+
|
|
83
104
|
return lightness
|
|
84
|
-
? shouldDarken(
|
|
85
|
-
? (darken(lightness,
|
|
86
|
-
: (lighten(lightness,
|
|
105
|
+
? shouldDarken(fixedColor)
|
|
106
|
+
? (darken(lightness, fixedColor) as TReqoreHexColor)
|
|
107
|
+
: (lighten(lightness, fixedColor) as TReqoreHexColor)
|
|
87
108
|
: color;
|
|
88
109
|
};
|
|
89
110
|
|
|
90
|
-
export const changeDarkness = (color: TReqoreHexColor, lightness?: number): TReqoreHexColor =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
111
|
+
export const changeDarkness = (color: TReqoreHexColor, lightness?: number): TReqoreHexColor => {
|
|
112
|
+
const fixedColor = hexAToRGBA(color);
|
|
113
|
+
|
|
114
|
+
return lightness
|
|
115
|
+
? shouldDarken(fixedColor)
|
|
116
|
+
? (lighten(lightness, fixedColor) as TReqoreHexColor)
|
|
117
|
+
: (darken(lightness, fixedColor) as TReqoreHexColor)
|
|
95
118
|
: color;
|
|
119
|
+
};
|
|
96
120
|
|
|
97
121
|
export const getColorByBgColor = (bgColor) => {
|
|
98
122
|
if (!bgColor) {
|
|
@@ -95,8 +95,13 @@ const Template: StoryFn<typeof ReqoreButton> = (buttonProps) => {
|
|
|
95
95
|
<ReqoreButton {...buttonProps} verticalPadding='small'>
|
|
96
96
|
Vertical padding small
|
|
97
97
|
</ReqoreButton>
|
|
98
|
-
<ReqoreButton
|
|
99
|
-
|
|
98
|
+
<ReqoreButton
|
|
99
|
+
{...buttonProps}
|
|
100
|
+
verticalPadding='normal'
|
|
101
|
+
rightIcon={undefined}
|
|
102
|
+
badge={{ align: 'right', label: 'R' }}
|
|
103
|
+
>
|
|
104
|
+
Vertical padding
|
|
100
105
|
</ReqoreButton>
|
|
101
106
|
<ReqoreButton {...buttonProps} verticalPadding='big'>
|
|
102
107
|
Vertical padding big
|
|
@@ -111,17 +116,34 @@ const Template: StoryFn<typeof ReqoreButton> = (buttonProps) => {
|
|
|
111
116
|
</ReqoreButton>
|
|
112
117
|
</ReqoreControlGroup>
|
|
113
118
|
<ReqoreControlGroup fluid wrap>
|
|
114
|
-
<ReqoreButton
|
|
115
|
-
|
|
119
|
+
<ReqoreButton
|
|
120
|
+
{...buttonProps}
|
|
121
|
+
fluid
|
|
122
|
+
badge={[
|
|
123
|
+
1,
|
|
124
|
+
{ label: 'in da middle', align: 'center' },
|
|
125
|
+
{ label: 'right align', align: 'right' },
|
|
126
|
+
2,
|
|
127
|
+
]}
|
|
128
|
+
>
|
|
129
|
+
Positioned badges
|
|
130
|
+
</ReqoreButton>
|
|
131
|
+
<ReqoreButton
|
|
132
|
+
{...buttonProps}
|
|
133
|
+
fluid
|
|
134
|
+
badge={[1, { label: 'right align', align: 'right' }, 2]}
|
|
135
|
+
>
|
|
136
|
+
Positioned badges
|
|
116
137
|
</ReqoreButton>
|
|
117
138
|
</ReqoreControlGroup>
|
|
139
|
+
|
|
118
140
|
<ReqoreControlGroup fluid wrap>
|
|
119
141
|
<ReqoreButton {...buttonProps} fluid textAlign='center'>
|
|
120
142
|
Fluid button with centered text
|
|
121
143
|
</ReqoreButton>
|
|
122
144
|
</ReqoreControlGroup>
|
|
123
145
|
<ReqoreControlGroup fluid wrap>
|
|
124
|
-
<ReqoreButton {...buttonProps} fluid textAlign='center' iconsAlign='center'>
|
|
146
|
+
<ReqoreButton {...buttonProps} fluid textAlign='center' iconsAlign='center' badge='badge'>
|
|
125
147
|
Fluid button with centered text & icons
|
|
126
148
|
</ReqoreButton>
|
|
127
149
|
<ReqoreButton
|
|
@@ -130,6 +152,7 @@ const Template: StoryFn<typeof ReqoreButton> = (buttonProps) => {
|
|
|
130
152
|
fluid
|
|
131
153
|
textAlign='center'
|
|
132
154
|
iconsAlign='center'
|
|
155
|
+
badge={[{ label: 'test', align: 'right' }, 2]}
|
|
133
156
|
>
|
|
134
157
|
Fluid button with centered text & icons
|
|
135
158
|
</ReqoreButton>
|
|
@@ -107,6 +107,15 @@ export const Pending: Story = {
|
|
|
107
107
|
},
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
export const Muted: Story = {
|
|
111
|
+
render: Template,
|
|
112
|
+
|
|
113
|
+
args: {
|
|
114
|
+
opaque: true,
|
|
115
|
+
intent: 'muted',
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
110
119
|
export const CustomTheme: Story = {
|
|
111
120
|
render: Template,
|
|
112
121
|
|