Skip to content

Commit

Permalink
refactor(cxl-lumo-styles): update storybook with current home page st…
Browse files Browse the repository at this point in the history
…yles
  • Loading branch information
freudFlintstone committed Aug 8, 2023
1 parent 5d62417 commit bb559b1
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/cxl-lumo-styles/src/icons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/cxl-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"directory": "packages/cxl-ui"
},
"dependencies": {
"@conversionxl/cxl-lumo-styles": "^1.6.4"
"@conversionxl/cxl-lumo-styles": "^1.6.4",
"@lit-labs/observers": "^2.0.0"
},
"devDependencies": {
"@conversionxl/normalize-wheel": "^1.0.1",
Expand Down
114 changes: 114 additions & 0 deletions packages/cxl-ui/scss/cxl-filter-header.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
@use "~@conversionxl/cxl-lumo-styles/scss/mq";

:host {
display: block;
font-weight: 400;

.container {
width: 100%;
}

.tabs {
display: flex;
position: relative;
width: 100%;

.scroll-control {
position: absolute;

&:first-child {
left: -2px;
background: linear-gradient(to left, rgba(255, 255, 255, 0), var(--lumo-base-color));
z-index: 1;
}

&:last-child {
right: -2px;
background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--lumo-base-color));
z-index: 1;
}
}
}

.filters {
display: flex;
border-bottom: 1px solid var(--lumo-shade-20pct);
max-width: 100%;
overflow-x: scroll;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;

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

/* This seems more future-proof than \`overflow: -moz-scrollbars-none\` which is marked obsolete
and is no longer guaranteed to work:
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow#Mozilla_Extensions
*/
@-moz-document url-prefix() {
overflow: hidden;
}

::slotted(*) {
scroll-snap-align: start;
scroll-snap-stop: always;
}

}

.controls {
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap-reverse;
justify-content: stretch;
padding-top: var(--lumo-space-l);
gap: var(--lumo-space-m);

.flex-group {
display: flex;
flex-direction: row-reverse;
justify-content: stretch;
width: 100%;
gap: var(--lumo-space-m);

> ::slotted(*) {
flex: 1;
width: auto !important;
}

#show-filters {
--lumo-button-size: var(--lumo-size-l);
display: block;
margin: 0;
text-align: start;
flex-basis: 50%;
}
}

::slotted([slot="search"]) {
width: 100%;
line-height: var(--lumo-size-l);
}
}

@media #{mq.$small} {
.controls {
flex-direction: row;
flex-wrap: nowrap;

.flex-group {
width: auto;

#show-filters {
display: none;
}
}

.search {
line-height: normal;
}
}
}
}
94 changes: 94 additions & 0 deletions packages/cxl-ui/src/components/cxl-filter-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 } from 'lit';
import { ResizeController } from '@lit-labs/observers/resize-controller.js';
import { customElement, state, query } from 'lit/decorators.js';
import './cxl-vaadin-accordion';
import '@vaadin/button'
import cxlDashboardFilterHeaderStyles from '../styles/cxl-filter-header-css.js';

const supportsScrollEndEvent = 'onscrollend' in window
const isFirefox = document.scrollingElement.scrollLeftMax !== undefined

