Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 46 additions & 43 deletions packages/sit-onyx/src/components/OnyxCheckbox/OnyxCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,49 +75,52 @@ useAutofocus(input, props);
</div>

<OnyxErrorTooltip v-else :disabled="disabled" :error-messages="errorMessages" v-bind="rootAttrs">
<label
class="onyx-component onyx-checkbox"
:class="[requiredTypeClass, densityClass]"
:title="title"
>
<div class="onyx-checkbox__container">
<OnyxLoadingIndicator v-if="props.loading" class="onyx-checkbox__loading" type="circle" />
<input
v-else
ref="input"
v-model="isChecked"
v-custom-validity
:aria-label="props.hideLabel ? props.label : undefined"
class="onyx-checkbox__input"
type="checkbox"
:indeterminate="props.indeterminate"
:disabled="disabled"
:required="props.required"
:value="props.value"
:autofocus="props.autofocus"
v-bind="restAttrs"
/>
</div>

<template v-if="!props.hideLabel">
<p
class="onyx-checkbox__label"
:class="[
`onyx-truncation-${props.truncation}`,
// shows the required marker inline for multiline labels
props.truncation === 'multiline' ? requiredMarkerClass : undefined,
]"
>
{{ props.label }}
</p>
<!-- shows the required marker fixed on the right for truncated labels -->
<div
v-if="props.truncation === 'ellipsis'"
class="onyx-checkbox__marker"
:class="[requiredMarkerClass]"
></div>
</template>
</label>
<template #default="{ trigger }">
<label
class="onyx-component onyx-checkbox"
:class="[requiredTypeClass, densityClass]"
:title="title"
v-bind="trigger"
>
<div class="onyx-checkbox__container">
<OnyxLoadingIndicator v-if="props.loading" class="onyx-checkbox__loading" type="circle" />
<input
v-else
ref="input"
v-model="isChecked"
v-custom-validity
:aria-label="props.hideLabel ? props.label : undefined"
class="onyx-checkbox__input"
type="checkbox"
:indeterminate="props.indeterminate"
:disabled="disabled"
:required="props.required"
:value="props.value"
:autofocus="props.autofocus"
v-bind="restAttrs"
/>
</div>

