Skip to content

Commit ee015cb

Browse files
committed
chore(card): handle stretched link and disabled card
1 parent 1856c31 commit ee015cb

File tree

5 files changed

+154
-40
lines changed

5 files changed

+154
-40
lines changed

index.html

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,11 +1280,11 @@ <h2>Selectable card</h2>
12801280
<div class="container">
12811281
<h2>Card</h2>
12821282
<div class="d-grid">
1283-
<sgds-card>
1283+
<sgds-card disabled>
12841284
<img slot="image" alt="img alternate text goes here" width="467" height="312"
12851285
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1286-
<span slot="metadata">METADATA</span>
1287-
<h3 slot="title">Vertical Image Card</h3>
1286+
<span slot="subtitle">SUBTITLE</span>
1287+
<span slot="title">Vertical Image Card</span>
12881288
<span slot="description">default vertical card</span>
12891289
<sgds-link slot="link">
12901290
<a href="#">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
@@ -1293,17 +1293,17 @@ <h3 slot="title">Vertical Image Card</h3>
12931293
<sgds-card imageAdjustment="padding around">
12941294
<img slot="image" alt="img alternate text goes here" width="467" height="312"
12951295
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1296-
<span slot="metadata">METADATA</span>
1297-
<h3 slot="title">Vertical Image Card</h3>
1296+
<span slot="subtitle">SUBTITLE</span>
1297+
<a href="#" slot="title"><span>Vertical Image Card</span></a>
12981298
<span slot="description">vertical card with image adjustment prop set to padding around</span>
1299-
<sgds-link slot="link">
1300-
<a href="#">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
1301-
</sgds-link>
1299+
<!-- <sgds-link slot="link"> -->
1300+
<a href="#" slot="link">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
1301+
<!-- </sgds-link> -->
13021302
</sgds-card>
1303-
<sgds-card imageAdjustment="aspect ratio">
1303+
<sgds-card imageAdjustment="aspect ratio" stretchedLink>
13041304
<img slot="image" alt="img alternate text goes here" width="467" height="300"
13051305
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1306-
<span slot="metadata">METADATA</span>
1306+
<span slot="subtitle">SUBTITLE</span>
13071307
<h3 slot="title">Vertical Image Card</h3>
13081308
<span slot="description">vertical card with image adjustment prop set to aspect ratio</span>
13091309
<sgds-link slot="link">
@@ -1313,17 +1313,17 @@ <h3 slot="title">Vertical Image Card</h3>
13131313
<sgds-card orientation="horizontal">
13141314
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13151315
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1316-
<span slot="metadata">METADATA</span>
1316+
<span slot="subtitle">SUBTITLE</span>
13171317
<h3 slot="title">Horizontal Image Card</h3>
13181318
<span slot="description">horizontal card with card orientation set to horizontal</span>
1319-
<sgds-link slot="link">
1320-
<a href="#">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
1321-
</sgds-link>
1319+
<!-- <sgds-link slot="link"> -->
1320+
<a href="#" slot="link">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
1321+
<!-- </sgds-link> -->
13221322
</sgds-card>
13231323
<sgds-card orientation="horizontal" imagePosition="after">
13241324
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13251325
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1326-
<span slot="metadata">METADATA</span>
1326+
<span slot="subtitle">SUBTITLE</span>
13271327
<h3 slot="title">Horizontal Image Card</h3>
13281328
<span slot="description">horizontal card with image position set to after</span>
13291329
<sgds-link slot="link">
@@ -1333,7 +1333,7 @@ <h3 slot="title">Horizontal Image Card</h3>
13331333
<sgds-card hideBorder>
13341334
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13351335
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1336-
<span slot="metadata">METADATA</span>
1336+
<span slot="subtitle">SUBTITLE</span>
13371337
<h3 slot="title">Vertical Image Card</h3>
13381338
<span slot="description">vertical card with no border</span>
13391339
<sgds-link slot="link">
@@ -1343,17 +1343,17 @@ <h3 slot="title">Vertical Image Card</h3>
13431343
<sgds-card orientation="horizontal" hideBorder>
13441344
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13451345
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1346-
<span slot="metadata">METADATA</span>
1346+
<span slot="subtitle">SUBTITLE</span>
13471347
<h3 slot="title">Horizontal Image Card</h3>
13481348
<span slot="description">horizontal card with no border</span>
13491349
<sgds-link slot="link">
13501350
<a href="#">SM light dom anchor <sgds-icon name="arrow-right"></sgds-icon></a>
13511351
</sgds-link>
13521352
</sgds-card>
1353-
<sgds-card tinted>
1353+
<sgds-card tinted stretchedLink>
13541354
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13551355
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1356-
<span slot="metadata">METADATA</span>
1356+
<span slot="subtitle">SUBTITLE</span>
13571357
<h3 slot="title">Vertical Image Card</h3>
13581358
<span slot="description">vertical card with tinted background</span>
13591359
<sgds-link slot="link">
@@ -1363,7 +1363,7 @@ <h3 slot="title">Vertical Image Card</h3>
13631363
<sgds-card orientation="horizontal" tinted>
13641364
<img slot="image" alt="img alternate text goes here" width="467" height="312"
13651365
src="https://images.unsplash.com/photo-1473093295043-cdd812d0e601?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=1740&amp;q=80">
1366-
<span slot="metadata">METADATA</span>
1366+
<span slot="subtitle">SUBTITLE</span>
13671367
<h3 slot="title">Horizontal Image Card</h3>
13681368
<span slot="description">horizontal card with tinted background</span>
13691369
<sgds-link slot="link">
@@ -1372,7 +1372,7 @@ <h3 slot="title">Horizontal Image Card</h3>
13721372
</sgds-card>
13731373
<sgds-card>
13741374
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1375-
<span slot="metadata">METADATA</span>
1375+
<span slot="subtitle">SUBTITLE</span>
13761376
<h3 slot="title">Vertical Icon Card</h3>
13771377
<span slot="description">default vertical card</span>
13781378
<sgds-link slot="link">
@@ -1381,7 +1381,7 @@ <h3 slot="title">Vertical Icon Card</h3>
13811381
</sgds-card>
13821382
<sgds-card orientation="horizontal">
13831383
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1384-
<span slot="metadata">METADATA</span>
1384+
<span slot="subtitle">SUBTITLE</span>
13851385
<h3 slot="title">Horizontal Icon Card</h3>
13861386
<span slot="description">horizontal card with card orientation set to horizontal</span>
13871387
<sgds-link slot="link">
@@ -1390,7 +1390,7 @@ <h3 slot="title">Horizontal Icon Card</h3>
13901390
</sgds-card>
13911391
<sgds-card hideBorder>
13921392
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1393-
<span slot="metadata">METADATA</span>
1393+
<span slot="subtitle">SUBTITLE</span>
13941394
<h3 slot="title">Vertical Icon Card</h3>
13951395
<span slot="description">vertical card with no border</span>
13961396
<sgds-link slot="link">
@@ -1399,7 +1399,7 @@ <h3 slot="title">Vertical Icon Card</h3>
13991399
</sgds-card>
14001400
<sgds-card orientation="horizontal" hideBorder>
14011401
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1402-
<span slot="metadata">METADATA</span>
1402+
<span slot="subtitle">SUBTITLE</span>
14031403
<h3 slot="title">Horizontal Icon Card</h3>
14041404
<span slot="description">horizontal card with no border</span>
14051405
<sgds-link slot="link">
@@ -1408,7 +1408,7 @@ <h3 slot="title">Horizontal Icon Card</h3>
14081408
</sgds-card>
14091409
<sgds-card tinted>
14101410
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1411-
<span slot="metadata">METADATA</span>
1411+
<span slot="subtitle">SUBTITLE</span>
14121412
<h3 slot="title">Vertical Icon Card</h3>
14131413
<span slot="description">vertical card with tinted background</span>
14141414
<sgds-link slot="link">
@@ -1417,7 +1417,7 @@ <h3 slot="title">Vertical Icon Card</h3>
14171417
</sgds-card>
14181418
<sgds-card orientation="horizontal" tinted>
14191419
<sgds-icon slot="icon" name="placeholder" size="3-xl"></sgds-icon>
1420-
<span slot="metadata">METADATA</span>
1420+
<span slot="subtitle">SUBTITLE</span>
14211421
<h3 slot="title">Horizontal Icon Card</h3>
14221422
<span slot="description">horizontal card with tinted background</span>
14231423
<sgds-link slot="link">

