Skip to content

Commit

Permalink
Merge pull request #25 from azriel91/feature/playground-ui-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
azriel91 authored Jul 20, 2024
2 parents 50365c2 + f663b51 commit e6246b4
Show file tree
Hide file tree
Showing 11 changed files with 627 additions and 316 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Add `ThemeAttr::Cursor` for better support for [cursor styling].
* Support `dasharray:5,2,3,2..` in `stroke_style` in SVG.
* Support stroke style for ellipse elements in SVG.
* Reimplement playground for better responsive layout.

[monaco]: https://github.com/microsoft/monaco-editor
[rust-monaco]: https://github.com/siku2/rust-monaco
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@
Try it yourself: ([demo_1][demo_1], [demo_2][demo_2])

Original concept:
<details open><summary>Example</summary>

![](./doc/example.svg)

</details>

<details><summary>Original Concept</summary>

https://user-images.githubusercontent.com/2993230/253878816-0729970f-651f-45ef-a986-470f383b8018.mp4

</details>


# Usage

Expand Down Expand Up @@ -59,7 +67,7 @@ For server side rendering, the `"server_side_graphviz"` feature needs to be pass
* [x] Split crate into multiple subcrates.
* [ ] Split `app::info_graph::InfoGraph` into smaller components.
* [ ] Probably get rid of `main.scss` and replace with tailwind classes.
* [x] Get rid of `main.scss` and replace with tailwind classes.
* [x] Inline styles in SVG.
* [x] Inline font in SVG styles.
* [ ] Change `rt/into_graphviz_dot_src/info_graph.rs` to write to a buffer, instead of individual strings.
Expand All @@ -73,4 +81,4 @@ For server side rendering, the `"server_side_graphviz"` feature needs to be pass
- [ ] Link to gist

