Skip to content

refactor: align how to use a DBCard as button or link #4506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6d72b42
feat: align how to use a DBCard as button or anchor
nmerget Jul 9, 2025
9b74f0b
Merge branch '3.0-release' into feat-card-inside-button
nmerget Jul 9, 2025
4fe9e4a
auto update snapshots (#4507)
github-actions[bot] Jul 9, 2025
41f2947
chore: update interactive card
nmerget Jul 11, 2025
5ea2877
auto update snapshots (#4525)
github-actions[bot] Jul 11, 2025
89fa873
Merge branch '3.0-release' into feat-card-inside-button
nmerget Jul 15, 2025
ae7560d
Update docs/migration/v2.x.x-to-v3.0.0.md
nmerget Jul 16, 2025
af2a3b7
Update docs/migration/v2.x.x-to-v3.0.0.md
nmerget Jul 16, 2025
506e194
Update showcases/vue-showcase/src/components/card/Card.vue
nmerget Jul 16, 2025
f3e29c2
Update showcases/react-showcase/src/components/card/index.tsx
nmerget Jul 16, 2025
2591024
Update showcases/angular-showcase/src/app/components/card/card.compon…
nmerget Jul 16, 2025
acc2c73
feat: add auto interactive mode when wrapping card in button or anchor
nmerget Jul 16, 2025
a9d2eac
fix: linting issue
nmerget Jul 16, 2025
9c5665e
feat: added playground page (#4543)
mfranzke Jul 16, 2025
1c34736
Revert "feat: added playground page (#4543)"
mfranzke Jul 16, 2025
2a72ce6
chore: run format
nmerget Jul 17, 2025
97641b7
Merge remote-tracking branch 'origin/feat-card-inside-button' into fe…
nmerget Jul 17, 2025
40886b8
fix: linting issue
nmerget Jul 17, 2025
ee845a1
auto update snapshots (#4558)
github-actions[bot] Jul 17, 2025
2a6d0f1
Apply suggestions from code review
mfranzke Jul 17, 2025
fd6e125
Update v2.x.x-to-v3.0.0.md
mfranzke Jul 17, 2025
775c114
refactor: prettier
mfranzke Jul 17, 2025
933fad1
auto update snapshots (#4563)
github-actions[bot] Jul 17, 2025
1a1d77d
Merge remote-tracking branch 'origin/3.0-release' into feat-card-insi…
nmerget Jul 18, 2025
f173b4c
fix: issue with vue showcase
nmerget Jul 18, 2025
4df2a02
Merge branch '3.0-release' into feat-card-inside-button
mfranzke Jul 18, 2025
d1f8b92
refactor: reformatting
mfranzke Jul 18, 2025
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
24 changes: 24 additions & 0 deletions docs/migration/v2.x.x-to-v3.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@ Please provide the correct `type` property in your code anyhow as a best practis
We removed the `state` property from the `db-button`/`DBButton` component for now.
It wasn't implemented in any framework causing some confusion, and we will reintroduce it in a future version.


## db-card/DBCard

### `behavior='interactive'` change

We changed the `behavior='interactive'` property not applying `role='button'` and `tabIndex` anymore.
If you want to use an interactive card, you should wrap the card with the correct HTML element, like a `button` or an `a` HTML tag:

```html
<!--Angular-->
<button type="button">
<db-card behavior="interactive">
<!-- card content -->
</db-card>
</button>

<!--React/Vue-->
<button type="button">
<DBCard behavior="interactive">
<!-- card content -->
</DBCard>
</button>
```

## breakpoints

We updated some breakpoints to align with design:
Expand Down
2 changes: 0 additions & 2 deletions packages/components/src/components/card/card.lite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ export default function DBCard(props: DBCardProps) {
data-behavior={props.behavior}
data-elevation-level={props.elevationLevel}
data-spacing={props.spacing}
role={props.behavior === 'interactive' ? 'button' : undefined}
tabIndex={props.behavior === 'interactive' ? 0 : undefined}
onClick={(event: ClickEvent<HTMLElement>) =>
state.handleClick(event)
}>
Expand Down
70 changes: 37 additions & 33 deletions packages/components/src/components/card/card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,58 @@
@use "@db-ux/core-foundations/build/styles/helpers";
@use "../../styles/internal/component";

:is(a, button) {
&:has(.db-card) {
all: unset;
}

@include helpers.hover {
> .db-card,
> db-card > .db-card {
background-color: var(--db-card-background-color-hovered);
}
}

@include helpers.active {
> .db-card,
> db-card > .db-card {
background-color: var(--db-card-background-color-pressed);
}
}
}

.db-card {
--db-card-background-color-default: #{colors.$db-adaptive-bg-basic-level-1-default};
--db-card-background-color-hovered: #{colors.$db-adaptive-bg-basic-level-1-hovered};
--db-card-background-color-pressed: #{colors.$db-adaptive-bg-basic-level-1-pressed};

@extend %default-card;

@include component.get-data-spacing();

display: flex;
flex-direction: column;
background-color: var(--db-card-background-color-default);

&[data-elevation-level="1"],
&:not([data-elevation-level]) {
background-color: colors.$db-adaptive-bg-basic-level-1-default;

&[data-behavior="interactive"] {
@include helpers.hover {
background-color: colors.$db-adaptive-bg-basic-level-1-hovered;
}
&[data-behavior="interactive"] {
@include helpers.hover {
background-color: var(--db-card-background-color-hovered);
}

@include helpers.active {
background-color: colors.$db-adaptive-bg-basic-level-1-pressed;
}
@include helpers.active {
background-color: var(--db-card-background-color-pressed);
}
}

&[data-elevation-level="2"] {
background-color: colors.$db-adaptive-bg-basic-level-2-default;

&[data-behavior="interactive"] {
@include helpers.hover {
background-color: colors.$db-adaptive-bg-basic-level-2-hovered;
}

@include helpers.active {
background-color: colors.$db-adaptive-bg-basic-level-2-pressed;
}
}
--db-card-background-color-default: #{colors.$db-adaptive-bg-basic-level-2-default};
--db-card-background-color-hovered: #{colors.$db-adaptive-bg-basic-level-2-hovered};
--db-card-background-color-pressed: #{colors.$db-adaptive-bg-basic-level-2-pressed};
}

&[data-elevation-level="3"] {
background-color: colors.$db-adaptive-bg-basic-level-3-default;

&[data-behavior="interactive"] {
@include helpers.hover {
background-color: colors.$db-adaptive-bg-basic-level-3-hovered;
}

@include helpers.active {
background-color: colors.$db-adaptive-bg-basic-level-3-pressed;
}
}
--db-card-background-color-default: #{colors.$db-adaptive-bg-basic-level-3-default};
--db-card-background-color-hovered: #{colors.$db-adaptive-bg-basic-level-3-hovered};
--db-card-background-color-pressed: #{colors.$db-adaptive-bg-basic-level-3-pressed};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,24 @@
let-exampleIndex="exampleIndex"
let-variantIndex="variantIndex"
>
<db-card
[behavior]="exampleProps?.behavior"
[elevationLevel]="exampleProps?.elevationLevel"
[spacing]="exampleProps?.spacing"
>
<strong>{{ exampleName }}</strong>
</db-card>
@if (exampleProps?.behavior === "interactive") {
<button type="button">
<db-card
[behavior]="exampleProps?.behavior"
[elevationLevel]="exampleProps?.elevationLevel"
[spacing]="exampleProps?.spacing"
>
<strong>{{ exampleName }}</strong>
</db-card>
</button>
} @else {
<db-card
[behavior]="exampleProps?.behavior"
[elevationLevel]="exampleProps?.elevationLevel"
[spacing]="exampleProps?.spacing"
>
<strong>{{ exampleName }}</strong>
</db-card>
}
</ng-template>
</app-default-component>
40 changes: 23 additions & 17 deletions showcases/react-showcase/src/components/card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,31 @@ const getCard = ({
children,
spacing,
elevationLevel
}: DBCardProps) => (
<DBCard
behavior={behavior}
spacing={spacing}
elevationLevel={elevationLevel}>
<strong>{children}</strong>
</DBCard>
);
}: DBCardProps) => {
const card = (
<DBCard
behavior={behavior}
spacing={spacing}
elevationLevel={elevationLevel}>
<strong>{children}</strong>
</DBCard>
);

const CardComponent = (props: BaseComponentProps) => {
return (
<DefaultComponent
title={'DBCard'}
variants={getVariants(
defaultComponentVariants,
getCard,
props.slotCode
)}></DefaultComponent>
return behavior === 'interactive' ? (
<button type="button">{card}</button>
) : (
card
);
};

const CardComponent = (properties: BaseComponentProps) => (
<DefaultComponent
title={'DBCard'}
variants={getVariants(
defaultComponentVariants,
getCard,
properties.slotCode
)}></DefaultComponent>
);

export default CardComponent;
13 changes: 13 additions & 0 deletions showcases/vue-showcase/src/components/card/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,20 @@ import DefaultComponent from "../DefaultComponent.vue";
<template
#example="{ exampleIndex, variantIndex, exampleName, exampleProps }"
>
<button
type="button"
v-if="exampleProps?.behavior === 'interactive'"
>
<DBCard
:behavior="exampleProps?.behavior"
:elevationLevel="exampleProps?.elevationLevel"
:spacing="exampleProps?.spacing"
>
<strong>{{ exampleName }}</strong>
</DBCard>
</button>
<DBCard
v-if="exampleProps?.behavior !== 'interactive'"
:behavior="exampleProps?.behavior"
:elevationLevel="exampleProps?.elevationLevel"
:spacing="exampleProps?.spacing"
Expand Down