Skip to content

Commit

Permalink
HA 2024.8 support + fixes and more
Browse files Browse the repository at this point in the history
- [x] Fixed the large layout when used on a section view after the Home Assistant 2024.8 update.
- [x] Pop-ups are now A LOT smoother on every devices/browsers!
- [x] Fixed and optimized the displayed states/attributes system 
- [x] The `entity` variable (for templates) was not defined, this is now fixed! It refer to the card entity.
- [x] It was impossible to hide the name or the icon in a pop-up header, this is now fixed! #638
  • Loading branch information
Clooos authored Aug 9, 2024
1 parent 4ce3bcb commit 88e6314
Show file tree
Hide file tree
Showing 19 changed files with 141 additions and 129 deletions.
6 changes: 3 additions & 3 deletions dist/bubble-card.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/cards/button/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon, context.subButtonIcon, getWeatherIcon, context.card)
: '';
} catch (error) {
Expand Down
8 changes: 4 additions & 4 deletions src/cards/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,14 @@ export default `
}
.large .bubble-button-card-container {
height: 64px;
height: 56px;
border-radius: 32px;
}
.large .bubble-icon-container {
--mdc-icon-size: 28px;
min-width: 48px !important;
min-height: 48px !important;
--mdc-icon-size: 24px;
min-width: 42px !important;
min-height: 42px !important;
margin-left: 8px;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cards/cover/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon.icon, context.subButtonIcon, getWeatherIcon, context.card)
: '';
} catch (error) {
Expand Down
10 changes: 5 additions & 5 deletions src/cards/cover/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default `
}
.large .bubble-cover-card-container {
height: 64px;
height: 56px;
display: flex;
background: var(--background-color-2, var(--secondary-background-color));
border-radius: 32px;
Expand All @@ -100,17 +100,17 @@ export default `
}
.large .bubble-header-container {
height: 64px;
height: 56px;
}
.large .bubble-header {
width: 100%;
}
.large .bubble-icon-container {
--mdc-icon-size: 28px;
min-width: 48px !important;
min-height: 48px !important;
--mdc-icon-size: 24px;
min-width: 42px !important;
min-height: 42px !important;
margin-left: 2px;
align-content: center;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cards/horizontal-buttons-stack/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.card)
: '';
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion src/cards/media-player/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon, context.subButtonIcon, getWeatherIcon, context.card)
: '';
} catch (error) {
Expand Down
22 changes: 11 additions & 11 deletions src/cards/media-player/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,36 +254,36 @@ export default `
}
.large .bubble-media-player-container {
height: 64px;
border-radius: 34px;
height: 56px;
border-radius: 32px;
}
.large .bubble-icon-container {
--mdc-icon-size: 28px;
min-width: 48px !important;
min-height: 48px !important;
--mdc-icon-size: 24px;
min-width: 42px !important;
min-height: 42px !important;
margin-left: 8px;
}
.large .bubble-play-pause-button {
display: flex;
height: 48px;
width: 48px;
height: 42px;
width: 42px;
padding: 0;
align-items: center;
justify-content: center;
}
.large .bubble-volume-slider {
height: 48px !important;
height: 42px;
border-radius: 24px;
left: 66px !important;
width: calc(100% - 190px) !important;
left: 60px;
width: calc(100% - 174px);
}
.large .bubble-range-value {
place-items: center;
height: 48px;
height: 42px;
}
.large .bubble-button-container {
Expand Down
2 changes: 1 addition & 1 deletion src/cards/pop-up/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon, context.subButtonIcon, getWeatherIcon, context.popUp)
: '';
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions src/cards/pop-up/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export function createStructure(context) {
contextOnUrlChange();
}, 0);

