@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.
Files changed (267) hide show
  1. package/.storybook/TopTheme.js +82 -0
  2. package/.storybook/TopThemeManager.js +44 -0
  3. package/.storybook/main.ts +43 -0
  4. package/.storybook/manager.ts +28 -0
  5. package/.storybook/preview-head.html +16 -0
  6. package/.storybook/preview.ts +48 -0
  7. package/.storybook/vue/coreDecorator.ts +19 -0
  8. package/.storybook/vue/vModelDecorator.ts +27 -0
  9. package/.vscode/extensions.json +11 -0
  10. package/.vscode/keybindings.example.json +121 -0
  11. package/.vscode/settings.json +46 -0
  12. package/Dockerfile +3 -0
  13. package/NPM.md +25 -0
  14. package/PUBLISH.md +18 -0
  15. package/README.md +19 -52
  16. package/STORYBOOK.md +27 -0
  17. package/USE_IN_PROJECT.md +29 -0
  18. package/build/afterBuild.sh +12 -0
  19. package/build/cssModules.ts +39 -0
  20. package/build/plugin/amdFix.ts +46 -0
  21. package/build/rollup.config.ts +18 -0
  22. package/nbproject/project.properties +11 -0
  23. package/nbproject/project.xml +9 -0
  24. package/package.json +68 -19
  25. package/public/README.md +63 -0
  26. package/src/components/common/common.ts +1 -0
  27. package/src/components/common/icon/icon.ts +4 -0
  28. package/src/components/common/icon/icon.vue +15 -0
  29. package/src/components/component.ts +133 -0
  30. package/src/components/forms/button/button.stories.ts +112 -0
  31. package/src/components/forms/button/button.ts +51 -0
  32. package/src/components/forms/button/button.vue +75 -0
  33. package/src/components/forms/button/stories/README.md +35 -0
  34. package/src/components/forms/button/stories/overview.vue +33 -0
  35. package/src/components/forms/button/style/button.css +124 -0
  36. package/src/components/forms/button/style/style-outline.css +42 -0
  37. package/src/components/forms/button/style/style-soft.css +31 -0
  38. package/src/components/forms/button/style/style-transparent.css +35 -0
  39. package/src/components/forms/checkbox/checkbox.stories.ts +33 -0
  40. package/src/components/forms/checkbox/checkbox.ts +23 -0
  41. package/src/components/forms/checkbox/checkbox.vue +135 -0
  42. package/src/components/forms/checkbox/stories/overview.vue +171 -0
  43. package/src/components/forms/controlLabel/controlLabel.stories.ts +38 -0
  44. package/src/components/forms/controlLabel/controlLabel.ts +4 -0
  45. package/src/components/forms/controlLabel/controlLabel.vue +48 -0
  46. package/src/components/forms/forms.ts +10 -0
  47. package/src/components/forms/helpers.ts +10 -0
  48. package/src/components/forms/hint/hint.stories.ts +46 -0
  49. package/src/components/forms/hint/hint.ts +8 -0
  50. package/src/components/forms/hint/hint.vue +32 -0
  51. package/src/components/forms/input/input.stories.ts +31 -0
  52. package/src/components/forms/input/input.ts +34 -0
  53. package/src/components/forms/input/input.vue +170 -0
  54. package/src/components/forms/input/stories/overview.vue +61 -0
  55. package/src/components/forms/inputDate/datepicker.css +233 -0
  56. package/src/components/forms/inputDate/datepicker.ts +101 -0
  57. package/src/components/forms/inputDate/inputDate.stories.ts +41 -0
  58. package/src/components/forms/inputDate/inputDate.ts +4 -0
  59. package/src/components/forms/inputDate/inputDate.vue +127 -0
  60. package/src/components/forms/inputDate/stories/overview.vue +35 -0
  61. package/src/components/forms/radio/radio.stories.ts +34 -0
  62. package/src/components/forms/radio/radio.ts +15 -0
  63. package/src/components/forms/radio/radio.vue +107 -0
  64. package/src/components/forms/radio/stories/overview.vue +79 -0
  65. package/src/components/forms/select/select.stories.ts +34 -0
  66. package/src/components/forms/select/select.ts +36 -0
  67. package/src/components/forms/select/select.vue +253 -0
  68. package/src/components/forms/select/stories/exampleOptions.ts +71 -0
  69. package/src/components/forms/select/stories/overview.vue +60 -0
  70. package/src/components/forms/switcher/stories/overview.vue +139 -0
  71. package/src/components/forms/switcher/switcher.stories.ts +33 -0
  72. package/src/components/forms/switcher/switcher.ts +22 -0
  73. package/src/components/forms/switcher/switcher.vue +113 -0
  74. package/src/components/forms/textarea/stories/overview.vue +62 -0
  75. package/src/components/forms/textarea/textarea.stories.ts +33 -0
  76. package/src/components/forms/textarea/textarea.ts +38 -0
  77. package/src/components/forms/textarea/textarea.vue +119 -0
  78. package/src/components/formsExt/editArea/editArea.stories.ts +72 -0
  79. package/src/components/formsExt/editArea/editArea.ts +25 -0
  80. package/src/components/formsExt/editArea/editArea.vue +172 -0
  81. package/src/components/formsExt/editArea/stories/README.md +17 -0
  82. package/src/components/formsExt/editArea/stories/overview.vue +66 -0
  83. package/src/components/formsExt/editInput/editInput.stories.ts +36 -0
  84. package/src/components/formsExt/editInput/editInput.ts +20 -0
  85. package/src/components/formsExt/editInput/editInput.vue +57 -0
  86. package/src/components/formsExt/editInput/stories/overview.vue +54 -0
  87. package/src/components/formsExt/formsExt.ts +3 -0
  88. package/src/components/formsExt/radioGroup/radioGroup.stories.ts +51 -0
  89. package/src/components/formsExt/radioGroup/radioGroup.ts +28 -0
  90. package/src/components/formsExt/radioGroup/radioGroup.vue +143 -0
  91. package/src/components/formsExt/radioGroup/stories/overview.vue +78 -0
  92. package/src/components/formsExt/radioGroup/styles/top-scrollBar.css +52 -0
  93. package/src/components/helper.js +10 -0
  94. package/src/components/helpersStories.ts +151 -0
  95. package/src/components/popup/lib/popup.globalEvents.js +205 -0
  96. package/src/components/popup/lib/popup.js +702 -0
  97. package/src/components/popup/lib/worker.globalEvents.js +78 -0
  98. package/src/components/popup/lib/worker.js +232 -0
  99. package/src/components/popup/popup/listItem.vue +42 -0
  100. package/src/components/popup/popup/opener.vue +74 -0
  101. package/src/components/popup/popup/popup.stories.ts +68 -0
  102. package/src/components/popup/popup/popup.ts +93 -0
  103. package/src/components/popup/popup/popup.vue +95 -0
  104. package/src/components/popup/popup/stories/README.md +34 -0
  105. package/src/components/popup/popup/stories/listItems.vue +44 -0
  106. package/src/components/popup/popup/stories/listSubItems.vue +52 -0
  107. package/src/components/popup/popup/stories/overview.vue +208 -0
  108. package/src/components/popup/popup/style/popup.css +243 -0
  109. package/src/components/popup/popup/style/popup.m.css +71 -0
  110. package/src/components/popup/popup/style/popup.pc.css +28 -0
  111. package/src/components/popup/popup.ts +3 -0
  112. package/src/components/popup/worker.ts +1 -0
  113. package/src/components/tabs/tabs/content.vue +24 -0
  114. package/src/components/tabs/tabs/stories/README.md +10 -0
  115. package/src/components/tabs/tabs/tab.vue +52 -0
  116. package/src/components/tabs/tabs/tabs.stories.ts +171 -0
  117. package/src/components/tabs/tabs/tabs.ts +22 -0
  118. package/src/components/tabs/tabs/tabs.vue +64 -0
  119. package/src/components/tabs/tabs.ts +3 -0
  120. package/src/core/base/Colors.stories.ts +15 -0
  121. package/src/core/base/Layout.stories.ts +15 -0
  122. package/src/core/base/Properties.stories.ts +15 -0
  123. package/src/core/base/base.mdx +21 -0
  124. package/src/core/core/core.ts +144 -0
  125. package/src/core/core/events.ts +54 -0
  126. package/src/core/core/options.ts +15 -0
  127. package/src/core/core/state.ts +44 -0
  128. package/src/core/directives/tooltip.ts +55 -0
  129. package/src/core/theme/Colors.stories.ts +15 -0
  130. package/src/core/theme/Properties.stories.ts +15 -0
  131. package/src/core/theme/theme.mdx +15 -0
  132. package/src/core/utils/date.ts +164 -0
  133. package/src/core/utils/device.ts +48 -0
  134. package/src/core/utils/dom.ts +185 -0
  135. 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
  136. 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
  137. 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
  138. package/src/docs/CSS/FAQ.mdx +43 -0
  139. 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
  140. 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
  141. 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
  142. 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
  143. package/src/docs/CSS//320/241/321/202/320/270/320/273/320/270.md +53 -0
  144. package/src/docs/CSS//320/241/321/202/320/270/320/273/320/270.mdx +4 -0
  145. 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
  146. package/src/docs/ROADMAP.md +17 -0
  147. package/src/docs/Roadmap.mdx +4 -0
  148. 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
  149. 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
  150. 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
  151. 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
  152. 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
  153. 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
  154. package/src/globals.d.ts +1 -0
  155. package/{icomoon → src/resources/icomoon}/demo-files/demo.css +161 -161
  156. package/{icomoon → src/resources/icomoon}/demo-files/demo.js +30 -30
  157. package/{icomoon → src/resources/icomoon}/demo.html +2945 -2945
  158. package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.svg +232 -232
  159. package/{icomoon → src/resources/icomoon}/style.css +647 -647
  160. package/src/resources/styles/core/colors.css +204 -0
  161. package/src/resources/styles/core/components.css +70 -0
  162. package/src/resources/styles/core/core.ts +10 -0
  163. package/src/resources/styles/core/forms/clear.css +19 -0
  164. package/src/resources/styles/core/forms/controls.css +20 -0
  165. package/src/resources/styles/core/forms/focusable.css +26 -0
  166. package/src/resources/styles/core/forms/forms.css +100 -0
  167. package/src/resources/styles/core/icon.css +58 -0
  168. package/src/resources/styles/core/layout.css +40 -0
  169. package/src/resources/styles/core/modifiers/as.css +9 -0
  170. package/src/resources/styles/core/modifiers/ellipsis.css +18 -0
  171. package/src/resources/styles/core/modifiers/modifiers.css +81 -0
  172. package/src/resources/styles/core/modifiers/only.css +19 -0
  173. package/src/resources/styles/core/select.css +16 -0
  174. package/src/resources/styles/jquery-ui.min.css +6 -0
  175. package/src/resources/styles/storybook.css +11 -0
  176. package/src/resources/styles/themes/dark/theme.css +139 -0
  177. package/src/resources/styles/themes/dark.ts +1 -0
  178. package/src/resources/styles/themes/light/theme.css +139 -0
  179. package/src/resources/styles/themes/light.ts +1 -0
  180. package/src/storybook/components/color.vue +45 -0
  181. package/src/storybook/components/colors.vue +34 -0
  182. package/src/storybook/components/icomoon.ts +38 -0
  183. package/src/storybook/components/properties.vue +82 -0
  184. package/src/storybook/resources/accessibility.png +0 -0
  185. package/src/storybook/resources/accessibility.svg +5 -0
  186. package/src/storybook/resources/addon-library.png +0 -0
  187. package/src/storybook/resources/assets.png +0 -0
  188. package/src/storybook/resources/context.png +0 -0
  189. package/src/storybook/resources/discord.svg +15 -0
  190. package/src/storybook/resources/docs.png +0 -0
  191. package/src/storybook/resources/figma-plugin.png +0 -0
  192. package/src/storybook/resources/github.svg +3 -0
  193. package/src/storybook/resources/share.png +0 -0
  194. package/src/storybook/resources/styling.png +0 -0
  195. package/src/storybook/resources/testing.png +0 -0
  196. package/src/storybook/resources/theming.png +0 -0
  197. package/src/storybook/resources/tutorials.svg +12 -0
  198. package/src/storybook/resources/youtube.svg +4 -0
  199. 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
  200. package/tsconfig.json +62 -0
  201. package/vite.config.ts +91 -0
  202. package/.chunks/datepicker-0b648b9f.es.js +0 -275
  203. package/.chunks/datepicker-0b648b9f.es.js.map +0 -1
  204. package/.chunks/datepicker-0e9a0541.amd.js +0 -234
  205. package/.chunks/datepicker-0e9a0541.amd.js.map +0 -1
  206. package/.chunks/forms-02202302.amd.js +0 -3
  207. package/.chunks/forms-02202302.amd.js.map +0 -1
  208. package/.chunks/forms-eb00d0c1.es.js +0 -946
  209. package/.chunks/forms-eb00d0c1.es.js.map +0 -1
  210. package/.chunks/popup-6f73b4b2.es.js +0 -700
  211. package/.chunks/popup-6f73b4b2.es.js.map +0 -1
  212. package/.chunks/popup-e1f34511.amd.js +0 -341
  213. package/.chunks/popup-e1f34511.amd.js.map +0 -1
  214. package/common/common.amd.js +0 -2
  215. package/common/common.amd.js.map +0 -1
  216. package/common/common.js +0 -2
  217. package/common/common.js.map +0 -1
  218. package/core/core.amd.js +0 -2
  219. package/core/core.amd.js.map +0 -1
  220. package/core/core.js +0 -6
  221. package/core/core.js.map +0 -1
  222. package/core.css +0 -1
  223. package/dark.css +0 -1
  224. package/forms/forms.amd.js +0 -2
  225. package/forms/forms.amd.js.map +0 -1
  226. package/forms/forms.js +0 -15
  227. package/forms/forms.js.map +0 -1
  228. package/forms/helpers.amd.js +0 -2
  229. package/forms/helpers.amd.js.map +0 -1
  230. package/forms/helpers.js +0 -9
  231. package/forms/helpers.js.map +0 -1
  232. package/forms.css +0 -1
  233. package/formsExt/formsExt.amd.js +0 -3
  234. package/formsExt/formsExt.amd.js.map +0 -1
  235. package/formsExt/formsExt.js +0 -152
  236. package/formsExt/formsExt.js.map +0 -1
  237. package/formsExt.css +0 -1
  238. package/light.css +0 -1
  239. package/popup/popup.amd.js +0 -3
  240. package/popup/popup.amd.js.map +0 -1
  241. package/popup/popup.js +0 -144
  242. package/popup/popup.js.map +0 -1
  243. package/popup/worker.amd.js +0 -2
  244. package/popup/worker.amd.js.map +0 -1
  245. package/popup/worker.js +0 -154
  246. package/popup/worker.js.map +0 -1
  247. package/popup.css +0 -1
  248. package/tabs/tabs.amd.js +0 -3
  249. package/tabs/tabs.amd.js.map +0 -1
  250. package/tabs/tabs.js +0 -97
  251. package/tabs/tabs.js.map +0 -1
  252. package/tabs.css +0 -1
  253. package/utils/date.amd.js +0 -2
  254. package/utils/date.amd.js.map +0 -1
  255. package/utils/date.js +0 -6
  256. package/utils/date.js.map +0 -1
  257. package/utils/device.amd.js +0 -2
  258. package/utils/device.amd.js.map +0 -1
  259. package/utils/device.js +0 -6
  260. package/utils/device.js.map +0 -1
  261. package/utils/dom.amd.js +0 -2
  262. package/utils/dom.amd.js.map +0 -1
  263. package/utils/dom.js +0 -64
  264. package/utils/dom.js.map +0 -1
  265. /package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.ttf +0 -0
  266. /package/{icomoon → src/resources/icomoon}/fonts/Topvisor-2.woff +0 -0
  267. /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
+ &nbsp;
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,3 @@
1
+ export { default as Tabs } from './tabs/tabs.vue'
2
+ export { default as TabsTab } from './tabs/tab.vue'
3
+ export { default as TabsContent } from './tabs/content.vue'
@@ -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;