mirror of
https://github.com/ziex-dev/ziex.git
synced 2026-07-20 02:29:36 -06:00
feat(core): add namespaced component support
Fixes: https://github.com/nurulhudaapon/ziex/issues/55
This commit is contained in:
parent
f4a18e27e8
commit
1d9dcaba44
@ -88,8 +88,8 @@ module.exports = grammar(zig, {
|
||||
'</>',
|
||||
),
|
||||
|
||||
// HTML tag name (e.g., div, main, button, CustomComponent)
|
||||
zx_tag_name: _$ => /[a-zA-Z_][a-zA-Z0-9_]*/,
|
||||
// HTML tag name (e.g., div, main, button, CustomComponent, icons.GitHub)
|
||||
zx_tag_name: _$ => /[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*/,
|
||||
|
||||
// HTML/ZX attributes
|
||||
zx_attribute: $ => choice(
|
||||
|
||||
2
pkg/tree-sitter-zx/src/grammar.json
generated
2
pkg/tree-sitter-zx/src/grammar.json
generated
@ -6689,7 +6689,7 @@
|
||||
},
|
||||
"zx_tag_name": {
|
||||
"type": "PATTERN",
|
||||
"value": "[a-zA-Z_][a-zA-Z0-9_]*"
|
||||
"value": "[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*"
|
||||
},
|
||||
"zx_attribute": {
|
||||
"type": "CHOICE",
|
||||
|
||||
3524
pkg/tree-sitter-zx/src/parser.c
generated
3524
pkg/tree-sitter-zx/src/parser.c
generated
File diff suppressed because it is too large
Load Diff
@ -691,9 +691,19 @@ pub fn transpileFragment(self: *Ast, node: ts.Node, ctx: *TranspileContext, is_r
|
||||
}
|
||||
|
||||
pub fn isCustomComponent(tag: []const u8) bool {
|
||||
// Namespaced components (e.g., components.Button, icons.GitHub) are always custom
|
||||
if (std.mem.indexOfScalar(u8, tag, '.') != null) return true;
|
||||
return tag.len > 0 and std.ascii.isUpper(tag[0]);
|
||||
}
|
||||
|
||||
/// Extract the component display name from a tag (part after the last dot, or the full tag)
|
||||
fn componentDisplayName(tag: []const u8) []const u8 {
|
||||
if (std.mem.lastIndexOfScalar(u8, tag, '.')) |dot_pos| {
|
||||
return tag[dot_pos + 1 ..];
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
/// Check if element is a <pre> tag (preserve whitespace but still process children)
|
||||
fn isPreElement(tag: []const u8) bool {
|
||||
return std.mem.eql(u8, tag, "pre");
|
||||
@ -883,7 +893,7 @@ fn writeCustomComponent(self: *Ast, node: ts.Node, tag: []const u8, attributes:
|
||||
// Write _zx.client(.{ .name = "Name", .path = "path", .id = "id" }, .{ props })
|
||||
try ctx.writeM("_zx.client", node.startByte(), self);
|
||||
try ctx.write("(.{ .name = \"");
|
||||
try ctx.write(tag);
|
||||
try ctx.write(componentDisplayName(tag));
|
||||
try ctx.write("\", .path = \"");
|
||||
try ctx.write(full_path);
|
||||
try ctx.write("\", .id = \"");
|
||||
@ -951,9 +961,9 @@ fn writeCustomComponent(self: *Ast, node: ts.Node, tag: []const u8, attributes:
|
||||
try ctx.write(tag);
|
||||
try ctx.write(", ");
|
||||
try ctx.write(".{ .name = \"");
|
||||
try ctx.write(tag);
|
||||
try ctx.write(componentDisplayName(tag));
|
||||
try ctx.write("\", .client = .{ .name = \"");
|
||||
try ctx.write(tag);
|
||||
try ctx.write(componentDisplayName(tag));
|
||||
// try ctx.write("\", .path = \"");
|
||||
// try ctx.write(full_path);
|
||||
try ctx.write("\", .id = \"");
|
||||
@ -1017,7 +1027,7 @@ fn writeCustomComponent(self: *Ast, node: ts.Node, tag: []const u8, attributes:
|
||||
|
||||
// Write options parameter first (name + builtin attributes)
|
||||
try ctx.write(".{ .name = \"");
|
||||
try ctx.write(tag);
|
||||
try ctx.write(componentDisplayName(tag));
|
||||
try ctx.write("\"");
|
||||
try writeComponentBuiltinOptions(self, builtin_attrs.items, ctx, true);
|
||||
try ctx.write(" }, ");
|
||||
|
||||
@ -199,6 +199,11 @@ test "expression_multiline_string" {
|
||||
test "component_basic" {
|
||||
try test_fmt("component/basic");
|
||||
}
|
||||
|
||||
test "component_namespace" {
|
||||
try test_fmt("component/namespace");
|
||||
}
|
||||
|
||||
test "component_multiple" {
|
||||
try test_fmt("component/multiple");
|
||||
}
|
||||
|
||||
1
test/data/component/namespace.html
generated
Normal file
1
test/data/component/namespace.html
generated
Normal file
@ -0,0 +1 @@
|
||||
<main><button>Custom Button</button></main>
|
||||
34
test/data/component/namespace.zig
Normal file
34
test/data/component/namespace.zig
Normal file
@ -0,0 +1,34 @@
|
||||
pub fn Page(allocator: zx.Allocator) zx.Component {
|
||||
var _zx = @import("zx").allocInit(allocator);
|
||||
return _zx.ele(
|
||||
.main,
|
||||
.{
|
||||
.allocator = allocator,
|
||||
.children = &.{
|
||||
_zx.cmp(
|
||||
components.Button,
|
||||
.{ .name = "Button" },
|
||||
.{ .title = "Custom Button" },
|
||||
),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const components = struct {
|
||||
const ButtonProps = struct { title: []const u8 };
|
||||
pub fn Button(allocator: zx.Allocator, props: ButtonProps) zx.Component {
|
||||
var _zx = @import("zx").allocInit(allocator);
|
||||
return _zx.ele(
|
||||
.button,
|
||||
.{
|
||||
.allocator = allocator,
|
||||
.children = &.{
|
||||
_zx.expr(props.title),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const zx = @import("zx");
|
||||
16
test/data/component/namespace.zx
Normal file
16
test/data/component/namespace.zx
Normal file
@ -0,0 +1,16 @@
|
||||
pub fn Page(allocator: zx.Allocator) zx.Component {
|
||||
return (
|
||||
<main @allocator={allocator}>
|
||||
<components.Button title="Custom Button" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
const components = struct {
|
||||
const ButtonProps = struct { title: []const u8 };
|
||||
pub fn Button(allocator: zx.Allocator, props: ButtonProps) zx.Component {
|
||||
return (<button @allocator={allocator}>{props.title}</button>);
|
||||
}
|
||||
};
|
||||
|
||||
const zx = @import("zx");
|
||||
@ -310,6 +310,10 @@ test "component_basic" {
|
||||
try test_transpile("component/basic");
|
||||
try test_render("component/basic", @import("./../data/component/basic.zig").Page);
|
||||
}
|
||||
test "component_namespace" {
|
||||
try test_transpile("component/namespace");
|
||||
try test_render("component/namespace", @import("./../data/component/namespace.zig").Page);
|
||||
}
|
||||
test "component_multiple" {
|
||||
try test_transpile("component/multiple");
|
||||
try test_render("component/multiple", @import("./../data/component/multiple.zig").Page);
|
||||
@ -540,6 +544,7 @@ fn getPageFn(comptime path: []const u8) ?fn (std.mem.Allocator) zx.Component {
|
||||
.{ "expression/optional", @import("./../data/expression/optional.zig") },
|
||||
.{ "expression/template", @import("./../data/expression/template.zig") },
|
||||
.{ "component/basic", @import("./../data/component/basic.zig") },
|
||||
.{ "component/namespace", @import("./../data/component/namespace.zig") },
|
||||
.{ "component/multiple", @import("./../data/component/multiple.zig") },
|
||||
.{ "component/nested", @import("./../data/component/nested.zig") },
|
||||
.{ "component/children_only", @import("./../data/component/children_only.zig") },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user