diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html new file mode 100644 index 0000000000000000000000000000000000000000..657a1b80ee9ff6812a340b117a507dd94429fb66 --- /dev/null +++ b/.storybook/manager-head.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <link rel="icon" href="./storybook.ico"> + <title>Storybook</title> +</head> +<body> + +</body> +</html> \ No newline at end of file diff --git a/README.md b/README.md index 4e72dcb4ab3a4092810af9340b74eaa5b59d609b..5b1dc0d7a7e6cd746294d2e9e6e2e0125c754f45 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,9 @@ yarn dev ```sh yarn build ``` + +## Важные моменты при разработке + +ПоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¸: +1. Добавить иконку в iconsSet (src/common/constants/icons); +2. Добавить иконку в ÑоответÑтвующий маÑÑив в App.vue. \ No newline at end of file diff --git a/public/storybook.ico b/public/storybook.ico new file mode 100644 index 0000000000000000000000000000000000000000..690ee543d1b7a8d727252f9d278e2538ad02a61f Binary files /dev/null and b/public/storybook.ico differ diff --git a/src/common/constants/icons.ts b/src/common/constants/icons.ts new file mode 100644 index 0000000000000000000000000000000000000000..376201538b534b6331a8c979ff32622064447f7d --- /dev/null +++ b/src/common/constants/icons.ts @@ -0,0 +1,209 @@ +import type { Component } from 'vue'; + +import Age18Icon from '@stories/icons/Mono/Age18Icon.vue'; +import AirplaneIcon from '@stories/icons/Mono/AirplaneIcon.vue'; +import AlarmIcon from '@stories/icons/Mono/AlarmIcon.vue'; +import AlignCenterIcon from '@stories/icons/Mono/AlignCenterIcon.vue'; +import AlignLeftIcon from '@stories/icons/Mono/AlignLeftIcon.vue'; +import AlignRightIcon from '@stories/icons/Mono/AlignRightIcon.vue'; +import AnchorIcon from '@stories/icons/Mono/AnchorIcon.vue'; +import AnchorLinkIcon from '@stories/icons/Mono/AnchorLinkIcon.vue'; +import ArchiveIcon from '@stories/icons/Mono/ArchiveIcon.vue'; +import ArrowForwardIcon from '@stories/icons/Mono/ArrowForwardIcon.vue'; +import ArrowLeftIcon from '@stories/icons/Mono/ArrowLeftIcon.vue'; +import ArrowRightIcon from '@stories/icons/Mono/ArrowRightIcon.vue'; +import ArrowsVerticalIcon from '@stories/icons/Mono/ArrowsVerticalIcon.vue'; +import AtIcon from '@stories/icons/Mono/AtIcon.vue'; +import AwardIcon from '@stories/icons/Mono/AwardIcon.vue'; +import BackspaceIcon from '@stories/icons/Mono/BackspaceIcon.vue'; +import BadgeIcon from '@stories/icons/Mono/BadgeIcon.vue'; +import BallFootballIcon from '@stories/icons/Mono/BallFootballIcon.vue'; +import BallIcon from '@stories/icons/Mono/BallIcon.vue'; +import BanknoteIcon from '@stories/icons/Mono/BanknoteIcon.vue'; +import BellIcon from '@stories/icons/Mono/BellIcon.vue'; +import BellOffIcon from '@stories/icons/Mono/BellOffIcon.vue'; +import BoxIcon from '@stories/icons/Mono/BoxIcon.vue'; +import BrightnessIcon from '@stories/icons/Mono/BrightnessIcon.vue'; +import BulbIcon from '@stories/icons/Mono/BulbIcon.vue'; +import CalculatorIcon from '@stories/icons/Mono/CalculatorIcon.vue'; +import CalendarAddIcon from '@stories/icons/Mono/CalendarAddIcon.vue'; +import CalendarIcon from '@stories/icons/Mono/CalendarIcon.vue'; +import CalendarRemoveIcon from '@stories/icons/Mono/CalendarRemoveIcon.vue'; +import CardsIcon from '@stories/icons/Mono/CardsIcon.vue'; +import ChartLineIcon from '@stories/icons/Mono/ChartLineIcon.vue'; +import ChartPieIcon from '@stories/icons/Mono/ChartPieIcon.vue'; +import ChatIcon from '@stories/icons/Mono/ChatIcon.vue'; +import CrossCircleIcon from '@stories/icons/Mono/CrossCircleIcon.vue'; +import CropIcon from '@stories/icons/Mono/CropIcon.vue'; +import ChatWritingIcon from '@stories/icons/Mono/ChatWritingIcon.vue' +import CheckmarkIcon from '@stories/icons/Mono/CheckmarkIcon.vue' +import ChemistryFlaskIcon from '@stories/icons/Mono/ChemistryFlaskIcon.vue' +import CodeIcon from '@stories/icons/Mono/CodeIcon.vue' +import CoinsIcon from '@stories/icons/Mono/CoinsIcon.vue' +import ColorPaletteIcon from '@stories/icons/Mono/ColorPaletteIcon.vue' +import CompassIcon from '@stories/icons/Mono/CompassIcon.vue' +import ConstructionWorkerIcon from '@stories/icons/Mono/ConstructionWorkerIcon.vue' +import ContactsIcon from '@stories/icons/Mono/ContactsIcon.vue' +import CrossIcon from '@stories/icons/Mono/CrossIcon.vue' +import CubeIcon from '@stories/icons/Mono/CubeIcon.vue' +import CupIcon from '@stories/icons/Mono/CupIcon.vue' +import CursorIcon from '@stories/icons/Mono/CursorIcon.vue' +import DiamondIcon from '@stories/icons/Mono/DiamondIcon.vue' +import DiaryIcon from '@stories/icons/Mono/DiaryIcon.vue' +import DiceIcon from '@stories/icons/Mono/DiceIcon.vue' +import DigIcon from '@stories/icons/Mono/DigIcon.vue' +import DislikeIcon from '@stories/icons/Mono/DislikeIcon.vue' +import DisplayIcon from '@stories/icons/Mono/DisplayIcon.vue' +import DocumentIcon from '@stories/icons/Mono/DocumentIcon.vue' +import DocumentAddIcon from '@stories/icons/Mono/DocumentAddIcon.vue' +import DocumentDeleteIcon from '@stories/icons/Mono/DocumentDeleteIcon.vue' +import DocumentEditIcon from '@stories/icons/Mono/DocumentEditIcon.vue' +import DollarIcon from '@stories/icons/Mono/DollarIcon.vue' +import DotsHorizontalIcon from '@stories/icons/Mono/DotsHorizontalIcon.vue' +import DotsVerticalIcon from '@stories/icons/Mono/DotsVerticalIcon.vue' +import DownloadIcon from '@stories/icons/Mono/DownloadIcon.vue' +import DropIcon from '@stories/icons/Mono/DropIcon.vue' +import DumbbelIcon from '@stories/icons/Mono/DumbbelIcon.vue' +import EarthIcon from '@stories/icons/Mono/EarthIcon.vue' +import EditIcon from '@stories/icons/Mono/EditIcon.vue' +import EncyclopediaIcon from '@stories/icons/Mono/EncyclopediaIcon.vue' +import ExitIcon from '@stories/icons/Mono/ExitIcon.vue' +import EyeIcon from '@stories/icons/Mono/EyeIcon.vue' +import FeedbackIcon from '@stories/icons/Mono/FeedbackIcon.vue' +import FilterIcon from '@stories/icons/Mono/FilterIcon.vue' +import FingerprintIcon from '@stories/icons/Mono/FingerprintIcon.vue' +import FireIcon from '@stories/icons/Mono/FireIcon.vue' +import FlagIcon from '@stories/icons/Mono/FlagIcon.vue' +import FlashIcon from '@stories/icons/Mono/FlashIcon.vue' +import FlashlightIcon from '@stories/icons/Mono/FlashlightIcon.vue' +import FolderLockIcon from '@stories/icons/Mono/FolderLockIcon.vue' +import FrameIcon from '@stories/icons/Mono/FrameIcon.vue' +import FullScreenIcon from '@stories/icons/Mono/FullScreenIcon.vue' +import GameControllerIcon from '@stories/icons/Mono/GameControllerIcon.vue' +import GiftIcon from '@stories/icons/Mono/GiftIcon.vue' +import GlassesIcon from '@stories/icons/Mono/GlassesIcon.vue' +import HamburgerIcon from '@stories/icons/Mono/HamburgerIcon.vue' +import HandIcon from '@stories/icons/Mono/HandIcon.vue' +import HomeIcon from '@stories/icons/Mono/HomeIcon.vue' +import ImageIcon from '@stories/icons/Mono/ImageIcon.vue' +import ImageEditIcon from '@stories/icons/Mono/ImageEditIcon.vue' +import LineIcon from '@stories/icons/Mono/LineIcon.vue' +import LineDashedIcon from '@stories/icons/Mono/LineDashedIcon.vue' +import LineDottedIcon from '@stories/icons/Mono/LineDottedIcon.vue' +import LineDiagonalIcon from '@stories/icons/Mono/LineDiagonalIcon.vue' +import MoveIcon from '@stories/icons/Mono/MoveIcon.vue' +import ParagraphIcon from '@stories/icons/Mono/ParagraphIcon.vue' +import PhoneHandsetIcon from '@stories/icons/Mono/PhoneHandsetIcon.vue' +import PlusCircleIcon from '@stories/icons/Mono/PlusCircleIcon.vue' +import PlusIcon from '@stories/icons/Mono/PlusIcon.vue' +import PointerIcon from '@stories/icons/Mono/PointerIcon.vue' +import SaveIcon from '@stories/icons/Mono/SaveIcon.vue' +import SettingsIcon from '@stories/icons/Mono/SettingsIcon.vue' +import TableIcon from '@stories/icons/Mono/TableIcon.vue' +import TrashIcon from '@stories/icons/Mono/TrashIcon.vue' +import UserIcon from '@stories/icons/Mono/UserIcon.vue' + +export const iconsSet: Record<string, Component> = { + Age18Icon: Age18Icon, + AirplaneIcon: AirplaneIcon, + AlarmIcon: AlarmIcon, + AlignCenterIcon: AlignCenterIcon, + AlignLeftIcon: AlignLeftIcon, + AlignRightIcon: AlignRightIcon, + AnchorIcon: AnchorIcon, + AnchorLinkIcon: AnchorLinkIcon, + ArchiveIcon: ArchiveIcon, + ArrowForwardIcon: ArrowForwardIcon, + ArrowLeftIcon: ArrowLeftIcon, + ArrowRightIcon: ArrowRightIcon, + ArrowsVerticalIcon: ArrowsVerticalIcon, + AtIcon: AtIcon, + AwardIcon: AwardIcon, + BackspaceIcon: BackspaceIcon, + BadgeIcon: BadgeIcon, + BallFootballIcon: BallFootballIcon, + BallIcon: BallIcon, + BanknoteIcon: BanknoteIcon, + BellIcon: BellIcon, + BellOffIcon: BellOffIcon, + BoxIcon: BoxIcon, + BrightnessIcon: BrightnessIcon, + BulbIcon: BulbIcon, + CalculatorIcon: CalculatorIcon, + CalendarAddIcon: CalendarAddIcon, + CalendarIcon: CalendarIcon, + CalendarRemoveIcon: CalendarRemoveIcon, + CardsIcon: CardsIcon, + ChartLineIcon: ChartLineIcon, + ChartPieIcon: ChartPieIcon, + ChatIcon: ChatIcon, + ChatWritingIcon: ChatWritingIcon, + CheckmarkIcon: CheckmarkIcon, + ChemistryFlaskIcon: ChemistryFlaskIcon, + CodeIcon: CodeIcon, + CoinsIcon: CoinsIcon, + ColorPaletteIcon: ColorPaletteIcon, + CompassIcon: CompassIcon, + ConstructionWorkerIcon: ConstructionWorkerIcon, + ContactsIcon: ContactsIcon, + CropIcon: CropIcon, + CrossIcon: CrossIcon, + CrossCircleIcon: CrossCircleIcon, + CubeIcon: CubeIcon, + CupIcon: CupIcon, + CursorIcon: CursorIcon, + DiamondIcon: DiamondIcon, + DiaryIcon: DiaryIcon, + DiceIcon: DiceIcon, + DigIcon: DigIcon, + DislikeIcon: DislikeIcon, + DisplayIcon: DisplayIcon, + DocumentIcon: DocumentIcon, + DocumentAddIcon: DocumentAddIcon, + DocumentDeleteIcon: DocumentDeleteIcon, + DocumentEditIcon: DocumentEditIcon, + DollarIcon: DollarIcon, + DotsHorizontalIcon: DotsHorizontalIcon, + DotsVerticalIcon: DotsVerticalIcon, + DownloadIcon: DownloadIcon, + DropIcon: DropIcon, + DumbbelIcon: DumbbelIcon, + EarthIcon: EarthIcon, + EditIcon: EditIcon, + EncyclopediaIcon: EncyclopediaIcon, + ExitIcon: ExitIcon, + EyeIcon: EyeIcon, + FeedbackIcon: FeedbackIcon, + FilterIcon: FilterIcon, + FingerprintIcon: FingerprintIcon, + FireIcon: FireIcon, + FlagIcon: FlagIcon, + FlashIcon: FlashIcon, + FlashlightIcon: FlashlightIcon, + FolderLockIcon: FolderLockIcon, + FrameIcon: FrameIcon, + FullScreenIcon: FullScreenIcon, + GameControllerIcon: GameControllerIcon, + GiftIcon: GiftIcon, + GlassesIcon: GlassesIcon, + HamburgerIcon: HamburgerIcon, + HandIcon: HandIcon, + HomeIcon: HomeIcon, + ImageIcon: ImageIcon, + ImageEditIcon: ImageEditIcon, + LineIcon: LineIcon, + LineDashedIcon: LineDashedIcon, + LineDottedIcon: LineDottedIcon, + LineDiagonalIcon: LineDiagonalIcon, + MoveIcon: MoveIcon, + ParagraphIcon: ParagraphIcon, + PhoneHandsetIcon: PhoneHandsetIcon, + PlusCircleIcon: PlusCircleIcon, + PlusIcon: PlusIcon, + PointerIcon: PointerIcon, + SaveIcon: SaveIcon, + SettingsIcon: SettingsIcon, + TableIcon: TableIcon, + TrashIcon: TrashIcon, + UserIcon: UserIcon, +}; diff --git a/src/common/helpers/icons.ts b/src/common/helpers/icons.ts deleted file mode 100644 index 7fbd44b1cdc79d19f684d3a0dfd24f8dec202753..0000000000000000000000000000000000000000 --- a/src/common/helpers/icons.ts +++ /dev/null @@ -1,8 +0,0 @@ -import CrossCircleIcon from '@stories/icons/Mono/CrossCircleIcon.vue'; -import CropIcon from '@stories/icons/Mono/CropIcon.vue'; -import type { Component } from 'vue'; - -export const iconsSet: Record<string, Component> = { - CrossCircleIcon: CrossCircleIcon, - CropIcon: CropIcon, -}; diff --git a/src/common/interfaces/common.ts b/src/common/interfaces/common.ts index 8cbf8a92e7df793f5f5fb50bfe0c9262701b0a8a..ffde71b1b74bafc18c584a7aad5cdce0dfc19afd 100644 --- a/src/common/interfaces/common.ts +++ b/src/common/interfaces/common.ts @@ -1,3 +1,5 @@ +import type { iconsSet } from '@/common/constants/icons'; + export type TThemeColor = | 'white' | 'slate' @@ -14,3 +16,5 @@ export type TThemeColor = | 'rose' | 'red' | 'black'; + +export type TIcons = keyof typeof iconsSet; diff --git a/src/stories/components/Divider/Divider.stories.ts b/src/stories/components/Divider/Divider.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa8f21218f50f5b5f8d98d4a7c0b0063733c9186 --- /dev/null +++ b/src/stories/components/Divider/Divider.stories.ts @@ -0,0 +1,58 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import Divider from './Divider.vue'; + +const meta: Meta = { + title: 'Components/Divider', + component: Divider, + tags: ['autodocs'], + argTypes: { + height: { control: 'number' }, + type: { control: 'select', options: ['solid', 'dashed', 'dotted'] }, + color: { + control: 'select', + options: [ + 'white', + 'slate', + 'blue', + 'sky', + 'teal', + 'green', + 'yellow', + 'orange', + 'pink', + 'fuchsia', + 'purple', + 'indigo', + 'rose', + 'red', + 'black', + ], + }, + }, + args: { + // primary: false, + // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args + // onClick: fn(), + }, +} satisfies Meta<typeof Divider>; + +export default meta; + +type Story = StoryObj<typeof meta>; +/* + *👇 Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/api/csf + * to learn how to use render functions. + */ +export const Primary: Story = { + args: {}, +}; + +export const RedDashed: Story = { + args: { + height: 2, + color: 'red', + type: 'dashed', + }, +}; diff --git a/src/stories/components/Divider/Divider.vue b/src/stories/components/Divider/Divider.vue index ed057348da341a02e7e8253d22ea8e0eac0b1761..32f230ae1a73061b0422d45eed4525d4b64cdd79 100644 --- a/src/stories/components/Divider/Divider.vue +++ b/src/stories/components/Divider/Divider.vue @@ -1,13 +1,23 @@ <script setup lang="ts"> +import { computed } from 'vue'; +import type { TThemeColor } from '@interfaces/common'; +import { convert500ThemeToColor } from '@helpers/colors'; + interface Props { height?: number; type?: 'solid' | 'dashed' | 'dotted'; + color?: TThemeColor; } -defineProps<Props>(); +const props = withDefaults(defineProps<Props>(), { + height: 1, + type: 'solid', + color: 'black', +}); +const colorConverted = computed(() => convert500ThemeToColor(props.color)); </script> <template> - <div :style="`border-bottom: ${height ?? 1}px ${type ?? 'solid'} #6b7280`" class="w-full"></div> + <div :style="`border-bottom: ${height}px ${type} ${colorConverted}`" class="w-full"></div> </template> <style scoped></style> diff --git a/src/stories/components/Drawer/Drawer.stories.ts b/src/stories/components/Drawer/Drawer.stories.ts index d86ecef950651fcc21a9013d8a3cb05fc3831b53..1cc0506655c11536651bc41979a377e09f9fff71 100644 --- a/src/stories/components/Drawer/Drawer.stories.ts +++ b/src/stories/components/Drawer/Drawer.stories.ts @@ -1,12 +1,24 @@ import type { Meta, StoryObj } from '@storybook/vue3'; import Drawer from './Drawer.vue'; +import { iconsSet } from '@/common/constants/icons'; const meta: Meta = { title: 'Components/Drawer', component: Drawer, tags: ['autodocs'], argTypes: { + visible: { control: 'boolean' }, + position: { control: 'select', options: ['left', 'right', 'top', 'bottom'] }, + width: { control: 'number' }, + header: { control: 'text' }, + default: { control: 'text' }, + footer: { control: 'text' }, + isModal: { control: 'boolean' }, + isDismissible: { control: 'boolean' }, + closeIcon: { control: 'select', options: Object.keys(iconsSet) }, + isHeaderDivider: { control: 'boolean' }, + isFooterDivider: { control: 'boolean' }, theme: { control: 'select', options: [ @@ -27,11 +39,6 @@ const meta: Meta = { 'black', ], }, - visible: { control: 'boolean' }, - width: { control: 'number' }, - header: { control: 'text' }, - default: { control: 'text' }, - footer: { control: 'text' }, }, args: { // primary: false, @@ -51,5 +58,24 @@ type Story = StoryObj<typeof meta>; export const Primary: Story = { args: { visible: true, + default: 'Какой-то текÑÑ‚.', + }, +}; + +export const BlackFull: Story = { + args: { + visible: true, + width: 200, + theme: 'black', + closeIcon: 'CrossIcon', + header: 'Drawer', + footer: 'The end.', + isHeaderDivider: true, + isFooterDivider: true, + + default: + ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto dicta dolorum eaque explicabo illo. Beatae et eveniet itaque libero sint. Atque blanditiis consequuntur dolorum explicabo, facilis iste nulla numquam provident.', + + isModal: true, }, }; diff --git a/src/stories/components/Drawer/Drawer.vue b/src/stories/components/Drawer/Drawer.vue index ddd4d21f5e3459a3d838cdbf09dec93cb74a4cd0..01c5691c1b86b307b6f885c3c977d89d045e0d70 100644 --- a/src/stories/components/Drawer/Drawer.vue +++ b/src/stories/components/Drawer/Drawer.vue @@ -1,20 +1,30 @@ <script setup lang="ts"> -import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors'; -import type { TThemeColor } from '@interfaces/common'; import { computed } from 'vue'; -import { iconsSet } from '@helpers/icons'; +import { iconsSet } from '@/common/constants/icons'; +import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors'; +import type { TIcons, TThemeColor } from '@interfaces/common'; const props = withDefaults( defineProps<{ + position: 'left' | 'right' | 'top' | 'bottom'; width?: string | number; theme?: TThemeColor; - closeIcon?: string; + isModal?: boolean; + isDismissible?: boolean; + closeIcon?: TIcons; + isHeaderDivider?: boolean; + isFooterDivider?: boolean; }>(), { visible: false, + position: 'left', width: 400, + isModal: true, + isDismissible: true, theme: 'white', - closeIcon: 'CrossCircleIcon', + closeIcon: 'CrossIcon', + isHeaderDivider: false, + isFooterDivider: false, }, ); const emit = defineEmits(['onClose']); @@ -27,28 +37,33 @@ const textColor = computed(() => { return 'white'; }); const drawerWidth = computed(() => { - if (+props.width < 100) return '100px'; + if (+props.width < 200) return '200px'; return `${props.width}px`; }); </script> - <template> <article> <section + v-if="isModal" :class="[ 'drawerBackground', { drawerBackgroundOpened: visible, }, ]" - @click.prevent="visible = false" + @click.prevent="isDismissible ? (visible = false) : false" ></section> <section :style="`color: ${textColor}; background-color: ${themeColor}`" :class="[ 'drawer', { + drawerLeft: position === 'left', + drawerRight: position === 'right', + drawerTop: position === 'top', + drawerBottom: position === 'bottom', drawerOpened: visible, + drawerVertical: position === 'top' || position === 'bottom', }, ]" > @@ -66,11 +81,12 @@ const drawerWidth = computed(() => { <component :is="iconsSet[closeIcon]" :color="textColor" /> </button> </header> + <div v-if="isHeaderDivider" class="divider divider-header"></div> <div class="main"> <slot /> </div> <div v-if="$slots.footer"> - <div class="divider"></div> + <div v-if="isFooterDivider" class="divider"></div> <footer class="drawerFooter"> <slot name="footer" /> </footer> @@ -98,47 +114,76 @@ const drawerWidth = computed(() => { .drawer { width: v-bind(drawerWidth); position: fixed; - top: 0; - left: 0; z-index: 31; height: 100vh; display: flex; flex-direction: column; justify-content: space-between; padding: 20px; - transform: translateX(-100%); transition: transform ease-out 0.2s; - border-right: 2px solid gray; + border-right: 2px solid #b1b1b1; +} +.drawerVertical { + width: 100vw !important; + height: v-bind(drawerWidth) !important; } .drawerOpened { - transform: translateX(0); + transform: translateX(0) !important; +} +.drawerLeft { + transform: translateX(-100%); + top: 0; + left: 0; +} +.drawerRight { + transform: translateX(100%); + top: 0; + right: 0; +} +.drawerTop { + transform: translateY(-100%); + top: 0; + left: 0; +} +.drawerBottom { + transform: translateY(100%); + bottom: 0; + left: 0; } .drawerHeader { font-weight: bold; - font-size: 2rem; - padding-right: 50px; + font-size: 32px; + width: calc(100% - 30px); margin-bottom: 10px; - min-height: 1rem; + height: 37px; overflow: auto; } .main { flex: 1 1 auto; overflow: auto; - padding: 10px; + margin: 10px; } .drawerFooter { - overflow: auto; padding: 10px 10px 0 10px; + overflow: auto; } .divider { height: 2px; background-color: v-bind(scrollColor); } +.divider-header { + position: absolute; + left: 20px; + top: 65px; + width: calc(100% - 40px); +} .buttonClose { position: absolute; - top: 20px; + top: 25px; right: 20px; width: 30px; + display: flex; + align-items: center; } ::-webkit-scrollbar { width: 8px;