g2-kit 99 samples · 57 components

Charts, controls and HUD pieces for Even Realities G2 Hub plugins, drawn on the phone into 4-bit image tiles. Previews are 2× and use the brightness curve measured in evenhub-simulator 0.9.5; real-glasses brightness is not yet verified. Unofficial; not affiliated with Even Realities.

Live demos run in your browser with a mock host: on-screen gesture buttons, or ↓ ↑ Enter D H

Quickstart →Bar chart + KPI above a native list: the README snippet.Dashboard →Four panels; swipe moves focus, tap opens one chart across all four tiles.Pickers →Carousel typing, a time picker with edit mode, a keyboard prompt.Keyboard →Every keyboard option: letters, symbols layer / beside / below, rows or columns, action keys.Text components →Spinner and progress as firmware text, and a slider per text box: no image sends.Tic-tac-toe →The game kit with one gesture axis.Calibration card →16 levels, theme levels, patterns and fonts, for tuning a device.

Charts

Bar chart
Bar chartBarChart · 288×144 · P0 · ink 32%
props
import { BarChart } from 'g2-kit/charts'

g2.draw('left', BarChart, {
  "title": "Steps / day",
  "data": [
    {
      "label": "M",
      "value": 6200
    },
    {
      "label": "T",
      "value": 8400
    },
    {
      "label": "W",
      "value": 4100
    },
    {
      "label": "T",
      "value": 9900
    },
    {
      "label": "F",
      "value": 7300
    },
    {
      "label": "S",
      "value": 12100
    },
    {
      "label": "S",
      "value": 3000
    }
  ],
  "highlight": 5,
  "peak": true,
  "format": "compact"
})
Bar chart: negatives
Bar chart: negativesBarChart · 288×144 · P0 · ink 15%
props
import { BarChart } from 'g2-kit/charts'

g2.draw('left', BarChart, {
  "title": "Net flow",
  "data": [
    3,
    -2,
    5,
    -4,
    1,
    6
  ],
  "categories": [
    "Q1",
    "Q2",
    "Q3",
    "Q4",
    "Q5",
    "Q6"
  ]
})
Bar chart: horizontal
Bar chart: horizontalBarChart · 288×144 · P0 · ink 20%
props
import { BarChart } from 'g2-kit/charts'

g2.draw('left', BarChart, {
  "title": "Languages",
  "orientation": "horizontal",
  "data": [
    {
      "label": "TypeScript",
      "value": 48
    },
    {
      "label": "Rust",
      "value": 21
    },
    {
      "label": "Go",
      "value": 14
    },
    {
      "label": "Python",
      "value": 9
    }
  ],
  "highlight": 0,
  "format": {
    "suffix": "%"
  }
})
Bar chart: 24 bars, sparse labels
Bar chart: 24 bars, sparse labelsBarChart · 288×144 · P0 · ink 16%
props
import { BarChart } from 'g2-kit/charts'

g2.draw('left', BarChart, {
  "title": "Load by hour",
  "data": [
    50,
    63,
    75,
    84,
    89,
    90,
    86,
    79,
    68,
    56,
    42,
    30,
    20,
    13,
    10,
    12,
    17,
    27,
    39,
    52,
    65,
    76,
    85,
    89
  ],
  "categories": [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "10",
    "11",
    "12",
    "13",
    "14",
    "15",
    "16",
    "17",
    "18",
    "19",
    "20",
    "21",
    "22",
    "23"
  ],
  "fill": "hatch",
  "highlight": 14
})
Line chart: 2 series
Line chart: 2 seriesLineChart · 288×144 · P0 · ink 11%
props
import { LineChart } from 'g2-kit/charts'

g2.draw('left', LineChart, {
  "title": "Revenue",
  "series": [
    {
      "name": "This year",
      "values": [
        12,
        15,
        14,
        18,
        22,
        19,
        25,
        28,
        26,
        31,
        29,
        34
      ]
    },
    {
      "name": "Last year",
      "values": [
        10,
        11,
        13,
        12,
        14,
        16,
        15,
        17,
        19,
        18,
        20,
        22
      ]
    }
  ],
  "xLabels": [
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec"
  ],
  "annotateMinMax": true,
  "area": "dots",
  "format": {
    "suffix": "k"
  }
})
Line chart: long series
Line chart: long seriesLineChart · 288×144 · P0 · ink 4%
props
import { LineChart } from 'g2-kit/charts'

g2.draw('left', LineChart, {
  "title": "Heart rate",
  "series": [
    70,
    74,
    78,
    81,
    85,
    88,
    90,
    85,
    86,
    87,
    87,
    86,
    85,
    84,
    75,
    73,
    71,
    69,
    67,
    66,
    65,
    57,
    57,
    57,
    58,
    60,
    62,
    64,
    61,
    64,
    68,
    72,
    76,
    80,
    83,
    80,
    83,
    85,
    88,
    89
  ],
  "xLabels": [
    "6am",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "now"
  ]
})
Line chart: 3 series + gaps
Line chart: 3 series + gapsLineChart · 288×144 · P0 · ink 6%
props
import { LineChart } from 'g2-kit/charts'

g2.draw('left', LineChart, {
  "series": [
    {
      "values": [
        5,
        7,
        6,
        9,
        8,
        11,
        10
      ]
    },
    {
      "values": [
        3,
        4,
        null,
        6,
        7,
        6,
        8
      ]
    },
    {
      "values": [
        1,
        2,
        2,
        3,
        5,
        4,
        6
      ]
    }
  ],
  "labels": "normal",
  "xLabels": [
    "M",
    "T",
    "W",
    "T",
    "F",
    "S",
    "S"
  ]
})
Sparkline
SparklineSparkline · 128×28 · P0 · ink 14%
props
import { Sparkline } from 'g2-kit/charts'

g2.draw('left', Sparkline, {
  "values": [
    12,
    15,
    14,
    18,
    22,
    19,
    25,
    28,
    26,
    31,
    29,
    34
  ],
  "band": [
    15,
    25
  ]
})
Sparkline: 16 px
Sparkline: 16 pxSparkline · 96×16 · P0 · ink 14%
props
import { Sparkline } from 'g2-kit/charts'

g2.draw('left', Sparkline, {
  "values": [
    10,
    11,
    13,
    12,
    14,
    16,
    15,
    17,
    19,
    18,
    20,
    22
  ],
  "extremes": true
})
KPI / big number
KPI / big numberKpi · 288×144 · P0 · ink 8%
props
import { Kpi } from 'g2-kit/charts'

g2.draw('left', Kpi, {
  "label": "Active users",
  "value": 12840,
  "format": "compact",
  "delta": 0.042,
  "deltaFormat": "percent",
  "footnote": "vs last week",
  "spark": [
    12,
    15,
    14,
    18,
    22,
    19,
    25,
    28,
    26,
    31,
    29,
    34
  ]
})
KPI: 7-segment
KPI: 7-segmentKpi · 144×144 · P0 · ink 7%
props
import { Kpi } from 'g2-kit/charts'

g2.draw('left', Kpi, {
  "label": "Temp",
  "value": "21.5",
  "unit": "°C",
  "delta": -1.2,
  "style": "segment"
})
KPI: bad delta
KPI: bad deltaKpi · 288×96 · P0 · ink 7%
props
import { Kpi } from 'g2-kit/charts'

g2.draw('left', Kpi, {
  "label": "Latency",
  "value": 182,
  "unit": "ms",
  "delta": 34,
  "good": "down",
  "align": "center"
})
Gauge: semicircle
Gauge: semicircleGauge · 288×144 · P0 · ink 16%
props
import { Gauge } from 'g2-kit/charts'

g2.draw('left', Gauge, {
  "value": 63,
  "label": "Battery",
  "unit": "%",
  "thresholds": [
    20,
    50
  ]
})
Gauge: 270° dial
Gauge: 270° dialGauge · 144×144 · P0 · ink 14%
props
import { Gauge } from 'g2-kit/charts'

g2.draw('left', Gauge, {
  "value": 72,
  "label": "CPU",
  "unit": "%",
  "thresholds": [
    80
  ]
})
Gauge: needle
Gauge: needleGauge · 144×144 · P0 · ink 16%
props
import { Gauge } from 'g2-kit/charts'

g2.draw('left', Gauge, {
  "value": 30,
  "style": "needle",
  "label": "Speed",
  "max": 50
})
Chart state: empty
Chart state: emptyBarChart · 288×144 · P0 · ink 1%
props
import { BarChart } from 'g2-kit/charts'

g2.draw('left', BarChart, {
  "title": "Sales",
  "data": [],
  "message": "No sales yet"
})
Chart state: error
Chart state: errorLineChart · 288×144 · P0 · ink 3%
props
import { LineChart } from 'g2-kit/charts'

g2.draw('left', LineChart, {
  "title": "Weather",
  "series": [],
  "state": "error",
  "message": "Offline: showing nothing"
})
Grouped bars
Grouped barsMultiBarChart · 288×144 · P1 · ink 36%
props
import { MultiBarChart } from 'g2-kit/charts'

g2.draw('left', MultiBarChart, {
  "title": "Sleep vs goal",
  "series": [
    {
      "name": "Sleep",
      "values": [
        6.5,
        7.2,
        5.9,
        8.1,
        7
      ]
    },
    {
      "name": "Goal",
      "values": [
        8,
        8,
        8,
        8,
        8
      ]
    }
  ],
  "categories": [
    "M",
    "T",
    "W",
    "T",
    "F"
  ],
  "valueLabels": false
})
Stacked bars
Stacked barsMultiBarChart · 288×144 · P1 · ink 31%
props
import { MultiBarChart } from 'g2-kit/charts'

g2.draw('left', MultiBarChart, {
  "title": "Time by app (h)",
  "mode": "stacked",
  "series": [
    {
      "name": "Work",
      "values": [
        5,
        6,
        4,
        7,
        5,
        1,
        0
      ]
    },
    {
      "name": "Chat",
      "values": [
        1,
        2,
        1,
        1,
        2,
        1,
        1
      ]
    },
    {
      "name": "Media",
      "values": [
        1,
        1,
        2,
        1,
        2,
        4,
        3
      ]
    }
  ],
  "categories": [
    "M",
    "T",
    "W",
    "T",
    "F",
    "S",
    "S"
  ]
})
Donut
DonutPieChart · 288×144 · P1 · ink 19%
props
import { PieChart } from 'g2-kit/charts'

g2.draw('left', PieChart, {
  "slices": [
    {
      "label": "Rent",
      "value": 1200
    },
    {
      "label": "Food",
      "value": 450
    },
    {
      "label": "Travel",
      "value": 220
    },
    {
      "label": "Other",
      "value": 330
    }
  ]
})
Pie: outside labels
Pie: outside labelsPieChart · 288×144 · P1 · ink 16%
props
import { PieChart } from 'g2-kit/charts'

g2.draw('left', PieChart, {
  "slices": [
    {
      "label": "Yes",
      "value": 62
    },
    {
      "label": "No",
      "value": 28
    },
    {
      "label": "?",
      "value": 10
    }
  ],
  "donut": 0,
  "labelMode": "outside"
})
Progress rings
Progress ringsProgressRings · 288×144 · P1 · ink 21%
props
import { ProgressRings } from 'g2-kit/charts'

g2.draw('left', ProgressRings, {
  "rings": [
    {
      "label": "Move",
      "value": 420,
      "max": 500
    },
    {
      "label": "Exercise",
      "value": 0.8
    },
    {
      "label": "Stand",
      "value": 0.5
    }
  ]
})
Heatmap 7×24
Heatmap 7×24Heatmap · 288×144 · P1 · ink 26%
props
import { Heatmap } from 'g2-kit/charts'

g2.draw('left', Heatmap, {
  "title": "Commits by hour",
  "values": [
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      9,
      7,
      6,
      4,
      2,
      1,
      0,
      0,
      0,
      1,
      2,
      4,
      5,
      7,
      8,
      9,
      10
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      4,
      2,
      1,
      0,
      0,
      0,
      1,
      2,
      4,
      5,
      7,
      8,
      9,
      10,
      10,
      9,
      8
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      2,
      4,
      5,
      7,
      8,
      9,
      10,
      10,
      9,
      8,
      7,
      5,
      4
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      2,
      4,
      5,
      7,
      8,
      9,
      10,
      10,
      9,
      8,
      7,
      5,
      4,
      2,
      1,
      0
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      5,
      7,
      8,
      9,
      10,
      10,
      9,
      8,
      7,
      5,
      4,
      2,
      1,
      0,
      0,
      0,
      1
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      3,
      3,
      3,
      3,
      3,
      2,
      2,
      1,
      1,
      0,
      0,
      0,
      0,
      0,
      1,
      1,
      2
    ],
    [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      3,
      3,
      2,
      2,
      1,
      1,
      0,
      0,
      0,
      0,
      0,
      1,
      1,
      2,
      2,
      3,
      3
    ]
  ],
  "rowLabels": [
    "M",
    "T",
    "W",
    "T",
    "F",
    "S",
    "S"
  ],
  "colLabels": [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "10",
    "11",
    "12",
    "13",
    "14",
    "15",
    "16",
    "17",
    "18",
    "19",
    "20",
    "21",
    "22",
    "23"
  ],
  "encoding": "both",
  "highlight": [
    2,
    15
  ]
})
Calendar heatmap
Calendar heatmapCalendarHeatmap · 288×144 · P1 · ink 21%
props
import { CalendarHeatmap } from 'g2-kit/charts'

g2.draw('left', CalendarHeatmap, {
  "title": "Workouts",
  "days": [
    0,
    0,
    2,
    0,
    0,
    1,
    0,
    0,
    5,
    0,
    1,
    0,
    0,
    5,
    0,
    0,
    4,
    0,
    0,
    3,
    0,
    4,
    0,
    0,
    3,
    0,
    0,
    2,
    0,
    0,
    1,
    0,
    2,
    0,
    0,
    1,
    0,
    0,
    5,
    0,
    0,
    4,
    0,
    5,
    0,
    0,
    4,
    0,
    0,
    3,
    0,
    0,
    2,
    0,
    3,
    0,
    0,
    2,
    0,
    0,
    1,
    0,
    0,
    5,
    0,
    1,
    0,
    0,
    5,
    0,
    0,
    4,
    0,
    0,
    3,
    0,
    4,
    0,
    0,
    3,
    0,
    0,
    2,
    0,
    0,
    1,
    0,
    2,
    0,
    0,
    1,
    0,
    0,
    5,
    0,
    0,
    4,
    0,
    5,
    0,
    0,
    4,
    0,
    0,
    3,
    0,
    0,
    2,
    0,
    3,
    0,
    0,
    2,
    0,
    0,
    1,
    0,
    0,
    5,
    0,
    1,
    0,
    0,
    5,
    0,
    0,
    4,
    0,
    0,
    3,
    0,
    4,
    0,
    0,
    3,
    0,
    0,
    2,
    0,
    0
  ],
  "end": "2026-09-29T00:00:00.000Z"
})
Funnel
FunnelFunnel · 288×144 · P1 · ink 16%
props
import { Funnel } from 'g2-kit/charts'

g2.draw('left', Funnel, {
  "stages": [
    {
      "label": "Visits",
      "value": 12000
    },
    {
      "label": "Sign-ups",
      "value": 3100
    },
    {
      "label": "Trials",
      "value": 1400
    },
    {
      "label": "Paid",
      "value": 420
    }
  ],
  "format": "compact"
})
Bullet chart
Bullet chartBulletChart · 288×36 · P1 · ink 21%
props
import { BulletChart } from 'g2-kit/charts'

g2.draw('left', BulletChart, {
  "label": "Revenue",
  "value": 270,
  "target": 250,
  "ranges": [
    150,
    225,
    300
  ],
  "format": {
    "suffix": "k"
  }
})
Event timeline
Event timelineTimeline · 288×96 · P1 · ink 10%
props
import { Timeline } from 'g2-kit/charts'

g2.draw('left', Timeline, {
  "start": 8,
  "end": 18,
  "now": 13.5,
  "events": [
    {
      "at": 9,
      "end": 10.5,
      "label": "Standup",
      "lane": 0
    },
    {
      "at": 11,
      "end": 12,
      "label": "Review",
      "lane": 1
    },
    {
      "at": 14,
      "end": 16,
      "label": "Focus",
      "lane": 0
    },
    {
      "at": 12.5,
      "label": "Lunch",
      "lane": 1,
      "marker": "dot"
    }
  ],
  "ticks": [
    [
      8,
      "8:00"
    ],
    [
      12,
      "12:00"
    ],
    [
      18,
      "18:00"
    ]
  ]
})
Waffle chart
Waffle chartWaffleChart · 288×144 · P2 · ink 26%
props
import { WaffleChart } from 'g2-kit/charts'

g2.draw('left', WaffleChart, {
  "parts": [
    {
      "label": "Done",
      "value": 62
    },
    {
      "label": "Doing",
      "value": 23
    },
    {
      "label": "Todo",
      "value": 15
    }
  ]
})
Scatter + trend
Scatter + trendScatterChart · 288×144 · P2 · ink 5%
props
import { ScatterChart } from 'g2-kit/charts'

g2.draw('left', ScatterChart, {
  "title": "Sleep vs steps",
  "series": [
    {
      "points": [
        [
          4,
          5.5
        ],
        [
          6,
          6.2
        ],
        [
          7,
          6.8
        ],
        [
          9,
          7.1
        ],
        [
          10,
          7.6
        ],
        [
          12,
          7.4
        ],
        [
          13,
          8.1
        ],
        [
          8,
          6.1
        ],
        [
          5,
          6.4
        ]
      ]
    },
    {
      "points": [
        [
          3,
          7.5
        ],
        [
          5,
          7.2
        ],
        [
          6,
          6.8
        ],
        [
          9,
          6
        ],
        [
          11,
          5.9
        ]
      ]
    }
  ],
  "trend": true,
  "xLabel": "k steps"
})
Histogram
HistogramHistogram · 288×144 · P2 · ink 26%
props
import { Histogram } from 'g2-kit/charts'

g2.draw('left', Histogram, {
  "title": "Commute (min)",
  "values": [
    22,
    25,
    31,
    28,
    24,
    35,
    41,
    27,
    26,
    29,
    33,
    30,
    23,
    38,
    45,
    27,
    29,
    31,
    26,
    28
  ],
  "mark": 33
})
Box plot
Box plotBoxPlot · 288×144 · P2 · ink 4%
props
import { BoxPlot } from 'g2-kit/charts'

g2.draw('left', BoxPlot, {
  "title": "Response (ms)",
  "boxes": [
    {
      "label": "API",
      "min": 120,
      "q1": 145,
      "median": 160,
      "q3": 195,
      "max": 260
    },
    {
      "label": "CDN",
      "min": 60,
      "q1": 71.25,
      "median": 77.5,
      "q3": 91.25,
      "max": 130
    },
    {
      "label": "DB",
      "min": 200,
      "q1": 270,
      "median": 320,
      "q3": 400,
      "max": 600
    }
  ]
})
Candlestick
CandlestickCandlestickChart · 288×144 · P2 · ink 4%
props
import { CandlestickChart } from 'g2-kit/charts'

g2.draw('left', CandlestickChart, {
  "title": "ACME",
  "candles": [
    {
      "open": 10,
      "high": 12,
      "low": 9,
      "close": 11.5,
      "label": "Mon"
    },
    {
      "open": 11.5,
      "high": 13,
      "low": 11,
      "close": 12.4
    },
    {
      "open": 12.4,
      "high": 12.8,
      "low": 10.5,
      "close": 10.9
    },
    {
      "open": 10.9,
      "high": 11.6,
      "low": 10.2,
      "close": 11.2
    },
    {
      "open": 11.2,
      "high": 14,
      "low": 11,
      "close": 13.6,
      "label": "Fri"
    }
  ]
})

Legends & encodings

Legend: series encodings
Legend: series encodingsLegend · 288×144 · P1 · ink 3%
props
import { Legend } from 'g2-kit/charts'

