Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions examples/accessibility.zig
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,21 @@ const Model = struct {
return .none;
}

pub fn view(self: *const Model, ctx: *const zz.Context) []const u8 {
pub fn view(self: *const Model, ctx: *const zz.Context) ![]const u8 {
var result: Writer.Allocating = .init(ctx.allocator);
const w = &result.writer;

// Title
const title = (zz.Style{})
const title = try (zz.Style{})
.bold(true)
.fg(.white)
.inline_style(true)
.render(ctx.allocator, "Accessibility: WCAG Contrast Checker") catch "A11y Demo";
w.print("{s}\n\n", .{title}) catch {};
.render(ctx.allocator, "Accessibility: WCAG Contrast Checker");
try w.print("{s}\n\n", .{title});

// Table header
w.writeAll(" Name Ratio Level Sample\n") catch {};
w.writeAll(" ────────────────────── ──────── ───────── ──────────────\n") catch {};
try w.writeAll(" Name Ratio Level Sample\n");
try w.writeAll(" ────────────────────── ──────── ───────── ──────────────\n");

// Color pairs
for (&self.pairs, 0..) |*pair, i| {
Expand All @@ -86,78 +86,78 @@ const Model = struct {

// Row indicator
const prefix: []const u8 = if (i == self.selected) "> " else " ";
w.writeAll(prefix) catch {};
try w.writeAll(prefix);

// Name (padded to 23 chars)
w.print("{s}", .{pair.name}) catch {};
try w.print("{s}", .{pair.name});
const name_len = pair.name.len;
if (name_len < 23) {
for (0..23 - name_len) |_| w.writeByte(' ') catch {};
for (0..23 - name_len) |_| try w.writeByte(' ');
}

// Ratio
w.print("{d:.1}:1 ", .{ratio}) catch {};
try w.print("{d:.1}:1 ", .{ratio});

// Level badge
const badge = (zz.Style{})
const badge = try (zz.Style{})
.fg(level_color)
.bold(true)
.inline_style(true)
.render(ctx.allocator, level_name) catch level_name;
w.print("{s}", .{badge}) catch {};
.render(ctx.allocator, level_name);
try w.print("{s}", .{badge});
const badge_len = level_name.len;
if (badge_len < 10) {
for (0..10 - badge_len) |_| w.writeByte(' ') catch {};
for (0..10 - badge_len) |_| try w.writeByte(' ');
}

// Sample text with the actual colors
const sample = (zz.Style{})
const sample = try (zz.Style{})
.fg(pair.fg)
.bg(pair.bg)
.inline_style(true)
.render(ctx.allocator, " Sample Text ") catch "Sample";
w.print("{s}", .{sample}) catch {};
.render(ctx.allocator, " Sample Text ");
try w.print("{s}", .{sample});

w.writeByte('\n') catch {};
try w.writeByte('\n');
}

// Selected pair detail
const pair = &self.pairs[self.selected];
w.writeAll("\n") catch {};
try w.writeAll("\n");

// Accessible label demo
const a11y_label = zz.AccessibleLabel{
.role = .status,
.name = pair.name,
.value = std.fmt.allocPrint(ctx.allocator, "contrast {d:.1}:1", .{pair.fg.contrastRatio(pair.bg)}) catch "",
.value = try std.fmt.allocPrint(ctx.allocator, "contrast {d:.1}:1", .{pair.fg.contrastRatio(pair.bg)}),
.state = switch (zz.a11y.checkContrast(pair.fg, pair.bg)) {
.aaa => "passes AAA",
.aa => "passes AA",
.aa_large => "passes AA for large text only",
.fail => "fails WCAG requirements",
},
};
const label_text = a11y_label.format(ctx.allocator) catch "?";
const label = (zz.Style{})
const label_text = try a11y_label.format(ctx.allocator);
const label = try (zz.Style{})
.fg(.gray(14))
.inline_style(true)
.render(ctx.allocator, label_text) catch label_text;
w.print("Screen reader: {s}\n", .{label}) catch {};
.render(ctx.allocator, label_text);
try w.print("Screen reader: {s}\n", .{label});

// Suggested foreground
const suggested = zz.a11y.suggestForeground(pair.bg);
const sugg_name: []const u8 = if (std.meta.eql(suggested, .white)) "white" else "black";
w.print("Suggested foreground for this bg: {s}\n", .{sugg_name}) catch {};
try w.print("Suggested foreground for this bg: {s}\n", .{sugg_name});

// Help
w.writeAll("\n") catch {};
const help = (zz.Style{})
try w.writeAll("\n");
const help = try (zz.Style{})
.fg(.gray(12))
.inline_style(true)
.render(ctx.allocator, "Up/Down: select pair | q: quit") catch "";
w.writeAll(help) catch {};
.render(ctx.allocator, "Up/Down: select pair | q: quit");
try w.writeAll(help);

return result.toOwnedSlice() catch "Error";
return result.toOwnedSlice();
}
};

Expand Down
62 changes: 31 additions & 31 deletions examples/action_system.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,69 +15,69 @@ const Model = struct {
key: zz.KeyEvent,
};

pub fn init(self: *Model, ctx: *zz.Context) zz.Cmd(Msg) {
pub fn init(self: *Model, ctx: *zz.Context) !zz.Cmd(Msg) {
const persistent = ctx.persistent_allocator;
var reg = zz.ActionRegistry.init(persistent);

// Footer-visible actions.
try // Footer-visible actions.
reg.register(.{
.id = "app.quit",
.label = "Quit",
.description = "Exit the program",
.binding = .{ .key = .{ .char = 'q' } },
.show_in_footer = true,
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "counter.inc",
.label = "Increment",
.description = "Add one to the counter",
.binding = .{ .key = .{ .char = '+' } },
.show_in_footer = true,
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "counter.dec",
.label = "Decrement",
.description = "Subtract one from the counter",
.binding = .{ .key = .{ .char = '-' } },
.show_in_footer = true,
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "palette.open",
.label = "Command Palette",
.description = "Open the searchable command list",
.binding = .{ .key = .{ .char = 'p' }, .modifiers = .{ .ctrl = true } },
.show_in_footer = true,
}) catch {};
});

// Hidden-from-footer actions still show up in the palette.
try // Hidden-from-footer actions still show up in the palette.
reg.register(.{
.id = "counter.reset",
.label = "Reset counter",
.description = "Set the counter back to zero",
.category = "Counter",
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "counter.times_ten",
.label = "Multiply by 10",
.description = "Multiply the counter by ten",
.category = "Counter",
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "counter.negate",
.label = "Negate",
.description = "Flip the counter sign",
.category = "Counter",
}) catch {};
reg.register(.{
});
try reg.register(.{
.id = "help.about",
.label = "About this demo",
.description = "Show what this example illustrates",
.category = "Help",
}) catch {};
});

