-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(EstimateDropdown): create component
- Loading branch information
1 parent
73794f9
commit b36bc3c
Showing
5 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/components/EstimateDropdown/EstimateDropdown.i18n/en.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
17
src/components/EstimateDropdown/EstimateDropdown.i18n/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
12
src/components/EstimateDropdown/EstimateDropdown.i18n/ru.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": "Выбранная дата уже прошла" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.EstimateDropdownPanel { | ||
padding: var(--gap-sm); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |