Skip to content

Commit

Permalink
feat(EstimateDropdown): create component
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisVorop committed Feb 27, 2024
1 parent 73794f9 commit b36bc3c
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/components/EstimateDropdown/EstimateDropdown.i18n/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Year": "",
"Choose year": "",
"Quarter": "",
"Choose quarter": "",
"Strict Date": "",
"Set date": "",
"or type the strict date": "",
"hint": "If only the year is selected, the date will be the end of the year, for example: {date}",
"Reset": "",
"warning": "Selected date is past"
}
17 changes: 17 additions & 0 deletions src/components/EstimateDropdown/EstimateDropdown.i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable */
// Do not edit, use generator to update
import { i18n, fmt, I18nLangSet } from 'easy-typed-intl';
import getLang from '../../../utils/getLang';

import ru from './ru.json';
import en from './en.json';

export type I18nKey = keyof typeof ru & keyof typeof en;
type I18nLang = 'ru' | 'en';

const keyset: I18nLangSet<I18nKey> = {};

keyset['ru'] = ru;
keyset['en'] = en;

export const tr = i18n<I18nLang, I18nKey>(keyset, fmt, getLang);
12 changes: 12 additions & 0 deletions src/components/EstimateDropdown/EstimateDropdown.i18n/ru.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Year": "Год",
"Choose year": "Выбрать год",
"Quarter": "Квартал",
"Choose quarter": "Выбрать квартал",
"Strict Date": "Дата",
"Set date": "Установить дату",
"or type the strict date": "или выберите точную дату",
"hint": "Если выбрать только год, то датой будет выбран конец года, например: {date}",
"Reset": "Сбросить",
"warning": "Выбранная дата уже прошла"
}
3 changes: 3 additions & 0 deletions src/components/EstimateDropdown/EstimateDropdown.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.EstimateDropdownPanel {
padding: var(--gap-sm);
}
115 changes: 115 additions & 0 deletions src/components/EstimateDropdown/EstimateDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { DatePicker, DatePickerYear, DatePickerQuarter, DatePickerStrict, Text } from '@taskany/bricks/harmony';
import { ComponentProps, useCallback, useMemo, useState } from 'react';
import { nullable } from '@taskany/bricks';

import { formateEstimate, getDateString } from '../../utils/dateTime';
import { DropdownPanel, Dropdown, DropdownTrigger } from '../Dropdown/Dropdown';
import { useLocale } from '../../hooks/useLocale';
import { DateType } from '../../types/date';
import { estimateYearTrigger, estimateQuarterTrigger, estimateStrictDateTrigger } from '../../utils/domObjects';

import { tr } from './EstimateDropdown.i18n';
import s from './EstimateDropdown.module.css';

interface Estimate {
date: string;
type?: DateType;
}

interface EstimateState {
type?: DateType;
range: { end: Date };
}

interface EstimateDropdownProps {
label?: ComponentProps<typeof DropdownTrigger>['label'];
error?: ComponentProps<typeof DropdownTrigger>['error'];
onChange: (date: Estimate | null) => void;
value?: Estimate;
}

export const EstimateDropdown = ({ onChange, value, label, ...props }: EstimateDropdownProps) => {
const locale = useLocale();
const [estimate, setEstimate] = useState<EstimateState | undefined>(
value
? {
range: { end: new Date(value.date) },
type: value.type,
}
: undefined,
);

const onChangeHandler = useCallback(
(value?: EstimateState) => {
onChange(
value
? {
date: getDateString(value.range.end),
type: value.type,
}
: null,
);

setEstimate(value);
},
[onChange],
);

const translates = useMemo(
() => ({
year: {
title: tr('Year'),
trigger: tr('Choose year'),
},
quarter: {
title: tr('Quarter'),
trigger: tr('Choose quarter'),
},
strict: {
title: tr('Strict Date'),
trigger: tr('Set date'),
advice: tr('or type the strict date'),
},
default: {
reset: tr('Reset'),
warning: tr('warning'),
},
}),
[],
);

const dateFragments: Record<'en' | 'ru', ('month' | 'day' | 'year')[]> = useMemo(
() => ({
en: ['month', 'day', 'year'],
ru: ['day', 'month', 'year'],
}),
[],
);

return (
<Dropdown>
<DropdownTrigger label={label} {...props}>
{nullable(value, (v) => (
<Text size="s" as="span">
{formateEstimate(new Date(v.date), {
locale,
type: v.type,
})}
</Text>
))}
</DropdownTrigger>
<DropdownPanel width={330} placement="top-end" className={s.EstimateDropdownPanel}>
<DatePicker translates={translates.default} value={estimate} onChange={onChangeHandler}>
<DatePickerYear translates={translates.year} {...estimateYearTrigger.attr} />
<DatePickerQuarter translates={translates.quarter} {...estimateQuarterTrigger.attr} />
<DatePickerStrict
translates={translates.strict}
dateFragments={dateFragments[locale]}
splitter="/"
{...estimateStrictDateTrigger.attr}
/>
</DatePicker>
</DropdownPanel>
</Dropdown>
);
};

0 comments on commit b36bc3c

Please sign in to comment.