Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Various issues #150

Merged
merged 34 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
24c5b15
testing with overflow
ildar170975 Feb 18, 2025
a72ce18
Update build.yml
ildar170975 Feb 18, 2025
d4728d4
uses classes instead of "has" selectors
ildar170975 Feb 18, 2025
d2e5fc3
fix for "--restriction-invalid-lock-color" variable
ildar170975 Feb 18, 2025
ab3af60
prettier
ildar170975 Feb 18, 2025
6ec9051
lint
ildar170975 Feb 18, 2025
44267df
lint
ildar170975 Feb 18, 2025
6b2a2f6
outline -> border (prevent issues for iOS)
ildar170975 Feb 18, 2025
7c855a0
background opacity transition
ildar170975 Feb 18, 2025
c73ef43
transition border-color
ildar170975 Feb 18, 2025
797aec0
border-color transition
ildar170975 Feb 18, 2025
65e0dad
border-color transition
ildar170975 Feb 18, 2025
6c54497
toggle could be accessed
ildar170975 Feb 18, 2025
d72dcdf
toggle can be accessible
ildar170975 Feb 19, 2025
2812f57
prettier
ildar170975 Feb 19, 2025
124f669
prettier
ildar170975 Feb 19, 2025
ff5f6ab
fixes for subContainer
ildar170975 Feb 19, 2025
8180947
Update restriction-card.ts
ildar170975 Feb 19, 2025
9dbab64
Update restriction-card.ts
ildar170975 Feb 19, 2025
c02b8f5
Update restriction-card.ts
ildar170975 Feb 19, 2025
bef0358
block fix
ildar170975 Feb 19, 2025
41ca012
Update restriction-card.ts
ildar170975 Feb 19, 2025
0326d94
Update restriction-card.ts
ildar170975 Feb 19, 2025
dacdd56
Update restriction-card.ts
ildar170975 Feb 19, 2025
859a221
Update restriction-card.ts
ildar170975 Feb 19, 2025
6948c4e
Update restriction-card.ts
ildar170975 Feb 19, 2025
03eb534
Update restriction-card.ts
ildar170975 Feb 19, 2025
07fc7a3
shouldUpdate() fix
ildar170975 Feb 20, 2025
3f59b57
Update restriction-card.ts
ildar170975 Feb 20, 2025
584029c
lint
ildar170975 Feb 20, 2025
a2598b9
Update restriction-card.ts
ildar170975 Feb 20, 2025
2830dc1
--restriction-lock-margin-top added
ildar170975 Feb 20, 2025
a1d38d5
Update restriction-card.ts
ildar170975 Feb 20, 2025
4fab121
Update restriction-card.ts
ildar170975 Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Cache Dependencies
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Can be specified by color name, hexadecimal, rgb, rgba, hsl, hsla, basically any
| `restriction-regular-lock-color` | `primary-text-color` | Lock color |
| `restriction-success-lock-color` | `primary-color` | Lock color when unlocked |
| `restriction-blocked-lock-color` | `error-state-color` | Lock color when card is blocked |
| `restriction-invalid--color` | `error-state-color` | Lock color after an invalid attempt to unlock |
| `restriction-invalid-lock-color` | `error-state-color` | Lock color after an invalid attempt to unlock |
| `restriction-lock-margin-left` | `0px` | Manually bump the left margin of the lock icon (right for RTL) |
| `restriction-lock-row-margin-left` | `24px` | Manually bump the left margin of the lock icon in a row (right for RTL) |
| `restriction-lock-row-margin-top` | `0px` | Manually bump the top margin of the lock icon in a row |
Expand Down
193 changes: 112 additions & 81 deletions src/restriction-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,28 @@ class RestrictionCard extends LitElement implements LovelaceCard {
return true;
}

