feat(build): type generated event constants

Generate EventName constants for data-slhx-on metadata and exercise them through typed event emission in techdemo.

req: codegen/006
This commit is contained in:
slhx agent
2026-05-26 00:09:07 +02:00
parent 0b6ad64d98
commit 5364135c5e
5 changed files with 45 additions and 6 deletions
+1 -1
View File
@@ -238,7 +238,7 @@ a `data-*` handle param is statically known or runtime-extracted.
005 Generated module `atoms` exports `Atom<T>` for values that must be addressable, bootstrapped, or synced. Ordinary Rust fields on app/components are not automatically atoms.
### req: codegen/006
006 `slhx-build` discovers `data-slhx-on` event names from hemplate Surface inputs and emits generated event constants. Event constants are metadata for checked Rust authoring and diagnostics; they do not create a trigger mini-language or new browser runtime semantics. [north_star]
006 `slhx-build` discovers `data-slhx-on` event names from hemplate Surface inputs and emits generated `slhx::EventName` constants. Event constants are metadata for checked Rust authoring and diagnostics; they do not create a trigger mini-language or new browser runtime semantics. [north_star]
---
+5 -1
View File
@@ -74,6 +74,10 @@ mod tests {
// req: codegen/006
#[test]
fn techdemo_exports_generated_event_constants() {
assert_eq!(ui::issue_lane::events::drop, "drop");
assert_eq!(ui::issue_lane::events::drop.as_str(), "drop");
assert!(matches!(
slhx::event(ui::issue_lane::events::drop, "card-1"),
Effect::Emit { name, payload } if name == "drop" && payload == "card-1"
));
}
}
+3 -3
View File
@@ -408,7 +408,7 @@ impl Resources {
continue;
}
out.push_str(&format!(
"{inner}pub const {}: &'static str = {};\n",
"{inner}pub const {}: ::slhx::EventName = ::slhx::EventName::new({});\n",
event.ident,
rust_str(&event.name)
));
@@ -1031,8 +1031,8 @@ mod tests {
assert!(generated.contains("pub mod atoms"));
assert!(generated.contains("pub const filter"));
assert!(generated.contains("pub mod events"));
assert!(generated.contains("pub const click: &'static str = \"click\""));
assert!(generated.contains("pub const keydown: &'static str = \"keydown\""));
assert!(generated.contains("pub const click: ::slhx::EventName = ::slhx::EventName::new(\"click\")"));
assert!(generated.contains("pub const keydown: ::slhx::EventName = ::slhx::EventName::new(\"keydown\")"));
assert!(generated.contains("pub const new_todo"));
assert!(generated.contains("pub mod todo"));
assert!(generated.contains("pub const ALL_IDS"));
+35
View File
@@ -186,6 +186,41 @@ impl core::fmt::Display for CssClass {
}
}
/// A generated, checked event token.
/// req: codegen/006
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct EventName {
name: &'static str,
}
impl EventName {
pub const fn new(name: &'static str) -> Self {
Self { name }
}
pub const fn as_str(self) -> &'static str {
self.name
}
}
impl AsRef<str> for EventName {
fn as_ref(&self) -> &str {
self.name
}
}
impl From<EventName> for String {
fn from(event: EventName) -> Self {
event.name.to_string()
}
}
impl core::fmt::Display for EventName {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.name)
}
}
/// A small displayable list of generated CSS class tokens for hemplate `+class`.
/// req: style/003
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+1 -1
View File
@@ -9,7 +9,7 @@ pub use slhx_derive::{app, component, form, handler, surface};
pub mod prelude {
pub use slhx_core::{
navigate, push, redirect, replace, Atom, BuildFingerprint, CssClass, CssClasses, Effect,
Form, FormModel, FormValue, Handle, IntoEffect, KeyedSlot, Slot,
EventName, Form, FormModel, FormValue, Handle, IntoEffect, KeyedSlot, Slot,
};
pub use slhx_derive::{app, component, form, handler, surface};
}