mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Use page instead of demo (#11118)
* Use page instead of demo * Update netlify script * Update ci.yml * Rename demo -> page
This commit is contained in:
parent
2c0d330f1f
commit
3133f9b01f
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -30,7 +30,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
- name: Build resources
|
- name: Build resources
|
||||||
run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-demos
|
run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages
|
||||||
- name: Run eslint
|
- name: Run eslint
|
||||||
run: yarn run lint:eslint
|
run: yarn run lint:eslint
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
|
@ -19,14 +19,14 @@ require("./service-worker.js");
|
|||||||
require("./entry-html.js");
|
require("./entry-html.js");
|
||||||
require("./rollup.js");
|
require("./rollup.js");
|
||||||
|
|
||||||
gulp.task("gather-gallery-demos", async function gatherDemos() {
|
gulp.task("gather-gallery-pages", async function gatherPages() {
|
||||||
const demoDir = path.resolve(paths.gallery_dir, "src/demos");
|
const pageDir = path.resolve(paths.gallery_dir, "src/pages");
|
||||||
const files = glob.sync(path.resolve(demoDir, "**/*"));
|
const files = glob.sync(path.resolve(pageDir, "**/*"));
|
||||||
|
|
||||||
const galleryBuild = path.resolve(paths.gallery_dir, "build");
|
const galleryBuild = path.resolve(paths.gallery_dir, "build");
|
||||||
fs.mkdirSync(galleryBuild, { recursive: true });
|
fs.mkdirSync(galleryBuild, { recursive: true });
|
||||||
|
|
||||||
let content = "export const DEMOS = {\n";
|
let content = "export const PAGES = {\n";
|
||||||
|
|
||||||
const processed = new Set();
|
const processed = new Set();
|
||||||
|
|
||||||
@ -34,17 +34,17 @@ gulp.task("gather-gallery-demos", async function gatherDemos() {
|
|||||||
if (fs.lstatSync(file).isDirectory()) {
|
if (fs.lstatSync(file).isDirectory()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
demoId = file.substring(demoDir.length + 1, file.lastIndexOf("."));
|
const pageId = file.substring(pageDir.length + 1, file.lastIndexOf("."));
|
||||||
|
|
||||||
if (processed.has(demoId)) {
|
if (processed.has(pageId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
processed.add(demoId);
|
processed.add(pageId);
|
||||||
|
|
||||||
const [category, name] = demoId.split("/", 2);
|
const [category, name] = pageId.split("/", 2);
|
||||||
|
|
||||||
const demoFile = path.resolve(demoDir, `${demoId}.ts`);
|
const demoFile = path.resolve(pageDir, `${pageId}.ts`);
|
||||||
const descriptionFile = path.resolve(demoDir, `${demoId}.markdown`);
|
const descriptionFile = path.resolve(pageDir, `${pageId}.markdown`);
|
||||||
const hasDemo = fs.existsSync(demoFile);
|
const hasDemo = fs.existsSync(demoFile);
|
||||||
let hasDescription = fs.existsSync(descriptionFile);
|
let hasDescription = fs.existsSync(descriptionFile);
|
||||||
let metadata = {};
|
let metadata = {};
|
||||||
@ -63,24 +63,25 @@ gulp.task("gather-gallery-demos", async function gatherDemos() {
|
|||||||
if (descriptionContent === "") {
|
if (descriptionContent === "") {
|
||||||
hasDescription = false;
|
hasDescription = false;
|
||||||
} else {
|
} else {
|
||||||
|
descriptionContent = marked(descriptionContent).replace(/`/g, "\\`");
|
||||||
fs.mkdirSync(path.resolve(galleryBuild, category), { recursive: true });
|
fs.mkdirSync(path.resolve(galleryBuild, category), { recursive: true });
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve(galleryBuild, `${demoId}-description.ts`),
|
path.resolve(galleryBuild, `${pageId}-description.ts`),
|
||||||
`
|
`
|
||||||
import {html} from "lit";
|
import {html} from "lit";
|
||||||
export default html\`${marked(descriptionContent)}\`
|
export default html\`${descriptionContent}\`
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content += ` "${demoId}": {
|
content += ` "${pageId}": {
|
||||||
metadata: ${JSON.stringify(metadata)},
|
metadata: ${JSON.stringify(metadata)},
|
||||||
${
|
${
|
||||||
hasDescription
|
hasDescription
|
||||||
? `description: () => import("./${demoId}-description").then(m => m.default),`
|
? `description: () => import("./${pageId}-description").then(m => m.default),`
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
${hasDemo ? `load: () => import("../src/demos/${demoId}")` : ""}
|
${hasDemo ? `demo: () => import("../src/pages/${pageId}")` : ""}
|
||||||
|
|
||||||
},\n`;
|
},\n`;
|
||||||
}
|
}
|
||||||
@ -93,51 +94,54 @@ gulp.task("gather-gallery-demos", async function gatherDemos() {
|
|||||||
delete require.cache[sidebarPath];
|
delete require.cache[sidebarPath];
|
||||||
const sidebar = require(sidebarPath);
|
const sidebar = require(sidebarPath);
|
||||||
|
|
||||||
const demosToProcess = {};
|
const pagesToProcess = {};
|
||||||
for (const key of processed) {
|
for (const key of processed) {
|
||||||
const [category, demo] = key.split("/", 2);
|
const [category, page] = key.split("/", 2);
|
||||||
if (!(category in demosToProcess)) {
|
if (!(category in pagesToProcess)) {
|
||||||
demosToProcess[category] = new Set();
|
pagesToProcess[category] = new Set();
|
||||||
}
|
}
|
||||||
demosToProcess[category].add(demo);
|
pagesToProcess[category].add(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const group of Object.values(sidebar)) {
|
for (const group of Object.values(sidebar)) {
|
||||||
const toProcess = demosToProcess[group.category];
|
const toProcess = pagesToProcess[group.category];
|
||||||
delete demosToProcess[group.category];
|
delete pagesToProcess[group.category];
|
||||||
|
|
||||||
if (!toProcess) {
|
if (!toProcess) {
|
||||||
console.error("Unknown category", group.category);
|
console.error("Unknown category", group.category);
|
||||||
|
if (!group.pages) {
|
||||||
|
group.pages = [];
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any pre-defined groups will not be sorted.
|
// Any pre-defined groups will not be sorted.
|
||||||
if (group.demos) {
|
if (group.pages) {
|
||||||
for (const demo of group.demos) {
|
for (const page of group.pages) {
|
||||||
if (!toProcess.delete(demo)) {
|
if (!toProcess.delete(page)) {
|
||||||
console.error("Found unreferenced demo", demo);
|
console.error("Found unreferenced demo", page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
group.demos = [];
|
group.pages = [];
|
||||||
}
|
}
|
||||||
for (const demo of Array.from(toProcess).sort()) {
|
for (const page of Array.from(toProcess).sort()) {
|
||||||
group.demos.push(demo);
|
group.pages.push(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [category, demos] of Object.entries(demosToProcess)) {
|
for (const [category, pages] of Object.entries(pagesToProcess)) {
|
||||||
sidebar.push({
|
sidebar.push({
|
||||||
category,
|
category,
|
||||||
header: category,
|
header: category,
|
||||||
demos: Array.from(demos),
|
pages: Array.from(pages).sort(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
content += `export const SIDEBAR = ${JSON.stringify(sidebar, null, 2)};\n`;
|
content += `export const SIDEBAR = ${JSON.stringify(sidebar, null, 2)};\n`;
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve(galleryBuild, "import-demos.ts"),
|
path.resolve(galleryBuild, "import-pages.ts"),
|
||||||
content,
|
content,
|
||||||
"utf-8"
|
"utf-8"
|
||||||
);
|
);
|
||||||
@ -155,7 +159,7 @@ gulp.task(
|
|||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
"build-translations",
|
"build-translations",
|
||||||
"build-locale-data",
|
"build-locale-data",
|
||||||
"gather-gallery-demos"
|
"gather-gallery-pages"
|
||||||
),
|
),
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
"gen-index-gallery-dev",
|
"gen-index-gallery-dev",
|
||||||
@ -166,10 +170,10 @@ gulp.task(
|
|||||||
async function watchMarkdownFiles() {
|
async function watchMarkdownFiles() {
|
||||||
gulp.watch(
|
gulp.watch(
|
||||||
[
|
[
|
||||||
path.resolve(paths.gallery_dir, "src/demos/**/*.markdown"),
|
path.resolve(paths.gallery_dir, "src/pages/**/*.markdown"),
|
||||||
path.resolve(paths.gallery_dir, "sidebar.js"),
|
path.resolve(paths.gallery_dir, "sidebar.js"),
|
||||||
],
|
],
|
||||||
gulp.series("gather-gallery-demos")
|
gulp.series("gather-gallery-pages")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -188,7 +192,7 @@ gulp.task(
|
|||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
"build-translations",
|
"build-translations",
|
||||||
"build-locale-data",
|
"build-locale-data",
|
||||||
"gather-gallery-demos"
|
"gather-gallery-pages"
|
||||||
),
|
),
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery",
|
env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
TARGET_LABEL="Needs gallery preview"
|
TARGET_LABEL="Needs design preview"
|
||||||
|
|
||||||
if [[ "$NETLIFY" != "true" ]]; then
|
if [[ "$NETLIFY" != "true" ]]; then
|
||||||
echo "This script can only be run on Netlify"
|
echo "This script can only be run on Netlify"
|
||||||
@ -13,7 +13,7 @@ function createStatus() {
|
|||||||
target_url="$3"
|
target_url="$3"
|
||||||
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
|
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
|
||||||
"https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \
|
"https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \
|
||||||
-d '{"state": "'"${state}"'", "context": "Netlify/Gallery Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}'
|
-d '{"state": "'"${state}"'", "context": "Netlify/Design Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ if [[ "${PULL_REQUEST}" == "false" ]]; then
|
|||||||
else
|
else
|
||||||
if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
|
if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \
|
||||||
"https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then
|
"https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then
|
||||||
createStatus "pending" "Building gallery preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID"
|
createStatus "pending" "Building design preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID"
|
||||||
gulp build-gallery
|
gulp build-gallery
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
createStatus "success" "Build complete" "$DEPLOY_URL"
|
createStatus "success" "Build complete" "$DEPLOY_URL"
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
{
|
{
|
||||||
category: "introduction",
|
// This section has no header and so all page links are shown directly in the sidebar
|
||||||
demos: ["introduction"],
|
category: "concepts",
|
||||||
|
pages: ["home"],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
category: "lovelace",
|
category: "lovelace",
|
||||||
// Each section has a header
|
// Label for in the sidebar
|
||||||
header: "Lovelace",
|
header: "Lovelace",
|
||||||
// Specify demos to make sure they are put on top.
|
// Specify order of pages. Any pages in the category folder but not listed here will
|
||||||
demos: [],
|
// automatically be added after the pages listed here.
|
||||||
// Add a demoStart to automatically gather demos based on their name
|
pages: ["introduction"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "automation",
|
category: "automation",
|
||||||
@ -19,22 +20,17 @@ module.exports = [
|
|||||||
{
|
{
|
||||||
category: "components",
|
category: "components",
|
||||||
header: "Components",
|
header: "Components",
|
||||||
demos: [
|
|
||||||
"ha-alert",
|
|
||||||
"ha-bar",
|
|
||||||
"ha-chips",
|
|
||||||
"ha-faded",
|
|
||||||
"ha-form",
|
|
||||||
"ha-label-badge",
|
|
||||||
"ha-selector",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "more-info",
|
category: "more-info",
|
||||||
header: "More Info",
|
header: "More Info dialogs",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "rest",
|
category: "misc",
|
||||||
header: "Rest",
|
header: "Miscelaneous",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "design.home-assistant.io",
|
||||||
|
header: "Design Documentation",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
import { html, css, LitElement } from "lit";
|
|
||||||
import { customElement, property } from "lit/decorators";
|
|
||||||
import { until } from "lit/directives/until";
|
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
|
||||||
import { DEMOS } from "../../build/import-demos";
|
|
||||||
|
|
||||||
@customElement("demo-description")
|
|
||||||
class DemoDescription extends LitElement {
|
|
||||||
@property() public demo!: string;
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!DEMOS[this.demo].description) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return html`
|
|
||||||
${until(
|
|
||||||
DEMOS[this.demo].description().then(
|
|
||||||
(content) => html`
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">${content}</div>
|
|
||||||
</ha-card>
|
|
||||||
`
|
|
||||||
),
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = [
|
|
||||||
haStyle,
|
|
||||||
css`
|
|
||||||
ha-card {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 16px auto;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"demo-description": DemoDescription;
|
|
||||||
}
|
|
||||||
}
|
|
50
gallery/src/components/page-description.ts
Normal file
50
gallery/src/components/page-description.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { html, css } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { until } from "lit/directives/until";
|
||||||
|
import { HaMarkdown } from "../../../src/components/ha-markdown";
|
||||||
|
import { PAGES } from "../../build/import-pages";
|
||||||
|
|
||||||
|
@customElement("page-description")
|
||||||
|
class PageDescription extends HaMarkdown {
|
||||||
|
@property() public page!: string;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!PAGES[this.page].description) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
${until(
|
||||||
|
PAGES[this.page].description().then(
|
||||||
|
(content) => html`
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">${content}</div>
|
||||||
|
</ha-card>
|
||||||
|
`
|
||||||
|
),
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = [
|
||||||
|
HaMarkdown.styles,
|
||||||
|
css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 16px auto;
|
||||||
|
}
|
||||||
|
.card-content > *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.card-content > *:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"page-description": PageDescription;
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ import "../../src/components/ha-card";
|
|||||||
import "../../src/components/ha-icon-button";
|
import "../../src/components/ha-icon-button";
|
||||||
import "../../src/managers/notification-manager";
|
import "../../src/managers/notification-manager";
|
||||||
import { haStyle } from "../../src/resources/styles";
|
import { haStyle } from "../../src/resources/styles";
|
||||||
import { DEMOS, SIDEBAR } from "../build/import-demos";
|
import { PAGES, SIDEBAR } from "../build/import-pages";
|
||||||
import { dynamicElement } from "../../src/common/dom/dynamic-element-directive";
|
import { dynamicElement } from "../../src/common/dom/dynamic-element-directive";
|
||||||
import "./components/demo-description";
|
import "./components/page-description";
|
||||||
|
|
||||||
const GITHUB_DEMO_URL =
|
const GITHUB_DEMO_URL =
|
||||||
"https://github.com/home-assistant/frontend/blob/dev/gallery/src/demos/";
|
"https://github.com/home-assistant/frontend/blob/dev/gallery/src/pages/";
|
||||||
|
|
||||||
const FAKE_HASS = {
|
const FAKE_HASS = {
|
||||||
// Just enough for computeRTL for notification-manager
|
// Just enough for computeRTL for notification-manager
|
||||||
@ -24,9 +24,9 @@ const FAKE_HASS = {
|
|||||||
|
|
||||||
@customElement("ha-gallery")
|
@customElement("ha-gallery")
|
||||||
class HaGallery extends LitElement {
|
class HaGallery extends LitElement {
|
||||||
@property() private _demo =
|
@property() private _page =
|
||||||
document.location.hash.substring(1) ||
|
document.location.hash.substring(1) ||
|
||||||
`${SIDEBAR[0].category}/${SIDEBAR[0].demos![0]}`;
|
`${SIDEBAR[0].category}/${SIDEBAR[0].pages![0]}`;
|
||||||
|
|
||||||
@query("notification-manager")
|
@query("notification-manager")
|
||||||
private _notifications!: HTMLElementTagNameMap["notification-manager"];
|
private _notifications!: HTMLElementTagNameMap["notification-manager"];
|
||||||
@ -42,12 +42,12 @@ class HaGallery extends LitElement {
|
|||||||
for (const group of SIDEBAR) {
|
for (const group of SIDEBAR) {
|
||||||
const links: unknown[] = [];
|
const links: unknown[] = [];
|
||||||
|
|
||||||
for (const demo of group.demos!) {
|
for (const page of group.pages!) {
|
||||||
const key = `${group.category}/${demo}`;
|
const key = `${group.category}/${page}`;
|
||||||
const active = this._demo === key;
|
const active = this._page === key;
|
||||||
const title = DEMOS[key].metadata.title || demo;
|
const title = PAGES[key].metadata.title || page;
|
||||||
links.push(html`
|
links.push(html`
|
||||||
<a ?active=${active} href=${`#${group.category}/${demo}`}>${title}</a>
|
<a ?active=${active} href=${`#${group.category}/${page}`}>${title}</a>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,28 +81,28 @@ class HaGallery extends LitElement {
|
|||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
|
|
||||||
<div slot="title">
|
<div slot="title">
|
||||||
${DEMOS[this._demo].metadata.title || this._demo.split("/")[1]}
|
${PAGES[this._page].metadata.title || this._page.split("/")[1]}
|
||||||
</div>
|
</div>
|
||||||
</mwc-top-app-bar-fixed>
|
</mwc-top-app-bar-fixed>
|
||||||
<div>
|
<div>
|
||||||
<demo-description .demo=${this._demo}></demo-description>
|
<page-description .page=${this._page}></page-description>
|
||||||
${dynamicElement(`demo-${this._demo.replace("/", "-")}`)}
|
${dynamicElement(`demo-${this._page.replace("/", "-")}`)}
|
||||||
<div class="demo-footer">
|
<div class="page-footer">
|
||||||
${DEMOS[this._demo].description ||
|
${PAGES[this._page].description ||
|
||||||
Object.keys(DEMOS[this._demo].metadata).length > 0
|
Object.keys(PAGES[this._page].metadata).length > 0
|
||||||
? html`
|
? html`
|
||||||
<a
|
<a
|
||||||
href=${`${GITHUB_DEMO_URL}${this._demo}.markdown`}
|
href=${`${GITHUB_DEMO_URL}${this._page}.markdown`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Edit text
|
Edit text
|
||||||
</a>
|
</a>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${DEMOS[this._demo].load
|
${PAGES[this._page].load
|
||||||
? html`
|
? html`
|
||||||
<a
|
<a
|
||||||
href=${`${GITHUB_DEMO_URL}${this._demo}.ts`}
|
href=${`${GITHUB_DEMO_URL}${this._page}.ts`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Edit demo
|
Edit demo
|
||||||
@ -137,10 +137,10 @@ class HaGallery extends LitElement {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.location.hash = this._demo;
|
document.location.hash = this._page;
|
||||||
|
|
||||||
window.addEventListener("hashchange", () => {
|
window.addEventListener("hashchange", () => {
|
||||||
this._demo = document.location.hash.substring(1);
|
this._page = document.location.hash.substring(1);
|
||||||
if (this._narrow) {
|
if (this._narrow) {
|
||||||
this._drawer.open = false;
|
this._drawer.open = false;
|
||||||
}
|
}
|
||||||
@ -149,15 +149,20 @@ class HaGallery extends LitElement {
|
|||||||
|
|
||||||
updated(changedProps: PropertyValues) {
|
updated(changedProps: PropertyValues) {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
if (changedProps.has("_demo") && DEMOS[this._demo].load) {
|
if (!changedProps.has("_page")) {
|
||||||
DEMOS[this._demo].load();
|
return;
|
||||||
const menuItem = this.shadowRoot!.querySelector(
|
}
|
||||||
`a[href="#${this._demo}"]`
|
|
||||||
)!;
|
if (PAGES[this._page].demo) {
|
||||||
// Make sure section is expanded
|
PAGES[this._page].demo();
|
||||||
if (menuItem.parentElement instanceof HTMLDetailsElement) {
|
}
|
||||||
menuItem.parentElement.open = true;
|
|
||||||
}
|
const menuItem = this.shadowRoot!.querySelector(
|
||||||
|
`a[href="#${this._page}"]`
|
||||||
|
)!;
|
||||||
|
// Make sure section is expanded
|
||||||
|
if (menuItem.parentElement instanceof HTMLDetailsElement) {
|
||||||
|
menuItem.parentElement.open = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,12 +216,12 @@ class HaGallery extends LitElement {
|
|||||||
opacity: 0.12;
|
opacity: 0.12;
|
||||||
}
|
}
|
||||||
|
|
||||||
.demo-footer {
|
.page-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.demo-footer a {
|
.page-footer a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
/>
|
/>
|
||||||
<meta name="theme-color" content="#2157BC" />
|
<meta name="theme-color" content="#2157BC" />
|
||||||
<title>HAGallery</title>
|
<title>Home Assistant Design</title>
|
||||||
|
|
||||||
<script type="module" src="<%= latestGalleryJS %>"></script>
|
<script type="module" src="<%= latestGalleryJS %>"></script>
|
||||||
<style>
|
<style>
|
||||||
|
7
gallery/src/pages/concepts/home.markdown
Normal file
7
gallery/src/pages/concepts/home.markdown
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Home
|
||||||
|
---
|
||||||
|
|
||||||
|
# Welcome to Home Assistant Design
|
||||||
|
|
||||||
|
This portal aims to aid designers and developers on improving the Home Assistant interface.
|
80
gallery/src/pages/design.home-assistant.io/editing.markdown
Normal file
80
gallery/src/pages/design.home-assistant.io/editing.markdown
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
title: Editing design.home-assistant.io
|
||||||
|
---
|
||||||
|
|
||||||
|
# How to edit design.home-assistant.io
|
||||||
|
|
||||||
|
All pages are stored in [the pages folder][pages-folder] on GitHub. Pages are grouped in a folder per sidebar section. Each page can contain a `<page name>.markdown` description file, a `<page name>.ts` demo file or both. If both are defined the description is rendered first. The description can contain metadata to specify the title of the page.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
You can develop design.home-assistant.io locally by checking out [the Home Assistant frontend repository](https://github.com/home-assistant/frontend). The command to run the gallery is `gallery/script/develop_gallery`. It will automatically open a browser window and load the development version of the website.
|
||||||
|
|
||||||
|
## Creating a page
|
||||||
|
|
||||||
|
Navigate to the [the pages folder][pages-folder] on GitHub. If the folder for your category does not exist yet, create it. Create a new Markdown file inside this folder for your description, ie `usability.markdown`. This filename will be used in the URL. Add the following content:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: My new page
|
||||||
|
---
|
||||||
|
|
||||||
|
Hello and welcome to my new page!
|
||||||
|
```
|
||||||
|
|
||||||
|
Once saved, the page will be automatically added to the bottom of the sidebar. The title specified in the header will be shown as the page title and used in the sidebar.
|
||||||
|
|
||||||
|
## Linking the page in the sidebar
|
||||||
|
|
||||||
|
By default the sidebar will gather all pages and group them by category. You can override the order of the categories, define a name for categories and change the order of the pages in [`sidebar.js`](https://github.com/home-assistant/frontend/blob/dev/gallery/sidebar.js).
|
||||||
|
|
||||||
|
Any category not listed in `sidebar.js` will be placed at the end of the sidebar.
|
||||||
|
|
||||||
|
Any page not listed in `sidebar.js` will be placed at the end of its category.
|
||||||
|
|
||||||
|
## Adding a demo to a page
|
||||||
|
|
||||||
|
Create a file next to the description file with the same name as the description file, but with the `.ts` extension: `usability.ts`. For this example, we assume that the category folder that contains `usability.markdown` and `usability.ts` is called `user-experience`. Add the following content to `usability.ts`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { html, css, LitElement } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
|
import "../../../../src/components/ha-card";
|
||||||
|
|
||||||
|
|
||||||
|
@customElement("demo-user-experience-usability")
|
||||||
|
export class DemoUserExperienceUsability extends LitElement {
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
Hello world!
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-user-experience-usability": DemoUserExperienceUsability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the demo deosn't need to render anything itself. It can also be used to declare web components to be used by the page description. Because page descriptions are using markdown, they can embed any HTML.
|
||||||
|
|
||||||
|
## Publishing changes
|
||||||
|
|
||||||
|
The website is automatically published whenever the source files in the `dev` branch change. So to get your changes published, open a pull request with your changes.
|
||||||
|
|
||||||
|
[pages-folder]: https://github.com/home-assistant/frontend/tree/dev/gallery/src/pages
|
@ -3,7 +3,7 @@ import { customElement, property } from "lit/decorators";
|
|||||||
import "./ha-markdown-element";
|
import "./ha-markdown-element";
|
||||||
|
|
||||||
@customElement("ha-markdown")
|
@customElement("ha-markdown")
|
||||||
class HaMarkdown extends LitElement {
|
export class HaMarkdown extends LitElement {
|
||||||
@property() public content?;
|
@property() public content?;
|
||||||
|
|
||||||
@property({ type: Boolean }) public allowSvg = false;
|
@property({ type: Boolean }) public allowSvg = false;
|
||||||
@ -38,35 +38,35 @@ class HaMarkdown extends LitElement {
|
|||||||
ha-markdown-element > *:last-child {
|
ha-markdown-element > *:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
ha-markdown-element a {
|
a {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
ha-markdown-element img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
ha-markdown-element code,
|
code,
|
||||||
pre {
|
pre {
|
||||||
background-color: var(--markdown-code-background-color, none);
|
background-color: var(--markdown-code-background-color, none);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
ha-markdown-element svg {
|
svg {
|
||||||
background-color: var(--markdown-svg-background-color, none);
|
background-color: var(--markdown-svg-background-color, none);
|
||||||
color: var(--markdown-svg-color, none);
|
color: var(--markdown-svg-color, none);
|
||||||
}
|
}
|
||||||
ha-markdown-element code {
|
code {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
}
|
}
|
||||||
ha-markdown-element pre code {
|
pre code {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
ha-markdown-element pre {
|
pre {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
font-family: var(--code-font-family, monospace);
|
font-family: var(--code-font-family, monospace);
|
||||||
}
|
}
|
||||||
ha-markdown-element h2 {
|
h2 {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user