@customElement('cxl-filter-header')
export class CXLFilterHeaderElement extends LitElement {
static get styles() {
return [cxlDashboardFilterHeaderStyles];
}

@state() tabsWidth = 0

@state() tabsNumber = 1

@query('.filters') filtersContainer = null

@query('#filters-slot') filtersSlot = null

isOverflowing = new ResizeController(this, {
callback: (entries) => {
const entry = entries[0];
this.showScrollers = entry && entry.borderBoxSize[0].inlineSize < this.tabsWidth;
return this.showScrollers
}
});

_checkTabsMaxWidth () {
if (!this.filtersSlot) return 0
const tabs = this.filtersSlot.assignedElements()
const fullWidth = tabs.map(tab => tab.clientWidth).reduce((total, w) => total + w, 0);
this.tabsWidth = fullWidth
this.tabsNumber = tabs.length
return this.tabsWidth
}

_scrollForwards () {
// `behavior: 'smooth'` option not being used due to firefox bug
this.filtersContainer.scrollBy({ left: (this.filtersContainer.scrollWidth - this.filtersContainer.clientWidth), behavior: isFirefox ? 'instant' : 'smooth' })
// Workaround for browsers that don't support scrollend event to update rendering
if (!supportsScrollEndEvent) {
setTimeout(() => { this.requestUpdate() }, 100)
}
}

_scrollBackwards () {
// `behavior: 'smooth'` option not being used due to firefox bug
this.filtersContainer.scrollBy({ left: -(this.filtersContainer.scrollWidth - this.filtersContainer.clientWidth), behavior: isFirefox ? 'instant' : 'smooth' })
// Workaround for browsers that don't support scrollend event to update rendering
if (!supportsScrollEndEvent) {
setTimeout(() => { this.requestUpdate() }, 100)
}
}

get showBackwardScroller () {
return this.isOverflowing.value && this.filtersContainer.scrollLeft > 0
}

get showForwardScroller () {
return this.isOverflowing.value && this.filtersContainer.scrollLeft < (this.filtersContainer.scrollWidth - this.filtersContainer.clientWidth)
}

render () {
return html`
<div class="container">
<div class="tabs">
<vaadin-button ?hidden=${!this.showBackwardScroller} class="scroll-control backwards" theme="icon tertiary" @click=${this._scrollBackwards}><vaadin-icon icon="lumo:angle-left"></vaadin-icon></vaadin-button>
<div class="filters" @scrollend=${() => { this.requestUpdate() }}>
<slot id="filters-slot" @slotchange=${this._checkTabsMaxWidth}></slot>
</div>
<vaadin-button ?hidden=${!this.showForwardScroller} class="scroll-control forwards" theme="icon tertiary" @click=${this._scrollForwards}><vaadin-icon icon="lumo:angle-right"></vaadin-icon></vaadin-button>
</div>
<div class="controls">
<!-- search -->
<slot name="search"></slot>
<div class="flex-group">
<!-- sort -->
<slot name="sort"></slot>
<vaadin-button id="show-filters">
<vaadin-icon icon="vaadin:filter" slot="prefix"></vaadin-icon>
<span>Filters</span>
</vaadin-button>
</div>
</div>
</div>
`
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* eslint-disable import/no-extraneous-dependencies */
import { html } from 'lit';
import '@conversionxl/cxl-ui/src/components/cxl-filter-header.js';
import '@conversionxl/cxl-ui/src/components/cxl-filter-header-item.js';

export default {
title: 'CXL UI/cxl-search-filters',
parameters: {
layout: 'centered',
docs: {
description: {
component: 'CXL Search Filter Header',
},
},
},
}

const mockMarkAsChecked = (e) => {
const el = e.currentTarget
const parent = el.parentElement
const children = [...parent.children]

children.forEach(child => {
if (child.nodeName === 'CXL-FILTER-HEADER-ITEM') {
child.classList.remove('checked')
}
});
el.classList.add('checked')
}

export const CXLFilterHeader = ({ filters }) => html`
<style>
#search {
width: 100%;
}
#sort {
width: 100%;
}
cxl-filter-header {
display: flex;
max-width: calc(100vw - 32px);
}
</style>
<cxl-filter-header>
${filters.map((filter, i) => html`<cxl-filter-header-item class="${i === 0 ? 'checked' : ''}" label="${filter.label}" count="${filter.count}" @click="${mockMarkAsChecked}"></cxl-filter-header-item>`)}
<select placeholder="Sort by (A-Z)" id="sort" type="select" slot="sort">
<option value="">- No selection --</option>
</select>
<input id="search" type="search" slot="search" placeholder="Search by title"/>
</cxl-filter-header>
`;

CXLFilterHeader.args = {
filters: [
{ label: 'All contents', count: '108' },
{ label: 'Deep marketing', count: '32' },
{ label: 'Broad marketing', count: '40' },
{ label: 'Fast marketing', count: '36' },
],
}
14 changes: 14 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2353,11 +2353,25 @@
npmlog "^4.1.2"
write-file-atomic "^2.3.0"

"@lit-labs/observers@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@lit-labs/observers/-/observers-2.0.0.tgz#b1ab73e43460e97b3910f6be68121bfabf14669a"
integrity sha512-NMbCjJEqp8V9TpTtt8HhzFVymx/WGpTD7iU+FMKSis4u3iBWwu2UYh6KChwFTEPW9xMum70r2IBnaViBINaGTA==
dependencies:
"@lit/reactive-element" "^1.1.0"

"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz#64df34e2f12e68e78ac57e571d25ec07fa460ca9"
integrity sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==

"@lit/reactive-element@^1.1.0":
version "1.6.3"
resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03"
integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==
dependencies:
"@lit-labs/ssr-dom-shim" "^1.0.0"

"@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0":
version "1.6.2"
resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.2.tgz#c256690f82f2d7d0ffb0b1cdf68dcb1ec86cea28"
Expand Down

0 comments on commit bb559b1

Please sign in to comment.