Skip to content

Commit

Permalink
TimePicker component
Browse files Browse the repository at this point in the history
  • Loading branch information
nighto committed Dec 10, 2024
1 parent 9dd613a commit 0ec4aa1
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/components/forms/controls/TimePicker/TimePicker.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* Copyright (c) Fortanix, Inc.
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */

@use '../../../../styling/defs.scss' as bk;

@layer baklava.components {
.bk-timepicker {
@include bk.component-base(bk-timepicker);
}
}
44 changes: 44 additions & 0 deletions src/components/forms/controls/TimePicker/TimePicker.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Copyright (c) Fortanix, Inc.
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { Meta, StoryObj } from '@storybook/react';

import * as React from 'react';

import { TimePicker } from './TimePicker.tsx';


type TimePickerArgs = React.ComponentProps<typeof TimePicker>;
type Story = StoryObj<TimePickerArgs>;

export default {
component: TimePicker,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
},
args: {},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
} satisfies Meta<TimePickerArgs>;

export const TimePickerStory: Story = {
name: 'Time Picker',
render: (args) => {
const [date, setDate] = React.useState<Date>(new Date());

return (
<div>
<TimePicker date={date} onUpdate={setDate}/>
<p>
The selected time is:&nbsp;
{date.getHours().toString().padStart(2, '0')}:{date.getMinutes().toString().padStart(2, '0')}
</p>
</div>
);
}
};
51 changes: 51 additions & 0 deletions src/components/forms/controls/TimePicker/TimePicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Copyright (c) Fortanix, Inc.
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import * as React from 'react';

import { classNames as cx, type ClassNameArgument, type ComponentProps } from '../../../../util/componentUtil.ts';

import { Input } from '../Input/Input.tsx';

import cl from './TimePicker.module.scss';


export type TimePickerProps = ComponentProps<'input'> & {
/** Whether this component should be unstyled. */
unstyled?: undefined | boolean,

/** An optional class name to be appended to the class list. */
className?: ClassNameArgument,

/** The date object to show / manipulate the time. */
date: Date,

/** A callback function to update the time. */
onUpdate: (date: Date) => void,
};

export const TimePicker = ({ unstyled = false, className, date, onUpdate, ...propsRest }: TimePickerProps) => {
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const time = `${hours}:${minutes}`;

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newTimeString = e.target.value;
const [newHours, newMinutes] = newTimeString.split(':');
let newDate = new Date(date);
newDate.setHours(Number(newHours));
newDate.setMinutes(Number(newMinutes));
onUpdate(newDate);
};

return (
<div className={cx(
'bk',
{ [cl['bk-timepicker']]: !unstyled },
className,
)}>
<Input type="time" value={time} onChange={onChange} {...propsRest} />
</div>
);
};

0 comments on commit 0ec4aa1

Please sign in to comment.