g2.draw('left', Legend, {
  "items": [
    {
      "label": "Solid / dot",
      "dash": "solid",
      "marker": "dot"
    },
    {
      "label": "Dashed / square",
      "dash": "dashed",
      "marker": "square"
    },
    {
      "label": "Dotted / triangle",
      "dash": "dotted",
      "marker": "triangle"
    },
    {
      "label": "Hatch fill",
      "paint": {
        "pattern": "hatch",
        "level": 15
      }
    },
    {
      "label": "Dots fill",
      "paint": {
        "pattern": "dots",
        "level": 15
      }
    },
    {
      "label": "Cross-hatch fill",
      "paint": {
        "pattern": "crossHatch",
        "level": 15
      }
    }
  ]
})
Legend: cell marks (key page)
Legend: cell marks (key page)Legend · 288×144 · P1 · ink 3%
props
import { Legend } from 'g2-kit/charts'

g2.draw('left', Legend, {
  "items": [
    {
      "label": "Right spot",
      "mark": "filled",
      "glyph": "A"
    },
    {
      "label": "Wrong spot",
      "mark": "ring",
      "glyph": "B"
    },
    {
      "label": "Not in word",
      "mark": "strike",
      "glyph": "C"
    }
  ],
  "large": true,
  "valign": "middle"
})

Input controls

Button: icon + label, focused
Button: icon + label, focusedButton · 120×36 · P0 · ink 20%
props
import { Button } from 'g2-kit/widgets'

g2.draw('left', Button, {
  "label": "Refresh",
  "icon": "refresh",
  "state": "focused"
})
Button row: states
Button row: statesButtonRow · 288×44 · P0 · ink 34%
props
import { ButtonRow } from 'g2-kit/widgets'

g2.draw('left', ButtonRow, {
  "buttons": [
    {
      "label": "Normal"
    },
    {
      "label": "Focus"
    },
    {
      "label": "Press"
    },
    {
      "label": "On",
      "active": true
    },
    {
      "label": "Off",
      "disabled": true
    }
  ],
  "focus": 1,
  "pressed": 2
})
Button row: icons + pill
Button row: icons + pillButtonRow · 288×44 · P0 · ink 10%
props
import { ButtonRow } from 'g2-kit/widgets'

g2.draw('left', ButtonRow, {
  "buttons": [
    {
      "icon": "play",
      "label": "Play"
    },
    {
      "icon": "pause"
    },
    {
      "icon": "refresh",
      "label": "Again"
    }
  ],
  "focus": 0,
  "variant": "pill"
})
Toggle: on, focused
Toggle: on, focusedToggle · 160×36 · P0 · ink 26%
props
import { Toggle } from 'g2-kit/widgets'

g2.draw('left', Toggle, {
  "on": true,
  "label": "Wi-Fi",
  "focused": true
})
Toggle: off
Toggle: offToggle · 160×36 · P0 · ink 10%
props
import { Toggle } from 'g2-kit/widgets'

g2.draw('left', Toggle, {
  "on": false,
  "label": "Alerts"
})
Segmented control
Segmented controlSegmentedControl · 288×36 · P1 · ink 34%
props
import { SegmentedControl } from 'g2-kit/widgets'

g2.draw('left', SegmentedControl, {
  "options": [
    "Day",
    "Week",
    "Month"
  ],
  "selected": 1,
  "focused": true
})
Slider
SliderSlider · 288×56 · P1 · ink 14%
props
import { Slider } from 'g2-kit/widgets'

g2.draw('left', Slider, {
  "label": "Brightness",
  "value": 60,
  "step": 10,
  "focused": true
})
Slider: edit mode
Slider: edit modeSlider · 288×56 · P1 · ink 11%
props
import { Slider } from 'g2-kit/widgets'

g2.draw('left', Slider, {
  "label": "Volume",
  "value": 35,
  "step": 5,
  "editing": true
})
Slider: vertical
Slider: verticalSlider · 72×144 · P1 · ink 6%
props
import { Slider } from 'g2-kit/widgets'

g2.draw('left', Slider, {
  "label": "Temp",
  "value": 21,
  "min": 16,
  "max": 28,
  "orientation": "vertical"
})
Number roller: PIN
Number roller: PINRoller · 288×120 · P1 · ink 6%
props
import { Roller } from 'g2-kit/widgets'

g2.draw('left', Roller, {
  "columns": [
    {
      "values": [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9"
      ],
      "index": 4
    },
    {
      "values": [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9"
      ],
      "index": 0
    },
    {
      "values": [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9"
      ],
      "index": 7
    },
    {
      "values": [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9"
      ],
      "index": 1
    }
  ],
  "focus": 2,
  "editing": true,
  "label": "Enter PIN"
})
Time picker
Time pickerTimePicker · 288×120 · P1 · ink 4%
props
import { TimePicker } from 'g2-kit/widgets'

g2.draw('left', TimePicker, {
  "hours": 7,
  "minutes": 30,
  "focus": 1,
  "label": "Alarm",
  "minuteStep": 5
})
Date picker
Date pickerDatePicker · 288×120 · P1 · ink 9%
props
import { DatePicker } from 'g2-kit/widgets'

g2.draw('left', DatePicker, {
  "year": 2026,
  "month": 9,
  "day": 29,
  "focus": 0,
  "editing": true
})
Checklist
ChecklistChecklist · 288×144 · P1 · ink 4%
props
import { Checklist } from 'g2-kit/widgets'

g2.draw('left', Checklist, {
  "items": [
    {
      "label": "Milk",
      "done": true
    },
    {
      "label": "Eggs",
      "done": true
    },
    {
      "label": "Coffee beans"
    },
    {
      "label": "Bread"
    },
    {
      "label": "Tomatoes"
    },
    {
      "label": "Olive oil"
    },
    {
      "label": "Basil"
    }
  ],
  "focus": 2
})
Status keyboard
Status keyboardStatusKeyboard · 288×120 · P1 · ink 17%
props
import { StatusKeyboard } from 'g2-kit/widgets'

g2.draw('left', StatusKeyboard, {
  "marks": {
    "A": "filled",
    "R": "filled",
    "E": "ring",
    "S": "strike",
    "T": "strike",
    "O": "ring",
    "L": "strike",
    "I": "strike"
  },
  "focus": "N"
})
ABC grid keyboard
ABC grid keyboardGridKeyboard · 288×144 · P1 · ink 16%
props
import { GridKeyboard } from 'g2-kit/widgets'

g2.draw('left', GridKeyboard, {
  "row": 1,
  "col": 3,
  "text": "HELLO WOR"
})
T9 keyboard: row focus
T9 keyboard: row focusGridKeyboard · 288×144 · P1 · ink 13%
props
import { GridKeyboard } from 'g2-kit/widgets'

g2.draw('left', GridKeyboard, {
  "rows": [
    [
      ".,?",
      "ABC",
      "DEF"
    ],
    [
      "GHI",
      "JKL",
      "MNO"
    ],
    [
      "PQRS",
      "TUV",
      "WXYZ"
    ],
    [
      "SPACE",
      "DEL",
      "OK"
    ]
  ],
  "row": 2,
  "col": -1
})
Text keyboard: key frames (the image under TextKeyboard)
Text keyboard: key frames (the image under TextKeyboard)TextKeyboardFrames · 576×144 · P1 · ink 4%Drawn once; the letters and focus are firmware text on top.
props
import { TextKeyboardFrames } from 'g2-kit/widgets'

g2.draw('left', TextKeyboardFrames, {
  "grid": {
    "layout": {
      "keyboardLayout": {}
    },
    "cols": 28,
    "lines": 4,
    "views": [
      [
        {
          "key": 0,
          "line": 0,
          "start": 4,
          "len": 1
        },
        {
          "key": 1,
          "line": 0,
          "start": 6,
          "len": 1
        },
        {
          "key": 2,
          "line": 0,
          "start": 8,
          "len": 1
        },
        {
          "key": 3,
          "line": 0,
          "start": 10,
          "len": 1
        },
        {
          "key": 4,
          "line": 0,
          "start": 12,
          "len": 1
        },
        {
          "key": 5,
          "line": 0,
          "start": 14,
          "len": 1
        },
        {
          "key": 6,
          "line": 0,
          "start": 16,
          "len": 1
        },
        {
          "key": 7,
          "line": 0,
          "start": 18,
          "len": 1
        },
        {
          "key": 8,
          "line": 0,
          "start": 20,
          "len": 1
        },
        {
          "key": 9,
          "line": 0,
          "start": 22,
          "len": 1
        },
        {
          "key": 10,
          "line": 1,
          "start": 5,
          "len": 1
        },
        {
          "key": 11,
          "line": 1,
          "start": 7,
          "len": 1
        },
        {
          "key": 12,
          "line": 1,
          "start": 9,
          "len": 1
        },
        {
          "key": 13,
          "line": 1,
          "start": 11,
          "len": 1
        },
        {
          "key": 14,
          "line": 1,
          "start": 13,
          "len": 1
        },
        {
          "key": 15,
          "line": 1,
          "start": 15,
          "len": 1
        },
        {
          "key": 16,
          "line": 1,
          "start": 17,
          "len": 1
        },
        {
          "key": 17,
          "line": 1,
          "start": 19,
          "len": 1
        },
        {
          "key": 18,
          "line": 1,
          "start": 21,
          "len": 1
        },
        {
          "key": 19,
          "line": 2,
          "start": 7,
          "len": 1
        },
        {
          "key": 20,
          "line": 2,
          "start": 9,
          "len": 1
        },
        {
          "key": 21,
          "line": 2,
          "start": 11,
          "len": 1
        },
        {
          "key": 22,
          "line": 2,
          "start": 13,
          "len": 1
        },
        {
          "key": 23,
          "line": 2,
          "start": 15,
          "len": 1
        },
        {
          "key": 24,
          "line": 2,
          "start": 17,
          "len": 1
        },
        {
          "key": 25,
          "line": 2,
          "start": 19,
          "len": 1
        },
        {
          "key": 26,
          "line": 3,
          "start": 6,
          "len": 1
        },
        {
          "key": 27,
          "line": 3,
          "start": 8,
          "len": 4
        },
        {
          "key": 28,
          "line": 3,
          "start": 13,
          "len": 3
        },
        {
          "key": 29,
          "line": 3,
          "start": 17,
          "len": 1
        },
        {
          "key": 30,
          "line": 3,
          "start": 19,
          "len": 2
        }
      ],
      [
        {
          "key": 0,
          "line": 0,
          "start": 4,
          "len": 1
        },
        {
          "key": 1,
          "line": 0,
          "start": 6,
          "len": 1
        },
        {
          "key": 2,
          "line": 0,
          "start": 8,
          "len": 1
        },
        {
          "key": 3,
          "line": 0,
          "start": 10,
          "len": 1
        },
        {
          "key": 4,
          "line": 0,
          "start": 12,
          "len": 1
        },
        {
          "key": 5,
          "line": 0,
          "start": 14,
          "len": 1
        },
        {
          "key": 6,
          "line": 0,
          "start": 16,
          "len": 1
        },
        {
          "key": 7,
          "line": 0,
          "start": 18,
          "len": 1
        },
        {
          "key": 8,
          "line": 0,
          "start": 20,
          "len": 1
        },
        {
          "key": 9,
          "line": 0,
          "start": 22,
          "len": 1
        },
        {
          "key": 10,
          "line": 1,
          "start": 4,
          "len": 1
        },
        {
          "key": 11,
          "line": 1,
          "start": 6,
          "len": 1
        },
        {
          "key": 12,
          "line": 1,
          "start": 8,
          "len": 1
        },
        {
          "key": 13,
          "line": 1,
          "start": 10,
          "len": 1
        },
        {
          "key": 14,
          "line": 1,
          "start": 12,
          "len": 1
        },
        {
          "key": 15,
          "line": 1,
          "start": 14,
          "len": 1
        },
        {
          "key": 16,
          "line": 1,
          "start": 16,
          "len": 1
        },
        {
          "key": 17,
          "line": 1,
          "start": 18,
          "len": 1
        },
        {
          "key": 18,
          "line": 1,
          "start": 20,
          "len": 1
        },
        {
          "key": 19,
          "line": 1,
          "start": 22,
          "len": 1
        },
        {
          "key": 20,
          "line": 2,
          "start": 4,
          "len": 1
        },
        {
          "key": 21,
          "line": 2,
          "start": 6,
          "len": 1
        },
        {
          "key": 22,
          "line": 2,
          "start": 8,
          "len": 1
        },
        {
          "key": 23,
          "line": 2,
          "start": 10,
          "len": 1
        },
        {
          "key": 24,
          "line": 2,
          "start": 12,
          "len": 1
        },
        {
          "key": 25,
          "line": 2,
          "start": 14,
          "len": 1
        },
        {
          "key": 26,
          "line": 2,
          "start": 16,
          "len": 1
        },
        {
          "key": 27,
          "line": 2,
          "start": 18,
          "len": 1
        },
        {
          "key": 28,
          "line": 2,
          "start": 20,
          "len": 1
        },
        {
          "key": 29,
          "line": 2,
          "start": 22,
          "len": 1
        },
        {
          "key": 30,
          "line": 3,
          "start": 6,
          "len": 1
        },
        {
          "key": 31,
          "line": 3,
          "start": 8,
          "len": 3
        },
        {
          "key": 32,
          "line": 3,
          "start": 12,
          "len": 3
        },
        {
          "key": 33,
          "line": 3,
          "start": 16,
          "len": 1
        },
        {
          "key": 34,
          "line": 3,
          "start": 18,
          "len": 2
        }
      ]
    ]
  },
  "origin": {
    "x": 8,
    "y": 30
  }
})
Keyboard: QWERTY, choosing a row
Keyboard: QWERTY, choosing a rowKeyboard · 288×144 · P1 · ink 15%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {}
  },
  "group": 1
})
Keyboard: key focus, shift once
Keyboard: key focus, shift onceKeyboard · 288×144 · P1 · ink 14%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {}
  },
  "group": 0,
  "key": 4,
  "shift": "once"
})
Keyboard: symbols layer
Keyboard: symbols layerKeyboard · 288×144 · P1 · ink 16%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {}
  },
  "view": 1,
  "group": 3,
  "key": 1
})
Keyboard: ABC by columns, caps lock
Keyboard: ABC by columns, caps lockKeyboard · 288×144 · P1 · ink 15%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {
      "letters": "abc",
      "scan": "columns",
      "punctuation": ".,",
      "actions": [
        "caps",
        "symbols",
        "space",
        "delete",
        "submit"
      ],
      "labels": {
        "submit": "Send"
      }
    }
  },
  "group": 2,
  "shift": "lock"
})
Keyboard: symbols beside, two tiles
Keyboard: symbols beside, two tilesKeyboard · 576×144 · P1 · ink 11%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {
      "panels": "side"
    }
  },
  "group": 2,
  "key": 3
})
Keyboard: symbols below, digits row
Keyboard: symbols below, digits rowKeyboard · 288×288 · P1 · ink 15%
props
import { Keyboard } from 'g2-kit/widgets'

