Skip to content

Commit

Permalink
feat(cxl-ui): add cxl-certificate-header component
Browse files Browse the repository at this point in the history
  • Loading branch information
Hener Hoop committed Dec 8, 2023
1 parent e25fb2e commit 51996f3
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 44 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-max-width: 48em;
--cxl-content-max-width-wide: calc(var(--cxl-content-max-width) * 2);
--cxl-wrap-padding: var(--lumo-space-m);
--cxl-hero-content-max-width: 650px;
--cxl-hero-certificate-max-width: 480px;
--cxl-space-sm: 12px;
--cxl-color-light-gray: hsla(0, 0%, 96%, 1);
--cxl-color-medium-gray: hsla(210, 20%, 96%, 1);
Expand Down
3 changes: 2 additions & 1 deletion packages/cxl-lumo-styles/scss/themes/cxl-tabs-slider.scss
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@
* Theme "cxl-course-slider" and "cxl-category-accordion"
*/

:host([theme~="cxl-course-slider"][theme~="cxl-category-accordion"][theme~="minimal"]) {
:host([theme~="cxl-course-slider"][theme~="minimal"][theme~="cxl-category-accordion"]),
:host([theme~="cxl-course-slider"][theme~="minimal"][theme~="cxl-category-slider"]) {
margin-left: calc(-1 * var(--lumo-space-m));

@media #{mq.$small} {
Expand Down
13 changes: 13 additions & 0 deletions packages/cxl-ui/scss/cxl-app-layout/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,16 @@ slot[name="action-bar"]::slotted(div) {
}
}
}

/**
* Certificate layout
*/
:host([layout^="1c"][theme~="cxl-certificate"]:not([layout="1c"])) {
overflow: hidden;

main {
> slot {
padding: 0;
}
}
}
116 changes: 116 additions & 0 deletions packages/cxl-ui/scss/cxl-certificate-header.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
@use "~@conversionxl/cxl-lumo-styles/scss/mq";
@use "./mixins";

:host {
color: var(--lumo-tint);
background-color: var(--lumo-shade);
overflow: hidden;
@include mixins.pesudo-element-full-width(var(--lumo-shade));

@media #{mq.$medium} {
overflow: visible;
}

.container {
position: relative;
box-sizing: border-box;
width: 100%;
max-width: var(--cxl-content-max-width-wide);
padding: var(--lumo-space-l) 0;

@media #{mq.$small} {
display: flex;
justify-content: space-between;
gap: var(--lumo-space-m);
}

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

.content {
max-width: var(--cxl-hero-content-max-width);
}

.title {
margin: 0;
font-family: var(--cxl-lumo-font-secondary);
}

.completed {
display: flex;
margin-top: var(--lumo-space-l);
font-size: var(--lumo-font-size-xl);
font-weight: 700;
color: var(--lumo-primary-color);
}

.completed-icon {
display: inline-flex;
width: 32px;
height: 32px;
align-items: center;
justify-content: center;
margin-right: var(--lumo-space-m);
color: var(--lumo-primary-color);
background-color: var(--lumo-primary-color-10pct);
border-radius: 100%;
}

.description {
margin-top: var(--lumo-space-l);
font-family: var(--cxl-lumo-font-secondary);
line-height: var(--lumo-line-height-m);
}

.stats {
margin-top: var(--lumo-space-l);

@media #{mq.$medium} {
margin-top: calc(4 * var(--lumo-space-m));
}
}

.actions {
display: flex;
flex-direction: column;
gap: var(--lumo-space-s);
margin-top: var(--lumo-space-m);

@media #{mq.$medium} {
flex-direction: row;
gap: var(--lumo-space-m);
margin-top: var(--lumo-space-xl);
}
}

.credential {
width: 100%;
max-width: 100%;
margin-top: var(--lumo-space-l);
padding-top: var(--lumo-space-l);
border-top: solid 1px var(--cxl-color-dark-gray);

@media #{mq.$medium} {
max-width: var(--cxl-hero-certificate-max-width);
margin-top: 0;
padding-top: 0;
border-top: none;
}
}
}

