RAGS - v1.10.0
    Preparing search index...

    Use them like regular GTK widgets

    import Gtk from "gi://Gtk";

    const calendar = new Gtk.Calendar({
    showDayNames: false,
    showHeading: true,
    });

    You can subclass Gtk.Widget not builtin to behave like RAGS widgets.

    const Calendar = Widget.subclass(Gtk.Calendar);

    const myCalendar = Calendar({
    showDayNames: false,
    showHeading: true,

    // now you can set AGS props
    className: "my-calendar",
    setup(self) {
    self.bind();
    },
    });
    Tip

    Calendar is available on Widget [!NOTE] Open up an issue/PR if you want to see a widget to be available on Widget by default.

    Usually in GTK custom widgets are achieved by subclassing. The idea behind RAGS is to use functions that create widgets and utilize closures.

    function CounterButton(({ color = 'aqua', ...rest })) {
    const count = Variable(0)

    const label = Widget.Label({
    label: count.bind().as(v => `count: ${v}`),
    style: `color: ${color}`,
    })

    return Widget.Button({
    ...rest, // spread passed parameters
    child: label,
    onClicked: () => count++,
    })
    }

    // then simply call it
    const button = CounterButton({
    color: 'blue',
    className: 'my-widget',
    })

    This approach comes with the limitation that parameters passed to these functions are that, just parameters and not GObject properties. If you still want to subclass, you can do so by subclassing a Gtk.WIdget and registering it Widget.register.

    class CounterButton extends Gtk.Button {
    static {
    Widget.register(this, {
    properties: {
    "count": ["int", "rw"],
    },
    });
    }

    // the super constructor will take care of setting the count prop
    // so you don't have to explicitly set count in the constructor
    constructor(props) {
    super(props);

    const label = new Gtk.Label({
    label: `${this.count}`,
    });

    this.add(label);

    this.connect("clicked", () => {
    this.count++;
    label.label = `${this.count}`;
    });
    }

    get count() {
    return this._count || 0;
    }

    set count(num) {
    this._count = num;
    this.notify("count");
    }
    }

    You can now construct it like any other Gtk.Widget with the new keyword.

    const counterButton = new CounterButton({
    count: 0,

    // you can set AGS widget props on it
    className: "",
    });

    counterButton.connect("notify::count", ({ count }) => {
    print(count);
    });

    counterButton.count += 1;
    Tip

    You will never actually need to subclass, you can fake gobject props using Variables

    function CounterButton({ count, ...props }) {
    const counter = Variable(count);

    const button = Widget.Button({
    on_clicked: () => counter.value += 1,
    child: Widget.Label({
    label: counter.bind().as((c) => `${c}`),
    }),
    ...props,
    });

    return Object.assign(button, {
    count: counter,
    });
    }

    const counterButton = CounterButton({
    count: 0,
    });

    counterButton.count.connect("changed", ({ value }) => {
    print(value);
    });

    counterButton.count.value += 1;