MainUI: How to set custom UI components to default component colors? And how to find these defaults?

Since the default openHAB Main-UI components have trouble with combining a oh-stepper-item with actions or an accordion item(see also this topic), I’m trying my hand at building my own list / accordion item:

UI:


Code

uid: radiator_list_v2
tags:
  - list
  - radiator
props:
  parameters:
    - description: Widget Title
      label: Title
      name: title
      required: false
      type: TEXT
    - context: item
      description: Radiator Item Group
      label: Group
      name: prefix
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jul 7, 2021, 8:02:42 PM
component: f7-list-item
slots:
  content:
    - component: f7-row
      config:
        style:
          height: 32px
      slots:
        default:
          - component: oh-button
            config:
              class:
                - no-padding
                - display-flex
                - justify-content-flex-start
              style:
                overflow: hidden
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: thermometer
                    style:
                      width: 32px
                      color: '=(Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 18) ? "blue" : (Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 21) ? "green" : (Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 23) ? "orange" : "red"'
                - component: Label
                  config:
                    text: =props.title
          - component: oh-button
            config:
              class:
                - no-padding
                - display-flex
                - justify-content-flex-end
            slots:
              default:
                - component: oh-stepper
                  config:
                    item: =props.prefix + "_SetTemperature"
                    min: 15
                    max: 23
                    step: 0.5
                    autorepeat: true
                    autorepeatDynamic: true
                - component: oh-button
                  config:
                    iconF7: '=(items[props.prefix + "_ShowOptions"].state == "OFF") ? "chevron_down" : "chevron_up"'
                    action: toggle
                    actionItem: =props.prefix + "_ShowOptions"
                    actionCommand: ON
                    actionCommandAlt: OFF
                    style:
                      width: 40px

And while the arrangement is now more or less acceptable, I’m struggling with how to set colors, font weight, icon size and such to values similar to the MainUI default component values. And where / how to find said defaults…
Of course the best option would be to set said values in a way that they would change with the selected theme (dark / light) similar to the default components…

Reading up on some other posts in the forum it seems like I would need to set CSS style variables?

@ysc you were able to offer some help with that in other post - would you know to what I have to do to have my custom widget look similar to an oh-list-item?

Ok, it seems like one way to find the right CSS variables is to inspect the website* (following examples are for Chrome):

If a certain variable should not work, for example var(--f7-list-item-title-text-color), then just take the one higher up in the hierarchie (in this example try var(--f7-text-color)).

So for the label of my custom widget I can use:

  - component: Label
    config:
      text: =props.title
      style:
        color: var(--f7-text-color)
        font-size: var(--f7-list-font-size)
        font-weight: var(--f7-list-index-label-font-weight)

to achieve

That seems to fit.

Does anyone have tips how to correct the icon size? That still eludes me… :thinking:


*) Thx @ @AndyMB for this comment: OH3 Standard height and shadow - #4 by AndyMB

No idea why - but font-size: 32px does scale the icon to the correct size, while align-self: flex-start takes care of vertical alignment :thinking:

Full code:

uid: radiator_list_v2
tags:
  - list
  - radiator
props:
  parameters:
    - context: item
      description: Radiator Item Group
      label: Group
      name: prefix
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jul 14, 2021, 8:03:37 PM
component: f7-list-item
config:
  style:
    height: 42px
slots:
  content:
    - component: f7-row
      config:
        class:
          - no-padding
        style:
          height: 42px
          align-self: flex-start
      slots:
        default:
          - component: oh-button
            config:
              class:
                - no-padding
                - display-flex
              style:
                overflow: hidden
                align-self: flex-start
                height: 42px
                padding-left: 0
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: thermometer
                    style:
                      font-size: 32px
                      align-self: flex-start
                      color: '=(Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 18) ? "blue" : (Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 21) ? "green" : (Number.parseFloat(items[props.prefix + "_SetTemperature"].state) < 23) ? "orange" : "red"'
                - component: Label
                  config:
                    text: Zieltemperatur
                    style:
                      align-self: flex-start
                      padding-left: 5px
                      color: var(--f7-text-color)
                      font-size: var(--f7-list-font-size)
                      font-weight: var(--f7-list-index-label-font-weight)
          - component: oh-button
            config:
              class:
                - no-padding
                - display-flex
                - justify-content-flex-end
            slots:
              default:
                - component: oh-stepper
                  config:
                    item: =props.prefix + "_SetTemperature"
                    min: 15
                    max: 23
                    step: 0.5
                    autorepeat: true
                    autorepeatDynamic: true
                - component: oh-button
                  config:
                    iconF7: '=(items[props.prefix + "_ShowOptions"].state == "OFF") ? "chevron_down" : "chevron_up"'
                    action: toggle
                    actionItem: =props.prefix + "_ShowOptions"
                    actionCommand: ON
                    actionCommandAlt: OFF
                    style:
                      width: 40px

UI:

Would think it’s now acceptable, only difference that I still notice is, that the default oh-list-item aligns the label / title higher than centred :thinking:

And when the button next to the stepper is clicked (the down chevron), additional information / controls will become visible:

Code:

uid: radiator_list_accordion
tags:
  - list
  - radiator
props:
  parameters:
    - description: Widget Title
      label: Title
      name: title
      required: false
      type: TEXT
    - context: item
      description: Radiator Item Group
      label: Group
      name: prefix
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jul 14, 2021, 7:04:08 PM
component: f7-list-item
config:
  mediaList: true
  visible: '=(items[props.prefix + "_ShowOptions"].state == "ON") ? true : false'
slots:
  default:
    - component: oh-list-item
      config:
        title: Aktuelle Temperatur
        icon: f7:thermometer
        iconColor: '=(Number.parseFloat(items[props.prefix + "_ActualTemperature"].state) < 18) ? "blue" : (Number.parseFloat(items[props.prefix + "_ActualTemperature"].state) < 21) ? "green" : (Number.parseFloat(items[props.prefix + "_ActualTemperature"].state) < 23) ? "orange" : "red"'
        after: =items[props.prefix + "_ActualTemperature"].state
        action: analyzer
        actionAnalyzerCoordSystem: time
        actionAnalyzerItems: =items[props.prefix + "_ActualTemperature"]
    - component: oh-list-item
      config:
        title: Boostmode
        icon: f7:flame
        iconColor: '=(Number.parseFloat(items[props.prefix + "_BoostState"].state) > 0) ? "orange" : "blue"'
        action: command
        actionItem: =props.prefix + "_BoostMode"
        actionCommand: ON
        badge: '=(Number.parseFloat(items[props.prefix + "_BoostState"].state) > 0) ? "Verlängern" : "Starten"'
        badgeColor: '=(Number.parseFloat(items[props.prefix + "_BoostState"].state) > 0) ? "red" : "green"'
        noChevron: true
    - component: oh-list-item
      config:
        title: Restdauer Boostmode
        icon: f7:clock
        after: =items[props.prefix + "_BoostState"].state
        visible: =(Number.parseFloat(items[props.prefix + "_BoostState"].state) > 0)
    - component: oh-list-item
      config:
        title: Signalstärke
        icon: f7:chart_bar
        iconColor: '=(items[props.prefix + "_SignalStrength"].state == "kein Signal") ? "red": "orange"'
        after: =items[props.prefix + "_SignalStrength"].displayState
        visible: =(Number.parseFloat(items[props.prefix + "_SignalStrength"].state) < 3)
    - component: oh-list-item
      config:
        title: Batterie schwach
        icon: f7:battery_25
        iconColor: red
        visible: =(items[props.prefix + "_LowBattery"].state == "ON")
    - component: f7-list-item
      config:
        divider: true
    - component: oh-stepper-item
      config:
        title: Zieltemperatur bei Abwesenheit
        subtitle: global - gilt für alle Räume
        icon: f7:thermometer
        iconColor: '=(Number.parseFloat(items.HeatingAbsence_SetTemperature.state) < 18.5) ? "green" : "red"'
        item: HeatingAbsence_SetTemperature
        min: 15
        max: 23
        step: 0.5
        autorepeat: true
        autorepeatDynamic: true
    - component: oh-stepper-item
      config:
        title: Zieltemperatur Nachts
        subtitle: global - gilt für alle Räume
        icon: f7:thermometer
        iconColor: '=(Number.parseFloat(items.HeatingNight_SetTemperature.state) < 18.5) ? "green" : "red"'
        item: HeatingNight_SetTemperature
        min: 15
        max: 23
        step: 0.5
        autorepeat: true
        autorepeatDynamic: true

UI:

1 Like