diff --git a/package.json b/package.json index 5c2a0a7b1..a0867a639 100644 --- a/package.json +++ b/package.json @@ -27,15 +27,15 @@ "@chakra-ui/counter": "1.0.0-rc.3", "@chakra-ui/hooks": "1.0.0-rc.3", "@chakra-ui/utils": "1.0.0-rc.3", - "@react-aria/button": "^3.2.1", - "@react-aria/interactions": "^3.2.0", - "@react-aria/link": "^3.1.1", - "@react-aria/utils": "^3.2.1", - "@react-stately/toggle": "^3.2.0", - "emotion": "^10.0.27", - "reakit": "^1.2.4", - "reakit-system": "^0.14.4", - "reakit-utils": "^0.14.3" + "@react-aria/button": "3.2.1", + "@react-aria/interactions": "3.2.0", + "@react-aria/link": "3.1.1", + "@react-aria/utils": "3.2.1", + "@react-stately/toggle": "3.2.0", + "emotion": "10.0.27", + "reakit": "1.2.4", + "reakit-system": "0.14.4", + "reakit-utils": "0.14.3" }, "devDependencies": { "@babel/core": "7.11.6", @@ -49,8 +49,8 @@ "@storybook/react": "6.0.21", "@types/react": "16.9.49", "@types/react-dom": "16.9.8", - "@typescript-eslint/eslint-plugin": "4.0.1", - "@typescript-eslint/parser": "4.0.1", + "@typescript-eslint/eslint-plugin": "4.1.0", + "@typescript-eslint/parser": "4.1.0", "babel-eslint": "10.1.0", "babel-loader": "8.1.0", "eslint": "7.8.1", @@ -63,7 +63,7 @@ "eslint-plugin-react": "7.20.6", "eslint-plugin-react-hooks": "4.1.0", "gacp": "2.10.0", - "husky": "4.2.5", + "husky": "4.3.0", "lint-staged": "10.3.0", "prettier": "2.1.1", "react": "16.13.1", diff --git a/src/number-input/NumberInputDecrementButton.ts b/src/number-input/NumberInputDecrementButton.ts index 5d2018d1e..c45fa637c 100644 --- a/src/number-input/NumberInputDecrementButton.ts +++ b/src/number-input/NumberInputDecrementButton.ts @@ -1,8 +1,9 @@ import { createComponent } from "reakit-system"; -import { createNumberInputHook } from "./createNumberInputHook"; + +import { createNumberInputButtonsHook } from "./createNumberInputButtonsHook"; export const NumberInputDecrementButton = createComponent({ as: "button", memo: true, - useHook: createNumberInputHook("decrement"), + useHook: createNumberInputButtonsHook("decrement"), }); diff --git a/src/number-input/NumberInputIncrementButton.ts b/src/number-input/NumberInputIncrementButton.ts index fbe4efedb..c321dae68 100644 --- a/src/number-input/NumberInputIncrementButton.ts +++ b/src/number-input/NumberInputIncrementButton.ts @@ -1,8 +1,9 @@ import { createComponent } from "reakit-system"; -import { createNumberInputHook } from "./createNumberInputHook"; + +import { createNumberInputButtonsHook } from "./createNumberInputButtonsHook"; export const NumberInputIncrementButton = createComponent({ as: "button", memo: true, - useHook: createNumberInputHook("increment"), + useHook: createNumberInputButtonsHook("increment"), }); diff --git a/src/number-input/NumberInputState.ts b/src/number-input/NumberInputState.ts index ad99b0634..ee70e2a85 100644 --- a/src/number-input/NumberInputState.ts +++ b/src/number-input/NumberInputState.ts @@ -1,7 +1,8 @@ -import { useCounter, UseCounterProps } from "@chakra-ui/counter"; +import { useCallback, useRef } from "react"; import { useBoolean } from "@chakra-ui/hooks"; +import { useCounter, UseCounterProps } from "@chakra-ui/counter"; import { focus, minSafeInteger, maxSafeInteger } from "@chakra-ui/utils"; -import { useCallback, useRef } from "react"; + import { useSpinner } from "./__utils"; export interface UseNumberInputProps extends UseCounterProps { @@ -84,7 +85,7 @@ export function useNumberInputState(props: UseNumberInputProps = {}) { * * This leverages `setInterval` internally */ - const spinner = useSpinner(increment, decrement, isAtMin, isAtMax); + const spinner = useSpinner(increment, decrement); const focusInput = useCallback(() => { if (focusInputOnChange && inputRef.current) { diff --git a/src/number-input/__utils.ts b/src/number-input/__utils.ts index 8075fb5b4..7076efa18 100644 --- a/src/number-input/__utils.ts +++ b/src/number-input/__utils.ts @@ -38,12 +38,15 @@ export function isValidNumericKeyboardEvent(event: React.KeyboardEvent) { export function getStepFactor(event: KeyboardEvent) { let ratio = 1; + if (event.metaKey || event.ctrlKey) { ratio = 0.1; } + if (event.shiftKey) { ratio = 10; } + return ratio; } diff --git a/src/number-input/createNumberInputHook.ts b/src/number-input/createNumberInputButtonsHook.ts similarity index 69% rename from src/number-input/createNumberInputHook.ts rename to src/number-input/createNumberInputButtonsHook.ts index ef03edd5d..d3fbc1ddc 100644 --- a/src/number-input/createNumberInputHook.ts +++ b/src/number-input/createNumberInputButtonsHook.ts @@ -2,8 +2,8 @@ import { createHook } from "reakit-system"; import { ButtonHTMLProps, ButtonOptions, useButton } from "reakit/Button"; import { useSpinButton } from "./__utils"; -import { NumberInputStateReturn } from "./NumberInputState"; import { NUMBERINPUT_BUTTON_KEYS } from "./__keys"; +import { NumberInputStateReturn } from "./NumberInputState"; export type NumberInputButtonOptions = ButtonOptions & Pick, "keepWithinRange"> & @@ -12,8 +12,15 @@ export type NumberInputButtonOptions = ButtonOptions & "focusInput" | "increment" | "decrement" | "isAtMin" | "isAtMax" | "spinner" >; -export const createNumberInputHook = (type: "increment" | "decrement") => { - return createHook({ +export type NumberInputButtonHTMLProps = ButtonHTMLProps; + +export type NumberInputButtonProps = NumberInputButtonOptions & + NumberInputButtonHTMLProps; + +export const createNumberInputButtonsHook = ( + type: "increment" | "decrement", +) => { + return createHook({ name: `NumberInput`, compose: useButton, keys: NUMBERINPUT_BUTTON_KEYS, diff --git a/src/number-input/stories/NumberInput.stories.tsx b/src/number-input/stories/NumberInput.stories.tsx index 4d5817667..2d329a059 100644 --- a/src/number-input/stories/NumberInput.stories.tsx +++ b/src/number-input/stories/NumberInput.stories.tsx @@ -30,7 +30,6 @@ export const Default = () => { return ; }; -// TODO: Also handle mouse wheel disabling for disabled input export const DefaultValue = () => { const props = { defaultValue: 15, @@ -40,3 +39,76 @@ export const DefaultValue = () => { return ; }; + +export const Step = () => { + const props = { + defaultValue: 15, + min: 10, + max: 30, + step: 5, + }; + + return ; +}; + +export const Precision = () => { + const props = { + defaultValue: 15, + min: 10, + max: 30, + step: 0.2, + precision: 2, + }; + + return ; +}; + +export const ClampValueOnBlurFalse = () => { + const props = { + defaultValue: 15, + min: 10, + max: 30, + step: 0.2, + precision: 2, + clampValueOnBlur: false, + keepWithinRange: false, + }; + + return ; +}; + +export const KeepWithinRangeFalse = () => { + const props = { + defaultValue: 15, + min: 10, + max: 30, + step: 0.2, + precision: 2, + clampValueOnBlur: false, + keepWithinRange: false, + }; + + return ; +}; + +export const Disabled = () => { + const props = { + defaultValue: 15, + min: 10, + max: 20, + isDisabled: true, + }; + + return ; +}; + +export const ReadOnly = () => { + const props = { + defaultValue: 15, + min: 10, + max: 20, + isReadOnly: true, + }; + + return ; +};