Skip to content

Commit e0088f2

Browse files
committed
Initial release: sections-grid-layout v0.1.0-alpha
A Home Assistant Lovelace view plugin that places native hui-section elements into a CSS Grid with Jinja template evaluation and responsive design support. Features: - Named grid areas with grid-template-areas/columns/rows - Per-section styling: scrollable, background, tint, blur, zoom, padding, overflow, and scoped CSS variables - Jinja-like template evaluation in custom_css and background_image (states, state_attr, is_state, conditional blocks) - Full-screen overlay system with pulse/fade/flash/slide-up animations triggered by entity state, with edit-mode tester panel - Background images with blur, opacity, and template support - Kiosk mode for wall-mounted dashboards with mobile fallback - Named breakpoints and responsive media query overrides at both layout and per-section level - Section YAML editor (ha-yaml-editor / ha-code-editor / textarea) - Layout zoom and per-section zoom - FAB suppression in sections mode - Coexists safely with stock layout-card via distinct guard flag Derived from lovelace-layout-card by Thomas Loven (MIT).
0 parents  commit e0088f2

38 files changed

Lines changed: 7634 additions & 0 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
sections-grid-layout.js binary
2+
package-lock.json binary
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
name: Bug report
3+
about: Report a bug or unexpected behavior
4+
title: ""
5+
labels: "bug"
6+
assignees: ""
7+
---
8+
9+
**Home Assistant version:** 2024.X.X
10+
**Sections Grid Layout version:**
11+
**Browser:** (e.g. Chrome 120, Safari 17, Firefox 121)
12+
13+
## Description
14+
15+
What happened:
16+
17+
What you expected:
18+
19+
## Steps to Reproduce
20+
21+
1.
22+
2.
23+
3.
24+
25+
## Configuration
26+
27+
```yaml
28+
# Minimal YAML to reproduce the issue
29+
type: custom:sections-grid-layout
30+
layout:
31+
grid-template-areas: |
32+
"main"
33+
sections:
34+
- grid_area: main
35+
type: grid
36+
cards: []
37+
```
38+
39+
## Browser Console Errors
40+
41+
```
42+
(paste any errors here)
43+
```
44+
45+
## Checklist
46+
47+
- [ ] I am using the latest version of sections-grid-layout
48+
- [ ] I am running Home Assistant 2024.2 or newer
49+
- [ ] I have checked existing issues for duplicates
50+
- [ ] I have included a minimal configuration that reproduces the issue
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: Feature request
3+
about: Suggest a new feature or improvement
4+
title: ""
5+
labels: "enhancement"
6+
assignees: ""
7+
---
8+
9+
## Problem
10+
11+
What limitation or pain point does this address?
12+
13+
## Proposed Solution
14+
15+
Describe the feature you'd like to see.
16+
17+
## Example Configuration
18+
19+
```yaml
20+
# How you'd expect the feature to work in YAML
21+
```
22+
23+
## Alternatives Considered
24+
25+
Any alternative approaches you've considered.

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: "20"
19+
20+
- name: Install dependencies
21+
run: npm ci
22+
23+
- name: Build
24+
run: npm run build
25+
26+
- name: Test
27+
run: npm test

.github/workflows/release.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Version tag (e.g. v0.2.0-alpha)"
8+
required: true
9+
prerelease:
10+
description: "Mark as pre-release"
11+
type: boolean
12+
default: true
13+
14+
jobs:
15+
release:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: write
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- uses: actions/setup-node@v4
24+
with:
25+
node-version: "20"
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Build
31+
run: npm run build
32+
33+
- name: Tag
34+
run: |
35+
git config user.name "github-actions[bot]"
36+
git config user.email "github-actions[bot]@users.noreply.github.com"
37+
git tag ${{ github.event.inputs.version }}
38+
git push origin ${{ github.event.inputs.version }}
39+
40+
- name: Create GitHub Release
41+
uses: softprops/action-gh-release@v2
42+
with:
43+
tag_name: ${{ github.event.inputs.version }}
44+
files: sections-grid-layout.js
45+
generate_release_notes: true
46+
prerelease: ${{ github.event.inputs.prerelease }}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
.vscode/settings.json
3+
.DS_Store
4+
*.log
5+
dist/
6+
.env
7+
*.tgz

