edvoyui-component-library-test-flight 0.0.21 → 0.0.23
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/dist/EUIButton.vue.d.ts.map +1 -0
- package/dist/library-vue-ts.cjs.js +4 -3
- package/dist/library-vue-ts.es.js +3 -8
- package/dist/library-vue-ts.umd.js +4 -3
- package/dist/select/EUISelect.vue.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/App.vue +16 -0
- package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
- package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
- package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
- package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
- package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
- package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
- package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
- package/src/assets/scss/body.scss +15 -0
- package/src/assets/svg/ChevronDownSolid.vue +19 -0
- package/src/assets/svg/ChevronDownStroke.vue +22 -0
- package/src/assets/svg/SortArrow.vue +24 -0
- package/src/assets/svg/Student.vue +30 -0
- package/src/assets/svg/partner.vue +33 -0
- package/src/assets/svg/people.vue +25 -0
- package/src/assets/vue.svg +1 -0
- package/src/components/HelloWorld.vue +999 -0
- package/src/components/accordion/EUIAccordion.stories.ts +157 -0
- package/src/components/accordion/EUIAccordion.vue +90 -0
- package/src/components/avatar/EUIAvatar.stories.ts +157 -0
- package/src/components/avatar/EUIAvatar.vue +96 -0
- package/src/components/button/EUIButton.stories.ts +252 -0
- package/src/components/button/EUIButton.vue +151 -0
- package/src/components/checkbox/EUICheckbox.stories.ts +58 -0
- package/src/components/checkbox/EUICheckbox.vue +103 -0
- package/src/components/datepicker/EUIDatepicker.stories.ts +236 -0
- package/src/components/datepicker/EUIDatepicker.vue +185 -0
- package/src/components/delete.vue +108 -0
- package/src/components/dropdown/EUIMultiDropdown.stories.ts +187 -0
- package/src/components/dropdown/EUIMultiDropdown.vue +129 -0
- package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
- package/src/components/errorMessage/EUIErrorMessage.stories.ts +41 -0
- package/src/components/errorMessage/EUIErrorMessage.vue +25 -0
- package/src/components/index.ts +46 -0
- package/src/components/input/EUIInput.stories.ts +174 -0
- package/src/components/input/EUIInput.vue +169 -0
- package/src/components/inputNormal/EUIInputNormal.stories.ts +164 -0
- package/src/components/inputNormal/EUIInputNormal.vue +161 -0
- package/src/components/loader/EUICircleLoader.vue +31 -0
- package/src/components/loader/EUICubeLoader.vue +237 -0
- package/src/components/loader/EUILoader.stories.ts +99 -0
- package/src/components/loader/EUILoader.vue +17 -0
- package/src/components/loader/EUISquareLoader.vue +47 -0
- package/src/components/modal/EUIModal.stories.ts +372 -0
- package/src/components/modal/EUIModal.vue +163 -0
- package/src/components/pillSelect/EUIPillSelect.stories.ts +74 -0
- package/src/components/pillSelect/EUIPillSelect.vue +149 -0
- package/src/components/popover/EUIPopover.stories.ts +247 -0
- package/src/components/popover/EUIPopover.vue +159 -0
- package/src/components/radio/EUIRadio.stories.ts +54 -0
- package/src/components/radio/EUIRadio.vue +78 -0
- package/src/components/searchInput/EUISearch.stories.ts +24 -0
- package/src/components/searchInput/EUISearch.vue +215 -0
- package/src/components/select/EUISelect.scss +0 -0
- package/src/components/select/EUISelect.stories.ts +49 -0
- package/src/components/select/EUISelect.vue +682 -0
- package/src/components/selectSearch/EUISelectSearch.vue +23 -0
- package/src/components/slideover/EUISlideover.stories.ts +318 -0
- package/src/components/slideover/EUISlideover.vue +207 -0
- package/src/components/stepperTimeline/EUIStepperHorizontal.vue +112 -0
- package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +54 -0
- package/src/components/stepperTimeline/EUIStepperTimeline.vue +16 -0
- package/src/components/stepperTimeline/EUIStepperVertical.vue +112 -0
- package/src/components/table/EUIDashboardTable.vue +482 -0
- package/src/components/table/EUIPageLimit.vue +66 -0
- package/src/components/table/EUIPagination.vue +175 -0
- package/src/components/table/EUIStudentPagination.vue +172 -0
- package/src/components/table/EUITable.stories.ts +190 -0
- package/src/components/table/EUITable.vue +508 -0
- package/src/components/table/EUITableCheckbox.vue +97 -0
- package/src/components/tabs/EUITabs.vue +128 -0
- package/src/components/tabs/EUItabs.stories.ts +123 -0
- package/src/components/tag/EUITag.stories.ts +46 -0
- package/src/components/tag/EUITag.vue +46 -0
- package/src/components/telephone/EUITelephone.stories.ts +202 -0
- package/src/components/telephone/EUITelephone.vue +280 -0
- package/src/components/textArea/EUITextArea.stories.ts +82 -0
- package/src/components/textArea/EUITextArea.vue +122 -0
- package/src/components/timeLine/EUITimeLine.stories.ts +247 -0
- package/src/components/timeLine/EUITimeLine.vue +43 -0
- package/src/components/timeLine/EUITimeLineItem.vue +124 -0
- package/src/components/toggle/EUIToggle.stories.ts +63 -0
- package/src/components/toggle/EUIToggle.vue +99 -0
- package/src/components/tooltip/EUITooltip.stories.ts +53 -0
- package/src/components/tooltip/EUITooltip.vue +108 -0
- package/src/data/books.ts +163 -0
- package/src/data/tab.ts +33 -0
- package/src/data/table.ts +5392 -0
- package/src/main.ts +5 -0
- package/src/utils/lodash.ts +9 -0
- package/src/utils/types.ts +9 -0
- package/src/vite-env.d.ts +5 -0
- package/dist/EUISelect.vue.d.ts.map +0 -1
- package/dist/button/EUIButton.vue.d.ts.map +0 -1
- package/dist/library-vue-ts.css +0 -1
- package/dist/style.scss +0 -118
- /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
- /package/dist/{EUISelect.vue.d.ts → select/EUISelect.vue.d.ts} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div
|
|
4
|
+
:class="disabled ? 'pointer-events-none cursor-not-allowed' : ''"
|
|
5
|
+
class="relative w-full mb-2 overflow-hidden border border-gray-100 cursor-pointer group h-14 rounded-2xl focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600"
|
|
6
|
+
>
|
|
7
|
+
<label
|
|
8
|
+
:for="`${name}-${id}`"
|
|
9
|
+
:class="[
|
|
10
|
+
getIconClass(),
|
|
11
|
+
inputValue
|
|
12
|
+
? 'top-3.5 text-xs text-gray-400 leading-none cursor-default'
|
|
13
|
+
: 'top-1/2 text-sm w-full text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-white ring-1 ring-gray-200',
|
|
14
|
+
disabled ? ' cursor-not-allowed' : '',
|
|
15
|
+
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
16
|
+
]"
|
|
17
|
+
class="absolute font-medium left-0 px-4 z-0 -translate-y-1/2 duration-200 group-focus-within:top-3.5 group-focus-within:text-xs group-focus-within:text-gray-400 rounded-2xl group-focus-within:bg-transparent group-focus-within:-translate-y-1/2 group-focus-within:ring-transparent group-focus-within:h-auto group-focus-within:py-0"
|
|
18
|
+
>
|
|
19
|
+
{{ label }}
|
|
20
|
+
</label>
|
|
21
|
+
<div
|
|
22
|
+
v-if="icon && iconType"
|
|
23
|
+
class="absolute inset-y-0 flex items-center pointer-events-none"
|
|
24
|
+
:class="[
|
|
25
|
+
iconType === 'startIcon' ? 'left-0 pl-3' : 'right-0 pr-3',
|
|
26
|
+
disabled ? 'cursor-not-allowed' : '',
|
|
27
|
+
]"
|
|
28
|
+
>
|
|
29
|
+
<component
|
|
30
|
+
:is="icon"
|
|
31
|
+
class="w-6 h-6 text-gray-400"
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<input
|
|
37
|
+
:id="`${name}-${id}`"
|
|
38
|
+
ref="input"
|
|
39
|
+
:type="type"
|
|
40
|
+
:value="modelValue"
|
|
41
|
+
:placeholder="placeholder"
|
|
42
|
+
:name="name"
|
|
43
|
+
class="z-10 block w-full h-full pt-6 pb-3 text-sm font-medium leading-6 appearance-none rounded-2xl placeholder:text-gray-400 focus:outline-none disabled:opacity-75 focus:border-purple-600 autofill:bg-white"
|
|
44
|
+
:class="[getIconClass(), disabled ? 'cursor-not-allowed' : '']"
|
|
45
|
+
:required="required"
|
|
46
|
+
:disabled="disabled"
|
|
47
|
+
:readonly="readonly"
|
|
48
|
+
autocomplete="off"
|
|
49
|
+
@input="emitInput"
|
|
50
|
+
@focus="hasFocus = true"
|
|
51
|
+
@blur="hasFocus = false"
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
<EUIErrorMessage :errors="errors" :name="name" />
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script lang="ts" setup>
|
|
59
|
+
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
60
|
+
import {
|
|
61
|
+
defineProps,
|
|
62
|
+
defineEmits,
|
|
63
|
+
computed,
|
|
64
|
+
PropType,
|
|
65
|
+
ref,
|
|
66
|
+
onMounted,
|
|
67
|
+
} from "vue";
|
|
68
|
+
|
|
69
|
+
const props = defineProps({
|
|
70
|
+
errors: { type: Object, required: false, default: () => {} },
|
|
71
|
+
type: {
|
|
72
|
+
type: String as PropType<
|
|
73
|
+
"text" | "number" | "email" | "password" | "search" | "date" | "url"
|
|
74
|
+
>,
|
|
75
|
+
default: "text",
|
|
76
|
+
},
|
|
77
|
+
modelValue: {
|
|
78
|
+
type: [String, Number],
|
|
79
|
+
default: "",
|
|
80
|
+
},
|
|
81
|
+
name: {
|
|
82
|
+
type: String,
|
|
83
|
+
required: false,
|
|
84
|
+
default: "",
|
|
85
|
+
},
|
|
86
|
+
label: {
|
|
87
|
+
type: String,
|
|
88
|
+
required: true,
|
|
89
|
+
default: "",
|
|
90
|
+
},
|
|
91
|
+
autoFocus: {
|
|
92
|
+
type: Boolean,
|
|
93
|
+
required: false,
|
|
94
|
+
default: false,
|
|
95
|
+
},
|
|
96
|
+
placeholder: {
|
|
97
|
+
type: String,
|
|
98
|
+
required: false,
|
|
99
|
+
default: "",
|
|
100
|
+
},
|
|
101
|
+
iconType: {
|
|
102
|
+
type: String as PropType<"startIcon" | "endIcon">,
|
|
103
|
+
default: "",
|
|
104
|
+
},
|
|
105
|
+
icon: {
|
|
106
|
+
type: [Object, String],
|
|
107
|
+
default: "",
|
|
108
|
+
},
|
|
109
|
+
disabled: {
|
|
110
|
+
type: Boolean,
|
|
111
|
+
default: false,
|
|
112
|
+
},
|
|
113
|
+
required: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
default: false,
|
|
116
|
+
},
|
|
117
|
+
readonly: {
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const hasFocus = ref(false);
|
|
124
|
+
const input = ref<HTMLInputElement>();
|
|
125
|
+
|
|
126
|
+
const id = "id"; //generateUID();
|
|
127
|
+
|
|
128
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
129
|
+
const emitInput = (event: Event) => {
|
|
130
|
+
const newValue = (event?.target as HTMLInputElement)?.value;
|
|
131
|
+
if (newValue !== undefined) {
|
|
132
|
+
emit("update:modelValue", newValue);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const inputValue = computed(() => {
|
|
137
|
+
return props.modelValue === 0 ? true : !!props.modelValue;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const getIconClass = () => {
|
|
141
|
+
switch (props.iconType) {
|
|
142
|
+
case "startIcon":
|
|
143
|
+
return "pl-12 pr-4";
|
|
144
|
+
case "endIcon":
|
|
145
|
+
return "pr-12 pl-4";
|
|
146
|
+
default:
|
|
147
|
+
return "px-4";
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
onMounted(() => {
|
|
152
|
+
if (props?.autoFocus) {
|
|
153
|
+
input?.value?.focus();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
</script>
|
|
157
|
+
|
|
158
|
+
<style lang="scss" scoped>
|
|
159
|
+
/* Chrome, Safari, Edge, Opera */
|
|
160
|
+
input::-webkit-outer-spin-button,
|
|
161
|
+
input::-webkit-inner-spin-button {
|
|
162
|
+
-webkit-appearance: none;
|
|
163
|
+
margin: 0;
|
|
164
|
+
}
|
|
165
|
+
/* Firefox */
|
|
166
|
+
input[type="number"] {
|
|
167
|
+
-moz-appearance: textfield;
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { expect, userEvent, within } from "@storybook/test";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
3
|
+
import EUIInputNormal from "./EUIInputNormal.vue";
|
|
4
|
+
import { UserCircleIcon } from "@heroicons/vue/24/outline";
|
|
5
|
+
|
|
6
|
+
// Meta configuration for the component's stories
|
|
7
|
+
const meta = {
|
|
8
|
+
title: "Forms/InputNormal",
|
|
9
|
+
component: EUIInputNormal,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
argTypes: {
|
|
12
|
+
modelValue: {
|
|
13
|
+
control: "text",
|
|
14
|
+
description:
|
|
15
|
+
"The value of the input. This is a two-way binding property, used to reflect the current value of the input field.",
|
|
16
|
+
},
|
|
17
|
+
name: {
|
|
18
|
+
control: "text",
|
|
19
|
+
description:
|
|
20
|
+
"The `name` attribute of the input, typically used for form identification and validation.",
|
|
21
|
+
},
|
|
22
|
+
label: {
|
|
23
|
+
control: "text",
|
|
24
|
+
description:
|
|
25
|
+
"The label for the input field, usually displayed above or inside the input.",
|
|
26
|
+
},
|
|
27
|
+
type: {
|
|
28
|
+
control: {
|
|
29
|
+
type: "select",
|
|
30
|
+
options: [
|
|
31
|
+
"text",
|
|
32
|
+
"number",
|
|
33
|
+
"email",
|
|
34
|
+
"password",
|
|
35
|
+
"search",
|
|
36
|
+
"date",
|
|
37
|
+
"url",
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
description:
|
|
41
|
+
"Specifies the type of input, such as `text`, `number`, `email`, etc.",
|
|
42
|
+
},
|
|
43
|
+
placeholder: {
|
|
44
|
+
control: "text",
|
|
45
|
+
description:
|
|
46
|
+
"A short hint that describes the expected value when the input is empty.",
|
|
47
|
+
},
|
|
48
|
+
autoFocus: {
|
|
49
|
+
control: "boolean",
|
|
50
|
+
description:
|
|
51
|
+
"Automatically focuses the input field when the page loads or the component mounts.",
|
|
52
|
+
},
|
|
53
|
+
required: {
|
|
54
|
+
control: "boolean",
|
|
55
|
+
description:
|
|
56
|
+
"Marks the field as required, showing validation for non-empty input.",
|
|
57
|
+
},
|
|
58
|
+
readonly: {
|
|
59
|
+
control: "boolean",
|
|
60
|
+
description:
|
|
61
|
+
"Makes the input field read-only, which means users can see the value but cannot edit it.",
|
|
62
|
+
},
|
|
63
|
+
disabled: {
|
|
64
|
+
control: "boolean",
|
|
65
|
+
description:
|
|
66
|
+
"Disables the input field, making it uneditable and unclickable.",
|
|
67
|
+
},
|
|
68
|
+
iconType: {
|
|
69
|
+
control: "select",
|
|
70
|
+
options: ["", "startIcon", "endIcon"],
|
|
71
|
+
description:
|
|
72
|
+
"Defines the position of the icon. It can be placed at the `start` or `end` of the input field.",
|
|
73
|
+
},
|
|
74
|
+
icon: {
|
|
75
|
+
control: { type: "text" },
|
|
76
|
+
description:
|
|
77
|
+
"Specifies an SVG icon or icon component to be displayed inside the input field.",
|
|
78
|
+
},
|
|
79
|
+
errors: {
|
|
80
|
+
control: "object",
|
|
81
|
+
description:
|
|
82
|
+
"An object containing error messages or validation information, typically used for form validation.",
|
|
83
|
+
},
|
|
84
|
+
rounded: {
|
|
85
|
+
control: "boolean",
|
|
86
|
+
description: "rounded the input field.",
|
|
87
|
+
},
|
|
88
|
+
className: {
|
|
89
|
+
control: "text",
|
|
90
|
+
description: "Required design to add class",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
} satisfies Meta<typeof EUIInputNormal>;
|
|
94
|
+
|
|
95
|
+
export default meta;
|
|
96
|
+
type Story = StoryObj<typeof meta>;
|
|
97
|
+
|
|
98
|
+
// Default story with minimum props
|
|
99
|
+
export const Default: Story = {
|
|
100
|
+
argTypes: {
|
|
101
|
+
type: {
|
|
102
|
+
control: "select",
|
|
103
|
+
options: ["text", "number", "email", "password", "search", "date"],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
args: {
|
|
107
|
+
label: "Username",
|
|
108
|
+
type: "text",
|
|
109
|
+
placeholder: "Enter fullname here..",
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const InputValue: Story = {
|
|
114
|
+
args: {
|
|
115
|
+
label: "User Name",
|
|
116
|
+
type: "text",
|
|
117
|
+
placeholder: "Enter fullname here..",
|
|
118
|
+
modelValue: "John Cena",
|
|
119
|
+
},
|
|
120
|
+
play: async ({ canvasElement }) => {
|
|
121
|
+
const canvas = within(canvasElement);
|
|
122
|
+
const inputElement = canvas.getByPlaceholderText("Enter fullname here..");
|
|
123
|
+
await userEvent.type(inputElement, "Storybook Test");
|
|
124
|
+
await expect(inputElement).toBe("Storybook Test");
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const IconUsingStart: Story = {
|
|
129
|
+
args: {
|
|
130
|
+
label: "User Name",
|
|
131
|
+
type: "text",
|
|
132
|
+
placeholder: "Enter fullname here..",
|
|
133
|
+
modelValue: "John Cena",
|
|
134
|
+
disabled: false,
|
|
135
|
+
iconType: "startIcon",
|
|
136
|
+
icon: UserCircleIcon,
|
|
137
|
+
},
|
|
138
|
+
render: (args) => ({
|
|
139
|
+
components: { EUIInputNormal },
|
|
140
|
+
setup() {
|
|
141
|
+
return { args };
|
|
142
|
+
},
|
|
143
|
+
template: '<EUIInputNormal v-bind="args" />',
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const IconUsingEnd: Story = {
|
|
148
|
+
args: {
|
|
149
|
+
label: "User Name",
|
|
150
|
+
type: "text",
|
|
151
|
+
placeholder: "Enter fullname here..",
|
|
152
|
+
modelValue: "John Cena",
|
|
153
|
+
disabled: false,
|
|
154
|
+
iconType: "endIcon",
|
|
155
|
+
icon: UserCircleIcon,
|
|
156
|
+
},
|
|
157
|
+
render: (args) => ({
|
|
158
|
+
components: { EUIInputNormal },
|
|
159
|
+
setup() {
|
|
160
|
+
return { args };
|
|
161
|
+
},
|
|
162
|
+
template: '<EUIInputNormal v-bind="args" />',
|
|
163
|
+
}),
|
|
164
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<label
|
|
4
|
+
v-if="label"
|
|
5
|
+
:for="`${name}-${id}`"
|
|
6
|
+
:class="[
|
|
7
|
+
'text-sm w-full text-gray-600 cursor-pointer font-medium',
|
|
8
|
+
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
9
|
+
]"
|
|
10
|
+
>
|
|
11
|
+
{{ label }}
|
|
12
|
+
</label>
|
|
13
|
+
<div
|
|
14
|
+
:class="disabled || readonly ? 'pointer-events-none cursor-not-allowed' : ''"
|
|
15
|
+
class="relative w-full overflow-hidden cursor-pointer group"
|
|
16
|
+
>
|
|
17
|
+
<div
|
|
18
|
+
v-if="icon && iconType"
|
|
19
|
+
class="absolute inset-y-0 flex items-center pointer-events-none"
|
|
20
|
+
:class="[
|
|
21
|
+
iconType === 'startIcon' ? 'left-0 pl-3' : 'right-0 pr-3',
|
|
22
|
+
disabled ? 'cursor-not-allowed' : '',
|
|
23
|
+
]"
|
|
24
|
+
>
|
|
25
|
+
<component
|
|
26
|
+
:is="icon"
|
|
27
|
+
class="text-gray-400 size-6"
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
<input
|
|
32
|
+
:id="`${name}-${id}`"
|
|
33
|
+
ref="input"
|
|
34
|
+
:type="type"
|
|
35
|
+
:value="modelValue"
|
|
36
|
+
:placeholder="placeholder"
|
|
37
|
+
:name="name"
|
|
38
|
+
:class="['z-10 h-10 w-full px-4 py-3 placeholder:text-gray-400 focus:outline-none block text-sm font-medium appearance-none disabled:opacity-75 autofill:bg-white leading-6 ring-1 ring-gray-100 focus-within:ring-purple-600 focus-within:ring-2 ring-inset transition-all duration-100 border-none outline-none', rounded ? 'rounded-2xl' : 'rounded-md', getIconClass(), disabled ? 'cursor-not-allowed' : 'cursor-text', className]"
|
|
39
|
+
:required="required"
|
|
40
|
+
:disabled="disabled"
|
|
41
|
+
:readonly="readonly"
|
|
42
|
+
autocomplete="off"
|
|
43
|
+
@input="emitInput"
|
|
44
|
+
@focus="hasFocus = true"
|
|
45
|
+
@blur="hasFocus = false"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
<EUIErrorMessage :errors="errors" :name="name" />
|
|
49
|
+
</div>
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
<script lang="ts" setup>
|
|
53
|
+
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
54
|
+
import {
|
|
55
|
+
defineProps,
|
|
56
|
+
defineEmits,
|
|
57
|
+
PropType,
|
|
58
|
+
ref,
|
|
59
|
+
onMounted,
|
|
60
|
+
} from "vue";
|
|
61
|
+
|
|
62
|
+
const props = defineProps({
|
|
63
|
+
errors: { type: Object, required: false, default: () => {} },
|
|
64
|
+
type: {
|
|
65
|
+
type: String as PropType<
|
|
66
|
+
"text" | "number" | "email" | "password" | "search" | "date"
|
|
67
|
+
>,
|
|
68
|
+
default: "text",
|
|
69
|
+
},
|
|
70
|
+
modelValue: {
|
|
71
|
+
type: [String, Number],
|
|
72
|
+
default: "",
|
|
73
|
+
},
|
|
74
|
+
name: {
|
|
75
|
+
type: String,
|
|
76
|
+
required: false,
|
|
77
|
+
default: "",
|
|
78
|
+
},
|
|
79
|
+
label: {
|
|
80
|
+
type: String,
|
|
81
|
+
required: true,
|
|
82
|
+
default: "",
|
|
83
|
+
},
|
|
84
|
+
placeholder: {
|
|
85
|
+
type: String,
|
|
86
|
+
required: false,
|
|
87
|
+
default: "",
|
|
88
|
+
},
|
|
89
|
+
iconType: {
|
|
90
|
+
type: String as PropType<"startIcon" | "endIcon">,
|
|
91
|
+
default: "",
|
|
92
|
+
},
|
|
93
|
+
icon: {
|
|
94
|
+
type: [Object, String],
|
|
95
|
+
default: "",
|
|
96
|
+
},
|
|
97
|
+
autoFocus: {
|
|
98
|
+
type: Boolean,
|
|
99
|
+
required: false,
|
|
100
|
+
default: false,
|
|
101
|
+
},
|
|
102
|
+
disabled: {
|
|
103
|
+
type: Boolean,
|
|
104
|
+
default: false,
|
|
105
|
+
},
|
|
106
|
+
required: {
|
|
107
|
+
type: Boolean,
|
|
108
|
+
default: false,
|
|
109
|
+
},
|
|
110
|
+
readonly:{
|
|
111
|
+
type:Boolean,
|
|
112
|
+
default: false
|
|
113
|
+
},
|
|
114
|
+
rounded:Boolean,
|
|
115
|
+
className: {
|
|
116
|
+
type: Array as PropType<string[]>,
|
|
117
|
+
required: false,
|
|
118
|
+
default: () => [],
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const hasFocus = ref(false);
|
|
123
|
+
const input = ref<HTMLInputElement>();
|
|
124
|
+
const id = "id"; //generateUID();
|
|
125
|
+
|
|
126
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
127
|
+
const emitInput = (event: Event) => {
|
|
128
|
+
const newValue = (event?.target as HTMLInputElement)?.value;
|
|
129
|
+
if (newValue !== undefined) {
|
|
130
|
+
emit("update:modelValue", newValue);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const getIconClass = () => {
|
|
135
|
+
switch (props.iconType) {
|
|
136
|
+
case "startIcon":
|
|
137
|
+
return "pl-12 pr-4";
|
|
138
|
+
case "endIcon":
|
|
139
|
+
return "pr-12 pl-4";
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
onMounted(() => {
|
|
144
|
+
if (props?.autoFocus) {
|
|
145
|
+
input?.value?.focus();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
</script>
|
|
149
|
+
|
|
150
|
+
<style lang="scss" scoped>
|
|
151
|
+
/* Chrome, Safari, Edge, Opera */
|
|
152
|
+
input::-webkit-outer-spin-button,
|
|
153
|
+
input::-webkit-inner-spin-button {
|
|
154
|
+
-webkit-appearance: none;
|
|
155
|
+
margin: 0;
|
|
156
|
+
}
|
|
157
|
+
/* Firefox */
|
|
158
|
+
input[type="number"] {
|
|
159
|
+
-moz-appearance: textfield;
|
|
160
|
+
}
|
|
161
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col items-center justify-center gap-4 size-72 mx-auto">
|
|
3
|
+
<div class="min-h-16 relative">
|
|
4
|
+
<div class="circle-loader">
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<style lang="scss" scoped>
|
|
15
|
+
.circle-loader {
|
|
16
|
+
@apply box-border size-16 rounded-full relative transform rotate-45 border-[0.8rem] border-solid border-violet-500/25;
|
|
17
|
+
&::before {
|
|
18
|
+
content: "";
|
|
19
|
+
@apply absolute box-border -inset-3 rounded-full border-[0.8rem] border-solid border-violet-600;
|
|
20
|
+
animation: circleProgress 2s infinite linear;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@keyframes circleProgress {
|
|
25
|
+
0% {clip-path:polygon(50% 50%,0 0,0 0,0 0,0 0,0 0)}
|
|
26
|
+
25% {clip-path:polygon(50% 50%,0 0,100% 0,100% 0,100% 0,100% 0)}
|
|
27
|
+
50% {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,100% 100%,100% 100%)}
|
|
28
|
+
75% {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 100%)}
|
|
29
|
+
100% {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 0)}
|
|
30
|
+
}
|
|
31
|
+
</style>
|