dxd-style-code 0.1.10 → 0.1.12
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 +9785 -8652
- 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 +99 -0
- package/src/components/{layout → atoms}/DXBox/DXBox.stories.js +2 -2
- package/src/components/{layout → 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 +95 -0
- package/src/components/{layout → atoms}/DXContainer/DXContainer.stories.js +2 -2
- package/src/components/{layout → atoms}/DXContainer/DXContainer.vue +28 -1
- package/src/components/atoms/DXDivider/DXDivider.stories.js +84 -1
- package/src/components/{layout → atoms}/DXFlex/DXFlex.stories.js +2 -2
- package/src/components/{layout → atoms}/DXFlex/DXFlex.vue +57 -3
- package/src/components/atoms/DXFormLabel/DXFormLabel.stories.js +70 -1
- package/src/components/{layout → atoms}/DXGrid/DXGrid.stories.js +2 -2
- package/src/components/atoms/DXHeading/DXHeading.stories.js +143 -0
- 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 +101 -0
- 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 +125 -0
- 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/{layout → atoms}/DXSpacer/DXSpacer.stories.js +2 -2
- package/src/components/{layout → atoms}/DXStack/DXStack.stories.js +2 -2
- package/src/components/{layout → atoms}/DXStack/DXStack.vue +5 -2
- package/src/components/atoms/DXTags/DXTags.stories.js +77 -0
- package/src/components/atoms/DXText/DXText.stories.js +129 -0
- 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 +16 -1
- package/src/components/index.js +1 -7
- 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 +2 -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 +28 -26
- 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 +262 -53
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.stories.js +1 -1
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.vue +7 -5
- 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 +2 -2
- 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/index.js +1 -7
- package/src/components/layout/index.js +0 -8
- package/src/components/typography/DXBlockquote/DXBlockquote.stories.js +0 -33
- package/src/components/typography/DXCode/DXCode.stories.js +0 -29
- package/src/components/typography/DXHeading/DXHeading.stories.js +0 -54
- package/src/components/typography/DXLabel/DXLabel.stories.js +0 -40
- package/src/components/typography/DXList/DXList.stories.js +0 -50
- package/src/components/typography/DXText/DXText.stories.js +0 -47
- package/src/components/typography/index.js +0 -8
- /package/src/components/{typography → atoms}/DXBlockquote/DXBlockquote.vue +0 -0
- /package/src/components/{typography → atoms}/DXBlockquote/index.js +0 -0
- /package/src/components/{layout → atoms}/DXBox/index.js +0 -0
- /package/src/components/{typography → atoms}/DXCode/DXCode.vue +0 -0
- /package/src/components/{typography → atoms}/DXCode/index.js +0 -0
- /package/src/components/{layout → atoms}/DXContainer/index.js +0 -0
- /package/src/components/{layout → atoms}/DXFlex/index.js +0 -0
- /package/src/components/{layout → atoms}/DXGrid/DXGrid.vue +0 -0
- /package/src/components/{layout → atoms}/DXGrid/index.js +0 -0
- /package/src/components/{typography → atoms}/DXHeading/DXHeading.vue +0 -0
- /package/src/components/{typography → atoms}/DXHeading/index.js +0 -0
- /package/src/components/{typography → atoms}/DXLabel/DXLabel.vue +0 -0
- /package/src/components/{typography → atoms}/DXLabel/index.js +0 -0
- /package/src/components/{typography → atoms}/DXList/DXList.vue +0 -0
- /package/src/components/{typography → atoms}/DXList/index.js +0 -0
- /package/src/components/{layout → atoms}/DXSpacer/DXSpacer.vue +0 -0
- /package/src/components/{layout → atoms}/DXSpacer/index.js +0 -0
- /package/src/components/{layout → atoms}/DXStack/index.js +0 -0
- /package/src/components/{typography → atoms}/DXText/DXText.vue +0 -0
- /package/src/components/{typography → atoms}/DXText/index.js +0 -0
- /package/src/components/{molecules → organisms}/DXBaseTable/index.js +0 -0
|
@@ -3,28 +3,30 @@
|
|
|
3
3
|
<p v-if="label" class="text-[11px] uppercase tracking-wide text-slate-500 font-semibold">
|
|
4
4
|
{{ label }}
|
|
5
5
|
</p>
|
|
6
|
-
<div class="
|
|
7
|
-
<p
|
|
6
|
+
<div :class="containerClasses">
|
|
7
|
+
<p
|
|
8
|
+
class="font-semibold text-slate-900 break-all flex-1 text-center"
|
|
9
|
+
:class="textSize"
|
|
10
|
+
>
|
|
8
11
|
{{ value || "—" }}
|
|
9
12
|
</p>
|
|
10
13
|
<button
|
|
11
14
|
type="button"
|
|
12
|
-
class="
|
|
13
|
-
:class="{ 'border-emerald-300 bg-emerald-50': copied }"
|
|
15
|
+
:class="buttonClasses"
|
|
14
16
|
:aria-label="`Скопировать ${label || 'значение'}`"
|
|
15
17
|
@click="copyToClipboard"
|
|
16
18
|
>
|
|
17
19
|
<DXIcon
|
|
18
20
|
v-if="copied"
|
|
19
21
|
:icon="CheckIcon"
|
|
20
|
-
size="
|
|
22
|
+
:size="iconSize"
|
|
21
23
|
:animation="copiedIconAnimation"
|
|
22
24
|
class="text-emerald-600"
|
|
23
25
|
/>
|
|
24
26
|
<DXIcon
|
|
25
27
|
v-else
|
|
26
28
|
:icon="copyIcon"
|
|
27
|
-
size="
|
|
29
|
+
:size="iconSize"
|
|
28
30
|
:animation="copyIconAnimation"
|
|
29
31
|
/>
|
|
30
32
|
</button>
|
|
@@ -33,7 +35,9 @@
|
|
|
33
35
|
</template>
|
|
34
36
|
|
|
35
37
|
<script setup>
|
|
36
|
-
import { ref } from "vue";
|
|
38
|
+
import { ref, computed } from "vue";
|
|
39
|
+
import { useSize } from "../../../composables/useSize";
|
|
40
|
+
import { useClassComposition } from "../../../composables/useClassComposition";
|
|
37
41
|
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
38
42
|
import { ClipboardDocumentIcon, ClipboardDocumentCheckIcon, CheckIcon } from "@heroicons/vue/24/outline";
|
|
39
43
|
|
|
@@ -42,6 +46,12 @@ const props = defineProps({
|
|
|
42
46
|
label: { type: String, default: "" },
|
|
43
47
|
/** Значение для копирования */
|
|
44
48
|
value: { type: String, default: "" },
|
|
49
|
+
/** Размер: sm | md | lg */
|
|
50
|
+
size: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: "md",
|
|
53
|
+
validator: (value) => ["sm", "md", "lg"].includes(value),
|
|
54
|
+
},
|
|
45
55
|
/** Иконка для копирования */
|
|
46
56
|
copyIcon: { type: [Object, Function], default: () => ClipboardDocumentIcon },
|
|
47
57
|
/** Иконка успешного копирования */
|
|
@@ -58,6 +68,49 @@ const emit = defineEmits(["copied"]);
|
|
|
58
68
|
|
|
59
69
|
const copied = ref(false);
|
|
60
70
|
|
|
71
|
+
// Базовые классы контейнера
|
|
72
|
+
const BASE_CONTAINER_CLASSES = "flex items-center justify-between gap-2 rounded-xl border border-slate-200 bg-white";
|
|
73
|
+
|
|
74
|
+
// Извлекаем padding из useSize для контейнера (без высоты)
|
|
75
|
+
const containerClasses = computed(() => {
|
|
76
|
+
const fullSizeClass = useSize(props.size, 'input');
|
|
77
|
+
// Извлекаем только padding классы (px-* и py-*), убираем высоту и размер текста
|
|
78
|
+
const paddingClasses = fullSizeClass
|
|
79
|
+
.split(' ')
|
|
80
|
+
.filter(c => c.startsWith('px-') || c.startsWith('py-'))
|
|
81
|
+
.join(' ');
|
|
82
|
+
|
|
83
|
+
return useClassComposition(BASE_CONTAINER_CLASSES, paddingClasses);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Размер текста из useSize
|
|
87
|
+
const textSize = computed(() => useSize(props.size, 'text'));
|
|
88
|
+
|
|
89
|
+
// Базовые классы кнопки
|
|
90
|
+
const BASE_BUTTON_CLASSES = "inline-flex items-center justify-center rounded-xl border border-slate-200 text-slate-700 hover:border-slate-300 bg-white transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2";
|
|
91
|
+
|
|
92
|
+
// Размер кнопки из useSize (только высота и ширина, без padding и text)
|
|
93
|
+
const buttonClasses = computed(() => {
|
|
94
|
+
const fullSizeClass = useSize(props.size, 'buttonIcon');
|
|
95
|
+
// Извлекаем только размеры (h-* и w-*), убираем padding и text
|
|
96
|
+
const sizeClasses = fullSizeClass
|
|
97
|
+
.split(' ')
|
|
98
|
+
.filter(c => c.startsWith('h-') || c.startsWith('w-'))
|
|
99
|
+
.join(' ');
|
|
100
|
+
|
|
101
|
+
return useClassComposition(
|
|
102
|
+
BASE_BUTTON_CLASSES,
|
|
103
|
+
sizeClasses,
|
|
104
|
+
{ 'border-emerald-300 bg-emerald-50': copied.value }
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Размер иконки (маппинг размера компонента на размер иконки)
|
|
109
|
+
const iconSize = computed(() => {
|
|
110
|
+
const sizeMap = { sm: 'xs', md: 'sm', lg: 'md' };
|
|
111
|
+
return sizeMap[props.size] || 'sm';
|
|
112
|
+
});
|
|
113
|
+
|
|
61
114
|
const copyToClipboard = async () => {
|
|
62
115
|
if (!props.value) return;
|
|
63
116
|
try {
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
<!-- Заголовок -->
|
|
8
8
|
<div v-if="title || $slots.header" :class="headerClasses">
|
|
9
9
|
<slot name="header">
|
|
10
|
-
<
|
|
10
|
+
<DXHeading v-if="title" level="3" size="lg" weight="semibold" color="default">
|
|
11
11
|
{{ title }}
|
|
12
|
-
</
|
|
12
|
+
</DXHeading>
|
|
13
13
|
</slot>
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
|
|
53
53
|
<!-- Определение фильтра -->
|
|
54
54
|
<div class="flex-1">
|
|
55
|
-
<label
|
|
55
|
+
<DXText tag="label" size="sm" weight="medium" color="default" class="block mb-1">
|
|
56
56
|
{{ filter.label || filterDefinitions[filter.id]?.label }}
|
|
57
|
-
</
|
|
57
|
+
</DXText>
|
|
58
58
|
|
|
59
59
|
<!-- Текстовый фильтр -->
|
|
60
60
|
<DXInput
|
|
@@ -104,9 +104,9 @@
|
|
|
104
104
|
:filter="filter"
|
|
105
105
|
:filter-definition="filterDefinitions[filter.id]"
|
|
106
106
|
>
|
|
107
|
-
<p
|
|
107
|
+
<DXText tag="p" size="sm" color="muted">
|
|
108
108
|
Используйте slot filter-{{ filter.type }} для кастомного фильтра
|
|
109
|
-
</
|
|
109
|
+
</DXText>
|
|
110
110
|
</slot>
|
|
111
111
|
</div>
|
|
112
112
|
</div>
|
|
@@ -133,6 +133,8 @@ import DXSelect from "../DXSelect/DXSelect.vue";
|
|
|
133
133
|
import DXDatePicker from "../DXDatePicker/DXDatePicker.vue";
|
|
134
134
|
import DXButton from "../../atoms/DXButton/DXButton.vue";
|
|
135
135
|
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
136
|
+
import DXHeading from "../../atoms/DXHeading/DXHeading.vue";
|
|
137
|
+
import DXText from "../../atoms/DXText/DXText.vue";
|
|
136
138
|
import { XMarkIcon } from "@heroicons/vue/24/outline";
|
|
137
139
|
|
|
138
140
|
const props = defineProps({
|
|
@@ -5,6 +5,64 @@ export default {
|
|
|
5
5
|
title: 'Molecules/DXDatePicker',
|
|
6
6
|
component: DXDatePicker,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXDatePicker
|
|
13
|
+
|
|
14
|
+
Компонент выбора даты с поддержкой одиночной даты и диапазона дат.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXDatePicker предоставляет стандартизированный способ выбора даты или диапазона дат.
|
|
19
|
+
Компонент использует нативный input type="date" для одиночной даты и кастомный интерфейс
|
|
20
|
+
для выбора диапазона.
|
|
21
|
+
|
|
22
|
+
## Архитектура
|
|
23
|
+
|
|
24
|
+
### Использует
|
|
25
|
+
- Нативный input type="date" - для одиночной даты
|
|
26
|
+
- Кастомный интерфейс - для диапазона дат
|
|
27
|
+
|
|
28
|
+
### Используется в
|
|
29
|
+
- Формы с датами
|
|
30
|
+
- Фильтры по датам
|
|
31
|
+
- Календари событий
|
|
32
|
+
- Любые места, требующие выбор даты
|
|
33
|
+
|
|
34
|
+
## Внутренняя логика
|
|
35
|
+
|
|
36
|
+
### Режимы
|
|
37
|
+
- **single** (по умолчанию): Выбор одной даты
|
|
38
|
+
- **range**: Выбор диапазона дат (от и до)
|
|
39
|
+
|
|
40
|
+
### Формат значений
|
|
41
|
+
- **single**: Строка в формате YYYY-MM-DD
|
|
42
|
+
- **range**: Объект \`{ start: 'YYYY-MM-DD', end: 'YYYY-MM-DD' }\`
|
|
43
|
+
|
|
44
|
+
### Отображение диапазона
|
|
45
|
+
При range режиме:
|
|
46
|
+
- Отображается форматированная строка "DD.MM.YYYY - DD.MM.YYYY"
|
|
47
|
+
- При клике открывается календарь с двумя полями (от/до)
|
|
48
|
+
- Кнопки "Применить" и "Отмена" для подтверждения выбора
|
|
49
|
+
|
|
50
|
+
## Особенности
|
|
51
|
+
|
|
52
|
+
### v-model
|
|
53
|
+
Полностью поддерживает двустороннее связывание через \`v-model\`:
|
|
54
|
+
- Для single: String (YYYY-MM-DD)
|
|
55
|
+
- Для range: Object ({ start, end })
|
|
56
|
+
|
|
57
|
+
### Форматирование
|
|
58
|
+
Даты форматируются в локализованном формате (ru-RU) для отображения.
|
|
59
|
+
|
|
60
|
+
### Иконка календаря
|
|
61
|
+
Отображается иконка календаря справа от поля для визуальной индикации.
|
|
62
|
+
`,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
8
66
|
};
|
|
9
67
|
|
|
10
68
|
export const Default = {
|
|
@@ -5,6 +5,72 @@ export default {
|
|
|
5
5
|
title: 'Molecules/DXFileUpload',
|
|
6
6
|
component: DXFileUpload,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXFileUpload
|
|
13
|
+
|
|
14
|
+
Компонент загрузки файлов с поддержкой drag & drop, предпросмотра и множественного выбора.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXFileUpload предоставляет полнофункциональный компонент для загрузки файлов с поддержкой
|
|
19
|
+
перетаскивания, предпросмотра изображений, множественного выбора и валидации типов/размеров.
|
|
20
|
+
|
|
21
|
+
## Архитектура
|
|
22
|
+
|
|
23
|
+
### Использует
|
|
24
|
+
- \`DXIcon\` - для иконок загрузки и удаления
|
|
25
|
+
- Нативный input type="file" - для выбора файлов
|
|
26
|
+
|
|
27
|
+
### Используется в
|
|
28
|
+
- Загрузка документов
|
|
29
|
+
- Загрузка изображений
|
|
30
|
+
- Множественная загрузка файлов
|
|
31
|
+
- Любые места, требующие загрузку файлов
|
|
32
|
+
|
|
33
|
+
## Внутренняя логика
|
|
34
|
+
|
|
35
|
+
### Drag & Drop
|
|
36
|
+
Поддерживает перетаскивание файлов:
|
|
37
|
+
- Визуальная индикация при наведении (scale, изменение цвета)
|
|
38
|
+
- Обработка событий dragenter, dragover, dragleave, drop
|
|
39
|
+
|
|
40
|
+
### Предпросмотр
|
|
41
|
+
Для изображений:
|
|
42
|
+
- Автоматически создается preview через FileReader
|
|
43
|
+
- Отображается миниатюра 48×48px
|
|
44
|
+
- Для других файлов отображается иконка документа
|
|
45
|
+
|
|
46
|
+
### Множественный выбор
|
|
47
|
+
При \`multiple={true}\`:
|
|
48
|
+
- Можно выбрать несколько файлов
|
|
49
|
+
- Отображается кнопка "Добавить ещё" для добавления дополнительных файлов
|
|
50
|
+
|
|
51
|
+
### Валидация
|
|
52
|
+
- \`accept\` - ограничение типов файлов (например, "image/*", ".pdf")
|
|
53
|
+
- \`maxSize\` - максимальный размер файла (отображается в подсказке)
|
|
54
|
+
|
|
55
|
+
## Особенности
|
|
56
|
+
|
|
57
|
+
### v-model
|
|
58
|
+
Полностью поддерживает двустороннее связывание через \`v-model\`:
|
|
59
|
+
- Для single: File объект или null
|
|
60
|
+
- Для multiple: Array файлов
|
|
61
|
+
|
|
62
|
+
### События
|
|
63
|
+
- \`@change\` - эмитится при изменении файлов
|
|
64
|
+
|
|
65
|
+
### Удаление файлов
|
|
66
|
+
Каждый файл имеет кнопку удаления для удаления из списка.
|
|
67
|
+
|
|
68
|
+
### Форматирование размера
|
|
69
|
+
Размер файла автоматически форматируется в читаемый формат (KB, MB).
|
|
70
|
+
`,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
8
74
|
};
|
|
9
75
|
|
|
10
76
|
export const Default = {
|
|
@@ -5,6 +5,67 @@ export default {
|
|
|
5
5
|
title: 'Molecules/DXFilterGroup',
|
|
6
6
|
component: DXFilterGroup,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXFilterGroup
|
|
13
|
+
|
|
14
|
+
Компонент группы фильтров для выбора одного значения из списка опций с поддержкой счетчиков.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXFilterGroup предоставляет простой способ создания группы фильтров с кнопками-переключателями.
|
|
19
|
+
Компонент поддерживает счетчики для каждой опции и возможность сброса выбранного значения.
|
|
20
|
+
|
|
21
|
+
## Архитектура
|
|
22
|
+
|
|
23
|
+
### Использует
|
|
24
|
+
- Нативные HTML элементы - для простоты и доступности
|
|
25
|
+
|
|
26
|
+
### Используется в
|
|
27
|
+
- Фильтры списков и таблиц
|
|
28
|
+
- Переключение режимов отображения
|
|
29
|
+
- Категории и теги
|
|
30
|
+
- Любые места, требующие выбор одного значения из группы
|
|
31
|
+
|
|
32
|
+
## Внутренняя логика
|
|
33
|
+
|
|
34
|
+
### Структура опций
|
|
35
|
+
Опции передаются через массив объектов:
|
|
36
|
+
\`\`\`
|
|
37
|
+
[{ value: 'all', label: 'All', count?: 50 }]
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
Каждая опция может содержать:
|
|
41
|
+
- \`value\` - значение опции (обязательно)
|
|
42
|
+
- \`label\` - текст опции (обязательно)
|
|
43
|
+
- \`count\` - счетчик (опционально)
|
|
44
|
+
|
|
45
|
+
### Счетчики
|
|
46
|
+
При наличии \`count\` в опции, счетчик отображается рядом с текстом.
|
|
47
|
+
|
|
48
|
+
### Сброс
|
|
49
|
+
При \`clearable={true}\` (по умолчанию) и выбранном значении:
|
|
50
|
+
- Отображается кнопка "Сбросить"
|
|
51
|
+
- При клике значение сбрасывается в \`null\`
|
|
52
|
+
|
|
53
|
+
## Особенности
|
|
54
|
+
|
|
55
|
+
### v-model
|
|
56
|
+
Полностью поддерживает двустороннее связывание через \`v-model\` для String или Boolean значений.
|
|
57
|
+
|
|
58
|
+
### Визуальное оформление
|
|
59
|
+
- Активная опция: темный фон (\`bg-slate-800\`), белый текст
|
|
60
|
+
- Неактивные опции: белый фон, серый текст, hover эффект
|
|
61
|
+
- Кнопка сброса: желтый фон (\`bg-amber-50\`), желтый текст
|
|
62
|
+
|
|
63
|
+
### Лейбл
|
|
64
|
+
Поддерживает опциональный \`label\` prop для отображения заголовка группы.
|
|
65
|
+
`,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
8
69
|
};
|
|
9
70
|
|
|
10
71
|
const filters = [
|
|
@@ -5,6 +5,82 @@ export default {
|
|
|
5
5
|
title: 'Molecules/DXFormControl',
|
|
6
6
|
component: DXFormControl,
|
|
7
7
|
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
# DXFormControl
|
|
13
|
+
|
|
14
|
+
Компонент обертки для полей форм с поддержкой лейбла, валидации, иконок и счетчика символов.
|
|
15
|
+
|
|
16
|
+
## Назначение
|
|
17
|
+
|
|
18
|
+
DXFormControl предоставляет комплексную обертку для полей форм, объединяя лейбл, поле ввода,
|
|
19
|
+
иконки валидации, сообщения об ошибках и вспомогательный текст в единый компонент. Компонент
|
|
20
|
+
поддерживает различные состояния валидации и автоматически управляет отступами для иконок.
|
|
21
|
+
|
|
22
|
+
## Архитектура
|
|
23
|
+
|
|
24
|
+
### Использует
|
|
25
|
+
- \`DXText\` - для лейбла, ошибок и вспомогательного текста
|
|
26
|
+
- \`DXIcon\` - для иконки-префикса
|
|
27
|
+
- \`DXValidationIcon\` - для иконки валидации (успех/ошибка)
|
|
28
|
+
|
|
29
|
+
### Используется в
|
|
30
|
+
- Обертка для любых полей форм
|
|
31
|
+
- Кастомные поля ввода
|
|
32
|
+
- Интеграция с нативными input элементами
|
|
33
|
+
- Любые места, требующие полную структуру поля формы
|
|
34
|
+
|
|
35
|
+
## Внутренняя логика
|
|
36
|
+
|
|
37
|
+
### Структура
|
|
38
|
+
Компонент состоит из:
|
|
39
|
+
1. **Лейбл** - отображается над полем (если указан \`label\`)
|
|
40
|
+
2. **Счетчик символов** - отображается справа от лейбла (если \`showCount={true}\`)
|
|
41
|
+
3. **Поле** - слот для input/textarea/select
|
|
42
|
+
4. **Иконка-префикс** - слева от поля (если указан \`prefixIcon\` или слот \`prefix\`)
|
|
43
|
+
5. **Иконка валидации** - справа от поля (если \`validationState\` установлен)
|
|
44
|
+
6. **Сообщение об ошибке** - отображается под полем (если указан \`error\`)
|
|
45
|
+
7. **Вспомогательный текст** - отображается под полем (если нет ошибки и указан \`helper\`)
|
|
46
|
+
|
|
47
|
+
### Состояния валидации
|
|
48
|
+
Поддерживает три состояния:
|
|
49
|
+
- **success** - успешная валидация (зеленая иконка)
|
|
50
|
+
- **error** - ошибка валидации (красная иконка)
|
|
51
|
+
- **""** (пустая строка) - нет валидации
|
|
52
|
+
|
|
53
|
+
### Отступы для иконок
|
|
54
|
+
Автоматически управляет отступами:
|
|
55
|
+
- При наличии префикс-иконки: \`pl-11\` (padding-left)
|
|
56
|
+
- При наличии иконки валидации: \`pr-10\` (padding-right)
|
|
57
|
+
|
|
58
|
+
### Счетчик символов
|
|
59
|
+
При \`showCount={true}\` и указанном \`maxLength\`:
|
|
60
|
+
- Отображается в формате "текущее / максимальное" (например, "150 / 500")
|
|
61
|
+
- Показывается справа от лейбла
|
|
62
|
+
|
|
63
|
+
## Особенности
|
|
64
|
+
|
|
65
|
+
### Слоты
|
|
66
|
+
- **default** - поле ввода (input/textarea/select)
|
|
67
|
+
- **prefix** - кастомная префикс-иконка или элемент
|
|
68
|
+
|
|
69
|
+
### Обязательное поле
|
|
70
|
+
При \`required={true}\` автоматически добавляется красная звездочка (*) справа от лейбла.
|
|
71
|
+
|
|
72
|
+
### Валидация
|
|
73
|
+
Компонент поддерживает визуальную индикацию валидации:
|
|
74
|
+
- Иконка валидации справа от поля
|
|
75
|
+
- Цветные сообщения об ошибках/успехе
|
|
76
|
+
- Автоматическое скрытие helper при наличии ошибки
|
|
77
|
+
|
|
78
|
+
### Интеграция
|
|
79
|
+
Компонент предназначен для обертки любых полей ввода, включая нативные HTML элементы.
|
|
80
|
+
`,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
8
84
|
};
|
|
9
85
|
|
|
10
86
|
export const Default = {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="w-full" data-component="DXFormControl">
|
|
3
3
|
<div class="flex items-center justify-between mb-1">
|
|
4
|
-
<
|
|
4
|
+
<DXText v-if="label" tag="label" size="sm" weight="medium" color="default">
|
|
5
5
|
{{ label }}
|
|
6
|
-
<
|
|
7
|
-
</
|
|
8
|
-
<
|
|
6
|
+
<DXText v-if="required" tag="span" color="danger">*</DXText>
|
|
7
|
+
</DXText>
|
|
8
|
+
<DXText v-if="maxLength && showCount" tag="span" size="xs" color="muted">
|
|
9
9
|
{{ currentLength }} / {{ maxLength }}
|
|
10
|
-
</
|
|
10
|
+
</DXText>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
13
|
<div class="relative">
|
|
@@ -31,17 +31,18 @@
|
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
|
-
<
|
|
34
|
+
<DXText v-if="error" tag="p" size="xs" color="danger" class="mt-1 flex items-center gap-1">
|
|
35
35
|
<DXValidationIcon state="error" size="xs" />
|
|
36
36
|
{{ error }}
|
|
37
|
-
</
|
|
38
|
-
<
|
|
37
|
+
</DXText>
|
|
38
|
+
<DXText v-else-if="helper" tag="p" size="xs" color="muted" class="mt-1">{{ helper }}</DXText>
|
|
39
39
|
</div>
|
|
40
40
|
</template>
|
|
41
41
|
|
|
42
42
|
<script setup>
|
|
43
43
|
import { computed } from "vue";
|
|
44
44
|
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
45
|
+
import DXText from "../../atoms/DXText/DXText.vue";
|
|
45
46
|
import DXValidationIcon from "../DXValidationIcon/DXValidationIcon.vue";
|
|
46
47
|
|
|
47
48
|
const props = defineProps({
|
|
@@ -18,7 +18,106 @@ import {
|
|
|
18
18
|
export default {
|
|
19
19
|
title: 'Molecules/DXInput',
|
|
20
20
|
component: DXInput,
|
|
21
|
-
tags: ['autodocs'],
|
|
21
|
+
tags: ['autodocs', 'category:form'],
|
|
22
|
+
parameters: {
|
|
23
|
+
docs: {
|
|
24
|
+
description: {
|
|
25
|
+
component: `
|
|
26
|
+
# DXInput
|
|
27
|
+
|
|
28
|
+
Компонент поля ввода с поддержкой иконок, валидации и интеграции с группами полей.
|
|
29
|
+
|
|
30
|
+
## Назначение
|
|
31
|
+
|
|
32
|
+
DXInput предоставляет стандартизированное поле ввода с поддержкой различных типов (text, email, number, tel, url),
|
|
33
|
+
иконок слева и справа, валидации, состояний ошибок и автоматической адаптации при использовании внутри DXInputGroup.
|
|
34
|
+
|
|
35
|
+
## Архитектура
|
|
36
|
+
|
|
37
|
+
### Использует
|
|
38
|
+
- \`DXFormLabel\` - для отображения лейбла, ошибок и вспомогательного текста
|
|
39
|
+
- \`DXIconWrapper\` - для отображения иконок слева и справа
|
|
40
|
+
- \`useSize\` composable - для унификации размеров (sm, md, lg)
|
|
41
|
+
- \`useClassComposition\` composable - для объединения CSS классов
|
|
42
|
+
- \`provide/inject\` - для интеграции с DXInputGroup
|
|
43
|
+
|
|
44
|
+
### Используется в
|
|
45
|
+
- \`DXInputGroup\` - группы полей с аддонами
|
|
46
|
+
- \`DXFormControl\` - контроль форм
|
|
47
|
+
- \`DXAuthenticationForm\` - формы аутентификации
|
|
48
|
+
- Любые формы, требующие текстового ввода
|
|
49
|
+
|
|
50
|
+
## Внутренняя логика
|
|
51
|
+
|
|
52
|
+
### Интеграция с DXInputGroup
|
|
53
|
+
При использовании внутри \`DXInputGroup\`:
|
|
54
|
+
- Поле автоматически регистрируется в группе через \`provide/inject\`
|
|
55
|
+
- Размер синхронизируется с размером группы
|
|
56
|
+
- Состояние \`disabled\` наследуется от группы
|
|
57
|
+
- Состояние \`error\` синхронизируется с группой
|
|
58
|
+
- Border-radius адаптируется в зависимости от наличия аддонов слева/справа:
|
|
59
|
+
- Оба аддона → \`rounded-none\`
|
|
60
|
+
- Только слева → \`rounded-l-none rounded-r-xl\`
|
|
61
|
+
- Только справа → \`rounded-l-xl rounded-r-none\`
|
|
62
|
+
- Нет аддонов → \`rounded-xl\`
|
|
63
|
+
|
|
64
|
+
### Иконки
|
|
65
|
+
Поддерживает иконки через:
|
|
66
|
+
- \`prefixIcon\` prop - иконка слева (Heroicon компонент)
|
|
67
|
+
- \`suffixIcon\` prop - иконка справа (Heroicon компонент)
|
|
68
|
+
- Слоты \`prefix\` и \`suffix\` - для кастомных элементов
|
|
69
|
+
|
|
70
|
+
Размер иконки автоматически адаптируется к размеру поля:
|
|
71
|
+
- sm → sm
|
|
72
|
+
- md → md
|
|
73
|
+
- lg → lg
|
|
74
|
+
|
|
75
|
+
Padding для текста автоматически увеличивается при наличии иконок:
|
|
76
|
+
- sm: pl-10 / pr-10
|
|
77
|
+
- md: pl-11 / pr-11
|
|
78
|
+
- lg: pl-12 / pr-12
|
|
79
|
+
|
|
80
|
+
### Валидация
|
|
81
|
+
- При наличии \`error\` prop, поле получает красную рамку (\`border-rose-300\`)
|
|
82
|
+
- Текст ошибки отображается через \`DXFormLabel\`
|
|
83
|
+
- Состояние ошибки синхронизируется с \`DXInputGroup\`
|
|
84
|
+
|
|
85
|
+
### Размеры
|
|
86
|
+
Поддерживает три размера:
|
|
87
|
+
- **sm** - компактный размер
|
|
88
|
+
- **md** - средний размер (по умолчанию)
|
|
89
|
+
- **lg** - крупный размер
|
|
90
|
+
|
|
91
|
+
## Особенности
|
|
92
|
+
|
|
93
|
+
### v-model
|
|
94
|
+
Полностью поддерживает двустороннее связывание через \`v-model\` для String или Number значений.
|
|
95
|
+
|
|
96
|
+
### Типы полей
|
|
97
|
+
Поддерживает стандартные HTML типы:
|
|
98
|
+
- \`text\` - обычный текст (по умолчанию)
|
|
99
|
+
- \`email\` - email адрес
|
|
100
|
+
- \`number\` - число
|
|
101
|
+
- \`tel\` - телефон
|
|
102
|
+
- \`url\` - URL адрес
|
|
103
|
+
- И другие стандартные типы input
|
|
104
|
+
|
|
105
|
+
### Состояния
|
|
106
|
+
- **disabled** - отключает поле (opacity-60, cursor-not-allowed, bg-slate-50)
|
|
107
|
+
- **error** - визуально выделяет ошибку (красная рамка)
|
|
108
|
+
- **required** - отмечает поле как обязательное (через DXFormLabel)
|
|
109
|
+
|
|
110
|
+
### Лейбл и вспомогательный текст
|
|
111
|
+
- \`label\` - отображается над полем
|
|
112
|
+
- \`helper\` - вспомогательный текст под полем
|
|
113
|
+
- \`error\` - текст ошибки (заменяет helper при наличии)
|
|
114
|
+
|
|
115
|
+
### Кастомные классы
|
|
116
|
+
Поддерживает \`inputClass\` prop для добавления дополнительных CSS классов к input элементу.
|
|
117
|
+
`,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
22
121
|
argTypes: {
|
|
23
122
|
size: {
|
|
24
123
|
control: 'select',
|