Conversation
…e test coverage update directive imports to Lit 3 paths align card typing with latest HA/custom-card-helpers (including async card size support) tighten Restriction card/types definitions and remove implicit any usage improve runtime safety around helper loading and overlay element checks add focused Vitest coverage for shouldUpdate decision branches add reactive hass getter to satisfy Lit property contract warnings resolve lint issues and keep build/test pipeline green
Add a full Lovelace visual editor (src/editor.ts) and integrate it into restriction-card (src/restriction-card.ts). The card now exposes getConfigElement/getStubConfig, dynamically loads the editor, caches the inner card element, builds it lazily, and forwards hass updates. Improved helpers loading, added robust polling/timeout for loadCardHelpers, added timer management (_timers) with a helper to schedule/clear timeouts, and switched blocked-message alerts to dispatch hass-notification events. Coerce duration to number and add duration field in types (deprecated delay retained). Devcontainer updated: switch to thomasloven/hass-custom-devcontainer base, install Node 24 in image, enable corepack, fix CRLF in container script, and set LOVELACE_LOCAL_FILES env. UI Lovelace example trimmed and README Home Assistant minimum version bumped to 2026.2.3. Misc: console logging for debug and small refactors to rendering/shouldUpdate logic.
There was a problem hiding this comment.
Pull request overview
This PR modernizes the development/tooling setup for the Home Assistant custom card and upgrades the runtime codebase to a new major version, aligning builds, linting, tests, and the devcontainer workflow with newer Node/Yarn/Lit/TypeScript.
Changes:
- Upgrade runtime to Lit 3 and introduce a Lovelace visual editor for the card (v2.0.0).
- Modernize build/test/lint toolchain (Rollup 4, ESLint flat config, Prettier 3, Vitest) and move to Yarn 4 via Corepack.
- Refresh devcontainer + CI workflows for Node.js 24 and updated contributor documentation.
Reviewed changes
Copilot reviewed 27 out of 31 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Updates TS target/libs and switches module resolution to bundler. |
| src/types.ts | Adds duration, refactors restriction config types, and introduces typed card helper interfaces. |
| src/restriction-card.ts | Migrates to Lit 3, adds editor hooks/stub config, refactors helper loading, caching, and timeout handling. |
| src/restriction-card.test.ts | Adds Vitest coverage for shouldUpdate. |
| src/editor.ts | Adds a full visual editor implementation (restriction-card-editor). |
| src/const.ts | Bumps card version to 2.0.0. |
| src/action-handler-directive.ts | Migrates directive implementation to Lit 3 directive APIs and expands action handling behavior. |
| rollup.config.js | Replaces legacy Rollup plugins with modern @rollup/* plugins; adds dev/prod behaviors and warning filtering. |
| rollup.config.dev.js | Switches dev build to esbuild + improved watch config for container mounts. |
| package.json | Moves to ESM, bumps version, adopts Yarn 4, adds Vitest, updates dependencies and scripts. |
| package-lock.json | Removes npm lockfile (migration to Yarn). |
| eslint.config.js | Introduces ESLint 9 flat config with TS + Prettier integration. |
| README.md | Updates minimum supported Home Assistant version for v2.0.0. |
| LICENSE | Replaces file contents (currently not license text). |
| CLAUDE.md | Adds reference to Copilot instructions. |
| AGENTS.md | Adds reference to Copilot instructions. |
| .yarnrc.yml | Configures Yarn to use node-modules linker. |
| .prettierrc.json | Adds Prettier config (incl. LF line endings). |
| .prettierrc.js | Removes old Prettier config. |
| .gitignore | Expands ignored paths, including devcontainer HA data and Yarn artifacts. |
| .github/workflows/release.yml | Updates release pipeline for Node 24 + Yarn 4 and adds semver/version-bump validation. |
| .github/workflows/build.yml | Updates CI build to Node 24 + Yarn 4 (Corepack). |
| .github/copilot-instructions.md | Adds project-specific Copilot/contributor guidance. |
| .gitattributes | Enforces LF line endings and declares binary files. |
| .eslintrc.js | Removes legacy ESLint config. |
| .devcontainer/ui-lovelace.yaml | Removes example usage of restriction-card from dev Lovelace dashboard. |
| .devcontainer/devcontainer.json | Replaces devcontainer config to build from Dockerfile and run HA + watch builds. |
| .devcontainer/config/configuration.yaml | Updates HA config defaults for devcontainer environment. |
| .devcontainer/README.md | Adds devcontainer setup/workflow documentation. |
| .devcontainer/Dockerfile | Introduces a custom devcontainer image (Node 24 + Corepack). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Support legacy `delay` config and ensure `duration` is a positive number (coerced and validated), storing a sanitized numeric value in the card config. Update unit tests to use the correct `hass` change key and adjust test setup to compare previous vs current hass state. Rename references in devcontainer README and Copilot instructions from `config-template-card` to `restriction-card`. Replace LICENSE file content with the MIT license.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 31 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@iantrich |
Refactor card helper loading and timeout handling, tighten touch handling, and clean up debug logs. Key changes: - .devcontainer: remove LOVELACE_LOCAL_FILES entry. - action-handler-directive: import forwardHaptic and trigger haptic on hold; wrap touchend listener to call preventDefault before ending action. - editor: remove customElement decorator import/usage and reorder action option entries. - restriction-card: - remove noisy console logging and lower one message to debug. - add _cancelWaitForHelpers and lifecycle cancellation to avoid leaks when disconnected. - replace _scheduleTimeout to return IDs and add _clearScheduledTimeout for consistent timeout management. - make loadCardHelpers and _waitForCardHelpers more robust: use Promise.race with scheduled timeout, clear resolve timeout on success, add cancellable polling, handle disconnection, and ensure window.load event + polling cooperate. - conditionally define the custom element at the end to avoid double-registration. These changes fix potential timer leaks, improve reliability of helper resolution, and make touch/hold UX more responsive.
Use the Lovelace CardHelpers showConfirmationDialog helper when present to display confirmation dialogs (with localized title/button text), and fall back to window.confirm otherwise. Adds an optional showConfirmationDialog signature to CardHelpers in types.ts and updates restriction-card.ts to build localized text and await the helper result before proceeding.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 31 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Clarify and expand README: document that restriction types are map objects and that an empty map (e.g. block: {} or hide: {}) enables a restriction; add examples for hide with exemptions and condition and update examples to use empty maps instead of booleans. Fix action handler touch behavior: preventDefault on cancelable touchend events and simplify touchend listener to call element.actionHandler.end directly to avoid duplicate handling and unwanted clicks on touch devices. Also remove an obsolete comment in restriction-card.ts.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 32 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -118,7 +145,9 @@ class RestrictionCard extends LitElement implements LovelaceCard { | |||
| return html` | |||
| <div id="mainContainer" style=${ifDefined(styleMap(this._config.css_variables || {}))}> | |||
There was a problem hiding this comment.
The style binding nests Lit directives (ifDefined(styleMap(...))), which Lit doesn’t support; this can result in the style attribute not being applied (or rendering as "[object Object]"). Bind the style directive directly (and drop ifDefined here), letting styleMap handle empty/undefined values.
| <div id="mainContainer" style=${ifDefined(styleMap(this._config.css_variables || {}))}> | |
| <div id="mainContainer" style=${styleMap(this._config.css_variables || {})}> |
There was a problem hiding this comment.
@ildar170975 I feel like are much more well versed in the css world of things, can you verify this with the beta release?
There was a problem hiding this comment.
I will check in a few days. away from PC now
There was a problem hiding this comment.
Hi @ildar170975, just checking in to see if you've had a chance to test this release yet. Thanks!
There was a problem hiding this comment.
Hi Ian, please let me recheck all my test cases once again! Last time I checked (almost immediately after your PR) things were OK, but let me be more sure.
In a few days I will be near a PC and recheck everything, please give me a week.
There was a problem hiding this comment.
@iantrich
Hi again!
I think we need a bit more efforts to release a "real" 2.0 version, please check the latest issues I just registered.
Will start thinking how to solve these issues.
Also, right now I am testing UI for editing the card's options, may be it will get us issues...
|
@ildar170975 I cut a beta release that should be available on HACS now. Please test it out at your leisure. Thanks for all your help in my absence! |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 33 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 33 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 33 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const legacyDelay = (config as { delay?: unknown }).delay; | ||
| const rawDuration = config.duration ?? legacyDelay ?? 5; | ||
| const coercedDuration = Number(rawDuration); | ||
|
|
||
| this._config = { | ||
| duration: 5, | ||
| duration: Number.isFinite(coercedDuration) && coercedDuration > 0 ? coercedDuration : 5, | ||
| action: 'tap', | ||
| locked_icon: 'mdi:lock-outline', | ||
| ...config, | ||
| }; | ||
| // Keep validated duration in case YAML input is null/blank/invalid | ||
| this._config.duration = Number.isFinite(coercedDuration) && coercedDuration > 0 ? coercedDuration : 5; | ||
| // Clear cached element so it is rebuilt with the new config |
There was a problem hiding this comment.
setConfig() assigns duration twice: once in the object literal (before spreading ...config) and again immediately after. This duplication makes the initialization harder to follow. Consider constructing _config so the validated duration is applied once after spreading the user config (so it can’t be overridden by invalid input).
|
|
||
| expect( | ||
| card.shouldUpdate( | ||
| changedProps([ | ||
| ['_config', {}], | ||
| ['_hass', createHass('off')], |
There was a problem hiding this comment.
In this test, changedProps uses the key '_hass', but RestrictionCard.shouldUpdate() reads the previous hass from changedProps.get('hass'). That makes this assertion pass for the wrong reason (it will behave as if there was no previous hass). Use ['hass', previousHass] consistently so the test reflects real Lit update behavior.
| expect( | |
| card.shouldUpdate( | |
| changedProps([ | |
| ['_config', {}], | |
| ['_hass', createHass('off')], | |
| const previousHass = createHass('on'); | |
| (card as RestrictionCardElementForTest & { hass?: HomeAssistant }).hass = createHass('off'); | |
| expect( | |
| card.shouldUpdate( | |
| changedProps([ | |
| ['_config', {}], | |
| ['hass', previousHass], |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 32 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| protected render(): TemplateResult | void { | ||
| if (!this._config || !this._hass || !this._config.card || !this._helpers) { | ||
| console.info('[RC] render() → bailing early (missing required state)'); | ||
| return html``; |
There was a problem hiding this comment.
render() logs at console.info every time required state is missing. Since render() can run frequently in Lovelace, this can spam the console and add overhead during initial load and updates. Consider removing this log or gating it behind an explicit debug flag.
This pull request modernizes and standardizes the development environment, tooling, and workflows for the Home Assistant restriction-card project. It introduces a new dev container setup for seamless local development, upgrades Node.js and build tooling, enforces consistent code style and linting, and refines the CI/CD pipelines for reliability and reproducibility. Documentation and configuration files are also updated to reflect these changes.
Development Environment and Tooling Modernization:
.devcontainersetup using a custom Dockerfile based onthomasloven/hass-custom-devcontainer, installing Node.js 24, enabling corepack for Yarn 4, and fixing line endings for compatibility. This provides a consistent, ready-to-use environment for developing and testing the custom card. (.devcontainer/Dockerfile, .devcontainer/DockerfileR1-R13).devcontainer/README.mdwith setup instructions, workflow details, and troubleshooting for the new dev container environment. (.devcontainer/README.md, .devcontainer/README.mdR1-R111).devcontainer/devcontainer.jsonto use the new Dockerfile, improved volume mounts, environment variables, port forwarding, and VS Code extension recommendations for TypeScript and YAML. (.devcontainer/devcontainer.json, .devcontainer/devcontainer.jsonL1-R68).gitattributesto enforce LF line endings and explicitly declare text/binary file types, ensuring cross-platform consistency. (.gitattributes, .gitattributesR1-R19).yarnrc.ymlto usenode-moduleslinker for Yarn 4. (.yarnrc.yml, .yarnrc.ymlR1)Code Quality, Linting, and Formatting:
.eslintrc.jsto a moderneslint.config.jswith ESLint Flat Config, TypeScript, Prettier, and import plugins, and updated rules for stricter code quality. (eslint.config.js, [1]; removed.eslintrc.js, [2]R1).prettierrc.jsto.prettierrc.jsonfor better compatibility and added explicitendOfLine: "lf". (.prettierrc.json, [1]; removed.prettierrc.js, [2]CI/CD Pipeline Improvements:
package.jsonandsrc/const.tsbased on the release tag. (.github/workflows/build.yml, [1];.github/workflows/release.yml, [2].github/workflows/build.yml, [1];.github/workflows/release.yml, [2]Documentation and Configuration Updates:
.github/copilot-instructions.md, [1]; referenced inAGENTS.md,CLAUDE.md, [2]package.jsonto specify Yarn 4, Node.js 24, and new version2.0.0. (package.json, package.jsonL3-R5)README.mdto reflect new requirements. (README.md, README.mdL21-R21).devcontainer/config/configuration.yaml, [1];.devcontainer/ui-lovelace.yaml, [2]These changes collectively bring the project up to date with modern development practices, improve reliability and onboarding for contributors, and ensure a consistent workflow across local development and CI/CD.