# Bubble Modules # # How to use: # # - To edit or add modules (global styles and templates), first copy the # "bubble-modules.yaml" file from "/www/community/Bubble-Card/" (if installed via HACS) # to "/www/bubble/" (you'll need to create this folder). # # Then add these lines in your "configuration.yaml" under "homeassistant:": # # homeassistant: # allowlist_external_dirs: # - /config/www/bubble # # This step is not needed if you already have this line: # - /config/www # # Then save and restart Home Assistant. # # - After making changes, you need to refresh your page to apply the modifications. # # - Styles and templates defined under "default:" are applied globally to all cards by default. # # - See the final example in this file for further details on how to create a module. # # - You can share/find modules here: # github.com/Clooos/Bubble-Card/discussions/categories/share-your-modules default: name: Default description: Empty and enabled by default. Move your styles/templates here in the bubble-modules.yaml file to apply them to all cards. code: | /* CSS or JS templates (see examples below) */ home-assistant-default: name: Home Assistant default styling version: "v1.1" creator: "Clooos" link: "https://github.com/Clooos/Bubble-Card/discussions/1230" description: This module applies Home Assistant’s default styling to Bubble Card. To set it as the default, move it under default: in the bubble-modules.yaml file. code: | :host { --bubble-button-accent-color: rgba(0,140,255,0.3); /* Edit this color if needed */ --bubble-main-background-color: var(--ha-card-background, var(--card-background-color, #fff)); --bubble-border-radius: var(--ha-card-border-radius, 12px); --bubble-icon-border-radius: 32px; --bubble-button-border-radius: var(--bubble-border-radius); --bubble-climate-button-background-color: var(--bubble-icon-background-color); --bubble-border: var(--ha-card-border-width, 1px) solid var(--ha-card-border-color, var(--divider-color, #e0e0e0)); --bubble-secondary-background-color: transparent; } .bubble-container { -webkit-backdrop-filter: var(--ha-card-backdrop-filter, none); backdrop-filter: var(--ha-card-backdrop-filter, none); box-shadow: var(--ha-card-box-shadow, none); box-sizing: border-box; } .bubble-icon-container, .large .bubble-icon-container { --mdc-icon-size: 22px; min-width: 36px !important; min-height: 36px !important; } .large .bubble-cover-card-container > .bubble-buttons { --bubble-cover-main-background-color: none; } .bubble-range-fill { --bubble-accent-color: var(--bubble-button-accent-color); } .bubble-sub-button.background-on::before, .bubble-sub-button.background-off::before, .bubble-temperature-container::before, .bubble-icon-container::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: var(--control-number-buttons-background-opacity, .2); border-radius: var(--bubble-border-radius); background: var(--control-number-buttons-background-color, var(--disabled-color)); } .is-on { --bubble-icon-background-color: var(--view-background,var(--lovelace-background,var(--primary-background-color))); transition: all ease-in 0.3s !important; } .bubble-icon-container::before { background: var(--state-inactive-color); border-radius: var(--bubble-icon-border-radius); } .bubble-sub-button { border: 0px solid transparent !important; } .no-icon-select-arrow { right: 4px !important; } .large .bubble-icon-container { margin-left: 9px; } .bubble-state { opacity: 1; font-weight: 400; font-size: 12px; letter-spacing: .4px; } :not(.bubble-separator) > .bubble-name { font-weight: 500; font-size: 14px; letter-spacing: 0.1px; } .bubble-pop-up-background { filter: brightness(0.96); /* Improve pop-up background contrast */ --bubble-pop-up-border-radius: calc(var(--ha-card-border-radius, 12px) * 1.4); } .bubble-header-container { --bubble-secondary-background-color: var(--background-color-2); } ha-select { --bubble-list-item-accent-color: none !important; --mdc-theme-surface: var(--card-background-color); } mwc-list-item[selected] { color: inherit !important; --mdc-ripple-press-opacity: 0 !important; } mwc-list-item[selected]::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--primary-color); opacity: 0.24; } icon_container_color: name: "Example: Customize the icon container color" version: "v1.1" creator: "Clooos" link: "https://github.com/Clooos/Bubble-Card/discussions/1231" unsupported: - horizontal-buttons-stack - separator description: | A list of predefined colors to customize the icon container color. Configure this module via the editor or in YAML, for example:

        icon_container_color: 
            color: light-blue
        
code: | .bubble-icon-container { opacity: 1 !important; background: var(--${this.config.icon_container_color?.color}-color) !important; } editor: - name: color label: "Color" selector: ui_color: include_none: true get_state_attribute: # Some informations about your module (this is shown in the editor) name: "Advanced example: Get state/attribute from other entities" version: "v1.1" creator: "Clooos" link: "https://github.com/Clooos/Bubble-Card" # Disable this module for unsupported "card_type" unsupported: - horizontal-buttons-stack - separator # The description have HTML support like in this example. This model is my favorite. description: | Get state/attribute from other entities and replace the default state/attribute field. Configure this module via the editor or in YAML, for example:

        get_state_attribute:
            - entity: weather.home
            - entity: sensor.weather_station
              attribute: humidity
            - entity: sensor.weather_station
              attribute: temperature
        

If it doesn't work, make sure at least one of "Show state" or "Show attribute" is turned on in your card configuration. # Code blocks must always start with ${(() => { and end with })()} # Inline codes must always start with ${ and end with } # # This section only supports JavaScript and/or CSS code: | ${(() => { // Retrieve the configuration or use an empty array by default const config = this.config.get_state_attribute || []; // Format the retrieved value from the entity for each entry const values = config .map(cfg => { const entity = hass.states[cfg.entity]; if (entity) { return cfg.attribute ? hass.formatEntityAttributeValue(entity, cfg.attribute) : hass.formatEntityState(entity); } return null; }) .filter(value => value !== null); // Remove null values // Update the DOM element with the class 'bubble-state' // displaying values separated by ' • ' card.querySelector('.bubble-state').innerText = values.join(' • '); })()} # The editor part can be tricky, but improves modules a lot! # # In this example, it will create your configuration to this variable: # this.config.get_state_attribute # # To understand what you can do here, take a look at the "ha-form" sources here: # https://github.com/home-assistant/frontend/tree/03a415beff6e6f9c87a95287804f6c03c8fef3d5/src/components/ha-form # # And here for the selectors: # https://github.com/home-assistant/frontend/blob/03a415beff6e6f9c87a95287804f6c03c8fef3d5/src/data/selector.ts # # I will try to document that for clarity! editor: - type: expandable title: "Select entities and attributes" icon: "mdi:list-box-outline" schema: - name: '0' type: expandable title: "Entity 1" schema: - name: entity label: "Entity" selector: entity: {} - name: attribute label: "Attribute" selector: attribute: {} - name: '1' type: expandable title: "Entity 2" schema: - name: entity label: "Entity" selector: entity: {} - name: attribute label: "Attribute" selector: attribute: {} - name: '2' type: expandable title: "Entity 3" schema: - name: entity label: "Entity" selector: entity: {} - name: attribute label: "Attribute" selector: attribute: {} - name: '3' type: expandable title: "Entity 4" schema: - name: entity label: "Entity" selector: entity: {} - name: attribute label: "Attribute" selector: attribute: {}