@qoretechnologies/reqore 0.28.0 → 0.28.2

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 (98) hide show
  1. package/__tests__/effect.test.tsx +6 -6
  2. package/dist/components/Button/index.d.ts +3 -1
  3. package/dist/components/Button/index.d.ts.map +1 -1
  4. package/dist/components/Button/index.js +14 -10
  5. package/dist/components/Button/index.js.map +1 -1
  6. package/dist/components/Collection/item.js +1 -1
  7. package/dist/components/Collection/item.js.map +1 -1
  8. package/dist/components/Dropdown/list.d.ts.map +1 -1
  9. package/dist/components/Dropdown/list.js +1 -2
  10. package/dist/components/Dropdown/list.js.map +1 -1
  11. package/dist/components/Effect/index.d.ts +14 -6
  12. package/dist/components/Effect/index.d.ts.map +1 -1
  13. package/dist/components/Effect/index.js +32 -19
  14. package/dist/components/Effect/index.js.map +1 -1
  15. package/dist/components/Header/index.d.ts.map +1 -1
  16. package/dist/components/Header/index.js +1 -2
  17. package/dist/components/Header/index.js.map +1 -1
  18. package/dist/components/Input/index.d.ts +1 -0
  19. package/dist/components/Input/index.d.ts.map +1 -1
  20. package/dist/components/Input/index.js +2 -2
  21. package/dist/components/Input/index.js.map +1 -1
  22. package/dist/components/InternalPopover/index.d.ts.map +1 -1
  23. package/dist/components/InternalPopover/index.js.map +1 -1
  24. package/dist/components/Menu/divider.js +1 -4
  25. package/dist/components/Menu/divider.js.map +1 -1
  26. package/dist/components/Menu/index.d.ts +3 -2
  27. package/dist/components/Menu/index.d.ts.map +1 -1
  28. package/dist/components/Menu/index.js +11 -7
  29. package/dist/components/Menu/index.js.map +1 -1
  30. package/dist/components/Message/index.d.ts.map +1 -1
  31. package/dist/components/Message/index.js +4 -1
  32. package/dist/components/Message/index.js.map +1 -1
  33. package/dist/components/Notifications/notification.d.ts.map +1 -1
  34. package/dist/components/Notifications/notification.js +1 -1
  35. package/dist/components/Notifications/notification.js.map +1 -1
  36. package/dist/components/Panel/index.d.ts.map +1 -1
  37. package/dist/components/Panel/index.js +1 -1
  38. package/dist/components/Panel/index.js.map +1 -1
  39. package/dist/components/Table/row.d.ts.map +1 -1
  40. package/dist/components/Table/row.js +4 -2
  41. package/dist/components/Table/row.js.map +1 -1
  42. package/dist/components/Tabs/list.d.ts.map +1 -1
  43. package/dist/components/Tabs/list.js +5 -3
  44. package/dist/components/Tabs/list.js.map +1 -1
  45. package/dist/components/Tag/index.d.ts +6 -3
  46. package/dist/components/Tag/index.d.ts.map +1 -1
  47. package/dist/components/Tag/index.js +58 -27
  48. package/dist/components/Tag/index.js.map +1 -1
  49. package/dist/components/Textarea/index.d.ts +1 -0
  50. package/dist/components/Textarea/index.d.ts.map +1 -1
  51. package/dist/components/Textarea/index.js +2 -2
  52. package/dist/components/Textarea/index.js.map +1 -1
  53. package/dist/constants/colors.js +1 -1
  54. package/dist/constants/theme.d.ts +43 -42
  55. package/dist/constants/theme.d.ts.map +1 -1
  56. package/dist/constants/theme.js.map +1 -1
  57. package/dist/containers/UIProvider.d.ts +1 -1
  58. package/dist/containers/UIProvider.d.ts.map +1 -1
  59. package/dist/helpers/colors.d.ts +11 -10
  60. package/dist/helpers/colors.d.ts.map +1 -1
  61. package/dist/helpers/colors.js +34 -10
  62. package/dist/helpers/colors.js.map +1 -1
  63. package/dist/hooks/useTheme.d.ts +9 -1
  64. package/dist/hooks/useTheme.d.ts.map +1 -1
  65. package/dist/hooks/useTheme.js +7 -0
  66. package/dist/hooks/useTheme.js.map +1 -1
  67. package/dist/types/global.d.ts +13 -0
  68. package/dist/types/global.d.ts.map +1 -1
  69. package/package.json +1 -1
  70. package/src/components/Button/index.tsx +37 -13
  71. package/src/components/Collection/item.tsx +1 -1
  72. package/src/components/Dropdown/list.tsx +0 -2
  73. package/src/components/Effect/index.tsx +67 -18
  74. package/src/components/Header/index.tsx +1 -3
  75. package/src/components/Input/index.tsx +3 -0
  76. package/src/components/InternalPopover/index.tsx +2 -1
  77. package/src/components/Menu/divider.tsx +1 -1
  78. package/src/components/Menu/index.tsx +16 -7
  79. package/src/components/Message/index.tsx +4 -1
  80. package/src/components/Notifications/notification.tsx +3 -0
  81. package/src/components/Panel/index.tsx +3 -3
  82. package/src/components/Table/row.tsx +8 -5
  83. package/src/components/Tabs/list.tsx +5 -3
  84. package/src/components/Tag/index.tsx +136 -47
  85. package/src/components/Textarea/index.tsx +3 -0
  86. package/src/constants/colors.ts +1 -1
  87. package/src/constants/theme.ts +44 -42
  88. package/src/containers/UIProvider.tsx +1 -1
  89. package/src/helpers/colors.ts +58 -26
  90. package/src/hooks/useTheme.ts +20 -3
  91. package/src/mock/collectionData.tsx +1 -1
  92. package/src/stories/Button/Button.stories.tsx +1 -1
  93. package/src/stories/Menu/Menu.stories.tsx +50 -3
  94. package/src/stories/Message/Message.stories.tsx +3 -4
  95. package/src/stories/Panel/Panel.stories.tsx +1 -0
  96. package/src/stories/Tag/Tag.stories.tsx +43 -0
  97. package/src/types/global.ts +14 -0
  98. package/tests.json +1 -1
