Skip to content

Commit 8ecdac1

Browse files
authored
Merge pull request #28 from azriel91/feature/better-error-feedback
2 parents 781f67a + 34bf2c6 commit 8ecdac1

File tree

14 files changed

+665
-219
lines changed

14 files changed

+665
-219
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@
1414
* Take in `tags` which only include tag names.
1515
* Take in `tag_items` for nodes and edges instead of tags per node.
1616
* Support theming nodes based on tag focus.
17+
* Add `ThemeAttr::Animate` to support setting [`animation`].
18+
* Add `ThemeAttr::Visibility` to support setting [`visibility`].
19+
* Fix black outline shown on focused nodes in Chrome / Edge.
20+
* Show feedback to user when stroke / outline / fill class partials are not all specified.
1721

1822
[monaco]: https://github.com/microsoft/monaco-editor
1923
[rust-monaco]: https://github.com/siku2/rust-monaco
2024
[cursor styling]: https://tailwindcss.com/docs/cursor
25+
[`animation`]: https://tailwindcss.com/docs/animation
26+
[`visibility`]: https://tailwindcss.com/docs/visibility
2127

2228

2329
## 0.7.0 (2024-06-30)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
11
use serde::{Deserialize, Serialize};
22

3+
use crate::theme::ThemeWarnings;
4+
35
/// Graphviz dot source and CSS styles.
46
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
57
pub struct DotSrcAndStyles {
68
/// Graphviz dot source to run in `dot`.
79
pub dot_src: String,
810
/// Tailwind CSS styles to put into `<styles>..</styles>`.
911
pub styles: String,
12+
/// Warnings detected while computing CSS utility classes.
13+
pub theme_warnings: ThemeWarnings,
14+
}
15+
16+
impl DotSrcAndStyles {
17+
/// Returns a new `DotSrcAndStyles` object.
18+
pub fn new(dot_src: String, styles: String, theme_warnings: ThemeWarnings) -> Self {
19+
Self {
20+
dot_src,
21+
styles,
22+
theme_warnings,
23+
}
24+
}
25+
26+
/// Returns the Graphviz dot source to run in `dot`.
27+
pub fn dot_src(&self) -> &str {
28+
&self.dot_src
29+
}
30+
31+
/// Returns the tailwind CSS styles to put into `<styles>..</styles>`.
32+
pub fn styles(&self) -> &str {
33+
&self.styles
34+
}
35+
36+
/// Returns the warnings detected while computing CSS utility classes.
37+
pub fn theme_warnings(&self) -> &ThemeWarnings {
38+
&self.theme_warnings
39+
}
1040
}

crate/model/src/theme.rs

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,27 @@ use crate::common::{AnyId, EdgeId, NodeId, TagId};
1010
pub use self::{
1111
any_id_or_defaults::AnyIdOrDefaults, color_params::ColorParams,
1212
css_class_merger::CssClassMerger, css_class_partials::CssClassPartials,
13-
css_classes::CssClasses, css_classes_builder::CssClassesBuilder, el_css_classes::ElCssClasses,
13+
css_classes::CssClasses, css_classes_and_warnings::CssClassesAndWarnings,
14+
css_classes_builder::CssClassesBuilder, el_css_classes::ElCssClasses,
1415
highlight_state::HighlightState, stroke_params::StrokeParams, style_for::StyleFor,
15-
theme_attr::ThemeAttr, theme_styles::ThemeStyles, themeable::Themeable,
16+
theme_attr::ThemeAttr, theme_styles::ThemeStyles, theme_warnings::ThemeWarnings,
17+
themeable::Themeable,
1618
};
1719

1820
mod any_id_or_defaults;
1921
mod color_params;
2022
mod css_class_merger;
2123
mod css_class_partials;
2224
mod css_classes;
25+
mod css_classes_and_warnings;
2326
mod css_classes_builder;
2427
mod el_css_classes;
2528
mod highlight_state;
2629
mod stroke_params;
2730
mod style_for;
2831
mod theme_attr;
2932
mod theme_styles;
33+
mod theme_warnings;
3034
mod themeable;
3135

3236
/// Theme to style the generated diagram.
@@ -227,7 +231,7 @@ impl Theme {
227231
///
228232
/// The [`CssClasses`] produced will contain an entry for each node / edge
229233
/// ID from the themeable type.
230-
pub fn el_css_classes<T>(&self, themeable: &T) -> ElCssClasses
234+
pub fn el_css_classes<T>(&self, themeable: &T) -> (ElCssClasses, ThemeWarnings)
231235
where
232236
T: Themeable,
233237
{
@@ -240,13 +244,32 @@ impl Theme {
240244
theme
241245
.node_el_css_classes(themeable)
242246
.chain(theme.edge_el_css_classes(themeable))
243-
.collect()
247+
.fold(
248+
(
249+
ElCssClasses::with_capacity(
250+
themeable.node_ids().count() + themeable.edge_ids().count(),
251+
),
252+
ThemeWarnings::new(),
253+
),
254+
|(mut el_css_classes, mut theme_warnings_acc),
255+
(any_id, css_classes_and_warnings)| {
256+
let CssClassesAndWarnings {
257+
css_classes,
258+
theme_warnings,
259+
} = css_classes_and_warnings;
260+
261+
el_css_classes.insert(any_id, css_classes);
262+
theme_warnings_acc.extend(theme_warnings.into_inner());
263+
264+
(el_css_classes, theme_warnings_acc)
265+
},
266+
)
244267
}
245268

246269
fn node_el_css_classes<'f, T>(
247270
&'f self,
248271
themeable: &'f T,
249-
) -> impl Iterator<Item = (AnyId, CssClasses)> + 'f
272+
) -> impl Iterator<Item = (AnyId, CssClassesAndWarnings)> + 'f
250273
where
251274
T: Themeable,
252275
{
@@ -255,13 +278,13 @@ impl Theme {
255278
let node_class_partials_specified = self.node_class_partials_specified(node_id);
256279

257280
let any_id = Some(AnyId::from(node_id.clone()));
258-
let node_classes = CssClassMerger::node_classes(
281+
let node_classes_and_warnings = CssClassMerger::node_classes(
259282
node_class_partials_defaults,
260283
node_class_partials_specified,
261284
themeable,
262285
);
263286

264-
any_id.map(|any_id| (any_id, node_classes))
287+
any_id.map(|any_id| (any_id, node_classes_and_warnings))
265288
})
266289
}
267290