g2.draw('left', Keyboard, {
  "layout": {
    "keyboardLayout": {
      "panels": "stack",
      "digits": "row",
      "actions": [
        "shift",
        "space",
        "delete",
        "cancel",
        "submit"
      ]
    }
  },
  "group": 5,
  "text": "Hello, world"
})
Rating stars
Rating starsRating · 160×32 · P2 · ink 21%
props
import { Rating } from 'g2-kit/widgets'

g2.draw('left', Rating, {
  "value": 3.5,
  "focused": true
})

Text, feedback & chrome

Progress bar
Progress barProgressBar · 260×40 · P0 · ink 24%
props
import { ProgressBar } from 'g2-kit/widgets'

g2.draw('left', ProgressBar, {
  "value": 0.62,
  "label": "Download"
})
Progress: segmented
Progress: segmentedProgressBar · 260×40 · P0 · ink 25%
props
import { ProgressBar } from 'g2-kit/widgets'

g2.draw('left', ProgressBar, {
  "value": 7,
  "max": 10,
  "segments": 10,
  "label": "Reps",
  "valueText": "7/10"
})
Big text: auto-fit
Big text: auto-fitBigText · 288×144 · P0 · ink 14%
props
import { BigText } from 'g2-kit/widgets'

g2.draw('left', BigText, {
  "text": "Turn left in 200 m"
})
Big text: short
Big text: shortBigText · 144×96 · P0 · ink 10%
props
import { BigText } from 'g2-kit/widgets'

g2.draw('left', BigText, {
  "text": "GO!"
})
Toast: info
Toast: infoToast · 288×48 · P1 · ink 16%
props
import { Toast } from 'g2-kit/widgets'

g2.draw('left', Toast, {
  "text": "Synced 3 new items",
  "remaining": 0.6
})
Toast: success
Toast: successToast · 288×48 · P1 · ink 11%
props
import { Toast } from 'g2-kit/widgets'

g2.draw('left', Toast, {
  "text": "Saved",
  "kind": "success"
})
Toast: warning
Toast: warningToast · 288×48 · P1 · ink 9%
props
import { Toast } from 'g2-kit/widgets'

g2.draw('left', Toast, {
  "text": "Battery low: 15%",
  "kind": "warning"
})
Toast: error
Toast: errorToast · 288×48 · P1 · ink 95%
props
import { Toast } from 'g2-kit/widgets'

g2.draw('left', Toast, {
  "text": "Upload failed. Retrying…",
  "kind": "error"
})
Tabs
TabsTabs · 288×24 · P1 · ink 15%
props
import { Tabs } from 'g2-kit/widgets'

g2.draw('left', Tabs, {
  "tabs": [
    "Today",
    "Week",
    "Month",
    "Year"
  ],
  "active": 1
})
Tabs: boxed
Tabs: boxedTabs · 144×24 · P1 · ink 50%
props
import { Tabs } from 'g2-kit/widgets'

g2.draw('left', Tabs, {
  "tabs": [
    "Map",
    "List"
  ],
  "active": 0,
  "variant": "boxed"
})
Pagination dots
Pagination dotsPaginationDots · 96×16 · P1 · ink 13%
props
import { PaginationDots } from 'g2-kit/widgets'

g2.draw('left', PaginationDots, {
  "count": 5,
  "active": 2
})
Scroll indicator
Scroll indicatorScrollIndicator · 6×144 · P1 · ink 18%
props
import { ScrollIndicator } from 'g2-kit/widgets'

g2.draw('left', ScrollIndicator, {
  "total": 40,
  "visible": 8,
  "offset": 12
})
Status bar
Status barStatusBar · 288×20 · P1 · ink 16%
props
import { StatusBar } from 'g2-kit/widgets'

g2.draw('left', StatusBar, {
  "time": "09:41",
  "battery": 0.72,
  "signal": 3,
  "slots": [
    {
      "icon": "bell",
      "text": "2"
    },
    {
      "icon": "music"
    }
  ],
  "title": "Home"
})
HUD frame: brackets
HUD frame: bracketsHudFrame · 288×144 · P1 · ink 1%
props
import { HudFrame } from 'g2-kit/widgets'

g2.draw('left', HudFrame, {
  "title": "Target",
  "style": "brackets"
})
HUD frame: notched + bar title
HUD frame: notched + bar titleHudFrame · 288×144 · P1 · ink 10%
props
import { HudFrame } from 'g2-kit/widgets'

g2.draw('left', HudFrame, {
  "title": "System",
  "style": "notched",
  "titleStyle": "bar"
})
Ticker (one frame)
Ticker (one frame)Ticker · 288×24 · P1 · ink 10%Each frame is one image send (~350 ms on glasses).
props
import { Ticker } from 'g2-kit/widgets'

g2.draw('left', Ticker, {
  "text": "AAPL 232.1 +1.2%   MSFT 511.9 -0.4%   NVDA 184.2 +2.9%",
  "offset": 40
})
Table
TableTable · 288×144 · P2 · ink 19%
props
import { Table } from 'g2-kit/widgets'

