Skip to content

Commit

Permalink
feat: add featured-course-card component
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelkmpt authored and phkel committed Jul 14, 2023
1 parent 3bdb785 commit 3958587
Show file tree
Hide file tree
Showing 8 changed files with 2,399 additions and 1,988 deletions.
1 change: 1 addition & 0 deletions packages/cxl-lumo-styles/scss/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ html {
--cxl-content-width: 36em;
--cxl-wrap-width: 72rem;
--cxl-wrap-padding: var(--lumo-space-m);
--cxl-color-light-gray: hsla(0, 0%, 96%, 1);

/**
* Lumo Icons have a documented 4px "safe area" around them. Vaadin Icons don't, for unknown reasons.
Expand Down
4 changes: 4 additions & 0 deletions packages/cxl-lumo-styles/scss/themes/vaadin-tab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
:host([theme~="cxl-marketing-nav"][hidden]) {
visibility: hidden;
}

:host([theme~="cxl-featured-course-slider"]) {
padding: 0;
}
63 changes: 63 additions & 0 deletions packages/cxl-lumo-styles/scss/themes/vaadin-tabs.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@use "../mixins";
@use "../mq";

// Collapse margins.
:host([orientation="vertical"][theme~="cxl-marketing-nav"]) {
Expand Down Expand Up @@ -65,3 +66,65 @@ $vaadin-tab-horizontal-padding: 0.75rem;
margin-right: auto;
margin-left: auto;
}

// Featured course slider
:host([theme~="cxl-featured-course-slider"][orientation="horizontal"]) {
background-color: var(--cxl-color-light-gray);

[part="tabs"] {
padding: 0;
margin: 0;
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;

&::-webkit-scrollbar {
display: none;
}
}

[part="back-button"],
[part="forward-button"] {
width: var(--lumo-size-s);
height: var(--lumo-size-s);
color: var(--lumo-primary-color);
border-radius: 100%;

&::after {
font-size: var(--lumo-font-size-xl);
}

@media #{mq.$medium} {
width: var(--lumo-space-xl);
height: var(--lumo-space-xl);

&::after {
font-size: var(--lumo-font-size-xxl);
}
}
}

@media #{mq.$medium} {
[part="back-button"] {
margin-left: var(--lumo-space-s);
}

[part="forward-button"] {
margin-right: var(--lumo-space-s);
}
}

::slotted(vaadin-tab) {
padding: 0 var(--lumo-space-m);

@media #{mq.$medium} {
padding: 0;
}
}

::slotted(vaadin-tab:not(:first-child)) {
@media #{mq.$medium} {
padding-left: var(--lumo-size-xl);
}
}
}
121 changes: 121 additions & 0 deletions packages/cxl-ui/scss/cxl-featured-course-card.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
@use "~@conversionxl/cxl-lumo-styles/scss/mq";

:host {
.container {
position: relative;
display: block;
background-color: var(--cxl-color-light-gray);

@media #{mq.$medium} {
display: grid;
grid-template-columns: repeat(12, 1fr);
}
}

.instructor-img {
max-height: calc(var(--lumo-space-xl) * 6);
object-fit: contain;

@media #{mq.$medium} {
position: absolute;
top: 0;
right: 0;
height: 100%;
max-height: none;
}
}

.info {
position: relative;
z-index: 0;
grid-column: span 7 / span 7;
padding: 0 var(--lumo-space-m);
font-size: var(--lumo-font-size-s);

@media #{mq.$medium} {
padding: var(--lumo-space-l) 0 0 var(--lumo-space-l);
}

.swoosh {
position: absolute;
top: 0;
right: calc(var(--lumo-space-l) * -1);
bottom: 0;
left: calc(var(--lumo-space-l) * -1);
z-index: -1;
margin-top: calc(var(--lumo-space-m) * -2);

@media #{mq.$medium} {
display: none;
}
}

.tags {
display: flex;
flex-wrap: wrap;
max-width: 100%;
overflow: hidden;
column-gap: var(--lumo-space-s);
line-height: 1.2;

> span:first-child {
color: var(--lumo-primary-color);
}
}

.title {
margin: var(--lumo-space-s) 0;
font-size: var(--lumo-font-size-xl);
font-weight: 700;
line-height: normal;

strong {
color: var(--lumo-primary-color);
}
}

.attributes {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-bottom: var(--lumo-space-m);
gap: var(--lumo-space-s);
line-height: 1;
color: var(--lumo-shade-60pct);
}

.time {
display: flex;
align-items: center;
}

.content {
line-height: var(--lumo-line-height-m);
}

.cta {
display: block;
padding-bottom: var(--lumo-space-l);
margin-top: var(--lumo-space-m);
font-size: var(--lumo-font-size-m);
font-weight: 700;
line-height: var(--lumo-line-height-m);
color: var(--lumo-primary-color);
text-decoration: none;

vaadin-icon {
width: var(--lumo-icon-size-s);
height: var(--lumo-icon-size-s);
padding: calc(var(--lumo-space-xs) / 2);
margin-left: var(--lumo-space-s);
color: var(--lumo-primary-color);
background-color: var(--lumo-primary-color-10pct);
border-radius: 100%;
}

&:hover {
text-decoration: underline;
}
}
}
}
72 changes: 72 additions & 0 deletions packages/cxl-ui/src/components/cxl-featured-course-card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* eslint-disable import/no-extraneous-dependencies */
import { LitElement, html } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { customElement, property } from 'lit/decorators.js';
import '@conversionxl/cxl-lumo-styles';
import cxlFeaturedCourseCardStyles from '../styles/cxl-featured-course-card-css.js';

@customElement('cxl-featured-course-card')
export class CXLCourseCardElement extends LitElement {
static get styles() {
return [cxlFeaturedCourseCardStyles];
}

separator = html`<span> | </span>`;

@property({ type: String }) id = '';

@property({ type: String }) featuredCourse = 'Featured course';

@property({ type: String }) title = '';

@property({ type: String }) time = '';

@property({ type: String }) instructor = '';

@property({ type: String }) avatar = '';

@property({ type: Boolean, reflect: true }) new = false;

@property({ type: String, attribute: 'cta-label' }) ctaLabel = 'View course';

@property({ type: String, attribute: 'cta-url' }) ctaUrl = '#';

_slotHasChildren(e) {
const slot = e.target;
const { name } = slot;
const children = slot.assignedNodes();
this[`_${name}HasChildren`] = !!children.length;
}

render() {
return html`
<div class="container">
<img class="instructor-img" src=${this.avatar} alt="${this.instructor}" />
<div class="info">
<svg class="swoosh" viewBox="0 0 360 199" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill="var(--cxl-color-light-gray)"
d="M1199.64 104.027C1113.56 105.678 1029.17 107.177 943.442 114.375C832.023 123.729 722.816 117.784 614.335 95.3047C457.633 62.838 336.264 14.1676 141.043 11.5174C-1.67221 9.57723 -248.398 6.15004 -458 0V199H1608C1555.37 176.893 1506.06 147.493 1450.34 130.627C1371.01 106.653 1284.33 102.401 1199.64 104.027Z"
/>
</svg>
<div class="tags">
<span>${this.featuredCourse}</span>
${this.separator}
<slot name="tags" @slotchange=${this._slotHasChildren}></slot>
</div>
<h4 class="title">${unsafeHTML(this.title)}</h4>
<div class="attributes">
<span class="time"><vaadin-icon icon="lumo:clock"></vaadin-icon>${this.time}</span>
<span class="instructor">By: ${this.instructor}</span>
</div>
<div class="content">
<slot name="content"></slot>
</div>
<a class="cta" href="${this.ctaUrl}"
>${this.ctaLabel}<vaadin-icon icon="lumo:angle-right"></vaadin-icon
></a>
</div>
</div>
`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { html } from 'lit';
import '@conversionxl/cxl-ui/src/components/cxl-featured-course-card.js';
import '@conversionxl/cxl-ui/src/components/cxl-tabs-slider.js';
import '@conversionxl/cxl-lumo-styles';
import { CXLFeatureadCourseCard } from './default.stories.js';

export default {
title: 'CXL UI/cxl-featured-course-card',
};

const Template = () => html`
<style>
vaadin-tab {
max-width: 100%;
}
</style>
<cxl-tabs-slider theme="minimal cxl-featured-course-slider">
<vaadin-tab theme="cxl-featured-course-slider"
>${CXLFeatureadCourseCard(CXLFeatureadCourseCard.args)}</vaadin-tab
>
<vaadin-tab theme="cxl-featured-course-slider"
>${CXLFeatureadCourseCard(CXLFeatureadCourseCard.args)}</vaadin-tab
>
<vaadin-tab theme="cxl-featured-course-slider"
>${CXLFeatureadCourseCard(CXLFeatureadCourseCard.args)}</vaadin-tab
>
</cxl-tabs-slider>
`;

export const DashboardSlider = Template.bind({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { html } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import '@conversionxl/cxl-ui/src/components/cxl-featured-course-card.js';

export default {
title: 'CXL UI/cxl-featured-course-card',
};

const renderTags = (tags, slot) =>
tags.map(
(tag, i) =>
html`${i > 0 ? html`<span slot=${slot}> | </span>` : ''}<span slot=${slot}>${tag}</span>`
);

const FeaturedCourseCardTemplate = (course) => html`
<cxl-featured-course-card
id=${course.id}
title=${course.title}
time=${course.time}
instructor=${course.instructor}
avatar=${course.avatar}
cta-url=${course.ctaUrl}
.new=${course.new}
>
${course.tags ? renderTags(course.tags, 'tags') : ''}
<div slot="content">${unsafeHTML(course.description)}</div>
</cxl-featured-course-card>
`;

export const CXLFeatureadCourseCard = FeaturedCourseCardTemplate.bind({});

CXLFeatureadCourseCard.args = {
id: 'cxl-featured-course-1',
title: 'Get ahead with <strong>Google Analytics 4</strong>',
time: '5h 04min',
instructor: 'Fred Pike',
description:
"<p>GA4 is packed with new capabilities that help you improve acquisition, engagement, revenue, and retention for your website.</p><p>In five hours, we'll have you confident, capable, and armed with new insights into your business and your website. <strong>This course pays back for you real quick.</strong></p>",
tags: ['Marketing', 'Analytics'],
ctaUrl: 'https://google.com',
avatar:
'https://cxl.com/institute/wp-content/uploads/2020/04/fred-pike-instructor-headshot-1x1-color-bw-min-1024x1024.png',
};
Loading

0 comments on commit 3958587

Please sign in to comment.