@@ -278,7 +301,7 @@ impl Theme {
278301
fn edge_el_css_classes<'f, T>(
279302
&'f self,
280303
themeable: &'f T,
281-
) -> impl Iterator<Item = (AnyId, CssClasses)> + 'f
304+
) -> impl Iterator<Item = (AnyId, CssClassesAndWarnings)> + 'f
282305
where
283306
T: Themeable,
284307
{
@@ -288,13 +311,13 @@ impl Theme {
288311
let edge_class_partials_specified = self.edge_class_partials_specified(edge_id);
289312

290313
let any_id = Some(AnyId::from(edge_id.clone()));
291-
let edge_classes = CssClassMerger::edge_classes(
314+
let edge_classes_and_warnings = CssClassMerger::edge_classes(
292315
edge_class_partials_defaults,
293316
edge_class_partials_specified,
294317
themeable,
295318
);
296319

297-
any_id.map(|any_id| (any_id, edge_classes))
320+
any_id.map(|any_id| (any_id, edge_classes_and_warnings))
298321
})
299322
}
300323

@@ -314,7 +337,7 @@ impl Theme {
314337
themeable: &T,
315338
diagram_theme: &Theme,
316339
tag_id: &TagId,
317-
) -> ElCssClasses
340+
) -> (ElCssClasses, ThemeWarnings)
318341
where
319342
T: Themeable,
320343
{
@@ -339,14 +362,33 @@ impl Theme {
339362
tag_theme
340363
.node_tag_el_css_classes(themeable, tag_id)
341364
.chain(tag_theme.edge_tag_el_css_classes(themeable, tag_id))
342-
.collect()
365+
.fold(
366+
(
367+
ElCssClasses::with_capacity(
368+
themeable.node_ids().count() + themeable.edge_ids().count(),
369+
),
370+
ThemeWarnings::new(),
371+
),
372+
|(mut el_css_classes, mut theme_warnings_acc),
373+
(any_id, css_classes_and_warnings)| {
374+
let CssClassesAndWarnings {
375+
css_classes,
376+
theme_warnings,
377+
} = css_classes_and_warnings;
378+
379+
el_css_classes.insert(any_id, css_classes);
380+
theme_warnings_acc.extend(theme_warnings.into_inner());
381+
382+
(el_css_classes, theme_warnings_acc)
383+
},
384+
)
343385
}
344386

345387
fn node_tag_el_css_classes<'f, T>(
346388
&'f self,
347389
themeable: &'f T,
348390
tag_id: &'f TagId,
349-
) -> impl Iterator<Item = (AnyId, CssClasses)> + 'f
391+
) -> impl Iterator<Item = (AnyId, CssClassesAndWarnings)> + 'f
350392
where
351393
T: Themeable,
352394
{
@@ -355,22 +397,22 @@ impl Theme {
355397
let node_class_partials_specified = self.node_class_partials_specified(node_id);
356398

357399
let any_id = Some(AnyId::from(node_id.clone()));
358-
let node_classes = CssClassMerger::node_tag_classes(
400+
let node_classes_and_warnings = CssClassMerger::node_tag_classes(
359401
node_class_partials_defaults,
360402
node_class_partials_specified,
361403
themeable,
362404
tag_id,
363405
);
364406

365-
any_id.map(|any_id| (any_id, node_classes))
407+
any_id.map(|any_id| (any_id, node_classes_and_warnings))
366408
})
367409
}
368410

369411
fn edge_tag_el_css_classes<'f, T>(
370412
&'f self,
371413
themeable: &'f T,
372414
tag_id: &'f TagId,
373-
) -> impl Iterator<Item = (AnyId, CssClasses)> + 'f
415+
) -> impl Iterator<Item = (AnyId, CssClassesAndWarnings)> + 'f
374416
where
375417
T: Themeable,
376418
{
@@ -380,14 +422,14 @@ impl Theme {
380422
let edge_class_partials_specified = self.edge_class_partials_specified(edge_id);
381423

382424
let any_id = Some(AnyId::from(edge_id.clone()));
383-
let edge_classes = CssClassMerger::edge_tag_classes(
425+
let edge_classes_and_warnings = CssClassMerger::edge_tag_classes(
384426
edge_class_partials_defaults,
385427
edge_class_partials_specified,
386428
themeable,
387429
tag_id,
388430
);
389431

390-
any_id.map(|any_id| (any_id, edge_classes))
432+
any_id.map(|any_id| (any_id, edge_classes_and_warnings))
391433
})
392434
}
393435
}

0 commit comments

Comments
 (0)