@qoretechnologies/reqore 0.29.1 → 0.29.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 (58) hide show
  1. package/dist/components/Button/index.d.ts.map +1 -1
  2. package/dist/components/Button/index.js +3 -1
  3. package/dist/components/Button/index.js.map +1 -1
  4. package/dist/components/Checkbox/index.d.ts +2 -0
  5. package/dist/components/Checkbox/index.d.ts.map +1 -1
  6. package/dist/components/Checkbox/index.js +16 -20
  7. package/dist/components/Checkbox/index.js.map +1 -1
  8. package/dist/components/Effect/index.d.ts +6 -3
  9. package/dist/components/Effect/index.d.ts.map +1 -1
  10. package/dist/components/Effect/index.js +41 -32
  11. package/dist/components/Effect/index.js.map +1 -1
  12. package/dist/components/Menu/divider.d.ts +1 -1
  13. package/dist/components/Menu/divider.d.ts.map +1 -1
  14. package/dist/components/Panel/index.d.ts.map +1 -1
  15. package/dist/components/Panel/index.js.map +1 -1
  16. package/dist/components/RadioGroup/index.d.ts +2 -1
  17. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  18. package/dist/components/RadioGroup/index.js +2 -2
  19. package/dist/components/RadioGroup/index.js.map +1 -1
  20. package/dist/constants/sizes.d.ts +7 -0
  21. package/dist/constants/sizes.d.ts.map +1 -1
  22. package/dist/constants/sizes.js +8 -1
  23. package/dist/constants/sizes.js.map +1 -1
  24. package/dist/constants/theme.d.ts +4 -1
  25. package/dist/constants/theme.d.ts.map +1 -1
  26. package/dist/constants/theme.js.map +1 -1
  27. package/dist/helpers/colors.d.ts +5 -4
  28. package/dist/helpers/colors.d.ts.map +1 -1
  29. package/dist/helpers/colors.js +35 -8
  30. package/dist/helpers/colors.js.map +1 -1
  31. package/dist/hooks/useReqoreEffect.d.ts +4 -0
  32. package/dist/hooks/useReqoreEffect.d.ts.map +1 -0
  33. package/dist/hooks/useReqoreEffect.js +42 -0
  34. package/dist/hooks/useReqoreEffect.js.map +1 -0
  35. package/dist/hooks/useTheme.d.ts +1 -0
  36. package/dist/hooks/useTheme.d.ts.map +1 -1
  37. package/dist/hooks/useTheme.js.map +1 -1
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +5 -1
  41. package/dist/index.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/components/Button/index.tsx +4 -2
  44. package/src/components/Checkbox/index.tsx +41 -17
  45. package/src/components/Effect/index.tsx +57 -10
  46. package/src/components/Menu/divider.tsx +1 -1
  47. package/src/components/Panel/index.tsx +3 -3
  48. package/src/components/RadioGroup/index.tsx +4 -2
  49. package/src/constants/sizes.ts +8 -0
  50. package/src/constants/theme.ts +8 -1
  51. package/src/helpers/colors.ts +54 -11
  52. package/src/hooks/useReqoreEffect.ts +49 -0
  53. package/src/hooks/useTheme.ts +2 -1
  54. package/src/index.tsx +2 -0
  55. package/src/stories/Button/Button.stories.tsx +14 -0
  56. package/src/stories/Panel/Panel.stories.tsx +1 -1
  57. package/src/stories/RadioGroup/RadioGroup.stories.tsx +47 -0
  58. package/tests.json +1 -1
@@ -52,6 +52,8 @@ export interface IReqoreCheckboxProps
52
52
  offText?: string | number;
53
53
  switchTextEffect?: IReqoreEffect;
54
54
  labelEffect?: IReqoreEffect;
55
+ margin?: 'left' | 'right' | 'both' | 'none';
56
+ wrapLabel?: boolean;
55
57
  }
56
58
 