src/base/card.css

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,35 @@
4646
min-width: 0;
4747
position: relative;
4848
box-shadow: none;
49+
transition: box-shadow 0.3s ease;
50+
}
51+
52+
a.card {
53+
text-decoration: none;
54+
color: initial;
55+
}
56+
57+
@media (prefers-reduced-motion: reduce) {
58+
.card {
59+
transition: none;
60+
}
61+
}
62+
63+
.card.disabled {
64+
opacity: var(--sgds-opacity-50);
65+
cursor: not-allowed;
66+
}
67+
68+
.card:not(.disabled):hover {
69+
box-shadow: 0px 0px 1px 0px rgba(14, 14, 14, 0.12), 0px 8px 16px 0px rgba(14, 14, 14, 0.12);
70+
}
71+
72+
a.card:focus {
73+
outline: 0;
74+
}
75+
76+
a.card:not(.disabled):focus-visible {
77+
box-shadow: var(--sgds-box-shadow-focus);
4978
}
5079

5180
.card-image {
@@ -77,12 +106,23 @@
77106
margin-bottom: var(--sgds-margin-none);
78107
}
79108

109+
slot[name="title"]::slotted(a) {
110+
--sgds-link-color: var(--sgds-primary-color);
111+
--sgds-font-size-2: var(--sgds-font-size-4);
112+
--sgds-font-weight-regular: var(--sgds-font-weight-semibold);
113+
color: var(--sgds-link-color);
114+
font-size: var(--sgds-font-size-4);
115+
font-weight: var(--sgds-font-weight-semibold);
116+
text-decoration: none !important;
117+
}
118+
80119
slot[name="description"]::slotted(*) {
81120
color: var(--sgds-default-color-subtle);
82121
}
83122

