acrool / acrool-react-picker

This is a react method to quickly combine buttons/input with Picker
https://acrool-react-picker.pages.dev/
MIT License
5 stars 0 forks source link
react-picker reactjs

Acrool React Picker

Acrool React Picker Logo

This is a react method to quickly combine buttons with Picker

[![NPM](https://img.shields.io/npm/v/@acrool/react-picker.svg?style=for-the-badge)](https://www.npmjs.com/package/@acrool/react-picker) [![npm](https://img.shields.io/bundlejs/size/@acrool/react-picker?style=for-the-badge)](https://github.com/acrool/@acrool/react-picker/blob/main/LICENSE) [![npm](https://img.shields.io/npm/l/@acrool/react-picker?style=for-the-badge)](https://github.com/acrool/react-picker/blob/main/LICENSE) [![npm downloads](https://img.shields.io/npm/dm/@acrool/react-picker.svg?style=for-the-badge)](https://www.npmjs.com/package/@acrool/react-picker) [![npm](https://img.shields.io/npm/dt/@acrool/react-picker.svg?style=for-the-badge)](https://www.npmjs.com/package/@acrool/react-picker)

Features

Install

yarn add @acrool/react-picker

Usage

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%);
    `}

`;

If you need to automatically infer types


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:

Play react-editext-example

Precautions

Ref warning

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>) => {}

License

MIT © Acrool & Imagine