Recipes

Battery

Battery percentage chip with low-battery red flip and a hover popover showing charge state + ETA.

Demonstrates if for conditional styling, dynamic SF Symbol via binding, and a multi-state hover popover.

yaml
id: battery
interval: 30
order: 50
location: tray
click:
    shell: "open 'x-apple.systempreferences:com.apple.preference.battery'"
command: |
    pmset -g batt | awk '
      /InternalBattery/ {
        match($0, /[0-9]+%/); pct = substr($0, RSTART, RLENGTH-1)
        charging = "false"; charged = "false"
        if ($0 ~ /; charging/)  charging = "true"
        if ($0 ~ /; charged/)   charged  = "true"
        match($0, /[0-9]+:[0-9]+/); rem = (RSTART > 0) ? substr($0, RSTART, RLENGTH) : ""
        bucket = (pct >= 87) ? "100" : (pct >= 62) ? "75" : (pct >= 37) ? "50" : (pct >= 12) ? "25" : "0"
        printf "{\"pct\":%s,\"charging\":%s,\"charged\":%s,\"remaining\":\"%s\",\"icon_bucket\":\"%s\"}\n",
               pct, charging, charged, rem, bucket
      }'
view:
    hstack:
      spacing: 3
      children:
        - if:
            when: "${charging} == true"
            then:
              symbol: { name: battery.100.bolt, size: 14, color: green }
            else:
              if:
                when: "${pct} < 20"
                then:
                  symbol: { name: battery.0, size: 14, color: "#FF3B30" }
                else:
                  symbol: { name: battery.${icon_bucket}, size: 14, color: primary }
        - text:
            content: "${pct}%"
            size: 10
            weight: medium
            design: rounded
            monospacedDigit: true
hover:
    vstack:
      spacing: 8
      alignment: leading
      frame: { width: 200 }
      children:
        - hstack:
            children:
              - text: { content: "Battery", size: 11, color: secondary, weight: medium }
              - spacer: {}
              - text: { content: "${pct}%", size: 18, weight: semibold, design: rounded, monospacedDigit: true }
        - gauge:
            value: "${pct}"
            min: 0
            max: 100
            tint: green
            width: 176
            height: 6
        - if:
            when: "${charged} == true"
            then:
              text: { content: "Fully charged", size: 11, color: secondary }
        - if:
            when: "${charging} == true"
            then:
              text: { content: "Charging — ${remaining} until full", size: 11, color: secondary }
        - if:
            when: "${charging} == false"
            then:
              if:
                when: "${remaining} != \"\""
                then:
                  text: { content: "${remaining} remaining", size: 11, color: secondary }

What this teaches

  • Nested if — three states (charging / low / normal) without compound && operators.
  • Symbol name bindingname: battery.${icon_bucket} interpolates into the symbol name itself.
  • Color literal vs binding — colors can be #hex, named (green, primary), or path-bound.
  • Charge-state messaging — three optional rows in the popover, each gated by an if so only the relevant one renders.

Building on this

  • Pair with the Disk recipe so power-savings users can see both at once.
  • Add a notify-send style alert when crossing the 20% threshold by spawning a osascript -e 'display notification ...' from the script.
  • Wire click.url to x-apple.systempreferences:com.apple.preference.energysaver for the related Settings pane.