84123
slot[name="image"]::slotted(img) {
85124
width: 100%;
125+
display: block;
86126
border-top-left-radius: calc(var(--sgds-border-radius-md) - var(--sgds-border-width-1));
87127
border-top-right-radius: calc(var(--sgds-border-radius-md) - var(--sgds-border-width-1));
88128
}
@@ -94,6 +134,32 @@ slot[name="image"]::slotted(img) {
94134
}
95135

96136
slot[name="link"]::slotted(*) {
97-
padding-top: var(--sgds-padding-sm);
137+
margin-top: var(--sgds-padding-sm);
98138
font-weight: 700;
99139
}
140+
141+
slot[name="link"]::slotted(a) {
142+
--sgds-link-color: var(--sgds-primary-color);
143+
display: inline-flex;
144+
gap: var(--sgds-gap-2-xs);
145+
color: var(--sgds-link-color);
146+
text-decoration: none !important;
147+
}
148+
149+
slot[name="title"]::slotted(a:hover),
150+
slot[name="title"]::slotted(a:focus),
151+
slot[name="link"]::slotted(a:hover),
152+
slot[name="link"]::slotted(a:focus) {
153+
--sgds-link-color-emphasis: var(--sgds-primary-color-emphasis);
154+
color: var(--sgds-link-color-emphasis);
155+
}
156+
157+
slot[name="title"]::slotted(a:focus),
158+
slot[name="link"]::slotted(a:focus) {
159+
outline: 0;
160+
}
161+
162+
slot[name="title"]::slotted(a:focus-visible),
163+
slot[name="link"]::slotted(a:focus-visible) {
164+
box-shadow: var(--sgds-box-shadow-focus);
165+
}

src/components/Card/card.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
gap: var(--sgds-gap-xs);
1414
}
1515

