This is a react method to quickly combine buttons with Picker
framer-motion
yarn add @acrool/react-picker
add in your index.tsx
import "@acrool/react-picker/dist/index.css";
add in your App.tsx
import {isEmpty} from '@acrool/js-utils/equal';
import clsx from 'clsx';
import React, {ForwardedRef} from 'react';
import styled, {css} from 'styled-components';
import NumberKeyboard from './NumberKeyboard';
import {createPicker, usePicker} from '@acrool/react-picker';
interface IProps extends FCProps {
value?: number
options?: number[]
onChange?: (value: number) => void
placeholder?: string
}
/**
* Select Number Keyboard
*/
const SelectNumberKeyboard = ({
id,
placeholder = '0',
}: IProps, ref?: ForwardedRef<HTMLButtonElement>) => {
const Picker = usePicker();
/**
* Clean
*/
const handleClear = (e: React.MouseEvent) => {
e.stopPropagation();
Picker.onChange(0);
};
const isPlaceholderValue = isEmpty(Picker.value);
return <SelectNumberKeyboardRoot
ref={ref}
type="button"
onMouseDown={Picker.toggle}
isFocus={Picker.isInputFocus}
onFocus={Picker.inputFocus}
>
<Text isPlaceholderValue={isPlaceholderValue}>
{isPlaceholderValue ? placeholder: Picker.value}
</Text>
</SelectNumberKeyboardRoot>;
};
const Picker = (props: IProps) => {
const Picker = usePicker();
const handleClickPicker = (addNumber: number) => {
let result = 0;
const currValue = Picker.value ?? 0;
if(addNumber >= 0){
result = currValue + addNumber;
}
Picker.onChange(result);
};
return <NumberKeyboard
data={props.options}
onChange={handleClickPicker}
/>;
};
export default createPicker(
SelectNumberKeyboard,
Picker
);
const SelectNumberKeyboardRoot = styled.button<{
isFocus?: boolean,
}>`
transition: box-shadow .15s ease-in-out;
${props => props.isFocus && css`
box-shadow: 0 0 0 0.2rem rgb(0 123 255 / 25%);
`}
`;
export default createPicker(
SelectNumberKeyboard,
Picker
) as <V extends any>(props: IProps<V>) => JSX.Element;
There is also a example that you can play with it:
onMousedown
instead of onClick
.react-hook-form
is very usefulbutton > button
is an html structure error, and you need to use onMousedown
instead of onClick
.Warning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
interface IProps {
value: string,
onChange:(value: string) => void
}
const DateTimeField = (props: IProps) => {}
// fix to
const DateTimeFieldAfter = (props: IProps, ref?: ForwardedRef<HTMLElement>) => {}