Framework WIP:

App slots & positioning for default view
This commit is contained in:
nathan 2024-04-29 15:04:56 -06:00
parent d60d667bd3
commit 29c8baaa83
4 changed files with 152 additions and 58 deletions

View File

@ -71,6 +71,7 @@ egw-framework#egw_fw_basecontainer {
egw-app { egw-app {
&::part(name) { &::part(name) {
display: flex;
align-items: center; align-items: center;
} }
} }

View File

@ -50,7 +50,7 @@
<!-- Fake app --> <!-- Fake app -->
<egw-app name="fake app" class="placeholder"> <egw-app name="fake app" class="placeholder">
<div slot="banner">Something inside the app - main</div> <div style="border: 1px dotted">Something inside the app - main</div>
</egw-app> </egw-app>
</egw-framework> </egw-framework>

View File

@ -9,7 +9,8 @@ export default css`
width: 100%; width: 100%;
height: 100%; height: 100%;
display: grid; display: flex;
flex-direction: column;
} }
:host > * { :host > * {
@ -17,53 +18,89 @@ export default css`
display: flex; display: flex;
} }
.egw_fw_app__left { .egw_fw_app__name {
grid-area: left; max-width: 20vw;
overflow-x: hidden; flex: 1 1 20vw;
overflow-y: auto;
}
.egw_fw_app__right {
grid-area: right;
overflow-x: hidden;
overflow-y: auto;
}
.egw_fw_app__main {
grid-area: main;
overflow: hidden;
overflow-x: auto;
} }
.egw_fw_app__header { .egw_fw_app__header {
grid-area: header; justify-content: flex-start;
align-items: center;
justify-items: stretch;
flex: 1 0 2em;
max-height: 3em;
}
.egw_fw_app__aside {
overflow-x: hidden;
overflow-y: auto;
display: grid;
grid-template-rows: subgrid;
grid-row: start / end;
} }
.egw_fw_app__aside_header {
grid-row: sub-header / main;
}
.egw_fw_app__aside_content {
height: 100%;
grid-row: main / footer;
}
.egw_fw_app__aside_footer {
grid-row: footer / end;
}
.egw_fw_app__left {
grid-column: left / left;
}
.egw_fw_app__right {
grid-column: right / right;
}
.egw_fw_app__main {
flex: 1 1 100%;
display: grid;
align-items: stretch;
justify-content: stretch;
overflow: hidden;
overflow-x: auto;
}
.egw_fw_app__header {
grid-row: sub-header / main;
grid-column: main / main;
}
.egw_fw_app__main_content {
grid-row: main / footer;
grid-column: main / main;
}
.egw_fw_app__footer { .egw_fw_app__footer {
grid-area: footer; grid-column: main / right;
grid-row: footer / end;
} }
@media (min-width: 500px) { @media (min-width: 500px) {
:host { .egw_fw_app__main {
grid-template-columns: [start left] fit-content(20%) [main] 1fr [right] fit-content(50%) [end]; grid-template-columns: [start left] fit-content(20%) [main] 1fr [right] fit-content(50%) [end];
grid-template-rows: [header] fit-content(2em) [main] 1fr [footer bottom] fit-content(2em) [end]; grid-template-rows: [start sub-header] fit-content(2em) [main] auto [footer] fit-content(2em) [end];
grid-template-areas: }
"left-header header right-header"
"left main right" ::slotted(*) {
"left-footer footer right-footer" height: 100%;
} }
} }
@media (max-width: 500px) { @media (max-width: 500px) {
:host { .egw_fw_app__main {
grid-template-areas: grid-template-areas:
"header" "header"
"main" "main"
"left right" "left right"
} "footer"
[slot="footer"] {
display: none;
} }
} }
` `

View File

