ftml_viewer_components/components/
sections.rs

1use super::navigation::{NavElems, SectionOrInputref};
2use crate::{
3    components::counters::{LogicalLevel, SectionCounters},
4    config::IdPrefix,
5    ts::{FragmentContinuation, OnSectionTitle, TsCont},
6};
7use flams_ontology::{
8    narration::sections::SectionLevel,
9    uris::{DocumentElementURI, NarrativeURI},
10};
11use flams_web_utils::inject_css;
12use leptos::{context::Provider, prelude::*};
13
14pub(super) fn section<V: IntoView + 'static>(
15    uri: DocumentElementURI,
16    children: impl FnOnce() -> V + Send + 'static,
17) -> impl IntoView {
18    let id = expect_context::<IdPrefix>().new_id(uri.name().last_name().as_ref());
19    NavElems::update_untracked(|ne| {
20        ne.ids.insert(id.clone(), SectionOrInputref::Section);
21    });
22    inject_css("ftml-sections", include_str!("sections.css"));
23
24    //let end = use_context::<OnSectionEnd>().map(|s| s.view(&uri));
25    let mut counters: SectionCounters = expect_context();
26    let (style, cls) = counters.next_section();
27    let lvl = counters.current_level();
28
29    view! {
30      <Provider value=IdPrefix(id.clone())>
31        <Provider value=NarrativeURI::Element(uri.clone())>
32        <Provider value=counters>
33        <div id=id style=style class=cls>
34          {
35            if let LogicalLevel::Section(lvl) = lvl {
36              leptos::either::Either::Left(FragmentContinuation::wrap(&(uri,lvl.into()) ,children()))
37            } else {
38              leptos::either::Either::Right(children())
39            }
40          }
41          //{end}
42        </div>
43        </Provider>
44        </Provider>
45      </Provider>
46    }
47}
48
49pub(super) fn title<V: IntoView + 'static>(
50    children: impl FnOnce() -> V + Send + 'static,
51) -> impl IntoView {
52    let counters: SectionCounters = expect_context();
53    let (begin, cls) = match counters.current_level() {
54        LogicalLevel::Section(l) => (
55            if let Some(NarrativeURI::Element(uri)) = use_context() {
56                expect_context::<Option<OnSectionTitle>>()
57                    .map(|s| TsCont::res_into_view(s.0.apply(&(uri, l))))
58            } else {
59                tracing::error!("Sectioning error");
60                None
61            },
62            match l {
63                SectionLevel::Part => "ftml-title-part",
64                SectionLevel::Chapter => "ftml-title-chapter",
65                SectionLevel::Section => "ftml-title-section",
66                SectionLevel::Subsection => "ftml-title-subsection",
67                SectionLevel::Subsubsection => "ftml-title-subsubsection",
68                SectionLevel::Paragraph => "ftml-title-paragraph",
69                SectionLevel::Subparagraph => "ftml-title-subparagraph",
70            },
71        ),
72        LogicalLevel::BeamerSlide => (None, "ftml-title-slide"),
73        LogicalLevel::Paragraph => (None, "ftml-title-paragraph"),
74        _ => (None, "ftml-title"),
75    };
76    view! {
77      <div class=cls>{children()}</div>
78      {begin}
79    }
80}
81
82pub(super) fn skip<V: IntoView + 'static>(
83    children: impl FnOnce() -> V + Send + 'static,
84) -> impl IntoView {
85    let mut counters: SectionCounters = expect_context();
86    match counters.current_level() {
87        LogicalLevel::Section(l) => {
88            counters.current = LogicalLevel::Section(l.inc()); //.set_section(l.inc());
89        }
90        LogicalLevel::None => {
91            counters.current = LogicalLevel::Section(counters.max); //.set_section(counters.max);
92        }
93        _ => (),
94    };
95
96    view! {
97        <Provider value=counters>
98          {children()}
99      </Provider>
100    }
101}