use proc_macro2::Span;
use syn::Error;
pub fn error<T: std::fmt::Display>(span: Span, msg: T) -> Error {
Error::new(span, msg)
}
pub fn is_widget_builder_method(name: &str) -> bool {
matches!(
name,
"on_tap"
| "on_double_tap"
| "on_triple_tap"
| "on_long_press"
| "on_drag"
| "on_swipe"
| "on_pinch"
| "accept_tap_buttons"
| "accept_double_tap_buttons"
| "accept_triple_tap_buttons"
| "accept_long_press_buttons"
| "on_focus"
| "on_key"
| "on_key_preview"
| "on_pointer_event"
| "on_hover"
| "on_scroll"
| "focusable"
| "tab_index"
| "cursor"
| "clips_children_on"
| "ime_input"
| "event_pass_through"
| "hit_transparent"
| "context_menu"
| "focus_within"
| "hover_within"
| "visible_when"
| "on_drag_hover"
| "on_drag_leave"
| "on_drag_tick"
| "on_drag_ended"
| "on_drop"
| "on_access_action"
| "on_access_action_request"
| "access_action"
| "access_remove_action"
| "access_custom_action"
| "access_custom_action_literal"
| "access_customize"
| "access_label"
| "access_label_literal"
| "access_description"
| "access_description_literal"
| "access_hint"
| "access_hint_literal"
| "access_value"
| "access_value_literal"
| "access_role"
| "access_hidden"
| "access_disabled"
| "access_identifier"
| "access_controls"
| "access_described_by"
| "access_labelled_by"
| "access_live"
| "access_current"
| "access_has_popup"
| "access_orientation"
| "access_numeric_value"
| "access_numeric_range"
| "access_numeric_step"
| "access_shortcut_literal"
| "access_shortcut_id"
| "access_exclude_subtree"
| "access_merge_subtree"
| "access_subtree"
)
}
pub fn category_b_bare_child(parent_ty: &str, child_span: Span) -> Error {
let slot_hint = category_b_slot_hint(parent_ty);
Error::new(
child_span,
format!(
"`{parent_ty}` is a Category B widget with named slots — \
use `{slot_hint}: <widget>` instead of a bare child element"
),
)
}
pub fn is_category_b_widget(ident: &str) -> bool {
matches!(
ident,
"Card"
| "Accordion"
| "TitleBar"
| "DialogContent"
| "Breadcrumb"
| "TabWidget"
| "Popover"
| "Snackbar"
| "Dialog"
| "Wizard"
)
}
fn category_b_slot_hint(ident: &str) -> &'static str {
match ident {
"Card" => "content",
"Accordion" => "content",
"TitleBar" => "leading",
"DialogContent" => "body",
"Breadcrumb" => "item",
"TabWidget" => "tab",
"Popover" => "content",
"Snackbar" => "content",
"Dialog" => "content",
"Wizard" => "step",
_ => "content",
}
}