===== moon.pkg =====
import {
  "example/canonical/model",
  "KKKIIO/selene/app",
  "KKKIIO/selene/entity",
  "KKKIIO/selene/event",
  "KKKIIO/selene/xaml_view",
}

supported_targets = "native+js"

===== view.generated.mbt =====
// Generated by selene-xaml@0.37.3. DO NOT EDIT.
// input user fixtures/formatting/acceptance-view.xaml sha256=2b434a2360faddd869fc34044a18cc41fcffe2ae4ddbc8e60d36c73ff60a2f9f
// input moon-info fixtures/formatting/canonical-model.mbti sha256=65eb35037c6f705e3b84507853448e53987270d67a39747e91156d6471f2cf14

///|
type CanonicalFormattingState = @model.CanonicalFormattingState

///|
pub(all) enum CanonicalFormattingViewAction {
  SelectItem(String)
} derive(Eq, Debug)

///|
#warnings("-unused_value")
fn generated_rect_component(
  value : String,
  index : Int,
  path : String,
  image_region : Bool,
  corner_radius : Bool,
  non_negative : Bool,
) -> Double raise {
  @xaml_view.generated_view_rect_component(
    value,
    index,
    path,
    image_region,
    corner_radius~,
    non_negative~,
  )
}

///|
#warnings("-unused_value")
fn generated_image_drop_shadow(
  value : String,
  path : String,
) -> @xaml_view.ImageDropShadow? raise {
  @xaml_view.generated_view_image_drop_shadow(value, path)
}

///|
#warnings("-struct_never_constructed")
pub struct CanonicalFormattingView {}

///|
let generated_runtime : @xaml_view.GeneratedViewRuntime[
  CanonicalFormattingState,
  CanonicalFormattingViewAction,
] = @xaml_view.GeneratedViewRuntime::new(generated_handle_event)

///|
/// World-isolated typed actions emitted by this view.
pub let action_event_bus : @event.Events[
  @xaml_view.GeneratedViewAction[CanonicalFormattingViewAction],
] = generated_runtime.action_events()

///|
/// ViewModel components mounted by this View in the current World.
pub fn CanonicalFormattingView::view_models() -> Map[
  @entity.Entity,
  CanonicalFormattingState,
] {
  generated_runtime.view_models()
}

///|
#warnings("-unused_error_type")
fn generated_specs(
  state : CanonicalFormattingState,
) -> Array[@xaml_view.NodeSpec] raise {
  let nodes : Array[@xaml_view.NodeSpec] = []
  nodes.push({
    key: "extraordinarily-long-formatting-acceptance-root",
    parent: None,
    kind: @xaml_view.NodeKind::View,
    text: "",
    spans: [],
    source: "",
    path_geometry: None,
    active: true,
    enabled: true,
    focusable: false,
    tab_index: 0,
    focus_scope: true,
    auto_focus: false,
    navigation_up: "",
    navigation_down: "",
    navigation_left: "",
    navigation_right: "",
    automation_name: "",
    style: { ..@xaml_view.NodeStyle::default() },
    visual_state_groups: [],
  })
  let generated_seen_1 : Map[String, Bool] = Map([])
  for generated_item_1 in state.items {
    let generated_item_key_1 = generated_item_1.id
    if generated_item_key_1 == "" ||
      generated_seen_1.contains(generated_item_key_1) {
      fail("duplicate or empty key in items: " + generated_item_key_1)
    }
    generated_seen_1[generated_item_key_1] = true
    nodes.push({
      key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
      parent: Some("extraordinarily-long-formatting-acceptance-root"),
      kind: @xaml_view.NodeKind::Button,
      text: "",
      spans: [],
      source: "",
      path_geometry: None,
      active: true,
      enabled: true,
      focusable: true,
      tab_index: 10,
      focus_scope: false,
      auto_focus: true,
      navigation_up: "",
      navigation_down: "Stop",
      navigation_left: "",
      navigation_right: "",
      automation_name: "",
      style: {
        ..@xaml_view.NodeStyle::default(),
        margin_left: 4,
        margin_top: 1,
        margin_right: 2,
        margin_bottom: 3,
      },
      visual_state_groups: [],
    })
    nodes.push({
      key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-label",
      parent: Some(
        "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
      ),
      kind: @xaml_view.NodeKind::Text,
      text: generated_item_1.label,
      spans: [],
      source: "",
      path_geometry: None,
      active: true,
      enabled: true,
      focusable: false,
      tab_index: 0,
      focus_scope: false,
      auto_focus: false,
      navigation_up: "",
      navigation_down: "",
      navigation_left: "",
      navigation_right: "",
      automation_name: "",
      style: { ..@xaml_view.NodeStyle::default() },
      visual_state_groups: [],
    })
  }
  nodes
}

