@mmb-digital/design-system-web 0.1.0

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 (127) hide show
  1. package/.babelrc.json +16 -0
  2. package/.eslintrc.js +165 -0
  3. package/.prettierrc.js +15 -0
  4. package/.storybook/main.ts +23 -0
  5. package/.storybook/preview.tsx +27 -0
  6. package/dist/cjs/index.js +131 -0
  7. package/dist/cjs/index.js.map +1 -0
  8. package/dist/cjs/types/jest.config.d.ts +7 -0
  9. package/dist/cjs/types/src/components/button/button.d.ts +4 -0
  10. package/dist/cjs/types/src/components/button/button.styles.d.ts +4 -0
  11. package/dist/cjs/types/src/components/button/button.test.d.ts +1 -0
  12. package/dist/cjs/types/src/components/button/button.types.d.ts +29 -0
  13. package/dist/cjs/types/src/components/form/hint/formHint.d.ts +4 -0
  14. package/dist/cjs/types/src/components/form/hint/formHint.style.d.ts +1 -0
  15. package/dist/cjs/types/src/components/form/hint/formHint.types.d.ts +4 -0
  16. package/dist/cjs/types/src/components/slider/slider/slider.d.ts +5 -0
  17. package/dist/cjs/types/src/components/slider/slider/slider.style.d.ts +5 -0
  18. package/dist/cjs/types/src/components/slider/slider/slider.types.d.ts +47 -0
  19. package/dist/cjs/types/src/components/slider/slider/sliderFunction/default/sliderFunctionDefault.d.ts +2 -0
  20. package/dist/cjs/types/src/components/slider/slider/sliderFunction/default/sliderStep.d.ts +7 -0
  21. package/dist/cjs/types/src/components/slider/slider/sliderFunction/default/sliderStep.test.d.ts +1 -0
  22. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderFunctionLinearVisualSteps.d.ts +2 -0
  23. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.d.ts +8 -0
  24. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.test.d.ts +1 -0
  25. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.d.ts +9 -0
  26. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.test.d.ts +1 -0
  27. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.d.ts +2 -0
  28. package/dist/cjs/types/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.test.d.ts +1 -0
  29. package/dist/cjs/types/src/components/slider/slider/sliderHandleSvgHandler.d.ts +2 -0
  30. package/dist/cjs/types/src/components/storeButton/assets/androidSvg.d.ts +8 -0
  31. package/dist/cjs/types/src/components/storeButton/assets/appleSvg.d.ts +8 -0
  32. package/dist/cjs/types/src/components/storeButton/storeButton.d.ts +4 -0
  33. package/dist/cjs/types/src/components/storeButton/storeButton.styles.d.ts +3 -0
  34. package/dist/cjs/types/src/components/storeButton/storeButton.test.d.ts +1 -0
  35. package/dist/cjs/types/src/components/storeButton/storeButton.types.d.ts +13 -0
  36. package/dist/cjs/types/src/icons/systemIcon.d.ts +8 -0
  37. package/dist/cjs/types/src/index.d.ts +1 -0
  38. package/dist/cjs/types/src/provider/storybook/storybookProvider.d.ts +4 -0
  39. package/dist/cjs/types/src/provider/storybook/storybookProvider.types.d.ts +4 -0
  40. package/dist/cjs/types/src/provider/styledComponents/theme/styledComponentsThemeProvider.d.ts +4 -0
  41. package/dist/cjs/types/src/provider/styledComponents/theme/styledComponentsThemeProvider.types..d.ts +4 -0
  42. package/dist/cjs/types/src/style/styledComponents/theme.d.ts +441 -0
  43. package/dist/esm/index.js +131 -0
  44. package/dist/esm/index.js.map +1 -0
  45. package/dist/esm/types/jest.config.d.ts +7 -0
  46. package/dist/esm/types/src/components/button/button.d.ts +4 -0
  47. package/dist/esm/types/src/components/button/button.styles.d.ts +4 -0
  48. package/dist/esm/types/src/components/button/button.test.d.ts +1 -0
  49. package/dist/esm/types/src/components/button/button.types.d.ts +29 -0
  50. package/dist/esm/types/src/components/form/hint/formHint.d.ts +4 -0
  51. package/dist/esm/types/src/components/form/hint/formHint.style.d.ts +1 -0
  52. package/dist/esm/types/src/components/form/hint/formHint.types.d.ts +4 -0
  53. package/dist/esm/types/src/components/slider/slider/slider.d.ts +5 -0
  54. package/dist/esm/types/src/components/slider/slider/slider.style.d.ts +5 -0
  55. package/dist/esm/types/src/components/slider/slider/slider.types.d.ts +47 -0
  56. package/dist/esm/types/src/components/slider/slider/sliderFunction/default/sliderFunctionDefault.d.ts +2 -0
  57. package/dist/esm/types/src/components/slider/slider/sliderFunction/default/sliderStep.d.ts +7 -0
  58. package/dist/esm/types/src/components/slider/slider/sliderFunction/default/sliderStep.test.d.ts +1 -0
  59. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderFunctionLinearVisualSteps.d.ts +2 -0
  60. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.d.ts +8 -0
  61. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.test.d.ts +1 -0
  62. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.d.ts +9 -0
  63. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.test.d.ts +1 -0
  64. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.d.ts +2 -0
  65. package/dist/esm/types/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.test.d.ts +1 -0
  66. package/dist/esm/types/src/components/slider/slider/sliderHandleSvgHandler.d.ts +2 -0
  67. package/dist/esm/types/src/components/storeButton/assets/androidSvg.d.ts +8 -0
  68. package/dist/esm/types/src/components/storeButton/assets/appleSvg.d.ts +8 -0
  69. package/dist/esm/types/src/components/storeButton/storeButton.d.ts +4 -0
  70. package/dist/esm/types/src/components/storeButton/storeButton.styles.d.ts +3 -0
  71. package/dist/esm/types/src/components/storeButton/storeButton.test.d.ts +1 -0
  72. package/dist/esm/types/src/components/storeButton/storeButton.types.d.ts +13 -0
  73. package/dist/esm/types/src/icons/systemIcon.d.ts +8 -0
  74. package/dist/esm/types/src/index.d.ts +1 -0
  75. package/dist/esm/types/src/provider/storybook/storybookProvider.d.ts +4 -0
  76. package/dist/esm/types/src/provider/storybook/storybookProvider.types.d.ts +4 -0
  77. package/dist/esm/types/src/provider/styledComponents/theme/styledComponentsThemeProvider.d.ts +4 -0
  78. package/dist/esm/types/src/provider/styledComponents/theme/styledComponentsThemeProvider.types..d.ts +4 -0
  79. package/dist/esm/types/src/style/styledComponents/theme.d.ts +441 -0
  80. package/jest.config.ts +197 -0
  81. package/package.json +97 -0
  82. package/readme.md +39 -0
  83. package/rollup.config.js +33 -0
  84. package/src/@types/json.d.ts +5 -0
  85. package/src/@types/styledComponentCssProps.d.ts +11 -0
  86. package/src/@types/styledComponentTheme.d.ts +9 -0
  87. package/src/components/button/button.stories.tsx +97 -0
  88. package/src/components/button/button.styles.ts +162 -0
  89. package/src/components/button/button.test.tsx +25 -0
  90. package/src/components/button/button.tsx +31 -0
  91. package/src/components/button/button.types.ts +33 -0
  92. package/src/components/form/hint/formHint.style.ts +10 -0
  93. package/src/components/form/hint/formHint.tsx +13 -0
  94. package/src/components/form/hint/formHint.types.ts +5 -0
  95. package/src/components/slider/slider/slider.stories.tsx +176 -0
  96. package/src/components/slider/slider/slider.style.ts +29 -0
  97. package/src/components/slider/slider/slider.tsx +136 -0
  98. package/src/components/slider/slider/slider.types.ts +58 -0
  99. package/src/components/slider/slider/sliderFunction/default/sliderFunctionDefault.ts +21 -0
  100. package/src/components/slider/slider/sliderFunction/default/sliderStep.test.ts +90 -0
  101. package/src/components/slider/slider/sliderFunction/default/sliderStep.ts +18 -0
  102. package/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderFunctionLinearVisualSteps.ts +28 -0
  103. package/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.test.ts +83 -0
  104. package/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax.ts +34 -0
  105. package/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.test.ts +249 -0
  106. package/src/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue.ts +41 -0
  107. package/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.test.ts +204 -0
  108. package/src/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue.ts +35 -0
  109. package/src/components/slider/slider/sliderHandleSvgHandler.ts +26 -0
  110. package/src/components/storeButton/assets/androidSvg.tsx +159 -0
  111. package/src/components/storeButton/assets/appleSvg.tsx +31 -0
  112. package/src/components/storeButton/storeButton.stories.tsx +67 -0
  113. package/src/components/storeButton/storeButton.styles.ts +36 -0
  114. package/src/components/storeButton/storeButton.test.tsx +22 -0
  115. package/src/components/storeButton/storeButton.tsx +30 -0
  116. package/src/components/storeButton/storeButton.types.tsx +15 -0
  117. package/src/icons/systemIcon.tsx +26 -0
  118. package/src/index.ts +1 -0
  119. package/src/provider/storybook/storybookProvider.tsx +11 -0
  120. package/src/provider/storybook/storybookProvider.types.ts +5 -0
  121. package/src/provider/styledComponents/theme/styledComponentsThemeProvider.tsx +14 -0
  122. package/src/provider/styledComponents/theme/styledComponentsThemeProvider.types..ts +5 -0
  123. package/src/style/styledComponents/mmb_variables-5224.json +958 -0
  124. package/src/style/styledComponents/theme.ts +450 -0
  125. package/stylelint.config.js +15 -0
  126. package/tsconfig.json +29 -0
  127. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+
