dxd-style-code 0.1.11 → 0.1.13
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.
- package/dist/dxd-style-code.js +7470 -6336
- package/dist/dxd-style-code.umd.cjs +3 -3
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/components/atoms/DX/DX.stories.js +265 -0
- package/src/components/atoms/DX/DX.vue +80 -0
- package/src/components/atoms/DX/index.js +2 -0
- package/src/components/atoms/DXAvatar/DXAvatar.stories.js +1 -2
- package/src/components/atoms/DXBackdrop/DXBackdrop.stories.js +77 -1
- package/src/components/atoms/DXBadge/DXBadge.stories.js +83 -1
- package/src/components/atoms/DXBlockquote/DXBlockquote.stories.js +67 -1
- package/src/components/atoms/DXBox/DXBox.stories.js +1 -1
- package/src/components/atoms/DXBox/DXBox.vue +69 -2
- package/src/components/atoms/DXButton/DXButton.stories.js +94 -1
- package/src/components/atoms/DXButton/DXButton.vue +145 -11
- package/src/components/atoms/DXCard/DXCard.stories.js +72 -14
- package/src/components/atoms/DXCard/DXCard.vue +3 -4
- package/src/components/atoms/DXCheckbox/DXCheckbox.stories.js +85 -1
- package/src/components/atoms/DXCode/DXCode.stories.js +67 -1
- package/src/components/atoms/DXContainer/DXContainer.stories.js +1 -1
- package/src/components/atoms/DXContainer/DXContainer.vue +28 -1
- package/src/components/atoms/DXDivider/DXDivider.stories.js +84 -1
- package/src/components/atoms/DXFlex/DXFlex.stories.js +1 -1
- package/src/components/atoms/DXFlex/DXFlex.vue +57 -3
- package/src/components/atoms/DXFormLabel/DXFormLabel.stories.js +70 -1
- package/src/components/atoms/DXGrid/DXGrid.stories.js +1 -1
- package/src/components/atoms/DXHeading/DXHeading.stories.js +90 -1
- package/src/components/atoms/DXIcon/DXIcon.stories.js +74 -0
- package/src/components/atoms/DXIconWrapper/DXIconWrapper.stories.js +69 -0
- package/src/components/atoms/DXImage/DXImage.stories.js +483 -0
- package/src/components/atoms/DXImage/DXImage.vue +294 -0
- package/src/components/atoms/DXImage/index.js +2 -0
- package/src/components/atoms/DXInputAddon/DXInputAddon.stories.js +86 -1
- package/src/components/atoms/DXLabel/DXLabel.stories.js +62 -1
- package/src/components/atoms/DXLink/DXLink.stories.js +75 -10
- package/src/components/atoms/DXLink/DXLink.vue +59 -3
- package/src/components/atoms/DXList/DXList.stories.js +76 -1
- package/src/components/atoms/DXLoader/DXLoader.stories.js +75 -1
- package/src/components/atoms/DXNav/DXNav.stories.js +236 -0
- package/src/components/atoms/DXNav/DXNav.vue +114 -0
- package/src/components/atoms/DXNav/index.js +2 -0
- package/src/components/atoms/DXProgress/DXProgress.stories.js +76 -1
- package/src/components/atoms/DXRadio/DXRadio.stories.js +85 -1
- package/src/components/atoms/DXSkeleton/DXSkeleton.stories.js +59 -1
- package/src/components/atoms/DXSlider/DXSlider.stories.js +89 -0
- package/src/components/atoms/DXSpacer/DXSpacer.stories.js +1 -1
- package/src/components/atoms/DXStack/DXStack.stories.js +1 -1
- package/src/components/atoms/DXStack/DXStack.vue +5 -2
- package/src/components/atoms/DXTags/DXTags.stories.js +77 -0
- package/src/components/atoms/DXText/DXText.stories.js +83 -1
- package/src/components/atoms/DXToast/DXToast.stories.js +64 -1
- package/src/components/atoms/DXToggle/DXToggle.stories.js +84 -1
- package/src/components/atoms/DXToggleButton/DXToggleButton.stories.js +78 -1
- package/src/components/atoms/DXTooltip/DXTooltip.stories.js +98 -1
- package/src/components/atoms/index.js +3 -0
- package/src/components/molecules/DXActionButtons/DXActionButtons.stories.js +280 -77
- package/src/components/molecules/DXActionButtons/DXActionButtons.vue +31 -31
- package/src/components/molecules/DXAlert/DXAlert.stories.js +199 -1
- package/src/components/molecules/DXAlert/DXAlert.vue +35 -13
- package/src/components/molecules/DXBreadcrumb/DXBreadcrumb.stories.js +125 -1
- package/src/components/molecules/DXBreadcrumb/DXBreadcrumb.vue +22 -18
- package/src/components/molecules/DXButtonGroup/DXButtonGroup.stories.js +193 -6
- package/src/components/molecules/DXButtonGroup/DXButtonGroup.vue +39 -3
- package/src/components/molecules/DXCloseButton/DXCloseButton.stories.js +64 -1
- package/src/components/molecules/DXComboBox/DXComboBox.stories.js +66 -0
- package/src/components/molecules/DXCopyField/DXCopyField.stories.js +128 -1
- package/src/components/molecules/DXCopyField/DXCopyField.vue +60 -7
- package/src/components/molecules/DXDataFilter/DXDataFilter.vue +8 -6
- package/src/components/molecules/DXDatePicker/DXDatePicker.stories.js +58 -0
- package/src/components/molecules/DXFileUpload/DXFileUpload.stories.js +66 -0
- package/src/components/molecules/DXFilterGroup/DXFilterGroup.stories.js +61 -0
- package/src/components/molecules/DXFormControl/DXFormControl.stories.js +76 -0
- package/src/components/molecules/DXFormControl/DXFormControl.vue +9 -8
- package/src/components/molecules/DXInput/DXInput.stories.js +100 -1
- package/src/components/molecules/DXInputGroup/DXInputGroup.stories.js +89 -1
- package/src/components/molecules/DXInputMask/DXInputMask.stories.js +67 -0
- package/src/components/molecules/DXMenu/DXMenu.stories.js +111 -4
- package/src/components/molecules/DXMenu/DXMenu.vue +18 -5
- package/src/components/molecules/DXMenu/README.md +1 -1
- package/src/components/molecules/DXPagination/DXPagination.stories.js +105 -2
- package/src/components/molecules/DXPagination/DXPagination.vue +18 -33
- package/src/components/molecules/DXPasswordInput/DXPasswordInput.stories.js +67 -1
- package/src/components/molecules/DXRadioCard/DXRadioCard.stories.js +64 -0
- package/src/components/molecules/DXRadioGroup/DXRadioGroup.stories.js +84 -0
- package/src/components/molecules/DXRating/DXRating.stories.js +3 -2
- package/src/components/molecules/DXSearchBar/DXSearchBar.stories.js +1 -1
- package/src/components/molecules/DXSearchBar/DXSearchBar.vue +16 -12
- package/src/components/molecules/DXSearchSelect/DXSearchSelect.stories.js +71 -0
- package/src/components/molecules/DXSegmentedControl/DXSegmentedControl.stories.js +74 -0
- package/src/components/molecules/DXSelect/DXSelect.stories.js +92 -1
- package/src/components/molecules/DXStatCard/DXStatCard.stories.js +1 -1
- package/src/components/molecules/DXStatCard/DXStatCard.vue +30 -26
- package/src/components/molecules/DXTableFiltersPanel/index.js +3 -0
- package/src/components/molecules/DXTablePagination/DXTablePagination.stories.js +67 -0
- package/src/components/molecules/DXTableToolbar/DXTableToolbar.stories.js +71 -0
- package/src/components/molecules/DXTextarea/DXTextarea.stories.js +87 -1
- package/src/components/molecules/DXTimePicker/DXTimePicker.stories.js +1 -1
- package/src/components/molecules/DXValidationIcon/DXValidationIcon.stories.js +59 -1
- package/src/components/molecules/index.js +0 -1
- package/src/components/organisms/DXAccordion/DXAccordion.stories.js +75 -0
- package/src/components/organisms/DXAppLayout/DXAppLayout.stories.js +27 -25
- package/src/components/organisms/DXAuthenticationForm/DXAuthenticationForm.stories.js +0 -2
- package/src/components/organisms/DXAuthenticationForm/DXAuthenticationForm.vue +5 -8
- package/src/components/{molecules → organisms}/DXBaseTable/DXBaseTable.stories.js +78 -1
- package/src/components/{molecules → organisms}/DXBaseTable/DXBaseTable.vue +2 -2
- package/src/components/organisms/DXChartContainer/DXChartContainer.stories.js +1 -1
- package/src/components/organisms/DXChartContainer/DXChartContainer.vue +10 -6
- package/src/components/organisms/DXChatInterface/DXChatInterface.stories.js +1 -1
- package/src/components/organisms/DXChatInterface/DXChatInterface.vue +6 -4
- package/src/components/organisms/DXCommentSection/DXCommentSection.stories.js +1 -1
- package/src/components/organisms/DXCommentSection/DXCommentSection.vue +7 -6
- package/src/components/organisms/DXDashboardGrid/DXDashboardGrid.stories.js +1 -1
- package/src/components/organisms/DXDashboardGrid/DXDashboardGrid.vue +4 -2
- package/src/components/organisms/DXDashboardWidget/DXDashboardWidget.stories.js +1 -1
- package/src/components/organisms/DXDashboardWidget/DXDashboardWidget.vue +3 -2
- package/src/components/organisms/DXDataTable/DXDataTable.stories.js +1 -1
- package/src/components/organisms/DXDropdown/DXDropdown.stories.js +84 -1
- package/src/components/organisms/DXEmptyState/DXEmptyState.stories.js +64 -0
- package/src/components/organisms/DXEmptyState/DXEmptyState.vue +4 -2
- package/src/components/organisms/DXHeaderBar/DXHeaderBar.stories.js +409 -3
- package/src/components/organisms/DXHeaderBar/DXHeaderBar.vue +261 -52
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.stories.js +1 -1
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.vue +6 -4
- package/src/components/organisms/DXModal/DXModal.stories.js +93 -1
- package/src/components/organisms/DXModal/DXModal.vue +3 -2
- package/src/components/organisms/DXNotificationCenter/DXNotificationCenter.stories.js +1 -1
- package/src/components/organisms/DXNotificationCenter/DXNotificationCenter.vue +2 -1
- package/src/components/organisms/DXReportGenerator/DXReportGenerator.vue +4 -3
- package/src/components/organisms/DXSettingsPanel/DXSettingsPanel.vue +11 -8
- package/src/components/organisms/DXSidebar/DXSidebar.stories.js +1 -1
- package/src/components/organisms/DXSidebarMenu/DXSidebarMenu.stories.js +104 -1
- package/src/components/organisms/DXSidebarMenu/DXSidebarMenu.vue +14 -4
- package/src/components/organisms/DXSidebarMenu/README.md +3 -3
- package/src/components/organisms/DXTable/DXTable.stories.js +138 -11
- package/src/components/organisms/DXTable/DXTable.vue +1 -1
- package/src/components/organisms/DXTabs/DXTabs.stories.js +91 -1
- package/src/components/organisms/DXUserProfileCard/DXUserProfileCard.stories.js +1 -1
- package/src/components/organisms/DXUserProfileCard/DXUserProfileCard.vue +20 -18
- package/src/components/organisms/index.js +1 -0
- package/src/components/utilities/DXAnimatePresence/DXAnimatePresence.stories.js +1 -1
- package/src/components/utilities/DXBreakpointProvider/DXBreakpointProvider.stories.js +1 -1
- package/src/components/utilities/DXObserver/DXObserver.stories.js +1 -1
- package/src/components/utilities/DXPortal/DXPortal.stories.js +1 -1
- package/src/components/utilities/DXStaggeredAnimation/DXStaggeredAnimation.stories.js +2 -2
- package/src/components/utilities/DXThemeProvider/DXThemeProvider.stories.js +1 -1
- package/src/components/utilities/DXTransitionGroup/DXTransitionGroup.stories.js +1 -1
- package/src/composables/useSize.js +8 -1
- /package/src/components/{molecules → organisms}/DXBaseTable/index.js +0 -0
|
@@ -13,7 +13,95 @@ import {
|
|
|
13
13
|
export default {
|
|
14
14
|
title: 'Molecules/DXInputGroup',
|
|
15
15
|
component: DXInputGroup,
|
|
16
|
-
tags: ['autodocs'],
|
|
16
|
+
tags: ['autodocs', 'category:form'],
|
|
17
|
+
parameters: {
|
|
18
|
+
docs: {
|
|
19
|
+
description: {
|
|
20
|
+
component: `
|
|
21
|
+
# DXInputGroup
|
|
22
|
+
|
|
23
|
+
Группа полей ввода с поддержкой аддонов (префиксов и суффиксов) и синхронизацией состояний.
|
|
24
|
+
|
|
25
|
+
## Назначение
|
|
26
|
+
|
|
27
|
+
DXInputGroup предоставляет способ группировки полей ввода с дополнительными элементами (аддонами)
|
|
28
|
+
слева и справа. Компонент автоматически управляет синхронизацией размеров, состояний disabled/error
|
|
29
|
+
и правильным применением border-radius для создания визуально единой группы.
|
|
30
|
+
|
|
31
|
+
## Архитектура
|
|
32
|
+
|
|
33
|
+
### Использует
|
|
34
|
+
- \`DXInput\` - основное поле ввода (автоматически адаптируется при использовании внутри группы)
|
|
35
|
+
- \`DXInputAddon\` - аддоны слева и справа от поля
|
|
36
|
+
- \`DXSelect\` - может использоваться вместо DXInput
|
|
37
|
+
- \`DXTextarea\` - может использоваться вместо DXInput
|
|
38
|
+
- \`provide/inject\` - для передачи контекста группы к дочерним компонентам
|
|
39
|
+
- Система регистрации компонентов - для отслеживания структуры и правильного применения стилей
|
|
40
|
+
|
|
41
|
+
### Используется в
|
|
42
|
+
- Формы с префиксами (например, https:// для URL)
|
|
43
|
+
- Формы с суффиксами (например, валюта для цены)
|
|
44
|
+
- Формы с обоими аддонами (например, $ и .00 для суммы)
|
|
45
|
+
- Интеграция с селектами и textarea
|
|
46
|
+
|
|
47
|
+
## Внутренняя логика
|
|
48
|
+
|
|
49
|
+
### Система регистрации компонентов
|
|
50
|
+
Компонент отслеживает порядок регистрации дочерних компонентов для:
|
|
51
|
+
- Определения наличия аддонов слева и справа от каждого поля
|
|
52
|
+
- Правильного применения border-radius:
|
|
53
|
+
- Оба аддона → \`rounded-none\` (без скругления)
|
|
54
|
+
- Только слева → \`rounded-l-none rounded-r-xl\` (скругление справа)
|
|
55
|
+
- Только справа → \`rounded-l-xl rounded-r-none\` (скругление слева)
|
|
56
|
+
- Нет аддонов → \`rounded-xl\` (полное скругление)
|
|
57
|
+
- Синхронизации размеров всех компонентов в группе
|
|
58
|
+
|
|
59
|
+
### Интеграция с дочерними компонентами
|
|
60
|
+
При использовании дочерних компонентов внутри группы:
|
|
61
|
+
- **DXInput**: Автоматически регистрируется как 'input', получает информацию о позиции аддонов
|
|
62
|
+
- **DXInputAddon**: Автоматически регистрируется как 'addon', синхронизирует размер и состояние
|
|
63
|
+
- **DXSelect**: Может использоваться вместо DXInput, также регистрируется
|
|
64
|
+
- **DXTextarea**: Может использоваться вместо DXInput, также регистрируется
|
|
65
|
+
|
|
66
|
+
### Синхронизация состояний
|
|
67
|
+
- **size**: Размер применяется ко всем компонентам в группе
|
|
68
|
+
- **disabled**: Состояние disabled наследуется всеми компонентами
|
|
69
|
+
- **error**: Состояние ошибки синхронизируется со всеми компонентами (красная рамка)
|
|
70
|
+
|
|
71
|
+
## Особенности
|
|
72
|
+
|
|
73
|
+
### Размеры
|
|
74
|
+
Поддерживает три размера: \`sm\`, \`md\` (по умолчанию), \`lg\`.
|
|
75
|
+
Размер применяется ко всем компонентам в группе автоматически.
|
|
76
|
+
|
|
77
|
+
### Label и Helper
|
|
78
|
+
- **label**: Отображается над группой полей
|
|
79
|
+
- **helper**: Вспомогательный текст под группой полей
|
|
80
|
+
- **error**: Текст ошибки (заменяет helper при наличии)
|
|
81
|
+
|
|
82
|
+
### Аддоны
|
|
83
|
+
Аддоны могут содержать:
|
|
84
|
+
- Текст (например, "https://", "USD", "$")
|
|
85
|
+
- Иконки (через \`icon\` prop в DXInputAddon)
|
|
86
|
+
- Комбинацию текста и иконки
|
|
87
|
+
|
|
88
|
+
### Гибкость
|
|
89
|
+
Группа может содержать:
|
|
90
|
+
- Только поле без аддонов
|
|
91
|
+
- Поле с аддоном слева
|
|
92
|
+
- Поле с аддоном справа
|
|
93
|
+
- Поле с аддонами с обеих сторон
|
|
94
|
+
- Несколько полей с аддонами
|
|
95
|
+
|
|
96
|
+
### Визуальное единство
|
|
97
|
+
Все компоненты в группе визуально объединены:
|
|
98
|
+
- Общие границы между элементами
|
|
99
|
+
- Синхронизированные размеры
|
|
100
|
+
- Единое состояние (disabled/error)
|
|
101
|
+
`,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
17
105
|
};
|
|
18
106
|
|
|
19
107
|
export const Default = {
|
|
@@ -5,6 +5,73 @@ export default {
|
|
|
5
5
|
title: 'Molecules/DXInputMask',
|
|
6
6
|
component: DXInputMask,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXInputMask
|
|
13
|
+
|
|
14
|
+
Компонент поля ввода с маской для форматирования ввода (телефоны, карты, даты и т.д.).
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXInputMask предоставляет способ форматирования ввода данных по заданной маске.
|
|
19
|
+
Компонент автоматически применяет маску при вводе и извлекает сырое значение для v-model.
|
|
20
|
+
|
|
21
|
+
## Архитектура
|
|
22
|
+
|
|
23
|
+
### Использует
|
|
24
|
+
- Нативный input - для ввода текста
|
|
25
|
+
- Логика маскирования - для форматирования
|
|
26
|
+
|
|
27
|
+
### Используется в
|
|
28
|
+
- Ввод телефонов
|
|
29
|
+
- Ввод номеров карт
|
|
30
|
+
- Ввод дат в определенном формате
|
|
31
|
+
- Ввод SSN и других форматов
|
|
32
|
+
- Любые места, требующие форматированный ввод
|
|
33
|
+
|
|
34
|
+
## Внутренняя логика
|
|
35
|
+
|
|
36
|
+
### Маска
|
|
37
|
+
Маска задается через \`mask\` prop:
|
|
38
|
+
- \`#\` - цифра (0-9)
|
|
39
|
+
- Любые другие символы - статичные символы маски
|
|
40
|
+
|
|
41
|
+
Примеры:
|
|
42
|
+
- \`"+7 (###) ###-##-##"\` - телефон
|
|
43
|
+
- \`"#### #### #### ####"\` - номер карты
|
|
44
|
+
- \`"##/##/####"\` - дата
|
|
45
|
+
|
|
46
|
+
### Форматирование
|
|
47
|
+
- При вводе автоматически применяется маска
|
|
48
|
+
- Извлекаются только цифры для v-model
|
|
49
|
+
- Статичные символы маски добавляются автоматически
|
|
50
|
+
|
|
51
|
+
### Валидация ввода
|
|
52
|
+
- Разрешаются только цифры (для масок с #)
|
|
53
|
+
- Служебные клавиши (Backspace, Delete, стрелки) разрешены
|
|
54
|
+
- Остальные символы блокируются
|
|
55
|
+
|
|
56
|
+
## Особенности
|
|
57
|
+
|
|
58
|
+
### v-model
|
|
59
|
+
Полностью поддерживает двустороннее связывание через \`v-model\`:
|
|
60
|
+
- Значение содержит только цифры (без форматирования)
|
|
61
|
+
- При установке значения автоматически применяется маска
|
|
62
|
+
|
|
63
|
+
### Позиция курсора
|
|
64
|
+
Курсор автоматически позиционируется в конец введенного текста.
|
|
65
|
+
|
|
66
|
+
### Примеры масок
|
|
67
|
+
- Телефон: \`"+7 (###) ###-##-##"\`
|
|
68
|
+
- Карта: \`"#### #### #### ####"\`
|
|
69
|
+
- Дата: \`"##/##/####"\`
|
|
70
|
+
- SSN: \`"###-##-####"\`
|
|
71
|
+
`,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
8
75
|
};
|
|
9
76
|
|
|
10
77
|
export const Phone = {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
2
|
import DXMenu from './DXMenu.vue';
|
|
3
|
+
import DXHeading from '../../atoms/DXHeading/DXHeading.vue';
|
|
4
|
+
import DXText from '../../atoms/DXText/DXText.vue';
|
|
3
5
|
import {
|
|
4
6
|
HomeIcon,
|
|
5
7
|
ChartBarIcon,
|
|
@@ -12,7 +14,112 @@ import {
|
|
|
12
14
|
export default {
|
|
13
15
|
title: 'Molecules/DXMenu',
|
|
14
16
|
component: DXMenu,
|
|
15
|
-
tags: ['autodocs'],
|
|
17
|
+
tags: ['autodocs', 'category:navigation'],
|
|
18
|
+
parameters: {
|
|
19
|
+
docs: {
|
|
20
|
+
description: {
|
|
21
|
+
component: `
|
|
22
|
+
# DXMenu
|
|
23
|
+
|
|
24
|
+
Компонент меню навигации с поддержкой вертикального и горизонтального режимов, поиска, компактного режима и вложенных элементов.
|
|
25
|
+
|
|
26
|
+
## Назначение
|
|
27
|
+
|
|
28
|
+
DXMenu предоставляет полнофункциональное меню навигации с поддержкой секций, вложенных элементов, поиска,
|
|
29
|
+
компактного режима и различных вариантов визуального оформления. Компонент автоматически адаптируется
|
|
30
|
+
для вертикального и горизонтального отображения.
|
|
31
|
+
|
|
32
|
+
## Архитектура
|
|
33
|
+
|
|
34
|
+
### Использует
|
|
35
|
+
- \`DXCard\` - контейнер меню с настраиваемым padding и вариантом
|
|
36
|
+
- \`DXNav\` - семантическая обертка для навигации
|
|
37
|
+
- \`DXSidebarMenuItem\` - элементы меню
|
|
38
|
+
- \`DXInput\` - поле поиска
|
|
39
|
+
- \`DXHeading\` - заголовок меню
|
|
40
|
+
- \`DXIcon\` - иконки в элементах меню
|
|
41
|
+
|
|
42
|
+
### Используется в
|
|
43
|
+
- Боковые панели навигации
|
|
44
|
+
- Горизонтальные меню
|
|
45
|
+
- Навигация в приложениях
|
|
46
|
+
- Меню настроек
|
|
47
|
+
- Любые места, требующие структурированной навигации
|
|
48
|
+
|
|
49
|
+
## Внутренняя логика
|
|
50
|
+
|
|
51
|
+
### Направления
|
|
52
|
+
- **vertical** (по умолчанию): Вертикальное меню, элементы расположены в колонку
|
|
53
|
+
- **horizontal**: Горизонтальное меню, элементы расположены в строку
|
|
54
|
+
|
|
55
|
+
### Структура меню
|
|
56
|
+
Меню состоит из секций, каждая секция может содержать:
|
|
57
|
+
- \`title\` - заголовок секции (опционально)
|
|
58
|
+
- \`items\` - массив элементов меню
|
|
59
|
+
|
|
60
|
+
Каждый элемент может содержать:
|
|
61
|
+
- \`id\` - уникальный идентификатор
|
|
62
|
+
- \`label\` - текст элемента
|
|
63
|
+
- \`icon\` - иконка (Heroicon компонент, опционально)
|
|
64
|
+
- \`to\` - путь для навигации (Vue Router)
|
|
65
|
+
- \`href\` - обычная ссылка
|
|
66
|
+
- \`badge\` - бейдж/счетчик (опционально)
|
|
67
|
+
- \`badgeVariant\` - вариант бейджа
|
|
68
|
+
- \`children\` - вложенные элементы (опционально)
|
|
69
|
+
- \`active\` - активное состояние (опционально)
|
|
70
|
+
|
|
71
|
+
### Поиск
|
|
72
|
+
При \`searchable={true}\`:
|
|
73
|
+
- В вертикальном режиме: поле поиска под заголовком
|
|
74
|
+
- В горизонтальном режиме: поле поиска в заголовке справа
|
|
75
|
+
- Фильтрация элементов меню по тексту в реальном времени
|
|
76
|
+
- В компактном режиме поиск скрывается
|
|
77
|
+
|
|
78
|
+
### Компактный режим
|
|
79
|
+
При \`compact={true}\`:
|
|
80
|
+
- Скрывается текст элементов, показываются только иконки
|
|
81
|
+
- Скрывается заголовок (если не переопределен через слот)
|
|
82
|
+
- Скрывается поиск
|
|
83
|
+
- Меню занимает минимальную ширину
|
|
84
|
+
|
|
85
|
+
### Заголовок
|
|
86
|
+
- Автоматически показывается, если есть \`title\` или слот \`header\`
|
|
87
|
+
- Можно принудительно показать/скрыть через \`showHeader\`
|
|
88
|
+
- Размер заголовка: \`sm\`, \`md\`, \`lg\`
|
|
89
|
+
|
|
90
|
+
### Визуальное оформление
|
|
91
|
+
- **cardVariant**: Вариант карточки (default, bordered, elevated, flat)
|
|
92
|
+
- **cardPadding**: Padding карточки (none, sm, md, lg)
|
|
93
|
+
- Настраивается через props DXCard
|
|
94
|
+
|
|
95
|
+
## Особенности
|
|
96
|
+
|
|
97
|
+
### Вложенные элементы
|
|
98
|
+
Поддерживает многоуровневую вложенность элементов через \`children\`:
|
|
99
|
+
- Вложенные элементы отображаются с отступом
|
|
100
|
+
- Поддержка активного состояния для вложенных элементов
|
|
101
|
+
- Клик по родительскому элементу может открывать/закрывать вложенные
|
|
102
|
+
|
|
103
|
+
### Активное состояние
|
|
104
|
+
- Автоматическое определение активного элемента на основе текущего маршрута (если используется \`to\`)
|
|
105
|
+
- Можно задать явно через \`active\` prop в элементе
|
|
106
|
+
|
|
107
|
+
### Бейджи
|
|
108
|
+
- Отображаются справа от текста элемента
|
|
109
|
+
- Поддерживают различные варианты (info, warning, danger и т.д.)
|
|
110
|
+
- Полезны для отображения счетчиков уведомлений
|
|
111
|
+
|
|
112
|
+
### Слоты
|
|
113
|
+
- \`header\` - кастомный заголовок меню
|
|
114
|
+
- Слоты для кастомизации элементов меню
|
|
115
|
+
|
|
116
|
+
### Интеграция с Vue Router
|
|
117
|
+
При использовании \`to\` prop, элементы автоматически становятся \`router-link\` и поддерживают
|
|
118
|
+
активные состояния на основе текущего маршрута.
|
|
119
|
+
`,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
16
123
|
argTypes: {
|
|
17
124
|
direction: {
|
|
18
125
|
control: { type: 'select' },
|
|
@@ -98,8 +205,8 @@ const ContentPlaceholder = `
|
|
|
98
205
|
<div class="flex-1 bg-slate-50 rounded-xl border-2 border-dashed border-slate-300 p-8 flex items-center justify-center">
|
|
99
206
|
<div class="text-center">
|
|
100
207
|
<div class="text-4xl mb-2">📄</div>
|
|
101
|
-
<
|
|
102
|
-
<p
|
|
208
|
+
<DXHeading level="3" size="lg" weight="semibold" color="default">Content Area</DXHeading>
|
|
209
|
+
<DXText tag="p" size="sm" color="muted">Main content goes here</DXText>
|
|
103
210
|
</div>
|
|
104
211
|
</div>
|
|
105
212
|
`;
|
|
@@ -116,7 +223,7 @@ export const Playground = {
|
|
|
116
223
|
showHeader: undefined,
|
|
117
224
|
headerSize: 'md',
|
|
118
225
|
cardPadding: 'none',
|
|
119
|
-
cardVariant: '
|
|
226
|
+
cardVariant: 'bordered',
|
|
120
227
|
},
|
|
121
228
|
render: (args) => ({
|
|
122
229
|
components: { DXMenu },
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<!-- Horizontal режим: все в одну строку -->
|
|
14
14
|
<template v-if="direction === 'horizontal'">
|
|
15
15
|
<slot v-if="!compact" name="header">
|
|
16
|
-
<
|
|
16
|
+
<DXHeading v-if="title" level="2" :size="headerSizeMap" weight="bold" color="default" :class="headerTitleClasses">{{ title }}</DXHeading>
|
|
17
17
|
</slot>
|
|
18
18
|
|
|
19
19
|
<!-- Search inline для horizontal -->
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<!-- Vertical режим: текущий layout -->
|
|
49
49
|
<template v-else>
|
|
50
50
|
<slot v-if="!compact" name="header">
|
|
51
|
-
<
|
|
51
|
+
<DXHeading v-if="title" level="2" :size="headerSizeMap" weight="bold" color="default" :class="headerTitleClasses">{{ title }}</DXHeading>
|
|
52
52
|
</slot>
|
|
53
53
|
|
|
54
54
|
<button
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
</div>
|
|
84
84
|
|
|
85
85
|
<!-- Меню -->
|
|
86
|
-
<
|
|
86
|
+
<DXNav type="menu" :class="navClasses">
|
|
87
87
|
<!-- Horizontal режим: items в строку без section titles -->
|
|
88
88
|
<template v-if="direction === 'horizontal'">
|
|
89
89
|
<template v-for="(section, sectionIndex) in filteredSections" :key="sectionIndex">
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
/>
|
|
131
131
|
</div>
|
|
132
132
|
</template>
|
|
133
|
-
</
|
|
133
|
+
</DXNav>
|
|
134
134
|
|
|
135
135
|
<!-- Футер (только для vertical) -->
|
|
136
136
|
<div v-if="$slots.footer && !compact && direction === 'vertical'" :class="footerClasses">
|
|
@@ -153,6 +153,8 @@ import DXSidebarMenuItem from '../../organisms/DXSidebarMenu/DXSidebarMenuItem.v
|
|
|
153
153
|
import DXInput from '../DXInput/DXInput.vue';
|
|
154
154
|
import DXIcon from '../../atoms/DXIcon/DXIcon.vue';
|
|
155
155
|
import DXDivider from '../../atoms/DXDivider/DXDivider.vue';
|
|
156
|
+
import DXHeading from '../../atoms/DXHeading/DXHeading.vue';
|
|
157
|
+
import DXNav from '../../atoms/DXNav/DXNav.vue';
|
|
156
158
|
|
|
157
159
|
const $slots = useSlots();
|
|
158
160
|
|
|
@@ -288,10 +290,21 @@ const headerClasses = computed(() => {
|
|
|
288
290
|
});
|
|
289
291
|
|
|
290
292
|
const headerTitleClasses = computed(() => [
|
|
291
|
-
'font-bold text-slate-900',
|
|
292
293
|
props.direction === 'horizontal' ? 'text-base' : HEADER_SIZE_CLASSES[props.headerSize].title
|
|
293
294
|
]);
|
|
294
295
|
|
|
296
|
+
const headerSizeMap = computed(() => {
|
|
297
|
+
if (props.direction === 'horizontal') {
|
|
298
|
+
return 'base';
|
|
299
|
+
}
|
|
300
|
+
const sizeMap = {
|
|
301
|
+
sm: 'base',
|
|
302
|
+
md: 'lg',
|
|
303
|
+
lg: 'xl',
|
|
304
|
+
};
|
|
305
|
+
return sizeMap[props.headerSize] || sizeMap.md;
|
|
306
|
+
});
|
|
307
|
+
|
|
295
308
|
const navClasses = computed(() => {
|
|
296
309
|
if (props.direction === 'horizontal') {
|
|
297
310
|
return 'flex flex-row items-center gap-1 px-4 py-2 overflow-visible';
|
|
@@ -269,7 +269,7 @@ const currentPage = ref('/home');
|
|
|
269
269
|
| `showHeader` | Boolean | `undefined` | Показывать header (undefined = автоматически) |
|
|
270
270
|
| `headerSize` | String | `'md'` | Размер header: sm, md, lg (только vertical) |
|
|
271
271
|
| `cardPadding` | String | `'none'` | Padding карточки: none, sm, md, lg |
|
|
272
|
-
| `cardVariant` | String | `'
|
|
272
|
+
| `cardVariant` | String | `'bordered'` | Вариант карточки: bordered, elevated, flat |
|
|
273
273
|
|
|
274
274
|
## Структура данных sections
|
|
275
275
|
|
|
@@ -4,9 +4,112 @@ import { ref } from 'vue';
|
|
|
4
4
|
export default {
|
|
5
5
|
title: 'Molecules/DXPagination',
|
|
6
6
|
component: DXPagination,
|
|
7
|
-
tags: ['autodocs'],
|
|
7
|
+
tags: ['autodocs', 'category:navigation'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXPagination
|
|
13
|
+
|
|
14
|
+
Компонент пагинации для навигации по страницам с поддержкой v-model.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXPagination предоставляет удобный способ навигации по страницам с визуальным отображением
|
|
19
|
+
текущей страницы и быстрым доступом к соседним страницам. Компонент автоматически управляет
|
|
20
|
+
отображением номеров страниц и эллипсисов для больших списков.
|
|
21
|
+
|
|
22
|
+
## Архитектура
|
|
23
|
+
|
|
24
|
+
### Использует
|
|
25
|
+
- \`DXNav\` - семантическая обертка навигации с автоматическим aria-label
|
|
26
|
+
- \`DXButton\` - кнопки для навигации и номеров страниц
|
|
27
|
+
- \`DXIcon\` - иконки для кнопок Previous/Next (ChevronLeftIcon, ChevronRightIcon)
|
|
28
|
+
|
|
29
|
+
### Используется в
|
|
30
|
+
- Таблицы с пагинацией (\`DXTable\`, \`DXTablePagination\`)
|
|
31
|
+
- Списки элементов с разбивкой на страницы
|
|
32
|
+
- Результаты поиска
|
|
33
|
+
- Любые компоненты, требующие навигации по страницам
|
|
34
|
+
|
|
35
|
+
## Внутренняя логика
|
|
36
|
+
|
|
37
|
+
### Отображение страниц
|
|
38
|
+
Компонент автоматически вычисляет видимые страницы:
|
|
39
|
+
- Всегда показывает первую страницу
|
|
40
|
+
- Показывает страницы вокруг текущей (количество определяется \`siblingCount\`)
|
|
41
|
+
- Добавляет эллипсисы (\`...\`) когда есть пропуски
|
|
42
|
+
- Всегда показывает последнюю страницу (если страниц больше 1)
|
|
43
|
+
|
|
44
|
+
### Варианты кнопок
|
|
45
|
+
- **Previous/Next**: Используют \`DXButton\` с \`variant="ghost"\` и \`iconOnly={true}\`
|
|
46
|
+
- **Активная страница**: Использует \`DXButton\` с \`variant="primary"\`
|
|
47
|
+
- **Неактивные страницы**: Используют \`DXButton\` с \`variant="ghost"\`
|
|
48
|
+
|
|
49
|
+
### Состояния
|
|
50
|
+
- **disabled**: Кнопки Previous/Next автоматически отключаются на первой/последней странице
|
|
51
|
+
- **active**: Текущая страница визуально выделяется через \`variant="primary"\`
|
|
52
|
+
- **aria-current**: Автоматически добавляется к текущей странице для accessibility
|
|
53
|
+
|
|
54
|
+
## Особенности
|
|
55
|
+
|
|
56
|
+
### Размеры
|
|
57
|
+
Поддерживает три размера: \`sm\`, \`md\` (по умолчанию), \`lg\`.
|
|
58
|
+
Размер применяется ко всем кнопкам в пагинации.
|
|
59
|
+
|
|
60
|
+
### v-model
|
|
61
|
+
Полностью поддерживает двустороннее связывание через \`v-model\`:
|
|
62
|
+
- Значение - номер текущей страницы (Number, начиная с 1)
|
|
63
|
+
- Автоматически валидирует границы (не может быть меньше 1 или больше \`totalPages\`)
|
|
64
|
+
|
|
65
|
+
### Accessibility
|
|
66
|
+
- Использует \`DXNav\` с \`aria-label="Pagination"\`
|
|
67
|
+
- Кнопки Previous/Next имеют \`aria-label\`
|
|
68
|
+
- Текущая страница имеет \`aria-current="page"\`
|
|
69
|
+
- Все кнопки поддерживают клавиатурную навигацию через \`DXButton\`
|
|
70
|
+
|
|
71
|
+
## Ограничения
|
|
72
|
+
|
|
73
|
+
- Минимальное количество страниц: 1
|
|
74
|
+
- Номер страницы начинается с 1 (не с 0)
|
|
75
|
+
- \`siblingCount\` определяет количество страниц вокруг текущей (по умолчанию 1)
|
|
76
|
+
`,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
8
80
|
argTypes: {
|
|
9
|
-
|
|
81
|
+
modelValue: {
|
|
82
|
+
control: { type: 'number' },
|
|
83
|
+
description: 'Текущая страница (v-model)',
|
|
84
|
+
table: {
|
|
85
|
+
type: { summary: 'number' },
|
|
86
|
+
defaultValue: { summary: '1' },
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
totalPages: {
|
|
90
|
+
control: { type: 'number' },
|
|
91
|
+
description: 'Всего страниц',
|
|
92
|
+
table: {
|
|
93
|
+
type: { summary: 'number' },
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
siblingCount: {
|
|
97
|
+
control: { type: 'number' },
|
|
98
|
+
description: 'Сколько страниц показывать вокруг текущей',
|
|
99
|
+
table: {
|
|
100
|
+
type: { summary: 'number' },
|
|
101
|
+
defaultValue: { summary: '1' },
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
size: {
|
|
105
|
+
control: { type: 'select' },
|
|
106
|
+
options: ['sm', 'md', 'lg'],
|
|
107
|
+
description: 'Размер кнопок',
|
|
108
|
+
table: {
|
|
109
|
+
type: { summary: 'string' },
|
|
110
|
+
defaultValue: { summary: 'md' },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
10
113
|
},
|
|
11
114
|
};
|
|
12
115
|
|
|
@@ -1,47 +1,51 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<DXNav type="pagination" class="flex items-center gap-1" data-component="DXPagination">
|
|
3
3
|
<!-- Previous -->
|
|
4
|
-
<
|
|
5
|
-
|
|
4
|
+
<DXButton
|
|
5
|
+
variant="ghost"
|
|
6
|
+
:size="size"
|
|
7
|
+
icon-only
|
|
6
8
|
:disabled="modelValue <= 1"
|
|
7
|
-
:class="[navButtonClasses, modelValue <= 1 && 'opacity-50 cursor-not-allowed']"
|
|
8
9
|
@click="goTo(modelValue - 1)"
|
|
9
10
|
aria-label="Предыдущая"
|
|
10
11
|
>
|
|
11
12
|
<DXIcon :icon="ChevronLeftIcon" size="sm" animation="none" />
|
|
12
|
-
</
|
|
13
|
+
</DXButton>
|
|
13
14
|
|
|
14
15
|
<!-- Pages -->
|
|
15
16
|
<template v-for="page in visiblePages" :key="page">
|
|
16
17
|
<span v-if="page === '...'" class="px-2 text-slate-400">...</span>
|
|
17
|
-
<
|
|
18
|
+
<DXButton
|
|
18
19
|
v-else
|
|
19
|
-
|
|
20
|
-
:
|
|
20
|
+
:variant="page === modelValue ? 'primary' : 'ghost'"
|
|
21
|
+
:size="size"
|
|
21
22
|
:aria-current="page === modelValue ? 'page' : undefined"
|
|
22
23
|
@click="goTo(page)"
|
|
23
24
|
>
|
|
24
25
|
{{ page }}
|
|
25
|
-
</
|
|
26
|
+
</DXButton>
|
|
26
27
|
</template>
|
|
27
28
|
|
|
28
29
|
<!-- Next -->
|
|
29
|
-
<
|
|
30
|
-
|
|
30
|
+
<DXButton
|
|
31
|
+
variant="ghost"
|
|
32
|
+
:size="size"
|
|
33
|
+
icon-only
|
|
31
34
|
:disabled="modelValue >= totalPages"
|
|
32
|
-
:class="[navButtonClasses, modelValue >= totalPages && 'opacity-50 cursor-not-allowed']"
|
|
33
35
|
@click="goTo(modelValue + 1)"
|
|
34
36
|
aria-label="Следующая"
|
|
35
37
|
>
|
|
36
38
|
<DXIcon :icon="ChevronRightIcon" size="sm" animation="none" />
|
|
37
|
-
</
|
|
38
|
-
</
|
|
39
|
+
</DXButton>
|
|
40
|
+
</DXNav>
|
|
39
41
|
</template>
|
|
40
42
|
|
|
41
43
|
<script setup>
|
|
42
44
|
import { computed } from "vue";
|
|
43
45
|
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/vue/24/outline";
|
|
46
|
+
import DXButton from "../../atoms/DXButton/DXButton.vue";
|
|
44
47
|
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
48
|
+
import DXNav from "../../atoms/DXNav/DXNav.vue";
|
|
45
49
|
|
|
46
50
|
const props = defineProps({
|
|
47
51
|
/** Текущая страница (v-model) */
|
|
@@ -100,24 +104,5 @@ const visiblePages = computed(() => {
|
|
|
100
104
|
|
|
101
105
|
return pages;
|
|
102
106
|
});
|
|
103
|
-
|
|
104
|
-
const sizeClasses = {
|
|
105
|
-
sm: "h-7 min-w-7 text-xs",
|
|
106
|
-
md: "h-9 min-w-9 text-sm",
|
|
107
|
-
lg: "h-11 min-w-11 text-base",
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const navButtonClasses = computed(() => [
|
|
111
|
-
"inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 hover:border-slate-300 transition-colors",
|
|
112
|
-
sizeClasses[props.size] || sizeClasses.md,
|
|
113
|
-
]);
|
|
114
|
-
|
|
115
|
-
const pageButtonClasses = computed(() => [
|
|
116
|
-
"inline-flex items-center justify-center rounded-lg font-medium transition-colors",
|
|
117
|
-
sizeClasses[props.size] || sizeClasses.md,
|
|
118
|
-
"text-slate-600 hover:bg-slate-100",
|
|
119
|
-
]);
|
|
120
|
-
|
|
121
|
-
const activeClasses = "bg-slate-900 text-white hover:bg-slate-800";
|
|
122
107
|
</script>
|
|
123
108
|
|
|
@@ -4,7 +4,73 @@ import { ref } from 'vue';
|
|
|
4
4
|
export default {
|
|
5
5
|
title: 'Molecules/DXPasswordInput',
|
|
6
6
|
component: DXPasswordInput,
|
|
7
|
-
tags: ['autodocs'],
|
|
7
|
+
tags: ['autodocs', 'category:form'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXPasswordInput
|
|
13
|
+
|
|
14
|
+
Компонент поля ввода пароля с кнопкой показа/скрытия пароля.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXPasswordInput предоставляет специализированное поле ввода для паролей с автоматическим
|
|
19
|
+
скрытием введенного текста и возможностью показать пароль при необходимости. Компонент
|
|
20
|
+
интегрируется с DXFormLabel для поддержки лейблов, ошибок и вспомогательного текста.
|
|
21
|
+
|
|
22
|
+
## Архитектура
|
|
23
|
+
|
|
24
|
+
### Использует
|
|
25
|
+
- \`DXFormLabel\` - для отображения лейбла, ошибок и вспомогательного текста
|
|
26
|
+
- \`DXIcon\` - для иконок показа/скрытия пароля (EyeIcon, EyeSlashIcon)
|
|
27
|
+
- \`useClassComposition\` composable - для объединения CSS классов
|
|
28
|
+
|
|
29
|
+
### Используется в
|
|
30
|
+
- Формы регистрации и входа
|
|
31
|
+
- Смена пароля
|
|
32
|
+
- Настройки безопасности
|
|
33
|
+
- Любые места, требующие ввода пароля
|
|
34
|
+
|
|
35
|
+
## Внутренняя логика
|
|
36
|
+
|
|
37
|
+
### Переключение видимости
|
|
38
|
+
- По умолчанию пароль скрыт (\`type="password"\`)
|
|
39
|
+
- При клике на иконку пароль показывается (\`type="text"\`)
|
|
40
|
+
- Иконка автоматически меняется: EyeIcon ↔ EyeSlashIcon
|
|
41
|
+
|
|
42
|
+
### Валидация
|
|
43
|
+
- При наличии \`error\` prop, поле получает красную рамку (\`border-rose-300\`)
|
|
44
|
+
- Текст ошибки отображается через \`DXFormLabel\`
|
|
45
|
+
|
|
46
|
+
### Размеры
|
|
47
|
+
Использует фиксированный размер, соответствующий стандартным полям ввода:
|
|
48
|
+
- Высота: \`h-10\` (40px)
|
|
49
|
+
- Padding: \`px-4 py-2.5\`
|
|
50
|
+
- Размер текста: \`text-sm\`
|
|
51
|
+
|
|
52
|
+
## Особенности
|
|
53
|
+
|
|
54
|
+
### v-model
|
|
55
|
+
Полностью поддерживает двустороннее связывание через \`v-model\` для String значений.
|
|
56
|
+
|
|
57
|
+
### Состояния
|
|
58
|
+
- **disabled** - отключает поле и кнопку показа/скрытия
|
|
59
|
+
- **error** - визуально выделяет ошибку (красная рамка)
|
|
60
|
+
- **required** - отмечает поле как обязательное
|
|
61
|
+
|
|
62
|
+
### Лейбл и вспомогательный текст
|
|
63
|
+
- \`label\` - отображается над полем
|
|
64
|
+
- \`helper\` - вспомогательный текст под полем
|
|
65
|
+
- \`error\` - текст ошибки (заменяет helper при наличии)
|
|
66
|
+
|
|
67
|
+
### Доступность
|
|
68
|
+
- Кнопка показа/скрытия имеет \`aria-label\` для описания действия
|
|
69
|
+
- Поддержка клавиатурной навигации
|
|
70
|
+
`,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
8
74
|
};
|
|
9
75
|
|
|
10
76
|
export const Default = {
|