///|
#warnings("-unused_error_type")
fn generated_items_specs(
  state : CanonicalFormattingState,
) -> Array[@xaml_view.NodeSpec] raise {
  let nodes : Array[@xaml_view.NodeSpec] = []
  let generated_seen_1 : Map[String, Bool] = Map([])
  for generated_item_1 in state.items {
    let generated_item_key_1 = generated_item_1.id
    if generated_item_key_1 == "" ||
      generated_seen_1.contains(generated_item_key_1) {
      fail("duplicate or empty key in items: " + generated_item_key_1)
    }
    generated_seen_1[generated_item_key_1] = true
    nodes.push({
      key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
      parent: Some("extraordinarily-long-formatting-acceptance-root"),
      kind: @xaml_view.NodeKind::Button,
      text: "",
      spans: [],
      source: "",
      path_geometry: None,
      active: true,
      enabled: true,
      focusable: true,
      tab_index: 10,
      focus_scope: false,
      auto_focus: true,
      navigation_up: "",
      navigation_down: "Stop",
      navigation_left: "",
      navigation_right: "",
      automation_name: "",
      style: {
        ..@xaml_view.NodeStyle::default(),
        margin_left: 4,
        margin_top: 1,
        margin_right: 2,
        margin_bottom: 3,
      },
      visual_state_groups: [],
    })
    nodes.push({
      key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-label",
      parent: Some(
        "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
      ),
      kind: @xaml_view.NodeKind::Text,
      text: generated_item_1.label,
      spans: [],
      source: "",
      path_geometry: None,
      active: true,
      enabled: true,
      focusable: false,
      tab_index: 0,
      focus_scope: false,
      auto_focus: false,
      navigation_up: "",
      navigation_down: "",
      navigation_left: "",
      navigation_right: "",
      automation_name: "",
      style: { ..@xaml_view.NodeStyle::default() },
      visual_state_groups: [],
    })
  }
  nodes
}

///|
#warnings("-unused_error_type")
fn generated_items_item_specs(
  state : CanonicalFormattingState,
  generated_requested_key : String,
) -> Array[@xaml_view.NodeSpec] raise {
  let nodes : Array[@xaml_view.NodeSpec] = []
  let mut generated_matched_1 = false
  let generated_seen_1 : Map[String, Bool] = Map([])
  for generated_item_1 in state.items {
    let generated_item_key_1 = generated_item_1.id
    if generated_item_key_1 == "" ||
      generated_seen_1.contains(generated_item_key_1) {
      fail("duplicate or empty key in items: " + generated_item_key_1)
    }
    generated_seen_1[generated_item_key_1] = true
    if generated_item_key_1 == generated_requested_key {
      generated_matched_1 = true
      nodes.push({
        key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
        parent: Some("extraordinarily-long-formatting-acceptance-root"),
        kind: @xaml_view.NodeKind::Button,
        text: "",
        spans: [],
        source: "",
        path_geometry: None,
        active: true,
        enabled: true,
        focusable: true,
        tab_index: 10,
        focus_scope: false,
        auto_focus: true,
        navigation_up: "",
        navigation_down: "Stop",
        navigation_left: "",
        navigation_right: "",
        automation_name: "",
        style: {
          ..@xaml_view.NodeStyle::default(),
          margin_left: 4,
          margin_top: 1,
          margin_right: 2,
          margin_bottom: 3,
        },
        visual_state_groups: [],
      })
      nodes.push({
        key: "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-label",
        parent: Some(
          "extraordinarily-long-formatting-acceptance-root/items:\{generated_item_key_1}/extraordinarily-long-formatting-acceptance-button",
        ),
        kind: @xaml_view.NodeKind::Text,
        text: generated_item_1.label,
        spans: [],
        source: "",
        path_geometry: None,
        active: true,
        enabled: true,
        focusable: false,
        tab_index: 0,
        focus_scope: false,
        auto_focus: false,
        navigation_up: "",
        navigation_down: "",
        navigation_left: "",
        navigation_right: "",
        automation_name: "",
        style: { ..@xaml_view.NodeStyle::default() },
        visual_state_groups: [],
      })
    }
  }
  if !generated_matched_1 {
    fail(
      "generated collection item key does not exist: " + generated_requested_key,
    )
  }
  nodes
}

