@faststore/ui 1.10.6 → 1.10.13

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/CHANGELOG.md CHANGED
@@ -3,6 +3,33 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.10.13](https://github.com/vtex/faststore/compare/v1.10.12...v1.10.13) (2022-07-13)
7
+
8
+ **Note:** Version bump only for package @faststore/ui
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.10.12](https://github.com/vtex/faststore/compare/v1.10.11...v1.10.12) (2022-07-12)
15
+
16
+ **Note:** Version bump only for package @faststore/ui
17
+
18
+
19
+
20
+
21
+
22
+ ## [1.10.7](https://github.com/vtex/faststore/compare/v1.10.6...v1.10.7) (2022-07-06)
23
+
24
+
25
+ ### Features
26
+
27
+ * Supports update of `Slider` and `PriceRange` values ([#1380](https://github.com/vtex/faststore/issues/1380)) ([41dca35](https://github.com/vtex/faststore/commit/41dca35f0c320cf1659e8a74032cc2ee755a9f6f))
28
+
29
+
30
+
31
+
32
+
6
33
  ## 1.10.6 (2022-07-05)
7
34
 
8
35
 
@@ -1,4 +1,8 @@
1
- /// <reference types="react" />
1
+ /**
2
+ * This code is inspired by the work of [sandra-lewis](https://codesandbox.io/u/sandra-lewis)
3
+ */
4
+ import React from 'react';
5
+ import type { ReactNode } from 'react';
2
6
  interface Range {
3
7
  absolute: number;
4
8
  selected: number;
@@ -40,6 +44,20 @@ export declare type SliderProps = {
40
44
  * Returns the value of element's class content attribute.
41
45
  */
42
46
  className?: string;
47
+ /**
48
+ * Component that renders min value label above the left thumb.
49
+ */
50
+ minValueLabelComponent?: (minValue: number) => ReactNode;
51
+ /**
52
+ * Component that renders max value label above the right thumb.
53
+ */
54
+ maxValueLabelComponent?: (maxValue: number) => ReactNode;
55
+ };
56
+ declare type SliderRefType = {
57
+ setSliderValues: (values: {
58
+ min: number;
59
+ max: number;
60
+ }) => void;
43
61
  };
44
- declare const Slider: ({ min, max, onChange, onEnd, testId, getAriaValueText, className, }: SliderProps) => JSX.Element;
62
+ declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<SliderRefType | undefined>>;
45
63
  export default Slider;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * This code is inspired by the work of [sandra-lewis](https://codesandbox.io/u/sandra-lewis)
3
3
  */
4
- import React, { useState, useMemo } from 'react';
4
+ import React, { useState, useMemo, useImperativeHandle, forwardRef, } from 'react';
5
5
  const percent = (value, min, max) => Math.round(((value - min) / (max - min)) * 100);
6
- const Slider = ({ min, max, onChange, onEnd, testId = 'store-slider', getAriaValueText, className, }) => {
6
+ const Slider = forwardRef(function Slider({ min, max, onChange, onEnd, testId = 'store-slider', getAriaValueText, className, minValueLabelComponent, maxValueLabelComponent, }, ref) {
7
7
  const [minPercent, setMinPercent] = useState(() => percent(min.selected, min.absolute, max.absolute));
8
8
  const [maxPercent, setMaxPercent] = useState(() => percent(max.selected, min.absolute, max.absolute));
9
9
  const { minVal, maxVal } = useMemo(() => {
@@ -13,18 +13,33 @@ const Slider = ({ min, max, onChange, onEnd, testId = 'store-slider', getAriaVal
13
13
  maxVal: min.absolute + maxPercent * widthPercent,
14
14
  };
15
15
  }, [min, max, maxPercent, minPercent]);
16
+ useImperativeHandle(ref, () => ({
17
+ setSliderValues: (values) => {
18
+ const sliderMinValue = Math.min(Number(values.min), maxVal);
19
+ const sliderMaxValue = Math.max(Number(values.max), minVal);
20
+ setMinPercent(percent(sliderMinValue, min.absolute, max.absolute));
21
+ setMaxPercent(percent(sliderMaxValue, min.absolute, max.absolute));
22
+ },
23
+ }));
16
24
  return (React.createElement("div", { "data-store-slider": true, "data-testid": testId, className: className },
17
- React.createElement("div", { style: { left: `${minPercent}%`, width: `${maxPercent - minPercent}%` }, "data-slider-range": true }),
25
+ React.createElement("div", { style: {
26
+ left: `${minPercent < min.absolute ? min.absolute : minPercent}%`,
27
+ width: `${maxPercent - minPercent > 100
28
+ ? 100 - minPercent
29
+ : maxPercent - minPercent}%`,
30
+ }, "data-slider-range": true }),
31
+ minValueLabelComponent && minValueLabelComponent(minVal),
18
32
  React.createElement("input", { type: "range", min: min.absolute, max: max.absolute, value: minVal, onMouseUp: () => onEnd?.({ min: minVal, max: maxVal }), onTouchEnd: () => onEnd?.({ min: minVal, max: maxVal }), onChange: (event) => {
19
33
  const minValue = Math.min(Number(event.target.value), maxVal);
20
34
  setMinPercent(percent(minValue, min.absolute, max.absolute));
21
35
  onChange?.({ min: minValue, max: maxVal });
22
36
  }, "data-slider-thumb": "left", "aria-valuemin": min.absolute, "aria-valuemax": max.absolute, "aria-valuenow": minVal, "aria-label": String(minVal), "aria-labelledby": getAriaValueText?.(minVal, 'min') }),
37
+ maxValueLabelComponent && maxValueLabelComponent(maxVal),
23
38
  React.createElement("input", { type: "range", min: min.absolute, max: max.absolute, value: maxVal, onMouseUp: () => onEnd?.({ min: minVal, max: maxVal }), onTouchEnd: () => onEnd?.({ min: minVal, max: maxVal }), onChange: (event) => {
24
39
  const maxValue = Math.max(Number(event.target.value), minVal);
25
40
  setMaxPercent(percent(maxValue, min.absolute, max.absolute));
26
41
  onChange?.({ min: minVal, max: maxValue });
27
42
  }, "data-slider-thumb": "right", "aria-valuemin": min.absolute, "aria-valuemax": max.absolute, "aria-valuenow": maxVal, "aria-label": String(maxVal), "aria-labelledby": getAriaValueText?.(maxVal, 'max') })));
28
- };
43
+ });
29
44
  export default Slider;
30
45
  //# sourceMappingURL=Slider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../../src/atoms/Slider/Slider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../../src/atoms/Slider/Slider.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import type { AriaAttributes } from 'react';
2
3
  import type { PriceProps } from '../../atoms/Price';
3
4
  import type { SliderProps } from '../../atoms/Slider';
@@ -19,5 +20,28 @@ export declare type PriceRangeProps = SliderProps & {
19
20
  */
20
21
  'aria-label'?: AriaAttributes['aria-label'];
21
22
  };
22
- declare const PriceRange: ({ className, formatter, max, min, onChange, onEnd, testId, variant, "aria-label": ariaLabel, }: PriceRangeProps) => JSX.Element;
23
+ declare type PriceRangeRefType = {
24
+ setPriceRangeValues: (values: {
25
+ min: number;
26
+ max: number;
27
+ }) => void;
28
+ };
29
+ declare const PriceRange: React.ForwardRefExoticComponent<SliderProps & {
30
+ /**
31
+ * The current use case variant for prices.
32
+ */
33
+ variant?: PriceProps['variant'];
34
+ /**
35
+ * Formatter function that transforms the raw price value and render the result.
36
+ */
37
+ formatter: PriceProps['formatter'];
38
+ /**
39
+ * Returns the value of element's class content attribute.
40
+ */
41
+ className?: string | undefined;
42
+ /**
43
+ * Defines a string value that labels the current element.
44
+ */
45
+ 'aria-label'?: AriaAttributes['aria-label'];
46
+ } & React.RefAttributes<PriceRangeRefType | undefined>>;
23
47
  export default PriceRange;
@@ -1,16 +1,28 @@
1
- import React, { useState } from 'react';
1
+ import React, { useRef, useImperativeHandle, forwardRef } from 'react';
2
2
  import Price from '../../atoms/Price';
3
3
  import Slider from '../../atoms/Slider';
4
- const PriceRange = ({ className, formatter, max, min, onChange, onEnd, testId = 'store-price-range', variant, 'aria-label': ariaLabel, }) => {
5
- const [edges, setEdges] = useState({ min: min.selected, max: max.selected });
4
+ const PriceRange = forwardRef(function PriceRange({ className, formatter, max, min, onChange, onEnd, testId = 'store-price-range', variant, 'aria-label': ariaLabel, }, ref) {
5
+ const sliderRef = useRef();
6
+ useImperativeHandle(ref, () => ({
7
+ setPriceRangeValues: (values) => {
8
+ onChange?.(values);
9
+ sliderRef.current?.setSliderValues(values);
10
+ },
11
+ }));
6
12
  return (React.createElement("div", { "data-store-price-range": true, "data-testid": testId, className: className },
7
- React.createElement(Slider, { min: min, max: max, onEnd: onEnd, onChange: (value) => {
8
- setEdges(value);
9
- onChange?.(value);
10
- }, "aria-label": ariaLabel }),
11
- React.createElement("div", { "data-price-range-values": true },
12
- React.createElement(Price, { formatter: formatter, "data-price-range-value": "min", value: edges.min, variant: variant }),
13
- React.createElement(Price, { formatter: formatter, "data-price-range-value": "max", value: edges.max, variant: variant }))));
14
- };
13
+ React.createElement(Slider, { ref: sliderRef, min: min, max: max, onEnd: onEnd, "aria-label": ariaLabel, onChange: (value) => onChange?.(value), minValueLabelComponent: (minValue) => {
14
+ const minPercent = (minValue / max.absolute) * 100;
15
+ return (React.createElement(Price, { value: minValue, variant: variant, formatter: formatter, "data-price-range-value-label": "min", style: {
16
+ position: 'absolute',
17
+ left: `calc(${minPercent}% + (${8 - minPercent * 0.2}px))`,
18
+ } }));
19
+ }, maxValueLabelComponent: (maxValue) => {
20
+ const maxPercent = (maxValue / max.absolute) * 100;
21
+ return (React.createElement(Price, { formatter: formatter, variant: variant, value: maxValue, "data-price-range-value-label": "max", style: {
22
+ position: 'absolute',
23
+ left: `calc(${maxPercent}% + (${8 - maxPercent * 0.2}px))`,
24
+ } }));
25
+ } })));
26
+ });
15
27
  export default PriceRange;
16
28
  //# sourceMappingURL=PriceRange.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PriceRange.js","sourceRoot":"","sources":["../../../src/molecules/PriceRange/PriceRange.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGvC,OAAO,KAAK,MAAM,mBAAmB,CAAA;AACrC,OAAO,MAAM,MAAM,oBAAoB,CAAA;AAuBvC,MAAM,UAAU,GAAG,CAAC,EAClB,SAAS,EACT,SAAS,EACT,GAAG,EACH,GAAG,EACH,QAAQ,EACR,KAAK,EACL,MAAM,GAAG,mBAAmB,EAC5B,OAAO,EACP,YAAY,EAAE,SAAS,GACP,EAAE,EAAE;IACpB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAE5E,OAAO,CACL,4EAAyC,MAAM,EAAE,SAAS,EAAE,SAAS;QACnE,oBAAC,MAAM,IACL,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACf,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,gBACW,SAAS,GACrB;QACF;YACE,oBAAC,KAAK,IACJ,SAAS,EAAE,SAAS,4BACG,KAAK,EAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,EAChB,OAAO,EAAE,OAAO,GAChB;YACF,oBAAC,KAAK,IACJ,SAAS,EAAE,SAAS,4BACG,KAAK,EAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,EAChB,OAAO,EAAE,OAAO,GAChB,CACE,CACF,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,UAAU,CAAA"}
1
+ {"version":3,"file":"PriceRange.js","sourceRoot":"","sources":["../../../src/molecules/PriceRange/PriceRange.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGtE,OAAO,KAAK,MAAM,mBAAmB,CAAA;AACrC,OAAO,MAAM,MAAM,oBAAoB,CAAA;AA2BvC,MAAM,UAAU,GAAG,UAAU,CAC3B,SAAS,UAAU,CACjB,EACE,SAAS,EACT,SAAS,EACT,GAAG,EACH,GAAG,EACH,QAAQ,EACR,KAAK,EACL,MAAM,GAAG,mBAAmB,EAC5B,OAAO,EACP,YAAY,EAAE,SAAS,GACxB,EACD,GAAG;IAEH,MAAM,SAAS,GAAG,MAAM,EAEpB,CAAA;IAEJ,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9B,mBAAmB,EAAE,CAAC,MAAoC,EAAE,EAAE;YAC5D,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAA;YAClB,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;QAC5C,CAAC;KACF,CAAC,CAAC,CAAA;IAEH,OAAO,CACL,4EAAyC,MAAM,EAAE,SAAS,EAAE,SAAS;QACnE,oBAAC,MAAM,IACL,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,gBACA,SAAS,EACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,EACtC,sBAAsB,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACnC,MAAM,UAAU,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAA;gBAElD,OAAO,CACL,oBAAC,KAAK,IACJ,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,kCACS,KAAK,EAClC,KAAK,EAAE;wBACL,QAAQ,EAAE,UAAU;wBACpB,IAAI,EAAE,QAAQ,UAAU,QAAQ,CAAC,GAAG,UAAU,GAAG,GAAG,MAAM;qBAC3D,GACD,CACH,CAAA;YACH,CAAC,EACD,sBAAsB,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACnC,MAAM,UAAU,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAA;gBAElD,OAAO,CACL,oBAAC,KAAK,IACJ,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,QAAQ,kCACc,KAAK,EAClC,KAAK,EAAE;wBACL,QAAQ,EAAE,UAAU;wBACpB,IAAI,EAAE,QAAQ,UAAU,QAAQ,CAAC,GAAG,UAAU,GAAG,GAAG,MAAM;qBAC3D,GACD,CACH,CAAA;YACH,CAAC,GACD,CACE,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,eAAe,UAAU,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/ui",
3
- "version": "1.10.6",
3
+ "version": "1.10.13",
4
4
  "description": "A lightweight, framework agnostic component library for React",
5
5
  "author": "emersonlaurentino",
6
6
  "license": "MIT",
@@ -86,5 +86,5 @@
86
86
  "tsdx": "^0.14.1",
87
87
  "typescript": "^4.2.4"
88
88
  },
89
- "gitHead": "654744a6c3b29afacbd83c4d9ebefe4270d1ae2a"
89
+ "gitHead": "8381cea806c0a98b5fea50dfea4e9e6bcee351e9"
90
90
  }
@@ -1,7 +1,13 @@
1
1
  /**
2
2
  * This code is inspired by the work of [sandra-lewis](https://codesandbox.io/u/sandra-lewis)
3
3
  */
4
- import React, { useState, useMemo } from 'react'
4
+ import React, {
5
+ useState,
6
+ useMemo,
7
+ useImperativeHandle,
8
+ forwardRef,
9
+ } from 'react'
10
+ import type { ReactNode } from 'react'
5
11
 
6
12
  interface Range {
7
13
  absolute: number
@@ -39,85 +45,123 @@ export type SliderProps = {
39
45
  * Returns the value of element's class content attribute.
40
46
  */
41
47
  className?: string
48
+ /**
49
+ * Component that renders min value label above the left thumb.
50
+ */
51
+ minValueLabelComponent?: (minValue: number) => ReactNode
52
+ /**
53
+ * Component that renders max value label above the right thumb.
54
+ */
55
+ maxValueLabelComponent?: (maxValue: number) => ReactNode
56
+ }
57
+
58
+ type SliderRefType = {
59
+ setSliderValues: (values: { min: number; max: number }) => void
42
60
  }
43
61
 
44
62
  const percent = (value: number, min: number, max: number) =>
45
63
  Math.round(((value - min) / (max - min)) * 100)
46
64
 
47
- const Slider = ({
48
- min,
49
- max,
50
- onChange,
51
- onEnd,
52
- testId = 'store-slider',
53
- getAriaValueText,
54
- className,
55
- }: SliderProps) => {
56
- const [minPercent, setMinPercent] = useState(() =>
57
- percent(min.selected, min.absolute, max.absolute)
58
- )
65
+ const Slider = forwardRef<SliderRefType | undefined, SliderProps>(
66
+ function Slider(
67
+ {
68
+ min,
69
+ max,
70
+ onChange,
71
+ onEnd,
72
+ testId = 'store-slider',
73
+ getAriaValueText,
74
+ className,
75
+ minValueLabelComponent,
76
+ maxValueLabelComponent,
77
+ },
78
+ ref
79
+ ) {
80
+ const [minPercent, setMinPercent] = useState(() =>
81
+ percent(min.selected, min.absolute, max.absolute)
82
+ )
59
83
 
60
- const [maxPercent, setMaxPercent] = useState(() =>
61
- percent(max.selected, min.absolute, max.absolute)
62
- )
84
+ const [maxPercent, setMaxPercent] = useState(() =>
85
+ percent(max.selected, min.absolute, max.absolute)
86
+ )
63
87
 
64
- const { minVal, maxVal } = useMemo(() => {
65
- const widthPercent = (max.absolute - min.absolute) / 100
88
+ const { minVal, maxVal } = useMemo(() => {
89
+ const widthPercent = (max.absolute - min.absolute) / 100
66
90
 
67
- return {
68
- minVal: min.absolute + minPercent * widthPercent,
69
- maxVal: min.absolute + maxPercent * widthPercent,
70
- }
71
- }, [min, max, maxPercent, minPercent])
91
+ return {
92
+ minVal: min.absolute + minPercent * widthPercent,
93
+ maxVal: min.absolute + maxPercent * widthPercent,
94
+ }
95
+ }, [min, max, maxPercent, minPercent])
72
96
 
73
- return (
74
- <div data-store-slider data-testid={testId} className={className}>
75
- <div
76
- style={{ left: `${minPercent}%`, width: `${maxPercent - minPercent}%` }}
77
- data-slider-range
78
- />
79
- <input
80
- type="range"
81
- min={min.absolute}
82
- max={max.absolute}
83
- value={minVal}
84
- onMouseUp={() => onEnd?.({ min: minVal, max: maxVal })}
85
- onTouchEnd={() => onEnd?.({ min: minVal, max: maxVal })}
86
- onChange={(event) => {
87
- const minValue = Math.min(Number(event.target.value), maxVal)
97
+ useImperativeHandle(ref, () => ({
98
+ setSliderValues: (values: { min: number; max: number }) => {
99
+ const sliderMinValue = Math.min(Number(values.min), maxVal)
100
+ const sliderMaxValue = Math.max(Number(values.max), minVal)
88
101
 
89
- setMinPercent(percent(minValue, min.absolute, max.absolute))
90
- onChange?.({ min: minValue, max: maxVal })
91
- }}
92
- data-slider-thumb="left"
93
- aria-valuemin={min.absolute}
94
- aria-valuemax={max.absolute}
95
- aria-valuenow={minVal}
96
- aria-label={String(minVal)}
97
- aria-labelledby={getAriaValueText?.(minVal, 'min')}
98
- />
99
- <input
100
- type="range"
101
- min={min.absolute}
102
- max={max.absolute}
103
- value={maxVal}
104
- onMouseUp={() => onEnd?.({ min: minVal, max: maxVal })}
105
- onTouchEnd={() => onEnd?.({ min: minVal, max: maxVal })}
106
- onChange={(event) => {
107
- const maxValue = Math.max(Number(event.target.value), minVal)
102
+ setMinPercent(percent(sliderMinValue, min.absolute, max.absolute))
103
+ setMaxPercent(percent(sliderMaxValue, min.absolute, max.absolute))
104
+ },
105
+ }))
108
106
 
109
- setMaxPercent(percent(maxValue, min.absolute, max.absolute))
110
- onChange?.({ min: minVal, max: maxValue })
111
- }}
112
- data-slider-thumb="right"
113
- aria-valuemin={min.absolute}
114
- aria-valuemax={max.absolute}
115
- aria-valuenow={maxVal}
116
- aria-label={String(maxVal)}
117
- aria-labelledby={getAriaValueText?.(maxVal, 'max')}
118
- />
119
- </div>
120
- )
121
- }
107
+ return (
108
+ <div data-store-slider data-testid={testId} className={className}>
109
+ <div
110
+ style={{
111
+ left: `${minPercent < min.absolute ? min.absolute : minPercent}%`,
112
+ width: `${
113
+ maxPercent - minPercent > 100
114
+ ? 100 - minPercent
115
+ : maxPercent - minPercent
116
+ }%`,
117
+ }}
118
+ data-slider-range
119
+ />
120
+ {minValueLabelComponent && minValueLabelComponent(minVal)}
121
+ <input
122
+ type="range"
123
+ min={min.absolute}
124
+ max={max.absolute}
125
+ value={minVal}
126
+ onMouseUp={() => onEnd?.({ min: minVal, max: maxVal })}
127
+ onTouchEnd={() => onEnd?.({ min: minVal, max: maxVal })}
128
+ onChange={(event) => {
129
+ const minValue = Math.min(Number(event.target.value), maxVal)
130
+
131
+ setMinPercent(percent(minValue, min.absolute, max.absolute))
132
+ onChange?.({ min: minValue, max: maxVal })
133
+ }}
134
+ data-slider-thumb="left"
135
+ aria-valuemin={min.absolute}
136
+ aria-valuemax={max.absolute}
137
+ aria-valuenow={minVal}
138
+ aria-label={String(minVal)}
139
+ aria-labelledby={getAriaValueText?.(minVal, 'min')}
140
+ />
141
+ {maxValueLabelComponent && maxValueLabelComponent(maxVal)}
142
+ <input
143
+ type="range"
144
+ min={min.absolute}
145
+ max={max.absolute}
146
+ value={maxVal}
147
+ onMouseUp={() => onEnd?.({ min: minVal, max: maxVal })}
148
+ onTouchEnd={() => onEnd?.({ min: minVal, max: maxVal })}
149
+ onChange={(event) => {
150
+ const maxValue = Math.max(Number(event.target.value), minVal)
151
+
152
+ setMaxPercent(percent(maxValue, min.absolute, max.absolute))
153
+ onChange?.({ min: minVal, max: maxValue })
154
+ }}
155
+ data-slider-thumb="right"
156
+ aria-valuemin={min.absolute}
157
+ aria-valuemax={max.absolute}
158
+ aria-valuenow={maxVal}
159
+ aria-label={String(maxVal)}
160
+ aria-labelledby={getAriaValueText?.(maxVal, 'max')}
161
+ />
162
+ </div>
163
+ )
164
+ }
165
+ )
122
166
 
123
167
  export default Slider
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import React, { useRef, useImperativeHandle, forwardRef } from 'react'
2
2
  import type { AriaAttributes } from 'react'
3
3
 
4
4
  import Price from '../../atoms/Price'
@@ -25,47 +25,81 @@ export type PriceRangeProps = SliderProps & {
25
25
  'aria-label'?: AriaAttributes['aria-label']
26
26
  }
27
27
 
28
- const PriceRange = ({
29
- className,
30
- formatter,
31
- max,
32
- min,
33
- onChange,
34
- onEnd,
35
- testId = 'store-price-range',
36
- variant,
37
- 'aria-label': ariaLabel,
38
- }: PriceRangeProps) => {
39
- const [edges, setEdges] = useState({ min: min.selected, max: max.selected })
28
+ type PriceRangeRefType = {
29
+ setPriceRangeValues: (values: { min: number; max: number }) => void
30
+ }
40
31
 
41
- return (
42
- <div data-store-price-range data-testid={testId} className={className}>
43
- <Slider
44
- min={min}
45
- max={max}
46
- onEnd={onEnd}
47
- onChange={(value) => {
48
- setEdges(value)
49
- onChange?.(value)
50
- }}
51
- aria-label={ariaLabel}
52
- />
53
- <div data-price-range-values>
54
- <Price
55
- formatter={formatter}
56
- data-price-range-value="min"
57
- value={edges.min}
58
- variant={variant}
59
- />
60
- <Price
61
- formatter={formatter}
62
- data-price-range-value="max"
63
- value={edges.max}
64
- variant={variant}
32
+ const PriceRange = forwardRef<PriceRangeRefType | undefined, PriceRangeProps>(
33
+ function PriceRange(
34
+ {
35
+ className,
36
+ formatter,
37
+ max,
38
+ min,
39
+ onChange,
40
+ onEnd,
41
+ testId = 'store-price-range',
42
+ variant,
43
+ 'aria-label': ariaLabel,
44
+ },
45
+ ref
46
+ ) {
47
+ const sliderRef = useRef<{
48
+ setSliderValues: (values: { min: number; max: number }) => void
49
+ }>()
50
+
51
+ useImperativeHandle(ref, () => ({
52
+ setPriceRangeValues: (values: { min: number; max: number }) => {
53
+ onChange?.(values)
54
+ sliderRef.current?.setSliderValues(values)
55
+ },
56
+ }))
57
+
58
+ return (
59
+ <div data-store-price-range data-testid={testId} className={className}>
60
+ <Slider
61
+ ref={sliderRef}
62
+ min={min}
63
+ max={max}
64
+ onEnd={onEnd}
65
+ aria-label={ariaLabel}
66
+ onChange={(value) => onChange?.(value)}
67
+ minValueLabelComponent={(minValue) => {
68
+ const minPercent = (minValue / max.absolute) * 100
69
+
70
+ return (
71
+ <Price
72
+ value={minValue}
73
+ variant={variant}
74
+ formatter={formatter}
75
+ data-price-range-value-label="min"
76
+ style={{
77
+ position: 'absolute',
78
+ left: `calc(${minPercent}% + (${8 - minPercent * 0.2}px))`,
79
+ }}
80
+ />
81
+ )
82
+ }}
83
+ maxValueLabelComponent={(maxValue) => {
84
+ const maxPercent = (maxValue / max.absolute) * 100
85
+
86
+ return (
87
+ <Price
88
+ formatter={formatter}
89
+ variant={variant}
90
+ value={maxValue}
91
+ data-price-range-value-label="max"
92
+ style={{
93
+ position: 'absolute',
94
+ left: `calc(${maxPercent}% + (${8 - maxPercent * 0.2}px))`,
95
+ }}
96
+ />
97
+ )
98
+ }}
65
99
  />
66
100
  </div>
67
- </div>
68
- )
69
- }
101
+ )
102
+ }
103
+ )
70
104
 
71
105
  export default PriceRange
@@ -5,7 +5,7 @@ import PriceRange from '../PriceRange'
5
5
  # PriceRange
6
6
 
7
7
  <Canvas>
8
- <Story id="molecules-price-range--price-range" />
8
+ <Story id="molecules-pricerange--price-range" />
9
9
  </Canvas>
10
10
 
11
11
  # Props
@@ -22,12 +22,12 @@ function formatter(price: number) {
22
22
 
23
23
  const argTypes: ComponentArgTypes<PriceRangeProps> = {
24
24
  min: {
25
- control: { type: 'number', min: 0 },
26
- defaultValue: 0,
25
+ control: { type: 'object' },
26
+ defaultValue: { selected: 10, absolute: 0 },
27
27
  },
28
28
  max: {
29
- control: { type: 'number', min: 1 },
30
- defaultValue: 500,
29
+ control: { type: 'object' },
30
+ defaultValue: { selected: 90, absolute: 100 },
31
31
  },
32
32
  formatter: {
33
33
  defaultValue: formatter,