Skip to content

Commit

Permalink
Merge pull request #291 from conversionxl/kertu/feat/dashoard-stats-c…
Browse files Browse the repository at this point in the history
…omponent
  • Loading branch information
pawelkmpt authored and phkel committed Jul 14, 2023
2 parents 3bdb785 + 723fe39 commit 8e8e5e0
Show file tree
Hide file tree
Showing 15 changed files with 2,521 additions and 1,988 deletions.
2 changes: 2 additions & 0 deletions packages/cxl-lumo-styles/scss/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ 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);
--cxl-color-black-50pct: hsla(0, 0%, 0%, 0.5);

/**
* 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;
}
}
}
}
17 changes: 17 additions & 0 deletions packages/cxl-ui/scss/cxl-stats.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@use "~@conversionxl/cxl-lumo-styles/scss/mq";

:host {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--lumo-space-m);
padding: var(--lumo-space-xl) var(--lumo-space-m) var(--lumo-space-m);
border-bottom: 1px solid var(--cxl-color-light-gray);

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

@media #{mq.$medium} {
grid-template-columns: repeat(4, 1fr);
}
}
16 changes: 16 additions & 0 deletions packages/cxl-ui/scss/global/cxl-stats.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cxl-stats {
.stats-title {
margin-top: 0;
font-size: var(--lumo-font-size-xs);
font-weight: 400;
line-height: 1;
color: var(--cxl-color-black-50pct);
text-transform: uppercase;
}

.stats-count {
margin: 0;
font-size: var(--lumo-font-size-xxl);
font-weight: 700;
}
}
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>
`;
}
}
28 changes: 28 additions & 0 deletions packages/cxl-ui/src/components/cxl-stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { LitElement, html } from 'lit';
// eslint-disable-next-line import/no-extraneous-dependencies
import { customElement } from 'lit/decorators.js';
import { registerGlobalStyles } from '@conversionxl/cxl-lumo-styles/src/utils';
import '@conversionxl/cxl-lumo-styles';
import cxlStatsStyles from '../styles/cxl-stats-css.js';
import cxlStatsGlobalStyles from '../styles/global/cxl-stats-css.js';

@customElement('cxl-stats')
export class CXLStatsElement extends LitElement {
static get styles() {
return [cxlStatsStyles];
}

render() {
return html`<slot></slot>`;
}

firstUpdated(_changedProperties) {
super.firstUpdated(_changedProperties);

// Global styles.
registerGlobalStyles(cxlStatsGlobalStyles, {
moduleId: 'cxl-stats',
});
}
}
1 change: 1 addition & 0 deletions packages/cxl-ui/src/index-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { CXLCardElement } from './components/cxl-card.js';
export { CXLCheckoutDetailsElement } from './components/cxl-checkout-details.js';
export { CXLMarketingNavElement } from './components/cxl-marketing-nav.js';
export { CXLSectionElement } from './components/cxl-section.js';
export { CXLStatsElement } from './components/cxl-stats.js';
export { CXLTabsSliderElement } from './components/cxl-tabs-slider.js';
export { CXLNotification } from './components/cxl-notification.js';

Expand Down
1 change: 1 addition & 0 deletions packages/cxl-ui/src/index-storybook.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { CXLAppLayoutElement } from './components/cxl-app-layout.js';
export { CXLCardElement } from './components/cxl-card.js';
export { CXLMarketingNavElement } from './components/cxl-marketing-nav.js';
export { CXLSectionElement } from './components/cxl-section.js';
export { CXLStatsElement } from './components/cxl-stats.js';
export { CXLTabsSliderElement } from './components/cxl-tabs-slider.js';

// Order matters.
Expand Down
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({});
Loading

0 comments on commit 8e8e5e0

Please sign in to comment.