@ramathibodi/nuxt-commons 0.1.74 → 0.1.75

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 (96) hide show
  1. package/README.md +115 -115
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/components/Alert.vue +58 -58
  4. package/dist/runtime/components/BarcodeReader.vue +130 -130
  5. package/dist/runtime/components/ExportCSV.vue +110 -110
  6. package/dist/runtime/components/FileBtn.vue +79 -79
  7. package/dist/runtime/components/ImportCSV.vue +151 -151
  8. package/dist/runtime/components/MrzReader.vue +168 -168
  9. package/dist/runtime/components/SplitterPanel.vue +67 -67
  10. package/dist/runtime/components/TabsGroup.vue +39 -39
  11. package/dist/runtime/components/TextBarcode.vue +66 -66
  12. package/dist/runtime/components/device/IdCardButton.vue +95 -95
  13. package/dist/runtime/components/device/IdCardWebSocket.vue +207 -207
  14. package/dist/runtime/components/device/Scanner.vue +350 -350
  15. package/dist/runtime/components/dialog/Confirm.vue +112 -112
  16. package/dist/runtime/components/dialog/Host.vue +88 -88
  17. package/dist/runtime/components/dialog/Index.vue +84 -84
  18. package/dist/runtime/components/dialog/Loading.vue +51 -51
  19. package/dist/runtime/components/dialog/default/Confirm.vue +112 -112
  20. package/dist/runtime/components/dialog/default/Loading.vue +60 -60
  21. package/dist/runtime/components/dialog/default/Notify.vue +82 -82
  22. package/dist/runtime/components/dialog/default/Printing.vue +46 -46
  23. package/dist/runtime/components/dialog/default/VerifyUser.vue +144 -144
  24. package/dist/runtime/components/document/Form.vue +50 -50
  25. package/dist/runtime/components/document/TemplateBuilder.vue +536 -536
  26. package/dist/runtime/components/form/ActionPad.vue +156 -156
  27. package/dist/runtime/components/form/Birthdate.vue +116 -116
  28. package/dist/runtime/components/form/CheckboxGroup.vue +99 -99
  29. package/dist/runtime/components/form/CodeEditor.vue +45 -45
  30. package/dist/runtime/components/form/Date.vue +270 -270
  31. package/dist/runtime/components/form/DateTime.vue +220 -220
  32. package/dist/runtime/components/form/Dialog.vue +178 -178
  33. package/dist/runtime/components/form/EditPad.vue +157 -157
  34. package/dist/runtime/components/form/File.vue +295 -295
  35. package/dist/runtime/components/form/Hidden.vue +44 -44
  36. package/dist/runtime/components/form/Iterator.vue +538 -538
  37. package/dist/runtime/components/form/Login.vue +143 -143
  38. package/dist/runtime/components/form/Pad.vue +399 -399
  39. package/dist/runtime/components/form/SignPad.vue +226 -226
  40. package/dist/runtime/components/form/System.vue +34 -34
  41. package/dist/runtime/components/form/Table.vue +391 -391
  42. package/dist/runtime/components/form/TableData.vue +236 -236
  43. package/dist/runtime/components/form/Time.vue +177 -177
  44. package/dist/runtime/components/form/images/Capture.vue +245 -245
  45. package/dist/runtime/components/form/images/Edit.vue +133 -133
  46. package/dist/runtime/components/form/images/Field.vue +331 -331
  47. package/dist/runtime/components/form/images/Pad.vue +54 -54
  48. package/dist/runtime/components/label/Date.vue +37 -37
  49. package/dist/runtime/components/label/DateAgo.vue +102 -102
  50. package/dist/runtime/components/label/DateCount.vue +152 -152
  51. package/dist/runtime/components/label/Field.vue +111 -111
  52. package/dist/runtime/components/label/FormatMoney.vue +37 -37
  53. package/dist/runtime/components/label/Mask.vue +46 -46
  54. package/dist/runtime/components/label/Object.vue +21 -21
  55. package/dist/runtime/components/master/Autocomplete.vue +89 -89
  56. package/dist/runtime/components/master/Combobox.vue +88 -88
  57. package/dist/runtime/components/master/RadioGroup.vue +90 -90
  58. package/dist/runtime/components/master/Select.vue +70 -70
  59. package/dist/runtime/components/master/label.vue +55 -55
  60. package/dist/runtime/components/model/Autocomplete.vue +91 -91
  61. package/dist/runtime/components/model/Combobox.vue +90 -90
  62. package/dist/runtime/components/model/Pad.vue +114 -114
  63. package/dist/runtime/components/model/Select.vue +78 -84
  64. package/dist/runtime/components/model/Table.vue +370 -370
  65. package/dist/runtime/components/model/iterator.vue +497 -497
  66. package/dist/runtime/components/model/label.vue +58 -58
  67. package/dist/runtime/components/pdf/Print.vue +75 -75
  68. package/dist/runtime/components/pdf/View.vue +146 -146
  69. package/dist/runtime/composables/dialog.d.ts +1 -1
  70. package/dist/runtime/composables/graphql.d.ts +1 -1
  71. package/dist/runtime/composables/graphqlModel.d.ts +9 -9
  72. package/dist/runtime/composables/graphqlModelItem.d.ts +7 -7
  73. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  74. package/dist/runtime/composables/userPermission.d.ts +1 -1
  75. package/dist/runtime/labs/Calendar.vue +99 -99
  76. package/dist/runtime/labs/form/EditMobile.vue +152 -152
  77. package/dist/runtime/labs/form/TextFieldMask.vue +43 -43
  78. package/dist/runtime/plugins/clientConfig.d.ts +1 -1
  79. package/dist/runtime/plugins/default.d.ts +1 -1
  80. package/dist/runtime/plugins/dialogManager.d.ts +1 -1
  81. package/dist/runtime/plugins/permission.d.ts +1 -1
  82. package/dist/runtime/types/alert.d.ts +11 -11
  83. package/dist/runtime/types/clientConfig.d.ts +13 -13
  84. package/dist/runtime/types/dialogManager.d.ts +35 -35
  85. package/dist/runtime/types/formDialog.d.ts +5 -5
  86. package/dist/runtime/types/graphqlOperation.d.ts +23 -23
  87. package/dist/runtime/types/menu.d.ts +31 -31
  88. package/dist/runtime/types/modules.d.ts +7 -7
  89. package/dist/runtime/types/permission.d.ts +13 -13
  90. package/package.json +131 -131
  91. package/scripts/enrich-vue-docs-from-ai.mjs +197 -197
  92. package/scripts/generate-ai-summary.mjs +321 -321
  93. package/scripts/generate-composables-md.mjs +129 -129
  94. package/scripts/postInstall.cjs +70 -70
  95. package/templates/.codegen/codegen.ts +32 -32
  96. package/templates/.codegen/plugin-schema-object.js +161 -161
