mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-20 03:17:20 +00:00
Compare commits
No commits in common. "dev" and "20250109.2" have entirely different histories.
dev
...
20250109.2
@ -1,4 +1,5 @@
|
||||
FROM mcr.microsoft.com/devcontainers/python:1-3.13
|
||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/python-3/.devcontainer/base.Dockerfile
|
||||
FROM mcr.microsoft.com/devcontainers/python:3.12
|
||||
|
||||
ENV \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
|
@ -5,15 +5,12 @@
|
||||
"context": ".."
|
||||
},
|
||||
"appPort": "8124:8123",
|
||||
"postCreateCommand": "./.devcontainer/post_create.sh",
|
||||
"postCreateCommand": "sudo apt update && sudo apt upgrade -y && sudo apt install -y libpcap-dev",
|
||||
"postStartCommand": "script/bootstrap",
|
||||
"containerEnv": {
|
||||
"DEV_CONTAINER": "1",
|
||||
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
|
||||
},
|
||||
"remoteEnv": {
|
||||
"NODE_OPTIONS": "--max_old_space_size=8192"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
|
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will run after the container is created
|
||||
|
||||
# add github cli
|
||||
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
|
||||
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
|
||||
&& out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
||||
&& cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
|
||||
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
||||
|
||||
# Update package lists
|
||||
sudo apt-get update
|
||||
|
||||
sudo apt upgrade -y
|
||||
|
||||
# Install necessary packages
|
||||
sudo apt-get install -y libpcap-dev gh
|
||||
|
||||
# Display a message
|
||||
echo "Post-create script has been executed successfully."
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -74,7 +74,7 @@ body:
|
||||
If known, otherwise leave blank.
|
||||
- type: input
|
||||
attributes:
|
||||
label: In which browser are you experiencing the issue?
|
||||
label: In which browser are you experiencing the issue with?
|
||||
placeholder: Google Chrome 88.0.4324.150
|
||||
description: >
|
||||
Provide the full name and don't forget to add the version!
|
||||
|
4
.github/workflows/cast_deployment.yaml
vendored
4
.github/workflows/cast_deployment.yaml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
ref: dev
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -62,7 +62,7 @@ jobs:
|
||||
ref: master
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
|
14
.github/workflows/ci.yaml
vendored
14
.github/workflows/ci.yaml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
- name: Build resources
|
||||
run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages
|
||||
- name: Setup lint cache
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v4.2.0
|
||||
with:
|
||||
path: |
|
||||
node_modules/.cache/prettier
|
||||
@ -60,7 +60,7 @@ jobs:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -78,7 +78,7 @@ jobs:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -89,7 +89,7 @@ jobs:
|
||||
env:
|
||||
IS_TEST: "true"
|
||||
- name: Upload bundle stats
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
with:
|
||||
name: frontend-bundle-stats
|
||||
path: build/stats/*.json
|
||||
@ -102,7 +102,7 @@ jobs:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -113,7 +113,7 @@ jobs:
|
||||
env:
|
||||
IS_TEST: "true"
|
||||
- name: Upload bundle stats
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
with:
|
||||
name: supervisor-bundle-stats
|
||||
path: build/stats/*.json
|
||||
|
4
.github/workflows/demo_deployment.yaml
vendored
4
.github/workflows/demo_deployment.yaml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
ref: dev
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -63,7 +63,7 @@ jobs:
|
||||
ref: master
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
|
2
.github/workflows/design_deployment.yaml
vendored
2
.github/workflows/design_deployment.yaml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
|
2
.github/workflows/design_preview.yaml
vendored
2
.github/workflows/design_preview.yaml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
|
8
.github/workflows/nightly.yaml
vendored
8
.github/workflows/nightly.yaml
vendored
@ -6,7 +6,7 @@ on:
|
||||
- cron: "0 1 * * *"
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: "3.13"
|
||||
PYTHON_VERSION: "3.12"
|
||||
NODE_OPTIONS: --max_old_space_size=6144
|
||||
|
||||
permissions:
|
||||
@ -28,7 +28,7 @@ jobs:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -57,14 +57,14 @@ jobs:
|
||||
run: tar -czvf translations.tar.gz translations
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
with:
|
||||
name: wheels
|
||||
path: dist/home_assistant_frontend*.whl
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload translations
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
with:
|
||||
name: translations
|
||||
path: translations.tar.gz
|
||||
|
2
.github/workflows/relative-ci.yaml
vendored
2
.github/workflows/relative-ci.yaml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send bundle stats and build information to RelativeCI
|
||||
uses: relative-ci/agent-action@v2.2.0
|
||||
uses: relative-ci/agent-action@v2.1.14
|
||||
with:
|
||||
key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }}
|
||||
token: ${{ github.token }}
|
||||
|
2
.github/workflows/release-drafter.yaml
vendored
2
.github/workflows/release-drafter.yaml
vendored
@ -18,6 +18,6 @@ jobs:
|
||||
pull-requests: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@v6.1.0
|
||||
- uses: release-drafter/release-drafter@v6.0.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
18
.github/workflows/release.yaml
vendored
18
.github/workflows/release.yaml
vendored
@ -6,7 +6,7 @@ on:
|
||||
- published
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: "3.13"
|
||||
PYTHON_VERSION: "3.12"
|
||||
NODE_OPTIONS: --max_old_space_size=6144
|
||||
|
||||
# Set default workflow permissions
|
||||
@ -34,7 +34,7 @@ jobs:
|
||||
uses: home-assistant/actions/helpers/verify-version@master
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -55,7 +55,7 @@ jobs:
|
||||
script/release
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: |
|
||||
dist/*.whl
|
||||
@ -74,9 +74,9 @@ jobs:
|
||||
echo "home-assistant-frontend==$version" > ./requirements.txt
|
||||
|
||||
- name: Build wheels
|
||||
uses: home-assistant/wheels@2025.03.0
|
||||
uses: home-assistant/wheels@2024.11.0
|
||||
with:
|
||||
abi: cp313
|
||||
abi: cp312
|
||||
tag: musllinux_1_2
|
||||
arch: amd64
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -107,7 +107,7 @@ jobs:
|
||||
- name: Tar folder
|
||||
run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist .
|
||||
- name: Upload release asset
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz
|
||||
|
||||
@ -121,7 +121,7 @@ jobs:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4.4.0
|
||||
uses: actions/setup-node@v4.1.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: yarn
|
||||
@ -136,6 +136,6 @@ jobs:
|
||||
- name: Tar folder
|
||||
run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build .
|
||||
- name: Upload release asset
|
||||
uses: softprops/action-gh-release@v2.2.1
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz
|
||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 90 days stale policy
|
||||
uses: actions/stale@v9.1.0
|
||||
uses: actions/stale@v9.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 90
|
||||
|
42
.vscode/tasks.json
vendored
42
.vscode/tasks.json
vendored
@ -1,42 +1,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Develop and serve Frontend",
|
||||
"type": "shell",
|
||||
"command": "script/develop_and_serve -c ${input:coreUrl}",
|
||||
// Sync changes here to other tasks until issue resolved
|
||||
// https://github.com/Microsoft/vscode/issues/61497
|
||||
"problemMatcher": {
|
||||
"owner": "ha-build",
|
||||
"source": "ha-build",
|
||||
"fileLocation": "absolute",
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||
"severity": 1,
|
||||
"file": 2,
|
||||
"message": 3,
|
||||
"line": 4,
|
||||
"column": 5
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "Changes detected. Starting compilation",
|
||||
"endsPattern": "Build done @"
|
||||
}
|
||||
},
|
||||
"isBackground": true,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"runOptions": {
|
||||
"instanceLimit": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Develop Frontend",
|
||||
"type": "gulp",
|
||||
@ -277,12 +241,6 @@
|
||||
"id": "supervisorToken",
|
||||
"type": "promptString",
|
||||
"description": "The token for the Remote API proxy add-on"
|
||||
},
|
||||
{
|
||||
"id": "coreUrl",
|
||||
"type": "promptString",
|
||||
"description": "The URL of the Home Assistant Core instance",
|
||||
"default": "http://127.0.0.1:8123"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
34
.yarn/patches/@polymer/polymer/pr-5569.patch
Normal file
34
.yarn/patches/@polymer/polymer/pr-5569.patch
Normal file
@ -0,0 +1,34 @@
|
||||
diff --git a/lib/legacy/class.js b/lib/legacy/class.js
|
||||
index aee2511be1cd9bf900ee552bc98190c1631c57c0..f2f499d68bf52034cac9c28307c99e8ce6b8417d 100644
|
||||
--- a/lib/legacy/class.js
|
||||
+++ b/lib/legacy/class.js
|
||||
@@ -304,17 +304,23 @@ function GenerateClassFromInfo(info, Base, behaviors) {
|
||||
// only proceed if the generated class' prototype has not been registered.
|
||||
const generatedProto = PolymerGenerated.prototype;
|
||||
if (!generatedProto.hasOwnProperty(JSCompiler_renameProperty('__hasRegisterFinished', generatedProto))) {
|
||||
- generatedProto.__hasRegisterFinished = true;
|
||||
+ // make sure legacy lifecycle is called on the *element*'s prototype
|
||||
+ // and not the generated class prototype; if the element has been
|
||||
+ // extended, these are *not* the same.
|
||||
+ const proto = Object.getPrototypeOf(this);
|
||||
+ // Only set flag when generated prototype itself is registered,
|
||||
+ // as this element may be extended from, and needs to run `registered`
|
||||
+ // on all behaviors on the subclass as well.
|
||||
+ if (proto === generatedProto) {
|
||||
+ generatedProto.__hasRegisterFinished = true;
|
||||
+ }
|
||||
// ensure superclass is registered first.
|
||||
super._registered();
|
||||
// copy properties onto the generated class lazily if we're optimizing,
|
||||
- if (legacyOptimizations) {
|
||||
+ if (legacyOptimizations && !Object.hasOwnProperty(generatedProto, '__hasCopiedProperties')) {
|
||||
+ generatedProto.__hasCopiedProperties = true;
|
||||
copyPropertiesToProto(generatedProto);
|
||||
}
|
||||
- // make sure legacy lifecycle is called on the *element*'s prototype
|
||||
- // and not the generated class prototype; if the element has been
|
||||
- // extended, these are *not* the same.
|
||||
- const proto = Object.getPrototypeOf(this);
|
||||
let list = lifecycle.beforeRegister;
|
||||
if (list) {
|
||||
for (let i=0; i < list.length; i++) {
|
934
.yarn/releases/yarn-4.5.3.cjs
vendored
Executable file
934
.yarn/releases/yarn-4.5.3.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
948
.yarn/releases/yarn-4.9.1.cjs
vendored
948
.yarn/releases/yarn-4.9.1.cjs
vendored
File diff suppressed because one or more lines are too long
@ -6,4 +6,4 @@ enableGlobalCache: false
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.9.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.5.3.cjs
|
||||
|
@ -2,7 +2,7 @@ import defineProvider from "@babel/helper-define-polyfill-provider";
|
||||
import { join } from "node:path";
|
||||
import paths from "../paths.cjs";
|
||||
|
||||
const POLYFILL_DIR = join(paths.root_dir, "src/resources/polyfills");
|
||||
const POLYFILL_DIR = join(paths.polymer_dir, "src/resources/polyfills");
|
||||
|
||||
// List of polyfill keys with supported browser targets for the functionality
|
||||
const polyfillSupport = {
|
||||
|
@ -18,18 +18,30 @@ module.exports.sourceMapURL = () => {
|
||||
module.exports.ignorePackages = () => [];
|
||||
|
||||
// Files from NPM packages that we should replace with empty file
|
||||
module.exports.emptyPackages = ({ isHassioBuild }) =>
|
||||
module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) =>
|
||||
[
|
||||
// Contains all color definitions for all material color sets.
|
||||
// We don't use it
|
||||
require.resolve("@polymer/paper-styles/color.js"),
|
||||
require.resolve("@polymer/paper-styles/default-theme.js"),
|
||||
// Loads stuff from a CDN
|
||||
require.resolve("@polymer/font-roboto/roboto.js"),
|
||||
require.resolve("@vaadin/vaadin-material-styles/typography.js"),
|
||||
require.resolve("@vaadin/vaadin-material-styles/font-icons.js"),
|
||||
// Compatibility not needed for latest builds
|
||||
latestBuild &&
|
||||
// wrapped in require.resolve so it blows up if file no longer exists
|
||||
require.resolve(
|
||||
path.resolve(paths.polymer_dir, "src/resources/compatibility.ts")
|
||||
),
|
||||
// Icons in supervisor conflict with icons in HA so we don't load.
|
||||
isHassioBuild &&
|
||||
require.resolve(
|
||||
path.resolve(paths.root_dir, "src/components/ha-icon.ts")
|
||||
path.resolve(paths.polymer_dir, "src/components/ha-icon.ts")
|
||||
),
|
||||
isHassioBuild &&
|
||||
require.resolve(
|
||||
path.resolve(paths.root_dir, "src/components/ha-icon-picker.ts")
|
||||
path.resolve(paths.polymer_dir, "src/components/ha-icon-picker.ts")
|
||||
),
|
||||
].filter(Boolean);
|
||||
|
||||
@ -43,9 +55,8 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
|
||||
__STATIC_PATH__: "/static/",
|
||||
__HASS_URL__: `\`${
|
||||
"HASS_URL" in process.env
|
||||
? process.env.HASS_URL
|
||||
: // eslint-disable-next-line no-template-curly-in-string
|
||||
"${location.protocol}//${location.host}"
|
||||
? process.env["HASS_URL"]
|
||||
: "${location.protocol}//${location.host}"
|
||||
}\``,
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
isProdBuild ? "production" : "development"
|
||||
@ -159,7 +170,7 @@ module.exports.babelOptions = ({
|
||||
],
|
||||
],
|
||||
exclude: [
|
||||
path.join(paths.root_dir, "src/resources/polyfills"),
|
||||
path.join(paths.polymer_dir, "src/resources/polyfills"),
|
||||
...[
|
||||
"@formatjs/(?:ecma402-abstract|intl-\\w+)",
|
||||
"@lit-labs/virtualizer/polyfills",
|
||||
@ -177,7 +188,6 @@ module.exports.babelOptions = ({
|
||||
include: /\/node_modules\//,
|
||||
exclude: [
|
||||
"element-internals-polyfill",
|
||||
"@shoelace-style",
|
||||
"@?lit(?:-labs|-element|-html)?",
|
||||
].map((p) => new RegExp(`/node_modules/${p}/`)),
|
||||
},
|
||||
|
@ -21,7 +21,7 @@ module.exports = {
|
||||
},
|
||||
version() {
|
||||
const version = fs
|
||||
.readFileSync(path.resolve(paths.root_dir, "pyproject.toml"), "utf8")
|
||||
.readFileSync(path.resolve(paths.polymer_dir, "pyproject.toml"), "utf8")
|
||||
.match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/);
|
||||
if (!version) {
|
||||
throw Error("Version not found");
|
||||
|
@ -1,16 +1,16 @@
|
||||
// @ts-check
|
||||
|
||||
import tseslint from "typescript-eslint";
|
||||
import rootConfig from "../eslint.config.mjs";
|
||||
|
||||
export default tseslint.config(...rootConfig, {
|
||||
rules: {
|
||||
"no-console": "off",
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"import/extensions": "off",
|
||||
"import/no-dynamic-require": "off",
|
||||
"global-require": "off",
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
export default [
|
||||
...rootConfig,
|
||||
{
|
||||
rules: {
|
||||
"no-console": "off",
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"import/extensions": "off",
|
||||
"import/no-dynamic-require": "off",
|
||||
"global-require": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
},
|
||||
},
|
||||
});
|
||||
];
|
||||
|
@ -56,7 +56,6 @@ const getCommonTemplateVars = () => {
|
||||
);
|
||||
return {
|
||||
modernRegex: compileRegex(browserRegexes.concat(haMacOSRegex)).toString(),
|
||||
hassUrl: process.env.HASS_URL || "",
|
||||
};
|
||||
};
|
||||
|
||||
@ -169,14 +168,14 @@ const APP_PAGE_ENTRIES = {
|
||||
|
||||
gulp.task(
|
||||
"gen-pages-app-dev",
|
||||
genPagesDevTask(APP_PAGE_ENTRIES, paths.root_dir, paths.app_output_root)
|
||||
genPagesDevTask(APP_PAGE_ENTRIES, paths.polymer_dir, paths.app_output_root)
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
"gen-pages-app-prod",
|
||||
genPagesProdTask(
|
||||
APP_PAGE_ENTRIES,
|
||||
paths.root_dir,
|
||||
paths.polymer_dir,
|
||||
paths.app_output_root,
|
||||
paths.app_output_latest,
|
||||
paths.app_output_es5
|
||||
|
@ -6,8 +6,8 @@ import path from "path";
|
||||
import paths from "../paths.cjs";
|
||||
|
||||
const npmPath = (...parts) =>
|
||||
path.resolve(paths.root_dir, "node_modules", ...parts);
|
||||
const polyPath = (...parts) => path.resolve(paths.root_dir, ...parts);
|
||||
path.resolve(paths.polymer_dir, "node_modules", ...parts);
|
||||
const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts);
|
||||
|
||||
const copyFileDir = (fromFile, toDir) =>
|
||||
fs.copySync(fromFile, path.join(toDir, path.basename(fromFile)));
|
||||
@ -59,11 +59,6 @@ function copyPolyfills(staticDir) {
|
||||
npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js.map"),
|
||||
staticPath("polyfills/")
|
||||
);
|
||||
// Lit polyfill support
|
||||
fs.copySync(
|
||||
npmPath("lit/polyfill-support.js"),
|
||||
path.join(staticPath("polyfills/"), "lit-polyfill-support.js")
|
||||
);
|
||||
|
||||
// dialog-polyfill css
|
||||
copyFileDir(
|
||||
@ -95,10 +90,6 @@ function copyMapPanel(staticDir) {
|
||||
npmPath("leaflet/dist/leaflet.css"),
|
||||
staticPath("images/leaflet/")
|
||||
);
|
||||
copyFileDir(
|
||||
npmPath("leaflet.markercluster/dist/MarkerCluster.css"),
|
||||
staticPath("images/leaflet/")
|
||||
);
|
||||
fs.copySync(
|
||||
npmPath("leaflet/dist/images"),
|
||||
staticPath("images/leaflet/images/")
|
||||
|
@ -1,17 +0,0 @@
|
||||
import "./app.js";
|
||||
import "./cast.js";
|
||||
import "./clean.js";
|
||||
import "./compress.js";
|
||||
import "./demo.js";
|
||||
import "./download-translations.js";
|
||||
import "./entry-html.js";
|
||||
import "./fetch-nightly-translations.js";
|
||||
import "./gallery.js";
|
||||
import "./gather-static.js";
|
||||
import "./gen-icons-json.js";
|
||||
import "./hassio.js";
|
||||
import "./landing-page.js";
|
||||
import "./locale-data.js";
|
||||
import "./rspack.js";
|
||||
import "./service-worker.js";
|
||||
import "./translations.js";
|
@ -4,7 +4,7 @@ import gulp from "gulp";
|
||||
import { join, resolve } from "node:path";
|
||||
import paths from "../paths.cjs";
|
||||
|
||||
const formatjsDir = join(paths.root_dir, "node_modules", "@formatjs");
|
||||
const formatjsDir = join(paths.polymer_dir, "node_modules", "@formatjs");
|
||||
const outDir = join(paths.build_dir, "locale-data");
|
||||
|
||||
const INTL_POLYFILLS = {
|
||||
|
@ -40,17 +40,20 @@ class CustomJSON extends Transform {
|
||||
this._reviver = reviver;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
async _transform(file, _, callback) {
|
||||
let obj = JSON.parse(file.contents.toString(), this._reviver);
|
||||
if (this._func) obj = this._func(obj, file.path);
|
||||
for (const [outObj, dir] of Array.isArray(obj) ? obj : [[obj, ""]]) {
|
||||
const outFile = file.clone({ contents: false });
|
||||
outFile.contents = Buffer.from(JSON.stringify(outObj));
|
||||
outFile.dirname += `/${dir}`;
|
||||
this.push(outFile);
|
||||
try {
|
||||
let obj = JSON.parse(file.contents.toString(), this._reviver);
|
||||
if (this._func) obj = this._func(obj, file.path);
|
||||
for (const [outObj, dir] of Array.isArray(obj) ? obj : [[obj, ""]]) {
|
||||
const outFile = file.clone({ contents: false });
|
||||
outFile.contents = Buffer.from(JSON.stringify(outObj));
|
||||
outFile.dirname += `/${dir}`;
|
||||
this.push(outFile);
|
||||
}
|
||||
callback(null);
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,19 +68,25 @@ class MergeJSON extends Transform {
|
||||
this._reviver = reviver;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
async _transform(file, _, callback) {
|
||||
this._objects.push(JSON.parse(file.contents.toString(), this._reviver));
|
||||
if (!this._outFile) this._outFile = file.clone({ contents: false });
|
||||
callback(null);
|
||||
try {
|
||||
this._objects.push(JSON.parse(file.contents.toString(), this._reviver));
|
||||
if (!this._outFile) this._outFile = file.clone({ contents: false });
|
||||
callback(null);
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
async _flush(callback) {
|
||||
const mergedObj = merge(this._startObj, ...this._objects);
|
||||
this._outFile.contents = Buffer.from(JSON.stringify(mergedObj));
|
||||
this._outFile.stem = this._stem;
|
||||
callback(null, this._outFile);
|
||||
try {
|
||||
const mergedObj = merge(this._startObj, ...this._objects);
|
||||
this._outFile.contents = Buffer.from(JSON.stringify(mergedObj));
|
||||
this._outFile.stem = this._stem;
|
||||
callback(null, this._outFile);
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
root_dir: path.resolve(__dirname, ".."),
|
||||
polymer_dir: path.resolve(__dirname, ".."),
|
||||
|
||||
build_dir: path.resolve(__dirname, "../build"),
|
||||
app_output_root: path.resolve(__dirname, "../hass_frontend"),
|
||||
|
@ -1,17 +1,12 @@
|
||||
const { existsSync } = require("fs");
|
||||
const path = require("path");
|
||||
const rspack = require("@rspack/core");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { RsdoctorRspackPlugin } = require("@rsdoctor/rspack-plugin");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { StatsWriterPlugin } = require("webpack-stats-plugin");
|
||||
const filterStats = require("@bundle-stats/plugin-webpack-filter");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const filterStats = require("@bundle-stats/plugin-webpack-filter").default;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { WebpackManifestPlugin } = require("rspack-manifest-plugin");
|
||||
const log = require("fancy-log");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const WebpackBar = require("webpackbar/rspack");
|
||||
const paths = require("./paths.cjs");
|
||||
const bundle = require("./bundle.cjs");
|
||||
@ -160,8 +155,10 @@ const createRspackConfig = ({
|
||||
},
|
||||
}),
|
||||
new rspack.NormalModuleReplacementPlugin(
|
||||
new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")),
|
||||
path.resolve(paths.root_dir, "src/util/empty.js")
|
||||
new RegExp(
|
||||
bundle.emptyPackages({ latestBuild, isHassioBuild }).join("|")
|
||||
),
|
||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||
),
|
||||
!isProdBuild && new LogStartCompilePlugin(),
|
||||
isProdBuild &&
|
||||
@ -195,7 +192,6 @@ const createRspackConfig = ({
|
||||
"lit/directives/if-defined$": "lit/directives/if-defined.js",
|
||||
"lit/directives/guard$": "lit/directives/guard.js",
|
||||
"lit/directives/cache$": "lit/directives/cache.js",
|
||||
"lit/directives/join$": "lit/directives/join.js",
|
||||
"lit/directives/repeat$": "lit/directives/repeat.js",
|
||||
"lit/directives/live$": "lit/directives/live.js",
|
||||
"lit/directives/keyed$": "lit/directives/keyed.js",
|
||||
|
@ -3,7 +3,7 @@ import "@material/mwc-list/mwc-list";
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list";
|
||||
import { mdiCast, mdiCastConnected, mdiViewDashboard } from "@mdi/js";
|
||||
import type { Auth, Connection } from "home-assistant-js-websocket";
|
||||
import type { TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import type { CastManager } from "../../../../src/cast/cast_manager";
|
||||
@ -203,72 +203,74 @@ class HcCast extends LitElement {
|
||||
}
|
||||
this.connection.close();
|
||||
location.reload();
|
||||
} catch (_err: any) {
|
||||
} catch (err: any) {
|
||||
alert("Unable to log out!");
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.center-item {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
.center-item {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.question {
|
||||
position: relative;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
.question {
|
||||
position: relative;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.question:before {
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
background-color: var(--primary-color);
|
||||
opacity: 0.12;
|
||||
will-change: opacity;
|
||||
}
|
||||
.question:before {
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
background-color: var(--primary-color);
|
||||
opacity: 0.12;
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
.connection,
|
||||
.connection a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.connection,
|
||||
.connection a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
mwc-button ha-svg-icon {
|
||||
margin-right: 8px;
|
||||
margin-inline-end: 8px;
|
||||
margin-inline-start: initial;
|
||||
height: 18px;
|
||||
}
|
||||
mwc-button ha-svg-icon {
|
||||
margin-right: 8px;
|
||||
margin-inline-end: 8px;
|
||||
margin-inline-start: initial;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
ha-list-item ha-icon,
|
||||
ha-list-item ha-svg-icon {
|
||||
padding: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-list-item ha-icon,
|
||||
ha-list-item ha-svg-icon {
|
||||
padding: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
:host([hide-icons]) ha-icon {
|
||||
display: none;
|
||||
}
|
||||
:host([hide-icons]) ha-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-content a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
.card-content a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
ERR_INVALID_HTTPS_TO_HTTP,
|
||||
getAuth,
|
||||
} from "home-assistant-js-websocket";
|
||||
import type { TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import type { CastManager } from "../../../../src/cast/cast_manager";
|
||||
@ -215,7 +215,7 @@ export class HcConnect extends LitElement {
|
||||
let url: URL;
|
||||
try {
|
||||
url = new URL(value);
|
||||
} catch (_err: any) {
|
||||
} catch (err: any) {
|
||||
this.error = "Invalid URL";
|
||||
return;
|
||||
}
|
||||
@ -288,39 +288,41 @@ export class HcConnect extends LitElement {
|
||||
try {
|
||||
saveTokens(null);
|
||||
location.reload();
|
||||
} catch (_err: any) {
|
||||
} catch (err: any) {
|
||||
alert("Unable to log out!");
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.card-content a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.card-actions a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
.card-content a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.card-actions a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.error a {
|
||||
color: darkred;
|
||||
}
|
||||
.error a {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
mwc-button ha-svg-icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
mwc-button ha-svg-icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
ha-textfield {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
ha-textfield {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Auth, Connection, HassUser } from "home-assistant-js-websocket";
|
||||
import { getUser } from "home-assistant-js-websocket";
|
||||
import type { TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-card";
|
||||
@ -63,94 +63,96 @@ class HcLayout extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
min-height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
ha-card {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
color: var(--ha-card-header-color, var(--primary-text-color));
|
||||
font-family: var(--ha-card-header-font-family, inherit);
|
||||
font-size: var(--ha-card-header-font-size, 24px);
|
||||
letter-spacing: -0.012em;
|
||||
line-height: 32px;
|
||||
padding: 24px 16px 16px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hero {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--secondary-text-color);
|
||||
line-height: initial;
|
||||
}
|
||||
.subtitle a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
:host ::slotted(.card-content:not(:first-child)),
|
||||
slot:not(:first-child)::slotted(.card-content) {
|
||||
padding-top: 0px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
:host ::slotted(.section-header) {
|
||||
font-weight: 500;
|
||||
padding: 4px 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
:host ::slotted(.card-content) {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
:host ::slotted(.card-actions) {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 5px 16px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding: 8px 0 24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.footer a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
@media all and (max-width: 500px) {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
justify-content: flex-start;
|
||||
min-height: 90%;
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
min-height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
ha-card {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
color: var(--ha-card-header-color, var(--primary-text-color));
|
||||
font-family: var(--ha-card-header-font-family, inherit);
|
||||
font-size: var(--ha-card-header-font-size, 24px);
|
||||
letter-spacing: -0.012em;
|
||||
line-height: 32px;
|
||||
padding: 24px 16px 16px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hero {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--secondary-text-color);
|
||||
line-height: initial;
|
||||
}
|
||||
.subtitle a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
:host ::slotted(.card-content:not(:first-child)),
|
||||
slot:not(:first-child)::slotted(.card-content) {
|
||||
padding-top: 0px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
:host ::slotted(.section-header) {
|
||||
font-weight: 500;
|
||||
padding: 4px 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
:host ::slotted(.card-content) {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
:host ::slotted(.card-actions) {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 5px 16px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding: 8px 0 24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.footer a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
@media all and (max-width: 500px) {
|
||||
:host {
|
||||
justify-content: flex-start;
|
||||
min-height: 90%;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
@ -24,29 +24,31 @@ class HcLaunchScreen extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100vh;
|
||||
background-color: #f2f4f9;
|
||||
font-size: 24px;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
img {
|
||||
max-width: 80%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.status {
|
||||
color: #1d2126;
|
||||
}
|
||||
`;
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100vh;
|
||||
background-color: #f2f4f9;
|
||||
font-size: 24px;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
img {
|
||||
max-width: 80%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.status {
|
||||
color: #1d2126;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { css, html, LitElement, type TemplateResult } from "lit";
|
||||
import {
|
||||
css,
|
||||
type CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
type TemplateResult,
|
||||
} from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import type { LovelaceConfig } from "../../../../src/data/lovelace/config/types";
|
||||
@ -111,18 +117,20 @@ class HcLovelace extends LitElement {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
hui-view-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
hui-view-container > * {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
hui-view-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
hui-view {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export interface CastViewChanged {
|
||||
|
@ -309,7 +309,7 @@ export class HcMain extends HassElement {
|
||||
"../../../../src/panels/lovelace/strategies/get-strategy"
|
||||
);
|
||||
const config = await generateLovelaceDashboardStrategy(
|
||||
rawConfig,
|
||||
rawConfig.strategy,
|
||||
this.hass!
|
||||
);
|
||||
this._handleNewLovelaceConfig(config);
|
||||
@ -351,7 +351,10 @@ export class HcMain extends HassElement {
|
||||
"../../../../src/panels/lovelace/strategies/get-strategy"
|
||||
);
|
||||
this._handleNewLovelaceConfig(
|
||||
await generateLovelaceDashboardStrategy(DEFAULT_CONFIG, this.hass!)
|
||||
await generateLovelaceDashboardStrategy(
|
||||
DEFAULT_CONFIG.strategy,
|
||||
this.hass!
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import type { Lovelace } from "../../../src/panels/lovelace/types";
|
||||
import { energyEntities } from "../stubs/entities";
|
||||
import type { DemoConfig } from "./types";
|
||||
|
||||
export const demoConfigs: (() => Promise<DemoConfig>)[] = [
|
||||
export const demoConfigs: Array<() => Promise<DemoConfig>> = [
|
||||
() => import("./sections").then((mod) => mod.demoSections),
|
||||
() => import("./arsaboo").then((mod) => mod.demoArsaboo),
|
||||
() => import("./teachingbirds").then((mod) => mod.demoTeachingbirds),
|
||||
|
@ -3,6 +3,7 @@ export const demoThemeJimpower = () => ({
|
||||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#5294E2",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"paper-tabs-selection-bar-color": "green",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#383C45",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
|
@ -4,6 +4,7 @@ export const demoThemeKernehed = () => ({
|
||||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#2980b9",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"paper-tabs-selection-bar-color": "green",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#222222",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { mdiTelevision } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import type { CastManager } from "../../../src/cast/cast_manager";
|
||||
@ -66,35 +67,37 @@ class CastDemoRow extends LitElement implements LovelaceRow {
|
||||
this.style.display = this._castManager ? "" : "none";
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
ha-svg-icon {
|
||||
padding: 8px;
|
||||
color: var(--paper-item-icon-color);
|
||||
}
|
||||
.flex {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
margin-left: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
google-cast-launcher {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
`;
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
ha-svg-icon {
|
||||
padding: 8px;
|
||||
color: var(--paper-item-icon-color);
|
||||
}
|
||||
.flex {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
margin-left: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
google-cast-launcher {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -5,7 +5,7 @@ import { until } from "lit/directives/until";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-button";
|
||||
import "../../../src/components/ha-spinner";
|
||||
import "../../../src/components/ha-circular-progress";
|
||||
import type { LovelaceCardConfig } from "../../../src/data/lovelace/config/card";
|
||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||
import type {
|
||||
@ -32,7 +32,6 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
return this._hidden ? 0 : 2;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public setConfig(_config: LovelaceCardConfig) {}
|
||||
|
||||
protected render() {
|
||||
@ -44,7 +43,9 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
<div class="picker">
|
||||
<div class="label">
|
||||
${this._switching
|
||||
? html`<ha-spinner></ha-spinner>`
|
||||
? html`
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
`
|
||||
: until(
|
||||
selectedDemoConfig.then(
|
||||
(conf) => html`
|
||||
|
@ -1,3 +1,5 @@
|
||||
// Compat needs to be first import
|
||||
import "../../src/resources/compatibility";
|
||||
import { customElement } from "lit/decorators";
|
||||
import { isNavigationClick } from "../../src/common/dom/is-navigation-click";
|
||||
import { navigate } from "../../src/common/navigate";
|
||||
@ -63,7 +65,6 @@ export class HaDemo extends HomeAssistantAppEl {
|
||||
mockEntityRegistry(hass, [
|
||||
{
|
||||
config_entry_id: "co2signal",
|
||||
config_subentry_id: null,
|
||||
device_id: "co2signal",
|
||||
area_id: null,
|
||||
disabled_by: null,
|
||||
@ -84,7 +85,6 @@ export class HaDemo extends HomeAssistantAppEl {
|
||||
},
|
||||
{
|
||||
config_entry_id: "co2signal",
|
||||
config_subentry_id: null,
|
||||
device_id: "co2signal",
|
||||
area_id: null,
|
||||
disabled_by: null,
|
||||
|
@ -1,10 +1,9 @@
|
||||
import type { validateConfig } from "../../../src/data/config";
|
||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||
|
||||
export const mockConfig = (hass: MockHomeAssistant) => {
|
||||
hass.mockWS<typeof validateConfig>("validate_config", () => ({
|
||||
actions: { valid: true, error: null },
|
||||
conditions: { valid: true, error: null },
|
||||
triggers: { valid: true, error: null },
|
||||
hass.mockWS("validate_config", () => ({
|
||||
actions: { valid: true },
|
||||
conditions: { valid: true },
|
||||
triggers: { valid: true },
|
||||
}));
|
||||
};
|
||||
|
@ -1,26 +1,19 @@
|
||||
import type { getConfigEntries } from "../../../src/data/config_entries";
|
||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||
|
||||
export const mockConfigEntries = (hass: MockHomeAssistant) => {
|
||||
hass.mockWS<typeof getConfigEntries>("config_entries/get", () => [
|
||||
{
|
||||
entry_id: "mock-entry-co2signal",
|
||||
domain: "co2signal",
|
||||
title: "Electricity Maps",
|
||||
source: "user",
|
||||
state: "loaded",
|
||||
supports_options: false,
|
||||
supports_remove_device: false,
|
||||
supports_unload: true,
|
||||
supports_reconfigure: true,
|
||||
supported_subentry_types: {},
|
||||
pref_disable_new_entities: false,
|
||||
pref_disable_polling: false,
|
||||
disabled_by: null,
|
||||
reason: null,
|
||||
num_subentries: 0,
|
||||
error_reason_translation_key: null,
|
||||
error_reason_translation_placeholders: null,
|
||||
},
|
||||
]);
|
||||
hass.mockWS("config_entries/get", () => ({
|
||||
entry_id: "co2signal",
|
||||
domain: "co2signal",
|
||||
title: "Electricity Maps",
|
||||
source: "user",
|
||||
state: "loaded",
|
||||
supports_options: false,
|
||||
supports_remove_device: false,
|
||||
supports_unload: true,
|
||||
supports_reconfigure: true,
|
||||
pref_disable_new_entities: false,
|
||||
pref_disable_polling: false,
|
||||
disabled_by: null,
|
||||
reason: null,
|
||||
}));
|
||||
};
|
||||
|
@ -131,7 +131,6 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
|
||||
});
|
||||
}, 1);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
return () => {};
|
||||
}
|
||||
);
|
||||
|
@ -43,7 +43,7 @@ customElements.whenDefined("hui-root").then(() => {
|
||||
const index = (ev as CustomEvent).detail.index;
|
||||
try {
|
||||
await setDemoConfig(this.hass, this.lovelace!, index);
|
||||
} catch (_err: any) {
|
||||
} catch (err: any) {
|
||||
setDemoConfig(this.hass, this.lovelace!, selectedDemoConfigIndex);
|
||||
alert("Failed to switch config :-(");
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ export const mockPersistentNotification = (hass: MockHomeAssistant) => {
|
||||
},
|
||||
},
|
||||
} as PersistentNotificationMessage);
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
return () => {};
|
||||
});
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||
const generateMeanStatistics = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
// eslint-disable-next-line default-param-last
|
||||
// eslint-disable-next-line @typescript-eslint/default-param-last
|
||||
period: "5minute" | "hour" | "day" | "month" = "hour",
|
||||
initValue: number,
|
||||
maxDiff: number
|
||||
@ -52,7 +52,7 @@ const generateMeanStatistics = (
|
||||
const generateSumStatistics = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
// eslint-disable-next-line default-param-last
|
||||
// eslint-disable-next-line @typescript-eslint/default-param-last
|
||||
period: "5minute" | "hour" | "day" | "month" = "hour",
|
||||
initValue: number,
|
||||
maxDiff: number
|
||||
@ -89,7 +89,7 @@ const generateSumStatistics = (
|
||||
const generateCurvedStatistics = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
// eslint-disable-next-line default-param-last
|
||||
// eslint-disable-next-line @typescript-eslint/default-param-last
|
||||
_period: "5minute" | "hour" | "day" | "month" = "hour",
|
||||
initValue: number,
|
||||
maxDiff: number,
|
||||
|
@ -11,7 +11,6 @@ export const mockTemplate = (hass: MockHomeAssistant) => {
|
||||
result: msg.template,
|
||||
listeners: { all: false, domains: [], entities: [], time: false },
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
return () => {};
|
||||
});
|
||||
};
|
||||
|
@ -22,6 +22,5 @@ export const mockTodo = (hass: MockHomeAssistant) => {
|
||||
},
|
||||
] as TodoItem[],
|
||||
}));
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
hass.mockWS("todo/item/subscribe", (_msg, _hass) => () => {});
|
||||
};
|
||||
|
@ -1,16 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import unusedImports from "eslint-plugin-unused-imports";
|
||||
import globals from "globals";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import js from "@eslint/js";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import tseslint from "typescript-eslint";
|
||||
import eslintConfigPrettier from "eslint-config-prettier";
|
||||
import { configs as litConfigs } from "eslint-plugin-lit";
|
||||
import { configs as wcConfigs } from "eslint-plugin-wc";
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
const _dirname = path.dirname(_filename);
|
||||
@ -20,14 +15,16 @@ const compat = new FlatCompat({
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default tseslint.config(
|
||||
...compat.extends("airbnb-base", "plugin:lit-a11y/recommended"),
|
||||
eslintConfigPrettier,
|
||||
litConfigs["flat/all"],
|
||||
tseslint.configs.recommended,
|
||||
tseslint.configs.strict,
|
||||
tseslint.configs.stylistic,
|
||||
wcConfigs["flat/recommended"],
|
||||
export default [
|
||||
...compat.extends(
|
||||
"airbnb-base",
|
||||
"airbnb-typescript/base",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:wc/recommended",
|
||||
"plugin:lit/all",
|
||||
"plugin:lit-a11y/recommended",
|
||||
"prettier"
|
||||
),
|
||||
{
|
||||
plugins: {
|
||||
"unused-imports": unusedImports,
|
||||
@ -42,9 +39,10 @@ export default tseslint.config(
|
||||
__VERSION__: false,
|
||||
__STATIC_PATH__: false,
|
||||
__SUPERVISOR__: false,
|
||||
Polymer: true,
|
||||
},
|
||||
|
||||
parser: tseslint.parser,
|
||||
parser: tsParser,
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
|
||||
@ -52,6 +50,8 @@ export default tseslint.config(
|
||||
ecmaFeatures: {
|
||||
modules: true,
|
||||
},
|
||||
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
},
|
||||
|
||||
@ -148,15 +148,15 @@ export default tseslint.config(
|
||||
},
|
||||
],
|
||||
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
|
||||
"unused-imports/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
args: "all",
|
||||
argsIgnorePattern: "^_",
|
||||
caughtErrors: "all",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
destructuredArrayIgnorePattern: "^_",
|
||||
vars: "all",
|
||||
varsIgnorePattern: "^_",
|
||||
args: "after-used",
|
||||
argsIgnorePattern: "^_",
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
@ -174,16 +174,6 @@ export default tseslint.config(
|
||||
"lit-a11y/role-has-required-aria-attrs": "error",
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
camelcase: "off",
|
||||
"@typescript-eslint/no-dynamic-delete": "off",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
allowInterfaces: "always",
|
||||
allowObjectTypes: "always",
|
||||
},
|
||||
],
|
||||
"no-use-before-define": "off",
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
];
|
||||
|
@ -1,10 +1,10 @@
|
||||
// @ts-check
|
||||
|
||||
import tseslint from "typescript-eslint";
|
||||
import rootConfig from "../eslint.config.mjs";
|
||||
|
||||
export default tseslint.config(...rootConfig, {
|
||||
rules: {
|
||||
"no-console": "off",
|
||||
export default [
|
||||
...rootConfig,
|
||||
{
|
||||
rules: {
|
||||
"no-console": "off",
|
||||
},
|
||||
},
|
||||
});
|
||||
];
|
||||
|
@ -1,10 +0,0 @@
|
||||
<svg width="94" height="64" viewBox="0 0 94 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="94" height="64" rx="8" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="93" height="63" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
|
||||
<path d="M8 27C8 25.3431 9.34315 24 11 24H31C32.6569 24 34 25.3431 34 27V29C34 30.6569 32.6569 32 31 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M38 27C38 25.3431 39.3431 24 41 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H41C39.3431 32 38 30.6569 38 29V27Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M8 39C8 37.3431 9.34315 36 11 36H53C54.6569 36 56 37.3431 56 39V41C56 42.6569 54.6569 44 53 44H11C9.34315 44 8 42.6569 8 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M60 39C60 37.3431 61.3431 36 63 36H83C84.6569 36 86 37.3431 86 39V41C86 42.6569 84.6569 44 83 44H63C61.3431 44 60 42.6569 60 41V39Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M8 51C8 49.3431 9.34315 48 11 48H31C32.6569 48 34 49.3431 34 51V53C34 54.6569 32.6569 56 31 56H11C9.34315 56 8 54.6569 8 53V51Z" fill="black" fill-opacity="0.12"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,7 +0,0 @@
|
||||
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 11C0 9.34315 1.34315 8 3 8H23C24.6569 8 26 9.34315 26 11V13C26 14.6569 24.6569 16 23 16H3C1.34315 16 0 14.6569 0 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M30 11C30 9.34315 31.3431 8 33 8H91C92.6569 8 94 9.34315 94 11V13C94 14.6569 92.6569 16 91 16H33C31.3431 16 30 14.6569 30 13V11Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M0 23C0 21.3431 1.34315 20 3 20H61C62.6569 20 64 21.3431 64 23V25C64 26.6569 62.6569 28 61 28H3C1.34315 28 0 26.6569 0 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M68 23C68 21.3431 69.3431 20 71 20H91C92.6569 20 94 21.3431 94 23V25C94 26.6569 92.6569 28 91 28H71C69.3431 28 68 26.6569 68 25V23Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M0 35C0 33.3431 1.34315 32 3 32H23C24.6569 32 26 33.3431 26 35V37C26 38.6569 24.6569 40 23 40H3C1.34315 40 0 38.6569 0 37V35Z" fill="black" fill-opacity="0.12"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 964 B |
@ -177,24 +177,26 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
this._action = ev.detail.isValid ? ev.detail.value : undefined;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.action {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.action {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -98,24 +98,26 @@ export class DemoAutomationDescribeCondition extends LitElement {
|
||||
this._condition = ev.detail.isValid ? ev.detail.value : undefined;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.condition {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.condition {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -121,24 +121,26 @@ export class DemoAutomationDescribeTrigger extends LitElement {
|
||||
this._trigger = ev.detail.isValid ? ev.detail.value : undefined;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.trigger {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.trigger {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
span {
|
||||
margin-right: 16px;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -58,20 +58,22 @@ export class DemoAutomationTraceTimeline extends LitElement {
|
||||
hass.updateTranslations("config", "en");
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
}
|
||||
button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
}
|
||||
button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -68,26 +68,28 @@ export class DemoAutomationTrace extends LitElement {
|
||||
this._selected = { ...this._selected, [sampleIdx]: ev.detail.path };
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
}
|
||||
.card-content > * {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.card-content > *:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
}
|
||||
.card-content > * {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.card-content > *:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -177,44 +177,46 @@ export class DemoHaAlert extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dark,
|
||||
.light {
|
||||
display: block;
|
||||
background-color: var(--primary-background-color);
|
||||
padding: 0 50px;
|
||||
}
|
||||
ha-card {
|
||||
margin: 24px auto;
|
||||
}
|
||||
ha-alert {
|
||||
display: block;
|
||||
margin: 24px 0;
|
||||
}
|
||||
.condition {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.image {
|
||||
display: inline-flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
img {
|
||||
max-height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
mwc-button {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dark,
|
||||
.light {
|
||||
display: block;
|
||||
background-color: var(--primary-background-color);
|
||||
padding: 0 50px;
|
||||
}
|
||||
ha-card {
|
||||
margin: 24px auto;
|
||||
}
|
||||
ha-alert {
|
||||
display: block;
|
||||
margin: 24px 0;
|
||||
}
|
||||
.condition {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.image {
|
||||
display: inline-flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
img {
|
||||
max-height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
mwc-button {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -63,18 +63,20 @@ export class DemoHaBar extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.warning {
|
||||
--ha-bar-primary-color: var(--warning-color);
|
||||
}
|
||||
.error {
|
||||
--ha-bar-primary-color: var(--error-color);
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.warning {
|
||||
--ha-bar-primary-color: var(--warning-color);
|
||||
}
|
||||
.error {
|
||||
--ha-bar-primary-color: var(--error-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -103,17 +103,19 @@ export class DemoHaChips extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,4 +1,4 @@
|
||||
---
|
||||
title: Spinner
|
||||
title: Circular Progress
|
||||
subtitle: Can be used to indicate an ongoing task.
|
||||
---
|
65
gallery/src/pages/components/ha-circular-progress.ts
Normal file
65
gallery/src/pages/components/ha-circular-progress.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { html, css, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-bar";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "@material/web/progress/circular-progress";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
|
||||
@customElement("demo-components-ha-circular-progress")
|
||||
export class DemoHaCircularProgress extends LitElement {
|
||||
@property({ attribute: false }) hass!: HomeAssistant;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`<ha-card header="Basic circular progress">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress indeterminate></ha-circular-progress></div
|
||||
></ha-card>
|
||||
<ha-card header="Different circular progress sizes">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="tiny"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="medium"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="large"
|
||||
></ha-circular-progress></div
|
||||
></ha-card>
|
||||
<ha-card header="Circular progress with an aria-label">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
aria-label="Doing something..."
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
.ariaLabel=${"Doing something..."}
|
||||
></ha-circular-progress></div
|
||||
></ha-card>`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-circular-progress": DemoHaCircularProgress;
|
||||
}
|
||||
}
|
@ -14,12 +14,12 @@ import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import "../../../../src/components/ha-control-button-group";
|
||||
|
||||
interface Button {
|
||||
type Button = {
|
||||
label: string;
|
||||
icon?: string;
|
||||
class?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
const buttons: Button[] = [
|
||||
{
|
||||
@ -35,10 +35,10 @@ const buttons: Button[] = [
|
||||
},
|
||||
];
|
||||
|
||||
interface ButtonGroup {
|
||||
type ButtonGroup = {
|
||||
vertical?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
};
|
||||
|
||||
const buttonGroups: ButtonGroup[] = [
|
||||
{},
|
||||
@ -137,51 +137,53 @@ export class DemoHaBarButton extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
--control-button-background-color: var(--primary-color);
|
||||
--control-button-background-opacity: 0.2;
|
||||
--control-button-border-radius: 18px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
.custom-group {
|
||||
--control-button-group-thickness: 100px;
|
||||
--control-button-group-border-radius: 36px;
|
||||
--control-button-group-spacing: 20px;
|
||||
}
|
||||
.custom-group ha-control-button {
|
||||
--control-button-border-radius: 18px;
|
||||
--mdc-icon-size: 32px;
|
||||
}
|
||||
.vertical-buttons {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-switches > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
--control-button-background-color: var(--primary-color);
|
||||
--control-button-background-opacity: 0.2;
|
||||
--control-button-border-radius: 18px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
.custom-group {
|
||||
--control-button-group-thickness: 100px;
|
||||
--control-button-group-border-radius: 36px;
|
||||
--control-button-group-spacing: 20px;
|
||||
}
|
||||
.custom-group ha-control-button {
|
||||
--control-button-border-radius: 18px;
|
||||
--mdc-icon-size: 32px;
|
||||
}
|
||||
.vertical-buttons {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-switches > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -133,37 +133,39 @@ export class DemoHaCircularSlider extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
ha-control-circular-slider {
|
||||
--control-circular-slider-color: #ff9800;
|
||||
}
|
||||
ha-control-circular-slider[inverted] {
|
||||
--control-circular-slider-color: #2196f3;
|
||||
}
|
||||
ha-control-circular-slider[dual] {
|
||||
--control-circular-slider-high-color: #2196f3;
|
||||
--control-circular-slider-low-color: #ff9800;
|
||||
}
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
ha-control-circular-slider {
|
||||
--control-circular-slider-color: #ff9800;
|
||||
}
|
||||
ha-control-circular-slider[inverted] {
|
||||
--control-circular-slider-color: #2196f3;
|
||||
}
|
||||
ha-control-circular-slider[dual] {
|
||||
--control-circular-slider-high-color: #2196f3;
|
||||
--control-circular-slider-low-color: #ff9800;
|
||||
}
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -73,30 +73,32 @@ export class DemoHarControlNumberButtons extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
color: #2196f3;
|
||||
--control-number-buttons-color: #2196f3;
|
||||
--control-number-buttons-background-color: #2196f3;
|
||||
--control-number-buttons-background-opacity: 0.1;
|
||||
--control-number-buttons-thickness: 100px;
|
||||
--control-number-buttons-border-radius: 36px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
color: #2196f3;
|
||||
--control-number-buttons-color: #2196f3;
|
||||
--control-number-buttons-background-color: #2196f3;
|
||||
--control-number-buttons-background-opacity: 0.1;
|
||||
--control-number-buttons-thickness: 100px;
|
||||
--control-number-buttons-border-radius: 36px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -8,19 +8,19 @@ import "../../../../src/components/ha-control-select-menu";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
|
||||
interface SelectMenuOptions {
|
||||
type SelectMenuOptions = {
|
||||
label: string;
|
||||
value: string;
|
||||
icon?: string;
|
||||
}
|
||||
};
|
||||
|
||||
interface SelectMenu {
|
||||
type SelectMenu = {
|
||||
label: string;
|
||||
icon: string;
|
||||
class?: string;
|
||||
disabled?: boolean;
|
||||
options: SelectMenuOptions[];
|
||||
}
|
||||
};
|
||||
|
||||
const selects: SelectMenu[] = [
|
||||
{
|
||||
@ -112,30 +112,32 @@ export class DemoHaControlSelectMenu extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
--control-button-background-color: var(--primary-color);
|
||||
--control-button-background-opacity: 0.2;
|
||||
--control-button-border-radius: 18px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
--control-button-background-color: var(--primary-color);
|
||||
--control-button-background-opacity: 0.2;
|
||||
--control-button-border-radius: 18px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -168,40 +168,42 @@ export class DemoHaControlSelect extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--mdc-icon-size: 24px;
|
||||
--control-select-color: var(--state-fan-active-color);
|
||||
--control-select-thickness: 130px;
|
||||
--control-select-border-radius: 36px;
|
||||
}
|
||||
.vertical-selects {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-selects > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--mdc-icon-size: 24px;
|
||||
--control-select-color: var(--state-fan-active-color);
|
||||
--control-select-thickness: 130px;
|
||||
--control-select-border-radius: 36px;
|
||||
}
|
||||
.vertical-selects {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-selects > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -131,41 +131,43 @@ export class DemoHaBarSlider extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-slider-color: #ffcf4c;
|
||||
--control-slider-background: #ffcf4c;
|
||||
--control-slider-background-opacity: 0.2;
|
||||
--control-slider-thickness: 130px;
|
||||
--control-slider-border-radius: 36px;
|
||||
}
|
||||
.vertical-sliders {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-sliders > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-slider-color: #ffcf4c;
|
||||
--control-slider-background: #ffcf4c;
|
||||
--control-slider-background-opacity: 0.2;
|
||||
--control-slider-thickness: 130px;
|
||||
--control-slider-border-radius: 36px;
|
||||
}
|
||||
.vertical-sliders {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-sliders > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -99,42 +99,44 @@ export class DemoHaControlSwitch extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-switch-on-color: var(--green-color);
|
||||
--control-switch-off-color: var(--red-color);
|
||||
--control-switch-thickness: 130px;
|
||||
--control-switch-border-radius: 36px;
|
||||
--control-switch-padding: 6px;
|
||||
--mdc-icon-size: 24px;
|
||||
}
|
||||
.vertical-switches {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-switches > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom {
|
||||
--control-switch-on-color: var(--green-color);
|
||||
--control-switch-off-color: var(--red-color);
|
||||
--control-switch-thickness: 130px;
|
||||
--control-switch-border-radius: 36px;
|
||||
--control-switch-padding: 6px;
|
||||
--mdc-icon-size: 24px;
|
||||
}
|
||||
.vertical-switches {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.vertical-switches > *:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { mdiLightbulbOn, mdiPacMan } from "@mdi/js";
|
||||
import { mdiPacMan } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
@ -125,23 +125,6 @@ const SAMPLES: {
|
||||
`;
|
||||
},
|
||||
},
|
||||
{
|
||||
template(slot, leftChevron) {
|
||||
return html`
|
||||
<ha-expansion-panel
|
||||
slot=${slot}
|
||||
.leftChevron=${leftChevron}
|
||||
header="Attr Header with actions"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="leading-icon"
|
||||
.path=${mdiLightbulbOn}
|
||||
></ha-svg-icon>
|
||||
${SHORT_TEXT}
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@customElement("demo-components-ha-expansion-panel")
|
||||
@ -160,11 +143,13 @@ export class DemoHaExpansionPanel extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-expansion-panel {
|
||||
margin: -16px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-expansion-panel {
|
||||
margin: -16px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -61,12 +61,14 @@ export class DemoHaFaded extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -48,7 +48,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: "bedroom",
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_1"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -72,7 +71,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: "backyard",
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_2"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -96,7 +94,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: null,
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_3"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -127,8 +124,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
@ -140,8 +135,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
@ -153,8 +146,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
|
@ -91,25 +91,27 @@ export class DemoHaHsColorPicker extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
ha-hs-color-picker {
|
||||
width: 400px;
|
||||
}
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
ha-hs-color-picker {
|
||||
width: 400px;
|
||||
}
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -95,23 +95,25 @@ export class DemoHaLabelBadge extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-left: 16px;
|
||||
background-color: var(--markdown-code-background-color);
|
||||
padding: 8px;
|
||||
}
|
||||
.badge {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-left: 16px;
|
||||
background-color: var(--markdown-code-background-color);
|
||||
padding: 8px;
|
||||
}
|
||||
.badge {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,3 +0,0 @@
|
||||
---
|
||||
title: Select box
|
||||
---
|
@ -1,152 +0,0 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-select-box";
|
||||
import type { SelectBoxOption } from "../../../../src/components/ha-select-box";
|
||||
|
||||
const basicOptions: SelectBoxOption[] = [
|
||||
{
|
||||
value: "text-only",
|
||||
label: "Text only",
|
||||
},
|
||||
{
|
||||
value: "card",
|
||||
label: "Card",
|
||||
},
|
||||
{
|
||||
value: "disabled",
|
||||
label: "Disabled option",
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
const fullOptions: SelectBoxOption[] = [
|
||||
{
|
||||
value: "text-only",
|
||||
label: "Text only",
|
||||
description: "Only text, no border and background",
|
||||
image: "/images/select_box/text_only.svg",
|
||||
},
|
||||
{
|
||||
value: "card",
|
||||
label: "Card",
|
||||
description: "With border and background",
|
||||
image: "/images/select_box/card.svg",
|
||||
},
|
||||
{
|
||||
value: "disabled",
|
||||
label: "Disabled",
|
||||
description: "Option that can not be selected",
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
const selects: {
|
||||
id: string;
|
||||
label: string;
|
||||
class?: string;
|
||||
options: SelectBoxOption[];
|
||||
disabled?: boolean;
|
||||
}[] = [
|
||||
{
|
||||
id: "basic",
|
||||
label: "Basic",
|
||||
options: basicOptions,
|
||||
},
|
||||
{
|
||||
id: "full",
|
||||
label: "With description and image",
|
||||
options: fullOptions,
|
||||
},
|
||||
];
|
||||
|
||||
@customElement("demo-components-ha-select-box")
|
||||
export class DemoHaSelectBox extends LitElement {
|
||||
@state() private value?: string = "off";
|
||||
|
||||
handleValueChanged(e: CustomEvent) {
|
||||
this.value = e.detail.value as string;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
${repeat(selects, (select) => {
|
||||
const { id, label, options } = select;
|
||||
return html`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<label id=${id}>${label}</label>
|
||||
<ha-select-box
|
||||
.value=${this.value}
|
||||
.options=${options}
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-select-box>
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
})}
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<p class="title"><b>Column layout</b></p>
|
||||
<div class="vertical-selects">
|
||||
${repeat(selects, (select) => {
|
||||
const { options } = select;
|
||||
return html`
|
||||
<ha-select-box
|
||||
.value=${this.value}
|
||||
.options=${options}
|
||||
.maxColumns=${1}
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-select-box>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
.custom {
|
||||
--mdc-icon-size: 24px;
|
||||
--control-select-color: var(--state-fan-active-color);
|
||||
--control-select-thickness: 130px;
|
||||
--control-select-border-radius: 36px;
|
||||
}
|
||||
|
||||
p.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.vertical-selects ha-select-box {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-select-box": DemoHaSelectBox;
|
||||
}
|
||||
}
|
@ -47,7 +47,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: "bedroom",
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_1"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -71,7 +70,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: "backyard",
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_2"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -95,7 +93,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
area_id: null,
|
||||
configuration_url: null,
|
||||
config_entries: ["config_entry_3"],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
disabled_by: null,
|
||||
entry_type: null,
|
||||
@ -126,8 +123,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
@ -139,8 +134,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
@ -152,8 +145,6 @@ const AREAS: AreaRegistryEntry[] = [
|
||||
picture: null,
|
||||
aliases: [],
|
||||
labels: [],
|
||||
temperature_entity_id: null,
|
||||
humidity_entity_id: null,
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
},
|
||||
|
@ -1,44 +0,0 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { html, css, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-bar";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
|
||||
@customElement("demo-components-ha-spinner")
|
||||
export class DemoHaSpinner extends LitElement {
|
||||
@property({ attribute: false }) hass!: HomeAssistant;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`<ha-card header="Basic spinner">
|
||||
<div class="card-content">
|
||||
<ha-spinner></ha-spinner></div
|
||||
></ha-card>
|
||||
<ha-card header="Different spinner sizes">
|
||||
<div class="card-content">
|
||||
<ha-spinner size="tiny"></ha-spinner>
|
||||
<ha-spinner size="small"></ha-spinner>
|
||||
<ha-spinner size="medium"></ha-spinner>
|
||||
<ha-spinner size="large"></ha-spinner></div
|
||||
></ha-card>
|
||||
<ha-card header="Spinner with an aria-label">
|
||||
<div class="card-content">
|
||||
<ha-spinner aria-label="Doing something..."></ha-spinner>
|
||||
<ha-spinner .ariaLabel=${"Doing something..."}></ha-spinner></div
|
||||
></ha-card>`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-spinner": DemoHaSpinner;
|
||||
}
|
||||
}
|
@ -48,25 +48,27 @@ export class DemoHaTip extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dark,
|
||||
.light {
|
||||
display: block;
|
||||
background-color: var(--primary-background-color);
|
||||
padding: 0 50px;
|
||||
}
|
||||
ha-tip {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
ha-card {
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dark,
|
||||
.light {
|
||||
display: block;
|
||||
background-color: var(--primary-background-color);
|
||||
padding: 0 50px;
|
||||
}
|
||||
ha-tip {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
ha-card {
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,30 +0,0 @@
|
||||
---
|
||||
title: Tooltip
|
||||
---
|
||||
|
||||
A tooltip's target is its _first child element_, so you should only wrap one element inside of the tooltip. If you need the tooltip to show up for multiple elements, nest them inside a container first.
|
||||
|
||||
Tooltips use `display: contents` so they won't interfere with how elements are positioned in a flex or grid layout.
|
||||
|
||||
<ha-tooltip content="This is a tooltip">
|
||||
<ha-button>Hover Me</ha-button>
|
||||
</ha-tooltip>
|
||||
|
||||
```
|
||||
<ha-tooltip content="This is a tooltip">
|
||||
<ha-button>Hover Me</ha-button>
|
||||
</ha-tooltip>
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
This element is based on sholace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation.
|
||||
|
||||
<a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a>
|
||||
|
||||
### HA style tokens
|
||||
|
||||
In your theme settings use this without the prefixed `--`.
|
||||
|
||||
- `--ha-tooltip-border-radius` (Default: 4px)
|
||||
- `--ha-tooltip-arrow-size` (Default: 8px)
|
@ -1,2 +0,0 @@
|
||||
import "../../../../src/components/ha-tooltip";
|
||||
import "../../../../src/components/ha-button";
|
@ -100,30 +100,32 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeDateTimeShort extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeDateTime extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -90,26 +90,28 @@ export class DemoDateTimeDate extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeTimeSeconds extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeTimeWeekday extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -100,30 +100,32 @@ export class DemoDateTimeTime extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
max-width: 800px;
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 12px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
.container > div {
|
||||
flex-grow: 1;
|
||||
width: 20%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -321,13 +321,13 @@ function createEntity(
|
||||
};
|
||||
}
|
||||
|
||||
interface EntityRowData {
|
||||
type EntityRowData = {
|
||||
stateObj: HassEntity;
|
||||
entity_id: string;
|
||||
state: string;
|
||||
device_class?: string;
|
||||
domain: string;
|
||||
}
|
||||
};
|
||||
|
||||
function createRowData(stateObj: HassEntity): EntityRowData {
|
||||
return {
|
||||
@ -429,15 +429,17 @@ export class DemoEntityState extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.color {
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(--color);
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
.color {
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(--color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -76,12 +76,14 @@ export class DemoMiscMarkdown extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
margin: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
`;
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
margin: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -32,8 +32,6 @@ const createConfigEntry = (
|
||||
supports_remove_device: false,
|
||||
supports_unload: true,
|
||||
supports_reconfigure: true,
|
||||
supported_subentry_types: {},
|
||||
num_subentries: 0,
|
||||
disabled_by: null,
|
||||
pref_disable_new_entities: false,
|
||||
pref_disable_polling: false,
|
||||
@ -137,12 +135,12 @@ const configFlows: DataEntryFlowProgressExtended[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const configEntries: {
|
||||
const configEntries: Array<{
|
||||
items: ConfigEntryExtended[];
|
||||
is_custom?: boolean;
|
||||
disabled?: boolean;
|
||||
highlight?: string;
|
||||
}[] = [
|
||||
}> = [
|
||||
{ items: [loadedEntry] },
|
||||
{ items: [configPanelEntry] },
|
||||
{ items: [optionsFlowEntry] },
|
||||
@ -190,7 +188,6 @@ const createEntityRegistryEntries = (
|
||||
): EntityRegistryEntry[] => [
|
||||
{
|
||||
config_entry_id: item.entry_id,
|
||||
config_subentry_id: null,
|
||||
device_id: "mock-device-id",
|
||||
area_id: null,
|
||||
disabled_by: null,
|
||||
@ -217,7 +214,6 @@ const createDeviceRegistryEntries = (
|
||||
{
|
||||
entry_type: null,
|
||||
config_entries: [item.entry_id],
|
||||
config_entries_subentries: {},
|
||||
connections: [],
|
||||
manufacturer: "ESPHome",
|
||||
model: "Mock Device",
|
||||
@ -353,24 +349,26 @@ export class DemoIntegrationCard extends LitElement {
|
||||
this.isCloud = !this.isCloud;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
grid-gap: 8px 8px;
|
||||
padding: 8px 16px 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
static get styles() {
|
||||
return css`
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
grid-gap: 8px 8px;
|
||||
padding: 8px 16px 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.container > * {
|
||||
max-width: 500px;
|
||||
}
|
||||
.container > * {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
ha-formfield {
|
||||
margin: 8px 0;
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
ha-formfield {
|
||||
margin: 8px 0;
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
14
gulpfile.js
14
gulpfile.js
@ -1,4 +1,16 @@
|
||||
import { globIterate } from "glob";
|
||||
import { availableParallelism } from "node:os";
|
||||
import "./build-scripts/gulp/index.mjs";
|
||||
|
||||
process.env.UV_THREADPOOL_SIZE = availableParallelism();
|
||||
|
||||
const gulpImports = [];
|
||||
|
||||
for await (const gulpModule of globIterate("build-scripts/gulp/*.?(c|m)js", {
|
||||
dotRelative: true,
|
||||
})) {
|
||||
gulpImports.push(import(gulpModule));
|
||||
}
|
||||
|
||||
// Since all tasks are currently registered with gulp.task(), this is enough
|
||||
// If any are converted to named exports, need to loop and aggregate exports here
|
||||
await Promise.all(gulpImports);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import type { PropertyValues, TemplateResult } from "lit";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
@ -211,33 +211,35 @@ export class HassioAddonStore extends LitElement {
|
||||
this._filter = e.detail.value;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
hassio-addon-repository {
|
||||
margin-top: 24px;
|
||||
}
|
||||
.search {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
search-input {
|
||||
display: block;
|
||||
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||
}
|
||||
.advanced {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.advanced a {
|
||||
margin-left: 0.5em;
|
||||
margin-inline-start: 0.5em;
|
||||
margin-inline-end: initial;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
hassio-addon-repository {
|
||||
margin-top: 24px;
|
||||
}
|
||||
.search {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
search-input {
|
||||
display: block;
|
||||
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||
}
|
||||
.advanced {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.advanced a {
|
||||
margin-left: 0.5em;
|
||||
margin-inline-start: 0.5em;
|
||||
margin-inline-end: initial;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
import { haStyle } from "../../../../src/resources/styles";
|
||||
@ -21,7 +21,7 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-spinner></ha-spinner>`;
|
||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
}
|
||||
const hasConfiguration =
|
||||
(this.addon.options && Object.keys(this.addon.options).length) ||
|
||||
|
@ -113,9 +113,8 @@ class HassioAddonConfig extends LitElement {
|
||||
required: entry.required,
|
||||
selector: {
|
||||
text: {
|
||||
type: entry.format
|
||||
? entry.format
|
||||
: MASKED_FIELDS.includes(entry.name)
|
||||
type:
|
||||
entry.format || MASKED_FIELDS.includes(entry.name)
|
||||
? "password"
|
||||
: "text",
|
||||
},
|
||||
@ -300,7 +299,7 @@ class HassioAddonConfig extends LitElement {
|
||||
if (this.addon.schema && this._canShowSchema && !this._yamlMode) {
|
||||
this._valid = true;
|
||||
this._configHasChanged = true;
|
||||
this._options = ev.detail.value;
|
||||
this._options! = ev.detail.value;
|
||||
} else {
|
||||
this._configHasChanged = true;
|
||||
this._valid = ev.detail.isValid;
|
||||
|
@ -151,7 +151,7 @@ class HassioAddonNetwork extends LitElement {
|
||||
|
||||
private async _configChanged(ev: CustomEvent): Promise<void> {
|
||||
this._configHasChanged = true;
|
||||
this._config = ev.detail.value;
|
||||
this._config! = ev.detail.value;
|
||||
}
|
||||
|
||||
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user