vueless 0.0.557 → 0.0.558
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 +1 -1
- package/types.ts +6 -0
- package/ui.form-label/ULabel.vue +68 -142
- package/ui.form-label/storybook/Docs.mdx +2 -2
- package/ui.form-label/storybook/{stories.js → stories.ts} +22 -7
- package/ui.form-label/types.ts +55 -0
- package/ui.form-label/useAttrs.ts +20 -0
- package/ui.form-switch/USwitch.vue +57 -143
- package/ui.form-switch/storybook/Docs.mdx +2 -2
- package/ui.form-switch/storybook/{stories.js → stories.ts} +12 -5
- package/ui.form-switch/types.ts +88 -0
- package/ui.form-switch/useAttrs.ts +28 -0
- package/ui.form-textarea/UTextarea.vue +100 -206
- package/ui.form-textarea/{config.js → config.ts} +2 -2
- package/ui.form-textarea/storybook/Docs.mdx +2 -2
- package/ui.form-textarea/storybook/{stories.js → stories.ts} +14 -6
- package/ui.form-textarea/types.ts +85 -0
- package/ui.form-textarea/useAttrs.ts +21 -0
- package/web-types.json +72 -43
- package/ui.form-label/useAttrs.js +0 -14
- package/ui.form-switch/useAttrs.js +0 -14
- package/ui.form-switch/utilVariant.js +0 -31
- package/ui.form-textarea/useAttrs.js +0 -15
- /package/ui.form-label/{config.js → config.ts} +0 -0
- /package/ui.form-label/{constants.js → constants.ts} +0 -0
- /package/ui.form-switch/{config.js → config.ts} +0 -0
- /package/ui.form-switch/{constants.js → constants.ts} +0 -0
- /package/ui.form-textarea/{constants.js → constants.ts} +0 -0
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -43,6 +43,9 @@ import UCheckboxGroupConfig from "./ui.form-checkbox-group/config.ts";
|
|
|
43
43
|
import UCheckboxMultiStateConfig from "./ui.form-checkbox-multi-state/config.ts";
|
|
44
44
|
import URadioConfig from "./ui.form-radio/config.ts";
|
|
45
45
|
import URadioGroupConfig from "./ui.form-radio-group/config.ts";
|
|
46
|
+
import USwitchConfig from "./ui.form-switch/config.ts";
|
|
47
|
+
import UTextareaConfig from "./ui.form-textarea/config.ts";
|
|
48
|
+
import ULabelConfig from "./ui.form-label/config.ts";
|
|
46
49
|
|
|
47
50
|
import type { ComputedRef, MaybeRef, Ref, UnwrapRef } from "vue";
|
|
48
51
|
import type { Props } from "tippy.js";
|
|
@@ -201,6 +204,9 @@ export interface Components {
|
|
|
201
204
|
UCheckboxMultiState?: Partial<typeof UCheckboxMultiStateConfig>;
|
|
202
205
|
URadio?: Partial<typeof URadioConfig>;
|
|
203
206
|
URadioGroup?: Partial<typeof URadioGroupConfig>;
|
|
207
|
+
USwitch?: Partial<typeof USwitchConfig>;
|
|
208
|
+
UTextarea?: Partial<typeof UTextareaConfig>;
|
|
209
|
+
ULabel?: Partial<typeof ULabelConfig>;
|
|
204
210
|
}
|
|
205
211
|
|
|
206
212
|
export interface Directives {
|
package/ui.form-label/ULabel.vue
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
|
|
4
|
+
import { getDefault } from "../utils/ui.ts";
|
|
5
|
+
|
|
6
|
+
import defaultConfig from "./config.ts";
|
|
7
|
+
import { ULabel, PLACEMENT } from "./constants.ts";
|
|
8
|
+
import useAttrs from "./useAttrs.ts";
|
|
9
|
+
|
|
10
|
+
import type { ULabelProps } from "./types.ts";
|
|
11
|
+
|
|
12
|
+
defineOptions({ inheritAttrs: false });
|
|
13
|
+
|
|
14
|
+
const props = withDefaults(defineProps<ULabelProps>(), {
|
|
15
|
+
align: getDefault<ULabelProps>(defaultConfig, ULabel).align,
|
|
16
|
+
size: getDefault<ULabelProps>(defaultConfig, ULabel).size,
|
|
17
|
+
disabled: getDefault<ULabelProps>(defaultConfig, ULabel).disabled,
|
|
18
|
+
centred: getDefault<ULabelProps>(defaultConfig, ULabel).centred,
|
|
19
|
+
dataTest: "",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits([
|
|
23
|
+
/**
|
|
24
|
+
* Triggers when the label is clicked.
|
|
25
|
+
*/
|
|
26
|
+
"click",
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
const labelRef = ref(null);
|
|
30
|
+
const wrapperRef = ref(null);
|
|
31
|
+
|
|
32
|
+
const { wrapperAttrs, contentAttrs, labelAttrs, descriptionAttrs } = useAttrs(props);
|
|
33
|
+
|
|
34
|
+
const isHorizontalPlacement = computed(() => {
|
|
35
|
+
return props.align === PLACEMENT.left || props.align === PLACEMENT.right;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const isTopWithDescPlacement = computed(() => {
|
|
39
|
+
return props.align === PLACEMENT.topWithDesc;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const labelElement = computed(() => {
|
|
43
|
+
return labelRef.value;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const wrapperElement = computed(() => {
|
|
47
|
+
return wrapperRef.value;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
function onClick(event: MouseEvent) {
|
|
51
|
+
emit("click", event);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
defineExpose({
|
|
55
|
+
/**
|
|
56
|
+
* Reference to the label element.
|
|
57
|
+
* @property {HTMLElement}
|
|
58
|
+
*/
|
|
59
|
+
labelElement,
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Reference to the wrapper element containing the label and content.
|
|
63
|
+
* @property {HTMLElement}
|
|
64
|
+
*/
|
|
65
|
+
wrapperElement,
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
1
69
|
<template>
|
|
2
70
|
<div
|
|
3
71
|
v-if="isHorizontalPlacement || isTopWithDescPlacement"
|
|
@@ -62,145 +130,3 @@
|
|
|
62
130
|
<slot name="bottom" />
|
|
63
131
|
</div>
|
|
64
132
|
</template>
|
|
65
|
-
|
|
66
|
-
<script setup>
|
|
67
|
-
import { computed, ref } from "vue";
|
|
68
|
-
|
|
69
|
-
import { getDefault } from "../utils/ui.ts";
|
|
70
|
-
|
|
71
|
-
import defaultConfig from "./config.js";
|
|
72
|
-
import { ULabel, PLACEMENT } from "./constants.js";
|
|
73
|
-
import useAttrs from "./useAttrs.js";
|
|
74
|
-
|
|
75
|
-
defineOptions({ inheritAttrs: false });
|
|
76
|
-
|
|
77
|
-
const emit = defineEmits([
|
|
78
|
-
/**
|
|
79
|
-
* Triggers when the label is clicked.
|
|
80
|
-
*/
|
|
81
|
-
"click",
|
|
82
|
-
]);
|
|
83
|
-
|
|
84
|
-
const props = defineProps({
|
|
85
|
-
/**
|
|
86
|
-
* Label text.
|
|
87
|
-
*/
|
|
88
|
-
label: {
|
|
89
|
-
type: String,
|
|
90
|
-
default: "",
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Label description.
|
|
95
|
-
*/
|
|
96
|
-
description: {
|
|
97
|
-
type: String,
|
|
98
|
-
default: "",
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Label error message.
|
|
103
|
-
*/
|
|
104
|
-
error: {
|
|
105
|
-
type: String,
|
|
106
|
-
default: "",
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Label align.
|
|
111
|
-
* @values top, topInside, topWithDesc, left, right
|
|
112
|
-
*/
|
|
113
|
-
align: {
|
|
114
|
-
type: String,
|
|
115
|
-
default: getDefault(defaultConfig, ULabel).align,
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Label size.
|
|
120
|
-
* @values sm, md, lg
|
|
121
|
-
*/
|
|
122
|
-
size: {
|
|
123
|
-
type: String,
|
|
124
|
-
default: getDefault(defaultConfig, ULabel).size,
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Make label disabled.
|
|
129
|
-
*/
|
|
130
|
-
disabled: {
|
|
131
|
-
type: Boolean,
|
|
132
|
-
default: getDefault(defaultConfig, ULabel).disabled,
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Centre label horizontally.
|
|
137
|
-
*/
|
|
138
|
-
centred: {
|
|
139
|
-
type: Boolean,
|
|
140
|
-
default: getDefault(defaultConfig, ULabel).centred,
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Set input id for label `for` attribute.
|
|
145
|
-
*/
|
|
146
|
-
for: {
|
|
147
|
-
type: String,
|
|
148
|
-
default: "",
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Component config object.
|
|
153
|
-
*/
|
|
154
|
-
config: {
|
|
155
|
-
type: Object,
|
|
156
|
-
default: () => ({}),
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Data-test attribute for automated testing.
|
|
161
|
-
*/
|
|
162
|
-
dataTest: {
|
|
163
|
-
type: String,
|
|
164
|
-
default: "",
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
const labelRef = ref(null);
|
|
169
|
-
const wrapperRef = ref(null);
|
|
170
|
-
|
|
171
|
-
const { wrapperAttrs, contentAttrs, labelAttrs, descriptionAttrs } = useAttrs(props);
|
|
172
|
-
|
|
173
|
-
const isHorizontalPlacement = computed(() => {
|
|
174
|
-
return props.align === PLACEMENT.left || props.align === PLACEMENT.right;
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const isTopWithDescPlacement = computed(() => {
|
|
178
|
-
return props.align === PLACEMENT.topWithDesc;
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
const labelElement = computed(() => {
|
|
182
|
-
return labelRef.value;
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const wrapperElement = computed(() => {
|
|
186
|
-
return wrapperRef.value;
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
function onClick(event) {
|
|
190
|
-
emit("click", event);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
defineExpose({
|
|
194
|
-
/**
|
|
195
|
-
* Reference to the label element.
|
|
196
|
-
* @property {HTMLElement}
|
|
197
|
-
*/
|
|
198
|
-
labelElement,
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Reference to the wrapper element containing the label and content.
|
|
202
|
-
* @property {HTMLElement}
|
|
203
|
-
*/
|
|
204
|
-
wrapperElement,
|
|
205
|
-
});
|
|
206
|
-
</script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
2
2
|
import { getSource } from "../../utils/storybook.ts";
|
|
3
3
|
|
|
4
|
-
import * as stories from "./stories.
|
|
5
|
-
import defaultConfig from "../config.
|
|
4
|
+
import * as stories from "./stories.ts";
|
|
5
|
+
import defaultConfig from "../config.ts?raw"
|
|
6
6
|
|
|
7
7
|
<Meta of={stories} />
|
|
8
8
|
<Title of={stories} />
|
|
@@ -5,6 +5,14 @@ import UCol from "../../ui.container-col/UCol.vue";
|
|
|
5
5
|
import UText from "../../ui.text-block/UText.vue";
|
|
6
6
|
import UIcon from "../../ui.image-icon/UIcon.vue";
|
|
7
7
|
|
|
8
|
+
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
9
|
+
import type { ULabelProps } from "../types.ts";
|
|
10
|
+
|
|
11
|
+
interface ULabelArgs extends ULabelProps {
|
|
12
|
+
slotTemplate?: string;
|
|
13
|
+
enum: "align" | "size";
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
/**
|
|
9
17
|
* The `ULabel` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/ui.form-label)
|
|
10
18
|
*/
|
|
@@ -19,11 +27,11 @@ export default {
|
|
|
19
27
|
argTypes: {
|
|
20
28
|
...getArgTypes(ULabel.__name),
|
|
21
29
|
},
|
|
22
|
-
};
|
|
30
|
+
} as Meta;
|
|
23
31
|
|
|
24
32
|
const defaultTemplate = "This is plain text";
|
|
25
33
|
|
|
26
|
-
const DefaultTemplate = (args) => ({
|
|
34
|
+
const DefaultTemplate: StoryFn<ULabelArgs> = (args: ULabelArgs) => ({
|
|
27
35
|
components: { ULabel, UText, UIcon },
|
|
28
36
|
setup() {
|
|
29
37
|
const slots = getSlotNames(ULabel.__name);
|
|
@@ -38,19 +46,26 @@ const DefaultTemplate = (args) => ({
|
|
|
38
46
|
`,
|
|
39
47
|
});
|
|
40
48
|
|
|
41
|
-
const EnumVariantTemplate = (args, { argTypes }) => ({
|
|
49
|
+
const EnumVariantTemplate: StoryFn<ULabelArgs> = (args: ULabelArgs, { argTypes }) => ({
|
|
42
50
|
components: { ULabel, UCol, UText },
|
|
43
51
|
setup() {
|
|
44
|
-
function getText(value, name) {
|
|
52
|
+
function getText(value: string, name: string) {
|
|
45
53
|
return name === "size" ? `This is ${value} size.` : `This is ${value} label placement.`;
|
|
46
54
|
}
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
let prefixedOptions;
|
|
57
|
+
|
|
58
|
+
const enumArgType = argTypes?.[args.enum];
|
|
59
|
+
|
|
60
|
+
if (enumArgType && "name" in enumArgType && "options" in enumArgType) {
|
|
61
|
+
const { name, options } = enumArgType;
|
|
62
|
+
|
|
63
|
+
prefixedOptions = options?.map((option: string) => getText(option, name));
|
|
64
|
+
}
|
|
50
65
|
|
|
51
66
|
return {
|
|
52
67
|
args,
|
|
53
|
-
options: argTypes[args.enum]
|
|
68
|
+
options: argTypes?.[args.enum]?.options,
|
|
54
69
|
prefixedOptions,
|
|
55
70
|
};
|
|
56
71
|
},
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import defaultConfig from "./config.ts";
|
|
2
|
+
|
|
3
|
+
export type Config = Partial<typeof defaultConfig>;
|
|
4
|
+
|
|
5
|
+
export interface ULabelProps {
|
|
6
|
+
/**
|
|
7
|
+
* Label text.
|
|
8
|
+
*/
|
|
9
|
+
label?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Label description.
|
|
13
|
+
*/
|
|
14
|
+
description?: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Label error message.
|
|
18
|
+
*/
|
|
19
|
+
error?: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Label align.
|
|
23
|
+
*/
|
|
24
|
+
align?: "top" | "topInside" | "topWithDesc" | "left" | "right";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Label size.
|
|
28
|
+
*/
|
|
29
|
+
size?: "sm" | "md" | "lg";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Make label disabled.
|
|
33
|
+
*/
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Centre label horizontally.
|
|
38
|
+
*/
|
|
39
|
+
centred?: boolean;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set input id for label `for` attribute.
|
|
43
|
+
*/
|
|
44
|
+
for?: string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Component config object.
|
|
48
|
+
*/
|
|
49
|
+
config?: Config;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Data-test attribute for automated testing.
|
|
53
|
+
*/
|
|
54
|
+
dataTest?: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import useUI from "../composables/useUI.ts";
|
|
3
|
+
|
|
4
|
+
import defaultConfig from "./config.ts";
|
|
5
|
+
|
|
6
|
+
import type { UseAttrs } from "../types.ts";
|
|
7
|
+
import type { ULabelProps, Config } from "./types.ts";
|
|
8
|
+
|
|
9
|
+
export default function useAttrs(props: ULabelProps): UseAttrs<Config> {
|
|
10
|
+
const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
|
|
11
|
+
|
|
12
|
+
const mutatedProps = computed(() => ({
|
|
13
|
+
error: Boolean(props.error),
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
config,
|
|
18
|
+
...getKeysAttrs(mutatedProps),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -1,43 +1,4 @@
|
|
|
1
|
-
<
|
|
2
|
-
<ULabel
|
|
3
|
-
:for="elementId"
|
|
4
|
-
:size="size"
|
|
5
|
-
:label="label"
|
|
6
|
-
:description="description"
|
|
7
|
-
:align="labelAlign"
|
|
8
|
-
:disabled="disabled"
|
|
9
|
-
:data-test="dataTest"
|
|
10
|
-
v-bind="switchLabelAttrs"
|
|
11
|
-
@click="onClickToggle"
|
|
12
|
-
>
|
|
13
|
-
<label :for="elementId" v-bind="wrapperAttrs">
|
|
14
|
-
<input
|
|
15
|
-
:id="elementId"
|
|
16
|
-
v-model="checkedValue"
|
|
17
|
-
type="checkbox"
|
|
18
|
-
:disabled="disabled"
|
|
19
|
-
v-bind="inputAttrs"
|
|
20
|
-
@click="onClickToggle"
|
|
21
|
-
@keydown.space="onKeydownSpace"
|
|
22
|
-
/>
|
|
23
|
-
|
|
24
|
-
<span v-bind="circleAttrs">
|
|
25
|
-
<UIcon
|
|
26
|
-
v-if="toggleIcon"
|
|
27
|
-
internal
|
|
28
|
-
:name="checkedValue ? config.defaults.onIcon : config.defaults.offIcon"
|
|
29
|
-
:color="iconColor"
|
|
30
|
-
:size="iconSize"
|
|
31
|
-
v-bind="toggleIconAttrs"
|
|
32
|
-
/>
|
|
33
|
-
</span>
|
|
34
|
-
|
|
35
|
-
<span v-if="toggleLabel" v-bind="toggleLabelAttrs" v-text="switchLabel" />
|
|
36
|
-
</label>
|
|
37
|
-
</ULabel>
|
|
38
|
-
</template>
|
|
39
|
-
|
|
40
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
41
2
|
import { computed, useId } from "vue";
|
|
42
3
|
import { merge } from "lodash-es";
|
|
43
4
|
|
|
@@ -45,111 +6,25 @@ import UIcon from "../ui.image-icon/UIcon.vue";
|
|
|
45
6
|
import ULabel from "../ui.form-label/ULabel.vue";
|
|
46
7
|
import { getDefault } from "../utils/ui.ts";
|
|
47
8
|
|
|
48
|
-
import { USwitch } from "./constants.
|
|
49
|
-
import defaultConfig from "./config.
|
|
50
|
-
import useAttrs from "./useAttrs.
|
|
9
|
+
import { USwitch } from "./constants.ts";
|
|
10
|
+
import defaultConfig from "./config.ts";
|
|
11
|
+
import useAttrs from "./useAttrs.ts";
|
|
51
12
|
import { useLocale } from "../composables/useLocale.ts";
|
|
52
13
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const props = defineProps({
|
|
56
|
-
/**
|
|
57
|
-
* Switch value.
|
|
58
|
-
*/
|
|
59
|
-
modelValue: {
|
|
60
|
-
type: Boolean,
|
|
61
|
-
default: false,
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Label alignment.
|
|
66
|
-
* @values top, left, right
|
|
67
|
-
*/
|
|
68
|
-
labelAlign: {
|
|
69
|
-
type: String,
|
|
70
|
-
default: getDefault(defaultConfig, USwitch).labelAlign,
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Switch label.
|
|
75
|
-
*/
|
|
76
|
-
label: {
|
|
77
|
-
type: String,
|
|
78
|
-
default: "",
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Switch description.
|
|
83
|
-
*/
|
|
84
|
-
description: {
|
|
85
|
-
type: String,
|
|
86
|
-
default: "",
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Switch size.
|
|
91
|
-
* @values sm, md, lg
|
|
92
|
-
*/
|
|
93
|
-
size: {
|
|
94
|
-
type: String,
|
|
95
|
-
default: getDefault(defaultConfig, USwitch).size,
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Switch color.
|
|
100
|
-
* @values brand, grayscale, gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose, white */
|
|
101
|
-
color: {
|
|
102
|
-
type: String,
|
|
103
|
-
default: getDefault(defaultConfig, USwitch).color,
|
|
104
|
-
},
|
|
14
|
+
import type { USwitchProps, IconSize } from "./types.ts";
|
|
105
15
|
|
|
106
|
-
|
|
107
|
-
* Show toggle icons inside the circle.
|
|
108
|
-
*/
|
|
109
|
-
toggleIcon: {
|
|
110
|
-
type: Boolean,
|
|
111
|
-
default: getDefault(defaultConfig, USwitch).toggleIcon,
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Show toggle labels (on / off).
|
|
116
|
-
*/
|
|
117
|
-
toggleLabel: {
|
|
118
|
-
type: Boolean,
|
|
119
|
-
default: getDefault(defaultConfig, USwitch).toggleLabel,
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Set switch disabled.
|
|
124
|
-
*/
|
|
125
|
-
disabled: {
|
|
126
|
-
type: Boolean,
|
|
127
|
-
default: getDefault(defaultConfig, USwitch).disabled,
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Unique element id.
|
|
132
|
-
*/
|
|
133
|
-
id: {
|
|
134
|
-
type: String,
|
|
135
|
-
default: "",
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Component config object.
|
|
140
|
-
*/
|
|
141
|
-
config: {
|
|
142
|
-
type: Object,
|
|
143
|
-
default: () => ({}),
|
|
144
|
-
},
|
|
16
|
+
defineOptions({ inheritAttrs: false });
|
|
145
17
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
18
|
+
const props = withDefaults(defineProps<USwitchProps>(), {
|
|
19
|
+
labelAlign: getDefault<USwitchProps>(defaultConfig, USwitch).labelAlign,
|
|
20
|
+
size: getDefault<USwitchProps>(defaultConfig, USwitch).size,
|
|
21
|
+
color: getDefault<USwitchProps>(defaultConfig, USwitch).color,
|
|
22
|
+
toggleIcon: getDefault<USwitchProps>(defaultConfig, USwitch).toggleIcon,
|
|
23
|
+
toggleLabel: getDefault<USwitchProps>(defaultConfig, USwitch).toggleLabel,
|
|
24
|
+
disabled: getDefault<USwitchProps>(defaultConfig, USwitch).disabled,
|
|
25
|
+
modelValue: false,
|
|
26
|
+
dataTest: "",
|
|
27
|
+
config: () => ({}),
|
|
153
28
|
});
|
|
154
29
|
|
|
155
30
|
const emit = defineEmits([
|
|
@@ -163,7 +38,7 @@ const emit = defineEmits([
|
|
|
163
38
|
const { tm } = useLocale();
|
|
164
39
|
|
|
165
40
|
const i18nGlobal = tm(USwitch);
|
|
166
|
-
const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config
|
|
41
|
+
const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config?.i18n));
|
|
167
42
|
|
|
168
43
|
const checkedValue = computed({
|
|
169
44
|
get: () => props.modelValue,
|
|
@@ -193,7 +68,7 @@ const iconSize = computed(() => {
|
|
|
193
68
|
lg: "sm",
|
|
194
69
|
};
|
|
195
70
|
|
|
196
|
-
return sizes[props.size];
|
|
71
|
+
return sizes[props.size] as IconSize;
|
|
197
72
|
});
|
|
198
73
|
|
|
199
74
|
const iconColor = computed(() => {
|
|
@@ -214,3 +89,42 @@ function onKeydownSpace() {
|
|
|
214
89
|
toggle();
|
|
215
90
|
}
|
|
216
91
|
</script>
|
|
92
|
+
|
|
93
|
+
<template>
|
|
94
|
+
<ULabel
|
|
95
|
+
:for="elementId"
|
|
96
|
+
:size="size"
|
|
97
|
+
:label="label"
|
|
98
|
+
:description="description"
|
|
99
|
+
:align="labelAlign"
|
|
100
|
+
:disabled="disabled"
|
|
101
|
+
:data-test="dataTest"
|
|
102
|
+
v-bind="switchLabelAttrs"
|
|
103
|
+
@click="onClickToggle"
|
|
104
|
+
>
|
|
105
|
+
<label :for="elementId" v-bind="wrapperAttrs">
|
|
106
|
+
<input
|
|
107
|
+
:id="elementId"
|
|
108
|
+
v-model="checkedValue"
|
|
109
|
+
type="checkbox"
|
|
110
|
+
:disabled="disabled"
|
|
111
|
+
v-bind="inputAttrs"
|
|
112
|
+
@click="onClickToggle"
|
|
113
|
+
@keydown.space="onKeydownSpace"
|
|
114
|
+
/>
|
|
115
|
+
|
|
116
|
+
<span v-bind="circleAttrs">
|
|
117
|
+
<UIcon
|
|
118
|
+
v-if="toggleIcon"
|
|
119
|
+
internal
|
|
120
|
+
:name="checkedValue ? config.defaults?.onIcon : config.defaults?.offIcon"
|
|
121
|
+
:color="iconColor"
|
|
122
|
+
:size="iconSize"
|
|
123
|
+
v-bind="toggleIconAttrs"
|
|
124
|
+
/>
|
|
125
|
+
</span>
|
|
126
|
+
|
|
127
|
+
<span v-if="toggleLabel" v-bind="toggleLabelAttrs" v-text="switchLabel" />
|
|
128
|
+
</label>
|
|
129
|
+
</ULabel>
|
|
130
|
+
</template>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
2
2
|
import { getSource } from "../../utils/storybook.ts";
|
|
3
3
|
|
|
4
|
-
import * as stories from "./stories.
|
|
5
|
-
import defaultConfig from "../config.
|
|
4
|
+
import * as stories from "./stories.ts";
|
|
5
|
+
import defaultConfig from "../config.ts?raw"
|
|
6
6
|
|
|
7
7
|
<Meta of={stories} />
|
|
8
8
|
<Title of={stories} />
|
|
@@ -4,6 +4,13 @@ import USwitch from "../../ui.form-switch/USwitch.vue";
|
|
|
4
4
|
import UIcon from "../../ui.image-icon/UIcon.vue";
|
|
5
5
|
import URow from "../../ui.container-row/URow.vue";
|
|
6
6
|
|
|
7
|
+
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
8
|
+
import type { USwitchProps } from "../types.ts";
|
|
9
|
+
|
|
10
|
+
interface USwitchArgs extends USwitchProps {
|
|
11
|
+
slotTemplate?: string;
|
|
12
|
+
enum: "size" | "color";
|
|
13
|
+
}
|
|
7
14
|
/**
|
|
8
15
|
* The `USwitch` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/ui.form-switch)
|
|
9
16
|
*/
|
|
@@ -17,9 +24,9 @@ export default {
|
|
|
17
24
|
argTypes: {
|
|
18
25
|
...getArgTypes(USwitch.__name),
|
|
19
26
|
},
|
|
20
|
-
};
|
|
27
|
+
} as Meta;
|
|
21
28
|
|
|
22
|
-
const DefaultTemplate = (args) => ({
|
|
29
|
+
const DefaultTemplate: StoryFn<USwitchArgs> = (args: USwitchArgs) => ({
|
|
23
30
|
components: { USwitch, UIcon },
|
|
24
31
|
setup() {
|
|
25
32
|
const slots = getSlotNames(USwitch.__name);
|
|
@@ -28,17 +35,17 @@ const DefaultTemplate = (args) => ({
|
|
|
28
35
|
},
|
|
29
36
|
template: `
|
|
30
37
|
<USwitch v-bind="args" v-model="args.modelValue">
|
|
31
|
-
${args.slotTemplate || getSlotsFragment()}
|
|
38
|
+
${args.slotTemplate || getSlotsFragment("")}
|
|
32
39
|
</USwitch>
|
|
33
40
|
`,
|
|
34
41
|
});
|
|
35
42
|
|
|
36
|
-
const EnumVariantTemplate = (args, { argTypes }) => ({
|
|
43
|
+
const EnumVariantTemplate: StoryFn<USwitchArgs> = (args: USwitchArgs, { argTypes }) => ({
|
|
37
44
|
components: { USwitch, URow },
|
|
38
45
|
setup() {
|
|
39
46
|
return {
|
|
40
47
|
args,
|
|
41
|
-
options: argTypes[args.enum]
|
|
48
|
+
options: argTypes?.[args.enum]?.options,
|
|
42
49
|
};
|
|
43
50
|
},
|
|
44
51
|
template: `
|