Skip to content

Commit

Permalink
refactor(Frontend): 🚧 Refactor frontend style & code
Browse files Browse the repository at this point in the history
  • Loading branch information
KAIYOHUGO committed Aug 1, 2024
1 parent fe7845a commit 9ab9969
Show file tree
Hide file tree
Showing 17 changed files with 423 additions and 393 deletions.
4 changes: 4 additions & 0 deletions frontend/src/components/badge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use leptos::*;

#[component]
pub fn Badge() -> impl IntoView {}
35 changes: 19 additions & 16 deletions frontend/src/components/button.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
use leptos::{ev::MouseEvent, *};
use leptos::*;
use tailwind_fuse::*;

use super::Merge;
#[derive(TwVariant)]
pub enum ButtonVariant {
#[tw(default, class = "text-background bg-primary")]
Primary,
#[tw(class = "text-background bg-secondary")]
Secondary,
#[tw(class = "text-slate-950 bg-accent")]
Accent,
}

#[component]
pub fn Button(
#[prop(into, default = "button".to_owned().into())] kind: MaybeSignal<
#[prop(into, default = "button".to_owned().into())] type_: MaybeSignal<
String,
>,
#[prop(into, default = false.into())] disabled: MaybeSignal<bool>,
#[prop(into, optional)] on_click: Option<Callback<MouseEvent>>,
#[prop(into, optional)] variant: ButtonVariant,
#[prop(into, optional)] disabled: MaybeSignal<bool>,
#[prop(into, optional)] id: Option<AttributeValue>,
#[prop(into, optional)] class: Option<AttributeValue>,
#[prop(into, default = "".into())] class: String,
children: Children,
) -> impl IntoView {
view! {
<button
class=Merge(
class,
"text-background bg-primary p-2 rounded-md disabled:cursor-not-allowed disabled:brightness-50",
class=tw_join!(
class, variant,
"p-2 hover:brightness-110 disabled:cursor-not-allowed disabled:brightness-50 transition-all",
)

type=kind
type=type_
disabled=disabled
id=id
on:click=move |e| {
if let Some(f) = on_click {
e.stop_propagation();
f(e);
}
}
>

{children()}
Expand Down
42 changes: 0 additions & 42 deletions frontend/src/components/catch.rs

This file was deleted.

156 changes: 81 additions & 75 deletions frontend/src/components/editor.rs
Original file line number Diff line number Diff line change
@@ -1,91 +1,97 @@
use std::{collections::HashMap, path};

use gloo::console::console;
use js_sys::{Object, Reflect};
use leptos::{leptos_dom::logging::console_log, *};
// #[derive(Debug, Clone, Copy)]
// pub enum Language {
// Unselected,
// Rust,
// Python,
// JavaScript,
// C,
// }
use wasm_bindgen::prelude::*;
use web_sys::Event;

// impl Language {
// fn to_ident(self) -> Option<&'static str> {
// match self {
// Self::Unselected => None,
// Self::Rust => Some("rust"),
// Self::Python => Some("python"),
// Self::JavaScript => Some("javascript"),
// Self::C => Some("c"),
// }
// }
// }
#[wasm_bindgen]
extern "C" {
fn require(modules: Vec<String>, on_load: &Closure<dyn FnMut()>);

pub fn get_editor_code() -> Option<String> {
js_sys::eval("editor_inject_1083hdkjla.getValue()")
.ok()?
.as_string()
#[wasm_bindgen(js_namespace = require, js_name="config")]
fn loader_config(config: Object);
}

fn uuid_to_lang(uuid: &str) -> &'static str {
match uuid {
"7daff707-26b5-4153-90ae-9858b9fd9619" => "c",
"8a9e1daf-ff89-42c3-b011-bf6fb4bd8b26" => "cpp",
"1c41598f-e253-4f81-9ef5-d50bf1e4e74f" => "lua",
_ => "javascript",
}
#[wasm_bindgen]
extern "C" {
type Monaco;

#[wasm_bindgen(js_name = "monaco")]
static MONACO: Monaco;

type MonacoEditor;

#[wasm_bindgen(method, getter)]
fn editor(this: &Monaco) -> MonacoEditor;

/// Create a new editor under `domElement`.
/// `domElement` should be empty (not contain other dom nodes).
/// The editor will read the size of `domElement`.
#[wasm_bindgen(method, js_name = "create")]
fn create_editor(
this: &MonacoEditor,
el: web_sys::HtmlElement,
config: Option<Object>,
);
}

#[component]
pub fn Editor(
#[prop(into, default = "".to_owned().into())] language: MaybeSignal<String>,
#[prop(into, optional)] on_submit: Option<Callback<String>>,
#[prop(into, default = "".to_owned())] class: String,
) -> impl IntoView {
/// compacted version of the script
/// ```javascript
/// (async() => {
/// let parent = null;
/// while(parent==null || typeof monaco=='undefined'){
/// await new Promise(r=>setTimeout(r, 5));
/// parent = document.getElementById('editor-inject-1083hdkjla');
/// }
///
/// while(parent.firstChild) parent.removeChild(parent.firstChild);
///
/// let child = document.createElement('div');
/// parent.appendChild(child);
/// child.style = 'width:100%;height:65vh';
///
/// monaco.editor.setTheme('vs-dark');
/// editor_inject_1083hdkjla = monaco.editor.create(child, {
/// value: '',
/// language: 'pro-lang'
/// });
/// })()
/// ```
static EDITOR_SCRIPT_SOURCE: &str =
"(async() => {let parent=null;while(parent==null || typeof \
monaco=='undefined'){await new Promise(r=>setTimeout(r, \
5));parent=document.getElementById('editor-inject-1083hdkjla');\
}while(parent.firstChild) parent.removeChild(parent.firstChild);let \
child=document.createElement('div');parent.appendChild(child);child.\
style='width:100%;height:65vh'; \
monaco.editor.setTheme('vs-dark');editor_inject_1083hdkjla=monaco.\
editor.create(child, {value:'',language:'pro-lang'});})()";
let node_ref = create_node_ref::<html::Div>();
let on_load = move |_| {
let c = Object::new();
let paths = Object::new();
Reflect::set(
&*paths,
&"vs".into(),
&"https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs".into(),
).unwrap();
Reflect::set(&*c, &"paths".into(), &*paths).unwrap();
loader_config(c);

create_effect(move |_| {
js_sys::eval(
&EDITOR_SCRIPT_SOURCE
.replace("pro-lang", uuid_to_lang(&language())),
)
.unwrap();
});
let config = Object::new();
Reflect::set(&*config, &"theme".into(), &"vs-dark".into()).unwrap();
Reflect::set(&*config, &"language".into(), &"rust".into()).unwrap();

let init_monaco = Closure::once(move || {
MONACO.editor().create_editor(
(**(node_ref.get_untracked().unwrap())).clone(),
Some(config),
);
});

require(vec!["vs/editor/editor.main".into()], &init_monaco);
init_monaco.forget();
};
view! {
<div>
<div
id="editor-inject-1083hdkjla"
style="width: 100%; border: 1px solid grey"
></div>
</div>
<div node_ref=node_ref class=class></div>
<DynamicLoad
src="https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs/loader.js"
on_load
/>
}
}

#[component]
fn DynamicLoad(
#[prop(into)] src: String,
on_load: impl FnMut(Event) + 'static,
) -> impl IntoView {
let (load_src, set_load_src) = create_signal(None);
let node_ref = create_node_ref::<html::Script>();
node_ref.on_load(move |_| {
set_load_src(Some(src));
});
view! { <script on:load=on_load src=load_src node_ref=node_ref></script> }
}

pub fn get_editor_code() -> Option<String> {
js_sys::eval("editor_inject_1083hdkjla.getValue()")
.ok()?
.as_string()
}
65 changes: 49 additions & 16 deletions frontend/src/components/input.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,60 @@
use leptos::*;
use tailwind_fuse::tw_merge;

#[derive(Debug, Default, Clone, Copy)]
pub enum InputVariant {
#[default]
Text,
Password,
Textarea,
}

#[component]
pub fn TextInput(
#[prop(into, default = "text".to_owned().into())] kind: MaybeProp<String>,
pub fn Input(
#[prop(into)] value: RwSignal<String>,
#[prop(into, optional)] placeholder: Option<AttributeValue>,
#[prop(into, optional)] id: Option<AttributeValue>,
#[prop(into, optional)] variant: InputVariant,
#[prop(into, default = "".into())] class: String,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView {
let (get, set) = value.split();
view! {
<input
class=tw_merge!(
class,
"text-text outline-none p-2 bg-slate-800 border-b-2 border-slate-800 focus:border-primary transition-colors duration-300",
)
match variant {
InputVariant::Text => view! {
<input
class=tw_merge!(
class,
"text-text outline-none p-2 bg-slate-800 border-b-2 border-slate-800 focus:border-primary transition-colors duration-300",
)

type="text"
prop:value=get
on:input=move |e| set(event_target_value(&e))
{..attrs}
/>
}.into_view(),
InputVariant::Password => view! {
<input
class=tw_merge!(
class,
"text-text outline-none p-2 bg-slate-800 border-b-2 border-slate-800 focus:border-primary transition-colors duration-300",
)

type="password"
prop:value=get
on:input=move |e| set(event_target_value(&e))
{..attrs}
/>
}.into_view(),
InputVariant::Textarea => view! {
<textarea
class=tw_merge!(
class,
"text-text outline-none p-2 bg-slate-800 border-b-2 border-slate-800 focus:border-primary transition-colors duration-300",
)

id=id
type=kind
prop:value=get
placeholder=placeholder
on:input=move |e| set(event_target_value(&e))
/>
prop:value=get
on:input=move |e| set(event_target_value(&e))
{..attrs}
></textarea>
}.into_view(),
}
}
10 changes: 5 additions & 5 deletions frontend/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
pub mod button;
pub mod catch;
pub mod editor;
pub mod footer;
pub mod highlight;
pub mod input;
pub mod markdown;
pub mod modal;
pub mod navbar;
pub mod redirect_if;
pub mod select;
pub mod text_input;
pub mod toast;
pub mod toggle;
pub mod badge;

pub use button::Button;
pub use catch::{provide_catch, use_ball, use_has_ball, CatchBoundary};
pub use button::{Button, ButtonVariant};
pub use editor::Editor;
pub use footer::Footer;
pub use highlight::Highlight;
pub use input::{Input, InputVariant};
pub use markdown::Markdown;
pub use modal::{Modal, ModalLevel};
pub use navbar::Navbar;
pub use redirect_if::RedirectIf;
pub use select::{Select, SelectOption};
pub use text_input::TextInput;
pub use toast::{toast, ProvideToast};
pub use badge::Badge;
Loading

0 comments on commit 9ab9969

Please sign in to comment.