@ -6,6 +6,31 @@ import {property} from "lit/decorators/property.js";
import styles from "./EgwApp.styles"; import styles from "./EgwApp.styles";
import {state} from "lit/decorators/state.js"; import {state} from "lit/decorators/state.js";
/**
* @summary Application component inside EgwFramework
*
* @dependency sl-icon-button
*
* @slot - Main application content. Other slots are normally hidden if they have no content
* @slot header - Top of app, contains logo, app icons.
* @slot footer - Very bottom of the main content.
* @slot left - Optional content to the left. Use for application navigation.
* @slot left-header - Top of left side
* @slot left-footer - bottom of left side
* @slot right - Optional content to the right. Use for application context details.
* @slot right-header - Top of right side
* @slot right-footer - bottom of right side
*
* @csspart name - Top left, holds the application name.
* @csspart header - Top main application header, optional application toolbar goes here.
* @csspart content-header - Top of center, optional.
* @csspart main - Main application content.
* @csspart left - Left optional content.
* @csspart right - Right optional content.
* @csspart footer - Very bottom of the main content.
*
* @cssproperty [--icon-size=32] - Height of icons used in the framework
*/
@customElement('egw-app') @customElement('egw-app')
//@ts-ignore //@ts-ignore
export class EgwApp extends LitElement export class EgwApp extends LitElement
@ -17,27 +42,34 @@ export class EgwApp extends LitElement
// TEMP STUFF // TEMP STUFF
css` css`
:host { :host .placeholder {
display: none;
}
:host(.placeholder) .placeholder {
display: block;
--placeholder-background-color: #e97234; --placeholder-background-color: #e97234;
} }
.placeholder { .placeholder {
width: 100%; width: 100%;
display: block;
font-size: 200%; font-size: 200%;
text-align: center; text-align: center;
background-color: var(--placeholder-background-color, silver); background-color: var(--placeholder-background-color);
} }
.placeholder:after { .placeholder:after, .placeholder:before {
content: " (placeholder)"; content: " ";
} }
[class*="left"] .placeholder, [class*="right"] .placeholder { :host(.placeholder) [class*="left"] .placeholder {
background-color: color-mix(in lch, var(--placeholder-background-color), rgba(1, 1, 1, .5)); background-color: color-mix(in lch, var(--placeholder-background-color), rgba(.5, .5, 1, .1));
} }
[class*="footer"] .placeholder { :host(.placeholder) [class*="right"] .placeholder {
background-color: color-mix(in lch, var(--placeholder-background-color), rgba(.5, 1, .5, .1));
}
:host(.placeholder) [class*="footer"] .placeholder {
background-color: color-mix(in lch, var(--placeholder-background-color), rgba(1, 1, 1, .05)); background-color: color-mix(in lch, var(--placeholder-background-color), rgba(1, 1, 1, .05));
} }
` `
@ -58,6 +90,7 @@ export class EgwApp extends LitElement
render() render()
{ {
return html` return html`
<div class="egw_fw_app__header">
<div class="egw_fw_app__name" part="name"> <div class="egw_fw_app__name" part="name">
<sl-icon-button name="${this.leftCollapsed ? "chevron-double-right" : "chevron-double-left"}" <sl-icon-button name="${this.leftCollapsed ? "chevron-double-right" : "chevron-double-left"}"
label="${this.egw?.lang("Hide area")}" label="${this.egw?.lang("Hide area")}"
@ -65,22 +98,45 @@ export class EgwApp extends LitElement
></sl-icon-button> ></sl-icon-button>
<h2>${this.egw?.lang(this.name) ?? this.name}</h2> <h2>${this.egw?.lang(this.name) ?? this.name}</h2>
</div> </div>
<aside class="egw_fw_app__left" part="left">
<slot name="left"><span class="placeholder">left</span></slot>
</aside>
<aside class="egw_fw_app__right" part="right">
<slot name="right"><span class="placeholder">right</span></slot>
</aside>
<header class="egw_fw_app__header" part="header"> <header class="egw_fw_app__header" part="header">
<slot name="main-header"><span class="placeholder"> ${this.name} main-header</span></slot> <slot name="main-header"><span class="placeholder"> ${this.name} main-header</span></slot>
</header> </header>
</div>
<main class="egw_fw_app__main" part="main" <main class="egw_fw_app__main" part="main"
aria-label="${this.name}" tabindex="0"> aria-label="${this.name}" tabindex="0">
<aside class="egw_fw_app__aside egw_fw_app__left" part="left">
<div class="egw_fw_app__aside_header">
<slot name="left-header"><span class="placeholder">left-header</span></slot>
</div>
<div class="egw_fw_app__aside_content">
<slot name="left"><span class="placeholder">left</span></slot>
</div>
<div class="egw_fw_app__aside_footer">
<slot name="left-footer"><span class="placeholder">left-footer</span></slot>
</div>
</aside>
<aside class="egw_fw_app__aside egw_fw_app__right" part="right">
<div class="egw_fw_app__aside_header">
<slot name="right-header"><span class="placeholder">right-header</span></slot>
</div>
<div class="egw_fw_app__aside_content">
<slot name="right"><span class="placeholder">right</span></slot>
</div>
<div class="egw_fw_app__aside_footer">
<slot name="right-footer"><span class="placeholder">right-footer</span></slot>
</div>
</aside>
<header class="egw_fw_app__header" part="content-header">
<slot name="header"><span class="placeholder">header</span></slot>
</header>
<main class="egw_fw_app__main_content" part="content">
<slot><span class="placeholder">main</span></slot> <slot><span class="placeholder">main</span></slot>
</main> </main>
<footer class="egw_fw_app__footer" part="footer"> <footer class="egw_fw_app__footer" part="footer">
<slot name="footer"><span class="placeholder">main-footer</span></slot> <slot name="footer"><span class="placeholder">main-footer</span></slot>
</footer> </footer>
</main>
`; `;
} }
} }