///|
/// Refreshes the complete keyed items presentation collection.
pub fn CanonicalFormattingView::refresh_items(
  root : @entity.Entity,
) -> Unit raise {
  generated_runtime.refresh_region(root, "items", generated_items_specs)
  let generated_keys : Array[String] = []
  for item in generated_runtime.view_model(root).items {
    generated_keys.push(item.id)
  }
  generated_runtime.index_collection(root, "items", generated_keys)
}

///|
/// Refreshes one keyed CanonicalFormattingItem presentation subtree.
/// Call refresh_items when the item key or collection structure changed.
pub fn CanonicalFormattingView::refresh_items_item(
  root : @entity.Entity,
  key : String,
) -> Unit raise {
  let generated_key = key
  ignore(generated_runtime.collection_index(root, "items", generated_key))
  generated_runtime.refresh_region_slice(
    root,
    "items",
    "/items:" + generated_key + "/",
    state => generated_items_item_specs(state, generated_key),
  )
}

///|
/// Mounts this view on an alive root entity in the current world.
/// Destroying the root ends the view lifetime.
pub fn CanonicalFormattingView::mount(
  entity : @entity.Entity,
  view_model : CanonicalFormattingState,
) -> Unit raise {
  let desired = generated_specs(view_model)
  generated_runtime.mount(entity, view_model, desired)
  generated_runtime.index_region(entity, "items", "/items:")
  let generated_items_keys : Array[String] = []
  for item in view_model.items {
    generated_items_keys.push(item.id)
  }
  generated_runtime.index_collection(entity, "items", generated_items_keys)
}

///|
/// Releases this View while leaving its caller-owned root entity alive.
pub fn CanonicalFormattingView::unmount(entity : @entity.Entity) -> Unit raise {
  generated_runtime.unmount(entity)
}

///|
/// Refreshes the complete presentation from the current ViewModel component.
pub fn CanonicalFormattingView::refresh(entity : @entity.Entity) -> Unit raise {
  let view_model = generated_runtime.view_model(entity)
  let desired = generated_specs(view_model)
  generated_runtime.refresh(entity, desired)
  generated_runtime.index_region(entity, "items", "/items:")
  let generated_items_keys : Array[String] = []
  for item in view_model.items {
    generated_items_keys.push(item.id)
  }
  generated_runtime.index_collection(entity, "items", generated_items_keys)
}

///|
/// Reconciles this mounted View with a new ViewModel.
pub fn CanonicalFormattingView::replace(
  entity : @entity.Entity,
  view_model : CanonicalFormattingState,
) -> Unit raise {
  let desired = generated_specs(view_model)
  generated_runtime.replace(entity, view_model, desired)
  let generated_items_keys : Array[String] = []
  for item in view_model.items {
    generated_items_keys.push(item.id)
  }
  generated_runtime.index_collection(entity, "items", generated_items_keys)
}

///|
fn generated_handle_event(
  view_model : CanonicalFormattingState,
  event : @xaml_view.UiEvent,
) -> CanonicalFormattingViewAction? {
  if event.kind == @xaml_view.UiEventKind::Click {
    for generated_action_item in view_model.items {
      let generated_action_key = generated_action_item.id
      let generated_action_node_key = "extraordinarily-long-formatting-acceptance-root/items:\{generated_action_key}/extraordinarily-long-formatting-acceptance-button"
      if event.key == generated_action_node_key {
        return Some(
          CanonicalFormattingViewAction::SelectItem(generated_action_key),
        )
      }
    }
  }
  None
}

///|
/// Installs this View below a root generated View that owns the shared host.
pub fn component_plugin(app : @app.App) -> @app.App {
  generated_runtime.install_component(
    app, "selene_xaml_CanonicalFormattingView_events",
  )
}

///|
/// Installs the shared host and this View package component tree.
pub fn plugin(app : @app.App) -> @app.App {
  app.add_plugin(@xaml_view.plugin).add_plugin(component_plugin)
}

===== view.generated.mbt.map.json =====
{
  "mappings": [
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 368,
      "generated_offset": 2496,
      "length": 11
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 406,
      "generated_offset": 2541,
      "length": 19
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 755,
      "generated_offset": 3983,
      "length": 22
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 368,
      "generated_offset": 4708,
      "length": 11
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 406,
      "generated_offset": 4753,
      "length": 19
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 755,
      "generated_offset": 6195,
      "length": 22
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 368,
      "generated_offset": 6999,
      "length": 11
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 406,
      "generated_offset": 7044,
      "length": 19
    },
    {
      "source": "fixtures/formatting/acceptance-view.xaml",
      "original_offset": 755,
      "generated_offset": 8646,
      "length": 22
    }
  ]
}

