@topvisor/ui 0.0.34 → 0.0.35
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/.storybook/TopTheme.js +82 -0
- package/.storybook/TopThemeManager.js +44 -0
- package/.storybook/main.ts +43 -0
- package/.storybook/manager.ts +28 -0
- package/.storybook/preview-head.html +16 -0
- package/.storybook/preview.ts +48 -0
- package/.storybook/vue/coreDecorator.ts +19 -0
- package/.storybook/vue/vModelDecorator.ts +27 -0
- package/.vscode/extensions.json +11 -0
- package/.vscode/keybindings.example.json +121 -0
- package/.vscode/settings.json +46 -0
- package/Dockerfile +3 -0
- package/NPM.md +25 -0
- package/PUBLISH.md +18 -0
- package/README.md +19 -52
- package/STORYBOOK.md +27 -0
- package/USE_IN_PROJECT.md +29 -0
- package/build/afterBuild.sh +12 -0
- package/build/cssModules.ts +39 -0
- package/build/plugin/amdFix.ts +46 -0
- package/build/rollup.config.ts +18 -0
- package/nbproject/project.properties +11 -0
- package/nbproject/project.xml +9 -0
- package/package.json +68 -19
- package/public/README.md +63 -0
- package/src/components/common/common.ts +1 -0
- package/src/components/common/icon/icon.ts +4 -0
- package/src/components/common/icon/icon.vue +15 -0
- package/src/components/component.ts +133 -0
- package/src/components/forms/button/button.stories.ts +112 -0
- package/src/components/forms/button/button.ts +51 -0
- package/src/components/forms/button/button.vue +75 -0
- package/src/components/forms/button/stories/README.md +35 -0
- package/src/components/forms/button/stories/overview.vue +33 -0
- package/src/components/forms/button/style/button.css +124 -0
- package/src/components/forms/button/style/style-outline.css +42 -0
- package/src/components/forms/button/style/style-soft.css +31 -0
- package/src/components/forms/button/style/style-transparent.css +35 -0
- package/src/components/forms/checkbox/checkbox.stories.ts +33 -0
- package/src/components/forms/checkbox/checkbox.ts +23 -0
- package/src/components/forms/checkbox/checkbox.vue +135 -0
- package/src/components/forms/checkbox/stories/overview.vue +171 -0
- package/src/components/forms/controlLabel/controlLabel.stories.ts +38 -0
- package/src/components/forms/controlLabel/controlLabel.ts +4 -0
- package/src/components/forms/controlLabel/controlLabel.vue +48 -0
- package/src/components/forms/forms.ts +10 -0
- package/src/components/forms/helpers.ts +10 -0
- package/src/components/forms/hint/hint.stories.ts +46 -0
- package/src/components/forms/hint/hint.ts +8 -0
- package/src/components/forms/hint/hint.vue +32 -0
- package/src/components/forms/input/input.stories.ts +31 -0
- package/src/components/forms/input/input.ts +34 -0
- package/src/components/forms/input/input.vue +170 -0
- package/src/components/forms/input/stories/overview.vue +61 -0
- package/src/components/forms/inputDate/datepicker.css +233 -0
- package/src/components/forms/inputDate/datepicker.ts +101 -0
- package/src/components/forms/inputDate/inputDate.stories.ts +41 -0
- package/src/components/forms/inputDate/inputDate.ts +4 -0
- package/src/components/forms/inputDate/inputDate.vue +127 -0
- package/src/components/forms/inputDate/stories/overview.vue +35 -0
- package/src/components/forms/radio/radio.stories.ts +34 -0
- package/src/components/forms/radio/radio.ts +15 -0
- package/src/components/forms/radio/radio.vue +107 -0
- package/src/components/forms/radio/stories/overview.vue +79 -0
- package/src/components/forms/select/select.stories.ts +34 -0
- package/src/components/forms/select/select.ts +36 -0
- package/src/components/forms/select/select.vue +253 -0
- package/src/components/forms/select/stories/exampleOptions.ts +71 -0
- package/src/components/forms/select/stories/overview.vue +60 -0
- package/src/components/forms/switcher/stories/overview.vue +139 -0
- package/src/components/forms/switcher/switcher.stories.ts +33 -0
- package/src/components/forms/switcher/switcher.ts +22 -0
- package/src/components/forms/switcher/switcher.vue +113 -0
- package/src/components/forms/textarea/stories/overview.vue +62 -0
- package/src/components/forms/textarea/textarea.stories.ts +33 -0
- package/src/components/forms/textarea/textarea.ts +38 -0
- package/src/components/forms/textarea/textarea.vue +119 -0
- package/src/components/formsExt/editArea/editArea.stories.ts +72 -0
- package/src/components/formsExt/editArea/editArea.ts +25 -0
- package/src/components/formsExt/editArea/editArea.vue +172 -0
- package/src/components/formsExt/editArea/stories/README.md +17 -0
- package/src/components/formsExt/editArea/stories/overview.vue +66 -0
- package/src/components/formsExt/editInput/editInput.stories.ts +36 -0
- package/src/components/formsExt/editInput/editInput.ts +20 -0
- package/src/components/formsExt/editInput/editInput.vue +57 -0
- package/src/components/formsExt/editInput/stories/overview.vue +54 -0
- package/src/components/formsExt/formsExt.ts +3 -0
- package/src/components/formsExt/radioGroup/radioGroup.stories.ts +51 -0
- package/src/components/formsExt/radioGroup/radioGroup.ts +28 -0
- package/src/components/formsExt/radioGroup/radioGroup.vue +143 -0
- package/src/components/formsExt/radioGroup/stories/overview.vue +78 -0
- package/src/components/formsExt/radioGroup/styles/top-scrollBar.css +52 -0
- package/src/components/helper.js +10 -0
- package/src/components/helpersStories.ts +151 -0
- package/src/components/popup/lib/popup.globalEvents.js +205 -0
- package/src/components/popup/lib/popup.js +702 -0
- package/src/components/popup/lib/worker.globalEvents.js +78 -0
- package/src/components/popup/lib/worker.js +232 -0
- package/src/components/popup/popup/listItem.vue +42 -0
- package/src/components/popup/popup/opener.vue +74 -0
- package/src/components/popup/popup/popup.stories.ts +68 -0
- package/src/components/popup/popup/popup.ts +93 -0
- package/src/components/popup/popup/popup.vue +95 -0
- package/src/components/popup/popup/stories/README.md +34 -0
- package/src/components/popup/popup/stories/listItems.vue +44 -0
- package/src/components/popup/popup/stories/listSubItems.vue +52 -0
- package/src/components/popup/popup/stories/overview.vue +208 -0
- package/src/components/popup/popup/style/popup.css +243 -0
- package/src/components/popup/popup/style/popup.m.css +71 -0
- package/src/components/popup/popup/style/popup.pc.css +28 -0
- package/src/components/popup/popup.ts +3 -0
- package/src/components/popup/worker.ts +1 -0
- package/src/components/tabs/tabs/content.vue +24 -0
- package/src/components/tabs/tabs/stories/README.md +10 -0
- package/src/components/tabs/tabs/tab.vue +52 -0
- package/src/components/tabs/tabs/tabs.stories.ts +171 -0
- package/src/components/tabs/tabs/tabs.ts +22 -0
- package/src/components/tabs/tabs/tabs.vue +64 -0
- package/src/components/tabs/tabs.ts +3 -0
- package/src/core/base/Colors.stories.ts +15 -0
- package/src/core/base/Layout.stories.ts +15 -0
- package/src/core/base/Properties.stories.ts +15 -0
- package/src/core/base/base.mdx +21 -0
- package/src/core/core/core.ts +144 -0
- package/src/core/core/events.ts +54 -0
- package/src/core/core/options.ts +15 -0
- package/src/core/core/state.ts +44 -0
- package/src/core/directives/tooltip.ts +55 -0
- package/src/core/theme/Colors.stories.ts +15 -0
- package/src/core/theme/Properties.stories.ts +15 -0
- package/src/core/theme/theme.mdx +15 -0
- package/src/core/utils/date.ts +164 -0
- package/src/core/utils/device.ts +48 -0
- package/src/core/utils/dom.ts +185 -0
- package/src/core//320/235/320/260/320/261/320/276/321/200 /320/270/320/272/320/276/320/275/320/276/320/272/gallery.vue" +72 -0
- package/src/core//320/235/320/260/320/261/320/276/321/200 /320/270/320/272/320/276/320/275/320/276/320/272//320/235/320/260/320/261/320/276/321/200 /320/270/320/272/320/276/320/275/320/276/320/272.mdx" +31 -0
- package/src/core//320/235/320/260/320/261/320/276/321/200 /320/270/320/272/320/276/320/275/320/276/320/272//320/235/320/260/320/261/320/276/321/200 /320/270/320/272/320/276/320/275/320/276/320/272.stories.ts" +14 -0
- package/src/docs/CSS/FAQ.mdx +43 -0
- package/src/docs/CSS//320/236/320/261/321/211/320/270/320/265 /320/274/320/276/320/264/320/270/321/204/320/270/320/272/320/260/321/202/320/276/321/200/321/213.mdx" +156 -0
- package/src/docs/CSS//320/237/320/265/321/200/320/265/320/274/320/265/320/275/320/275/321/213/320/265.mdx +47 -0
- package/src/docs/CSS//320/237/321/200/320/265/320/264/320/277/321/200/320/276/321/206/320/265/321/201/321/201/320/276/321/200/321/213.mdx +15 -0
- package/src/docs/CSS//320/240/320/265/320/272/320/276/320/274/320/265/320/275/320/264/320/260/321/206/320/270/320/270 /320/221/320/255/320/234.mdx" +49 -0
- package/src/docs/CSS//320/241/321/202/320/270/320/273/320/270.md +53 -0
- package/src/docs/CSS//320/241/321/202/320/270/320/273/320/270.mdx +4 -0
- package/src/docs/CSS//320/247/321/202/320/276 /321/202/320/260/320/272/320/276/320/265 css /320/274/320/276/320/264/321/203/320/273/321/214.mdx" +53 -0
- package/src/docs/ROADMAP.md +17 -0
- package/src/docs/Roadmap.mdx +4 -0
- package/src/docs//320/222/320/262/320/265/320/264/320/265/320/275/320/270/320/265 /320/262 Storybook.mdx" +323 -0
- package/src/docs//320/232/320/276/320/274/320/277/320/276/320/275/320/265/320/275/321/202/321/213.mdx +20 -0
- package/src/docs//320/237/320/276/320/273/320/265/320/267/320/275/320/260/321/217 /320/270/320/275/321/204/320/276/321/200/320/274/320/260/321/206/320/270/321/217.mdx" +8 -0
- package/src/docs//320/241/321/202/320/260/320/275/320/264/320/260/321/200/321/202/321/213 /320/272/320/276/320/264/320/260/IDE.mdx" +42 -0
- package/src/docs//320/241/321/202/320/260/320/275/320/264/320/260/321/200/321/202/321/213 /320/272/320/276/320/264/320/260//320/233/320/270/320/275/321/202/320/265/321/200.mdx" +72 -0
- package/src/docs//320/241/321/202/320/260/320/275/320/264/320/260/321/200/321/202/321/213 /320/272/320/276/320/264/320/260//320/241/321/202/320/260/320/275/320/264/320/260/321/200/321/202/321/213 /320/272/320/276/320/264/320/260.mdx" +29 -0
- package/src/globals.d.ts +1 -0
- package/{icomoon → src/resources/icomoon}/demo-files/demo.css +161 -161
- package/{icomoon → src/resources/icomoon}/demo-files/demo.js +30 -30
- package/{icomoon → src/resources/icomoon}/demo.html +2945 -2945
- package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.svg +232 -232
- package/{icomoon → src/resources/icomoon}/style.css +647 -647
- package/src/resources/styles/core/colors.css +204 -0
- package/src/resources/styles/core/components.css +70 -0
- package/src/resources/styles/core/core.ts +10 -0
- package/src/resources/styles/core/forms/clear.css +19 -0
- package/src/resources/styles/core/forms/controls.css +20 -0
- package/src/resources/styles/core/forms/focusable.css +26 -0
- package/src/resources/styles/core/forms/forms.css +100 -0
- package/src/resources/styles/core/icon.css +58 -0
- package/src/resources/styles/core/layout.css +40 -0
- package/src/resources/styles/core/modifiers/as.css +9 -0
- package/src/resources/styles/core/modifiers/ellipsis.css +18 -0
- package/src/resources/styles/core/modifiers/modifiers.css +81 -0
- package/src/resources/styles/core/modifiers/only.css +19 -0
- package/src/resources/styles/core/select.css +16 -0
- package/src/resources/styles/jquery-ui.min.css +6 -0
- package/src/resources/styles/storybook.css +11 -0
- package/src/resources/styles/themes/dark/theme.css +139 -0
- package/src/resources/styles/themes/dark.ts +1 -0
- package/src/resources/styles/themes/light/theme.css +139 -0
- package/src/resources/styles/themes/light.ts +1 -0
- package/src/storybook/components/color.vue +45 -0
- package/src/storybook/components/colors.vue +34 -0
- package/src/storybook/components/icomoon.ts +38 -0
- package/src/storybook/components/properties.vue +82 -0
- package/src/storybook/resources/accessibility.png +0 -0
- package/src/storybook/resources/accessibility.svg +5 -0
- package/src/storybook/resources/addon-library.png +0 -0
- package/src/storybook/resources/assets.png +0 -0
- package/src/storybook/resources/context.png +0 -0
- package/src/storybook/resources/discord.svg +15 -0
- package/src/storybook/resources/docs.png +0 -0
- package/src/storybook/resources/figma-plugin.png +0 -0
- package/src/storybook/resources/github.svg +3 -0
- package/src/storybook/resources/share.png +0 -0
- package/src/storybook/resources/styling.png +0 -0
- package/src/storybook/resources/testing.png +0 -0
- package/src/storybook/resources/theming.png +0 -0
- package/src/storybook/resources/tutorials.svg +12 -0
- package/src/storybook/resources/youtube.svg +4 -0
- package/src//320/224/320/276/320/261/321/200/320/276 /320/277/320/276/320/266/320/260/320/273/320/276/320/262/320/260/321/202/321/214.mdx" +3 -0
- package/tsconfig.json +62 -0
- package/vite.config.ts +91 -0
- package/.chunks/datepicker-0b648b9f.es.js +0 -275
- package/.chunks/datepicker-0b648b9f.es.js.map +0 -1
- package/.chunks/datepicker-0e9a0541.amd.js +0 -234
- package/.chunks/datepicker-0e9a0541.amd.js.map +0 -1
- package/.chunks/forms-02202302.amd.js +0 -3
- package/.chunks/forms-02202302.amd.js.map +0 -1
- package/.chunks/forms-eb00d0c1.es.js +0 -946
- package/.chunks/forms-eb00d0c1.es.js.map +0 -1
- package/.chunks/popup-6f73b4b2.es.js +0 -700
- package/.chunks/popup-6f73b4b2.es.js.map +0 -1
- package/.chunks/popup-e1f34511.amd.js +0 -341
- package/.chunks/popup-e1f34511.amd.js.map +0 -1
- package/common/common.amd.js +0 -2
- package/common/common.amd.js.map +0 -1
- package/common/common.js +0 -2
- package/common/common.js.map +0 -1
- package/core/core.amd.js +0 -2
- package/core/core.amd.js.map +0 -1
- package/core/core.js +0 -6
- package/core/core.js.map +0 -1
- package/core.css +0 -1
- package/dark.css +0 -1
- package/forms/forms.amd.js +0 -2
- package/forms/forms.amd.js.map +0 -1
- package/forms/forms.js +0 -15
- package/forms/forms.js.map +0 -1
- package/forms/helpers.amd.js +0 -2
- package/forms/helpers.amd.js.map +0 -1
- package/forms/helpers.js +0 -9
- package/forms/helpers.js.map +0 -1
- package/forms.css +0 -1
- package/formsExt/formsExt.amd.js +0 -3
- package/formsExt/formsExt.amd.js.map +0 -1
- package/formsExt/formsExt.js +0 -152
- package/formsExt/formsExt.js.map +0 -1
- package/formsExt.css +0 -1
- package/light.css +0 -1
- package/popup/popup.amd.js +0 -3
- package/popup/popup.amd.js.map +0 -1
- package/popup/popup.js +0 -144
- package/popup/popup.js.map +0 -1
- package/popup/worker.amd.js +0 -2
- package/popup/worker.amd.js.map +0 -1
- package/popup/worker.js +0 -154
- package/popup/worker.js.map +0 -1
- package/popup.css +0 -1
- package/tabs/tabs.amd.js +0 -3
- package/tabs/tabs.amd.js.map +0 -1
- package/tabs/tabs.js +0 -97
- package/tabs/tabs.js.map +0 -1
- package/tabs.css +0 -1
- package/utils/date.amd.js +0 -2
- package/utils/date.amd.js.map +0 -1
- package/utils/date.js +0 -6
- package/utils/date.js.map +0 -1
- package/utils/device.amd.js +0 -2
- package/utils/device.amd.js.map +0 -1
- package/utils/device.js +0 -6
- package/utils/device.js.map +0 -1
- package/utils/dom.amd.js +0 -2
- package/utils/dom.amd.js.map +0 -1
- package/utils/dom.js +0 -64
- package/utils/dom.js.map +0 -1
- /package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.ttf +0 -0
- /package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.woff +0 -0
- /package/{icomoon → src/resources/icomoon}/selection.json +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PropsContent } from './tabs';
|
|
3
|
+
|
|
4
|
+
defineProps<PropsContent>();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div
|
|
9
|
+
:class="{
|
|
10
|
+
'top-tabs_content': true,
|
|
11
|
+
}"
|
|
12
|
+
:data-tabs-name="name"
|
|
13
|
+
>
|
|
14
|
+
<slot></slot>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<style module>
|
|
19
|
+
.top-tabs_content {
|
|
20
|
+
padding: 14px;
|
|
21
|
+
overflow: auto;
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
В компоненте используется 3 именованых слота:
|
|
2
|
+
**#header** - шаблон или текст справа от вкладок
|
|
3
|
+
**#buttons** - для вставки самих вкладок
|
|
4
|
+
**#contents** - для шаблона или текста под вкладкой
|
|
5
|
+
|
|
6
|
+
Также нужно использовать два вспомогательных компонента:
|
|
7
|
+
**TabsTab** - компонент вкладки
|
|
8
|
+
**TabsContent** - компонент содержания вкладки
|
|
9
|
+
|
|
10
|
+
Для совместимости с версткой в html поддерживает 6 вкладок
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PropsTab } from './tabs';
|
|
3
|
+
|
|
4
|
+
defineProps<PropsTab>();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<input
|
|
9
|
+
type="radio"
|
|
10
|
+
class="top-tabs_tabInput top-unvisible"
|
|
11
|
+
:id="tabsId + name"
|
|
12
|
+
:name="tabsId"
|
|
13
|
+
:value="name"
|
|
14
|
+
:checked="active"
|
|
15
|
+
:disabled="disabled"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<label
|
|
19
|
+
:class="{
|
|
20
|
+
'top-tabs_tabLabel': true,
|
|
21
|
+
'top-forms-focusable': true,
|
|
22
|
+
'top-disabled': disabled,
|
|
23
|
+
}"
|
|
24
|
+
:for="tabsId + name"
|
|
25
|
+
>
|
|
26
|
+
<slot></slot>
|
|
27
|
+
</label>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<style module>
|
|
31
|
+
.top-tabs_tabLabel {
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
border-bottom: 2px solid transparent;
|
|
34
|
+
padding: 14px 20px;
|
|
35
|
+
position: relative;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.top-tabs_tabLabel:hover {
|
|
41
|
+
border-color: var(--color-line-2-opacity);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.top-tabs_tabInput:checked + .top-tabs_tabLabel {
|
|
45
|
+
border-color: var(--color-primary);
|
|
46
|
+
color: var(--color-primary);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.top-tabs_tabLabel.top-disabled {
|
|
50
|
+
color: var(--color-text-3);
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
|
|
3
|
+
import { genArgsTypes } from '@/components/helpersStories';
|
|
4
|
+
|
|
5
|
+
import Component from './tabs.vue';
|
|
6
|
+
import TabsTab from './tab.vue';
|
|
7
|
+
import TabsContent from './content.vue';
|
|
8
|
+
import * as ComponentsConst from './tabs';
|
|
9
|
+
import ReadMe from './stories/README.md?raw';
|
|
10
|
+
|
|
11
|
+
import Button from '@/components/forms/button/button.vue';
|
|
12
|
+
import Hint from '@/components/forms/hint/hint.vue';
|
|
13
|
+
import Textarea from '@/components/forms/textarea/textarea.vue';
|
|
14
|
+
|
|
15
|
+
const argTypes = genArgsTypes(Component, ComponentsConst);
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
component: Component,
|
|
19
|
+
tags: ['autodocs'],
|
|
20
|
+
argTypes,
|
|
21
|
+
parameters: {
|
|
22
|
+
docs: {
|
|
23
|
+
description: {
|
|
24
|
+
component: ReadMe,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
} satisfies Meta<typeof Component>;
|
|
29
|
+
|
|
30
|
+
type Story = StoryObj<typeof meta>;
|
|
31
|
+
|
|
32
|
+
export const Overview = {
|
|
33
|
+
args: {
|
|
34
|
+
id: 'tabs',
|
|
35
|
+
},
|
|
36
|
+
render: (args) => ({
|
|
37
|
+
components: {
|
|
38
|
+
Tabs: Component,
|
|
39
|
+
TabsTab,
|
|
40
|
+
TabsContent,
|
|
41
|
+
Button,
|
|
42
|
+
Textarea,
|
|
43
|
+
Hint,
|
|
44
|
+
},
|
|
45
|
+
setup () {
|
|
46
|
+
return { args };
|
|
47
|
+
},
|
|
48
|
+
template: `
|
|
49
|
+
<Tabs :id="args.id">
|
|
50
|
+
<template #header>
|
|
51
|
+
<Hint hint="В шапку табов можно вставлять произвольный HTML код"></Hint>
|
|
52
|
+
|
|
53
|
+
<Button icon="" color="theme"/>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<template #buttons>
|
|
57
|
+
<TabsTab
|
|
58
|
+
:tabsId="args.id"
|
|
59
|
+
name="tab_1"
|
|
60
|
+
active
|
|
61
|
+
>
|
|
62
|
+
Вкладка 1
|
|
63
|
+
</TabsTab>
|
|
64
|
+
|
|
65
|
+
<TabsTab
|
|
66
|
+
:tabsId="args.id"
|
|
67
|
+
name="tab_2"
|
|
68
|
+
>
|
|
69
|
+
Вкладка 2
|
|
70
|
+
</TabsTab>
|
|
71
|
+
|
|
72
|
+
<TabsTab
|
|
73
|
+
:tabsId="args.id"
|
|
74
|
+
name="tab_3"
|
|
75
|
+
>
|
|
76
|
+
Вкладка 3
|
|
77
|
+
</TabsTab>
|
|
78
|
+
|
|
79
|
+
<TabsTab
|
|
80
|
+
:tabsId="args.id"
|
|
81
|
+
name="tab_4"
|
|
82
|
+
>
|
|
83
|
+
Вкладка 4
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<Hint hint="В заголовок вкладки можно вставлять произвольный HTML код"></Hint>
|
|
88
|
+
</TabsTab>
|
|
89
|
+
|
|
90
|
+
<TabsTab
|
|
91
|
+
:tabsId="args.id"
|
|
92
|
+
name="tab_5"
|
|
93
|
+
>
|
|
94
|
+
Вкладка 5 (вложенные)
|
|
95
|
+
</TabsTab>
|
|
96
|
+
|
|
97
|
+
<TabsTab
|
|
98
|
+
:tabsId="args.id"
|
|
99
|
+
name="tab_6"
|
|
100
|
+
disabled
|
|
101
|
+
>
|
|
102
|
+
Вкладка 6 (disabled)
|
|
103
|
+
</TabsTab>
|
|
104
|
+
</template>
|
|
105
|
+
|
|
106
|
+
<template #contents>
|
|
107
|
+
<TabsContent>
|
|
108
|
+
<p>
|
|
109
|
+
Текст для вкладки 1 с вставкой большого блока
|
|
110
|
+
</p>
|
|
111
|
+
|
|
112
|
+
<div style="background: var(--color-theme-100); width: 150%; height: 50vh; padding: 10px; display: block;">
|
|
113
|
+
Большой блок
|
|
114
|
+
</div>
|
|
115
|
+
</TabsContent>
|
|
116
|
+
|
|
117
|
+
<TabsContent>
|
|
118
|
+
<Textarea modelValue="" placeholder="Напишите что-нибудь..."/>
|
|
119
|
+
</TabsContent>
|
|
120
|
+
|
|
121
|
+
<TabsContent>
|
|
122
|
+
<Button>
|
|
123
|
+
Кнопка
|
|
124
|
+
</Button>
|
|
125
|
+
</TabsContent>
|
|
126
|
+
|
|
127
|
+
<TabsContent>
|
|
128
|
+
Текст для вкладки 4
|
|
129
|
+
</TabsContent>
|
|
130
|
+
|
|
131
|
+
<TabsContent>
|
|
132
|
+
<Tabs :id="args.id + '-2'">
|
|
133
|
+
<template #buttons>
|
|
134
|
+
<TabsTab
|
|
135
|
+
:tabsId="args.id + '2'"
|
|
136
|
+
name="subtab_1"
|
|
137
|
+
active
|
|
138
|
+
>
|
|
139
|
+
Вкладка 1
|
|
140
|
+
</TabsTab>
|
|
141
|
+
|
|
142
|
+
<TabsTab
|
|
143
|
+
:tabsId="args.id + '2'"
|
|
144
|
+
name="subtab_2"
|
|
145
|
+
>
|
|
146
|
+
Вкладка 2
|
|
147
|
+
</TabsTab>
|
|
148
|
+
</template>
|
|
149
|
+
|
|
150
|
+
<template #contents>
|
|
151
|
+
<TabsContent name="tab_1">
|
|
152
|
+
Текст для вкладки 1
|
|
153
|
+
</TabsContent>
|
|
154
|
+
|
|
155
|
+
<TabsContent name="tab_2">
|
|
156
|
+
Текст для вкладки 2
|
|
157
|
+
</TabsContent>
|
|
158
|
+
</template>
|
|
159
|
+
</Tabs>
|
|
160
|
+
</TabsContent>
|
|
161
|
+
|
|
162
|
+
<TabsContent>
|
|
163
|
+
Текст для вкладки 6
|
|
164
|
+
</TabsContent>
|
|
165
|
+
</template>
|
|
166
|
+
</Tabs>
|
|
167
|
+
`,
|
|
168
|
+
}),
|
|
169
|
+
} satisfies Story;
|
|
170
|
+
|
|
171
|
+
export default meta;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
/**
|
|
3
|
+
* Уникальный id табов для нативного DOM и возмоэности сохранения state
|
|
4
|
+
*/
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface PropsTab {
|
|
9
|
+
tabsId: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Обязательный атрибут, должен быть уникален для каждого таба в пределах одного компонента
|
|
13
|
+
*/
|
|
14
|
+
name: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
active?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PropsContent {
|
|
21
|
+
name?: string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { Props } from './tabs';
|
|
3
|
+
|
|
4
|
+
const props = defineProps<Props>();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div
|
|
9
|
+
:class="{
|
|
10
|
+
'top-tabs': true,
|
|
11
|
+
}"
|
|
12
|
+
>
|
|
13
|
+
<!-- @slot Кнопки вкладок, ожидает передачу компонентов TabTitle -->
|
|
14
|
+
<slot name="buttons"></slot>
|
|
15
|
+
|
|
16
|
+
<div v-if="$slots.header" class="top-tabs_header">
|
|
17
|
+
<!-- @slot Слот с проивзольным содержимым, которое будет добавлено справа от вкладок -->
|
|
18
|
+
<slot name="header"></slot>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="top-tabs_contents">
|
|
22
|
+
<!-- @slot Контент вкладок, ожидает передачу компонентов TabContent -->
|
|
23
|
+
<slot name="contents"></slot>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<style module>
|
|
29
|
+
.top-tabs {
|
|
30
|
+
background: var(--content-background-color);
|
|
31
|
+
border-radius: 8px;
|
|
32
|
+
border: 1px solid var(--color-line-2-opacity);
|
|
33
|
+
padding: 0;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: wrap;
|
|
36
|
+
align-items: stretch;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.top-tabs_header {
|
|
40
|
+
padding: 6px;
|
|
41
|
+
margin-left: auto;
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 8px;
|
|
45
|
+
flex-wrap: wrap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Содержимое вкладок */
|
|
49
|
+
.top-tabs_contents {
|
|
50
|
+
border-top: 1px solid var(--color-line-2-opacity);
|
|
51
|
+
width: 100%;
|
|
52
|
+
margin-top: -1px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Состояние открытости вкладок */
|
|
56
|
+
.top-tabs_tabInput:checked:nth-child(1) ~ .top-tabs_contents > .top-tabs_content:nth-child(1),
|
|
57
|
+
.top-tabs_tabInput:checked:nth-child(3) ~ .top-tabs_contents > .top-tabs_content:nth-child(2),
|
|
58
|
+
.top-tabs_tabInput:checked:nth-child(5) ~ .top-tabs_contents > .top-tabs_content:nth-child(3),
|
|
59
|
+
.top-tabs_tabInput:checked:nth-child(7) ~ .top-tabs_contents > .top-tabs_content:nth-child(4),
|
|
60
|
+
.top-tabs_tabInput:checked:nth-child(9) ~ .top-tabs_contents > .top-tabs_content:nth-child(5),
|
|
61
|
+
.top-tabs_tabInput:checked:nth-child(11) ~ .top-tabs_contents > .top-tabs_content:nth-child(6) {
|
|
62
|
+
display: block;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import colorsCSS from '@/resources/styles/core/colors.css?raw';
|
|
3
|
+
import Component from '@/storybook/components/colors.vue';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
component: Component,
|
|
7
|
+
} satisfies Meta<typeof Component>;
|
|
8
|
+
|
|
9
|
+
export const Colors = {
|
|
10
|
+
args: {
|
|
11
|
+
style: colorsCSS
|
|
12
|
+
}
|
|
13
|
+
} satisfies StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import layoutCSS from '@/resources/styles/core/layout.css?raw';
|
|
3
|
+
import Component from '@/storybook/components/properties.vue';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
component: Component,
|
|
7
|
+
} satisfies Meta<typeof Component>;
|
|
8
|
+
|
|
9
|
+
export const Layout = {
|
|
10
|
+
args: {
|
|
11
|
+
style: layoutCSS
|
|
12
|
+
}
|
|
13
|
+
} satisfies StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import colorsCSS from '@/resources/styles/core/colors.css?raw';
|
|
3
|
+
import Component from '@/storybook/components/properties.vue';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
component: Component,
|
|
7
|
+
} satisfies Meta<typeof Component>;
|
|
8
|
+
|
|
9
|
+
export const Properties = {
|
|
10
|
+
args: {
|
|
11
|
+
style: colorsCSS
|
|
12
|
+
}
|
|
13
|
+
} satisfies StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Canvas } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
# Основные стили и переменные
|
|
4
|
+
|
|
5
|
+
Основные стили и переменные доступны в:
|
|
6
|
+
- после сборки: **core.css**
|
|
7
|
+
- до сборки: **src/resources/styles/core/*.css**
|
|
8
|
+
|
|
9
|
+
## Палитра
|
|
10
|
+
|
|
11
|
+
Палитра содержит все основные цвета и является постоянной в пределах проекта независимо от темы.
|
|
12
|
+
|
|
13
|
+
👌 Переменные палитры **рекомендуется** импользовтаь в переменных темы.
|
|
14
|
+
|
|
15
|
+
❌ Переменные палитры **не рекомендуется** импользовтаь в переменных и стилях компонентов.
|
|
16
|
+
|
|
17
|
+
## Стили макета
|
|
18
|
+
|
|
19
|
+
Стили макета содержат основные переменные и классы для расположения и оформления элементов на странице.
|
|
20
|
+
|
|
21
|
+
Компоненты должны использовать предоставляемые классы макета, вместо реализации своих аналогичных стилей.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { reactive } from 'vue';
|
|
2
|
+
import Device from '@/core/utils/device';
|
|
3
|
+
import Events from '@/core/core/events';
|
|
4
|
+
import options from '@/core/core/options';
|
|
5
|
+
import state from '@/core/core/state';
|
|
6
|
+
import directiveTooltip from '@/core/directives/tooltip';
|
|
7
|
+
|
|
8
|
+
const _window: any = window;
|
|
9
|
+
|
|
10
|
+
class Core {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Настройки словаря
|
|
14
|
+
*/
|
|
15
|
+
static L = reactive({
|
|
16
|
+
Not_date: 'Not date',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
static page = _window?.page || {};
|
|
20
|
+
|
|
21
|
+
static options = options;
|
|
22
|
+
|
|
23
|
+
static state = reactive({ ...state });
|
|
24
|
+
|
|
25
|
+
static matchMediaIsMobile?: MediaQueryList;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Добавить на страницу стили, используется для загрузки стилей из js
|
|
29
|
+
*
|
|
30
|
+
* Условная загрузка стилей m и pc отключена в пользу производительсности, стили грузятся всегда, но применяются по условию
|
|
31
|
+
* @param style - css стили в строке
|
|
32
|
+
* @param type - если указать 'm' или 'pc', то стили будут применяться по условию в зависимости от настройки this.options.widthForMobile
|
|
33
|
+
*/
|
|
34
|
+
static appendStyle(style: string, type: '' | 'm' | 'pc' = ''): void {
|
|
35
|
+
let media = 'all';
|
|
36
|
+
|
|
37
|
+
if (type === 'm') {
|
|
38
|
+
media = '(max-width: ' + this.options.widthForMobile + 'px)';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (type === 'pc') {
|
|
42
|
+
media = '(min-width: ' + this.options.widthForMobile + 'px)';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const elStyle = document.createElement('style');
|
|
46
|
+
elStyle.innerHTML = style;
|
|
47
|
+
elStyle.media = media;
|
|
48
|
+
|
|
49
|
+
document.head.append(elStyle);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Установить как плагин в прилоежнии Vue
|
|
54
|
+
* Core.state является общим для всех приложений Vue на странице
|
|
55
|
+
* Core.options является общим для всех приложений Vue на странице
|
|
56
|
+
* @param app - Vue App
|
|
57
|
+
* @param {typeof options} options - параметры UI
|
|
58
|
+
*/
|
|
59
|
+
static install(app: any, options: typeof this.options) {
|
|
60
|
+
Core.defineOptions(options);
|
|
61
|
+
|
|
62
|
+
app.provide('top-core', Core);
|
|
63
|
+
|
|
64
|
+
this.installDirectives(app);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static installDirectives(app: any) {
|
|
68
|
+
app.directive('top-tooltip', directiveTooltip);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Установить конфигурацию UI
|
|
73
|
+
* @param {typeof options} options
|
|
74
|
+
*/
|
|
75
|
+
static defineOptions(options: typeof this.options) {
|
|
76
|
+
if (options?.widthForMobile) {
|
|
77
|
+
this.options.widthForMobile = options.widthForMobile;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (options?.dateFormat) {
|
|
81
|
+
this.options.dateFormat = options.dateFormat;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (options?.gmt) {
|
|
85
|
+
this.options.gmt = options.gmt;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Core.setState();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static setState() {
|
|
92
|
+
Core.matchMediaIsMobile = window.matchMedia(`(max-width: ${Core.options.widthForMobile}px)`);
|
|
93
|
+
|
|
94
|
+
Core.state.isMobileUA = Device.isMobile();
|
|
95
|
+
Core.state.isRetina = Device.isRetina();
|
|
96
|
+
Core.state.isApp = Device.isApp();
|
|
97
|
+
Core.state.dateFormat = this.options.dateFormat;
|
|
98
|
+
Core.state.gmt = this.options.gmt;
|
|
99
|
+
|
|
100
|
+
Core.setStateByWindowSize();
|
|
101
|
+
|
|
102
|
+
// пересчет значений, зависящих от рамзеров окна
|
|
103
|
+
Events.addOnReize(Core.onResize);
|
|
104
|
+
|
|
105
|
+
Core.onResize();
|
|
106
|
+
|
|
107
|
+
Core.saveToCookie();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static onResize() {
|
|
111
|
+
Core.setStateByWindowSize();
|
|
112
|
+
|
|
113
|
+
// честный vh
|
|
114
|
+
document.documentElement.style.setProperty('--100vh', window.innerHeight + 'px');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static setStateByWindowSize() {
|
|
118
|
+
Core.state.isMobile = !!Core.matchMediaIsMobile?.matches;
|
|
119
|
+
Core.state.isLandscape = (window.innerWidth > window.innerHeight);
|
|
120
|
+
Core.state.isPortrait = !Core.state.isLandscape;
|
|
121
|
+
Core.state.size = (window.innerWidth > window.innerHeight) ? window.innerWidth : window.innerHeight;
|
|
122
|
+
|
|
123
|
+
Core.saveToCookie();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Сохранить информацию об устройстве в cookie
|
|
128
|
+
*/
|
|
129
|
+
static saveToCookie() {
|
|
130
|
+
const device = [
|
|
131
|
+
1,
|
|
132
|
+
window.innerWidth,
|
|
133
|
+
window.innerHeight,
|
|
134
|
+
window.devicePixelRatio,
|
|
135
|
+
Number(Core.state.isMobile),
|
|
136
|
+
Number(Core.state.isRetina),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
document.cookie = 'device=' + device.join(',') + '; path=/;';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export default Core;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const onResizeDelay = 100;
|
|
2
|
+
|
|
3
|
+
let onResizeTimer: NodeJS.Timeout;
|
|
4
|
+
|
|
5
|
+
type TopEvent = Event & { topEvent: { widthDiff: number, hightDiff: number } }
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Установленные обрабочики на событие изменения размеров окна
|
|
9
|
+
*/
|
|
10
|
+
const onResizeListeners: Map<(ev: TopEvent) => any, (ev: TopEvent) => any> = new Map();
|
|
11
|
+
|
|
12
|
+
// зафиксированное состояние размеров окна
|
|
13
|
+
const windowSize = {
|
|
14
|
+
width: window.innerWidth,
|
|
15
|
+
height: window.innerHeight,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Добавить обработчик на событие изменения размеров экрана
|
|
20
|
+
* вызов таких обработчиков будет опмизирован и объединен в одно событие
|
|
21
|
+
*/
|
|
22
|
+
function addOnReize (listener: (this: Element, ev: TopEvent) => any) {
|
|
23
|
+
onResizeListeners.set(listener, listener);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Удаление обработчика на событие изменений размеров экрана
|
|
28
|
+
*/
|
|
29
|
+
function removeOnResize (listener: (this: Element, ev: TopEvent) => any) {
|
|
30
|
+
onResizeListeners.delete(listener);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function onResize (e: any) {
|
|
34
|
+
clearTimeout(onResizeTimer);
|
|
35
|
+
|
|
36
|
+
onResizeTimer = setTimeout(function () {
|
|
37
|
+
e.topEvent = {
|
|
38
|
+
widthDiff: windowSize.width - window.innerWidth,
|
|
39
|
+
hightDiff: windowSize.height - window.innerHeight,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
windowSize.width = window.innerWidth;
|
|
43
|
+
windowSize.height = window.innerHeight;
|
|
44
|
+
|
|
45
|
+
onResizeListeners.forEach((callback) => callback(e));
|
|
46
|
+
}, onResizeDelay);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
window.addEventListener('resize', onResize);
|
|
50
|
+
|
|
51
|
+
export default {
|
|
52
|
+
addOnReize,
|
|
53
|
+
removeOnResize,
|
|
54
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Конфигурация UI
|
|
3
|
+
* Можно переопределить при подклчюении UI во Vue приложение через app.use(Core, options)
|
|
4
|
+
*/
|
|
5
|
+
const options = {
|
|
6
|
+
widthForMobile: 900,
|
|
7
|
+
dateFormat: 'Y-m-d',
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Для Москвы: +0300
|
|
11
|
+
*/
|
|
12
|
+
gmt: new Date().toString().match(/GMT(\S+)/)?.[1],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default options;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State UI для взаимодейсвтиями с приложениями Vue
|
|
3
|
+
*/
|
|
4
|
+
const state = {
|
|
5
|
+
/**
|
|
6
|
+
* Device by size
|
|
7
|
+
* @see widthForMobile
|
|
8
|
+
*/
|
|
9
|
+
isMobile: false,
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Device by user agent
|
|
13
|
+
*/
|
|
14
|
+
isMobileUA: false,
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* true, если плотность пикселей экрана больше 1
|
|
18
|
+
*/
|
|
19
|
+
isRetina: false,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* true, елси это приложение
|
|
23
|
+
*/
|
|
24
|
+
isApp: false,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* true при горизонтальном расположении устройства
|
|
28
|
+
*/
|
|
29
|
+
isLandscape: true,
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* true при вертикальном расположении устройства
|
|
33
|
+
*/
|
|
34
|
+
isPortrait: false,
|
|
35
|
+
size: 0,
|
|
36
|
+
|
|
37
|
+
// См. core.options
|
|
38
|
+
dateFormat: 'Y-m-d',
|
|
39
|
+
|
|
40
|
+
// См. core.options
|
|
41
|
+
gmt: new Date().toString().match(/GMT(\S+)/)?.[1],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default state;
|