diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/c-alert/c-alert.demo.vue | 8 | ||||
-rw-r--r-- | src/ui/c-alert/c-alert.theme.ts | 1 | ||||
-rw-r--r-- | src/ui/c-alert/c-alert.vue | 20 | ||||
-rw-r--r-- | src/ui/c-button/c-button.demo.vue | 18 | ||||
-rw-r--r-- | src/ui/c-button/c-button.theme.ts | 32 | ||||
-rw-r--r-- | src/ui/c-button/c-button.vue | 48 | ||||
-rw-r--r-- | src/ui/c-card/c-card.demo.vue | 2 | ||||
-rw-r--r-- | src/ui/c-card/c-card.vue | 20 | ||||
-rw-r--r-- | src/ui/c-input-text/c-input-text.demo.vue | 32 | ||||
-rw-r--r-- | src/ui/c-input-text/c-input-text.test.ts | 8 | ||||
-rw-r--r-- | src/ui/c-input-text/c-input-text.vue | 178 | ||||
-rw-r--r-- | src/ui/c-link/c-link.demo.vue | 14 | ||||
-rw-r--r-- | src/ui/c-link/c-link.vue | 18 | ||||
-rw-r--r-- | src/ui/color/color.models.test.ts | 2 | ||||
-rw-r--r-- | src/ui/demo/demo-wrapper.vue | 20 |
15 files changed, 208 insertions, 213 deletions
diff --git a/src/ui/c-alert/c-alert.demo.vue b/src/ui/c-alert/c-alert.demo.vue index 5d8d1f2..546c785 100644 --- a/src/ui/c-alert/c-alert.demo.vue +++ b/src/ui/c-alert/c-alert.demo.vue @@ -1,3 +1,7 @@ +<script lang="ts" setup> +const variants = ['warning'] as const; +</script> + <template> <c-alert v-for="variant in variants" :key="variant" :type="variant" mb-4> Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni reprehenderit itaque enim? Suscipit magni optio velit @@ -5,7 +9,3 @@ odio! </c-alert> </template> - -<script lang="ts" setup> -const variants = ['warning'] as const; -</script> diff --git a/src/ui/c-alert/c-alert.theme.ts b/src/ui/c-alert/c-alert.theme.ts index b974c37..36d5d34 100644 --- a/src/ui/c-alert/c-alert.theme.ts +++ b/src/ui/c-alert/c-alert.theme.ts @@ -2,7 +2,6 @@ import { darken } from '../color/color.models'; import { defineThemes } from '../theme/theme.models'; import { appThemes } from '../theme/themes'; -// eslint-disable-next-line import WarningIcon from '~icons/mdi/alert-circle-outline'; export const { useTheme } = defineThemes({ diff --git a/src/ui/c-alert/c-alert.vue b/src/ui/c-alert/c-alert.vue index 1fedbb0..607acb9 100644 --- a/src/ui/c-alert/c-alert.vue +++ b/src/ui/c-alert/c-alert.vue @@ -1,3 +1,13 @@ +<script lang="ts" setup> +import { useTheme } from './c-alert.theme'; + +const props = withDefaults(defineProps<{ type?: 'warning' }>(), { type: 'warning' }); +const { type } = toRefs(props); + +const theme = useTheme(); +const variantTheme = computed(() => theme.value[type.value]); +</script> + <template> <div class="c-alert" flex items-center b-rd-4px pa-5> <div class="c-alert--icon" mr-4 text-40px op-60> @@ -12,16 +22,6 @@ </div> </template> -<script lang="ts" setup> -import { useTheme } from './c-alert.theme'; - -const props = withDefaults(defineProps<{ type?: 'warning' }>(), { type: 'warning' }); -const { type } = toRefs(props); - -const theme = useTheme(); -const variantTheme = computed(() => theme.value[type.value]); -</script> - <style lang="less" scoped> .c-alert { background-color: v-bind('variantTheme.backgroundColor'); diff --git a/src/ui/c-button/c-button.demo.vue b/src/ui/c-button/c-button.demo.vue index 48576f6..b9d011a 100644 --- a/src/ui/c-button/c-button.demo.vue +++ b/src/ui/c-button/c-button.demo.vue @@ -1,3 +1,11 @@ +<script lang="ts" setup> +import _ from 'lodash'; + +const buttonVariants = ['basic', 'text'] as const; +const buttonTypes = ['default', 'primary', 'warning', 'error'] as const; +const buttonSizes = ['small', 'medium', 'large'] as const; +</script> + <template> <div v-for="buttonVariant of buttonVariants" :key="buttonVariant"> <h2>{{ _.capitalize(buttonVariant) }}</h2> @@ -40,13 +48,3 @@ </div> </div> </template> - -<script lang="ts" setup> -import _ from 'lodash'; - -const buttonVariants = ['basic', 'text'] as const; -const buttonTypes = ['default', 'primary', 'warning', 'error'] as const; -const buttonSizes = ['small', 'medium', 'large'] as const; -</script> - -<style lang="less" scoped></style> diff --git a/src/ui/c-button/c-button.theme.ts b/src/ui/c-button/c-button.theme.ts index e2e1591..926cd11 100644 --- a/src/ui/c-button/c-button.theme.ts +++ b/src/ui/c-button/c-button.theme.ts @@ -2,7 +2,7 @@ import { darken, lighten } from '../color/color.models'; import { defineThemes } from '../theme/theme.models'; import { appThemes } from '../theme/themes'; -const createState = ({ +function createState({ textColor, backgroundColor, hoverBackground, @@ -10,20 +10,22 @@ const createState = ({ pressedBackground, pressedTextColor = textColor, }: { - textColor: string; - backgroundColor: string; - hoverBackground: string; - hoveredTextColor?: string; - pressedBackground: string; - pressedTextColor?: string; -}) => ({ - textColor, - backgroundColor, - hover: { textColor: hoveredTextColor, backgroundColor: hoverBackground }, - pressed: { textColor: pressedTextColor, backgroundColor: pressedBackground }, -}); + textColor: string + backgroundColor: string + hoverBackground: string + hoveredTextColor?: string + pressedBackground: string + pressedTextColor?: string +}) { + return { + textColor, + backgroundColor, + hover: { textColor: hoveredTextColor, backgroundColor: hoverBackground }, + pressed: { textColor: pressedTextColor, backgroundColor: pressedBackground }, + }; +} -const createTheme = ({ style }: { style: 'light' | 'dark' }) => { +function createTheme({ style }: { style: 'light' | 'dark' }) { const theme = appThemes[style]; return { @@ -95,7 +97,7 @@ const createTheme = ({ style }: { style: 'light' | 'dark' }) => { }), }, }; -}; +} export const { useTheme } = defineThemes({ dark: createTheme({ style: 'dark' }), diff --git a/src/ui/c-button/c-button.vue b/src/ui/c-button/c-button.vue index 24b91b8..06a4786 100644 --- a/src/ui/c-button/c-button.vue +++ b/src/ui/c-button/c-button.vue @@ -1,31 +1,18 @@ -<template> - <component - :is="tag" - :href="href ?? to" - class="c-button" - :class="{ disabled, round, circle }" - :to="to" - @click="handleClick" - > - <slot /> - </component> -</template> - <script lang="ts" setup> import type { RouteLocationRaw } from 'vue-router'; -import { useTheme } from './c-button.theme'; import { useAppTheme } from '../theme/themes'; +import { useTheme } from './c-button.theme'; const props = withDefaults( defineProps<{ - type?: 'default' | 'primary' | 'warning' | 'error'; - variant?: 'basic' | 'text'; - disabled?: boolean; - round?: boolean; - circle?: boolean; - href?: string; - to?: RouteLocationRaw; - size?: 'small' | 'medium' | 'large'; + type?: 'default' | 'primary' | 'warning' | 'error' + variant?: 'basic' | 'text' + disabled?: boolean + round?: boolean + circle?: boolean + href?: string + to?: RouteLocationRaw + size?: 'small' | 'medium' | 'large' }>(), { type: 'default', @@ -38,10 +25,10 @@ const props = withDefaults( size: 'medium', }, ); -const { variant, disabled, round, circle, href, type, to, size: sizeName } = toRefs(props); - const emits = defineEmits(['click']); +const { variant, disabled, round, circle, href, type, to, size: sizeName } = toRefs(props); + function handleClick(event: MouseEvent) { if (!disabled.value) { emits('click', event); @@ -64,6 +51,19 @@ const appTheme = useAppTheme(); const size = computed(() => theme.value.size[sizeName.value]); </script> +<template> + <component + :is="tag" + :href="href ?? to" + class="c-button" + :class="{ disabled, round, circle }" + :to="to" + @click="handleClick" + > + <slot /> + </component> +</template> + <style lang="less" scoped> .c-button { line-height: 1; diff --git a/src/ui/c-card/c-card.demo.vue b/src/ui/c-card/c-card.demo.vue index 6d81ee6..2a6fb9d 100644 --- a/src/ui/c-card/c-card.demo.vue +++ b/src/ui/c-card/c-card.demo.vue @@ -9,5 +9,3 @@ </c-card> </div> </template> - -<script lang="ts" setup></script> diff --git a/src/ui/c-card/c-card.vue b/src/ui/c-card/c-card.vue index 11d86fd..739e657 100644 --- a/src/ui/c-card/c-card.vue +++ b/src/ui/c-card/c-card.vue @@ -1,17 +1,8 @@ -<template> - <div class="c-card"> - <div v-if="title" class="c-card-title"> - {{ title }} - </div> - <slot /> - </div> -</template> - <script lang="ts" setup> import { useTheme } from './c-card.theme'; const props = defineProps<{ - title?: string; + title?: string }>(); const { title } = toRefs(props); @@ -19,6 +10,15 @@ const { title } = toRefs(props); const theme = useTheme(); </script> +<template> + <div class="c-card"> + <div v-if="title" class="c-card-title"> + {{ title }} + </div> + <slot /> + </div> +</template> + <style lang="less" scoped> .c-card { background-color: v-bind('theme.backgroundColor'); diff --git a/src/ui/c-input-text/c-input-text.demo.vue b/src/ui/c-input-text/c-input-text.demo.vue index 5a5fa99..b027787 100644 --- a/src/ui/c-input-text/c-input-text.demo.vue +++ b/src/ui/c-input-text/c-input-text.demo.vue @@ -1,3 +1,19 @@ +<script lang="ts" setup> +import { useValidation } from '@/composable/validation'; + +const value = ref('value'); +const valueLong = ref( + 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, est modi iusto repellendus fuga accusantium atque at magnam aliquam eum explicabo vero quia, nobis quasi quis! Earum amet quam a?', +); + +const validationRules = [{ message: 'Length must be > 10', validator: (value: string) => value.length > 10 }]; + +const validation = useValidation({ + source: value, + rules: validationRules, +}); +</script> + <template> <h2>Default</h2> @@ -58,19 +74,3 @@ clearable /> </template> - -<script lang="ts" setup> -import { useValidation } from '@/composable/validation'; - -const value = ref('value'); -const valueLong = ref( - 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, est modi iusto repellendus fuga accusantium atque at magnam aliquam eum explicabo vero quia, nobis quasi quis! Earum amet quam a?', -); - -const validationRules = [{ message: 'Length must be > 10', validator: (value: string) => value.length > 10 }]; - -const validation = useValidation({ - source: value, - rules: validationRules, -}); -</script> diff --git a/src/ui/c-input-text/c-input-text.test.ts b/src/ui/c-input-text/c-input-text.test.ts index 69f4046..2d1908d 100644 --- a/src/ui/c-input-text/c-input-text.test.ts +++ b/src/ui/c-input-text/c-input-text.test.ts @@ -1,9 +1,9 @@ -import { describe, expect, it, beforeEach } from 'vitest'; -import { shallowMount, mount } from '@vue/test-utils'; -import { setActivePinia, createPinia } from 'pinia'; +import { beforeEach, describe, expect, it } from 'vitest'; +import { mount, shallowMount } from '@vue/test-utils'; +import { createPinia, setActivePinia } from 'pinia'; import _ from 'lodash'; -import { useValidation } from '@/composable/validation'; import CInputText from './c-input-text.vue'; +import { useValidation } from '@/composable/validation'; describe('CInputText', () => { beforeEach(() => { diff --git a/src/ui/c-input-text/c-input-text.vue b/src/ui/c-input-text/c-input-text.vue index cd5f067..90d7152 100644 --- a/src/ui/c-input-text/c-input-text.vue +++ b/src/ui/c-input-text/c-input-text.vue @@ -1,95 +1,35 @@ -<template> - <div - class="c-input-text" - :class="{ disabled, error: !validation.isValid, 'label-left': labelPosition === 'left', multiline }" - > - <label v-if="label" :for="id" class="label"> {{ label }} </label> - - <div class="feedback-wrapper"> - <div ref="inputWrapperRef" class="input-wrapper"> - <slot name="prefix" /> - - <textarea - v-if="multiline" - :id="id" - ref="textareaRef" - v-model="value" - class="input" - :placeholder="placeholder" - :readonly="readonly" - :disabled="disabled" - :data-test-id="testId" - :autocapitalize="autocapitalize ?? (rawText ? 'off' : undefined)" - :autocomplete="autocomplete ?? (rawText ? 'off' : undefined)" - :autocorrect="autocorrect ?? (rawText ? 'off' : undefined)" - :spellcheck="spellcheck ?? (rawText ? false : undefined)" - :rows="rows" - /> - - <input - v-else - :id="id" - v-model="value" - :type="htmlInputType" - class="input" - size="1" - :placeholder="placeholder" - :readonly="readonly" - :disabled="disabled" - :data-test-id="testId" - :autocapitalize="autocapitalize ?? (rawText ? 'off' : undefined)" - :autocomplete="autocomplete ?? (rawText ? 'off' : undefined)" - :autocorrect="autocorrect ?? (rawText ? 'off' : undefined)" - :spellcheck="spellcheck ?? (rawText ? false : undefined)" - /> - - <c-button v-if="clearable && value" variant="text" circle size="small" @click="value = ''"> - <icon-mdi-close /> - </c-button> - - <c-button v-if="type === 'password'" variant="text" circle size="small" @click="showPassword = !showPassword"> - <icon-mdi-eye v-if="!showPassword" /> - <icon-mdi-eye-off v-if="showPassword" /> - </c-button> - <slot name="suffix" /> - </div> - <span v-if="!validation.isValid" class="feedback"> {{ validation.message }} </span> - </div> - </div> -</template> - <script lang="ts" setup> -import { generateRandomId } from '@/utils/random'; -import { useValidation, type UseValidationRule } from '@/composable/validation'; import type { Ref } from 'vue'; -import { useTheme } from './c-input-text.theme'; import { useAppTheme } from '../theme/themes'; +import { useTheme } from './c-input-text.theme'; +import { generateRandomId } from '@/utils/random'; +import { type UseValidationRule, useValidation } from '@/composable/validation'; const props = withDefaults( defineProps<{ - value?: string; - id?: string; - placeholder?: string; - label?: string; - readonly?: boolean; - disabled?: boolean; - validationRules?: UseValidationRule<string>[]; - validationWatch?: Ref<unknown>[]; - validation?: ReturnType<typeof useValidation>; - labelPosition?: 'top' | 'left'; - labelWidth?: string; - labelAlign?: 'left' | 'right'; - clearable?: boolean; - testId?: string; - autocapitalize?: 'none' | 'sentences' | 'words' | 'characters' | 'on' | 'off' | string; - autocomplete?: 'on' | 'off' | string; - autocorrect?: 'on' | 'off' | string; - spellcheck?: 'true' | 'false' | boolean; - rawText?: boolean; - type?: 'text' | 'password'; - multiline?: boolean; - rows?: number | string; - autosize?: boolean; + value?: string + id?: string + placeholder?: string + label?: string + readonly?: boolean + disabled?: boolean + validationRules?: UseValidationRule<string>[] + validationWatch?: Ref<unknown>[] + validation?: ReturnType<typeof useValidation> + labelPosition?: 'top' | 'left' + labelWidth?: string + labelAlign?: 'left' | 'right' + clearable?: boolean + testId?: string + autocapitalize?: 'none' | 'sentences' | 'words' | 'characters' | 'on' | 'off' | string + autocomplete?: 'on' | 'off' | string + autocorrect?: 'on' | 'off' | string + spellcheck?: 'true' | 'false' | boolean + rawText?: boolean + type?: 'text' | 'password' + multiline?: boolean + rows?: number | string + autosize?: boolean }>(), { value: '', @@ -123,9 +63,9 @@ const showPassword = ref(false); const { id, placeholder, label, validationRules, labelPosition, labelWidth, labelAlign, autosize } = toRefs(props); -const validation = - props.validation ?? - useValidation({ +const validation + = props.validation + ?? useValidation({ rules: validationRules, source: value, watch: props.validationWatch, @@ -170,6 +110,66 @@ const htmlInputType = computed(() => { }); </script> +<template> + <div + class="c-input-text" + :class="{ disabled, 'error': !validation.isValid, 'label-left': labelPosition === 'left', multiline }" + > + <label v-if="label" :for="id" class="label"> {{ label }} </label> + + <div class="feedback-wrapper"> + <div ref="inputWrapperRef" class="input-wrapper"> + <slot name="prefix" /> + + <textarea + v-if="multiline" + :id="id" + ref="textareaRef" + v-model="value" + class="input" + :placeholder="placeholder" + :readonly="readonly" + :disabled="disabled" + :data-test-id="testId" + :autocapitalize="autocapitalize ?? (rawText ? 'off' : undefined)" + :autocomplete="autocomplete ?? (rawText ? 'off' : undefined)" + :autocorrect="autocorrect ?? (rawText ? 'off' : undefined)" + :spellcheck="spellcheck ?? (rawText ? false : undefined)" + :rows="rows" + /> + + <input + v-else + :id="id" + v-model="value" + :type="htmlInputType" + class="input" + size="1" + :placeholder="placeholder" + :readonly="readonly" + :disabled="disabled" + :data-test-id="testId" + :autocapitalize="autocapitalize ?? (rawText ? 'off' : undefined)" + :autocomplete="autocomplete ?? (rawText ? 'off' : undefined)" + :autocorrect="autocorrect ?? (rawText ? 'off' : undefined)" + :spellcheck="spellcheck ?? (rawText ? false : undefined)" + > + + <c-button v-if="clearable && value" variant="text" circle size="small" @click="value = ''"> + <icon-mdi-close /> + </c-button> + + <c-button v-if="type === 'password'" variant="text" circle size="small" @click="showPassword = !showPassword"> + <icon-mdi-eye v-if="!showPassword" /> + <icon-mdi-eye-off v-if="showPassword" /> + </c-button> + <slot name="suffix" /> + </div> + <span v-if="!validation.isValid" class="feedback"> {{ validation.message }} </span> + </div> + </div> +</template> + <style lang="less" scoped> .c-input-text { display: inline-flex; diff --git a/src/ui/c-link/c-link.demo.vue b/src/ui/c-link/c-link.demo.vue index a655f11..2573e9f 100644 --- a/src/ui/c-link/c-link.demo.vue +++ b/src/ui/c-link/c-link.demo.vue @@ -1,12 +1,12 @@ +<script lang="ts" setup> +import CLink from './c-link.vue'; +</script> + <template> <div> <h2>Default</h2> - <c-link mx-1> Link </c-link> + <CLink mx-1> + Link + </CLink> </div> </template> - -<script lang="ts" setup> -import CLink from './c-link.vue'; -</script> - -<style lang="less" scoped></style> diff --git a/src/ui/c-link/c-link.vue b/src/ui/c-link/c-link.vue index a7d1b83..828d56f 100644 --- a/src/ui/c-link/c-link.vue +++ b/src/ui/c-link/c-link.vue @@ -1,16 +1,10 @@ -<template> - <component :is="tag" :href="href ?? to" class="c-link" :to="to"> - <slot /> - </component> -</template> - <script lang="ts" setup> -import { RouterLink, type RouteLocationRaw } from 'vue-router'; +import { type RouteLocationRaw, RouterLink } from 'vue-router'; import { useTheme } from './c-link.theme'; const props = defineProps<{ - href?: string; - to?: RouteLocationRaw; + href?: string + to?: RouteLocationRaw }>(); const { href, to } = toRefs(props); @@ -27,6 +21,12 @@ const tag = computed(() => { }); </script> +<template> + <component :is="tag" :href="href ?? to" class="c-link" :to="to"> + <slot /> + </component> +</template> + <style lang="less" scoped> .c-link { line-height: inherit; diff --git a/src/ui/color/color.models.test.ts b/src/ui/color/color.models.test.ts index dc59fa8..256c100 100644 --- a/src/ui/color/color.models.test.ts +++ b/src/ui/color/color.models.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'vitest'; +import { describe, expect, test } from 'vitest'; import { darken, lighten, setOpacity } from './color.models'; describe('color models', () => { diff --git a/src/ui/demo/demo-wrapper.vue b/src/ui/demo/demo-wrapper.vue index 8d4bae0..c4d3604 100644 --- a/src/ui/demo/demo-wrapper.vue +++ b/src/ui/demo/demo-wrapper.vue @@ -1,3 +1,12 @@ +<script lang="ts" setup> +import _ from 'lodash'; +import { demoRoutes } from './demo.routes'; + +const route = useRoute(); + +const componentName = computed(() => _.startCase(String(route.name).replace(/^c-/, ''))); +</script> + <template> <div mt-2 w-full p-8> <h1>c-lib components</h1> @@ -25,14 +34,3 @@ </div> </div> </template> - -<script lang="ts" setup> -import _ from 'lodash'; -import { demoRoutes } from './demo.routes'; - -const route = useRoute(); - -const componentName = computed(() => _.startCase(String(route.name).replace(/^c-/, ''))); -</script> - -<style lang="less" scoped></style> |