Skip to content

Commit 29cdb63

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 29cdb63

40 files changed

Lines changed: 8442 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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
}

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