16-
slot[name="metadata"]::slotted(*) {
16+
slot[name="subtitle"]::slotted(*) {
1717
--sgds-margin-2-xs: var(--sgds-margin-none);
1818
--sgds-margin-xs: var(--sgds-margin-none);
1919
--sgds-font-size-4: var(--sgds-font-size-1);

src/components/Card/sgds-card.ts

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { html } from "lit";
2-
import { property, queryAssignedNodes } from "lit/decorators.js";
1+
import { html, literal } from "lit/static-html.js";
2+
import { property, query, queryAssignedNodes } from "lit/decorators.js";
3+
import { classMap } from "lit/directives/class-map.js";
34
import { CardElement } from "../../base/card-element";
45
import cardStyle from "./card.css";
56

@@ -10,20 +11,32 @@ export type CardOrientation = "vertical" | "horizontal";
1011
/**
1112
* @summary Cards can be used for headers and footers, a wide variety of content, contain contextual background colors and images.
1213
* @slot image - Accepts an image or svg element of the card. Only a single element is allowed to be passed in.
13-
* @slot metadata - The metadata of the card
14+
* @slot subtitle - The subtitle of the card
1415
* @slot title - The title of the card
1516
* @slot description - The paragrapher text of the card
1617
* @slot link - Accepts an anchor element. Only a single element is allowed to be passed in.
1718
*/
1819
export class SgdsCard extends CardElement {
1920
static styles = [...CardElement.styles, cardStyle];
2021

22+
/** @internal */
23+
@query("a.card") card: HTMLAnchorElement;
24+
2125
/** @internal */
2226
@queryAssignedNodes({ slot: "image", flatten: true })
2327
_imageNode!: Array<Node>;
2428
/** @internal */
2529
@queryAssignedNodes({ slot: "icon", flatten: true })
2630
_iconNode!: Array<Node>;
31+
/** @internal */
32+
@queryAssignedNodes({ slot: "link", flatten: true })
33+
_linkNode!: Array<Node>;
34+
35+
/** Extends the link passed in slot[name="link"] to the entire card */
36+
@property({ type: Boolean, reflect: true }) stretchedLink = false;
37+
38+
/** Disables the card */
39+
@property({ type: Boolean, reflect: true }) disabled = false;
2740

2841
/** Sets the orientation of the card */
2942
@property({ type: String, reflect: true }) orientation: CardOrientation = "vertical";
@@ -43,28 +56,60 @@ export class SgdsCard extends CardElement {
4356
const icon = this.shadowRoot.querySelector(".card-icon") as HTMLDivElement;
4457
icon.style.display = "none";
4558
}
59+
if (this.disabled && this._linkNode.length > 0) {
60+
const hyperlink = (this._linkNode[0] as HTMLLinkElement).querySelector("a");
61+
hyperlink.setAttribute("disabled", "true");
62+
hyperlink.removeAttribute("href");
63+
}
64+
}
65+
66+
handleTitleSlotChange(e: Event) {
67+
const childNodes = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }) as Array<HTMLElement>;
68+
69+
if (this.stretchedLink && childNodes[0] instanceof HTMLAnchorElement) {
70+
const hyperlink = childNodes[0].querySelector("a") || childNodes[0];
71+
hyperlink.removeAttribute("href");
72+
}
73+
return;
4674
}
4775

4876
handleLinkSlotChange(e: Event) {
49-
const childNodes = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }) as Array<HTMLLinkElement>;
50-
console.log(childNodes);
77+
const childNodes = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }) as
78+
| Array<HTMLLinkElement>
79+
| Array<HTMLAnchorElement>;
80+
5181
if (childNodes.length > 1) {
5282
return console.error("Multiple elements passed into SgdsCard's link slot");
5383
}
84+
85+
if (this.stretchedLink) {
86+
const hyperlink = childNodes[0].querySelector("a") || childNodes[0];
87+
this.card.setAttribute("href", hyperlink.href);
88+
const linkSlot = this.shadowRoot.querySelector("slot[name='link']") as HTMLSlotElement;
89+
linkSlot.style.display = "none";
90+
}
5491
return;
5592
}
5693

5794
handleImgSlotChange(e: Event) {
5895
const childNodes = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }) as Array<HTMLOrSVGImageElement>;
59-
console.log(childNodes);
96+
6097
if (childNodes.length > 1) {
6198
return console.error("Multiple elements passed into SgdsCard's image slot");
6299
}
63100
}
64101

65102
render() {
103+
const tag = this.stretchedLink ? literal`a` : literal`div`;
104+
const cardTabIndex = !this.stretchedLink || this.disabled ? -1 : 0;
105+
66106
return html`
67-
<div class="card">
107+
<${tag}
108+
class="card ${classMap({
109+
disabled: this.disabled
110+
})}"
111+
tabindex=${cardTabIndex}
112+
>
68113
<div class="card-image">
69114
<slot name="image" @slotchange=${this.handleImgSlotChange}></slot>
70115
</div>
@@ -73,15 +118,15 @@ export class SgdsCard extends CardElement {
73118
</div>
74119
<div class="card-body">
75120
<div class="card-header">
76-
<slot name="metadata"></slot>
77-
<h3 class="card-title"><slot name="title"></slot></h3>
121+
<slot name="subtitle"></slot>
122+
<h3 class="card-title"><slot name="title" @slotchange=${this.handleTitleSlotChange}></slot></h3>
78123
</div>
79124
<p class="card-text">
80125
<slot name="description"></slot>
81126
</p>
82127
<slot name="link" @slotchange=${this.handleLinkSlotChange}></slot>
83128
</div>
84-
</div>
129+
</${tag}>
85130
`;
86131
}
87132
}

0 commit comments

Comments
 (0)