// Aliases let multiple keys map to the same action.
reg.addAlias("counter.inc", .{ .key = .up }) catch {};
reg.addAlias("counter.dec", .{ .key = .down }) catch {};
try // Aliases let multiple keys map to the same action.
reg.addAlias("counter.inc", .{ .key = .up });
try reg.addAlias("counter.dec", .{ .key = .down });

var palette = zz.CommandPalette.init(persistent) catch return .quit;
palette.placeholder = "Search commands…";
Expand All @@ -93,7 +93,7 @@ const Model = struct {
// One-shot integration: pull every registered action into the
// palette, formatting bindings as shortcut hints. The palette owns
// the strings, so no lifetime tracking on our side.
self.palette.setFromRegistry(&self.registry) catch {};
try self.palette.setFromRegistry(&self.registry);

return .none;
}
Expand Down Expand Up @@ -151,16 +151,16 @@ const Model = struct {
return .none;
}

pub fn view(self: *const Model, ctx: *const zz.Context) []const u8 {
pub fn view(self: *const Model, ctx: *const zz.Context) ![]const u8 {
const alloc = ctx.allocator;

var title = zz.Style{};
title = title.bold(true);
title = title.fg(zz.Color.cyan);
title = title.inline_style(true);
const title_str = title.render(alloc, "ActionRegistry — one source of truth") catch "";
const title_str = try title.render(alloc, "ActionRegistry — one source of truth");

const body = std.fmt.allocPrint(
const body = try std.fmt.allocPrint(
alloc,
\\Counter {d}
\\Last action {s}
Expand All @@ -170,36 +170,36 @@ const Model = struct {
\\including ones with no key binding (try "negate" or "ten").
,
.{ self.counter, self.last_action },
) catch "";
);

var box = zz.Style{};
box = box.borderAll(zz.Border.rounded);
box = box.borderForeground(zz.Color.gray(8));
box = box.paddingAll(1);
const boxed = box.render(alloc, body) catch body;
const boxed = try box.render(alloc, body);

var footer = zz.ActionFooter.init(&self.registry);
footer.setWidth(@intCast(ctx.width));
const footer_str = footer.view(alloc) catch "";
const footer_str = try footer.view(alloc);

const main_view = std.fmt.allocPrint(
const main_view = try std.fmt.allocPrint(
alloc,
"{s}\n\n{s}\n\n{s}",
.{ title_str, boxed, footer_str },
) catch "";
);

if (!self.palette_open) return main_view;

// Overlay the palette centered on top of the main view.
const palette_view = self.palette.view(alloc) catch "";
const palette_view = try self.palette.view(alloc);
return zz.place.placeFloat(
alloc,
ctx.width,
ctx.height,
0.5,
0.5,
palette_view,
) catch main_view;
);
}
};

Expand Down
42 changes: 21 additions & 21 deletions examples/animation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,27 @@ const Model = struct {
return .none;
}

pub fn view(self: *const Model, ctx: *const zz.Context) []const u8 {
pub fn view(self: *const Model, ctx: *const zz.Context) ![]const u8 {
var title_style = zz.Style{};
title_style = title_style.bold(true);
title_style = title_style.fg(zz.Color.magenta);
title_style = title_style.inline_style(true);
const title = title_style.render(ctx.allocator, "Animation & Easing Demo") catch "Animation";
const title = try title_style.render(ctx.allocator, "Animation & Easing Demo");

var buf: Writer.Allocating = .init(ctx.allocator);
const writer = &buf.writer;
writer.writeAll(title) catch {};
writer.writeAll("\n\n") catch {};
try writer.writeAll(title);
try writer.writeAll("\n\n");

// Render each tween as a bar
for (&self.tweens, self.easing_names) |*tw, name| {
// Label
var label_style = zz.Style{};
label_style = label_style.fg(zz.Color.cyan);
label_style = label_style.inline_style(true);
const label = std.fmt.allocPrint(ctx.allocator, "{s:>20}: ", .{name}) catch "";
const styled_label = label_style.render(ctx.allocator, label) catch label;
writer.writeAll(styled_label) catch {};
const label = try std.fmt.allocPrint(ctx.allocator, "{s:>20}: ", .{name});
const styled_label = try label_style.render(ctx.allocator, label);
try writer.writeAll(styled_label);

// Bar
const pos = @as(usize, @intFromFloat(@max(0, tw.value())));
Expand All @@ -115,45 +115,45 @@ const Model = struct {
dot_style = dot_style.fg(zz.Color.green);
dot_style = dot_style.bold(true);
dot_style = dot_style.inline_style(true);
const dot = dot_style.render(ctx.allocator, "●") catch "o";
writer.writeAll(dot) catch {};
const dot = try dot_style.render(ctx.allocator, "●");
try writer.writeAll(dot);
} else {
var track_style = zz.Style{};
track_style = track_style.fg(zz.Color.gray(6));
track_style = track_style.inline_style(true);
const track = track_style.render(ctx.allocator, "─") catch "-";
writer.writeAll(track) catch {};
const track = try track_style.render(ctx.allocator, "─");
try writer.writeAll(track);
}
}
writer.writeByte('\n') catch {};
try writer.writeByte('\n');
}

// Color tween demo
writer.writeAll("\n") catch {};
try writer.writeAll("\n");
var color_label_style = zz.Style{};
color_label_style = color_label_style.fg(zz.Color.cyan);
color_label_style = color_label_style.inline_style(true);
const color_label = color_label_style.render(ctx.allocator, " Color tween: ") catch "";
writer.writeAll(color_label) catch {};
const color_label = try color_label_style.render(ctx.allocator, " Color tween: ");
try writer.writeAll(color_label);

const ct = self.color_tween.value();
const color = zz.tweenColor(zz.Color.red, zz.Color.cyan, ct);
var cs = zz.Style{};
cs = cs.fg(color);
cs = cs.bold(true);
cs = cs.inline_style(true);
const color_block = cs.render(ctx.allocator, "████████████████████████████████") catch "";
writer.writeAll(color_block) catch {};
const color_block = try cs.render(ctx.allocator, "████████████████████████████████");
try writer.writeAll(color_block);

// Help
writer.writeAll("\n\n") catch {};
try writer.writeAll("\n\n");
var help_style = zz.Style{};
help_style = help_style.fg(zz.Color.gray(12));
help_style = help_style.inline_style(true);
const help = help_style.render(ctx.allocator, "r: restart animations | q: quit") catch "";
writer.writeAll(help) catch {};
const help = try help_style.render(ctx.allocator, "r: restart animations | q: quit");
try writer.writeAll(help);

return buf.toOwnedSlice() catch "Error";
return buf.toOwnedSlice();
}
};

Expand Down
Loading
Loading