@@ -13,17 +13,23 @@ import {
13
13
  } from '../../constants/sizes';
14
14
  import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
15
15
  import ThemeContext from '../../context/ThemeContext';
16
- import { changeLightness, getReadableColor, getReadableColorFrom } from '../../helpers/colors';
16
+ import {
17
+ changeLightness,
18
+ getColorFromMaybeString,
19
+ getReadableColor,
20
+ getReadableColorFrom,
21
+ } from '../../helpers/colors';
17
22
  import { useCombinedRefs } from '../../hooks/useCombinedRefs';
18
23
  import { useTooltip } from '../../hooks/useTooltip';
19
24
  import {
20
25
  IReqoreDisabled,
21
26
  IReqoreIntent,
22
27
  IWithReqoreEffect,
28
+ IWithReqoreMinimal,
23
29
  IWithReqoreTooltip,
24
30
  } from '../../types/global';
25
31
  import { IReqoreIconName } from '../../types/icons';
26
- import { StyledEffect } from '../Effect';
32
+ import { StyledEffect, TReqoreEffectColor, TReqoreHexColor } from '../Effect';
27
33
  import ReqoreIcon from '../Icon';
28
34
 
29
35
  export interface IReqoreTagAction extends IWithReqoreTooltip, IReqoreDisabled, IReqoreIntent {
@@ -35,7 +41,8 @@ export interface IReqoreTagProps
35
41
  extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'>,
36
42
  IWithReqoreTooltip,
37
43
  IReqoreDisabled,
38
- IWithReqoreEffect {
44
+ IWithReqoreEffect,
45
+ IWithReqoreMinimal {
39
46
  size?: TSizes;
40
47
  label?: string | number;
41
48
  labelKey?: string | number;
@@ -43,56 +50,74 @@ export interface IReqoreTagProps
43
50
  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
44
51
  icon?: IReqoreIconName;
45
52
  rightIcon?: IReqoreIconName;
46
- color?: string;
53
+ color?: TReqoreEffectColor;
47
54
  actions?: IReqoreTagAction[];
48
55
  width?: string;
49
56
  badge?: boolean;
50
57
  intent?: TReqoreIntent;
58
+ wrap?: boolean;
51
59
  }
52
60
 
53
61
  export interface IReqoreTagStyle extends IReqoreTagProps {
54
62
  theme: IReqoreTheme;
55
63
  removable?: boolean;
56
64
  interactive?: boolean;
65
+ color?: TReqoreHexColor;
57
66
  }
58
67
 
59
68
  export const StyledTag = styled(StyledEffect)<IReqoreTagStyle>`
60
69
  display: inline-flex;
61
70
  justify-content: center;
62
71
  flex-shrink: 0;
63
- align-items: center;
72
+ align-items: stretch;
64
73
  font-family: system-ui;
65
74
  font-weight: 600;
66
75
  overflow: hidden;
67
76
  vertical-align: middle;
68
77
  font-size: ${({ size }) => TEXT_FROM_SIZE[size]}px;
69
- height: ${({ size, badge }) => (badge ? BADGE_SIZE_TO_PX[size] : SIZE_TO_PX[size])}px;
78
+
70
79
  min-width: ${({ size }) => SIZE_TO_PX[size]}px;
71
80
  border-radius: ${({ badge, size }) => (badge ? 18 : RADIUS_FROM_SIZE[size])}px;
72
81
  width: ${({ width }) => width || undefined};
73
82
  transition: all 0.2s ease-out;
74
83
 
75
- ${({ theme, color, labelKey }) =>
84
+ ${({ wrap, hasWidth }) =>
85
+ wrap || hasWidth
86
+ ? css`
87
+ min-height: ${({ size, badge }) => (badge ? BADGE_SIZE_TO_PX[size] : SIZE_TO_PX[size])}px;
88
+ `
89
+ : css`
90
+ height: ${({ size, badge }) => (badge ? BADGE_SIZE_TO_PX[size] : SIZE_TO_PX[size])}px;
91
+ `}
92
+
93
+ ${({ theme, color, labelKey, minimal }: IReqoreTagStyle) =>
76
94
  css`
77
95
  background-color: ${color || changeLightness(theme.main, 0.1)};
78
- color: ${color ? getReadableColorFrom(color) : getReadableColor(theme, undefined, undefined)};
96
+ color: ${minimal
97
+ ? getReadableColor(theme, undefined, undefined, true, theme.originalMain)
98
+ : color
99
+ ? getReadableColorFrom(color)
100
+ : getReadableColor(theme, undefined, undefined)};
79
101
 
80
- ${StyledTagContentWrapper} {
102
+ ${StyledTagKeyWrapper} {
81
103
  background-color: ${labelKey ? rgba('#000000', 0.2) : undefined};
82
104
  }
83
105
  `}
84
106
 
85
- ${({ theme, color, interactive }) =>
86
- interactive &&
87
- css`
88
- cursor: pointer;
89
- &:hover {
90
- background-color: ${changeLightness(color || theme.main, color ? 0.05 : 0.15)};
91
- color: ${color
92
- ? getReadableColorFrom(color)
93
- : getReadableColor(theme, undefined, undefined)};
94
- }
95
- `}
107
+ ${({ theme, color, interactive, minimal, effect }) =>
108
+ interactive && !effect?.gradient
109
+ ? css`
110
+ cursor: pointer;
111
+ &:hover {
112
+ background-color: ${changeLightness(color || theme.main, color ? 0.05 : 0.15)};
113
+ color: ${minimal
114
+ ? getReadableColor(theme, undefined, undefined, false, theme.originalMain)
115
+ : color
116
+ ? getReadableColorFrom(color)
117
+ : getReadableColor(theme, undefined, undefined)};
118
+ }
119
+ `
120
+ : undefined}
96
121
 
97
122
 
98
123
  ${({ disabled }) =>
@@ -106,48 +131,74 @@ export const StyledTag = styled(StyledEffect)<IReqoreTagStyle>`
106
131
 
107
132
  const StyledTagRightIcon = styled(ReqoreIcon)``;
108
133
 
109
- const StyledTagContentWrapper = styled.div<{ size: TSizes }>`
134
+ const StyledTagKeyWrapper = styled.span<{ size: TSizes }>`
110
135
  display: flex;
111
136
  align-items: center;
112
137
  justify-content: center;
138
+ flex: ${({ hasKey }) => (hasKey ? 1 : undefined)};
113
139
  flex-shrink: 0;
140
+ min-height: 100%;
141
+ `;
142
+
143
+ const StyledTagContentWrapper = styled.span<{ size: TSizes }>`
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: center;
114
147
  flex: 1;
115
- overflow: hidden;
116
- height: 100%;
148
+ flex-shrink: 0;
149
+ min-height: 100%;
117
150
  `;
118
151
 
119
152
  const StyledTagContent = styled.span<{ size: TSizes }>`
120
- padding: 0 ${({ size }) => PADDING_FROM_SIZE[size]}px;
121
- height: 100%;
153
+ padding: 4px ${({ size }) => PADDING_FROM_SIZE[size]}px;
154
+ min-height: 100%;
122
155
  display: flex;
123
156
  align-items: center;
124
- overflow: hidden;
125
- text-overflow: ellipsis;
126
- white-space: nowrap;
157
+ flex: 1;
158
+
159
+ ${({ wrap, hasWidth }) =>
160
+ !wrap && !hasWidth
161
+ ? css`
162
+ overflow: hidden;
163
+ text-overflow: ellipsis;
164
+ white-space: nowrap;
165
+ `
166
+ : css`
167
+ word-break: break-word;
168
+ `}
127
169
  `;
128
170
 
129
171
  const StyledTagContentKey = styled(StyledTagContent)`
130
172
  font-weight: 800;
173
+ flex: 1;
174
+
175
+ ${({ wrap, hasWidth }) =>
176
+ !wrap && !hasWidth
177
+ ? undefined
178
+ : css`
179
+ word-break: break-word;
180
+ `}
131
181
  `;
132
182
 
133
- const StyledButtonWrapper = styled.div<IReqoreTagStyle>`
183
+ const StyledButtonWrapper = styled.span<IReqoreTagStyle>`
134
184
  flex-shrink: 0;
135
185
  font-size: ${({ size }) => TEXT_FROM_SIZE[size]}px;
136
- height: ${({ size }) => SIZE_TO_PX[size]}px;
137
186
  width: ${({ size }) => SIZE_TO_PX[size]}px;
138
187
  display: flex;
139
188
  justify-content: center;
140
189
  align-items: center;
141
190
  transition: all 0.2s ease-out;
142
191
 
143
- ${({ color }) =>
192
+ ${({ color, effect }) =>
144
193
  css`
145
194
  .reqore-icon {
146
195
  transform: scale(0.85);
147
196
  }
148
197
  &:hover {
149
198
  cursor: pointer;
150
- background-color: ${color ? changeLightness(color, 0.09) : rgba('#000000', 0.2)};
199
+ background-color: ${color && !effect?.gradient
200
+ ? changeLightness(color, 0.09)
201
+ : rgba('#000000', 0.2)};
151
202
 
152
203
  .reqore-icon {
153
204
  transform: scale(1);
@@ -172,6 +223,9 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
172
223
  badge,
173
224
  intent,
174
225
  color,
226
+ minimal,
227
+ wrap = false,
228
+ width,
175
229
  ...rest
176
230
  }: IReqoreTagProps,
177
231
  ref
@@ -182,38 +236,71 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
182
236
  useTooltip(targetRef.current, tooltip);
183
237
 
184
238
  // If color or intent was specified, set the color
185
- const customColor = intent ? theme.intents[intent] : color;
239
+ let customColor: TReqoreHexColor = intent
240
+ ? theme.intents[intent]
241
+ : getColorFromMaybeString(theme, color);
242
+ customColor = minimal ? `${customColor || '#000000'}40` : customColor;
186
243
 
187
244
  return (
188
245
  <StyledTag
189
246
  {...rest}
247
+ effect={{
248
+ ...rest.effect,
249
+ interactive: !!onClick && !rest.disabled,
250
+ }}
251
+ width={width}
190
252
  labelKey={labelKey}
191
253
  color={customColor}
192
254
  className={`${className || ''} reqore-tag`}
193
255
  size={size}
194
256
  ref={targetRef}
195
257
  badge={badge}
258
+ minimal={minimal}
196
259
  removable={!!onRemoveClick}
197
260
  interactive={!!onClick && !rest.disabled}
261
+ wrap={wrap}
262
+ hasWidth={!!width}
198
263
  >
199
264
  {icon || labelKey ? (
200
- <StyledTagContentWrapper size={size} className='reqore-tag-content' onClick={onClick}>
265
+ <StyledTagKeyWrapper
266
+ size={size}
267
+ className='reqore-tag-key-content'
268
+ onClick={onClick}
269
+ wrap={wrap}
270
+ hasWidth={!!width}
271
+ hasKey={!!labelKey}
272
+ >
201
273
  {icon && <ReqoreIcon icon={icon} size={size} margin={label ? 'left' : 'both'} />}
202
- {labelKey && <StyledTagContentKey size={size}>{labelKey}</StyledTagContentKey>}
203
- </StyledTagContentWrapper>
274
+ {labelKey && (
275
+ <StyledTagContentKey wrap={wrap} hasWidth={!!width} size={size}>
276
+ {labelKey}
277
+ </StyledTagContentKey>
278
+ )}
279
+ </StyledTagKeyWrapper>
204
280
  ) : null}
205
- {label && (
206
- <StyledTagContent size={size} onClick={onClick}>
207
- {label}
208
- </StyledTagContent>
209
- )}
210
- {rightIcon && (
211
- <StyledTagRightIcon
212
- icon={rightIcon}
281
+ {label || label === 0 || rightIcon ? (
282
+ <StyledTagContentWrapper
213
283
  size={size}
214
- margin={label || icon ? 'right' : 'both'}
215
- />
216
- )}
284
+ className='reqore-tag-content'
285
+ onClick={onClick}
286
+ wrap={wrap}
287
+ hasWidth={!!width}
288
+ hasKey={!!labelKey}
289
+ >
290
+ {label || label === 0 ? (
291
+ <StyledTagContent size={size} onClick={onClick} wrap={wrap} hasWidth={!!width}>
292
+ {label}
293
+ </StyledTagContent>
294
+ ) : null}
295
+ {rightIcon && (
296
+ <StyledTagRightIcon
297
+ icon={rightIcon}
298
+ size={size}
299
+ margin={label || icon ? 'right' : 'both'}
300
+ />
301
+ )}
302
+ </StyledTagContentWrapper>
303
+ ) : null}
217
304
  {_size(actions)
218
305
  ? actions.map((action) => (
219
306
  <>
@@ -224,6 +311,7 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
224
311
  color: customColor,
225
312
  className: 'reqore-tag-action',
226
313
  onClick: action.onClick,
314
+ effect: rest.effect,
227
315
  }}
228
316
  {...(action.tooltip
229
317
  ? typeof action.tooltip === 'string'
@@ -245,6 +333,7 @@ const ReqoreTag = forwardRef<HTMLSpanElement, IReqoreTagProps>(
245
333
  color: customColor,
246
334
  className: 'reqore-tag-remove',
247
335
  onClick: onRemoveClick,
336
+ effect: rest.effect,
248
337
  }}
249
338
  noWrapper
250
339
  content='Remove'
@@ -41,6 +41,7 @@ export interface IReqoreTextareaProps
41
41
  rounded?: boolean;
42
42
  flat?: boolean;
43
43
  onClearClick?: () => any;
44
+ wrapperStyle?: React.CSSProperties;
44
45
  }
45
46
 
46
47
  export interface IReqoreTextareaStyle extends IReqoreTextareaProps {
@@ -132,6 +133,7 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
132
133
  customTheme,
133
134
  intent,
134
135
  rounded = true,
136
+ wrapperStyle,
135
137
  ...rest
136
138
  }: IReqoreTextareaProps,
137
139
  ref: any
@@ -149,6 +151,7 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
149
151
  fluid={fluid}
150
152
  _size={size}
151
153
  theme={theme}
154
+ style={wrapperStyle}
152
155
  >
153
156
  <StyledTextarea
154
157
  {...rest}
@@ -1,5 +1,5 @@
1
1
  export const Colors = {
2
- DARK: '#222222',
2
+ DARK: '#000000',
3
3
  LIGHT: '#ffffff',
4
4
  BLUE: '#0E5A8A',
5
5
  GREEN: '#0A6640',
@@ -1,64 +1,66 @@
1
+ import { TReqoreEffectColor, TReqoreHexColor } from '../components/Effect';
2
+
1
3
  export interface IReqoreSidebarTheme {
2
- main?: string;
3
- color?: string;
4
- border?: string;
4
+ main?: TReqoreHexColor;
5
+ color?: TReqoreHexColor;
6
+ border?: TReqoreHexColor;
5
7
  item?: {
6
- color?: string;
7
- background?: string;
8
- border?: string;
9
- hoverColor?: string;
10
- hoverBackground?: string;
11
- activeColor?: string;
12
- activeBackground?: string;
8
+ color?: TReqoreHexColor;
9
+ background?: TReqoreHexColor;
10
+ border?: TReqoreHexColor;
11
+ hoverColor?: TReqoreHexColor;
12
+ hoverBackground?: TReqoreHexColor;
13
+ activeColor?: TReqoreHexColor;
14
+ activeBackground?: TReqoreHexColor;
13
15
  };
14
16
  subItem?: {
15
- color?: string;
16
- border?: string;
17
- background?: string;
18
- hoverColor?: string;
19
- hoverBackground?: string;
20
- activeColor?: string;
21
- activeBackground?: string;
17
+ color?: TReqoreHexColor;
18
+ border?: TReqoreHexColor;
19
+ background?: TReqoreHexColor;
20
+ hoverColor?: TReqoreHexColor;
21
+ hoverBackground?: TReqoreHexColor;
22
+ activeColor?: TReqoreHexColor;
23
+ activeBackground?: TReqoreHexColor;
22
24
  };
23
25
  icon?: {
24
- color?: string;
25
- hoverColor?: string;
26
- activeColor?: string;
26
+ color?: TReqoreHexColor;
27
+ hoverColor?: TReqoreHexColor;
28
+ activeColor?: TReqoreHexColor;
27
29
  };
28
30
  section?: {
29
- background?: string;
31
+ background?: TReqoreHexColor;
30
32
  };
31
33
  }
32
34
 
33
35
  export interface IReqoreBreadcrumbsTheme {
34
- main?: string;
36
+ main?: TReqoreHexColor;
35
37
  item?: {
36
- color?: string;
37
- hoverColor?: string;
38
- activeColor?: string;
38
+ color?: TReqoreHexColor;
39
+ hoverColor?: TReqoreHexColor;
40
+ activeColor?: TReqoreHexColor;
39
41
  };
40
42
  }
41
43
 
42
44
  export interface IReqoreNavbarTheme {
43
- main?: string;
44
- color?: string;
45
- border?: string;
46
- background?: string;
47
- hoverColor?: string;
45
+ main?: TReqoreHexColor;
46
+ color?: TReqoreHexColor;
47
+ border?: TReqoreHexColor;
48
+ background?: TReqoreHexColor;
49
+ hoverColor?: TReqoreHexColor;
48
50
  }
49
51
 
50
52
  export interface IReqoreTheme {
51
- main: string;
52
- originalMain?: string;
53
+ main: TReqoreHexColor;
54
+ originalMain?: TReqoreHexColor;
53
55
  text?: {
54
- color?: string;
56
+ color?: TReqoreHexColor;
55
57
  dim?: boolean;
56
58
  };
57
59
  intents: IReqoreIntents;
58
60
  sidebar?: IReqoreSidebarTheme;
59
61
  notifications: IReqoreIntents;
60
62
  popover?: {
61
- main: string;
63
+ main: TReqoreHexColor;
62
64
  };
63
65
  header?: IReqoreNavbarTheme;
64
66
  footer?: IReqoreNavbarTheme;
@@ -66,20 +68,20 @@ export interface IReqoreTheme {
66
68
  }
67
69
 
68
70
  export interface IReqoreCustomTheme {
69
- main?: string;
71
+ main?: TReqoreEffectColor;
70
72
  text?: {
71
- color?: string;
73
+ color?: TReqoreEffectColor;
72
74
  dim?: boolean;
73
75
  };
74
76
  }
75
77
 
76
78
  export interface IReqoreIntents {
77
- info?: string;
78
- success?: string;
79
- pending?: string;
80
- warning?: string;
81
- danger?: string;
82
- muted?: string;
79
+ info?: TReqoreHexColor;
80
+ success?: TReqoreHexColor;
81
+ pending?: TReqoreHexColor;
82
+ warning?: TReqoreHexColor;
83
+ danger?: TReqoreHexColor;
84
+ muted?: TReqoreHexColor;
83
85
  }
84
86
 
85
87
  export type TReqoreIntent = 'info' | 'success' | 'pending' | 'warning' | 'danger' | 'muted';
@@ -20,7 +20,7 @@ export interface IReqoreOptions {
20
20
  };
21
21
  }
22
22
  export interface IReqoreUIProviderProps {
23
- children: any;
23
+ children?: any;
24
24
  theme?: Partial<IReqoreTheme>;
25
25
  options?: IReqoreOptions;
26
26
  }
@@ -1,15 +1,16 @@
1
1
  import { cloneDeep, merge } from 'lodash';
2
2
  import { darken, lighten, readableColor } from 'polished';
3
+ import { TReqoreEffectColor, TReqoreEffectColorList, TReqoreHexColor } from '../components/Effect';
3
4
  import { Colors } from '../constants/colors';
4
5
  import { DEFAULT_INTENTS, IReqoreTheme, TReqoreIntent } from '../constants/theme';
5
6
 
6
7
  export const getReadableColor: (
7
8
  theme: Partial<IReqoreTheme>,
8
- ifLight?: string,
9
- ifDark?: string,
9
+ ifLight?: TReqoreHexColor,
10
+ ifDark?: TReqoreHexColor,
10
11
  dimmed?: boolean,
11
- fallback?: string
12
- ) => string = (theme, ifLight, ifDark, dimmed, fallback) => {
12
+ fallback?: TReqoreHexColor
13
+ ) => TReqoreHexColor = (theme, ifLight, ifDark, dimmed, fallback) => {
13
14
  if (theme.text?.color) {
14
15
  return theme.text.dim
15
16
  ? dimmed
@@ -25,15 +26,15 @@ export const getReadableColor: (
25
26
  };
26
27
 
27
28
  export const getReadableColorFrom = (
28
- from: string,
29
+ from: TReqoreHexColor,
29
30
  dim?: boolean,
30
- ifLight?: string,
31
- ifDark?: string
32
- ) => {
31
+ ifLight?: TReqoreHexColor,
32
+ ifDark?: TReqoreHexColor
33
+ ): TReqoreHexColor => {
33
34
  const returnIfLight = ifLight || lighten(dim ? 0.05 : 0, Colors.DARK);
34
35
  const returnIfDark = ifDark || darken(dim ? 0.05 : 0, Colors.LIGHT);
35
36
 
36
- return readableColor(from, returnIfLight, returnIfDark, false);
37
+ return readableColor(from, returnIfLight, returnIfDark, false) as TReqoreHexColor;
37
38
  };
38
39
 
39
40
  export const percentToHexAlpha = (p: number) => {
@@ -44,29 +45,33 @@ export const percentToHexAlpha = (p: number) => {
44
45
  return hexValue.padStart(2, '0').toUpperCase(); // format with leading 0 and upper case characters
45
46
  };
46
47
 
47
- export const shouldDarken = (mainColor: string) => {
48
+ export const shouldDarken = (mainColor: TReqoreHexColor): boolean => {
48
49
  const contrast = getColorByBgColor(mainColor);
49
50
 
50
51
  return contrast === '#000000';
51
52
  };
52
53
 
53
- export const getMainColor: (theme: IReqoreTheme, component: string) => string = (
54
+ export const getMainColor: (theme: IReqoreTheme, component: string) => TReqoreHexColor = (
54
55
  theme,
55
56
  component
56
57
  ) => theme[component]?.main || theme.main;
57
58
 
58
59
  //export const changeBasedOnContrast = (color: string, lightness?: number): string =>
59
60
 
60
- export const changeLightness = (color: string, lightness?: number): string => {
61
+ export const changeLightness = (color: TReqoreHexColor, lightness?: number): TReqoreHexColor => {
61
62
  return lightness
62
63
  ? shouldDarken(color)
63
- ? darken(lightness, color)
64
- : lighten(lightness, color)
64
+ ? (darken(lightness, color) as TReqoreHexColor)
65
+ : (lighten(lightness, color) as TReqoreHexColor)
65
66
  : color;
66
67
  };
67
68
 
68
- export const changeDarkness = (color: string, lightness?: number): string =>
69
- lightness ? (shouldDarken(color) ? lighten(lightness, color) : darken(lightness, color)) : color;
69
+ export const changeDarkness = (color: TReqoreHexColor, lightness?: number): TReqoreHexColor =>
70
+ lightness
71
+ ? shouldDarken(color)
72
+ ? (lighten(lightness, color) as TReqoreHexColor)
73
+ : (darken(lightness, color) as TReqoreHexColor)
74
+ : color;
70
75
 
71
76
  export const getColorByBgColor = (bgColor) => {
72
77
  if (!bgColor) {
@@ -76,7 +81,7 @@ export const getColorByBgColor = (bgColor) => {
76
81
  };
77
82
 
78
83
  export const isValidSixCharHex = (hex: string): boolean => {
79
- return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex);
84
+ return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/.test(hex);
80
85
  };
81
86
 
82
87
  export const buildTheme = (theme: IReqoreTheme): IReqoreTheme => {
@@ -142,20 +147,47 @@ export const getNotificationIntent = (theme: IReqoreTheme, intent?: TReqoreInten
142
147
  return changeLightness(theme.main, 0.1);
143
148
  };
144
149
 
145
- export const getMainBackgroundColor = (theme: IReqoreTheme): string =>
150
+ export const getMainBackgroundColor = (theme: IReqoreTheme): TReqoreHexColor =>
146
151
  changeLightness(theme.main, 0.02);
147
152
 
148
- export const getColorFromMaybeIntentOrString = (
153
+ export const getColorFromMaybeString = (
149
154
  theme: IReqoreTheme,
150
- intent: TReqoreIntent | string
151
- ): string => {
152
- if (theme.intents[intent]) {
153
- return theme.intents[intent];
155
+ color: TReqoreEffectColor
156
+ ): TReqoreHexColor => {
157
+ if (!color) {
158
+ return undefined;
159
+ }
160
+
161
+ const [providedColor, shading, multiplier = 1]: TReqoreEffectColorList = color.split(
162
+ ':'
163
+ ) as TReqoreEffectColorList;
164
+
165
+ if (providedColor === 'transparent') {
166
+ return '#00000000';
167
+ }
168
+
169
+ // First we need to get the actual color
170
+ let _color: TReqoreHexColor;
171
+
172
+ if (!providedColor || providedColor === 'main') {
173
+ _color = theme.main;
174
+ }
175
+
176
+ if (theme.intents[providedColor]) {
177
+ _color = theme.intents[providedColor];
178
+ }
179
+
180
+ if (isValidSixCharHex(color)) {
181
+ _color = providedColor as TReqoreHexColor;
154
182
  }
155
183
 
156
- if (isValidSixCharHex(intent)) {
157
- return intent;
184
+ if (shading) {
185
+ if (shading === 'lighten') {
186
+ _color = lighten(0.1 * multiplier, _color) as TReqoreHexColor;
187
+ } else if (shading === 'darken') {
188
+ _color = darken(0.1 * multiplier, _color) as TReqoreHexColor;
189
+ }
158
190
  }
159
191
 
160
- return theme.main;
192
+ return _color;
161
193
  };
@@ -1,16 +1,33 @@
1
1
  import { cloneDeep } from 'lodash';
2
2
  import { useContext } from 'react';
3
+ import { TReqoreEffectColor } from '../components/Effect';
3
4
  import { IReqoreTheme, TReqoreIntent } from '../constants/theme';
4
5
  import ThemeContext from '../context/ThemeContext';
5
- import { mergeThemes } from '../helpers/colors';
6
+ import { getColorFromMaybeString, mergeThemes } from '../helpers/colors';
7
+
8
+ export interface IReqoreCustomTheme extends Partial<Omit<IReqoreTheme, 'main' | 'text'>> {
9
+ main?: TReqoreEffectColor;
10
+ text?: {
11
+ color?: TReqoreEffectColor;
12
+ dim?: boolean;
13
+ };
14
+ }
6
15
 
7
16
  export const useReqoreTheme = (
8
17
  element: string,
9
- customTheme: Partial<IReqoreTheme> = {},
18
+ customTheme: IReqoreCustomTheme = {},
10
19
  intent?: TReqoreIntent
11
20
  ) => {
12
21
  const theme: IReqoreTheme = useContext<IReqoreTheme>(ThemeContext);
13
- let _customTheme: Partial<IReqoreTheme> = cloneDeep(customTheme);
22
+ let _customTheme: IReqoreCustomTheme = cloneDeep(customTheme);
23
+
24
+ if (_customTheme.main) {
25
+ _customTheme.main = getColorFromMaybeString(theme, customTheme.main);
26
+ }
27
+
28
+ if (_customTheme.text?.color) {
29
+ _customTheme.text.color = getColorFromMaybeString(theme, customTheme.text.color);
30
+ }
14
31
 
15
32
  if (element === 'main' && intent) {
16
33
  _customTheme.main = theme.intents[intent];