@@ -1,69 +1,69 @@
1
- <script setup lang="ts">
2
- /**
3
- * SplitterPanel provides a resizable split layout panel for flexible, user-adjustable page composition.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import { ref } from 'vue'
7
- import { VCard } from 'vuetify/components/VCard'
8
-
9
- const isResizing = ref(false)
10
- const pane1Width = ref('50%')
11
- const containerRef = ref<HTMLElement>()
12
- interface Props extends /* @vue-ignore */ InstanceType<typeof VCard['$props']> {
13
- height?: number | string // Fixed or minimum height applied to the component container.
14
- }
15
- /**
16
- * Public props accepted by SplitterPanel.
17
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
18
- */
19
- const props = defineProps<Props>()
20
-
21
- const startResize = () => {
22
- isResizing.value = true
23
- }
24
-
25
- const stopResize = () => {
26
- isResizing.value = false
27
- }
28
-
29
- const resize = (event: MouseEvent) => {
30
- if (isResizing.value && containerRef.value) {
31
- const containerRect = containerRef.value.getBoundingClientRect()
32
- const newWidth = event.clientX - containerRect.left
33
- pane1Width.value = `${(newWidth / containerRect.width) * 100}%`
34
- }
35
- }
36
- </script>
37
-
38
- <template>
39
- <v-card :="$attrs">
40
- <v-sheet
41
- border
42
- :height="props.height"
43
- >
44
- <div
45
- ref="containerRef"
46
- class="d-flex"
47
- @mouseup="stopResize"
48
- @mousemove="resize"
49
- >
50
- <v-sheet :width="pane1Width">
51
- <slot name="left" />
52
- </v-sheet>
53
- <v-divider
54
- :thickness="3"
55
- vertical
56
- class="cursor-move"
57
- @mousedown="startResize"
58
- />
59
- <v-sheet :width="`calc(100% - ${pane1Width})`">
60
- <slot name="right" />
61
- </v-sheet>
62
- </div>
63
- </v-sheet>
64
- </v-card>
65
- </template>
66
-
1
+ <script setup lang="ts">
2
+ /**
3
+ * SplitterPanel provides a resizable split layout panel for flexible, user-adjustable page composition.
4
+ * This doc block is consumed by vue-docgen for generated API documentation.
5
+ */
6
+ import { ref } from 'vue'
7
+ import { VCard } from 'vuetify/components/VCard'
8
+
9
+ const isResizing = ref(false)
10
+ const pane1Width = ref('50%')
11
+ const containerRef = ref<HTMLElement>()
12
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VCard['$props']> {
13
+ height?: number | string // Fixed or minimum height applied to the component container.
14
+ }
15
+ /**
16
+ * Public props accepted by SplitterPanel.
17
+ * Document each prop field with intent, defaults, and side effects for clear generated docs.
18
+ */
19
+ const props = defineProps<Props>()
20
+
21
+ const startResize = () => {
22
+ isResizing.value = true
23
+ }
24
+
25
+ const stopResize = () => {
26
+ isResizing.value = false
27
+ }
28
+
29
+ const resize = (event: MouseEvent) => {
30
+ if (isResizing.value && containerRef.value) {
31
+ const containerRect = containerRef.value.getBoundingClientRect()
32
+ const newWidth = event.clientX - containerRect.left
33
+ pane1Width.value = `${(newWidth / containerRect.width) * 100}%`
34
+ }
35
+ }
36
+ </script>
37
+
38
+ <template>
39
+ <v-card :="$attrs">
40
+ <v-sheet
41
+ border
42
+ :height="props.height"
43
+ >
44
+ <div
45
+ ref="containerRef"
46
+ class="d-flex"
47
+ @mouseup="stopResize"
48
+ @mousemove="resize"
49
+ >
50
+ <v-sheet :width="pane1Width">
51
+ <slot name="left" />
52
+ </v-sheet>
53
+ <v-divider
54
+ :thickness="3"
55
+ vertical
56
+ class="cursor-move"
57
+ @mousedown="startResize"
58
+ />
59
+ <v-sheet :width="`calc(100% - ${pane1Width})`">
60
+ <slot name="right" />
61
+ </v-sheet>
62
+ </div>
63
+ </v-sheet>
64
+ </v-card>
65
+ </template>
66
+
67
67
  <style scoped>