g2.draw('left', Table, {
  "columns": [
    {
      "label": "Stop",
      "weight": 2
    },
    {
      "label": "Line"
    },
    {
      "label": "Min",
      "align": "right"
    }
  ],
  "rows": [
    [
      "Central Station",
      "U2",
      3
    ],
    [
      "Market Square",
      "14",
      7
    ],
    [
      "Harbour",
      "S1",
      12
    ],
    [
      "Old Town Hall",
      "4",
      15
    ],
    [
      "University",
      "U2",
      21
    ],
    [
      "Airport",
      "S8",
      34
    ]
  ],
  "focus": 1,
  "font": "body"
})
Card
CardCard · 144×96 · P2 · ink 15%
props
import { Card } from 'g2-kit/widgets'

g2.draw('left', Card, {
  "title": "Heart rate",
  "value": "72",
  "icon": "heart",
  "footnote": "resting",
  "focused": true
})
Badges
BadgesBadge · 96×16 · P2 · ink 30%
props
import { Badge } from 'g2-kit/widgets'

g2.draw('left', Badge, {
  "text": "LIVE",
  "variant": "solid",
  "icon": "record"
})
Spinner (1 of 4 frames)
Spinner (1 of 4 frames)Spinner · 144×32 · P2 · ink 7%Each frame is one send; advance slowly.
props
import { Spinner } from 'g2-kit/widgets'

g2.draw('left', Spinner, {
  "frame": 1,
  "label": "Syncing"
})

Glanceable data faces

Analog clock
Analog clockAnalogClock · 144×144 · P1 · ink 6%
props
import { AnalogClock } from 'g2-kit/widgets'

g2.draw('left', AnalogClock, {
  "hours": 10,
  "minutes": 8,
  "seconds": 36
})
Analog clock: numbers
Analog clock: numbersAnalogClock · 144×144 · P1 · ink 8%
props
import { AnalogClock } from 'g2-kit/widgets'

g2.draw('left', AnalogClock, {
  "hours": 3,
  "minutes": 45,
  "ticks": "numbers",
  "label": "Tokyo"
})
Timer ring (pomodoro)
Timer ring (pomodoro)TimerRing · 144×144 · P1 · ink 22%
props
import { TimerRing } from 'g2-kit/widgets'

g2.draw('left', TimerRing, {
  "remaining": 1062,
  "total": 1500,
  "label": "Focus"
})
Compass strip
Compass stripCompassStrip · 288×48 · P1 · ink 4%
props
import { CompassStrip } from 'g2-kit/widgets'

g2.draw('left', CompassStrip, {
  "heading": 62,
  "markers": [
    {
      "bearing": 95
    },
    {
      "bearing": 250
    }
  ]
})
Turn arrow: right
Turn arrow: rightTurnArrow · 288×96 · P1 · ink 7%
props
import { TurnArrow } from 'g2-kit/widgets'

g2.draw('left', TurnArrow, {
  "direction": "right",
  "distance": "200 m",
  "street": "Main Street"
})
Turn arrow: slight left
Turn arrow: slight leftTurnArrow · 288×96 · P1 · ink 6%
props
import { TurnArrow } from 'g2-kit/widgets'

g2.draw('left', TurnArrow, {
  "direction": "slightLeft",
  "distance": "1.2 km",
  "street": "A7 north"
})
Turn arrow: U-turn
Turn arrow: U-turnTurnArrow · 288×96 · P1 · ink 8%
props
import { TurnArrow } from 'g2-kit/widgets'

g2.draw('left', TurnArrow, {
  "direction": "uturn",
  "distance": "50 m"
})
Weather glyph
Weather glyphWeatherGlyph · 288×96 · P2 · ink 11%
props
import { WeatherGlyph } from 'g2-kit/widgets'

g2.draw('left', WeatherGlyph, {
  "condition": "partly",
  "temp": "18°",
  "label": "Berlin",
  "hiLo": "H 21°  L 12°"
})
Weather glyph: rain
Weather glyph: rainWeatherGlyph · 144×72 · P2 · ink 19%
props
import { WeatherGlyph } from 'g2-kit/widgets'

g2.draw('left', WeatherGlyph, {
  "condition": "rain",
  "temp": "9°"
})

Game kit

Grid board: word game
Grid board: word gameGridBoard · 144×144 · P1 · ink 23%
props
import { GridBoard } from 'g2-kit/widgets'

g2.draw('left', GridBoard, {
  "cells": [
    [
      {
        "glyph": "C",
        "mark": "strike"
      },
      {
        "glyph": "R",
        "mark": "ring"
      },
      {
        "glyph": "A",
        "mark": "filled"
      },
      {
        "glyph": "N",
        "mark": "strike"
      },
      {
        "glyph": "E",
        "mark": "ring"
      }
    ],
    [
      {
        "glyph": "B",
        "mark": "strike"
      },
      {
        "glyph": "E",
        "mark": "filled"
      },
      {
        "glyph": "A",
        "mark": "filled"
      },
      {
        "glyph": "R",
        "mark": "filled"
      },
      {
        "glyph": "D",
        "mark": "strike"
      }
    ],
    [
      {
        "glyph": "S",
        "mark": "focus"
      },
      {
        "glyph": "P"
      },
      null,
      null,
      null
    ],
    [
      null,
      null,
      null,
      null,
      null
    ]
  ]
})
Grid board: tic-tac-toe
Grid board: tic-tac-toeGridBoard · 144×144 · P1 · ink 12%
props
import { GridBoard } from 'g2-kit/widgets'

g2.draw('left', GridBoard, {
  "cells": [
    [
      {
        "glyph": "X"
      },
      {
        "glyph": "O"
      },
      null
    ],
    [
      null,
      {
        "glyph": "X"
      },
      null
    ],
    [
      {
        "glyph": "O"
      },
      null,
      null
    ]
  ],
  "focus": [
    2,
    2
  ]
})
Grid board: 2048
Grid board: 2048GridBoard · 144×144 · P1 · ink 25%
props
import { GridBoard } from 'g2-kit/widgets'

g2.draw('left', GridBoard, {
  "cells": [
    [
      {
        "glyph": "2"
      },
      null,
      {
        "glyph": "4"
      },
      null
    ],
    [
      {
        "glyph": "8",
        "mark": "ring"
      },
      {
        "glyph": "16",
        "mark": "ring"
      },
      null,
      null
    ],
    [
      {
        "glyph": "128",
        "mark": "filled"
      },
      {
        "glyph": "32",
        "mark": "ring"
      },
      {
        "glyph": "4"
      },
      null
    ],
    [
      {
        "glyph": "512",
        "mark": "filled"
      },
      {
        "glyph": "64",
        "mark": "ring"
      },
      {
        "glyph": "2"
      },
      {
        "glyph": "2"
      }
    ]
  ],
  "gap": 3
})
Score HUD
Score HUDScoreHud · 288×24 · P1 · ink 11%
props
import { ScoreHud } from 'g2-kit/widgets'

g2.draw('left', ScoreHud, {
  "score": 1280,
  "best": 4096,
  "streak": 3,
  "lives": {
    "current": 2,
    "max": 3
  }
})
Score HUD: stacked
Score HUD: stackedScoreHud · 144×96 · P1 · ink 6%
props
import { ScoreHud } from 'g2-kit/widgets'

