diff --git a/apps/cookbook/src/app/examples/card-example/card-example.module.ts b/apps/cookbook/src/app/examples/card-example/card-example.module.ts new file mode 100644 index 0000000000..ae918eea7d --- /dev/null +++ b/apps/cookbook/src/app/examples/card-example/card-example.module.ts @@ -0,0 +1,27 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { KirbyModule } from '@kirbydesign/designsystem'; + +import { CardExampleComponent } from './card-example.component'; +import { CardBackgroundImageExampleComponent } from './examples/card-background-image-example.component'; +import { CardClickableExampleComponent } from './examples/card-clickable-example/card-clickable-example.component'; +import { CardCssBackgroundImageExampleComponent } from './examples/card-css-background-image-example/card-css-background-image-example.component'; +import { CardElevationsExampleComponent } from './examples/card-elevations-example/card-elevations-example.component'; +import { CardThemecolorExampleComponent } from './examples/card-themecolor-example/card-themecolor-example.component'; + +const COMPONENT_DECLARATIONS = [ + CardExampleComponent, + CardClickableExampleComponent, + CardElevationsExampleComponent, + CardThemecolorExampleComponent, + CardBackgroundImageExampleComponent, + CardCssBackgroundImageExampleComponent, +]; + +@NgModule({ + declarations: COMPONENT_DECLARATIONS, + imports: [CommonModule, KirbyModule], + exports: COMPONENT_DECLARATIONS, +}) +export class CardExampleModule {} diff --git a/apps/cookbook/src/app/examples/card-example/examples/card-background-image-example.component.ts b/apps/cookbook/src/app/examples/card-example/examples/card-background-image-example.component.ts new file mode 100644 index 0000000000..50e0dd51c6 --- /dev/null +++ b/apps/cookbook/src/app/examples/card-example/examples/card-background-image-example.component.ts @@ -0,0 +1,33 @@ +import { Component } from '@angular/core'; + +const config = { + selector: 'cookbook-card-background-image-example', + template: ` +

+ Example using input property to set background +

+

+ Lorem, ipsum dolor sit amet consectetur adipisicing elit. Mollitia facere molestias recusandae + necessitatibus ab veniam repellendus doloremque culpa quam libero, est quo accusamus cumque, in + quia itaque cupiditate ratione repellat! +

+
`, + style: `kirby-card { + min-height: 300px; +} +`, +}; + +@Component({ + selector: config.selector, + template: config.template, + styles: [config.style], +}) +export class CardBackgroundImageExampleComponent { + template: string = config.template; + style: string = config.style; +} diff --git a/apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.html b/apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.html similarity index 100% rename from apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.html rename to apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.html diff --git a/apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.scss b/apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.scss similarity index 100% rename from apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.scss rename to apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.scss diff --git a/apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.ts b/apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.ts similarity index 100% rename from apps/cookbook/src/app/examples/card/card-clickable-example/card-clickable-example.component.ts rename to apps/cookbook/src/app/examples/card-example/examples/card-clickable-example/card-clickable-example.component.ts diff --git a/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.scss b/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.scss new file mode 100644 index 0000000000..a0b1d5b7c3 --- /dev/null +++ b/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.scss @@ -0,0 +1,25 @@ +/* + In order to use sass functionality the styles for this example + has to be stored in a seperate scss file. Otherwise the preprocessor + won't kick in. + */ +@use '~@kirbydesign/core/src/scss/utils'; + +kirby-card { + --kirby-card-background-image: linear-gradient( + 0deg, + rgba(255, 255, 255, 0) 0%, + rgba(0, 0, 0, 0.6) 100% + ), + url('https://images.unsplash.com/photo-1512917774080-9991f1c4c750'); + + @include utils.media('>=medium') { + --kirby-card-background-image: linear-gradient( + 0deg, + rgba(255, 255, 255, 0) 0%, + rgba(0, 0, 0, 0.4) 100% + ), + url('https://images.unsplash.com/photo-1560840067-ddcaeb7831d2'); + } + min-height: 300px; +} diff --git a/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.ts b/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.ts new file mode 100644 index 0000000000..d971566ffd --- /dev/null +++ b/apps/cookbook/src/app/examples/card-example/examples/card-css-background-image-example/card-css-background-image-example.component.ts @@ -0,0 +1,46 @@ +import { Component } from '@angular/core'; + +const config = { + selector: 'cookbook-card-css-background-image-example', + template: ` + +

+ Example using custom css property to set background +

+

+ Lorem, ipsum dolor sit amet consectetur adipisicing elit. Mollitia facere molestias recusandae necessitatibus ab veniam repellendus doloremque culpa quam libero, est quo accusamus cumque, in quia itaque cupiditate ratione repellat! +

+
+ `, + style: `@use '~@kirbydesign/core/src/scss/utils'; + +kirby-card { + min-height: 300px; + + --kirby-card-background-image: linear-gradient( + 0deg, + rgba(255, 255, 255, 0) 0%, + rgba(0, 0, 0, 0.6) 100% + ), + url('https://images.unsplash.com/photo-1512917774080-9991f1c4c750'); + + @include utils.media('>=medium') { + --kirby-card-background-image: linear-gradient( + 0deg, + rgba(255, 255, 255, 0) 0%, + rgba(0, 0, 0, 0.4) 100% + ), + url('https://images.unsplash.com/photo-1560840067-ddcaeb7831d2'); + } +}`, +}; + +@Component({ + selector: config.selector, + template: config.template, + styleUrls: ['./card-css-background-image-example.component.scss'], +}) +export class CardCssBackgroundImageExampleComponent { + template: string = config.template; + style: string = config.style; +} diff --git a/apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.html b/apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.html similarity index 100% rename from apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.html rename to apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.html diff --git a/apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.scss b/apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.scss similarity index 100% rename from apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.scss rename to apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.scss diff --git a/apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.ts b/apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.ts similarity index 100% rename from apps/cookbook/src/app/examples/card/card-elevations-example/card-elevations-example.component.ts rename to apps/cookbook/src/app/examples/card-example/examples/card-elevations-example/card-elevations-example.component.ts diff --git a/apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.html b/apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.html similarity index 100% rename from apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.html rename to apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.html diff --git a/apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.scss b/apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.scss similarity index 100% rename from apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.scss rename to apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.scss diff --git a/apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.ts b/apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.ts similarity index 100% rename from apps/cookbook/src/app/examples/card/card-themecolor-example/card-themecolor-example.component.ts rename to apps/cookbook/src/app/examples/card-example/examples/card-themecolor-example/card-themecolor-example.component.ts diff --git a/apps/cookbook/src/app/examples/examples.common.ts b/apps/cookbook/src/app/examples/examples.common.ts index f3fb93e58d..41ee083016 100644 --- a/apps/cookbook/src/app/examples/examples.common.ts +++ b/apps/cookbook/src/app/examples/examples.common.ts @@ -10,10 +10,6 @@ import { AvatarExampleComponent } from './avatar-example/avatar-example.componen import { ButtonExampleComponent } from './button-example/button-example.component'; import { CalendarCardExampleComponent } from './calendar-example/calendar-card-example.component'; import { CalendarExampleComponent } from './calendar-example/calendar-example.component'; -import { CardExampleComponent } from './card-example/card-example.component'; -import { CardClickableExampleComponent } from './card/card-clickable-example/card-clickable-example.component'; -import { CardElevationsExampleComponent } from './card/card-elevations-example/card-elevations-example.component'; -import { CardThemecolorExampleComponent } from './card/card-themecolor-example/card-themecolor-example.component'; import { CheckboxExampleComponent } from './checkbox-example/checkbox-example.component'; import { ChipExampleComponent } from './chip-example/chip-example.component'; import { DividerExampleComponent } from './divider-example/divider-example.component'; @@ -75,10 +71,6 @@ export const COMPONENT_DECLARATIONS: any[] = [ ExamplesComponent, ButtonExampleComponent, SlideButtonExampleComponent, - CardExampleComponent, - CardClickableExampleComponent, - CardThemecolorExampleComponent, - CardElevationsExampleComponent, ListExampleComponent, ListLoadOnDemandExampleComponent, ListSwipeExampleComponent, diff --git a/apps/cookbook/src/app/examples/examples.module.ts b/apps/cookbook/src/app/examples/examples.module.ts index 5a8d7d75a6..ff994c9c53 100644 --- a/apps/cookbook/src/app/examples/examples.module.ts +++ b/apps/cookbook/src/app/examples/examples.module.ts @@ -8,6 +8,7 @@ import { AccordionExampleModule } from './accordion-example/accordion-example.mo import { AvatarExampleModule } from './avatar-example/avatar-example.module'; import { BadgeExampleModule } from './badge-example/badge-example.module'; import { CardExampleComponent } from './card-example/card-example.component'; +import { CardExampleModule } from './card-example/card-example.module'; import { ChartDeprecatedExampleModule } from './chart-deprecated-example/chart-deprecated-example.module'; import { ChartExampleModule } from './chart-example/chart-example.module'; import { CheckboxExampleModule } from './checkbox-example/checkbox-example.module'; @@ -41,6 +42,7 @@ const IMPORTS = [ SegmentedControlExampleModule, ChartDeprecatedExampleModule, ChartExampleModule, + CardExampleModule, ItemSlidingExampleModule, BadgeExampleModule, ProgressCircleExampleModule, diff --git a/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.html b/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.html index 6a36b9ff7c..55ddd43a83 100644 --- a/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.html +++ b/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.html @@ -59,14 +59,83 @@ > -

Properties:

+

Colors

+

+ +

+ +

Elevation

+

+ +

+ +

Clickable

+

+ +

+ +

Background image

+

+ The card can use an image as a background by either using the + backgroundImageUrl input property or the + --kirby-card-background-image custom css property. +

+

Setting background image from Javascript

+

+ In this example the backgroundImageUrl input property is used for setting the + background image. Notice the poor readability as the contrast between the text and background + image is too low. This could be improved by applying a linear gradient; using the + backgroundImageUrl this would have to be done by editing the image itself. +

+

+ Furthermore using backgroundImageUrl requires a Javascript mechanism in order to + change based on viewport width. In contrast the + --kirby-card-background-image custom css property allows for media queries to be + used. +

+

+ + + + +

+

Setting background image from CSS with media queries & linear gradient

+

+ This example uses the --kirby-card-background-image custom css property to set the + background image. Furthermore a linear gradient is applied to improve the readability of the + text and a media query is used to change the image based on viewport width. +

+

+ Note: this example uses + include-media for + media queries. This is re-exported from the '@kirbydesign/core/src/scss/utils' Sass + module. +

+

+ + + +

+ + + +

API Description

+

Properties:

-

Colors:

- -

Elevation:

- -

Clickable:

- +

CSS Custom Properties

+ + diff --git a/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.ts b/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.ts index ce3c7c5451..1bbbee9293 100644 --- a/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.ts +++ b/apps/cookbook/src/app/showcase/card-showcase/card-showcase.component.ts @@ -1,5 +1,8 @@ import { Component } from '@angular/core'; -import { ApiDescriptionProperty } from '~/app/shared/api-description/api-description-properties/api-description-properties.component'; +import { + ApiDescriptionProperty, + ApiDescriptionPropertyColumns, +} from '~/app/shared/api-description/api-description-properties/api-description-properties.component'; @Component({ selector: 'cookbook-card-showcase', @@ -22,6 +25,12 @@ export class CardShowcaseComponent { defaultValue: 'null', type: ['string'], }, + { + name: 'backgroundImageUrl', + description: '(Optional) Provided a valid URL will set the background image of the card.', + defaultValue: '', + type: ['string'], + }, { name: 'mode', description: @@ -52,4 +61,32 @@ export class CardShowcaseComponent { ], }, ]; + + customCssPropertiesColumns: ApiDescriptionPropertyColumns = { + name: 'Attribute', + description: 'Description', + default: 'Default', + }; + + customCssProperties: ApiDescriptionProperty[] = [ + { + name: '--kirby-card-background-image', + description: "Sets the 'background-image' property of the card.", + }, + { + name: '--kirby-card-background-repeat', + description: "Sets the 'background-repeat' property of the card", + defaultValue: 'no-repeat', + }, + { + name: '--kirby-card-background-position', + description: "Sets the 'background-position' property of the card", + defaultValue: 'center', + }, + { + name: '--kirby-card-background-size', + description: "Sets the 'background-size' property of the card", + defaultValue: 'cover', + }, + ]; } diff --git a/libs/designsystem/src/lib/components/card/card.component.scss b/libs/designsystem/src/lib/components/card/card.component.scss index 3732509761..69ad699a92 100644 --- a/libs/designsystem/src/lib/components/card/card.component.scss +++ b/libs/designsystem/src/lib/components/card/card.component.scss @@ -10,6 +10,10 @@ box-shadow: utils.get-elevation(2); color: var(--kirby-card-main-color); background-color: var(--kirby-card-main-background-color); + background-image: var(--kirby-card-background-image); + background-repeat: var(--kirby-card-background-repeat, no-repeat); + background-position: var(--kirby-card-background-position, center); + background-size: var(--kirby-card-background-size, cover); display: flex; flex-direction: column; justify-content: space-between; diff --git a/libs/designsystem/src/lib/components/card/card.component.spec.ts b/libs/designsystem/src/lib/components/card/card.component.spec.ts index c93482c1e7..35530538cf 100644 --- a/libs/designsystem/src/lib/components/card/card.component.spec.ts +++ b/libs/designsystem/src/lib/components/card/card.component.spec.ts @@ -22,6 +22,30 @@ describe('CardComponent', () => { }); }); + describe("with 'backgroundImageUrl' set", () => { + const testUrl = 'https://notarealurl/'; + let cardElement: HTMLElement; + + beforeEach(() => { + spectator = createHost(``); + cardElement = spectator.queryHost('kirby-card'); + }); + + it("should use the url for the 'background-image' property", () => { + expect(cardElement).toHaveComputedStyle({ + 'background-image': `url("${testUrl}")`, + }); + }); + + it('should have correct defaults for properties related to background', () => { + expect(cardElement).toHaveComputedStyle({ + 'background-repeat': 'no-repeat', + 'background-position': '50% 50%', + 'background-size': 'cover', + }); + }); + }); + describe('with mode attribute', () => { beforeEach(() => { spectator = createHost(''); diff --git a/libs/designsystem/src/lib/components/card/card.component.ts b/libs/designsystem/src/lib/components/card/card.component.ts index 962de9500d..7c296a4a0c 100644 --- a/libs/designsystem/src/lib/components/card/card.component.ts +++ b/libs/designsystem/src/lib/components/card/card.component.ts @@ -20,6 +20,14 @@ export class CardComponent implements OnInit, OnDestroy { @Input() title: string; @Input() subtitle: string; + @HostBinding('style.--kirby-card-background-image') + _backgroundImage: string; + + @Input() + set backgroundImageUrl(value: string) { + this._backgroundImage = `url('${value}')`; + } + @Input() hasPadding: boolean;