Loading src/Playground.vue +7 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ import Popup from '@stories/components/Popup/Popup.vue'; import Table from '@stories/components/Table/Table.vue'; import { ref } from 'vue'; import type { ISBOption, ISliderOptions, ITableColumn } from '@interfaces/componentsProp'; import Checkbox from '@stories/components/Checkbox/Checkbox.vue'; const visibleDrawer = ref(false); const sliderOptions: ISliderOptions[] = [ Loading Loading @@ -178,10 +179,16 @@ const tableData = [ }, ], ]; const activeCheckbox = ref(); </script> <template> <h2 class="title gradient-text">Playground</h2> {{ activeCheckbox }} <Checkbox v-model:active="activeCheckbox" size="small" /> <Checkbox v-model:active="activeCheckbox" /> <Checkbox v-model:active="activeCheckbox" size="large" /> <Checkbox v-model:active="activeCheckbox" size="huge" /> <Table show-all-lines :columns="tableColumns" Loading src/common/interfaces/componentsProps.ts +17 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,23 @@ export interface ITSProps { disabled?: boolean; } export interface ICheckboxProps { label?: string; labelPos?: TPosition; name?: string; size?: TSize; disabled?: boolean; invalid?: boolean; theme?: TThemeColor; activeTheme?: TThemeColor; textColor?: TThemeColor; borderColor?: TThemeColor; darknessTheme?: TDarkness; darknessActiveTheme?: TDarkness; darknessTextColor?: TDarkness; darknessBorderColor?: TDarkness; } export interface IDividerProps { height?: number; type?: TBorder; Loading src/stories/components/Checkbox/Checkbox.stories.ts 0 → 100644 +171 −0 Original line number Diff line number Diff line import type { Meta, StoryObj } from '@storybook/vue3'; import Checkbox from './Checkbox.vue'; const meta: Meta = { title: 'Components/Checkbox', component: Checkbox, tags: ['autodocs'], parameters: { docs: { description: { component: 'A component that is used as a Checkbox. Can be used with icon.', }, }, }, argTypes: { active: { control: 'boolean' }, invalid: { control: 'boolean' }, disabled: { control: 'boolean' }, label: { control: 'text' }, name: { control: 'text' }, size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] }, labelPos: { control: 'select', options: ['left', 'top', 'right', 'bottom'] }, darknessTheme: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] }, darknessActiveTheme: { 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'], }, darknessBorderColor: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'], }, theme: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, activeTheme: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, textColor: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, borderColor: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, }, args: {}, } satisfies Meta<typeof Checkbox>; export default meta; type Story = StoryObj<typeof meta>; export const Simple: Story = { args: { active: true, }, }; export const Small: Story = { args: { active: false, size: 'small', theme: 'yellow', activeTheme: 'blue', darknessTheme: '300', darknessActiveTheme: '700', label: 'Are you gay?', }, }; export const Large: Story = { args: { active: true, size: 'large', theme: 'green', activeTheme: 'sky', darknessTheme: '700', darknessActiveTheme: '300', label: 'Checkbox', labelPos: 'top', invalid: true, }, }; export const Huge: Story = { args: { active: false, size: 'huge', theme: 'indigo', activeTheme: 'purple', darknessTheme: '500', darknessActiveTheme: '500', label: 'Checkbox', textColor: 'blue', invalid: false, disabled: true, labelPos: 'left', }, }; src/stories/components/Checkbox/Checkbox.vue 0 → 100644 +143 −0 Original line number Diff line number Diff line <script setup lang="ts"> import type { ICheckboxProps } from '@interfaces/componentsProps'; import { computed } from 'vue'; import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; import CheckMarkIcon from '@stories/icons/Mono/CheckMarkIcon.vue'; const props = withDefaults(defineProps<ICheckboxProps>(), { label: '', name: '', labelPos: 'right', size: 'normal', theme: 'white', activeTheme: 'black', textColor: 'black', borderColor: 'black', darknessTheme: '500', darknessActiveTheme: '500', darknessTextColor: '500', darknessBorderColor: '500', }); const active = defineModel('active'); // watch(, () => {}); const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const activeThemeColor = computed(() => convertThemeToColor(props.activeTheme, props.darknessActiveTheme)); const iconColor = computed(() => props.disabled ? '#62708c' : convertThemeToTextColor(props.activeTheme, props.darknessActiveTheme), ); const color = computed(() => convertThemeToColor(props.textColor, props.darknessTextColor)); const borderColor = computed(() => props.invalid ? 'red' : props.disabled ? '#62708c' : convertThemeToColor(props.borderColor, props.darknessBorderColor), ); const elSize = computed(() => { const size = props.size; if (size === 'normal') return 20; if (size === 'large') return 30; if (size === 'huge') return 40; return 13; }); const gap = computed(() => { if (!props.label) return '0px'; const size = props.size; if (size === 'normal') return '7px'; if (size === 'large') return '10px'; if (size === 'huge') return '15px'; return '5px'; }); const borderWidth = computed(() => (props.size === 'large' || props.size === 'huge' ? 2 : 1)); const borderRadius = computed(() => `${elSize.value / 7 - borderWidth.value}px`); </script> <template> <section :class="[ 'container', { flexColumn: ['top', 'bottom'].includes(labelPos), }, ]" @click.prevent="!disabled ? (active = !active) : ''" > <div class="main" :style="`width: ${elSize}px; height: ${elSize}px; border: ${borderWidth}px solid ${borderColor}`"> <input :style="`width: ${elSize}px; height: ${elSize}px; position: absolute; z-index: 100; cursor: ${disabled ? 'initial' : 'pointer'}`" v-model="active" type="checkbox" :name="name" :value="label" :disabled="disabled" /> <div :class="[ { inactive: !active, active: active, disabled: disabled, }, ]" > <CheckMarkIcon :style="`transition: all 0.3s ease-in-out; opacity: ${active ? 1 : 0}; position: absolute;`" :color="iconColor" :size="elSize" /> </div> </div> <p :class="[ { first: ['top', 'left'].includes(labelPos), }, ]" :style="`color: ${color}; line-height: 0.9; font-size: ${elSize}px; pointer-events: none`" > {{ label }} </p> </section> </template> <style scoped> .container { position: relative; display: flex; gap: v-bind(gap); box-sizing: content-box; width: max-content; } .main { position: relative; border-radius: 15%; } .inactive { height: 100%; border-radius: v-bind(borderRadius); background-color: v-bind(themeColor); transition: all 0.2s ease-in-out; } .active { width: 100%; height: 100%; border-radius: v-bind(borderRadius); background-color: v-bind(activeThemeColor); transition: all 0.2s ease-in-out; } .disabled { background-color: #e1e7f1 !important; } .first { order: -1; } .flexColumn { flex-direction: column; align-items: center; } input[type='checkbox'] { all: unset; width: 100%; } </style> src/stories/components/Table/Table.stories.ts +0 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,6 @@ export const Full: Story = { }, ], ], fontSize: '24px', showAllLines: true, border: 'fuchsia', Loading Loading
src/Playground.vue +7 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ import Popup from '@stories/components/Popup/Popup.vue'; import Table from '@stories/components/Table/Table.vue'; import { ref } from 'vue'; import type { ISBOption, ISliderOptions, ITableColumn } from '@interfaces/componentsProp'; import Checkbox from '@stories/components/Checkbox/Checkbox.vue'; const visibleDrawer = ref(false); const sliderOptions: ISliderOptions[] = [ Loading Loading @@ -178,10 +179,16 @@ const tableData = [ }, ], ]; const activeCheckbox = ref(); </script> <template> <h2 class="title gradient-text">Playground</h2> {{ activeCheckbox }} <Checkbox v-model:active="activeCheckbox" size="small" /> <Checkbox v-model:active="activeCheckbox" /> <Checkbox v-model:active="activeCheckbox" size="large" /> <Checkbox v-model:active="activeCheckbox" size="huge" /> <Table show-all-lines :columns="tableColumns" Loading
src/common/interfaces/componentsProps.ts +17 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,23 @@ export interface ITSProps { disabled?: boolean; } export interface ICheckboxProps { label?: string; labelPos?: TPosition; name?: string; size?: TSize; disabled?: boolean; invalid?: boolean; theme?: TThemeColor; activeTheme?: TThemeColor; textColor?: TThemeColor; borderColor?: TThemeColor; darknessTheme?: TDarkness; darknessActiveTheme?: TDarkness; darknessTextColor?: TDarkness; darknessBorderColor?: TDarkness; } export interface IDividerProps { height?: number; type?: TBorder; Loading
src/stories/components/Checkbox/Checkbox.stories.ts 0 → 100644 +171 −0 Original line number Diff line number Diff line import type { Meta, StoryObj } from '@storybook/vue3'; import Checkbox from './Checkbox.vue'; const meta: Meta = { title: 'Components/Checkbox', component: Checkbox, tags: ['autodocs'], parameters: { docs: { description: { component: 'A component that is used as a Checkbox. Can be used with icon.', }, }, }, argTypes: { active: { control: 'boolean' }, invalid: { control: 'boolean' }, disabled: { control: 'boolean' }, label: { control: 'text' }, name: { control: 'text' }, size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] }, labelPos: { control: 'select', options: ['left', 'top', 'right', 'bottom'] }, darknessTheme: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] }, darknessActiveTheme: { 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'], }, darknessBorderColor: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'], }, theme: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, activeTheme: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, textColor: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, borderColor: { control: 'select', options: [ 'white', 'blue', 'sky', 'cyan', 'teal', 'green', 'yellow', 'orange', 'pink', 'fuchsia', 'purple', 'indigo', 'rose', 'red', 'black', ], }, }, args: {}, } satisfies Meta<typeof Checkbox>; export default meta; type Story = StoryObj<typeof meta>; export const Simple: Story = { args: { active: true, }, }; export const Small: Story = { args: { active: false, size: 'small', theme: 'yellow', activeTheme: 'blue', darknessTheme: '300', darknessActiveTheme: '700', label: 'Are you gay?', }, }; export const Large: Story = { args: { active: true, size: 'large', theme: 'green', activeTheme: 'sky', darknessTheme: '700', darknessActiveTheme: '300', label: 'Checkbox', labelPos: 'top', invalid: true, }, }; export const Huge: Story = { args: { active: false, size: 'huge', theme: 'indigo', activeTheme: 'purple', darknessTheme: '500', darknessActiveTheme: '500', label: 'Checkbox', textColor: 'blue', invalid: false, disabled: true, labelPos: 'left', }, };
src/stories/components/Checkbox/Checkbox.vue 0 → 100644 +143 −0 Original line number Diff line number Diff line <script setup lang="ts"> import type { ICheckboxProps } from '@interfaces/componentsProps'; import { computed } from 'vue'; import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; import CheckMarkIcon from '@stories/icons/Mono/CheckMarkIcon.vue'; const props = withDefaults(defineProps<ICheckboxProps>(), { label: '', name: '', labelPos: 'right', size: 'normal', theme: 'white', activeTheme: 'black', textColor: 'black', borderColor: 'black', darknessTheme: '500', darknessActiveTheme: '500', darknessTextColor: '500', darknessBorderColor: '500', }); const active = defineModel('active'); // watch(, () => {}); const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const activeThemeColor = computed(() => convertThemeToColor(props.activeTheme, props.darknessActiveTheme)); const iconColor = computed(() => props.disabled ? '#62708c' : convertThemeToTextColor(props.activeTheme, props.darknessActiveTheme), ); const color = computed(() => convertThemeToColor(props.textColor, props.darknessTextColor)); const borderColor = computed(() => props.invalid ? 'red' : props.disabled ? '#62708c' : convertThemeToColor(props.borderColor, props.darknessBorderColor), ); const elSize = computed(() => { const size = props.size; if (size === 'normal') return 20; if (size === 'large') return 30; if (size === 'huge') return 40; return 13; }); const gap = computed(() => { if (!props.label) return '0px'; const size = props.size; if (size === 'normal') return '7px'; if (size === 'large') return '10px'; if (size === 'huge') return '15px'; return '5px'; }); const borderWidth = computed(() => (props.size === 'large' || props.size === 'huge' ? 2 : 1)); const borderRadius = computed(() => `${elSize.value / 7 - borderWidth.value}px`); </script> <template> <section :class="[ 'container', { flexColumn: ['top', 'bottom'].includes(labelPos), }, ]" @click.prevent="!disabled ? (active = !active) : ''" > <div class="main" :style="`width: ${elSize}px; height: ${elSize}px; border: ${borderWidth}px solid ${borderColor}`"> <input :style="`width: ${elSize}px; height: ${elSize}px; position: absolute; z-index: 100; cursor: ${disabled ? 'initial' : 'pointer'}`" v-model="active" type="checkbox" :name="name" :value="label" :disabled="disabled" /> <div :class="[ { inactive: !active, active: active, disabled: disabled, }, ]" > <CheckMarkIcon :style="`transition: all 0.3s ease-in-out; opacity: ${active ? 1 : 0}; position: absolute;`" :color="iconColor" :size="elSize" /> </div> </div> <p :class="[ { first: ['top', 'left'].includes(labelPos), }, ]" :style="`color: ${color}; line-height: 0.9; font-size: ${elSize}px; pointer-events: none`" > {{ label }} </p> </section> </template> <style scoped> .container { position: relative; display: flex; gap: v-bind(gap); box-sizing: content-box; width: max-content; } .main { position: relative; border-radius: 15%; } .inactive { height: 100%; border-radius: v-bind(borderRadius); background-color: v-bind(themeColor); transition: all 0.2s ease-in-out; } .active { width: 100%; height: 100%; border-radius: v-bind(borderRadius); background-color: v-bind(activeThemeColor); transition: all 0.2s ease-in-out; } .disabled { background-color: #e1e7f1 !important; } .first { order: -1; } .flexColumn { flex-direction: column; align-items: center; } input[type='checkbox'] { all: unset; width: 100%; } </style>
src/stories/components/Table/Table.stories.ts +0 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,6 @@ export const Full: Story = { }, ], ], fontSize: '24px', showAllLines: true, border: 'fuchsia', Loading