57
59
  export interface IReqoreCheckboxStyle extends IReqoreCheckboxProps {
@@ -78,10 +80,10 @@ const StyledSwitchToggle = styled.div`
78
80
  : !checked
79
81
  ? parentEffect?.gradient
80
82
  ? changeLightness(getNthGradientColor(theme, parentEffect?.gradient?.colors, 1), 0.2)
81
- : theme.main
83
+ : changeLightness(theme.main, 0.2)
82
84
  : parentEffect?.gradient
83
85
  ? changeLightness(getNthGradientColor(theme, parentEffect?.gradient?.colors, 2), 0.2)
84
- : theme.main};
86
+ : changeLightness(theme.main, 0.25)};
85
87
  `;
86
88
 
87
89
  const StyledSwitch = styled(StyledEffect)<IReqoreCheckboxStyle>`
@@ -90,6 +92,7 @@ const StyledSwitch = styled(StyledEffect)<IReqoreCheckboxStyle>`
90
92
  display: flex;
91
93
  align-items: center;
92
94
  justify-content: center;
95
+ flex-shrink: 0;
93
96
 
94
97
  height: ${({ size }) => SIZE_TO_PX[size]}px;
95
98
  min-width: ${({ size }) => SIZE_TO_PX[size] * 1.8}px;
@@ -97,11 +100,7 @@ const StyledSwitch = styled(StyledEffect)<IReqoreCheckboxStyle>`
97
100
  border: 1px solid ${({ theme, checked }) => changeLightness(theme.main, checked ? 0.25 : 0.2)};
98
101
  border-radius: 50px;
99
102
 
100
- margin-right: ${({ size }) => PADDING_FROM_SIZE[size]}px;
101
- margin-left: ${({ size }) => PADDING_FROM_SIZE[size]}px;
102
-
103
- background-color: ${({ theme, checked }) =>
104
- checked ? rgba(changeLightness(theme.main, 0.15), 0.5) : 'transparent'};
103
+ background-color: ${({ theme }) => rgba(changeLightness(theme.main, 0.3), 0.1)};
105
104
 
106
105
  ${StyledIconWrapper} {
107
106
  z-index: 1;
@@ -117,13 +116,15 @@ const StyledSwitchTextWrapper = styled(StyledTextEffect)`
117
116
  `;
118
117
 
119
118
  const StyledOnSwitchText = styled(StyledSwitchTextWrapper)<IReqoreCheckboxStyle>`
120
- color: ${({ theme, checked }) =>
121
- getReadableColorFrom(!checked ? theme.originalMain : theme.main)};
119
+ color: ${({ theme, checked, parentHasGradient }) =>
120
+ !parentHasGradient &&
121
+ getReadableColorFrom(checked ? changeLightness(theme.main, 0.25) : theme.originalMain)};
122
122
  `;
123
123
 
124
124
  const StyledOffSwitchText = styled(StyledSwitchTextWrapper)<IReqoreCheckboxStyle>`
125
- color: ${({ theme, checked }) =>
126
- getReadableColorFrom(!checked ? theme.main : changeLightness(theme.main, 0.1))};
125
+ color: ${({ theme, checked, parentHasGradient }) =>
126
+ !parentHasGradient &&
127
+ getReadableColorFrom(checked ? theme.originalMain : changeLightness(theme.main, 0.2))};
127
128
  `;
128
129
 
129
130
  const StyledCheckbox = styled.div<IReqoreCheckboxStyle>`
@@ -170,6 +171,7 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
170
171
  labelDetail,
171
172
  labelDetailPosition = 'right',
172
173
  size = 'normal',
174
+ margin = 'left',
173
175
  checked,
174
176
  disabled,
175
177
  className,
@@ -187,6 +189,7 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
187
189
  intent,
188
190
  effect,
189
191
  customTheme,
192
+ wrapLabel,
190
193
  ...rest
191
194
  }: IReqoreCheckboxProps,
192
195
  ref
@@ -221,17 +224,24 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
221
224
  readOnly={readOnly}
222
225
  className={`${className || ''} reqore-checkbox reqore-control`}
223
226
  >
