srcdev-nuxt-forms 6.1.0 → 6.1.1
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/app/components/forms/form-fieldset/FormFieldset.vue +19 -10
- package/app/components/forms/input-button/InputButtonCore.vue +25 -28
- package/app/components/forms/input-checkbox/MultipleCheckboxes.vue +48 -27
- package/app/components/forms/input-checkbox/SingleCheckbox.vue +52 -33
- package/app/components/forms/input-checkbox-radio/InputCheckboxRadioButton.vue +40 -22
- package/app/components/forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +33 -17
- package/app/components/forms/input-label/InputLabel.vue +10 -12
- package/app/components/forms/input-number/InputNumberCore.vue +26 -22
- package/app/components/forms/input-number/variants/InputNumberDefault.vue +50 -27
- package/app/components/forms/input-radio/MultipleRadiobuttons.vue +31 -25
- package/app/components/forms/input-range/InputRangeCore.vue +30 -28
- package/app/components/forms/input-range/variants/InputRangeDefault.vue +45 -28
- package/app/components/forms/input-range-fancy/InputRangeFancyWithLabel.vue +31 -18
- package/app/components/forms/input-select/variants/InputSelectWithLabel.vue +48 -37
- package/app/components/forms/input-text/InputTextCore.vue +4 -6
- package/app/components/forms/input-text/variants/InputTextAsNumberWithLabel.vue +42 -33
- package/app/components/forms/input-text/variants/InputTextWithLabel.vue +51 -42
- package/app/components/forms/input-textarea/InputTextareaCore.vue +29 -24
- package/app/components/forms/input-textarea/variants/InputTextareaWithLabel.vue +41 -31
- package/app/components/forms/toggle-switch/ToggleSwitchCore.vue +43 -25
- package/app/components/forms/toggle-switch/ToggleSwitchCoreOld.vue +36 -22
- package/app/components/forms/toggle-switch/variants/ToggleSwitchWithLabel.vue +42 -25
- package/app/components/forms/toggle-switch/variants/ToggleSwitchWithLabelInline.vue +30 -26
- package/package.json +1 -1
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div
|
|
4
|
-
|
|
3
|
+
<div
|
|
4
|
+
class="input-text-with-label"
|
|
5
|
+
:data-theme="formTheme"
|
|
6
|
+
:class="[elementClasses, inputVariant, { dirty: isDirty }, { active: isActive }]"
|
|
7
|
+
>
|
|
8
|
+
<InputLabel
|
|
9
|
+
:for="id"
|
|
10
|
+
:id
|
|
11
|
+
:theme
|
|
12
|
+
:name
|
|
13
|
+
:input-variant
|
|
14
|
+
:field-has-error
|
|
15
|
+
:style-class-passthrough="['input-text-label']"
|
|
16
|
+
>
|
|
5
17
|
<template #textLabel>{{ label }}</template>
|
|
6
18
|
</InputLabel>
|
|
7
19
|
|
|
8
|
-
<div v-if="inputVariant === 'normal' &&
|
|
20
|
+
<div v-if="inputVariant === 'normal' && slots.description" :id="`${id}-description`">
|
|
9
21
|
<slot name="description"></slot>
|
|
10
22
|
</div>
|
|
11
23
|
|
|
@@ -29,10 +41,10 @@
|
|
|
29
41
|
:size
|
|
30
42
|
:inputVariant
|
|
31
43
|
>
|
|
32
|
-
<template v-if="
|
|
44
|
+
<template v-if="slots.left" #left>
|
|
33
45
|
<slot name="left"></slot>
|
|
34
46
|
</template>
|
|
35
|
-
<template v-if="
|
|
47
|
+
<template v-if="slots.right" #right>
|
|
36
48
|
<slot name="right"></slot>
|
|
37
49
|
</template>
|
|
38
50
|
</InputTextCore>
|
|
@@ -40,28 +52,28 @@
|
|
|
40
52
|
<InputError :errorMessage :showError="fieldHasError" :id="errorId" :isDetached="false" :inputVariant />
|
|
41
53
|
</div>
|
|
42
54
|
|
|
43
|
-
<div v-if="inputVariant !== 'normal' &&
|
|
55
|
+
<div v-if="inputVariant !== 'normal' && slots.description" :id="`${id}-description`">
|
|
44
56
|
<slot name="description"></slot>
|
|
45
57
|
</div>
|
|
46
58
|
</div>
|
|
47
59
|
</template>
|
|
48
60
|
|
|
49
61
|
<script setup lang="ts">
|
|
50
|
-
import propValidators from
|
|
62
|
+
import propValidators from "../../c12/prop-validators"
|
|
51
63
|
const props = defineProps({
|
|
52
64
|
maxlength: {
|
|
53
65
|
type: Number,
|
|
54
66
|
default: 255,
|
|
55
67
|
},
|
|
56
68
|
type: {
|
|
57
|
-
type: String as PropType<
|
|
69
|
+
type: String as PropType<"text" | "email" | "password" | "number" | "tel" | "url">,
|
|
58
70
|
required: true,
|
|
59
71
|
},
|
|
60
72
|
inputmode: {
|
|
61
|
-
type: String as PropType<
|
|
62
|
-
default:
|
|
73
|
+
type: String as PropType<"text" | "email" | "tel" | "url" | "search" | "numeric" | "none" | "decimal">,
|
|
74
|
+
default: "text",
|
|
63
75
|
validator(value: string) {
|
|
64
|
-
return propValidators.inputMode.includes(value)
|
|
76
|
+
return propValidators.inputMode.includes(value)
|
|
65
77
|
},
|
|
66
78
|
},
|
|
67
79
|
name: {
|
|
@@ -70,7 +82,7 @@ const props = defineProps({
|
|
|
70
82
|
},
|
|
71
83
|
placeholder: {
|
|
72
84
|
type: String,
|
|
73
|
-
default:
|
|
85
|
+
default: "",
|
|
74
86
|
},
|
|
75
87
|
label: {
|
|
76
88
|
type: String,
|
|
@@ -94,65 +106,62 @@ const props = defineProps({
|
|
|
94
106
|
},
|
|
95
107
|
theme: {
|
|
96
108
|
type: String as PropType<string>,
|
|
97
|
-
default:
|
|
109
|
+
default: "primary",
|
|
98
110
|
validator(value: string) {
|
|
99
|
-
return propValidators.theme.includes(value)
|
|
111
|
+
return propValidators.theme.includes(value)
|
|
100
112
|
},
|
|
101
113
|
},
|
|
102
114
|
size: {
|
|
103
115
|
type: String as PropType<string>,
|
|
104
|
-
default:
|
|
116
|
+
default: "default",
|
|
105
117
|
validator(value: string) {
|
|
106
|
-
return propValidators.size.includes(value)
|
|
118
|
+
return propValidators.size.includes(value)
|
|
107
119
|
},
|
|
108
120
|
},
|
|
109
121
|
inputVariant: {
|
|
110
122
|
type: String as PropType<string>,
|
|
111
|
-
default:
|
|
123
|
+
default: "normal",
|
|
112
124
|
validator(value: string) {
|
|
113
|
-
return propValidators.inputVariant.includes(value)
|
|
125
|
+
return propValidators.inputVariant.includes(value)
|
|
114
126
|
},
|
|
115
127
|
},
|
|
116
|
-
})
|
|
128
|
+
})
|
|
117
129
|
|
|
118
|
-
const slots = useSlots()
|
|
119
|
-
const hasDescriptionSlot = computed(() => slots.description !== undefined);
|
|
120
|
-
const hasLeftSlot = computed(() => slots.left !== undefined);
|
|
121
|
-
const hasRightSlot = computed(() => slots.right !== undefined);
|
|
130
|
+
const slots = useSlots()
|
|
122
131
|
|
|
123
132
|
const formTheme = computed(() => {
|
|
124
|
-
return props.fieldHasError ?
|
|
125
|
-
})
|
|
133
|
+
return props.fieldHasError ? "error" : props.theme
|
|
134
|
+
})
|
|
126
135
|
|
|
127
|
-
const id = `${props.name}-${useId()}
|
|
128
|
-
const errorId = `${id}-error-message
|
|
136
|
+
const id = `${props.name}-${useId()}`
|
|
137
|
+
const errorId = `${id}-error-message`
|
|
129
138
|
const ariaDescribedby = computed(() => {
|
|
130
|
-
const ariaDescribedbyId =
|
|
131
|
-
return props.fieldHasError ? errorId : ariaDescribedbyId
|
|
132
|
-
})
|
|
139
|
+
const ariaDescribedbyId = slots.description ? `${id}-description` : undefined
|
|
140
|
+
return props.fieldHasError ? errorId : ariaDescribedbyId
|
|
141
|
+
})
|
|
133
142
|
|
|
134
|
-
const modelValue = defineModel()
|
|
135
|
-
const isActive = ref<boolean>(false)
|
|
136
|
-
const isDirty = ref<boolean>(false)
|
|
143
|
+
const modelValue = defineModel()
|
|
144
|
+
const isActive = ref<boolean>(false)
|
|
145
|
+
const isDirty = ref<boolean>(false)
|
|
137
146
|
|
|
138
|
-
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
147
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
139
148
|
|
|
140
149
|
const testDirty = () => {
|
|
141
|
-
const watchValue = modelValue.value ??
|
|
150
|
+
const watchValue = modelValue.value ?? ""
|
|
142
151
|
|
|
143
|
-
if (!isDirty.value && typeof watchValue ===
|
|
144
|
-
isDirty.value = true
|
|
152
|
+
if (!isDirty.value && typeof watchValue === "string" && watchValue.length > 0) {
|
|
153
|
+
isDirty.value = true
|
|
145
154
|
}
|
|
146
|
-
}
|
|
155
|
+
}
|
|
147
156
|
|
|
148
157
|
onMounted(() => {
|
|
149
|
-
testDirty()
|
|
150
|
-
})
|
|
158
|
+
testDirty()
|
|
159
|
+
})
|
|
151
160
|
|
|
152
161
|
watch(
|
|
153
162
|
() => modelValue.value,
|
|
154
163
|
() => {
|
|
155
|
-
testDirty()
|
|
164
|
+
testDirty()
|
|
156
165
|
}
|
|
157
|
-
)
|
|
166
|
+
)
|
|
158
167
|
</script>
|
|
@@ -3,9 +3,16 @@
|
|
|
3
3
|
class="input-textarea-wrapper"
|
|
4
4
|
:data-theme="formTheme"
|
|
5
5
|
:data-size="size"
|
|
6
|
-
:class="[
|
|
6
|
+
:class="[
|
|
7
|
+
inputVariant,
|
|
8
|
+
{ dirty: isDirty },
|
|
9
|
+
{ active: isActive },
|
|
10
|
+
{ error: fieldHasError },
|
|
11
|
+
{ 'has-left-slot': slots.left },
|
|
12
|
+
{ 'has-right-slot': slots.right },
|
|
13
|
+
]"
|
|
7
14
|
>
|
|
8
|
-
<span v-if="
|
|
15
|
+
<span v-if="slots.left" class="slot left-slot">
|
|
9
16
|
<slot name="left"></slot>
|
|
10
17
|
</span>
|
|
11
18
|
|
|
@@ -24,14 +31,14 @@
|
|
|
24
31
|
@focusout="updateFocus(false)"
|
|
25
32
|
></textarea>
|
|
26
33
|
|
|
27
|
-
<span v-if="
|
|
34
|
+
<span v-if="slots.right" class="slot right-slot">
|
|
28
35
|
<slot name="right"></slot>
|
|
29
36
|
</span>
|
|
30
37
|
</div>
|
|
31
38
|
</template>
|
|
32
39
|
|
|
33
40
|
<script setup lang="ts">
|
|
34
|
-
import propValidators from
|
|
41
|
+
import propValidators from "../c12/prop-validators"
|
|
35
42
|
const props = defineProps({
|
|
36
43
|
maxlength: {
|
|
37
44
|
type: Number,
|
|
@@ -47,7 +54,7 @@ const props = defineProps({
|
|
|
47
54
|
},
|
|
48
55
|
placeholder: {
|
|
49
56
|
type: String,
|
|
50
|
-
default:
|
|
57
|
+
default: "",
|
|
51
58
|
},
|
|
52
59
|
fieldHasError: {
|
|
53
60
|
type: Boolean,
|
|
@@ -63,46 +70,44 @@ const props = defineProps({
|
|
|
63
70
|
},
|
|
64
71
|
theme: {
|
|
65
72
|
type: String as PropType<string>,
|
|
66
|
-
default:
|
|
73
|
+
default: "primary",
|
|
67
74
|
validator(value: string) {
|
|
68
|
-
return propValidators.theme.includes(value)
|
|
75
|
+
return propValidators.theme.includes(value)
|
|
69
76
|
},
|
|
70
77
|
},
|
|
71
78
|
size: {
|
|
72
79
|
type: String as PropType<string>,
|
|
73
|
-
default:
|
|
80
|
+
default: "default",
|
|
74
81
|
validator(value: string) {
|
|
75
|
-
return propValidators.size.includes(value)
|
|
82
|
+
return propValidators.size.includes(value)
|
|
76
83
|
},
|
|
77
84
|
},
|
|
78
85
|
inputVariant: {
|
|
79
86
|
type: String as PropType<string>,
|
|
80
|
-
default:
|
|
87
|
+
default: "normal",
|
|
81
88
|
validator(value: string) {
|
|
82
|
-
return propValidators.inputVariant.includes(value)
|
|
89
|
+
return propValidators.inputVariant.includes(value)
|
|
83
90
|
},
|
|
84
91
|
},
|
|
85
|
-
})
|
|
92
|
+
})
|
|
86
93
|
|
|
87
|
-
const slots = useSlots()
|
|
88
|
-
const hasLeftSlot = computed(() => slots.left !== undefined);
|
|
89
|
-
const hasRightSlot = computed(() => slots.right !== undefined);
|
|
94
|
+
const slots = useSlots()
|
|
90
95
|
|
|
91
96
|
const formTheme = computed(() => {
|
|
92
|
-
return props.fieldHasError ?
|
|
93
|
-
})
|
|
97
|
+
return props.fieldHasError ? "error" : props.theme
|
|
98
|
+
})
|
|
94
99
|
|
|
95
|
-
const modelValue = defineModel<string | number | readonly string[] | null | undefined>()
|
|
96
|
-
const isDirty = defineModel(
|
|
97
|
-
const isActive = defineModel(
|
|
100
|
+
const modelValue = defineModel<string | number | readonly string[] | null | undefined>()
|
|
101
|
+
const isDirty = defineModel("isDirty")
|
|
102
|
+
const isActive = defineModel("isActive")
|
|
98
103
|
|
|
99
104
|
const updateFocus = (isFocused: boolean) => {
|
|
100
|
-
isActive.value = isFocused
|
|
101
|
-
}
|
|
105
|
+
isActive.value = isFocused
|
|
106
|
+
}
|
|
102
107
|
|
|
103
|
-
const inputField = ref<HTMLInputElement | null>(null)
|
|
108
|
+
const inputField = ref<HTMLInputElement | null>(null)
|
|
104
109
|
|
|
105
|
-
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
110
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
106
111
|
</script>
|
|
107
112
|
|
|
108
113
|
<style lang="css">
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
2
|
+
<div
|
|
3
|
+
class="input-textarea-with-label"
|
|
4
|
+
:data-theme="formTheme"
|
|
5
|
+
:class="[elementClasses, inputVariant, { dirty: isDirty }, { active: isActive }]"
|
|
6
|
+
>
|
|
7
|
+
<InputLabel
|
|
8
|
+
:for="id"
|
|
9
|
+
:id
|
|
10
|
+
:theme
|
|
11
|
+
:name
|
|
12
|
+
:input-variant
|
|
13
|
+
:field-has-error
|
|
14
|
+
:style-class-passthrough="['input-textarea-label']"
|
|
15
|
+
>
|
|
4
16
|
<template #textLabel>{{ label }}</template>
|
|
5
17
|
</InputLabel>
|
|
6
18
|
|
|
@@ -20,10 +32,10 @@
|
|
|
20
32
|
:size
|
|
21
33
|
:inputVariant
|
|
22
34
|
>
|
|
23
|
-
<template v-if="
|
|
35
|
+
<template v-if="slots.left" #left>
|
|
24
36
|
<slot name="left"></slot>
|
|
25
37
|
</template>
|
|
26
|
-
<template v-if="
|
|
38
|
+
<template v-if="slots.right" #right>
|
|
27
39
|
<slot name="right"></slot>
|
|
28
40
|
</template>
|
|
29
41
|
</InputTextareaCore>
|
|
@@ -32,7 +44,7 @@
|
|
|
32
44
|
</template>
|
|
33
45
|
|
|
34
46
|
<script setup lang="ts">
|
|
35
|
-
import propValidators from
|
|
47
|
+
import propValidators from "../../c12/prop-validators"
|
|
36
48
|
const props = defineProps({
|
|
37
49
|
maxlength: {
|
|
38
50
|
type: Number,
|
|
@@ -44,7 +56,7 @@ const props = defineProps({
|
|
|
44
56
|
},
|
|
45
57
|
placeholder: {
|
|
46
58
|
type: String,
|
|
47
|
-
default:
|
|
59
|
+
default: "",
|
|
48
60
|
},
|
|
49
61
|
label: {
|
|
50
62
|
type: String,
|
|
@@ -68,58 +80,56 @@ const props = defineProps({
|
|
|
68
80
|
},
|
|
69
81
|
theme: {
|
|
70
82
|
type: String as PropType<string>,
|
|
71
|
-
default:
|
|
83
|
+
default: "primary",
|
|
72
84
|
validator(value: string) {
|
|
73
|
-
return propValidators.theme.includes(value)
|
|
85
|
+
return propValidators.theme.includes(value)
|
|
74
86
|
},
|
|
75
87
|
},
|
|
76
88
|
size: {
|
|
77
89
|
type: String as PropType<string>,
|
|
78
|
-
default:
|
|
90
|
+
default: "default",
|
|
79
91
|
validator(value: string) {
|
|
80
|
-
return propValidators.size.includes(value)
|
|
92
|
+
return propValidators.size.includes(value)
|
|
81
93
|
},
|
|
82
94
|
},
|
|
83
95
|
inputVariant: {
|
|
84
96
|
type: String as PropType<string>,
|
|
85
|
-
default:
|
|
97
|
+
default: "normal",
|
|
86
98
|
validator(value: string) {
|
|
87
|
-
return propValidators.inputVariant.includes(value)
|
|
99
|
+
return propValidators.inputVariant.includes(value)
|
|
88
100
|
},
|
|
89
101
|
},
|
|
90
|
-
})
|
|
102
|
+
})
|
|
91
103
|
|
|
92
|
-
const slots = useSlots()
|
|
93
|
-
const hasLeftSlot = computed(() => slots.left !== undefined);
|
|
94
|
-
const hasRightSlot = computed(() => slots.right !== undefined);
|
|
104
|
+
const slots = useSlots()
|
|
95
105
|
|
|
96
|
-
const id = useId()
|
|
106
|
+
const id = useId()
|
|
97
107
|
const formTheme = computed(() => {
|
|
98
|
-
return props.fieldHasError ?
|
|
99
|
-
})
|
|
108
|
+
return props.fieldHasError ? "error" : props.theme
|
|
109
|
+
})
|
|
100
110
|
|
|
101
|
-
const modelValue = defineModel<string | number | readonly string[] | null | undefined>()
|
|
102
|
-
const isActive = ref<boolean>(false)
|
|
103
|
-
const isDirty = ref<boolean>(false)
|
|
111
|
+
const modelValue = defineModel<string | number | readonly string[] | null | undefined>()
|
|
112
|
+
const isActive = ref<boolean>(false)
|
|
113
|
+
const isDirty = ref<boolean>(false)
|
|
104
114
|
|
|
105
|
-
const { elementClasses
|
|
115
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
106
116
|
|
|
107
117
|
const testDirty = () => {
|
|
108
|
-
const watchValue = modelValue.value ??
|
|
118
|
+
const watchValue = modelValue.value ?? ""
|
|
109
119
|
|
|
110
|
-
if (!isDirty.value && typeof watchValue ===
|
|
111
|
-
isDirty.value = true
|
|
120
|
+
if (!isDirty.value && typeof watchValue === "string" && watchValue.length > 0) {
|
|
121
|
+
isDirty.value = true
|
|
112
122
|
}
|
|
113
|
-
}
|
|
123
|
+
}
|
|
114
124
|
|
|
115
125
|
onMounted(() => {
|
|
116
|
-
testDirty()
|
|
117
|
-
})
|
|
126
|
+
testDirty()
|
|
127
|
+
})
|
|
118
128
|
|
|
119
129
|
watch(
|
|
120
130
|
() => modelValue.value,
|
|
121
131
|
() => {
|
|
122
|
-
testDirty()
|
|
132
|
+
testDirty()
|
|
123
133
|
}
|
|
124
|
-
)
|
|
134
|
+
)
|
|
125
135
|
</script>
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="toggle-switch-core" :class="elementClasses" :data-size="size" :data-theme="formTheme">
|
|
3
|
-
<div
|
|
4
|
-
|
|
3
|
+
<div
|
|
4
|
+
@click="toggleSwitchValue"
|
|
5
|
+
class="toggle-switch-wrapper"
|
|
6
|
+
:class="[{ round }, { 'use-default-icons': useDefaultIcons }]"
|
|
7
|
+
:for="inputId"
|
|
8
|
+
>
|
|
9
|
+
<input
|
|
10
|
+
type="checkbox"
|
|
11
|
+
v-model="modelValue"
|
|
12
|
+
:true-value
|
|
13
|
+
:false-value
|
|
14
|
+
:aria-invalid="fieldHasError"
|
|
15
|
+
:id="inputId"
|
|
16
|
+
:aria-describedby="`${id}-description`"
|
|
17
|
+
:name
|
|
18
|
+
:required
|
|
19
|
+
:checked="isChecked"
|
|
20
|
+
/>
|
|
5
21
|
<div class="symbol-wrapper" :class="[{ round }]">
|
|
6
22
|
<div class="symbol" :class="[{ round }]">
|
|
7
23
|
<div class="symbol-icon icon-on">
|
|
@@ -22,7 +38,7 @@
|
|
|
22
38
|
</template>
|
|
23
39
|
|
|
24
40
|
<script setup lang="ts">
|
|
25
|
-
import propValidators from
|
|
41
|
+
import propValidators from "../c12/prop-validators"
|
|
26
42
|
|
|
27
43
|
const props = defineProps({
|
|
28
44
|
id: {
|
|
@@ -55,9 +71,9 @@ const props = defineProps({
|
|
|
55
71
|
},
|
|
56
72
|
theme: {
|
|
57
73
|
type: String as PropType<string>,
|
|
58
|
-
default:
|
|
74
|
+
default: "primary",
|
|
59
75
|
validator(value: string) {
|
|
60
|
-
return propValidators.theme.includes(value)
|
|
76
|
+
return propValidators.theme.includes(value)
|
|
61
77
|
},
|
|
62
78
|
},
|
|
63
79
|
round: {
|
|
@@ -66,39 +82,36 @@ const props = defineProps({
|
|
|
66
82
|
},
|
|
67
83
|
size: {
|
|
68
84
|
type: String as PropType<string>,
|
|
69
|
-
default:
|
|
85
|
+
default: "default",
|
|
70
86
|
validator(value: string) {
|
|
71
|
-
return propValidators.size.includes(value)
|
|
87
|
+
return propValidators.size.includes(value)
|
|
72
88
|
},
|
|
73
89
|
},
|
|
74
90
|
ariaDescribedby: {
|
|
75
91
|
type: String,
|
|
76
92
|
default: null,
|
|
77
93
|
},
|
|
78
|
-
})
|
|
94
|
+
})
|
|
79
95
|
|
|
80
|
-
const slots = useSlots()
|
|
81
|
-
const
|
|
82
|
-
const hasIconOffSlot = computed(() => slots.iconOff !== undefined);
|
|
83
|
-
const useDefaultIcons = computed(() => !hasIconOnSlot.value && !hasIconOffSlot.value);
|
|
96
|
+
const slots = useSlots()
|
|
97
|
+
const useDefaultIcons = computed(() => !slots.iconOn && !slots.iconOff)
|
|
84
98
|
|
|
85
99
|
const formTheme = computed(() => {
|
|
86
|
-
return props.fieldHasError ?
|
|
87
|
-
})
|
|
100
|
+
return props.fieldHasError ? "error" : props.theme
|
|
101
|
+
})
|
|
88
102
|
|
|
89
|
-
const modelValue = defineModel()
|
|
90
|
-
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
103
|
+
const modelValue = defineModel()
|
|
104
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
91
105
|
|
|
92
|
-
const inputId = computed(() => `toggle-sitch-${props.id}`)
|
|
106
|
+
const inputId = computed(() => `toggle-sitch-${props.id}`)
|
|
93
107
|
|
|
94
108
|
const isChecked = computed(() => {
|
|
95
|
-
return modelValue.value === props.trueValue
|
|
96
|
-
})
|
|
109
|
+
return modelValue.value === props.trueValue
|
|
110
|
+
})
|
|
97
111
|
|
|
98
112
|
const toggleSwitchValue = () => {
|
|
99
|
-
modelValue.value = modelValue.value === props.trueValue ? props.falseValue : props.trueValue
|
|
100
|
-
|
|
101
|
-
};
|
|
113
|
+
modelValue.value = modelValue.value === props.trueValue ? props.falseValue : props.trueValue
|
|
114
|
+
}
|
|
102
115
|
</script>
|
|
103
116
|
|
|
104
117
|
<style lang="css">
|
|
@@ -149,16 +162,21 @@ const toggleSwitchValue = () => {
|
|
|
149
162
|
/* background: blue; */
|
|
150
163
|
border: var(--theme-form-toggle-border-width) solid var(--theme-form-toggle-border-color);
|
|
151
164
|
outline: var(--theme-form-toggle-outline-width) solid var(--theme-form-toggle-outline-color);
|
|
152
|
-
border-radius: calc(
|
|
165
|
+
border-radius: calc(
|
|
166
|
+
var(--_symbol-size) + calc(var(--theme-form-toggle-border-width) * 2) + calc(var(--_switch-padding) * 2)
|
|
167
|
+
);
|
|
153
168
|
display: inline-flex;
|
|
154
169
|
align-items: center;
|
|
155
170
|
justify-content: start;
|
|
156
|
-
width: calc(
|
|
171
|
+
width: calc(
|
|
172
|
+
var(--_symbol-size) + var(--_symbol-checked-offset) + calc(var(--theme-form-toggle-border-width) * 2) +
|
|
173
|
+
calc(var(--_switch-padding) * 2)
|
|
174
|
+
);
|
|
157
175
|
padding: var(--_switch-padding);
|
|
158
176
|
|
|
159
177
|
.symbol {
|
|
160
178
|
display: inline-grid;
|
|
161
|
-
grid-template-areas:
|
|
179
|
+
grid-template-areas: "icon";
|
|
162
180
|
place-content: center;
|
|
163
181
|
|
|
164
182
|
aspect-ratio: 1/1;
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="toggle-switch-core" :class="elementClasses" :data-size="size" :data-theme="formTheme">
|
|
3
3
|
<div @click="toggleSwitchValue" class="toggle-switch-input" :class="[{ round }]" :for="inputId">
|
|
4
|
-
<input
|
|
4
|
+
<input
|
|
5
|
+
type="checkbox"
|
|
6
|
+
v-model="modelValue"
|
|
7
|
+
:true-value
|
|
8
|
+
:false-value
|
|
9
|
+
:aria-invalid="fieldHasError"
|
|
10
|
+
:id="inputId"
|
|
11
|
+
:aria-describedby="`${id}-description`"
|
|
12
|
+
:name
|
|
13
|
+
:required
|
|
14
|
+
/>
|
|
5
15
|
<div class="symbol-wrapper" :class="[{ round }]">
|
|
6
16
|
<div class="symbol" :class="[{ round }]">
|
|
7
|
-
<div v-if="
|
|
17
|
+
<div v-if="slots.iconOn" class="symbol-icon icon-on">
|
|
8
18
|
<slot name="iconOn"></slot>
|
|
9
19
|
</div>
|
|
10
20
|
|
|
11
|
-
<div v-if="
|
|
21
|
+
<div v-if="slots.iconOff" class="symbol-icon icon-off">
|
|
12
22
|
<slot name="iconOff"></slot>
|
|
13
23
|
</div>
|
|
14
24
|
</div>
|
|
@@ -18,7 +28,7 @@
|
|
|
18
28
|
</template>
|
|
19
29
|
|
|
20
30
|
<script setup lang="ts">
|
|
21
|
-
import propValidators from
|
|
31
|
+
import propValidators from "../c12/prop-validators"
|
|
22
32
|
|
|
23
33
|
const props = defineProps({
|
|
24
34
|
id: {
|
|
@@ -51,9 +61,9 @@ const props = defineProps({
|
|
|
51
61
|
},
|
|
52
62
|
theme: {
|
|
53
63
|
type: String as PropType<string>,
|
|
54
|
-
default:
|
|
64
|
+
default: "primary",
|
|
55
65
|
validator(value: string) {
|
|
56
|
-
return propValidators.theme.includes(value)
|
|
66
|
+
return propValidators.theme.includes(value)
|
|
57
67
|
},
|
|
58
68
|
},
|
|
59
69
|
round: {
|
|
@@ -62,33 +72,31 @@ const props = defineProps({
|
|
|
62
72
|
},
|
|
63
73
|
size: {
|
|
64
74
|
type: String as PropType<string>,
|
|
65
|
-
default:
|
|
75
|
+
default: "default",
|
|
66
76
|
validator(value: string) {
|
|
67
|
-
return propValidators.size.includes(value)
|
|
77
|
+
return propValidators.size.includes(value)
|
|
68
78
|
},
|
|
69
79
|
},
|
|
70
80
|
ariaDescribedby: {
|
|
71
81
|
type: String,
|
|
72
82
|
default: null,
|
|
73
83
|
},
|
|
74
|
-
})
|
|
84
|
+
})
|
|
75
85
|
|
|
76
|
-
const slots = useSlots()
|
|
77
|
-
const hasIconOnSlot = computed(() => slots.iconOn !== undefined);
|
|
78
|
-
const hasIconOffSlot = computed(() => slots.iconOff !== undefined);
|
|
86
|
+
const slots = useSlots()
|
|
79
87
|
|
|
80
88
|
const formTheme = computed(() => {
|
|
81
|
-
return props.fieldHasError ?
|
|
82
|
-
})
|
|
89
|
+
return props.fieldHasError ? "error" : props.theme
|
|
90
|
+
})
|
|
83
91
|
|
|
84
|
-
const modelValue = defineModel()
|
|
85
|
-
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
92
|
+
const modelValue = defineModel()
|
|
93
|
+
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
86
94
|
|
|
87
|
-
const inputId = computed(() => `toggle-sitch-${props.id}`)
|
|
95
|
+
const inputId = computed(() => `toggle-sitch-${props.id}`)
|
|
88
96
|
|
|
89
97
|
const toggleSwitchValue = () => {
|
|
90
|
-
modelValue.value = modelValue.value === props.trueValue ? props.falseValue : props.trueValue
|
|
91
|
-
}
|
|
98
|
+
modelValue.value = modelValue.value === props.trueValue ? props.falseValue : props.trueValue
|
|
99
|
+
}
|
|
92
100
|
</script>
|
|
93
101
|
|
|
94
102
|
<style lang="css">
|
|
@@ -102,8 +110,14 @@ const toggleSwitchValue = () => {
|
|
|
102
110
|
.toggle-switch-input {
|
|
103
111
|
position: relative;
|
|
104
112
|
display: inline-block;
|
|
105
|
-
height: calc(
|
|
106
|
-
|
|
113
|
+
height: calc(
|
|
114
|
+
var(--form-toggle-symbol-size) + calc(var(--form-element-border-width) * 2) +
|
|
115
|
+
calc(var(--form-element-outline-width) * 2)
|
|
116
|
+
);
|
|
117
|
+
width: calc(
|
|
118
|
+
var(--form-toggle-symbol-size) * 2 - calc(var(--form-element-border-width) * 2) +
|
|
119
|
+
calc(var(--form-element-outline-width) * 2) + var(--form-toggle-switch-width-adjustment)
|
|
120
|
+
);
|
|
107
121
|
|
|
108
122
|
input {
|
|
109
123
|
opacity: 0;
|
|
@@ -126,7 +140,7 @@ const toggleSwitchValue = () => {
|
|
|
126
140
|
|
|
127
141
|
.symbol {
|
|
128
142
|
display: grid;
|
|
129
|
-
grid-template-areas:
|
|
143
|
+
grid-template-areas: "icon-stack";
|
|
130
144
|
overflow: clip;
|
|
131
145
|
position: absolute;
|
|
132
146
|
|