window.addEventListener('click', contextOnUrlChange);
window.addEventListener('location-changed', contextOnUrlChange);
window.addEventListener('popstate', contextOnUrlChange);
window.addEventListener('keydown', (event) => {
Expand Down
85 changes: 48 additions & 37 deletions src/cards/pop-up/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,106 +30,116 @@ export function addHash(hash) {
history.pushState(null, "", newURL);
window.dispatchEvent(new Event('location-changed'));
}

export function closePopup(context) {
if (context.popUp.classList.contains('is-popup-opened') === false) {
return;
}

if (context.popUp.classList.contains('is-popup-closed')) return;

popupCount--;
document.body.style.overflow = '';
context.hideContentTimeout = setTimeout(function() {

// Clear any existing timeouts
clearTimeout(context.hideContentTimeout);
clearTimeout(context.removeDomTimeout);
clearTimeout(context.closeTimeout);

// Hide content after delay
context.hideContentTimeout = setTimeout(() => {
context.popUp.style.display = 'none';

if (context.sectionRow?.tagName.toLowerCase() === 'hui-card') {
context.sectionRow.toggleAttribute("hidden", true);
context.sectionRow.hidden = true;
context.sectionRow.style.display = "none";

if (context.sectionRowContainer?.classList.contains('card')) {
context.sectionRowContainer.style.display = "none";
}
}
}, 380);
context.resetCloseTimeout = () => {
clearTimeout(context.closeTimeout);
}

context.popUp.removeEventListener('touchstart', context.resetCloseTimeout);

if (context.config.close_by_clicking_outside ?? true) {
window.removeEventListener('click', clickOutside);
}

const closeOnClick = context.config.close_on_click ?? false;
if (closeOnClick) {
context.popUp.removeEventListener('mouseup', removeHash);
context.popUp.removeEventListener('touchend', removeHash);
if (context.config.close_on_click ?? false) {
context.popUp.removeEventListener('mouseup', removeHash);
context.popUp.removeEventListener('touchend', removeHash);
}

context.removeDomTimeout = window.setTimeout(() => {
// Remove popup from DOM after delay
context.removeDomTimeout = setTimeout(() => {
if (context.popUp.parentNode === context.verticalStack) {
context.verticalStack.removeChild(context.popUp);
}
}, 360);

context.popUp.classList.add('is-popup-closed');
context.popUp.classList.remove('is-popup-opened');
context.popUp.classList.replace('is-popup-opened', 'is-popup-closed');

// Execute close action if defined
if (context.config.close_action) {
callAction(context, context.config, 'close_action')
callAction(context, context.config, 'close_action');
}
}
export function openPopup(context) {
if (context.popUp.classList.contains('is-popup-opened')) {
return;
}

context.popUp.classList.add('is-popup-opened');

export function openPopup(context) {
if (context.popUp.classList.contains('is-popup-opened')) return;

if (context.sectionRow?.tagName.toLowerCase() === 'hui-card') {
context.sectionRow.toggleAttribute("hidden", false);
context.sectionRow.hidden = false;
context.sectionRow.style.display = "";

if (context.sectionRowContainer?.classList.contains('card')) {
context.sectionRowContainer.style.display = "";
}
}

window.clearTimeout(context.removeDomTimeout);
clearTimeout(context.removeDomTimeout);

// Ensure popup is appended before doing anything else
if (context.popUp.parentNode !== context.verticalStack) {
context.verticalStack.appendChild(context.popUp);
}

// Force a reflow to ensure the popup is fully appended and recognized by the DOM
void context.popUp.offsetWidth;

popupCount++;
clearTimeout(context.closeTimeout);
clearTimeout(context.hideContentTimeout);
document.body.style.overflow = 'hidden';
context.popUp.style.display = '';
context.popUp.style.transform = '';

// Add event listeners
context.popUp.addEventListener('touchstart', context.resetCloseTimeout, { passive: true });

const closeOnClick = context.config.close_on_click ?? false;
if (closeOnClick) {
context.popUp.addEventListener('mouseup', removeHash, { passive: true });
context.popUp.addEventListener('touchend', removeHash, { passive: true });
if (context.config.close_on_click ?? false) {
context.popUp.addEventListener('mouseup', removeHash, { passive: true });
context.popUp.addEventListener('touchend', removeHash, { passive: true });
}

// Ensure display is set before the transition
context.popUp.style.display = '';

// Apply the transition in the next frame
requestAnimationFrame(() => {
context.popUp.classList.remove('is-popup-closed');
context.popUp.classList.replace('is-popup-closed', 'is-popup-opened');
context.popUp.style.transform = '';

if (context.config.close_by_clicking_outside ?? true) {
window.addEventListener('click', clickOutside, { passive: true });
}
});

// Auto-close if configured
if (context.config.auto_close > 0) {
context.closeTimeout = setTimeout(removeHash, context.config.auto_close);
}

// Execute open action if defined
if (context.config.open_action) {
callAction(context.popUp, context.config, 'open_action')
callAction(context.popUp, context.config, 'open_action');
}
}

export function onUrlChange(context) {
const { hideBackdrop, showBackdrop } = getBackdrop(context);

return function() {
if (context.config.hash === location.hash) {
openPopup(context);
Expand All @@ -144,6 +154,7 @@ export function onUrlChange(context) {
}
}
}

export function onEditorChange(context) {
const { hideBackdrop, showBackdrop } = getBackdrop(context);
const detectedEditor = context.verticalStack.host?.closest('hui-card-preview') || context.verticalStack.host?.closest('hui-card[preview][class]') || context.verticalStack.host?.getRootNode().host?.closest('hui-section[preview][class]');
Expand Down
3 changes: 3 additions & 0 deletions src/cards/pop-up/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export async function handlePopUp(context) {
prepareStructure(context);
changeStyle(context);
createHeader(context);
if (context.config.entity || context.config.name) {
handleButton(context, context.elements.buttonContainer, context.elements.header);
}
createStructure(context);
}

Expand Down
22 changes: 8 additions & 14 deletions src/cards/pop-up/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export default `
padding: 0 !important;
}
.bubble-pop-up {
transition: all .36s;
transition: transform 0.3s ease;
will-change: transform;
position: fixed;
width: 100%;
max-width: 100%;
Expand All @@ -45,13 +46,6 @@ export default `
.bubble-pop-up-container::-webkit-scrollbar {
display: none; /* for Chrome, Safari, and Opera */
}
// .bubble-pop-up > :first-child {
// position: sticky;
// top: 0;
// z-index: 1;
// background: none !important;
// overflow: visible;
// }
.is-popup-opened {
box-shadow: 0px 0px 50px rgba(0, 0, 0, var(--custom-shadow-opacity));
backdrop-filter: var(--custom-popup-filter);
Expand Down Expand Up @@ -148,7 +142,7 @@ export default `
}
.large .bubble-button-card-container {
height: 64px;
height: 56px;
border-radius: 32px;
}
Expand All @@ -157,15 +151,15 @@ export default `
}
.large .bubble-icon-container {
--mdc-icon-size: 28px;
min-width: 48px !important;
min-height: 48px !important;
--mdc-icon-size: 24px;
min-width: 42px !important;
min-height: 42px !important;
margin-left: 8px;
}
.large .bubble-close-button {
height: 64px;
width: 64px;
height: 56px;
width: 56px;
border: none;
border-radius: 50%;
z-index: 1;
Expand Down
2 changes: 1 addition & 1 deletion src/cards/select/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon, context.subButtonIcon, getWeatherIcon, context.card)
: '';
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion src/cards/separator/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function changeStyle(context) {

try {
customStyle = context.config.styles
? Function('hass', 'entityId', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
? Function('hass', 'entity', 'state', 'icon', 'subButtonIcon', 'getWeatherIcon', 'card', `return \`${context.config.styles}\`;`)
(context._hass, context.config.entity, state, context.elements.icon, context.subButtonIcon, getWeatherIcon, context.card)
: '';
} catch (error) {
Expand Down
Loading

0 comments on commit 88e6314

Please sign in to comment.