aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/c-alert/c-alert.demo.vue8
-rw-r--r--src/ui/c-alert/c-alert.theme.ts1
-rw-r--r--src/ui/c-alert/c-alert.vue20
-rw-r--r--src/ui/c-button/c-button.demo.vue18
-rw-r--r--src/ui/c-button/c-button.theme.ts32
-rw-r--r--src/ui/c-button/c-button.vue48
-rw-r--r--src/ui/c-card/c-card.demo.vue2
-rw-r--r--src/ui/c-card/c-card.vue20
-rw-r--r--src/ui/c-input-text/c-input-text.demo.vue32
-rw-r--r--src/ui/c-input-text/c-input-text.test.ts8
-rw-r--r--src/ui/c-input-text/c-input-text.vue178
-rw-r--r--src/ui/c-link/c-link.demo.vue14
-rw-r--r--src/ui/c-link/c-link.vue18
-rw-r--r--src/ui/color/color.models.test.ts2
-rw-r--r--src/ui/demo/demo-wrapper.vue20
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>