From e3d5451d9ae8058bdd721d9163b33c0489676539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 18 Dec 2024 11:23:19 +0500 Subject: [PATCH 1/4] feat: component "Popup" --- README.md | 6 +- src/App.vue | 23 ++++++ src/common/interfaces/componentsProps.ts | 8 +++ src/stories/components/Button/Button.vue | 2 +- src/stories/components/Popup/Popup.stories.ts | 72 +++++++++++++++++++ src/stories/components/Popup/Popup.vue | 71 ++++++++++++++++++ 6 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 src/stories/components/Popup/Popup.stories.ts create mode 100644 src/stories/components/Popup/Popup.vue diff --git a/README.md b/README.md index 1976a8e..bf8163a 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,17 @@ ## СпиÑок компонентов: - TreeList; - MenuDial; +- Popup; - Slider; - Drawer; - Modal; - SelectButton; - Button; - ToggleSwitch; -- Divider; +- Divider. + +## Components count: 10 +## Bundle size: 248.7KB ### ÐаÑтройка Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ diff --git a/src/App.vue b/src/App.vue index 5838a25..d7bf047 100644 --- a/src/App.vue +++ b/src/App.vue @@ -111,6 +111,7 @@ import Slider from '@stories/components/Slider/Slider.vue'; import type { ISBOption } from '@interfaces/componentsProp'; import Modal from '@stories/components/Modal/Modal.vue'; import MenuDial from '@stories/components/MenuDial/MenuDial.vue'; +import Popup from '@stories/components/Popup/Popup.vue'; const gentleIcons = [ Age18Icon, @@ -282,10 +283,32 @@ const visible = ref(false); const onClose = () => console.log('close!'); const value = ref(); const active = ref(false); +const popupActive = ref(false); +const popupActive2 = ref(false); const sliderValue = ref(1); </script> <template> + <div class="hui" style="width: 500px; height: 500px; background-color: gray"></div> + <Popup v-model:active="popupActive" parentSelector=".hui" theme="sky"> + <Button + @click=" + () => { + popupActive = false; + visible = true; + } + " + label="Открыть модальное окно" + /> + </Popup> + <Popup v-model:active="popupActive2" theme="sky" + >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet fugiat harum maiores placeat + soluta, vel velit voluptas. Accusamus aut, error et minima neque praesentium, ratione, + reprehenderit repudiandae saepe ut vero! Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Amet fugiat harum maiores placeat soluta, vel velit voluptas. Accusamus aut, error et + minima neque praesentium, ratione, reprehenderit repudiandae saepe ut vero!</Popup + > + <Modal v-model:visible="visible" theme="red" @onClose="onClose" ><template #header>huuuuuuuuuuui</template>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque explicabo, facere fuga hic id impedit magnam maiores minima necessitatibus, nemo diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts index 8d663ab..8a1459e 100644 --- a/src/common/interfaces/componentsProps.ts +++ b/src/common/interfaces/componentsProps.ts @@ -77,6 +77,14 @@ export interface IModalProps { headerDivider?: boolean; } +export interface IPopupProps { + parentSelector?: string; + theme?: TThemeColor; + maxWidth?: string; + maxHeight?: string; + padding?: string; +} + export interface ISBProps { options: ISBOption[]; size?: TSize; diff --git a/src/stories/components/Button/Button.vue b/src/stories/components/Button/Button.vue index cef4d55..be2e174 100644 --- a/src/stories/components/Button/Button.vue +++ b/src/stories/components/Button/Button.vue @@ -80,7 +80,7 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content')) .button { position: relative; border-radius: 7px; - display: flex; + display: inline-flex; gap: 8px; justify-content: center; align-items: center; diff --git a/src/stories/components/Popup/Popup.stories.ts b/src/stories/components/Popup/Popup.stories.ts new file mode 100644 index 0000000..c8d3e5c --- /dev/null +++ b/src/stories/components/Popup/Popup.stories.ts @@ -0,0 +1,72 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import Popup from './Popup.vue'; +import Button from '@stories/components/Button/Button.vue'; + +const meta: Meta = { + title: 'Components/Popup', + component: Popup, + tags: ['autodocs'], + parameters: { + docs: { + description: { + component: 'A component that is used as a Popup. Can be used with icon.', + }, + }, + }, + argTypes: { + default: { control: 'text' }, + parentSelector: { control: 'text' }, + maxWidth: { control: 'text' }, + maxHeight: { control: 'text' }, + padding: { control: 'text' }, + theme: { + control: 'select', + options: [ + 'white', + 'slate', + 'blue', + 'sky', + 'teal', + 'green', + 'yellow', + 'orange', + 'pink', + 'fuchsia', + 'purple', + 'indigo', + 'rose', + 'red', + 'black', + ], + }, + }, + args: {}, +} satisfies Meta<typeof Popup>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Primary: Story = { + args: { + default: + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet fugiat harum maiores placeat\n soluta, vel velit voluptas. Accusamus aut, error et minima neque praesentium, ratione,\n reprehenderit repudiandae saepe ut vero! Lorem ipsum dolor sit amet, consectetur adipisicing\n elit. Amet fugiat harum maiores placeat soluta, vel velit voluptas. Accusamus aut, error et\n minima neque praesentium, ratione, reprehenderit repudiandae saepe ut vero!', + maxWidth: '200px', + maxHeight: '100px', + }, +}; + +export const Full: Story = { + render: (args) => ({ + components: { Popup, Button }, + setup() { + return { args }; + }, + template: + '<Popup v-bind="args"><Button label="Создать" theme="sky" /><p style="display: inline-block; padding: 0 30px"></p><Button label="Удалить" theme="red" /></Popup>', + }), + args: { + theme: 'black', + }, +}; diff --git a/src/stories/components/Popup/Popup.vue b/src/stories/components/Popup/Popup.vue new file mode 100644 index 0000000..a9eb103 --- /dev/null +++ b/src/stories/components/Popup/Popup.vue @@ -0,0 +1,71 @@ +<script setup lang="ts"> +import type { IPopupProps } from '@interfaces/componentsProps'; +import { computed, ref } from 'vue'; +import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors'; + +const props = withDefaults(defineProps<IPopupProps>(), { + parentSelector: 'body', + theme: 'white', + maxWidth: '300px', + maxHeight: '100px', + padding: '5px', +}); +const active = defineModel<boolean>('active'); +const themeColor = computed(() => convert500ThemeToColor(props.theme)); +const scrollColor = computed(() => convert300ThemeToColor(props.theme)); + +const top = ref(); +const left = ref(); +const isContainer = ref(); + +const container = document.querySelector(props.parentSelector); +if (container) { + container.addEventListener('pointerdown', (e) => { + if (e.button === 2) { + console.log('e.clientY, e.clientX ', e.clientY, e.clientX); + isContainer.value = true; + if (!active.value) active.value = true; + top.value = e.clientY; + left.value = e.clientX; + e.stopPropagation(); + } + }); + container.addEventListener('contextmenu', (e) => { + if (isContainer.value) e.preventDefault(); + }); +} + +document.addEventListener('pointerdown', (e) => { + if (e.button === 0) active.value = false; +}); +</script> + +<template> + <section + oncontextmenu="return false" + id="popup" + @pointerdown.stop="" + :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}`" + > + <div :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto;`"> + <slot /> + <p v-if="!$slots.default" style="background-color: black; color: white; padding: 10px"> + Popup + </p> + </div> + </section> +</template> + +<style scoped> +#popup { + position: fixed; + transition: opacity 0.2s ease-in-out; + background-color: v-bind(themeColor); + border: 1px solid #403e46; + border-radius: 5px; +} +::-webkit-scrollbar-thumb { + border-radius: 5px; + background-color: v-bind(scrollColor); +} +</style> -- GitLab From a8c3443a36a6f470bc64d092ac76eacc346e82a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 18 Dec 2024 17:11:04 +0500 Subject: [PATCH 2/4] refactor: favicon --- .storybook/manager-head.html | 2 +- index.html | 2 +- public/storybook.ico | Bin 218174 -> 0 bytes public/storybook.svg | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 public/storybook.ico create mode 100644 public/storybook.svg diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html index 657a1b8..2634a89 100644 --- a/.storybook/manager-head.html +++ b/.storybook/manager-head.html @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="UTF-8"> - <link rel="icon" href="./storybook.ico"> + <link rel="icon" href="./storybook.svg"> <title>Storybook</title> </head> <body> diff --git a/index.html b/index.html index 0ab5bb4..dcb9d19 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ <html lang=""> <head> <meta charset="UTF-8"> - <link rel="icon" href="/storybook.ico"> + <link rel="icon" href="/storybook.svg"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>UI Storybook</title> </head> diff --git a/public/storybook.ico b/public/storybook.ico deleted file mode 100644 index 690ee543d1b7a8d727252f9d278e2538ad02a61f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218174 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	P{zbzWB(J& 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 diff --git a/public/storybook.svg b/public/storybook.svg new file mode 100644 index 0000000..63075c1 --- /dev/null +++ b/public/storybook.svg @@ -0,0 +1 @@ +<svg height="319" preserveAspectRatio="xMidYMid" viewBox="0 0 256 319" width="256" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="m9.87245893 293.324145-9.86099779-262.7509283c-.3256701-8.6776325 6.32802782-16.0318249 14.99485846-16.5735018l223.4880694-13.96800436c8.821799-.55136241 16.420248 6.15315109 16.971611 14.97495016.020773.3323713.031167.6653101.031167.99833v286.3136053c0 8.839012-7.165435 16.004447-16.004448 16.004447-.239453 0-.478875-.005374-.718087-.016117l-213.6270715-9.594673c-8.3199296-.373675-14.9627611-7.06565-15.27510157-15.388108z"/><mask id="b" fill="#fff"><use fill="#fff" xlink:href="#a"/></mask></defs><use fill="#ff4785" xlink:href="#a"/><path d="m188.665358 39.126973 1.526545-36.71548766 30.691632-2.41148534 1.32222 37.8634126c.046016 1.317734-.984915 2.423272-2.302649 2.4692883-.564237.0197036-1.117199-.1611913-1.560697-.5105633l-11.83568-9.323726-14.013155 10.6298328c-1.050497.7968662-2.548081.5912577-3.344947-.4592396-.335442-.4422072-.506327-.9874722-.483269-1.5420318zm-39.251655 80.853336c0 6.226666 41.941975 3.242387 47.572316-1.131416 0-42.4021104-22.751978-64.6837519-64.414689-64.6837519-41.6627118 0-65.0056495 22.6283131-65.0056495 56.5707999 0 59.116499 79.7796605 60.247915 79.7796605 92.493278 0 9.05133-4.432203 14.425558-14.18305 14.425558-12.70565 0-17.728814-6.488863-17.137853-28.551479 0-4.786197-48.4587575-6.278336-49.9361587 0-3.7620647 53.465572 29.5480226 68.887096 67.6649717 68.887096 36.935028 0 65.89209-19.687271 65.89209-55.326883 0-63.359309-80.961582-61.662185-80.961582-93.058985 0-12.7284338 9.455368-14.425558 15.069492-14.425558 5.909604 0 16.546892 1.0415999 15.660452 24.801341z" fill="#fff" mask="url(#b)"/></svg> \ No newline at end of file -- GitLab From ea28f7472cb7a70cb0401fa29cfb6c0324c03641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 18 Dec 2024 17:26:33 +0500 Subject: [PATCH 3/4] docs: edit README.md --- README.md | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index bf8163a..0866e44 100644 --- a/README.md +++ b/README.md @@ -16,29 +16,40 @@ - ToggleSwitch; - Divider. -## Components count: 10 -## Bundle size: 248.7KB - -### ÐаÑтройка Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ - +--- +## ÐžÐ±Ñ‰Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ +### Components count: 10 +### Bundle size: 254.6KB +--- +## Важные моменты при разработке +### Общее начало шаблона Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð¾Ð²: +``` +const props = withDefaults(defineProps<IProps>(), { + +}); +const emit = defineEmits(['']); +const visible = defineModel(''); +watch(, () => {}); +const computed = computed(() => ); +``` +- I*Componentname*Props вмеÑто ```IProps```; +- watchers поÑле defineModel; +- далее - computeds; +- затем - функции (handlers). +### ПоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¸: +1. Добавить иконку в iconsSet (src/common/constants/icons); +2. Добавить иконку в ÑоответÑтвующий маÑÑив в App.vue. +--- +## ÐаÑтройка Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ +### УÑтановка завиÑимоÑтей: ```sh yarn ``` - -### ПроÑмотр ÑущеÑтвующих иконок в виде ÑпиÑка и теÑтирование компонентов - +### ПроÑмотр ÑущеÑтвующих иконок в виде ÑпиÑка и теÑтирование компонентов: ```sh yarn dev ``` - -### Проверка типов, компилÑÑ†Ð¸Ñ Ð¸ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ production - +### Проверка типов, компилÑÑ†Ð¸Ñ Ð¸ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ production: ```sh yarn build -``` - -## Важные моменты при разработке - -ПоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¸: -1. Добавить иконку в iconsSet (src/common/constants/icons); -2. Добавить иконку в ÑоответÑтвующий маÑÑив в App.vue. \ No newline at end of file +``` \ No newline at end of file -- GitLab From cfe12013d0a726c69fed391f129560b765606598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 18 Dec 2024 17:30:42 +0500 Subject: [PATCH 4/4] refactor: change color logic and fix some problems of components --- src/App.vue | 4 +- src/assets/main.css | 9 + src/common/helpers/colors.ts | 276 +++++++++++++++++- src/common/helpers/common.ts | 28 ++ src/common/interfaces/common.ts | 10 +- src/common/interfaces/componentsProp.ts | 22 +- src/common/interfaces/componentsProps.ts | 39 ++- .../components/Button/Button.stories.ts | 12 +- src/stories/components/Button/Button.vue | 15 +- .../components/Divider/Divider.stories.ts | 3 +- src/stories/components/Divider/Divider.vue | 5 +- .../components/Drawer/Drawer.stories.ts | 3 +- src/stories/components/Drawer/Drawer.vue | 35 ++- .../components/MenuDial/MenuDial.stories.ts | 53 +++- src/stories/components/MenuDial/MenuDial.vue | 24 +- src/stories/components/Modal/Modal.stories.ts | 3 +- src/stories/components/Modal/Modal.vue | 31 +- src/stories/components/Popup/Popup.stories.ts | 3 +- src/stories/components/Popup/Popup.vue | 33 ++- .../SelectButton/SelectButton.stories.ts | 13 +- .../components/SelectButton/SelectButton.vue | 22 +- .../components/Slider/Slider.stories.ts | 9 +- src/stories/components/Slider/Slider.vue | 14 +- .../ToggleSwitch/ToggleSwitch.stories.ts | 14 +- .../components/ToggleSwitch/ToggleSwitch.vue | 11 +- src/stories/components/TreeList/TreeItems.vue | 12 +- .../components/TreeList/TreeList.stories.ts | 6 +- src/stories/components/TreeList/TreeList.vue | 11 +- 28 files changed, 592 insertions(+), 128 deletions(-) create mode 100644 src/common/helpers/common.ts diff --git a/src/App.vue b/src/App.vue index d7bf047..ad430e4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -108,7 +108,7 @@ import ToggleSwitch from '@stories/components/ToggleSwitch/ToggleSwitch.vue'; import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue'; import Button from '@stories/components/Button/Button.vue'; import Slider from '@stories/components/Slider/Slider.vue'; -import type { ISBOption } from '@interfaces/componentsProp'; +import type { ISBOption, ISliderOptions } from '@interfaces/componentsProp'; import Modal from '@stories/components/Modal/Modal.vue'; import MenuDial from '@stories/components/MenuDial/MenuDial.vue'; import Popup from '@stories/components/Popup/Popup.vue'; @@ -219,7 +219,7 @@ const gentleIcons = [ UserIcon, ]; const visibleDrawer = ref(true); -const sliderOptions = [ +const sliderOptions: ISliderOptions[] = [ { label: 0, value: 0, diff --git a/src/assets/main.css b/src/assets/main.css index 7b91d0d..21b455a 100644 --- a/src/assets/main.css +++ b/src/assets/main.css @@ -82,6 +82,15 @@ --teal-700: #0f766e; --teal-800: #115e59; --teal-900: #134e4a; + --cyan-100: #cffafe; + --cyan-200: #a5f3fc; + --cyan-300: #67e8f9; + --cyan-400: #22d3ee; + --cyan-500: #06b6d4; + --cyan-600: #0891b2; + --cyan-700: #0e7490; + --cyan-800: #155e75; + --cyan-900: #164e63; --sky-100: #e0f2fe; --sky-200: #bae6fd; --sky-300: #7dd3fc; diff --git a/src/common/helpers/colors.ts b/src/common/helpers/colors.ts index 5ec5279..74a597b 100644 --- a/src/common/helpers/colors.ts +++ b/src/common/helpers/colors.ts @@ -1,13 +1,106 @@ -export const convert300ThemeToColor = (theme: string | undefined) => { +import type { TDarkness, TThemeColor } from '@interfaces/common'; + +export const convertWhiteOrBlackToColor = (theme: 'white' | 'black', darkness: TDarkness) => { + if (theme === 'white') { + if (darkness === 500 || darkness === 400 || darkness === 600) return '#cbd5e1'; + if (darkness === 300 || darkness === 700) return '#94a3b8'; + if (darkness === 200 || darkness === 800) return '#f1f5f9'; + if (darkness === 100 || darkness === 900) return '#e2e8f0'; + } + if (darkness === 500 || darkness === 400 || darkness === 600) return '#475569'; + if (darkness === 300 || darkness === 700) return '#64748b'; + if (darkness === 200 || darkness === 800) return '#94a3b8'; + if (darkness === 100 || darkness === 900) return '#cbd5e1'; +}; + +export const convert100ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#9ca3af'; + case 'blue': + return '#dbeafe'; + case 'sky': + return '#e0f2fe'; + case 'cyan': + return '#cffafe'; + case 'teal': + return '#ccfbf1'; + case 'lime': + return '#ecfccb'; + case 'green': + return '#dcfce7'; + case 'yellow': + return '#fef9c3'; + case 'amber': + return '#fef3c7'; + case 'orange': + return '#ffedd5'; + case 'pink': + return '#fce7f3'; + case 'fuchsia': + return '#fae8ff'; + case 'purple': + return '#f3e8ff'; + case 'indigo': + return '#e0e7ff'; + case 'rose': + return '#ffe4e6'; + case 'red': + return '#fee2e2'; + case 'black': + return '#4b5563'; + } +}; + +export const convert200ThemeToColor = (theme: TThemeColor) => { switch (theme) { case 'white': - return '#cbd5e1'; - case 'slate': - return '#cbd5e1'; + return '#d1d5db'; + case 'blue': + return '#bfdbfe'; + case 'sky': + return '#bae6fd'; + case 'cyan': + return '#a5f3fc'; + case 'teal': + return '#99f6e4'; + case 'lime': + return '#d9f99d'; + case 'green': + return '#bbf7d0'; + case 'yellow': + return '#fef08a'; + case 'amber': + return '#fde68a'; + case 'orange': + return '#fed7aa'; + case 'pink': + return '#fbcfe8'; + case 'fuchsia': + return '#f5d0fe'; + case 'purple': + return '#e9d5ff'; + case 'indigo': + return '#c7d2fe'; + case 'rose': + return '#fecdd3'; + case 'red': + return '#fecaca'; + case 'black': + return '#374151'; + } +}; + +export const convert300ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#e5e7eb'; case 'blue': return '#93c5fd'; case 'sky': return '#7dd3fc'; + case 'cyan': + return '#67e8f9'; case 'teal': return '#5eead4'; case 'lime': @@ -33,20 +126,59 @@ export const convert300ThemeToColor = (theme: string | undefined) => { case 'red': return '#fca5a5'; case 'black': - return '#334155'; + return '#1f2937'; + } +}; + +export const convert400ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#f3f4f6'; + case 'blue': + return '#60a5fa'; + case 'sky': + return '#38bdf8'; + case 'cyan': + return '#22d3ee'; + case 'teal': + return '#2dd4bf'; + case 'lime': + return '#a3e635'; + case 'green': + return '#4ade80'; + case 'yellow': + return '#facc15'; + case 'amber': + return '#fbbf24'; + case 'orange': + return '#fb923c'; + case 'pink': + return '#f472b6'; + case 'fuchsia': + return '#e879f9'; + case 'purple': + return '#c084fc'; + case 'indigo': + return '#818cf8'; + case 'rose': + return '#fb7185'; + case 'red': + return '#f87171'; + case 'black': + return '#111827'; } }; -export const convert500ThemeToColor = (theme: string | undefined) => { +export const convert500ThemeToColor = (theme: TThemeColor) => { switch (theme) { case 'white': return '#ffffff'; - case 'slate': - return '#64748b'; case 'blue': return '#3b82f6'; case 'sky': return '#0ea5e9'; + case 'cyan': + return '#06b6d4'; case 'teal': return '#14b8a6'; case 'lime': @@ -74,19 +206,96 @@ export const convert500ThemeToColor = (theme: string | undefined) => { case 'black': return '#000000'; } - return '#000000'; }; -export const convert800ThemeToColor = (theme: string | undefined) => { +export const convert600ThemeToColor = (theme: TThemeColor) => { switch (theme) { case 'white': - return '#ffffff'; - case 'slate': - return '#1e293b'; + return '#f3f4f6'; + case 'blue': + return '#2563eb'; + case 'sky': + return '#0284c7'; + case 'cyan': + return '#0891b2'; + case 'teal': + return '#0d9488'; + case 'lime': + return '#65a30d'; + case 'green': + return '#16a34a'; + case 'yellow': + return '#ca8a04'; + case 'amber': + return '#d97706'; + case 'orange': + return '#ea580c'; + case 'pink': + return '#db2777'; + case 'fuchsia': + return '#c026d3'; + case 'purple': + return '#9333ea'; + case 'indigo': + return '#4f46e5'; + case 'rose': + return '#e11d48'; + case 'red': + return '#dc2626'; + case 'black': + return '#111827'; + } +}; + +export const convert700ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#e5e7eb'; + case 'blue': + return '#1d4ed8'; + case 'sky': + return '#0369a1'; + case 'cyan': + return '#0e7490'; + case 'teal': + return '#0f766e'; + case 'lime': + return '#4d7c0f'; + case 'green': + return '#15803d'; + case 'yellow': + return '#a16207'; + case 'amber': + return '#b45309'; + case 'orange': + return '#c2410c'; + case 'pink': + return '#be185d'; + case 'fuchsia': + return '#a21caf'; + case 'purple': + return '#7e22ce'; + case 'indigo': + return '#4338ca'; + case 'rose': + return '#be123c'; + case 'red': + return '#b91c1c'; + case 'black': + return '#1f2937'; + } +}; + +export const convert800ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#d1d5db'; case 'blue': return '#1e40af'; case 'sky': return '#075985'; + case 'cyan': + return '#155e75'; case 'teal': return '#115e59'; case 'lime': @@ -112,6 +321,45 @@ export const convert800ThemeToColor = (theme: string | undefined) => { case 'red': return '#991b1b'; case 'black': - return '#000000'; + return '#374151'; + } +}; + +export const convert900ThemeToColor = (theme: TThemeColor) => { + switch (theme) { + case 'white': + return '#9ca3af'; + case 'blue': + return '#1e3a8a'; + case 'sky': + return '#0c4a6e'; + case 'cyan': + return '#164e63'; + case 'teal': + return '#134e4a'; + case 'lime': + return '#365314'; + case 'green': + return '#14532d'; + case 'yellow': + return '#713f12'; + case 'amber': + return '#78350f'; + case 'orange': + return '#7c2d12'; + case 'pink': + return '#831843'; + case 'fuchsia': + return '#701a75'; + case 'purple': + return '#581c87'; + case 'indigo': + return '#312e81'; + case 'rose': + return '#881337'; + case 'red': + return '#7f1d1d'; + case 'black': + return '#4b5563'; } }; diff --git a/src/common/helpers/common.ts b/src/common/helpers/common.ts new file mode 100644 index 0000000..e4ec1fb --- /dev/null +++ b/src/common/helpers/common.ts @@ -0,0 +1,28 @@ +import type { TDarkness, TThemeColor } from '@interfaces/common'; +import { + convert100ThemeToColor, + convert200ThemeToColor, + convert300ThemeToColor, + convert400ThemeToColor, + convert500ThemeToColor, + convert600ThemeToColor, + convert700ThemeToColor, + convert800ThemeToColor, + convert900ThemeToColor, +} from '@helpers/colors'; + +export const convertThemeToColor = ( + theme: TThemeColor, + darkness: TDarkness | number = 500, +): string => { + if (darkness === 500) return convert500ThemeToColor(theme); + if (darkness === 100) return convert100ThemeToColor(theme); + if (darkness === 200) return convert200ThemeToColor(theme); + if (darkness === 300) return convert300ThemeToColor(theme); + if (darkness === 400) return convert400ThemeToColor(theme); + if (darkness === 600) return convert600ThemeToColor(theme); + if (darkness === 700) return convert700ThemeToColor(theme); + if (darkness === 800) return convert800ThemeToColor(theme); + if (darkness === 900) return convert900ThemeToColor(theme); + return convert500ThemeToColor(theme); +}; diff --git a/src/common/interfaces/common.ts b/src/common/interfaces/common.ts index 7ff7e70..6a854a8 100644 --- a/src/common/interfaces/common.ts +++ b/src/common/interfaces/common.ts @@ -1,13 +1,17 @@ import type { iconsSet } from '@/common/constants/icons'; +export type TIcons = keyof typeof iconsSet; + export type TThemeColor = | 'white' - | 'slate' | 'blue' | 'sky' + | 'cyan' | 'teal' + | 'lime' | 'green' | 'yellow' + | 'amber' | 'orange' | 'pink' | 'fuchsia' @@ -17,6 +21,8 @@ export type TThemeColor = | 'red' | 'black'; +export type TDarkness = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900; + export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>; export type TSize = 'small' | 'medium' | 'large' | 'huge'; @@ -30,5 +36,3 @@ export type TPosition = 'top' | 'right' | 'bottom' | 'left'; export type TExpandedPosition = TPosition | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; export type TBorder = 'solid' | 'dashed' | 'dotted'; - -export type TIcons = keyof typeof iconsSet; diff --git a/src/common/interfaces/componentsProp.ts b/src/common/interfaces/componentsProp.ts index 1f0e3c3..aa30d5c 100644 --- a/src/common/interfaces/componentsProp.ts +++ b/src/common/interfaces/componentsProp.ts @@ -1,4 +1,4 @@ -import type { TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common'; +import type { TDarkness, TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common'; export interface ITreeItem { label: string; @@ -11,22 +11,38 @@ export interface ITreeItem { iconAfter?: TIcons; iconColor?: TThemeColor; children?: ITreeItem[]; + darknessColor?: TDarkness; + darknessIconColor?: TDarkness; isLinkClicked?: boolean; } +export interface IMDItemProps { + label: string; + theme?: TThemeColor; + darknessTheme?: TDarkness; + textStyle?: TTextStyle; + link?: string; + linkBlank?: boolean; + onClick?: () => void; +} + export interface ISBOption { label: string; value?: never; color?: TThemeColor; activeColor?: TThemeColor; backgroundColor?: TThemeColor; + darknessColor?: TDarkness; + darknessActiveColor?: TDarkness; + darknessBackgroundColor?: TDarkness; isLabelHidden?: boolean; iconPosition?: TPosition; textStyle?: TTextStyle; } export interface ISliderOptions { - label: string | number; + label: string | number | boolean; value?: string | number; - color?: string; + color?: TThemeColor; + darknessColor?: TDarkness; } diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts index 8a1459e..c80425a 100644 --- a/src/common/interfaces/componentsProps.ts +++ b/src/common/interfaces/componentsProps.ts @@ -1,5 +1,6 @@ import type { TBorder, + TDarkness, TDirection, TExpandedPosition, TIcons, @@ -9,13 +10,19 @@ import type { TThemeColor, TThemeColorNoWhite, } from '@interfaces/common'; -import type { ISBOption, ISliderOptions, ITreeItem } from '@interfaces/componentsProp'; +import type { + IMDItemProps, + ISBOption, + ISliderOptions, + ITreeItem, +} from '@interfaces/componentsProp'; export interface ITLProps { items: ITreeItem[]; maxWidth?: number; expand?: boolean; theme?: TThemeColor; + darknessTheme?: TDarkness; } export interface ITIProps { @@ -24,21 +31,15 @@ export interface ITIProps { label: string; }[]; items: ITreeItem[]; - textColor: TThemeColor; + textColor: string; themeColor: string; } export interface IMDProps { - items: { - label: string; - theme?: string; - textStyle?: TTextStyle; - link?: string; - linkBlank?: boolean; - onClick?: () => void; - }[]; + items: IMDItemProps[]; size?: TSize; - theme?: string; + theme?: TThemeColor; + darknessTheme?: TDarkness; direction?: TDirection; // direction?: TDirection | 'circle'; } @@ -51,6 +52,8 @@ export interface ISliderProps { size?: TSize; theme?: TThemeColor; backgroundColor?: TThemeColor; + darknessTheme?: TDarkness; + darknessBackgroundColor?: TDarkness; orientation?: 'horizontal' | 'vertical'; isSmooth?: boolean; options?: ISliderOptions[]; @@ -60,6 +63,7 @@ export interface IDrawerProps { position?: TPosition; width?: string | number; theme?: TThemeColor; + darknessTheme?: TDarkness; modal?: boolean; dismissible?: boolean; closeIcon?: TIcons; @@ -69,6 +73,7 @@ export interface IDrawerProps { export interface IModalProps { theme?: TThemeColor; + darknessTheme?: TDarkness; width?: string; height?: string; position?: TExpandedPosition; @@ -80,6 +85,7 @@ export interface IModalProps { export interface IPopupProps { parentSelector?: string; theme?: TThemeColor; + darknessTheme?: TDarkness; maxWidth?: string; maxHeight?: string; padding?: string; @@ -91,6 +97,8 @@ export interface ISBProps { rounded?: boolean; activeBackgroundColor?: TThemeColor; border?: TThemeColor; + darknessActiveBackgroundColor?: TDarkness; + darknessBorder?: TDarkness; disabled?: boolean; } @@ -100,17 +108,21 @@ export interface IButtonProps { textStyle?: TTextStyle; iconPos?: TPosition; width?: string | number; + iconOnly?: boolean; theme?: TThemeColor; textColor?: TThemeColor; border?: TThemeColor; - iconOnly?: boolean; + darknessTheme?: TDarkness; + darknessTextColor?: TDarkness; + darknessBorder?: TDarkness; } export interface ITSProps { size?: TSize; theme?: TThemeColorNoWhite; negativeTheme?: TThemeColor; - darkNegative?: boolean; + darknessTheme?: TDarkness; + darknessNegativeTheme?: TDarkness; disabled?: boolean; } @@ -118,4 +130,5 @@ export interface IDividerProps { height?: number; type?: TBorder; color?: TThemeColor; + darknessColor?: TDarkness; } diff --git a/src/stories/components/Button/Button.stories.ts b/src/stories/components/Button/Button.stories.ts index bdbacf4..337bc5b 100644 --- a/src/stories/components/Button/Button.stories.ts +++ b/src/stories/components/Button/Button.stories.ts @@ -19,13 +19,19 @@ const meta: Meta = { textStyle: { control: 'select', options: ['bold', 'italic'] }, iconPos: { control: 'select', options: ['left', 'top', 'right', 'bottom'] }, width: { control: 'text' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, + darknessTextColor: { + control: 'select', + options: [100, 200, 300, 400, 500, 600, 700, 800, 900], + }, + darknessBorder: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -43,9 +49,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -63,9 +69,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Button/Button.vue b/src/stories/components/Button/Button.vue index be2e174..45df8f5 100644 --- a/src/stories/components/Button/Button.vue +++ b/src/stories/components/Button/Button.vue @@ -1,18 +1,25 @@ <script setup lang="ts"> import { computed } from 'vue'; -import { convert500ThemeToColor } from '@helpers/colors'; import type { IButtonProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<IButtonProps>(), { size: 'medium', theme: 'white', textColor: 'black', iconPos: 'left', + darknessTheme: 500, + darknessTextColor: 500, + darknessBorder: 500, }); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const textColorComputed = computed(() => convert500ThemeToColor(props.textColor)); -const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : '')); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const textColorComputed = computed(() => + convertThemeToColor(props.textColor, props.darknessTextColor), +); +const borderColor = computed(() => + !props.border ? '' : convertThemeToColor(props.border, props.darknessBorder), +); const textSize = computed(() => { switch (props.size) { case 'small': diff --git a/src/stories/components/Divider/Divider.stories.ts b/src/stories/components/Divider/Divider.stories.ts index b7a6350..960e6f5 100644 --- a/src/stories/components/Divider/Divider.stories.ts +++ b/src/stories/components/Divider/Divider.stories.ts @@ -16,13 +16,14 @@ const meta: Meta = { argTypes: { height: { control: 'number' }, type: { control: 'select', options: ['solid', 'dashed', 'dotted'] }, + darknessColor: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, color: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Divider/Divider.vue b/src/stories/components/Divider/Divider.vue index 54164cd..b195e97 100644 --- a/src/stories/components/Divider/Divider.vue +++ b/src/stories/components/Divider/Divider.vue @@ -1,14 +1,15 @@ <script setup lang="ts"> import { computed } from 'vue'; -import { convert500ThemeToColor } from '@helpers/colors'; import type { IDividerProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<IDividerProps>(), { height: 1, type: 'solid', color: 'black', + darknessColor: 500, }); -const colorConverted = computed(() => convert500ThemeToColor(props.color)); +const colorConverted = computed(() => convertThemeToColor(props.color, props.darknessColor)); </script> <template> diff --git a/src/stories/components/Drawer/Drawer.stories.ts b/src/stories/components/Drawer/Drawer.stories.ts index cd0c0de..9cfdc30 100644 --- a/src/stories/components/Drawer/Drawer.stories.ts +++ b/src/stories/components/Drawer/Drawer.stories.ts @@ -26,13 +26,14 @@ const meta: Meta = { closeIcon: { control: 'select', options: Object.keys(iconsSet) }, headerDivider: { control: 'boolean' }, footerDivider: { control: 'boolean' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Drawer/Drawer.vue b/src/stories/components/Drawer/Drawer.vue index 913796f..1656f88 100644 --- a/src/stories/components/Drawer/Drawer.vue +++ b/src/stories/components/Drawer/Drawer.vue @@ -1,8 +1,9 @@ <script setup lang="ts"> -import { computed } from 'vue'; +import { computed, watch } from 'vue'; import { iconsSet } from '@/common/constants/icons'; -import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors'; +import { convertWhiteOrBlackToColor } from '@helpers/colors'; import type { IDrawerProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<IDrawerProps>(), { visible: false, @@ -11,25 +12,37 @@ const props = withDefaults(defineProps<IDrawerProps>(), { modal: true, dismissible: true, theme: 'white', + darknessTheme: 500, closeIcon: 'CrossIcon', headerDivider: false, footerDivider: false, }); +const body = document.querySelector('body')!; const emit = defineEmits(['onClose']); const visible = defineModel<boolean>('visible', { set(value) { if (!value) { + body.style.overflow = 'auto'; emit('onClose'); } return value; }, }); - -const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const scrollColor = computed(() => convert300ThemeToColor(props.theme)); +watch(visible, () => { + if (visible.value) { + body.style.overflow = 'hidden'; + } +}); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const scrollAndBorderColor = computed(() => + props.theme === 'white' || props.theme === 'black' + ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme) + : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)), +); const textColor = computed(() => { - if (!props.theme || props.theme === 'white') return 'black'; - return 'white'; + if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black')) + return '#000000'; + return '#ffffff'; }); const drawerWidth = computed(() => { if (+props.width < 200) return '200px'; @@ -46,7 +59,7 @@ const drawerWidth = computed(() => { drawerBackgroundOpened: visible, }, ]" - @click.prevent="dismissible ? (visible = false) : ''" + @pointerdown.stop="dismissible ? (visible = false) : ''" ></section> <section :style="`color: ${textColor}; background-color: ${themeColor}`" @@ -108,7 +121,7 @@ const drawerWidth = computed(() => { justify-content: space-between; padding: 20px; transition: transform ease-out 0.2s; - border-right: 2px solid #b1b1b1; + border-right: 2px solid v-bind(scrollAndBorderColor); } .drawerVertical { width: 100vw !important; @@ -158,7 +171,7 @@ const drawerWidth = computed(() => { } .divider { height: 2px; - background-color: v-bind(scrollColor); + background-color: v-bind(scrollAndBorderColor); } .divider-header { position: absolute; @@ -176,6 +189,6 @@ const drawerWidth = computed(() => { } ::-webkit-scrollbar-thumb { border-radius: 5px; - background-color: v-bind(scrollColor); + background-color: v-bind(scrollAndBorderColor); } </style> diff --git a/src/stories/components/MenuDial/MenuDial.stories.ts b/src/stories/components/MenuDial/MenuDial.stories.ts index a91196a..1fb7c18 100644 --- a/src/stories/components/MenuDial/MenuDial.stories.ts +++ b/src/stories/components/MenuDial/MenuDial.stories.ts @@ -16,14 +16,15 @@ const meta: Meta = { argTypes: { items: { control: 'object' }, size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] }, - direction: { control: 'select', options: ['top', 'bottom', 'left', 'right'] }, + direction: { control: 'select', options: ['up', 'down', 'left', 'right'] }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -79,3 +80,51 @@ export const Full: Story = { theme: 'sky', }, }; + +export const Down: Story = { + args: { + items: [ + { + label: 'font-family link', + theme: 'green', + darknessTheme: 700, + link: 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family', + linkBlank: true, + }, + { + label: 'Second', + theme: 'green', + darknessTheme: 800, + textStyle: 'italic', + }, + ], + theme: 'red', + darknessTheme: 700, + direction: 'down', + }, +}; + +export const Huge: Story = { + args: { + items: [ + { + label: 'font-family link', + theme: 'green', + darknessTheme: 700, + link: 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family', + linkBlank: true, + }, + { + label: 'Second', + theme: 'green', + darknessTheme: 800, + textStyle: 'italic', + }, + ], + + theme: 'red', + darknessTheme: 700, + direction: 'right', + size: 'medium', + }, +}; diff --git a/src/stories/components/MenuDial/MenuDial.vue b/src/stories/components/MenuDial/MenuDial.vue index 5b54129..933d5f1 100644 --- a/src/stories/components/MenuDial/MenuDial.vue +++ b/src/stories/components/MenuDial/MenuDial.vue @@ -1,21 +1,29 @@ <script setup lang="ts"> import { computed } from 'vue'; import type { IMDProps } from '@interfaces/componentsProps'; -import { convert500ThemeToColor } from '@helpers/colors'; import PlusIcon from '@stories/icons/Mono/PlusIcon.vue'; +import { convertThemeToColor } from '@helpers/common'; +import { convertWhiteOrBlackToColor } from '@helpers/colors'; const props = withDefaults(defineProps<IMDProps>(), { theme: 'white', + darknessTheme: 500, size: 'medium', direction: 'right', }); const active = defineModel('active'); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const textColor = computed(() => { - if (props.theme === 'white') return '#000000'; + if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black')) + return '#000000'; return '#ffffff'; }); +const borderColor = computed(() => + props.theme === 'white' || props.theme === 'black' + ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme) + : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)), +); const elementsSize = computed(() => { switch (props.size) { case 'small': @@ -34,7 +42,7 @@ const menuListStyles = computed(() => { case 'up': return `flex-direction: column-reverse; transform: translateY(-${active.value ? (0.5 + props.items.length) * elementsSize.value + 15 : 1.5 * elementsSize.value}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`; case 'down': - return `flex-direction: column; transform: translateY(${active.value ? 25 : -20}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`; + return `flex-direction: column; transform: translateY(${active.value ? elementsSize.value / 1.75 : -20}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`; } return `transform: translateY(-${elementsSize.value / 2}px) translateX(${active.value ? elementsSize.value + 10 : -20}px)`; }); @@ -60,7 +68,7 @@ const openLink = (url: string, isBlank: boolean | undefined) => <template> <section class="menuContainer"> <button - :style="`border: ${theme === 'white' ? '2px solid black' : ''}; background-color: ${themeColor ?? 'white'}; width: ${elementsSize}px; height: ${elementsSize}px; transform: ${active ? 'rotate(135deg)' : ''};`" + :style="`border: 2px solid ${borderColor}; background-color: ${themeColor ?? 'white'}; width: ${elementsSize}px; height: ${elementsSize}px; transform: ${active ? 'rotate(135deg)' : ''};`" class="menuButton" @click.prevent="active = !active" > @@ -80,8 +88,8 @@ const openLink = (url: string, isBlank: boolean | undefined) => <li v-for="(item, index) of items" :key="item.label" - :style="`height: ${elementsSize}px; background-color: ${convert500ThemeToColor(item.theme ?? 'white')}; - color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'}; border-color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'};`" + :style="`height: ${elementsSize}px; background-color: ${convertThemeToColor(item.theme ?? 'white', item.darknessTheme ?? 500)}; + color: ${item.theme === 'white' || ((item.darknessTheme ?? 500) <= 600 && item.theme !== 'black') ? 'black' : 'white'}; border-color: ${borderColor};`" class="menuElement" @click=" () => { @@ -147,7 +155,7 @@ const openLink = (url: string, isBlank: boolean | undefined) => justify-content: center; align-items: center; padding: 10px; - border: 1px solid white; + border: 1px solid v-bind(borderColor); border-radius: 5px; user-select: none; cursor: pointer; diff --git a/src/stories/components/Modal/Modal.stories.ts b/src/stories/components/Modal/Modal.stories.ts index b23779a..d5c6d08 100644 --- a/src/stories/components/Modal/Modal.stories.ts +++ b/src/stories/components/Modal/Modal.stories.ts @@ -36,13 +36,14 @@ const meta: Meta = { 'bottomRight', ], }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Modal/Modal.vue b/src/stories/components/Modal/Modal.vue index 1ebe15a..5c8e74c 100644 --- a/src/stories/components/Modal/Modal.vue +++ b/src/stories/components/Modal/Modal.vue @@ -1,32 +1,45 @@ <script setup lang="ts"> -import { computed } from 'vue'; -import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors'; +import { computed, watch } from 'vue'; +import { convertWhiteOrBlackToColor } from '@helpers/colors'; import type { IModalProps } from '@interfaces/componentsProps'; import { iconsSet } from '@/common/constants/icons'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<IModalProps>(), { visible: false, dismissible: false, theme: 'white', + darknessTheme: 500, width: '30%', height: '30%', headerDivider: false, closeIcon: 'CrossIcon', }); +const body = document.querySelector('body')!; const emit = defineEmits(['onClose']); const visible = defineModel('visible', { set(value) { if (!value) { + body.style.overflow = 'auto'; emit('onClose'); } return value; }, }); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const scrollColor = computed(() => convert300ThemeToColor(props.theme)); +watch(visible, () => { + if (visible.value) { + body.style.overflow = 'hidden'; + } +}); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const scrollAndBorderColor = computed(() => + props.theme === 'white' || props.theme === 'black' + ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme) + : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)), +); const textColor = computed(() => { - if (!props.theme) return '#000000'; - if (props.theme === 'white') return '#000000'; + if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black')) + return '#000000'; return '#ffffff'; }); const onKeydown = (event: KeyboardEvent) => { @@ -101,7 +114,7 @@ document.addEventListener('keydown', onKeydown); min-width: 250px; min-height: 100px; padding: 20px; - border: 2px solid gray; + border: 2px solid v-bind(scrollAndBorderColor); border-radius: 15px; opacity: 0; transform: scale(0.5); @@ -145,7 +158,7 @@ document.addEventListener('keydown', onKeydown); } .divider { height: 2px; - background-color: v-bind(scrollColor); + background-color: v-bind(scrollAndBorderColor); position: absolute; left: 20px; top: 60px; @@ -153,7 +166,7 @@ document.addEventListener('keydown', onKeydown); } ::-webkit-scrollbar-thumb { border-radius: 5px; - background-color: v-bind(scrollColor); + background-color: v-bind(scrollAndBorderColor); } .toTop { top: 10px !important; diff --git a/src/stories/components/Popup/Popup.stories.ts b/src/stories/components/Popup/Popup.stories.ts index c8d3e5c..7f515ed 100644 --- a/src/stories/components/Popup/Popup.stories.ts +++ b/src/stories/components/Popup/Popup.stories.ts @@ -20,13 +20,14 @@ const meta: Meta = { maxWidth: { control: 'text' }, maxHeight: { control: 'text' }, padding: { control: 'text' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Popup/Popup.vue b/src/stories/components/Popup/Popup.vue index a9eb103..e199b8b 100644 --- a/src/stories/components/Popup/Popup.vue +++ b/src/stories/components/Popup/Popup.vue @@ -1,18 +1,31 @@ <script setup lang="ts"> import type { IPopupProps } from '@interfaces/componentsProps'; import { computed, ref } from 'vue'; -import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors'; +import { convertThemeToColor } from '@helpers/common'; +import { convertWhiteOrBlackToColor } from '@helpers/colors'; const props = withDefaults(defineProps<IPopupProps>(), { parentSelector: 'body', theme: 'white', + border: 'black', maxWidth: '300px', maxHeight: '100px', padding: '5px', + darknessTheme: 500, + darknessBorder: 500, }); const active = defineModel<boolean>('active'); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const scrollColor = computed(() => convert300ThemeToColor(props.theme)); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const scrollAndBorderColor = computed(() => + props.theme === 'white' || props.theme === 'black' + ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme) + : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)), +); +const textColor = computed(() => { + if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black')) + return '#000000'; + return '#ffffff'; +}); const top = ref(); const left = ref(); @@ -20,9 +33,9 @@ const isContainer = ref(); const container = document.querySelector(props.parentSelector); if (container) { - container.addEventListener('pointerdown', (e) => { + container.addEventListener('pointerdown', (event: Event) => { + const e = event as PointerEvent; if (e.button === 2) { - console.log('e.clientY, e.clientX ', e.clientY, e.clientX); isContainer.value = true; if (!active.value) active.value = true; top.value = e.clientY; @@ -45,9 +58,11 @@ document.addEventListener('pointerdown', (e) => { oncontextmenu="return false" id="popup" @pointerdown.stop="" - :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}`" + :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}; color: ${textColor}`" > - <div :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto;`"> + <div + :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto; padding-right: 5px`" + > <slot /> <p v-if="!$slots.default" style="background-color: black; color: white; padding: 10px"> Popup @@ -61,11 +76,11 @@ document.addEventListener('pointerdown', (e) => { position: fixed; transition: opacity 0.2s ease-in-out; background-color: v-bind(themeColor); - border: 1px solid #403e46; + border: 1px solid v-bind(scrollAndBorderColor); border-radius: 5px; } ::-webkit-scrollbar-thumb { border-radius: 5px; - background-color: v-bind(scrollColor); + background-color: v-bind(scrollAndBorderColor); } </style> diff --git a/src/stories/components/SelectButton/SelectButton.stories.ts b/src/stories/components/SelectButton/SelectButton.stories.ts index 0e7f8c8..03c49b6 100644 --- a/src/stories/components/SelectButton/SelectButton.stories.ts +++ b/src/stories/components/SelectButton/SelectButton.stories.ts @@ -19,13 +19,21 @@ const meta: Meta = { }, size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] }, rounded: { control: 'boolean' }, + darknessActiveBackgroundColor: { + control: 'select', + options: [100, 200, 300, 400, 500, 600, 700, 800, 900], + }, + darknessBorder: { + control: 'select', + options: [100, 200, 300, 400, 500, 600, 700, 800, 900], + }, activeBackgroundColor: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -43,9 +51,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -94,6 +102,7 @@ export const LargeFull: Story = { }, { label: 'Second', + color: 'red', activeColor: 'blue', backgroundColor: 'yellow', }, diff --git a/src/stories/components/SelectButton/SelectButton.vue b/src/stories/components/SelectButton/SelectButton.vue index 2f3761b..43ba74b 100644 --- a/src/stories/components/SelectButton/SelectButton.vue +++ b/src/stories/components/SelectButton/SelectButton.vue @@ -1,20 +1,25 @@ <script setup lang="ts"> import { computed } from 'vue'; -import { convert500ThemeToColor } from '@helpers/colors'; import type { ISBProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<ISBProps>(), { size: 'medium', - border: 'black', activeBackgroundColor: 'sky', + darknessActiveBackgroundColor: 500, + darknessBorder: 500, }); const emit = defineEmits(['onClick']); const value = defineModel<never>('value'); const activeBackgroundColorComputed = computed(() => - props.activeBackgroundColor ? convert500ThemeToColor(props.activeBackgroundColor) : '', + props.activeBackgroundColor + ? convertThemeToColor(props.activeBackgroundColor, props.darknessActiveBackgroundColor) + : '', +); +const borderColor = computed(() => + !props.border ? '' : convertThemeToColor(props.border, props.darknessBorder), ); -const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : '')); const textSize = computed(() => { switch (props.size) { case 'small': @@ -79,7 +84,7 @@ const buttonHeight = computed(() => { " > <span - :style="`background-color: ${activeBackgroundColorComputed && ((value && value === item.value) || value === item.label) ? activeBackgroundColorComputed : convert500ThemeToColor(item.backgroundColor ?? 'white')}`" + :style="`background-color: ${activeBackgroundColorComputed && ((value && value === item.value) || value === item.label) ? activeBackgroundColorComputed : convertThemeToColor(item.backgroundColor ?? 'white', item.darknessBackgroundColor ?? 500)}`" :class="[ 'background', { @@ -92,7 +97,7 @@ const buttonHeight = computed(() => { ></span> <span v-if="!item.isLabelHidden" - :style="`color: ${value === item.value || value === item.label ? item.activeColor : convert500ThemeToColor(item.color ?? 'black')}; font-size: ${textSize}`" + :style="`color: ${(item.value && value === item.value) || value === item.label ? convertThemeToColor(item.activeColor ?? 'black', item.darknessActiveColor ?? 500) : convertThemeToColor(item.color ?? 'black', item.darknessColor ?? 500)}; font-size: ${textSize}`" :class="[ 'text', { @@ -102,7 +107,8 @@ const buttonHeight = computed(() => { ]" >{{ item.label ?? index }}</span > - <div + <span + v-if="$slots[`${index + 1}Icon`]" :class="[ 'icon', { @@ -111,7 +117,7 @@ const buttonHeight = computed(() => { ]" > <slot :name="`${index + 1}Icon`" /> - </div> + </span> </button> </div> </template> diff --git a/src/stories/components/Slider/Slider.stories.ts b/src/stories/components/Slider/Slider.stories.ts index d465efa..98211f2 100644 --- a/src/stories/components/Slider/Slider.stories.ts +++ b/src/stories/components/Slider/Slider.stories.ts @@ -22,13 +22,18 @@ const meta: Meta = { size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] }, orientation: { control: 'select', options: ['horizontal', 'vertical'] }, isSmooth: { control: 'boolean' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, + darknessBackgroundColor: { + control: 'select', + options: [100, 200, 300, 400, 500, 600, 700, 800, 900], + }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -46,9 +51,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', diff --git a/src/stories/components/Slider/Slider.vue b/src/stories/components/Slider/Slider.vue index 47b6fcb..5d57dc4 100644 --- a/src/stories/components/Slider/Slider.vue +++ b/src/stories/components/Slider/Slider.vue @@ -1,13 +1,15 @@ <script setup lang="ts"> import { computed, ref, watch } from 'vue'; -import { convert500ThemeToColor } from '@helpers/colors'; import type { ISliderProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<ISliderProps>(), { width: '100', size: 'medium', theme: 'sky', backgroundColor: 'black', + darknessTheme: 500, + darknessBackgroundColor: 500, }); const value = defineModel('value'); const optionValue = ref( @@ -57,8 +59,10 @@ const widthHalf = computed(() => `${Math.floor(+props.width / 2)}px`); const sliderHeight = computed(() => `${Math.floor(+sliderButtonSize.value.slice(0, -2) / 2.5)}px`); const sliderBorderRadius = computed(() => (props.isSmooth ? sliderHeight.value : '0%')); const sliderButtonBorderRadius = computed(() => (props.isSmooth ? '50%' : '0%')); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const themeBackground = computed(() => convert500ThemeToColor(props.backgroundColor)); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const themeBackground = computed(() => + convertThemeToColor(props.backgroundColor, props.darknessBackgroundColor), +); const marksListPadding = computed( () => `${Math.floor(+sliderButtonSize.value.slice(0, -2) / 2)}px`, ); @@ -86,9 +90,9 @@ const marksListPadding = computed( <ul class="marksList" :style="`width: ${width ?? 200}px`"> <li v-for="option of options" - :key="option.label" + :key="String(option.label)" class="mark" - :style="`color: ${convert500ThemeToColor(option?.color) ?? 'white'}; font-size: ${optionsFontSize}`" + :style="`color: ${convertThemeToColor(option.color ?? 'black', option.darknessColor ?? 500) ?? 'white'}; font-size: ${optionsFontSize}`" > {{ option.label }} </li> diff --git a/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts b/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts index c003e86..0fe5c11 100644 --- a/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts +++ b/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts @@ -20,9 +20,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -40,9 +40,9 @@ const meta: Meta = { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -56,7 +56,11 @@ const meta: Meta = { 'black', ], }, - darkNegative: { control: 'boolean' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, + darknessNegativeTheme: { + control: 'select', + options: [100, 200, 300, 400, 500, 600, 700, 800, 900], + }, disabled: { control: 'boolean' }, }, args: {}, @@ -68,14 +72,12 @@ type Story = StoryObj<typeof meta>; export const Primary: Story = { args: { - darkNegative: true, active: false, }, }; export const SmallLight: Story = { args: { - darkNegative: false, negativeTheme: 'yellow', theme: 'red', size: 'small', @@ -84,7 +86,6 @@ export const SmallLight: Story = { export const Large: Story = { args: { - darkNegative: true, negativeTheme: 'purple', theme: 'green', size: 'large', @@ -93,7 +94,6 @@ export const Large: Story = { export const Huge: Story = { args: { - darkNegative: true, negativeTheme: 'blue', theme: 'orange', size: 'huge', diff --git a/src/stories/components/ToggleSwitch/ToggleSwitch.vue b/src/stories/components/ToggleSwitch/ToggleSwitch.vue index 503feb5..7be5d7a 100644 --- a/src/stories/components/ToggleSwitch/ToggleSwitch.vue +++ b/src/stories/components/ToggleSwitch/ToggleSwitch.vue @@ -1,21 +1,20 @@ <script setup lang="ts"> import { computed } from 'vue'; -import { convert500ThemeToColor, convert800ThemeToColor } from '@helpers/colors'; import type { ITSProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; const props = withDefaults(defineProps<ITSProps>(), { size: 'medium', theme: 'sky', negativeTheme: 'black', - darkNegative: true, + darknessTheme: 500, + darknessNegativeTheme: 500, }); const active = defineModel<boolean>('active'); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const inactiveColor = computed(() => - props.darkNegative - ? convert800ThemeToColor(props.negativeTheme) - : convert500ThemeToColor(props.negativeTheme), + convertThemeToColor(props.negativeTheme, props.darknessNegativeTheme), ); const sizes = computed(() => { if (!props?.size) { diff --git a/src/stories/components/TreeList/TreeItems.vue b/src/stories/components/TreeList/TreeItems.vue index 2dd704c..bbd871b 100644 --- a/src/stories/components/TreeList/TreeItems.vue +++ b/src/stories/components/TreeList/TreeItems.vue @@ -1,8 +1,8 @@ <script setup lang="ts"> import { iconsSet } from '@/common/constants/icons'; import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue'; -import { convert500ThemeToColor } from '@helpers/colors'; import type { ITIProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; defineProps<ITIProps>(); const emit = defineEmits(['toggleIsOpen', 'onClick']); @@ -44,7 +44,9 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); }, ]" :color=" - item.color && item.isTriangleToColor ? convert500ThemeToColor(item.color) : textColor + item.color && item.isTriangleToColor + ? convertThemeToColor(item.color, item.darknessColor ?? 500) + : textColor " size="17" /> @@ -59,7 +61,7 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); isDarkerOnHover: item.link, }, ]" - :style="`color: ${item.color ? convert500ThemeToColor(item.color) : textColor}`" + :style="`color: ${item.color ? convertThemeToColor(item.color, item.darknessColor ?? 500) : textColor}`" @click=" () => { item.isLinkClicked = true; @@ -72,14 +74,14 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); ><component :is="iconsSet[item.iconBefore]" v-if="item.iconBefore" - :color="convert500ThemeToColor(item.iconColor)" + :color="convertThemeToColor(item.iconColor ?? 'black', item.darknessIconColor ?? 500)" style="min-width: 17px" size="17" /> <span>{{ item.label }}</span ><component :is="iconsSet[item.iconAfter]" v-if="item.iconAfter" - :color="convert500ThemeToColor(item.iconColor)" + :color="convertThemeToColor(item.iconColor ?? 'black', item.darknessIconColor ?? 500)" style="min-width: 17px" size="17" /></a> diff --git a/src/stories/components/TreeList/TreeList.stories.ts b/src/stories/components/TreeList/TreeList.stories.ts index 9be416a..8c2165e 100644 --- a/src/stories/components/TreeList/TreeList.stories.ts +++ b/src/stories/components/TreeList/TreeList.stories.ts @@ -18,13 +18,14 @@ const meta: Meta = { items: { control: 'object' }, maxWidth: { control: 'number' }, expand: { control: 'boolean' }, + darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] }, theme: { control: 'select', options: [ 'white', - 'slate', 'blue', 'sky', + 'cyan', 'teal', 'green', 'yellow', @@ -124,6 +125,8 @@ export const Full: Story = { color: 'red', iconAfter: 'DiceIcon', iconColor: 'red', + darknessColor: 400, + darknessIconColor: 400, children: [ { label: '1-1-1-1', @@ -160,5 +163,6 @@ export const Full: Story = { expand: true, theme: 'black', + darknessTheme: 800, }, }; diff --git a/src/stories/components/TreeList/TreeList.vue b/src/stories/components/TreeList/TreeList.vue index 061fe64..d4b1f5c 100644 --- a/src/stories/components/TreeList/TreeList.vue +++ b/src/stories/components/TreeList/TreeList.vue @@ -1,9 +1,9 @@ <script setup lang="ts"> import { computed, ref, watch } from 'vue'; import type { ITreeItem } from '@interfaces/componentsProp'; -import { convert500ThemeToColor } from '@helpers/colors'; import TreeItems from '@stories/components/TreeList/TreeItems.vue'; import type { ITLProps } from '@interfaces/componentsProps'; +import { convertThemeToColor } from '@helpers/common'; interface IStateItem { isOpen: boolean; @@ -13,14 +13,15 @@ interface IStateItem { const props = withDefaults(defineProps<ITLProps>(), { theme: 'white', maxWidth: 300, + darknessTheme: 500, }); const emit = defineEmits(['onClick']); const items = computed(() => props.items); -const themeColor = computed(() => convert500ThemeToColor(props.theme)); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const textColor = computed(() => { - if (!props.theme) return 'black'; - if (props.theme === 'white') return 'black'; - return 'white'; + if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black')) + return '#000000'; + return '#ffffff'; }); const state = ref<IStateItem[]>([]); -- GitLab