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
|
@@ -1,11 +1,103 @@
|
|
|
1
1
|
import DXAlert from './DXAlert.vue';
|
|
2
|
+
import DXButton from '../../atoms/DXButton/DXButton.vue';
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
title: 'Molecules/DXAlert',
|
|
5
6
|
component: DXAlert,
|
|
6
|
-
tags: ['autodocs'],
|
|
7
|
+
tags: ['autodocs', 'category:feedback'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXAlert
|
|
13
|
+
|
|
14
|
+
Компонент уведомления с поддержкой различных вариантов, иконок, возможности закрытия и действий.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXAlert предоставляет стандартизированный способ отображения уведомлений, предупреждений и сообщений
|
|
19
|
+
пользователю. Компонент поддерживает различные семантические варианты (info, success, warning, danger),
|
|
20
|
+
иконки, возможность закрытия и слот для кнопок действий.
|
|
21
|
+
|
|
22
|
+
## Архитектура
|
|
23
|
+
|
|
24
|
+
### Использует
|
|
25
|
+
- \`DX\` - базовый polymorphic компонент
|
|
26
|
+
- \`DXIcon\` - иконка уведомления
|
|
27
|
+
- \`DXText\` - текст заголовка
|
|
28
|
+
- \`DXBox\` - контейнеры для контента
|
|
29
|
+
- \`DXFlex\` - layout для элементов
|
|
30
|
+
- \`DXCloseButton\` - кнопка закрытия
|
|
31
|
+
|
|
32
|
+
### Используется в
|
|
33
|
+
- Уведомления об успешных операциях
|
|
34
|
+
- Предупреждения перед действиями
|
|
35
|
+
- Сообщения об ошибках
|
|
36
|
+
- Информационные сообщения
|
|
37
|
+
- Любые места, требующие обратной связи с пользователем
|
|
38
|
+
|
|
39
|
+
## Внутренняя логика
|
|
40
|
+
|
|
41
|
+
### Варианты
|
|
42
|
+
- **info** (по умолчанию): Информационное сообщение (синий цвет)
|
|
43
|
+
- **success**: Успешная операция (зеленый цвет)
|
|
44
|
+
- **warning**: Предупреждение (желтый цвет)
|
|
45
|
+
- **danger**: Ошибка или критическое сообщение (красный цвет)
|
|
46
|
+
|
|
47
|
+
### Иконки
|
|
48
|
+
- По умолчанию для каждого варианта используется соответствующая иконка:
|
|
49
|
+
- info → InformationCircleIcon
|
|
50
|
+
- success → CheckCircleIcon
|
|
51
|
+
- warning → ExclamationTriangleIcon
|
|
52
|
+
- danger → XCircleIcon
|
|
53
|
+
- Можно переопределить через \`icon\` prop
|
|
54
|
+
- Можно скрыть через \`showIcon={false}\`
|
|
55
|
+
|
|
56
|
+
### Закрытие
|
|
57
|
+
- При \`dismissible={true}\` отображается кнопка закрытия справа
|
|
58
|
+
- При закрытии компонент скрывается (управляется внутренним состоянием)
|
|
59
|
+
- Событие \`dismiss\` при закрытии
|
|
60
|
+
|
|
61
|
+
### Действия
|
|
62
|
+
- Слот \`actions\` для размещения кнопок действий
|
|
63
|
+
- Выравнивание действий через \`actionsAlign\`: \`left\` (по умолчанию), \`center\`, \`right\`
|
|
64
|
+
|
|
65
|
+
## Особенности
|
|
66
|
+
|
|
67
|
+
### Структура
|
|
68
|
+
Алерт состоит из:
|
|
69
|
+
1. **Иконка** (слева) - визуальный индикатор типа сообщения
|
|
70
|
+
2. **Заголовок** (опционально) - через \`title\` prop
|
|
71
|
+
3. **Контент** - основной текст через default slot
|
|
72
|
+
4. **Кнопка закрытия** (справа, опционально) - при \`dismissible={true}\`
|
|
73
|
+
5. **Действия** (внизу, опционально) - через слот \`actions\`
|
|
74
|
+
|
|
75
|
+
### Цветовая схема
|
|
76
|
+
Каждый вариант имеет свою цветовую схему:
|
|
77
|
+
- Фон: светлый оттенок цвета варианта (например, bg-blue-50)
|
|
78
|
+
- Рамка: средний оттенок (например, border-blue-200)
|
|
79
|
+
- Иконка: основной цвет (например, text-blue-500)
|
|
80
|
+
- Заголовок: темный оттенок (например, text-blue-900)
|
|
81
|
+
- Контент: средний оттенок (например, text-blue-800)
|
|
82
|
+
|
|
83
|
+
### Доступность
|
|
84
|
+
- Использует \`role="alert"\` для семантики
|
|
85
|
+
- Автоматически скрывается при закрытии
|
|
86
|
+
- Поддержка клавиатурной навигации
|
|
87
|
+
|
|
88
|
+
### Использование
|
|
89
|
+
Алерты обычно используются для:
|
|
90
|
+
- Временных уведомлений (успех, ошибка)
|
|
91
|
+
- Предупреждений перед действиями
|
|
92
|
+
- Информационных сообщений
|
|
93
|
+
- Сообщений о состоянии системы
|
|
94
|
+
`,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
7
98
|
argTypes: {
|
|
8
99
|
variant: { control: { type: 'select' }, options: ['info', 'success', 'warning', 'danger'] },
|
|
100
|
+
actionsAlign: { control: { type: 'select' }, options: ['left', 'center', 'right'] },
|
|
9
101
|
},
|
|
10
102
|
};
|
|
11
103
|
|
|
@@ -68,3 +160,109 @@ export const AllVariants = {
|
|
|
68
160
|
}),
|
|
69
161
|
};
|
|
70
162
|
|
|
163
|
+
export const WithActions = {
|
|
164
|
+
parameters: {
|
|
165
|
+
docs: {
|
|
166
|
+
description: {
|
|
167
|
+
story: 'Пример использования слота `actions` для добавления кнопок действий в alert.',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
render: () => ({
|
|
172
|
+
components: { DXAlert, DXButton },
|
|
173
|
+
setup() {
|
|
174
|
+
const handleConfirm = () => alert('Подтверждено!');
|
|
175
|
+
const handleCancel = () => alert('Отменено');
|
|
176
|
+
const handleRetry = () => alert('Повторная попытка...');
|
|
177
|
+
const handleUpdate = () => alert('Обновление...');
|
|
178
|
+
const handleLater = () => alert('Отложено');
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
handleConfirm,
|
|
182
|
+
handleCancel,
|
|
183
|
+
handleRetry,
|
|
184
|
+
handleUpdate,
|
|
185
|
+
handleLater,
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
template: `
|
|
189
|
+
<div class="space-y-4">
|
|
190
|
+
<DXAlert variant="warning" title="Подтвердите действие">
|
|
191
|
+
Вы уверены, что хотите удалить этот элемент? Это действие нельзя отменить.
|
|
192
|
+
<template #actions>
|
|
193
|
+
<DXButton variant="outline" size="sm" @click="handleCancel">Отменить</DXButton>
|
|
194
|
+
<DXButton variant="danger" size="sm" @click="handleConfirm">Удалить</DXButton>
|
|
195
|
+
</template>
|
|
196
|
+
</DXAlert>
|
|
197
|
+
|
|
198
|
+
<DXAlert variant="danger" title="Ошибка загрузки">
|
|
199
|
+
Не удалось загрузить данные. Пожалуйста, попробуйте еще раз.
|
|
200
|
+
<template #actions>
|
|
201
|
+
<DXButton variant="primary" size="sm" @click="handleRetry">Повторить</DXButton>
|
|
202
|
+
</template>
|
|
203
|
+
</DXAlert>
|
|
204
|
+
|
|
205
|
+
<DXAlert variant="info" title="Доступно обновление">
|
|
206
|
+
Доступна новая версия приложения. Рекомендуем обновить для получения новых функций и исправлений.
|
|
207
|
+
<template #actions>
|
|
208
|
+
<DXButton variant="primary" size="sm" @click="handleUpdate">Обновить</DXButton>
|
|
209
|
+
<DXButton variant="ghost" size="sm" @click="handleLater">Позже</DXButton>
|
|
210
|
+
</template>
|
|
211
|
+
</DXAlert>
|
|
212
|
+
|
|
213
|
+
<DXAlert variant="success" title="Изменения сохранены" dismissible>
|
|
214
|
+
Все ваши изменения были успешно сохранены.
|
|
215
|
+
<template #actions>
|
|
216
|
+
<DXButton variant="outline" size="sm" @click="handleCancel">Закрыть</DXButton>
|
|
217
|
+
</template>
|
|
218
|
+
</DXAlert>
|
|
219
|
+
</div>
|
|
220
|
+
`,
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export const ActionsAlignment = {
|
|
225
|
+
parameters: {
|
|
226
|
+
docs: {
|
|
227
|
+
description: {
|
|
228
|
+
story: 'Различные варианты выравнивания кнопок действий через проп `actionsAlign`.',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
render: () => ({
|
|
233
|
+
components: { DXAlert, DXButton },
|
|
234
|
+
setup() {
|
|
235
|
+
const handleAction = () => alert('Действие выполнено!');
|
|
236
|
+
|
|
237
|
+
return { handleAction };
|
|
238
|
+
},
|
|
239
|
+
template: `
|
|
240
|
+
<div class="space-y-4">
|
|
241
|
+
<DXAlert variant="info" title="Выравнивание слева (по умолчанию)" actions-align="left">
|
|
242
|
+
Кнопки действий выровнены по левому краю.
|
|
243
|
+
<template #actions>
|
|
244
|
+
<DXButton variant="outline" size="sm" @click="handleAction">Отмена</DXButton>
|
|
245
|
+
<DXButton variant="primary" size="sm" @click="handleAction">Применить</DXButton>
|
|
246
|
+
</template>
|
|
247
|
+
</DXAlert>
|
|
248
|
+
|
|
249
|
+
<DXAlert variant="info" title="Выравнивание по центру" actions-align="center">
|
|
250
|
+
Кнопки действий выровнены по центру.
|
|
251
|
+
<template #actions>
|
|
252
|
+
<DXButton variant="outline" size="sm" @click="handleAction">Отмена</DXButton>
|
|
253
|
+
<DXButton variant="primary" size="sm" @click="handleAction">Применить</DXButton>
|
|
254
|
+
</template>
|
|
255
|
+
</DXAlert>
|
|
256
|
+
|
|
257
|
+
<DXAlert variant="info" title="Выравнивание справа" actions-align="right">
|
|
258
|
+
Кнопки действий выровнены по правому краю.
|
|
259
|
+
<template #actions>
|
|
260
|
+
<DXButton variant="outline" size="sm" @click="handleAction">Отмена</DXButton>
|
|
261
|
+
<DXButton variant="primary" size="sm" @click="handleAction">Применить</DXButton>
|
|
262
|
+
</template>
|
|
263
|
+
</DXAlert>
|
|
264
|
+
</div>
|
|
265
|
+
`,
|
|
266
|
+
}),
|
|
267
|
+
};
|
|
268
|
+
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<DX
|
|
3
3
|
v-if="!dismissed"
|
|
4
4
|
:class="alertClasses"
|
|
5
5
|
role="alert"
|
|
6
6
|
data-component="DXAlert"
|
|
7
7
|
:data-variant="variant"
|
|
8
8
|
>
|
|
9
|
-
<
|
|
9
|
+
<DXFlex align="start" class="gap-3">
|
|
10
10
|
<DXIcon v-if="iconToShow" :icon="iconToShow" size="md" animation="none" :class="iconClasses" />
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
11
|
+
<DXBox class="flex-1 min-w-0">
|
|
12
|
+
<DXText v-if="title" tag="p" weight="semibold" :color="alertTitleColor">{{ title }}</DXText>
|
|
13
|
+
<DXBox :class="contentClasses">
|
|
14
14
|
<slot />
|
|
15
|
-
</
|
|
16
|
-
</
|
|
15
|
+
</DXBox>
|
|
16
|
+
</DXBox>
|
|
17
17
|
<DXCloseButton
|
|
18
18
|
v-if="dismissible"
|
|
19
19
|
size="sm"
|
|
20
20
|
variant="default"
|
|
21
21
|
@click="dismiss"
|
|
22
22
|
/>
|
|
23
|
-
</
|
|
24
|
-
<
|
|
23
|
+
</DXFlex>
|
|
24
|
+
<DXFlex v-if="$slots.actions" class="mt-3" gap="sm" :justify="actionsJustify">
|
|
25
25
|
<slot name="actions" />
|
|
26
|
-
</
|
|
27
|
-
</
|
|
26
|
+
</DXFlex>
|
|
27
|
+
</DX>
|
|
28
28
|
</template>
|
|
29
29
|
|
|
30
30
|
<script setup>
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
ExclamationTriangleIcon,
|
|
36
36
|
XCircleIcon,
|
|
37
37
|
} from "@heroicons/vue/24/solid";
|
|
38
|
-
import DXIcon from "../../atoms
|
|
38
|
+
import { DX, DXIcon, DXText, DXBox, DXFlex } from "../../atoms";
|
|
39
39
|
import DXCloseButton from "../DXCloseButton/DXCloseButton.vue";
|
|
40
40
|
|
|
41
41
|
const props = defineProps({
|
|
@@ -49,6 +49,8 @@ const props = defineProps({
|
|
|
49
49
|
showIcon: { type: Boolean, default: true },
|
|
50
50
|
/** Можно закрыть */
|
|
51
51
|
dismissible: { type: Boolean, default: false },
|
|
52
|
+
/** Выравнивание кнопок действий: left | center | right */
|
|
53
|
+
actionsAlign: { type: String, default: "left" },
|
|
52
54
|
});
|
|
53
55
|
|
|
54
56
|
const emit = defineEmits(["dismiss"]);
|
|
@@ -109,8 +111,28 @@ const alertClasses = computed(() => [
|
|
|
109
111
|
]);
|
|
110
112
|
|
|
111
113
|
const iconClasses = computed(() => ["w-5 h-5 flex-shrink-0 mt-0.5", styles.value.icon]);
|
|
112
|
-
const
|
|
114
|
+
const alertTitleColor = computed(() => {
|
|
115
|
+
const colorMap = {
|
|
116
|
+
info: 'primary',
|
|
117
|
+
success: 'success',
|
|
118
|
+
warning: 'warning',
|
|
119
|
+
danger: 'danger',
|
|
120
|
+
};
|
|
121
|
+
return colorMap[props.variant] || 'primary';
|
|
122
|
+
});
|
|
113
123
|
const contentClasses = computed(() => ["text-sm", styles.value.content, props.title && "mt-1"]);
|
|
114
124
|
const closeClasses = computed(() => styles.value.close);
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Маппинг actionsAlign prop в justify prop для DXFlex
|
|
128
|
+
*/
|
|
129
|
+
const actionsJustify = computed(() => {
|
|
130
|
+
const alignMap = {
|
|
131
|
+
left: "start",
|
|
132
|
+
center: "center",
|
|
133
|
+
right: "end",
|
|
134
|
+
};
|
|
135
|
+
return alignMap[props.actionsAlign] || "start";
|
|
136
|
+
});
|
|
115
137
|
</script>
|
|
116
138
|
|
|
@@ -17,10 +17,91 @@ import {
|
|
|
17
17
|
export default {
|
|
18
18
|
title: 'Molecules/DXBreadcrumb',
|
|
19
19
|
component: DXBreadcrumb,
|
|
20
|
-
tags: ['autodocs'],
|
|
20
|
+
tags: ['autodocs', 'category:navigation'],
|
|
21
|
+
parameters: {
|
|
22
|
+
docs: {
|
|
23
|
+
description: {
|
|
24
|
+
component: `
|
|
25
|
+
# DXBreadcrumb
|
|
26
|
+
|
|
27
|
+
Навигационные хлебные крошки для отображения иерархии страниц и навигации.
|
|
28
|
+
|
|
29
|
+
## Назначение
|
|
30
|
+
|
|
31
|
+
DXBreadcrumb предоставляет стандартизированный способ отображения пути навигации
|
|
32
|
+
в приложении. Компонент автоматически обрабатывает стилизацию, разделители и
|
|
33
|
+
состояние текущей страницы.
|
|
34
|
+
|
|
35
|
+
## Архитектура
|
|
36
|
+
|
|
37
|
+
### Использует
|
|
38
|
+
- \`DXLink\` - все элементы breadcrumb являются ссылками (DXLink компонентами)
|
|
39
|
+
- \`DXIcon\` - для иконок элементов и разделителей
|
|
40
|
+
- \`ChevronRightIcon\` - иконка разделителя по умолчанию
|
|
41
|
+
|
|
42
|
+
### Используется в
|
|
43
|
+
- Навигация в приложениях
|
|
44
|
+
- Файловые системы
|
|
45
|
+
- E-commerce категории
|
|
46
|
+
- Административные панели
|
|
47
|
+
- Многоуровневая навигация
|
|
48
|
+
|
|
49
|
+
## Внутренняя логика
|
|
50
|
+
|
|
51
|
+
### Все элементы - DXLink
|
|
52
|
+
Все элементы breadcrumb рендерятся как \`DXLink\` компоненты, что обеспечивает:
|
|
53
|
+
- Единообразие стилей
|
|
54
|
+
- Правильную семантику
|
|
55
|
+
- Поддержку всех возможностей DXLink (router-link, href, варианты)
|
|
56
|
+
|
|
57
|
+
### Автоматическое неактивное состояние
|
|
58
|
+
Последний элемент (конечная точка) автоматически получает \`inactive={true}\`:
|
|
59
|
+
- Визуально приглушенный вид
|
|
60
|
+
- Остается кликабельным (если указан href/to)
|
|
61
|
+
- Правильная семантика с \`aria-current="page"\`
|
|
62
|
+
|
|
63
|
+
### Варианты стилизации
|
|
64
|
+
Через prop \`variant\` можно выбрать стиль ссылок:
|
|
65
|
+
- \`link\` (по умолчанию) - обычные текстовые ссылки
|
|
66
|
+
- \`primary\`, \`secondary\`, \`ghost\`, \`outline\` - варианты с padding и border-radius
|
|
67
|
+
|
|
68
|
+
### Разделители
|
|
69
|
+
Поддерживает два типа разделителей:
|
|
70
|
+
- \`chevron\` (по умолчанию) - иконка ChevronRightIcon
|
|
71
|
+
- \`slash\` - текстовый разделитель "/"
|
|
72
|
+
|
|
73
|
+
### Анимация иконок
|
|
74
|
+
Поддерживает анимацию иконок элементов:
|
|
75
|
+
- Глобальная анимация для всех иконок
|
|
76
|
+
- Анимация только для текущей страницы (\`animateCurrentOnly={true}\`)
|
|
77
|
+
- Индивидуальная анимация для каждого элемента
|
|
78
|
+
|
|
79
|
+
## Особенности
|
|
80
|
+
|
|
81
|
+
### Структура данных
|
|
82
|
+
Элементы передаются через prop \`items\`:
|
|
83
|
+
\`\`\`js
|
|
84
|
+
[
|
|
85
|
+
{ label: 'Home', href: '/' },
|
|
86
|
+
{ label: 'Products', to: '/products' },
|
|
87
|
+
{ label: 'Current Page' } // Без href/to - будет неактивной ссылкой
|
|
88
|
+
]
|
|
89
|
+
\`\`\`
|
|
90
|
+
|
|
91
|
+
### Размеры
|
|
92
|
+
Поддерживает три размера: \`sm\`, \`md\` (по умолчанию), \`lg\`.
|
|
93
|
+
Размер влияет на размер текста и иконок.
|
|
94
|
+
|
|
95
|
+
### Кастомизация разделителей
|
|
96
|
+
Можно кастомизировать разделители через slot \`separator\`.
|
|
97
|
+
`,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
21
101
|
argTypes: {
|
|
22
102
|
separator: { control: { type: 'select' }, options: ['slash', 'chevron'] },
|
|
23
103
|
size: { control: { type: 'select' }, options: ['sm', 'md', 'lg'] },
|
|
104
|
+
variant: { control: { type: 'select' }, options: ['link', 'primary', 'secondary', 'ghost', 'outline'] },
|
|
24
105
|
iconAnimation: { control: { type: 'select' }, options: ['none', 'wiggle', 'scale', 'rotate'] },
|
|
25
106
|
},
|
|
26
107
|
};
|
|
@@ -170,6 +251,49 @@ export const Sizes = {
|
|
|
170
251
|
}),
|
|
171
252
|
};
|
|
172
253
|
|
|
254
|
+
export const LinkVariants = {
|
|
255
|
+
render: () => ({
|
|
256
|
+
components: { DXBreadcrumb },
|
|
257
|
+
setup() {
|
|
258
|
+
const items = [
|
|
259
|
+
{ label: 'Home', href: '/' },
|
|
260
|
+
{ label: 'Products', href: '/products' },
|
|
261
|
+
{ label: 'Current' },
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
return { items };
|
|
265
|
+
},
|
|
266
|
+
template: `
|
|
267
|
+
<div class="space-y-6">
|
|
268
|
+
<div>
|
|
269
|
+
<h3 class="text-sm font-semibold text-slate-900 mb-3">Link (default)</h3>
|
|
270
|
+
<DXBreadcrumb :items="items" variant="link" />
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<div>
|
|
274
|
+
<h3 class="text-sm font-semibold text-slate-900 mb-3">Ghost</h3>
|
|
275
|
+
<DXBreadcrumb :items="items" variant="ghost" />
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<div>
|
|
279
|
+
<h3 class="text-sm font-semibold text-slate-900 mb-3">Outline</h3>
|
|
280
|
+
<DXBreadcrumb :items="items" variant="outline" />
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<div>
|
|
284
|
+
<h3 class="text-sm font-semibold text-slate-900 mb-3">Primary</h3>
|
|
285
|
+
<DXBreadcrumb :items="items" variant="primary" />
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<div>
|
|
289
|
+
<h3 class="text-sm font-semibold text-slate-900 mb-3">Secondary</h3>
|
|
290
|
+
<DXBreadcrumb :items="items" variant="secondary" />
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
`,
|
|
294
|
+
}),
|
|
295
|
+
};
|
|
296
|
+
|
|
173
297
|
export const AllVariants = {
|
|
174
298
|
render: () => ({
|
|
175
299
|
components: { DXBreadcrumb },
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<DXNav type="breadcrumb" data-component="DXBreadcrumb">
|
|
3
3
|
<ol class="flex items-center flex-wrap" :class="sizeClasses">
|
|
4
4
|
<li v-for="(item, index) in items" :key="index" class="flex items-center">
|
|
5
5
|
<!-- Separator -->
|
|
6
|
-
<span v-if="index > 0" class="mx-
|
|
6
|
+
<span v-if="index > 0" class="mx-1 text-slate-400" aria-hidden="true">
|
|
7
7
|
<slot name="separator">
|
|
8
8
|
<DXIcon
|
|
9
9
|
v-if="separator === 'chevron'"
|
|
@@ -16,14 +16,12 @@
|
|
|
16
16
|
</span>
|
|
17
17
|
|
|
18
18
|
<!-- Item -->
|
|
19
|
-
<
|
|
20
|
-
:is="getLinkComponent(item)"
|
|
19
|
+
<DXLink
|
|
21
20
|
:href="item.href"
|
|
22
21
|
:to="item.to"
|
|
23
|
-
:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
]"
|
|
22
|
+
:size="linkSize"
|
|
23
|
+
:variant="variant"
|
|
24
|
+
:inactive="index === items.length - 1"
|
|
27
25
|
:aria-current="index === items.length - 1 ? 'page' : undefined"
|
|
28
26
|
>
|
|
29
27
|
<DXIcon
|
|
@@ -31,18 +29,20 @@
|
|
|
31
29
|
:icon="item.icon"
|
|
32
30
|
:size="iconSize"
|
|
33
31
|
:animation="getIconAnimation(item, index)"
|
|
34
|
-
|
|
32
|
+
|
|
35
33
|
/>
|
|
36
34
|
{{ item.label }}
|
|
37
|
-
</
|
|
35
|
+
</DXLink>
|
|
38
36
|
</li>
|
|
39
37
|
</ol>
|
|
40
|
-
</
|
|
38
|
+
</DXNav>
|
|
41
39
|
</template>
|
|
42
40
|
|
|
43
41
|
<script setup>
|
|
44
42
|
import { computed } from "vue";
|
|
45
43
|
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
44
|
+
import DXLink from "../../atoms/DXLink/DXLink.vue";
|
|
45
|
+
import DXNav from "../../atoms/DXNav/DXNav.vue";
|
|
46
46
|
import { ChevronRightIcon } from "@heroicons/vue/24/outline";
|
|
47
47
|
|
|
48
48
|
const props = defineProps({
|
|
@@ -52,6 +52,8 @@ const props = defineProps({
|
|
|
52
52
|
separator: { type: String, default: "chevron" },
|
|
53
53
|
/** Размер: sm | md | lg */
|
|
54
54
|
size: { type: String, default: "md" },
|
|
55
|
+
/** Вариант стилизации ссылок: link | primary | secondary | ghost | outline */
|
|
56
|
+
variant: { type: String, default: "ghost" },
|
|
55
57
|
/** Анимация иконок: none | wiggle | scale | rotate */
|
|
56
58
|
iconAnimation: { type: String, default: "none" },
|
|
57
59
|
/** Анимировать только иконку текущей страницы */
|
|
@@ -72,13 +74,15 @@ const iconSize = computed(() => {
|
|
|
72
74
|
return "xs";
|
|
73
75
|
});
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
77
|
+
// Маппинг размера breadcrumb на размер DXLink
|
|
78
|
+
const linkSize = computed(() => {
|
|
79
|
+
const sizeMap = {
|
|
80
|
+
sm: "xs",
|
|
81
|
+
md: "sm",
|
|
82
|
+
lg: "md",
|
|
83
|
+
};
|
|
84
|
+
return sizeMap[props.size] || "sm";
|
|
85
|
+
});
|
|
82
86
|
|
|
83
87
|
const getIconAnimation = (item, index) => {
|
|
84
88
|
// Если у элемента своя анимация
|