Skip to content

Commit

Permalink
Fix for Slider to support Form properly
Browse files Browse the repository at this point in the history
  • Loading branch information
metalix2 committed Aug 2, 2024
1 parent 427b406 commit 2bff815
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 11 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} />
</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;
82 changes: 73 additions & 9 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 2bff815

Please sign in to comment.