[demo_1]: https://azriel.im/dot_ix/
[demo_2]: https://azriel.im/dot_ix/?src=BYSwpgTghhDGwE8BcAoABGqS0G8C%2B6aARtvobKQRgCaUopjUDmYAzqhlCWgNpQA0xALqEiFXkUGwRGWLV6xB1ESgB2Ae2pgA%2BqqgBbNh0zYAgqOwAhctgDCheQBF6AF2BhDxwxBbaA7iBu2kRQrGDYLhAArmCErC4IADZGhBgaWtpaAGZQUYku7KkYaGAAHpFYaLBREKzqEAC0AA7qIKoukGgQ6lGqWtQNiUxFGPowTG3apdgALEWMvtm5%2BYXFxWUV2NW19c2t7ZBFlThorMBQTTqw6on12EwQYGCqaFTFJCOn55fa17cQ2CIiRin3i3QA1joAtQ3NgAEygyLqSHaeJJcJoaihdzUT4baDYAB8DU%2BGB4ADJCU0oG4hEgoKoQGMOg0eGDkWAGlizuoslkwi4Gvp1AA3HQAZlY2kSbTAMG0bSybUCYBka2K2zqjRabQ6EFJXR6fUYg2Gay4xjWZwuVxudzQDyeqkREJ01oyGggY0S2AAbAAGf2fJWJRKo84e%2Bre7AAVkD9FgrHYaGJhAAApCEFloIZWKckZCudjefywILhWLcEV-QBSYondmF7nAEsC7D%2BgDcryKAEZA3WGwXOc3W2XZgAOLtvAhAA
[demo_2]: https://azriel.im/dot_ix/#src=LQhQBMEsCcFMGMAukD2A7AXAAgG62svAIYA2oAFpPkdPOQJ4ahZZEDuAzkyy+xwPoBzEigBGpbj16chI8SX6QiAW37QUJWP1GwiaDolIBrbAG8AvsymsZwsaUUq1GrZH2G08WGctS+a2EFUTCs-GTgg9H4cAAd4SWsbAQjg6Lj+IgTEpIDItDT4DP4OchpYcGKAV1E0WEQfUOz-FKjYwqJ+cFgcKpq6huyeZsDUtqKY9QqOatr6rAtGsOSR1vTRLMThvILtTu7e2YHBnJb8sdF+CZQpmf753ybwlbP0+MXrLdHXvZ7pvrmFscTs8doUrjd-g1QGhrlo0CpYFwrHxsAAiACCyiIAC90FgAOqwURYADK+BwkC8HFRyNscgkWFRAB5RAA+ADi9JIWAASoiUJVaIimQB6NmM2kCOzyRyqdSabS6dzGNEASXRAFleS4adIpVzZc4FW4DHovGrNdrNLrgXk0SzWXy8qRefzBVTReKbZ9VvFGQA1AAKAGFvU9tmNMoyncEsOiw8sI+kOiUyhDDoyABQk0pwcAASlJt0QCdyX3aPwOd1RmYAIgBRf2FknF0unHYdcFVuY1wM8gDytebrclZd92jRMbxACE2yDzpW-hmaw2m0X-nOk4ULl2l9XM33B8ON6P22M-aip2gsKHT-Pvl1fsW0XXG8fZpvy-wwZNuy-D0O64fqA0KwnsHDwEiLAGLAMT8AAjGiABibjgFgoiVIIpbSg4Shyi4ip6KaJAmIyfDALAJBEAYlI6ERhgkcAHDkpSsDAPKsDYQaeFGq4yqeN4ZGcBRVE0fAdHKoxCAAEzsTqd5bmi8EAOzSQAdAAzPBakAAy6SK8EAGyfuOKa5uUf6Mip6labp+nSdJJkvBWj6Wai1madpAAs9kaU5OwXK5e49h5tmGb5-nnouz5WapnlqQAHBFClfp2v7BUpcW2fBek6SK0l+Sl447ulMXuVl2nwepeUFZF3y7mVoWVT5NWFaBXT8LAygoAAVpAUFJNggCAZIA8H+jjhJDYIAPBuAPD743cU4HGEZJpGALwbgAjO-N9gKDxS0mh45pYBtRWYEdgB-uydBTTYACPuXZGxTmemdyrYAHrtjXqY7OUUQUxa9722l+gX7BlR1vXdD7A79YMfWeyaXKVkKg-9PpfSV1yWX94OFD+6Mg5joDlIIiKSCjHYPWm3b8Bk4apdFiMANqk-dqZ5t2AA0AOmXTswALpY0ULMWcFVNM2s3N3IzNNc4LT2IBzovbuLiB8zD94VjLlPU4mX6FD9DMKwLj3s5zX265D-x8-zHR67MItS19aW4zFkva1zNt1PL9tkw1Fv80DT7-Hbruo-DTv617C7u3LJsBaHssqzHUVR0Hn2gnHlku6nSfm7MnvB2nPu8yBH0TYaS0ScRRgp6Xu0EftZqCZnNeLQRFcMUYeeyNtZd1-xXgJ-4zf4cafdaFrWfJtgTcLcPfGmgJnew+0luGIIA2r138jYFIphYPCyiCaiE2olgDwb202+JLv++H20J9n0QgjFKvWiPtv18ImippE1gr5NvfVgN7fy0OCd+e9P6MmAb-AC+YAHtS0KvAag8Z68WWpXbe9MN4TQHnSbutcR7z0OiwTBj9N6kBwfnC+QJsgkKfm0ChE91ZGxBrQgoDCl7fRzncHgrDgE-HYWrXYUdL5YF4S-fh-MzYBwzDwoB4jHwCK3OMBGMjRFyMfiAyYijAbpxBsQ9RRM47aPHDjWWl8xEaKMSBQQ0AiAxHIBSbEGRECIGgANGIRB4BV26l0bANBbH0H4IgaSIFEDkC6t4KwBh6CaAGiwGEHUugADMiCVBIIgOJPBYAAA9XFRgAOTwEFBwFA0BgAxBQG4RA+AsDqEqGgLo4BgAkEEPkxohNX6wBSWkjJGwsA5LydgIpbjSnlMqWgap0BGiUHAF0U6AAyGZcz5j9NybY7ASzYDXgeKrJRZkKbC3Hhw62XC5gACpNloEaAbfZrNDkG39pZC5kBZlbOuRHOGGt7kfOxkrbAzzXlXKWGQnaLcFRt2MNXFBe1R7-Mue8yhcNk5HMEY7MxWAAVzIRYwoRpyU4cLRuizFbzgUcKkZrA2pinnwuBUPVB9cBL4tRXCl5WKpAkEgIIcgcx5kcq5Ygd4STIAkAUKmDqMJoBYkmlgfJOUdJtMSEKkV5MOrkBQHgaA2B8kAFZ5WCuFaK0oHUkkoCKVwGVcqFXWCVYaogHVPHIDwFqy17wDDqCMFoMVcJSlSq1V5HSerEhupQB6lVWg1Uaq1RpANVqpDBtDV6jISBIBOplbqwN1h42esQDEwS4AUAuPKO8Dxsy3CCCjbGwa7wmRMn+Xy7lrrSgxC0PADQpTsD0EoiINg7wBSIA5bUb8bbNVYE7SKlAPapCNDgCU90WgbEChiNgeZM6BRCiEHUmI1ba0YvrQKoNTaW3DuwAYdAsBe2VH7W4I9IgR2ntqNiia-zV1zo3Yu7Fpxn1unXQuyoW7SVqz6TWutnKG1BtcSG7NuaT0aBedO54y7TjbpA-yxtdib3tqwBwKi1SL1XsHa229J6cPnoA3sr9eQP2CPWBipDZGdYUeCMXHgIN5nBWQ7u0D+7M2HqHUR9CJBKikesH2gdGGR2iEE8JuNEGE05s0DBjl4AqN7PJncmKZz2P0bdqc-5Wmhg-OUWHDMmniwqZ0cIjF+ndk6MLncUz-xzMmL+VZsz2nTa6I0+xoAA
45 changes: 23 additions & 22 deletions crate/model/src/theme/theme_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,16 @@ pub enum ThemeAttr {
/// [`HighlightState`]: crate::theme::HighlightState
FillShade,
/// Shade for the background when an element is not focused /
/// hovered over, e.g. `"300"` for nodes, "800" for edges.
/// hovered over, e.g. `"300"` for nodes, `"800"` for edges.
FillShadeNormal,
/// Shade for the background when an element is focused, e.g.
/// `"200"` for nodes, "700" for edges.
/// `"200"` for nodes, `"700"` for edges.
FillShadeFocus,
/// Shade for the background when an element has the cursor
/// hovering over it, e.g. `"100"` for nodes, "600" for edges.
/// hovering over it, e.g. `"100"` for nodes, `"600"` for edges.
FillShadeHover,
/// Shade for the background when an element is being clicked /
/// pressed, e.g. `"200"` for nodes, "700" for edges.
/// pressed, e.g. `"200"` for nodes, `"700"` for edges.
FillShadeActive,
/// All padding within a node, e.g. `"1.5"` in `"p-1.5"`.
///
Expand Down Expand Up @@ -398,33 +398,34 @@ pub enum ThemeAttr {
/// [`HighlightState`]: crate::theme::HighlightState
OutlineShade,
/// Outline shade when an element is not focused / hovered over, e.g.
/// `"600"` for nodes, "900" for edges. Defaults to nothing.
/// `"600"` for nodes, `"900"` for edges. Defaults to nothing.
OutlineShadeNormal,
/// Outline shade when an element is focused, e.g.
/// `"500"` for nodes, "800" for edges. Defaults to the aforementioned
/// `"500"` for nodes, `"800"` for edges. Defaults to the aforementioned
/// values.
OutlineShadeFocus,
/// Outline shade when an element has the cursor hovering over it, e.g.
/// `"400"` for nodes, "700" for edges. Defaults to nothing.
/// `"400"` for nodes, `"700"` for edges. Defaults to nothing.
OutlineShadeHover,
/// Outline shade when an element is being clicked / pressed, e.g.
/// `"700"` for nodes, "950" for edges. Defaults to nothing.
/// `"700"` for nodes, `"950"` for edges. Defaults to nothing.
OutlineShadeActive,
/// Width of the border for nodes, or line for edges. Defaults to `"2"`.
OutlineWidth,
/// Outline style for all states, e.g. "none", "solid", "dashed", "dotted".
/// Outline style for all states, e.g. `"none"`, `"solid"`, `"dashed"`,
/// `"dotted"`.
OutlineStyle,
/// Outline style when an element is not focused / hovered over, e.g.
/// "none", "solid", "dashed", "dotted".
/// `"none"`, `"solid"`, `"dashed"`, `"dotted"`.
OutlineStyleNormal,
/// Outline style when an element is focused, e.g. "none", "solid",
/// "dashed", "dotted".
/// Outline style when an element is focused, e.g. `"none"`, `"solid"`,
/// `"dashed"`, `"dotted"`.
OutlineStyleFocus,
/// Outline style when an element has the cursor hovering over it, e.g.
/// "none", "solid", "dashed", "dotted".
/// `"none"`, `"solid"`, `"dashed"`, `"dotted"`.
OutlineStyleHover,
/// Outline style when an element is being clicked / pressed, e.g. "none",
/// "solid", "dashed", "dotted".
/// Outline style when an element is being clicked / pressed, e.g. `"none"`,
/// `"solid"`, `"dashed"`, `"dotted"`.
OutlineStyleActive,
/// Base colour for shape colourable attributes, e.g. stroke/border, fill.
ShapeColor,
Expand All @@ -449,32 +450,32 @@ pub enum ThemeAttr {
/// [`HighlightState`]: crate::theme::HighlightState
StrokeShade,
/// Line/border shade when an element is not focused / hovered over, e.g.
/// `"600"` for nodes, "900" for edges.
/// `"600"` for nodes, `"900"` for edges.
StrokeShadeNormal,
/// Line/border shade when an element is focused, e.g.
/// `"500"` for nodes, "800" for edges.
/// `"500"` for nodes, `"800"` for edges.
StrokeShadeFocus,
/// Line/border shade when an element has the cursor hovering over it, e.g.
/// `"400"` for nodes, "700" for edges.
/// `"400"` for nodes, `"700"` for edges.
StrokeShadeHover,
/// Line/border shade when an element is being clicked / pressed, e.g.
/// `"500"` for nodes, "800" for edges.
/// `"500"` for nodes, `"800"` for edges.
StrokeShadeActive,
/// Width of the border for nodes, or line for edges.
StrokeWidth,
/// Line/border style for all states, e.g. "none", "solid", "dashed",
/// "dotted".
StrokeStyle,
/// Line/border style when an element is not focused / hovered over, e.g.
/// "none", "solid", "dashed", "dotted".
/// `"none"`, `"solid"`, `"dashed"`, `"dotted"`.
StrokeStyleNormal,
/// Line/border style when an element is focused, e.g. "none", "solid",
/// "dashed", "dotted".
StrokeStyleFocus,
/// Line/border style when an element has the cursor hovering over it, e.g.
/// "none", "solid", "dashed", "dotted".
/// `"none"`, `"solid"`, `"dashed"`, `"dotted"`.
StrokeStyleHover,
/// Line/border style when an element is being clicked / pressed, e.g.
/// "none", "solid", "dashed", "dotted".
/// `"none"`, `"solid"`, `"dashed"`, `"dotted"`.
StrokeStyleActive,
}
4 changes: 2 additions & 2 deletions crate/web_components/src/dot_svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ pub fn DotSvg(
// Button
<div
class="
hidden
group-hover:block
lg:hidden
lg:group-hover:block
"
>
<input
Expand Down
219 changes: 219 additions & 0 deletions doc/example.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion playground/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ site-root = "target/site"
site-pkg-dir = "pkg"

# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to <site-root>/<site-pkg>/app.css
style-file = "style/main.scss"
# style-file = "style/main.scss"
tailwind-input-file = "style/tailwind.css"
tailwind-config-file = "style/tailwind.config.js"
# Assets source dir. All files found here will be copied and synchronized to site-root.
Expand Down
119 changes: 38 additions & 81 deletions playground/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,59 @@ use leptos::*;
use leptos_meta::*;
use leptos_router::*;

use self::{info_graph::InfoGraph, text_editor::TextEditor};
use self::{info_graph::InfoGraph, tabs::TabLabel, text_editor::TextEditor};

mod info_graph;
mod tabs;
mod text_editor;

/// Whether to only draw the diagram and hide the text boxes.
#[cfg(target_arch = "wasm32")]
const QUERY_PARAM_DIAGRAM_ONLY: &str = "diagram_only";

/// Sets the info graph src using logic purely executed on the client side.
#[cfg(not(target_arch = "wasm32"))]
fn diagram_only_init() -> bool {
true // Prevents text editor flicker from first render
}

/// Sets the info graph src using logic purely executed on the client side.
///
/// This is for a pure client side rendered app, so updating a signal within
/// `create_effect` is safe.
#[cfg(target_arch = "wasm32")]
fn diagram_only_init(set_diagram_only: WriteSignal<bool>) {
fn diagram_only_init() -> bool {
use js_sys::Array;
use web_sys::{console, Url, UrlSearchParams};

create_effect(move |_| {
let url_search_params = web_sys::window().and_then(|window| {
let url = Url::new(&String::from(window.location().to_string()))
.expect("Expected URL to be valid.");

let hash = url.hash();
if hash.is_empty() {
Some(url.search_params())
} else {
let hash = hash.replacen('#', "?", 1);
match UrlSearchParams::new_with_str(hash.as_str()) {
Ok(search_params) => Some(search_params),
Err(error) => {
let message = Array::new_with_length(1);
message.set(0, error);
console::log(&message);
None
}
let url_search_params = web_sys::window().and_then(|window| {
let url = Url::new(&String::from(window.location().to_string()))
.expect("Expected URL to be valid.");

let hash = url.hash();
if hash.is_empty() {
Some(url.search_params())
} else {
let hash = hash.replacen('#', "?", 1);
match UrlSearchParams::new_with_str(hash.as_str()) {
Ok(search_params) => Some(search_params),
Err(error) => {
let message = Array::new_with_length(1);
message.set(0, error);
console::log(&message);
None
}
}
});
if let Some(url_search_params) = url_search_params {
let diagram_only = url_search_params
.get(QUERY_PARAM_DIAGRAM_ONLY)
.and_then(|diagram_only_str| serde_yaml::from_str::<bool>(&diagram_only_str).ok())
.unwrap_or(false);
set_diagram_only.set(diagram_only);
} else {
set_diagram_only.set(false);
}
});
if let Some(url_search_params) = url_search_params {
url_search_params
.get(QUERY_PARAM_DIAGRAM_ONLY)
.and_then(|diagram_only_str| serde_yaml::from_str::<bool>(&diagram_only_str).ok())
.unwrap_or(false)
} else {
false
}
}

/// Top level playground application.
Expand Down Expand Up @@ -84,6 +88,7 @@ pub fn App() -> impl IntoView {
<Stylesheet id="leptos" href=stylesheet_path />
<Stylesheet id="fonts" href=fonts_path />
<Title text="dot_ix: Interactive dot graphs" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

// content for this welcome page
<Router
Expand All @@ -107,6 +112,7 @@ pub fn App() -> impl IntoView {
<Stylesheet id="leptos" href=stylesheet_path />
<Stylesheet id="fonts" href=fonts_path />
<Title text="dot_ix: Interactive dot graphs" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

// content for this welcome page
<Router
Expand Down Expand Up @@ -156,70 +162,21 @@ fn RouterFallback() -> impl IntoView {
/// Renders the home page of your application.
#[component]
fn HomePage() -> impl IntoView {
let (diagram_only, set_diagram_only) = create_signal(true);

#[cfg(target_arch = "wasm32")]
diagram_only_init(set_diagram_only);
let (diagram_only, set_diagram_only) = create_signal(diagram_only_init());

let _set_diagram_only = set_diagram_only;

let main_div_classes = move || {
if diagram_only.get() { "" } else { "md:p-12" }
};
let disclaimer_classes = move || {
if diagram_only.get() {
"hidden"
"font-sans"
} else {
"
border
border-amber-300
bg-gradient-to-b from-amber-100 to-amber-200
my-2
p-2
rounded
"
"font-sans lg:p-4"
}
};

view! {
<div class=main_div_classes>
<InfoGraph diagram_only=diagram_only />
<div class=disclaimer_classes>
<p>
<span class="font-bold">"🐱 GitHub: "</span>
<a
class="text-sky-600 hover:text-sky-400 active:text-sky-300"
href="https://github.com/azriel91/dot_ix"
>
"azriel91/dot_ix"
</a>
</p>
<p>
"This is an "<i>"early"</i>" frontend prototype for the "
<a
class="text-sky-600 hover:text-sky-400 active:text-sky-300"
href="https://peace.mk"
>
"Peace"
</a>
" automation framework"
</p>
<p>
<b>"Notes:"</b>
<ol class="list-disc mx-4">
<li>"The Flex Diagram is still experimental, and the arrows don't \
receive styling."</li>
<li>"Docs for theme keys can be found at: "<a
class="text-sky-600 hover:text-sky-400 active:text-sky-300"
href="https://docs.rs/dot_ix_model/latest/dot_ix_model/theme/enum.ThemeAttr.html"
>
"docs.rs/dot_ix_model/theme/enum.ThemeAttr.html"
</a></li>
<li>"If you'd like to contribute to the development of this library, \
I'd be super delighted, since I'm not a web-dev™️ 🙃."</li>
</ol>
</p>
</div>
</div>
}
}
Loading

0 comments on commit e6246b4

Please sign in to comment.