diff --git a/packages/overdrive/lib/components/PinInput/PinInput.css.ts b/packages/overdrive/lib/components/PinInput/PinInput.css.ts new file mode 100644 index 000000000..8d698d078 --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/PinInput.css.ts @@ -0,0 +1,10 @@ +import { styleVariants } from '@vanilla-extract/css'; + +export const inputDigit = styleVariants({ + small: { + width: '24px', + }, + medium: { + width: '40px', + }, +}); diff --git a/packages/overdrive/lib/components/PinInput/PinInput.spec.jsx b/packages/overdrive/lib/components/PinInput/PinInput.spec.jsx new file mode 100644 index 000000000..0503d0774 --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/PinInput.spec.jsx @@ -0,0 +1,23 @@ +import { render } from '@testing-library/react'; +import * as React from 'react'; + +import { PinInput } from './PinInput'; + +describe('', () => { + it('should not throw', () => + expect(() => render()).not.toThrow()); + + it('should match snapshot', () => { + expect( + render( + , + ).container.firstChild, + ).toMatchSnapshot(); + + expect(render().container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/overdrive/lib/components/PinInput/PinInput.tsx b/packages/overdrive/lib/components/PinInput/PinInput.tsx new file mode 100644 index 000000000..eef7d2c3a --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/PinInput.tsx @@ -0,0 +1,62 @@ +import * as React from 'react'; +import { FunctionComponent, useRef } from 'react'; +import { Box } from '../Box'; +import { Inline } from '../Inline'; +import { TextInput } from '../TextInput'; + +import * as styles from './PinInput.css'; +import { Tokens } from '../../themes/tokens'; + +export enum EPinInputSize { + Small = 'small', + Medium = 'medium', +} + +export interface Props { + className?: string; // TODO: Remove this in the future + digits: number; + size?: EPinInputSize; + value?: string; +} + +const labelSizeMap: Map = + new Map([ + [EPinInputSize.Small, '3'], + [EPinInputSize.Medium, '4'], + ]); + +export const PinInput: FunctionComponent = ({ + className = '', + digits, + value = digits, + size = EPinInputSize.Medium, + }) => { + const handleOnPaste = (event) => { + const stringPasted = event.clipboardData.getData('Text'); + //const stringPastedLength = event.clipboardData.getData('Text').length; + + [...stringPasted].forEach((digit, index) => { + document.querySelector(`#input-pin-${index}`).value = digit; + const nextfield = document.querySelector(`#input-pin-${index + 1}`); + if (nextfield !== null) { + nextfield.focus(); + } + event.preventDefault(); + }) + }; + + return ( + + + {Array.from({ length: digits }) + .fill(0) + .map((_, index) => ( + + // + ))} + + + ); +}; + +export default PinInput; diff --git a/packages/overdrive/lib/components/PinInput/__snapshots__/StarRating.spec.jsx.snap b/packages/overdrive/lib/components/PinInput/__snapshots__/StarRating.spec.jsx.snap new file mode 100644 index 000000000..875e2b153 --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/__snapshots__/StarRating.spec.jsx.snap @@ -0,0 +1,511 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should match snapshot for small size 1`] = ` +
+
+
+
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+
+ + Hello World! + +
+
+
+`; + +exports[` should match snapshot with label 1`] = ` +
+
+
+
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+
+ + Hello World! + +
+
+
+`; + +exports[` should match snapshot with value 1`] = ` +
+
+
+
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+
+ + 2.7 + +
+
+
+`; + +exports[` should match snapshot without value 1`] = ` +
+
+
+
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+
+ +
+
+
+`; diff --git a/packages/overdrive/lib/components/PinInput/index.ts b/packages/overdrive/lib/components/PinInput/index.ts new file mode 100644 index 000000000..deb43ca8a --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/index.ts @@ -0,0 +1 @@ +export { PinInput, EPinInputSize } from './PinInput'; diff --git a/packages/overdrive/lib/components/PinInput/stories.tsx b/packages/overdrive/lib/components/PinInput/stories.tsx new file mode 100644 index 000000000..5509114c3 --- /dev/null +++ b/packages/overdrive/lib/components/PinInput/stories.tsx @@ -0,0 +1,45 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import * as React from 'react'; + +import { EPinInputSize, PinInput } from '.'; + +export default { + title: 'Components/PinInput', + component: PinInput, + argTypes: { + size: { + options: EPinInputSize, + control: { + type: 'select', + }, + }, + digits: { + control: { + type: 'range', + min: 0, + max: 8, + step: 1, + }, + }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +const standardProps = { + digits: 3, + size: EPinInputSize.Medium, + value: '', +}; +export const standard = Template.bind(standardProps); +standard.args = standardProps; + +const smallSizeProps = { + digits: 1, + size: EPinInputSize.Small, + value: '', +}; +export const smallSize = Template.bind(smallSizeProps); +smallSize.args = smallSizeProps;