.vscode/tasks.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "npm: build",
6+
"type": "npm",
7+
"script": "build",
8+
"problemMatcher": []
9+
},
10+
{
11+
"label": "npm: watch",
12+
"type": "npm",
13+
"script": "watch",
14+
"problemMatcher": [],
15+
"presentation": {
16+
"panel": "shared",
17+
"group": "test"
18+
}
19+
},
20+
{
21+
"label": "Run hass",
22+
"type": "shell",
23+
"command": "sudo container launch",
24+
"problemMatcher": [],
25+
"presentation": {
26+
"panel": "shared",
27+
"group": "test"
28+
}
29+
}
30+
]
31+
}

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Changelog
2+
3+
## 0.1.0-alpha
4+
5+
Initial release as **sections-grid-layout**, forked from [lovelace-layout-card](https://github.com/thomasloven/lovelace-layout-card) by Thomas Loven.
6+
7+
### Added
8+
- CSS Grid view layout with `grid-template-areas`, `grid-template-columns`, `grid-template-rows`
9+
- Native `hui-section` wrappers with per-section styling (scrollable, background, tint, blur, zoom, padding, overflow, CSS variables)
10+
- Jinja-like template evaluation in `custom_css` and `background_image` (`states()`, `state_attr()`, `is_state()`, conditionals)
11+
- Full-screen overlay system with pulse/fade/flash/slide-up/none animations
12+
- Background images with blur, opacity, and template support
13+
- Kiosk mode for wall-mounted dashboards with mobile fallback
14+
- Named breakpoints and responsive media query overrides (layout and per-section)
15+
- Section YAML editor (ha-yaml-editor / ha-code-editor / textarea fallback)
16+
- Layout and per-section zoom
17+
- Edit-mode overlay tester panel
18+
- Coexistence with stock layout-card via distinct guard flag
19+
20+
### Removed
21+
- Masonry, horizontal, and vertical layout types (sections-grid-layout registers only the grid view)
22+
- `gap-card` and `layout-break` helper cards
23+
- `BaseLayout` / `BaseColumnLayout` class hierarchy (GridLayout extends LitElement directly)

CLAUDE.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# CLAUDE.md -- AI Assistant Guide for sections-grid-layout
2+
3+
---
4+
5+
## Project Overview
6+
7+
**sections-grid-layout** is a Home Assistant Lovelace custom **view** plugin that places native HA `hui-section` elements into a CSS Grid with Jinja template evaluation and responsive design support.
8+
9+
- **Version**: 0.1.0-alpha
10+
- **License**: MIT
11+
- **Author**: Stormsys
12+
- **HA minimum version**: 2024.2.0 (native Sections view required)
13+
- **Distribution**: HACS
14+
- **Compiled output**: `sections-grid-layout.js`
15+
16+
The project registers one custom element (`sections-grid-layout`) and two patches. It coexists safely with the stock `layout-card`.
17+
18+
---
19+
20+
## Repository Layout
21+
22+
```
23+
/
24+
├── src/
25+
│ ├── main.ts # Entry point
26+
│ ├── types.ts # Shared TypeScript interfaces
27+
│ ├── helpers.ts # Selector options constant
28+
│ ├── template.ts # Template evaluation (pure functions)
29+
│ ├── grid-utils.ts # Grid area parsing and section helpers (pure functions)
30+
│ ├── yaml.ts # YAML serializer/parser (pure functions)
31+
│ ├── layouts/
32+
│ │ └── grid.ts # <sections-grid-layout> -- main file
33+
│ └── patches/
34+
│ ├── hui-view-editor.ts # Adds "Sections Grid" to view type dropdown
35+
│ └── hui-card-element-editor.ts # Preserves view_layout on card save
36+
├── tests/
37+
│ ├── template-evaluation.test.ts
38+
│ ├── grid-utils.test.ts
39+
│ ├── yaml.test.ts
40+
│ └── build-output.test.ts
41+
├── rollup.config.js
42+
├── tsconfig.json
43+
├── vitest.config.ts
44+
├── package.json
45+
├── hacs.json
46+
├── sections-grid-layout.js # Compiled output -- DO NOT edit
47+
├── CHANGELOG.md
48+
└── README.md
49+
```
50+
51+
---
52+
53+
## Build & Test
54+
55+
```bash
56+
npm install
57+
npm run build # Production build -> sections-grid-layout.js
58+
npm run watch # Watch mode (no minification)
59+
npm test # Run unit tests (vitest)
60+
npm run test:watch # Watch mode for tests
61+
```
62+
63+
---
64+
65+
## Architecture
66+
67+
```
68+
LitElement
69+
└── GridLayout (src/layouts/grid.ts)
70+
```
71+
72+
`GridLayout` extends `LitElement` directly (no base class).
73+
74+
### `grid.ts`
75+
- **CSS Grid rendering**: Applies `grid-template-areas/columns/rows` from `layout` config
76+
- **Section management**: Creates/destroys `hui-section` wrappers; maintains `_sectionsCache`; auto-saves new sections to lovelace config
77+
- **Jinja template evaluation**: Calls pure functions from `template.ts` for `{{ states() }}`, `{{ state_attr() }}`, `{% if %}` in `custom_css`; tracks entities in `_trackedEntities`; debounced via `requestAnimationFrame`
78+
- **Background images**: Fixed positioning, blur, opacity, template support
79+
- **Kiosk mode**: `layout.kiosk: true` makes `#root` fixed-position, filling viewport below HA header; edit-mode offset adjusts for tab bar
80+
- **Layout zoom**: `layout.zoom` applies CSS `zoom` to `#root`
81+
- **Per-section styling**: `scrollable`, `background`, `backdrop_blur`, `zoom`, `overflow`, `padding`, `tint`, `variables`, `mediaquery` on each section
82+
- **Edit mode UI**: Section labels with grid-area name; loose-cards container for orphan cards; overlay tester panel
83+
- **`_updateSectionsLovelace()`**: Pushes fresh `lovelace` AND fresh `config` to each `hui-section`
84+
85+
### Extracted utility modules (pure functions, testable without DOM)
86+
- **`template.ts`**: `evaluateCssTemplates()`, `evaluateOverlayContent()`, `extractEntitiesFromTemplate()`
87+
- **`grid-utils.ts`**: `detectAllGridAreas()`, `formatAreaName()`, `ensureSectionsForAllAreas()`
88+
- **`yaml.ts`**: `sectionConfigToYaml()`, `yamlScalar()`, `parseYaml()`
89+
90+
### `patches/hui-view-editor.ts`
91+
Adds `sections-grid-layout` to the view type dropdown. Guard flag `_sectionsGridLayoutPatched` prevents double-patching when layout-card is also loaded.
92+
93+
### `patches/hui-card-element-editor.ts`
94+
Preserves `view_layout` when the card element editor saves changes.
95+
96+
---
97+
98+
## Code Conventions
99+
100+
- Private methods/props: `_` prefix
101+
- Constants: `UPPER_SNAKE_CASE`
102+
- `@property()` for external props, `@state()` for internal state
103+
- Clean up observers in `disconnectedCallback()`
104+
- Debounce heavy ops with `requestAnimationFrame`
105+
- Lit 3 only
106+
107+
---
108+
109+
## Template System (`custom_css`)
110+
111+
| Syntax | Example |
112+
|---|---|
113+
| State value | `{{ states('sensor.temperature') }}` |
114+
| Attribute value | `{{ state_attr('climate.living', 'temperature') }}` |
115+
| Conditional | `{% if is_state('binary_sensor.dark', 'on') %}...{% endif %}` |
116+
| Negative | `{% if not is_state('binary_sensor.dark', 'on') %}...{% endif %}` |
117+
118+
---
119+
120+
## Key Files for Common Tasks
121+
122+
| Task | File |
123+
|---|---|
124+
| Grid rendering / section logic | `src/layouts/grid.ts` |
125+
| Template evaluation | `src/template.ts` |
126+
| Grid area parsing | `src/grid-utils.ts` |
127+
| YAML serializer/parser | `src/yaml.ts` |
128+
| Shared types | `src/types.ts` |
129+
| View type dropdown | `src/patches/hui-view-editor.ts` |
130+
| view_layout preservation | `src/patches/hui-card-element-editor.ts` |
131+
132+
---
133+
134+
## Compatibility with layout-card
135+
136+
- Only `sections-grid-layout` is registered -- masonry/horizontal/vertical are untouched
137+
- Patch guard is `_sectionsGridLayoutPatched` (distinct from layout-card's guard)
138+
- Both can be loaded simultaneously without conflict
139+
140+
---
141+
142+
## Constraints
143+
144+
- **Never edit `sections-grid-layout.js` directly** -- overwritten on build
145+
- **HA 2024.2+ only** -- `hui-section` did not exist before that release
146+
147+
---
148+
149+
## Known Gaps
150+
151+
- `background_blur` is NOT handled in layout-level `mediaquery` overrides (only works at base level)

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024-2026 Stormsys
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)