227
+ {margin === 'left' || margin === 'both' ? (
228
+ <ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
229
+ ) : null}
224
230
  {label && labelPosition === 'left' ? (
225
231
  <>
226
- <ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
227
232
  {labelDetailPosition === 'left' && labelDetail}
228
233
  <ReqoreTextEffect
229
234
  active={checked}
230
- effect={{ ...labelEffect, interactive: !disabled && !readOnly && !checked }}
235
+ effect={{
236
+ ...labelEffect,
237
+ interactive: !disabled && !readOnly && !checked,
238
+ noWrap: !wrapLabel,
239
+ }}
231
240
  >
232
241
  {label}
233
242
  </ReqoreTextEffect>
234
243
  {labelDetailPosition === 'right' && labelDetail}
244
+ <ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
235
245
  </>
236
246
  ) : null}
237
247
  {asSwitch ? (
@@ -241,7 +251,12 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
241
251
  checked={checked}
242
252
  theme={theme}
243
253
  as='div'
244
- effect={effect}
254
+ effect={
255
+ {
256
+ interactive: !disabled && !readOnly,
257
+ ...effect,
258
+ } as IReqoreEffect
259
+ }
245
260
  >
246
261
  <>
247
262
  {offText || offText === 0 ? (
@@ -250,6 +265,7 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
250
265
  size={size}
251
266
  theme={theme}
252
267
  checked={checked}
268
+ parentHasGradient={!!effect?.gradient}
253
269
  effect={
254
270
  {
255
271
  uppercase: true,
@@ -278,13 +294,14 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
278
294
  size={size}
279
295
  theme={theme}
280
296
  checked={checked}
297
+ parentHasGradient={!!effect?.gradient}
281
298
  effect={
282
299
  {
283
300
  uppercase: true,
284
301
  textSize: getOneLessSize(size),
285
302
  weight: 'thick',
286
303
  ...switchTextEffect,
287
- opacity: checked ? 1 : 0.5,
304
+ opacity: checked ? 1 : 0.3,
288
305
  } as IReqoreEffect
289
306
  }
290
307
  >
@@ -330,22 +347,29 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
330
347
  }
331
348
  image={image}
332
349
  effect={{ grayscale: image ? !checked : undefined, opacity: checked ? 1 : 0.5 }}
333
- margin='both'
334
350
  intent={intent}
335
351
  />
336
352
  )}
337
353
  {label && labelPosition === 'right' ? (
338
354
  <>
355
+ <ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
339
356
  {labelDetailPosition === 'left' && labelDetail}
340
357
  <ReqoreTextEffect
341
358
  active={checked}
342
- effect={{ ...labelEffect, interactive: !disabled && !readOnly && !checked }}
359
+ effect={{
360
+ ...labelEffect,
361
+ interactive: !disabled && !readOnly && !checked,
362
+ noWrap: !wrapLabel,
363
+ }}
343
364
  >
344
365
  {label}
345
366
  </ReqoreTextEffect>
346
367
  {labelDetailPosition === 'right' && labelDetail}
347
368
  </>
348
369
  ) : null}
370
+ {margin === 'right' || margin === 'both' ? (
371
+ <ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
372
+ ) : null}
349
373
  </StyledCheckbox>
350
374
  );
351
375
  }
@@ -1,6 +1,7 @@
1
1
  import { rgba } from 'polished';
2
2
  import { HTMLAttributes } from 'react';
3
- import styled, { css } from 'styled-components';
3
+ import styled, { css, keyframes } from 'styled-components';
4
+ import { Colors } from '../../constants/colors';
4
5
  import { TEXT_FROM_SIZE, TSizes, WEIGHT_TO_NUMBER } from '../../constants/sizes';
5
6
  import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
6
7
  import {
@@ -23,12 +24,21 @@ export type TReqoreEffectColor =
23
24
  | `${TReqoreIntent}:${TReqoreEffectColorManipulation}:${TReqoreEffectColorManipulationMultiplier}`
24
25
  | 'main'
25
26
  | `main:${TReqoreEffectColorManipulation}`
26
- | `main:${TReqoreEffectColorManipulation}:${TReqoreEffectColorManipulationMultiplier}`;
27
+ | `main:${TReqoreEffectColorManipulation}:${TReqoreEffectColorManipulationMultiplier}`
28
+ | `${TReqoreHexColor}:${TReqoreEffectColorManipulation}`
29
+ | `${TReqoreHexColor}:${TReqoreEffectColorManipulation}:${TReqoreEffectColorManipulationMultiplier}`;
27
30
  export type TReqoreEffectColorList = [
28
31
  'main' | TReqoreIntent | TReqoreColor,
29
32
  TReqoreEffectColorManipulation | undefined,
30
33
  TReqoreEffectColorManipulationMultiplier | undefined
31
34
  ];
35
+ export type TReqoreEffectGradientColors =
36
+ | 'main'
37
+ | TReqoreIntent
38
+ | TReqoreHexColor
39
+ | TReqoreEffectGradientColorsObject;
40
+ export type TReqoreEffectGradientColorsObject = Record<number, TReqoreEffectColor>;
41
+ export type TReqoreEffectGradientAnimationTrigger = 'always' | 'hover' | 'active' | 'never';
32
42
 
33
43
  export interface IReqoreEffectFilters {
34
44
  grayscale?: boolean;
@@ -45,9 +55,10 @@ export interface IReqoreEffect extends IReqoreEffectFilters {
45
55
  gradient?: {
46
56
  type?: 'linear' | 'radial';
47
57
  shape?: 'circle' | 'ellipse';
48
- colors: Record<number, TReqoreEffectColor>;
58
+ colors: TReqoreEffectGradientColors;
49
59
  direction?: string;
50
60
  borderColor?: TReqoreEffectColor;
61
+ animate?: TReqoreEffectGradientAnimationTrigger;
51
62
  };
52
63
  noWrap?: boolean;
53
64
  color?: TReqoreEffectColor;
@@ -61,7 +72,6 @@ export interface IReqoreEffect extends IReqoreEffectFilters {
61
72
  color: TReqoreEffectColor;
62
73
  inset?: boolean;
63
74
  blur?: number;
64
- useBorder?: boolean;
65
75
  };
66
76
  interactive?: boolean;
67
77
  }
@@ -77,6 +87,19 @@ export interface IReqoreTextEffectProps
77
87
  isText?: boolean;
78
88
  }
79
89
 
90
+ // Animate the gradient
91
+ const StyledGradientKeyframes = keyframes`
92
+ 0% {
93
+ background-position: 0% 0%;
94
+ }
95
+ 50% {
96
+ background-position: 100% 100%;
97
+ }
98
+ 100% {
99
+ background-position: 0% 0%;
100
+ }
101
+ `;
102
+
80
103
  export const StyledEffect = styled.span`
81
104
  transition: all 0.2s ease-in-out;
82
105
 
@@ -154,6 +177,13 @@ export const StyledEffect = styled.span`
154
177
  }
155
178
  `}
156
179
 
180
+ ${effect.gradient.animate === 'always' || (effect.gradient.animate === 'active' && active)
181
+ ? css`
182
+ background-size: 200% 200%;
183
+ animation: ${StyledGradientKeyframes} 1.5s linear infinite;
184
+ `
185
+ : undefined}
186
+
157
187
  ${effect.interactive &&
158
188
  css`
159
189
  cursor: pointer;
@@ -163,26 +193,43 @@ export const StyledEffect = styled.span`
163
193
  &:active {
164
194
  background: ${gradientActive};
165
195
  border-color: ${borderHoverColor} !important;
196
+
197
+ ${effect.gradient.animate === 'hover' ||
198
+ (effect.gradient.animate === 'active' && active) ||
199
+ effect.gradient.animate === 'always'
200
+ ? css`
201
+ background-size: 200% 200%;
202
+ animation: ${StyledGradientKeyframes} 2s linear infinite;
203
+ `
204
+ : undefined}
166
205
  }
167
206
  `}
