Skip to content

Instantly share code, notes, and snippets.

@hotdang-ca
Last active September 8, 2023 08:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hotdang-ca/16d3d9fceb9b948096db8bc44e19c3a3 to your computer and use it in GitHub Desktop.
Save hotdang-ca/16d3d9fceb9b948096db8bc44e19c3a3 to your computer and use it in GitHub Desktop.
Numeric Keypad in TypeScript React
import * as React from 'react';
import { KeypadKey } from './KeypadKey';
import './styles.less';
export interface IKeypadProps
{
onKeyPressed: (keyPressed: KeypadKeys) => void;
}
export enum KeypadKeys
{
ONE = '1',
TWO = '2',
THREE = '3',
FOUR = '4',
FIVE = '5',
SIX = '6',
SEVEN = '7',
EIGHT = '8',
NINE = '9',
CLEAR = 'CLR',
BKSP = 'Bksp',
ZERO = '0',
}
const KEY_SIZE = 80;
const Keypad: React.SFC<IKeypadProps> = (props): JSX.Element => {
const rows:string[][] = [
[...Object.keys(KeypadKeys).slice(0, 3)],
[...Object.keys(KeypadKeys).slice(3, 6)],
[...Object.keys(KeypadKeys).slice(6, 9)],
[...Object.keys(KeypadKeys).slice(9, 12)],
];
return (
<div className="keypad">
{
rows.map((row: any, idx: number) => (
<div className="keypad-row" key={idx}>
{
row.map((keyPadNumber: keyof typeof KeypadKeys) => {
return (
<KeypadKey
keypadKey={KeypadKeys[keyPadNumber]}
key={keyPadNumber}
keySize={KEY_SIZE}
onKeyPressed={(keyPressed: KeypadKeys) => props.onKeyPressed(keyPressed)}
/>
)
})
}
</div>
))
}
</div>
);
}
import * as React from 'react';
import { KeypadKeys } from './Keypad';
import './styles.less';
export interface IKeypadKeyProps
{
keySize?: number;
keypadKey: KeypadKeys;
onKeyPressed: (keyPressed: KeypadKeys) => void;
}
export const KeypadKey: React.SFC<IKeypadKeyProps> = (props): JSX.Element => (
<div
className="keypad-key"
data-role="button"
onClick={() => props.onKeyPressed(props.keypadKey)}
style={ props.keySize ? { width: props.keySize, height: props.keySize } : null }
tabIndex={0}
>
{props.keypadKey.toString()}
</div>
);
import * as React from 'react';
import { Keypad, KeypadKeys } from './Keypad';
export class SampleUsage extends React.Component<any, any> {
constructor(props: any, state: any) {
super(props, state);
this.state = {
keypadEntries: [],
}
}
private _keypadEntriesAsCurrency = (keypadEntries:string[]): number => {
// assumes dollar-like currency with two decimal places.
const dollars:string = keypadEntries.join('').slice(0, keypadEntries.join('').length - 2);
const cents:string = keypadEntries.join('').slice(-2);
const numberArrayAsString = `${dollars}.${cents}`;
const number = parseFloat(numberArrayAsString);
return isNaN(number) ? 0 : number;
}
public handleKeypadKeyPress = (keyPadKey: KeypadKeys): void => {
if (keyPadKey === KeypadKeys.CLEAR) {
this.setState({ keypadEntries: [] });
return;
}
if (keyPadKey === KeypadKeys.BKSP) {
let newKeypadEntries:string[] = this.state.keypadEntries;
newKeypadEntries.pop();
this.setState({ keypadEntries: newKeypadEntries });
return;
}
let newKeypadEntries:string[] = this.state.keypadEntries;
newKeypadEntries.push(keyPadKey.toString());
this.setState({ keypadEntries: newKeypadEntries });
}
render(): JSX.Element {
return (
<div>
<div>
Input: <strong>{ this._keypadEntriesAsCurrency(this.state.keypadEntries) }</strong>
</div>
<Keypad
onKeyPressed={this.handleKeypadKeyPress}
/>
</div>
);
}
}
.keypad {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
.keypad-row {
align-items: center;
display: flex;
flex-direction: row;
height: 100%;
justify-content: center;
width: 100%;
}
.keypad-key {
width: 40px; /* Default Width */
height: 40px; /* Default Height */
align-items: center;
border: 1px solid #888;
cursor: pointer;
display: flex;
flex-direction: row;
justify-content: center;
margin: 8px;
padding: 8px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment