{
}
};
const testA11y = () => {
+ test('should have same aria-snapshot', async ({ mount }, testInfo) => {
+ const component = await mount(defaultComp);
+ const snapshot = await component.ariaSnapshot();
+ expect(snapshot).toMatchSnapshot(`${testInfo.testId}.yaml`);
+ });
test('should not have A11y issues', async ({ page, mount }) => {
await mount(defaultComp);
const accessibilityScanResults = await new AxeBuilder({ page })
diff --git a/packages/components/src/components/card/model.ts b/packages/components/src/components/card/model.ts
index 14622939e39..24b43061578 100644
--- a/packages/components/src/components/card/model.ts
+++ b/packages/components/src/components/card/model.ts
@@ -18,6 +18,9 @@ export type DBCardDefaultProps = {
*/
behaviour?: CardBehaviourType;
+ /**
+ * Changes the elevation of the card which is equal to `basic-background-level`
+ */
elevationLevel?: CardElevationLevelType;
};
diff --git a/packages/components/src/components/checkbox/checkbox-web-component.scss b/packages/components/src/components/checkbox/checkbox-web-component.scss
deleted file mode 100644
index f1b786acb95..00000000000
--- a/packages/components/src/components/checkbox/checkbox-web-component.scss
+++ /dev/null
@@ -1 +0,0 @@
-@forward "checkbox";
diff --git a/packages/components/src/components/checkbox/checkbox.lite.tsx b/packages/components/src/components/checkbox/checkbox.lite.tsx
index 2990ddb59db..36f058f316d 100644
--- a/packages/components/src/components/checkbox/checkbox.lite.tsx
+++ b/packages/components/src/components/checkbox/checkbox.lite.tsx
@@ -4,10 +4,18 @@ import {
Show,
useMetadata,
useRef,
- useStore
+ useStore,
+ useTarget
} from '@builder.io/mitosis';
import { DBCheckboxProps, DBCheckboxState } from './model';
-import { cls, uuid } from '../../utils';
+import {
+ cls,
+ delay,
+ stringPropVisible,
+ getHideProp,
+ hasVoiceOver,
+ uuid
+} from '../../utils';
import {
DEFAULT_INVALID_MESSAGE,
DEFAULT_INVALID_MESSAGE_ID_SUFFIX,
@@ -17,10 +25,12 @@ import {
} from '../../shared/constants';
import { ChangeEvent, InteractionEvent } from '../../shared/model';
import { handleFrameworkEvent } from '../../utils/form-components';
-import { DBInfotext } from '../infotext';
+import DBInfotext from '../infotext/infotext.lite';
useMetadata({
- isAttachedToShadowDom: true
+ angular: {
+ nativeAttributes: ['disabled', 'required', 'checked', 'indeterminate']
+ }
});
export default function DBCheckbox(props: DBCheckboxProps) {
@@ -28,11 +38,12 @@ export default function DBCheckbox(props: DBCheckboxProps) {
// jscpd:ignore-start
const state = useStore
({
initialized: false,
- _id: 'checkbox-' + uuid(),
- _messageId: this._id + DEFAULT_MESSAGE_ID_SUFFIX,
- _validMessageId: this._id + DEFAULT_VALID_MESSAGE_ID_SUFFIX,
- _invalidMessageId: this._id + DEFAULT_INVALID_MESSAGE_ID_SUFFIX,
+ _id: undefined,
+ _messageId: undefined,
+ _validMessageId: undefined,
+ _invalidMessageId: undefined,
_descByIds: '',
+ _voiceOverFallback: '',
handleChange: (event: ChangeEvent) => {
if (props.onChange) {
props.onChange(event);
@@ -41,17 +52,33 @@ export default function DBCheckbox(props: DBCheckboxProps) {
if (props.change) {
props.change(event);
}
- handleFrameworkEvent(this, event, 'checked');
+
+ useTarget({
+ angular: () => handleFrameworkEvent(this, event, 'checked'),
+ vue: () => handleFrameworkEvent(this, event, 'checked')
+ });
/* For a11y reasons we need to map the correct message with the checkbox */
- if (!ref?.validity.valid || props.customValidity === 'invalid') {
+ if (!ref?.validity.valid || props.validation === 'invalid') {
state._descByIds = state._invalidMessageId;
+ if (hasVoiceOver()) {
+ state._voiceOverFallback =
+ props.invalidMessage ??
+ ref?.validationMessage ??
+ DEFAULT_INVALID_MESSAGE;
+ delay(() => (state._voiceOverFallback = ''), 1000);
+ }
} else if (
- props.customValidity === 'valid' ||
+ props.validation === 'valid' ||
(ref?.validity.valid && props.required)
) {
state._descByIds = state._validMessageId;
- } else if (props.message) {
+ if (hasVoiceOver()) {
+ state._voiceOverFallback =
+ props.validMessage ?? DEFAULT_VALID_MESSAGE;
+ delay(() => (state._voiceOverFallback = ''), 1000);
+ }
+ } else if (stringPropVisible(props.message, props.showMessage)) {
state._descByIds = state._messageId;
} else {
state._descByIds = '';
@@ -79,20 +106,22 @@ export default function DBCheckbox(props: DBCheckboxProps) {
onMount(() => {
state.initialized = true;
- state._id = props.id || state._id;
+ const mId = props.id ?? `checkbox-${uuid()}`;
+ state._id = mId;
+ state._messageId = mId + DEFAULT_MESSAGE_ID_SUFFIX;
+ state._validMessageId = mId + DEFAULT_VALID_MESSAGE_ID_SUFFIX;
+ state._invalidMessageId = mId + DEFAULT_INVALID_MESSAGE_ID_SUFFIX;
});
onUpdate(() => {
if (state._id) {
const messageId = state._id + DEFAULT_MESSAGE_ID_SUFFIX;
- const validMessageId = state._id + DEFAULT_VALID_MESSAGE_ID_SUFFIX;
- const invalidMessageId =
- state._id + DEFAULT_INVALID_MESSAGE_ID_SUFFIX;
state._messageId = messageId;
- state._validMessageId = validMessageId;
- state._invalidMessageId = invalidMessageId;
+ state._validMessageId = state._id + DEFAULT_VALID_MESSAGE_ID_SUFFIX;
+ state._invalidMessageId =
+ state._id + DEFAULT_INVALID_MESSAGE_ID_SUFFIX;
- if (props.message) {
+ if (stringPropVisible(props.message, props.showMessage)) {
state._descByIds = messageId;
}
}
@@ -123,13 +152,13 @@ export default function DBCheckbox(props: DBCheckboxProps) {
return (
+ data-hide-label={getHideProp(props.showLabel)}>
-
+
+
+ {/* * https://www.davidmacd.com/blog/test-aria-describedby-errormessage-aria-live.html
+ * Currently VoiceOver isn't supporting changes from aria-describedby.
+ * This is an internal Fallback */}
+
+ {state._voiceOverFallback}
+
);
}
diff --git a/packages/components/src/components/checkbox/checkbox.scss b/packages/components/src/components/checkbox/checkbox.scss
index 286baf065c4..26aca44bdce 100644
--- a/packages/components/src/components/checkbox/checkbox.scss
+++ b/packages/components/src/components/checkbox/checkbox.scss
@@ -6,30 +6,48 @@
@use "../../styles/component";
@use "../../styles/form-components";
+%center-icon {
+ &::before {
+ --db-icon-margin-end: 0;
+
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ block-size: calc(
+ #{form-components.$font-size-height} - 2 *
+ #{variables.$db-border-height-3xs}
+ );
+ inline-size: calc(
+ #{form-components.$font-size-height} - 2 *
+ #{variables.$db-border-height-3xs}
+ );
+ }
+}
+
.db-checkbox {
@extend %helper-message;
@include form-components.set-default-check-element(check);
input {
+ display: flex;
border-radius: variables.$db-border-radius-2xs;
+ margin-block: auto;
+ align-items: center;
+ justify-content: center;
- &::before {
- --db-icon-margin-end: 0;
+ &:checked {
+ --db-check-element-border-color: #{colors.$db-adaptive-on-bg-basic-emphasis-70-default};
- position: absolute;
- inset-inline: 0;
- inset-block: 0;
- }
+ @extend %center-icon;
- &:checked {
// Check icon
@include icons.set-icon("check");
@include colors.set-current-colors(
- colors.$db-current-color-on-bg-enabled,
- colors.$db-current-color-bg-lvl-1-enabled,
- colors.$db-current-color-on-bg-hover,
- colors.$db-current-color-on-bg-pressed
+ colors.$db-adaptive-bg-inverted-contrast-max-default,
+ colors.$db-adaptive-on-bg-inverted-default,
+ colors.$db-adaptive-bg-inverted-contrast-max-hovered,
+ colors.$db-adaptive-bg-inverted-contrast-max-pressed
);
// The icon within the checkbox has the same dimensions as the checkbox itself and that for there can't be any border
@@ -37,20 +55,23 @@
}
&:indeterminate {
+ @extend %center-icon;
+
@include icons.set-icon("minus");
}
@media (forced-colors: active) {
&:indeterminate,
&:checked {
- --db-check-element-border-color: #{colors.$db-current-color-on-bg-enabled};
+ --db-check-element-border-color: #{colors.$db-adaptive-on-bg-basic-emphasis-100-default};
border-width: form-components.$check-border-size;
- &::before {
+ &:not([data-hide-icon-before="true"])::before {
align-content: center;
font-size: calc(
- var(--db-icon-font-size) - 2 * #{form-components.$check-border-size}
+ var(--db-icon-font-size) - 2 *
+ #{form-components.$check-border-size}
);
padding: #{form-components.$check-border-size};
}
diff --git a/packages/components/src/components/checkbox/checkbox.spec.tsx b/packages/components/src/components/checkbox/checkbox.spec.tsx
index 479ba6fc584..4ed1db11dc2 100644
--- a/packages/components/src/components/checkbox/checkbox.spec.tsx
+++ b/packages/components/src/components/checkbox/checkbox.spec.tsx
@@ -1,4 +1,4 @@
-import { test, expect } from '@playwright/experimental-ct-react';
+import { expect, test } from '@playwright/experimental-ct-react';
import AxeBuilder from '@axe-core/playwright';
import { DBCheckbox } from './index';
@@ -19,6 +19,15 @@ const testComponent = () => {
});
};
const testA11y = () => {
+ test('should have same aria-snapshot', async ({ mount }, testInfo) => {
+ const component = await mount(comp);
+ const snapshot = await component.ariaSnapshot();
+ // Some wired issue with react and playwright ariaSnapshot in this case
+ const playwrightReactIssueFix = snapshot.replace(': "on"', '');
+ expect(playwrightReactIssueFix).toMatchSnapshot(
+ `${testInfo.testId}.yaml`
+ );
+ });
test('should not have A11y issues', async ({ page, mount }) => {
await mount(comp);
const accessibilityScanResults = await new AxeBuilder({ page })
diff --git a/packages/components/src/components/checkbox/model.ts b/packages/components/src/components/checkbox/model.ts
index 27d2af17afe..da6786d153b 100644
--- a/packages/components/src/components/checkbox/model.ts
+++ b/packages/components/src/components/checkbox/model.ts
@@ -13,12 +13,12 @@ import {
SizeProps
} from '../../shared/model';
-export interface DBCheckboxDefaultProps {
+export type DBCheckboxDefaultProps = {
/**
* Define an [indeterminate](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#indeterminate) state of a checkbox
*/
indeterminate?: boolean;
-}
+};
export type DBCheckboxProps = DBCheckboxDefaultProps &
GlobalProps &
diff --git a/packages/components/src/components/divider/divider-web-component.scss b/packages/components/src/components/divider/divider-web-component.scss
deleted file mode 100644
index 76adbe55af8..00000000000
--- a/packages/components/src/components/divider/divider-web-component.scss
+++ /dev/null
@@ -1 +0,0 @@
-@forward "divider";
diff --git a/packages/components/src/components/divider/divider.lite.tsx b/packages/components/src/components/divider/divider.lite.tsx
index fd79090d603..b332eebf73e 100644
--- a/packages/components/src/components/divider/divider.lite.tsx
+++ b/packages/components/src/components/divider/divider.lite.tsx
@@ -2,9 +2,7 @@ import { useMetadata, useRef, useStore } from '@builder.io/mitosis';
import { DBDividerProps, DBDividerState } from './model';
import { cls } from '../../utils';
-useMetadata({
- isAttachedToShadowDom: true
-});
+useMetadata({});
export default function DBDivider(props: DBDividerProps) {
const ref = useRef(null);
@@ -20,6 +18,7 @@ export default function DBDivider(props: DBDividerProps) {
data-margin={props.margin}
data-variant={props.variant}
data-emphasis={props.emphasis}
+ data-width={props.width}
class={cls('db-divider', props.className)}
/>
);
diff --git a/packages/components/src/components/divider/divider.scss b/packages/components/src/components/divider/divider.scss
index 4e7d7e51809..fdf3d726d14 100644
--- a/packages/components/src/components/divider/divider.scss
+++ b/packages/components/src/components/divider/divider.scss
@@ -2,25 +2,55 @@
@use "@db-ui/foundations/build/scss/helpers";
.db-divider {
- &:not([data-margin="none"]) {
+ &:is(:not([data-margin]), [data-margin="small"]) {
margin: variables.$db-spacing-fixed-sm 0;
}
+ &[data-margin="medium"] {
+ margin: variables.$db-spacing-fixed-md 0;
+ }
+
+ &[data-margin="large"] {
+ margin: variables.$db-spacing-fixed-lg 0;
+ }
+
+ &[data-margin="none"] {
+ margin: 0;
+ }
+
&:not([data-variant="vertical"]) {
@include helpers.divider();
block-size: variables.$db-border-height-3xs;
- inline-size: 100%;
+
+ &[data-width="full"] {
+ inline-size: 100%;
+ }
}
&[data-variant="vertical"] {
@include helpers.divider("left");
- block-size: 100%;
inline-size: variables.$db-border-height-3xs;
- &:not([data-margin="none"]) {
+ &:is(:not([data-margin]), [data-margin="small"]) {
margin: 0 variables.$db-spacing-fixed-sm;
}
+
+ &[data-margin="medium"] {
+ margin: 0 variables.$db-spacing-fixed-md;
+ }
+
+ &[data-margin="large"] {
+ margin: 0 variables.$db-spacing-fixed-lg;
+ }
+
+ &[data-margin="none"] {
+ margin: 0;
+ }
+
+ &[data-width="full"] {
+ block-size: 100%;
+ }
}
}
diff --git a/packages/components/src/components/divider/divider.spec.tsx b/packages/components/src/components/divider/divider.spec.tsx
index 6021661d23d..3a29df7ac83 100644
--- a/packages/components/src/components/divider/divider.spec.tsx
+++ b/packages/components/src/components/divider/divider.spec.tsx
@@ -1,4 +1,4 @@
-import { test, expect } from '@playwright/experimental-ct-react';
+import { expect, test } from '@playwright/experimental-ct-react';
import AxeBuilder from '@axe-core/playwright';
import { DBDivider } from './index';
@@ -22,6 +22,11 @@ const testComponent = () => {
});
};
const testA11y = () => {
+ test('should have same aria-snapshot', async ({ mount }, testInfo) => {
+ const component = await mount(comp);
+ const snapshot = await component.ariaSnapshot();
+ expect(snapshot).toMatchSnapshot(`${testInfo.testId}.yaml`);
+ });
test('should not have any A11y issues', async ({ page, mount }) => {
await mount(comp);
const accessibilityScanResults = await new AxeBuilder({ page })
diff --git a/packages/components/src/components/divider/model.ts b/packages/components/src/components/divider/model.ts
index 7a572b869e7..dc7c33da7e0 100644
--- a/packages/components/src/components/divider/model.ts
+++ b/packages/components/src/components/divider/model.ts
@@ -1,4 +1,10 @@
-import { EmphasisProps, GlobalProps, GlobalState } from '../../shared/model';
+import {
+ EmphasisProps,
+ GlobalProps,
+ GlobalState,
+ MarginProps,
+ WidthProps
+} from '../../shared/model';
export const DividerMarginList = ['none', '_'] as const;
export type DividerMarginType = (typeof DividerMarginList)[number];
@@ -7,13 +13,21 @@ export const DividerVariantList = ['horizontal', 'vertical'] as const;
export type DividerVariantType = (typeof DividerVariantList)[number];
export type DBDividerDefaultProps = {
+ /**
+ * Removes the margin of the divider.
+ */
margin?: DividerMarginType;
+ /**
+ * Changes the orientation of the divider.
+ */
variant?: DividerVariantType;
};
export type DBDividerProps = DBDividerDefaultProps &
GlobalProps &
- EmphasisProps;
+ EmphasisProps &
+ MarginProps &
+ WidthProps;
export type DBDividerDefaultState = {};
diff --git a/packages/components/src/components/drawer/docs/Angular.md b/packages/components/src/components/drawer/docs/Angular.md
index 2e315d0bc3e..069ffcb3649 100644
--- a/packages/components/src/components/drawer/docs/Angular.md
+++ b/packages/components/src/components/drawer/docs/Angular.md
@@ -25,10 +25,11 @@ import { DBDrawer } from '@db-ui/ngx-components';
```html app.component.html
+ Open me
+
My Drawer content
- Open me
```
```ts app.component.ts
diff --git a/packages/components/src/components/drawer/docs/React.md b/packages/components/src/components/drawer/docs/React.md
index 87010b96f88..6861bb14240 100644
--- a/packages/components/src/components/drawer/docs/React.md
+++ b/packages/components/src/components/drawer/docs/React.md
@@ -17,21 +17,22 @@ const App = () => {
const [open, setOpen] = useState(false);
return (
+ {
+ setOpen(true);
+ }}
+ >
+ Open Me
+
{
setOpen(false);
}}
+ drawerHeader={}
>
My Drawer content
- {
- setOpen(true);
- }}
- >
- Open Me
-
);
};
diff --git a/packages/components/src/components/drawer/docs/Vue.md b/packages/components/src/components/drawer/docs/Vue.md
index 6920b4c1c29..31c2b265cd5 100644
--- a/packages/components/src/components/drawer/docs/Vue.md
+++ b/packages/components/src/components/drawer/docs/Vue.md
@@ -22,9 +22,10 @@ const toggleDrawer = (open: boolean) => {
+ Open me
+
My Drawer content
- Open me
```
diff --git a/packages/components/src/components/drawer/drawer-web-component.scss b/packages/components/src/components/drawer/drawer-web-component.scss
deleted file mode 100644
index 65995a5369c..00000000000
--- a/packages/components/src/components/drawer/drawer-web-component.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-@use "@db-ui/foundations/build/scss/helpers/functions";
-
-@forward "../../styles/dialog-init";
-@forward "drawer";
diff --git a/packages/components/src/components/drawer/drawer.lite.tsx b/packages/components/src/components/drawer/drawer.lite.tsx
index 0b3bab71b2d..8e57502963c 100644
--- a/packages/components/src/components/drawer/drawer.lite.tsx
+++ b/packages/components/src/components/drawer/drawer.lite.tsx
@@ -1,20 +1,17 @@
import {
onMount,
onUpdate,
- Show,
Slot,
useMetadata,
useRef,
useStore
} from '@builder.io/mitosis';
import { DBDrawerProps, DBDrawerState } from './model';
-import { DBButton } from '../button';
+import DBButton from '../button/button.lite';
import { DEFAULT_CLOSE_BUTTON } from '../../shared/constants';
-import { cls } from '../../utils';
+import { cls, delay } from '../../utils';
-useMetadata({
- isAttachedToShadowDom: true
-});
+useMetadata({});
export default function DBDrawer(props: DBDrawerProps) {
const ref = useRef(null);
@@ -44,7 +41,10 @@ export default function DBDrawer(props: DBDrawerProps) {
if (dialogContainerRef) {
dialogContainerRef.hidden = false;
}
- if (props.backdrop === 'none') {
+ if (
+ props.backdrop === 'none' ||
+ props.variant === 'inside'
+ ) {
ref.show();
} else {
ref.showModal();
@@ -54,7 +54,7 @@ export default function DBDrawer(props: DBDrawerProps) {
if (dialogContainerRef) {
dialogContainerRef.hidden = true;
}
- setTimeout(() => {
+ delay(() => {
if (dialogContainerRef) {
dialogContainerRef.hidden = false;
}
@@ -82,7 +82,8 @@ export default function DBDrawer(props: DBDrawerProps) {
state.handleClose(event);
}}
onKeyDown={(event) => state.handleClose(event)}
- data-backdrop={props.backdrop}>
+ data-backdrop={props.backdrop}
+ data-variant={props.variant}>