@dxtmisha/wiki 0.24.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,288 @@
1
+ import {Meta} from '@storybook/addon-docs/blocks'
2
+
3
+ <Meta title='@dxtmisha/functional/ru/Composables/useGeoIntlRef'/>
4
+
5
+ # Композабл useGeoIntlRef
6
+
7
+ Композабл для создания реактивного объекта интернационализации. Предоставляет методы форматирования чисел, валют, дат и названий с автоматическим учётом локали пользователя. Все методы возвращают computed значения, которые автоматически обновляются при изменении входных данных.
8
+
9
+ ## Основные возможности
10
+
11
+ - **Форматирование чисел** — локализованное представление чисел с разделителями
12
+ - **Форматирование валют** — отображение денежных сумм с символами валют
13
+ - **Форматирование дат** — различные форматы дат и времени по региональным стандартам
14
+ - **Названия стран и языков** — локализованные названия регионов
15
+ - **Относительное время** — "2 дня назад", "через 5 минут" и т.д.
16
+ - **Проценты и единицы** — форматирование процентов и единиц измерения
17
+ - **Реактивность** — все методы возвращают computed, обновляющиеся автоматически
18
+ - **Автоопределение локали** — использует геолокацию пользователя по умолчанию
19
+
20
+ ## Функция
21
+
22
+ ### `useGeoIntlRef()`
23
+
24
+ Создаёт и возвращает экземпляр класса `GeoIntlRef` для работы с форматированием данных.
25
+
26
+ **Параметры:** нет
27
+
28
+ **Возвращает:** `GeoIntlRef` — объект с методами форматирования
29
+
30
+ ```javascript
31
+ import { useGeoIntlRef } from '@dxtmisha/functional'
32
+
33
+ // Создание экземпляра
34
+ const intl = useGeoIntlRef()
35
+
36
+ // Все методы возвращают ComputedRef
37
+ const formatted = intl.number(1234.56)
38
+ ```
39
+
40
+ ## Методы форматирования чисел
41
+
42
+ ### `number`
43
+
44
+ Форматирование числа согласно локали.
45
+
46
+ **Параметры:**
47
+ - `value: RefOrNormal<NumberOrString>` — число для форматирования
48
+ - `options?: Intl.NumberFormatOptions` — опции форматирования
49
+
50
+ **Возвращает:** `ComputedRef<string>`
51
+
52
+ ```javascript
53
+ const intl = useGeoIntlRef()
54
+ const count = ref(1234567.89)
55
+
56
+ intl.number(count) // ComputedRef<'1 234 567,89'>
57
+ intl.number(1000, { minimumFractionDigits: 2 }) // ComputedRef<'1 000,00'>
58
+ ```
59
+
60
+ ### `decimal`
61
+
62
+ Возвращает символ десятичного разделителя для текущей локали.
63
+
64
+ **Возвращает:** `ComputedRef<string>`
65
+
66
+ ```javascript
67
+ const intl = useGeoIntlRef()
68
+ intl.decimal() // ComputedRef<','> (для ru-RU)
69
+ // ComputedRef<'.'> (для en-US)
70
+ ```
71
+
72
+ ### `percent`
73
+
74
+ Форматирование числа как процента.
75
+
76
+ **Параметры:**
77
+ - `value: RefOrNormal<NumberOrString>` — число для форматирования (0.15 = 15%)
78
+ - `options?: Intl.NumberFormatOptions` — опции форматирования
79
+
80
+ **Возвращает:** `ComputedRef<string>`
81
+
82
+ ```javascript
83
+ intl.percent(0.15) // ComputedRef<'15%'>
84
+ intl.percent(1.25) // ComputedRef<'125%'>
85
+ ```
86
+
87
+ ### `percentBy100`
88
+
89
+ Форматирование числа как процента (значение уже в процентах).
90
+
91
+ **Параметры:**
92
+ - `value: RefOrNormal<NumberOrString>` — число для форматирования (15 = 15%)
93
+ - `options?: Intl.NumberFormatOptions` — опции форматирования
94
+
95
+ **Возвращает:** `ComputedRef<string>`
96
+
97
+ ```javascript
98
+ intl.percentBy100(15) // ComputedRef<'15%'>
99
+ intl.percentBy100(125) // ComputedRef<'125%'>
100
+ ```
101
+
102
+ ## Методы форматирования валют
103
+
104
+ ### `currency`
105
+
106
+ Форматирование денежной суммы.
107
+
108
+ **Параметры:**
109
+ - `value: RefOrNormal<NumberOrString>` — сумма для форматирования
110
+ - `currencyOptions?: RefOrNormal<string | Intl.NumberFormatOptions>` — код валюты или опции
111
+ - `numberOnly?: boolean` — не показывать символ валюты (по умолчанию `false`)
112
+
113
+ **Возвращает:** `ComputedRef<string>`
114
+
115
+ ```javascript
116
+ const intl = useGeoIntlRef()
117
+ const price = ref(99.99)
118
+
119
+ intl.currency(price, 'USD') // ComputedRef<'$99,99'>
120
+ intl.currency(1234.56, 'RUB') // ComputedRef<'1 234,56 ₽'>
121
+ intl.currency(500, 'EUR', true) // ComputedRef<'500,00'> (без символа)
122
+ ```
123
+
124
+ ### `unit`
125
+
126
+ Форматирование с единицами измерения.
127
+
128
+ **Параметры:**
129
+ - `value: RefOrNormal<NumberOrString>` — значение для форматирования
130
+ - `unitOptions?: string | Intl.NumberFormatOptions` — единица измерения или опции
131
+
132
+ **Возвращает:** `ComputedRef<string>`
133
+
134
+ ```javascript
135
+ intl.unit(100, 'kilometer') // ComputedRef<'100 км'>
136
+ intl.unit(50, 'kilogram') // ComputedRef<'50 кг'>
137
+ intl.unit(1.5, 'hour') // ComputedRef<'1,5 ч'>
138
+ ```
139
+
140
+ ## Методы форматирования дат
141
+
142
+ ### `date`
143
+
144
+ Форматирование даты и времени.
145
+
146
+ **Параметры:**
147
+ - `value: RefOrNormal<NumberOrStringOrDate>` — дата для форматирования
148
+ - `type?: GeoDate` — тип формата ('date' | 'time' | 'datetime' | 'full' | 'long' | 'medium' | 'short')
149
+ - `styleOptions?: Intl.DateTimeFormatOptions['month'] | Intl.DateTimeFormatOptions` — стиль или опции
150
+ - `hour24?: boolean` — использовать 24-часовой формат
151
+
152
+ **Возвращает:** `ComputedRef<string>`
153
+
154
+ ```javascript
155
+ const date = ref(new Date('2024-10-15 14:30:00'))
156
+
157
+ intl.date(date) // ComputedRef<'15.10.2024'>
158
+ intl.date(date, 'time') // ComputedRef<'14:30'>
159
+ intl.date(date, 'datetime') // ComputedRef<'15.10.2024, 14:30'>
160
+ intl.date(date, 'full') // ComputedRef<'вторник, 15 октября 2024 г.'>
161
+ ```
162
+
163
+ ### `relative`
164
+
165
+ Форматирование относительного времени ("2 дня назад", "через час").
166
+
167
+ **Параметры:**
168
+ - `value: RefOrNormal<NumberOrStringOrDate>` — дата для сравнения
169
+ - `styleOptions?: Intl.RelativeTimeFormatStyle | Intl.RelativeTimeFormatOptions` — стиль ('long' | 'short' | 'narrow')
170
+ - `todayValue?: Date` — текущая дата (по умолчанию `new Date()`)
171
+
172
+ **Возвращает:** `ComputedRef<string>`
173
+
174
+ ```javascript
175
+ const twoDaysAgo = new Date()
176
+ twoDaysAgo.setDate(twoDaysAgo.getDate() - 2)
177
+
178
+ intl.relative(twoDaysAgo) // ComputedRef<'2 дня назад'>
179
+ intl.relative(twoDaysAgo, 'short') // ComputedRef<'2 дн. назад'>
180
+ ```
181
+
182
+ ### `relativeLimit`
183
+
184
+ Форматирование относительного времени с ограничением. Если разница превышает лимит, выводится абсолютная дата.
185
+
186
+ **Параметры:**
187
+ - `value: RefOrNormal<NumberOrStringOrDate>` — дата для форматирования
188
+ - `limit: number` — лимит в днях
189
+ - `todayValue?: Date` — текущая дата
190
+ - `relativeOptions?: Intl.RelativeTimeFormatStyle | Intl.RelativeTimeFormatOptions` — опции относительного формата
191
+ - `dateOptions?: Intl.DateTimeFormatOptions['month'] | Intl.DateTimeFormatOptions` — опции формата даты
192
+ - `type?: GeoDate` — тип формата даты
193
+ - `hour24?: boolean` — 24-часовой формат
194
+
195
+ **Возвращает:** `ComputedRef<string>`
196
+
197
+ ```javascript
198
+ const threeDaysAgo = new Date()
199
+ threeDaysAgo.setDate(threeDaysAgo.getDate() - 3)
200
+
201
+ intl.relativeLimit(threeDaysAgo, 7) // ComputedRef<'3 дня назад'>
202
+
203
+ const tenDaysAgo = new Date()
204
+ tenDaysAgo.setDate(tenDaysAgo.getDate() - 10)
205
+
206
+ intl.relativeLimit(tenDaysAgo, 7) // ComputedRef<'05.10.2024'> (абсолютная дата)
207
+ ```
208
+
209
+ ## Методы для названий
210
+
211
+ ### `display`
212
+
213
+ Получение локализованного названия (языка, региона, скрипта и т.д.).
214
+
215
+ **Параметры:**
216
+ - `value?: RefOrNormal<string>` — код для получения названия
217
+ - `typeOptions?: Intl.DisplayNamesOptions['type'] | Intl.DisplayNamesOptions` — тип ('language' | 'region' | 'script' | 'currency')
218
+
219
+ **Возвращает:** `ComputedRef<string>`
220
+
221
+ ```javascript
222
+ intl.display('US', 'region') // ComputedRef<'США'>
223
+ intl.display('en', 'language') // ComputedRef<'английский'>
224
+ intl.display('USD', 'currency') // ComputedRef<'доллар США'>
225
+ ```
226
+
227
+ ### `languageName`
228
+
229
+ Получение названия языка.
230
+
231
+ **Параметры:**
232
+ - `value?: RefOrNormal<string>` — код языка
233
+ - `style?: Intl.RelativeTimeFormatStyle` — стиль отображения
234
+
235
+ **Возвращает:** `ComputedRef<string>`
236
+
237
+ ```javascript
238
+ intl.languageName('en') // ComputedRef<'английский'>
239
+ intl.languageName('de') // ComputedRef<'немецкий'>
240
+ ```
241
+
242
+ ### `countryName`
243
+
244
+ Получение названия страны.
245
+
246
+ **Параметры:**
247
+ - `value?: RefOrNormal<string>` — код страны
248
+ - `style?: Intl.RelativeTimeFormatStyle` — стиль отображения
249
+
250
+ **Возвращает:** `ComputedRef<string>`
251
+
252
+ ```javascript
253
+ intl.countryName('US') // ComputedRef<'США'>
254
+ intl.countryName('GB') // ComputedRef<'Великобритания'>
255
+ ```
256
+
257
+ ## Примеры использования
258
+
259
+ ### Базовое использование
260
+
261
+ ```javascript
262
+ import { ref } from 'vue'
263
+ import { useGeoIntlRef } from '@dxtmisha/functional'
264
+
265
+ const intl = useGeoIntlRef()
266
+ const price = ref(1234.56)
267
+
268
+ // Все методы возвращают ComputedRef
269
+ const formatted = intl.currency(price, 'USD')
270
+ console.log(formatted.value) // '$1,234.56'
271
+
272
+ // Автоматическое обновление при изменении
273
+ price.value = 2000
274
+ console.log(formatted.value) // '$2,000.00'
275
+ ```
276
+
277
+ ### Реактивные параметры
278
+
279
+ ```javascript
280
+ const price = ref(100)
281
+ const currency = ref('USD')
282
+
283
+ // Реактивная валюта и значение
284
+ const formatted = intl.currency(price, currency)
285
+
286
+ currency.value = 'EUR'
287
+ // formatted.value автоматически обновится
288
+ ```
@@ -0,0 +1,302 @@
1
+ import {Meta} from '@storybook/addon-docs/blocks'
2
+
3
+ <Meta title='@dxtmisha/functional/ru/Composables/useHashRef'/>
4
+
5
+ # Композабл useHashRef
6
+
7
+ Композабл для создания реактивной переменной, синхронизированной с URL hash. Автоматически управляет чтением и записью значений в hash часть URL, обеспечивая двустороннюю синхронизацию между реактивным состоянием Vue и параметрами в адресной строке браузера.
8
+
9
+ ## Основные возможности
10
+
11
+ - **Двусторонняя синхронизация** — автоматическая синхронизация между ref и URL hash
12
+ - **Автоматическое сохранение** — изменения ref автоматически отражаются в URL
13
+ - **Реактивность** — изменения URL hash автоматически обновляют ref
14
+ - **Кеширование экземпляров** — переиспользование ref для одинаковых имён параметров
15
+ - **Типобезопасность** — полная поддержка TypeScript с дженериками
16
+ - **Значения по умолчанию** — поддержка начальных значений и функций-фабрик
17
+ - **Автоматическая инициализация** — загрузка существующих значений из URL при создании
18
+
19
+ ## Функция
20
+
21
+ ### `useHashRef`
22
+
23
+ Создаёт реактивную переменную, синхронизированную с параметром в URL hash.
24
+
25
+ **Параметры:**
26
+ - `name: string` — имя параметра в hash URL
27
+ - `defaultValue?: T | (() => T)` — значение по умолчанию или функция для его генерации (опционально)
28
+
29
+ **Возвращает:** `Ref<T>` — реактивная переменная Vue, связанная с hash параметром
30
+
31
+ ```javascript
32
+ import { useHashRef } from '@dxtmisha/functional'
33
+
34
+ // Простое использование без значения по умолчанию
35
+ const currentTab = useHashRef('tab')
36
+ console.log(currentTab.value) // undefined (если hash пустой)
37
+
38
+ // С значением по умолчанию
39
+ const activeView = useHashRef('view', 'grid')
40
+ console.log(activeView.value) // 'grid' (если hash не содержит 'view')
41
+
42
+ // С функцией-фабрикой для значения по умолчанию
43
+ const userId = useHashRef('userId', () => Math.floor(Math.random() * 1000))
44
+ ```
45
+
46
+ ## Основное использование
47
+
48
+ ### Базовая синхронизация
49
+
50
+ ```javascript
51
+ import { useHashRef } from '@dxtmisha/functional'
52
+
53
+ // Создание ref, синхронизированного с hash
54
+ const currentPage = useHashRef('page', 1)
55
+
56
+ // При изменении ref - URL автоматически обновляется
57
+ currentPage.value = 2
58
+ // URL: #page=2
59
+
60
+ currentPage.value = 5
61
+ // URL: #page=5
62
+
63
+ // При изменении URL вручную - ref автоматически обновляется
64
+ // Пользователь меняет URL на: #page=10
65
+ console.log(currentPage.value) // 10
66
+ ```
67
+
68
+ ### Работа с несколькими параметрами
69
+
70
+ ```javascript
71
+ // Несколько независимых hash параметров
72
+ const searchQuery = useHashRef('q', '')
73
+ const sortOrder = useHashRef('sort', 'asc')
74
+ const pageNumber = useHashRef('page', 1)
75
+
76
+ searchQuery.value = 'vue композаблы'
77
+ sortOrder.value = 'desc'
78
+ pageNumber.value = 3
79
+
80
+ // URL: #q=vue композаблы;sort=desc;page=3
81
+
82
+ // Все параметры остаются синхронизированными
83
+ console.log(searchQuery.value) // 'vue композаблы'
84
+ console.log(sortOrder.value) // 'desc'
85
+ console.log(pageNumber.value) // 3
86
+ ```
87
+
88
+ ### Кеширование экземпляров
89
+
90
+ ```javascript
91
+ // При повторном вызове с тем же именем возвращается существующий ref
92
+ const tab1 = useHashRef('activeTab', 'home')
93
+ const tab2 = useHashRef('activeTab', 'profile')
94
+
95
+ console.log(tab1 === tab2) // true - тот же ref
96
+
97
+ tab1.value = 'settings'
98
+ console.log(tab2.value) // 'settings' - оба указывают на один ref
99
+ ```
100
+
101
+ ## Использование в компонентах
102
+
103
+ ### Управление табами
104
+
105
+ ```javascript
106
+ import { useHashRef } from '@dxtmisha/functional'
107
+
108
+ export default {
109
+ setup() {
110
+ const activeTab = useHashRef('tab', 'overview')
111
+
112
+ return {
113
+ activeTab,
114
+ tabs: ['overview', 'details', 'settings']
115
+ }
116
+ }
117
+ }
118
+
119
+ // Template:
120
+ // <div>
121
+ // <button
122
+ // v-for="tab in tabs"
123
+ // :key="tab"
124
+ // @click="activeTab = tab"
125
+ // :class="{ active: activeTab === tab }"
126
+ // >
127
+ // {{ tab }}
128
+ // </button>
129
+ // </div>
130
+ ```
131
+
132
+ ### Пагинация с сохранением состояния
133
+
134
+ ```javascript
135
+ import { computed } from 'vue'
136
+ import { useHashRef } from '@dxtmisha/functional'
137
+
138
+ export default {
139
+ setup() {
140
+ const currentPage = useHashRef('page', 1)
141
+ const itemsPerPage = 20
142
+ const totalItems = 100
143
+
144
+ const totalPages = computed(() =>
145
+ Math.ceil(totalItems / itemsPerPage)
146
+ )
147
+
148
+ const nextPage = () => {
149
+ if (currentPage.value < totalPages.value) {
150
+ currentPage.value++
151
+ }
152
+ }
153
+
154
+ const prevPage = () => {
155
+ if (currentPage.value > 1) {
156
+ currentPage.value--
157
+ }
158
+ }
159
+
160
+ return {
161
+ currentPage,
162
+ totalPages,
163
+ nextPage,
164
+ prevPage
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Фильтры и поиск
171
+
172
+ ```javascript
173
+ import { watch } from 'vue'
174
+ import { useHashRef } from '@dxtmisha/functional'
175
+
176
+ export default {
177
+ setup() {
178
+ const searchQuery = useHashRef('q', '')
179
+ const category = useHashRef('category', 'all')
180
+ const sortBy = useHashRef('sort', 'date')
181
+
182
+ // Отслеживание изменений для загрузки данных
183
+ watch([searchQuery, category, sortBy], () => {
184
+ console.log('Загрузка данных с параметрами:')
185
+ console.log('Поиск:', searchQuery.value)
186
+ console.log('Категория:', category.value)
187
+ console.log('Сортировка:', sortBy.value)
188
+ // Здесь выполняется запрос к API
189
+ })
190
+
191
+ return {
192
+ searchQuery,
193
+ category,
194
+ sortBy
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ ## Работа с типами данных
201
+
202
+ ### Числовые значения
203
+
204
+ ```javascript
205
+ // Hash автоматически преобразует типы
206
+ const pageNumber = useHashRef<number>('page', 1)
207
+
208
+ pageNumber.value = 5
209
+ // URL: #page=5
210
+
211
+ // При загрузке из URL строка автоматически преобразуется
212
+ // URL: #page=10
213
+ console.log(typeof pageNumber.value) // 'number'
214
+ console.log(pageNumber.value) // 10
215
+ ```
216
+
217
+ ### Булевы значения
218
+
219
+ ```javascript
220
+ const isActive = useHashRef<boolean>('active', false)
221
+
222
+ isActive.value = true
223
+ // URL: #active=true
224
+
225
+ // Автоматическое преобразование из строки
226
+ // URL: #active=false
227
+ console.log(typeof isActive.value) // 'boolean'
228
+ console.log(isActive.value) // false
229
+ ```
230
+
231
+ ### Объекты и массивы
232
+
233
+ ```javascript
234
+ // Для сложных типов используется сериализация
235
+ const filters = useHashRef('filters', { min: 0, max: 100 })
236
+
237
+ filters.value = { min: 20, max: 80 }
238
+ // URL будет содержать сериализованное представление
239
+
240
+ // Значения восстанавливаются при загрузке
241
+ console.log(filters.value) // { min: 20, max: 80 }
242
+ ```
243
+
244
+ ## Интеграция с классом Hash
245
+
246
+ Композабл использует класс `Hash` для управления URL hash:
247
+
248
+ ```javascript
249
+ import { Hash } from '@dxtmisha/functional'
250
+
251
+ // Прямое использование класса
252
+ Hash.set('tab', 'profile')
253
+ console.log(Hash.get('tab')) // 'profile'
254
+
255
+ // useHashRef автоматически синхронизируется с Hash
256
+ const tab = useHashRef('tab')
257
+ console.log(tab.value) // 'profile'
258
+
259
+ // Изменения через Hash отражаются в ref
260
+ Hash.set('tab', 'settings')
261
+ console.log(tab.value) // 'settings'
262
+ ```
263
+
264
+ ## Примеры использования
265
+
266
+ ### Сохранение состояния формы
267
+
268
+ ```javascript
269
+ const formData = {
270
+ name: useHashRef('name', ''),
271
+ email: useHashRef('email', ''),
272
+ role: useHashRef('role', 'user')
273
+ }
274
+
275
+ // При заполнении формы состояние сохраняется в URL
276
+ formData.name.value = 'Иван'
277
+ formData.email.value = 'ivan@example.com'
278
+ formData.role.value = 'admin'
279
+
280
+ // URL: #name=Иван;email=ivan@example.com;role=admin
281
+
282
+ // При перезагрузке страницы состояние восстанавливается
283
+ ```
284
+
285
+ ### Управление модальными окнами
286
+
287
+ ```javascript
288
+ const modalOpen = useHashRef('modal', null)
289
+
290
+ const openModal = (modalName) => {
291
+ modalOpen.value = modalName
292
+ // URL: #modal=confirmation
293
+ }
294
+
295
+ const closeModal = () => {
296
+ modalOpen.value = null
297
+ // URL: #modal=null или hash очищается
298
+ }
299
+
300
+ // Кнопка "Назад" в браузере закрывает модальное окно
301
+ ```
302
+