168
207
  `;
169
208
  }}
170
209
 
171
- ${({ effect, theme }: IReqoreTextEffectProps) => {
210
+ ${({ effect, theme, isText }: IReqoreTextEffectProps) => {
172
211
  if (!effect || !effect.glow) {
173
212
  return undefined;
174
213
  }
175
214
 
176
- if (effect.glow.useBorder) {
215
+ if (!isText) {
177
216
  return css`
178
- border: ${effect.glow.size || 2}px solid
179
- ${getColorFromMaybeString(theme, effect.glow.color)} !important;
217
+ box-shadow: ${effect.glow.inset ? 'inset ' : ''} 0 0 ${effect.glow.blur || 0}px
218
+ ${effect.glow.size || 2}px ${getColorFromMaybeString(theme, effect.glow.color)};
180
219
  `;
181
220
  }
182
221
 
222
+ const color = getColorFromMaybeString(
223
+ theme,
224
+ effect.glow.color === 'main' ? 'main:lighten:2' : effect.glow.color
225
+ );
226
+ const blur = effect.glow.blur || 0;
227
+
183
228
  return css`
184
- box-shadow: ${effect.glow.inset ? 'inset ' : ''} 0 0 ${effect.glow.blur || 0}px
185
- ${effect.glow.size || 2}px ${getColorFromMaybeString(theme, effect.glow.color)};
229
+ color: ${Colors.LIGHT};
230
+ text-shadow: 0 0 ${blur}px ${color}, 0 0 ${blur + 5}px ${color}, 0 0 ${blur + 10}px ${color},
231
+ 0 0 1px ${getReadableColorFrom(color)}, 0 0 2px ${getReadableColorFrom(color)},
232
+ 0 0 3px ${getReadableColorFrom(color)};
186
233
  `;
187
234
  }}
188
235
 
@@ -11,7 +11,7 @@ export interface IReqoreMenuDividerProps
11
11
  IWithReqoreEffect,
12
12
  IWithReqoreSize {
13
13
  label?: string | number;
14
- margin?: 'left' | 'right' | 'both';
14
+ margin?: 'left' | 'right' | 'both' | 'none';
15
15
  align?: 'left' | 'center' | 'right';
16
16
  }
17
17
 
@@ -1,6 +1,6 @@
1
1
  import { size } from 'lodash';
2
2
  import { darken, rgba } from 'polished';
3
- import { forwardRef, ReactElement, useCallback, useMemo, useState } from 'react';
3
+ import { ReactElement, forwardRef, useCallback, useMemo, useState } from 'react';
4
4
  import { useUpdateEffect } from 'react-use';
5
5
  import styled, { css } from 'styled-components';
6
6
  import {
@@ -34,7 +34,7 @@ import { StyledCollectionItemContent } from '../Collection/item';
34
34
  import ReqoreControlGroup from '../ControlGroup';
35
35
  import ReqoreDropdown from '../Dropdown';
36
36
  import { IReqoreDropdownItem } from '../Dropdown/list';
37
- import { IReqoreEffect, StyledEffect } from '../Effect';
37
+ import { IReqoreEffect, StyledEffect, TReqoreEffectColor } from '../Effect';
38
38
  import { ReqoreHeading } from '../Header';
39
39
  import ReqoreIcon, { StyledIconWrapper } from '../Icon';
40
40
  import { ReqoreSpacer } from '../Spacer';
@@ -275,7 +275,7 @@ export const ReqorePanel = forwardRef<HTMLDivElement, IReqorePanelProps>(
275
275
  'main',
276
276
  customTheme ||
277
277
  (contentEffect?.gradient && minimal
278
- ? { main: Object.values(contentEffect.gradient.colors)[0] }
278
+ ? { main: Object.values(contentEffect.gradient.colors)[0] as TReqoreEffectColor }
279
279
  : undefined)
280
280
  );
281
281
  const { targetRef } = useCombinedRefs(ref);
@@ -21,6 +21,7 @@ export interface IReqoreRadioGroupProps
21
21
  asSwitch?: boolean;
22
22
  onText?: string;
23
23
  offText?: string;
24
+ margin?: 'left' | 'right' | 'both' | 'none';
24
25
  }
25
26
 
26
27
  const ReqoreRadioGroup = ({
@@ -33,6 +34,7 @@ const ReqoreRadioGroup = ({
33
34
  vertical = true,
34
35
  onText,
35
36
  offText,
37
+ margin = 'left',
36
38
  ...rest
37
39
  }: IReqoreRadioGroupProps) => (
38
40
  <ReqoreControlGroup {...rest} vertical={vertical}>
@@ -41,8 +43,8 @@ const ReqoreRadioGroup = ({
41
43
  <ReqoreMenuDivider
42
44
  {...itemRest}
43
45
  size={size || itemRest.size}
44
- effect={{ ...itemRest.effect, textAlign: 'left' }}
45
- margin='left'
46
+ effect={{ textAlign: 'left', ...itemRest.effect }}
47
+ margin={margin}
46
48
  label={vertical ? itemRest.label : undefined}
47
49
  />
48
50
  ) : (
@@ -1,6 +1,14 @@
1
1
  export type TSizes = 'tiny' | 'small' | 'normal' | 'big' | 'huge';
2
2
  export type TWeights = 'soft' | 'normal' | 'heavy';
3
3
 
4
+ export const ReqoreSizes = {
5
+ TINY: 'tiny',
6
+ SMALL: 'small',
7
+ NORMAL: 'normal',
8
+ BIG: 'big',
9
+ HUGE: 'huge',
10
+ };
11
+
4
12
  export const SIZES = ['tiny', 'small', 'normal', 'big', 'huge'] as const;
5
13
 
6
14
  export const SIZE_TO_NUMBER = {
@@ -1,4 +1,8 @@
1
- import { TReqoreEffectColor, TReqoreHexColor } from '../components/Effect';
1
+ import {
2
+ TReqoreEffectColor,
3
+ TReqoreEffectGradientAnimationTrigger,
4
+ TReqoreHexColor,
5
+ } from '../components/Effect';
2
6
 
3
7
  export interface IReqoreSidebarTheme {
4
8
  main?: TReqoreHexColor;
@@ -65,6 +69,7 @@ export interface IReqoreTheme {
65
69
  header?: IReqoreNavbarTheme;
66
70
  footer?: IReqoreNavbarTheme;
67
71
  breadcrumbs?: IReqoreBreadcrumbsTheme;
72
+ buttons?: IReqoreCustomTheme;
68
73
  }
69
74
 
70
75
  export interface IReqoreCustomTheme {
@@ -73,6 +78,8 @@ export interface IReqoreCustomTheme {
73
78
  color?: TReqoreEffectColor;
74
79
  dim?: boolean;
75
80
  };
81
+ gradient?: boolean;
82
+ animate?: TReqoreEffectGradientAnimationTrigger;
76
83
  }
77
84
 
78
85
  export interface IReqoreIntents {
@@ -1,6 +1,12 @@
1
1
  import { cloneDeep, merge, reduce } from 'lodash';
2
2
  import { darken, getLuminance, lighten, mix, readableColor } from 'polished';
3
- import { TReqoreEffectColor, TReqoreEffectColorList, TReqoreHexColor } from '../components/Effect';
3
+ import {
4
+ TReqoreEffectColor,
5
+ TReqoreEffectColorList,
6
+ TReqoreEffectGradientColors,
7
+ TReqoreEffectGradientColorsObject,
8
+ TReqoreHexColor,
9
+ } from '../components/Effect';
4
10
  import { Colors } from '../constants/colors';
5
11
  import { DEFAULT_INTENTS, IReqoreTheme, TReqoreIntent } from '../constants/theme';
6
12
 
@@ -175,7 +181,7 @@ export const getColorFromMaybeString = (
175
181
  _color = theme.intents[providedColor];
176
182
  }
177
183
 
178
- if (isValidSixCharHex(color)) {
184
+ if (isValidSixCharHex(providedColor)) {
179
185
  _color = providedColor as TReqoreHexColor;
180
186
  }
181
187
 
@@ -192,28 +198,62 @@ export const getColorFromMaybeString = (
192
198
 
193
199
  export const createEffectGradient = (
194
200
  theme: IReqoreTheme,
195
- colors: Record<number, TReqoreEffectColor>,
201
+ colors: TReqoreEffectGradientColors,
196
202
  lighten: number = 0,
197
203
  minimal?: boolean
198
204
  ): string => {
205
+ let _colors: TReqoreEffectGradientColorsObject;
206
+ // Check if the colors are valid
207
+ if (!colors) {
208
+ throw new Error('You need to provide colors');
209
+ }
210
+
211
+ if (typeof colors === 'string') {
212
+ _colors = buildGradientColorsFromString(theme, colors);
213
+ } else {
214
+ _colors = colors;
215
+ }
216
+
199
217
  return reduce(
200
- colors,
218
+ _colors,
201
219
  (colorsString, color, percentage) => {
202
220
  return `${colorsString}, ${
203
- minimal ? theme.main : changeLightness(getColorFromMaybeString(theme, color), lighten)
221
+ minimal
222
+ ? theme.originalMain
223
+ : changeLightness(getColorFromMaybeString(theme, color), lighten)
204
224
  } ${percentage}%`;
205
225
  },
206
226
  ''
207
227
  );
208
228
  };
209
229
 
230
+ export const buildGradientColorsFromString = (
231
+ theme: IReqoreTheme,
232
+ color: 'main' | TReqoreHexColor | TReqoreIntent
233
+ ): TReqoreEffectGradientColorsObject => {
234
+ if (!color) {
235
+ throw new Error('You need to provide a color or intent');
236
+ }
237
+
238
+ const colorFrom: TReqoreHexColor = getColorFromMaybeString(theme, `${color}:lighten:1`);
239
+ const colorTo: TReqoreHexColor = getColorFromMaybeString(theme, `${color}`);
240
+
241
+ return {
242
+ 0: colorFrom,
243
+ 100: colorTo,
244
+ };
245
+ };
246
+
210
247
  export const getNthGradientColor = (
211
248
  theme: IReqoreTheme,
212
- colors?: Record<number, TReqoreEffectColor>,
249
+ colors?: TReqoreEffectGradientColors,
213
250
  nth: number = 1
214
251
  ): TReqoreHexColor | undefined => {
215
- if (colors) {
216
- return getColorFromMaybeString(theme, Object.values(colors)[nth - 1]);
252
+ const _colors =
253
+ typeof colors === 'string' ? buildGradientColorsFromString(theme, colors) : colors;
254
+
255
+ if (_colors) {
256
+ return getColorFromMaybeString(theme, Object.values(_colors)[nth - 1]);
217
257
  }
218
258
 
219
259
  return undefined;
@@ -221,12 +261,15 @@ export const getNthGradientColor = (
221
261
 
222
262
  export const getGradientMix = (
223
263
  theme: IReqoreTheme,
224
- colors: Record<number, TReqoreEffectColor>,
264
+ colors: TReqoreEffectGradientColors,
225
265
  fallback?: TReqoreHexColor
226
266
  ): TReqoreHexColor | undefined => {
267
+ const _colors =
268
+ typeof colors === 'string' ? buildGradientColorsFromString(theme, colors) : colors;
269
+
227
270
  if (colors && Object.keys(colors).length === 2) {
228
- const gradientColor1: TReqoreHexColor = getNthGradientColor(theme, colors);
229
- const gradientColor2: TReqoreHexColor = getNthGradientColor(theme, colors, 2);
271
+ const gradientColor1: TReqoreHexColor = getNthGradientColor(theme, _colors);
272
+ const gradientColor2: TReqoreHexColor = getNthGradientColor(theme, _colors, 2);
230
273
 
231
274
  return mix(
232
275
  0.5,
@@ -0,0 +1,49 @@
1
+ import { useContext, useMemo } from 'react';
2
+ import {
3
+ IReqoreEffect,
4
+ TReqoreEffectGradientAnimationTrigger,
5
+ TReqoreHexColor,
6
+ } from '../components/Effect';
7
+ import { IReqoreTheme } from '../constants/theme';
8
+ import ThemeContext from '../context/ThemeContext';
9
+
10
+ export const useReqoreEffect = (
11
+ component: 'buttons',
12
+ theme: IReqoreTheme,
13
+ effect?: IReqoreEffect
14
+ ): IReqoreEffect => {
15
+ let _theme: IReqoreTheme = useContext<IReqoreTheme>(ThemeContext);
16
+
17
+ // Return the effect if the component is not defined in the theme
18
+ if (!theme[component]) {
19
+ return effect;
20
+ }
21
+
22
+ if (theme) {
23
+ // No other way to conditionally use a hook
24
+ _theme = theme;
25
+ }
26
+
27
+ const colors: TReqoreHexColor = useMemo(() => {
28
+ return _theme[component].gradient ? _theme.main : undefined;
29
+ }, [_theme, effect]);
30
+
31
+ const animate: TReqoreEffectGradientAnimationTrigger = useMemo(() => {
32
+ return _theme[component].animate;
33
+ }, [_theme, effect]);
34
+
35
+ const _effect = useMemo(() => {
36
+ return {
37
+ ...effect,
38
+ gradient: {
39
+ colors,
40
+ animate,
41
+
42
+ // If the user has defined a gradient, we don't want to override it
43
+ ...effect?.gradient,
44
+ },
45
+ };
46
+ }, [colors, animate, effect]);
47
+
48
+ return _effect;
49
+ };
@@ -11,13 +11,14 @@ export interface IReqoreCustomTheme extends Partial<Omit<IReqoreTheme, 'main' |
11
11
  color?: TReqoreEffectColor;
12
12
  dim?: boolean;
13
13
  };
14
+ gradient?: boolean;
14
15
  }
15
16
 
16
17
  export const useReqoreTheme = (
17
18
  element?: string,
18
19
  customTheme: IReqoreCustomTheme = {},
19
20
  intent?: TReqoreIntent
20
- ) => {
21
+ ): IReqoreTheme => {
21
22
  const theme: IReqoreTheme = useContext<IReqoreTheme>(ThemeContext);
22
23
 
23
24
  if (!element) {
package/src/index.tsx CHANGED
@@ -54,6 +54,8 @@ export { default as ReqoreTextarea } from './components/Textarea';
54
54
  export { TimeAgo as ReqoreTimeAgo } from './components/TimeAgo';
55
55
  export { ReqoreTree } from './components/Tree';
56
56
  export { Colors as ReqoreColors } from './constants/colors';
57
+ export { ReqoreSizes } from './constants/sizes';
58
+ export { ReqoreIntents } from './constants/theme';
57
59
  export { default as ReqoreNotifications } from './containers/ReqoreProvider';
58
60
  export { default as ReqoreUIProvider } from './containers/UIProvider';
59
61
  export { default as ReqoreContext } from './context/ReqoreContext';
@@ -1,6 +1,7 @@
1
1
  import { ComponentMeta, ComponentStory } from '@storybook/react';
2
2
  import { noop } from 'lodash';
3
3
  import ReqoreButton from '../../components/Button';
4
+ import { IReqoreTheme } from '../../constants/theme';
4
5
  import { ReqoreControlGroup } from '../../index';
5
6
  import { IconArg, SizeArg } from '../utils/args';
6
7
 
@@ -185,6 +186,7 @@ Effect.args = {
185
186
  gradient: {
186
187
  direction: 'to right bottom',
187
188
  colors: { 0: '#33023c', 100: '#0a487b' },
189
+ animate: 'active',
188
190
  },
189
191
  spaced: 2,
190
192
  uppercase: true,
@@ -192,3 +194,15 @@ Effect.args = {
192
194
  textSize: 'small',
193
195
  },
194
196
  };
197
+
198
+ export const GlobalEffect: ComponentStory<
199
+ typeof ReqoreButton & { otherThemeOptions?: IReqoreTheme }
200
+ > = Template.bind({});
201
+ GlobalEffect.args = {
202
+ otherThemeOptions: {
203
+ buttons: {
204
+ gradient: true,
205
+ animate: 'active',
206
+ },
207
+ },
208
+ } as any;
@@ -181,7 +181,7 @@ WithEffect.args = {
181
181
  type: 'radial',
182
182
  shape: 'ellipse',
183
183
  colors: { 0: '#670079', 100: '#180222' },
184
- //borderColor: '#fff349',
184
+ animate: 'hover',
185
185
  },
186
186
  },
187
187
  headerEffect: {