0

I'm building a custom web component with LitElement and would like to give it a color attribute. I've got the color working but its hardcoded. I want the color to change based on user preference. for example, <fhir-create-patient background="red"></fhir-create-patient> should change the background of the element to red.

    class FhirCreatePatient extends LitElement {
    static get properties() {
        return {
            /**url is used to make AJAX call to FHIR resource. Default: null */
            url: String,
            background:String
        }
    }

    constructor() {
        super();
        this.background=""
    }
    _didRender(){
        this.shadowRoot.getElementById("background").style.color = "blue"

    }


    _render({url}) {
        return html`
        <style>
        :host{
            font:sans-serif;
            display: block;
            border: 1px solid green;
            margin: 2px;
            padding:5px;
        }
        #patientRelation{
            display:block;
            border: 1px solid;
            margin:5px;
        }
        #patientMarriage{
            display:block;
            border:1px solid;
            padding:5px;
            margin:3px;
        }
        #patientGender{
            display:block;
            border:1px solid;
            padding:5px;
            margin:3px;  
        }
        #patientContact{
            display:block;
            border:1px solid;
            padding:5px;
            margin:3px; 
        }
        #patientAddress{
            display:block;
            border:1px solid;
            padding:5px;
            margin:3px; 
        }

        </style>
       <div id="background"> 
       <fhir-human-name id="patientName"></fhir-human-name>
       <fhir-active-status id="patientActive"></fhir-active-status>
       <fhir-decease-status id="patientDecease"></fhir-decease-status>
       <fhir-birth-date id="patientBirthday"></fhir-birth-date>
       <fhir-human-gender id="patientGender"></fhir-human-gender>
       <fhir-marital-status id="patientMarriage"></fhir-marital-status>
       <fhir-human-contact id="patientContact"></fhir-human-contact>
       <fhir-human-address id="patientAddress"></fhir-human-address>
       <fhir-human-language id="patientLanguage"></fhir-human-language>
       <fhir-human-relation id="patientRelation"></fhir-human-relation>
       <mwc-button id="button" raised on-click=${() => this.doPost()}>Submit</mwc-button>
       <iron-ajax bubbles method ="POST" id="ajax" url="${url}" on-response="handleResponse"></iron-ajax>
       <div>
    `;
    }

    doPost() {
        var pname = this.shadowRoot.getElementById('patientName').value;
        var pstatus = this.shadowRoot.getElementById('patientActive').value;
        var pdecease = this.shadowRoot.getElementById('patientDecease').value;
        var pbirth = this.shadowRoot.getElementById('patientBirthday').value;
        var pgender = this.shadowRoot.getElementById('patientGender').value;
        var pmarriage = this.shadowRoot.getElementById('patientMarriage').value;
        var pcontact = this.shadowRoot.getElementById('patientContact').value;
        var paddress = this.shadowRoot.getElementById('patientAddress').value;
        var planguage = this.shadowRoot.getElementById('patientLanguage').value;
        var prelation = this.shadowRoot.getElementById('patientRelation').value;
        this.shadowRoot.getElementById('ajax').contentType = 'application/json';
        this.shadowRoot.getElementById('ajax').body = {
            "resourceType": "Patient",
            "name": pname,
            "active": pstatus,
            "deceased": pdecease,
            "birthDate": pbirth,
            "gender": pgender,
            "maritalStatus": pmarriage,
            "telecom": pcontact,
            "address": paddress,
            "contact": prelation,
            "communication": planguage
        };
        this.shadowRoot.getElementById('ajax').generateRequest();
    }    


  }

window.customElements.define('fhir-create-patient', FhirCreatePatient);

Thanks

  • Shouldn't ``_didrender`` be ``updated`` ??? ``style.color`` is the textcolor, I presume ``this.shadowRoot.style.backgroundColor = "blue"`` will set the background – Danny '365CSI' Engelman Feb 04 '20 at 09:22
  • I still use polymer 3 so I use _didRender. my question is how do I use the make the color or background color or any other design an attribute that can be changed by the user. – Bolu Oluwalade Feb 04 '20 at 18:13

1 Answers1

1

In your case, the easiest solution is to use a css variable in your style for your background and set it whenever the background property is set like this (note that the function names might be different as it seems you're using a prerelease version instead of the latest one)

<custom-background></custom-background>
<custom-background background="seagreen"></custom-background>
<custom-background background="purple"></custom-background>

<script type="module">
import {
  html,
  css,
  LitElement
} from 'https://cdn.pika.dev/lit-element@^2.2.1';

export default class CustomBackground extends LitElement {
  static get properties() {
    return {
      background: { type: String }
    };
  }

  constructor() {
    super();
    this.background = "";
  }

  set background(value) {
    this.style.setProperty("--background", value);
  }

  get background() {
    this.style.getPropertyValue("--background");
  }

  static get styles() {
    // the name of the css variable should be more descriptive
    return css`
      .container {
        background: var(--background);
        line-height: 2;
      }
    `;
  }

  render() {
    return html`
      <div class="container">
        Some random content with background color: "${this.background}"
      </div>
    `;
  }
}

customElements.define("custom-background", CustomBackground);
</script>

Full working demo

Note that you could actually do away with the JS property as a whole and just let your users to set the css variable directly and it will properly style, in this case something like:

<custom-background style="--background: red;"></custom-background>

or just in the css like

custom-background.special {
  --background: blue;
}

Just an extra observation, as you can see in the demo, just changing the background might mess up with the contrast so you might also want to allow for the text color to be changed

Alan Dávalos
  • 2,568
  • 11
  • 19