vueless 1.2.15-beta.2 → 1.2.15-beta.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/bin/commands/copy.js +1 -1
- package/composables/tests/useUI.test.ts +1 -1
- package/composables/useBreakpoint.ts +1 -1
- package/composables/useUI.ts +1 -5
- package/constants.d.ts +1 -1
- package/constants.js +1 -1
- package/index.d.ts +3 -3
- package/index.ts +3 -3
- package/locales/en.json +1 -1
- package/package.json +1 -1
- package/types.ts +2 -2
- package/ui.boilerplate/UBoilerplate.vue +1 -1
- package/ui.button/UButton.vue +1 -1
- package/ui.button-link/ULink.vue +1 -1
- package/ui.button-toggle/UToggle.vue +1 -1
- package/ui.container-accordion/UAccordion.vue +1 -1
- package/ui.container-accordion-item/UAccordionItem.vue +2 -6
- package/ui.container-accordion-item/tests/UAccordionItem.test.ts +5 -5
- package/ui.container-card/UCard.vue +1 -1
- package/ui.container-col/UCol.vue +1 -1
- package/ui.container-divider/UDivider.vue +1 -1
- package/ui.container-drawer/UDrawer.vue +1 -1
- package/ui.container-group/UGroup.vue +1 -1
- package/ui.container-groups/UGroups.vue +1 -1
- package/ui.container-modal/UModal.vue +1 -1
- package/ui.container-modal-confirm/UModalConfirm.vue +1 -1
- package/ui.container-page/UPage.vue +1 -1
- package/ui.container-page/config.ts +3 -3
- package/ui.container-row/URow.vue +1 -1
- package/ui.data-list/UDataList.vue +1 -1
- package/ui.data-list/config.ts +1 -1
- package/ui.data-table/UTable.vue +1 -1
- package/ui.data-table/UTableRow.vue +1 -1
- package/ui.data-table/config.ts +2 -0
- package/ui.data-table/storybook/stories.ts +3 -1
- package/ui.dropdown-badge/UDropdownBadge.vue +1 -1
- package/ui.dropdown-button/UDropdownButton.vue +1 -1
- package/ui.dropdown-link/UDropdownLink.vue +1 -1
- package/ui.form-calendar/UCalendar.vue +5 -1
- package/ui.form-calendar/UCalendarDayView.vue +1 -1
- package/ui.form-calendar/UCalendarMonthView.vue +1 -1
- package/ui.form-calendar/UCalendarYearView.vue +1 -1
- package/ui.form-calendar/config.ts +5 -0
- package/ui.form-checkbox/UCheckbox.vue +24 -5
- package/ui.form-checkbox/config.ts +4 -0
- package/ui.form-checkbox/tests/UCheckbox.test.ts +1 -1
- package/ui.form-checkbox-group/UCheckboxGroup.vue +1 -1
- package/ui.form-checkbox-multi-state/UCheckboxMultiState.vue +1 -1
- package/{ui.form-color-picker/UColorPicker.vue → ui.form-color-toggle/UColorToggle.vue} +1 -1
- package/{ui.form-color-picker → ui.form-color-toggle}/constants.ts +1 -1
- package/{ui.form-color-picker → ui.form-color-toggle}/storybook/stories.ts +14 -14
- package/{ui.form-color-picker/tests/UColorPicker.test.ts → ui.form-color-toggle/tests/UColorToggle.test.ts} +8 -8
- package/ui.form-date-picker/UDatePicker.vue +1 -1
- package/ui.form-date-picker/config.ts +5 -0
- package/ui.form-date-picker-range/UDatePickerRange.vue +1 -1
- package/ui.form-input/UInput.vue +10 -4
- package/ui.form-input-counter/UInputCounter.vue +10 -1
- package/ui.form-input-counter/config.ts +5 -0
- package/ui.form-input-file/UInputFile.vue +1 -1
- package/ui.form-input-number/UInputNumber.vue +1 -1
- package/ui.form-input-password/UInputPassword.vue +12 -13
- package/ui.form-input-password/tests/UInputPassword.test.ts +2 -2
- package/ui.form-input-rating/UInputRating.vue +1 -1
- package/ui.form-input-search/UInputSearch.vue +1 -1
- package/ui.form-label/ULabel.vue +6 -2
- package/ui.form-label/types.ts +5 -0
- package/ui.form-listbox/UListbox.vue +38 -12
- package/ui.form-radio/URadio.vue +1 -1
- package/ui.form-radio-group/URadioGroup.vue +1 -1
- package/ui.form-select/USelect.vue +38 -3
- package/ui.form-select/tests/USelect.test.ts +3 -1
- package/ui.form-switch/USwitch.vue +21 -8
- package/ui.form-switch/config.ts +2 -0
- package/ui.form-switch/tests/USwitch.test.ts +6 -4
- package/ui.form-textarea/UTextarea.vue +16 -6
- package/ui.form-textarea/tests/UTextarea.test.ts +1 -1
- package/ui.image-avatar/UAvatar.vue +1 -1
- package/ui.image-icon/UIcon.vue +1 -1
- package/ui.loader/ULoader.vue +1 -1
- package/ui.loader-overlay/ULoaderOverlay.vue +1 -1
- package/ui.loader-progress/ULoaderProgress.vue +1 -1
- package/ui.navigation-breadcrumbs/UBreadcrumbs.vue +1 -1
- package/ui.navigation-pagination/UPagination.vue +15 -1
- package/ui.navigation-pagination/config.ts +9 -0
- package/ui.navigation-progress/UProgress.vue +1 -1
- package/ui.navigation-progress/UStepperProgress.vue +1 -1
- package/ui.navigation-tab/UTab.vue +1 -1
- package/ui.navigation-tabs/UTabs.vue +1 -1
- package/ui.other-chip/UChip.vue +1 -1
- package/ui.other-dot/UDot.vue +1 -1
- package/ui.other-theme-color-toggle/UThemeColorToggle.vue +4 -4
- package/ui.other-theme-color-toggle/config.ts +2 -2
- package/ui.other-theme-color-toggle/tests/UThemeColorToggle.test.ts +10 -10
- package/ui.skeleton/USkeleton.vue +1 -1
- package/ui.skeleton-choice/USkeletonChoice.vue +1 -1
- package/ui.skeleton-input/USkeletonInput.vue +1 -1
- package/ui.skeleton-text/USkeletonText.vue +1 -1
- package/ui.text-alert/UAlert.vue +9 -1
- package/ui.text-alert/config.ts +4 -0
- package/ui.text-badge/UBadge.vue +1 -1
- package/ui.text-block/UText.vue +1 -1
- package/ui.text-block/config.ts +5 -4
- package/ui.text-empty/UEmpty.vue +1 -1
- package/ui.text-file/UFile.vue +1 -1
- package/ui.text-files/UFiles.vue +1 -1
- package/ui.text-header/UHeader.vue +1 -1
- package/ui.text-notify/UNotify.vue +1 -1
- package/ui.text-number/UNumber.vue +1 -1
- /package/{ui.form-color-picker → ui.form-color-toggle}/config.ts +0 -0
- /package/{ui.form-color-picker → ui.form-color-toggle}/storybook/docs.mdx +0 -0
- /package/{ui.form-color-picker → ui.form-color-toggle}/types.ts +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { inject, ref, onMounted, computed, watchEffect, toValue, useId } from "vue";
|
|
2
|
+
import { inject, ref, onMounted, computed, watchEffect, toValue, useId, useSlots } from "vue";
|
|
3
3
|
import { isEqual } from "lodash-es";
|
|
4
4
|
|
|
5
|
-
import useUI from "../composables/useUI";
|
|
5
|
+
import { useUI } from "../composables/useUI";
|
|
6
6
|
import { getDefaults } from "../utils/ui";
|
|
7
|
+
import { useComponentLocaleMessages } from "../composables/useComponentLocaleMassages";
|
|
7
8
|
|
|
8
9
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
9
10
|
import ULabel from "../ui.form-label/ULabel.vue";
|
|
@@ -48,12 +49,24 @@ const emit = defineEmits([
|
|
|
48
49
|
"input",
|
|
49
50
|
]);
|
|
50
51
|
|
|
52
|
+
const { localeMessages } = useComponentLocaleMessages<typeof defaultConfig.i18n>(
|
|
53
|
+
COMPONENT_NAME,
|
|
54
|
+
defaultConfig.i18n,
|
|
55
|
+
props?.config?.i18n,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const slots = useSlots();
|
|
59
|
+
|
|
51
60
|
const checkboxName = ref("");
|
|
52
61
|
const checkboxSize = ref(props.size);
|
|
53
62
|
const checkboxColor = ref(props.color);
|
|
54
63
|
|
|
55
64
|
const elementId = props.id || useId();
|
|
56
65
|
|
|
66
|
+
const hasLabel = computed(() => Boolean(props.label || slots.label));
|
|
67
|
+
|
|
68
|
+
const inputAriaLabelledBy = computed(() => (hasLabel.value ? elementId : undefined));
|
|
69
|
+
|
|
57
70
|
const isBinary = computed(() => !Array.isArray(props.modelValue));
|
|
58
71
|
const isCheckboxInGroup = computed(() => Boolean(toValue(getCheckboxGroupName)));
|
|
59
72
|
|
|
@@ -108,6 +121,10 @@ function onChange() {
|
|
|
108
121
|
emit("input", newModelValue);
|
|
109
122
|
}
|
|
110
123
|
|
|
124
|
+
function onIconClick() {
|
|
125
|
+
document.getElementById(elementId)?.click();
|
|
126
|
+
}
|
|
127
|
+
|
|
111
128
|
/**
|
|
112
129
|
* Get element / nested component attributes for each config token ✨
|
|
113
130
|
* Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
|
|
@@ -161,15 +178,17 @@ const {
|
|
|
161
178
|
:name="checkboxName"
|
|
162
179
|
:checked="isChecked"
|
|
163
180
|
:disabled="disabled"
|
|
181
|
+
:aria-labelledby="inputAriaLabelledBy"
|
|
182
|
+
:aria-label="!hasLabel ? localeMessages.checkbox : undefined"
|
|
164
183
|
v-bind="checkboxAttrs"
|
|
165
184
|
:data-test="getDataTest()"
|
|
166
185
|
@change="onChange"
|
|
167
186
|
/>
|
|
168
187
|
|
|
169
|
-
<
|
|
188
|
+
<div
|
|
170
189
|
v-if="isChecked"
|
|
171
190
|
v-bind="partial ? partiallyCheckedAttrs : checkedAttrs"
|
|
172
|
-
|
|
191
|
+
@click="onIconClick"
|
|
173
192
|
>
|
|
174
193
|
<UIcon
|
|
175
194
|
v-if="partial"
|
|
@@ -179,7 +198,7 @@ const {
|
|
|
179
198
|
/>
|
|
180
199
|
|
|
181
200
|
<UIcon v-else :name="config.defaults.checkedIcon" color="inherit" v-bind="checkedIconAttrs" />
|
|
182
|
-
</
|
|
201
|
+
</div>
|
|
183
202
|
|
|
184
203
|
<template #bottom>
|
|
185
204
|
<!-- @slot Use it to add something below the checkbox. -->
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { provide, ref, watch, useTemplateRef } from "vue";
|
|
3
3
|
import { isEqual } from "lodash-es";
|
|
4
4
|
|
|
5
|
-
import useUI from "../composables/useUI";
|
|
5
|
+
import { useUI } from "../composables/useUI";
|
|
6
6
|
import { getDefaults } from "../utils/ui";
|
|
7
7
|
|
|
8
8
|
import ULabel from "../ui.form-label/ULabel.vue";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { computed, ref, watchEffect } from "vue";
|
|
3
3
|
import { cloneDeep } from "../utils/helper";
|
|
4
4
|
|
|
5
|
-
import useUI from "../composables/useUI";
|
|
5
|
+
import { useUI } from "../composables/useUI";
|
|
6
6
|
import { getDefaults } from "../utils/ui";
|
|
7
7
|
|
|
8
8
|
import UCheckbox from "../ui.form-checkbox/UCheckbox.vue";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed, useId, useTemplateRef } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
|
|
7
7
|
import vTooltip from "../v.tooltip/vTooltip";
|
|
@@ -6,22 +6,22 @@ import {
|
|
|
6
6
|
getDocsDescription,
|
|
7
7
|
} from "../../utils/storybook";
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import UColorToggle from "../UColorToggle.vue";
|
|
10
10
|
import UCol from "../../ui.container-col/UCol.vue";
|
|
11
11
|
import UButton from "../../ui.button/UButton.vue";
|
|
12
12
|
|
|
13
13
|
import type { Meta, StoryFn } from "@storybook/vue3-vite";
|
|
14
14
|
import type { Props } from "../types";
|
|
15
15
|
|
|
16
|
-
interface
|
|
16
|
+
interface UColorToggleArgs extends Props {
|
|
17
17
|
slotTemplate?: string;
|
|
18
18
|
enum: "size";
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export default {
|
|
22
22
|
id: "3190",
|
|
23
|
-
title: "Form Inputs & Controls / Color
|
|
24
|
-
component:
|
|
23
|
+
title: "Form Inputs & Controls / Color Toggle",
|
|
24
|
+
component: UColorToggle,
|
|
25
25
|
args: {
|
|
26
26
|
modelValue: "",
|
|
27
27
|
colors: /*tw*/ {
|
|
@@ -47,31 +47,31 @@ export default {
|
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
49
|
argTypes: {
|
|
50
|
-
...getArgTypes(
|
|
50
|
+
...getArgTypes(UColorToggle.__name),
|
|
51
51
|
},
|
|
52
52
|
parameters: {
|
|
53
53
|
docs: {
|
|
54
|
-
...getDocsDescription(
|
|
54
|
+
...getDocsDescription(UColorToggle.__name),
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
} as Meta;
|
|
58
58
|
|
|
59
|
-
const DefaultTemplate: StoryFn<
|
|
60
|
-
components: {
|
|
61
|
-
setup: () => ({ args, slots: getSlotNames(
|
|
59
|
+
const DefaultTemplate: StoryFn<UColorToggleArgs> = (args: UColorToggleArgs) => ({
|
|
60
|
+
components: { UColorToggle, UButton, UCol },
|
|
61
|
+
setup: () => ({ args, slots: getSlotNames(UColorToggle.__name) }),
|
|
62
62
|
template: `
|
|
63
|
-
<
|
|
63
|
+
<UColorToggle v-bind="args" v-model="args.modelValue">
|
|
64
64
|
${args.slotTemplate || getSlotsFragment("")}
|
|
65
|
-
</
|
|
65
|
+
</UColorToggle>
|
|
66
66
|
`,
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
const EnumTemplate: StoryFn<
|
|
70
|
-
components: { UCol,
|
|
69
|
+
const EnumTemplate: StoryFn<UColorToggleArgs> = (args: UColorToggleArgs, { argTypes }) => ({
|
|
70
|
+
components: { UCol, UColorToggle },
|
|
71
71
|
setup: () => ({ args, argTypes, getArgs }),
|
|
72
72
|
template: `
|
|
73
73
|
<UCol>
|
|
74
|
-
<
|
|
74
|
+
<UColorToggle
|
|
75
75
|
v-for="option in argTypes?.[args.enum]?.options"
|
|
76
76
|
v-bind="getArgs(args, option)"
|
|
77
77
|
:key="option"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { mount } from "@vue/test-utils";
|
|
2
2
|
import { describe, it, expect } from "vitest";
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import UColorToggle from "../UColorToggle.vue";
|
|
5
5
|
import UButton from "../../ui.button/UButton.vue";
|
|
6
6
|
|
|
7
7
|
import type { Props } from "../types";
|
|
8
8
|
|
|
9
|
-
describe("
|
|
9
|
+
describe("UColorToggle.vue", () => {
|
|
10
10
|
describe("Props", () => {
|
|
11
11
|
it("Model Value – selects the correct color based on modelValue", async () => {
|
|
12
12
|
const modelValue = "primary";
|
|
@@ -18,7 +18,7 @@ describe("UColorPicker.vue", () => {
|
|
|
18
18
|
secondary: "bg-secondary-500",
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const component = mount(
|
|
21
|
+
const component = mount(UColorToggle, {
|
|
22
22
|
props: {
|
|
23
23
|
modelValue,
|
|
24
24
|
"onUpdate:modelValue": (value) => component.setProps({ modelValue: value }),
|
|
@@ -47,7 +47,7 @@ describe("UColorPicker.vue", () => {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
Object.entries(sizes).forEach(([size, classes]) => {
|
|
50
|
-
const component = mount(
|
|
50
|
+
const component = mount(UColorToggle, {
|
|
51
51
|
props: {
|
|
52
52
|
modelValue: "",
|
|
53
53
|
size: size as Props["size"],
|
|
@@ -70,7 +70,7 @@ describe("UColorPicker.vue", () => {
|
|
|
70
70
|
error: "bg-error-500",
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
const component = mount(
|
|
73
|
+
const component = mount(UColorToggle, {
|
|
74
74
|
props: {
|
|
75
75
|
modelValue: "",
|
|
76
76
|
colors,
|
|
@@ -89,7 +89,7 @@ describe("UColorPicker.vue", () => {
|
|
|
89
89
|
it("Id – applies the correct id attribute", () => {
|
|
90
90
|
const id = "test-color-picker-id";
|
|
91
91
|
|
|
92
|
-
const component = mount(
|
|
92
|
+
const component = mount(UColorToggle, {
|
|
93
93
|
props: {
|
|
94
94
|
modelValue: "",
|
|
95
95
|
id,
|
|
@@ -107,7 +107,7 @@ describe("UColorPicker.vue", () => {
|
|
|
107
107
|
secondary: "bg-secondary-500",
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
-
const component = mount(
|
|
110
|
+
const component = mount(UColorToggle, {
|
|
111
111
|
props: {
|
|
112
112
|
modelValue: "",
|
|
113
113
|
dataTest,
|
|
@@ -127,7 +127,7 @@ describe("UColorPicker.vue", () => {
|
|
|
127
127
|
|
|
128
128
|
describe("Exposed properties", () => {
|
|
129
129
|
it("ListRef – exposes listRef", () => {
|
|
130
|
-
const component = mount(
|
|
130
|
+
const component = mount(UColorToggle, {
|
|
131
131
|
props: {
|
|
132
132
|
modelValue: "",
|
|
133
133
|
colors: {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { computed, nextTick, ref, useId, useTemplateRef, watchEffect } from "vue";
|
|
3
3
|
import { merge } from "lodash-es";
|
|
4
4
|
|
|
5
|
-
import useUI from "../composables/useUI";
|
|
5
|
+
import { useUI } from "../composables/useUI";
|
|
6
6
|
|
|
7
7
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
8
8
|
import UInput from "../ui.form-input/UInput.vue";
|
|
@@ -125,6 +125,11 @@ export default /*tw*/ {
|
|
|
125
125
|
},
|
|
126
126
|
timeLabel: "Time",
|
|
127
127
|
okLabel: "Ok",
|
|
128
|
+
/* These are used for a11y. */
|
|
129
|
+
previousYear: "Previous Year",
|
|
130
|
+
nextYear: "Next Year",
|
|
131
|
+
previousMonth: "Previous Month",
|
|
132
|
+
nextMonth: "Next Month",
|
|
128
133
|
},
|
|
129
134
|
defaults: {
|
|
130
135
|
size: "md",
|
|
@@ -3,7 +3,7 @@ import { computed, watch, ref, nextTick, provide, useId, useTemplateRef, watchEf
|
|
|
3
3
|
|
|
4
4
|
import { merge } from "lodash-es";
|
|
5
5
|
|
|
6
|
-
import useUI from "../composables/useUI";
|
|
6
|
+
import { useUI } from "../composables/useUI";
|
|
7
7
|
import { getDefaults } from "../utils/ui";
|
|
8
8
|
|
|
9
9
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
package/ui.form-input/UInput.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, onMounted, useSlots, useId, useTemplateRef, watch } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
import { hasSlotContent } from "../utils/helper";
|
|
7
7
|
import { useMutationObserver } from "../composables/useMutationObserver";
|
|
@@ -91,7 +91,7 @@ const VALIDATION_RULES_REG_EX = {
|
|
|
91
91
|
|
|
92
92
|
const slots = useSlots();
|
|
93
93
|
|
|
94
|
-
const wrapperRef = useTemplateRef<
|
|
94
|
+
const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
|
|
95
95
|
const inputRef = useTemplateRef<HTMLInputElement>("input");
|
|
96
96
|
const leftSlotWrapperRef = useTemplateRef<HTMLSpanElement>("leftSlotWrapper");
|
|
97
97
|
const labelComponentRef = useTemplateRef<InstanceType<typeof ULabel>>("labelComponent");
|
|
@@ -176,6 +176,10 @@ function onKeydown(event: KeyboardEvent) {
|
|
|
176
176
|
emit("keydown", event);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
function onSlotClick() {
|
|
180
|
+
inputRef.value?.focus();
|
|
181
|
+
}
|
|
182
|
+
|
|
179
183
|
/**
|
|
180
184
|
* This trick prevents default browser autocomplete behavior.
|
|
181
185
|
* @param toggleState { boolean }
|
|
@@ -286,11 +290,12 @@ const {
|
|
|
286
290
|
<slot name="label" :label="label" />
|
|
287
291
|
</template>
|
|
288
292
|
|
|
289
|
-
<
|
|
293
|
+
<div ref="wrapper" v-bind="wrapperAttrs">
|
|
290
294
|
<span
|
|
291
295
|
v-if="hasSlotContent($slots['left'], { iconName: leftIcon }) || leftIcon"
|
|
292
296
|
v-bind="leftSlotAttrs"
|
|
293
297
|
ref="leftSlotWrapper"
|
|
298
|
+
@click="onSlotClick"
|
|
294
299
|
>
|
|
295
300
|
<!--
|
|
296
301
|
@slot Use it to add something before the text.
|
|
@@ -328,6 +333,7 @@ const {
|
|
|
328
333
|
<span
|
|
329
334
|
v-if="hasSlotContent($slots['right'], { iconName: rightIcon }) || rightIcon"
|
|
330
335
|
v-bind="rightSlotAttrs"
|
|
336
|
+
@click="onSlotClick"
|
|
331
337
|
>
|
|
332
338
|
<!--
|
|
333
339
|
@slot Use it to add something after the text.
|
|
@@ -337,6 +343,6 @@ const {
|
|
|
337
343
|
<UIcon v-if="rightIcon" color="neutral" :name="rightIcon" v-bind="rightIconAttrs" />
|
|
338
344
|
</slot>
|
|
339
345
|
</span>
|
|
340
|
-
</
|
|
346
|
+
</div>
|
|
341
347
|
</ULabel>
|
|
342
348
|
</template>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed, useTemplateRef, watch } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
|
+
import { useComponentLocaleMessages } from "../composables/useComponentLocaleMassages";
|
|
6
7
|
|
|
7
8
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
8
9
|
import UButton from "../ui.button/UButton.vue";
|
|
@@ -41,6 +42,12 @@ const emit = defineEmits([
|
|
|
41
42
|
"blur",
|
|
42
43
|
]);
|
|
43
44
|
|
|
45
|
+
const { localeMessages } = useComponentLocaleMessages<typeof defaultConfig.i18n>(
|
|
46
|
+
COMPONENT_NAME,
|
|
47
|
+
defaultConfig.i18n,
|
|
48
|
+
props?.config?.i18n,
|
|
49
|
+
);
|
|
50
|
+
|
|
44
51
|
const inputComponentRef = useTemplateRef<InstanceType<typeof UInput>>("inputComponent");
|
|
45
52
|
|
|
46
53
|
const addIntervalId = ref<number | null>(null);
|
|
@@ -181,6 +188,7 @@ const {
|
|
|
181
188
|
:size="size"
|
|
182
189
|
variant="outlined"
|
|
183
190
|
:disabled="isSubtractButtonDisabled || disabled"
|
|
191
|
+
:aria-label="localeMessages.subtract"
|
|
184
192
|
v-bind="subtractButtonAttrs"
|
|
185
193
|
:data-test="getDataTest('subtract')"
|
|
186
194
|
@click.prevent
|
|
@@ -221,6 +229,7 @@ const {
|
|
|
221
229
|
square
|
|
222
230
|
variant="outlined"
|
|
223
231
|
:disabled="isAddButtonDisabled || disabled"
|
|
232
|
+
:aria-label="localeMessages.add"
|
|
224
233
|
v-bind="addButtonAttrs"
|
|
225
234
|
:data-test="getDataTest('add')"
|
|
226
235
|
@click.prevent
|
|
@@ -31,6 +31,11 @@ export default /*tw*/ {
|
|
|
31
31
|
subtractButton: "{>actionButton}",
|
|
32
32
|
addIcon: "{UIcon}",
|
|
33
33
|
subtractIcon: "{UIcon}",
|
|
34
|
+
/* These are used for a11y. */
|
|
35
|
+
i18n: {
|
|
36
|
+
add: "Add",
|
|
37
|
+
subtract: "Subtract",
|
|
38
|
+
},
|
|
34
39
|
defaults: {
|
|
35
40
|
size: "md",
|
|
36
41
|
decimalSeparator: ",",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useTemplateRef,
|
|
11
11
|
} from "vue";
|
|
12
12
|
|
|
13
|
-
import useUI from "../composables/useUI";
|
|
13
|
+
import { useUI } from "../composables/useUI";
|
|
14
14
|
import { getDefaults } from "../utils/ui";
|
|
15
15
|
import { hasSlotContent } from "../utils/helper";
|
|
16
16
|
import { getFileMbSize } from "./utilFileForm";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, watch, onMounted, useId, useTemplateRef } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
|
|
7
7
|
import UInput from "../ui.form-input/UInput.vue";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, computed, useId } from "vue";
|
|
2
|
+
import { ref, computed, useId, useTemplateRef, nextTick } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
|
|
7
7
|
import defaultConfig from "./config";
|
|
@@ -42,6 +42,7 @@ const emit = defineEmits([
|
|
|
42
42
|
|
|
43
43
|
const elementId = props.id || useId();
|
|
44
44
|
|
|
45
|
+
const inputRef = useTemplateRef<InstanceType<typeof UInput>>("input");
|
|
45
46
|
const isShownPassword = ref(false);
|
|
46
47
|
|
|
47
48
|
const localValue = computed({
|
|
@@ -59,8 +60,12 @@ const passwordIcon = computed(() => {
|
|
|
59
60
|
: config.value.defaults.passwordHiddenIcon || "";
|
|
60
61
|
});
|
|
61
62
|
|
|
62
|
-
function onClickShowPassword() {
|
|
63
|
+
async function onClickShowPassword() {
|
|
63
64
|
isShownPassword.value = !isShownPassword.value;
|
|
65
|
+
|
|
66
|
+
await nextTick();
|
|
67
|
+
|
|
68
|
+
inputRef.value?.inputRef?.focus();
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
function onFocus(event: FocusEvent) {
|
|
@@ -86,6 +91,7 @@ const { getDataTest, config, passwordInputAttrs, passwordIconAttrs, passwordIcon
|
|
|
86
91
|
<template>
|
|
87
92
|
<UInput
|
|
88
93
|
:id="elementId"
|
|
94
|
+
ref="input"
|
|
89
95
|
v-model="localValue"
|
|
90
96
|
:type="inputType"
|
|
91
97
|
:label="label"
|
|
@@ -120,29 +126,22 @@ const { getDataTest, config, passwordInputAttrs, passwordIconAttrs, passwordIcon
|
|
|
120
126
|
</template>
|
|
121
127
|
|
|
122
128
|
<template #right>
|
|
123
|
-
<
|
|
129
|
+
<div v-bind="passwordIconWrapperAttrs" @click="onClickShowPassword">
|
|
124
130
|
<!--
|
|
125
131
|
@slot Use it to add something instead of the password icon.
|
|
126
132
|
@binding {string} icon-name
|
|
127
133
|
@binding {boolean} visible
|
|
128
|
-
@binding {function} toggle
|
|
129
134
|
-->
|
|
130
|
-
<slot
|
|
131
|
-
name="right"
|
|
132
|
-
:icon-name="passwordIcon"
|
|
133
|
-
:visible="isShownPassword"
|
|
134
|
-
:toggle="onClickShowPassword"
|
|
135
|
-
>
|
|
135
|
+
<slot name="right" :icon-name="passwordIcon" :visible="isShownPassword">
|
|
136
136
|
<UIcon
|
|
137
137
|
:name="passwordIcon"
|
|
138
138
|
color="neutral"
|
|
139
139
|
interactive
|
|
140
140
|
v-bind="passwordIconAttrs"
|
|
141
141
|
:data-test="getDataTest('password-icon')"
|
|
142
|
-
@click="onClickShowPassword"
|
|
143
142
|
/>
|
|
144
143
|
</slot>
|
|
145
|
-
</
|
|
144
|
+
</div>
|
|
146
145
|
</template>
|
|
147
146
|
</UInput>
|
|
148
147
|
</template>
|
|
@@ -190,14 +190,14 @@ describe("UInputPassword.vue", () => {
|
|
|
190
190
|
expect(input.attributes("type")).toBe("password");
|
|
191
191
|
expect(passwordIcon.props("name")).toBe("visibility_off-fill");
|
|
192
192
|
|
|
193
|
-
await flushPromises();
|
|
194
193
|
await passwordIcon.trigger("click");
|
|
194
|
+
await flushPromises();
|
|
195
195
|
|
|
196
196
|
expect(input.attributes("type")).toBe("text");
|
|
197
197
|
expect(passwordIcon.props("name")).toBe("visibility-fill");
|
|
198
198
|
|
|
199
|
-
await flushPromises();
|
|
200
199
|
await passwordIcon.trigger("click");
|
|
200
|
+
await flushPromises();
|
|
201
201
|
|
|
202
202
|
expect(input.attributes("type")).toBe("password");
|
|
203
203
|
expect(passwordIcon.props("name")).toBe("visibility_off-fill");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, useTemplateRef } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { hasSlotContent } from "../utils/helper";
|
|
6
6
|
import { getDefaults } from "../utils/ui";
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { useId, ref, computed, watchEffect, useTemplateRef } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
import { createDebounce } from "../utils/helper";
|
|
7
7
|
|
package/ui.form-label/ULabel.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, useTemplateRef, useSlots } from "vue";
|
|
2
|
+
import { computed, useTemplateRef, useSlots, useId } from "vue";
|
|
3
3
|
|
|
4
|
-
import useUI from "../composables/useUI";
|
|
4
|
+
import { useUI } from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
6
6
|
import { hasSlotContent } from "../utils/helper";
|
|
7
7
|
|
|
@@ -26,6 +26,8 @@ const emit = defineEmits([
|
|
|
26
26
|
|
|
27
27
|
const slots = useSlots();
|
|
28
28
|
|
|
29
|
+
const elementId = props.id || useId();
|
|
30
|
+
|
|
29
31
|
const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
|
|
30
32
|
const labelRef = useTemplateRef<HTMLLabelElement>("label");
|
|
31
33
|
|
|
@@ -102,6 +104,7 @@ const { getDataTest, wrapperAttrs, contentAttrs, labelAttrs, descriptionAttrs, e
|
|
|
102
104
|
<component
|
|
103
105
|
:is="tag"
|
|
104
106
|
v-if="label || hasSlotContent(slots['label'], { label })"
|
|
107
|
+
:id="elementId"
|
|
105
108
|
ref="label"
|
|
106
109
|
:for="props.for"
|
|
107
110
|
v-bind="labelAttrs"
|
|
@@ -140,6 +143,7 @@ const { getDataTest, wrapperAttrs, contentAttrs, labelAttrs, descriptionAttrs, e
|
|
|
140
143
|
<component
|
|
141
144
|
:is="tag"
|
|
142
145
|
v-if="label || hasSlotContent(slots['label'], { label })"
|
|
146
|
+
:id="elementId"
|
|
143
147
|
v-bind="labelAttrs"
|
|
144
148
|
ref="label"
|
|
145
149
|
:for="props.for"
|