:host([theme~="completed"]) {
color: var(--lumo-shade);
background-color: var(--lumo-tint);

@media #{mq.$medium} {
@include mixins.pesudo-element-full-width(var(--lumo-tint));
}

.credential {
padding-top: 0;
border-top: none;
}
}
2 changes: 1 addition & 1 deletion packages/cxl-ui/scss/cxl-featured-course-card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
position: relative;
z-index: 0;
display: block;
max-width: 650px;
max-width: var(--cxl-hero-content-max-width);
padding: 0 var(--lumo-space-m);

@media #{mq.$large} {
Expand Down
28 changes: 25 additions & 3 deletions packages/cxl-ui/scss/cxl-section.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
@use "~@conversionxl/cxl-lumo-styles/scss/mixins";
@use "~@conversionxl/cxl-lumo-styles/scss/mq";
@use "~@conversionxl/cxl-lumo-styles/scss/mixins";
@use "./mixins" as cxl-mixins;

:host {
position: relative;
display: block;
--figure-height-multiplier: 0.10;
--figure-height-factor: calc(var(--figure-height-multiplier) * var(--cxl-content-max-width-wide));
Expand All @@ -13,6 +15,12 @@
}
}

:host([theme~="cxl-section-certificate-unfinished"]) {
@media #{mq.$medium} {
@include cxl-mixins.pesudo-element-full-width(var(--cxl-color-medium-gray));
}
}

/**
* Avoid margin collapse with background.
*/
Expand All @@ -31,19 +39,33 @@
/**
* Spacious section spacing.
*/
margin-top: var(--cxl-section-wrap-margin-top, var(--lumo-space-xl));
margin-bottom: var(--cxl-section-wrap-margin-bottom, var(--lumo-space-xl));
margin-top: var(--cxl-section-wrap-margin-top, var(--lumo-space-l));
margin-bottom: var(--cxl-section-wrap-margin-bottom, var(--lumo-space-l));

/**
* Block editor integration.
*/
:host([theme~="full"]) > &,
:host(.alignfull) > & {
max-width: unset;
}

:host([theme~="wide"]) > &,
:host(.alignwide) > & {
max-width: var(--cxl-content-max-width-wide);
}

:host([theme~="cxl-certificate-header"]) > & {
margin-top: 0;
margin-bottom: 0;
}

:host([theme~="cxl-section-certificate-unfinished"]) > & {
margin-top: 0;
margin-bottom: 0;
padding-top: var(--lumo-space-m);
padding-bottom: var(--lumo-space-xl);
}
}

:host(.has-gray-background-color) {
Expand Down
5 changes: 5 additions & 0 deletions packages/cxl-ui/scss/global/cxl-certificate-header.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cxl-certificate-header {
position: relative;
display: block;
z-index: 1;
}
16 changes: 16 additions & 0 deletions packages/cxl-ui/scss/global/cxl-stats.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ cxl-stats {
}
}

.stat-item.featured .stat-count {
color: var(--lumo-primary-color);
}

a.stat-count {
color: var(--cxl-color-black);
text-decoration: underline;
Expand All @@ -33,4 +37,16 @@ cxl-stats {
color: var(--lumo-primary-color);
}
}

&[theme~="dark"] {
color: var(--lumo-tint);

.stat-title {
color: var(--lumo-tint);
}

a.stat-count {
color: var(--lumo-tint);
}
}
}
94 changes: 94 additions & 0 deletions packages/cxl-ui/src/components/cxl-certificate-header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable import/no-extraneous-dependencies */
import { LitElement, html, nothing } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { customElement, property } from 'lit/decorators.js';
import '@conversionxl/cxl-lumo-styles';
import '@conversionxl/cxl-ui/src/components/cxl-section.js';
import { registerGlobalStyles } from '@conversionxl/cxl-lumo-styles/src/utils';

import cxlCertificateHeaderStyles from '../styles/cxl-certificate-header-css.js';
import cxlCertificateHeaderGlobalStyles from '../styles/global/cxl-certificate-header-css.js';

