Skip to content

Commit

Permalink
[LOOM-1520][BpkSlider] Fix for Slider to support Form properly (#3567)
Browse files Browse the repository at this point in the history
* Fix for Slider to support Form properly

* fix minor thing

* Slider snapshots

---------

Co-authored-by: metalix2 <[email protected]>
  • Loading branch information
metalix2 and metalix2 authored Aug 6, 2024
1 parent 52c4847 commit 7d9573d
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 16 deletions.
1 change: 1 addition & 0 deletions examples/bpk-component-slider/examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class SliderContainer extends Component {
value={this.state.value}
ariaLabel={['minimum', 'maximum']}
ariaValuetext={[this.state.value[0], this.state.value[1]]}
inputProps={[{name: 'min'}, {name: 'max'}]}
/>
<br />
</div>
Expand Down
58 changes: 56 additions & 2 deletions packages/bpk-component-slider/src/BpkSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
forwardRef,
useRef,
useEffect,
type ComponentPropsWithRef,
} from 'react';

import { useComposedRefs } from '@radix-ui/react-compose-refs';
import * as Slider from '@radix-ui/react-slider';
import { usePrevious } from '@radix-ui/react-use-previous';

import { cssModules, isRTL } from '../../bpk-react-utils';
import { cssModules, isRTL, setNativeValue } from '../../bpk-react-utils';

import STYLES from './BpkSlider.module.scss';

Expand All @@ -34,12 +42,14 @@ export type Props = {
value: number[] | number;
ariaLabel: string[];
ariaValuetext?: string[];
inputProps?: [{ [key: string]: any }];
[rest: string]: any;
};

const BpkSlider = ({
ariaLabel,
ariaValuetext,
inputProps,
max,
min,
minDistance,
Expand Down Expand Up @@ -93,10 +103,54 @@ const BpkSlider = ({
aria-valuetext={ariaValuetext ? ariaValuetext[index] : val.toString()}
className={getClassName('bpk-slider__thumb')}
aria-valuenow={currentValue[index]}
/>
asChild
>
{/* custom thumb with child input */}
<span>
<BubbleInput value={currentValue[index]} {...(inputProps && inputProps[index])} />
</span>
</Slider.Thumb>
))}
</Slider.Root>
);
};

// Work around until radix-ui/react-slider is updated to accept an inputRef prop https://github.com/radix-ui/primitives/pull/3033
const BubbleInput = forwardRef(
(props: ComponentPropsWithRef<'input'>, forwardedRef) => {
const { value, ...inputProps } = props;
const ref = useRef<HTMLInputElement>();
const composedRefs = useComposedRefs(forwardedRef, ref);

const prevValue = usePrevious(value);

// Bubble value change to parents (e.g form change event)
useEffect(() => {
const input = ref.current!;
if (prevValue !== value) {
setNativeValue(input, `${value}`);
}
}, [prevValue, value]);

/**
* We purposefully do not use `type="hidden"` here otherwise forms that
* wrap it will not be able to access its value via the FormData API.
*
* We purposefully do not add the `value` attribute here to allow the value
* to be set programatically and bubble to any parent form `onChange` event.
* Adding the `value` will cause React to consider the programatic
* dispatch a duplicate and it will get swallowed.
*/
return (
<input
style={{ display: 'none' }}
{...inputProps}
ref={composedRefs}
type="number"
defaultValue={value}
/>
);
},
);

export default BpkSlider;
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ exports[`BpkSlider should render correctly 1`] = `
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="25"
/>
</span>
</span>
</span>
</DocumentFragment>
Expand Down Expand Up @@ -76,7 +82,13 @@ exports[`BpkSlider should render correctly with a "step" attribute 1`] = `
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="25"
/>
</span>
</span>
</span>
</DocumentFragment>
Expand Down Expand Up @@ -117,7 +129,13 @@ exports[`BpkSlider should render correctly with a minimum distance between contr
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="10"
/>
</span>
</span>
<span
style="transform: var(--radix-slider-thumb-transform); position: absolute; left: calc(90% + 0px);"
Expand All @@ -135,7 +153,13 @@ exports[`BpkSlider should render correctly with a minimum distance between contr
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="90"
/>
</span>
</span>
</span>
</DocumentFragment>
Expand Down Expand Up @@ -176,7 +200,13 @@ exports[`BpkSlider should render correctly with a range of values 1`] = `
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="10"
/>
</span>
</span>
<span
style="transform: var(--radix-slider-thumb-transform); position: absolute; left: calc(90% + 0px);"
Expand All @@ -194,7 +224,13 @@ exports[`BpkSlider should render correctly with a range of values 1`] = `
role="slider"
style=""
tabindex="0"
/>
>
<input
style="display: none;"
type="number"
value="90"
/>
</span>
</span>
</span>
</DocumentFragment>
Expand Down
80 changes: 72 additions & 8 deletions packages/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"dependencies": {
"@floating-ui/react": "^0.26.12",
"@popperjs/core": "^2.11.8",
"@radix-ui/react-compose-refs": "^1.1.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-use-previous": "^1.1.0",
"@react-google-maps/api": "^2.19.3",
"@skyscanner/bpk-foundations-web": "^18.1.0",
"@skyscanner/bpk-svgs": "^19.3.0",
Expand Down

0 comments on commit 7d9573d

Please sign in to comment.