Loading src/common/helpers/colors.ts +0 −1 Original line number Diff line number Diff line Loading @@ -113,5 +113,4 @@ export const convert800ThemeToColor = (theme: string | undefined) => { case 'black': return '#000000'; } return '#9294a1'; }; src/common/interfaces/common.ts +2 −0 Original line number Diff line number Diff line Loading @@ -17,4 +17,6 @@ export type TThemeColor = | 'red' | 'black'; export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>; export type TIcons = keyof typeof iconsSet; src/stories/components/Button/Button.vue 0 → 100644 +134 −0 Original line number Diff line number Diff line <script setup lang="ts"> import { computed } from 'vue'; import { convertThemeToColorBlackDefault, convertThemeToColorWhiteDefault } from './helpers/index'; import type { TThemeColor } from './interfaces/index'; interface Props { label?: string; iconPos?: 'left' | 'top' | 'right' | 'bottom'; textStyle?: 'bold' | 'italic'; border?: TThemeColor; size?: 'small' | 'medium' | 'large' | 'extraLarge'; textColor?: TThemeColor; theme?: TThemeColor; width?: string | number; } const props = withDefaults(defineProps<Props>(), { iconPos: 'left' }); const themeColor = computed(() => convertThemeToColorWhiteDefault(props.theme)); const textColor = computed(() => convertThemeToColorBlackDefault(props.textColor)); const borderColor = computed(() => props.border ? convertThemeToColorBlackDefault(props.border) : '' ); const textSize = computed(() => { if (!props?.size || props.size === 'medium') return '16px'; switch (props.size) { case 'small': return '12px'; case 'large': return '20px'; case 'extraLarge': return '24px'; } }); const buttonPadding = computed(() => { if (!props?.size || props.size === 'medium') return '0.75rem 0.5rem'; switch (props.size) { case 'small': return '0.5rem 0.375rem'; case 'large': return '1.2rem 0.8rem'; case 'extraLarge': return '1.8rem 1.2rem'; } }); const width = computed(() => (props.width ? `${props.width}px` : 'max-content')); </script> <template> <button :class="[ 'button', { 'flex-column': iconPos === 'top' || iconPos === 'bottom', border: borderColor } ]" :style="`padding: ${buttonPadding}; width: ${width}`" > <span :style="`background-color: ${themeColor}`" class="background"></span> <span :style="`color: ${textColor}; font-size: ${textSize}`" :class="[ 'text', { bold: textStyle === 'bold', italic: textStyle === 'italic' } ]" >{{ label ?? 'Button' }}</span > <span :class="[ 'icon', { 'order-1': iconPos === 'left' || iconPos === 'top' } ]" > <slot /> </span> </button> </template> <style scoped> .button { position: relative; border-radius: 7px; display: flex; gap: 8px; justify-content: center; align-items: center; user-select: none; } .button:hover .background { filter: brightness(90%); } .background { width: 100%; height: 100%; position: absolute; top: 0; left: 0; border-radius: 5px; transition: filter 0.2s ease-in-out; } .text { position: relative; z-index: 2; line-height: 1; } .icon { position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; } .flex-column { flex-direction: column; } .order-1 { order: -1; } .bold { font-weight: bold; } .italic { font-style: italic; } .border { border: 2px solid v-bind(borderColor); } </style> src/stories/components/Drawer/Drawer.stories.ts +5 −9 Original line number Diff line number Diff line Loading @@ -14,11 +14,11 @@ const meta: Meta = { header: { control: 'text' }, default: { control: 'text' }, footer: { control: 'text' }, isModal: { control: 'boolean' }, isDismissible: { control: 'boolean' }, modal: { control: 'boolean' }, dismissible: { control: 'boolean' }, closeIcon: { control: 'select', options: Object.keys(iconsSet) }, isHeaderDivider: { control: 'boolean' }, isFooterDivider: { control: 'boolean' }, headerDivider: { control: 'boolean' }, footerDivider: { control: 'boolean' }, theme: { control: 'select', options: [ Loading Loading @@ -50,11 +50,7 @@ const meta: Meta = { 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: { visible: true, Loading src/stories/components/Drawer/Drawer.vue +12 −12 Original line number Diff line number Diff line Loading @@ -9,22 +9,22 @@ const props = withDefaults( position: 'left' | 'right' | 'top' | 'bottom'; width?: string | number; theme?: TThemeColor; isModal?: boolean; isDismissible?: boolean; modal?: boolean; dismissible?: boolean; closeIcon?: TIcons; isHeaderDivider?: boolean; isFooterDivider?: boolean; headerDivider?: boolean; footerDivider?: boolean; }>(), { visible: false, position: 'left', width: 400, isModal: true, isDismissible: true, modal: true, dismissible: true, theme: 'white', closeIcon: 'CrossIcon', isHeaderDivider: false, isFooterDivider: false, headerDivider: false, footerDivider: false, }, ); const emit = defineEmits(['onClose']); Loading @@ -44,14 +44,14 @@ const drawerWidth = computed(() => { <template> <article> <section v-if="isModal" v-if="modal" :class="[ 'drawerBackground', { drawerBackgroundOpened: visible, }, ]" @click.prevent="isDismissible ? (visible = false) : false" @click.prevent="dismissible ? (visible = false) : false" ></section> <section :style="`color: ${textColor}; background-color: ${themeColor}`" Loading Loading @@ -81,12 +81,12 @@ const drawerWidth = computed(() => { <component :is="iconsSet[closeIcon]" :color="textColor" /> </button> </header> <div v-if="isHeaderDivider" class="divider divider-header"></div> <div v-if="headerDivider" class="divider divider-header"></div> <div class="main"> <slot /> </div> <div v-if="$slots.footer"> <div v-if="isFooterDivider" class="divider"></div> <div v-if="footerDivider" class="divider"></div> <footer class="drawerFooter"> <slot name="footer" /> </footer> Loading Loading
src/common/helpers/colors.ts +0 −1 Original line number Diff line number Diff line Loading @@ -113,5 +113,4 @@ export const convert800ThemeToColor = (theme: string | undefined) => { case 'black': return '#000000'; } return '#9294a1'; };
src/common/interfaces/common.ts +2 −0 Original line number Diff line number Diff line Loading @@ -17,4 +17,6 @@ export type TThemeColor = | 'red' | 'black'; export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>; export type TIcons = keyof typeof iconsSet;
src/stories/components/Button/Button.vue 0 → 100644 +134 −0 Original line number Diff line number Diff line <script setup lang="ts"> import { computed } from 'vue'; import { convertThemeToColorBlackDefault, convertThemeToColorWhiteDefault } from './helpers/index'; import type { TThemeColor } from './interfaces/index'; interface Props { label?: string; iconPos?: 'left' | 'top' | 'right' | 'bottom'; textStyle?: 'bold' | 'italic'; border?: TThemeColor; size?: 'small' | 'medium' | 'large' | 'extraLarge'; textColor?: TThemeColor; theme?: TThemeColor; width?: string | number; } const props = withDefaults(defineProps<Props>(), { iconPos: 'left' }); const themeColor = computed(() => convertThemeToColorWhiteDefault(props.theme)); const textColor = computed(() => convertThemeToColorBlackDefault(props.textColor)); const borderColor = computed(() => props.border ? convertThemeToColorBlackDefault(props.border) : '' ); const textSize = computed(() => { if (!props?.size || props.size === 'medium') return '16px'; switch (props.size) { case 'small': return '12px'; case 'large': return '20px'; case 'extraLarge': return '24px'; } }); const buttonPadding = computed(() => { if (!props?.size || props.size === 'medium') return '0.75rem 0.5rem'; switch (props.size) { case 'small': return '0.5rem 0.375rem'; case 'large': return '1.2rem 0.8rem'; case 'extraLarge': return '1.8rem 1.2rem'; } }); const width = computed(() => (props.width ? `${props.width}px` : 'max-content')); </script> <template> <button :class="[ 'button', { 'flex-column': iconPos === 'top' || iconPos === 'bottom', border: borderColor } ]" :style="`padding: ${buttonPadding}; width: ${width}`" > <span :style="`background-color: ${themeColor}`" class="background"></span> <span :style="`color: ${textColor}; font-size: ${textSize}`" :class="[ 'text', { bold: textStyle === 'bold', italic: textStyle === 'italic' } ]" >{{ label ?? 'Button' }}</span > <span :class="[ 'icon', { 'order-1': iconPos === 'left' || iconPos === 'top' } ]" > <slot /> </span> </button> </template> <style scoped> .button { position: relative; border-radius: 7px; display: flex; gap: 8px; justify-content: center; align-items: center; user-select: none; } .button:hover .background { filter: brightness(90%); } .background { width: 100%; height: 100%; position: absolute; top: 0; left: 0; border-radius: 5px; transition: filter 0.2s ease-in-out; } .text { position: relative; z-index: 2; line-height: 1; } .icon { position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; } .flex-column { flex-direction: column; } .order-1 { order: -1; } .bold { font-weight: bold; } .italic { font-style: italic; } .border { border: 2px solid v-bind(borderColor); } </style>
src/stories/components/Drawer/Drawer.stories.ts +5 −9 Original line number Diff line number Diff line Loading @@ -14,11 +14,11 @@ const meta: Meta = { header: { control: 'text' }, default: { control: 'text' }, footer: { control: 'text' }, isModal: { control: 'boolean' }, isDismissible: { control: 'boolean' }, modal: { control: 'boolean' }, dismissible: { control: 'boolean' }, closeIcon: { control: 'select', options: Object.keys(iconsSet) }, isHeaderDivider: { control: 'boolean' }, isFooterDivider: { control: 'boolean' }, headerDivider: { control: 'boolean' }, footerDivider: { control: 'boolean' }, theme: { control: 'select', options: [ Loading Loading @@ -50,11 +50,7 @@ const meta: Meta = { 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: { visible: true, Loading
src/stories/components/Drawer/Drawer.vue +12 −12 Original line number Diff line number Diff line Loading @@ -9,22 +9,22 @@ const props = withDefaults( position: 'left' | 'right' | 'top' | 'bottom'; width?: string | number; theme?: TThemeColor; isModal?: boolean; isDismissible?: boolean; modal?: boolean; dismissible?: boolean; closeIcon?: TIcons; isHeaderDivider?: boolean; isFooterDivider?: boolean; headerDivider?: boolean; footerDivider?: boolean; }>(), { visible: false, position: 'left', width: 400, isModal: true, isDismissible: true, modal: true, dismissible: true, theme: 'white', closeIcon: 'CrossIcon', isHeaderDivider: false, isFooterDivider: false, headerDivider: false, footerDivider: false, }, ); const emit = defineEmits(['onClose']); Loading @@ -44,14 +44,14 @@ const drawerWidth = computed(() => { <template> <article> <section v-if="isModal" v-if="modal" :class="[ 'drawerBackground', { drawerBackgroundOpened: visible, }, ]" @click.prevent="isDismissible ? (visible = false) : false" @click.prevent="dismissible ? (visible = false) : false" ></section> <section :style="`color: ${textColor}; background-color: ${themeColor}`" Loading Loading @@ -81,12 +81,12 @@ const drawerWidth = computed(() => { <component :is="iconsSet[closeIcon]" :color="textColor" /> </button> </header> <div v-if="isHeaderDivider" class="divider divider-header"></div> <div v-if="headerDivider" class="divider divider-header"></div> <div class="main"> <slot /> </div> <div v-if="$slots.footer"> <div v-if="isFooterDivider" class="divider"></div> <div v-if="footerDivider" class="divider"></div> <footer class="drawerFooter"> <slot name="footer" /> </footer> Loading