bonkers-ui 1.0.4 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/preview.js +1 -2
- package/package.json +1 -1
- package/src/{_colors.json → _styles/classTypes/_colors.json} +2 -2
- package/src/{_font-sizes.json → _styles/classTypes/_font-sizes.json} +1 -1
- package/src/{_shadow.json → _styles/classTypes/_shadow.json} +1 -1
- package/src/{_spacing.json → _styles/classTypes/_spacing.json} +1 -0
- package/src/_styles/{colors.css → variables/colors.css} +0 -0
- package/src/_styles/{font-sizes.css → variables/font-sizes.css} +1 -1
- package/src/_styles/variables/shadow.css +8 -0
- package/src/_styles/{spacing.css → variables/spacing.css} +1 -0
- package/src/components/ui-badge/_typings.ts +11 -0
- package/src/components/ui-badge/index.ts +2 -0
- package/src/components/ui-badge/ui-badge.stories.ts +41 -0
- package/src/components/ui-badge/ui-badge.vue +57 -0
- package/src/components/ui-ber-rank/index.ts +1 -0
- package/src/components/ui-ber-rank/ui-ber-rank.stories.ts +30 -0
- package/src/components/ui-ber-rank/ui-ber-rank.vue +142 -0
- package/src/components/ui-button/ui-button.stories.ts +27 -13
- package/src/components/ui-button/ui-button.test.ts +5 -3
- package/src/components/ui-button/ui-button.vue +34 -8
- package/src/components/ui-card-cta/ui-card-cta.stories.ts +3 -13
- package/src/components/ui-card-cta/ui-card-cta.vue +3 -10
- package/src/components/ui-card-result/index.ts +1 -0
- package/src/components/ui-card-result/ui-card-result.stories.ts +103 -0
- package/src/components/ui-card-result/ui-card-result.vue +70 -0
- package/src/components/ui-card-simple/ui-card-simple.stories.ts +2 -8
- package/src/components/ui-card-simple/ui-card-simple.vue +1 -6
- package/src/components/ui-checkbox/ui-checkbox.stories.ts +1 -5
- package/src/components/ui-checkbox/ui-checkbox.vue +0 -2
- package/src/components/ui-icon/_typings.ts +9 -2
- package/src/components/ui-icon/ui-icon.stories.ts +2 -6
- package/src/components/ui-icon/ui-icon.vue +0 -2
- package/src/components/ui-input/_typings.ts +0 -2
- package/src/components/ui-input/ui-input.stories.ts +9 -7
- package/src/components/ui-input/ui-input.vue +48 -21
- package/src/components/ui-input-range/index.ts +1 -0
- package/src/components/ui-input-range/ui-input-range.stories.ts +44 -0
- package/src/components/ui-input-range/ui-input-range.vue +60 -0
- package/src/components/ui-list-item/index.ts +1 -0
- package/src/components/ui-list-item/ui-list-item.stories.ts +35 -0
- package/src/components/ui-list-item/ui-list-item.vue +29 -0
- package/src/components/ui-radio/ui-radio.stories.ts +8 -7
- package/src/components/ui-radio/ui-radio.vue +35 -4
- package/src/components/ui-radio-list-fancy/ui-radio-item/ui-radio-item.vue +3 -4
- package/src/components/ui-radio-list-fancy/ui-radio-list-fancy.stories.ts +2 -8
- package/src/components/ui-radio-list-fancy/ui-radio-list-fancy.vue +5 -6
- package/src/components/ui-ripple/ui-ripple.stories.ts +3 -8
- package/src/components/ui-ripple/ui-ripple.vue +0 -5
- package/src/components/ui-select/index.ts +1 -0
- package/src/components/ui-select/ui-select.stories.ts +41 -0
- package/src/components/ui-select/ui-select.vue +68 -0
- package/src/components/ui-tabs/index.ts +1 -0
- package/src/components/ui-tabs/ui-tabs.stories.ts +27 -0
- package/src/components/ui-tabs/ui-tabs.vue +58 -0
- package/src/components/ui-toggle/index.ts +1 -0
- package/src/components/ui-toggle/ui-toggle.stories.ts +39 -0
- package/src/components/ui-toggle/ui-toggle.vue +127 -0
- package/src/components/ui-typography/_typings.ts +5 -31
- package/src/components/ui-typography/index.ts +1 -1
- package/src/components/ui-typography/ui-typography.stories.ts +7 -6
- package/src/components/ui-typography/ui-typography.vue +4 -6
- package/src/components/ui-verification-input/ui-verification-input.stories.ts +1 -6
- package/src/components/ui-verification-input/ui-verification-input.vue +0 -2
- package/src/main.css +6 -5
- package/src/stories/colors/ui-colors.vue +1 -1
- package/src/stories/font-sizes/font-sizes.stories.ts +13 -0
- package/src/stories/font-sizes/ui-font-sizes.vue +28 -0
- package/src/stories/spacings/ui-spacings.vue +1 -1
- package/tailwind.config.js +4 -4
- package/vite.config.ts +5 -3
- package/src/_styles/shadow.css +0 -7
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
justify === EJustify.BETWEEN && 'justify-between',
|
|
10
10
|
justify === EJustify.EVENLY && 'justify-evenly',
|
|
11
11
|
justify === EJustify.CENTER && 'justify-center',
|
|
12
|
-
|
|
12
|
+
disabled && 'pointer-events-none',
|
|
13
13
|
]"
|
|
14
14
|
>
|
|
15
15
|
<input
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
type="radio"
|
|
19
19
|
:name="name"
|
|
20
20
|
:value="value"
|
|
21
|
+
:disabled="disabled"
|
|
21
22
|
class="appearance-none absolute"
|
|
22
23
|
@input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement)?.value)"
|
|
23
24
|
>
|
|
24
25
|
<span
|
|
25
|
-
class="ui-radio_custom block w-md h-md border border-
|
|
26
|
+
class="ui-radio_custom block w-md h-md border border-secondary-alt rounded-full relative hover:border-secondary-alt-700 focus:border-secondary-alt-700"
|
|
26
27
|
:class="invertOrder && 'order-last'"
|
|
27
28
|
>
|
|
28
29
|
<span class="ui-radio__dot absolute top-2/4 left-2/4 w-xs h-xs block bg-primary rounded-full" />
|
|
@@ -37,18 +38,18 @@
|
|
|
37
38
|
const slots = useSlots();
|
|
38
39
|
const props = defineProps<{
|
|
39
40
|
modelValue: string;
|
|
40
|
-
className?: string;
|
|
41
41
|
name: string;
|
|
42
42
|
value: string;
|
|
43
43
|
justify?: EJustify;
|
|
44
44
|
invertOrder?: boolean;
|
|
45
|
+
disabled?: boolean;
|
|
45
46
|
}>();
|
|
46
47
|
|
|
47
48
|
defineEmits(["update:modelValue"]);
|
|
48
49
|
|
|
49
50
|
const localValue = ref(props.modelValue);
|
|
50
51
|
|
|
51
|
-
watch(()=>props.modelValue, (newValue)=>{
|
|
52
|
+
watch(() => props.modelValue, (newValue) => {
|
|
52
53
|
if(newValue !== localValue.value){
|
|
53
54
|
localValue.value = newValue;
|
|
54
55
|
}
|
|
@@ -65,7 +66,37 @@
|
|
|
65
66
|
transition: transform 0.2s ease-in-out;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
input:disabled + .ui-radio_custom {
|
|
70
|
+
border: 1px solid var(--color-secondary-alt-400);
|
|
71
|
+
background-color: var(--color-secondary-alt-200);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
input:focus + .ui-radio_custom {
|
|
75
|
+
box-shadow: var(--shadow-border-primary);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
input:checked + .ui-radio_custom {
|
|
79
|
+
border: 2px solid var(--color-primary);
|
|
80
|
+
}
|
|
81
|
+
|
|
68
82
|
input:checked + .ui-radio_custom .ui-radio__dot {
|
|
69
83
|
transform: translate3d(-50%, -50%, 0) scale(1);
|
|
70
84
|
}
|
|
85
|
+
|
|
86
|
+
input:checked + .ui-radio_custom:hover {
|
|
87
|
+
border: 2px solid var(--color-primary-600);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
input:checked + .ui-radio_custom:hover .ui-radio__dot {
|
|
91
|
+
background-color: var(--color-primary-600);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
input:checked:disabled + .ui-radio_custom {
|
|
95
|
+
border: 2px solid var(--color-primary-300);
|
|
96
|
+
background-color: var(--color-white);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
input:checked:disabled + .ui-radio_custom .ui-radio__dot {
|
|
100
|
+
background-color: var(--color-primary-300);
|
|
101
|
+
}
|
|
71
102
|
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<label
|
|
3
|
-
class="ui-radio-item block p-sm border border-secondary-alt rounded-2xl hover:border-primary
|
|
3
|
+
class="ui-radio-item block p-sm border border-secondary-alt rounded-2xl hover:border-primary cursor-pointer"
|
|
4
4
|
:class="[
|
|
5
5
|
isActive && 'bg-primary text-white pointer-events-none',
|
|
6
6
|
]"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<ui-icon
|
|
19
19
|
:icon-name="iconName"
|
|
20
20
|
:size="ESize.MD"
|
|
21
|
-
class
|
|
21
|
+
class="mb-md"
|
|
22
22
|
/>
|
|
23
23
|
<ui-typography
|
|
24
24
|
:size="ETypographySizes.SM"
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
import { ESize } from "../../../_types/sizing";
|
|
38
38
|
import { EColors } from "../../../_types/colors";
|
|
39
39
|
|
|
40
|
-
const props = defineProps<
|
|
41
|
-
className?: string;
|
|
40
|
+
const props = defineProps<{
|
|
42
41
|
modelValue: string;
|
|
43
42
|
name: string;
|
|
44
43
|
value: string;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
2
|
import UiRadioFancy from "./ui-radio-list-fancy.vue";
|
|
3
|
-
import { Story } from "@storybook/vue3";
|
|
3
|
+
import type { Story } from "@storybook/vue3";
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
title: "Components/ui-radio-list-fancy",
|
|
7
7
|
component: UiRadioFancy,
|
|
8
8
|
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
|
|
9
|
-
argTypes: {
|
|
10
|
-
className: {
|
|
11
|
-
control: { type: "text" },
|
|
12
|
-
description: "The Element classes",
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
},
|
|
9
|
+
argTypes: {},
|
|
16
10
|
args: {},
|
|
17
11
|
};
|
|
18
12
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="ui-radio-fancy grid gap-sm"
|
|
4
|
-
:class="className"
|
|
5
4
|
>
|
|
6
5
|
<ui-radio-item
|
|
7
6
|
v-for="(item, index) in items"
|
|
@@ -10,7 +9,7 @@
|
|
|
10
9
|
:title="item.title"
|
|
11
10
|
:value="String(index)"
|
|
12
11
|
:name="name"
|
|
13
|
-
:icon-name="[
|
|
12
|
+
:icon-name="[EIconType.FAR,'face-smile']"
|
|
14
13
|
@update:model-value="$emit('update:modelValue', $event)"
|
|
15
14
|
/>
|
|
16
15
|
</div>
|
|
@@ -19,9 +18,9 @@
|
|
|
19
18
|
<script lang="ts" setup>
|
|
20
19
|
import UiRadioItem from "./ui-radio-item";
|
|
21
20
|
import { ref, watch } from "vue";
|
|
21
|
+
import { EIconType } from "../ui-icon/_typings";
|
|
22
22
|
|
|
23
23
|
const props = defineProps< {
|
|
24
|
-
className? : string;
|
|
25
24
|
name: string;
|
|
26
25
|
modelValue: string;
|
|
27
26
|
}>();
|
|
@@ -31,15 +30,15 @@
|
|
|
31
30
|
const items = [
|
|
32
31
|
{
|
|
33
32
|
title: "title",
|
|
34
|
-
iconName: [
|
|
33
|
+
iconName: [EIconType.FAR, "face-smile"],
|
|
35
34
|
},
|
|
36
35
|
{
|
|
37
36
|
title: "title",
|
|
38
|
-
iconName: [
|
|
37
|
+
iconName: [EIconType.FAR, "face-smile"],
|
|
39
38
|
},
|
|
40
39
|
{
|
|
41
40
|
title: "title",
|
|
42
|
-
iconName: [
|
|
41
|
+
iconName: [EIconType.FAR, "face-smile"],
|
|
43
42
|
},
|
|
44
43
|
];
|
|
45
44
|
|
|
@@ -2,18 +2,13 @@ import UiRipple from "./ui-ripple.vue";
|
|
|
2
2
|
import UiButton from "../ui-button";
|
|
3
3
|
import UiTypography from "../ui-typography";
|
|
4
4
|
|
|
5
|
-
import { Story } from "@storybook/vue3";
|
|
5
|
+
import type { Story } from "@storybook/vue3";
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
title: "Components/ui-ripple",
|
|
9
9
|
component: UiRipple,
|
|
10
10
|
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
|
|
11
|
-
argTypes: {
|
|
12
|
-
className: {
|
|
13
|
-
control: { type: "text" },
|
|
14
|
-
description: "The Element classes",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
11
|
+
argTypes: {},
|
|
17
12
|
args: {
|
|
18
13
|
// slot: "Some text",
|
|
19
14
|
},
|
|
@@ -45,7 +40,7 @@ const Template2: Story<TComponentProps> = (args) => ({
|
|
|
45
40
|
},
|
|
46
41
|
template: `
|
|
47
42
|
<div class="flex">
|
|
48
|
-
<ui-button class
|
|
43
|
+
<ui-button class="relative">
|
|
49
44
|
<ui-typography is="div">
|
|
50
45
|
<ui-ripple v-bind="args" />
|
|
51
46
|
hello world
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
<div
|
|
3
3
|
ref="tiBtn"
|
|
4
4
|
class="ui-ripple"
|
|
5
|
-
:class="className"
|
|
6
5
|
@click="animateRipple"
|
|
7
6
|
>
|
|
8
7
|
<slot />
|
|
@@ -36,10 +35,6 @@
|
|
|
36
35
|
const tiBtn = ref<HTMLDivElement>();
|
|
37
36
|
const inputsRefs = ref<VNodeRef>();
|
|
38
37
|
|
|
39
|
-
defineProps<{
|
|
40
|
-
className?: string;
|
|
41
|
-
}>();
|
|
42
|
-
|
|
43
38
|
const animateRipple = (e:MouseEvent)=> {
|
|
44
39
|
if(tiBtn.value){
|
|
45
40
|
const pos = tiBtn.value.getBoundingClientRect();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ui-select.vue";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import UiSelect from "./ui-select.vue";
|
|
2
|
+
import type { Story } from "@storybook/vue3";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Components/ui-select",
|
|
7
|
+
component: UiSelect,
|
|
8
|
+
argTypes: {
|
|
9
|
+
disabled: {
|
|
10
|
+
control: { type: "boolean" },
|
|
11
|
+
description: "The Element disabled state",
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
args: {
|
|
15
|
+
slot: "default text",
|
|
16
|
+
disabled: false,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type TComponentProps = InstanceType<typeof UiSelect>["$props"];
|
|
21
|
+
|
|
22
|
+
const Template: Story<TComponentProps> = (args) => ({
|
|
23
|
+
components: { UiSelect },
|
|
24
|
+
setup() {
|
|
25
|
+
const list = ["Option 1", "Option 2", "Option 3"];
|
|
26
|
+
const valueModel = ref(list[0]);
|
|
27
|
+
return { args, valueModel, list };
|
|
28
|
+
},
|
|
29
|
+
template: `
|
|
30
|
+
<ui-select v-bind="args" :list="list" v-model:value="valueModel" heading="heading" subLabel="subLabel">
|
|
31
|
+
{{ args.slot }}
|
|
32
|
+
<template #postfix-icon>
|
|
33
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
34
|
+
<path d="M13.25 6.8125L8.5 11.2812C8.34375 11.4375 8.15625 11.5 8 11.5C7.8125 11.5 7.625 11.4375 7.46875 11.3125L2.71875 6.8125C2.40625 6.53125 2.40625 6.0625 2.6875 5.75C2.96875 5.4375 3.4375 5.4375 3.75 5.71875L8 9.71875L12.2188 5.71875C12.5312 5.4375 13 5.4375 13.2812 5.75C13.5625 6.0625 13.5625 6.53125 13.25 6.8125Z" fill="currentColor"/>
|
|
35
|
+
</svg>
|
|
36
|
+
</template>
|
|
37
|
+
</ui-select>
|
|
38
|
+
`,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const Default = Template.bind({});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-select">
|
|
3
|
+
<ui-typography
|
|
4
|
+
v-if="heading"
|
|
5
|
+
:weight="ETextWeight.SEMI_BOLD"
|
|
6
|
+
class="mb-sm"
|
|
7
|
+
>
|
|
8
|
+
{{ heading }}
|
|
9
|
+
</ui-typography>
|
|
10
|
+
<div
|
|
11
|
+
class="relative rounded-lg border bg-white border-secondary-alt-500 hover:border-secondary-alt-700"
|
|
12
|
+
:class="[disabled && 'pointer-events-none bg-secondary-alt-200 border-secondary-alt-300']"
|
|
13
|
+
>
|
|
14
|
+
<select
|
|
15
|
+
v-model="localModel"
|
|
16
|
+
class="appearance-none bg-transparent border-0 m-0 outline-0 w-full p-sm cursor-pointer italic text-secondary-alt"
|
|
17
|
+
@change=" $emit('update:value', ($event.target as HTMLTextAreaElement)?.value)"
|
|
18
|
+
>
|
|
19
|
+
<option
|
|
20
|
+
v-for="item in list"
|
|
21
|
+
:key="item"
|
|
22
|
+
:value="item"
|
|
23
|
+
>
|
|
24
|
+
{{ item }}
|
|
25
|
+
</option>
|
|
26
|
+
</select>
|
|
27
|
+
|
|
28
|
+
<div class="ui-select__icon-wrapper absolute right-sm">
|
|
29
|
+
<slot name="postfix-icon" />
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<ui-typography
|
|
33
|
+
v-if="subLabel"
|
|
34
|
+
:size="ETypographySizes.SM"
|
|
35
|
+
class="mt-sm"
|
|
36
|
+
>
|
|
37
|
+
{{ subLabel }}
|
|
38
|
+
</ui-typography>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script lang="ts" setup>
|
|
43
|
+
import { ref, watch } from "vue";
|
|
44
|
+
import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
|
|
45
|
+
|
|
46
|
+
const props = defineProps<{
|
|
47
|
+
list: string[];
|
|
48
|
+
value: string;
|
|
49
|
+
heading?: string;
|
|
50
|
+
subLabel?: string;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
}>();
|
|
53
|
+
|
|
54
|
+
defineEmits(["update:value"]);
|
|
55
|
+
|
|
56
|
+
const localModel = ref(props.value);
|
|
57
|
+
|
|
58
|
+
watch(() => props.value, (value) => {
|
|
59
|
+
localModel.value = value;
|
|
60
|
+
});
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<style scoped>
|
|
64
|
+
.ui-select__icon-wrapper {
|
|
65
|
+
top: 50%;
|
|
66
|
+
transform: translateY(-50%);
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ui-tabs.vue";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import UiTabs from "./ui-tabs.vue";
|
|
3
|
+
import type { Story } from "@storybook/vue3";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Components/ui-tabs",
|
|
7
|
+
component: UiTabs,
|
|
8
|
+
argTypes: {},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type TComponentProps = InstanceType<typeof UiTabs>["$props"];
|
|
12
|
+
|
|
13
|
+
const Template: Story<TComponentProps> = (args) => ({
|
|
14
|
+
components: { UiTabs },
|
|
15
|
+
setup() {
|
|
16
|
+
const value = ref("Tab1");
|
|
17
|
+
const value2 = ref("Tab1");
|
|
18
|
+
return { args, value, value2 };
|
|
19
|
+
},
|
|
20
|
+
template: `
|
|
21
|
+
<ui-tabs v-bind="args" :tabs="['Tab1', 'Tab2', 'Tab3']" v-model:modelValue="value" />
|
|
22
|
+
<br/>
|
|
23
|
+
<ui-tabs v-bind="args" :tabs="['Tab1', 'Tab2']" v-model:modelValue="value2" />
|
|
24
|
+
`,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const Default = Template.bind({});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ul class="ui-tabs bg-secondary-alt-200 rounded-full grid grid-flow-col">
|
|
3
|
+
<li
|
|
4
|
+
v-for="tab in tabs"
|
|
5
|
+
:key="tab"
|
|
6
|
+
class="rounded-full text-center"
|
|
7
|
+
:class="[localValue === tab && 'bg-white']"
|
|
8
|
+
>
|
|
9
|
+
<label class="block cursor-pointer py-xs px-md">
|
|
10
|
+
<input
|
|
11
|
+
v-model="localValue"
|
|
12
|
+
type="radio"
|
|
13
|
+
class="appearance-none"
|
|
14
|
+
:value="tab"
|
|
15
|
+
:name="name || 'default'"
|
|
16
|
+
@input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement)?.value)"
|
|
17
|
+
>
|
|
18
|
+
<ui-typography
|
|
19
|
+
is="span"
|
|
20
|
+
:size="ETypographySizes.XS"
|
|
21
|
+
:kind="localValue === tab?EColors.SECONDARY_500:EColors.SECONDARY_400"
|
|
22
|
+
:weight="ETextWeight.SEMI_BOLD"
|
|
23
|
+
>
|
|
24
|
+
{{ tab }}
|
|
25
|
+
</ui-typography>
|
|
26
|
+
</label>
|
|
27
|
+
</li>
|
|
28
|
+
</ul>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts" setup>
|
|
32
|
+
import { ref, watch } from "vue";
|
|
33
|
+
import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
|
|
34
|
+
import { EColors } from "../../_types/colors";
|
|
35
|
+
|
|
36
|
+
const props = defineProps<{
|
|
37
|
+
tabs: string[];
|
|
38
|
+
modelValue: string;
|
|
39
|
+
name: string;
|
|
40
|
+
}>();
|
|
41
|
+
|
|
42
|
+
defineEmits(["update:modelValue"]);
|
|
43
|
+
|
|
44
|
+
const localValue = ref(props.modelValue);
|
|
45
|
+
|
|
46
|
+
watch(() => props.modelValue, (newValue) => {
|
|
47
|
+
if(newValue !== localValue.value){
|
|
48
|
+
localValue.value = newValue;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<style scoped>
|
|
55
|
+
.ui-tabs {
|
|
56
|
+
padding: 2px;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ui-toggle.vue";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import UiToggle from "./ui-toggle.vue";
|
|
2
|
+
import type { Story } from "@storybook/vue3";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Components/ui-toggle",
|
|
7
|
+
component: UiToggle,
|
|
8
|
+
argTypes: {
|
|
9
|
+
disabled: {
|
|
10
|
+
control: { type: "boolean" },
|
|
11
|
+
description: "The Element disabled state",
|
|
12
|
+
},
|
|
13
|
+
invertOrder: {
|
|
14
|
+
control: { type: "boolean" },
|
|
15
|
+
description: "The Element order state",
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
slot: "default text",
|
|
20
|
+
disabled: false,
|
|
21
|
+
invertOrder: false,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type TComponentProps = InstanceType<typeof UiToggle>["$props"];
|
|
26
|
+
|
|
27
|
+
const Template: Story<TComponentProps> = (args) => ({
|
|
28
|
+
components: { UiToggle },
|
|
29
|
+
setup() {
|
|
30
|
+
const modelValue = ref(false);
|
|
31
|
+
|
|
32
|
+
return { args, modelValue };
|
|
33
|
+
},
|
|
34
|
+
template: `
|
|
35
|
+
<ui-toggle v-bind="args" v-model:model-value="modelValue" header="Header" :title="args.slot" />
|
|
36
|
+
`,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const Default = Template.bind({});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="ui-toggle"
|
|
4
|
+
>
|
|
5
|
+
<ui-typography
|
|
6
|
+
:weight="ETextWeight.BOLD"
|
|
7
|
+
class="mb-sm"
|
|
8
|
+
>
|
|
9
|
+
{{ header }}
|
|
10
|
+
</ui-typography>
|
|
11
|
+
|
|
12
|
+
<label
|
|
13
|
+
class="rounded-full cursor-pointer flex gap-sm"
|
|
14
|
+
:class="[
|
|
15
|
+
disabled && 'pointer-events-none ui-toggle_disabled',
|
|
16
|
+
invertOrder && 'flex-row-reverse',
|
|
17
|
+
]"
|
|
18
|
+
>
|
|
19
|
+
<span class="ui-input__input-wrapper block relative h-md">
|
|
20
|
+
<input
|
|
21
|
+
type="checkbox"
|
|
22
|
+
class="appearance-none absolute w-0 h-0 border-0"
|
|
23
|
+
:checked="modelValue"
|
|
24
|
+
@input="$emit('update:modelValue', !!($event.target as HTMLInputElement)?.value)"
|
|
25
|
+
>
|
|
26
|
+
|
|
27
|
+
<span class="ui-toggle__bg-block w-lg h-md bg-secondary-alt block rounded-full" />
|
|
28
|
+
|
|
29
|
+
<span class="ui-toggle__dot block bg-white absolute top-0 rounded-full">
|
|
30
|
+
<svg
|
|
31
|
+
class="ui-toggle__check-icon absolute"
|
|
32
|
+
:class="disabled ? 'text-primary-300' : 'text-primary'"
|
|
33
|
+
width="16"
|
|
34
|
+
height="12"
|
|
35
|
+
viewBox="0 0 16 12"
|
|
36
|
+
fill="none"
|
|
37
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
38
|
+
>
|
|
39
|
+
<path
|
|
40
|
+
d="M1 4.40106L6.60071 10.1135L15.1694 1.71245"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
stroke-width="1.6"
|
|
43
|
+
stroke-linecap="round"
|
|
44
|
+
/>
|
|
45
|
+
</svg>
|
|
46
|
+
</span>
|
|
47
|
+
</span>
|
|
48
|
+
|
|
49
|
+
<ui-typography
|
|
50
|
+
:size="ETypographySizes.SM"
|
|
51
|
+
class="w-full"
|
|
52
|
+
line-height
|
|
53
|
+
>{{ title }}</ui-typography>
|
|
54
|
+
</label>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script lang="ts" setup>
|
|
59
|
+
import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
|
|
60
|
+
|
|
61
|
+
defineProps<{
|
|
62
|
+
header?: string;
|
|
63
|
+
title?: string;
|
|
64
|
+
modelValue: boolean;
|
|
65
|
+
disabled?: boolean;
|
|
66
|
+
invertOrder?: boolean;
|
|
67
|
+
}>();
|
|
68
|
+
|
|
69
|
+
defineEmits<{
|
|
70
|
+
(e: "update:modelValue", state: boolean): void
|
|
71
|
+
}>();
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style scoped>
|
|
75
|
+
.ui-toggle__dot {
|
|
76
|
+
top: 50%;
|
|
77
|
+
width: 22px;
|
|
78
|
+
height: 22px;
|
|
79
|
+
transform: translate3d(1px, -50%, 0);
|
|
80
|
+
transition: transform 0.2s ease-in-out;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.ui-toggle__check-icon {
|
|
84
|
+
top: 50%;
|
|
85
|
+
left: 50%;
|
|
86
|
+
transform: translate3d(-50%, -50%, 0);
|
|
87
|
+
stroke-dasharray: 70;
|
|
88
|
+
stroke-dashoffset: 70;
|
|
89
|
+
transition: stroke-dashoffset 0.2s ease-in-out;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ui-toggle:hover .ui-toggle__dot,
|
|
93
|
+
.ui-toggle:active .ui-toggle__dot,
|
|
94
|
+
.ui-toggle:focus .ui-toggle__dot {
|
|
95
|
+
box-shadow: var(--shadow-border-secondary);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.ui-toggle input:checked ~ .ui-toggle__dot {
|
|
99
|
+
transform: translate3d(calc(var(--lg) - 100% - 1px), -50%, 0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ui-toggle:hover input:checked ~ .ui-toggle__dot,
|
|
103
|
+
.ui-toggle:active input:checked ~ .ui-toggle__dot,
|
|
104
|
+
.ui-toggle:focus input:checked ~ .ui-toggle__dot {
|
|
105
|
+
box-shadow: var(--shadow-border-primary);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ui-toggle__bg-block {
|
|
109
|
+
transition: background-color 0.2s ease-in-out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ui-toggle_disabled .ui-toggle__bg-block {
|
|
113
|
+
background-color: var(--color-secondary-alt-300);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.ui-toggle input:checked ~ .ui-toggle__bg-block {
|
|
117
|
+
background-color: var(--color-primary);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.ui-toggle input:checked ~ .ui-toggle__dot .ui-toggle__check-icon {
|
|
121
|
+
stroke-dashoffset: 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.ui-toggle_disabled input:checked ~ .ui-toggle__bg-block {
|
|
125
|
+
background-color: var(--color-primary-300);
|
|
126
|
+
}
|
|
127
|
+
</style>
|
|
@@ -2,7 +2,7 @@ export enum ETypographySizes {
|
|
|
2
2
|
XXS = "xxs",
|
|
3
3
|
XS = "xs",
|
|
4
4
|
SM = "sm",
|
|
5
|
-
|
|
5
|
+
MD = "m",
|
|
6
6
|
LG = "lg",
|
|
7
7
|
XL = "xl",
|
|
8
8
|
XXL = "2xl",
|
|
@@ -11,37 +11,11 @@ export enum ETypographySizes {
|
|
|
11
11
|
XXXXXL = "5xl",
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export enum ETypographyColors {
|
|
15
|
-
PRIMARY = "primary",
|
|
16
|
-
PRIMARY_300 = "primary-300",
|
|
17
|
-
PRIMARY_400 = "primary-400",
|
|
18
|
-
PRIMARY_600 = "primary-600",
|
|
19
|
-
PRIMARY_700 = "primary-700",
|
|
20
|
-
|
|
21
|
-
SECONDARY = "secondary",
|
|
22
|
-
SECONDARY_300 = "secondary-300",
|
|
23
|
-
SECONDARY_400 = "secondary-400",
|
|
24
|
-
SECONDARY_600 = "secondary-600",
|
|
25
|
-
SECONDARY_700 = "secondary-700",
|
|
26
|
-
|
|
27
|
-
ERROR = "error",
|
|
28
|
-
ERROR_300 = "error-300",
|
|
29
|
-
ERROR_400 = "error-400",
|
|
30
|
-
ERROR_600 = "error-600",
|
|
31
|
-
ERROR_700 = "error-700",
|
|
32
|
-
|
|
33
|
-
WARNING = "warning",
|
|
34
|
-
WARNING_300 = "warning-300",
|
|
35
|
-
WARNING_400 = "warning-400",
|
|
36
|
-
WARNING_600 = "warning-600",
|
|
37
|
-
WARNING_700 = "warning-700",
|
|
38
|
-
}
|
|
39
|
-
|
|
40
14
|
export enum ETextWeight {
|
|
41
|
-
LIGHT = "light",
|
|
42
|
-
REGULAR = "regular",
|
|
43
|
-
SEMI_BOLD = "semi_bold",
|
|
44
|
-
BOLD = "bold",
|
|
15
|
+
LIGHT = "light", // 300
|
|
16
|
+
REGULAR = "regular", // 400
|
|
17
|
+
SEMI_BOLD = "semi_bold", // 600
|
|
18
|
+
BOLD = "bold", // 900
|
|
45
19
|
}
|
|
46
20
|
|
|
47
21
|
export enum ETextAlign {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from "./ui-typography.vue";
|
|
2
|
-
export { ETypographySizes, ETextWeight, ETextAlign } from "./_typings";
|
|
2
|
+
export { ETypographySizes, ETextWeight, ETextAlign, ETextTransform } from "./_typings";
|