Skip to content

Commit

Permalink
add Component trait and feature-flagged comp! macro to seed proper
Browse files Browse the repository at this point in the history
  • Loading branch information
glennsl committed May 2, 2021
1 parent e9b6da1 commit 19b6608
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 45 deletions.
81 changes: 54 additions & 27 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## [unreleased]

- Added helpers for wheel event: `wheel_ev` and `to_wheel_event`.
- Use `wheel_ev` in `canvas` example to zoom rectangle with mouse scroll wheel.
- [BREAKING] Base path changed from `Rc<Vec<String>>` to `Rc<[String]>`. It means also `Orders::clone_base_path` returns a slice.
Expand All @@ -12,10 +13,12 @@
- Implemented `AsAtValue` for `Option<T>`
- [BREAKING] Added argument `Option<&Namespace>` to functions `Node::from_html` and `El::from_html`.
- Added macro `raw_svg!` (#589).
- Added `browser::dom::Namespace` to `prelude`.
- Added `browser::dom::Namespace` to `prelude`.
- Adapted to Rust 1.51.0.
- Added an experimental component API, feature-flagged behind `experimental-component-api`, and the `experimental-component` example to demonstrate its use.

## v0.8.0

- [BREAKING] Rename `linear_gradient!` to `linearGradient!` for consistency with the other svg macros (same with `radial_gradient!` and `mesh_gradient!`) (#377).
- Fixed `base_path` with a trailing slash parsing / handling.
- Fixed `C` macro memory / WASM file size issue.
Expand Down Expand Up @@ -55,6 +58,7 @@
- Added `Node::NoChange`.

## v0.7.0

- [BREAKING] Custom elements are now patched in-place (#364). Use `el_key` to force reinitialize an element.
- Added `el_key` method for adding keys to `El`s (#354).
- Enabled all additional markdown [extensions](https://docs.rs/pulldown-cmark/latest/pulldown_cmark/struct.Options.html).
Expand Down Expand Up @@ -91,7 +95,7 @@
- [deprecated] - `seed::browser::service::fetch` module is deprecated in favor of `seed::browser::fetch`.
- Implemented `IntoNodes` for `Option<Node<Msg>>` and `Option<Vec<Node<Msg>>>`.
- Implemented `UpdateEl` for `i64` and `u64`.
- Reset properties `checked` and `value` on attribute remove (#405).
- Reset properties `checked` and `value` on attribute remove (#405).
- Added examples `markdown`, `tea_component`, `subscribe`, `custom_elements`, `fetch`, `url`, `pages`, `pages_hash_routing`, `pages_keep_state`, `auth`, `bunnies` and `graphql` (#400).
- Updated examples.
- Removed examples `app_builder`, `orders`, `server_interaction`, `counter_advanced` and `mathjax`.
Expand All @@ -111,6 +115,7 @@
- Added `#[derive(Debug)]` to `fetch::Response`

## v0.6.0

- Implemented `UpdateEl` for `Filter` and `FilterMap`.
- Added method `El::is_custom(&self)`.
- Fixed custom elements patching (#325).
Expand Down Expand Up @@ -141,36 +146,39 @@
- Adapted to Rust 1.41.0.

## v0.5.1

- [BREAKING] `MessageMapper::map_message` changed to `MessageMapper::map_msg`.
- [BREAKING] `fetch` and `storage` moved to `seed::browser::service::{fetch, storage}`,
but reimported at the lib level. Ie: `seed::fetch`, and `seed::storage`.
but reimported at the lib level. Ie: `seed::fetch`, and `seed::storage`.
- Added support for `Vec<Attr>` and `Vec<Style>` in view macros.
- `App` included in `prelude`.
- [BREAKING] Seed refactored to use `async/.await`. `fetch.rs` docs updated.
- Export `Attrs`, `Style`, `Listener`. ie, can import with `seed::Style` etc.
- Fixed a bug causing the docs not to build.

## v0.5.0

- Added helper `seed::canvas()`, and `seed::canvas_context()` helper functions.
- Fixed `Url` parsing (resolves issue with hash routing).
- [BREAKING] `From<String> for Url` changed to `TryFrom<String> for Url`.
- Fixed jumping cursor in inputs (#158) .
- Added method `orders.after_next_render(Option<RenderTimestampDelta>)` (#207).
- Fixed a bug with back/forward routing to the landing page (#296).
- Deprecated `Init` struct, replacing it with `BeforeMount` and `AfterMount` structs to
better denote state before and after mounting the `App` occurs.
better denote state before and after mounting the `App` occurs.
- Added a new function `builder` which replaces `build` as part of deprecating `Init`.
- Added a new function `build_and_start` which replaces `finish` as part of deprecating `Init`.
- Added `IntoInit`and `IntoAfterMount` traits. It is possible to use these
in place of a closure or function to produce the corresponding `Init` and `AfterMount` structs.
in place of a closure or function to produce the corresponding `Init` and `AfterMount` structs.
- Messages sent from `IntoAfterMount` will now be run after the routing message.
- Added example `app_builder`.
- `events::Listener` is included in `prelude`.
- `()`s have been replaced with structs - e.g. `GMs = ()` => `GMs = UndefinedGMs`.
- `()`s have been replaced with structs - e.g. `GMs = ()` => `GMs = UndefinedGMs`.
- `WindowEvents` alias changed to `WindowEventsFn` for consistency with other `*Fn`.
- Commented builder and helper methods.

## v0.4.2

- Added an `Init` struct, which can help with initial routing (Breaking)
- The `routes` function now returns an `Option<Msg>` (Breaking)
- Updated `Tag::from()` to accept more input types
Expand All @@ -187,17 +195,19 @@ in place of a closure or function to produce the corresponding `Init` and `After
- Added `seed::html_document()` and `seed::cookies` convenience functions

## v0.4.1

- Added more SVG `At` variants
- Added the `St` enum, for style keys; similar to `At`
- Improved ergonomics of `add_child`, `add_attr`, `add_class`,
`add_style`, `replace_text`, and `add_text`, `Node` methods
`add_style`, `replace_text`, and `add_text`, `Node` methods

## v0.4.0

- `ElContainer`, imported in prelude, renamed to `View`. (Breaking)
- Internal refactor of `El`: Now wrapped in `Node`, along with
`Empty` and `Text`. Creation macros return `Node(Element)`. (Breaking)
`Empty` and `Text`. Creation macros return `Node(Element)`. (Breaking)
- Changed the way special attributes like `disabled`, `autofocus`, and
`checked` are handled (Breaking)
`checked` are handled (Breaking)
- `MessageMapper` now accepts closures
- `Orders` is a trait now instead of a struct. (Breaking)
- Significant changes to MessageMapper
Expand All @@ -206,128 +216,145 @@ in place of a closure or function to produce the corresponding `Init` and `After
- Several minor bux fixes
- Examples updated to reflect these changes
- Improvements to Fetch API, especially regarding error handling
and deserialization
and deserialization

## v0.3.7

- `routes` now accepts `Url` instead of `&Url` (Breaking)
- Improvements to fetch API
- Added `raw!`, `md!`, and `plain!` macros that alias `El::from_html`, `El::from_markdown`,
and `El::new_text` respectively
and `El::new_text` respectively
- `Attrs!` and `Style!` macros can now use commas and whitespace as separators,
in addition to semicolons
in addition to semicolons
- Fixed typos in a few attributes (Breaking)
- Fixed a bug where an HTML namespace was applied to raw html/markdown elements
- New conditional syntax added in `class!` macro, similar to `Elm`'s `classList`
- `Listener` now implements `MessageMapper`
- `El methods` `add_child`, `add_style`, `add_attr`, and `set_text` now return the elements,
allowing chaining
allowing chaining
- Fixed a bug with `set_text`. Renamed to `replace_text`. Added `add_text`, which adds
a text node, but doesn't remove existing ones. Added `add_class`. (Breaking)

a text node, but doesn't remove existing ones. Added `add_class`. (Breaking)

## v0.3.6

- Fetch module and API heavily changed (breaking)
- Added support for `request​Animation​Frame`, which improves render performance,
especially for animations
especially for animations
- Styles no longer implicitly add `px`. Added `unit!` macro in its place
- `Map` can now be used directly in elements, without needing to annotate type and collect
(ie for child `Elements`, and `Listener`s)
(ie for child `Elements`, and `Listener`s)
- Significant changes to MessageMapper
- Orders hs new methods, `clone_app` and `msg_mapper` that allow access to app instance.
- Fixed a bug where `empty` elements at the top-level were rendering in the wrong order
- Added an `empty!` macro, which is similar to `seed::empty`
- Attributes and style now retain order

## v0.3.5

- Fixed a bug where view functions returning `Vec<El>` weren't rendering properly
- Fixed a typo with the `viewBox` attribute

## v0.3.4

- The `update` fn now accepts a (new) `Orders` struct, and returns nothing. Renders occur implicitly,
with the option to skip rendering, update with an additional message, or perform an asynchronous
action. (Breaking)
with the option to skip rendering, update with an additional message, or perform an asynchronous
action. (Breaking)
- `.mount()` now accepts elements. Deprecated `.mount_el()`
- The `log` function and macro now support items which implement `Debug`
- Removed deprecated `routing::push_path` function (breaking)

## v0.3.3

- Added `seed::update` function, which allows custom events, and updates from JS

## v0.3.2

- Top level view functions can now return `Vec<El<Ms>>`, `El<Ms>`, or something else implementing
the new ElContainer trait
the new ElContainer trait

## v0.3.1

- Top level view functions now return `Vec<El<Ms>>` instead of `El<Ms>`, mounted directly to
the mount point. (Breaking)
the mount point. (Breaking)
- `push_route()` can now accept a `Vec<&str>`, depreciating `push_path()`
- Fixed a bug where window events couldn't be enabled on initialization

## v0.3.0

- `update` function now takes a mutable ref of the model. (Breaking)
- `Update` (update's return type) is now a struct. (Breaking)
- Async, etc events are now handled through messages, instead of passing `App`
through the view func. (Breaking)
through the view func. (Breaking)
- Fixed some bugs with empty elements
- Internal code cleanup
- Added commented-out release command to example build files
- Added more tests

## v0.2.10

- Routing can be triggered by clicking any element containing a `Href` attribute
with value as a relative link
with value as a relative link
- Internal links no longer trigger a page refresh
- Models no longer need to implement `Clone`
- Fixed a bug introduced in 0.2.9 for `select` elements

## v0.2.9

- Added a `RenderThen` option to `Update`, which allows chaining update messages
- Added a `.model` method to `Update`, allowing for cleaner recursion in updates
- Improved controlled-component (sync fields with model) logic

## v0.2.8

- Reflowed `El::from_html` and `El::from_markdown` to return `Vec`s of `El`s, instead of wrapping
them in a single span.
them in a single span.
- Improved support for SVG and namespaces
- Added `set_timeout` wrapper

## v0.2.7

- Fixed a bug where `line!` macro interfered with builtin
- Fixed a bug with routing search (ie `?`)

## v0.2.6

- Fixed a bug where children would render out-of-order
- Improved vdom diffing logic

## v0.2.5

- Attributes and Events now can use `At` and `Ev` enums
- Routing overhauled; modelled after react-reason. Cleaner syntax, and more flexible
- Input, Textarea, and Select elements are now "controlled" - they always
stay in sync with the model
stay in sync with the model
- index.html file updated in examples and quickstart to use relative paths,
which fixes landing-page routing
which fixes landing-page routing

## v0.2.4

- Changed render func to use a new pattern (Breaking)
- Default mount point added: \"app\" for element id
- View func now takes a ref to the model instead of the model itself
- Routing refactored; now works dynamically
- Update function now returns an enum that returns Render or Skip,
to allow conditional rendering (Breaking)
to allow conditional rendering (Breaking)
- Elements can now store more than 1 text node

## V0.2.3

- Fixed a bug where initially-empty text won't update
- Added more tests
- Exposed web_sys Document and Window in top level of Seed create, with .expect
- Modified build scripts to keep the wasm output name fixed at 'package', simplifying example/quickstart renames
- Tests now work in Windows due to update in wasm-pack

## V0.2.2

- Overhaul of fetch module
- Added server-integration example

## V0.2.1

- Added support for custom tags
- Added `class!` and `id!` convenience macros for setting style

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,4 @@ exclude = [
default = ["panic-hook"]
panic-hook = ["console_error_panic_hook"]
markdown = ["pulldown-cmark"]
experimental-component-api = []
2 changes: 1 addition & 1 deletion examples/experimental_component/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ edition = "2018"
crate-type = ["cdylib"]

[dependencies]
seed = {path = "../../"}
seed = { path = "../../", features = ["experimental-component-api"] }
15 changes: 9 additions & 6 deletions examples/experimental_component/src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pub struct Button<S> {
}

impl<S: Into<Cow<'static, str>>> Button<S> {
pub fn into_component<Ms>(self) -> Component<Ms> {
Component {
pub fn into_component<Ms>(self) -> ButtonComponent<Ms> {
ButtonComponent {
label: self.label.into(),
outlined: false,
disabled: false,
Expand All @@ -19,14 +19,15 @@ impl<S: Into<Cow<'static, str>>> Button<S> {
}
}

pub struct Component<Ms: 'static> {
#[allow(clippy::module_name_repetitions)]
pub struct ButtonComponent<Ms: 'static> {
label: Cow<'static, str>,
outlined: bool,
disabled: bool,
on_clicks: Vec<Rc<dyn Fn() -> Ms>>,
}

impl<Ms> Component<Ms> {
impl<Ms> ButtonComponent<Ms> {
pub const fn outlined(mut self, outlined: bool) -> Self {
self.outlined = outlined;
self
Expand All @@ -41,8 +42,10 @@ impl<Ms> Component<Ms> {
self.on_clicks.push(Rc::new(move || on_click.clone()()));
self
}
}

pub fn into_node(self) -> Node<Ms> {
impl<Ms> Component<Ms> for ButtonComponent<Ms> {
fn render(&self) -> Node<Ms> {
let attrs = {
let mut attrs = attrs! {};

Expand Down Expand Up @@ -84,7 +87,7 @@ impl<Ms> Component<Ms> {
let mut button = button![css, attrs, self.label];

if !self.disabled {
for on_click in self.on_clicks {
for on_click in self.on_clicks.iter().cloned() {
button.add_event_handler(ev(Ev::Click, move |_| on_click()));
}
}
Expand Down
9 changes: 0 additions & 9 deletions examples/experimental_component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,6 @@ fn view(model: &Model) -> Node<Msg> {
]
}

#[macro_export]
macro_rules! comp {
($init:expr, $($opt_field:ident => $opt_val:expr),* $(,)?) => {
$init.into_component()
$( .$opt_field($opt_val) )*
.into_node()
};
}

// ------ ------
// Start
// ------ ------
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ pub mod prelude {
// https://github.com/rust-lang-nursery/reference/blob/master/src/macros-by-example.md
shortcuts::*,
virtual_dom::{
el_key, el_ref::el_ref, AsAtValue, At, AtValue, CSSValue, El, ElRef, Ev, EventHandler,
IntoNodes, Node, St, Tag, ToClasses, UpdateEl, UpdateElForIterator, View,
el_key, el_ref::el_ref, AsAtValue, At, AtValue, CSSValue, Component, El, ElRef, Ev,
EventHandler, IntoNodes, Node, St, Tag, ToClasses, UpdateEl, UpdateElForIterator, View,
},
};
pub use indexmap::IndexMap; // for attrs and style to work.
Expand Down
14 changes: 14 additions & 0 deletions src/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,3 +553,17 @@ macro_rules! key_value_pairs {
}
};
}

#[cfg(feature = "experimental-component-api")]
/// Instantiates and renders a `Component`
///
/// NOTE: This is an experimental API that requires the `experimental-component-api` feature.
#[macro_export]
macro_rules! comp {
($init:expr, $($opt_field:ident => $opt_val:expr),* $(,)?) => {
$crate::virtual_dom::component::instantiate(
$init.into_component()
$( .$opt_field($opt_val) )*
)
};
}
2 changes: 2 additions & 0 deletions src/virtual_dom.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod attrs;
pub mod component;
pub mod el_ref;
pub mod event_handler_manager;
pub mod mailbox;
Expand All @@ -11,6 +12,7 @@ pub mod values;
pub mod view;

pub use attrs::Attrs;
pub use component::Component;
pub use el_ref::{el_ref, ElRef, SharedNodeWs};
pub use event_handler_manager::{EventHandler, EventHandlerManager, Listener};
pub use mailbox::Mailbox;
Expand Down
Loading

0 comments on commit 19b6608

Please sign in to comment.