diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app-index.ts | 93 | ||||
-rw-r--r-- | src/components/header.ts | 79 | ||||
-rw-r--r-- | src/pages/app-about/about-styles.ts | 11 | ||||
-rw-r--r-- | src/pages/app-about/app-about.ts | 45 | ||||
-rw-r--r-- | src/pages/app-home.ts | 138 | ||||
-rw-r--r-- | src/styles/global.css | 32 | ||||
-rw-r--r-- | src/styles/shared-styles.ts | 15 |
7 files changed, 413 insertions, 0 deletions
diff --git a/src/app-index.ts b/src/app-index.ts new file mode 100644 index 0000000..7f381fb --- /dev/null +++ b/src/app-index.ts @@ -0,0 +1,93 @@ +import { LitElement, css, html } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { Router } from '@vaadin/router'; + +import './pages/app-home'; +import './components/header'; +import './styles/global.css'; + +const BASE_URL: string = (import.meta.env.BASE_URL).length > 2 ? (import.meta.env.BASE_URL).slice(1,-1) : (import.meta.env.BASE_URL); + +@customElement('app-index') +export class AppIndex extends LitElement { + static get styles() { + return css` + main { + padding-left: 16px; + padding-right: 16px; + padding-bottom: 16px; + } + + #routerOutlet > * { + width: 100% !important; + } + + #routerOutlet > .leaving { + animation: 160ms fadeOut ease-in-out; + } + + #routerOutlet > .entering { + animation: 160ms fadeIn linear; + } + + @keyframes fadeOut { + from { + opacity: 1; + } + + to { + opacity: 0; + } + } + + @keyframes fadeIn { + from { + opacity: 0.2; + } + + to { + opacity: 1; + } + } + `; + } + + constructor() { + super(); + } + + firstUpdated() { + // this method is a lifecycle even in lit + // for more info check out the lit docs https://lit.dev/docs/components/lifecycle/ + + // For more info on using the @vaadin/router check here https://vaadin.com/router + const router = new Router(this.shadowRoot?.querySelector('#routerOutlet')); + router.setRoutes([ + // temporarily cast to any because of a Type bug with the router + { + path: BASE_URL, + animate: true, + children: [ + { path: '', component: 'app-home' }, + { + path: 'about', + component: 'app-about', + action: async () => { + await import('./pages/app-about/app-about.js'); + }, + } + ], + } as any, + ]); + } + + render() { + return html` + <div> + <main> + <div id="routerOutlet"></div> + </main> + </div> + `; + } +} diff --git a/src/components/header.ts b/src/components/header.ts new file mode 100644 index 0000000..2c896d5 --- /dev/null +++ b/src/components/header.ts @@ -0,0 +1,79 @@ +import { LitElement, css, html } from 'lit'; +import { property, customElement } from 'lit/decorators.js'; + +import '@shoelace-style/shoelace/dist/components/button/button.js'; +@customElement('app-header') +export class AppHeader extends LitElement { + @property({ type: String }) title = 'PWA Starter'; + + @property({ type: Boolean}) enableBack: boolean = false; + + static get styles() { + return css` + header { + display: flex; + justify-content: space-between; + align-items: center; + background: var(--app-color-primary); + color: white; + height: 4em; + padding-left: 16px; + padding-top: 12px; + + position: fixed; + left: env(titlebar-area-x, 0); + top: env(titlebar-area-y, 0); + height: env(titlebar-area-height, 50px); + width: env(titlebar-area-width, 100%); + -webkit-app-region: drag; + } + + header h1 { + margin-top: 0; + margin-bottom: 0; + font-size: 20px; + font-weight: bold; + } + + nav a { + margin-left: 10px; + } + + #back-button-block { + display: flex; + justify-content: space-between; + align-items: center; + width: 12em; + } + + @media(prefers-color-scheme: light) { + header { + color: black; + } + + nav a { + color: initial; + } + } + `; + } + + constructor() { + super(); + } + + render() { + return html` + <header> + + <div id="back-button-block"> + ${this.enableBack ? html`<sl-button href="${(import.meta as any).env.BASE_URL}"> + Back + </sl-button>` : null} + + <h1>${this.title}</h1> + </div> + </header> + `; + } +} diff --git a/src/pages/app-about/about-styles.ts b/src/pages/app-about/about-styles.ts new file mode 100644 index 0000000..001bd3f --- /dev/null +++ b/src/pages/app-about/about-styles.ts @@ -0,0 +1,11 @@ +import { css } from 'lit'; + +// these styles can be imported from any component +// for an example of how to use this, check /pages/about-about.ts +export const styles = css` + @media(min-width: 1000px) { + sl-card { + max-width: 70vw; + } + } +`;
\ No newline at end of file diff --git a/src/pages/app-about/app-about.ts b/src/pages/app-about/app-about.ts new file mode 100644 index 0000000..1e148d8 --- /dev/null +++ b/src/pages/app-about/app-about.ts @@ -0,0 +1,45 @@ +import { LitElement, html } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +// You can also import styles from another file +// if you prefer to keep your CSS seperate from your component +import { styles } from './about-styles'; + +import { styles as sharedStyles } from '../../styles/shared-styles' + +import '@shoelace-style/shoelace/dist/components/card/card.js'; + +@customElement('app-about') +export class AppAbout extends LitElement { + static styles = [ + sharedStyles, + styles + ] + + constructor() { + super(); + } + + render() { + return html` + <app-header ?enableBack="${true}"></app-header> + + <main> + <h2>About Page</h2> + + <sl-card> + <h2>Did you know?</h2> + + <p>PWAs have access to many useful APIs in modern browsers! These + APIs have enabled many new types of apps that can be built as PWAs, such as advanced graphics editing apps, games, + apps that use machine learning and more! + </p> + + <p>Check out <a + href="https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files">these + docs</a> to learn more about the advanced features that you can use in your PWA</p> + </sl-card> + </main> + `; + } +} diff --git a/src/pages/app-home.ts b/src/pages/app-home.ts new file mode 100644 index 0000000..748e276 --- /dev/null +++ b/src/pages/app-home.ts @@ -0,0 +1,138 @@ +import { LitElement, css, html } from 'lit'; +import { property, customElement } from 'lit/decorators.js'; + +import '@shoelace-style/shoelace/dist/components/card/card.js'; +import '@shoelace-style/shoelace/dist/components/button/button.js'; + +import { styles } from '../styles/shared-styles'; + +@customElement('app-home') +export class AppHome extends LitElement { + + // For more information on using properties and state in lit + // check out this link https://lit.dev/docs/components/properties/ + @property() message = 'Welcome!'; + + static get styles() { + return [ + styles, + css` + #welcomeBar { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + } + + #welcomeCard, + #infoCard { + padding: 18px; + padding-top: 0px; + } + + sl-card::part(footer) { + display: flex; + justify-content: flex-end; + } + + @media(min-width: 750px) { + sl-card { + width: 70vw; + } + } + + + @media (horizontal-viewport-segments: 2) { + #welcomeBar { + flex-direction: row; + align-items: flex-start; + justify-content: space-between; + } + + #welcomeCard { + margin-right: 64px; + } + } + `]; + } + + constructor() { + super(); + } + + async firstUpdated() { + // this method is a lifecycle even in lit + // for more info check out the lit docs https://lit.dev/docs/components/lifecycle/ + console.log('This is your home page'); + } + + share() { + if ((navigator as any).share) { + (navigator as any).share({ + title: 'PWABuilder pwa-starter', + text: 'Check out the PWABuilder pwa-starter!', + url: 'https://github.com/pwa-builder/pwa-starter', + }); + } + } + + render() { + return html` + <app-header></app-header> + + <main> + <div id="welcomeBar"> + <sl-card id="welcomeCard"> + <div slot="header"> + <h2>${this.message}</h2> + </div> + + <p> + For more information on the PWABuilder pwa-starter, check out the + <a href="https://github.com/pwa-builder/pwa-starter/wiki/Getting-Started"> + Documentation on Github</a>. + </p> + + <p id="mainInfo"> + Welcome to the + <a href="https://pwabuilder.com">PWABuilder</a> + pwa-starter! Be sure to head back to + <a href="https://pwabuilder.com">PWABuilder</a> + when you are ready to ship this PWA to the Microsoft Store, Google Play + and the Apple App Store! + </p> + + ${'share' in navigator + ? html`<sl-button slot="footer" variant="primary" @click="${this.share}">Share this Starter!</sl-button>` + : null} + </sl-card> + + <sl-card id="infoCard"> + <h2>Technology Used</h2> + + <ul> + <li> + <a href="https://www.typescriptlang.org/">TypeScript</a> + </li> + + <li> + <a href="https://lit.dev">lit</a> + </li> + + <li> + <a href="https://shoelace.style/">Shoelace</a> + </li> + + <li> + <a href="https://vaadin.github.io/vaadin-router/vaadin-router/demo/#vaadin-router-getting-started-demos" + >Vaadin Router</a> + </li> + </ul> + </sl-card> + + <sl-button href="${(import.meta as any).env.BASE_URL}about" variant="primary">Navigate to About</sl-button> + </div> + </main> + `; + } +} diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..aab0c0d --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,32 @@ + +/* + This file is used for all of your global styles and CSS variables. + Check here https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties for more info on using CSS variables. +*/ +:root { + --font-family: sans-serif; +} + +html, body { + font-family: var(--font-family); + padding: 0; + margin: 0; +} + +@media (prefers-color-scheme: dark) { + + html, + body { + background-color: #181818; + color: white; + } +} + +@media (prefers-color-scheme: light) { + + html, + body { + background-color: white; + color: black; + } +} diff --git a/src/styles/shared-styles.ts b/src/styles/shared-styles.ts new file mode 100644 index 0000000..c4fb4a0 --- /dev/null +++ b/src/styles/shared-styles.ts @@ -0,0 +1,15 @@ +import { css } from 'lit'; + +// these styles can be imported from any component +// for an example of how to use this, check /pages/about-about.ts +export const styles = css` + @media(min-width: 1000px) { + sl-card { + max-width: 70vw; + } + } + + main { + margin-top: 80px; + } +`;
\ No newline at end of file |