68
68
 
69
- </style>
69
+ </style>
@@ -1,39 +1,39 @@
1
- <script lang="ts" setup>
2
- /**
3
- * TabsGroup renders grouped tab content and keeps tab state consistent across controlled and uncontrolled usage.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import {VTabs} from 'vuetify/components'
7
-
8
- interface Props extends /* @vue-ignore */ InstanceType<typeof VTabs['$props']> {
9
- flat?: boolean // Uses a flatter tab style with reduced elevation and borders.
10
- }
11
-
12
- defineOptions({
13
- inheritAttrs: false,
14
- })
15
-
16
- /**
17
- * Public props accepted by TabsGroup.
18
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
19
- */
20
- const props = defineProps<Props>()
21
- const currentTab = defineModel<string|number>()
22
- </script>
23
-
24
- <template>
25
- <v-card :flat="props.flat">
26
- <v-tabs
27
- v-bind="$attrs"
28
- v-model="currentTab"
29
- show-arrows
30
- >
31
- <slot name="tabs" />
32
- </v-tabs>
33
- <v-card-text>
34
- <v-tabs-window v-model="currentTab">
35
- <slot name="items" />
36
- </v-tabs-window>
37
- </v-card-text>
38
- </v-card>
39
- </template>
1
+ <script lang="ts" setup>
2
+ /**
3
+ * TabsGroup renders grouped tab content and keeps tab state consistent across controlled and uncontrolled usage.
4
+ * This doc block is consumed by vue-docgen for generated API documentation.
5
+ */
6
+ import {VTabs} from 'vuetify/components'
7
+
8
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VTabs['$props']> {
9
+ flat?: boolean // Uses a flatter tab style with reduced elevation and borders.
10
+ }
11
+
12
+ defineOptions({
13
+ inheritAttrs: false,
14
+ })
15
+
16
+ /**
17
+ * Public props accepted by TabsGroup.
18
+ * Document each prop field with intent, defaults, and side effects for clear generated docs.
19
+ */
20
+ const props = defineProps<Props>()
21
+ const currentTab = defineModel<string|number>()
22
+ </script>
23
+
24
+ <template>
25
+ <v-card :flat="props.flat">
26
+ <v-tabs
27
+ v-bind="$attrs"
28
+ v-model="currentTab"
29
+ show-arrows
30
+ >
31
+ <slot name="tabs" />
32
+ </v-tabs>
33
+ <v-card-text>
34
+ <v-tabs-window v-model="currentTab">
35
+ <slot name="items" />
36
+ </v-tabs-window>
37
+ </v-card-text>
38
+ </v-card>
39
+ </template>
@@ -1,66 +1,66 @@
1
- <script lang="ts" setup>
2
- /**
3
- * TextBarcode renders barcode output from plain text and updates when bound values change.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import {ref, watch} from 'vue'
7
- import {useAlert} from '../composables/alert'
8
-
9
- interface Props {
10
- modelValue?: string // Bound value for v-model synchronization with the parent component.
11
- }
12
-
13
- /**
14
- * Public props accepted by TextBarcode.
15
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
16
- */
17
- const props = defineProps<Props>()
18
- /**
19
- * Custom events emitted by TextBarcode.
20
- * Parents can listen to these events to react to user actions and internal state changes.
21
- */
22
- const emit = defineEmits<{
23
- (event: 'update:modelValue', value: string | undefined): void
24
- (event: 'decode', value: string | undefined): void
25
- }>()
26
- const alert = useAlert()
27
-
28
- const scanCode = ref<boolean>(false)
29
- const currentValue = ref<string>()
30
-
31
- const handleData = (data: string) => {
32
- currentValue.value = data
33
- scanCode.value = false
34
- emit('decode',data)
35
- }
36
-
37
- const handleError = (error: string | unknown) => {
38
- alert?.addAlert({ message: error as string, alertType: 'error' })
39
- }
40
-
41
- watch(() => props.modelValue, () => {
42
- currentValue.value = props.modelValue
43
- }, { immediate: true })
44
-
45
- watch(currentValue, (newValue) => {
46
- emit('update:modelValue', newValue)
47
- })
48
- </script>
49
-
50
- <template>
51
- <v-text-field
52
- v-model="currentValue"
53
- v-bind="$attrs"
54
- append-inner-icon="mdi mdi-qrcode-scan"
55
- @click:append-inner="scanCode = true"
56
- />
57
- <v-dialog
58
- v-model="scanCode"
59
- width="auto"
60
- >
61
- <BarcodeReader
62
- @decode="handleData"
63
- @error="handleError"
64
- />
65
- </v-dialog>
66
- </template>
1
+ <script lang="ts" setup>
2
+ /**
3
+ * TextBarcode renders barcode output from plain text and updates when bound values change.
4
+ * This doc block is consumed by vue-docgen for generated API documentation.
5
+ */
6
+ import {ref, watch} from 'vue'
7
+ import {useAlert} from '../composables/alert'
8
+
9
+ interface Props {
10
+ modelValue?: string // Bound value for v-model synchronization with the parent component.
11
+ }
12
+
13
+ /**
14
+ * Public props accepted by TextBarcode.
15
+ * Document each prop field with intent, defaults, and side effects for clear generated docs.
16
+ */
17
+ const props = defineProps<Props>()
18
+ /**
19
+ * Custom events emitted by TextBarcode.
20
+ * Parents can listen to these events to react to user actions and internal state changes.
21
+ */
22
+ const emit = defineEmits<{
23
+ (event: 'update:modelValue', value: string | undefined): void
24
+ (event: 'decode', value: string | undefined): void
25
+ }>()
26
+ const alert = useAlert()
27
+
28
+ const scanCode = ref<boolean>(false)
29
+ const currentValue = ref<string>()
30
+
31
+ const handleData = (data: string) => {
32
+ currentValue.value = data
33
+ scanCode.value = false
34
+ emit('decode',data)
35
+ }
36
+
37
+ const handleError = (error: string | unknown) => {
38
+ alert?.addAlert({ message: error as string, alertType: 'error' })
39
+ }
40
+
41
+ watch(() => props.modelValue, () => {
42
+ currentValue.value = props.modelValue
43
+ }, { immediate: true })
44
+
45
+ watch(currentValue, (newValue) => {
46
+ emit('update:modelValue', newValue)
47
+ })
48
+ </script>
49
+
50
+ <template>
51
+ <v-text-field
52
+ v-model="currentValue"
53
+ v-bind="$attrs"
54
+ append-inner-icon="mdi mdi-qrcode-scan"
55
+ @click:append-inner="scanCode = true"
56
+ />
57
+ <v-dialog
58
+ v-model="scanCode"
59
+ width="auto"
60
+ >
61
+ <BarcodeReader
62
+ @decode="handleData"
63
+ @error="handleError"
64
+ />
65
+ </v-dialog>
66
+ </template>
@@ -1,95 +1,95 @@
1
- <script setup lang="ts">
2
- /**
3
- * DeviceIdCardButton bridges UI actions with host-agent hardware/device operations and emits runtime scan/read results.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import { computed, ref, useAttrs } from 'vue'
7
- import { VBtn } from 'vuetify/components/VBtn'
8
- import { useAlert } from '../../composables/alert'
9
- import { useHostAgent, type PatientRegisterPayload } from '../../composables/hostAgent'
10
-
11
- interface Props extends /* @vue-ignore */ InstanceType<typeof VBtn['$props']> {
12
- /** If true -> call /idcard/infoAndPhoto, else /idcard/info */
13
- withPhoto?: boolean // Includes portrait/photo data in ID card read results.
14
- /** Optional reader name/query string */
15
- reader?: string | null // Preferred hardware reader identifier to connect or switch to.
16
- /** Auto-disable button while reading */
17
- disableWhileLoading?: boolean // Disables the trigger button while a read operation is in progress.
18
- }
19
-
20
- /**
21
- * Public props accepted by DeviceIdCardButton.
22
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
23
- */
24
- const props = withDefaults(defineProps<Props>(), {
25
- withPhoto: false,
26
- reader: null,
27
- disableWhileLoading: true,
28
- })
29
-
30
- /**
31
- * Custom events emitted by DeviceIdCardButton.
32
- * Parents can listen to these events to react to user actions and internal state changes.
33
- */
34
- const emit = defineEmits<{
35
- (e: 'read', payload: PatientRegisterPayload): void
36
- (e: 'error', err: unknown): void
37
- (e: 'loading', loading: boolean): void
38
- }>()
39
-
40
- const attrs = useAttrs()
41
- const host = useHostAgent()
42
-
43
- const loading = ref(false)
44
- const disabled = computed(() => (props.disableWhileLoading ? loading.value : false))
45
-
46
- async function onClick(ev: MouseEvent) {
47
- // allow parent to prevent if they attach their own click handler and call preventDefault
48
- if (ev.defaultPrevented) return
49
-
50
- try {
51
- loading.value = true
52
- emit('loading', true)
53
-
54
- const payload = props.withPhoto
55
- ? await host.getIdCardInfoAndPhoto(props.reader ?? undefined)
56
- : await host.getIdCardInfo(props.reader ?? undefined)
57
-
58
- emit('read', payload)
59
- } catch (e: any) {
60
- emit('error', e)
61
-
62
- const msg = e?.data?.detail || e?.data?.title || e?.message || 'ID card read failed'
63
- useAlert()?.addAlert({ message: msg, alertType: 'error' })
64
- } finally {
65
- loading.value = false
66
- emit('loading', false)
67
- }
68
- }
69
- </script>
70
-
71
- <template>
72
- <!--
73
- Extends Vuetify VBtn:
74
- - All unknown attrs (size, class, etc.) pass through via v-bind="attrs"
75
- - You can override content via default slot; label+icon is fallback
76
- -->
77
- <v-btn
78
- v-bind="attrs"
79
- class="idcard-btn"
80
- :loading="loading"
81
- :disabled="disabled || (attrs as any).disabled"
82
- @click="onClick"
83
- >
84
- <template
85
- v-for="(_, name, index) in ($slots as {})"
86
- :key="index"
87
- #[name]="slotData"
88
- >
89
- <slot
90
- :name="name"
91
- v-bind="((slotData || {}) as object)"
92
- />
93
- </template>
94
- </v-btn>
95
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * DeviceIdCardButton bridges UI actions with host-agent hardware/device operations and emits runtime scan/read results.
4
+ * This doc block is consumed by vue-docgen for generated API documentation.
5
+ */
6
+ import { computed, ref, useAttrs } from 'vue'
7
+ import { VBtn } from 'vuetify/components/VBtn'
8
+ import { useAlert } from '../../composables/alert'
9
+ import { useHostAgent, type PatientRegisterPayload } from '../../composables/hostAgent'
10
+
11
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VBtn['$props']> {
12
+ /** If true -> call /idcard/infoAndPhoto, else /idcard/info */
13
+ withPhoto?: boolean // Includes portrait/photo data in ID card read results.
14
+ /** Optional reader name/query string */
15
+ reader?: string | null // Preferred hardware reader identifier to connect or switch to.
16
+ /** Auto-disable button while reading */
17
+ disableWhileLoading?: boolean // Disables the trigger button while a read operation is in progress.
18
+ }
19
+
20
+ /**
21
+ * Public props accepted by DeviceIdCardButton.
22
+ * Document each prop field with intent, defaults, and side effects for clear generated docs.
23
+ */
24
+ const props = withDefaults(defineProps<Props>(), {
25
+ withPhoto: false,
26
+ reader: null,
27
+ disableWhileLoading: true,
28
+ })
29
+
30
+ /**
31
+ * Custom events emitted by DeviceIdCardButton.
32
+ * Parents can listen to these events to react to user actions and internal state changes.
33
+ */
34
+ const emit = defineEmits<{
35
+ (e: 'read', payload: PatientRegisterPayload): void
36
+ (e: 'error', err: unknown): void
37
+ (e: 'loading', loading: boolean): void
38
+ }>()
39
+
40
+ const attrs = useAttrs()
41
+ const host = useHostAgent()
42
+
43
+ const loading = ref(false)
44
+ const disabled = computed(() => (props.disableWhileLoading ? loading.value : false))
45
+
46
+ async function onClick(ev: MouseEvent) {
47
+ // allow parent to prevent if they attach their own click handler and call preventDefault
48
+ if (ev.defaultPrevented) return
49
+
50
+ try {
51
+ loading.value = true
52
+ emit('loading', true)
53
+
54
+ const payload = props.withPhoto
55
+ ? await host.getIdCardInfoAndPhoto(props.reader ?? undefined)
56
+ : await host.getIdCardInfo(props.reader ?? undefined)
57
+
58
+ emit('read', payload)
59
+ } catch (e: any) {
60
+ emit('error', e)
61
+
62
+ const msg = e?.data?.detail || e?.data?.title || e?.message || 'ID card read failed'
63
+ useAlert()?.addAlert({ message: msg, alertType: 'error' })
64
+ } finally {
65
+ loading.value = false
66
+ emit('loading', false)
67
+ }
68
+ }
69
+ </script>
70
+
71
+ <template>
72
+ <!--
73
+ Extends Vuetify VBtn:
74
+ - All unknown attrs (size, class, etc.) pass through via v-bind="attrs"
75
+ - You can override content via default slot; label+icon is fallback
76
+ -->
77
+ <v-btn
78
+ v-bind="attrs"
79
+ class="idcard-btn"
80
+ :loading="loading"
81
+ :disabled="disabled || (attrs as any).disabled"
82
+ @click="onClick"
83
+ >
84
+ <template
85
+ v-for="(_, name, index) in ($slots as {})"
86
+ :key="index"
87
+ #[name]="slotData"
88
+ >
89
+ <slot
90
+ :name="name"
91
+ v-bind="((slotData || {}) as object)"
92
+ />
93
+ </template>
94
+ </v-btn>
95
+ </template>