ftml_viewer_components/components/
sections.rs1use 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 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 </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()); }
90 LogicalLevel::None => {
91 counters.current = LogicalLevel::Section(counters.max); }
93 _ => (),
94 };
95
96 view! {
97 <Provider value=counters>
98 {children()}
99 </Provider>
100 }
101}