3
+ import React, { FC } from 'react';
4
+
5
+ import { ButtonStyled, IconWrapperStyled } from './button.styles';
6
+ import { ButtonType, Props } from './button.types';
7
+
8
+ const Button: FC<Props> = (props) => {
9
+ const { buttonStyle, children, disabled = false, displayOnlyIcon = false, iconLeft, iconRight, onClick, size, type = ButtonType.BUTTON } = props;
10
+
11
+ return (
12
+ <ButtonStyled
13
+ buttonStyle={buttonStyle}
14
+ disabled={disabled}
15
+ displayOnlyIcon={displayOnlyIcon}
16
+ size={size}
17
+ type={type}
18
+ onClick={onClick}
19
+ >
20
+ {iconLeft !== undefined && <IconWrapperStyled size={size}>{iconLeft}</IconWrapperStyled>}
21
+ {!displayOnlyIcon && (
22
+ <>
23
+ {children}
24
+ {iconRight !== undefined && <IconWrapperStyled size={size}>{iconRight}</IconWrapperStyled>}
25
+ </>
26
+ )}
27
+ </ButtonStyled>
28
+ );
29
+ };
30
+
31
+ export default Button;
@@ -0,0 +1,33 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ export enum ButtonStyle {
4
+ PRIMARY = 'primary',
5
+ SECONDARY = 'secondary',
6
+ TERTIARY = 'tertiary',
7
+ }
8
+
9
+ export enum ButtonSize {
10
+ MD = 'md',
11
+ SM = 'sm',
12
+ XL = 'xl',
13
+ XS = 'xs',
14
+ XXL = 'xxl',
15
+ }
16
+
17
+ export enum ButtonType {
18
+ BUTTON = 'button',
19
+ RESET = 'reset',
20
+ SUBMIT = 'submit',
21
+ }
22
+
23
+ export interface Props {
24
+ buttonStyle: ButtonStyle;
25
+ children: ReactNode;
26
+ disabled?: boolean;
27
+ displayOnlyIcon?: boolean;
28
+ iconLeft?: ReactNode;
29
+ iconRight?: ReactNode;
30
+ onClick?: () => void;
31
+ size: ButtonSize;
32
+ type?: ButtonType;
33
+ }
@@ -0,0 +1,10 @@
1
+ import { css } from 'styled-components';
2
+
3
+ export const hint = css`
4
+ display: inline;
5
+ font-size: ${({ theme }) => theme.font.size.body.sm};
6
+ line-height: ${({ theme }) => theme.font.lineHeight.body.sm};
7
+ font-weight: ${({ theme }) => theme.font.weight.normal};
8
+ letter-spacing: ${({ theme }) => theme.font.letterSpacing.body.md};
9
+ color: ${({ theme }) => theme.colors.fg.neutral.subtle.light};
10
+ `;
@@ -0,0 +1,13 @@
1
+ //TODO: this is mock
2
+
3
+ import React from 'react';
4
+ import { Props } from '@/components/form/hint/formHint.types';
5
+ import { hint } from '@/components/form/hint/formHint.style';
6
+
7
+ const FormHint: React.FC<Props> = (props) => {
8
+ const { children } = props;
9
+
10
+ return <span css={[hint]}>{children}</span>;
11
+ };
12
+
13
+ export default FormHint;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export interface Props {
4
+ readonly children: React.ReactNode;
5
+ }
@@ -0,0 +1,176 @@
1
+ import React, { useState } from 'react';
2
+ import type { Meta, Parameters, StoryObj } from '@storybook/react';
3
+ import Slider from '@/components/slider/slider/slider';
4
+ import { MinMaxLabels, Props, SliderSteps, SliderStepType } from '@/components/slider/slider/slider.types';
5
+
6
+ interface SliderParameters extends Parameters {
7
+ defaultValue: number;
8
+ }
9
+
10
+ const defaultValueParamName = 'defaultValue';
11
+
12
+ const defaultMin = 100;
13
+ const defaultMax = 1000;
14
+ const defaultMinMaxLabels: MinMaxLabels = {
15
+ min: `${defaultMin} Kč`,
16
+ max: `${defaultMax} Kč`,
17
+ };
18
+ const argTypeMinMaxLabels = {
19
+ default: defaultMinMaxLabels,
20
+ undefined: undefined,
21
+ };
22
+
23
+ const meta = {
24
+ title: 'Slider/Slider',
25
+ component: Slider,
26
+ parameters: {},
27
+ tags: ['autodocs'],
28
+ argTypes: {
29
+ stepType: {
30
+ type: {
31
+ name: 'enum',
32
+ value: Object.values(SliderStepType),
33
+ },
34
+ },
35
+ value: {
36
+ table: {
37
+ disable: true,
38
+ },
39
+ },
40
+ onChange: {
41
+ table: {
42
+ disable: true,
43
+ },
44
+ },
45
+ disable: {
46
+ type: {
47
+ name: 'boolean',
48
+ },
49
+ },
50
+ minMaxLabels: {
51
+ defaultValue: argTypeMinMaxLabels.default,
52
+ options: Object.keys(argTypeMinMaxLabels),
53
+ mapping: argTypeMinMaxLabels,
54
+ control: {
55
+ type: 'radio',
56
+ },
57
+ },
58
+ },
59
+ decorators: [
60
+ (story, context) => {
61
+ const { args, parameters } = context;
62
+ const params: SliderParameters = parameters as SliderParameters;
63
+
64
+ const [value, setValue] = useState<number>(params[defaultValueParamName]);
65
+
66
+ return (
67
+ <>
68
+ {story({
69
+ args: {
70
+ ...args,
71
+ value: value,
72
+ onChange: setValue,
73
+ },
74
+ })}
75
+ <span
76
+ style={{
77
+ fontSize: 32,
78
+ }}
79
+ >
80
+ {value.toLocaleString('cs-CZ')}
81
+ </span>
82
+ </>
83
+ );
84
+ },
85
+ ],
86
+ } satisfies Meta<typeof Slider>;
87
+
88
+ export default meta;
89
+
90
+ type Story = StoryObj<typeof meta>;
91
+
92
+ const defaultSteps: SliderSteps = {
93
+ baseStep: 2,
94
+ breakpointList: [
95
+ {
96
+ step: 50,
97
+ bottomBreakpoint: 500,
98
+ },
99
+ ],
100
+ };
101
+
102
+ const defaultOnFinalChange = (value: number) => {
103
+ console.log('defaultOnFinalChange', value);
104
+ };
105
+
106
+ const defaultProps: Props = {
107
+ steps: defaultSteps,
108
+ min: defaultMin,
109
+ max: defaultMax,
110
+ onFinalChange: defaultOnFinalChange,
111
+ stepType: SliderStepType.DEFAULT,
112
+ // is overwritten in the decorator
113
+ onChange: () => {
114
+ console.log('mock');
115
+ },
116
+ value: Number.NaN, // is overwritten in the decorator
117
+ minMaxLabels: defaultMinMaxLabels,
118
+ };
119
+
120
+ export const Default: Story = {
121
+ args: {
122
+ ...defaultProps,
123
+ },
124
+ parameters: ((): SliderParameters => {
125
+ return {
126
+ defaultValue: 200,
127
+ };
128
+ })(),
129
+ };
130
+
131
+ export const LinearVisualSteps: Story = {
132
+ args: {
133
+ ...defaultProps,
134
+ stepType: SliderStepType.LINEAR_VISUAL_STEP,
135
+ },
136
+ parameters: ((): SliderParameters => {
137
+ return {
138
+ defaultValue: 200,
139
+ };
140
+ })(),
141
+ };
142
+
143
+ export const AirBankMortgage: Story = {
144
+ args: {
145
+ ...defaultProps,
146
+ stepType: SliderStepType.LINEAR_VISUAL_STEP,
147
+ min: 334_000,
148
+ max: 38_000_000,
149
+ steps: {
150
+ baseStep: 16_000,
151
+ breakpointList: [
152
+ {
153
+ step: 25_000,
154
+ bottomBreakpoint: 350_000,
155
+ },
156
+ {
157
+ step: 50_000,
158
+ bottomBreakpoint: 1_500_000,
159
+ },
160
+ {
161
+ step: 100_000,
162
+ bottomBreakpoint: 2_500_000,
163
+ },
164
+ {
165
+ step: 2_500_000,
166
+ bottomBreakpoint: 10_000_000,
167
+ },
168
+ ],
169
+ },
170
+ },
171
+ parameters: ((): SliderParameters => {
172
+ return {
173
+ defaultValue: 3_000_000,
174
+ };
175
+ })(),
176
+ };
@@ -0,0 +1,29 @@
1
+ import { css } from 'styled-components';
2
+
3
+ export const sliderWrapper = css`
4
+ display: flex;
5
+ align-items: center;
6
+ height: 24px; /* height of handle */
7
+ `;
8
+
9
+ export const wrapper = css`
10
+ display: flex;
11
+ flex-direction: column;
12
+ row-gap: ${({ theme }) => theme.spacing.xs};
13
+ `;
14
+
15
+ export const labelsWrapper = css`
16
+ display: flex;
17
+ `;
18
+
19
+ export const hintLeft = css`
20
+ display: flex;
21
+ flex: 1;
22
+ justify-content: left;
23
+ `;
24
+
25
+ export const hintRight = css`
26
+ display: flex;
27
+ flex: 1;
28
+ justify-content: right;
29
+ `;
@@ -0,0 +1,136 @@
1
+ import 'rc-slider/assets/index.css';
2
+
3
+ import RcSlider from 'rc-slider';
4
+ import React, { useMemo } from 'react';
5
+ import { Props, SliderMapFunction, SliderMapOnChangeFunction, SliderStepType } from './slider.types';
6
+ import { hintLeft, hintRight, labelsWrapper, sliderWrapper, wrapper } from '@/components/slider/slider/slider.style';
7
+ import { sliderFunctionDefault } from '@/components/slider/slider/sliderFunction/default/sliderFunctionDefault';
8
+ import { sliderFunctionLinearVisualSteps } from '@/components/slider/slider/sliderFunction/linearVisualSteps/sliderFunctionLinearVisualSteps';
9
+ import { getValueBySliderValue } from '@/components/slider/slider/sliderFunction/linearVisualSteps/valueBySliderValue';
10
+ import { theme } from '@/style/styledComponents/theme';
11
+ import FormHint from '@/components/form/hint/formHint';
12
+ import { getSliderHandleBackgroundSvgBase64 } from '@/components/slider/slider/sliderHandleSvgHandler';
13
+
14
+ const Slider: React.FC<Props> = (props) => {
15
+ const { disable = false, max, min, minMaxLabels, onChange, onFinalChange, steps, stepType, value } = props;
16
+
17
+ // function for mapping values to slider values (if he wants to use non-linearity)
18
+ const sliderMapFunction = useMemo<SliderMapFunction>(() => {
19
+ switch (stepType) {
20
+ case SliderStepType.DEFAULT:
21
+ return sliderFunctionDefault;
22
+ case SliderStepType.LINEAR_VISUAL_STEP:
23
+ return sliderFunctionLinearVisualSteps;
24
+ default:
25
+ throw new Error('unexpected SliderStepType in Slider sliderMapFunction');
26
+ }
27
+ }, [stepType]);
28
+
29
+ const { sliderMax, sliderMin, sliderStep, sliderValue } = sliderMapFunction({
30
+ min: min,
31
+ max: max,
32
+ value: value,
33
+ steps: steps,
34
+ });
35
+
36
+ // basically inverse function to sliderMapFunction (used for onChange and onFinalChange if not undefined). Unlike sliderMapFunction, only value is remapped here (not the min step, max step, etc.).
37
+ const sliderMapOnChangeFunction = useMemo<SliderMapOnChangeFunction | undefined>(() => {
38
+ switch (stepType) {
39
+ case SliderStepType.DEFAULT:
40
+ return undefined;
41
+ case SliderStepType.LINEAR_VISUAL_STEP:
42
+ return getValueBySliderValue;
43
+ default:
44
+ throw new Error('unexpected SliderStepType in Slider sliderMapOnChangeFunction');
45
+ }
46
+ }, [stepType]);
47
+
48
+ const handleBackgroundSvgBase64 = useMemo(() => {
49
+ return getSliderHandleBackgroundSvgBase64(disable);
50
+ }, [disable]);
51
+
52
+ return (
53
+ <div css={[wrapper]}>
54
+ <div css={[sliderWrapper]}>
55
+ <RcSlider
56
+ max={sliderMax}
57
+ min={sliderMin}
58
+ step={sliderStep}
59
+ styles={{
60
+ track: {
61
+ background: disable ? theme.colors.fg.disabled.light : `linear-gradient(270deg, ${theme.palette.pink600} 10.24%, ${theme.palette.blue600} 100%)`,
62
+ height: 4,
63
+ borderRadius: theme.borderRadius.xs,
64
+ },
65
+ rail: {
66
+ backgroundColor: disable ? theme.colors.bg.disabled.light : theme.colors.bg.brand.default.light,
67
+ height: 4,
68
+ borderRadius: theme.borderRadius.xs,
69
+ },
70
+ handle: {
71
+ height: 24,
72
+ width: 24,
73
+ border: 'none',
74
+ backgroundImage: `url("data:image/svg+xml;base64,${handleBackgroundSvgBase64}")`,
75
+ opacity: 1,
76
+ marginTop: -9,
77
+ boxShadow: 'none',
78
+ cursor: disable ? 'default' : 'pointer',
79
+ },
80
+ }}
81
+ value={sliderValue}
82
+ onChange={(valueParam) => {
83
+ if (typeof valueParam !== 'number') {
84
+ throw new TypeError('unexpected type in onChange');
85
+ }
86
+ if (disable) {
87
+ return;
88
+ }
89
+
90
+ onChange(
91
+ sliderMapOnChangeFunction === undefined
92
+ ? valueParam
93
+ : sliderMapOnChangeFunction({
94
+ min: min,
95
+ max: max,
96
+ steps: steps,
97
+ sliderValue: valueParam,
98
+ }),
99
+ );
100
+ }}
101
+ onChangeComplete={(valueParam) => {
102
+ if (typeof valueParam !== 'number') {
103
+ throw new TypeError('unexpected type in onChangeComplete');
104
+ }
105
+ if (disable) {
106
+ return;
107
+ }
108
+
109
+ onFinalChange(
110
+ sliderMapOnChangeFunction === undefined
111
+ ? valueParam
112
+ : sliderMapOnChangeFunction({
113
+ min: min,
114
+ max: max,
115
+ steps: steps,
116
+ sliderValue: valueParam,
117
+ }),
118
+ );
119
+ }}
120
+ />
121
+ </div>
122
+ {minMaxLabels !== undefined && (
123
+ <div css={[labelsWrapper]}>
124
+ <div css={[hintLeft]}>
125
+ <FormHint>{minMaxLabels.min}</FormHint>
126
+ </div>
127
+ <div css={[hintRight]}>
128
+ <FormHint>{minMaxLabels.max}</FormHint>
129
+ </div>
130
+ </div>
131
+ )}
132
+ </div>
133
+ );
134
+ };
135
+
136
+ export default Slider;
@@ -0,0 +1,58 @@
1
+ export interface SliderMapFunctionParam {
2
+ readonly max: number;
3
+ readonly min: number;
4
+ readonly steps: SliderSteps;
5
+ readonly value: number;
6
+ }
7
+
8
+ export interface SliderMapFunctionReturn {
9
+ readonly sliderMax: number;
10
+ readonly sliderMin: number;
11
+ readonly sliderStep: number | undefined;
12
+ readonly sliderValue: number;
13
+ }
14
+
15
+ export type SliderMapFunction = (param: SliderMapFunctionParam) => SliderMapFunctionReturn;
16
+
17
+ export interface SliderMapOnChangeFunctionParam {
18
+ readonly max: number;
19
+ readonly min: number;
20
+ readonly sliderValue: number;
21
+ readonly steps: SliderSteps;
22
+ }
23
+
24
+ export type SliderMapOnChangeFunction = (param: SliderMapOnChangeFunctionParam) => number;
25
+
26
+ export interface SliderBreakpoint {
27
+ readonly bottomBreakpoint: number;
28
+ readonly step: number;
29
+ }
30
+
31
+ export interface SliderSteps {
32
+ readonly baseStep: number; // on the left side
33
+ readonly breakpointList: SliderBreakpoint[]; // if empty, baseStep is used for the whole length
34
+ }
35
+
36
+ export enum SliderStepType {
37
+ DEFAULT = 'default', // step changes dynamically (visually steps are of different sizes)
38
+ LINEAR_VISUAL_STEP = 'linearVisualStep', // step is visually always the same (step can be shifted by different values)
39
+ }
40
+
41
+ export interface MinMaxLabels {
42
+ readonly max: string;
43
+ readonly min: string;
44
+ }
45
+
46
+ export interface Props {
47
+ readonly disable?: boolean | undefined;
48
+ readonly max: number;
49
+ readonly min: number;
50
+ readonly minMaxLabels: MinMaxLabels | undefined;
51
+ // it is triggered during movement
52
+ readonly onChange: (values: number) => void;
53
+ // it is triggered after the user drops the handle
54
+ readonly onFinalChange: (values: number) => void;
55
+ readonly stepType: SliderStepType;
56
+ readonly steps: SliderSteps;
57
+ readonly value: number;
58
+ }
@@ -0,0 +1,21 @@
1
+ import { SliderMapFunction } from '@/components/slider/slider/slider.types';
2
+
3
+ export const sliderFunctionDefault: SliderMapFunction = (param) => {
4
+ const { max, min, steps, value } = param;
5
+
6
+ const step = steps.breakpointList.reduce((accumulator, currentValue) => {
7
+ if (value < currentValue.bottomBreakpoint) {
8
+ return accumulator;
9
+ }
10
+
11
+ return currentValue.step;
12
+ }, steps.baseStep);
13
+
14
+ return {
15
+ sliderStep: step,
16
+ sliderValue: value,
17
+ sliderMax: max,
18
+ sliderMin: min,
19
+ sliderMarks: undefined,
20
+ };
21
+ };
@@ -0,0 +1,90 @@
1
+ import { getSliderStep } from '@/components/slider/slider/sliderFunction/default/sliderStep';
2
+ import { SliderSteps } from '@/components/slider/slider/slider.types';
3
+
4
+ describe('Running Test for slider default step', () => {
5
+ test('one step', () => {
6
+ const steps: SliderSteps = {
7
+ baseStep: 1,
8
+ breakpointList: [],
9
+ };
10
+
11
+ expect(
12
+ getSliderStep({
13
+ steps: steps,
14
+ value: 1,
15
+ }),
16
+ ).toBe(1);
17
+
18
+ expect(
19
+ getSliderStep({
20
+ steps: steps,
21
+ value: 100,
22
+ }),
23
+ ).toBe(1);
24
+ });
25
+
26
+ test('multiple step', () => {
27
+ const steps: SliderSteps = {
28
+ baseStep: 1,
29
+ breakpointList: [
30
+ {
31
+ step: 2,
32
+ bottomBreakpoint: 20,
33
+ },
34
+ {
35
+ step: 3,
36
+ bottomBreakpoint: 30,
37
+ },
38
+ ],
39
+ };
40
+
41
+ expect(
42
+ getSliderStep({
43
+ steps: steps,
44
+ value: 1,
45
+ }),
46
+ ).toBe(1);
47
+
48
+ expect(
49
+ getSliderStep({
50
+ steps: steps,
51
+ value: 19,
52
+ }),
53
+ ).toBe(1);
54
+
55
+ expect(
56
+ getSliderStep({
57
+ steps: steps,
58
+ value: 20,
59
+ }),
60
+ ).toBe(2);
61
+
62
+ expect(
63
+ getSliderStep({
64
+ steps: steps,
65
+ value: 21,
66
+ }),
67
+ ).toBe(2);
68
+
69
+ expect(
70
+ getSliderStep({
71
+ steps: steps,
72
+ value: 29,
73
+ }),
74
+ ).toBe(2);
75
+
76
+ expect(
77
+ getSliderStep({
78
+ steps: steps,
79
+ value: 30,
80
+ }),
81
+ ).toBe(3);
82
+
83
+ expect(
84
+ getSliderStep({
85
+ steps: steps,
86
+ value: 300,
87
+ }),
88
+ ).toBe(3);
89
+ });
90
+ });
@@ -0,0 +1,18 @@
1
+ import { SliderSteps } from '@/components/slider/slider/slider.types';
2
+
3
+ interface GetSliderStepParam {
4
+ readonly steps: SliderSteps;
5
+ readonly value: number;
6
+ }
7
+
8
+ export const getSliderStep = (param: GetSliderStepParam): number => {
9
+ const { steps, value } = param;
10
+
11
+ return steps.breakpointList.reduce((accumulator, currentValue) => {
12
+ if (value < currentValue.bottomBreakpoint) {
13
+ return accumulator;
14
+ }
15
+
16
+ return currentValue.step;
17
+ }, steps.baseStep);
18
+ };
@@ -0,0 +1,28 @@
1
+ import { SliderMapFunction } from '@/components/slider/slider/slider.types';
2
+ import { getSliderMax } from '@/components/slider/slider/sliderFunction/linearVisualSteps/sliderMax';
3
+ import { getSliderValueByValue } from '@/components/slider/slider/sliderFunction/linearVisualSteps/sliderValueByValue';
4
+
5
+ export const sliderFunctionLinearVisualSteps: SliderMapFunction = (param) => {
6
+ const { max, min, steps, value } = param;
7
+
8
+ const sliderMax = getSliderMax({
9
+ max: max,
10
+ steps: steps,
11
+ min: min,
12
+ });
13
+
14
+ const sliderValue = getSliderValueByValue({
15
+ value: value,
16
+ steps: steps,
17
+ min: min,
18
+ max: max,
19
+ });
20
+
21
+ return {
22
+ sliderStep: 1,
23
+ sliderValue: sliderValue,
24
+ sliderMax: sliderMax,
25
+ sliderMin: min,
26
+ sliderMarks: undefined,
27
+ };
28
+ };