-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add examples for yew showing keymapping and button usage
- Loading branch information
1 parent
cac3ea1
commit f913990
Showing
10 changed files
with
293 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
[workspace] | ||
members = ["yew"] | ||
members = ["yew", "yew_events_external", "yew_events_keymapping"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
target | ||
dist | ||
dist/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "yew_events" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[dependencies] | ||
monaco = { path = "../..", features = ["yew-components"] } | ||
wasm-bindgen = "0.2" | ||
yew = { version = "0.20", features = ["csr"] } | ||
|
||
# Used for the randomess, not needed usually. | ||
getrandom = { version = "0.2", features = ["js"] } | ||
rand = "0.8" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Rust Monaco - Yew Key Mapping Events Example | ||
|
||
This is an example of how to use [Rust Monaco]() with Yew, and using a button to control the editor. | ||
|
||
To use, run `trunk serve`, then access `http://127.0.0.1:8080`. | ||
|
||
Press the button to see the editor change. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<meta charset="utf-8" /> | ||
<title>Yew Monaco</title> | ||
|
||
<style> | ||
.full-height { | ||
height: 100%; | ||
} | ||
#code-editor, #event-log-wrapper { | ||
float: left; | ||
width: 50%; | ||
height: 100%; | ||
} | ||
#event-log { | ||
margin-left: 20px; | ||
} | ||
#code-wrapper { | ||
height: 100%; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body style="height: 100vh; margin: 0; overflow: hidden;"></body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
use monaco::{ | ||
api::{CodeEditorOptions, TextModel}, | ||
sys::editor::BuiltinTheme, | ||
yew::CodeEditor, | ||
}; | ||
|
||
use rand::{distributions::Alphanumeric, Rng}; | ||
use yew::prelude::*; | ||
|
||
const CONTENT: &str = include_str!("main.rs"); | ||
|
||
fn get_options() -> CodeEditorOptions { | ||
CodeEditorOptions::default() | ||
.with_language("rust".to_owned()) | ||
.with_value(CONTENT.to_owned()) | ||
.with_builtin_theme(BuiltinTheme::VsDark) | ||
.with_automatic_layout(true) | ||
} | ||
|
||
#[derive(PartialEq, Properties)] | ||
pub struct CustomEditorProps { | ||
text_model: TextModel, | ||
} | ||
|
||
/// This is really just a helper component, so we can pass in props easier. | ||
/// It makes it much easier to use, as we can pass in what we need, and it | ||
/// will only re-render if the props change. | ||
#[function_component(CustomEditor)] | ||
pub fn custom_editor(props: &CustomEditorProps) -> Html { | ||
let CustomEditorProps { text_model } = props; | ||
|
||
html! { | ||
<CodeEditor classes={"full-height"} options={ get_options().to_sys_options() } model={text_model.clone()} /> | ||
} | ||
} | ||
|
||
// inefficient and silly, but fine for demo :-) | ||
fn random_string() -> String { | ||
rand::thread_rng() | ||
.sample_iter(&Alphanumeric) | ||
.take(50) | ||
.map(char::from) | ||
.collect() | ||
} | ||
|
||
#[function_component(App)] | ||
fn app() -> Html { | ||
// We need to create a new text model, so we can pass it to Monaco. | ||
// We use use_state_eq, as this allows us to only use it when it changes. | ||
let text_model = | ||
use_state_eq(|| TextModel::create(&random_string(), Some("rust"), None).unwrap()); | ||
|
||
// Here we define what we want to do when we click the button, which is bound to | ||
// the button below. We use the `use_callback` function in Yew to bind the | ||
// function to the button. We can then clone the text model, and use it in | ||
// the callback to set the value to whatever we want. | ||
let on_run_clicked = { | ||
let text_model = text_model.clone(); | ||
use_callback( | ||
move |_, text_model| { | ||
let s: String = random_string(); | ||
// Here we have full access to the text model. We can do whatever we want with | ||
// it. For this example, we'll just set the value to a random | ||
// string. | ||
text_model.set_value(&s); | ||
}, | ||
text_model, | ||
) | ||
}; | ||
|
||
html! { | ||
<div id="code-wrapper"> | ||
<div id="code-editor"> | ||
<CustomEditor text_model={(*text_model).clone()} /> | ||
</div> | ||
<div id="event-log-wrapper"> | ||
<div id="event-log"> | ||
<button onclick={on_run_clicked}>{ "Random code" }</button> | ||
</div> | ||
</div> | ||
</div> | ||
} | ||
} | ||
|
||
fn main() { | ||
yew::Renderer::<App>::new().render(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "yew_events" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[dependencies] | ||
monaco = { path = "../..", features = ["yew-components"] } | ||
wasm-bindgen = "0.2" | ||
yew = { version = "0.20", features = ["csr"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Rust Monaco - Yew Key Mapping Events Example | ||
|
||
This is an example of how to use [Rust Monaco]() with Yew, and using `on_editor_created` to add key mappings. | ||
|
||
To use, run `trunk serve`, then access `http://127.0.0.1:8080`. | ||
|
||
Type some code, then press Ctrl+Enter (Linux/Windows) or Cmd+Enter (Mac) to have the code reflect on the right hand | ||
side. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<meta charset="utf-8" /> | ||
<title>Yew Monaco</title> | ||
|
||
<style> | ||
.full-height { | ||
height: 100%; | ||
} | ||
#code-editor, #event-log-wrapper { | ||
float: left; | ||
width: 50%; | ||
height: 100%; | ||
} | ||
#event-log { | ||
margin-left: 20px; | ||
} | ||
#code-wrapper { | ||
height: 100%; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body style="height: 100vh; margin: 0; overflow: hidden;"></body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
use monaco::{ | ||
api::{CodeEditorOptions, TextModel}, | ||
sys::editor::{BuiltinTheme, IStandaloneCodeEditor}, | ||
yew::{CodeEditor, CodeEditorLink}, | ||
}; | ||
use wasm_bindgen::closure::Closure; | ||
use yew::prelude::*; | ||
|
||
use wasm_bindgen::JsCast; | ||
|
||
const CONTENT: &str = include_str!("main.rs"); | ||
|
||
fn get_options() -> CodeEditorOptions { | ||
CodeEditorOptions::default() | ||
.with_language("rust".to_owned()) | ||
.with_value(CONTENT.to_owned()) | ||
.with_builtin_theme(BuiltinTheme::VsDark) | ||
.with_automatic_layout(true) | ||
} | ||
|
||
#[derive(PartialEq, Properties)] | ||
pub struct CustomEditorProps { | ||
on_editor_created: Callback<CodeEditorLink>, | ||
text_model: TextModel, | ||
} | ||
|
||
/// | ||
/// This is really just a helper component, so we can pass in props easier. | ||
/// It makes it much easier to use, as we can pass in what we need, and it | ||
/// will only re-render if the props change. | ||
/// | ||
#[function_component(CustomEditor)] | ||
pub fn custom_editor(props: &CustomEditorProps) -> Html { | ||
let CustomEditorProps { | ||
on_editor_created, | ||
text_model, | ||
} = props; | ||
|
||
html! { | ||
<CodeEditor classes={"full-height"} options={ get_options().to_sys_options() } {on_editor_created} model={text_model.clone()} /> | ||
} | ||
} | ||
|
||
#[function_component(App)] | ||
fn app() -> Html { | ||
// We need to create a new text model, so we can pass it to Monaco. | ||
// We use use_state_eq, as this allows us to only use it when it changes. | ||
let text_model = use_state_eq(|| TextModel::create(CONTENT, Some("rust"), None).unwrap()); | ||
|
||
// This is the current code output. As it's static from the example, we set it to the content. | ||
let code = use_state_eq(|| String::from(CONTENT)); | ||
|
||
// Here we setup the Callback for when the editor is created. | ||
let on_editor_created = { | ||
// We need to clone the text_model/code so we can use them. | ||
let text_model = text_model.clone(); | ||
let code = code.clone(); | ||
|
||
// This is a javascript closure, used to pass to Monaco, using wasm-bindgen. | ||
let js_closure = { | ||
let text_model = text_model.clone(); | ||
|
||
// We update the code state when the Monaco model changes. | ||
// See https://yew.rs/docs/0.20.0/concepts/function-components/pre-defined-hooks | ||
Closure::<dyn Fn()>::new(move || { | ||
code.set(text_model.get_value()); | ||
}) | ||
}; | ||
|
||
// Here we define our callback, we use use_callback as we want to re-render when dependencies change. | ||
// See https://yew.rs/docs/concepts/function-components/state#general-view-of-how-to-store-state | ||
use_callback( | ||
move |editor_link: CodeEditorLink, _text_model| { | ||
editor_link.with_editor(|editor| { | ||
// Registers Ctrl/Cmd + Enter hotkey | ||
let keycode = monaco::sys::KeyCode::Enter.to_value() | ||
| (monaco::sys::KeyMod::ctrl_cmd() as u32); | ||
let raw_editor: &IStandaloneCodeEditor = editor.as_ref(); | ||
|
||
raw_editor.add_command( | ||
keycode.into(), | ||
js_closure.as_ref().unchecked_ref(), | ||
None, | ||
); | ||
}); | ||
}, | ||
text_model, | ||
) | ||
}; | ||
html! { | ||
<div id="code-wrapper"> | ||
<div id="code-editor"> | ||
<CustomEditor {on_editor_created} text_model={(*text_model).clone()} /> | ||
</div> | ||
<div id="event-log-wrapper"> | ||
<div id="event-log"> | ||
<h2>{"Code (press CTRL+Enter / Command+Enter to view)"}</h2> | ||
<pre>{code.to_string()}</pre> | ||
</div> | ||
</div> | ||
</div> | ||
} | ||
} | ||
|
||
fn main() { | ||
yew::Renderer::<App>::new().render(); | ||
} |