@components-1812/offcanvas
Version:
A web component for custom offcanvas, lateral panel
349 lines (304 loc) • 10.7 kB
CSS
/**
* package: @components-1812/offcanvas
* version: 0.0.3
*/
:host {
--offcanvas-position: absolute;
--offcanvas-z-index: 8010;
width: 100%;
height: 100%;
position: var(--offcanvas-position);
top: 0;
left: 0;
z-index: var(--offcanvas-z-index);
pointer-events: none;
/* Panel */
--offcanvas-panel-width: 300px;
--offcanvas-panel-height: 100%;
--offcanvas-panel-padding: 5px;
--offcanvas-panel-transition: margin 0.3s ease-in-out;
--offcanvas-panel-header-padding: 5px;
--offcanvas-panel-body-padding: 5px;
--offcanvas-panel-footer-padding: 5px;
--offcanvas-panel-bg: #222;
--offcanvas-panel-color: #fff;
--offcanvas-panel-header-bg: var(--offcanvas-panel-bg);
--offcanvas-panel-header-color: var(--offcanvas-panel-color);
--offcanvas-panel-footer-bg: var(--offcanvas-panel-bg);
--offcanvas-panel-footer-color: var(--offcanvas-panel-color);
--offcanvas-panel-border: 1px solid #ccc;
--offcanvas-panel-border-radius: 0px;
--offcanvas-panel-shadow: 0 1px 3px 0 #3c40434d, 0 4px 8px 3px #3c404326;
/* Backdrop */
--offcanvas-backdrop-bg: #00000080;
--offcanvas-backdrop-color: #fff;
--offcanvas-backdrop-transition: background-color 0.3s ease-in-out;
/* Close button */
--offcanvas-close-button-width: 40px;
--offcanvas-close-button-height: 40px;
--offcanvas-close-button-padding: 10px;
--offcanvas-close-button-bg: transparent;
--offcanvas-close-button-color: #fff;
--offcanvas-close-button-border: none;
--offcanvas-close-button-font-size: 1.5rem;
--offcanvas-close-button-cursor: pointer;
/* Handle button */
--offcanvas-handle-button-width: 50px;
--offcanvas-handle-button-height: 100px;
--offcanvas-handle-button-padding: 5px;
--offcanvas-handle-button-bg: #444;
--offcanvas-handle-button-color: #fff;
--offcanvas-handle-button-border: none;
--offcanvas-handle-button-border-radius: 10px;
--offcanvas-handle-button-cursor: pointer;
--offcanvas-handle-button-font-size: 1rem;
--offcanvas-handle-button-shadow: var(--offcanvas-panel-shadow);
}
:host([variant~="top"]), :host([variant~="bottom"]) {
--offcanvas-panel-width: 100%;
--offcanvas-panel-height: 300px;
--offcanvas-handle-button-width: 100px;
--offcanvas-handle-button-height: 50px;
--offcanvas-panel-shadow: 1px 0 3px 0 #3c40434d, 4px 0 8px 3px #3c404326;
}
:host([variant~="global"]) {
--offcanvas-position: fixed;
}
:host([variant~="local"]) {
--offcanvas-position: absolute;
}
:host .offcanvas {
width: 100%;
height: 100%;
background-color: transparent;
transition: var(--offcanvas-backdrop-transition);
pointer-events: none;
display: flex;
&[open]:not([variant~="backdrop-transparent"]) {
background-color: var(--offcanvas-backdrop-bg);
}
&[variant~="left"], & {
flex-direction: row;
}
&[variant~="right"] {
flex-direction: row-reverse;
}
&[variant~="top"] {
flex-direction: column;
}
&[variant~="bottom"] {
flex-direction: column-reverse;
}
}
/*MARK: Panel*/
:host .offcanvas {
.panel {
width: var(--offcanvas-panel-width);
height: var(--offcanvas-panel-height);
padding: var(--offcanvas-panel-padding);
position: relative;
box-sizing: border-box;
pointer-events: initial;
background: var(--offcanvas-panel-bg);
color: var(--offcanvas-panel-color);
overflow: hidden;
transition: var(--offcanvas-panel-transition);
.panel-content {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.panel-header {
position: relative;
padding: var(--offcanvas-panel-header-padding);
background: var(--offcanvas-panel-header-bg);
color: var(--offcanvas-panel-header-color);
}
.panel-body {
position: relative;
flex: 1 1 auto;
padding: var(--offcanvas-panel-body-padding);
}
.panel-footer {
position: relative;
padding: var(--offcanvas-panel-footer-padding);
background: var(--offcanvas-panel-footer-bg);
color: var(--offcanvas-panel-footer-color);
}
}
&[variant~="scroll-full"] .panel-content {
overflow: auto;
}
&[variant~="scroll-inner"] .panel-content {
overflow: auto;
.panel-header {
position: sticky;
inset: 0 auto auto 0;
z-index: 10;
}
}
&[variant~="scroll-body"] .panel {
.panel-body {
overflow: auto;
}
}
&[variant~="left"] .panel, .panel {
border-top: none;
border-left: none;
border-bottom: none;
border-right: var(--offcanvas-panel-border);
border-radius: 0 var(--offcanvas-panel-border-radius) var(--offcanvas-panel-border-radius) 0;
margin: 0 0 0 calc(-1 * var(--offcanvas-panel-width));
}
&[variant~="right"] .panel {
border-top: none;
border-left: var(--offcanvas-panel-border);;
border-bottom: none;
border-right: none;
border-radius: var(--offcanvas-panel-border-radius) 0 0 var(--offcanvas-panel-border-radius);
margin: 0 calc(-1 * var(--offcanvas-panel-width)) 0 0;
}
&[variant~="top"] .panel {
border-top: none;
border-left: none;
border-bottom: var(--offcanvas-panel-border);
border-right: none;
border-radius: 0 0 var(--offcanvas-panel-border-radius) var(--offcanvas-panel-border-radius);
margin: calc(-1 * var(--offcanvas-panel-height)) 0 0 0;
}
&[variant~="bottom"] .panel {
border-top: var(--offcanvas-panel-border);
border-left: none;
border-bottom: none;
border-right: none;
border-radius: var(--offcanvas-panel-border-radius) var(--offcanvas-panel-border-radius) 0 0;
margin: 0 0 calc(-1 * var(--offcanvas-panel-height)) 0;
}
&[open] .panel {
box-shadow: var(--offcanvas-panel-shadow);
margin: 0;
}
}
/*MARK: Backdrop */
:host .offcanvas {
.offcanvas-backdrop {
pointer-events: none;
flex: 1 1 auto;
position: relative;
color: var(--offcanvas-backdrop-color);
::slotted(*) {
pointer-events: initial;
}
::slotted([data-hide-when-closed]){
display: none;
}
}
&[open] .offcanvas-backdrop {
pointer-events: initial;
::slotted([data-hide-when-closed]){
display: unset;
}
::slotted([data-hide-when-opened]){
display: none;
}
}
&[open][variant~="backdrop-static"] .offcanvas-backdrop {
pointer-events: none;
}
}
/*MARK: Close button*/
:host .offcanvas {
.close-button {
pointer-events: initial;
position: absolute;
inset: 0 0 auto auto;
width: var(--offcanvas-close-button-width);
height: var(--offcanvas-close-button-height);
padding: var(--offcanvas-close-button-padding);
background: var(--offcanvas-close-button-bg);
color: var(--offcanvas-close-button-color);
border: var(--offcanvas-close-button-border);
font-size: var(--offcanvas-close-button-font-size);
cursor: var(--offcanvas-close-button-cursor);
display: flex;
align-items: center;
justify-content: center;
}
}
/*MARK: Handle button*/
:host .offcanvas {
.handle-button {
pointer-events: initial;
position: absolute;
box-sizing: border-box;
width: var(--offcanvas-handle-button-width);
height: var(--offcanvas-handle-button-height);
padding: var(--offcanvas-handle-button-padding);
background: var(--offcanvas-handle-button-bg);
color: var(--offcanvas-handle-button-color);
box-shadow: var(--offcanvas-handle-button-shadow);
border: var(--offcanvas-handle-button-border);
font-size: var(--offcanvas-handle-button-font-size);
cursor: var(--offcanvas-handle-button-cursor);
margin: auto;
}
&[variant~="left"], & {
.handle-button {
inset: 0 auto 0 0;
border-radius: 0 var(--offcanvas-handle-button-border-radius) var(--offcanvas-handle-button-border-radius) 0;
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 0deg;
}
}
&[open] .handle-button {
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 180deg;
}
}
}
&[variant~="right"] {
.handle-button {
inset: 0 0 0 auto;
border-radius: var(--offcanvas-handle-button-border-radius) 0 0 var(--offcanvas-handle-button-border-radius);
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 180deg;
}
}
&[open] .handle-button {
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 0deg;
}
}
}
&[variant~="top"] {
.handle-button {
inset: 0 0 auto 0;
border-radius: 0 0 var(--offcanvas-handle-button-border-radius) var(--offcanvas-handle-button-border-radius);
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 90deg;
}
}
&[open] .handle-button {
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: -90deg;
}
}
}
&[variant~="bottom"] {
.handle-button {
inset: auto 0 0 0;
border-radius: var(--offcanvas-handle-button-border-radius) var(--offcanvas-handle-button-border-radius) 0 0;
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: -90deg;
}
}
&[open] .handle-button {
::slotted([data-rotate-icon]), svg[data-rotate-icon]{
rotate: 90deg;
}
}
}
}