Skip to content

Commit 58f14ff

Browse files
authored
Merge pull request #33 from imsdev/32-reusable-component-course-card
Reusable course card
2 parents e852174 + fff943b commit 58f14ff

File tree

7 files changed

+1040
-1154
lines changed

7 files changed

+1040
-1154
lines changed

ims-education.html

Lines changed: 784 additions & 1127 deletions
Large diffs are not rendered by default.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
h2 {
2+
font-weight: 500;
3+
font-size: 1.5em;
4+
padding: 0em;
5+
margin: 0em;
6+
}
7+
8+
p {
9+
font-size: 1.125em;
10+
}
11+
12+
a {
13+
text-decoration: none;
14+
color: #0f62fe;
15+
}
16+
17+
img {
18+
max-width: 16em;
19+
}
20+
21+
/* Styling for a link group */
22+
.link-g {
23+
margin-top: 1.4em;
24+
display: flex;
25+
flex-flow: row wrap;
26+
gap: 2em;
27+
}
28+
29+
.column-g {
30+
display: flex;
31+
flex-flow: column nowrap;
32+
gap: 1em;
33+
}
34+
35+
/* Styling for inline group (level, time) */
36+
.inline-g {
37+
display: flex;
38+
flex-flow: row wrap;
39+
gap: 1em;
40+
}
41+
42+
.inline-g div {
43+
display: flex;
44+
flex-flow: row wrap;
45+
gap: 1em;
46+
}
47+
48+
.inline-g p {
49+
padding: 0em;
50+
margin: 0em;
51+
font-weight: bold;
52+
}
53+
54+
.inline-g span {
55+
font-weight: normal;
56+
}
57+
58+
/* Styling for course card */
59+
.course-card {
60+
margin: 1em 0em;
61+
padding: 2em 0em;
62+
display: flex;
63+
flex-flow: row wrap;
64+
align-items: flex-start;
65+
gap: 2em;
66+
border-bottom: 2px dotted lightgray;
67+
}
68+
69+
/* 768px and below screen sizes */
70+
@media screen and (max-width: 48em) {
71+
.inline-g {
72+
width: 90%;
73+
}
74+
}
75+
76+
/* 1024px and above screen sizes */
77+
@media screen and (min-width: 64em) {
78+
.course-card {
79+
flex-flow: row nowrap;
80+
}
81+
}
82+
83+
/* 1440px and above screen sizes */
84+
@media screen and (min-width: 90em) {
85+
.course-card {
86+
align-items: center;
87+
}
88+
89+
/* .inline-g {
90+
display: grid;
91+
grid-template-columns: 1fr 6fr;
92+
} */
93+
94+
.inline-g div {
95+
display: grid;
96+
grid-template-columns: repeat(4, 1fr);
97+
width: 90%;
98+
}
99+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!-- HTML template -->
2+
<link href="web-components/course-card/course-card.css" rel="stylesheet">
3+
<div class="course-card">
4+
<div>
5+
<img class="course-img" src="">
6+
</div>
7+
<div>
8+
<div>
9+
<h2 class="course-name"></h2>
10+
<p class="course-desc"></p>
11+
<div class="column-g">
12+
<div class="inline-g">
13+
<p>Level: <span class="course-level"></span></p>
14+
<p>Cost: <span class="course-cost"></span></p>
15+
<p>Badge: <span class="course-badge"></span></p>
16+
<p>Time: <span class="course-time"></span></p>
17+
</div>
18+
<!-- Uncomment if using self-paced/live distinction -->
19+
<!-- <div class="inline-g">
20+
<p>Self-paced:</p>
21+
<div>
22+
<p>Level: <span class="course-level"></span></p>
23+
<p>Cost: <span class="course-cost"></span></p>
24+
<p>Badge: <span class="course-badge"></span></p>
25+
<p>Time: <span class="course-time"></span></p>
26+
</div>
27+
</div> -->
28+
<div class="inline-g live-course">
29+
<p>Instructor-led:</p>
30+
<div>
31+
<p>Level: <span class="live-level"></span></p>
32+
<p>Cost: <span class="live-cost"></span></p>
33+
<p>Badge: <span class="live-badge"></span></p>
34+
<p>Time: <span class="live-time"></span></p>
35+
</div>
36+
</div>
37+
</div>
38+
</div>
39+
<div class="link-g">
40+
<a class="course-link" target="_blank" rel="noopener noreferrer">Learn more →</a>
41+
<a class="live-link" target="_blank" rel="noopener noreferrer">Instructor-led course →</a>
42+
</div>
43+
</div>
44+
</div>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Fetch HTML template
2+
fetch("web-components/course-card/course-card.html")
3+
.then(stream => stream.text())
4+
.then(text => createComponent(text))
5+
6+
// Create web component
7+
function createComponent(html) {
8+
9+
function setContent(cssSelector, content, shadow) {
10+
const selector = shadow.querySelector(cssSelector);
11+
selector.textContent = content;
12+
}
13+
14+
function setLink(cssSelector, url, name, shadow) {
15+
const link = shadow.querySelector(cssSelector);
16+
link.href = url;
17+
link.setAttribute('aria-label', `Learn more about ${name}`);
18+
}
19+
20+
// Web component class
21+
class CourseCard extends HTMLElement {
22+
23+
// Creates element with default values
24+
constructor() {
25+
super();
26+
}
27+
28+
// Return array of properties to observe
29+
static get observedAttributes() {
30+
return ['name', 'desc', 'imgsrc', 'level', 'cost', 'badge', 'time', 'link', 'livelevel', 'livecost', 'livebadge', 'livetime', 'livelink'];
31+
}
32+
33+
// Called when an attribute is defined or changed
34+
attributeChangedCallback(property, oldValue, newValue) {
35+
if (oldValue === newValue) return;
36+
this[property] = newValue;
37+
}
38+
39+
// Invoked when element is added to document
40+
connectedCallback() {
41+
// Create shadow root for element
42+
const shadow = this.attachShadow({mode: 'closed'});
43+
shadow.innerHTML = html;
44+
45+
// Set course img
46+
const courseImg = shadow.querySelector('.course-img');
47+
courseImg.src = this.imgsrc;
48+
courseImg.setAttribute('alt', `${this.name} badge`);
49+
50+
// Set course name
51+
setContent('.course-name', this.name, shadow);
52+
// Set course desc
53+
setContent('.course-desc', this.desc, shadow);
54+
// Set course level
55+
setContent('.course-level', this.level, shadow);
56+
// Set course cost
57+
setContent('.course-cost', this.cost, shadow);
58+
// Set course badge
59+
setContent('.course-badge', this.badge, shadow);
60+
// Set course time
61+
setContent('.course-time', this.time, shadow);
62+
// Set course link
63+
setLink('.course-link', this.link, this.name, shadow);
64+
65+
// Hide live course if not available
66+
if (this.livelevel == undefined) {
67+
const liveCourse = shadow.querySelector('.live-course');
68+
const liveCourseLink = shadow.querySelector('.live-link');
69+
liveCourse.style.display = liveCourseLink.style.display = "none";
70+
} else {
71+
// Set course level
72+
setContent('.live-level', this.livelevel, shadow);
73+
// Set course cost
74+
setContent('.live-cost', this.livecost, shadow);
75+
// Set course badge
76+
setContent('.live-badge', this.livebadge, shadow);
77+
// Set course time
78+
setContent('.live-time', this.livetime, shadow);
79+
// Set course link
80+
setLink('.live-link', this.livelink, this.name, shadow);
81+
}
82+
}
83+
}
84+
85+
customElements.define('course-card', CourseCard);
86+
}

web-components/video-card/video-card.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
:root {
2-
/* Color */
3-
--blue: #0f62fe;
4-
/* Background Color */
5-
--bg-light-gray: #f4f4f4;
6-
7-
/* Sizing */
8-
--plex-18: 1.125em;
9-
--plex-24: 1.5em;
10-
}
11-
121
h2 {
132
font-weight: 400;
143
font-size: var(--plex-24);

web-components/video-card/video-card.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ function createComponent(html) {
3939

4040
// Set video name
4141
const videoName = shadow.querySelector('.video-name');
42-
videoName.textContent = `${this.name}`;
42+
videoName.textContent = this.name;
4343

4444
// Set video desc
4545
const videoDesc = shadow.querySelector('.video-desc');
46-
videoDesc.textContent = `${this.desc}`;
46+
videoDesc.textContent = this.desc;
4747

4848
// Set video level
4949
const videoLevel = shadow.querySelector('.video-level');
50-
videoLevel.textContent = `${this.level}`;
50+
videoLevel.textContent = this.level;
5151

5252
// Set video time
5353
const videoTime = shadow.querySelector('.video-time');
54-
videoTime.textContent = `${this.time}`;
54+
videoTime.textContent = this.time;
5555

5656
// Set video links
5757
const videoLink = shadow.querySelector('.video-link');
@@ -71,8 +71,8 @@ function createComponent(html) {
7171
// Check if urls have been defined
7272
if (url != undefined) {
7373
linkObj.href = url;
74-
const altText = (linkText != 'now') ? `Watch ${this.name}, ${linkText}` : `Watch ${this.name}`; // Change link text if defined
75-
linkObj.setAttribute('alt', altText);
74+
const ariaText = (linkText != 'now') ? `Watch ${this.name}, ${linkText}` : `Watch ${this.name}`; // Change link text if defined
75+
linkObj.setAttribute('aria-label', ariaText);
7676
linkObj.textContent = `Watch ${linkText} →`;
7777
}
7878
})

wp-includes/css/page.css

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
--black: #000;
77
--blue: #0f62fe;
88
/* Background Color */
9-
--bg-light-gray: #f4f4f4;
9+
--bg-light-gray: #F9F9F9;
10+
--bg-gray: #f4f4f4;
1011
--bg-dark-gray-01: #1c1c1c;
1112
--bg-dark-gray-02: #2c2c2c;
1213
--bg-dark-blue: #003A6D;
@@ -71,10 +72,18 @@
7172
}
7273

7374
.gray-bg {
75+
background-color: var(--bg-gray);
76+
}
77+
78+
.light-gray-bg {
7479
background-color: var(--bg-light-gray);
7580
}
7681

77-
.gray-bg h3, .gray-bg h4 {
82+
.gray-bg a, .light-gray-bg a {
83+
color: var(--blue);
84+
}
85+
86+
.gray-bg h3, .gray-bg h4, .light-gray-bg h3, .light-gray-bg h4 {
7887
color: var(--black);
7988
}
8089

@@ -114,15 +123,12 @@
114123
margin-bottom: 1.25em;
115124
}
116125

117-
.icon-md {
118-
max-height: var(--plex-72);
119-
max-width: var(--plex-72);
120-
}
121-
122126
.icon-lg {
123127
height: var(--plex-28);
124-
max-height: var(--plex-72);
125-
max-width: var(--plex-72);
128+
}
129+
130+
.icon-xl {
131+
height: var(--plex-36);
126132
}
127133

128134
.icon {
@@ -323,7 +329,7 @@
323329
}
324330

325331
.quote-blk {
326-
background-color: var(--bg-light-gray);
332+
background-color: var(--bg-gray);
327333
margin: 0.2em;
328334
padding: 2em;
329335
color: var(--black);
@@ -347,6 +353,11 @@
347353
.spacer {
348354
height: 0.3125em;
349355
}
356+
357+
/* Hero section subtext */
358+
.subtext {
359+
font-weight: 300;
360+
}
350361
/* -------------------------------------------------------- */
351362

352363
/* Media queries */

0 commit comments

Comments
 (0)