├── .commit-template
├── .github
├── FUNDING.yml
└── workflows
│ ├── validate.yml
│ └── release.yml
├── hacs.json
├── commitlint.config.js
├── .all-contributorsrc
├── LICENSE
├── package.json
├── .gitignore
├── info.md
├── CODE_OF_CONDUCT.md
├── README.md
└── kb-frosted-cards.js
/.commit-template:
--------------------------------------------------------------------------------
1 | type(scope): subject
2 |
3 | description
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom:
2 | - https://paypal.me/thatkookooguy?locale.x=en_US
3 |
--------------------------------------------------------------------------------
/hacs.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kibibit Frosted Cards",
3 | "render_readme": true,
4 | "filename": "kb-frosted-cards.js"
5 | }
--------------------------------------------------------------------------------
/.github/workflows/validate.yml:
--------------------------------------------------------------------------------
1 | name: Validate
2 |
3 | on:
4 | push:
5 | pull_request:
6 | schedule:
7 | - cron: "0 0 * * *"
8 |
9 | jobs:
10 | validate:
11 | runs-on: "ubuntu-latest"
12 | steps:
13 | - uses: "actions/checkout@v2"
14 | - name: HACS validation
15 | uses: "hacs/integration/action@main"
16 | with:
17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 | CATEGORY: "plugin"
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [ '@commitlint/config-angular' ],
3 | rules: {
4 | 'type-enum': [
5 | 2,
6 | 'always', [
7 | 'build',
8 | 'chore',
9 | 'ci',
10 | 'docs',
11 | 'feat',
12 | 'fix',
13 | 'perf',
14 | 'refactor',
15 | 'revert',
16 | 'style',
17 | 'test'
18 | ]
19 | ]
20 | }
21 | };
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - master
6 | - next
7 | jobs:
8 | release:
9 | name: Release
10 | runs-on: ubuntu-18.04
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v2
14 | with:
15 | fetch-depth: 0
16 | - name: Setup Node.js
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: 12
20 | - name: Install dependencies
21 | run: npm ci
22 | - name: Release
23 | env:
24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
26 | run: npx semantic-release
--------------------------------------------------------------------------------
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "kb-frosted-cards",
3 | "projectOwner": "kibibit",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "badgeTemplate": "
-orange.svg?style=flat-square\" alt=\"All Contributors\">",
10 | "imageSize": 100,
11 | "commit": true,
12 | "commitConvention": "angular",
13 | "contributors": [
14 | {
15 | "login": "Thatkookooguy",
16 | "name": "Neil Kalman",
17 | "avatar_url": "https://avatars3.githubusercontent.com/u/10427304?v=4",
18 | "profile": "http://thatkookooguy.kibibit.io/",
19 | "contributions": [
20 | "code",
21 | "doc",
22 | "design",
23 | "infra",
24 | "maintenance"
25 | ]
26 | }
27 | ],
28 | "contributorsPerLine": 7
29 | }
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 neilkalman@gmail.com
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.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@kibibit/kb-frosted-cards",
3 | "version": "0.0.0-development",
4 | "description": "Make Cards and Popups blur everything behind them.",
5 | "homepage": "https://github.com/Kibibit/kb-frosted-cards#readme",
6 | "files": [
7 | "hacs.json",
8 | "kb-frosted-cards.js"
9 | ],
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/Kibibit/kb-frosted-cards.git"
13 | },
14 | "author": "thatkookooguy ",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/Kibibit/kb-frosted-cards/issues"
18 | },
19 | "devDependencies": {
20 | "@commitlint/cli": "^11.0.0",
21 | "@commitlint/config-angular": "^11.0.0",
22 | "@commitlint/config-conventional": "^11.0.0",
23 | "all-contributors-cli": "^6.19.0",
24 | "commitizen": "^4.2.2",
25 | "cross-env": "^7.0.2",
26 | "cz-conventional-changelog": "^3.3.0",
27 | "husky": "^4.3.0",
28 | "semantic-release": "^17.2.2",
29 | "semantic-release-cli": "^5.4.0"
30 | },
31 | "scripts": {
32 | "commit": "cz",
33 | "contributors:add": "cross-env HUSKY_SKIP_HOOKS=1 all-contributors add",
34 | "contributors:generate": "cross-env HUSKY_SKIP_HOOKS=1 all-contributors generate",
35 | "semantic-release": "semantic-release",
36 | "semantic-release:init": "semantic-release-cli setup"
37 | },
38 | "keywords": [
39 | "home-assistant",
40 | "hass",
41 | "automation",
42 | "hassio",
43 | "homeassistant",
44 | "theme"
45 | ],
46 | "config": {
47 | "commitizen": {
48 | "path": "./node_modules/cz-conventional-changelog"
49 | }
50 | },
51 | "husky": {
52 | "hooks": {
53 | "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
54 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
55 | }
56 | },
57 | "publishConfig": {
58 | "access": "public"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # kibibit
2 | test-results
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 |
12 | # Diagnostic reports (https://nodejs.org/api/report.html)
13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
14 |
15 | # Runtime data
16 | pids
17 | *.pid
18 | *.seed
19 | *.pid.lock
20 |
21 | # Directory for instrumented libs generated by jscoverage/JSCover
22 | lib-cov
23 |
24 | # Coverage directory used by tools like istanbul
25 | coverage
26 | *.lcov
27 |
28 | # nyc test coverage
29 | .nyc_output
30 |
31 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
32 | .grunt
33 |
34 | # Bower dependency directory (https://bower.io/)
35 | bower_components
36 |
37 | # node-waf configuration
38 | .lock-wscript
39 |
40 | # Compiled binary addons (https://nodejs.org/api/addons.html)
41 | build/Release
42 |
43 | # Dependency directories
44 | node_modules/
45 | jspm_packages/
46 |
47 | # Snowpack dependency directory (https://snowpack.dev/)
48 | web_modules/
49 |
50 | # TypeScript cache
51 | *.tsbuildinfo
52 |
53 | # Optional npm cache directory
54 | .npm
55 |
56 | # Optional eslint cache
57 | .eslintcache
58 |
59 | # Microbundle cache
60 | .rpt2_cache/
61 | .rts2_cache_cjs/
62 | .rts2_cache_es/
63 | .rts2_cache_umd/
64 |
65 | # Optional REPL history
66 | .node_repl_history
67 |
68 | # Output of 'npm pack'
69 | *.tgz
70 |
71 | # Yarn Integrity file
72 | .yarn-integrity
73 |
74 | # dotenv environment variables file
75 | .env
76 | .env.test
77 |
78 | # parcel-bundler cache (https://parceljs.org/)
79 | .cache
80 | .parcel-cache
81 |
82 | # Next.js build output
83 | .next
84 | out
85 |
86 | # Nuxt.js build / generate output
87 | .nuxt
88 | dist
89 |
90 | # Gatsby files
91 | .cache/
92 | # Comment in the public line in if your project uses Gatsby and not Next.js
93 | # https://nextjs.org/blog/next-9-1#public-directory-support
94 | # public
95 |
96 | # vuepress build output
97 | .vuepress/dist
98 |
99 | # Serverless directories
100 | .serverless/
101 |
102 | # FuseBox cache
103 | .fusebox/
104 |
105 | # DynamoDB Local files
106 | .dynamodb/
107 |
108 | # TernJS port file
109 | .tern-port
110 |
111 | # Stores VSCode versions used for testing VSCode extensions
112 | .vscode-test
113 |
114 | # yarn v2
115 | .yarn/cache
116 | .yarn/unplugged
117 | .yarn/build-state.yml
118 | .yarn/install-state.gz
119 | .pnp.*
--------------------------------------------------------------------------------
/info.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @kibibit/hass-kibibit-theme
6 |
7 |
8 |
9 |
10 |
11 |
12 | A milky glass theme for Home Assistant
13 |
14 |
15 |
16 | This is based on [Henrik](https://www.reddit.com/user/Trollet_/)'s [reddit post](https://www.reddit.com/r/homeassistant/comments/c4s28m/my_current_lovelace_ui_constructive_feedback_is/) with a few additions of mine
17 |
18 | ## Screenshots
19 | 
20 | 
21 |
22 | [more screenshots](https://imgur.com/a/b7HaXx3#ExNC57m)
23 |
24 | ## Installation
25 |
26 | ### Prerequisites
27 |
28 | Add the following code to your `configuration.yaml` file (reboot required).
29 |
30 | ```yaml
31 | frontend:
32 | ... # your configuration.
33 | themes: !include_dir_merge_named themes
34 | ... # your configuration.
35 | ```
36 |
37 | ### Add the font
38 | Right now, this theme requires you to add the `Comfortaa` font as a resource to your lovelace configuration:
39 | ```yaml
40 | resources:
41 | - url: https://fonts.googleapis.com/css?family=Comfortaa&display=swap
42 | type: css
43 | ```
44 |
45 | ### HACS
46 |
47 | 1. Go to the Community Store.
48 | 2. Search for `kibibit`.
49 | 3. Navigate to `kibibit` theme.
50 | 4. Press `Install`.
51 | 6. Go to services and trigger the `frontend.reload_themes` service.
52 |
53 | ### Change the background
54 |
55 | This theme comes with a background by default, but you can change it to whatever you like.
56 |
57 | You can use either a url or a local file.
58 |
59 | 1. Find a background you like (You can fetch the original one from [HERE](https://thatkookooguy.github.io/https-assets/bg-kibibit-theme.png))
60 | 2. If it's a local image, put the background image inside `/config/www` to make it a public asset accessible from the frontend (`/config/www/bg-kibibit-theme.png`).
61 |
62 | access the theme file `kibibit.yaml` and change the following line:
63 |
64 | ```yaml
65 | background-image: "center / cover no-repeat fixed url('https://thatkookooguy.github.io/https-assets/bg-kibibit-theme.png')"
66 | ```
67 |
68 | to include your url, or a local asset by mapping `/config/www/` to `/local/` (`/local/bg-kibibit-theme.png`)
69 |
70 | Refresh home assistant after that.
71 |
72 | ### Setting the default `backend-selected` theme
73 | In order to have this theme set automatically as the backend selected default, add the following automation to your home assistant:
74 | ```yaml
75 | - alias: Set Default Theme
76 | description: ''
77 | trigger:
78 | - event: start
79 | platform: homeassistant
80 | condition: []
81 | action:
82 | - data:
83 | name: kibibit
84 | service: frontend.set_theme
85 | ```
86 |
87 | ## Stay in touch
88 |
89 | - Author - [Neil Kalman](https://github.com/thatkookooguy)
90 | - Website - [https://github.com/kibibit](https://github.com/kibibit)
91 | - StackOverflow - [thatkookooguy](https://stackoverflow.com/users/1788884/thatkookooguy)
92 | - Twitter - [@thatkookooguy](https://twitter.com/thatkookooguy)
93 | - Twitter - [@kibibit_opensrc](https://twitter.com/kibibit_opensrc)
94 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at neilkalman@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @kibibit/kb-frosted-cards
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Make HA Cards and Popups blur everything behind them.
19 |
20 |
21 |
22 |
23 | Created for the Home Assistant [kibibit Theme](https://github.com/kibibit/hass-kibibit-theme)
24 | > It have transparent card background colors, support multiple backgrounds, and custom local backgrounds
25 |
26 |
27 |
28 | ## Installation
29 | ### HACS
30 |
31 | 1. Go to the Community Store.
32 | 2. Select `Frontend`.
33 | 3. Click on the `+` button
34 | 4. Search for `kibibit Frosted Cards`.
35 | 5. Click on it.
36 | 6. Press `Install this Repository in HACs`.
37 | 7. When prompted, reload the frontend
38 |
39 | ### Manual Installation
40 |
41 | 1. Create a folder named `kb-frosted-cards` in your `config/www` folder.
42 | 2. Copy the file `kb-frosted-cards.js` into that folder.
43 | 3. In HA GUI, go to `Configuration` => `Lovelace Dashboards` => `Resources`, and click the `+` button to add a resource.
44 | 4. A popup will open. In the url field, fill in `/local/kb-frosted-cards/kb-frosted-cards.js`, and select `JavaScript Module` in the dropdown.
45 | 5. Refresh the Home Assistant Frontend.
46 |
47 | ## How does it look?
48 | 
49 | 
50 |
51 |
52 | ## Contributors ✨
53 |
54 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
55 |
56 |
57 |
58 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
70 | ## Stay in touch
71 |
72 | - Author - [Neil Kalman](https://github.com/thatkookooguy)
73 | - Website - [https://github.com/kibibit](https://github.com/kibibit)
74 | - StackOverflow - [thatkookooguy](https://stackoverflow.com/users/1788884/thatkookooguy)
75 | - Twitter - [@thatkookooguy](https://twitter.com/thatkookooguy)
76 | - Twitter - [@kibibit_opensrc](https://twitter.com/kibibit_opensrc)
77 |
--------------------------------------------------------------------------------
/kb-frosted-cards.js:
--------------------------------------------------------------------------------
1 | (() => {
2 | let waitedFor = 0;
3 | const cardMods = new Map();
4 | cardMods.set("ha-card", ":host { backdrop-filter: blur(5px) }");
5 | cardMods.set(
6 | "ha-dialog",
7 | ".mdc-dialog__surface { backdrop-filter: blur(5px); }"
8 | );
9 | // cardMods.set('mwc-menu-surface', '.mdc-menu-surface { top: initial !important; left: initial !important; bottom: 0; right: 0 }');
10 |
11 | const injectPromises = Array.from(cardMods).map(([cardName, cssRule]) =>
12 | addCssToCard(cardName, cssRule, cardName === "ha-card")
13 | );
14 |
15 | // waitUntilDefined('ha-button-menu')
16 | // .then(() => {
17 | // customElements.get('ha-button-menu').render = function render() {
18 | // console.log('called MY rendering function!');
19 | // console.log('is THIS correct??');
20 | // console.log(this.corner);
21 | // return `
22 | //
23 | //
24 | //
25 | //
31 | //
32 | //
33 | // `;
34 | // }.bind(customElements.get('ha-button-menu'))
35 | // });
36 |
37 | Promise.resolve()
38 | .then(() => Promise.all(injectPromises))
39 | .then(() => {
40 | // Force lovelace to redraw everything
41 | const ev = new Event("ll-rebuild", {
42 | bubbles: true,
43 | cancelable: false,
44 | composed: true,
45 | });
46 |
47 | let root = document.querySelector("home-assistant");
48 | root = root && root.shadowRoot;
49 | root = root && root.querySelector("home-assistant-main");
50 | root = root && root.shadowRoot;
51 | root =
52 | root && root.querySelector("app-drawer-layout partial-panel-resolver");
53 | root = (root && root.shadowRoot) || root;
54 | root = root && root.querySelector("ha-panel-lovelace");
55 | root = root && root.shadowRoot;
56 | root = root && root.querySelector("hui-root");
57 | root = root && root.shadowRoot;
58 | root = root && root.querySelector("ha-app-layout #view");
59 | root = root && root.firstElementChild;
60 | if (root) root.dispatchEvent(ev);
61 | });
62 |
63 | function waitP(timeout) {
64 | return new Promise((resolve) => {
65 | setTimeout(() => resolve(), timeout || 3000);
66 | });
67 | }
68 |
69 | function addCssToCard(cardName, cssRule, enforceOld) {
70 | return Promise.resolve()
71 | .then(() => waitUntilDefined(cardName, undefined, enforceOld))
72 | .then((cardClass) => insertStyleRule(cardClass, cssRule))
73 | .catch((err) => console.error(err));
74 | }
75 |
76 | function insertStyleRule(card, rule) {
77 | const newWay = Array.isArray(card.getStyles())
78 | ? card.getStyles()[0].styleSheet
79 | : card.getStyles().styleSheet;
80 |
81 | const oldWay =
82 | card._styles && card._styles[0] && card._styles[0].styleSheet;
83 |
84 | newWay.insertRule(rule);
85 | if (oldWay && oldWay.insertRule) {
86 | oldWay.insertRule(rule, 0);
87 | }
88 | }
89 |
90 | function waitUntilDefined(elementName, timeout, enforceOld) {
91 | timeout = timeout || 10000;
92 | return Promise.resolve()
93 | .then(() => customElements.get(elementName))
94 | .then((customElement) => {
95 | const isOldStyleDefined =
96 | customElement && customElement._styles && customElement._styles[0];
97 | const isNewStyleDefined = Array.isArray(customElement.getStyles())
98 | ? customElement.getStyles()[0].styleSheet
99 | : customElement.getStyles().styleSheet;
100 |
101 | if (
102 | customElement &&
103 | (enforceOld
104 | ? isOldStyleDefined
105 | : isOldStyleDefined || isNewStyleDefined)
106 | ) {
107 | waitedFor = 0;
108 | return customElement;
109 | }
110 |
111 | if (waitedFor >= timeout) {
112 | // throw new Error(elementName + " was not defined before timeout");
113 | console.info('waited for a long time. going into hibernate mode (checking every 10 seconds)');
114 | }
115 |
116 | let waitMilli = waitedFor >= timeout ? 10000 : 2000;
117 | waitedFor += waitMilli;
118 | return waitP(waitMilli).then(() => waitUntilDefined(elementName, timeout, enforceOld));
119 | });
120 | }
121 | })();
122 |
--------------------------------------------------------------------------------