@bagelink/vue 0.0.25 → 0.0.35

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.
Files changed (82) hide show
  1. package/package.json +34 -9
  2. package/src/components/Btn.vue +221 -0
  3. package/src/components/Comments.vue +284 -0
  4. package/src/components/ContactArray.vue +142 -0
  5. package/src/components/ContactSubmissions.vue +45 -0
  6. package/src/components/DataPreview.vue +85 -0
  7. package/src/components/DropDown.vue +122 -0
  8. package/src/components/FileUploader.vue +353 -0
  9. package/src/components/FormKitTable.vue +299 -0
  10. package/src/components/FormSchema.vue +79 -0
  11. package/src/components/LangText.vue +32 -0
  12. package/src/components/ListItem.vue +20 -0
  13. package/src/components/ListView.vue +54 -0
  14. package/src/components/MaterialIcon.vue +19 -0
  15. package/src/components/Modal.vue +62 -0
  16. package/src/components/ModalForm.vue +109 -0
  17. package/src/components/NavBar.vue +353 -0
  18. package/src/components/PageTitle.vue +17 -0
  19. package/src/components/PersonPreview.vue +203 -0
  20. package/src/components/PersonPreviewFormkit.vue +205 -0
  21. package/src/components/RTXEditor.vue +151 -0
  22. package/src/components/RouterWrapper.vue +17 -0
  23. package/src/components/TabbedLayout.vue +83 -0
  24. package/src/components/TableSchema.vue +248 -0
  25. package/src/components/TopBar.vue +5 -0
  26. package/src/components/charts/BarChart.vue +316 -0
  27. package/src/components/dashboard/Lineart.vue +197 -0
  28. package/src/components/form/ItemRef.vue +45 -0
  29. package/src/components/form/MaterialIcon.vue +19 -0
  30. package/src/components/form/PlainInputField.vue +79 -0
  31. package/src/components/form/inputs/CheckInput.vue +143 -0
  32. package/src/components/form/inputs/Checkbox.vue +77 -0
  33. package/src/components/form/inputs/ColorPicker.vue +47 -0
  34. package/src/components/form/inputs/CurrencyInput.vue +137 -0
  35. package/src/components/form/inputs/DateInput.vue +55 -0
  36. package/src/components/form/inputs/DatetimeInput.vue +50 -0
  37. package/src/components/form/inputs/DurationInput.vue +55 -0
  38. package/src/components/form/inputs/DynamicLinkField.vue +142 -0
  39. package/src/components/form/inputs/EmailInput.vue +57 -0
  40. package/src/components/form/inputs/FloatInput.vue +52 -0
  41. package/src/components/form/inputs/IntInput.vue +53 -0
  42. package/src/components/form/inputs/JSONInput.vue +55 -0
  43. package/src/components/form/inputs/LinkField.vue +300 -0
  44. package/src/components/form/inputs/Password.vue +91 -0
  45. package/src/components/form/inputs/PasswordInput.vue +92 -0
  46. package/src/components/form/inputs/PlainText.vue +63 -0
  47. package/src/components/form/inputs/ReadOnlyInput.vue +28 -0
  48. package/src/components/form/inputs/RichTextEditor.vue +56 -0
  49. package/src/components/form/inputs/SelectField.vue +258 -0
  50. package/src/components/form/inputs/TableField.vue +319 -0
  51. package/src/components/form/inputs/TextArea.vue +79 -0
  52. package/src/components/form/inputs/TextInput.vue +63 -0
  53. package/src/components/form/inputs/index.ts +16 -0
  54. package/src/components/formkit/AddressArray.vue +240 -0
  55. package/src/components/formkit/BankDetailsArray.vue +265 -0
  56. package/src/components/formkit/ContactArrayFormKit.vue +192 -0
  57. package/src/components/formkit/FileUploader.vue +391 -0
  58. package/src/components/formkit/MiscFields.vue +74 -0
  59. package/src/components/formkit/Toggle.vue +164 -0
  60. package/src/components/formkit/index.ts +29 -0
  61. package/src/components/index.ts +20 -0
  62. package/src/components/whatsapp/form/MsgTemplate.vue +227 -0
  63. package/src/components/whatsapp/form/TextVariableExamples.vue +79 -0
  64. package/src/components/whatsapp/interfaces.ts +58 -0
  65. package/src/index.ts +1 -26
  66. package/src/plugins/bagel.ts +26 -0
  67. package/src/styles/modal.css +90 -0
  68. package/src/types/BagelField.ts +57 -0
  69. package/src/types/BtnOptions.ts +14 -0
  70. package/src/types/Person.ts +51 -0
  71. package/src/types/file.ts +12 -0
  72. package/src/types/index.ts +4 -0
  73. package/src/types/materialIcons.d.ts +3005 -0
  74. package/src/utils/index.ts +62 -0
  75. package/src/utils/modal.ts +101 -0
  76. package/src/utils/objects.ts +81 -0
  77. package/src/utils/strings.ts +36 -0
  78. package/dist/index.cjs +0 -23
  79. package/dist/index.d.cts +0 -12
  80. package/dist/index.d.mts +0 -12
  81. package/dist/index.d.ts +0 -12
  82. package/dist/index.mjs +0 -19
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+ <input
11
+ :value="modelValue"
12
+ maxlength="140"
13
+ type="email"
14
+ @input="handleInput"
15
+ :placeholder="bagelApp.translate(placeholder, true)"
16
+ :class="{ 'no-edit': !editMode }"
17
+ >
18
+ </div>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ // @ts-ignore TODO: remove this Nati
23
+ import { bagelApp } from '../../../index';
24
+
25
+ const emits = defineEmits(['update:modelValue']);
26
+ // @ts-ignore TODO: remove this Nati
27
+ const props = withDefaults(
28
+ defineProps<{
29
+ description?: string;
30
+ label?: string;
31
+ modelValue: any;
32
+ placeholder?: string;
33
+ editMode?: boolean;
34
+ small?: boolean;
35
+ }>(),
36
+ {
37
+ description: '',
38
+ editMode: true,
39
+ placeholder: '',
40
+ label: '',
41
+ },
42
+ );
43
+ const handleInput = (e: Event) => {
44
+ const el = e.target as HTMLInputElement;
45
+ emits('update:modelValue', el.value);
46
+ };
47
+ </script>
48
+
49
+ <style scoped>
50
+ input[type='email'] {
51
+ direction: ltr;
52
+ }
53
+
54
+ [dir='rtl'] input[type='email'] {
55
+ text-align: end;
56
+ }
57
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+ <input
11
+ :value="modelValue"
12
+ type="number"
13
+ @input="handleInput"
14
+ :placeholder="bagelApp.translate(placeholder, true)"
15
+ :class="{ 'no-edit': !editMode }"
16
+ >
17
+ </div>
18
+ </template>
19
+
20
+ <script setup lang="ts">
21
+ // @ts-ignore TODO: remove this Nati
22
+ import { bagelApp } from '../../../index';
23
+
24
+ const emits = defineEmits(['update:modelValue']);
25
+ // @ts-ignore TODO: remove this Nati
26
+ const props = withDefaults(
27
+ defineProps<{
28
+ description?: string;
29
+ label?: string;
30
+ modelValue: any;
31
+ placeholder?: string;
32
+ editMode?: boolean;
33
+ small?: boolean;
34
+ }>(),
35
+ {
36
+ description: '',
37
+ editMode: true,
38
+ placeholder: '',
39
+ label: '',
40
+ },
41
+ );
42
+ const handleInput = (e: Event) => {
43
+ const el = e.target as HTMLInputElement;
44
+ let value = parseFloat(el.value);
45
+ if (isNaN(value)) {
46
+ value = 0;
47
+ }
48
+ emits('update:modelValue', value);
49
+ };
50
+ </script>
51
+
52
+ <style scoped></style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+ <input
11
+ :value="modelValue"
12
+ type="number"
13
+ @input="handleInput"
14
+ :placeholder="bagelApp.translate(placeholder, true)"
15
+ :class="{ 'no-edit': !editMode }"
16
+ >
17
+ </div>
18
+ </template>
19
+
20
+ <script setup lang="ts">
21
+ // @ts-ignore TODO: remove this Nati
22
+ import { bagelApp } from '../../../index';
23
+
24
+ // @ts-ignore TODO: remove this Nati
25
+ const emits = defineEmits(['update:modelValue']);
26
+ // @ts-ignore TODO: remove this Nati
27
+ const props = withDefaults(
28
+ defineProps<{
29
+ description?: string;
30
+ label?: string;
31
+ modelValue: any;
32
+ placeholder?: string;
33
+ editMode?: boolean;
34
+ small?: boolean;
35
+ }>(),
36
+ {
37
+ description: '',
38
+ editMode: true,
39
+ placeholder: '',
40
+ label: '',
41
+ },
42
+ );
43
+ const handleInput = (e: Event) => {
44
+ const el = e.target as HTMLInputElement;
45
+ let value = parseInt(el.value);
46
+ if (isNaN(value)) {
47
+ value = 0;
48
+ }
49
+ emits('update:modelValue', value);
50
+ };
51
+ </script>
52
+
53
+ <style scoped></style>
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+ <textarea
11
+ :value="modelValue"
12
+ @input="handleInput"
13
+ :placeholder="bagelApp.translate(placeholder, true)"
14
+ :class="{ 'no-edit': !editMode }"
15
+ />
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ // @ts-ignore TODO: remove this Nati
21
+ import { bagelApp } from '../../../index';
22
+
23
+ const emits = defineEmits(['update:modelValue']);
24
+ // @ts-ignore TODO: remove this Nati
25
+ const props = withDefaults(
26
+ defineProps<{
27
+ description?: string;
28
+ label?: string;
29
+ modelValue: any;
30
+ placeholder?: string;
31
+ editMode?: boolean;
32
+ small?: boolean;
33
+ }>(),
34
+ {
35
+ description: '',
36
+ editMode: true,
37
+ placeholder: '',
38
+ label: '',
39
+ },
40
+ );
41
+ const handleInput = (e: Event) => {
42
+ const el = e.target as HTMLInputElement;
43
+ emits('update:modelValue', el.value);
44
+ };
45
+ </script>
46
+
47
+ <style scoped>
48
+ .bagel-input textarea {
49
+ font-family: monospace;
50
+ }
51
+
52
+ [dir='rtl'] .bagel-input textarea {
53
+ direction: ltr;
54
+ }
55
+ </style>
@@ -0,0 +1,300 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+
11
+ <input
12
+ @keydown.enter="handleEnter"
13
+ autocomplete="off"
14
+ @click="openList"
15
+ name="link-input"
16
+ v-model="selectedItem"
17
+ @focus="initList"
18
+ @input="handleInput"
19
+ :disabled="!editMode"
20
+ >
21
+
22
+ <div
23
+ class="custom-select"
24
+ ref="selectEl"
25
+ name="link-input"
26
+ :class="{ 'open-select': showList && linkOptions.length > 0 }"
27
+ >
28
+ <Teleport to="#app">
29
+ <div
30
+ ref="dropdown"
31
+ :class="{ 'open-select': showList && linkOptions.length > 0 }"
32
+ class="custom-select-drop"
33
+ >
34
+ <div
35
+ v-for="option in linkOptions"
36
+ :key="formatString(option.value, 'pascal')"
37
+ @click.stop="handleSelect(option)"
38
+ >
39
+ <div
40
+ class="option-label"
41
+ v-if="option.label"
42
+ >
43
+ {{ option.label }}<span>ID: {{ option.value }}</span>
44
+ </div>
45
+ <div
46
+ class="option-label"
47
+ v-else
48
+ >
49
+ ID: {{ option.value }}
50
+ </div>
51
+ <div class="option-description">
52
+ {{ option.description }}
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </Teleport>
57
+ </div>
58
+ </div>
59
+ </template>
60
+
61
+ <script lang="ts" setup>
62
+ import { onMounted, ref } from 'vue';
63
+ import { formatString } from '@/utils/strings';
64
+
65
+ const props = withDefaults(
66
+ defineProps<{
67
+ description?: string;
68
+ label?: string;
69
+ modelValue: any;
70
+ useId?: false;
71
+ bagelApp?: any;
72
+ entity: string;
73
+ editMode: boolean;
74
+ filters?: any;
75
+ small?: boolean;
76
+ }>(),
77
+ {
78
+ description: '',
79
+ label: '',
80
+ useId: false,
81
+ filters: {},
82
+ bagelApp: null,
83
+ },
84
+ );
85
+ const showList = ref(false);
86
+
87
+ const left = ref('0');
88
+ const top = ref(0);
89
+ const width = ref('0');
90
+ const selectEl = ref<HTMLElement>();
91
+ const dropdown = ref<HTMLElement>();
92
+ const linkOptions = ref<any>([]);
93
+ const item = ref<ListItem>();
94
+ const emits = defineEmits(['update:modelValue', 'selected']);
95
+ const selectedItem = ref<any>();
96
+ let bagel: any;
97
+
98
+ function handleSelect(item: ListItem) {
99
+ showList.value = false;
100
+ selectedItem.value = item;
101
+ if (props.useId || props.entity === 'Entity') {
102
+ selectedItem.value = item.value;
103
+ } else {
104
+ selectedItem.value = item.label || item.value;
105
+ }
106
+
107
+ emits('update:modelValue', item.value);
108
+ emits('selected', item.value);
109
+ }
110
+
111
+ async function getLinkOptions(inputString: string) {
112
+ linkOptions.value = await bagel.entity.getLinkedFieldList({
113
+ entity: props.entity,
114
+ txt: inputString,
115
+ reference_entity: '',
116
+ filters: props.filters,
117
+ });
118
+ }
119
+
120
+ function hideDrop(e: WheelEvent) {
121
+ const dropRect = dropdown.value?.getBoundingClientRect?.() ||
122
+ ({
123
+ left: 0,
124
+ right: 0,
125
+ } as DOMRect);
126
+ if (e.clientX < dropRect.left || e.clientX > dropRect.right) {
127
+ showList.value = false;
128
+ }
129
+ }
130
+
131
+ function openList() {
132
+ setPosition();
133
+ showList.value = true;
134
+ }
135
+
136
+ // @ts-ignore TODO: remove this Nati
137
+ function setPosition(e?: WheelEvent) {
138
+ const elInfo = selectEl.value?.getBoundingClientRect?.() ||
139
+ ({
140
+ top: 0,
141
+ left: 0,
142
+ bottom: 0,
143
+ width: 0,
144
+ } as DOMRect);
145
+
146
+ top.value = elInfo.bottom;
147
+
148
+ left.value = `${elInfo.left}px`;
149
+ width.value = `${elInfo.width}px`;
150
+ const dropRect = dropdown.value?.getBoundingClientRect?.() ||
151
+ ({
152
+ height: 0,
153
+ } as DOMRect);
154
+
155
+ if (window.innerHeight - elInfo.bottom < dropRect.height) {
156
+ top.value = elInfo.top - dropRect.height;
157
+ }
158
+ }
159
+
160
+ interface ListItem {
161
+ value: string;
162
+ label?: string;
163
+ description?: string;
164
+ }
165
+
166
+ // @ts-ignore TODO: remove this Nati
167
+ const initialized = ref(false);
168
+
169
+ async function initList(e: Event) {
170
+ await getLinkOptions(getElValue(e));
171
+ showList.value = true;
172
+ }
173
+
174
+ function getElValue(e: Event) {
175
+ const el = e.target as HTMLInputElement;
176
+ return el.value.trim();
177
+ }
178
+
179
+ function handleEnter(e: Event) {
180
+ emits('update:modelValue', getElValue(e));
181
+ emits('selected');
182
+ showList.value = false;
183
+ }
184
+
185
+ function handleClick(e: any) {
186
+ const { target } = e;
187
+ if (target.name != 'link-input' && showList.value == true) {
188
+ showList.value = false;
189
+ emits('update:modelValue', item.value);
190
+ emits('selected');
191
+ }
192
+ // showList.value = false
193
+ }
194
+
195
+ const handleInput = async (e: Event) => {
196
+ showList.value = true;
197
+ const el = e.target as HTMLInputElement;
198
+ emits('update:modelValue', el.value);
199
+ await getLinkOptions(el.value);
200
+ };
201
+ onMounted(() => {
202
+ bagel = props.bagelApp;
203
+ setPosition();
204
+ window.addEventListener('wheel', hideDrop);
205
+ selectedItem.value = props.modelValue;
206
+ document.addEventListener('click', handleClick);
207
+ });
208
+ </script>
209
+
210
+ <style scoped>
211
+ .custom-select {
212
+ position: relative;
213
+ font-size: var(--input-font-size);
214
+ }
215
+
216
+ .custom-select .input {
217
+ width: 100%;
218
+ cursor: pointer;
219
+ background: var(--input-bg);
220
+ min-height: var(--input-height);
221
+ border: none;
222
+ border-radius: var(--input-border-radius);
223
+ color: var(--input-color);
224
+ position: relative;
225
+ display: flex;
226
+ flex-direction: column;
227
+ text-align: start;
228
+ margin-inline-end: 20px;
229
+ justify-content: center;
230
+ }
231
+
232
+ .custom-select .input:after {
233
+ content: 'keyboard_arrow_down';
234
+ font-family: 'Material Symbols Outlined', serif;
235
+ position: absolute;
236
+ top: calc(var(--input-height) / 2 - 10px);
237
+ font-size: calc(var(--input-font-size) * 1.5);
238
+ right: calc(var(--input-height) / 4);
239
+ height: 100%;
240
+ }
241
+
242
+ .option-label {
243
+ font-size: var(--input-font-size);
244
+ /*color: var(--input-color);*/
245
+ }
246
+
247
+ .option-description {
248
+ font-size: var(--input-font-size);
249
+ color: var(--input-color);
250
+ }
251
+
252
+ [dir='rtl'] .custom-select .input:after {
253
+ right: unset;
254
+ left: calc(var(--input-font-size) / 2);
255
+ }
256
+
257
+ /*[dir='rtl'] .custom-select-drop {*/
258
+ /* right: v-bind(left);*/
259
+ /* left: unset;*/
260
+ /*}*/
261
+ [dir='rtl'] .custom-select-drop {
262
+ inset-inline-end: v-bind(left);
263
+ inset-inline-start: unset;
264
+ }
265
+
266
+ .custom-select-drop {
267
+ position: fixed;
268
+ cursor: pointer;
269
+ inset-inline-start: v-bind(left);
270
+ top: v-bind('`${top}px`');
271
+ box-sizing: border-box;
272
+ width: v-bind(width);
273
+ background: var(--bgl-white);
274
+ box-shadow: 0 0 10px 0 var(--bgl-shadow);
275
+ border-radius: 10px;
276
+ z-index: 10000;
277
+ overflow-y: auto;
278
+ opacity: 0;
279
+ pointer-events: none;
280
+ max-height: 0;
281
+ }
282
+
283
+ .open-select.custom-select-drop {
284
+ opacity: 1;
285
+ max-height: 150px;
286
+ pointer-events: all;
287
+ }
288
+
289
+ .custom-select-drop>* {
290
+ padding: 0.5rem 0.75rem;
291
+ }
292
+
293
+ .custom-select-drop>*:hover {
294
+ background: var(--bgl-blue-light);
295
+ }
296
+
297
+ .custom-select-drop>*:active {
298
+ filter: var(--bgl-hover-filter);
299
+ }
300
+ </style>
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :class="{ small: small }"
5
+ :title="field.description"
6
+ v-if="field.id"
7
+ >
8
+ <label :for="field.id">
9
+ {{ field.label }}
10
+ <input
11
+ :id="field.id"
12
+ v-model="inputVal"
13
+ :type="inputType"
14
+ :placeholder="field.placeholder || field.label"
15
+ :class="{ 'no-edit': !editMode }"
16
+ :required="required"
17
+ :pattern="pattern"
18
+ v-bind="nativeInputAttrs"
19
+ >
20
+ </label>
21
+ <MaterialIcon
22
+ @click="showPassword()"
23
+ :icon="seePassword ? 'visibility' : 'visibility_off'"
24
+ />
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { ref, watch, computed } from 'vue';
30
+ import { BagelField } from '@/types/BagelField';
31
+ import { MaterialIcon } from '@/components';
32
+
33
+ const emits = defineEmits(['update:modelValue']);
34
+ let seePassword = $ref<boolean>(false);
35
+ const inputType = computed(() => (seePassword ? 'text' : 'password'));
36
+
37
+ function showPassword() {
38
+ seePassword = !seePassword;
39
+ }
40
+ const props = withDefaults(
41
+ defineProps<{
42
+ field: BagelField;
43
+ modelValue: any;
44
+ editMode?: boolean;
45
+ small?: boolean;
46
+ required?: boolean;
47
+ pattern?: string;
48
+ nativeInputAttrs?: Record<string, any>;
49
+ }>(),
50
+ {
51
+ editMode: true,
52
+ },
53
+ );
54
+ const inputVal = ref<string>(props.modelValue);
55
+ // watch(
56
+ // () => props.modelValue,
57
+ // (newVal) => {
58
+ // if (inputVal.value !== newVal) inputVal.value = newVal;
59
+ // },
60
+ // );
61
+ watch(inputVal, (newVal) => emits('update:modelValue', newVal));
62
+ // onMounted(() => (inputVal.value = props.modelValue));
63
+ </script>
64
+
65
+ <style scoped>
66
+ .icon-font {
67
+ position: absolute;
68
+ cursor: pointer;
69
+ z-index: 2;
70
+ color: var(--bgl-gray);
71
+ inset-inline-end: 0.75rem;
72
+ inset-block-start: calc(var(--input-height) / 2 + 3px);
73
+ transition: var(--bgl-transition);
74
+ user-select: none;
75
+ border-radius: 100%;
76
+ height: 24px;
77
+ width: 24px;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ }
82
+
83
+ .icon-font:hover {
84
+ background: var(--bgl-white);
85
+ }
86
+
87
+ .icon-font:active {
88
+ background: var(--bgl-white);
89
+ filter: brightness(90%);
90
+ }
91
+ </style>
@@ -0,0 +1,92 @@
1
+ <template>
2
+ <div
3
+ class="bagel-input"
4
+ :title="description"
5
+ :class="{ small: small }"
6
+ >
7
+ <label v-if="label">
8
+ <LangText :input="label" />
9
+ </label>
10
+ <div class="password-input-wrap">
11
+ <input
12
+ :value="modelValue"
13
+ :type="inputType"
14
+ @input="handleInput"
15
+ :placeholder="placeholder"
16
+ :class="{ 'no-edit': !editMode }"
17
+ >
18
+ <div
19
+ class="icon-font password-icon"
20
+ @mousedown="toggleInputType"
21
+ >
22
+ visibility
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ const emits = defineEmits(['update:modelValue']);
30
+ withDefaults(
31
+ defineProps<{
32
+ description?: string;
33
+ label?: string;
34
+ modelValue: any;
35
+ placeholder?: string;
36
+ editMode?: boolean;
37
+ small?: boolean;
38
+ }>(),
39
+ {
40
+ description: '',
41
+ editMode: true,
42
+ placeholder: '',
43
+ label: '',
44
+ },
45
+ );
46
+
47
+ let inputType = $ref('password');
48
+ const handleInput = (e: Event) => {
49
+ const el = e.target as HTMLInputElement;
50
+ emits('update:modelValue', el.value);
51
+ };
52
+
53
+ function toggleInputType() {
54
+ inputType = 'text';
55
+ document.addEventListener(
56
+ 'mouseup',
57
+ () => {
58
+ inputType = 'password';
59
+ },
60
+ { once: true },
61
+ );
62
+ }
63
+ </script>
64
+
65
+ <style scoped>
66
+ .password-input-wrap {
67
+ position: relative;
68
+ }
69
+
70
+ .password-icon {
71
+ position: absolute;
72
+ top: calc(var(--input-height) / 2 - 10px);
73
+ right: calc(var(--input-height) / 2 - 10px);
74
+ cursor: pointer;
75
+ transition: var(--bgl-transition);
76
+ user-select: none;
77
+ }
78
+
79
+ .password-icon:hover {
80
+ filter: var(--bgl-hover-filter);
81
+ color: var(--bgl-blue);
82
+ }
83
+
84
+ .password-icon:active {
85
+ filter: var(--bgl-active-filter);
86
+ }
87
+
88
+ [dir='rtl'] .password-icon {
89
+ left: calc(var(--input-height) / 2 - 10px);
90
+ right: unset;
91
+ }
92
+ </style>