if (this._hass && this._config && this._config.condition && this._config.condition.entity) {
return oldHass.states[this._config.condition.entity] !== this._hass.states[this._config.condition.entity];
let entity;
if (!this._hass || !this._config) {
return false;
} else if (this._config.condition && this._config.condition.entity) {
entity = this._config.condition.entity;
return oldHass.states[entity] !== this._hass.states[entity];
} else if (!this._config.restrictions) {
return false;
} else if (
this._config.restrictions.block &&
this._config.restrictions.block.condition &&
this._config.restrictions.block.condition.entity
) {
entity = this._config.restrictions.block.condition.entity;
return oldHass.states[entity] !== this._hass.states[entity];
} else if (
this._config.restrictions.hide &&
this._config.restrictions.hide.condition &&
this._config.restrictions.hide.condition.entity
) {
entity = this._config.restrictions.hide.condition.entity;
return oldHass.states[entity] !== this._hass.states[entity];
} else {
return false;
}
Expand All @@ -93,8 +113,9 @@ class RestrictionCard extends LitElement implements LovelaceCard {
return html``;
}

const isBlocked = this._config.restrictions ? this._matchRestriction(this._config.restrictions.block) : false;
return html`
<div>
<div id="mainContainer">
${(this._config.exemptions &&
this._config.exemptions.some(e => (this._hass && this._hass.user ? e.user === this._hass.user.id : false))) ||
(this._config.condition &&
Expand All @@ -108,17 +129,27 @@ class RestrictionCard extends LitElement implements LovelaceCard {
hasDoubleClick: this._config.action === 'double_tap',
})}
id="overlay"
class="${classMap({
blocked: this._config.restrictions ? this._matchRestriction(this._config.restrictions.block) : false,
})}"
class=${classMap({
locked: !Boolean(this._unlocked) && !Boolean(isBlocked),
blocked: Boolean(isBlocked),
'has-row': Boolean(this._config.row),
'fill-available': true,
})}
>
<ha-icon
icon="${this._unlocked ? this._config.unlocked_icon! : this._config.locked_icon!}"
id="lock"
class="${classMap({
row: Boolean(this._config.row),
})}"
></ha-icon>
<div id="subContainer" class=${classMap({ 'fill-available': true })}>
<ha-icon
icon=${Boolean(this._unlocked)
? this._config.unlocked_icon
? this._config.unlocked_icon
: this._config.locked_icon
: this._config.locked_icon}
id="lock"
class=${classMap({
'icon-blocked': Boolean(isBlocked),
'icon-in-row': Boolean(this._config.row),
})}
></ha-icon>
</div>
</div>
`}
${this.renderCard(this._config.card)}
Expand All @@ -145,7 +176,7 @@ class RestrictionCard extends LitElement implements LovelaceCard {
element.hass = this._hass;

return html`
<div id="card" class=${classMap({ 'card-row': this._config.row === true })}>
<div id="card" class=${classMap({ 'is-row': Boolean(this._config.row) })}>
${element}
</div>
`;
Expand Down Expand Up @@ -176,18 +207,19 @@ class RestrictionCard extends LitElement implements LovelaceCard {
}

const lock = this.shadowRoot.getElementById('lock') as LitElement;
const overlay = this.shadowRoot.getElementById('overlay') as LitElement;

if (this._config.restrictions) {
if (this._config.restrictions.block && this._matchRestriction(this._config.restrictions.block)) {
if (this._config.restrictions.block.text) {
alert(this._config.restrictions.block.text);
}

lock.classList.add('invalid');
lock.classList.add('icon-invalid');
overlay.classList.add('overlay-invalid');
window.setTimeout(() => {
if (lock) {
lock.classList.remove('invalid');
}
lock.classList.remove('icon-invalid');
overlay.classList.remove('overlay-invalid');
}, 3000);
return;
}
Expand Down Expand Up @@ -222,7 +254,8 @@ class RestrictionCard extends LitElement implements LovelaceCard {
}

if (conditionString || conditionArray) {
lock.classList.add('invalid');
lock.classList.add('icon-invalid');
overlay.classList.add('overlay-invalid');
this._delay = Boolean(this._config.restrictions.pin.retry_delay);
if (this._config.restrictions.pin.max_retries) {
this._retries++;
Expand All @@ -233,9 +266,8 @@ class RestrictionCard extends LitElement implements LovelaceCard {

window.setTimeout(
() => {
if (lock) {
lock.classList.remove('invalid');
}
lock.classList.remove('icon-invalid');
overlay.classList.remove('overlay-invalid');
this._retries = 0;
this._maxed = false;
this._delay = false;
Expand All @@ -249,8 +281,9 @@ class RestrictionCard extends LitElement implements LovelaceCard {
() => {
this._delay = false;

if (lock && !this._maxed) {
lock.classList.remove('invalid');
if (!this._maxed) {
lock.classList.remove('icon-invalid');
overlay.classList.remove('overlay-invalid');
}
},
this._config.restrictions.pin.retry_delay ? this._config.restrictions.pin.retry_delay * 1000 : 3000,
Expand All @@ -270,109 +303,107 @@ class RestrictionCard extends LitElement implements LovelaceCard {
}
}

const overlay = this.shadowRoot.getElementById('overlay') as LitElement;
this._unlocked = true;
overlay.style.setProperty('pointer-events', 'none');
if (this._config.unlocked_icon) {
this._unlocked = true;
} else {
lock.classList.add('hidden');
}
lock.classList.add('icon-hidden');
overlay.classList.add('unlocked');
overlay.classList.remove('locked');

window.setTimeout(() => {
this._unlocked = false;
overlay.style.setProperty('pointer-events', '');
if (this._config?.unlocked_icon) {
this._unlocked = false;
}
if (lock) {
lock.classList.remove('hidden');
}
lock.classList.remove('icon-hidden');
overlay.classList.remove('unlocked');
overlay.classList.add('locked');
}, this._config.duration * 1000);
}

static get styles(): CSSResult {
return css`
:host {
position: relative;
--regular-lock-color: var(--restriction-regular-lock-color, var(--primary-text-color, #212121));
--success-lock-color: var(--restriction-success-lock-color, var(--primary-color, #03a9f4));
--blocked-lock-color: var(--restriction-blocked-lock-color, var(--error-state-color, #db4437));
--invalid-lock-color: var(--restriction-invalid--color, var(--error-state-color, #db4437));
--lock-margin-left: var(--restriction-lock-margin-left, 0px);
--lock-row-margin-left: var(--restriction-lock-row-margin-left, 24px);
--lock-row-margin-top: var(--restriction-lock-row-margin-top, 0px);
--lock-icon-size: var(--restriction-lock-icon-size, var(--mdc-icon-size, 24px));
--lock-opacity: var(--restriction-lock-opacity, 0.5);
}
div:has(#card) {
#mainContainer {
height: 100%;
position: relative;
}
ha-icon {
--mdc-icon-size: var(--lock-icon-size);
}
#overlay {
padding: 8px 7px;
.fill-available {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#overlay {
z-index: 1;
color: var(--regular-lock-color);
background: var(--restriction-overlay-background, unset);
}
#overlay:has(.hidden) {
opacity: 0 !important;
transition: opacity 2s linear;
#subContainer {
padding: 8px 7px;
border-radius: var(--ha-card-border-radius, 12px);
background: var(--restriction-overlay-background, unset);
}
#overlay:not(:has(.hidden)):has(+ #card.card-row) {
outline: var(--restriction-overlay-row-outline, none);
border-radius: var(--restriction-overlay-row-border-radius, 0);
#overlay.has-row #subContainer {
border-radius: var(--restriction-overlay-row-border-radius, 0) !important;
border: var(--restriction-overlay-row-outline, none);
}
#overlay:not(:has(+ #card.card-row)) {
border-radius: var(--ha-card-border-radius, 12px);
#overlay.unlocked #subContainer {
border-color: transparent;
opacity: 0 !important;
transition: border-color 2s, opacity 2s linear;
}
#overlay.blocked {
background: var(--restriction-overlay-background-blocked, unset);
#overlay.blocked #subContainer {
background: var(--restriction-overlay-background-blocked, unset) !important;
}
#overlay.blocked:has(+ #card.card-row) {
outline: var(--restriction-overlay-row-outline-blocked, none);
#overlay.has-row.blocked #subContainer {
border: var(--restriction-overlay-row-outline-blocked, none);
border-radius: var(--restriction-overlay-row-border-radius, 0) !important;
}
#card {
height: 100%;
}
#overlay:not(:has(.hidden)) {
overflow: clip;
}
#overlay:not(:has(.hidden)) + #card.card-row {
overflow: clip;
#overlay:not(.unlocked) {
overflow: hidden;
}
.blocked {
color: var(--blocked-lock-color) !important;
#overlay:not(.unlocked) + #card.is-row {
overflow: hidden;
}
#lock {
margin-inline-start: var(--lock-margin-left);
opacity: var(--lock-opacity);
}
.row {
margin-inline-start: var(--lock-row-margin-left) !important;
margin-top: var(--lock-row-margin-top) !important;
margin-inline-start: var(--restriction-lock-margin-left, 0px);
margin-top: var(--restriction-lock-margin-top, 0px);
opacity: var(--restriction-lock-opacity, 0.5);
color: var(--restriction-regular-lock-color, var(--primary-text-color, #212121));
position: inherit;
}
.hidden {
visibility: hidden;
.icon-in-row {
margin-inline-start: var(--restriction-lock-row-margin-left, 24px) !important;
margin-top: var(--restriction-lock-row-margin-top, 0px) !important;
}
.icon-hidden {
opacity: 0 !important;
transition: visibility 0s 2s, opacity 2s linear;
color: var(--success-lock-color);
}
.icon-unlocked {
color: var(--restriction-success-lock-color, var(--primary-color, #03a9f4)) !important;
}
.icon-blocked {
color: var(--restriction-blocked-lock-color, var(--error-state-color, #db4437)) !important;
}
.icon-invalid {
animation: blinker 1s linear infinite;
color: var(--restriction-invalid-lock-color, var(--error-state-color, #db4437)) !important;
}
.overlay-invalid {
animation: blinker 1s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0;
}
}
.invalid {
animation: blinker 1s linear infinite;
color: var(--invalid-lock-color);
}
`;
}
}
Expand Down