Skip to content

Instantly share code, notes, and snippets.

@Mariusthvdb
Last active May 1, 2023 07:57
Show Gist options
  • Save Mariusthvdb/11bbf8403da01f05ec4913cde76604fc to your computer and use it in GitHub Desktop.
Save Mariusthvdb/11bbf8403da01f05ec4913cde76604fc to your computer and use it in GitHub Desktop.
experimental rebuild of text-input-row to use Lit in stead of Polymer
const Name = "Text-input-full-row";
const Version = "2023.5.01";
const Description = "adapted to use local Lit";
const Url = "https://github.com/Mariusthvdb/text-input-full-row";
console.info(
`%c ${Name} \n%c Version ${Version} ${Description}`,
"color: gold; font-weight: bold; background: black",
"color: white; font-weight: bold; background: steelblue"
);
// as Type: module still using paper
// import { LitElement, html, css } from 'https://unpkg.com/lit-element@2.0.1/lit-element.js?module';
const LitElement = customElements.get("ha-panel-lovelace") ? Object.getPrototypeOf(customElements.get("ha-panel-lovelace")) : Object.getPrototypeOf(customElements.get("hc-lovelace"));
const html = LitElement.prototype.html;
const css = LitElement.prototype.css;
class TextInputFullRow extends LitElement {
static get properties() {
return {
label: { type: String },
value: { type: String },
minlength: { type: Number },
maxlength: { type: Number },
pattern: { type: String },
mode: { type: String },
stateObj: { type: Object },
_config: { type: Object },
};
}
constructor() {
super();
this.label = '';
this.value = '';
this.minlength = 0;
this.maxlength = Infinity;
this.pattern = '';
this.mode = '';
this.stateObj = null;
this._config = null;
}
render() {
const { label, value, minlength, maxlength, pattern, mode } = this;
return html`
<paper-input
label=${label}
value=${value}
minlength=${minlength}
maxlength=${maxlength}
autoValidate=${pattern}
pattern=${pattern}
type=${mode}
@change=${this.valueChanged}
id="textinput"
placeholder=""
></paper-input>
`;
}
firstUpdated() {
super.firstUpdated();
this.shadowRoot.getElementById('textinput').addEventListener('click', (ev) => ev.stopPropagation());
}
setConfig(config) {
this._config = config;
}
propertyObserver(prop, newVal, oldVal) {
if (prop === 'value' && newVal !== oldVal) {
this.shadowRoot.getElementById('textinput').value = newVal;
}
}
valueChanged(ev) {
// console.log('valueChanged called');
const newValue = this.shadowRoot.getElementById('textinput').value;
// console.log('newValue', newValue);
const param = {
entity_id: this._config.entity,
value: newValue,
};
this._hass.callService('input_text', 'set_value', param);
}
computeObjectId(entityId) {
return entityId.substr(entityId.indexOf('.') + 1);
}
computeStateName(stateObj) {
return stateObj.attributes.friendly_name === undefined
? this.computeObjectId(stateObj.entity_id).replace(/_/g, ' ')
: stateObj.attributes.friendly_name || '';
}
set hass(hass) {
this._hass = hass;
this.stateObj = hass.states[this._config.entity];
if (this.stateObj) {
this.value = this.stateObj.state;
this.minlength = this.stateObj.attributes.min;
this.maxlength = this.stateObj.attributes.max;
this.pattern = this.stateObj.attributes.pattern;
this.mode = this.minlength = this.stateObj.attributes.mode;
this.label = this._config.name ? this._config.name : this.computeStateName(this.stateObj);
}
}
}
customElements.define('text-input-full-row', TextInputFullRow);
// as type: js
// class TextInputFullRow extends HTMLElement {
// constructor() {
// super();
// this.attachShadow({ mode: 'open' });
// const style = document.createElement('style');
// style.textContent = `
// :host {
// display: block;
// }
// `;
// const input = document.createElement('paper-input');
// input.setAttribute('id', 'textinput');
// input.setAttribute('placeholder', '');
// input.addEventListener('change', this.valueChanged.bind(this));
// this.shadowRoot.appendChild(style);
// this.shadowRoot.appendChild(input);
// }
//
// setConfig(config) {
// this.config = config;
// this.entity = config.entity;
// this.name = config.name;
// }
//
// valueChanged(ev) {
// const newValue = ev.target.value;
// const param = {
// entity_id: this.entity,
// value: newValue,
// };
// this.hass.callService('input_text', 'set_value', param);
// }
//
// computeObjectId(entityId) {
// return entityId.substr(entityId.indexOf(".") + 1);
// }
//
// computeStateName(stateObj){
// return stateObj.attributes.friendly_name === undefined
// ? this.computeObjectId(stateObj.entity_id).replace(/_/g, " ")
// : stateObj.attributes.friendly_name || "";
// }
//
// set hass(hass) {
// this._hass = hass;
// const entityId = this.config.entity;
// const state = hass.states[entityId];
// const value = state ? state.state : '';
// const min = state && state.attributes.min ? state.attributes.min : 0;
// const max = state && state.attributes.max ? state.attributes.max : Infinity;
// const pattern = state && state.attributes.pattern ? state.attributes.pattern : '';
// const mode = state && state.attributes.mode ? state.attributes.mode : 'text';
// const name = this.config.name ? this.config.name : this.computeStateName(state);
// const input = this.shadowRoot.querySelector('paper-input');
// input.setAttribute('label', name);
// input.setAttribute('value', value);
// input.setAttribute('minlength', min);
// input.setAttribute('maxlength', max);
// input.setAttribute('auto-validate', pattern);
// input.setAttribute('pattern', pattern);
// input.setAttribute('type', mode);
// this.entity = entityId;
// this.name = name;
// }
// }
//
// customElements.define('text-input-full-row', TextInputFullRow);
@Mariusthvdb
Copy link
Author

Mariusthvdb commented Apr 30, 2023

note this is purely experimental and a built upon the original https://github.com/gadgetchnnel/lovelace-text-input-row/ by @gadgetchnnel

since that repo hasn't been touched in 4 years, I hoped to make an effort and keep this alive.

commented code in the resource was the original, improved version still in type: js format. Ive changed that to type: module in the current code above it.

Scherm­afbeelding 2023-04-30 om 14 21 19

This is how to show it in the Frontend, above the new resource I made here, below the core entity input_text albeit with a card_mod:

      - type: custom:text-input-full-row
        entity: input_text.message
      - entity: input_text.message
        <<: &no_icon
          card_mod:
            style:
              hui-generic-entity-row $: |
                state-badge {
                  display: none;
                }
              .: |
                hui-generic-entity-row {
                  margin: 0px -16px;
                }
#                 :host {
#                   --text-field-padding: 8px;
#                 }

@Mariusthvdb
Copy link
Author

Mariusthvdb commented Apr 30, 2023

fixed the red, appearing on entering text, because of auto-validating.

empty:

Scherm­afbeelding 2023-04-30 om 15 25 13

and with some text:

Scherm­afbeelding 2023-04-30 om 15 25 36

nice for now

wishlist:

  • better styling (font seems bigger than other core text fields
  • not use paper but mdc-text?

@Mariusthvdb
Copy link
Author

Mariusthvdb commented May 1, 2023

edited to use Local Lit import, a la Weather Card by frontend dev Bram Kragten

added Observer to check for changed input via other cards/elements...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment