@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,316 @@
1
+ <template>
2
+ <div class="bar-chart">
3
+ <div
4
+ class="graph-wrap"
5
+ v-for="(item, i) in dataArray"
6
+ :key="i"
7
+ >
8
+ <div
9
+ class="group-wrap"
10
+ v-if="item.group"
11
+ >
12
+ <p class="group-title">
13
+ {{ item.group }}
14
+ </p>
15
+ <div
16
+ v-for="(nested, i) in item?.data || []"
17
+ :key="i"
18
+ class="bar-wrap"
19
+ >
20
+ <div
21
+ class="bar"
22
+ :style="{ height: loaded ? `${percent(nested.value)}%` : '0' }"
23
+ />
24
+ <div
25
+ class="bar compare"
26
+ v-if="nested.compareValue"
27
+ :style="{
28
+ height: loaded ? `${percent(nested.compareValue)}%` : '0',
29
+ }"
30
+ />
31
+ <!-- <p class="bar-txt">{{ nested.title }}</p> -->
32
+ </div>
33
+ </div>
34
+ <div
35
+ v-else
36
+ class="bar-wrap"
37
+ >
38
+ <div
39
+ class="bar"
40
+ :style="{ height: loaded ? `${percent(item.value)}%` : '0' }"
41
+ />
42
+ <div
43
+ class="bar compare"
44
+ v-if="item?.compareValue"
45
+ :style="{ height: loaded ? `${percent(item.compareValue)}%` : '0' }"
46
+ />
47
+ <p class="bar-txt">
48
+ {{ item.title }}
49
+ </p>
50
+ </div>
51
+ </div>
52
+ <p class="factor">
53
+ {{ title }}
54
+ </p>
55
+ <div class="red-bar" />
56
+ <div class="bar-lines">
57
+ <p
58
+ v-for="mark in marks"
59
+ :key="mark"
60
+ >
61
+ {{ mark.toLocaleString() }}
62
+ </p>
63
+ </div>
64
+ </div>
65
+ </template>
66
+
67
+ <script setup lang="ts">
68
+ import { ref, onMounted, computed } from 'vue';
69
+
70
+ const props = defineProps<{
71
+ title?: string;
72
+ showMarks?: boolean;
73
+ flood?: number;
74
+ modelValue: {
75
+ value: number;
76
+ title?: string;
77
+ compareValue?: number;
78
+ group?: string;
79
+ data?: Record<string, any>[];
80
+ }[];
81
+ // | {
82
+ // group: string;
83
+ // data: {
84
+ // value: number;
85
+ // title: string;
86
+ // compareValue?: number | undefined;
87
+ // group?: string | undefined;
88
+ // data?: Record<string, any>[] | undefined;
89
+ // }[]
90
+ // }[]
91
+ }>();
92
+ const loaded = ref(false);
93
+
94
+ onMounted(() => {
95
+ setTimeout(() => {
96
+ loaded.value = true;
97
+ }, 400);
98
+ });
99
+
100
+ const dataArray = computed(
101
+ () => props.modelValue,
102
+ // const allData = []
103
+ // for (const item of props.modelValue) {
104
+ // if (item.group) {
105
+ // let groupIndex = allData.findIndex(d => d.group === item.group)
106
+ // if (groupIndex > -1) allData[groupIndex].data?.push(item);
107
+ // else allData.push({ group: item.group, data: [item] })
108
+ // } else {
109
+ // allData.push(item)
110
+ // }
111
+ // }
112
+ // return allData;
113
+ );
114
+
115
+ const maxValue = computed(() => Math.ceil(
116
+ Math.max(
117
+ ...dataArray.value.map((d) => d.value),
118
+ ...dataArray.value.map((d) => d?.compareValue || 0),
119
+ ),
120
+ ));
121
+
122
+ const marks = computed(() => {
123
+ const marksArray: number[] = [];
124
+ for (let i = 0; i <= 5; i += 1) {
125
+ const step = (i * maxValue.value) / 5;
126
+ marksArray.push(Math.round(step / 10) * 10);
127
+ }
128
+ return marksArray;
129
+ });
130
+
131
+ const percent = (val: number) => (val / maxValue.value) * 100;
132
+ const floodPercent = computed(() => `${props.flood}%`);
133
+ </script>
134
+
135
+ <style scoped>
136
+ /* .group-wrap * {
137
+ outline: 1px solid red;
138
+ } */
139
+
140
+ .group-wrap {
141
+ height: 100%;
142
+ display: flex;
143
+ align-items: center;
144
+ justify-content: center;
145
+ flex-wrap: wrap;
146
+ gap: 2px;
147
+ }
148
+
149
+ .group-wrap .bar-wrap {
150
+ gap: 2px;
151
+ }
152
+
153
+ .group-title {
154
+ font-size: 0.6em;
155
+ width: 100%;
156
+ }
157
+
158
+ .bar-txt {
159
+ font-size: 11px;
160
+ font-weight: 200;
161
+ /* max-width: 95%; */
162
+ width: max-content;
163
+ height: 20px;
164
+ line-height: 1.2;
165
+ margin: 5px auto 0;
166
+ position: absolute;
167
+ transform: rotate(300deg);
168
+ transform-origin: 40px 40px;
169
+ }
170
+
171
+ .graph-wrap {
172
+ display: flex;
173
+ flex-direction: row;
174
+ align-items: flex-end;
175
+ padding: 0 10px;
176
+ }
177
+
178
+ .bar-wrap {
179
+ text-align: center;
180
+ height: 100%;
181
+ /* flex: 0 1 16.6%; */
182
+ display: flex;
183
+ flex-direction: row;
184
+ align-items: flex-end;
185
+ position: relative;
186
+ }
187
+
188
+ .bar {
189
+ background: var(--bgl-blue);
190
+ position: relative;
191
+ min-width: 10px;
192
+ min-height: 5px;
193
+ width: 4px;
194
+ margin: 0 auto;
195
+ transition: all ease-out 0.8s;
196
+ }
197
+
198
+ .bar.compare {
199
+ background-color: #cf2135;
200
+ }
201
+
202
+ .bar-chart {
203
+ height: calc(100vh - 500px);
204
+ width: 90%;
205
+ margin: 30px auto;
206
+ display: flex;
207
+ justify-content: space-between;
208
+ position: relative;
209
+ }
210
+
211
+ .graps .bar-chart {
212
+ aspect-ratio: 9/5;
213
+ height: auto;
214
+ max-height: calc(100vh - 500px);
215
+ }
216
+
217
+ .bar-lines {
218
+ position: absolute;
219
+ /* font-size: 20px; */
220
+ display: flex;
221
+ flex-direction: column-reverse;
222
+ top: -15px;
223
+ bottom: -12px;
224
+ left: -30px;
225
+ justify-content: space-between;
226
+ width: calc(100% + 20px);
227
+ text-align: start;
228
+ }
229
+
230
+ .bar-lines p {
231
+ margin: 0;
232
+ position: relative;
233
+ }
234
+
235
+ .bar-lines p::after {
236
+ content: "";
237
+ background: var(--bgl-blue-tint);
238
+ height: 1px;
239
+ position: absolute;
240
+ width: calc(100% - 20px);
241
+ margin: 14px 0 0 10px;
242
+ opacity: 0.5;
243
+ }
244
+
245
+ .bar-lines p:first-child:after {
246
+ content: "";
247
+ background: var(--bgl-blue-tint);
248
+ height: 1px;
249
+ position: absolute;
250
+ width: calc(100% - 10px);
251
+ margin: 8px 0 0 10px;
252
+ opacity: 0.5;
253
+ }
254
+
255
+ .red-bar {
256
+ background: #cf2135;
257
+ height: v-bind(floodPercent);
258
+ width: 100%;
259
+ position: absolute;
260
+ left: 0px;
261
+ bottom: 0;
262
+ opacity: 0.6;
263
+ transition: all 200ms ease;
264
+ }
265
+
266
+ .red-bar.open-redbar {
267
+ height: 7%;
268
+ }
269
+
270
+ .factor {
271
+ position: absolute;
272
+ transform: rotate(270deg);
273
+ height: 0px;
274
+ width: 0;
275
+ left: -60px;
276
+ font-size: 22px;
277
+ text-align: center;
278
+ white-space: nowrap;
279
+ top: 60%;
280
+ }
281
+
282
+ .dash-hor {
283
+ /* border-bottom: 1px dashed white; */
284
+ position: absolute;
285
+ background-image: linear-gradient(to right, #cf2134 53%, transparent 0%);
286
+ height: 10px;
287
+ bottom: 41.5%;
288
+ width: 100%;
289
+ animation: 1s linear 0s infinite dash;
290
+ background-position: left;
291
+ background-repeat: repeat-x;
292
+ background-size: 15px 4px;
293
+ }
294
+
295
+ .dash-hor::after {
296
+ content: "Average Speedup = 25x";
297
+ position: absolute;
298
+ left: 0;
299
+ bottom: 10px;
300
+ font-size: 22px;
301
+ background: #cf2134;
302
+ z-index: 2;
303
+ padding: 1px 4px;
304
+ border-radius: 3px;
305
+ }
306
+
307
+ @keyframes dash {
308
+ 0% {
309
+ background-position: 0;
310
+ }
311
+
312
+ 100% {
313
+ background-position: 15px;
314
+ }
315
+ }
316
+ </style>
@@ -0,0 +1,197 @@
1
+ <template>
2
+ <div
3
+ ref="chartContainer"
4
+ class="chart-line"
5
+ >
6
+ <Chart
7
+ v-if="chartSize"
8
+ :size="chartSize"
9
+ :data="data"
10
+ :margin="chartMargin"
11
+ :axis="axisConfig"
12
+ >
13
+ <template #layers>
14
+ <Grid
15
+ :center="true"
16
+ strokeDasharray="2,2"
17
+ :hideY="true"
18
+ />
19
+ <Area
20
+ aria-label="Profit/Loss"
21
+ :dataKeys="['date', 'total_value']"
22
+ type="monotone"
23
+ :areaStyle="{ fill: 'url(#grad)' }"
24
+ />
25
+ <Line
26
+ :dataKeys="['date', 'total_value']"
27
+ type="monotone"
28
+ :dotStyle="dotStyling"
29
+ :lineStyle="{ stroke: BRAND_COLOR, r: 2 }"
30
+ />
31
+ <Marker
32
+ v-if="displayMarker"
33
+ :value="meanValue"
34
+ label="ממוצע"
35
+ :color="BRAND_COLOR"
36
+ :strokeWidth="2"
37
+ strokeDasharray="6 6"
38
+ />
39
+ <defs>
40
+ <linearGradient
41
+ id="grad"
42
+ gradientTransform="rotate(90)"
43
+ >
44
+ <stop
45
+ offset="0%"
46
+ :stop-color="BRAND_COLOR"
47
+ stop-opacity="1"
48
+ />
49
+ <stop
50
+ offset="100%"
51
+ stop-color="white"
52
+ stop-opacity="0.4"
53
+ />
54
+ </linearGradient>
55
+ </defs>
56
+ </template>
57
+ <template #widgets>
58
+ <Tooltip
59
+ color="white"
60
+ :config="tooltipConfiguration"
61
+ />
62
+ </template>
63
+ </Chart>
64
+ </div>
65
+ </template>
66
+
67
+ <script lang="ts" setup>
68
+ import { onMounted, onUnmounted } from 'vue';
69
+ import {
70
+ Chart, Grid, Line, Area, Tooltip, Marker,
71
+ } from 'vue3-charts';
72
+ import type { ChartAxis, Data } from 'vue3-charts/dist/types';
73
+
74
+ const props = defineProps<{ data: Data[], locale: string }>();
75
+
76
+ const data = $computed(() => (props.locale === 'he' ? [...props.data].reverse() : props.data));
77
+
78
+ interface Size {
79
+ width: number;
80
+ height: number;
81
+ }
82
+
83
+ // Computed properties
84
+ const meanValue = $computed(() => {
85
+ const sum = props.data.reduce((acc, curr) => acc + +curr.total_value, 0);
86
+ return sum / props.data.length;
87
+ });
88
+
89
+ const axisConfig = $computed<ChartAxis>(() => ({
90
+ primary: {
91
+ type: 'band',
92
+ rotate: true,
93
+ ticks: 5,
94
+ domain: ['dataMin', 'dataMax'],
95
+ tickValues: props.data?.length > 100 ? [''] : props.data.map((d: any) => d.date),
96
+ },
97
+ secondary: {
98
+ domain: ['dataMin', 'dataMax * 1.05'],
99
+ type: 'linear',
100
+ ticks: 8,
101
+ },
102
+ }));
103
+
104
+ // Constants
105
+ const BRAND_COLOR = 'var(--bgl-blue)';
106
+
107
+ const tooltipConfiguration = {
108
+ date: { label: 'תאריך' },
109
+ total_value: { color: BRAND_COLOR, label: 'סכום', format: (v: number) => `₪${v.toLocaleString()}` },
110
+ total_count: { label: 'מספר התרומות', format: (v: number) => `${v.toLocaleString()}` },
111
+ };
112
+
113
+ // Refs
114
+ let chartSize = $ref<Size | null>(null);
115
+ const chartContainer = $ref<HTMLElement>();
116
+ const displayMarker = $ref(true);
117
+ const chartMargin = $ref({
118
+ left: 0,
119
+ top: 0,
120
+ right: 0,
121
+ bottom: 0,
122
+ });
123
+
124
+ // Functions
125
+ const adjustChartSize = () => {
126
+ chartSize = null;
127
+ const el = chartContainer;
128
+ if (!el) return;
129
+ const { width, height } = el.getBoundingClientRect();
130
+ chartSize = { width: width - 5, height: height - 10 };
131
+ console.log(chartSize);
132
+ };
133
+
134
+ const handleResize = () => {
135
+ setTimeout(adjustChartSize, 300);
136
+ };
137
+
138
+ // Lifecycle hooks
139
+ onMounted(() => {
140
+ adjustChartSize();
141
+ window.addEventListener('resize', handleResize);
142
+ });
143
+
144
+ onUnmounted(() => {
145
+ window.removeEventListener('resize', handleResize);
146
+ });
147
+
148
+ // Style Configurations
149
+ const dotStyling = (ctx: Record<string, any>) => ({
150
+ r: ctx.active ? 5 : 1,
151
+ fill: BRAND_COLOR,
152
+ });
153
+ </script>
154
+
155
+ <style>
156
+ .chart-line {
157
+ width: 100%;
158
+ height: 300px;
159
+ }
160
+
161
+ [dir='rtl'] .chart-line {
162
+ direction: ltr;
163
+ }
164
+
165
+ .chart-line .v-tooltip-content>div {
166
+ border: none !important;
167
+ border-radius: 6px !important;
168
+ background-color: black !important;
169
+ opacity: 0.7;
170
+ padding: 0.5rem 1rem !important;
171
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06) !important;
172
+ font-weight: 300;
173
+ }
174
+
175
+ .chart-line .v-tooltip-content>div b {
176
+ font-weight: 400;
177
+ }
178
+
179
+ .layer-grid g:last-child {
180
+ display: none;
181
+ }
182
+
183
+ .layer-axis-x .tick:nth-child(2n + 1) {
184
+ opacity: 0;
185
+ }
186
+
187
+ @media screen and (max-width: 910px) {
188
+ .chart-line {
189
+ height: 140px;
190
+ }
191
+
192
+ .layer-axis-x .tick {
193
+ opacity: 0;
194
+ font-size: 0;
195
+ }
196
+ }
197
+ </style>
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <div>
3
+ {{ field.label || field.id }}
4
+
5
+ <Btn
6
+ color="gray"
7
+ @click="openModal()"
8
+ v-if="field.refCollection"
9
+ >
10
+ {{ content }}
11
+ <MaterialIcon icon="arrow_forward" />
12
+ </Btn>
13
+ <span
14
+ v-else
15
+ class="pill"
16
+ >
17
+ {{ content }}
18
+ </span>
19
+ </div>
20
+ </template>
21
+
22
+ <script lang="ts" setup>
23
+ import { ref, computed } from 'vue';
24
+ import { useRouter } from 'vue-router';
25
+ import type { BagelField } from '@/types';
26
+ import { Btn, MaterialIcon } from '@/components';
27
+
28
+ const router = useRouter();
29
+ // import Modal from '@/components/Modal.vue';
30
+
31
+ const openRef = ref(false);
32
+
33
+ const props = defineProps<{
34
+ modelValue: Record<string, any>;
35
+ field: BagelField;
36
+ }>();
37
+
38
+ const content = computed(() => props.field.refFields?.map((k) => props.modelValue?.[k] || '').join(' '));
39
+
40
+ const openModal = () => {
41
+ console.log(`openning ${props.modelValue?.id}`);
42
+ openRef.value = true;
43
+ void router.push(`/${props.field.refCollection}/${props.modelValue?.id}`);
44
+ };
45
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div
3
+ class="icon-font"
4
+ :style="{ fontSize: `${size}rem` }"
5
+ >
6
+ {{ icon }}
7
+ </div>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { MaterialIcons } from '@/types/materialIcons';
12
+
13
+ defineProps<{
14
+ icon: MaterialIcons
15
+ size?: number
16
+ }>();
17
+ </script>
18
+
19
+ <style scoped></style>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div class="bagel-input">
3
+ <label :for="formatString(name, 'pascal')">
4
+ <LangText :input="formatString(name, 'titleCase')" />
5
+ </label>
6
+ <input
7
+ v-if="type === 'checkbox'"
8
+ ref="el"
9
+ :checked="modelValue"
10
+ class="ctl"
11
+ type="checkbox"
12
+ @change="handleCheck"
13
+ >
14
+ <input
15
+ v-else-if="type === 'number'"
16
+ ref="el"
17
+ :name="formatString(name, 'pascal')"
18
+ :type="type"
19
+ :value="modelValue"
20
+ class="ctl"
21
+ @input="handleInput"
22
+ >
23
+ <input
24
+ v-else-if="type === 'text'"
25
+ ref="el"
26
+ :name="formatString(name, 'pascal')"
27
+ :type="type"
28
+ :value="modelValue"
29
+ class="ctl"
30
+ @input="handleInput"
31
+ >
32
+ <textarea
33
+ v-else-if="type === 'textarea'"
34
+ ref="el"
35
+ :name="formatString(name, 'pascal')"
36
+ :type="type"
37
+ :value="modelValue"
38
+ class="ctl"
39
+ @input="handleInput"
40
+ />
41
+ <div>
42
+ <LangText :input="errorMessage" />
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script lang="ts" setup>
48
+ import { onMounted, ref } from 'vue';
49
+
50
+ import LangText from '../translation/LangText.vue';
51
+ import { formatString } from '@/utils/strings';
52
+
53
+ const props = defineProps<{
54
+ type: 'text' | 'number' | 'password' | 'email' | 'checkbox' | 'textarea';
55
+ name: string;
56
+ value?: any;
57
+ modelValue: any;
58
+ errorMessage?: string;
59
+ focus?: boolean;
60
+ }>();
61
+
62
+ const emits = defineEmits(['update:modelValue']);
63
+ const el = ref<HTMLInputElement | null>(null);
64
+ const handleInput = (e: Event) => {
65
+ const el = e.target as HTMLInputElement;
66
+ emits('update:modelValue', el.value);
67
+ };
68
+ const handleCheck = (e: Event) => {
69
+ const el = e.target as HTMLInputElement;
70
+ emits('update:modelValue', el.checked ? 1 : 0);
71
+ };
72
+ onMounted(() => {
73
+ if (props.focus) {
74
+ el.value?.focus();
75
+ }
76
+ });
77
+ </script>
78
+
79
+ <style scoped></style>