@furo/layout
Version:
Layout components for furo
659 lines (577 loc) • 19.9 kB
JavaScript
import { __decorate } from "tslib";
import { css, html, LitElement } from "lit";
// eslint-disable-next-line import/extensions
import { property } from "lit/decorators.js";
import { ResponsiveLayoutSize } from "../types/ResponsiveLayoutSize";
/**
*
* ### Overview
*
* Use the furo-responsive-layout to structure your forms or other content.
*
* The heights are given by the highest `cell` in a `row`.
*
* > **Deprecation Warning:** The short form attributes (`tripple` instead of `layout-tripple`) will be removed in near future **(end of Q3/24)**
*
* It is based on a grid system with the following properties:
*
* #### Layout one
*
* ```html
* <furo-responsive-layout layout="one">
* <div>Item</div>
* <div>Item</div>
* <div layout-double>layout-double</div>
* <div>Item</div>
* <div>Item</div>
* </furo-responsive-layout>
* ```
* <img src="assets/layout-one.png">
*
* #### Layout two
* If the container size is smaller than `breakpoint-big` the layout will collapse in a layout one.
*
* <img src="assets/layout-two.png">
*
* #### Layout three
* If the container size is smaller than `breakpoint-big` the layout will collapse in a layout one.
*
* <img src="assets/layout-three.png">
*
*
* #### Layout four
* If the container size is smaller than `breakpoint-big` the layout will collapse in a layout two.
* If the container size is smaller than `breakpoint-small` the layout will collapse in a layout one.
*
* <img src="assets/layout-four.png">
*
*
* #### Layout six
* If the container size is smaller than `breakpoint-big` the layout will collapse in a layout three.
* If the container size is smaller than `breakpoint-small` the layout will collapse in a layout one.
*
* <img src="assets/layout-six.png">
*
* The ResponsiveLayout component is nestable, this means that you can put 2 six column ResponsiveLayouters in a two column ResponsiveLayout component.
*
* ### How to set the sizes
* Set the following **attributes** to set the space your item should take.
*
* - **layout-double** Uses 2 columns.
*
* - **layout-tripple** Uses 3 columns.
*
* - **layout-full** Uses the full width.
*
* - **layout-newline** Starts always on a new line.
*
* - **layout-end** Sticks to the end.
*
*
* > This layouter is a clone of the furo-form-layouter component with a slightly different API.
*
* ### ES6 Module Import
*
* `import "@furo/layout/dist/furo-responsive-layout.js";`
*
*
* @cssprop {1rem} [--GridRowGapSize] - width of row gap
* @cssprop {1rem} [--GridColumnGapSize] - width of column gap
*
* @slot {HTMLElement[]} default - slot to add content.
* @author veith
* @tagname furo-responsive-layout
* @public
*/
export class FuroResponsiveLayout extends LitElement {
constructor() {
super(...arguments);
/**
* Defines the layout of the component.
* Supported values are: one, two, three, four and six.
*
* @type {ResponsiveLayoutSize}
* @typeref ResponsiveLayoutSize - "@furo/layout/dist/types/ResponsiveLayoutSize.js"
* @defaultvalue one
* @public
*/
this.layout = ResponsiveLayoutSize.four;
/**
* Defines the size for when to switch from six to four.
*
* @type {number}
* @defaultvalue 810
* @public
*/
this.breakpointSix = 1250;
this.breakpointSixSmall = 650;
/**
* Defines the size for when to switch from six to three and four to two column layout.
*
* @type {number}
* @defaultvalue 810
* @public
*/
this.breakpointBig = 810;
/**
* Defines the size for when to switch from three to one or two to one.
*
* @type {number}
* @defaultvalue 405
* @public
*/
this.breakpointSmall = 405;
/**
* @private
*/
this._resizeListener = () => {
const cr = this.getBoundingClientRect();
this._checkSize(cr.width);
};
}
/**
*
* @private
*/
_fireResize() {
this.dispatchEvent(new CustomEvent("layout-changed", {
detail: this,
bubbles: true,
composed: true,
}));
}
/**
*
* @param width
* @private
*/
_checkSize(width) {
if (width > 0 && width < this.breakpointSix && width > this.breakpointBig && this.layout === "six") {
this.setAttribute("six-to-four", "");
this.removeAttribute("six-to-two");
this.removeAttribute("narrow");
this.removeAttribute("narrower");
this._fireResize();
}
else if (width > 0 && width < this.breakpointBig && width < this.breakpointSixSmall && width > this.breakpointSmall && this.layout === "six") {
this.setAttribute("six-to-two", "");
this.removeAttribute("six-to-four");
this.removeAttribute("narrow");
this.removeAttribute("narrower");
this._fireResize();
}
else if (width > 0 && width < this.breakpointBig && width > this.breakpointSmall) {
this.setAttribute("narrow", "");
this.removeAttribute("six-to-four");
this.removeAttribute("six-to-two");
this.removeAttribute("narrower");
this._fireResize();
}
else if (width > 0 && width <= this.breakpointSmall) {
this.setAttribute("narrower", "");
this.removeAttribute("six-to-four");
this.removeAttribute("six-to-two");
this.removeAttribute("narrow");
this._fireResize();
}
else {
this.removeAttribute("six-to-two");
this.removeAttribute("six-to-four");
this.removeAttribute("narrow");
this.removeAttribute("narrower");
}
}
connectedCallback() {
super.connectedCallback();
if (window.ResizeObserver) {
const ro = new ResizeObserver(entries => {
window.requestAnimationFrame(() => {
this._checkSize(entries[0].contentRect.width);
});
});
ro.observe(this);
}
else {
// fallback, just listen to the resize event
setTimeout(() => {
const cr = this.getBoundingClientRect();
this._checkSize(cr.width);
}, 1);
window.addEventListener("resize", this._resizeListener, true);
}
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener("resize", this._resizeListener, true);
}
/**
* Themable Styles
* @private
* @return {CSSResult}
*/
// language=CSS
static { this.styles = css `
:host {
display: grid;
grid-row-gap: var(--GridRowGapSize, 1rem);
grid-column-gap: var(--GridColumnGapSize, 1rem);
grid-template-columns: repeat(1, 1fr);
align-items: start;
}
:host([hidden]) {
display: none;
}
::slotted(*) {
width: 100%;
min-width: 0;
}
:host([narrow]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrow]) > ::slotted(*[layout-full]),
:host([narrow]) > ::slotted(*[full]) {
grid-column: 1 / auto;
}
:host([narrow-fix]) {
grid-template-columns: repeat(1, 1fr);
}
:host([layout="two"]) {
grid-template-columns: repeat(2, 1fr);
}
:host([layout="two"]) ::slotted(*[layout-double]),
:host([layout="two"]) ::slotted(*[double]) {
grid-column: span 2 / auto;
}
:host([layout="two"]) ::slotted(*[layout-newline]),
:host([layout="two"]) ::slotted(*[newline]) {
grid-column-start: 1;
grid-column-end: 1;
}
:host([layout="two"]) ::slotted(*[layout-newline][layout-double]),
:host([layout="two"]) ::slotted(*[newline][double]) {
grid-column-start: 1;
grid-column-end: 2;
}
:host([layout="two"]) ::slotted(*[layout-full]),
:host([layout="two"]) ::slotted(*[full]) {
grid-column: span 2 / auto;
}
:host([layout="two"][narrow]) > ::slotted(*),
:host([layout="two"][narrow]) > ::slotted(*[layout-full]),
:host([layout="two"][narrow]) > ::slotted(*[full]) {
grid-column: 1 / auto;
}
:host([layout="two"][narrow]) {
grid-template-columns: repeat(1, 1fr);
}
:host([layout="two"][narrow-fix]) {
grid-template-columns: repeat(1, 1fr);
}
:host([layout="two"][narrow-fix]) ::slotted(*) {
grid-column: span 1 / auto;
}
:host([layout="three"]) {
grid-template-columns: repeat(3, 1fr);
}
:host([layout="three"]) ::slotted(*[layout-double]),
:host([layout="three"]) ::slotted(*[double]) {
grid-column: span 2 / auto;
}
:host([layout="three"]) ::slotted(*[layout-newline]),
:host([layout="three"]) ::slotted(*[newline]) {
grid-column-start: 1;
grid-column-end: 2;
}
:host([layout="three"]) ::slotted(*[layout-newline][layout-double]),
:host([layout="three"]) ::slotted(*[newline][double]) {
grid-column-start: 1;
grid-column-end: 3;
}
:host([layout="three"]) ::slotted(*[layout-tripple]),
:host([layout="three"]) ::slotted(*[layout-full]),
:host([layout="three"]) ::slotted(*[full]) {
grid-column: span 3 / auto;
}
:host([layout="three"][narrow]) > ::slotted(*[layout-tripple]),
:host([layout="three"][narrow]) > ::slotted(*[tripple]),
:host([layout="three"][narrow]) > ::slotted(*[layout-full]),
:host([layout="three"][narrow]) > ::slotted(*[full]) {
grid-column: 1 / auto;
}
:host([layout="three"][narrow]) ::slotted(*[layout-double]),
:host([layout="three"][narrow]) ::slotted(*[double]) {
grid-column: span 1 / auto;
}
:host([layout="three"][narrow]) {
grid-template-columns: repeat(1, 1fr);
}
:host([layout="three"][narrow-fix]) {
grid-template-columns: repeat(1, 1fr);
}
:host([layout="three"][narrow-fix]) ::slotted(*) {
grid-column: span 1 / auto;
}
:host([layout="four"]) {
grid-template-columns: repeat(4, 1fr);
}
:host([layout="four"]) ::slotted(*[layout-double]),
:host([layout="four"]) ::slotted(*[double]) {
grid-column: span 2 / auto;
}
:host([layout="four"]) ::slotted(*[layout-tripple]),
:host([layout="four"]) ::slotted(*[tripple]) {
grid-column: span 3 / auto;
}
::slotted(*[layout-end]),
::slotted(*[end]) {
grid-column-end: -1;
}
:host([layout="four"]) ::slotted(*[layout-newline]),
:host([layout="four"]) ::slotted(*[newline]) {
grid-column-start: 1;
grid-column-end: 2;
}
:host([layout="four"]) ::slotted(*[layout-newline][layout-double]),
:host([layout="four"]) ::slotted(*[newline][double]) {
grid-column-start: 1;
grid-column-end: 3;
}
:host([layout="four"]) ::slotted(*[layout-newline][layout-tripple]),
:host([layout="four"]) ::slotted(*[newline][tripple]) {
grid-column-start: 1;
grid-column-end: 4;
}
:host([layout="four"]) ::slotted(*[layout-full]),
:host([layout="four"]) ::slotted(*[full]) {
grid-column: span 4 / auto;
}
:host([layout="four"][narrow]) > ::slotted(*[layout-full]),
:host([layout="four"][narrow]) > ::slotted(*[full]) {
grid-column: span 2 / auto;
}
:host([layout="four"][narrow]) {
grid-template-columns: repeat(2, 1fr);
}
:host([layout="four"][narrow-fix]) {
grid-template-columns: repeat(2, 1fr);
}
:host([layout="four"][narrow-fix]) > ::slotted(*) {
grid-column: span 1 / auto;
}
:host([layout="four"][narrow-fix]) > ::slotted(*[layout-double]),
:host([layout="four"][narrow-fix]) > ::slotted(*[double]) {
grid-column: span 2 / auto;
}
:host([layout="four"][narrow-fix]) > ::slotted(*[layout-full]),
:host([layout="four"][narrow-fix]) > ::slotted(*[full]) {
grid-column: span 2 / auto;
}
:host([layout="six"]) {
grid-template-columns: repeat(6, 1fr);
}
:host([layout="six"]) ::slotted(*[layout-double]),
:host([layout="six"]) ::slotted(*[double]) {
grid-column: span 2 / auto;
}
:host([layout="six"]) ::slotted(*[layout-end][layout-double]),
:host([layout="six"]) ::slotted(*[end][double]) {
grid-column-start: -3;
grid-column-end: -1;
}
:host([layout="six"]) ::slotted(*[layout-end][layout-tripple]),
:host([layout="six"]) ::slotted(*[end][tripple]) {
grid-column-start: -4;
grid-column-end: -1;
}
:host([layout="six"]) ::slotted(*[layout-tripple]),
:host([layout="six"]) ::slotted(*[tripple]) {
grid-column: span 3 / auto;
}
:host([layout="six"]) ::slotted(*[layout-newline]),
:host([layout="six"]) ::slotted(*[newline]) {
grid-column-start: 1;
grid-column-end: 2;
}
:host([layout="six"]) ::slotted(*[newline][double]),
:host([layout="six"]) ::slotted(*[layout-newline][layout-double]) {
grid-column-start: 1;
grid-column-end: 3;
}
:host([layout="six"]) ::slotted(*[newline][tripple]),
:host([layout="six"]) ::slotted(*[layout-newline][layout-tripple]) {
grid-column-start: 1;
grid-column-end: 4;
}
:host([layout="six"]) ::slotted(*[layout-full]),
:host([layout="six"]) ::slotted(*[full]) {
grid-column: span 6 / auto;
}
:host([layout="six"][narrow]) > ::slotted(*[layout-full]),
:host([layout="six"][narrow]) > ::slotted(*[full]) {
grid-column: span 3 / auto;
}
:host([layout="six"][six-to-four]) {
grid-template-columns: repeat(4, 1fr);
}
:host([layout="six"][six-to-four]) > ::slotted(*[layout-full]),
:host([layout="six"][six-to-four]) > ::slotted(*[full]) {
grid-column: span 4 / auto;
}
:host([layout="six"][six-to-two]) {
grid-template-columns: repeat(2, 1fr);
}
:host([layout="six"][six-to-two]) > ::slotted(*[layout-full]),
:host([layout="six"][six-to-two]) > ::slotted(*[full]),
:host([layout="six"][six-to-two]) > ::slotted(*[tripple]),
:host([layout="six"][six-to-two]) > ::slotted(*[layout-tripple]),
:host([layout="six"][six-to-two]) > ::slotted(*[double]),
:host([layout="six"][six-to-two]) > ::slotted(*[layout-double]) {
grid-column: span 2 / auto;
}
:host([layout="six"][narrow]) {
grid-template-columns: repeat(3, 1fr);
}
:host([layout="six"][narrow-fix]) {
grid-template-columns: repeat(3, 1fr);
}
:host([layout="six"][narrow-fix]) > ::slotted(*) {
grid-column: span 1 / auto;
}
:host([layout="six"][narrow-fix]) ::slotted(*[layout-newline]),
:host([layout="six"][narrow-fix]) ::slotted(*[newline]) {
grid-column-start: 1;
grid-column-end: 2;
}
:host([layout="six"][narrow-fix]) > ::slotted(*[layout-double]),
:host([layout="six"][narrow-fix]) > ::slotted(*[double]) {
grid-column: span 1 / auto;
}
:host([layout="six"][narrow-fix]) > ::slotted(*[layout-full]),
:host([layout="six"][narrow-fix]) > ::slotted(*[full]) {
grid-column: span 3 / auto;
}
:host([layout="four"][narrow]) > ::slotted(*[layout-tripple]),
:host([layout="four"][narrow]) > ::slotted(*[tripple]) {
grid-column: span 2 / auto;
}
:host([narrower]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower]) ::slotted(*[layout-double]),
:host([narrower]) ::slotted(*[double]) {
grid-column: 1 / auto;
}
:host([narrower][layout="six"]) ::slotted(*[layout-end][layout-double]),
:host([narrower][layout="six"]) ::slotted(*[end][double]) {
grid-column: 1 / auto;
}
:host([narrower][layout="six"]) ::slotted(*[layout-end][layout-tripple]),
:host([narrower][layout="six"]) ::slotted(*[end][tripple]) {
grid-column: 1 / auto;
}
:host([narrower]) ::slotted(*[layout-full]),
:host([narrower]) ::slotted(*[full]) {
grid-column: 1 / auto;
}
:host([narrower]) > ::slotted(*) {
grid-column: 1 / auto;
}
:host([narrower]) > ::slotted([end]),
:host([narrower]) > ::slotted(*[layout-end]),
:host([narrower]) > ::slotted(*[layout-tripple]),
:host([narrower]) > ::slotted([tripple]) {
grid-column: 1 / auto;
}
:host([narrower-fix]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower-fix][layout="two"]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower-fix][layout="three"]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower-fix][layout="four"]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower-fix][layout="six"]) {
grid-template-columns: repeat(1, 1fr);
}
:host([narrower-fix]) ::slotted(*[layout-double]),
:host([narrower-fix]) ::slotted(*[double]) {
grid-column: 1 / auto;
}
:host([narrower-fix][layout="two"]) ::slotted(*[layout-double]),
:host([narrower-fix][layout="two"]) ::slotted(*[double]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="three"]) ::slotted(*[layout-double]),
:host([narrower-fix][layout="three"]) ::slotted(*[double]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="four"]) ::slotted(*[layout-double]),
:host([narrower-fix][layout="four"]) ::slotted(*[double]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="six"]) ::slotted(*[layout-double]),
:host([narrower-fix][layout="six"]) ::slotted(*[double]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix]) > ::slotted(*[layout-full]),
:host([narrower-fix]) > ::slotted(*[full]) {
grid-column: 1 / auto;
}
:host([narrower-fix][layout="two"]) ::slotted(*[layout-full]),
:host([narrower-fix][layout="two"]) ::slotted(*[full]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="three"]) ::slotted(*[layout-full]),
:host([narrower-fix][layout="three"]) ::slotted(*[full]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="four"]) ::slotted(*[layout-full]),
:host([narrower-fix][layout="four"]) ::slotted(*[full]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix][layout="six"]) ::slotted(*[layout-full]),
:host([narrower-fix][layout="six"]) ::slotted(*[full]) {
grid-template-columns: repeat(1, 1fr);
grid-column: 1 / auto;
}
:host([narrower-fix]) > ::slotted(*) {
grid-column: 1 / auto;
}
`; }
/**
* @private
* @returns {TemplateResult}
* @private
*/
render() {
// language=HTML
return html ` <slot></slot> `;
}
}
__decorate([
property({
type: ResponsiveLayoutSize,
reflect: true,
})
], FuroResponsiveLayout.prototype, "layout", void 0);
__decorate([
property({ type: Number, attribute: "breakpoint-six", reflect: true })
], FuroResponsiveLayout.prototype, "breakpointSix", void 0);
__decorate([
property({ type: Number, attribute: "breakpoint-big", reflect: true })
], FuroResponsiveLayout.prototype, "breakpointBig", void 0);
__decorate([
property({ type: Number, attribute: "breakpoint-small", reflect: true })
], FuroResponsiveLayout.prototype, "breakpointSmall", void 0);
//# sourceMappingURL=FuroResponsiveLayout.js.map