@customElement('cxl-certificate-header')
export class CXLCertificateHeaderElement extends LitElement {
static get styles() {
return [cxlCertificateHeaderStyles];
}

@property({ type: String }) theme = '';
@property({ type: String }) title = '';
@property({ type: String }) description = '';
@property({ type: Boolean, attribute: 'hide-actions' }) hideActions = false;
@property({ type: Boolean, attribute: 'hide-stats' }) hideStats = false;
@property({ type: Boolean, attribute: 'hide-credential' }) hideCredential = false;
// eslint-disable-next-line class-methods-use-this
_renderCompletedEmblem() {
if (!this.theme.includes('completed')) {
return nothing;
}
return html`<div class="completed">
<span class="completed-icon"><vaadin-icon icon="lumo:checkmark"></vaadin-icon></span>
Course completed
</div>`;
}
// eslint-disable-next-line class-methods-use-this
_renderActions() {
if (this.hideActions) {
return nothing;
}
return html`<div class="actions"><slot name="actions"></slot></div>`;
}
// eslint-disable-next-line class-methods-use-this
_renderStats() {
if (this.hideStats) {
return nothing;
}
return html`<div class="stats"><slot name="stats"></slot></div>`;
}
// eslint-disable-next-line class-methods-use-this
_renderCredential() {
if (this.hideCredential) {
return nothing;
}
return html`<div class="credential"><slot name="credential"></slot>`;
}
render() {
return html`
<cxl-section class="alignfull" theme="cxl-certificate-header">
<div class="container">
<div class="content">
<h1 class="title">${this.title}</h1>
${this._renderCompletedEmblem()}
<div class="description">${unsafeHTML(this.description)}</div>
${this._renderStats()}
${this._renderActions()}
</div>
${this._renderCredential()}
</div>
</cxl-section>
`;
}
firstUpdated(_changedProperties) {
super.firstUpdated(_changedProperties);
// Global styles.
registerGlobalStyles(cxlCertificateHeaderGlobalStyles, {
moduleId: 'cxl-certificate-header-global',
});
}
}
10 changes: 8 additions & 2 deletions packages/cxl-ui/src/components/cxl-credential.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export class CXLCredentialElement extends LitElement {

@property({ type: String, attribute: 'full-name' }) fullName = '';
@property({ type: String }) theme = '';
@property({ type: String }) title = '';
/**
Expand All @@ -45,7 +47,7 @@ export class CXLCredentialElement extends LitElement {
@query('#qr-code') qrCodeCanvas = null;

defaultUrl ='https://cxl.com/institute/credential'

get url() {
return `${this.credentialUrl || this.defaultUrl}/${this.credentialId}`;
}
Expand Down Expand Up @@ -134,12 +136,16 @@ export class CXLCredentialElement extends LitElement {
}

if (changes.has('type')) {
this.setAttribute('theme', this.type === 'minidegree' ? 'dark' : 'light');
this.theme += ` ${this.type === 'minidegree' ? 'dark' : 'light'}`;
}

if (changes.has('scale') || changes.has('correctionFactor') || changes.has('codeScale')) {
requestAnimationFrame(() => this._handleScaling());
}

if (this.theme) {
this.setAttribute('theme', this.theme);
}
}

renderCredential() {
Expand Down
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 @@ -22,6 +22,7 @@ export { CXLCourseCardElement } from './components/cxl-course-card.js';
export { CXLCourseDialogElement } from './components/cxl-course-dialog.js';
export { CXLCheckoutDetailsElement } from './components/cxl-checkout-details.js';
export { CXLDashboardHeaderElement } from './components/cxl-dashboard-header.js';
export { CXLCertificateHeaderElement } from './components/cxl-certificate-header.js';
export { CxlDashboardSectionElement } from './components/cxl-dashboard-section.js';
export { CXLDashboardNotificationElement } from './components/cxl-dashboard-notification.js';
export { CxlDashboardTeamHeaderElement } from './components/cxl-dashboard-team-header.js';
Expand Down
Loading

0 comments on commit 51996f3

Please sign in to comment.