Skip to content

Implement <Checkbox> tag (egui::Checkbox) #27

Description

@ZhukMax

Add a declarative <Checkbox> widget with a controlled boolean binding and optional change handler. Supports inline text (children) or a text="..." attribute, plus common UX knobs like enabled, wrap, and tooltip.

  • Covers a core form/setting control with an idiomatic, template-first API.
  • Aligns with EFx’s controlled-input model (value comes from state; emits onChange).
  • Reduces imperative glue for simple preference panes and dialogs.

Scope

  • Tag: <Checkbox>
  • Required: checked={bool_expr}
  • Optional attributes:
    text="...", enabled=bool, wrap=bool, tooltip="...", id="..." (for stable identity)
  • Events: onChange={|checked: bool| ...} (fires once when the value toggles)
  • Content: either text="..." or inline text children (mutually exclusive; diagnostics on conflict)

Non-goals (here): tri-state/indeterminate mode, custom icons, per-state colors.


Proposed API (sketch)

Template

// With children text
efx!(ui, r#"
<Checkbox checked={prefs.notifications} onChange={|v| prefs.notifications = v} wrap="true">
  Enable notifications
</Checkbox>
"#);

// With text attribute
efx!(ui, r#"
<Checkbox checked={prefs.autosave} text="Autosave files" tooltip="Saves every 5 minutes"/>
"#);

Conceptual mapping to egui

let mut val = /* bound bool */;
let mut widget = egui::Checkbox::new(&mut val, text_str); // text_str from children or text=""
widget = widget.wrap(wrap);

let resp = if enabled {
    ui.add(widget)
} else {
    ui.add_enabled(false, widget)
};

if let Some(tip) = tooltip { resp.on_hover_text(tip); }
if resp.changed() {
    // emit onChange(val)
}

Tasks

  • AST & parsing

    • Add <Checkbox> node with checked (bool) and optional text, enabled, wrap, tooltip, id.
    • Allow exactly one text source: children or text=...; error on both.
  • Codegen

    • Bind checked={expr} by value-copy to a local, pass &mut to egui::Checkbox, then write back if changed.
    • Emit onChange(bool) when Response::changed() is true.
    • Support enabled=false via ui.add_enabled(false, ...).
    • Apply wrap flag and tooltip on Response.
    • Honor optional id using egui::Id if provided (stable identity).
  • Diagnostics

    • Missing checked or non-boolean type → clear compile error with expected type.
    • Both children text and text= present → actionable error (choose one).
    • Unknown/unsupported attributes → list allowed attrs for <Checkbox>.
  • Examples & docs

    • Minimal preferences pane with two checkboxes (children vs text=).
    • Disabled checkbox with tooltip; long text demonstrating wrap.
    • Documentation snippet in docs/cookbook.md and docs/tags.md.
  • Tests

    • trybuild UI tests: missing checked; wrong type; dual text sources; unknown attrs.
    • Unit test: toggling flows updates and fires onChange exactly once.
    • Ensure examples build for wasm32-unknown-unknown (no runtime launch).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions