Skip to content

Commit e637113

Browse files
author
Gurgen
committed
feat(v1-components): UiDate & format methods
1 parent 8995b73 commit e637113

File tree

15 files changed

+1178
-9
lines changed

15 files changed

+1178
-9
lines changed

packages/v1-components/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
"dependencies": {
5757
"@omnicajs/vue-remote": "^0.2.5",
5858
"@remote-ui/rpc": "^1.4.5",
59-
"@retailcrm/image-preview": "^1.0.2",
60-
"remark-gfm": "^4.0.0"
59+
"@retailcrm/image-preview": "^1.0.2"
6160
},
6261
"devDependencies": {
6362
"@storybook/addon-a11y": "^8.4.7",
@@ -77,17 +76,21 @@
7776
"@vitejs/plugin-vue": "^5.1.4",
7877
"@vue/compiler-sfc": "^3.5.12",
7978
"@yandex/ymaps3-types": "^0.0.21",
79+
"date-fns": "^4.1.0",
8080
"less": "^4.2.0",
8181
"react": "^18.3.1",
8282
"react-dom": "^18.3.1",
83+
"remark-gfm": "^4.0.0",
8384
"storybook": "^8.4.7",
8485
"tsx": "^4.19.2",
8586
"typescript": "^5.6.3",
8687
"uuid": "^11.0.3",
8788
"vite": "^5.4.11",
8889
"vite-plugin-dts": "^4.3.0",
8990
"vite-svg-loader": "^5.1.0",
91+
"vitest": "^3.0.4",
9092
"vue": "^3.5.12",
93+
"vue-i18n": "10",
9194
"vue3-perfect-scrollbar": "^1.6.0"
9295
}
9396
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export type Locale = 'en-GB' | 'es-ES' | 'ru-RU'
2+
3+
export type UiDateProperties = {
4+
date: Date | string;
5+
withTime: boolean;
6+
locale?: Locale;
7+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { Locale } from '@/common/components/date'
2+
3+
import { getCurrentInstance } from 'vue'
4+
5+
import { format } from 'date-fns'
6+
import { enGB, es, ru } from 'date-fns/locale'
7+
8+
export const formatDateLat = (date: Date | string) => format(date, 'dd/MM/yyyy', { locale: enGB })
9+
export const formatDateRu = (date: Date | string) => format(date, 'dd.MM.yyyy', { locale: ru })
10+
11+
export const formatTime = (date: Date | string) => format(date, 'HH:mm', { locale: enGB })
12+
13+
export const formatDate = (date: Date | string, locale?: Locale) => {
14+
return (detectLocale() ?? locale) === 'ru-RU'
15+
? formatDateRu(date)
16+
: formatDateLat(date)
17+
}
18+
19+
export const formatDateTime = (date: Date | string, locale?: Locale) => format(date, 'Pp', {
20+
locale: {
21+
'en-GB': enGB,
22+
'es-ES': es,
23+
'ru-RU': ru,
24+
}[locale ?? detectLocale()] ?? enGB,
25+
})
26+
27+
function detectLocale(): Locale {
28+
let detectedLocale: Locale = 'en-GB'
29+
const instance = getCurrentInstance()
30+
31+
// Safely access i18n instance with proper type checking
32+
const i18n = instance?.appContext?.app?.config?.globalProperties?.$i18n
33+
34+
if (i18n) {
35+
try {
36+
const localeValue = typeof i18n.locale === 'object' ? i18n.locale.value : i18n.locale
37+
const rawLocale = localeValue?.toString() || 'en-GB'
38+
39+
if (rawLocale.startsWith('en')) {
40+
detectedLocale = 'en-GB'
41+
} else if (rawLocale.startsWith('ru')) {
42+
detectedLocale = 'ru-RU'
43+
} else if (rawLocale.startsWith('es')) {
44+
detectedLocale = 'es-ES'
45+
}
46+
} catch (error) {
47+
console.warn('Error detecting locale:', error)
48+
}
49+
}
50+
51+
return detectedLocale
52+
}

packages/v1-components/src/host.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { default as UiAvatar } from '@/host/components/avatar/UiAvatar.vue'
22
export { default as UiAvatarList } from '@/host/components/avatar/UiAvatarList.vue'
33
export { default as UiButton } from '@/host/components/button/UiButton.vue'
44
export { default as UiCheckbox } from '@/host/components/checkbox/UiCheckbox.vue'
5+
export { default as UiDate } from '@/host/components/date/UiDate.vue'
56
export { default as UiError } from '@/host/components/error/UiError.vue'
67
export { default as UiImage } from '@/host/components/image/UiImage.vue'
78
export { default as UiLink } from '@/host/components/link/UiLink.vue'
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<template>
2+
<time v-bind="{ datetime: formatISO(date), ...$attrs }">
3+
{{ withTime ? formatDateTime(date, locale) : formatDate(date, locale) }}
4+
</time>
5+
</template>
6+
7+
<script lang="ts" setup>
8+
import type { Locale } from '@/common/components/date'
9+
import type { PropType } from 'vue'
10+
11+
import { formatISO } from 'date-fns'
12+
13+
import {
14+
formatDate,
15+
formatDateTime,
16+
} from '@/common/formatters/date'
17+
18+
defineProps({
19+
date: {
20+
type: [Date, String] as PropType<Date | string>,
21+
required: true,
22+
},
23+
24+
locale: {
25+
type: String as unknown as PropType<Locale>,
26+
default: 'en-GB',
27+
},
28+
29+
withTime: {
30+
type: Boolean,
31+
default: false,
32+
},
33+
})
34+
</script>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { DefineComponent } from '@/common/vue'
2+
3+
import type {
4+
UiDateProperties,
5+
} from '@/common/components/date'
6+
7+
declare const UiDate: DefineComponent<
8+
UiDateProperties
9+
>
10+
11+
export default UiDate
12+

packages/v1-components/src/remote.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ export * from '@/remote/components/yandex-map'
1717

1818
export { usePreview } from '@/common/preview'
1919

20-
export { ImageWorkersKey } from '@/common/preview'
20+
export { ImageWorkersKey } from '@/common/preview'
21+
22+
export {
23+
formatDate,
24+
formatDateTime,
25+
formatTime,
26+
} from '@/common/formatters/date'
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Функции форматирования даты и времени
2+
3+
В этой документации описывается работа функций `formatDate()`, `formatDateTime()` и `formatTime()` с различными локализациями в нашем приложении.
4+
5+
## formatDate(value)
6+
7+
Функция `formatDate()` форматирует даты в соответствии с текущими настройками локализации. Принимает два параметра:
8+
9+
- `value`: Строка с датой или объект Date
10+
11+
### Примеры использования
12+
13+
```javascript
14+
// Предположим, что дата "2024-01-22"
15+
const date = new Date('2024-01-22')
16+
17+
// Для локали ru_RU
18+
formatDate(date) // "22.01.24"
19+
20+
// Для локали en_GB
21+
formatDate(date) // "22/01/24"
22+
23+
// Для локали es_ES
24+
formatDate(date) // "22/01/24"
25+
```
26+
27+
### Шаблоны форматирования по локалям
28+
29+
| Локаль | Стандартный формат |
30+
| ------ | ------------------ |
31+
| ru_RU | dd.mm.yy |
32+
| en_GB | dd/mm/yy |
33+
| es_ES | dd/mm/yy |
34+
35+
## formatDateTime(value)
36+
37+
Функция `formatDateTime()` объединяет форматирование даты и времени. Использует формат даты в соответствии с локалью и добавляет время в 24-часовом формате.
38+
39+
### Примеры использования
40+
41+
```javascript
42+
// Предположим, что дата и время "2024-01-22 15:30:00"
43+
const datetime = new Date('2024-01-22 15:30:00')
44+
45+
// Для локали ru_RU
46+
formatDateTime(datetime) // Вернёт "22.01.24 15:30"
47+
48+
// Для локали en_GB
49+
formatDateTime(datetime) // Вернёт "22/01/24 15:30"
50+
51+
// Для локали es_ES
52+
formatDateTime(datetime) // Вернёт "22/01/24 15:30"
53+
```
54+
55+
## formatTime(value)
56+
57+
Функция `formatTime()` форматирует время в 24-часовом формате (HH:mm). Работает с разными типами входных данных.
58+
59+
### Параметры
60+
61+
- `value`: может быть строкой, объектом Date, null или undefined
62+
63+
### Примеры использования
64+
65+
```javascript
66+
// С объектом Date
67+
const date = new Date('2024-01-22 15:30:00')
68+
formatTime(date) // Вернёт "15:30"
69+
70+
// Со строкой
71+
formatTime('2024-01-22 15:30:00') // Вернёт "15:30"
72+
73+
// С невалидными значениями
74+
formatTime(null) // Вернёт ""
75+
formatTime(undefined) // Вернёт ""
76+
```
77+

packages/v1-components/storybook/main.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { dirname, join } from 'path'
55

66
import remarkGfm from 'remark-gfm'
77

8-
98
/* eslint-disable @typescript-eslint/ban-ts-comment */
109
// @ts-ignore Because of PHPStorm tsconfig recognition issues for import.meta specifically
1110
const require = createRequire(import.meta.url)
@@ -51,7 +50,6 @@ const config: StorybookConfig = {
5150
stories: [
5251
'./Intro.mdx',
5352
'./docs/**/*.mdx',
54-
'../src/**/*.mdx',
5553
'./**/*.stories.@(js|jsx|mjs|ts|tsx)',
5654
],
5755
viteFinal: async (config) => {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import ToReact from '../ToReact.ts'
2+
import UiDate from '@/host/components/date/UiDate.vue'
3+
4+
# UiDate
5+
6+
Компонент `UiDate` является обёрткой над HTML-элементом `<time>`. Он отображает отформатированные значения даты или даты и времени и поддерживает локализацию. Вы также можете включить или отключить отображение времени.
7+
8+
### Подробности о пропсах
9+
10+
| Пропс | Тип | Значение по умолчанию | Описание |
11+
|------------|---------------|-----------------------|------------------------------------------------------------|
12+
| `date` | `Date|string` | `new Date()` | Значение даты или даты и времени, которое нужно отобразить. |
13+
| `locale` | `string` | `'en-GB'` | Локаль, используемая для форматирования. Поддерживаются `'en-GB'`, `'es-ES'`, и `'ru-RU'`. |
14+
| `withTime` | `boolean` | `false` | Указывает, отображать ли время вместе с датой. |
15+
16+
17+
Этот пример отображает только дату, используя локаль по умолчанию (`en-GB`).
18+
19+
<ToReact is={UiDate} date={new Date()} />
20+
21+
### С отображением времени
22+
23+
Этот пример показывает, как отобразить дату вместе с временем.
24+
25+
<ToReact is={UiDate} date={new Date()} withTime />
26+
27+
---
28+
29+
### Использование
30+
31+
Пример использования компонента `UiDate` в вашем проекте:
32+
33+
```vue
34+
<template>
35+
<UiDate :date="new Date()" locale="ru-RU" :withTime="true" />
36+
</template>

0 commit comments

Comments
 (0)