Skip to content

Commit

Permalink
new version of api for custom components
Browse files Browse the repository at this point in the history
  • Loading branch information
rambip committed Dec 26, 2023
1 parent c783575 commit 36e0098
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ edition = "2021"
[dependencies]
dioxus = "0.4.0"
dioxus-web = "0.4.0"
# rust-web-markdown = { git = "https://github.com/rambip/rust-web-markdown/" }
rust-web-markdown = {path="../rust-web-markdown"}
rust-web-markdown = { git = "https://github.com/rambip/rust-web-markdown/" }
# rust-web-markdown = {path="../rust-web-markdown"}
wasm-bindgen = "=0.2.87"
web-sys = { version = "0.3", features = ["HtmlHeadElement"] }

Expand Down
2 changes: 1 addition & 1 deletion examples/editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use dioxus::prelude::*;
use dioxus_markdown::Markdown;
use dioxus_markdown::debug::EventInfo;

#[inline_props]
#[component]
fn Logger(cx: Scope) -> Element {
let debug_info = use_shared_state::<EventInfo>(cx).unwrap();
render!{
Expand Down
50 changes: 41 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rust_web_markdown::{
render_markdown,
CowStr,
ComponentCreationError
};

use std::collections::BTreeMap;

pub type MdComponentProps<'a> = rust_web_markdown::MdComponentProps<Element<'a>>;
pub type CustomComponents<'a> = rust_web_markdown::CustomComponents<&'a ScopeState, Element<'a>>;

use core::ops::Range;

Expand Down Expand Up @@ -81,19 +83,42 @@ pub struct MarkdownMouseEvent {
pub struct MdContext<'a>(pub &'a Scoped<'a, MdProps<'a>>);


/// component store.
/// It is called when therer is a `<CustomComponent>` inside the markdown source.
/// It is basically a hashmap but more efficient for a small number of items
pub struct CustomComponents<'a>(BTreeMap<&'static str,
Box<dyn Fn(&'a ScopeState, MdComponentProps<'a>) -> Result<Element<'a>, ComponentCreationError>>
>);

impl Default for CustomComponents<'_> {
fn default() -> Self {
Self (Default::default())
}
}

impl<'a> CustomComponents<'a>
{
pub fn new() -> Self {
Self(Default::default())
}

/// register a new component.
/// The function `component` takes a context and props of type `MdComponentProps`
/// and returns html
pub fn register<F>(&mut self, name: &'static str, component: F)
where F: Fn(&'a ScopeState, MdComponentProps<'a>) -> Result<Element<'a>, ComponentCreationError> + 'static
{
self.0.insert(name, Box::new(component));
}
}

impl<'a> Context<'a, 'a> for MdContext<'a> {
type View = Element<'a>;

type Handler<T: 'a> = EventHandler<'a, T>;

type MouseEvent = MouseEvent;

type Scope = &'a ScopeState;

fn scope(self) -> Self::Scope {
self.0.scope
}

#[cfg(feature="debug")]
fn send_debug_info(self, info: Vec<String>) {
let debug = use_shared_state::<debug::EventInfo>(self.0).unwrap();
Expand Down Expand Up @@ -232,12 +257,11 @@ impl<'a> Context<'a, 'a> for MdContext<'a> {
}))
}

fn props(self) -> rust_web_markdown::MarkdownProps<'a, 'a, Self> {
fn props(self) -> rust_web_markdown::MarkdownProps<'a> {
let props = self.0.props;

rust_web_markdown::MarkdownProps {
custom_links: props.render_links.is_some(),
components: &props.components,
hard_line_breaks: props.hard_line_breaks,
wikilinks: props.wikilinks,
parse_options: props.parse_options.as_ref(),
Expand Down Expand Up @@ -277,6 +301,14 @@ impl<'a> Context<'a, 'a> for MdContext<'a> {
Ok(self.0.props.render_links.as_ref().unwrap()(self.0.scope, link))
}

fn has_custom_component(self, name: &str) -> bool {
self.0.props.components.0.get(name).is_some()
}

fn render_custom_component(self, name: &str, input: rust_web_markdown::MdComponentProps<Self::View>) -> Result<Self::View, ComponentCreationError> {
let f = self.0.props.components.0.get(name).unwrap();
f(self.0.scope, input)
}
}

#[allow(non_snake_case)]
Expand Down

0 comments on commit 36e0098

Please sign in to comment.