g2.draw('left', ScoreHud, {
  "score": 42,
  "best": 97,
  "lives": {
    "current": 3,
    "max": 5
  },
  "layout": "stack"
})
Dice
DiceDice · 288×64 · P2 · ink 32%
props
import { Dice } from 'g2-kit/widgets'

g2.draw('left', Dice, {
  "values": [
    3,
    6,
    1,
    5,
    2
  ],
  "held": [
    false,
    true,
    false,
    true,
    false
  ],
  "focus": 2
})
Health bar
Health barHealthBar · 160×16 · P2 · ink 28%
props
import { HealthBar } from 'g2-kit/widgets'

g2.draw('left', HealthBar, {
  "value": 64,
  "max": 100,
  "icon": "heart"
})

Filled vs outline theme surface: 'outline': ink 24% → 14% over these 17 samples

Every lit pixel sits between the wearer and the world. With createTheme({ surface: 'outline' }) (or outlineTheme), components draw frames and light textures where they would paint solid blocks. Ink is the share of lit pixels; the budget is 25%.

Bar chart, filledfilled · ink 32%
Bar chart, outlineoutline · ink 16%
Bar chartBarChart
Bar chart: negatives, filledfilled · ink 15%
Bar chart: negatives, outlineoutline · ink 7%
Bar chart: negativesBarChart
Bar chart: horizontal, filledfilled · ink 20%
Bar chart: horizontal, outlineoutline · ink 14%
Bar chart: horizontalBarChart
Grouped bars, filledfilled · ink 36%
Grouped bars, outlineoutline · ink 20%
Grouped barsMultiBarChart
Stacked bars, filledfilled · ink 31%
Stacked bars, outlineoutline · ink 12%
Stacked barsMultiBarChart
Button row: states, filledfilled · ink 34%
Button row: states, outlineoutline · ink 24%
Button row: statesButtonRow
Toggle: on, focused, filledfilled · ink 26%
Toggle: on, focused, outlineoutline · ink 15%
Toggle: on, focusedToggle
Progress bar, filledfilled · ink 24%
Progress bar, outlineoutline · ink 14%
Progress barProgressBar
Progress: segmented, filledfilled · ink 25%
Progress: segmented, outlineoutline · ink 15%
Progress: segmentedProgressBar
Segmented control, filledfilled · ink 34%
Segmented control, outlineoutline · ink 22%
Segmented controlSegmentedControl
Keyboard: key focus, shift once, filledfilled · ink 14%
Keyboard: key focus, shift once, outlineoutline · ink 13%
Keyboard: key focus, shift onceKeyboard
Keyboard: symbols layer, filledfilled · ink 16%
Keyboard: symbols layer, outlineoutline · ink 14%
Keyboard: symbols layerKeyboard
Keyboard: ABC by columns, caps lock, filledfilled · ink 15%
Keyboard: ABC by columns, caps lock, outlineoutline · ink 14%
Keyboard: ABC by columns, caps lockKeyboard
Keyboard: symbols beside, two tiles, filledfilled · ink 11%
Keyboard: symbols beside, two tiles, outlineoutline · ink 10%
Keyboard: symbols beside, two tilesKeyboard
Toast: error, filledfilled · ink 95%
Toast: error, outlineoutline · ink 17%
Toast: errorToast
Tabs: boxed, filledfilled · ink 50%
Tabs: boxed, outlineoutline · ink 21%
Tabs: boxedTabs
Histogram, filledfilled · ink 26%
Histogram, outlineoutline · ink 12%
HistogramHistogram

Text components strings for firmware text containers: no image send (~60 ms vs ~260 ms per update on G2)

Shown in a monospace font here; the glasses use their own proportional firmware font. Put them in any text container with g2.textArea(name).draw(key, Component, props).

    Q W E R T Y U I O P 
     A S D[F]G H J K L  
       Z X C V B N M    
      ▲ ?123 ___ ◀ OK   
Text keyboard: key focus, shift onceTextKeyboardFullwidth text on the G2 grid over TextKeyboardFrames; a focus move is one text update.
   [q w e r t y u i o p]
     a s d f g h j k l  
       z x c v b n m    
      △ ?123 ___ ◀ OK   
Text keyboard: choosing a rowTextKeyboard
Syncing ↗
Text spinner: arrowsTextSpinnerFrames ↑ ↗ → ↘ ↓ ↙ ← ↖; one text update per frame.
Loading ▶
Text spinner: triangleTextSpinner
Syncing /
Text spinner: ASCIITextSpinner
Download ━━━━━━━━──────────── 40%
Text progress barTextProgress
█████▏────── 43%
Text progress: blocks, eighth-cell precisionTextProgress
Reps ━━━━━━━─── 7/10
Text progress: countTextProgress
Download [########------------] 40%
Text progress: ASCIITextProgress
▷ Brightness ━━━━━━━●──── 60
Text sliderTextSlider
▶ Volume ━━━━●─────── 35
Text slider: focusedTextSlider
▶ Volume ━━━━◆────── 40
Text slider: edit mode, knob style, one cell per stepTextSlidereditStyle: knob keeps the line still while editing.
▶ Temp ◀ ━━━━━●────── ▶ 21°C
Text slider: edit modeTextSlider
▷ Resume
▶ New game
▷ Settings
▷ Quit
Text menuTextMenuThe "fake buttons" pattern: a menu with no image.
▷ ○ Bread  ▲
▶ ○ Coffee
▷ ● Basil  ▼
Text menu: checks, 3 of 6 visibleTextMenu
▶ Wi-Fi  ● On
Text toggle: on, focusedTextToggle
▷ Alerts  ○ Off
Text toggle: offTextToggle
○ Hold to delete  ────────────
Text hold-to-confirm: idleTextHoldDrive it from HoldToConfirm; ~10 updates/s as text vs ~2 as an image.
● Hold to delete  ━━━━━━━─────
Text hold-to-confirm: holdingTextHold
● Deleted
Text hold-to-confirm: doneTextHold
[~] Hold to delete  [#######-----]
Text hold-to-confirm: ASCIITextHold
▲ Battery low
Text toast: warningTextToastKinds by shape: ▶ info, ● success, ▲ warning, ■ error.
■ Sync failed
   Tap to retry
Text toast: error with detailTextToast
[+] Saved
Text toast: ASCIITextToast
12:45 │ Steps 8 214 │ Bat 82%
Text status lineTextStatusLine
Heart rate  128 bpm  ↑ +4
Text readout with deltaTextReadoutLive values as text; pair with a tile drawn once.
▶ Pace  5.25 min/km  ↓ -0.10
Text readout: decimals, focusedTextReadout
p in 5 min, room 4B. Then: desig
Text tickerTextTickerA window that moves one character per update.