@vue-interface/select-field 2.0.2 → 2.0.4
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/package.json +4 -3
- package/src/SelectField.vue +160 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue-interface/select-field",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "A Vue select field component.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/select-field.umd.js",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"homepage": "https://vue-interface.github.io/packages/select-field",
|
|
36
36
|
"readme": "README.md",
|
|
37
37
|
"files": [
|
|
38
|
+
"src",
|
|
38
39
|
"dist",
|
|
39
40
|
"index.css",
|
|
40
41
|
"README.md",
|
|
@@ -42,8 +43,8 @@
|
|
|
42
43
|
],
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"vue": "^3.3.4",
|
|
45
|
-
"@vue-interface/activity-indicator": "3.0.
|
|
46
|
-
"@vue-interface/form-control": "2.0.
|
|
46
|
+
"@vue-interface/activity-indicator": "3.0.3",
|
|
47
|
+
"@vue-interface/form-control": "2.0.4"
|
|
47
48
|
},
|
|
48
49
|
"scripts": {
|
|
49
50
|
"dev": "vite",
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script setup lang="ts" generic="ModelValue, Value">
|
|
2
|
+
import { ActivityIndicator } from '@vue-interface/activity-indicator';
|
|
3
|
+
import type { FormControlEvents, FormControlProps, FormControlSlots } from '@vue-interface/form-control';
|
|
4
|
+
import { FormControlErrors, FormControlFeedback, useFormControl } from '@vue-interface/form-control';
|
|
5
|
+
import { InputHTMLAttributes, onMounted, ref, SelectHTMLAttributes, useSlots } from 'vue';
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<SelectFieldProps<ModelValue,Value>>(), {
|
|
8
|
+
formControlClass: 'form-select',
|
|
9
|
+
labelClass: 'form-label'
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
defineOptions({
|
|
13
|
+
inheritAttrs: false
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const model = defineModel<ModelValue>();
|
|
17
|
+
|
|
18
|
+
defineSlots<FormControlSlots<SelectFieldControlSizePrefix,ModelValue> & {
|
|
19
|
+
default: () => unknown
|
|
20
|
+
}>();
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits<FormControlEvents<ModelValue>>();
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
controlAttributes,
|
|
26
|
+
formGroupClasses,
|
|
27
|
+
listeners,
|
|
28
|
+
} = useFormControl<InputHTMLAttributes, SelectFieldControlSizePrefix, ModelValue, Value>({ model, props, emit });
|
|
29
|
+
|
|
30
|
+
const field = ref<HTMLSelectElement>();
|
|
31
|
+
|
|
32
|
+
function onMousedownLabel(e: MouseEvent) {
|
|
33
|
+
listeners.onClick(e);
|
|
34
|
+
|
|
35
|
+
field.value?.focus();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check the option slots for selected options. If the field has hardcoded
|
|
39
|
+
// selected options, this will ensure the value of the field is always set to
|
|
40
|
+
// the property. This will ensure the model is updated to the selected value.
|
|
41
|
+
onMounted(() => {
|
|
42
|
+
const slot = useSlots().default;
|
|
43
|
+
|
|
44
|
+
if(!slot) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for(const child of slot()) {
|
|
49
|
+
if(!child.props) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if('selected' in child.props && (child.props.value ?? child.children)) {
|
|
54
|
+
model.value = child.props.value ?? child.children;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<script lang="ts">
|
|
61
|
+
export type SelectFieldControlSizePrefix = 'form-select';
|
|
62
|
+
|
|
63
|
+
export type SelectFieldProps<ModelValue, Value> = FormControlProps<
|
|
64
|
+
SelectHTMLAttributes,
|
|
65
|
+
SelectFieldControlSizePrefix,
|
|
66
|
+
ModelValue,
|
|
67
|
+
Value
|
|
68
|
+
>;
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<template>
|
|
72
|
+
<div
|
|
73
|
+
class="select-field"
|
|
74
|
+
:class="formGroupClasses">
|
|
75
|
+
<slot name="label">
|
|
76
|
+
<label
|
|
77
|
+
v-if="label"
|
|
78
|
+
ref="label"
|
|
79
|
+
:for="controlAttributes.id"
|
|
80
|
+
:class="labelClass"
|
|
81
|
+
@mousedown="onMousedownLabel">
|
|
82
|
+
{{ label }}
|
|
83
|
+
</label>
|
|
84
|
+
</slot>
|
|
85
|
+
|
|
86
|
+
<div class="form-control-inner">
|
|
87
|
+
<slot
|
|
88
|
+
name="control"
|
|
89
|
+
v-bind="{ controlAttributes, listeners }">
|
|
90
|
+
<div
|
|
91
|
+
v-if="$slots.icon"
|
|
92
|
+
class="form-control-inner-icon"
|
|
93
|
+
@click="field?.focus()">
|
|
94
|
+
<slot name="icon" />
|
|
95
|
+
</div>
|
|
96
|
+
<select
|
|
97
|
+
ref="field"
|
|
98
|
+
v-model="model"
|
|
99
|
+
v-bind="{...controlAttributes, ...listeners}">
|
|
100
|
+
<slot />
|
|
101
|
+
</select>
|
|
102
|
+
</slot>
|
|
103
|
+
|
|
104
|
+
<div class="form-control-activity-indicator">
|
|
105
|
+
<slot name="activity">
|
|
106
|
+
<Transition name="select-field-fade">
|
|
107
|
+
<ActivityIndicator
|
|
108
|
+
v-if="activity && indicator"
|
|
109
|
+
key="activity"
|
|
110
|
+
ref="activity"
|
|
111
|
+
:type="indicator"
|
|
112
|
+
:size="indicatorSize" />
|
|
113
|
+
</Transition>
|
|
114
|
+
</slot>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<slot
|
|
119
|
+
name="errors"
|
|
120
|
+
v-bind="{ error, errors, id, name }">
|
|
121
|
+
<FormControlErrors
|
|
122
|
+
v-if="!!(error || errors)"
|
|
123
|
+
:id="id && String(id)"
|
|
124
|
+
v-slot="{ error }"
|
|
125
|
+
:name="name && String(name)"
|
|
126
|
+
:error="error"
|
|
127
|
+
:errors="errors">
|
|
128
|
+
<div
|
|
129
|
+
invalid
|
|
130
|
+
class="invalid-feedback">
|
|
131
|
+
{{ error }}<br>
|
|
132
|
+
</div>
|
|
133
|
+
</FormControlErrors>
|
|
134
|
+
</slot>
|
|
135
|
+
|
|
136
|
+
<slot
|
|
137
|
+
name="feedback"
|
|
138
|
+
v-bind="{ feedback }">
|
|
139
|
+
<FormControlFeedback
|
|
140
|
+
v-slot="{ feedback }"
|
|
141
|
+
:feedback="feedback">
|
|
142
|
+
<div
|
|
143
|
+
valid
|
|
144
|
+
class="valid-feedback">
|
|
145
|
+
{{ feedback }}
|
|
146
|
+
</div>
|
|
147
|
+
</FormControlFeedback>
|
|
148
|
+
</slot>
|
|
149
|
+
|
|
150
|
+
<slot
|
|
151
|
+
name="help"
|
|
152
|
+
v-bind="{ helpText }">
|
|
153
|
+
<small
|
|
154
|
+
v-if="helpText"
|
|
155
|
+
ref="help">
|
|
156
|
+
{{ helpText }}
|
|
157
|
+
</small>
|
|
158
|
+
</slot>
|
|
159
|
+
</div>
|
|
160
|
+
</template>
|