<template v-if="!props.hideLabel">
<p
class="onyx-checkbox__label"
:class="[
`onyx-truncation-${props.truncation}`,
// shows the required marker inline for multiline labels
props.truncation === 'multiline' ? requiredMarkerClass : undefined,
]"
>
{{ props.label }}
</p>
<!-- shows the required marker fixed on the right for truncated labels -->
<div
v-if="props.truncation === 'ellipsis'"
class="onyx-checkbox__marker"
:class="[requiredMarkerClass]"
></div>
</template>
</label>
</template>
</OnyxErrorTooltip>
</template>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { useMoreListChild } from "../../../../composables/useMoreList.js";
import type { VueTemplateRefElement } from "../../../../composables/useResizeObserver.js";
import { mergeVueProps } from "../../../../utils/attrs.js";
import { useForwardProps } from "../../../../utils/props.js";
import OnyxButton from "../../../OnyxButton/OnyxButton.vue";
Expand All @@ -25,6 +26,8 @@ const props = withDefaults(

const buttonProps = useForwardProps(props, OnyxButton);
const iconButtonProps = useForwardProps(props, OnyxIconButton);

const templateRef = (el?: VueTemplateRefElement) => (componentRef.value = el);
</script>

<!-- eslint-disable-next-line vue/no-root-v-if -- used for the OnyxMoreList -->
Expand All @@ -37,11 +40,11 @@ const iconButtonProps = useForwardProps(props, OnyxIconButton);
v-bind="buttonProps"
@click="props.onClick"
/>

<OnyxTooltip v-else :text="props.label">
<template #default="{ trigger }">
<OnyxIconButton
ref="componentRef"
v-bind="mergeVueProps(iconButtonProps, trigger)"
v-bind="mergeVueProps(iconButtonProps, trigger, { ref: templateRef })"
@click="props.onClick"
/>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { expect, test } from "../../playwright/a11y.js";
import OnyxErrorTooltip from "./OnyxErrorTooltip.vue";
import TestCase from "./TestCase.ct.vue";

test("should render without error-tooltip", async ({ mount, makeAxeBuilder }) => {
// ARRANGE
const component = await mount(
<OnyxErrorTooltip>
<button>Dummy button</button>
</OnyxErrorTooltip>,
);
const component = await mount(<TestCase />);

// ACT
await component.getByRole("button").hover();
Expand All @@ -24,9 +20,7 @@ test("should render error-tooltip on hover", async ({ mount, makeAxeBuilder }) =
const errorMessages = { shortMessage: "Dummy error", longMessage: "Further information" };
// ARRANGE
const component = await mount(
<OnyxErrorTooltip style="padding-top: 3rem;" errorMessages={errorMessages}>
<button>Dummy button</button>
</OnyxErrorTooltip>,
<TestCase style="padding-top: 3rem;" errorMessages={errorMessages} />,
);

// ACT
Expand All @@ -50,9 +44,7 @@ test("should render error-tooltip on focus", async ({ mount, makeAxeBuilder }) =
const errorMessages = { shortMessage: "Dummy error", longMessage: "Further information" };
// ARRANGE
const component = await mount(
<OnyxErrorTooltip style="padding-top: 3rem;" errorMessages={errorMessages}>
<button>Dummy button</button>
</OnyxErrorTooltip>,
<TestCase style="padding-top: 3rem;" errorMessages={errorMessages} />,
);

// ACT
Expand All @@ -75,12 +67,10 @@ test("should render error-tooltip on focus", async ({ mount, makeAxeBuilder }) =
test("should render without error-tooltip when disabled", async ({ mount, makeAxeBuilder }) => {
// ARRANGE
const component = await mount(
<OnyxErrorTooltip
<TestCase
errorMessages={{ shortMessage: "Dummy error", longMessage: "Further information" }}
disabled
>
<button disabled>Dummy button</button>
</OnyxErrorTooltip>,
/>,
);

// ACT
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { computed, useTemplateRef } from "vue";
import { type FormMessages, getFormMessageText } from "../../composables/useFormElementError.js";
import { computed, type AriaAttributes } from "vue";
import { getFormMessageText, type FormMessages } from "../../composables/useFormElementError.js";
import OnyxTooltip from "../OnyxTooltip/OnyxTooltip.vue";

const props = defineProps<{
Expand All @@ -21,48 +21,24 @@ defineSlots<{
* Any component. Will be wrapped in an OnyxTooltip showing
* an error message if an error message is set.
*/
default(): unknown;
default(props: { trigger?: AriaAttributes }): unknown;
}>();

const tooltipError = computed(() => getFormMessageText(props.errorMessages));

const target = useTemplateRef("target");
</script>

<template>
<div class="onyx-component">
<!-- component will be placed in here if no tooltip should be rendered -->
<div v-if="!tooltipError || props.disabled" ref="target"></div>
<div v-if="!tooltipError || props.disabled">
<slot></slot>
</div>

<!-- component will be placed inside the tooltip if it gets rendered -->
<OnyxTooltip
v-if="tooltipError && !props.disabled"
class="onyx-error-tooltip"
trigger="hover"
:text="tooltipError"
color="danger"
>
<OnyxTooltip v-else trigger="hover" :text="tooltipError" color="danger">
<template #default="{ trigger }">
<div ref="target" v-bind="trigger"></div>
<slot :trigger></slot>
</template>
</OnyxTooltip>

<!--
sends the given component to the desired target without destroying the component
the "v-if" is needed to support server side rendering
-->
<Teleport v-if="target" :to="target" defer>
<slot></slot>
</Teleport>
</div>
</template>

<style lang="scss">
@use "../../styles/mixins/layers";

.onyx-error-tooltip {
@include layers.component() {
max-width: 100%;
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts" setup>
import type { FormMessages } from "../../composables/useFormElementError.js";
import OnyxErrorTooltip from "./OnyxErrorTooltip.vue";

const props = defineProps<{
errorMessages?: FormMessages;
disabled?: boolean;
}>();
</script>

<template>
<OnyxErrorTooltip v-bind="props">
<template #default="{ trigger }">
<button v-bind="trigger" type="button">Dummy button</button>
</template>
</OnyxErrorTooltip>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,33 @@ useAutofocus(input, props);
</div>

<OnyxErrorTooltip v-else :disabled="disabled" :error-messages="errorMessages" v-bind="rootAttrs">
<label :class="['onyx-component', 'onyx-radio-button', densityClass]">
<OnyxLoadingIndicator v-if="props.loading" class="onyx-radio-button__loading" type="circle" />
<!-- TODO: accessible error: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-errormessage -->
<input
v-else
ref="input"
v-custom-validity
class="onyx-radio-button__selector"
type="radio"
:required="props.required"
:name="props.name"
:value="props.value"
:checked="props.checked"
:disabled="disabled"
:autofocus="props.autofocus"
v-bind="restAttrs"
/>
<span class="onyx-radio-button__label" :class="[`onyx-truncation-${props.truncation}`]">
{{ props.label }}
</span>
</label>
<template #default="{ trigger }">
<label :class="['onyx-component', 'onyx-radio-button', densityClass]" v-bind="trigger">
<OnyxLoadingIndicator
v-if="props.loading"
class="onyx-radio-button__loading"
type="circle"
/>
<!-- TODO: accessible error: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-errormessage -->
<input
v-else
ref="input"
v-custom-validity
class="onyx-radio-button__selector"
type="radio"
:required="props.required"
:name="props.name"
:value="props.value"
:checked="props.checked"
:disabled="disabled"
:autofocus="props.autofocus"
v-bind="restAttrs"
/>
<span class="onyx-radio-button__label" :class="[`onyx-truncation-${props.truncation}`]">
{{ props.label }}
</span>
</label>
</template>
</OnyxErrorTooltip>
</template>

Expand Down
Loading