Compare commits

...

2455 Commits
keys ... 4088

Author SHA1 Message Date
Greg Johnston
54764261b1 fix memory leak! 2025-06-25 10:02:41 -04:00
Greg Johnston
acd8fd52c3 fix ownership for root 2025-06-24 22:01:26 -04:00
Greg Johnston
51bd63a91a fix context providers (for <A> etc) 2025-06-23 21:50:21 -04:00
Greg Johnston
1d34ea7133 Merge remote-tracking branch 'origin' into 4088 2025-06-23 20:05:40 -04:00
Gabriel Lopes Veiga
f51c676e0d feat: add method take for BrowserFormData (#4102) 2025-06-22 13:55:48 -04:00
bicarlsen
cf0aa0e4d7 fix: create svg::InertElement templates in SVG namespace. (#4104) 2025-06-22 13:53:37 -04:00
Greg Johnston
a8894460e2 Merge remote-tracking branch 'origin' into 4088 2025-06-20 20:40:11 -04:00
bicarlsen
df09d4a7f6 fix: update svg::InertElement for dom cache. (#4100)
#4099 introduced caching for inert elements, changing the API for [`dom::Dom::create_element_from_html`](30b0a579ca/tachys/src/renderer/dom.rs (L495)). This updates `svg::InertElement` to match the new API.
2025-06-20 20:39:55 -04:00
Greg Johnston
403d6ed84e chore: clippy 2025-06-20 17:42:56 -04:00
TERRORW0LF
30b0a579ca enhance: handle ../ in aria-current for <A/> component (#4051) 2025-06-20 17:09:07 -04:00
dependabot[bot]
50a4c3b0d9 chore(deps): bump autofix-ci/action from 1.3.1 to 1.3.2 (#4072)
Bumps [autofix-ci/action](https://github.com/autofix-ci/action) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/autofix-ci/action/releases)
- [Commits](https://github.com/autofix-ci/action/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: autofix-ci/action
  dependency-version: 1.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 17:02:54 -04:00
bicarlsen
c76649d77b feat: add inert SVG elements. (#4085) 2025-06-20 17:02:38 -04:00
bicarlsen
911be5007e perf: add template cache for InertElement (#4099) 2025-06-20 17:01:19 -04:00
Greg Johnston
b37900ec55 update rebuild 2025-06-19 14:40:19 -04:00
Greg Johnston
fda2a1348c fix overwritten Outlet 2025-06-19 14:23:08 -04:00
Greg Johnston
c2ea59ca96 correct top-level Outlet rendering again 2025-06-18 15:38:09 -04:00
Greg Johnston
7af2a31e21 waypoint 2025-06-18 15:24:03 -04:00
Greg Johnston
0e45694c6e correctly render top-level Outlet once 2025-06-17 19:44:42 -04:00
Greg Johnston
ca5c179cb1 fix: correctly provide context via nested outlets (closes #4088) 2025-06-16 21:12:42 -04:00
Greg Johnston
5227221c96 docs: add document on adding class and other attributes to <A/> component (#4086) 2025-06-16 20:00:45 -04:00
Greg Johnston
3f48b77256 feat: impl IntoFragment for AnyView (#4087) 2025-06-16 20:00:32 -04:00
foldedwave
99117f496f fix: correctly remove :capture listeners (closes #4081) (#4082)
Co-authored-by: foldedwave <anon@foldedwave.com>
2025-06-16 20:00:15 -04:00
Moritz Hedtke
cf12ea3404 fix: conflicting changes between #4035 and #4074 (#4090) 2025-06-16 19:59:30 -04:00
martin frances
d555c1e0ce Removed crate once_cell (#4083)
* Removed crate once_cell

As of rust_version 1.80.0 there are now equivalent options in std.

Async and sync changes are as follows.

-use once_cell::sync::Lazy;
+use std::sync::LazyLock;

-use once_cell::sync::Lazy;
+use std::sync::LazyLock;

* ran cargo fmt.

* fixed server_fn errors.

* cargo fmt fixes.

* "use srd::sync" becomes "use std::sync".

* fixed formatting issue.

* formatting issues.

* Fixed error in examples/server_fns_axum

* more formatting issues.

* more formatting issues.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-06-16 10:38:32 -07:00
Moritz Hedtke
40ea20057f Remove unnecessary Option wrapping (#4035)
* Remove unnecessary Option wrapping.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-06-16 10:37:26 -07:00
Greg Johnston
5587ccd1eb fix: don't render a comment node for () attributes in template (closes #4079) (#4080) 2025-06-14 15:47:48 -04:00
Greg Johnston
50a9df9eea Merge pull request #4078 from leptos-rs/4066
Fix updates to static class names
2025-06-13 22:49:51 -04:00
Greg Johnston
c46b1c4e25 feat: allow dereferencing LocalResource to an AsyncDerived (see #4063) (#4077) 2025-06-13 18:03:18 -04:00
Greg Johnston
e6f86408a1 fix: ensure that dynamic classes are replaced if they have changed 2025-06-13 18:01:42 -04:00
Greg Johnston
aa13ed9431 fix: ensure that classes are replaced if they have changed (closes #4066) 2025-06-13 18:01:27 -04:00
TERRORW0LF
607a7987e5 fix: unresolved path in server side redirect (closes #4054) (#4074)
* feat: resolve path on server redirect

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-06-13 15:50:18 -04:00
Greg Johnston
c0c3279cbb Merge pull request #4056 from elias098/fixes
Bugfixes to `reactive_stores`
2025-06-13 11:07:09 -04:00
Greg Johnston
ece6d9dd93 feat(CI): add checking minimal-versions on release (#3987)
* feat(CI): add checking minimal-versions

* chore: unify all deps + exact versioning in root workspace for better maintenance

* feat(CI): run minimal-versions only on release tag

* feat(CI): re-adding dependabot with grouped weekly updates
2025-06-13 10:47:53 -04:00
Álvaro Mondéjar Rubio
74ecf4763a docs: update Tauri project to Leptos v0.8.2 (#4020) 2025-06-13 10:47:24 -04:00
Greg Johnston
2c5c69c2fe Merge pull request #4065 from leptos-rs/3729pt2
fix: memory leak introduced by #4015
2025-06-13 10:37:27 -04:00
Tommy Yu
0c275d6540 fix: IntoMaybeErased hygiene on view macro (#4071) 2025-06-13 10:37:13 -04:00
Greg Johnston
6be3266a2e fix: ensure that arena is reestablished for cleanups 2025-06-12 17:13:12 -04:00
Greg Johnston
c3efb8e476 Merge remote-tracking branch 'origin' into 3729pt2 2025-06-11 21:31:38 -04:00
Greg Johnston
32e0551b10 fix: correct set up sandboxing for AsyncDerived futures 2025-06-11 21:31:31 -04:00
Greg Johnston
671ada36ab Merge pull request #4064 from metatoaster/pr_4061
Tests for #4061
2025-06-11 15:49:40 -04:00
Greg Johnston
a9ab4ea372 fix: memory leak introduced by #4015 2025-06-10 21:38:41 -04:00
Tommy Yu
1d72b75d03 test: chained resources as per #4061 2025-06-11 13:32:55 +12:00
Tommy Yu
798d8a4a9e fix: suspense_test corrected due to previous fix
- The `res_overview` previously being tracked inside the async caused an
  extra fetch to happen, and with that tracking being corrected, this no
  longer happens.
- Left a comment about how this is untracked.
2025-06-11 13:32:32 +12:00
Greg Johnston
f4e0be2d59 fix: do not track anything inside the async block of a Resource (closes #4060) (#4061) 2025-06-10 21:11:29 -04:00
Josiah Parry
05f50f7d27 chore: fix checkboxes in issue template (#4031) 2025-06-08 20:55:16 -04:00
Greg Johnston
a22d6f58be fix: allow nested untracked reads without false positives (closes #4032) (#4049) 2025-06-08 20:54:37 -04:00
Greg Johnston
ff21c9cae2 fix: suppress false-positive warning when adding children to a <For/> that is not currently mounted (closes #3385) (#4050)
* fix: suppress false-positive warning when adding children to a `<For/>` that is not currently mounted (closes #3385)

* remove track_caller
2025-06-08 20:54:25 -04:00
elias098
726b7b3116 fix: rework Subfield::track_field to remove duplicate track 2025-06-08 13:56:53 +02:00
elias098
6e91b6fada fix: fix triggers_for_path to prevent duplicate trigger on empty path 2025-06-08 13:40:49 +02:00
elias098
76f1c7a50c fix: triggers_for_path Vec capacity calculation changed to prevent reallocations 2025-06-08 13:19:19 +02:00
Greg Johnston
733a353820 fix: allow multiple #[middleware] macros (closes #4029) (#4048) 2025-06-06 20:50:52 -04:00
Greg Johnston
829b07b598 Merge pull request #4033 from leptos-rs/update_session_auth
Update `session_auth_axum` example
2025-06-02 19:44:21 -04:00
Saber Haj Rabiee
8c6059774f feat(CI): re-adding dependabot with grouped weekly updates 2025-06-01 09:20:10 -07:00
Saber Haj Rabiee
0e65034b01 feat(CI): run minimal-versions only on release tag 2025-06-01 09:18:41 -07:00
Saber Haj Rabiee
e1549c5ab3 chore: unify all deps + exact versioning in root workspace for better maintenance 2025-06-01 09:18:40 -07:00
Saber Haj Rabiee
624e91bb2a feat(CI): add checking minimal-versions 2025-06-01 08:55:41 -07:00
Greg Johnston
0df6cd74ee feat: simplify session_auth_axumby removing custom handlers 2025-05-30 18:32:22 -04:00
Greg Johnston
1da833a0aa fix: update session_auth_axum to Axum 0.8 2025-05-30 17:30:09 -04:00
Saikat Das
f37d124d6a Fix typo (#4025) 2025-05-29 12:39:32 -07:00
benwis
5d0e683b0f Update tachys to v0.2.3 2025-05-29 12:37:21 -07:00
lcnr
f34e3a5bc9 remove unnecessary where-clauses (#4023)
they may cause tachys to break with -Znext-solver
2025-05-29 12:35:50 -07:00
martin frances
d7dd6a1109 chore: bump rkyv to 0.8.10. (#4018) 2025-05-27 21:15:59 -04:00
Greg Johnston
ff81d34084 fix: fix <select> value by ensuring HTML children are mounted before building attributes (closes #4005) (#4008) 2025-05-27 21:15:41 -04:00
Soso
40a7aba3bc feat: impl AttributeValue for Cow<'_, str> (#4013) 2025-05-27 21:15:12 -04:00
Greg Johnston
d4dcafd908 Merge pull request #4015 from leptos-rs/3042v2
Fix context issues with nesting routing
2025-05-27 21:12:58 -04:00
Greg Johnston
82ccbbf806 copy-paste errors 2025-05-25 15:32:33 -04:00
Greg Johnston
5ba45bb1ed fix: allow Outlet to access context provided in parent view (closes #3042) 2025-05-24 17:51:22 -04:00
Greg Johnston
06dfa37eee feat: allow joining two context trees 2025-05-24 17:50:51 -04:00
Nicolas Cura
e82a0bbc7f chore: handle_response_inner public to be used in custom file_and_error_handler (closes #3996) (#3998) 2025-05-23 14:51:08 -04:00
Álvaro Mondéjar Rubio
4a972fc09e Merge pull request #4003 from mondeja/document-prop-attrs
docs: document `#[prop(default = ...)]` and `#[prop(name = ...)]`
2025-05-23 14:49:59 -04:00
Greg Johnston
07cf649e3b Merge pull request #3994 from leptos-rs/3983
fix: don't use `Arc::ptr_eq` for string comparison (closes #3983)
2025-05-19 19:15:17 -04:00
Greg Johnston
0e9598b799 fix: don't assume classList is unchanged when rebuilding a class effect for the first time (#3983 part two) 2025-05-19 09:42:33 -04:00
Greg Johnston
82303d7e33 fix: don't use Arc::ptr_eq for string comparison (closes #3983) 2025-05-19 09:27:17 -04:00
Álvaro Mondéjar Rubio
c4354ac965 fix: forward missing lint attributes passed to #[component] macro (#3989) 2025-05-18 20:38:16 -04:00
Dennis Waldherr
7de550685a docs: provide error message if file hashing is enabled but no hash file is present (#3990)
Co-authored-by: Dennis Waldherr <bytekeeper@mailbox.org>
2025-05-18 20:30:53 -04:00
mskorkowski
b1f3f6023e fix: smooshed static segments no longer matches the path #3968 (#3973)
* fix: smooshed static segments no longer matches the path #3968

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-05-18 20:29:40 -04:00
Greg Johnston
c189c3a45d fix: meta tags not properly rendered inside synchronously-available Suspend (closes #3976) (#3991) 2025-05-18 20:29:14 -04:00
Eric Roman
3903867f82 Fix spelling typos. (#3965) 2025-05-17 08:49:57 +02:00
Greg Johnston
a42fa452fc feat: add missing Resource::write() and similar functions (see #3959) (#3984) 2025-05-16 09:23:28 -04:00
Saber Haj Rabiee
cd48a6ac8c fix: remove non-existent feature dep in leptos_macro (#3985) 2025-05-16 09:23:04 -04:00
Greg Johnston
34c14adcb8 fix: render identical branch structure for out-of-order and async streaming of Suspense (closes #3970) (#3977) 2025-05-15 19:44:46 -04:00
Saber Haj Rabiee
50cee1d614 chore: upgrade rand and getrandom (#3840)
* chore: update rand and getrandom

* fix: use rng instead of thread_rng

* fix: enable getrandom wasm js backend in build.rs
2025-05-15 11:17:32 +02:00
Saber Haj Rabiee
7ca691305f chore: unify all deps with min occurrences of 2 (#3854) 2025-05-14 20:34:33 -04:00
Greg Johnston
830882f330 fix: allow rebuilding Vec<_> before it is mounted (closes #3962) (#3966) 2025-05-12 15:26:05 -04:00
Scott Little
13110a35e2 fix: add namespace to g in svg portals (closes #3958) (#3960) 2025-05-09 16:44:40 -04:00
Marcus Whybrow
304dc081a2 fix: correct doc comment for SsrMode::PartiallyBlocked (closes #3963) (#3964) 2025-05-09 09:39:00 -07:00
Serhii Shliakhov
14f6bc658e fix: deprecated parameters js warning (#3956) 2025-05-09 08:04:15 -04:00
Eric Roman
09894aaca9 Remove unnecessary "crate::" prefix in a documentation example. (#3952) 2025-05-08 07:43:27 -07:00
Greg Johnston
2ee4444bb4 v0.8.2 2025-05-06 14:09:35 -04:00
Luxalpa
03a1c1e7a6 fix: ensure unique style caching hashes (#3947) 2025-05-06 14:00:29 -04:00
Greg Johnston
12e49ed996 Merge pull request #3950 from leptos-rs/3945
fix: correct order of meta content relative to surrounding tags (closes #3945)
2025-05-06 13:59:28 -04:00
Greg Johnston
1e281e9e74 fix(examples): bugfix revealed a pre-existing bug with meta tags in the hackernews demo! 2025-05-06 11:49:43 -04:00
Greg Johnston
bd475f89d0 fix: correct order of meta content relative to surrounding tags (closes #3945) 2025-05-06 11:19:19 -04:00
Greg Johnston
3d91b5e90f v0.8.1 2025-05-05 21:39:43 -04:00
Greg Johnston
96d8d5218c Merge pull request #3942 from leptos-rs/3907
Some `islands_router` improvements
2025-05-05 21:33:57 -04:00
Greg Johnston
84caa35cef feat: add .map() and .and_then() on LocalResource (#3941) 2025-05-05 21:20:34 -04:00
Greg Johnston
fc8b55161c fix: remove extra marker node after text node when marking a branch (closes #3936) (#3940) 2025-05-05 21:20:16 -04:00
Greg Johnston
657052466b fix: use a runtime check rather than an unnecessary Either to determine how to render islands (see #3896; closes #3929) (#3938) 2025-05-05 19:41:29 -04:00
william light
efe8336363 reactive_stores: implement PartialEq and Eq for Store (#3915)
StoredValue also has these implemented and does the same thing.
2025-05-05 14:32:42 -04:00
Greg Johnston
770881842c fix: correctly provide context through islands to children (closes #3928) (#3933) 2025-05-05 13:00:40 -04:00
Greg Johnston
0d540ef02f fix: ensure that nested children of a RenderEffect are dropped while dropped a RenderEffect (closes #3922) (#3926) 2025-05-05 13:00:20 -04:00
Saber Haj Rabiee
dc1885ad92 feat: check the counter_isomorphic release build with the leptos_debuginfo flag (#3918) 2025-05-04 15:22:04 -04:00
Eric Roman
61bf87439a Fix some typos in the documentation/examples for reactive store. (#3924) 2025-05-03 20:50:13 -04:00
Greg Johnston
308568e520 fix(CI): prevent regreession from nightly clippy in autofix (#3917)
* fix(CI): prevent regreession from nightly clippy in autofix

* chore: format

* chore: update nightly to 2025-04-16 (proc-macro span, #3852)

* chore: improve the autofix ci workflow

* fix: adjust ServerFn macro test stderr based on nightly-2025-04-16

* fix: limit server_fn server macro trybuild tests nightly only
2025-05-03 20:47:42 -04:00
Greg Johnston
1b0f32dc4c fix: clear and re-throw errors in correct order (#3923) 2025-05-03 20:46:57 -04:00
Greg Johnston
2e0b3011d9 fix: correct issues with StaticVec::rebuild() by aligning implementation with Vec::rebuild() (closes #3906) (#3920) 2025-05-03 08:56:36 -04:00
Greg Johnston
680d4ccd07 fix: do not diff islands in islands_router mode (see #3907) 2025-05-02 21:20:16 -04:00
Greg Johnston
325f9cbe33 fix: don't handle ActionForm (et al) with the islands_router default <form> behavior (see #3907) 2025-05-02 21:12:20 -04:00
Greg Johnston
26ab392c95 fix: allow nested Suspense > ErrorBoundary > Suspense (closes #3908) (#3913) 2025-05-02 16:59:04 -04:00
Saber Haj Rabiee
3a4e2a19aa fix: limit server_fn server macro trybuild tests nightly only 2025-05-02 08:32:38 -07:00
Saber Haj Rabiee
eed3d21b40 fix: adjust ServerFn macro test stderr based on nightly-2025-04-16 2025-05-02 08:01:15 -07:00
Saber Haj Rabiee
7ae386285d chore: improve the autofix ci workflow 2025-05-02 07:27:45 -07:00
Saber Haj Rabiee
ebcc51136d chore: update nightly to 2025-04-16 (proc-macro span, #3852) 2025-05-02 07:13:34 -07:00
Saber Haj Rabiee
e10ded4fd0 chore: format 2025-05-02 06:58:01 -07:00
Saber Haj Rabiee
67be872f58 fix(CI): prevent regreession from nightly clippy in autofix 2025-05-02 06:31:39 -07:00
LeoniePhiline
e5b21ac0fc fix(docs): correct panic message in copied example code (#3911) 2025-05-02 08:14:36 -04:00
benwis
9b2e313d20 v0.8.0 2025-05-01 15:26:21 -07:00
Greg Johnston
bc79232033 feat: impl From<MappedSignal<T>> for Signal<T> (#3897) 2025-05-01 14:56:27 -04:00
Saber Haj Rabiee
a7bb2565c4 fix(examples): websocket tests fail (occasionally) second attemp (#3910)
do not check the label immediately
2025-05-01 14:54:57 -04:00
zakstucke
2e393aaca0 fix: leptos_debuginfo (#3899) 2025-05-01 14:54:24 -04:00
Greg Johnston
e37711cb85 fix: correct hydration for elements after island children (closes #3904) (#3905) 2025-05-01 09:44:40 -04:00
Greg Johnston
627b553e60 fix: prevent sibling context leakage in islands (closes #3902) (#3903) 2025-04-30 21:33:54 -04:00
Greg Johnston
e2f9aca466 Merge pull request #3901 from leptos-rs/3896
Fix some island-routing issues
2025-04-30 14:27:31 -04:00
Greg Johnston
970544ed0b fix: correctly hydrate branches inside islands when using islands-router (closes #3896) 2025-04-30 08:48:40 -04:00
Greg Johnston
0c3b3c440f chore: remove forgotten log 2025-04-30 08:36:23 -04:00
nickburlett
6578086e09 fix(examples): incorrect routes in hackernews example (closes #3892) (#3894)
* fix(examples): incorrect routes in hackernews example (closes #3892)

1. `Avoid calling category()` twice on the story type.
2. `get_static_file()` returns Err on not found, so don’t
   unconditionally `unwrap()` it

* cargo fmt

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2025-04-30 07:43:12 -04:00
Greg Johnston
113aba9666 docs: add note about file hashing in Stylesheet docs (#3898) 2025-04-29 19:03:18 -07:00
Greg Johnston
58d7475193 fix: don't render branching comments inside script/style tags 2025-04-29 20:32:56 -04:00
Greg Johnston
04d80ff8d0 chore: clippy 2025-04-29 20:31:44 -04:00
Greg Johnston
7971a2dccb fix: marking AnyView branches with out-of-order streaming (for islands_router) 2025-04-29 20:30:40 -04:00
Greg Johnston
e2ea4277bc fix(examples): broken favicons in hackernews examples (closes #3890) (#3891) 2025-04-28 09:52:15 -04:00
Greg Johnston
171c8e7ff7 v0.8.0-rc3 2025-04-26 15:53:20 -04:00
Greg Johnston
53ffbeeb67 chore: fmt 2025-04-26 15:49:32 -04:00
Greg Johnston
ee86844077 Merge pull request #3882 from leptos-rs/3871
fix: remove event listeners from Suspense fallback during SSR (closes #3871)
2025-04-26 12:48:45 -04:00
Greg Johnston
1cee3f2f52 Merge branch 'main' into 3871 2025-04-26 12:48:40 -04:00
Greg Johnston
23c89dbfe1 Merge pull request #3878 from leptos-rs/3828
fix: correctly calculate starting index for first new key (closes #3828)
2025-04-26 12:48:12 -04:00
Greg Johnston
9f71f39f89 Merge branch 'main' into 3828 2025-04-26 12:47:56 -04:00
Greg Johnston
ef1d0f108a Merge pull request #3880 from sabify/websocket-example
fix(examples): websocket example tests fail on latency
2025-04-26 12:47:17 -04:00
Greg Johnston
a7a78317b7 Merge pull request #3879 from huuff/prelude-textprop
chore: put `TextProp` in the prelude (closes #3877)
2025-04-26 12:46:53 -04:00
autofix-ci[bot]
5005cc3587 [autofix.ci] apply automated fixes (attempt 2/3) 2025-04-26 16:15:06 +00:00
autofix-ci[bot]
08708f3388 [autofix.ci] apply automated fixes 2025-04-26 16:03:45 +00:00
Greg Johnston
c19c1b32f1 fix: remove event listeners from Suspense fallback during SSR (closes #3871) 2025-04-26 11:48:59 -04:00
Saber Haj Rabiee
e70cc08e96 fix(examples): websocket example tests fail on latency 2025-04-26 07:06:50 -07:00
autofix-ci[bot]
97175663ef [autofix.ci] apply automated fixes 2025-04-26 00:05:33 +00:00
Haf
92524a93cd chore: put TextProp in the prelude (closes #3877) 2025-04-25 23:50:08 +02:00
autofix-ci[bot]
9449f41ca9 [autofix.ci] apply automated fixes (attempt 2/3) 2025-04-25 20:31:56 +00:00
autofix-ci[bot]
d979055b70 [autofix.ci] apply automated fixes 2025-04-25 20:18:03 +00:00
Greg Johnston
97686f71a5 fix: improve support for keyed fields in ArcField<_> 2025-04-25 16:04:01 -04:00
Greg Johnston
06a0c768dc fix: correctly calculate starting index for first new key (closes #3828) 2025-04-25 15:57:30 -04:00
Saber Haj Rabiee
fff6a508fc feat(examples): add WebSocket example (#3853) 2025-04-24 20:17:08 -04:00
Greg Johnston
e65fc23fc7 fix: prevent infinite loop when sending Result over websocket, remove Display bound (#3848)
* chore: easing `Display` bound on `FromServerFnError`, #3811 follow-up

* fix: send/receive websocket data

* fix: clippy warnings

* fix: server_fn_axum example

* fix: make de/serialize_result functions public

* fix: make websocket result ser/de private

* chore: make the doc a comment and remove allow dead_code
2025-04-23 07:52:42 -04:00
Saber Haj Rabiee
f83b14d76c feat: enhancing ByteStream error handling (#3869)
* feat: enhancing `ByteStream` error handling

* fix: easing unnecessary trait bound over some `TextStream` methods
2025-04-23 07:38:39 -04:00
zakstucke
62dac6fb8a fix: prevent ScopedFuture stopping owner cleanup (#3863) 2025-04-23 07:37:12 -04:00
Rakshith Ravi
b36dec8269 feat: add header generation method to BrowserResponse (#3873) 2025-04-23 07:33:18 -04:00
Fea
0c50852251 fix: Use stabilized ClipboardEvent (#3849) 2025-04-23 07:27:24 -04:00
Nikolai Morin
50cb6005a8 chore(examples): complete the migration to Tailwind 4 (#3861)
The tailwind_csr example was not working yet with version 4, and the
tailwind_actix example still had the no-longer-needed config file.

This also brings the three tailwind examples back in sync, mostly. I
don't know why the axum example has a packages.json and
packages-lock.json file, to be honest.
2025-04-23 07:26:56 -04:00
Sathish
b725291ce9 chore: forward lint attributes used with #[component] macro (#3864)
* Forward lint attributes used with #[component] macro

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-04-23 07:26:26 -04:00
Greg Johnston
ed6d45d92d Merge pull request #3870 from leptos-rs/3851
Error boundary fixes
2025-04-23 07:25:41 -04:00
Greg Johnston
73b5587738 fix: correctly insert out-of-order stream chunks when Ok 2025-04-21 13:12:30 -04:00
Greg Johnston
68813a5918 fix: clear old errors when going from error state to error state (closes #3850) 2025-04-21 12:10:47 -04:00
Greg Johnston
8f6a96341e fix: wait for any inner Suspense before rendering ErrorBoundary (closes #3851) 2025-04-21 09:29:33 -04:00
Greg Johnston
046d5286c3 fix: correctly flush synchronous parts of SSR stream when appending another StreamBuilder 2025-04-21 09:28:14 -04:00
Greg Johnston
b45f982feb fix: close Actix websocket stream when browser disconnects (closes #3865) (#3866) 2025-04-19 16:47:09 -04:00
Greg Johnston
2b50ddc0db v0.8.0-rc2 2025-04-18 08:43:16 -04:00
Saber Haj Rabiee
c743f0641c chore: make the doc a comment and remove allow dead_code 2025-04-17 06:45:40 -07:00
Saber Haj Rabiee
078c252e2e fix: make websocket result ser/de private 2025-04-17 03:38:04 -07:00
martin frances
410aedbba8 chore: ran cargo outdated. (#3722)
* chore: ran cargo outdated fixed issues.

In bumping the rand crate, calls to thread_rng() becomes rng().

* backed out changes to rand.
2025-04-16 16:42:01 -07:00
Saber Haj Rabiee
00e474599f fix: reactive_graph keymap impl and clippy warnings (#3843) 2025-04-16 16:39:07 -07:00
Greg Johnston
8f38559aa2 chore(nightly): update proc-macro span file name method name (#3852) 2025-04-16 16:35:59 -07:00
Greg Johnston
3934c8b162 Update issue templates 2025-04-16 09:15:10 -04:00
Saber Haj Rabiee
de3a558203 fix: make de/serialize_result functions public 2025-04-15 09:24:43 -07:00
Saber Haj Rabiee
4d20105760 fix: server_fn_axum example 2025-04-15 09:23:32 -07:00
Saber Haj Rabiee
b95e827b8b fix: clippy warnings 2025-04-15 08:31:42 -07:00
Saber Haj Rabiee
30c445a419 fix: send/receive websocket data 2025-04-15 07:43:47 -07:00
Saber Haj Rabiee
6d5ab73594 chore: easing Display bound on FromServerFnError, #3811 follow-up 2025-04-14 23:52:02 -07:00
Greg Johnston
e0bf5ec480 fix: don't try to move keyed elements within the DOM if they're not yet mounted (closes #3844) (#3846) 2025-04-14 20:06:31 -04:00
Greg Johnston
28d9b3676d fix: correctly decode base64-encoded error messages stored in URL (#3842) 2025-04-13 13:28:58 -04:00
Greg Johnston
bb47916ebe fix: call additional_context after providing other server context in all cases (#3841) 2025-04-12 20:29:43 -04:00
Greg Johnston
cf843a8349 v0.8.0-rc1 2025-04-11 12:03:17 -04:00
Saber Haj Rabiee
7637e586d5 feat: enhancing server_fn errors (#3811)
* feat: enhancing server_fn errors

* fix: `server_fn` `not_result.stderr` line numbers

* fix: example server_fns_axum

* fix: not need to force ser/de traits

* fix(docs): deserialize error comment

* fix: remove unneeded traits bounds
2025-04-10 14:04:16 -07:00
Mykyta
ba7bfd8bac feat: allow using different error types for req/resp with WebSockets, closes #3724 (#3766)
* feat: allow using different error types for request/response with WebSocket

* [autofix.ci] apply automated fixes

* chore: clean up merge issues

* chore: fix custom client example

* we can't use nightly features on stable

* update flake inputs

* include gcc and glib to flake dev shell

* update expected stderr outputs server_fn/tests/invalid

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2025-04-09 10:03:47 -07:00
Saber Haj Rabiee
8bc4fd4198 Introducing cargo all-features clippy|nextest part of build process (#3767)
* fix: intoducing cargo all-features clippy

* fix: change check to clippy for better diagnostics

* chore: build is redundant

* fix: lint task

* feat: speed up tests by 2x with cargo-nextest

* fix: re-add flags

* fix: router example build process

* fix: correct clippy arguments

* fix: adapt examples makefile to new tools

* fix(CI): add cargo-all-features part of CI dep

* fix: just warn if there is no tests

* fix(CI): add clippy and rustfmt components

* fix: nextest in examples

* fix: clippy should not run on empty set of features in examples
(quickfix)

* fix: pin cargo-all-features installation to a branch

* fix: nextest --no-tests=warn?

* fix: do not use built-in cargo-make workflows

* fix: remove --all-targets

* fix: do not run tests in parallel in certain examples

* fix: disable nextest for examples

* fix: properly override the make task

* chore: run tests with no-deps

* fix: hackernews_islands_axum

* fix(CI): properly use --no-deps

* fix(CI): --no-deps is not supported in tests

* fix(CI): run doctests separately due to stable rust limitation in nextest

* fix(examples): makefile lint recursion

* fix(CI): run tests correctly

* fix: remove unused clear in test makefile

* fix: --no-deps positional arg in clippy

* fix: run doctests for all-features

* fix: running cargo-all-features over doctests

* fix: improve playwright makefile
2025-04-07 08:57:01 -07:00
Alexander Krivács Schrøder
3254d38d2d Revert "Remove getrandom (#3589)" (#3830)
Restores `getrandom` dependency to avoid compilation error when
compiling for WASM with the `nonce` feature.
2025-04-07 08:42:13 -07:00
Greg Johnston
b4abac2614 chore: missing Copy/Clone impls for MappedSignal (#3827) 2025-04-06 19:24:21 -04:00
Greg Johnston
767147f4ab Merge pull request #3802 from sabify/any-spawner-race
fix: prevent race condition in executor initialization + docs, optimization and tests
2025-04-06 15:39:34 -04:00
Greg Johnston
9128545388 fix: do not match static segment with last character missing before slash (closes #3817) (#3823) 2025-04-05 21:58:50 -04:00
Greg Johnston
b8810ba42f fix: correctly establish root ownership for static site generation (closes #3822) (#3824) 2025-04-05 19:50:28 -04:00
Saber Haj Rabiee
6006c33307 Revert "fix: more atomic orderings"
This reverts commit 02f4cfe437.
2025-04-03 09:11:14 -07:00
Saber Haj Rabiee
e113c79fb8 Revert "fix: preserve the ordering of read/write operations on atomic variables"
This reverts commit 2ea0381bb5.
2025-04-03 09:10:20 -07:00
尹吉峰
bdc73594ea change: pass reference to key for Selector::selected (#3694) 2025-04-02 21:43:13 -04:00
Pico Bolero
a55e82afe3 chore: migrate Axum example from Tailwind 3 to Tailwind 4 (#3804)
documentation e.g., input.css and output.css.
Uses @tailwindcss/cli tool to build the output.css
Removes no longer needed tailwind.config.js as that configuration can be
embedded in input.css.
Removes src/style.css as it only included tailwind 3 configurations that
are no longer needed.
2025-04-02 20:58:36 -04:00
Greg Johnston
300d301c11 Merge pull request #3755 from ifiokjr/feat/support_aliased_results_in_server_fn
feat: support aliased `Result` return types for `server_fn`
2025-04-02 20:56:29 -04:00
Greg Johnston
98ee336d0c fix: remove SendOption from public API of actions (#3812) 2025-04-02 13:03:21 -04:00
mahdi739
f102b2f43b fix: Move several Into* trait impls for store fields out of stable module for wider use (#3807)
* Move several Into* trait impls for store fields out of stable module for wider use

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-04-02 09:29:23 -04:00
Greg Johnston
47aebf3e22 fix: allow custom status codes or redirects for route fallbacks (#3808) 2025-04-01 19:25:59 -04:00
jasper
7d3a9da577 chore: add track_caller to store field methods (#3805) 2025-03-30 16:13:44 -04:00
Saber Haj Rabiee
6d90e05c13 fix: do not expose any_spawner::Executor in prelude to encourage local
spawn/spawn_local* implementations
2025-03-30 03:41:48 -07:00
Saber Haj Rabiee
5d0fd5b693 fix: four more spawns usage 2025-03-30 01:52:18 -07:00
Saber Haj Rabiee
d665719b27 fix: no global spawn for wasm executor 2025-03-30 00:28:33 -07:00
Saber Haj Rabiee
ae373b5a52 fix: revert back tick implementation to respect global executor 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
02f4cfe437 fix: more atomic orderings 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
40710adfd5 fix: glib test 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
d0f26ac64b chore: use futures_lite yield_now in glib test 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
9d2ac0a18f fix: improving tick logic in any_spawner 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
ab0832ad68 fix: correctly using executator tick instead of timer 2025-03-29 23:19:45 -07:00
Saber Haj Rabiee
2ea0381bb5 fix: preserve the ordering of read/write operations on atomic variables 2025-03-29 23:19:38 -07:00
Saber Haj Rabiee
94acdc24c7 fix: wasm-bindgen unused tests warnings 2025-03-29 23:17:35 -07:00
Saber Haj Rabiee
c175357e69 fix: lib docs 2025-03-29 23:17:35 -07:00
Saber Haj Rabiee
ef86a50c68 fix: wasm in spawn_local condition 2025-03-29 23:17:35 -07:00
Saber Haj Rabiee
e8e0808684 fix: run tests sequentially for glib 2025-03-29 23:17:35 -07:00
Saber Haj Rabiee
4973cc9eff fix: prevent race condition in executor + docs, optimization and tests 2025-03-29 23:17:35 -07:00
Greg Johnston
1a83a78980 Merge pull request #3803 from leptos-rs/store-test-fixes
Store test fixes
2025-03-29 14:55:36 -04:00
ChosunOne
4c6c79da40 feat: add support for more HTTP methods in server fn codecs (#3797) 2025-03-29 14:55:08 -04:00
Greg Johnston
c204df2ff3 Merge pull request #3785 from sabify/fix-portal-example
fix: portal example
2025-03-29 13:56:16 -04:00
zakstucke
0794681011 feat: derive_local for ArcSignal<T, LocalStorage> (#3798) 2025-03-29 13:55:11 -04:00
Greg Johnston
45dc1f4690 chore: update Store Option patch tests to reflect correct behavior 2025-03-29 13:45:39 -04:00
Greg Johnston
b80d58039e fix: prevent sibling over-notification due to #3799) 2025-03-29 13:20:52 -04:00
Greg Johnston
a7619c63bf Merge pull request #3793 from leptos-rs/3783
Improved handling of `<Title/>`
2025-03-28 15:43:45 -04:00
Greg Johnston
4038438cb4 Merge pull request #3799 from leptos-rs/3790
Fix Store notification order for nested keyed fields
2025-03-28 15:43:29 -04:00
Greg Johnston
f23335278b fix: allow repeated class= for all tuples, not only static ones (closes #3794) (#3801) 2025-03-28 15:43:13 -04:00
Greg Johnston
7f51a46b1a fix: correctly notify parent fields when patching 2025-03-27 20:20:04 -04:00
Greg Johnston
a54e3fdb40 fix: notify keyed Store fields from the top down (closes #3790) 2025-03-27 20:19:46 -04:00
Greg Johnston
64ba9b9dd4 fix: do not re-create effect when building a new route 2025-03-27 17:21:16 -04:00
Greg Johnston
568a16b880 chore: clippy 2025-03-26 22:07:32 -04:00
autofix-ci[bot]
d9179f0b19 [autofix.ci] apply automated fixes (attempt 2/3) 2025-03-26 20:05:52 +00:00
autofix-ci[bot]
62161c83c5 [autofix.ci] apply automated fixes 2025-03-26 19:58:41 +00:00
Greg Johnston
97f31f1af5 fix: smarter handling of <Title/> (closes #3783) 2025-03-26 15:46:55 -04:00
Greg Johnston
aa4dd53890 fix: correct insertion of a list of items when the first one doesn't exist in the DOM 2025-03-26 15:46:37 -04:00
Saber Haj Rabiee
a0c6f2b7ac fix: there is no way in cargo-make to override external task, so run
ordinary test for every examples
2025-03-26 08:25:28 -07:00
Ifiok Jr.
753d02a14c chore: fix formatting 2025-03-26 15:12:32 +00:00
Ifiok Jr.
ae23364ef8 chore: add comment explaining annotation 2025-03-26 15:12:32 +00:00
Ifiok Jr.
a74713a371 fix: only use diagnostic attribute on versions after 1.78 2025-03-26 15:12:31 +00:00
Ifiok Jr.
72e84f4e38 feat: support aliased Result return types for server_fn
- Enhanced error messages for better clarity when server functions do not meet the expected return type requirements.
- Added `trybuild` tests to ensure behaviour is not broken in future releases.
2025-03-26 15:12:31 +00:00
Ifiok Jr.
0a13ebd94d fix: also include ServerFnErrorErr in prelude 2025-03-26 15:12:30 +00:00
Ifiok Jr.
23c6f548ec fix: add FromServerFnError to leptos::prelude::* 2025-03-26 15:12:30 +00:00
Saber Haj Rabiee
543063ac24 fix: run cargo test for portal eample (minify tests) 2025-03-26 08:07:43 -07:00
Saber Haj Rabiee
04da08f82d fix: portal example makefile to run cargo test 2025-03-25 23:45:14 -07:00
Saber Haj Rabiee
c8ee4b3e05 fix: portal minify test 2025-03-25 23:42:09 -07:00
Saber Haj Rabiee
999a09d064 fix: quoting strings in portal example 2025-03-25 23:27:29 -07:00
Saber Haj Rabiee
9a32ae7bd5 fix: write simple minifier for portal tests 2025-03-25 23:12:19 -07:00
zakstucke
a96ef29d9e feat: re-export the codee crate to make custom encodings for resources easier (#3761) 2025-03-25 21:40:48 -04:00
Saber Haj Rabiee
0553c2af30 fix: signal CI to install chromedriver 2025-03-25 12:58:14 -07:00
Saber Haj Rabiee
668b7b4adb fix: limit opt-level to test 2025-03-25 12:57:51 -07:00
Saber Haj Rabiee
0a90def2da fix: portal example too many locals 2025-03-25 12:32:44 -07:00
Saber Haj Rabiee
d095879ef2 fix: portal example 2025-03-25 12:16:19 -07:00
Saber Haj Rabiee
2508b016d5 fix(CI): run only the exact examples on the only examples change (#3782)
* fix(CI): run only the exact examples on the only examples change

* chore: format html (retrigger ci)

* fix: missing the right field

* fix(CI): add missing output key

* fix(CI): properly set matrix directory for test-only-examples

* fix(CI): missing bracket token

* fix(CI): do not run semver check on examples only tests

* fix(CI): semver logic
2025-03-25 09:38:25 -07:00
Saber Haj Rabiee
bf35298708 fix: router example build process (#3779)
* fix: router example build process

* fix: a working router example
2025-03-24 23:53:45 -07:00
Greg Johnston
1a1e436cff fix: correctly handle optional parameters in ParentRoute (#3784) 2025-03-24 20:15:31 -04:00
Greg Johnston
b4731e61c6 Merge pull request #3781 from leptos-rs/partialeq-sendoption
Tweaks to `MaybeSendWrapperOption<_>`
2025-03-24 20:12:06 -04:00
autofix-ci[bot]
5bdc68a2f2 [autofix.ci] apply automated fixes 2025-03-24 21:56:27 +00:00
Greg Johnston
0a6cd9e33f update example 2025-03-24 17:40:52 -04:00
Greg Johnston
eca8e3cc72 chore: update tests 2025-03-23 20:33:51 -04:00
Greg Johnston
e0856eee33 chore: remove duplicate implementation due to merge 2025-03-23 20:20:30 -04:00
Greg Johnston
514cf62bf6 docs: add some more documentation to SendOption 2025-03-23 20:20:12 -04:00
Greg Johnston
26522666d5 chore: rename MaybeSendWrapperOption to SendOption 2025-03-23 20:19:30 -04:00
Greg Johnston
dcb3f202cd fix: correctly handle == and similar traits for MaybeSendWrapperOption 2025-03-23 20:14:43 -04:00
Greg Johnston
b032c15a84 Merge pull request #3762 from leptos-rs/reduce-local-signals
Reduce use local signals for `Action::new_local` and similar primitives
2025-03-23 15:55:02 -04:00
Saber Haj Rabiee
f24e804985 fix(CI): toolchain will be determined and test against by CI (#3778)
* fix(CI): toolchain will be determined and test against by CI

* chore: formatting examples

* fix: clippy
2025-03-23 10:10:52 -07:00
Alexander Krivács Schrøder
2c1194a71a docs: correct docs for default value for hash_files (closes #3774) (#3775)
Resolves #3774
2025-03-23 09:08:20 -04:00
Greg Johnston
fcdc9a07e4 Merge pull request #3777 from sabify/fix-ci-examples-logic
fix(CI): conditional executions of only changed examples
2025-03-23 09:07:16 -04:00
Greg Johnston
3d5b0127c2 Merge pull request #3776 from sabify/remove-ci-cache
fix(CI): remove caching
2025-03-23 09:06:59 -04:00
Saber Haj Rabiee
1cbbcda48b fix(CI): conditional executions of only changed examples 2025-03-23 01:42:53 -07:00
Saber Haj Rabiee
d9b998ed0c fix(CI): add was32 target in rust-toolchain setup 2025-03-23 01:12:46 -07:00
Saber Haj Rabiee
79f0482325 fix(CI): install trunk with bininstall 2025-03-23 01:12:13 -07:00
Saber Haj Rabiee
78d70fc400 fix(CI): caching may not be needed 2025-03-23 01:11:27 -07:00
Saber Haj Rabiee
2a011dd89c fix(CI): install deno only if needed, #3768 follow-up (#3773) 2025-03-23 00:04:07 -07:00
Saber Haj Rabiee
bc7c59d880 fix: clippy errors (#3772)
* fix: use map instead of if else

* fix: needless lifetime
2025-03-22 23:44:49 -07:00
Greg Johnston
a5d158765f fix: support IntoFragment for single element (closes #3757) (#3759) 2025-03-22 19:55:16 -04:00
Saber Haj Rabiee
999c8be6a0 fix(CI): install deps only if needed, speeds up CI (#3768) 2025-03-22 15:30:53 -07:00
Greg Johnston
5cfb16c79f feat: consolidate sync/unsync Action APIs 2025-03-22 15:24:10 -04:00
Greg Johnston
fd95f11dff Revert "fix: use signals rather than Action::new_local() (closes #3746) (#3749)"
This reverts commit 2658ae8b40.
2025-03-22 15:24:10 -04:00
Greg Johnston
2d8336ac91 feat: consolidate sync/unsync Action APIs 2025-03-22 15:24:10 -04:00
Saber Haj Rabiee
bb0c352f75 fix: remove duplicate semver (#3764) 2025-03-22 11:50:43 -07:00
Saber Haj Rabiee
b6eddca2c1 fix(CI): optimize CI workflow (#3758)
* chore: optimize CI

* chore: fomratting makefile to retrigger ci

* fix: run tests against both stable and nightly toolchains

* chore: simplify workflow

* fix(CI): remove unused inputs

* fix(CI): correctly indicating erased mode

* fix(CI): replace input with the name

* fix(CI): fixed logic of running cargo cmake on workspace on each example
and memeber!

* fix(CI): organized, simplified and unified CI jobs

* chore: change CI name

* fix(CI): keyword

* fix(CI): wait for dependent jobs
2025-03-22 09:48:54 -07:00
Saber Haj Rabiee
57272926ad fix: properly feature gating ui macro tests (Closes #3742) (#3756)
* fix: properly feature gating ui macro tests (Closes #3742)

* fix: wrongly gated main in test and added more gates

* docs: formatting
2025-03-22 09:48:08 -07:00
Greg Johnston
e903c297a9 chore: add SignalSetter to prelude (closes #3547) (#3753) 2025-03-21 16:58:00 -04:00
Nicolas Cura
b6e6588c8d fix: make trailing comma optional for either!() macro (#3736) 2025-03-21 16:39:52 -04:00
Greg Johnston
713abb3072 chore: ensure WASM target is installed for examples with provided rust-toolchain.toml (closes #3717) (#3752) 2025-03-21 16:38:35 -04:00
Greg Johnston
fce202db39 Merge pull request #3529 from leptos-rs/leptos_0.8
Leptos 0.8
2025-03-21 16:18:55 -04:00
Greg Johnston
1fe39bf7c8 Merge remote-tracking branch 'origin' into leptos_0.8 2025-03-21 16:18:01 -04:00
Jérôme MEVEL
fb5fdfc429 docs: in Effect::watch, refer to 'dependency_fn' and 'handler' in doc (#3731) 2025-03-21 16:01:56 -04:00
Alexander Krivács Schrøder
c738c5d81b feat: switch extract() helper to use ServerFnErrorErr (closes #3745) (#3750)
* feat: switch `extract()` helper to use `ServerFnErrorErr`

This provides much better compatibility with server functions using
custom errors while still working as before with server functions using
`ServerFnError`

* style: apply autofix diff
2025-03-21 16:01:12 -04:00
Greg Johnston
2658ae8b40 fix: use signals rather than Action::new_local() (closes #3746) (#3749) 2025-03-21 15:51:44 -04:00
Saber Haj Rabiee
a0d75fda03 chore: no need to filter out "nightly" feature as of #3735 (#3747)
* chore: no need to filter out "nightly" feature as of #3735

* fix: enable hot-reload only if in all debug mode, nightly feature and
nightly rustc

* fix: do not build/test against nightly feature alone

* fix: don not test against nightly feature alone

* fix: add trace-components to denylist
2025-03-21 10:16:16 -07:00
Saber Haj Rabiee
716c770a45 fix(CI): sermver job name (#3748) 2025-03-21 06:42:42 -07:00
Saber Haj Rabiee
a2d268606c fix(CI): cleanup directory no matter of results (#3743) 2025-03-20 17:53:25 -07:00
zakstucke
90fc727d60 ArcLocalResource fix (#3740) 2025-03-20 16:20:05 -07:00
zakstucke
aae827923c ArcLocalResource fix (0.8) (#3741) 2025-03-20 16:19:32 -07:00
Saber Haj Rabiee
52c770c7da fix(CI): free-up disk, properly gate nightly feature and pre-install deps (#3735)
* fix(CI): pre-install tailwind and sass

* chore: retrigger CI

* fix(CI): properly set `erased_mode` in examples

* fix(CI): workflow logic install deps locally

* chore(CI): organized tailwind and sass versions

* fix: properly ignore nightly features on stable rustc

* fix(CI): typo

* fix: missing cfg attr

* fix: properly gate nightly module in `reactive_graph``

* fix: complete `rustc_nightly` cfg gate

* fix(CI): making even more space for CI workers

* fix: missing one more rustc_nightly gated feature

* fix: maximize the speed of cargo-all-features by limiting combinations to 2
2025-03-20 14:28:07 -07:00
Saber Haj Rabiee
9210636266 fix(CI): cancel in-group inflight and pending jobs on new pushes in CI (#3739) 2025-03-20 13:02:17 -07:00
Saber Haj Rabiee
012616c4d8 fix(CI): switch to stable in semver for most compatibility (#3737) 2025-03-20 13:01:45 -07:00
Evan Almloff
6b9520f1a9 More flexible server fn macro api (#3725)
* Split up the server function expansion into multiple functions

* Use LitStr instead of Literal

* Refactor out more of the expansion

* Fix the parse example

* Expose some of the parsed server function arguments and body fields

* mark ServerFnBody as non_exhaustive

* [autofix.ci] apply automated fixes

* Fix server function paths

* rename from impl

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-03-20 09:55:38 -07:00
benwis
9052804ab4 v0.7.8 2025-03-20 08:21:11 -07:00
benwis
e95c903e85 v0.7.7 2025-03-19 18:19:37 -07:00
Greg Johnston
2faae43d5f v0.8.0-beta 2025-03-19 21:02:10 -04:00
Nicolas Cura
6760c87e83 Merge pull request #3727 from NCura/patch-1
Fix typo
2025-03-19 21:02:10 -04:00
bimoadityar
8a179e6f45 examples: update example tailwind input css to v4 (#3702) 2025-03-19 21:01:03 -04:00
Greg Johnston
e765f99016 fix: matching optional params after an initial static param (closes #3730) (#3732) 2025-03-19 20:59:41 -04:00
autofix-ci[bot]
e19e42c650 [autofix.ci] apply automated fixes 2025-03-19 23:42:02 +00:00
zakstucke
fb4be49ebf feat: remove SendWrapper from the external interface of LocalResource (#3715) 2025-03-19 19:26:14 -04:00
Nicolas Cura
30548eca31 Merge pull request #3727 from NCura/patch-1
Fix typo
2025-03-18 14:30:23 -04:00
Greg Johnston
0b4cbbc17d Merge remote-tracking branch 'origin' into leptos_0.8 2025-03-16 14:27:23 -04:00
Greg Johnston
dbbeb7c6ef fix: don't retrigger rendering when only param has changed (closes #3719( 2025-03-16 14:26:23 -04:00
Greg Johnston
36aef2565d chore: merge issues 2025-03-16 14:25:31 -04:00
Greg Johnston
a2a7eb8a2a Merge remote-tracking branch 'origin' into leptos_0.8 2025-03-16 14:21:21 -04:00
Zak Stucke
97e22e2506 Extra trait impls for MaybeSendWrapper 2025-03-16 14:20:35 -04:00
autofix-ci[bot]
8bedacb0c7 [autofix.ci] apply automated fixes 2025-03-16 14:20:35 -04:00
Zak Stucke
56b7b9a16a Remove SendWrapper from the external interface of LocalResource, by internalising a MaybeSendWrapper inside ArcAsyncDerived 2025-03-16 14:20:35 -04:00
Greg Johnston
d04d4c77f9 Merge pull request #3720 from metatoaster/regression_tests_3502
test: regression from #3502
2025-03-16 14:16:05 -04:00
Tommy Yu
5c75928b5b test: avoiding testdriver browser contention
- The number of tests have increased sufficiently that the browser test
  instances spawned by the driver are choked out on CI.
2025-03-16 22:43:21 +13:00
Tommy Yu
abc5631654 test: regression from #3502
- Also as reported in #3719, which has an actual minimum example.
- The "quicker" test had a reset but that runs into timing issue with
  the way this reset is done too soon after resource usage, so leaving
  this out and we will just trust the bigger counters.
2025-03-16 22:43:21 +13:00
Tommy Yu
40e5288ac1 fix instrumented use_context
- It shouldn't be in on_cleanup, move into it from the component to
  avoid BorrowMut error.
2025-03-16 22:43:21 +13:00
Greg Johnston
335934d40e Merge pull request #3716 from zakstucke/string-opt
view!{} macro optimisation: don't wrap string types in closures when passing to ToChildren
2025-03-15 10:56:40 -04:00
Greg Johnston
6ee72f42e2 Merge pull request #3687 from leptos-rs/3671
Various issues related to setting signals and context in cleanups
2025-03-15 10:34:53 -04:00
Thomas Versteeg
93af23a970 feat: allow closures for shell parameter in file_and_error_handler* (#3711) 2025-03-15 10:24:09 -04:00
Danik Vitek
95e8ae84af feat(reactive_stores): Replace AsRef bound of StoreFieldIterator blanket impl with Len bound (#3701) 2025-03-15 10:23:09 -04:00
Danik Vitek
5cfe7f6b5e fix: make tuple struct field locator in Patch impl Index instead of usize (#3700) 2025-03-15 10:19:41 -04:00
Greg Johnston
0404efd5c3 fix: ensure that store subfield mutations notify from the root down (closes #3704) (#3714) 2025-03-15 10:04:52 -04:00
Zak Stucke
93173c1400 view!} macro optimisation: don't wrap string types in closures when passing to ToChildren 2025-03-15 03:17:20 +00:00
Tommy Yu
cd2904f6a6 chore: prep common base to share example with 0.8 2025-03-15 14:35:55 +13:00
Greg Johnston
6b453845f9 fix: allow NodeRef to work with AttributeInterceptor (closes #3697) 2025-03-13 21:38:28 -04:00
zakstucke
111b84ce3b feat: allow LocalResource sync methods to be used outside Suspense (#3708) 2025-03-13 21:36:51 -04:00
zakstucke
5633148047 feat: allow LocalResource sync methods to be used outside Suspense (#3708) 2025-03-13 09:28:00 -04:00
autofix-ci[bot]
4edb012de3 [autofix.ci] apply automated fixes 2025-03-13 01:16:55 +00:00
Greg Johnston
b2bea2e6b7 fix: support for websockets under default features 2025-03-12 21:06:52 -04:00
Greg Johnston
acbd6378a8 chore: bump version for 0.8 2025-03-12 20:29:46 -04:00
Greg Johnston
b7462aab10 fix: broken type inference for Action::new_unsync (closes #3328) (#3705) 2025-03-12 19:12:46 -04:00
Greg Johnston
7593540774 Merge remote-tracking branch 'origin' into leptos_0.8 2025-03-12 16:16:10 -04:00
Greg Johnston
ed915f8e06 Merge pull request #3656 from ealmloff/websockets
Add websocket support for server functions
2025-03-12 16:13:41 -04:00
Greg Johnston
f65d87d566 chore: allow dead code in example 2025-03-10 21:07:41 -04:00
Greg Johnston
5034539411 chore: update server_fns_axum example 2025-03-10 21:06:36 -04:00
Greg Johnston
bc48aa4228 chore: reexport Bytes to make it easier to implement Client 2025-03-10 21:06:26 -04:00
Greg Johnston
d2c81fe955 change: enable url and json by default on server_fn 2025-03-10 16:02:50 -04:00
Greg Johnston
28eb96831a chore: fix up doctests on server_fn crate 2025-03-10 15:57:59 -04:00
Greg Johnston
330920eae2 chore: clippy 2025-03-10 10:14:46 -04:00
Greg Johnston
a94bc0a6da fix: only store a weak reference to an Owner in the current thread (see #3671) 2025-03-10 10:14:46 -04:00
Greg Johnston
f85e01f4d6 fix: do not panic unnecessarily in try_ methods on Arena (closes #3671) 2025-03-10 10:14:46 -04:00
autofix-ci[bot]
599c87c88a [autofix.ci] apply automated fixes 2025-03-10 14:03:07 +00:00
Evan Almloff
3ca98279e1 forward server fn visibility 2025-03-10 08:52:32 -05:00
mahdi739
a730bffe13 fix: Ensure reactive functions passed to TextProp are kept reactive (closes: #3689) (#3690) 2025-03-09 19:40:28 -04:00
Greg Johnston
d0bf843821 Merge pull request #3692 from QuartzLibrary/immediate-effect
`ImmediateEffect` follow up
2025-03-09 13:50:26 -04:00
QuartzLibrary
7250bc312e docs: clarify need for ThreadId 2025-03-09 11:49:23 +00:00
QuartzLibrary
0e8242f94c feat: simplify ImmediateEffect 2025-03-08 18:40:52 +00:00
QuartzLibrary
439b41f0e8 test: parallel ImmediateEffect r/w access 2025-03-08 18:35:16 +00:00
Evan Almloff
18570e970c Fix clippy 2025-03-07 17:19:24 -06:00
autofix-ci[bot]
787bf385d3 [autofix.ci] apply automated fixes 2025-03-07 23:18:19 +00:00
Evan Almloff
b6d2808671 Document the protocol trait and implementations 2025-03-07 17:12:49 -06:00
Evan Almloff
2e4d94b6c6 Add encoding suffix to the encoding types and revert renaming the post encodings 2025-03-07 17:12:49 -06:00
autofix-ci[bot]
66f9c8c999 [autofix.ci] apply automated fixes 2025-03-07 21:26:39 +00:00
Greg Johnston
352080d91a fix: don't use ws feature of Axum on JS-fetch/no-default platform 2025-03-07 16:19:11 -05:00
Greg Johnston
1e579614a5 chore: remove unused import 2025-03-07 15:55:28 -05:00
Greg Johnston
a4e47d4086 Merge pull request #3650 from QuartzLibrary/immediate-effect
`ImmediateEffect`
2025-03-07 15:18:50 -05:00
Greg Johnston
3164721fdb fix: untrack in NodeRef::on_load() to avoid re-triggering it if you read something reactively (closes #3684) (#3686) 2025-03-07 12:07:46 -05:00
Evan Almloff
fee4bccb32 Create post type aliases for encodings 2025-03-07 08:40:08 -06:00
mahdi739
4ba9f67440 feat: implement IntoClass for store fields (#3670)
* Implement `IntoClass` for store fields

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* [autofix.ci] apply automated fixes (attempt 3/3)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-03-07 08:22:59 -05:00
Saber Haj Rabiee
2242ad1847 fix: semver and feature handy script for update nightly (#3674) 2025-03-07 08:21:21 -05:00
Greg Johnston
131b18bddb Merge pull request #3677 from sabify/fix-enum-stack
fix: enum stack size
2025-03-07 08:20:20 -05:00
Greg Johnston
5e9d6e2dfd fix: point bind:group to correct location (closes #3678) (#3680) 2025-03-07 08:04:53 -05:00
Saber Haj Rabiee
d76e5bb4ea fix: moved value 2025-03-05 21:21:29 -08:00
Saber Haj Rabiee
f752e32ae3 fix: clippy on large enum variant (https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant) 2025-03-05 21:10:30 -08:00
Saber Haj Rabiee
a9197102a6 fix: clippy warning on match usage 2025-03-05 21:08:10 -08:00
Saber Haj Rabiee
58f1bf95e1 fix: clippy clone_on_copy (https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy) 2025-03-05 21:07:37 -08:00
autofix-ci[bot]
d84ab6d9bf [autofix.ci] apply automated fixes (attempt 2/3) 2025-03-05 16:23:48 +00:00
autofix-ci[bot]
f069d4478e [autofix.ci] apply automated fixes 2025-03-05 15:20:59 +00:00
Evan Almloff
65b5d55d62 deny missing docs 2025-03-05 09:01:22 -06:00
Evan Almloff
860ad7a221 return an error when the sever doesn't support spawning tasks 2025-03-05 09:00:26 -06:00
Evan Almloff
901e038aa0 update form integration 2025-03-05 08:53:54 -06:00
Evan Almloff
f49f0965bc remove default actix feature 2025-03-05 08:51:31 -06:00
Evan Almloff
bb62d08d3f implement actix integration 2025-03-05 08:47:06 -06:00
Greg Johnston
bfe04593fd Merge pull request #3658 from mahdi739/impl-several-into-traits-for-store-fields-0.8
Implement several into traits for store fields (0.8)
2025-03-04 08:54:02 -05:00
Greg Johnston
38a3aae28e Merge branch 'main' into immediate-effect 2025-03-03 21:02:43 -05:00
martin frances
5eaaff045f chore(clippy): replace mem::replace with Option::replace (#3668) 2025-03-03 18:01:19 -05:00
autofix-ci[bot]
5b484eaec4 [autofix.ci] apply automated fixes (attempt 3/3) 2025-03-03 22:02:22 +00:00
autofix-ci[bot]
e9384e3286 [autofix.ci] apply automated fixes 2025-03-03 21:42:06 +00:00
autofix-ci[bot]
5149ad54db [autofix.ci] apply automated fixes (attempt 2/3) 2025-03-03 21:36:44 +00:00
autofix-ci[bot]
4d9ec54ad1 [autofix.ci] apply automated fixes 2025-03-03 21:22:46 +00:00
Evan Almloff
a1cd7ae9a1 implement reqwest websocket integration 2025-03-03 14:58:37 -06:00
autofix-ci[bot]
083f9c663f [autofix.ci] apply automated fixes 2025-03-03 14:02:22 +00:00
Greg Johnston
63c9549120 fix: ensure cleanups run for all replaced nested routes (closes #3665) (#3666) 2025-03-03 08:19:05 -05:00
Greg Johnston
6232f6482a fix: param segments should not match an empty string that contains only / separator (closes #3527) (#3662) 2025-03-01 12:05:17 -05:00
Greg Johnston
825e89f25c fix: do not double-insert hash character in URLs (closes #3647) (#3661) 2025-03-01 12:05:05 -05:00
Greg Johnston
3dbb251853 fix: tweak bounds on For for backwards-compat (#3663) 2025-03-01 11:50:09 -05:00
zakstucke
98e00fcb3b Erased mode in CI (#3640)
* Erased mode in CI

* Trigger CI

* Rename dev_mode erased_mode plus add to more matrices

* nested routes in separate component fix

* Fix lint

* Small fixes

* Fixes

* proc-macro rustflags cross-compilation workaround with internal erasure feature for leptos_macro

* Re-trigger CI

* fix unrelated doc CI and remove unneeded IntoAttribute trait

* Fix StaticVec rebuild() fn

* Conflict fixes

* Maybe fix

* Bump example toolchain
2025-03-01 07:43:13 -08:00
martin frances
5da4c438d9 chore: examples/server_fns_axum - Bumped various packages (not axum). (#3655)
tower-http
tower
thiserror
strum
notify

axum has breaking changes and so will addressed in a separate PR.
2025-02-28 14:30:03 -05:00
mahdi739
80ed74c075 chore: implement Debug for ArcField and Field (#3660) 2025-02-28 14:29:35 -05:00
Greg Johnston
cdee2a9476 feat: "islands router" for client-side navigations when in islands mode (#3502) 2025-02-28 14:01:33 -05:00
autofix-ci[bot]
c97ab9a72c [autofix.ci] apply automated fixes 2025-02-28 15:27:34 +00:00
Evan Almloff
4fc8972f2b make the into websocket function async 2025-02-28 09:26:37 -06:00
QuartzLibrary
79e9340a9b refactor: improve naming and docs after changes 2025-02-27 23:26:36 +00:00
QuartzLibrary
41d01cedb2 fix: parallel execution in ImmediateEffect 2025-02-27 23:10:08 +00:00
Evan Almloff
b800c009c7 Integrate the websocket protocol with the server function macro 2025-02-27 16:31:06 -06:00
QuartzLibrary
374a020d84 feat: do not store user state in ImmediateEffect 2025-02-27 22:17:06 +00:00
QuartzLibrary
83fcf8663c feat: make ImmediateEffect more robust
The goal here is to make the behavior under recursion better defined.
2025-02-27 22:12:55 +00:00
Greg Johnston
e7a73595de chore: remove unnecessary Debug bound 2025-02-27 17:00:00 -05:00
autofix-ci[bot]
a9a988e0e1 [autofix.ci] apply automated fixes 2025-02-27 14:46:56 +00:00
Mahdi
db10d961df Implement Render, RenderHtml, AttributeValue for store fields 2025-02-27 17:44:07 +03:30
Mahdi
fb608158cb Implement IntoSplitSignal for AtKeyed, AtIndex and DerefedField 2025-02-27 17:16:51 +03:30
Mahdi
1a472ebad1 Implement InnerHtmlValue for store fields 2025-02-27 17:09:34 +03:30
Mahdi
2d1b66a5c6 Implement IntoProperty for store fields 2025-02-27 17:00:33 +03:30
Mahdi
c524b0aefc rename style_store_field macro to style_reactive 2025-02-27 16:55:37 +03:30
Mahdi
e4c977911c Implement IntoStyle and IntoStyleValue for store fields 2025-02-27 16:41:53 +03:30
autofix-ci[bot]
f488d4b5b7 [autofix.ci] apply automated fixes 2025-02-26 19:58:25 +00:00
Evan Almloff
d4cfd0e2cb Move content type to a separate trait 2025-02-26 13:56:59 -06:00
autofix-ci[bot]
a4b0d3408c [autofix.ci] apply automated fixes 2025-02-26 15:44:01 +00:00
Evan Almloff
2037bf12cb Merge branch 'leptos_0.8' into websockets 2025-02-26 09:40:58 -06:00
Evan Almloff
2747a496fc fix formatting 2025-02-26 09:40:22 -06:00
Evan Almloff
c286812116 move the server request and response into a separate trait 2025-02-26 09:36:02 -06:00
Greg Johnston
1e0a9ef189 fix: avoid hydration issues with HashedStylesheet (closes #3633) (#3654) 2025-02-26 09:18:23 -05:00
TERRORW0LF
1363b941bc feat: .map() and .and_then() for OnceResource and LocalResource (#3652) 2025-02-26 09:16:50 -05:00
Evan Almloff
7479010f84 unified http protocol for non-websocket sever functions 2025-02-25 16:20:33 -06:00
QuartzLibrary
f7a1a2cab2 feat: introduce ImmediateEffect 2025-02-25 21:45:28 +00:00
QuartzLibrary
92b82688a6 fix: relax bounds on OrPoisoned blanket impls 2025-02-25 20:59:47 +00:00
Evan Almloff
9b9983af79 expose encoding types 2025-02-25 08:36:04 -06:00
Greg Johnston
04e79a0dc4 chore: clean up fetch example a bit 2025-02-25 08:06:47 -05:00
Greg Johnston
f64951126e chore: merge issues 2025-02-25 07:42:39 -05:00
Greg Johnston
0a29071779 Merge remote-tracking branch 'origin' into leptos_0.8 2025-02-25 07:39:43 -05:00
Greg Johnston
efcb6f6d21 feat: support IntoSplitSignal for (Signal<T>, SignalSetter<T>) (closes #3634) (#3643) 2025-02-25 07:32:37 -05:00
Greg Johnston
42988b1bc1 chore: fix Axum test setup (#3651) 2025-02-25 07:22:12 -05:00
Evan Almloff
6904eec207 remove into/from request/response bounds on server fn 2025-02-24 13:05:37 -06:00
Evan Almloff
7eb8ca702d switch most encodings into the new system 2025-02-24 12:00:02 -06:00
QuartzLibrary
c75397ea75 chore: small refactor 2025-02-23 17:27:40 +00:00
Greg Johnston
848fd724dd Merge pull request #3644 from leptos-rs/nightly-ci-update 2025-02-22 15:19:44 -05:00
Greg Johnston
5bc254d49f chore: better way of not running whole doc tests 2025-02-22 14:29:25 -05:00
Greg Johnston
885f4a1654 chore: ignore type complexity lint 2025-02-22 08:39:00 -05:00
Greg Johnston
ddd243d07a chore: better way of not running whole doc tests 2025-02-22 08:38:39 -05:00
Greg Johnston
362c300eac chore: clippy doc comment indentation 2025-02-22 08:28:26 -05:00
Greg Johnston
284a724e5f chore(ci): update pinned nightly version 2025-02-22 07:35:09 -05:00
Evan Almloff
1a7b40b507 implement gloo websockets 2025-02-21 15:48:41 -06:00
Evan Almloff
73dd677843 switch to async fn for get implementation 2025-02-20 17:02:19 -06:00
Evan Almloff
131f414fdc move run client into the protocol trait 2025-02-20 17:01:51 -06:00
Evan Almloff
c3ed874d4d Create websocket protocol trait 2025-02-19 14:49:57 -06:00
benwis
f003e50446 Update throw_error to v0.3 2025-02-19 08:08:21 -08:00
Greg Johnston
ea29685c92 change: remove unused Result alias (#3543) 2025-02-19 07:22:20 -08:00
Greg Johnston
6ecc681cdd fix: allow decoding already-decoded URI components (closes #3606) (#3628)
* fix: allow decoding already-decoded URI components (closes #3606)

* clippy
2025-02-19 06:04:18 -08:00
zakstucke
49e44a2ec2 Erased routing, codegen opts (#3623) 2025-02-18 12:39:30 -08:00
Greg Johnston
7c34b4a4a5 fix: only render meta tags when rendered, not when created (closes #3629) (#3630) 2025-02-18 09:06:51 -05:00
Greg Johnston
7157958822 feat: support Option<_> in style: (closes #3568) (#3618) 2025-02-15 16:47:21 -05:00
martin frances
37cf25fba5 serde_json is common to (#3610)
integrations/actix
leptos/server
oco
server_fn

This is a defensive PR - Putting the crate definition into the root
workspcace makes it less likely to get difficult to trace version
slip bugs.

This does not help where sede_json is optional so care manual review
is required.
2025-02-15 10:24:07 -08:00
Greg Johnston
f975b8d33b fix: hydration of () (#3615) 2025-02-15 13:23:09 -05:00
zakstucke
d37450d12f Internally erase html elements (#3614) 2025-02-15 09:58:43 -08:00
Greg Johnston
4804dac32d chore: update either_of minimum version in workspace (#3612) 2025-02-15 08:19:05 -05:00
martin frances
a9f27d6128 chore: update syntax in README example (#3611) 2025-02-15 08:18:48 -05:00
Greg Johnston
04cb036a7d fix: reorder pause check in new_isomorphic (#3613) 2025-02-15 08:18:23 -05:00
jasper
1d3784ed7b feat: impl Into<Signal> for store subfields (#3579) 2025-02-14 17:14:49 -05:00
Greg Johnston
8cc1a34c00 feat: allow pausing and resuming effects (#3599) 2025-02-14 14:48:27 -05:00
mahdi739
68f4d46c5f feat: add invert to OptionStoreExt (#3534) 2025-02-14 13:52:38 -05:00
martin frances
590728e47e projects/bevy3d_ui: Bevy - Bugfix, clippy and crate bump (#3603)
The bugfix is related to access to a signal

"
bevy3d_ui-b20a0a6a298e7144.js:2637 At src/routes/demo1.rs:24:23, you access a
reactive_graph::signal::read::ReadSignal<bevy3d_ui::demos::bevydemo1::scene::Scene>
(defined at src/routes/demo1.rs:19:39) outside a reactive tracking context.
This might mean your app is not responding to changes in signal values in the way you expect.
"

The solution is to use .get_untracked() inside an "effect" block.

Lots of small clippy fixes.

Also here are the crates that have been bumped

-wasm-bindgen = "0.2.92"
-wasm-bindgen-test = "0.3.42"
-web-sys = "0.3.69"
+wasm-bindgen = "0.2.100"
+wasm-bindgen-test = "0.3.50"
+web-sys = "0.3.77"
2025-02-13 15:37:23 -08:00
martin frances
e84b527743 Minor: Bump tokio to 1.43. (#3600) 2025-02-12 23:14:00 -08:00
martin frances
96b125d54f Remove getrandom (#3589)
* Resolved this warning see while running cargo outdated

warning: Feature js of package getrandom has been obsolete in version 0.3.1

Now using the feature "wasm_js"

* the crate "getrandom" needs special configuration.

* getrandom_backend - a more generic config.

* Removed the crate getrandom
2025-02-12 23:13:27 -08:00
martin frances
16d66362f8 Minor: "wasm-bindgen" - Moved the crate definition up to the root workspace (#3588)
* Minor: "wasm-bindgen" - Moved the crate definition up to the root workspace

This synchronizes the version number amongst all sub-projects.
[Where the definition is "optional" manual adjustment is still required]

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-12 12:25:22 -08:00
martin frances
e27801a2c2 Minor: Bumped version of convert_case to 0.7 (#3590) 2025-02-12 12:17:36 -08:00
martin frances
b81f71997b Minor: Bump itertools to "0.14.0" (#3593)
The crate is used by "leptos_macro","reactive_stores" and "tachys"

So the definition of itertools can be centralized up into the root workspace
2025-02-12 12:16:47 -08:00
martin frances
2a11325749 Minor: leptos_config - Bump the "config" crate to version 0.15.8 (#3594) 2025-02-12 12:15:57 -08:00
martin frances
5604f3e979 projects/bevy3d_ui: Bevy migration (#3597)
-bevy = "0.14.1"
+bevy = "0.15.2"

<https://bevyengine.org/learn/migration-guides/0-14-to-0-15/>
2025-02-12 12:14:33 -08:00
martin frances
3a9a0891a3 projects/bevy3d_ui Migrate to leptos 0.7.7 (#3596)
* projects/bevy3d_ui Migrate to leptos 0.7.7

* Minor: projects/bevy3d_ui - Better Meta.
2025-02-12 12:13:32 -08:00
Greg Johnston
a39add50c0 fix: occasional use-after-disposed panic in Suspense (#3595) 2025-02-12 14:59:44 -05:00
Greg Johnston
2a2675dd36 fix: remove extra placeholder in Vec of text nodes (closes #3583) (#3592) 2025-02-12 10:45:56 -05:00
Greg Johnston
7be6a9da86 v0.7.7 2025-02-11 20:29:31 -05:00
Greg Johnston
c51e07b5a4 v0.7.6 (#3586) 2025-02-11 20:23:57 -05:00
jasper
b17a4c92c7 fix: allow non static lifetimes in component macro (#3571) 2025-02-10 20:51:15 -05:00
Alexis Fontaine
03f9c6cb6d fix: add <fieldset> attributes (#3581) 2025-02-10 15:19:00 -08:00
zakstucke
6ad300c592 Binary size wins (#3566)
* Random binary size opts

* [autofix.ci] apply automated fixes

* Stop autofixer removing an import

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-10 15:18:26 -08:00
zakstucke
b4e683d969 RenderHtml::into_owned (#3580) 2025-02-10 12:53:33 -08:00
Greg Johnston
c2289b23a7 fix: Actix stream error handling with 0.8 error types (#3574) 2025-02-10 08:32:44 -05:00
Greg Johnston
9e8b8886da feat: add :capture flag for events to handle them during capture phase (closes #3457) (#3575) 2025-02-10 08:26:00 -05:00
Greg Johnston
299acd25f3 implement AddAnyAttr for AnyView (#3562) 2025-02-09 20:46:41 -05:00
Danik Vitek
6a6b3dee15 fix(reactive_stores_macro): store attribute signature error message (#3567) 2025-02-09 14:09:43 -05:00
Alexis Fontaine
5d71913523 Handle erase_components on Either<A, B> (#3572) 2025-02-09 10:50:20 -08:00
mahdi739
706617ab0a fix: panic at fewer places in stores (#3551) 2025-02-07 14:45:12 -05:00
mahdi739
cd64bb9d67 fix: return empty set of keys instead of panicking when the KeyedSubfield is disposed (#3550) 2025-02-07 14:43:33 -05:00
Greg Johnston
f881c1877d fix: do not hold lock on arena when dispatching Action (#3561) 2025-02-07 14:26:58 -05:00
Greg Johnston
8783f6a478 fix: don't use InertElement for style: etc. (closes #3554) (#3558) 2025-02-06 21:26:15 -05:00
Greg Johnston
2add714c65 chore(ci): cargo install --locked for cargo-leptos installation (#3559) 2025-02-06 21:22:37 -05:00
Alexis Fontaine
88b1b2d882 feat: implement Attribute for Either<A, B> (#3556) 2025-02-06 21:21:53 -05:00
zakstucke
9d3a743d33 Fix ci (#3557) 2025-02-06 16:17:31 -08:00
zakstucke
287fc47163 "Update axum paths to 0.8 syntax" (#3555)
* Update axum paths to 0.8 syntax

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-06 16:17:12 -08:00
zakstucke
8f74a6d8a0 AddAnyAttr static (#3553) 2025-02-06 14:00:25 -08:00
Greg Johnston
c6de7c714e fix: emit syntax errors in components rather than swallowing them (closes #3535) (#3538) 2025-02-01 15:29:40 -05:00
starmaker
597175a54b Fixing closing brace (#3539)
Most likely confglict merge artefact
2025-02-01 09:40:03 -08:00
Greg Johnston
6154199850 fix: attribute type erasure nightly (closes #3536) (#3537) 2025-02-01 11:32:32 -05:00
Chris
ede25b9e3d fix: remove Default impl for LeptosOptions and ConfFile (#3522)
* fix: remove `Default` impl for `LeptosOptions` and `ConfFile`

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-01 09:41:44 -05:00
Ivan Radiček
32be3a023a feat: implement PatchField for Option<_> (#3528) 2025-02-01 09:40:43 -05:00
Greg Johnston
d9043e4f34 feat: impl From<ArcField<T>> for Field<T> (#3533)
* feat: impl `From<ArcField<T>>` for `Field<T>`

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-01 09:37:38 -05:00
Greg Johnston
8f636e354a change: allow IntoFuture for Suspend::new() (closes #3509) (#3532) 2025-01-31 14:25:35 -05:00
Serhii Stepanchuk
e3010c7f1f feat: add file_and_error_handler_with_context (#3526)
* add file_and_error_handler_with_context
like in leptos_routes_with_context func

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-31 12:33:55 -05:00
Greg Johnston
1dcc5838f7 v0.7.5 2025-01-30 21:42:39 -05:00
Greg Johnston
7da64f22c4 Merge branch 'main' into leptos_0.8 2025-01-30 21:32:58 -05:00
Greg Johnston
0073ae7d8a chore: update version numbers preparing for 0.8.0-alpha 2025-01-30 21:29:54 -05:00
Georg Vienna
1ff373dbc2 feat: allow raw identifiers in Params derive macro (#3525) 2025-01-29 19:39:23 -05:00
Greg Johnston
c35c42c6e3 fix: correctly notify descendants and ancestors of store fields (closes #3523) (#3524) 2025-01-29 19:28:26 -05:00
Geoffrey Garrett
d4cbba7c63 feat(callback): implement matches method for Callback and UnsyncCallback (#3520)
* feat(callback): implement matches method for Callback and UnsyncCallback

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-27 20:37:11 -05:00
stefnotch
9cc8ee3c5a fix: memo recomputation (closes #3252) (#3495) 2025-01-27 20:19:16 -05:00
SleeplessOne1917
f0c5ffe55f impl IntoAttributeValue for TextProp (#3517)
* impl IntoAttributeValue for TextProp

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-26 14:16:58 -05:00
benwis
8465716a19 Fix formatting 2025-01-26 09:51:22 -08:00
zakstucke
0e24b2e63f AddAnyAttr working with erase_components (#3518)
* AddAnyAttr working with erase_components

* CI fixes
2025-01-26 09:51:22 -08:00
Danik Vitek
c64d205984 feat (either_of): Extent API; Implement other iterator methods; Update deps (#3478)
* Implement other iterator methods. Update deps

* Formatting

* Update Cargo.lock

* [autofix.ci] apply automated fixes

* Formatting

* Move `Either` declaration into the `tuples` macro

* Comment out non-MSRV-compliant methods

* [autofix.ci] apply automated fixes

* Formatting

* Implement mapping functions

* Fix clippy warnings

* Impl `Error`; Impl `From<Result<A, B>> for Either<B, A>`

* Fix `Error` impl

* Move `Error` impl under `#[cfg(not(feature="no_std"))] until MSRV >= 1.81

* [autofix.ci] apply automated fixes

* Make `From<Result>` compliant with `EitherOr`. Add `impl EitherOr for Either`

* fix: use fully-qualified name

* fix: `EitherOf` test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-26 09:51:22 -08:00
Greg Johnston
f17cb98eb0 chore: update workspace dependency versions to latest (#3506) 2025-01-26 09:51:22 -08:00
Danik Vitek
30f3e82664 docs: Fix README.md & Add MSRV badge (#3480)
* Fix README.md

* Add MSRV badge

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-26 09:51:22 -08:00
starmaker
152d5a5c92 issue-3467 - bumping codee version to support rkyv 8 (#3504)
* issue-3467 - bumping codee version to support rkyv 8

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-26 09:51:22 -08:00
Sam Jude
669e1ba7fa hexagonal architecture (#3342)
Co-authored-by: Sam <@>
2025-01-26 09:51:22 -08:00
dcsturman
2ad6a086f9 Enhanced docs for reactive_stores (#3508)
Added docs on shadow traits, Option, Enum, Vec, and Box usage with Store.
2025-01-26 09:51:22 -08:00
Greg Johnston
32e58d6b66 fix: including node_ref after {..} on arbitrary components (#3503) 2025-01-26 09:51:22 -08:00
Greg Johnston
a107443104 chore(ci): add CI for leptos_0.8 branch (#3500) 2025-01-26 09:51:22 -08:00
Greg Johnston
c859b07901 feat: #[lazy] macros to support lazy loading and code splitting (#3477) 2025-01-26 09:51:22 -08:00
Greg Johnston
a9868bea2b chore: restore reactivity warning at top level of components (closes #3354) (#3499) 2025-01-26 09:51:22 -08:00
Greg Johnston
7183c2b993 fix: correctly handle ErrorBoundary through reactive views (closes #3487) (#3492) 2025-01-26 09:51:22 -08:00
Greg Johnston
7a03621db1 feat: implement unboxing support for recursive store nodes (closes #3491) (#3493) 2025-01-26 09:51:22 -08:00
benwis
586c330995 Fix formatting 2025-01-26 09:46:19 -08:00
zakstucke
72f960a026 AddAnyAttr working with erase_components (#3518)
* AddAnyAttr working with erase_components

* CI fixes
2025-01-26 09:43:32 -08:00
Danik Vitek
b62ae56094 feat (either_of): Extent API; Implement other iterator methods; Update deps (#3478)
* Implement other iterator methods. Update deps

* Formatting

* Update Cargo.lock

* [autofix.ci] apply automated fixes

* Formatting

* Move `Either` declaration into the `tuples` macro

* Comment out non-MSRV-compliant methods

* [autofix.ci] apply automated fixes

* Formatting

* Implement mapping functions

* Fix clippy warnings

* Impl `Error`; Impl `From<Result<A, B>> for Either<B, A>`

* Fix `Error` impl

* Move `Error` impl under `#[cfg(not(feature="no_std"))] until MSRV >= 1.81

* [autofix.ci] apply automated fixes

* Make `From<Result>` compliant with `EitherOr`. Add `impl EitherOr for Either`

* fix: use fully-qualified name

* fix: `EitherOf` test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-24 21:15:29 -08:00
Greg Johnston
9ccefbbd8c chore: update workspace dependency versions to latest (#3506) 2025-01-24 21:07:20 -08:00
Danik Vitek
d1108826cc docs: Fix README.md & Add MSRV badge (#3480)
* Fix README.md

* Add MSRV badge

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-24 21:06:19 -08:00
starmaker
d6c4cd2a81 issue-3467 - bumping codee version to support rkyv 8 (#3504)
* issue-3467 - bumping codee version to support rkyv 8

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-24 20:29:55 -08:00
Sam Jude
f8acdf9168 hexagonal architecture (#3342)
Co-authored-by: Sam <@>
2025-01-24 20:29:07 -08:00
dcsturman
09bbae2a72 Enhanced docs for reactive_stores (#3508)
Added docs on shadow traits, Option, Enum, Vec, and Box usage with Store.
2025-01-24 20:23:13 -08:00
Spencer Ferris
2b589fa61f feat: Add more options for generating server fn routes (#3438)
* feat: Allow disabling server fn hash and customizing the default prefix

Allow configuring the default prefix for server function API routes. This is useful to
override the default prefix (`/api`) for all server functions without needing to manually
specify via `#[server(prefix = "...")]` on every server function.

Also, allow disabling appending the server functions' hashes to the end of their API names.
This is useful when an app's client side needs a stable server API. For example, shipping
the CSR WASM binary in a Tauri app. Tauri app releases are dependent on each platform's
distribution method (e.g., the Apple App Store or the Google Play Store), which typically
are much slower than the frequency at which a website can be updated. In addition, it's
common for users to not have the latest app version installed. In these cases, the CSR WASM
app would need to be able to continue calling the backend server function API, so the API
path needs to be consistent and not have a hash appended.

* Mark public structs as `#[non_exhaustive]` and add doc comments

* Minor refactor to pull the fn hash logic out of the `path` statement

* feat: Use module path in prefix for server fn API route

Allow including the module path of the server function in the API route. This
is an alternative strategy to prevent duplicate server function API routes
(the default strategy is to add a hash to the end of the route). Each element
of the module path will be separated by a `/`. For example, a server function
with a fully qualified name of `parent:🧒:server_fn` would have an API
route of `/api/parent/child/server_fn` (possibly with a different prefix and
a hash suffix depending on the values of the other server fn configs).

* Fix `enable_hash` if statement

* Add missing import
2025-01-24 20:11:38 -08:00
Greg Johnston
ac3352724b fix: including node_ref after {..} on arbitrary components (#3503) 2025-01-18 09:18:05 -05:00
Greg Johnston
3413825638 chore(ci): add CI for leptos_0.8 branch (#3500) 2025-01-17 16:04:36 -05:00
Greg Johnston
22b2d8ec84 feat: #[lazy] macros to support lazy loading and code splitting (#3477) 2025-01-17 15:15:12 -05:00
Greg Johnston
1c3e013a63 chore: restore reactivity warning at top level of components (closes #3354) (#3499) 2025-01-17 14:06:39 -05:00
Saber Haj Rabiee
35e6f17930 chore: upgrade axum to v0.8 (#3439) 2025-01-17 13:38:37 -05:00
Greg Johnston
d1513a4a0b feat(breaking): allow make PossibleRouteMatch dyn-safe (#3421) 2025-01-17 13:33:00 -05:00
Mario Carbajal
aa27b9e474 feat: impl Dispose for Callback types and add try_run to the Callable trait (#3371)
* impl Dispose for Callback types and add try_run to the Callable trait

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-17 13:32:04 -05:00
Ryo Hirayama
cfe925d58f feat: allow any type that implements FromServerFnError as a replacement of the ServerFnError in server_fn (#3274) 2025-01-17 13:30:12 -05:00
Greg Johnston
9d4b1bc4b7 fix: correctly handle ErrorBoundary through reactive views (closes #3487) (#3492) 2025-01-17 13:22:06 -05:00
Greg Johnston
f303ff9706 feat: implement unboxing support for recursive store nodes (closes #3491) (#3493) 2025-01-17 13:21:40 -05:00
Georg Vienna
9fd2a75da4 feat: either_or combinator (#3417) 2025-01-17 13:12:18 -05:00
Michael Scofield
429d1b1262 feat: support for custom patch function on stores (#3449) 2025-01-17 13:10:44 -05:00
Greg Johnston
035586e5d8 chore: work around wasm-bindgen breakage (#3498) 2025-01-17 12:16:05 -05:00
Greg Johnston
fdd5671fe1 v0.7.4 2025-01-15 19:38:44 -05:00
Greg Johnston
293149eeb2 fix: include missing nonces on streaming script tags and on leptos_meta components (closes #3482) (#3485) 2025-01-13 22:06:14 -05:00
Greg Johnston
a9ce608433 fix: do not use stale values in AsyncDerived if it is mutated before running (#3475) 2025-01-13 21:32:08 -05:00
Thomas Versteeg
62196ff638 docs: warn about callbacks outside the ownership tree (#3442) 2025-01-10 15:23:08 -05:00
WorldSEnder
db9cabb365 chore: use cfg! macro instead of #[cfg] attribute (#3446)
this unifies the code path. The alternative will *move* arguments passed
to the debug_warn! macro only when compiling without debug_assertions.
This version will instead always use additional format arguments by reference.
2025-01-10 15:22:41 -05:00
Greg Johnston
5293afddb7 chore: fix tracing warning mess (#3473) 2025-01-10 14:27:03 -05:00
林玮 (Jade Lin)
eeb01e2d52 feat: add [Arc]LocalResource::refetch method (#3394) 2025-01-10 13:57:37 -05:00
Geoffrey Garrett
7d9cd43c0e feat: impl AddAnyAttr trait for Static<V> (#3464)
* Implement AddAnyAttr trait for Static<V>

Closes #3463

* [autofix.ci] apply automated fixes

---------

Co-authored-by: geoffreygarrett <geoffrey@apollo.xyz>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-10 12:54:01 -05:00
Greg Johnston
723685c370 fix: do not overwrite SuspenseContext in adjacent Transition components (closes #3465) (#3471) 2025-01-10 12:52:28 -05:00
Michael Kadziela
6d19e1a921 chore: derive Clone for RouteChildren (#3462)
This change allows users to clone RouteChildren and call .into_inner() on it to get an owned version of <Children>, and then pass on the original RouteChildren to an underlying Routes, or ParentRoute component.
This helps users snapshot all possible routes in an application.
2025-01-10 12:03:52 -05:00
Greg Johnston
165911b2e6 fix: allow multiple overlapping notifications of AsyncDerived/LocalResource (closes #3454) (#3455) 2025-01-06 22:53:15 -05:00
starmaker
575186349c Rkyv feature should propagate properly (#3448)
I suppose enabling `rkyv` feature on `leptos` crate should enable it on all dependencies.
2025-01-06 12:09:26 -08:00
Greg Johnston
10db2f83eb v0.7.3 2025-01-04 08:55:44 -05:00
Greg Johnston
357f3be393 fix: erase_components with AttributeInterceptor (#3435) 2025-01-04 08:46:17 -05:00
Soso
a1f5d6f79f feat: impl IntoClass for Cow<'_, str> (#3420)
I also thought about making the implementation more generic, for example over
T: AsRef<str>, but that would change the associated types and be a breaking change
it would also conflict with the `Option` impl due to the orphan rules.

Maybe there is something to be done with Borrow or Deref in a future release?
2025-01-03 15:42:42 -05:00
Michael Scofield
34ecd2d541 feat: add Dispose for Store (#3429) 2025-01-03 15:37:59 -05:00
Michael Scofield
df38b075d8 feat: add Default to stores (#3432) 2025-01-03 15:37:41 -05:00
Konstantin Stepanov
46233e3097 fix: avoid failure on guard try_new() functions (#3436) 2025-01-03 15:37:06 -05:00
Greg Johnston
46f6d9ae26 fix: correct ownership in redirect route hook (closes #3425) (#3428) 2024-12-31 11:48:52 -05:00
Chris
8264d478e4 docs: remove islands mention from leptos_axum (#3423) 2024-12-31 10:35:20 -05:00
Greg Johnston
9c54da304e Merge pull request #3424 from leptos-rs/3419
Fix issues with island hydration when nested in a closure, and with context (closes #3419)
2024-12-31 10:35:02 -05:00
Michael Scofield
1c002a2df8 chore: add missing #[track_caller]s (#3422) 2024-12-31 10:34:47 -05:00
Greg Johnston
6e4dac91bf perf: optimize and simplify island walk 2024-12-31 09:02:36 -05:00
Greg Johnston
6493b0b359 fix: a more substantial island context system that restores ownership properly 2024-12-30 19:13:55 -05:00
Greg Johnston
d58042b7ba fix: establish hydration status via ownership and context 2024-12-30 16:49:43 -05:00
Georg Vienna
7a5b27ad20 feat: allow prop destructuring via new #[prop(name = ...)] (#3382) 2024-12-27 16:57:34 -05:00
Spencer Ferris
78d0dbdfa2 fix: provide custom state in file_and_error_handler (#3408)
The `file_and_error_handler` provided by leptos_axum does not provide
the app's custom state in the context. This means that when the fallback
handler tries to render the app, the app will not be able to access the
custom state (and will panic if it uses `expect_context`).

The handle defined by `file_and_error_handler` has access to the custom
state from Axum, so we can pass the custom state from Axum into the
Leptos handler using the `additional_context` parameter of
`handle_response_inner`.
2024-12-27 13:44:39 -05:00
Greg Johnston
1c30a4c131 fix: getrandom needs js feature (used when nonce feature is active) (closes #3409) (#3410) 2024-12-26 07:29:53 -05:00
Greg Johnston
b91429d4f0 fix: correctly track updates to keyed fields in keyed iterator (closes #3401) (#3403) 2024-12-24 08:14:14 -05:00
Alexis Fontaine
6663fddf76 fix: enable console feature of web-sys (#3406) 2024-12-24 08:14:01 -05:00
Greg Johnston
28af33d511 v0.7.2 2024-12-21 14:09:01 -05:00
Greg Johnston
5a3413d3b3 fix: correct hydration position for static text nodes in nightly (closes #3395) (#3396) 2024-12-21 14:02:38 -05:00
Saber Haj Rabiee
702d2e247b fix(ci): add missing glib for semver checks (#3393) 2024-12-21 09:07:07 -05:00
Greg Johnston
71f698f322 fix: correct span for let: syntax (closes #3387) (#3391) 2024-12-20 15:35:48 -05:00
Michael Scofield
8d4776bf5f feat: add a From<ArcStore<T>> for Store<T, S> (#3389) 2024-12-20 13:02:48 -05:00
Oliver
65798e430f docs: showcase let syntax in for_loop (closes #3059) (#3383)
* docs: showcase let syntax in for_loop

* fix: doctests on for_loop

---------

Co-authored-by: Oliver Nordh <oliver.nordh@proton.me>
2024-12-20 13:00:46 -05:00
Greg Johnston
d46d1a4fab Merge pull request #3376 from sabify/fix-ci
fix(ci): missing glib in ci
2024-12-20 12:59:45 -05:00
Alyx Mote
f9533ab75b Update elements.rs (#3379)
fix: add missing `popovertarget` and `popovertargetaction` attributes for `<button>`
2024-12-17 19:26:04 -05:00
Saber Haj Rabiee
d08f8822c0 fix(ci): add missing glib for autofix ci 2024-12-16 23:35:05 -08:00
Saber Haj Rabiee
7357839efb fix(ci): missing glib in ci 2024-12-16 23:34:33 -08:00
Greg Johnston
1b8ad58114 chore: update lockfile 2024-12-16 20:57:56 -05:00
Greg Johnston
ef72f1ce96 v0.7.1 2024-12-16 20:52:00 -05:00
Gary Coady
6a5bfe9a5d feat: impl IntoSplitSignal for Field (closes #3362) (#3364) 2024-12-16 20:48:13 -05:00
stefnotch
1661fe2412 feat: add signal.into_inner() (#3343) 2024-12-16 20:47:25 -05:00
Greg Johnston
2324853155 chore: reenable cargo-semver-checks on PRs (#3375) 2024-12-16 19:48:52 -05:00
Greg Johnston
28a3859365 fix: rebuilding of InertElement (closes #3368) (#3370) 2024-12-16 19:23:15 -05:00
Greg Johnston
6b50179189 docs: clarify Signal::derive() behavior (#3351) 2024-12-16 09:22:30 -05:00
Paul Hansen
0bb825f6bd feat: AttributeInterceptor component to allow passing attributes to other elements (#3340) 2024-12-16 09:18:10 -05:00
Greg Johnston
a6aa111122 fix: only mark memos Check if they aren't already Dirty (closes #3339) (#3356) 2024-12-16 09:10:20 -05:00
Marcus Whybrow
753cfe8e44 chore: implement PatchField for usize (#3346) 2024-12-16 09:09:50 -05:00
zakstucke
bc9c3add87 feat: accessing context by reference (with_context and update_context) (#3279) 2024-12-16 09:09:22 -05:00
Michael Scofield
d0bb45dbc4 chore: update leptos_meta feature docs (#3350) 2024-12-16 08:33:24 -05:00
zakstucke
2a4b80cf22 feat: opt-in locations in release mode with --cfg locations (#3281) 2024-12-16 08:32:57 -05:00
redforks
881734b43a chore: impl Clone trait for TypedChildrenFn (#3349) 2024-12-16 08:32:17 -05:00
bicarlsen
68fdc8d9c4 docs: typo fix in ToChildren::to_children docs. (#3352) 2024-12-14 10:58:49 -05:00
sutantodadang
03ed805137 implemented actix multipart (#3361) 2024-12-14 10:58:29 -05:00
Greg Johnston
5d4603e988 fix: don't try to hydrate inside <noscript> (closes #3360) (#3363) 2024-12-14 10:57:51 -05:00
Greg Johnston
e65969cfcd fix: nested keyed fields in stores (closes #3338) (#3344) 2024-12-11 20:03:41 -05:00
Greg Johnston
e1e90b8595 Merge pull request #3341 from FreezyLemon/fix-some-doc-typos
Fix a doc typo and one broken intra-doc link
2024-12-10 16:27:30 -05:00
bicarlsen
71a136c7af feat: increase number of branch arms for either! macro (#3337) 2024-12-10 16:26:41 -05:00
Greg Johnston
49366be2a5 feat: add scroll prop to <A/> component to control scrolling behavior (closes #2666) (#3333) 2024-12-10 16:26:11 -05:00
FreezyLemon
6f5bdcc675 Fix rustdoc link to ArenaItem on Sandboxed::new 2024-12-09 23:01:27 +01:00
FreezyLemon
726a99441f Fix typo in Signal/ArcSignal 2024-12-09 22:49:07 +01:00
Greg Johnston
775bea46d9 fix: correctly mount/unmount hydrated static text nodes in nightly mode (closes #3334) (#3336) 2024-12-08 12:39:16 -05:00
Greg Johnston
2aa9827a1f fix: correctly support !Send Actix APIs in server functions (#3326)
* fix: correctly support `!Send` Actix APIs in server functions

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-12-07 15:41:32 -05:00
Greg Johnston
be3c1811fc fix: correctly swap Vec<_> in the DOM (closes #3321) (#3324)
* fix: correctly swap `Vec<_>` in the DOM (closes #3321)

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-12-05 21:08:05 -05:00
Greg Johnston
8df4f3c71d publish 0.1.1 to include either! macro 2024-12-04 18:53:18 -05:00
dependabot[bot]
3028a9acd0 chore(deps): bump rustls in the cargo group across 1 directory (#3289)
Bumps the cargo group with 1 update in the / directory: [rustls](https://github.com/rustls/rustls).


Updates `rustls` from 0.23.16 to 0.23.18
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.16...v/0.23.18)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: indirect
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 15:21:55 -08:00
dependabot[bot]
4b167fb809 chore(deps): bump hyper from 1.5.0 to 1.5.1 (#3265)
Bumps [hyper](https://github.com/hyperium/hyper) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 15:21:42 -08:00
dependabot[bot]
46ae8ef9b2 chore(deps): bump rkyv from 0.8.8 to 0.8.9 (#3290)
Bumps [rkyv](https://github.com/rkyv/rkyv) from 0.8.8 to 0.8.9.
- [Release notes](https://github.com/rkyv/rkyv/releases)
- [Commits](https://github.com/rkyv/rkyv/commits)

---
updated-dependencies:
- dependency-name: rkyv
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 15:21:26 -08:00
benwis
21f26e7a6b Remove dependa 2024-12-03 09:00:34 -08:00
dependabot[bot]
204648d388 chore(deps): bump wasm-bindgen from 0.2.95 to 0.2.97 (#3317)
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.95 to 0.2.97.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.95...0.2.97)

---
updated-dependencies:
- dependency-name: wasm-bindgen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ben Wishovich <benwis@users.noreply.github.com>
2024-12-03 08:54:32 -08:00
dependabot[bot]
a04bca55a2 chore(deps): bump tracing from 0.1.40 to 0.1.41 (#3294)
Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.40 to 0.1.41.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.40...tracing-0.1.41)

---
updated-dependencies:
- dependency-name: tracing
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ben Wishovich <benwis@users.noreply.github.com>
2024-12-03 08:50:46 -08:00
dependabot[bot]
1fec678174 chore(deps): bump url from 2.5.3 to 2.5.4 (#3291)
Bumps [url](https://github.com/servo/rust-url) from 2.5.3 to 2.5.4.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.5.3...v2.5.4)

---
updated-dependencies:
- dependency-name: url
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 08:49:04 -08:00
dependabot[bot]
4dbb8d1a42 chore(deps): bump bytes from 1.8.0 to 1.9.0 (#3297)
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.8.0...v1.9.0)

---
updated-dependencies:
- dependency-name: bytes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 08:48:33 -08:00
dependabot[bot]
fc2c52eb04 chore(deps): bump js-sys from 0.3.72 to 0.3.74 (#3306)
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.72 to 0.3.74.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

---
updated-dependencies:
- dependency-name: js-sys
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 08:48:03 -08:00
dependabot[bot]
1ae35ce5b3 chore(deps): bump wasm-bindgen-futures from 0.4.45 to 0.4.47 (#3318)
Bumps [wasm-bindgen-futures](https://github.com/rustwasm/wasm-bindgen) from 0.4.45 to 0.4.47.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

---
updated-dependencies:
- dependency-name: wasm-bindgen-futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 08:47:49 -08:00
dependabot[bot]
8edb11f324 chore(deps): bump postcard from 1.0.10 to 1.1.1 (#3319)
Bumps [postcard](https://github.com/jamesmunns/postcard) from 1.0.10 to 1.1.1.
- [Release notes](https://github.com/jamesmunns/postcard/releases)
- [Changelog](https://github.com/jamesmunns/postcard/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jamesmunns/postcard/compare/v1.0.10...postcard/v1.1.1)

---
updated-dependencies:
- dependency-name: postcard
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 08:47:36 -08:00
mahdi739
5a01a7f2ed chore: fix typo (#3320) 2024-12-03 08:47:25 -08:00
Greg Johnston
f252460d02 fix: wait for blocking resources before sending subsequent chunks (close #3280) (#3282) 2024-12-02 16:44:36 -08:00
rjmac
6331b488e4 Remove the Send requirement on a local Action's future (fixes #3309) (#3310)
Co-authored-by: Robert Macomber <robertm@mox>
2024-12-02 09:19:42 -08:00
Gabriel Lopes Veiga
fcba8b3b17 fix: prevent multiple location headers on redirect (#3298) (#3311) 2024-12-01 18:54:35 -08:00
Greg Johnston
d665dd4b89 v0.7.0 2024-11-30 12:09:41 -05:00
Greg Johnston
be740b38ee feat: add NodeRef::on_load() and writeable NodeRef (#3305) 2024-11-30 11:55:13 -05:00
Rakshith Ravi
d2803c938c chore: remove pre-release message from README (#3075) 2024-11-30 11:48:50 -05:00
Greg Johnston
f29224415a fix: sort tuple-syntax class and style in addition to colon-syntax (closes #3296) (#3303) 2024-11-29 19:28:11 -05:00
Greg Johnston
292772c4d6 fix: allow a deprecated wasm-bindgen struct 2024-11-29 15:50:57 -05:00
benwis
5947aa299e Release rc3 2024-11-28 11:28:20 -08:00
Greg Johnston
6098836cf7 docs: improve line location of hydration error message when using view macro (#3293) 2024-11-27 14:36:31 -05:00
Niklas Eicker
2dfa61ff6a docs: fix help message for island macro (#3287) 2024-11-24 14:45:10 -05:00
Darwin Boersma
4f39b0b0ef Version any_spawner alongside other crates, reexport CustomExecutor (#3284)
* rc2 version any_spawner

Signed-off-by: Darwin Boersma <darwin@sadlark.com>

* reexport full any_spawner crate

Signed-off-by: Darwin Boersma <darwin@sadlark.com>

---------

Signed-off-by: Darwin Boersma <darwin@sadlark.com>
2024-11-23 14:49:43 -08:00
dependabot[bot]
980595f1f0 chore(deps): bump proc-macro2 from 1.0.91 to 1.0.92 (#3276)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.91 to 1.0.92.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.91...1.0.92)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-23 08:29:52 -05:00
Greg Johnston
14eb707e82 rc2 2024-11-22 15:27:00 -05:00
Greg Johnston
3de0414ed5 docs: adds more helpful text for hydration errors (closes #3267) (#3275) 2024-11-22 15:10:37 -05:00
Greg Johnston
75cae91661 chore: expose some internals of routing to make wrappers easier (#3232) 2024-11-22 15:10:23 -05:00
Greg Johnston
8b258b0d26 fix: notify Suspense on subsequent reloads (closes #3277) (#3278) 2024-11-22 14:55:24 -05:00
dependabot[bot]
84bdd6b568 chore(deps): bump serde_json from 1.0.132 to 1.0.133 (#3261)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.132...v1.0.133)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:47 -05:00
dependabot[bot]
809023a2ad chore(deps): bump attribute-derive from 0.10.2 to 0.10.3 (#3260)
Bumps [attribute-derive](https://github.com/ModProg/attribute-derive) from 0.10.2 to 0.10.3.
- [Release notes](https://github.com/ModProg/attribute-derive/releases)
- [Changelog](https://github.com/ModProg/attribute-derive/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ModProg/attribute-derive/commits)

---
updated-dependencies:
- dependency-name: attribute-derive
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:39 -05:00
dependabot[bot]
1477ae2cfb chore(deps): bump axum from 0.7.8 to 0.7.9 (#3259)
Bumps [axum](https://github.com/tokio-rs/axum) from 0.7.8 to 0.7.9.
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.8...axum-v0.7.9)

---
updated-dependencies:
- dependency-name: axum
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:31 -05:00
dependabot[bot]
26995f8efd chore(deps): bump tower-http from 0.6.1 to 0.6.2 (#3266)
Bumps [tower-http](https://github.com/tower-rs/tower-http) from 0.6.1 to 0.6.2.
- [Release notes](https://github.com/tower-rs/tower-http/releases)
- [Commits](https://github.com/tower-rs/tower-http/compare/tower-http-0.6.1...tower-http-0.6.2)

---
updated-dependencies:
- dependency-name: tower-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:23 -05:00
dependabot[bot]
3c174b26a5 chore(deps): bump syn from 2.0.87 to 2.0.89 (#3272)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.87 to 2.0.89.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.87...2.0.89)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:13 -05:00
dependabot[bot]
0c7e77800a chore(deps): bump proc-macro2 from 1.0.89 to 1.0.91 (#3273)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.89 to 1.0.91.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.89...1.0.91)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 19:24:04 -05:00
Greg Johnston
fee2421047 chore: fix broken links, etc. in docs (#3269) 2024-11-21 19:23:55 -05:00
Ari Seyhun
89f26f6e9b feat: add fallback prop to ProtectedRoute and ProtectedParentRoute (#3264) 2024-11-19 22:32:45 -08:00
Silver
e76b22bec8 Remove unused shell() function definition (#3254) 2024-11-19 12:17:45 -08:00
Greg Johnston
cff277b3db fix: add Write implementatations for Field<T> and ArcField<T> (closes #3257) (#3262) 2024-11-19 10:04:40 -05:00
Ari Seyhun
0258ac6df4 feat(reactive_stores): add map_untracked to OptionStoreExt (#3245) 2024-11-18 09:41:04 -05:00
Greg Johnston
36132a5823 Merge pull request #3249 from metatoaster/pr3213_e2e_tests
test: aria-current end-to-end tests (#3213)
2024-11-17 15:50:13 -05:00
autofix-ci[bot]
6f35f8d197 [autofix.ci] apply automated fixes 2024-11-17 01:51:40 +00:00
Tommy Yu
3973c4f420 test: aria-current end-to-end tests (#3213) 2024-11-17 14:40:47 +13:00
benwis
7f2237b91e Remove hash.txt from tracking, update dependencies in tests 2024-11-16 11:19:11 -08:00
Tommy Yu
aa6cd08387 test: fixtures for testing aria-current (#3202) 2024-11-16 11:11:54 -08:00
dependabot[bot]
15fc7dd7be chore(deps): bump thiserror from 2.0.0 to 2.0.3 (#3231)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.0 to 2.0.3.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.0...2.0.3)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-16 11:07:00 -08:00
dependabot[bot]
eac979e309 chore(deps): bump serde from 1.0.214 to 1.0.215 (#3236)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.214 to 1.0.215.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.214...v1.0.215)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-16 11:06:49 -08:00
dependabot[bot]
f7ac7be32b chore(deps): bump glib from 0.20.5 to 0.20.6 (#3237)
Bumps [glib](https://github.com/gtk-rs/gtk-rs-core) from 0.20.5 to 0.20.6.
- [Release notes](https://github.com/gtk-rs/gtk-rs-core/releases)
- [Changelog](https://github.com/gtk-rs/gtk-rs-core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gtk-rs/gtk-rs-core/compare/0.20.5...0.20.6)

---
updated-dependencies:
- dependency-name: glib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-16 11:06:39 -08:00
dependabot[bot]
2462a1dc92 chore(deps): bump axum from 0.7.7 to 0.7.8 (#3246)
Bumps [axum](https://github.com/tokio-rs/axum) from 0.7.7 to 0.7.8.
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.7...axum-v0.7.8)

---
updated-dependencies:
- dependency-name: axum
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-16 11:06:30 -08:00
Greg Johnston
2c6d790cdb change: rename from experimental-islands to islands (#3247)
* change: rename from `experimental-islands` to `islands`

* update examples
2024-11-16 11:06:18 -08:00
Kalin Staykov
1c26261fd7 fix: migration syntax and insert query (#2597) 2024-11-13 09:37:19 -08:00
Saber Haj Rabiee
c2b239dba2 fix: run autofix.ci on pull requests only (#3238) 2024-11-12 14:16:34 -08:00
Saber Haj Rabiee
d4044cd5a1 feat: add autofix.ci to address formatting issues and possible clippy fixes (#3235)
* feat: add `autofix.ci` to address formatting issues and possible clippy
fixes

* fix: initial run of `autofix.ci` script to prevent PR pollution at first
run

* fix: typo and indent issue in `autofix.yml`

* fix: run `autofix.ci` over members with no features
2024-11-12 10:54:14 -08:00
Greg Johnston
43912f4fd0 chore: fmt 2024-11-12 09:05:36 -05:00
Greg Johnston
a5293f0b79 chore: add missing docs for 0.7 (#3203) 2024-11-11 19:58:38 -05:00
Niklas Eicker
998eefb8c5 chore: add tests for converting path segments into paths (#3229) 2024-11-10 20:04:04 -05:00
Greg Johnston
63f3508818 fix: don't generate additional / for empty static segments in static routes (closes #3224, #3226) (#3228) 2024-11-10 20:03:03 -05:00
Niklas Eicker
24308bb0eb feat: support browsers without startViewTransition (#3227) 2024-11-10 16:34:12 -05:00
Paul Hansen
f804a69f2f chore: fix deprecated parameters js warning (#3219) 2024-11-10 14:52:10 -05:00
dependabot[bot]
b596af45f0 chore(deps): bump tempfile from 3.13.0 to 3.14.0 (#3212)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.13.0 to 3.14.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.13.0...v3.14.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-10 14:51:44 -05:00
Greg Johnston
5206755124 chore: add docs for stores (#3216) 2024-11-10 14:51:25 -05:00
Greg Johnston
53a55a1ef2 fix: support all ___: attributes on components (#3218) 2024-11-10 14:51:11 -05:00
Niklas Eicker
0f74332d38 chore: remove obsolete build_static_routes (#3223) 2024-11-10 14:51:00 -05:00
Greg Johnston
bb0dff6af5 fix: support complex punctuated attribute keys in attr: syntax (closes #3221) (#3214) 2024-11-08 17:01:27 -05:00
Greg Johnston
d204ac6d5e fix: ensure that aria-current is set correctly (closes #3196) (#3213) 2024-11-08 16:19:03 -05:00
Greg Johnston
b0ad85e624 chore: clarify GTK example status in README (closes #3215) 2024-11-08 16:18:51 -05:00
Greg Johnston
0eebe9e289 fix: only register async work with transition if it isn't already done (closes #3197) (#3209) 2024-11-08 09:04:52 -05:00
Greg Johnston
2abbdb6594 fix: complete navigation after rendering fallback (closes #3199) (#3208) 2024-11-08 09:04:40 -05:00
dependabot[bot]
8f8f3e23e4 chore(deps): bump tokio from 1.41.0 to 1.41.1 (#3207)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.41.0 to 1.41.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.41.0...tokio-1.41.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-07 19:16:59 -05:00
Saber Haj Rabiee
aab952357e Dependabot, Attemp #2 (#3204)
* fix: remove examples and benchmarks from dependabot search path

* chore: update/upgrade deps to prevent dependabot PR pollution at first
run

* fix: increase number of pull requests from dependabot as the workspace
is pretty big

* fix: revert rkyv version as it was unexpectedly downgraded

* fix: tower in example
2024-11-07 10:55:57 -08:00
Saber Haj Rabiee
f1ebf77fa6 fix: make free space for ci workflows before running them (#3206) 2024-11-07 10:55:42 -08:00
Darwin Boersma
5cc2f3858d Add futures-executor feature for any_spawner (#3195)
Signed-off-by: Darwin Boersma <darwin@sadlark.com>
2024-11-05 10:11:34 -08:00
Tommy Yu
8252655959 Updated tests for #3182 (#3194)
* fix: ensure we check memos the first time a dependency uses them, even if the dependency always runs on its first run (closes #3181)

* Correct expected counter values down due to #3182

- As #3182 fixed the issue where superfluous resource fetches happened
  when hydration happened inside a nested component, the expected values
  for the counters are down to where they actually are supposed to be.

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-11-04 18:12:54 -08:00
Saber Haj Rabiee
14e47e87ba chore: add Cargo.lock (closes #2881) (#3192) 2024-11-04 16:21:35 -05:00
Greg Johnston
4a8cfad7c5 chore(ci): suppress warnings about unused code in example tests (#3193) 2024-11-04 13:08:50 -05:00
Louis Dispa
d9f52dad76 feat: implement rendering traits for fixed-size arrays (#3174) 2024-11-04 12:26:43 -05:00
Greg Johnston
3a8508df6c rc1 2024-11-03 20:19:57 -05:00
Daniëlle Huisman
865c6df483 wasm-bindgen 0.2.95 (#3186) 2024-11-03 20:19:21 -05:00
Greg Johnston
c1d7f0f8d1 fix: exclude excluded server fn paths instead of unregistering them (closes #3150, #3175) (#3176) 2024-11-03 20:02:11 -05:00
zakstucke
8c2dd73b70 chore: expose internals of SerializedDataId and SsrSharedContext to allow creating custom hydration contexts (#3145) 2024-11-03 19:55:59 -05:00
Greg Johnston
d5894555cc fix: allow !Send errors in Actix extract() (#3189) 2024-11-03 19:53:24 -05:00
Enzo Nocera
2ef1723607 Makes the wasm32-wasip1/2 target a first-class citizen for Leptos's Server-Side (#3063)
* feat: WIP wasi integrations crate

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(server_fn): add generic types

This commit adds `From` implementations for the
`Req` and `Res` types using abstraction that are deemed
"platform-agnostic".

Indeed, both the `http` and `bytes` crates contains types
that allows us to represent HTTP Request and Response,
while being capable to target unconventional platforms
(they even have `no-std` support). This allows the
server_fn functions to target new platforms,
for example, the `wasm32-wasip*` targets.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(server_fn): generic types cleanup

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(integrations/wasi): make WASI a first-class citizen of leptos server-side

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* WIP: chore(any_spawner): make the futures::Executor runable

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* fix(server_fn): include `generic` in axum.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(any_spawner): some clippy suggestions

I ran clippy in really annoying mode since I am still
learning Rust and I want to write clean idiomatic code.
I took suggestions that I thought made sense, if any
maintainers think those are *too much*, I can relax
those changes:

* Use `core` instead of `std` to ease migration to `no_std`
  (https://rust-lang.github.io/rust-clippy/master/index.html#/std_instead_of_core)
* Add documentation on exported types and statics
* Bring some types in, with `use`
* Add `#[non_exhaustive]` on types we are not sure we
  won't extend (https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_enums)
* Add `#[inline]` to help the compiler when doing
  cross-crate compilation and Link-Time optimization
  is not enabled. (https://rust-lang.github.io/rust-clippy/master/index.html#/missing_inline_in_public_items)
* Use generic types instead of anonymous `impl` params
  so callers can use the `::<>` turbofish syntax (https://rust-lang.github.io/rust-clippy/master/index.html#/impl_trait_in_params)

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(leptos_wasi): fine-tune linter and clean-up

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(leptos_wasi): better handling of server fn with form

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: cargo fmt

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: remove custom clippy

Remove clippy crate rules since it
seems to make tests fails in tests.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: use `wasi` crate

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: revert changes to any_spawner

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: simpler crate features + cleanup

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(any_spawner): add local custom executor

This commit adds a single-thread "local"
custom executor, which is useful for environments
like `wasm32` targets.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(leptos_wasi): async runtime

This commit adds a single-threaded
async runtime for `wasm32-wasip*`
targets.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* feat(leptos_wasi): error handling

This commit adds error types for the users
to implement better error handling.

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: migrate integration off-tree

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(ci): fix formatting

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore: remove ref to leptos_wasi in Cargo.toml

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(ci): fix fmt

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(ci): remove explicit into_inter()

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

* chore(ci): make generic mutually exclusive with other options

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

---------

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>
2024-11-02 09:44:50 -07:00
Greg Johnston
13f7387d45 fix: Oco equality check (closes #3178) (#3180) 2024-11-01 14:55:49 -04:00
Greg Johnston
0a13f7c08c chore: reexport unescape (closes #3177) (#3179) 2024-11-01 14:55:37 -04:00
Greg Johnston
7c83904aea Merge pull request #3173 from leptos-rs/store-tweaks
Store tweaks
2024-10-30 20:33:10 -04:00
Greg Johnston
6e13ff9787 feat: impl Into<Field<T>> for Store<T> (closes #3102) 2024-10-28 20:28:09 -04:00
Greg Johnston
234d138f03 chore: remove log 2024-10-28 20:17:23 -04:00
Greg Johnston
97110cd5ac chore: remove Then 2024-10-28 20:17:23 -04:00
Greg Johnston
5acc1b1a5a chore: rename .iter() to .iter_unkeyed() for clarity 2024-10-28 20:16:54 -04:00
Nicolas Cura
f3987246cb docs: remove duplicated "calls" word (#3171) 2024-10-28 20:04:33 -04:00
Greg Johnston
e5149fb348 fix: correctly track inner subfields on Field (closes #3169) (#3170) 2024-10-28 20:04:16 -04:00
Greg Johnston
d67ff03568 chore: fix leptos_dom reexports (closes #3166) (#3168) 2024-10-27 21:12:41 -04:00
Greg Johnston
1dbca3005d Merge pull request #3163 from leptos-rs/undep-mp
chores
2024-10-25 17:47:14 -04:00
Greg Johnston
af61be0c72 fix: correctly reset classes when using Option<T> (#3164) 2024-10-25 17:47:00 -04:00
Johannes Heuel
76facf9539 feat: improve tailwind config to also catch dynamic classes (#3143) 2024-10-25 14:06:19 -04:00
Tommy Yu
0e73d18d7b ci: regression tests for double suspense/double resource fetch (#3103)
* test: first cut of the instrumented suspense_tests

- Based on initial concepts developed for reproducing #2937 and others,
  streamlined and instrumented for e2e testing and refined for inclusion
  as a standalone module to be plugged into some other App.

* First cut of the fixtures and tests

* Actually make it work properly

- Instead of using examples, just feed it the table because examples
  will rerun the whole scenario from scratch, which isn't what we are
  trying to test here.
- Provide a basic example with item listing to show how this will work.

* Use ticketing system to disambiguate CSR calls

- Keep all SSR calls on ticket 0 as a means to disambiguate them from
  CSR calls.  For the mean time the focus of tests isn't on that
  behavior but this may be modified when suitable.

* Update the baseline fixtures

- Given the new understanding, the scenerios all being the baseline
  tests they are now moved into one file.
- Have the checks against all calls at once for better diff output,
  and reword the new scenerios into more idomatic gherkin.
- Streamline the steps and provide additional ones that will help with
  feature definitions.

* Translate the reproduction steps into Gherkin

* Comment out logging to avoid output interference.

* Be able to reset CSR counters everywhere

- Done by providing a button directly on the top level component with
  the navigation footer.  This will be useful for the next test.

* Test showing difference between hydrate and CSR

- Specifically, under hydrated load, resources that shouldn't need
  refetching gets refetched, while CSR does not show this issue.
2024-10-25 14:05:42 -04:00
Greg Johnston
d306a15f86 fix: avoid deadlocking if can't take Memo write lock (closes #3158) (#3160) 2024-10-25 13:57:44 -04:00
Greg Johnston
bf95648dc9 chore: clippy doc comment length 2024-10-25 13:56:02 -04:00
Greg Johnston
00edfc0e0a chore: undeprecate MaybeProp 2024-10-25 13:49:19 -04:00
zakstucke
396327b667 feat: Option<T> read-like traits & deprecate MaybeSignal (#3098) 2024-10-25 13:41:26 -04:00
zakstucke
a437289f81 feat: impl IntoStyle for Option<impl IntoStyle & Oco (#3119) 2024-10-25 13:31:07 -04:00
zakstucke
58e7897db6 fix: From<> impls between ArcLocalResource and LocalResource (#3144) 2024-10-25 13:30:18 -04:00
Greg Johnston
1be1f41fba fix: restore array syntax for setting multiple classes dynamically (closes #3151) (#3152) 2024-10-23 20:10:04 -04:00
Greg Johnston
7b8cd90a6e 0.7.0-rc0 2024-10-21 21:16:20 -04:00
Greg Johnston
d0ef7b904d feat: add OptionalParamSegment (closes #2896) (#3140) 2024-10-21 21:15:14 -04:00
Greg Johnston
7904e0c395 fix: unregister server functions whose paths are in excluded routes (closes #2735) (#3138) 2024-10-21 09:14:36 -04:00
Greg Johnston
7b4c470155 perf: type erasure in router (#3107) 2024-10-20 20:07:14 -04:00
Greg Johnston
98eccc9eb8 perf: make LeptosOptions lighter-weight to clone (closes #3036) (#3136) 2024-10-20 20:05:29 -04:00
Greg Johnston
70d06e2716 feat: Action::clear() to clear action value (closes #2364) (#3135) 2024-10-20 16:29:05 -04:00
PenguinWithATie
67c3bf2478 chore: add tachys::view::fragment::Fragment to prelude (#3125) 2024-10-20 14:15:15 -04:00
Corvus
f3aaae857a feat: allow axum to serve precompressed files (#3133) 2024-10-19 20:47:35 -04:00
Greg Johnston
d727e53dd6 chore(ci): reduce tachys feature set combinations (#3131) 2024-10-19 20:45:49 -04:00
zakstucke
e4543ab5df feat: new nostrip: prop prefix to pass Option<T> directly when prop(optional) (#3105) 2024-10-19 15:41:51 -04:00
Greg Johnston
1ca0f4430c feat: use View Transition API for router animations (#3112) 2024-10-19 15:41:20 -04:00
Joaquim Pedro França Simão
b59fa11853 feat: add two-way data binding support for stores (#3115) 2024-10-19 15:39:45 -04:00
Greg Johnston
e55f08e017 feat: expose use_matched() (closes #3124) (#3126) 2024-10-18 16:12:41 -04:00
zakstucke
fa1939e5b2 chore: From<ArcResource> for ArcResource and AsyncDerived (#3121) 2024-10-18 16:12:11 -04:00
zakstucke
8b2f0eaf44 fix: do not warn when reading resources in effect outside Suspense (#3118) 2024-10-18 15:24:09 -04:00
Chris
b118d69281 fix: remove unused Params attribute params (#3123)
See 1966 for original PR on older version
2024-10-18 15:20:45 -04:00
stefnotch
ee66f6c395 Add support for user-supplied executors (#3091) 2024-10-16 06:24:07 -07:00
Greg Johnston
eba08ad592 fix: don't render empty string as a space in unescaped elements (closes #3120) (#3122) 2024-10-15 18:57:09 -04:00
Greg Johnston
4833b4e287 fix: avoid double-polling synchronously-available Suspend (closes #3113) (#3114) 2024-10-15 08:49:40 -04:00
Greg Johnston
9d1be64e4d chore: publish stores (#3110) 2024-10-14 10:18:38 -04:00
benwis
d6e6cd3be0 v0.7.0gamma3 2024-10-14 05:01:19 -07:00
stefnotch
70476f9277 feat: add support for async-executor from smol-rs (#3090) 2024-10-14 07:57:19 -04:00
zakstucke
d8ddfc26e9 perf: use the Track trait for the Signal wrapper. (#3076) 2024-10-12 20:29:03 -04:00
stefnotch
c8acc3e8bd fix: correctly support local pools for futures-executor (#3089) 2024-10-12 20:13:50 -04:00
zakstucke
547442243b impl IntoClass for Option<impl IntoClass> (#3104) 2024-10-12 05:03:53 -07:00
Greg Johnston
6e58266f54 feat: support set_is_routing/RoutingProgress for nested routes (#3101) 2024-10-11 19:05:33 -04:00
Greg Johnston
f0cd0fb41d feat: condense Router/Routes base prop into one (#3100) 2024-10-11 14:06:11 -04:00
Daniil Polyakov
7585faf57e fix: use full path to Result in Params derive (#3096) 2024-10-10 15:20:38 -04:00
zakstucke
da7f6a34e8 chore: expose AnyView in prelude (#3099) 2024-10-10 15:20:24 -04:00
Greg Johnston
4f7fa41262 fix: don't on WASM server targets unless you actually try to generate static routes (closes #3094) (#3097) 2024-10-10 15:20:04 -04:00
Greg Johnston
4becfa39ca correct version number 2024-10-10 09:13:39 -04:00
Greg Johnston
f8388b122d fix: avoid reentering lock when initializing nested keyed store fields (closes #3086) (#3087) 2024-10-10 08:53:28 -04:00
Greg Johnston
f57a57b92b feat: restore AnimatedShow for 0.7 (#3084) 2024-10-10 08:53:05 -04:00
vsuryamurthy
f0bcbd9cfe remove unused dependencies leptos_axum and leptos_router (#2960)
* remove unused dependencies leptos_axum and leptos_router

* cargo fmt

* Restore http::Uri under default feature

* use axum re-exported headers instead of http directly

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-10-10 04:29:11 -07:00
Greg Johnston
115477ef1d chore: remove unused code from leptos package (#3085) 2024-10-10 04:23:37 -07:00
Greg Johnston
832b9cb321 chore: pin wasm-bindgen to 0.2.93 to fix example builds (#3088) 2024-10-09 22:56:05 -04:00
Greg Johnston
b0150ceeec fix: missing Copy/Clone implementations for OnceResource (#3080) 2024-10-09 19:33:33 -04:00
dependabot[bot]
af8df34360 chore(deps): bump denoland/setup-deno from 1 to 2 (#3081)
Bumps [denoland/setup-deno](https://github.com/denoland/setup-deno) from 1 to 2.
- [Release notes](https://github.com/denoland/setup-deno/releases)
- [Commits](https://github.com/denoland/setup-deno/compare/v1...v2)

---
updated-dependencies:
- dependency-name: denoland/setup-deno
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-09 18:50:31 -04:00
Greg Johnston
b2e6185b22 fix: don't escape script/style/textarea in InertHtml (closes #3078) (#3079) 2024-10-09 10:07:40 -04:00
Greg Johnston
d2bfb3080b Merge pull request #3077 from leptos-rs/router-fixes
Router fixes
2024-10-09 07:33:24 -04:00
Greg Johnston
72ebd17042 fix: only set browser URL if it matches current router URL (closes #2979( 2024-10-08 22:12:18 -04:00
Greg Johnston
e2f0b4deeb fix: prevent simultaneous \query_signal\ writes from canceling each other (closes #2369) 2024-10-08 22:12:02 -04:00
Greg Johnston
57c07e9aec feat: enable faster compile times with RUSTFLAGS="--cfg erase_components (#2905) 2024-10-08 17:03:40 -04:00
Greg Johnston
0835066bc0 chore: re-add regression tests from #2639 (#3073) 2024-10-08 17:02:18 -04:00
webmstk
656e83fe24 docs: fix comment for set_interval helper (#3074) 2024-10-08 13:30:17 -04:00
Greg Johnston
ad0252ecfd fix: inconsistencies in check for latest version in actions (#3070) 2024-10-07 21:02:02 -04:00
Greg Johnston
77f05c6f4e fix: add HEAD support for Actix in leptos_routes (closes #2885) (#3069) 2024-10-07 21:01:46 -04:00
zakstucke
a4ea491dc0 feat: add Read/ReadUntracked/Track for Signal/MaybeSignal/MaybeProp (#3031) 2024-10-07 19:55:07 -04:00
Greg Johnston
3c89b9c930 feat: add an optimized OnceResource and use it to rebuild Await (#3064) 2024-10-06 20:47:22 -04:00
Greg Johnston
93d7ba0d5f fix: add SVG <use> (closes #3065) (#3067) 2024-10-06 20:47:06 -04:00
Greg Johnston
e188993800 fix: remove unnecessary Send/Sync bounds on LocalResource (#3061) 2024-10-04 16:16:24 -04:00
Greg Johnston
c1dc8c7629 Merge pull request #3062 from leptos-rs/into-render
feat: add `IntoRender` for rendering custom data
2024-10-04 14:43:55 -04:00
Greg Johnston
ab9de1b8c0 chore: remove unused variable 2024-10-04 13:56:38 -04:00
Greg Johnston
b39985d9b8 fix: only use IntoAttributeValue for parts of view that are actually attribute values 2024-10-04 13:38:09 -04:00
Greg Johnston
5e8e93001d docs: IntoRender and IntoAttributeValue 2024-10-04 13:25:57 -04:00
Greg Johnston
a4ed0cbe5b feat: add IntoAttributeValue for rendering arbitrary attribute values 2024-10-04 13:24:39 -04:00
Greg Johnston
422fe9f43b feat: add IntoRender for rendering arbitrary types 2024-10-04 13:13:23 -04:00
kczimm
36df36e16c feat: allow ParamsMap to support multiple values per key (closes #2882) (#2966)
Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-10-03 18:35:50 -04:00
Chris
95fc79034b chore: dead router::router module from 0.6 (#2943) 2024-10-02 19:35:49 -04:00
Greg Johnston
7403e4084f Merge pull request #3040 from mahdi739/double-ended-iterator-for-stores
Double-ended-iterator-for-stores
2024-10-02 19:19:40 -04:00
jk
8feee5e5d7 Migrate rkyv 0.8.x (#3054) 2024-10-02 10:03:20 -07:00
Greg Johnston
e6da266b4f Merge pull request #3050 from leptos-rs/2086
Module restructuring and docs cleanup
2024-10-01 21:23:47 -04:00
Greg Johnston
0798e0812d fix: unused import in example 2024-10-01 21:23:22 -04:00
Greg Johnston
03514e68be chore: fix test import 2024-10-01 20:43:46 -04:00
Greg Johnston
4092368581 chore: remove unused import 2024-10-01 20:43:37 -04:00
Greg Johnston
dcc7865989 fix: remove r# from raw attribute names in InertHtml (closes #3049) (#3058) 2024-10-01 20:18:29 -04:00
Greg Johnston
896f7de8e1 fix: update import of spawn_local in test examples 2024-10-01 20:06:04 -04:00
Greg Johnston
29b2d3024a fix: update import of tick in test examples 2024-10-01 20:05:22 -04:00
Greg Johnston
c47893ad60 fix: <textarea> does not parse its children as HTML, like <script> and <style> (#3052) 2024-10-01 19:39:10 -04:00
Greg Johnston
0d4f3b51e9 fix: import of reactive_graph in integrations 2024-10-01 19:38:55 -04:00
Greg Johnston
2431b19cdf chore: reexport reactive_graph as leptos::reactive 2024-10-01 19:36:20 -04:00
Greg Johnston
4801e1ec6d chore: hide unwrap_signal from docs 2024-10-01 19:36:20 -04:00
Greg Johnston
e206b93ba5 chore: inline docs for reexported crates 2024-10-01 19:36:20 -04:00
Greg Johnston
f0675446d8 chore: reexport reactive_graph as leptos::reactive 2024-10-01 19:36:20 -04:00
Greg Johnston
2ac7eaad15 chore: add missing docs for tick 2024-10-01 19:36:20 -04:00
Greg Johnston
8a040fda69 chore: rename Writeable to Write for consistency 2024-10-01 19:36:20 -04:00
Greg Johnston
2f5c966cf4 chore: reexport untrack from leptos::prelude but not from reactive_graph 2024-10-01 19:36:20 -04:00
Greg Johnston
45e2629f0e chore: remove reexport of tachys in leptos::prelude 2024-10-01 19:36:20 -04:00
Greg Johnston
517566d085 change: rename spawn module to task 2024-10-01 19:35:45 -04:00
Greg Johnston
6df8657700 fix: escape text nodes and attributes in InertHtml (closes #3056) (#3057) 2024-10-01 19:19:21 -04:00
Georg Vienna
2a4063a259 projects: port session_auth_axum (#2970) 2024-10-01 09:40:57 -07:00
Marc-Stefan Cassola
013ec4a09d Two-way data binding (#2977)
* added two-way data binding to dom elements

* added two-way data binding to radio groups

* moved bind into reactive_graph mod

* chore: use `::leptos` absolute path in macro

* chore: move `Group` into the reactive module, as that's the only place it has meaning

* feat: use new `bind:` syntax

* chore: update for non-generic rendering

* chore: ignore this test

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-10-01 09:39:45 -07:00
Greg Johnston
d10fec08e2 Merge pull request #3037 from leptos-rs/rename-island-router
change: rename island-router feature so people don't use it
2024-09-30 20:55:08 -04:00
Greg Johnston
94f4328586 example: add README that actually explains this example 2024-09-30 20:08:39 -04:00
Greg Johnston
2b70961110 change: rename island-router feature so people don't use it 2024-09-30 20:08:24 -04:00
Greg Johnston
699c54e16c -gamma prerelease 2024-09-30 14:16:38 -04:00
Greg Johnston
1217ef4d8e beta7 2024-09-30 14:16:01 -04:00
Sean Aye
9aba3efbe4 chore: remove unnecessary trait bounds (#3046) 2024-09-29 17:26:31 -04:00
SleeplessOne1917
1b48a2f8d5 Replace proc-macro-error with proc-macro-error2 (#3044) 2024-09-28 18:03:28 -07:00
Greg Johnston
31cb766206 docs: restore warning when reading resource outside Suspense (closes #3038) (#3041) 2024-09-28 13:10:30 -04:00
Mahdi
4c3bcaa68d implement DoubleEndedIterator for StoreFieldKeyedIter 2024-09-28 17:15:43 +03:30
Mahdi
fe060617d2 implement DoubleEndedIterator for StoreFieldIter 2024-09-28 17:14:45 +03:30
Greg Johnston
de28a317f0 fix: do not emit HTML comments inside script/style, and do not try to hydrate them (closes #3033) (#3034) 2024-09-27 12:33:51 -04:00
Greg Johnston
d29433b98d fix: more robust arena sandboxing (closes #2995) (#3026) 2024-09-26 19:48:04 -04:00
Greg Johnston
f2582b6ac9 fix: properly scope Suspend rebuilds within ownership tree (closes #3024) (#3030) 2024-09-26 18:19:36 -04:00
zakstucke
67845be161 feat: read and write for StoredValue (#3027) 2024-09-26 15:46:09 -04:00
Greg Johnston
2bf1f46b88 fix: add correct namespaces for SVG and MathML elements (closes #3021) (#3025) 2024-09-25 19:42:42 -04:00
VincentBerthier
70ae3a0abb fix: island hydration warning message (#3023) 2024-09-25 15:38:04 -04:00
Greg Johnston
96e2b5cba1 fix: abort Suspend on cleanup, to avoid using disposed items (closes #3012) (#3019) 2024-09-24 21:45:39 -04:00
Greg Johnston
ef27a198d9 fix: correct Owner restoration in FlatRoutes (closes #3014) (#3018) 2024-09-24 21:45:30 -04:00
Greg Johnston
47299926bb fix: suppress resource loading during route generation (closes #3013) (#3017) 2024-09-24 21:45:22 -04:00
Greg Johnston
bdc2285658 change: remove generic rendering (#3015) 2024-09-24 17:01:57 -04:00
zakstucke
9d4ce6e526 Fix custom root when not using islands. (#3016) 2024-09-24 11:42:54 -07:00
Greg Johnston
3d2cdc21a1 beta6 2024-09-23 08:57:44 -04:00
Greg Johnston
93d939aef8 Merge pull request #3009 from leptos-rs/stores-patch
Stores patching
2024-09-22 21:45:10 -04:00
Greg Johnston
fb04750607 example: add example of patching fields 2024-09-22 19:52:48 -04:00
Greg Johnston
a080496e7e fix: notify correctly when patching stores 2024-09-22 19:51:50 -04:00
Greg Johnston
9fc1002167 perf: do not notify keyed iterator when only an inner field has changed 2024-09-22 19:50:30 -04:00
Greg Johnston
bc5c766530 fix: notify stores when modifying parent, without notifying siblings 2024-09-22 19:33:14 -04:00
Greg Johnston
17821f863a fix: restructure StoredValue so that nested calls do not deadlock (closes #2968) (#3004) 2024-09-22 19:21:49 -04:00
Baptiste
1ca4f34ef3 fix: optional props with islands (#3005) 2024-09-21 18:13:58 -04:00
Greg Johnston
8f0a1554b1 Merge pull request #3000 from leptos-rs/add-attr-any-view
Doing chores
2024-09-21 08:51:32 -04:00
Greg Johnston
38d4f26d03 fix: snip infinite type recursion 2024-09-21 07:51:27 -04:00
Greg Johnston
2b04c2710d Merge pull request #3002 from leptos-rs/fix-stores
Fix stores
2024-09-21 07:37:54 -04:00
Greg Johnston
a4937a1236 fix: correctly triggering parents vs siblings 2024-09-20 21:25:42 -04:00
Greg Johnston
f6f2c39686 chore: remove UntrackedWriter 2024-09-20 20:47:46 -04:00
Greg Johnston
d7eacf1ab5 chore: remove unused DocumentFragment mounting code 2024-09-20 20:41:51 -04:00
Greg Johnston
d1a4bbe28e chore: fix adding attr todo for static types 2024-09-20 20:41:51 -04:00
Greg Johnston
412ecd6b1b chore: remove dead iterator wrapper code 2024-09-20 20:41:51 -04:00
Greg Johnston
9bc0152121 chore: clean up todos in template SSR code 2024-09-20 20:41:51 -04:00
Greg Johnston
4b05cada8f chore: remove dead code for rendering guards 2024-09-20 20:41:51 -04:00
Greg Johnston
a818862704 chore: tidy up todos on EitherKeepAlive 2024-09-20 20:41:51 -04:00
Greg Johnston
173487debc fix: add add_any_attr() for AnyView<R> 2024-09-20 20:41:51 -04:00
Greg Johnston
449d96cc9a feat: add wrapper to support add_any_attr() fixes 2024-09-20 20:41:51 -04:00
Greg Johnston
f9bf6a95ed Merge pull request #3001 from leptos-rs/ci
Fix CI
2024-09-20 20:40:53 -04:00
Greg Johnston
5bf6c94bb2 chore: remove some testing combinations 2024-09-20 20:11:44 -04:00
Greg Johnston
e1ce94a28d fix: rationalize reactive_stores tests 2024-09-20 18:25:40 -04:00
Greg Johnston
2a62dcf27e chore: fix unused import 2024-09-20 18:18:11 -04:00
Greg Johnston
3094766c5c chore: allow unused methods 2024-09-20 18:08:09 -04:00
Greg Johnston
a52804595d chore: allow unused methods 2024-09-20 17:35:43 -04:00
Greg Johnston
e72f12d32b chore: clean up tests 2024-09-20 17:31:11 -04:00
Greg Johnston
e70083708a chore: fix dependencies 2024-09-20 16:39:21 -04:00
Greg Johnston
cbc4caef19 chore: fix testing 2024-09-20 16:36:40 -04:00
Greg Johnston
fbeee4dbf5 chore: cargo fmt 2024-09-20 16:31:07 -04:00
Greg Johnston
d13f7e5438 chore: remove unused import 2024-09-20 16:02:41 -04:00
Greg Johnston
7b543bd31c chore: fix syn features 2024-09-20 15:57:54 -04:00
Greg Johnston
1743724420 chore: AsRef/AsMut 2024-09-20 15:46:15 -04:00
Greg Johnston
73e0add670 chore: cargo fmt 2024-09-20 15:44:19 -04:00
Greg Johnston
4f5eb444bc chore: remove print 2024-09-20 15:43:46 -04:00
Greg Johnston
7de98823fb chore: clippy and missing GTK implementations 2024-09-20 15:38:15 -04:00
Georg Vienna
6d930573fc feat: add either macro (#2900) 2024-09-20 08:17:40 -07:00
Saber Haj Rabiee
3317002ff5 fix: improve CI workflow (#2838)
* fix: improve CI workflow

* fix: add missing `Makefile.toml` to workspace crates
(reactive_stores and reactive_stores_macro)

* fix: remove trailing slash in workflow names

* fix: add gtk example and improve excluding example's logic

* fix: install gtk example deps
2024-09-20 08:08:28 -07:00
martin frances
99403d0167 MSRV Bump to 1.80.0, drop crate lazy_static and use std::sync::LazyLock. (#2767) 2024-09-19 21:40:33 -07:00
Greg Johnston
23ce022c60 Merge pull request #2997 from leptos-rs/2971
Changes related to stack overflows
2024-09-19 17:20:45 -04:00
Greg Johnston
96e1fd0fb8 fix: turn off InertHtml for SVG/MathML (closes #2998) (#2999) 2024-09-19 17:20:30 -04:00
Greg Johnston
f28dac1093 chore: remove unused debug info from HtmlElement 2024-09-19 15:38:52 -04:00
Greg Johnston
ff28544fb2 feat: add BoxedView wrapper 2024-09-19 15:38:52 -04:00
Deep Gaurav
27765b417c fix: static generation should wait for file writes before resolving (#2994) 2024-09-19 15:36:54 -04:00
Greg Johnston
b0d8d4ee26 fix: properly trigger Suspense when Suspend is called again (#2993) 2024-09-18 21:35:37 -04:00
Greg Johnston
c4b1176a6a fix: drop lock on current URL before rendering, in case of redirect (closes #2990) (#2992) 2024-09-18 21:27:18 -04:00
Greg Johnston
fd133dd79a chore: re-export untrack 2024-09-18 20:25:35 -04:00
Greg Johnston
9c2477a4cf Revert "chore: re-export untrack (#2991)"
This reverts commit f3b6d1f351.
2024-09-18 20:25:03 -04:00
Greg Johnston
f3b6d1f351 chore: re-export untrack (#2991) 2024-09-18 19:51:20 -04:00
Greg Johnston
5af7b54c9c perf: optimize inert HTML elements (#2989) 2024-09-18 19:42:07 -04:00
Baptiste
ba9604101d fix: correct lifetimes for PartialPathMatch (#2981) 2024-09-16 21:59:49 -04:00
Greg Johnston
e136c1fc44 Merge pull request #2986 from leptos-rs/2957
fix: get Suspend and ErrorBoundary working together correctly
2024-09-16 21:58:49 -04:00
Greg Johnston
c581b3293e Merge pull request #2985 from leptos-rs/2982
fix: sort attributes so `class` and `style` always run before `class:` and `style:` (closes #2982)
2024-09-16 21:58:38 -04:00
Greg Johnston
cc7f861637 fix: add missing Debug and DefinedAt impls for Resource/ArcResource (closes #2983) (#2984) 2024-09-16 21:58:23 -04:00
Greg Johnston
642d6fc72b fix: stable hashes across different client and server builds for islands (closes #2978) (#2980) 2024-09-16 21:58:09 -04:00
Kajetan Welc
e69c7f4ae0 feat(#2946): add #[store(skip)] for #[derive(Store)] (#2975) 2024-09-16 21:57:57 -04:00
Greg Johnston
9ca36d4763 chore: remove deprecated function in doctest example 2024-09-16 21:34:04 -04:00
Greg Johnston
8dc600ca02 fix: do not sort class and style that are after spread marker 2024-09-16 21:33:46 -04:00
Greg Johnston
b621ead607 fix: forward subscribers for already-resolved Suspend during client-side build 2024-09-16 21:10:02 -04:00
Greg Johnston
66cf21f650 fix: Ok => Err transition with Suspend (closes #2957) 2024-09-16 21:02:30 -04:00
Greg Johnston
f3dcdc057d fix: sort attributes so class and style always run before class: and style: (closes #2982) 2024-09-16 20:26:51 -04:00
Greg Johnston
2bdacf636e Merge pull request #2974 from leptos-rs/more-stores
Improve efficiency of keyed stores
2024-09-14 21:49:27 -04:00
Greg Johnston
fc06980c60 feat: directly implement IntoIterator on keyed fields 2024-09-14 21:22:16 -04:00
Greg Johnston
550a3a4e6d perf: use FxHashMap for sets of keys 2024-09-14 21:20:09 -04:00
Greg Johnston
3310e7766b perf: only rebuild keys when we've touched the list itself, not when we edit a row 2024-09-14 18:33:59 -04:00
Greg Johnston
5ab865e89d example: fix so we remove by ID, not by id-as-index 2024-09-14 18:33:36 -04:00
Greg Johnston
f0c60f6ef6 Merge pull request #2871 from leptos-rs/more-stores
(draft) More work on stores
2024-09-14 17:34:13 -04:00
Greg Johnston
f3f685c923 chore: clean up Trigger <> Notify rename 2024-09-14 17:00:47 -04:00
Greg Johnston
3646bf31b0 example: only show date if in scheduling mode 2024-09-14 17:00:31 -04:00
Greg Johnston
b39895fa2d feat: remove outdated entries and recycle their keys 2024-09-14 17:00:11 -04:00
Greg Johnston
1fce8931ab fix: do not match incomplete static segments (closes #2916) (#2973) 2024-09-14 16:20:45 -04:00
Greg Johnston
6166f6edbd fix: ensure that we retain the correct sandoxed arena when spawning Futures (#2965) 2024-09-14 09:10:01 -04:00
Greg Johnston
dc9fbb0585 Merge branch 'main' into more-stores 2024-09-13 17:31:54 -04:00
Greg Johnston
d7b2f9d05b feat: keyed store fields, with keyed iteration 2024-09-13 17:21:09 -04:00
Greg Johnston
69c4090d32 example: update stores example to show enum matching 2024-09-13 12:12:05 -04:00
Greg Johnston
fff5fa3459 feat: add support for named and unnamed enum fields in Stores 2024-09-13 11:11:31 -04:00
Greg Johnston
e92b80c71e fix: tracking ArcStore should track, not trigger, its root trigger 2024-09-13 10:54:07 -04:00
Greg Johnston
8bb04ef248 chore: remove dead code 2024-09-13 10:53:27 -04:00
luoxiaozero
d7881ccfb5 fix: allow component to use span prop when tracing feature is enabled (#2969) 2024-09-13 09:35:59 -04:00
Álvaro Mondéjar Rubio
96a1f80daf tests: fix Effect doctests not being executed, and test-related issues (#2886) 2024-09-12 16:43:32 -04:00
Greg Johnston
a083b57260 fix: do not panic in automatic Track implementation if source is disposed (#2964) 2024-09-12 09:22:46 -04:00
Chris
4fa6660a3f doc: router::{Wildcard, Static, Param}Segment (#2949) 2024-09-11 21:02:02 -04:00
Baptiste
43f2ad7043 chore: add #[track_caller] to to_any_source (#2963) 2024-09-11 20:01:06 -04:00
Greg Johnston
2bf04072ea Merge pull request #2959 from leptos-rs/2956
fix: do not retrigger parent effect when Suspend's resources resolve (closes #2956)
2024-09-10 14:08:32 -04:00
Greg Johnston
efc6fc017d fix: forward subscribers for already-resolved Suspend during hydration 2024-09-10 06:59:47 -04:00
Greg Johnston
6cb10401df chore(ci): update list of core crates 2024-09-09 21:20:14 -04:00
Greg Johnston
346efd66f5 chore: remove unused cancellation logic for now 2024-09-09 21:19:55 -04:00
Greg Johnston
7c0889e873 fix: do not retrigger parent effect when Suspend's resources resolve (closes #2956) 2024-09-09 18:10:48 -04:00
Greg Johnston
bb40576bd5 Merge pull request #2955 from leptos-rs/fix-refetch
Fix refetch
2024-09-09 07:33:01 -04:00
Greg Johnston
6baf20275f fix: Resource::refetch() 2024-09-08 21:41:44 -04:00
Greg Johnston
5a57d48913 beta5 2024-09-08 19:40:32 -04:00
jk
73f0207a7d feat: add a copyable Trigger type (closes #2901) (#2939) 2024-09-08 19:39:40 -04:00
Greg Johnston
4e4fb8ab10 chore(examples): SsrMode is no longer clone (#2954) 2024-09-08 19:39:15 -04:00
Greg Johnston
b9cccc6b91 fix: revert change, making writes to children notify parents 2024-09-08 13:58:45 -04:00
Greg Johnston
d42163d888 fix: tracking a subfield should track its parents, as changing these can change it 2024-09-08 13:56:32 -04:00
Greg Johnston
2db3e4f4d8 chore: move Option tests into option module 2024-09-08 13:56:32 -04:00
Greg Johnston
45380a258a feat: add support for simple enums in stores 2024-09-08 13:56:32 -04:00
Greg Johnston
40292d0896 feat: add mapping over Option store fields 2024-09-08 13:56:32 -04:00
Greg Johnston
e8be9e31ff fix/change: do not trigger every parent when writing to a store subfield 2024-09-08 13:56:32 -04:00
Greg Johnston
3d0fdb1ab0 feat: add mapped unwrap for Option store fields 2024-09-08 13:56:32 -04:00
Tommy Yu
4dea1195e2 examples: include axum_js_ssr for discussion of integrating JS libraries (#2878) 2024-09-08 13:42:14 -04:00
Greg Johnston
92ea39ddac feat: version Resources to avoid race conditions (#2950) 2024-09-08 13:27:55 -04:00
Matt Kane
05e08166c4 chore: update suspense_test example to use Resource::map (#2877) 2024-09-07 20:56:30 -04:00
Greg Johnston
827cc0bdfa fix: ensure Resource always tracks its source, and does not double-run (#2948) 2024-09-07 18:57:31 -04:00
Greg Johnston
57bd343f4a fix: remove Owner from thread-local when it is ordinarily dropped, to ensure cleanup (closes #2942) (#2944) 2024-09-07 07:01:54 -04:00
Azriel Hoh
4a76aead68 Switch to proc-macro-error2 to address unmaintained security advisory. (#2934) 2024-09-06 17:24:03 -04:00
Greg Johnston
48c2148589 fix: untrack in the async block of a Resource (closes #2937) (#2941) 2024-09-06 17:23:40 -04:00
Greg Johnston
32bea69c28 fix: implement dry_resolve on Suspend so that resources created inside a Suspend are registered (closes #2917) (#2940) 2024-09-06 14:49:37 -04:00
Greg Johnston
f3c57f8bce Merge pull request #2929 from leptos-rs/relative-flat
feat: correctly support relative routing for `FlatRoutes`
2024-09-05 09:13:07 -04:00
Greg Johnston
000896b2f7 fix: allow clone: syntax on components (closes #2903) (#2928) 2024-09-04 20:44:37 -04:00
Greg Johnston
88004e5042 feat: correctly support relative routing for FlatRoutes 2024-09-04 20:43:59 -04:00
Greg Johnston
6001a93475 fix: correctly set ownership on view of ProtectedParentRoute (closes #2897) (#2927)
* fix: correctly set ownership on view of ProtectedParentRoute (closes #2897)

* chore: clippy false positive
2024-09-04 20:42:10 -04:00
Greg Johnston
4784b2ddab chore: remove dead code 2024-09-04 20:20:49 -04:00
Chris Biscardi
32b4cd008f Enable CDN support for assets (#2925)
* Enable CDN support for assets

This enables setting a root for a url, especially relating to generated .wasm, .js, and .css files.

This allows using a CDN for static assets.

* fix lint
2024-09-04 15:05:51 -07:00
Greg Johnston
823f8b51be Merge pull request #2924 from leptos-rs/2915 2024-09-04 11:15:11 -04:00
Greg Johnston
209743d6bc fix: ensure unique names for islands (closes #2915) 2024-09-04 08:53:03 -04:00
Greg Johnston
b93a88accc Merge pull request #2921 from leptos-rs/2920 2024-09-03 21:03:29 -04:00
Greg Johnston
dc2314d5e2 fix: ensure that LocalResource never creates a SendWrapper on the server 2024-09-03 20:40:12 -04:00
Greg Johnston
33aa676854 fix: ensure stability of hydration IDs on client and server, when using partial hydration (closes #2920) 2024-09-03 19:53:21 -04:00
Greg Johnston
4a3b3ffb8a fix: allow > 26 children for element children as well as top-level fragments (#2918) 2024-09-03 14:53:38 -04:00
Greg Johnston
ee5cbf1891 fix/change: remove replace and state props from <A/>, and add them via spreading instead (#2912) 2024-09-03 14:25:25 -04:00
mrvillage
8fcf3544a8 fix: trim spaces in file hashes (closes #2908) (#2913) 2024-09-03 08:51:03 -04:00
Greg Johnston
2b8e987cb8 fix: check whether we're on the server before adding window event listener (closes #2891) (#2910) 2024-09-02 09:11:07 -04:00
Greg Johnston
998165148b fix: automatically break children into tuples of a size the trait system can handle (closes #2863) (#2909) 2024-09-02 08:01:41 -04:00
Greg Johnston
c80eff1098 Merge pull request #2898 from leptos-rs/min-serialization
fix: only serialize Resources if we're in a part of the tree that needs hydration
2024-09-02 07:11:12 -04:00
Greg Johnston
cd8f2c2153 fix: correctly provide parent outlets when rebuilding from fewer to more nested routes (closes #2904) (#2906) 2024-09-02 07:08:15 -04:00
Greg Johnston
cb0abff2d5 fix: only serialize resource data if we're in a part of the tree being hydrated (i.e., in full hydration or in an island) 2024-08-31 16:18:06 -04:00
Greg Johnston
3b1b2e2dcc fix version for publish 2024-08-31 11:59:05 -04:00
Greg Johnston
7831e4ad05 next beta release 2024-08-31 11:59:05 -04:00
Greg Johnston
e7bb859cd9 feat: add support for static routing and incremental static regeneration (#2875) 2024-08-31 10:33:12 -04:00
Rakshith Ravi
9fc26e609c feat: allow for documentation and other attributes to fields in server fn (#2876) 2024-08-31 09:35:08 -04:00
mrvillage
4f1ee65e6c Add hash files support to 0.7 (#2894)
* Add support for JS and WASM file name hashing

* Add `<HashedStylesheet />`

* Update `<HashedStylesheet />`

* Whoops

* Fix formatting

* My IDE is just refusing to work apparently

* I hate my IDE

* Don't run the doctest

* Just remove the example, I don't know enough about doctest for this
2024-08-30 14:29:59 -07:00
Greg Johnston
ceff827a77 Merge pull request #2884 from leptos-rs/rstml-0.12
update to rstml and improve recoverability in attributes
2024-08-28 07:46:08 -04:00
Álvaro Mondéjar Rubio
a7db918775 docs: update main documentation of leptos crate (#2853) 2024-08-28 07:44:29 -04:00
Baptiste
be20ecd366 fix: implement Copy and Clone for HtmlElement without needing Rndr to be Clone/copy (#2889) 2024-08-28 07:25:51 -04:00
Greg Johnston
5790d8ad12 fix: derive various traits on Dom to make it easier to derive traits on structs that take a generic Renderer 2024-08-28 07:25:08 -04:00
luoxiaozero
7dc58e248c fix: compile attr:aria-* syntax (#2887) 2024-08-27 09:00:13 -07:00
Greg Johnston
7b03e63b23 docs: add note about curly braces 2024-08-26 21:00:45 -04:00
Greg Johnston
55fd7c6421 chore: clippy 2024-08-26 20:57:02 -04:00
Greg Johnston
ba1ea4c2bb do not error on unbraced 2024-08-26 20:56:23 -04:00
blorbb
6a4fc96835 rstml 0.12 and enforce braces in attribute values 2024-08-26 20:55:12 -04:00
Marc-Stefan Cassola
58476bb98e feat: variadic From for callbacks (#2873) 2024-08-26 20:47:11 -04:00
Oliver
88d4f14541 added attributes to source element (#2883)
Co-authored-by: Oliver Nordh <oliver.nordh@proton.me>
2024-08-26 19:27:01 -04:00
niklass-l
6bba233ba7 Add support for postcard codec in server_fn (#2879)
* Add support for postcard codec

* Add postcard feature set exclusions

* Add postcard server fn encoding example
2024-08-26 13:58:23 -07:00
Greg Johnston
1d99764740 Merge pull request #2870 from leptos-rs/dependabot/github_actions/tj-actions/changed-files-45
chore(deps): bump tj-actions/changed-files from 44 to 45
2024-08-23 17:36:21 -04:00
Álvaro Mondéjar Rubio
53cc479c14 chore: set tracing as feature for all crates (#2843) 2024-08-23 17:34:05 -04:00
Greg Johnston
d3707d9b88 Merge pull request #2865 from mkane0814/feat/add-map-and-then-for-resource
feat: add Resouce::map and Resouce::and_then
2024-08-23 17:30:57 -04:00
Marc-Stefan Cassola
1df4076fd2 updated codee version (#2874) 2024-08-23 13:50:55 -07:00
dependabot[bot]
28337bb6c9 chore(deps): bump tj-actions/changed-files from 44 to 45
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 45.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v44...v45)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-21 18:22:38 +00:00
Greg Johnston
c5dea52e69 chore: restore Playwright tests for counters example (#2864) 2024-08-20 13:38:22 -04:00
Greg Johnston
d5096ff2e6 feat: allow including a view from an external file (closes #2182) (#2862) 2024-08-20 09:00:40 -04:00
Matt Kane
84734f1110 feat: add ArcResource::and_then 2024-08-20 07:41:55 -05:00
Matt Kane
7094308287 feat: add Resource::and_then 2024-08-20 00:06:56 -05:00
Matt Kane
3b88c8ccd2 feat: add Resource::map 2024-08-19 23:38:36 -05:00
Greg Johnston
b932bd5e04 Merge pull request #2859 from leptos-rs/2743
Add `Resource::refetch()` and `Resource::update()`
2024-08-19 07:23:41 -04:00
Greg Johnston
a0638b786c feat: allow mutating AsyncDerived and therefore Resources (closes #2743) 2024-08-18 17:31:06 -04:00
Greg Johnston
1033133d3a feat: add Resource::refetch() 2024-08-18 17:05:06 -04:00
Matt Kane
ba40560ad7 added ToHref impl for Rc<str> (#2857) 2024-08-18 16:52:42 -04:00
Tomer Hanochi
78dc8b4410 fix: make any_spawner optional and dependent on the reactive_graph feature (#2858) 2024-08-18 16:32:20 -04:00
Greg Johnston
c6bf525270 chore: version bump for tachys and meta bug 2024-08-18 16:25:53 -04:00
Chris
fcdfd617f5 fix: redundant spans (#2836)
Per https://docs.rs/quote/latest/quote/macro.quote.html#hygiene
regarding token hygiene.

> Any interpolated tokens preserve the Span information provided by their
> `ToTokens` implementation.

In many instances, the procedural macros are spanning tokens with their
own span redundantly.
2024-08-16 20:25:56 -04:00
Álvaro Mondéjar Rubio
d9c8d4ff66 fix: #[component] macro attributes propagation (#2835) 2024-08-16 20:21:46 -04:00
Chris
621f112f4c docs: leptos_router_macro::path (#2841) 2024-08-16 20:19:38 -04:00
Greg Johnston
cfe2341dec fix: when in browser, resolve relative links relative to current origin (closes #2806) (#2846) 2024-08-16 20:18:59 -04:00
Greg Johnston
5ed2cc9596 docs: provide an error when you try to create identically-named attributes (closes #1692) (#2849) 2024-08-16 20:18:43 -04:00
Greg Johnston
47b07b0143 fix: support navigating to other origins with use_navigate (#2847) 2024-08-16 20:18:28 -04:00
Greg Johnston
0793d56648 Merge pull request #2851 from leptos-rs/2850
Fix nested routing/related issues
2024-08-16 20:17:42 -04:00
Greg Johnston
2dde9738b2 fix: unmount meta tags when state is dropped, because parents won't unmount them (closes #2832) 2024-08-16 17:51:37 -04:00
Greg Johnston
1b276e1e02 Revert "fix: run unmount logic for element children (closes #2832) (#2834)"
This reverts commit 951f4a73ee.
2024-08-16 17:43:55 -04:00
Greg Johnston
9771619b0d tests: add regression test for #2569 (#2848) 2024-08-16 16:53:00 -04:00
Greg Johnston
382a36406c chore: add crate info to router macro 2024-08-14 20:51:29 -04:00
Greg Johnston
a898d3f2f7 beta2 release 2024-08-14 20:13:14 -04:00
Greg Johnston
951f4a73ee fix: run unmount logic for element children (closes #2832) (#2834) 2024-08-14 19:59:54 -04:00
Greg Johnston
2a26a648ba examples: fix/update GTK example, and remove web parallels (#2839) 2024-08-14 19:47:33 -04:00
Saber Haj Rabiee
66d7cb5d12 feat: add memo! macro (closes #2708) (#2826) 2024-08-14 06:14:17 -07:00
Chris
aa49ad760b feat: StoredValue::default (#2818) 2024-08-13 21:20:10 -04:00
Álvaro Mondéjar Rubio
3469e9335c Provide several deprecated functions (#2831) 2024-08-13 21:19:52 -04:00
benwis
62408d9202 Run cargo fmt 2024-08-13 17:10:58 -07:00
Saber Haj Rabiee
db1c15f4e4 fix: fix web-sys warnings in server_fn (#2828)
* fix: fix web-sys warnings in server_fn

* fix: update web-sys to 0.3.70

* fix: web-sys clipboard api in 0.3.70
2024-08-13 15:46:34 -07:00
Álvaro Mondéjar Rubio
3f751551a8 feat: provide deprecated create_memo (#2825) 2024-08-13 15:43:17 -07:00
Álvaro Mondéjar Rubio
2470036f57 feat: provide deprecated create_rw_signal (#2824) 2024-08-13 15:42:47 -07:00
Saber Haj Rabiee
e01dfbf497 fix: update to wasm-bindgen 0.2.93 (#2827) 2024-08-13 15:21:57 -07:00
Saber Haj Rabiee
49c1661f92 fix: exclude projects from workspace (#2819) 2024-08-13 14:51:59 -07:00
Chris
b9dfd9a5ae docs: StoredValue methods and examples for 0.7 (#2817) 2024-08-13 14:38:07 -07:00
Saber Haj Rabiee
17a150b3bf fix: increase MSRV to 1.76 (#2829) 2024-08-13 14:31:22 -07:00
Rakshith Ravi
c860f524ad Add 0.7 warning to README (#2823) 2024-08-13 10:42:13 -04:00
mahmoud-eltahawy
20af4928b2 chore: use workspace edition for examples and crates (#2816) 2024-08-12 19:25:47 -04:00
Greg Johnston
7b62ad44d2 feat: restore hot reloading for 0.7 (#2775) 2024-08-12 16:11:30 -04:00
Greg Johnston
5657abc07d Merge pull request #2809 from leptos-rs/callback
Callback changes
2024-08-12 16:11:10 -04:00
Greg Johnston
9fc351ceac chore: remove unused import 2024-08-12 08:09:12 -04:00
Greg Johnston
893d47f1c5 feat: add missing server fn redirect hook to router (#2815) 2024-08-12 08:07:45 -04:00
Greg Johnston
3c2a2304e4 change: rename Callable::call() to Callable::run() to avoid warnings about name collision with Fn() 2024-08-12 07:48:22 -04:00
Greg Johnston
3de4b7b982 fix: impl Copy for UnsyncCallback 2024-08-12 07:45:29 -04:00
Greg Johnston
36957cb569 change: impl From<F: Fn> for all callbacks, rather than implement Fn traits on them in nightly (closes #2041, #2142) 2024-08-12 07:45:28 -04:00
Greg Johnston
27dbadb7d2 fix: allow generic parameters for directive functions (closes #2808) (#2812) 2024-08-11 20:37:57 -04:00
Greg Johnston
84590b98ed Merge pull request #2814 from leptos-rs/2719
Provide parent route params to children
2024-08-11 18:36:15 -04:00
Greg Johnston
0222182286 fix: provide parent params to children (closes #2719) 2024-08-11 17:20:25 -04:00
Greg Johnston
7ed4d08dab feat: From<ArcRwSignal<_>> for ArcMemo<_> 2024-08-11 17:19:35 -04:00
Greg Johnston
4fa2e58551 fix: properly resolve nested relative routes with multiple parents (closes #2720) (#2797) 2024-08-11 13:21:22 -04:00
Greg Johnston
5fe58369f5 fix: only implement global attributes on HtmlElement, not on all renderable types, to improve autocomplete (#2811) 2024-08-11 13:21:08 -04:00
Tommy Yu
10860ebb1e doc: more details on how redirect works (closes #2789) (#2796) 2024-08-11 07:11:05 -04:00
Greg Johnston
887eb99cf6 chore: cargo fmt 2024-08-10 20:31:28 -04:00
Tommy Yu
9f99571b28 fix: a more robust aria-current="page" algorithm for A (#2770) 2024-08-10 20:31:10 -04:00
Saber Haj Rabiee
b3e2040ec9 chore: upgrade dependencies (#2765) 2024-08-10 20:01:41 -04:00
Greg Johnston
693861434c Merge pull request #2799 from leptos-rs/2798
fix: ProtectedRoute calling view multiple times during server rendering
2024-08-09 10:27:10 -04:00
Greg Johnston
d1248d3faf fix: hydration for attributes with Option<_> (closes #2793) (#2794) 2024-08-08 14:11:26 -04:00
Greg Johnston
f1fae63064 fix: only run Suspense on the condition in ProtectedRoute (closes #2798) 2024-08-08 13:57:58 -04:00
Greg Johnston
f7053ac960 feat: add Unsuspend as a way to opt out of Suspense in a section of the tree 2024-08-08 13:56:02 -04:00
Greg Johnston
8670365594 fix: support complex struct form submits without JS (closes #2790) (#2792) 2024-08-07 11:10:59 -04:00
Alicia Garcia-Raboso
e0cc6fd7b9 fix: correctly report whether a stored_value is disposed (#2791) 2024-08-07 09:19:01 -04:00
Greg Johnston
84457b45ff fix: introduce more intuitive/useful behavior for new_with_initial (closes #2787) (#2788) 2024-08-07 09:14:22 -04:00
Greg Johnston
8c959d3e24 fix: correctly dispose of original RouteContext, allowing Owner to be dropped (closes #2785) (#2786) 2024-08-07 09:14:10 -04:00
Greg Johnston
288da232ac Merge pull request #2782 from leptos-rs/dependabot/github_actions/pnpm/action-setup-4
chore(deps): bump pnpm/action-setup from 3 to 4
2024-08-06 10:26:01 -04:00
Greg Johnston
ef52e8620b Merge pull request #2781 from leptos-rs/dependabot/github_actions/tj-actions/changed-files-44
chore(deps): bump tj-actions/changed-files from 41 to 44
2024-08-06 10:25:51 -04:00
Greg Johnston
a8c5ce2722 chore(ci): temporarily disable semver checks while main branch is itself a breaking change (#2783) 2024-08-06 09:51:21 -04:00
dependabot[bot]
a40ba9a39e chore(deps): bump pnpm/action-setup from 3 to 4
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 3 to 4.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v3...v4)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-06 01:32:44 +00:00
dependabot[bot]
83a110fb85 chore(deps): bump tj-actions/changed-files from 41 to 44
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 41 to 44.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v41...v44)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-06 01:32:42 +00:00
Saber Haj Rabiee
5deedf721e feat: add dependabot to get dep's update alerts and PRs automatically (#2768) 2024-08-05 21:23:45 -04:00
Álvaro Mondéjar Rubio
0ae67cf122 chore: clean up examples (#2779) 2024-08-05 21:23:17 -04:00
martin frances
97e0222061 chore: cargo outdated, bump rustc-hash to version 2.0.0, no additional fixup needed. (#2778) 2024-08-05 20:53:16 -04:00
luoxiaozero
a7aedee4fd feat: adds ForEnumerate component that gives reactive access to current index in list (#2773) 2024-08-05 20:52:18 -04:00
Corvus
f180941b7b feat: complete img and video attributes set (#2774) 2024-08-05 20:38:20 -04:00
Marc-Stefan Cassola
83cb3cb764 feat: allow effect functions without parameters (#2776) 2024-08-05 20:36:47 -04:00
Corvus
f174688974 feat: provide deprecated create_node_ref (#2777) 2024-08-05 20:33:58 -04:00
Greg Johnston
1f4c410f78 Merge pull request #2607 from leptos-rs/leptos_0.7
(draft) Leptos 0.7
2024-08-04 11:45:22 -04:00
Corvus
3dbedfc871 feat: reintroduce custom events (#2762) 2024-08-04 08:21:10 -04:00
luoxiaozero
026152d20e fix: correctly rebuild reactive attributes to avoid stale signals (#2763) 2024-08-04 08:16:02 -04:00
luoxiaozero
c70009243a fix: allow svg elements to use inner_html (#2764) 2024-08-04 08:14:22 -04:00
Greg Johnston
dcdad73476 chore: fmt 2024-08-03 21:55:07 -04:00
Corvus
42a8e49e1a feat: provide deprecated watch function (#2761) 2024-08-03 21:24:46 -04:00
Greg Johnston
9ba894764e chore: fmt 2024-08-03 11:52:21 -04:00
Greg Johnston
1d97494e19 fix: update syntax now that dispatch returns something 2024-08-03 11:52:09 -04:00
Greg Johnston
982bfd8011 feat: allow aborting dispatched actions (closes #2746) 2024-08-03 10:59:54 -04:00
Greg Johnston
a0ad927097 fix: generated tests should not use old APIs 2024-08-03 10:48:11 -04:00
Greg Johnston
4845459511 chore: update tests 2024-08-03 10:11:29 -04:00
Greg Johnston
54e4205541 chore: update tests 2024-08-02 11:16:35 -04:00
Greg Johnston
25f0186098 chore: update tests 2024-08-02 10:29:48 -04:00
Greg Johnston
00fb8f29d3 fix: do not pass SendWrappers through Suspense (closes #2756) 2024-08-02 10:27:35 -04:00
Greg Johnston
82ea4eb7ce chore: fix ssr tests 2024-08-02 09:40:18 -04:00
Greg Johnston
34382c0c23 chore: fix ssr tests 2024-08-02 09:24:51 -04:00
Greg Johnston
605e4b1eec chore: update examples and doctests 2024-08-02 09:07:23 -04:00
Greg Johnston
71ca02a432 chore: clippy 2024-08-01 22:25:16 -04:00
Greg Johnston
ac751dd0d3 chore(ci): update nightly 2024-08-01 21:28:19 -04:00
Greg Johnston
114df8797c chore: clippy 2024-08-01 21:25:35 -04:00
Greg Johnston
35b457aa82 chore: update examples and doctests 2024-08-01 20:59:39 -04:00
Greg Johnston
c43b71d3fa chore: update examples and doctests 2024-08-01 20:45:40 -04:00
Greg Johnston
5ad17d6b6c fix: correct thread-local behavior for Effects (closes #2754) 2024-08-01 19:43:10 -04:00
Greg Johnston
805be42f7a chore: fix doctest 2024-08-01 19:43:10 -04:00
Greg Johnston
bb63a1521e chore: update tests and doctests 2024-08-01 19:43:10 -04:00
Greg Johnston
05cd1bc6f0 chore: proper feature gating for imports 2024-08-01 19:43:10 -04:00
Greg Johnston
84ac64284c chore: update tests and doctests 2024-08-01 19:43:10 -04:00
Greg Johnston
8beb988ecc chore: update tests and doctests 2024-08-01 19:43:10 -04:00
Greg Johnston
05999069b7 feat: add create_slice functions 2024-08-01 19:43:10 -04:00
Greg Johnston
dbb4c79d9c chore: remove unused features 2024-08-01 19:43:10 -04:00
Greg Johnston
d1d6126259 chore: add makefile for CI 2024-08-01 19:43:10 -04:00
Greg Johnston
0e979a0767 chore: remove dead code from leptos_dom (now found in tachys) 2024-08-01 19:43:10 -04:00
Greg Johnston
3a4ad07a91 chore: remove unused dependencies 2024-08-01 19:43:10 -04:00
Greg Johnston
f2f35cd785 chore: fix imports in tests 2024-08-01 19:43:10 -04:00
Greg Johnston
c953432659 chore: fmt 2024-08-01 19:43:10 -04:00
Greg Johnston
27f2e60d16 chore: clean up unused imports in tests 2024-08-01 19:43:10 -04:00
Greg Johnston
9330cf23b1 fix: set default storage type for SignalTypes 2024-08-01 19:43:10 -04:00
Greg Johnston
04f5207457 fix: be ready to complete navigation immediately 2024-08-01 19:43:09 -04:00
Greg Johnston
c88409a333 fix: update reactive views for new requirements 2024-08-01 19:43:09 -04:00
Greg Johnston
a2d3d9431c feat: support memos with !Send values 2024-08-01 19:43:09 -04:00
Greg Johnston
213365e4e9 chore: clippy 2024-08-01 19:43:09 -04:00
Greg Johnston
ab3e94dafa chore: clippy 2024-08-01 19:43:09 -04:00
Greg Johnston
3e05b5bcb4 feat: support class = in view macro 2024-08-01 19:43:09 -04:00
Greg Johnston
632ce0f401 fix merge issues 2024-08-01 19:43:09 -04:00
Greg Johnston
93c893f4b3 fix: use correct Request type in Actix extractor 2024-08-01 19:43:09 -04:00
Greg Johnston
4fa72a94fb feat: allow reusing the same endpoint for server functions with different HTTP verbs in their input encodings 2024-08-01 19:43:09 -04:00
Greg Johnston
24775fb59b fix: properly handle islands used in the body of other islands (closes #2725) 2024-08-01 19:43:09 -04:00
Greg Johnston
6c749f5e24 fix: provide a hydration context during route generation 2024-08-01 19:43:09 -04:00
Marc-Stefan Cassola
c22f20ac28 feat: add Effect::watch (#2732) 2024-08-01 19:43:09 -04:00
Greg Johnston
11011c2bda fix: correct async resolution for islands (closes #2734) 2024-08-01 19:43:09 -04:00
Greg Johnston
a51faea9a9 fix: abort when leaving *this* owner, but don't force it if already complete 2024-08-01 19:43:09 -04:00
Greg Johnston
dcc43e574b fix: correctly handle Action abort if it has already completed (closes #2740) 2024-08-01 19:43:09 -04:00
Greg Johnston
6cc0604497 fix: no longer necessary to 'seal' ErrorBoundary (closes #2738) 2024-08-01 19:43:09 -04:00
Chris
8c375534bb fix: leptos_router_macro::path into public api (#2737) 2024-08-01 19:43:09 -04:00
Greg Johnston
f2d6375d93 fix: never resolve LocalResource synchronously (closes #2736) 2024-08-01 19:43:09 -04:00
Greg Johnston
5fb80aaa40 fix: cancel action when original owner, not current owner, is cleaned up (closes #2739) 2024-08-01 19:43:09 -04:00
Greg Johnston
29b0dca1d8 fix: allow Suspense to remount before rebuilding (closes #2721) 2024-08-01 19:43:09 -04:00
Greg Johnston
a6a65ba562 fix: release borrow on shared context when hydrating island (closes #2733) 2024-08-01 19:43:09 -04:00
Greg Johnston
260c624461 fix: serializing island props (closes #2730) 2024-08-01 19:43:09 -04:00
Greg Johnston
0f50aced26 fix: tracking/notifications for AsyncDerived if they start with initial values, and prevent over-notification (closes #2716) 2024-08-01 19:43:09 -04:00
Greg Johnston
1aa2752842 fix: if island is not entry point, update hydration cursor correctly to include island node (closes #2724) 2024-08-01 19:43:09 -04:00
Greg Johnston
b92bfa4ea7 docs: suppress warning about wrong client-side mode after initial call, for things like Portal (closes #2725) 2024-08-01 19:43:09 -04:00
Greg Johnston
30cf1167f2 fix: correct re-exports for islands with props (closes #2723) 2024-08-01 19:43:09 -04:00
Greg Johnston
1c05389707 fix: prevent LocalResource from spawning a local task on the server, when it should only run on the client (closes #2717) 2024-08-01 19:43:09 -04:00
Greg Johnston
1534dd5261 fix: CSR <ErrorBoundary/> 2024-08-01 19:43:09 -04:00
Greg Johnston
8b9685e01d fix: throw_error version 2024-08-01 19:43:09 -04:00
Greg Johnston
d9b590b8e0 fix: unique IDs and correct hydration for <ErrorBoundary/> (closes #2704) 2024-08-01 19:43:09 -04:00
Greg Johnston
25bfc27544 fix: set <Title/> text and formatter in context during client-side rendering (closes #2715) 2024-08-01 19:43:09 -04:00
Greg Johnston
89bbdc58af feat: patch reactive stores in place, only notifying on changed fields 2024-08-01 19:43:09 -04:00
Greg Johnston
4fb00e29d6 chore: remove unused imports 2024-08-01 19:43:09 -04:00
Greg Johnston
54401c6f69 beta version 2024-08-01 19:43:09 -04:00
Greg Johnston
6a705e2a21 chore: clippy 2024-08-01 19:43:09 -04:00
Greg Johnston
43421c56d5 example: use a local signal for the input 2024-08-01 19:43:09 -04:00
Greg Johnston
4c4d3dcfa3 feat: mark branches in AnyView 2024-08-01 19:43:09 -04:00
Greg Johnston
55053da00c chore: clippy 2024-08-01 19:43:09 -04:00
Greg Johnston
be83b5f27e chore: remove unused imports 2024-08-01 19:43:09 -04:00
Greg Johnston
a4ce79769a fix: improve type inference for the default threadsafe signal case 2024-08-01 19:43:09 -04:00
Greg Johnston
e3f64188c2 chore: clippy 2024-08-01 19:43:09 -04:00
Greg Johnston
f7abe727d9 fix: add missing imports 2024-08-01 19:43:09 -04:00
Greg Johnston
eb29d84169 docs: fix cfg for docsrs 2024-08-01 19:43:09 -04:00
Greg Johnston
200047a8bc chore: remove unnecessary default generics 2024-08-01 19:43:09 -04:00
Greg Johnston
634ac1c4a3 chore: clippy and fmt 2024-08-01 19:43:09 -04:00
Saber Haj Rabiee
efe832e39a fix: hackernews_js_fetch example for leptos_0.7 (#2678) 2024-08-01 19:43:09 -04:00
Greg Johnston
1f2b13a976 feat: allow !Send signals 2024-08-01 19:42:51 -04:00
Greg Johnston
d4ec5e187b fix: rename nightly feature for const generic &'static str (d0c11bf6e3\#diff-7b65e42e2b87910c94950caf7f0687fda2f9f98f311099404f5c4afb4a36e50c) 2024-08-01 19:42:51 -04:00
Greg Johnston
4fe7fe725f chore: remove pub field in Suspend so that Suspend::new() must be used 2024-08-01 19:42:51 -04:00
Greg Johnston
a1ca8549a1 chore: fmt 2024-08-01 19:42:51 -04:00
Greg Johnston
e7a8067f9b fix: only create Future once initially, and poll it twice, rather than creating it twice 2024-08-01 19:42:51 -04:00
Greg Johnston
6be090079f chore: fmt 2024-08-01 19:42:51 -04:00
Greg Johnston
8635887ca7 feat: optional branch-marking in HTML to support initial work on client-side islands routing 2024-08-01 19:42:51 -04:00
Corvus
e3482b433b feat: reintroduce queue_microtask (#2703) 2024-08-01 19:42:51 -04:00
Greg Johnston
e6c2f8c614 fix: allow one-element tuples for route matching 2024-08-01 19:42:51 -04:00
Greg Johnston
28fcfe4a46 example: use path! macro in router example 2024-08-01 19:42:51 -04:00
Greg Johnston
75336bc265 fix: add HTML global on___ attributes 2024-08-01 19:42:51 -04:00
boyswan
f4f129caaf feat: add path! macro in router to parse string paths into tuples (#2694) 2024-08-01 19:42:51 -04:00
mahmoud-eltahawy
873aec5787 feat: allow using enums for StaticSegment by implementing AsPath (#2685) 2024-08-01 19:42:51 -04:00
Greg Johnston
a2385e4c42 fix: set None observer properly in ScopedFuture 2024-08-01 19:42:51 -04:00
Greg Johnston
d24f97b59f fix: remove unnecessary untrack in Show 2024-08-01 19:42:51 -04:00
Greg Johnston
51f368c5c5 fix: Suspend::new() in router 2024-08-01 19:42:51 -04:00
Greg Johnston
4107203da2 examples: update to Suspend::new() 2024-08-01 19:42:51 -04:00
Greg Johnston
efb699a319 docs: improved warning location 2024-08-01 19:42:51 -04:00
Greg Johnston
93e6456e19 fix: require Suspend::new() to ensure the Future is properly scoped at creation time, not at render time 2024-08-01 19:42:51 -04:00
Greg Johnston
b24ae7a5e3 fix: explicitly untrack the children of <Show/> 2024-08-01 19:42:51 -04:00
Greg Johnston
bf8d2e079c fix: custom elements should support any attribute names 2024-08-01 19:42:50 -04:00
Greg Johnston
7752ab78e3 fix: custom elements SSR 2024-08-01 19:42:50 -04:00
Greg Johnston
64bc2580ff docs: add tachys docs 2024-08-01 19:42:50 -04:00
Greg Johnston
ddb596feb5 chore: start with a default sandbox, to avoid panics in tests 2024-08-01 19:42:50 -04:00
Greg Johnston
dac4589194 docs: finish reactive graph docs for 0.7 2024-08-01 19:42:50 -04:00
Greg Johnston
8f0a8e05b4 docs: porting docs from 0.6 to 0.7 2024-08-01 19:42:50 -04:00
Greg Johnston
05d01141c5 chore: remove unused AsyncState 2024-08-01 19:42:50 -04:00
Bruno De Simone
66d6038f2d add allow too_many_arguments (#2684) 2024-08-01 19:42:50 -04:00
Greg Johnston
3b09312e1a chore: clippy 2024-08-01 19:42:50 -04:00
Greg Johnston
62cb361031 chore: clippy 2024-08-01 19:42:50 -04:00
Greg Johnston
04c67cb8b6 chore: clear warnings 2024-08-01 19:42:50 -04:00
Greg Johnston
efd060c955 feat: Suspend on style: and class: 2024-08-01 19:42:50 -04:00
Greg Johnston
6290c42159 fix: proper building of paths for nested fields 2024-08-01 19:42:50 -04:00
Greg Johnston
0a89f151be feat: type-erased store Field structs 2024-08-01 19:42:50 -04:00
Greg Johnston
c72c2f4803 fix: allow creating resources inside Suspense 2024-08-01 19:42:50 -04:00
Greg Johnston
c771ab7e71 examples: revert changes to counter 2024-08-01 19:42:50 -04:00
Bruno De Simone
2c4f11b238 remove FromRef implementation from LeptosRoutes axum impl (#2670) 2024-08-01 19:42:50 -04:00
luoxiaozero
12a9e06c5e feat: additional ARIA attributes (#2677) 2024-08-01 19:42:50 -04:00
Greg Johnston
3515469835 feat: iteration over reactive store list 2024-08-01 19:42:50 -04:00
Greg Johnston
e5c159f7a5 feat: add arena-allocated/Copy Store 2024-08-01 19:42:50 -04:00
Greg Johnston
6590749956 docs: initial work on porting docs from 0.6 to 0.7 2024-08-01 19:42:50 -04:00
Greg Johnston
db8f5e4899 feat: initial work on reactive stores 2024-08-01 19:42:50 -04:00
Greg Johnston
6ca3639c3e fix: improved API for unsync actions that doesn't require SendWrapper on input 2024-08-01 19:42:50 -04:00
Greg Johnston
37db7b5d0a chore: leptosfmt 2024-08-01 19:42:50 -04:00
Greg Johnston
8ac1564b90 fix: properly handle errors in streaming body responses 2024-08-01 19:42:50 -04:00
Greg Johnston
e2721d53bd fix: invalid p/ul relationship causing hydration issue 2024-08-01 19:42:50 -04:00
Saber Haj Rabiee
e1f3be6416 chore: cargo fmt (#2672) 2024-08-01 19:42:50 -04:00
Greg Johnston
9536480739 feat: use codee for shared ser-de codexes with leptos-use (and more possibilities in future) 2024-08-01 19:42:50 -04:00
Greg Johnston
5d3a1752c4 chore: remove unused dependencies 2024-08-01 19:42:50 -04:00
Greg Johnston
4b539b524b fix: was disposing of Suspense Owner too early 2024-08-01 19:42:50 -04:00
Greg Johnston
67fe4cc540 fix: rebuilding NodeRef 2024-08-01 19:42:50 -04:00
Greg Johnston
fa731d5018 feat: top-level Suspend without Suspense 2024-08-01 19:42:50 -04:00
Greg Johnston
ccf6703274 chore: clippy and clean up unused functions 2024-08-01 19:42:50 -04:00
Greg Johnston
504c958001 docs: update syntax for Html/Body 2024-08-01 19:42:50 -04:00
Greg Johnston
f7b16b726b feat: correct HTML rendering for spread attributes on <Body/> and <Html/> 2024-08-01 19:42:50 -04:00
Greg Johnston
e9c7b50dfd feat: attributes on body and html 2024-08-01 19:42:50 -04:00
Greg Johnston
208ab97867 feat: move to a channel-based implementation for meta 2024-08-01 19:42:50 -04:00
Greg Johnston
4a0f173bb5 feat: support Suspend in attributes 2024-08-01 19:42:50 -04:00
Greg Johnston
0cf3113812 feat: local resources with .await 2024-08-01 19:42:50 -04:00
Greg Johnston
87f9fa23d5 chore: cfg warnings 2024-08-01 19:42:50 -04:00
Greg Johnston
746bf8e453 fix: MaybeProp None case 2024-08-01 19:42:50 -04:00
Greg Johnston
8b9bcffbb9 reexport SVG and MathML element types 2024-08-01 19:42:50 -04:00
Greg Johnston
dc80e387e3 router alpha 3 2024-08-01 19:42:50 -04:00
Greg Johnston
2006eca1a0 Form component in 0.7 2024-08-01 19:42:50 -04:00
Greg Johnston
1dae77d6b4 fix: don't break Routes SSR now that it uses Suspend 2024-08-01 19:42:50 -04:00
Alicia Garcia-Raboso
2f58191a56 Implement Default trait for signals with a parameter that also implements Default (#2662)
Co-authored-by: alicia.garcia.raboso <alicia.garcia.raboso@bbva.com>
2024-08-01 19:42:50 -04:00
Greg Johnston
a68653b385 feat: automatically replace Suspense blocks if they are still waiting to be flushed, without JS (replaces PartiallyBlocked) 2024-08-01 19:42:50 -04:00
Greg Johnston
d7ca969848 blocking resources 2024-08-01 19:42:50 -04:00
Greg Johnston
fd48a61eef macro alpha 2 2024-08-01 19:42:50 -04:00
Greg Johnston
52a3f84de5 router alpha 2 2024-08-01 19:42:50 -04:00
Luke Naylor
f8283f4674 Add missing 'form' attribute for <mo> (#2660)
This attribute seems to be missing in the attribute
table on Mozilla Docs, however does appear in the
compatibility table lower down.
This attribute is also frequently used by temml,
a common generator for mathml content.
2024-08-01 19:42:50 -04:00
Greg Johnston
989f2989fa allow Outlet to be called multiple times 2024-08-01 19:42:50 -04:00
Greg Johnston
33a3708f91 fix: prevent panicking if conditionally rendering Outlet 2024-08-01 19:42:50 -04:00
Greg Johnston
4eea1f046d remove log 2024-08-01 19:42:50 -04:00
Greg Johnston
8f46288973 fix: ensure correct ownership chain when passing views through Outlet 2024-08-01 19:42:50 -04:00
Greg Johnston
059c8abd2f chore: clippy 2024-08-01 19:42:50 -04:00
Greg Johnston
6885777c75 support MaybeSignal in view 2024-08-01 19:42:50 -04:00
Kajetan Welc
ddc7abf081 fix: impl Copy for Callback (#2658) 2024-08-01 19:42:50 -04:00
Greg Johnston
180511e9bb fix: update imports and methods 2024-08-01 19:42:50 -04:00
Greg Johnston
381ff8a7b0 fix: trait import 2024-08-01 19:42:50 -04:00
Greg Johnston
3ed1ad7b7f impl From<T> for (Arc)Signal<T> 2024-08-01 19:42:50 -04:00
Greg Johnston
2ccf5e99a9 Revert "lazy Future construction for AsyncDerived"
This reverts commit 9e84e1f57c.
2024-08-01 19:42:50 -04:00
Greg Johnston
055701ebf6 fix: <option> struct generation 2024-08-01 19:42:50 -04:00
Greg Johnston
88af893703 fix: <option> struct generation 2024-08-01 19:42:50 -04:00
Lucas Åström
ce4fe632a2 Destructuring let (0.7) (#2655)
* Use `let()` syntax for bindings

This lets users use destructuring when binding more complex values, and we also get better IDE support.

* Update rstml
2024-08-01 19:42:50 -04:00
Greg Johnston
c76208aad0 fix: nonexistent feature 2024-08-01 19:42:50 -04:00
Greg Johnston
514c51ca30 fix: rebuilding AnyView 2024-08-01 19:42:50 -04:00
Greg Johnston
7e3781b5dd support wasm-only 2024-08-01 19:42:50 -04:00
Greg Johnston
97dc3cc2e5 support wasm-only 2024-08-01 19:42:50 -04:00
Greg Johnston
61e51cbe1c support wasm-only 2024-08-01 19:42:50 -04:00
Greg Johnston
efa6d603f9 any_spawner tick version 2024-08-01 19:42:50 -04:00
Greg Johnston
da045f7358 un-break circular dependency 2024-08-01 19:42:50 -04:00
Greg Johnston
8502745036 chore: update test output 2024-08-01 19:42:50 -04:00
Greg Johnston
0a5e6fd85a chore: unused import 2024-08-01 19:42:50 -04:00
Greg Johnston
64fc6cd514 restore fallback for compressed version 2024-08-01 19:42:50 -04:00
Greg Johnston
a2d8fde8cf docs: working on memo docs 2024-08-01 19:42:50 -04:00
Greg Johnston
44eae4c2ed 0.7.0-alpha 2024-08-01 19:42:50 -04:00
Greg Johnston
38d51b01d7 feat: support reactive and asynchronous ProtectedRoute conditions 2024-08-01 19:42:49 -04:00
Greg Johnston
61876dff10 fix: correct For behavior when mounting with siblings, and when clearing 2024-08-01 19:42:49 -04:00
Ben Wishovich
c676cf921d Make get_configuration sync (#2647)
* Made get_configuraiton sync

* Update examples
2024-08-01 19:42:49 -04:00
Greg Johnston
fc59cdaf61 examples: update directives tests 2024-08-01 19:42:49 -04:00
Greg Johnston
081f4ec550 chore: cargo fmt 2024-08-01 19:42:49 -04:00
Greg Johnston
598c59b9c2 make RemoveEventHandler a concrete type 2024-08-01 19:42:49 -04:00
Greg Johnston
9de6c5bb4a feat: add ElementExt to give access to the same view APIs at runtime that we do at compile time 2024-08-01 19:42:49 -04:00
Greg Johnston
f65eaec9ba feat: add ElementExt to give access to the same view APIs at runtime that we do at compile time 2024-08-01 19:42:49 -04:00
Greg Johnston
95756aa2f7 chore: cargo fmt 2024-08-01 19:42:49 -04:00
Greg Johnston
fd121fd8c1 docs: warn on unused RenderEffect 2024-08-01 19:42:49 -04:00
Greg Johnston
c1877354f0 chore: missing Debug implementations 2024-08-01 19:42:49 -04:00
Greg Johnston
be92dc56aa chore: suppress unnecessary .into() warning 2024-08-01 19:42:49 -04:00
Greg Johnston
165a593b32 cargo fmt 2024-08-01 19:42:49 -04:00
Greg Johnston
18b33c7606 updated directives example 2024-08-01 19:42:49 -04:00
brofrain
d2ee093132 fix: update HtmlViewState & BodyViewState as well 2024-08-01 19:42:49 -04:00
Kajetan Welc
83e0438527 fix: do not accidentally mount things before meta tags in the <head> when updating the DOM v2 2024-08-01 19:42:49 -04:00
Greg Johnston
095dc78893 remove log 2024-08-01 19:42:49 -04:00
Greg Johnston
3ebea79e05 preliminary work on directives (not useful yet until we have an ElementExt that allows you to do things declaratively from an Element 2024-08-01 19:42:49 -04:00
Greg Johnston
fe7c7c3a99 omit () entirely if it is the only child of an HTML element 2024-08-01 19:42:49 -04:00
Greg Johnston
8b142c72f0 fix: don't override a text node's 'next sibling after text' position if it's in Either, now that they don't have separate marker nodes 2024-08-01 19:42:49 -04:00
Greg Johnston
70655b57b1 fix: do not accidentally mount things before meta tags in the <head> when updating the DOM 2024-08-01 19:42:49 -04:00
Greg Johnston
c6192badfb fix docs for hydrate_islands 2024-08-01 19:42:49 -04:00
Greg Johnston
5b7f5e3db3 hackernews islands example 2024-08-01 19:42:49 -04:00
Greg Johnston
ae14644806 update static file serving in Axum examples 2024-08-01 19:42:21 -04:00
Greg Johnston
7ca810d8bd fix islands ci setup 2024-08-01 19:42:21 -04:00
Greg Johnston
04e09d2005 fix: remove extra comment at end of Suspense now that Either no longer requires it 2024-08-01 19:42:21 -04:00
Greg Johnston
2916873985 feat: provide static file handling/fallback directly in integration 2024-08-01 19:42:21 -04:00
Greg Johnston
2a558aa3f0 islands example 2024-08-01 19:42:21 -04:00
Greg Johnston
36d16d9253 remove unused tests and dependencies 2024-08-01 19:42:21 -04:00
Greg Johnston
722fd0f6c2 fix: () in templates 2024-08-01 19:42:21 -04:00
Greg Johnston
a42e371e79 chore: clippy 2024-08-01 19:42:21 -04:00
Greg Johnston
11119144d2 fix js-framework-benchmark for stable 2024-08-01 19:42:21 -04:00
Greg Johnston
a0b158f016 update hackernews_axum to 0.7 2024-08-01 19:42:21 -04:00
Greg Johnston
8dc7338b85 fix ErrorBoundary starting in error state in CSR 2024-08-01 19:42:21 -04:00
Greg Johnston
737949cff6 fix example tests 2024-08-01 19:42:21 -04:00
Greg Johnston
d7e17a2ec9 remove unnecessary logs 2024-08-01 19:42:21 -04:00
Greg Johnston
7c5b7fcbb1 update islands example 2024-08-01 19:42:21 -04:00
Greg Johnston
1182aff410 chore: unused hooks 2024-08-01 19:42:21 -04:00
Greg Johnston
bdcd4cb1cc regression test for 7094dee150 2024-08-01 19:42:21 -04:00
Greg Johnston
c74a791d9f fix: signals mark subscribers dirty, but don't say they're always dirty if they haven't changed 2024-08-01 19:42:21 -04:00
Greg Johnston
772a837050 make Routes fallback run lazily 2024-08-01 19:42:21 -04:00
Greg Johnston
92552deb0d make ErrorBoundary fallback run lazily 2024-08-01 19:42:21 -04:00
Greg Johnston
417d345b83 examples: errors_axum 2024-08-01 19:42:21 -04:00
Greg Johnston
3fb2d49d89 chore(ci): fix examples 2024-08-01 19:42:21 -04:00
Greg Johnston
27feaf4309 enable reactive-graph hydration when hydration is enabled 2024-08-01 19:42:21 -04:00
Greg Johnston
35f489a52e allow conversion directly from Arc signal types to MaybeSignal 2024-08-01 19:42:21 -04:00
Greg Johnston
ba8bd2bc82 expose Owner::shared_context() 2024-08-01 19:42:21 -04:00
Greg Johnston
76506c03e1 0.7 Provider component 2024-08-01 19:42:21 -04:00
Greg Johnston
4323e30133 fix tests 2024-08-01 19:42:21 -04:00
Greg Johnston
81c0947ce5 fix reactive styles 2024-08-01 19:42:21 -04:00
Greg Johnston
309a3d504a fix: correctly rebuild reactive attributes to avoid stale signals 2024-08-01 19:42:21 -04:00
Greg Johnston
2a236e043a type-erase RenderEffeect functions for binary size improvements 2024-08-01 19:42:21 -04:00
luoxiaozero
63f8da2fb5 feat: Attr exposes PhantomData field (#2641) 2024-08-01 19:42:21 -04:00
Greg Johnston
c9e32b66bf chore(ci): remove warnings in tests 2024-08-01 19:42:21 -04:00
Greg Johnston
a32c71539d feat: 0.7 query signals 2024-08-01 19:42:21 -04:00
Greg Johnston
f7ee0c4764 chore(ci): add Makefiles for smaller packages 2024-08-01 19:42:21 -04:00
Greg Johnston
7034375cdd chore(ci): only run semver checks if not labeled 'breaking' 2024-08-01 19:42:21 -04:00
Greg Johnston
3c9c5aaf83 chore: clippy 2024-08-01 19:42:21 -04:00
Greg Johnston
ce832cef21 rename from new_serde to new 2024-08-01 19:42:21 -04:00
Greg Johnston
10230d6d65 remove most remaining marker/placeholder elements 2024-08-01 19:42:21 -04:00
Greg Johnston
e4d25608df add trait impls and encodings for SharedValue 2024-08-01 19:42:21 -04:00
Greg Johnston
bd1601e892 default to SerdeJson encoding for resources, use new_str() for Str encoding 2024-08-01 19:42:21 -04:00
Greg Johnston
602ac60a85 feat: synchronous serialized values with SharedValue 2024-08-01 19:42:21 -04:00
Greg Johnston
9e4c0b86f2 whenever we create a new root Owner, set it as the current owner, which will make it the default owner (e.g., during SSR) instead of None 2024-08-01 19:42:21 -04:00
Greg Johnston
4a80c8b65b fix: can't memoize JS properties, because they can be set between signal updates by user input 2024-08-01 19:42:21 -04:00
Greg Johnston
f191bb8324 fix: correctly escape style and class attributes 2024-08-01 19:42:21 -04:00
Greg Johnston
1ff1d48e6e chore: clippy 2024-08-01 19:42:21 -04:00
Greg Johnston
df6a4628c3 don't require spawn_local for actios 2024-08-01 19:42:21 -04:00
Greg Johnston
e28e5ceb1e catch resource reads inside Signal during Suspense 2024-08-01 19:42:21 -04:00
Greg Johnston
e69f62b939 fix CSS file names 2024-08-01 19:42:21 -04:00
Greg Johnston
2c48b07186 update todo app csr 2024-08-01 19:42:21 -04:00
Greg Johnston
0d867ba016 fix: correctly escape text nodes, except in script/style tags 2024-08-01 19:42:21 -04:00
Greg Johnston
3f83ad7dda chore: clean up examples for CI 2024-08-01 19:42:21 -04:00
Greg Johnston
50403846c9 fix: provide matched route via context when rebuilding (so <A> works) 2024-08-01 19:42:21 -04:00
Greg Johnston
4ead16e5d3 unused 2024-08-01 19:42:21 -04:00
Greg Johnston
32f77cc42b refactor insert_before_this to find parent lazily, and use it for rebuilding reactive components by replacing their whole contents 2024-08-01 19:42:21 -04:00
Greg Johnston
d8834a0423 make sure SendWrapper supports Futures 2024-08-01 19:42:21 -04:00
Greg Johnston
0d665c9c05 move several complex examples into projects 2024-08-01 19:42:21 -04:00
Greg Johnston
a03d74494d update js-framework-benchmark example 2024-08-01 19:42:20 -04:00
Greg Johnston
131c83e28e fix test text 2024-08-01 19:42:20 -04:00
Greg Johnston
6d93185478 fix: custom Stream implementation for streaming resource data that supports nested data/multiple polled values, rather than taking it all at once at the beginning 2024-08-01 19:42:20 -04:00
Greg Johnston
202abd1d35 suspense_tests: actually wait for other resource in nested case 2024-08-01 19:42:20 -04:00
Greg Johnston
a50c6b0140 can save a lookup here 2024-08-01 19:42:20 -04:00
Greg Johnston
705ea3a3bb remove unused workspace member 2024-08-01 19:42:20 -04:00
Greg Johnston
cb788758df update workflows 2024-08-01 19:42:20 -04:00
Greg Johnston
1afdc4fe1e remove unused leptos_reactive integration 2024-08-01 19:42:20 -04:00
Greg Johnston
3382047857 remove old router files 2024-08-01 19:42:20 -04:00
Greg Johnston
a29ffc8dcb fix Cargo.toml after merge 2024-08-01 19:42:20 -04:00
Greg Johnston
a18dd6dfd7 re-enable all routes 2024-08-01 19:42:20 -04:00
Greg Johnston
626bcdc9ae chore: clean up warnings and logging 2024-08-01 19:42:20 -04:00
Greg Johnston
d6dce76725 reverted Fn()/FnMut() change 2024-08-01 19:42:20 -04:00
Greg Johnston
36272a0b1b Revert "fix: constrain reactive rendering to Fn(), because using dry_resolve() for Suspense requires idempotent render functions so that they can be called once (to register resources) and called a second time to resolve"
This reverts commit 7ec5c77ba3e8f45bae04a7661a56741f95125adb.
2024-08-01 19:42:20 -04:00
Greg Johnston
96c956efdf progress on updating suspense tests 2024-08-01 19:42:20 -04:00
Greg Johnston
29cf1f4814 add server redirects 2024-08-01 19:42:20 -04:00
Greg Johnston
39c3a63787 fix: relative path resolution 2024-08-01 19:42:20 -04:00
Greg Johnston
068865b7de simplifying todo examples 2024-08-01 19:42:20 -04:00
Greg Johnston
fa8bb15a67 initial work updating suspense tests 2024-08-01 19:42:20 -04:00
Greg Johnston
faa481f2b6 clarify hydrate/csr warning 2024-08-01 19:42:20 -04:00
Greg Johnston
b41d988865 export actions in prelude 2024-08-01 19:42:20 -04:00
Greg Johnston
025c28b489 remove Into<_> by default for setting signals, because it interferes with type inference 2024-08-01 19:42:20 -04:00
Greg Johnston
0c7c7c9b38 add support for unsync actions 2024-08-01 19:42:20 -04:00
Greg Johnston
b109c3e9a3 simplifying and updating server fns example 2024-08-01 19:42:20 -04:00
Greg Johnston
0a559935e7 change name to shell 2024-08-01 19:42:20 -04:00
Greg Johnston
bccc05fec8 update control flow components to new Fn() constraint 2024-08-01 19:42:20 -04:00
Greg Johnston
e0f98dc0fd fix: constrain reactive rendering to Fn(), because using dry_resolve() for Suspense requires idempotent render functions so that they can be called once (to register resources) and called a second time to resolve 2024-08-01 19:42:20 -04:00
Greg Johnston
5d9bd8f913 add Debug impl 2024-08-01 19:42:20 -04:00
Greg Johnston
0a41ae9a5e fix: actually concatenate nested routes during route generation 2024-08-01 19:42:20 -04:00
Greg Johnston
fbc6be922d reorganize Outlet export 2024-08-01 19:42:20 -04:00
Greg Johnston
b5551863fe examples: porting to 0.7 and cleaning up 2024-08-01 19:42:20 -04:00
Greg Johnston
14b3877293 fix merge 2024-08-01 19:41:56 -04:00
Rakshith Ravi
98ea18009d Update import statements in examples (#2625) 2024-08-01 19:41:56 -04:00
Greg Johnston
d133cff092 examples: use application 404 page 2024-08-01 19:41:56 -04:00
Greg Johnston
48028b476a chore: cargo fmt 2024-08-01 19:41:56 -04:00
Greg Johnston
404ad50bd3 chore: cargo fmt 2024-08-01 19:41:56 -04:00
Greg Johnston
b89fbe027b add warnings if correct features not set for browser 2024-08-01 19:41:56 -04:00
Greg Johnston
0ba53afa08 use csr feature so that reactivity runs 2024-08-01 19:41:55 -04:00
Greg Johnston
c384b53a0f chore: clippy 2024-08-01 19:41:55 -04:00
Greg Johnston
2f53e09bb6 examples: fix input type so tests work, and update text to make the purpose clearer 2024-08-01 19:41:55 -04:00
Greg Johnston
319eefb169 remove leptos_reactive (moved into reactive_graph and leptos_server) 2024-08-01 19:41:55 -04:00
Greg Johnston
949f43d145 fix: Clone for ArcResource and default to SerdeJson for Resource 2024-08-01 19:41:55 -04:00
Greg Johnston
a47759007f chore: clippy 2024-08-01 19:41:55 -04:00
Greg Johnston
095faf15b1 fix: don't dispose of parent owners before Suspense children have been rendered 2024-08-01 19:41:55 -04:00
Greg Johnston
f9eb562050 warn if trying to use meta on server side without context 2024-08-01 19:41:55 -04:00
Greg Johnston
7f57b88e8d only run RenderEffects when effects are enabled 2024-08-01 19:41:55 -04:00
Greg Johnston
8a8862be9e add set_pending to <Transition/> 2024-08-01 19:41:55 -04:00
Greg Johnston
619dc59e1d simplify FlatRoutes logic by using existing OwnedView infrastructure 2024-08-01 19:41:55 -04:00
Greg Johnston
5f49504137 reexport tick() for testing 2024-08-01 19:41:55 -04:00
Greg Johnston
ca68fa5a3d fix: ensure that leptos_meta and leptos_router are in SSR mode if using one of the server integrations 2024-08-01 19:41:55 -04:00
Greg Johnston
e6a472b467 examples: update hackernews for SSR support 2024-08-01 19:41:55 -04:00
Greg Johnston
f8da9e30e0 fix: correctly notify multiple subscribers to same AsyncDerived 2024-08-01 19:41:36 -04:00
Greg Johnston
984ede8887 fix: Routes SSR 2024-08-01 19:41:36 -04:00
Greg Johnston
c3656416a2 fix: correct owner for HTML rendering in FlatRoutes 2024-08-01 19:41:36 -04:00
Greg Johnston
7ecfbd9109 testing: provide tick() that can be called anywhere in tests 2024-08-01 19:41:36 -04:00
Greg Johnston
531c39759a testing: provide tick() that can be called anywhere in tests 2024-08-01 19:41:36 -04:00
Greg Johnston
f5d06577f4 fix portal tests 2024-08-01 19:41:36 -04:00
Greg Johnston
39902d1e66 fix cleanups in render effects 2024-08-01 19:41:36 -04:00
Greg Johnston
7def5f65ed chore: clippy 2024-08-01 19:41:36 -04:00
Greg Johnston
6b60d48203 update counters_isomorphic 2024-08-01 19:41:36 -04:00
Greg Johnston
9ef51166d3 reexport spawn and spawn_local 2024-08-01 19:41:27 -04:00
Greg Johnston
8da6bbc3be ReadSignal from stream 2024-08-01 19:41:27 -04:00
Greg Johnston
3c39674622 refactor to allow rendering Resource directly in view 2024-08-01 19:41:27 -04:00
Greg Johnston
914b07491e removed AnimatedShow example (duplicates the component docs) 2024-08-01 19:41:27 -04:00
Greg Johnston
1d2d11b83d properly serialize errors 2024-08-01 19:41:27 -04:00
Greg Johnston
07e878adf7 chore: clear warning 2024-08-01 19:41:27 -04:00
Greg Johnston
f32d43ce94 pick up on server action error in both server and client 2024-08-01 19:41:27 -04:00
Greg Johnston
65e3c57ed1 fmt and chores in examples 2024-08-01 19:41:27 -04:00
Greg Johnston
2e40bace88 fix: serialize an empty string into HTML so it still works as a text node 2024-08-01 19:41:27 -04:00
Greg Johnston
b9945e0ce1 fix: make router fallback lazy 2024-08-01 19:41:27 -04:00
Greg Johnston
d7f70214b9 add expect_context 2024-08-01 19:41:27 -04:00
Greg Johnston
adf57f5771 fix attr:class when spreading onto a component 2024-08-01 19:41:27 -04:00
Greg Johnston
bae79e2b2c add ServerAction error handling for any error type (closes #2325) 2024-08-01 19:41:27 -04:00
Greg Johnston
e2b1210461 remove unused import 2024-08-01 19:41:13 -04:00
Greg Johnston
7c24b7482d clean up example 2024-08-01 19:41:13 -04:00
Greg Johnston
25c66a4624 add CollectView 2024-08-01 19:41:13 -04:00
Greg Johnston
71ddacef8e Actix todo_app_sqlite 2024-08-01 19:41:13 -04:00
Greg Johnston
338b01bee3 fix: don't drop Owner in FlatRoutes until route has been rendered (thanks @benwis) 2024-08-01 19:41:13 -04:00
Greg Johnston
a36f22e439 fix: make sure all resource reads are registered 2024-08-01 19:41:13 -04:00
Greg Johnston
56977411f2 chore: clippy and unused dependencies in integrations 2024-08-01 19:41:13 -04:00
Greg Johnston
0fc47e3a35 add some tracing and debug info to HTML elements 2024-08-01 19:41:13 -04:00
Greg Johnston
caf797dba0 refactor integrations and add Actix integration 2024-08-01 19:41:13 -04:00
Greg Johnston
2f54d937a1 feat: 0.7 nonce support 2024-08-01 19:41:13 -04:00
Greg Johnston
40c1f38a07 ResponseOptions support 2024-08-01 19:41:13 -04:00
Greg Johnston
402d6297f4 fix counters tests 2024-08-01 19:41:13 -04:00
Greg Johnston
93734a5222 allow .children() on HTML elements 2024-08-01 19:41:13 -04:00
Greg Johnston
770d02d8e6 remove async demo 2024-08-01 19:41:13 -04:00
Greg Johnston
e275862a20 fix: writing to lock that has a read 2024-08-01 19:41:13 -04:00
Greg Johnston
17f1d25d03 allow untracking on write guards to support maybe_update 2024-08-01 19:41:13 -04:00
Greg Johnston
0a99a378aa feat: allow .write() on all writeable signals 2024-08-01 19:41:13 -04:00
Greg Johnston
14b7073863 feat: add .by_ref() to create a Future from an AsyncDerived (etc.) that takes a reference, rather than cloning 2024-08-01 19:41:12 -04:00
Greg Johnston
4e4deef144 use impl trait in props 2024-08-01 19:41:12 -04:00
Greg Johnston
c360f0ed0d update wasm-bindgen testing approaches 2024-08-01 19:41:12 -04:00
Greg Johnston
88ab9693db chore: clearing warnings in examples 2024-08-01 19:41:12 -04:00
Greg Johnston
6dfea0b0a2 additional warnings 2024-08-01 19:41:12 -04:00
Greg Johnston
9fd881603f cargo fmt 2024-08-01 19:41:12 -04:00
Greg Johnston
9666c9c0c5 chore: clear up... a few warnings 2024-08-01 19:41:12 -04:00
Greg Johnston
9e8b304b8a update sledgehammer integration 2024-08-01 19:41:12 -04:00
Greg Johnston
064ccce5b1 remove signal function setter Send-only implementation (dead code) 2024-08-01 19:41:12 -04:00
Greg Johnston
2e31177f62 remove signal function call Read implementations (dead code) 2024-08-01 19:41:12 -04:00
Greg Johnston
4215cef04b remove leptos_reactive dependency 2024-08-01 19:41:12 -04:00
Greg Johnston
de3dd3c296 oco merge issues 2024-08-01 19:41:12 -04:00
Greg Johnston
846ff2fefb feat: return an async guard from .await rather than cloning the value every time 2024-08-01 19:41:12 -04:00
Greg Johnston
6003212f6e fix return type in async tests 2024-08-01 19:41:11 -04:00
Greg Johnston
054cff7883 fix tests that run effects 2024-08-01 19:41:11 -04:00
Greg Johnston
ce5738d7c4 feat: return Option from AsyncDerived.get() instead of AsyncState 2024-08-01 19:41:11 -04:00
Greg Johnston
47331b5c8d example: restore ErrorBoundary 2024-08-01 19:41:11 -04:00
Greg Johnston
a6cee3b1e9 docs for Owner and context 2024-08-01 19:41:11 -04:00
Greg Johnston
43c0e384c4 fix tests 2024-08-01 19:41:11 -04:00
Greg Johnston
db654cbfda poll AsyncDerived synchronously so that it has the correct value during hydration if it reads from a resource 2024-08-01 19:41:11 -04:00
Greg Johnston
e13b1561d8 correct dirty-checking on AsyncDerived 2024-08-01 19:41:11 -04:00
Greg Johnston
02f76dec35 fix regular suspense if nothing was read synchronously 2024-08-01 19:41:11 -04:00
Greg Johnston
4bd99a41e5 missing dry_resolve on Static 2024-08-01 19:41:11 -04:00
Greg Johnston
85d29a5af5 feat: support *either* .await or reactive reads inside Suspense 2024-08-01 19:41:11 -04:00
Greg Johnston
4d54574f9e feat: 0.7 slots 2024-08-01 19:41:11 -04:00
Greg Johnston
f6c7ac473a feat: enhanced spreading syntax 2024-08-01 19:41:11 -04:00
Greg Johnston
747d847183 fix external navigations 2024-08-01 19:41:11 -04:00
Greg Johnston
8dd63a402b make WindowListenerHandle Send + Sync so it can be remove via on_cleanup 2024-08-01 19:41:11 -04:00
Greg Johnston
694eccbadc restore ssr/hydration for Routes 2024-08-01 19:41:11 -04:00
Greg Johnston
24f2e71563 get nested Routes working again 2024-08-01 19:41:11 -04:00
Greg Johnston
1766bfedb9 default to Params::get() giving an owned value (which you want in a derived signal), but use reference in the macro 2024-08-01 19:41:11 -04:00
Greg Johnston
242d35cc37 add proper dirty checking on AsyncDerived so it can read from memos properly 2024-08-01 19:41:11 -04:00
Greg Johnston
85b9f87620 make NavigateOptions pub 2024-08-01 19:41:11 -04:00
Greg Johnston
db33bc2e61 feat: owning memo 2024-08-01 19:41:11 -04:00
Greg Johnston
a1329ea044 remove warnings in tests and only run if effects are enabled 2024-08-01 19:41:11 -04:00
Greg Johnston
050bf8f821 fix: prevent memos that have changed from re-triggering the running effect, by setting the Observer during .update_if_necessary() 2024-08-01 19:41:11 -04:00
Greg Johnston
1a68743fcc feat: add Popover API 2024-08-01 19:41:11 -04:00
Greg Johnston
2925db8676 fix Script children 2024-08-01 19:41:11 -04:00
Greg Johnston
13d5f12d7f fix hydration of Suspend by including the missing placeholder it expects during hydration 2024-08-01 19:41:11 -04:00
Greg Johnston
3d9c295613 add missing marker comments for Result 2024-08-01 19:41:11 -04:00
Greg Johnston
b2c0068e2c include marker comments in html len 2024-08-01 19:41:11 -04:00
Greg Johnston
94a3f7c092 unused owner 2024-08-01 19:41:11 -04:00
Greg Johnston
330dcfeb7c impl From/Into for Signal/ArcSignal 2024-08-01 19:41:11 -04:00
Greg Johnston
f7bbec5f06 add ArcSignal::derive() 2024-08-01 19:41:11 -04:00
Greg Johnston
8815529955 routing progress indicator 2024-08-01 19:41:11 -04:00
Greg Johnston
12db58a7e0 missing min attribute 2024-08-01 19:41:11 -04:00
Greg Johnston
83c9edde26 clean up 2024-08-01 19:41:11 -04:00
Greg Johnston
2037a6966a remove log 2024-08-01 19:41:11 -04:00
Greg Johnston
4f041f5a5e relax trait bounds on reactive types where possible 2024-08-01 19:41:11 -04:00
Greg Johnston
6467e067ef add SignalSetter 2024-08-01 19:41:11 -04:00
Greg Johnston
3814879d80 use transition between navigations 2024-08-01 19:41:11 -04:00
Greg Johnston
5e16ae6a26 add async transitions that wait for any AsyncDerived created/triggered under them before resolving 2024-08-01 19:41:11 -04:00
Greg Johnston
6d474713f6 resolve() on OwnedView 2024-08-01 19:41:11 -04:00
Greg Johnston
0d47399424 restore hydration feature for some of its feature-gating benefits for Resource deserialization 2024-08-01 19:41:11 -04:00
Greg Johnston
ae254836d7 cargo fmt 2024-08-01 19:41:11 -04:00
Greg Johnston
2dd5efc5d0 create separate URL/params signals for each route, to prevent updating them and running side effects while navigating away 2024-08-01 19:41:11 -04:00
Greg Johnston
15eeda9c7a fmt 2024-08-01 19:41:11 -04:00
Greg Johnston
1a739015e1 distinguish between dirty and check in effects, so that memos and signals both work correctly 2024-08-01 19:41:11 -04:00
Greg Johnston
8385287123 remove unused feature 2024-08-01 19:41:11 -04:00
Greg Johnston
c4aa3ba1ba updated future impls 2024-08-01 19:41:11 -04:00
Greg Johnston
ce5f2c81ed check whether ArcAsyncDerived actually needs to run when marked check 2024-08-01 19:41:11 -04:00
Greg Johnston
941689fc5b add ancestry debugging for owners 2024-08-01 19:41:11 -04:00
Greg Johnston
961bf89a8b lazy Future construction for AsyncDerived 2024-08-01 19:41:11 -04:00
Greg Johnston
d360cc280f support Resource in CSR for backward-compat 2024-08-01 19:41:11 -04:00
Greg Johnston
bb7bb8f4c2 allow let: syntax to work 2024-08-01 19:41:11 -04:00
Greg Johnston
b29b8fb5ff scope Suspense/Transition correctly within ownership tree 2024-08-01 19:41:11 -04:00
Greg Johnston
4ffa3c46b6 upgrading hackernews example 2024-08-01 19:41:10 -04:00
Greg Johnston
32294d6cab immediately commit URL signal updates 2024-08-01 19:40:57 -04:00
Greg Johnston
46d286755e reexport A from router::components 2024-08-01 19:40:57 -04:00
Greg Johnston
b936e0352f add IntoAny to tachys prelude 2024-08-01 19:40:57 -04:00
Greg Johnston
b5bd70ab94 finish support for innerHTML 2024-08-01 19:40:57 -04:00
Greg Johnston
0dd1932b7f feat: iterating over items in children with ChildrenFragment, ChildrenFragmentFn, ChildrenFragmentMut 2024-08-01 19:40:57 -04:00
Greg Johnston
f5d203f0c9 only warn about non-reactive accesses if effects are enabled 2024-08-01 19:40:57 -04:00
Greg Johnston
1bc0b414e3 only run effects on client 2024-08-01 19:40:57 -04:00
Greg Johnston
d6e19c0a60 resolve() implementation for AnyView 2024-08-01 19:40:57 -04:00
Greg Johnston
fc60d6b2d7 fix deadlock on nested Signals 2024-08-01 19:40:57 -04:00
Greg Johnston
292e7c1f27 fix FlatRouter SSR/hydration after lazy routes 2024-08-01 19:40:57 -04:00
Greg Johnston
1da84db1aa feat: nested islands with context for 0.7 2024-08-01 19:40:57 -04:00
Greg Johnston
535e3e3880 fix: correct Send + Sync bounds for children 2024-08-01 19:40:57 -04:00
Greg Johnston
109244b28b feat: minimal island support in 0.7 2024-08-01 19:40:57 -04:00
Greg Johnston
fd048295a4 docs: full docs and doctests for Action/MultiAction 2024-08-01 19:40:57 -04:00
Greg Johnston
26cf4848db remove support for rendering guards directly, as they are !Send and holding onto them in State is also a bad idea 2024-08-01 19:40:57 -04:00
Greg Johnston
757a5c73c3 support nightly static values for style:key="value" 2024-08-01 19:40:57 -04:00
Greg Johnston
da496def16 revert to using .get() for function calls 2024-08-01 19:40:57 -04:00
Greg Johnston
3a755bd8c3 fix: only rerun effects if they have dirty ancestors (or it's the first run) 2024-08-01 19:40:57 -04:00
Greg Johnston
e514f7144d start working on porting over docs and tests and 0.7... 2024-08-01 19:40:57 -04:00
Greg Johnston
b881167b8f fix meta issue with attributes 2024-08-01 19:40:57 -04:00
Greg Johnston
1e9d345831 fix tracing issue 2024-08-01 19:40:57 -04:00
Greg Johnston
7f7bba6ea3 chore: get tests in a working state 2024-08-01 19:40:57 -04:00
Greg Johnston
015a4b63ec fix: make Selector Send/Sync 2024-08-01 19:40:57 -04:00
Greg Johnston
dcec7af4f3 docs: runtime warning if you use .track() outside a tracking context 2024-08-01 19:40:57 -04:00
Greg Johnston
5bc97654dc preliminary tracing for tachys 2024-08-01 19:40:57 -04:00
Greg Johnston
2788d93e96 chore: warnings 2024-08-01 19:40:57 -04:00
Greg Johnston
604043b4d8 examples: router in 0.7 2024-08-01 19:40:57 -04:00
Greg Johnston
ab28c80593 fix: passing context through router 2024-08-01 19:40:57 -04:00
Greg Johnston
49da073fed chore: fix warnings about variable case 2024-08-01 19:40:57 -04:00
Greg Johnston
3629302f88 examples: timer in 0.7 2024-08-01 19:40:57 -04:00
Greg Johnston
274e31018b feat: Portals in 0.7 2024-08-01 19:40:57 -04:00
Greg Johnston
802fcc5c2a allow either eager or lazy routes 2024-08-01 19:40:57 -04:00
Greg Johnston
da084a2ece update StoredValue API in callbacks 2024-08-01 19:40:57 -04:00
Greg Johnston
d9f6836933 chore: clippy warnings 2024-08-01 19:40:57 -04:00
Greg Johnston
d8d2fdac5d smooth out StoredValue APIs 2024-08-01 19:40:57 -04:00
Greg Johnston
9818e7cb68 MaybeSignal and MaybeProp 2024-08-01 19:40:57 -04:00
Marc-Stefan Cassola
986fbe5328 added a few old deprecated functions to help users port (#2580) 2024-08-01 19:40:57 -04:00
Greg Johnston
711175a760 implement With(Untracked) for Signal 2024-08-01 19:40:57 -04:00
Greg Johnston
00a536a5dc don't over-rerender nested router 2024-08-01 19:40:57 -04:00
Greg Johnston
a7b1152910 initial async routing work (to support bundle splitting) 2024-08-01 19:40:57 -04:00
Greg Johnston
cfba7a2797 noop attribute 'spreading' for routers 2024-08-01 19:40:57 -04:00
Greg Johnston
cebe744a84 support arbitrary attributes on components in view 2024-08-01 19:40:57 -04:00
Greg Johnston
e93a34a2c9 full attribute spreading 2024-08-01 19:40:57 -04:00
Greg Johnston
9ec30d71d2 update counter_without_macros imports 2024-08-01 19:40:57 -04:00
Greg Johnston
3c13280bf6 stashing 2024-08-01 19:40:57 -04:00
Greg Johnston
45fd9423f8 give a route to upgrade any attribute into a cloneable one 2024-08-01 19:40:56 -04:00
Greg Johnston
7a92208c4f work on attribute spreading 2024-08-01 19:40:56 -04:00
Greg Johnston
89b972e3c5 disable AddAnyAttr again now that I remember why it was broken 2024-08-01 19:40:56 -04:00
Greg Johnston
8dac92b251 reenable AnyAttr 2024-08-01 19:40:56 -04:00
Greg Johnston
b24eaedfe9 reorganizing exports and updating examples 2024-08-01 19:40:56 -04:00
Greg Johnston
4336051f78 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
97ce5adb8e fix reorganized exports 2024-08-01 19:40:56 -04:00
Greg Johnston
20fb5454b0 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
aac607f338 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
738986415d prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
3406446ebd module restructuring for 0.7 2024-08-01 19:40:56 -04:00
Greg Johnston
21dd7e9c76 let ErrorBoundary own the fallback 2024-08-01 19:40:56 -04:00
Greg Johnston
9bab4da172 make Suspend a transparent wrapper 2024-08-01 19:40:56 -04:00
Greg Johnston
420dccda60 provide params properly in FlatRouter 2024-08-01 19:40:56 -04:00
Greg Johnston
53b22a9b74 clear some warnings 2024-08-01 19:40:56 -04:00
Greg Johnston
e68730d15f rename TupleBuilder to NextTuple and prep for release 2024-08-01 19:40:56 -04:00
Greg Johnston
11d134c4ba prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
2239f04f6b prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
78e5a7ebc3 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
0148d92f48 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
ab67bea7ec rename any_error 2024-08-01 19:40:56 -04:00
Greg Johnston
0beef3b2e0 prep for preview release 2024-08-01 19:40:56 -04:00
Greg Johnston
81fc7e6ada remove twiggy file 2024-08-01 19:40:56 -04:00
Greg Johnston
75d6763f4e move router crates 2024-08-01 19:40:56 -04:00
Greg Johnston
da4d2cf538 comparison demo 2024-08-01 19:40:25 -04:00
Greg Johnston
2470637b0b SSR optimizations for binary size, and flat router 2024-08-01 19:40:25 -04:00
Greg Johnston
2934c295b5 work on Axum integration and on error boundaries 2024-08-01 19:40:25 -04:00
Greg Johnston
789eef914d stash 2024-08-01 19:40:25 -04:00
Greg Johnston
782cb93743 feat: add <A> 2024-08-01 19:40:25 -04:00
Greg Johnston
8642c563d8 add use_navigate and Redirect 2024-08-01 19:40:25 -04:00
Greg Johnston
755fbd3866 preliminary use_navigate work 2024-08-01 19:40:25 -04:00
Greg Johnston
d83471e02b fix fallback => match update 2024-08-01 19:40:25 -04:00
Greg Johnston
2dd2bb5958 add more hooks and primitives to router 2024-08-01 19:40:25 -04:00
Greg Johnston
12f2cec5c7 nested route CSR working 2024-08-01 19:40:25 -04:00
Greg Johnston
a41bf2784f continuing on nested routes 2024-08-01 19:40:25 -04:00
Greg Johnston
ebdd31cd9f continuing on nested routes 2024-08-01 19:40:25 -04:00
Greg Johnston
acec3bb313 working on reconfiguring nested routing 2024-08-01 19:40:25 -04:00
Greg Johnston
464f157186 make placeholder-finding code consistent across container types 2024-08-01 19:40:25 -04:00
Greg Johnston
b53e4d8ff8 remove logs 2024-08-01 19:40:25 -04:00
Greg Johnston
cd438e0bcf fix Transition hydration 2024-08-01 19:40:25 -04:00
Greg Johnston
13da1e743d remove TryCatch/fallible rendering in favor of better ErrorBoundary model 2024-08-01 19:40:25 -04:00
Greg Johnston
0c9167fd30 finish todo_app_sqlite_axum 2024-08-01 19:40:25 -04:00
Greg Johnston
52da0e43ac fix Vec hydration 2024-08-01 19:40:25 -04:00
Greg Johnston
dad91f5960 add MultiActionForm 2024-08-01 19:40:25 -04:00
Greg Johnston
72e97047a5 add MultiAction/ServerMultiAction 2024-08-01 19:40:25 -04:00
Greg Johnston
883fd57fe1 stash 2024-08-01 19:40:25 -04:00
Greg Johnston
42b99dd912 ErrorBoundary SSR and serialization of errors to support hydration 2024-08-01 19:40:25 -04:00
Greg Johnston
851e1f73fd get types working with nested ErrorBoundary/Suspense 2024-08-01 19:40:25 -04:00
Greg Johnston
e11eea1af1 probably as far as I can go with the current SuspenseBoundary approach 2024-08-01 19:40:25 -04:00
Greg Johnston
f508cc4510 fix static types 2024-08-01 19:40:25 -04:00
Greg Johnston
e4f3cf9cca fix cancellation logic for server fn requests 2024-08-01 19:40:25 -04:00
Greg Johnston
60d883a26c only subscribe to memo manually if already loaded 2024-08-01 19:40:25 -04:00
Greg Johnston
add3be0ff5 Suspense SSR 2024-08-01 19:40:25 -04:00
Greg Johnston
a01640cafd updates toward todo_app_sqlite 2024-08-01 19:40:25 -04:00
Greg Johnston
e837e9fded fix stable examples 2024-08-01 19:40:25 -04:00
Greg Johnston
e0e67360aa implement rendering traits for signals directly on stable 2024-08-01 19:40:25 -04:00
Greg Johnston
439deea066 suspend!() macro 2024-08-01 19:40:25 -04:00
Greg Johnston
e5f5710f46 add Transition 2024-08-01 19:40:25 -04:00
Greg Johnston
8626db27d7 loosen requirements for Show 2024-08-01 19:40:25 -04:00
Greg Johnston
ec3f0933fe working on examples 2024-08-01 19:40:25 -04:00
Greg Johnston
b50de3a005 finish TodoMVC example 2024-08-01 19:40:25 -04:00
Greg Johnston
aa878534ad simplify Suspense: this should still work with hydration 2024-08-01 19:40:25 -04:00
Greg Johnston
603f9f96c4 working model for Suspense with new version 2024-08-01 19:40:25 -04:00
Greg Johnston
f78e675506 probably as far as I can go with the current SuspenseBoundary approach 2024-08-01 19:40:24 -04:00
Greg Johnston
cc2714c03d fix ErrorBoundary/Suspense 2024-08-01 19:40:24 -04:00
Greg Johnston
c06110128b feat: ErrorBoundary and Suspense 2024-08-01 19:40:24 -04:00
Greg Johnston
d7c62622ae feat: ErrorBoundary 2024-08-01 19:40:24 -04:00
Greg Johnston
1edec6c36a fix Cargo.toml merge issues 2024-08-01 19:40:24 -04:00
Greg Johnston
c5049ca1bb working on examples 2024-08-01 19:40:24 -04:00
Greg Johnston
f69dbb48ca styling with CSS 2024-08-01 19:40:24 -04:00
Greg Johnston
5feaf1aea6 example with isomorphic GTK/web design system 2024-08-01 19:40:24 -04:00
Greg Johnston
ec3ab6a355 gtk example 2024-08-01 19:40:24 -04:00
Greg Johnston
100ed7d926 ErrorBoundary component 2024-08-01 19:40:24 -04:00
Greg Johnston
88b93f40f9 Suspense/Transition components 2024-08-01 19:40:24 -04:00
Greg Johnston
b8b77138ea GTK example for 0.7 2024-08-01 19:40:24 -04:00
Greg Johnston
20c29cab89 add serde-wasm-bindgen encoding for resources 2024-08-01 19:40:24 -04:00
Greg Johnston
54fd74839a add typed children 2024-08-01 19:40:24 -04:00
Greg Johnston
ea3790d91c scope Arena to each request 2024-08-01 19:40:24 -04:00
Greg Johnston
f5935c6333 correctly omit HTML-generating code from AnyView 2024-08-01 19:40:24 -04:00
Greg Johnston
c8e5e1b16b experimental sledgehammer Renderer backend 2024-08-01 19:40:24 -04:00
Greg Johnston
a12c707f3f fix async context issues, add flat routing 2024-08-01 19:40:24 -04:00
Greg Johnston
6d9906111d test more dynamic string length work 2024-08-01 19:40:24 -04:00
Greg Johnston
5ea314c998 attribute value escaping 2024-08-01 19:40:24 -04:00
Greg Johnston
2bc04444e1 work related to 0.7 blog port 2024-08-01 19:40:24 -04:00
Greg Johnston
b41fde3ff9 work related to 0.7 blog port 2024-08-01 19:40:24 -04:00
Greg Johnston
c29081b12a completing work on meta 2024-08-01 19:40:24 -04:00
Greg Johnston
2fefc8b4bf completing work on meta 2024-08-01 19:40:24 -04:00
Greg Johnston
72b43d1e2b initial work on meta 2024-08-01 19:40:24 -04:00
Greg Johnston
39607adc94 initial work on meta 2024-08-01 19:40:24 -04:00
Greg Johnston
30c1cd921b stash 2024-08-01 19:40:24 -04:00
Greg Johnston
abfe3cabd2 fix nested route rebuilding 2024-08-01 19:40:24 -04:00
Greg Johnston
16bd2942db navigation between nested routes 2024-08-01 19:40:24 -04:00
Greg Johnston
13cccced06 initial stage for working nested route rendering 2024-08-01 19:40:24 -04:00
Greg Johnston
db4c1cb4b3 stash 2024-08-01 19:40:24 -04:00
Greg Johnston
9cdd8cac15 stash 2024-08-01 19:40:24 -04:00
Greg Johnston
84ebdc1b92 get basic routing working 2024-08-01 19:40:24 -04:00
Greg Johnston
9f02cc8cc1 stash 2024-08-01 19:40:24 -04:00
Greg Johnston
c3b9932172 reorganize 2024-08-01 19:40:24 -04:00
Greg Johnston
dbd9951a85 working on nesting routing 2024-08-01 19:40:24 -04:00
Greg Johnston
6eb8b44fff reorganize 2024-08-01 19:40:24 -04:00
Greg Johnston
4fa31be5dc stash 2024-08-01 19:40:24 -04:00
Greg Johnston
b46dffb729 abstract interface to walk nested routes and to access views 2024-08-01 19:40:24 -04:00
Greg Johnston
ca54762806 reorganize and clean up 2024-08-01 19:40:24 -04:00
Greg Johnston
f122f9109f nested route matching 2024-08-01 19:40:24 -04:00
Greg Johnston
f894d6e4f6 stash 2024-08-01 19:40:24 -04:00
Greg Johnston
4cc925c950 stash 2024-08-01 19:40:24 -04:00
Greg Johnston
21e53042e8 work on routing utils 2024-08-01 19:40:24 -04:00
Greg Johnston
4d3fb37b35 nested route matching working 2024-08-01 19:40:24 -04:00
Greg Johnston
d3a21c922d stash 2024-08-01 19:40:24 -04:00
Greg Johnston
317f90e1e3 use either_of crate 2024-08-01 19:40:24 -04:00
Greg Johnston
26869a78a0 nested routes take 1 2024-08-01 19:40:24 -04:00
Greg Johnston
f46f864f05 split EitherOfX into its own crate 2024-08-01 19:40:24 -04:00
Greg Johnston
b21f1853c6 work on routing 2024-08-01 19:40:24 -04:00
Greg Johnston
1454c5d272 work on routing 2024-08-01 19:40:24 -04:00
Greg Johnston
c1f4616a31 set up routing 2024-08-01 19:40:24 -04:00
Greg Johnston
a3c3478831 clear warning 2024-08-01 19:40:24 -04:00
Greg Johnston
1ca8a9189c chore: clear warnings 2024-08-01 19:40:24 -04:00
Greg Johnston
9e276a8879 pass on: to components (and lay basis for passing all other attributes) 2024-08-01 19:40:24 -04:00
Greg Johnston
53703f208a working on AddAttr 2024-08-01 19:40:24 -04:00
Greg Johnston
9a60b21a0a remove boilerplate: require that Node, Element, etc. types always be Clone + 'static 2024-08-01 19:40:24 -04:00
Greg Johnston
524ed395fa parent_child example 2024-08-01 19:40:24 -04:00
Greg Johnston
5bc8c4e0d3 use AnyError for all try_ rendering errors, so that they can compose 2024-08-01 19:40:24 -04:00
Greg Johnston
7f7003f7f1 support for guards with class: syntax 2024-08-01 19:40:24 -04:00
Greg Johnston
ddf2ac0cf7 add Borrow implementation to make it easier to abstract over T and Guard<T> 2024-08-01 19:40:24 -04:00
Greg Johnston
992e2bce78 finish error boundary (fix last state transition issue) 2024-08-01 19:40:24 -04:00
Greg Johnston
6c2469ec3a progress on error boundary that works with nested reactivity 2024-08-01 19:40:24 -04:00
Greg Johnston
a7162d7907 progress on error boundary that works with nested reactivity 2024-08-01 19:40:24 -04:00
Greg Johnston
f584154156 error example 2024-08-01 19:40:24 -04:00
Greg Johnston
13464b10c9 enable event delegation 2024-08-01 19:40:24 -04:00
Greg Johnston
696bf14d13 fix release build 2024-08-01 19:40:24 -04:00
Greg Johnston
be92bab3e5 update TODO.md 2024-08-01 19:40:24 -04:00
Greg Johnston
4bb2bc4797 store effects in reactive system 2024-08-01 19:40:24 -04:00
Greg Johnston
a8adf8eea2 todomvc example 2024-08-01 19:40:24 -04:00
Greg Johnston
1a7da39fb7 work on async demo 2024-08-01 19:40:23 -04:00
Greg Johnston
201adb7406 clone values for Futures 2024-08-01 19:40:23 -04:00
Greg Johnston
4df42cbc60 make guard types more nestable/flexible so that we can implement render traits on any of them 2024-08-01 19:40:23 -04:00
Greg Johnston
44a0a0a93a work on async demo 2024-08-01 19:40:23 -04:00
Greg Johnston
66e1e6d7a1 work on async demo 2024-08-01 19:40:23 -04:00
Greg Johnston
8252c4a977 feat: create generic any_spawner crate to share between reactive system and renderer 2024-08-01 19:40:23 -04:00
Greg Johnston
6a2eafcbc6 add other methods on Stored 2024-08-01 19:40:23 -04:00
Greg Johnston
b49a13f8c1 work on async demo 2024-08-01 19:40:23 -04:00
Greg Johnston
0d5c67408f stash: working on jsfb 2024-08-01 19:40:23 -04:00
Greg Johnston
1eddd5a5f1 chore: remove unnecessary log 2024-08-01 19:40:23 -04:00
Greg Johnston
ca1e62c0b9 fix: correct owner for rows of For, correct cleanup of arenas 2024-08-01 19:40:23 -04:00
Greg Johnston
043cd7dc61 fix: close memory leak in tasks waiting on channels 2024-08-01 19:40:23 -04:00
Greg Johnston
68486cfb72 feat: typed event targets 2024-08-01 19:40:23 -04:00
Greg Johnston
eea971b9fe working on examples 2024-08-01 19:40:23 -04:00
Greg Johnston
d726b56b71 begin migrating to leptos and leptos_dom packages 2024-08-01 19:40:23 -04:00
Greg Johnston
0fddfb4823 stash 2024-08-01 19:40:23 -04:00
Greg Johnston
17732a6e6a stash 2024-08-01 19:40:23 -04:00
Greg Johnston
c8441f0f00 chore: remove leptos_reactive and add reactive_graph 2024-08-01 19:40:23 -04:00
Greg Johnston
ff4cde0764 feat: improved ergonomics of read guards 2024-08-01 19:40:23 -04:00
Greg Johnston
1d38439bd8 feat: add Readable implementation for all types 2024-08-01 19:40:23 -04:00
Greg Johnston
9ca1cba504 feat: add no_std support in appropriate crates 2024-08-01 19:40:23 -04:00
Greg Johnston
63dacdcc95 feat: tachys 2024-08-01 19:40:23 -04:00
Greg Johnston
61f5294f67 feat: add Fn traits 2024-08-01 19:40:23 -04:00
Greg Johnston
0149632a4c docs: note re: execution order (see #2261 and #2262) 2024-08-01 19:40:23 -04:00
Greg Johnston
96384ed116 feat: modular SharedContext for hydration 2024-08-01 19:40:23 -04:00
Greg Johnston
f56023bb25 chore: split OrPoisoned trait into its own crate for reuse 2024-08-01 19:40:23 -04:00
Greg Johnston
6bb5d58369 feat: modular, trait-based, Send/Sync reactive system 2024-08-01 19:40:23 -04:00
Saber Haj Rabiee
d50012f8d4 chore: update gloo-net and reqwest to http 1.0 (closes #2688) (leptos 0.6) (#2751) 2024-08-01 19:39:54 -04:00
Greg Johnston
c9d4ea9307 Merge pull request #2755 from leptos-rs/nightly-july24
chore(ci): update nightly
2024-08-01 15:30:22 -04:00
Greg Johnston
77c74bccbb chore: cargo fmt 2024-08-01 14:53:24 -04:00
Greg Johnston
528d1eae65 chore(ci): update nightly 2024-08-01 14:48:52 -04:00
martin frances
5809c8f699 As of rust1.80: cargo clippy now reports doc indentation issues. (#2728) 2024-07-30 09:25:53 -07:00
renshuncui
b9c620d4cd chore: fix some comments (#2712)
Signed-off-by: renshuncui <renshun@111.com>
2024-07-29 09:30:50 -04:00
Greg Johnston
8c9dfd9c9d fix: untrack children in Portal to avoid re-triggering it accidentally (closes #2693) (#2713) 2024-07-29 09:29:18 -04:00
Greg Johnston
8848eb8b87 0.6.13 2024-07-24 08:00:11 -04:00
Ar4ys
7e75801f7c fix: move lint rules outside of quote_spanned (closes #2527) (#2709) 2024-07-24 07:54:46 -04:00
Dreo
0763a81cf1 fix: remove unnecessary 'static lifetime from argument in function Style::as_value_string() (#2683) 2024-07-12 11:53:48 -04:00
Dreo
3d37f08539 add impl IntoStyle for Style (#2682) 2024-07-12 11:13:29 -04:00
Oleg Shatov
b3db094618 chore: remove cfg-related warnings (#2654) 2024-07-03 06:49:32 -04:00
Oleg Shatov
0c817d51fe fix: accurately update number of pending action dispatches (closes #2652) (#2653) 2024-07-03 06:48:02 -04:00
Chris
fb5d8513ff docs: generate link to definition (#2656) 2024-07-03 06:46:02 -04:00
David Karrick
c53fc67d38 feat: Add Compression to Hacker News w/ Islands Example (#2613)
* Add task for cargo leptos w/ precompression

* Update makefile

* Update deps

* Serve precompressed assets

Code was taken from https://github.com/leptos-rs/cargo-leptos/pull/165#issuecomment-1647843037

Co-authored-by: Sebastian Dobe <sebastiandobe@mailbox.org>

* Dynamically compress html

* Update README

* Refactor: Format for ci

* Refactor: Replace use of format!

* Chore: Remove old build file

* Feat: Hash files

This will prevent users from using an old cached file after updates are made

* Fix: Prevent chicken & egg problem with target/site

* Refactor: Use normal cargo-leptos

---------

Co-authored-by: Sebastian Dobe <sebastiandobe@mailbox.org>
2024-06-28 15:01:05 -04:00
Greg Johnston
ff0c8252b0 fix: do not unescape / and other route characters when following a link (#2651) 2024-06-28 14:29:05 -04:00
Evan Almloff
551f9b0a04 feat: add a StreamingJson encoding (#2623) 2024-06-28 11:49:26 -04:00
Greg Johnston
44cd3272f9 Merge pull request #2639 from Giovanni-Tably/dispose-fix
fix: ensure everything is disposed of consistently
2024-06-28 11:30:31 -04:00
Vasily Zorin
73a9797ef9 book_ru: SUMMARY.md (#2648)
* book_ru: SUMMARY.md

* book_ru: SUMMARY.md

* book_ru: SUMMARY.md
2024-06-27 06:46:36 -07:00
Spencer Ferris
57a00a33a3 docs: Add docs for ToChildren (#2643)
* docs: Add docs for `ToChildren`

As discussed in https://github.com/leptos-rs/leptos/discussions/2640,
the `ToChildren` trait is useful to consumers who want to use the
builder syntax. However, because it is currently annotated with
`#[docs(hidden)]`, it's not visible in docs and also not included in
Jetbrains's auto-complete.

Add a doc comment for the `ToChildren` trait, including doc tests that
demonstrate how to use the trait and how it compares to directly
creating children.

* docs: Fix incorrect examples in `ToChildren` docs

Some examples were added to `ToChildren` that don't compile. This
wasn't caught earlier because no errors were seen in the IDE when
writing the examples. The issue was correctly caught by CI, however.
2024-06-26 14:57:40 -07:00
Adrian
5f445cdfbf Translating titles of sections in SUMMARY (#2542) 2024-06-26 14:56:59 -07:00
Hamir Mahal
c9d0ef5033 chore: simplify string interpolation (#2626) 2024-06-21 07:51:38 -04:00
Giovanni
af85623a22 test: add regression tests 2024-06-20 19:37:08 +01:00
Giovanni
40ecc2bd78 fix: dispose of watch effect normally 2024-06-20 15:36:03 +01:00
Giovanni
41a18a1218 fix: clean up recursively in dispose_node 2024-06-20 15:26:55 +01:00
Giovanni
739d1b2e3e refactor: split a couple of functions 2024-06-20 15:26:37 +01:00
Giovanni
9e6996a59f fix: untrack around all on_cleanups 2024-06-20 15:26:37 +01:00
Giovanni
cca3f1f42d refactor: rename cleanup_property -> dispose_property
The property and its node are removed entirely, so it's more aligned with `dispose_node` than `cleanup_node`.
2024-06-20 15:26:37 +01:00
Greg Johnston
80bbb20089 Merge pull request #2631 from leptos-rs/2610
fix `rkyv` feature interaction with Axum integration
2024-06-14 15:10:26 -04:00
Greg Johnston
33e7ed83cc fix: specify correct serialization trait in server fn handler (closes #2610) 2024-06-14 14:20:50 -04:00
Greg Johnston
dcaa1df63d fix: derive rkyv traits on ServerFnError 2024-06-14 14:19:54 -04:00
Oto Petřík
8606f3d928 fix: try_with should not panic on disposed resources (closes #2620) (#2621) 2024-06-12 20:19:44 -04:00
Thomas Versteeg
32e6ac7bb7 docs: remove duplicated code block in example of For (#2622) 2024-06-12 20:11:57 -04:00
ARSON
b22f3bb3bd fix: extract dyn_bindings impl into DynBindings trait (#2619) 2024-06-12 09:07:56 -04:00
Greg Johnston
00a42daa63 Merge pull request #2611 from leptos-rs/failing-ci
Fix failing CI
2024-06-02 15:39:58 -04:00
Greg Johnston
ec19c59850 chore: update hackernews_js_fetch example to latest versions of leptos and axum 2024-06-02 15:39:01 -04:00
Greg Johnston
b06097d085 chore(ci): fix wasm-pack installation 2024-06-02 15:38:22 -04:00
Greg Johnston
a59561f796 chore: clippy 2024-06-02 15:37:54 -04:00
Greg Johnston
96b448805d v0.6.12 2024-06-02 14:08:08 -04:00
Luxalpa
2ef27cb0bb fix: URL encoding issue (closes #2602) (#2601) 2024-06-02 14:06:41 -04:00
SleeplessOne1917
21a6551ce6 feat: allow slice! macro to index tuples (#2598)
* Allow slice! macro to index tuples

* Undo changes to component tests

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-05-29 09:07:41 -04:00
Mingwei Samuel
2f4fd87c05 feat: #[component] now handles impl Trait by converting to generic type params, fix #2274 (#2599)
Book needs to be updated to remove this line:
35c380ffc8/src/view/03_components.md (L233)
2024-05-29 09:06:52 -04:00
Hecatron
13ad1b235d projects: example using the bevy 3d game engine and leptos (#2577)
* feat: Added example using the bevy 3d game engine and leptos

* fix: moved example to projects

* workspace fix
2024-05-27 15:55:27 -04:00
David Pitoniak
a2c7e23d54 docs: grammar typo for MultiActon doc comment (#2589) 2024-05-11 15:05:35 -04:00
Greg Johnston
9e65f71db4 fix: only issue NodeRef warning in debug mode (necessary to compile in --release) (#2587) 2024-05-11 15:05:17 -04:00
Luxalpa
7f4a2926c1 fix: StoredValue and Resource borrowMut error during dispose (#2583) 2024-05-11 15:04:57 -04:00
Hecatron
7c5203db19 examples: counter with DWARF debugging (breakpoints and sourcemap) (#2563)
* feat: Added initial dwarf debug counter example

* fix: update to readme and launch.json, task.json

* fix: fix tasks.json for debugging

* fix: added Trunk.toml to fix the port

* fix: moved example to projects
2024-05-11 15:02:33 -04:00
Greg Johnston
3760ced0ec fix: allow temporaries as props (closes #2541) (#2582) 2024-05-08 19:35:57 -04:00
Greg Johnston
f3f3a053ba fix: don't insert empty child for comment/doctype (closes #2549) (#2581) 2024-05-08 07:19:57 -04:00
Antoine Büsch
6a8e4bb453 Fix empty_docs warnings in #[component] macro (#2574) 2024-05-06 22:09:19 -04:00
Luxalpa
20f4323e50 feat: allow customize derives for serverfn input struct (#2545) 2024-05-06 08:54:29 -04:00
martin frances
47bcee0ef4 docs: improve NodeRef warning (#2414) (#2467) 2024-05-06 08:51:32 -04:00
SleeplessOne1917
ac3b95d35a examples: use trunk's built-in way of handling tailwind (#2557)
* Use trunk built-in way of handling tailwind

* Remove package manager from package.json
2024-05-06 08:49:07 -04:00
Greg Johnston
a314a4fcd9 docs: clarify the purpose of local resources (#2543) 2024-05-06 08:48:29 -04:00
Sam Judelson
b2a77f06b9 projects: OpenAPI Utopia (#2556) 2024-05-06 08:48:09 -04:00
Sam Judelson
9741c41356 projects: added an index to projects README (#2555)
The Index gives a high level overview of the projects
2024-05-06 08:47:13 -04:00
Joey McKenzie
4e4a770600 projects: add sitemap demo project (#2553) 2024-05-06 08:46:49 -04:00
martin frances
289c02fdac Minor: examples/server_fns_axum FileWatcher logs errors to the console. (#2547)
* Minor: examples/server_fns_axum FileWatcher logs errors to the console.

The cause is an assumption that the directory

./watched_files/

exits.

* chore: Now using .gitkeep to preserve directory structure.
2024-05-06 08:45:27 -04:00
itowlson
123d95c34c Update leptos-spin-macro reference (#2570)
Signed-off-by: itowlson <ivan.towlson@fermyon.com>
2024-05-02 15:25:22 -07:00
Greg Johnston
da9711a743 docs: add caveats for ProtectedRoute (#2558) 2024-05-01 07:06:54 -04:00
Greg Johnston
9353316947 chore: create README for projects directory 2024-04-19 10:39:58 -04:00
Sam Judelson
2960dada4a docs: add projects directory with 4 projects (#2500) 2024-04-17 19:30:31 -04:00
kryesh
c1ebaf9d04 feat: add create_query_signal_with_options to leptos_router (#2517) 2024-04-17 19:23:33 -04:00
bicarlsen
9a7dbd50eb feat: ability to use multiple classes in view macro using array syntax. (#2532) 2024-04-17 19:04:33 -04:00
Ethan Niser
410225c4d1 docs: remove unnecessary type parameter and trait bound in component macro 'bad' example (#2520) 2024-04-17 18:53:18 -04:00
ARSON
8b1c0a7013 feat: spread component attrs (#2534)
* add `dyn_bindings` builder method to component

* Revert "add `dyn_bindings` builder method to component"

This reverts commit cdd5e0f682.

* add `dyn_bindings` builder method to component
2024-04-17 14:05:00 -07:00
0e4ef622
6e819737cd fix: make TextProp's IntoView and IntoAttribute impls reactive (#2518) 2024-04-17 14:02:52 -07:00
Adrian
c4560b7e76 Adding Russian book branch (#2516) 2024-04-17 13:22:32 -07:00
Greg Johnston
0d20f6aca8 chore: publish Oco separately as oco_ref crate so that it can be used elsewhere (#2536) 2024-04-16 20:25:34 -04:00
martin frances
158b0bd294 chore(ci): bump trunk-action to 0.5. (#2533) 2024-04-16 19:19:01 -04:00
Ben Wishovich
c8186eea13 Add id to ActionForm and MultiActionForm (#2535) 2024-04-16 14:52:51 -07:00
Greg Johnston
6141e73436 Merge pull request #2531 from leptos-rs/2523
fix: do not submit `<ActionForm>` on `formmethod="dialog"` submission (closes #2523)
2024-04-15 19:52:06 -04:00
Greg Johnston
03a56f8795 chore(ci): latest nightly 2024-04-15 18:33:06 -04:00
Greg Johnston
fe06c6b91b fix: do not submit <ActionForm> on formmethod="dialog" submission (closes #2523) 2024-04-15 16:49:02 -04:00
martin frances
9a51fb17fc Minor: Bumped serde_qs to 0.13. (#2512) 2024-04-14 14:39:44 -07:00
Sam Judelson
35a8ca1f39 Add beginner tip to ErrorBoundary (#2385)
* Add beginner tip to ErrorBoundary

This might seem simple, but the nuances of types and traits confuse many people learning the language.

* edit

* Update error_boundary.rs

* edits

* ignore error block
2024-04-14 14:38:08 -07:00
Ben Wishovich
1ff0a7176d Update spin_sdk to spin v3 (#2525)
* Update spin_sdk to spin v3

* Add id to Body
2024-04-14 14:34:38 -07:00
Greg Johnston
e29d31e686 0.6.11 2024-04-10 09:33:22 -04:00
Greg Johnston
e68f1bbad5 fix: stable Router IDs (closes #2514) (#2515) 2024-04-10 09:31:34 -04:00
Greg Johnston
454a4f4ccb Merge pull request #2511 from leptos-rs/simplify-stable
Simplify stable syntax in examples
2024-04-09 15:30:51 -04:00
Greg Johnston
85a91af7c6 examples: simplify stable syntax for using signals in view 2024-04-09 14:45:19 -04:00
Greg Johnston
871d2c1b9f feat: directly implement IntoView on resources on stable 2024-04-09 14:45:01 -04:00
Greg Johnston
f0c1061161 chore(ci): remove nightly feature on counter_isomorphic (#2510) 2024-04-09 13:18:37 -04:00
Greg Johnston
d74af819a0 fix: invalid Location header when using leptos_actix::redirect() without JS/WASM (#2507) 2024-04-08 20:10:09 -04:00
Ar4ys
36b2f919dd feat: signifiantly improved error reporting in view macro (#2289)
* Added name span to .build in component_to_tokens

* Added #[allow(unreachable_code)] to  leptos::component_view inside component_to_tokens

* Added span to name reference in component_to_tokens

* Added span to leptos::component_props_builder in component_to_tokens

* Added span to props in component_to_tokens

* Added span to "on" method in events component_to_tokens

* Added spans in directive_call_from_attribute_node

* Added spans in fragment_to_tokens and it's ssr version

* Added span to props in slot_to_tokens

* Added span to the whole slot quote

* Changed slots's name span to last slot node

* Added span to the slot vec

* Added #[allow(unreachable_code)] to `.into()` in slot_to_tokens

* Added span to `.build()` in slot_to_tokens

* Added span for the whole component

* Added span to "clone:" directive

* Added span to ".children()"

* Removed unused "_span" param from fragment_to_tokens and fragment_to_tokens_ssr

* Removed unnecessary parenthesis around values in `attribute_to_tokens`

* Removed unnecessary curly braces around value in `spread_attrs`

* Removed unnecessary parenthesis around children in `element_to_tokens`

* Added catch-all span to element_to_tokens

* Formatted `quote!` according to official guidelines

* Updated view/snapshots in leptos_macro

* Added span to spread props in element_to_tokens_ssr

* Removed unnecessary curly braces in element_to_token_ssr

* Updated view/snapshots in leptos_macro

* Added view macro tests to leptos_macro

* Fixed clippy warnings in view macro output

* Updated view snapshots in tests

* Fixed expected_one_let_bind_got_none test in leptos_macro

* Removed snapshot tests in leptos_macro/tests/ui/view

---------

Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
2024-04-08 08:14:33 -04:00
Greg Johnston
ab1c4ca7a6 chore(ci): run all examples under stable and fix remaining linting issue (#2503) 2024-04-05 16:09:23 -04:00
mahmoud-eltahawy
a1a989011a chore(ci): move all examples to run on stable (#2501) 2024-04-05 14:57:48 -04:00
Greg Johnston
43178b56dc chore(ci): move example CI over to stable (#2502) 2024-04-05 14:55:31 -04:00
Lukas Potthast
119c9ea23f feat: allow spreading of both attributes and event handlers (#2432) 2024-04-05 14:30:34 -04:00
Yann Dirson
fc537c14c4 feat: implement IntoView for Rc<str> (#2462)
With-help-from: Greg Johnston <greg.johnston@gmail.com>
Signed-off-by: Yann Dirson <ydirson@free.fr>
2024-04-05 09:58:35 -04:00
mahmoud-eltahawy
15f8bdd4dc stable todo_app_sqlite_axum example (#2493) 2024-04-04 20:12:45 -07:00
Sam Judelson
ca07d29db5 stable examples change (#2497) 2024-04-04 20:11:28 -07:00
Adrian
a82af6110f ex: counter_url_query; to stable (#2499) 2024-04-04 20:09:55 -07:00
Joseph Cruz
03ac6903f2 ci(examples/error-boundary): use stable syntax (#2496) 2024-04-04 20:08:50 -07:00
Joseph Cruz
e5af1456a6 fix(ci): false leptos changes detected (#2491) 2024-04-04 20:06:09 -07:00
mahmoud-eltahawy
8686d5aabb stable todomvc example (#2489) 2024-04-02 13:38:07 -07:00
Greg Johnston
c750f57ddc v0.6.10 2024-04-02 09:39:53 -04:00
Joseph Cruz
cc1f6f0a94 chore(ci): run semver checks on push (#2483) 2024-04-01 20:38:28 -04:00
Greg Johnston
a9034a92b0 fix: handle directives properly in SSR mode (closes #2488) (#2477) 2024-04-01 17:29:30 -04:00
zakstucke
9f1c09e131 feat: add View::on support for CoreComponent::{DynChild, Each} (#2422) 2024-04-01 17:09:05 -04:00
Greg Johnston
b79037b96f fix: correctly handle empty view! {} in hot-reloading code (closes #2421) (#2478) 2024-04-01 16:23:29 -04:00
Greg Johnston
41f3c46830 chore: bump nightly version in examples (#2479) 2024-04-01 15:16:53 -04:00
Greg Johnston
bfac4cba2a chore: cargo fmt 2024-03-31 14:12:33 -04:00
Paolo Barbolini
3e18edb8f9 chore: add repository field to server_fn_macro (#2474) 2024-03-31 14:10:47 -04:00
Joseph Cruz
e926ff24a6 ci: disable semver checks (#2471) 2024-03-30 20:05:20 +00:00
Gunnar Raßmann
d528cbd828 Fix: Environment variables do not overwrite Config.toml options (#2433)
* Fix environment variable parsing

* Fix failing tests

dfgdfgfd

dsf

* Add new test
2024-03-30 00:02:52 +00:00
Alex Lazar
642504f2ba Remove panic for axum ResponseOptions (#2468) 2024-03-29 07:37:12 +00:00
zakstucke
fd2817de26 Allow CDN_PKG_PATH at runtime as well as current build time, preferring it when available. (#2466) 2024-03-28 08:30:54 +00:00
Bart Toersche
73b8c7872e Fix: Small fix for location hash/fragment (#2464) 2024-03-27 06:45:29 +00:00
martin frances
f3d19ca744 Minor: Ran cargo clippy --fix (#2461)
Manually reviewed the changes. All look like reasonable nudges.

A summary :-

In one place removed a redundant call to .clone().

In two places, now using clone_from() which clippy says
**MAY** be an optimisation.
2024-03-23 18:27:31 -07:00
boyswan
0abcc348ca Persist parent span context within resource fetchers (#2456) 2024-03-22 15:51:50 -07:00
Joseph Cruz
572ae5bbdf test(ci): check semver (#2450)
* test(ci): check semver

* chore: simulate change

* fix(ci): add checkout

* fix(ci): version typo

* chore: remove simulated change
2024-03-22 15:51:13 -07:00
martin frances
0b70949118 Bumped base64 to 0.22. (#2457) 2024-03-22 15:07:04 -07:00
martin frances
5819014ccc Chore(ci) bumping tj-actions/changed-files to version 43. (#2454) 2024-03-22 07:23:57 -04:00
Joseph Cruz
630fd4570d fix(ci): trunk command not found (#2453)
* chore: simulate change

* chore: remove print trunk version

* Revert "chore: remove print trunk version"

This reverts commit c203a83b44.

* chore(ci): use jetli/trunk-action

* chore: remove simulated change
2024-03-22 07:23:48 -04:00
Ratul
d1560f9e1f Added missing link for #[server] macro (#2437)
* Added missing link for #[server] macro

Added missing link for #[server] macro

* Removed spurious entry
2024-03-20 14:24:54 -07:00
martin frances
841d7a690a chore: examples/tailwind_axum bumped tailwindcss to 3.4.2. (#2443) 2024-03-19 09:40:24 -07:00
sify21
104c09f3bf register server_fn first to allow for wildcard Route path (#2435)
It's normal to have a `NotFound` page with a wildcard path like this
```
<Routes>
    ...
    <Route path="*any" view=NotFound>
</Routes>
```
In `ssr` mode, most servers do a `first match win` approach, so we
should register server functions before view routes, or else a wildcard
route would block all api requests.

https://discord.com/channels/1031524867910148188/1218508054442545185

Signed-off-by: 司芳源 <sify21@163.com>
2024-03-19 09:37:42 -07:00
Joseph Cruz
ac75999c9f chore(ci): upgrade actions to node 20 (#2444)
* chore(ci): install jq with apt

* chore(ci): install trunk with cargo

* chore(ci): replace toolchain action

* chore(ci): upgrade pnpm cache action

* chore: simulate change

* fix(ci): pnpm cache action typo

* chore: remove simulated change
2024-03-19 09:36:30 -07:00
Richard Laughlin
7ef186f642 For the session_auth_axum example, move the passhash into a separate (#2446)
non-serializable struct.

This prevents it from being returned in the
get_user() API, and prevents it from being unintentionally returned on any
new API the end-user may create on top of this example code.
2024-03-19 09:35:53 -07:00
Joseph Cruz
fda4dba237 build(examples): clean more output (#2420)
* chore(examples): update workspace members

* build(examples): clean e2e crates

* build(examples): clean pkg directories

* chore: remove simulated change comment

* chore: add simulated change

* chore: remove simulated change
2024-03-18 11:58:37 -04:00
Roland Fredenhagen
4e578e335b chore: update attribute-derive (#2438) 2024-03-18 11:39:34 -04:00
Joseph Cruz
97fd8ff6c4 fix(ci): leptos examples fail with bindgen schema error (#2428) 2024-03-13 22:33:54 -04:00
battmdpkq
4faf3fa894 chore: fix types in some comments (#2413)
Signed-off-by: battmdpkq <cmaker@163.com>
2024-03-09 07:38:25 -05:00
Greg Johnston
480d741749 chore: update to gloo-net 0.5 (closes #2411) (#2416) 2024-03-08 15:22:12 -05:00
Álvaro Mondéjar
7928f61401 chore: add lint to disallow prints to stdout (#2404) 2024-03-08 13:18:37 -05:00
Giovanni
2b4f5e0f58 docs: runtime error if setting the same event listener 2x rather than silent failure (#2383)
Delegated event listeners do not support adding more than one event listener of the same type. This can cause confusion if two listeners are added, as one is silently dropped.
2024-03-07 16:49:23 -05:00
Giovanni
943a992570 fix: re-throw errors in delegated event listeners (#2382) 2024-03-07 16:48:21 -05:00
ARSON
372a241d78 feat: allow #[prop(attrs)] on slots (#2396) 2024-03-04 17:34:21 -08:00
Chris Biscardi
c06f6bede2 fix: remove erroneous debug println!()s in islands (#2402) 2024-03-04 06:56:18 -05:00
benwis
3e93a686f4 Fix and release deps 2024-03-03 17:04:34 -08:00
benwis
34cdff4cb3 Update deps in one crate to 0.6.8 2024-03-03 17:02:50 -08:00
John Lewis
530087d77d Add MessagePack codec (#2371)
* feat: added messagepack codec

* fix: deserialize msgpack from bytes, not string
2024-03-03 13:54:23 -08:00
martin frances
4bb43f6207 examples/todomvc - Rename Todos::new() Todos::default(). (#2390) 2024-03-03 13:48:40 -08:00
benwis
9e2fb62857 0.6.8 2024-03-02 18:01:10 -08:00
Ben Wishovich
1da2fff706 Fix missed stuff (#2398) 2024-03-02 17:57:20 -08:00
Greg Johnston
9fd2987447 fix: correctly reset hydration status in islands mode Suspense (closes #2332) (#2393) 2024-03-02 11:57:35 -05:00
zroug
7996f835d0 fix: remove unnecessary trait bound PartialEq from create_owning_memo (#2394) 2024-03-02 07:27:22 -05:00
Greg Johnston
d72b12524e Merge pull request #2395 from leptos-rs/int-ax-doc 2024-03-01 20:08:18 -05:00
Greg Johnston
8e79c5be5c fix: ignore as with other doctests for now 2024-03-01 18:39:55 -05:00
Greg Johnston
de25658c36 Merge pull request #2392 from paul-hansen/fix-ci
fix(ci): "needless borrow" error and example never exiting
2024-03-01 18:37:48 -05:00
Paul Hansen
e2e35a9659 fix(ci) Wait a bit longer for server to start
It took longer than I thought in Github and barely worked, giving it a
bit more of a buffer.
2024-03-01 15:47:59 -06:00
Paul Hansen
bf1ba589c5 fix(ci): Another attempt to fix hanging example 2024-03-01 15:41:22 -06:00
Sam Judelson
f70ebc1289 docs: add note on how to get ResponseOptions (#2380) 2024-03-01 10:47:02 -05:00
Paul Hansen
3cab09e015 fix(ci): error_boundary example never exiting 2024-03-01 09:21:58 -06:00
Paul Hansen
b431315f7c fix(ci): "needless borrow" error 2024-03-01 09:21:58 -06:00
Baptiste
5b40881e77 fix: specify path to wasm_bindgen in island macro (#2387) 2024-03-01 10:15:19 -05:00
benwis
59d3cce3be 0.6.7 2024-02-29 13:38:09 -08:00
Paul Hansen
6a83161368 chore: add MSRV (#2360) 2024-02-28 07:19:09 -05:00
Marc-Stefan Cassola
4b00c16cb9 added hashes generated from cargo-leptos (#2373)
* added hashes generated from cargo-leptos

* Added config option to disable frontend file name hash
2024-02-27 16:28:27 -08:00
haslersn
6d6019b956 fix: do not strip query in redirect hook when using client-side navigation (#2376) 2024-02-27 09:06:48 -08:00
Sam Judelson
3540291065 docs: Resource::read() in doc examples with Resource::get() (#2372) 2024-02-26 21:37:29 -05:00
zoomiti
4809cf473e feat: provide leptos_router::Method via context (#1808) (#2315) 2024-02-26 21:25:53 -05:00
Tadas Dailyda
aa977001c1 feat: add support for trailing slashes (closes #2154) (#2217) 2024-02-26 20:56:44 -05:00
Greg Johnston
c16189f095 Merge pull request #2362 from leptos-rs/remove-deprecation
chore(ci): fix failing CI by removing deprecation note
2024-02-24 13:05:02 -05:00
Greg Johnston
d0a013c248 chore(ci): omit a few feature flag in CI 2024-02-24 11:55:36 -05:00
Greg Johnston
531ea74e33 chore: cargo fmt in leptos_macro 2024-02-24 07:12:46 -05:00
Greg Johnston
545e87e540 chore(ci): fix failing CI by removing deprecation note 2024-02-24 07:07:31 -05:00
Joseph Cruz
2ca30a0b2d ci(examples): build hackernews_js_fetch with deno (#2344)
* ci(examples): refactor process management

* ci(examples): build hackernews_js_fetch with deno

* ci(workflows): detect hackernews_js_fetch change

* chore(web-report): report deno usage

* chore(web-report): ignore gtk example

* ci(todo_app_sqlite): simulate change

* ci(workflows): install deno

* ci(todo_app_sqlite): remove simulated change
2024-02-23 13:40:44 -05:00
zoomiti
753bf1ed54 Fix Broken Doc links and Deprecate FromUtf8Error in oco.rs (#2318)
* fix: deprecate `FromUtf8Error` in `oco.rs`

* chore: fix broken doc links (#859)

* chore: fix broken doc link to server attribute macro

* cargo fmt
2024-02-21 19:24:40 -08:00
Sam Judelson
37c6387fea finish doc sentence (#2348) 2024-02-21 19:21:57 -08:00
Janu (Janeshwar) Cambrelen
0a73487152 feat(leptos-axum): propagate trace context to server functions (#2340) 2024-02-21 19:21:00 -08:00
Sam Judelson
747aba0d7f add comment specifying edgecase of server function prefixes (#2345) 2024-02-20 18:17:20 -08:00
Sam Judelson
04cf47d5da Update suspense_component.rs documentation to use .get() instead of .read() (#2346) 2024-02-20 18:16:03 -08:00
rjmac
47abe00993 fix: don't leak canceled timeouts (#2331)
Instead of using `Closure::once_into_js`, this uses `into_js_value`,
which uses weak references to clean up the closure when Javascript no
longer has need of it.

It would be nice to make this (and the similar interval function) drop
the callback promptly when cancelled, but I don't think that's
possible while keeping the handles Copy.

Fixes #2330

Co-authored-by: Robert Macomber <robertm@mox>
2024-02-19 21:17:26 -05:00
eliza
aa3700ffb9 feat: add impl_from argument to #[server] proc_macro (#2335)
* Add `impl_into` argument

* Add `impl_into` argument

* Revert unneeded changes

* Address review comments

Rename `impl_into` back to be `impl_from`
Rework docstring

* Fix typo in docstring
2024-02-19 21:16:46 -05:00
Aphek
0770b87cb7 feat: Add owning memos to allow memos that re-use the previous value (#2139) 2024-02-19 21:16:19 -05:00
benwis
330ebdb018 v0.6.6 2024-02-19 13:48:32 -08:00
benwis
c3179d88cf Moved leptos-spin-macro dep to released version 2024-02-19 12:54:43 -08:00
Sahaj
ffcf3c2952 example: fix href path in tailwind_csr example (#2328) 2024-02-17 13:10:07 -05:00
haslersn
001ca5148e fix: handle cross-origin redirects in server function redirect hook (#2329)
In client-side navigation we now handle redirects returned from
server functions by resolving the location against the current
origin as a base. The base is only relevant if the location
doesn't already include an origin. This fixes cross-origin
redirects.

Note: in order to handle redirects in the same way as the browser
would handle them, we need to use the server function's URL
(typically `<origin>/api/something`) as a base. I leave this as
a TODO for a future leptos version, because it probably
requires changing the signature of the `server_fn` redirect hook.

In order to not be affected by a future breaking change, users
should already start making sure that their redirect locations
either include an origin or at least start with a single slash
(e.g. `Location: /foo`).
2024-02-17 13:09:39 -05:00
Greg Johnston
1e000afa78 examples: fix CSS file name in tailwind_axum (#2324) 2024-02-17 12:56:03 -05:00
Greg Johnston
0f7b8841b2 chore(ci): reduce set of tested features to prevent running out of disk space in server_fn (#2320) 2024-02-16 20:26:26 -05:00
Greg Johnston
7dc0441f6c docs: log error on failing to convert form to ServerFn type, in addition to setting action value (#2319) 2024-02-16 17:11:14 -05:00
Joseph Cruz
0a321a1bd7 docs(examples): update docs (#2313)
* docs(examples): fix metadata typo

* docs(examples): update first step about using cargo make
2024-02-16 13:32:01 -05:00
Greg Johnston
88742952f0 fix: Transition in hydrate mode that isn't initially created (closes #2279) (#2314) 2024-02-16 08:16:09 -05:00
martin frances
8a4b972e0b chore: bump config to 0.14 (#2302) 2024-02-15 20:24:12 -05:00
zoomiti
95bd9cc544 feat: use CDN_PKG_PATH at build time to set alternate base URL for JS/WASM bundles (#2281) (#2283) 2024-02-15 20:21:47 -05:00
Marc-Stefan Cassola
23bc892a24 fix: #[server] macro error type detection (#2298)
In most cases when you return `Result<..., ServerFnError<E>>` this worked but when you tried
`Result<..., leptos::ServerFnError<E>>` then it didn't.
2024-02-15 20:20:41 -05:00
Esteban Borai
830fba794e docs: add missing provide_meta_context() in example (#2311)
Otherwise user gets:

```
use_head() is being called without a MetaContext being provided. We'll automatically create and provide one, but if this is being called in a child route it may cause bugs. To be safe, you should provide_meta_context() somewhere in the root of the app.
```
2024-02-15 20:19:07 -05:00
martin frances
98633c8700 chore(ci): update node version for GitHub Actions (#2303) 2024-02-15 20:17:12 -05:00
David Rebbe
b0f5c39711 example: replace yanked version of session_auth_axum crate (#2310) 2024-02-15 20:16:26 -05:00
Greg Johnston
b54aa7f3f5 Merge pull request #2294 from agilarity/add-cargo-make-leptos 2024-02-15 18:52:37 -05:00
Sam Judelson
e33ee7ec99 pub export server is either from leptos_macro or leptos_spin_macro depending on if spin feature is enabled. (#2280)
* leptos spin server macro

* leptos spin

* git chng

* based on the fermyon official git for when that works
2024-02-15 14:37:19 -08:00
Joseph Cruz
cd70b2f52b fix(ci): should exclude cargo-make 2024-02-11 20:40:20 -05:00
Joseph Cruz
c75842ed0c ci(hackernews_islands_axum): build with cargo leptos 2024-02-11 15:40:32 -05:00
Joseph Cruz
4ad228bf47 docs(test-report): add leptos ci warning 2024-02-11 15:40:32 -05:00
Joseph Cruz
bbe7115360 docs(test-report): mention options 2024-02-11 15:40:32 -05:00
Greg Johnston
0658a550b0 fix(examples): align crate name and output name (closes #2206) (#2291) 2024-02-10 15:47:25 -05:00
Joseph Cruz
4222c832b1 fix(ci): empty directory vector error (#2288)
* fix(ci): empty directory vector error

* chore(ci): simulate example change

* chore(ci): remove simulated example change
2024-02-10 10:02:21 -08:00
Greg Johnston
dfddbd6bf9 docs: give a warning when you try to .dispatch() an action immediately (closes #2225) (#2286) 2024-02-09 20:55:10 -05:00
Greg Johnston
8a77691cb5 Merge pull request #2285 from leptos-rs/fix-issues
Fix remaining CI issues
2024-02-09 19:29:01 -05:00
Greg Johnston
1dbe8b2d4b fix: correct feature name for server-fn-macro crate (broken in #2270) 2024-02-09 17:18:44 -05:00
Greg Johnston
fe64f0d332 examples: fix counter_isomorphic (broken in #2244) and fix additional warnings 2024-02-09 17:12:31 -05:00
Joseph Cruz
c00207aa46 fix(test-report) should show all cargo-make leptos configuration (#2282)
* refactor(test-report): extract script
* refactor(test-report): extract functions
* refactor(test-report): split option to tasks
* chore(test-report): highlight examples without tags
* fix(test-report): show all cargo-make leptos configuration
* docs(test-report): update keys
* chore(test-report): include all crates in report
2024-02-09 16:31:46 -05:00
Joseph Cruz
65b7603192 fix(ci): address clippy issue (#2278)
* fix(ci): address clippy issue
* fix(ci): add missing nightly specifications
* fix(ci):  set all nightly references
* chore(ci): do not lint example crates
2024-02-09 16:30:11 -05:00
haslersn
d4bdc36062 fix: add key/value pair from submit button when parsing form event (#2268) 2024-02-07 11:09:01 -05:00
Sam Judelson
1b55227d10 fix: remove unnecessary default features on axum in server_fns to support running Axum in a WASM environment (#2270) 2024-02-07 11:08:48 -05:00
Saikat Das
a903e19eb2 chore: fix typo (#2267) 2024-02-06 17:55:35 -05:00
blorbb
38bf73947f fix: make directive .into() calls consistent (#2249) 2024-02-05 08:52:12 -05:00
Greg Johnston
e4b89ba243 Merge pull request #2262 from leptos-rs/2261
fix: guarantee execution order of effects (closes #2261)
2024-02-05 08:51:23 -05:00
Greg Johnston
701e3077fb chore: cargo fmt 2024-02-05 06:38:02 -05:00
Greg Johnston
aec4d680aa fix: guarantee execution order of effects (closes #2261) 2024-02-05 06:35:57 -05:00
Steffen
06721c5fcd examples: fix typos in examples (#2260) 2024-02-05 05:20:53 -05:00
SleeplessOne1917
1ddb39e9bd docs: typo in actix integrations docs (#2258)
Co-authored-by: SleeplessOne1917 <insomnia-void@protonmail.com>
2024-02-04 20:57:51 -05:00
Chris
15d4ca0638 feat(axum): provide state to server fn context (#2257)
Note that this is a minimal implementation and will __not__ allow the
user to `expect_state` if they have external calls to rendering their
app (i.e. using `render_app_to_*` directly).
2024-02-04 19:26:21 -05:00
zoomiti
85c3755f6d fix: bug with percent decoding of url params (#2251) 2024-02-04 19:24:02 -05:00
Sam Judelson
66ea072bc0 docs: a note to HtmlElement<El> about Deref (#2218) 2024-02-04 15:34:39 -05:00
Joris Hartog
b0b3c21285 docs: fix broken link in leptos_router (#2256) 2024-02-04 15:29:34 -05:00
Greg Johnston
56088a9ead fix: error rather than panicking if unable to send response in Axum integration (#2241)
* fix: error rather than panicking if unable to send response in Axum integration
2024-02-03 19:18:41 -05:00
martin frances
69d25d9c63 examples/hackernews: Add a "Suspense" wrapper. (#2253)
This warning appears in the browser's console log.

```
hackernews.js:933 At src/routes/stories.rs:39:17, you are reading a resource in `hydrate` mode outside a <Suspense/> or <Transition/>. This can cause hydration mismatch errors and loses out on a significant performance optimization. To fix this issue, you can either:
1. Wrap the place where you read the resource in a <Suspense/> or <Transition/> component, or
2. Switch to using create_local_resource(), which will wait to load the resource until the app is hydrated on the client side. (This will have worse performance in most cases.)
```
2024-02-03 14:24:46 -08:00
martin frances
5029b8f315 Chore: Minor, ran ``cargo fmt`` (#2254) 2024-02-03 14:24:12 -08:00
martin frances
0cba7bc22b example/counter_isomorphic Removed console warning. (#2244)
This warning is seen in the browsers console window.

```
counter_isomorphic.js:1068 At src/counters.rs:138:17, you are reading a resource in `hydrate` mode outside a <Suspense/> or <Transition/>. This can cause hydration mismatch errors and loses out on a significant performance optimization. To fix this issue, you can either:
1. Wrap the place where you read the resource in a <Suspense/> or <Transition/> component, or
2. Switch to using create_local_resource(), which will wait to load the resource until the app is hydrated on the client side. (This will have worse performance in most cases.)
```

Two derived signals "value" and "error_msg" need to be wrapped in a <Suspense> block.

"value" falls back to just the initial text.
"error" uses the default fallback.
2024-02-01 16:50:15 -08:00
Michael Kadziela
fb97c50886 Update rkyv example button text to accurately reflect what it does (#2250) 2024-02-01 16:49:29 -08:00
Greg Johnston
f1bc734dcf 0.6.5 2024-01-31 19:40:41 -05:00
Greg Johnston
f71b4aae69 feat: easily create custom server fn clients (#2247) 2024-01-31 09:15:30 -05:00
Greg Johnston
a834c03974 fix: bug with Actix redirects (#2246) 2024-01-31 09:14:40 -05:00
Greg Johnston
595013579c 0.6.4 2024-01-30 09:17:52 -05:00
Greg Johnston
8b1bd1ae9e Merge pull request #2240 from leptos-rs/err-serialization
fix: serialization error during SSR on ServerFnError
2024-01-29 16:32:55 -05:00
Greg Johnston
6ef1531059 example: file upload with streaming progress bar (#2242) 2024-01-29 15:20:19 -05:00
Greg Johnston
9f1406250e chore: update deprecated .remove() method on IndexSet 2024-01-29 11:32:15 -05:00
Greg Johnston
1f6a892291 fix: serialization error during SSR on ServerFnError 2024-01-29 10:36:08 -05:00
Greg Johnston
0ff1e279a2 fix: correctly track source in create_local_resource (#2238) 2024-01-28 10:09:03 -08:00
Chris
c6096cc2a0 chore: define edtion = "2021" in rustfmt.toml (#2235) 2024-01-27 16:04:25 -08:00
Greg Johnston
8a2ae7fc7c \v0.6.3\ 2024-01-26 21:00:21 -05:00
Greg Johnston
9de34b74cf 0.6.2 2024-01-26 18:07:04 -05:00
Greg Johnston
1b5961edaa fix: fix type inference on extract() functions (#2233) 2024-01-26 17:54:42 -05:00
Greg Johnston
26d1aee9ad Update README.md framework comparisons (#2232) 2024-01-26 17:01:26 -05:00
benwis
2bf09384df 0.6.1
Signed-off-by: benwis <ben@celcyon.com>
2024-01-26 12:32:14 -08:00
benwis
ac12e1a411 0.6.0
Signed-off-by: benwis <ben@celcyon.com>
2024-01-26 11:54:07 -08:00
Greg Johnston
b367b68a43 fix: use #[server(default)] to pass use default values for a field (#2231) 2024-01-26 14:46:31 -05:00
Greg Johnston
1f9dad421f fix: allow paths to ServerFnError type (#2230) 2024-01-26 11:32:43 -08:00
Greg Johnston
4648fb2cfc Update README.md 2024-01-25 20:34:15 -05:00
Saber Haj Rabiee
817ec045f7 chore: fix import of quote::quote (#2227) 2024-01-25 17:48:41 -05:00
Greg Johnston
ca3806e6bc v0.6.0-rc1 2024-01-24 21:35:14 -05:00
Greg Johnston
936c2077c3 Merge pull request #2222 from leptos-rs/2221
fix: `.refetch()` should not include any tracked reads
2024-01-24 20:44:51 -05:00
Greg Johnston
b3b18875c6 chore: allow unknown lints 2024-01-24 19:43:28 -05:00
Greg Johnston
5cbab48713 chore: avoid possible false positive in cargo check 2024-01-24 19:38:16 -05:00
Greg Johnston
5a8880dd2e fix: correctly track in the effect that creates the resource 2024-01-24 16:18:45 -05:00
Greg Johnston
ea6c957f3d fix: .refetch() should not track any reads (closes #2221) 2024-01-23 11:08:50 -05:00
Greg Johnston
694e5f1cb3 fix: cast to correct type on Memo::try_with_untracked 2024-01-23 11:08:33 -05:00
Greg Johnston
fce2c727ab feat: add support for custom encodings to #[server] macro (#2216) (closes #2210) 2024-01-21 16:14:02 -05:00
Greg Johnston
7d1ce45a57 chore: minimize features activated with leptos_axum's default feature (#1846) (#2213)
- `leptos_axum` default feature:
  - remove `tokio/full`, `axum/macros`
  - add `tokio/fs`, `tokio/sync`
- example `leptos-tailwind-axum`:
  - enable `tokio`'s `rt-multi-thread` and `macros` features
- example `ssr_modes_axum`:
  - enable `tokio`'s `rt-multi-thread` and `macros` features

Co-authored-by: Paul Nettleton <paulnett7@hotmail.com>
2024-01-21 15:22:46 -05:00
Niklas Eicker
997b99081b change: for static routes, remove .static and provide additional context for static_params closures (#2207) 2024-01-21 13:33:05 -05:00
Chris
d33e57d4b7 feat: Default for LeptosOptions, ConfFile (#2208)
Co-authored-by: chrisp60 <gh@cperry.me>
2024-01-21 13:26:10 -05:00
Greg Johnston
b450f0fd10 fix: don't enable tracing feature on leptos by default (#2211) 2024-01-20 17:58:22 -05:00
Greg Johnston
c84c6ee8cd Merge pull request #2158 from leptos-rs/leptos_v0.6 2024-01-20 15:58:25 -05:00
Greg Johnston
567644df8f clarify docs here 2024-01-20 14:29:22 -05:00
Greg Johnston
39f5481b8c clean up in docs and rename Axum extract() to match Actix extract() 2024-01-20 14:29:08 -05:00
Greg Johnston
c88bfbe0a0 tweak sets of features for CI 2024-01-20 14:18:25 -05:00
Greg Johnston
40da1fe94e clippy 2024-01-20 14:16:13 -05:00
Greg Johnston
8df46fcdb9 examples: use old Axum version of hackernews_js_fetch until supported by axum-js-fetch 2024-01-20 12:39:16 -05:00
Greg Johnston
b4a1d90327 clean up for CI 2024-01-20 12:32:51 -05:00
Chris
d746f83387 docs: View::render_to_string panic (#2200)
Co-authored-by: chrisp60 <gh@cperry.me>
2024-01-19 17:07:39 -08:00
Greg Johnston
2092c40bc7 missing derives 2024-01-19 18:21:57 -05:00
Greg Johnston
70ec0c2d0a update sso example 2024-01-19 18:02:22 -05:00
Greg Johnston
eb45d05f3b clippy 2024-01-19 17:43:05 -05:00
Greg Johnston
f19def9541 clippy 2024-01-19 16:55:16 -05:00
Greg Johnston
ddda785045 fix multipart support 2024-01-19 16:52:41 -05:00
Greg Johnston
26d9d75cf2 cargo fmt 2024-01-19 15:56:57 -05:00
Greg Johnston
46e7abf9ba allow custom req/res/client types 2024-01-19 15:48:14 -05:00
Greg Johnston
1b1e02729e clean up examples 2024-01-19 15:17:17 -05:00
Greg Johnston
fdd576535a clean up examples 2024-01-19 15:14:39 -05:00
Greg Johnston
2a9e502893 fix rkyv deserialization 2024-01-19 15:03:21 -05:00
Greg Johnston
a519859a66 Revert "use &[u8] instead of Bytes for requests"
This reverts commit e179db1d42.
2024-01-19 14:37:03 -05:00
Greg Johnston
25120c0e9f fix streaming requests and clarify in docs 2024-01-19 14:17:26 -05:00
Greg Johnston
94cb4c0ec3 remove pavex work (now in pavex branch) 2024-01-19 14:17:26 -05:00
Greg Johnston
f9cd8539e4 add missing PartialEq/Eq implementations on ServerFnError (closes #2198) 2024-01-19 14:17:26 -05:00
Greg Johnston
14072457d0 clean up docs (closes #2197) 2024-01-19 14:17:26 -05:00
Greg Johnston
e179db1d42 use &[u8] instead of Bytes for requests 2024-01-19 14:17:26 -05:00
Greg Johnston
2fa60103b4 share inventory collect across types 2024-01-19 14:17:26 -05:00
Greg Johnston
a3a15f244d expose all fields of ServerFnTraitObj via methods 2024-01-19 14:17:26 -05:00
Greg Johnston
0df5dfeaf8 weak dependency on Cargo.toml 2024-01-19 14:17:26 -05:00
Greg Johnston
3f22906053 fix warning 2024-01-19 14:17:26 -05:00
Greg Johnston
33ad30515d serde-lite support should be enabled directly on server_fn 2024-01-19 14:17:26 -05:00
Greg Johnston
c5bab09423 partial support for streaming requests (doesn't actually work in the browser) 2024-01-19 14:17:26 -05:00
Greg Johnston
320179bc04 remove misleading warning 2024-01-19 14:17:26 -05:00
Greg Johnston
5065bed594 example of middleware that can run before and/or after server fn 2024-01-19 14:17:26 -05:00
Greg Johnston
22b4537f27 fix version numbers 2024-01-19 14:17:26 -05:00
Greg Johnston
8d23d5136a add package metadata 2024-01-19 14:17:25 -05:00
Greg Johnston
c7fac64054 fix merge error 2024-01-19 14:17:25 -05:00
Greg Johnston
047235e7c1 clippy 2024-01-19 14:17:25 -05:00
Greg Johnston
7a086ad159 update version number 2024-01-19 14:17:25 -05:00
Greg Johnston
bb923b3f9b erroneous hyphen 2024-01-19 14:16:59 -05:00
Greg Johnston
6a8c26a820 streaming example with filesystem watcher 2024-01-19 14:16:59 -05:00
Greg Johnston
21f8085851 add streaming/file watcher example 2024-01-19 14:16:59 -05:00
Greg Johnston
9a5a102ce3 add middleware to kitchen-sink example 2024-01-19 14:16:59 -05:00
Greg Johnston
4d602c21f8 example with custom errors 2024-01-19 14:16:59 -05:00
Greg Johnston
7d114c7414 file upload example 2024-01-19 14:16:58 -05:00
Greg Johnston
1f017a2ade hm custom encodings have orphan rule issues 2024-01-19 14:16:58 -05:00
Greg Johnston
35e8e74dcf get rkyv working and work on custom encoding example 2024-01-19 14:16:58 -05:00
Markus Kohlhase
4366d786ac Update login example (CSR only) (#2155) 2024-01-19 14:16:58 -05:00
Ari Seyhun
1777a4057a fix!: remove clone in Cow<'static, str> IntoView impl (#1946) 2024-01-19 14:16:58 -05:00
Greg Johnston
0571ebbc36 working on example 2024-01-19 14:16:58 -05:00
Greg Johnston
06c478b7cb feature-gate the form redirect stuff, and clear old errors from query 2024-01-19 14:16:58 -05:00
Greg Johnston
90ba3529e9 working on Axum version 2024-01-19 14:16:58 -05:00
Greg Johnston
13a2691806 working on server fn example 2024-01-19 14:16:58 -05:00
Greg Johnston
1ad7ee8a03 generalize error redirect behavior across integrations 2024-01-19 14:16:58 -05:00
Greg Johnston
88fee243a8 support setting server URL on either platform 2024-01-19 14:16:58 -05:00
Greg Johnston
5e08253521 get both client and server side working 2024-01-19 14:16:58 -05:00
Greg Johnston
cc6f65cd83 initial version of server action error handling without JS 2024-01-19 14:16:58 -05:00
Greg Johnston
9488114801 docs 2024-01-19 14:16:58 -05:00
Greg Johnston
b0cdeab906 remove old code 2024-01-19 14:16:58 -05:00
Greg Johnston
def4be80b2 docs 2024-01-19 14:16:58 -05:00
Greg Johnston
15b04a8a85 more docs 2024-01-19 14:16:58 -05:00
Greg Johnston
0a9cdba22e getting started on docs 2024-01-19 14:16:58 -05:00
Greg Johnston
1d1de4ac38 remove cfg-if from all examples 2024-01-19 14:16:58 -05:00
Greg Johnston
31b2b9e94c remove explicit handle_server_fns in most cases because it's now included in .leptos_routes() 2024-01-19 14:16:58 -05:00
Greg Johnston
8f07818687 nicer formatting, remove cfg-if 2024-01-19 14:16:58 -05:00
Greg Johnston
a5cbfa0aad remove viz integration (see #2177) 2024-01-19 14:16:58 -05:00
Greg Johnston
6c8e704fb3 smh 2024-01-19 14:16:58 -05:00
Greg Johnston
81fb5160e5 missing makefiles 2024-01-19 14:16:58 -05:00
Greg Johnston
2af0d3d781 update session_auth_axum 2024-01-19 14:16:58 -05:00
Greg Johnston
7f532cda70 update todo_app_sqlite_csrs 2024-01-19 14:16:58 -05:00
Greg Johnston
c7941f7639 clippy 2024-01-19 14:16:58 -05:00
Greg Johnston
61148026d1 allow type paths for input/output, and properly namespace built-in encodings 2024-01-19 14:16:58 -05:00
Greg Johnston
738eeefe73 chore: clear warnings 2024-01-19 14:16:18 -05:00
Greg Johnston
be084a5d1d remove list of magic identifiers, use rust-analyzer to help with imports instead 2024-01-19 14:16:18 -05:00
Greg Johnston
f5c007df7b use server fns directly in ActionForm and MultiActionForm 2024-01-19 14:16:18 -05:00
Rakshith Ravi
a1bd84f3dc feat: add serde-lite codec for server functions (#2168) 2024-01-19 14:16:18 -05:00
Rakshith Ravi
f6ce82c9d1 Fixed tests for server_fn (#2167)
* Fixed server_fn tests

* Changed type_name to TypeId

* Fixed handling of leading slashes for server_fn endpoint
2024-01-19 14:16:18 -05:00
Greg Johnston
853c080707 add missing server fn registration 2024-01-19 14:16:18 -05:00
Greg Johnston
f6b95e40f4 make sure endpoint names begin with a / 2024-01-19 14:16:18 -05:00
Greg Johnston
db1497b9c2 set version, input, etc. correctly 2024-01-19 14:16:18 -05:00
Greg Johnston
f53ac1a4ae remove unused var 2024-01-19 14:16:18 -05:00
Greg Johnston
5e6f4403ca set up redirects in Actix 2024-01-19 14:16:18 -05:00
Greg Johnston
4e3f1c834c handle client-side and server-side redirects correctly (in Axum) 2024-01-19 14:16:18 -05:00
Greg Johnston
566df034ff actually use server functions in ActionForm 2024-01-19 14:16:17 -05:00
Greg Johnston
fd97e2e027 Restore the previous full functionality of Form 2024-01-19 14:16:17 -05:00
Greg Johnston
c8fbee18c8 finished Actix support? 2024-01-19 14:16:17 -05:00
Greg Johnston
e1a9856ca9 more Actix work 2024-01-19 14:16:17 -05:00
Greg Johnston
60efaefff4 start Actix work 2024-01-19 14:16:17 -05:00
Greg Johnston
db4158f5c3 clear up warnings 2024-01-19 14:16:17 -05:00
Greg Johnston
af62d2e900 automatically include server function handler in .leptos_router() 2024-01-19 14:16:17 -05:00
Greg Johnston
c3e3ce7878 changes to get todo_app_sqlite_axum example working 2024-01-19 14:16:17 -05:00
Greg Johnston
dec17fc65b fix server actions and server multi actions 2024-01-19 14:16:03 -05:00
Greg Johnston
2dbc5899f3 cargo fmt 2024-01-19 14:16:03 -05:00
Greg Johnston
dd368a845c @ealmloff changes to reexport actix/axum 2024-01-19 14:16:03 -05:00
Greg Johnston
9c258219dd fix Actix implementation with middleware 2024-01-19 14:16:03 -05:00
Greg Johnston
6a1685936b fix rkyv 2024-01-19 14:16:03 -05:00
Greg Johnston
7d45e6bb13 clean up my mistake 2024-01-19 14:16:03 -05:00
Greg Johnston
8fae76828e FromStr-based lightweight ServerFnError deserialization 2024-01-19 14:16:03 -05:00
Greg Johnston
d5b9e84f36 properly gate inventory 2024-01-19 14:16:03 -05:00
benwis
197edebd51 Made some progress, started work on pavex integration as well 2024-01-19 14:16:03 -05:00
benwis
2a5c855595 It starts to compile! 2024-01-19 14:16:03 -05:00
benwis
c9627bfeb4 Setup folder structure as before. Got a cyclical dependency though 2024-01-19 14:16:03 -05:00
benwis
c7422cd96e First commit, checkpoint for cyclical dependency error 2024-01-19 14:15:51 -05:00
Daniel Santana
cadd217078 Update integration with support for axum 0.7 (#2082)
* chore: update to axum 0.7

Removed http, since it's included in axum, and replaced hyper by http-body-util, which is a smaller.

* chore: update samples to work with nre axum

Missing sessions_axum_auth, pending PR merge.

* chore: all dependencies update to axum 0.7

* chore: cargo fmt

* chore: fix doctests

* chore: Fix example that in reality doesn't use axum.

Fixed anyway.

* chore: more examples support for axum 0.7

* Small tweak
2024-01-19 14:13:55 -05:00
Greg Johnston
0c4cf5471d v0.5.7 2024-01-19 13:03:44 -05:00
Greg Johnston
dd0c349554 examples: update axum-session because old version was yanked (#2205) 2024-01-19 12:54:08 -05:00
Greg Johnston
dd5a0ae094 Merge pull request #2203 from leptos-rs/2201
fix: routing regressions caused by `trailing_slash` support
2024-01-19 12:14:20 -05:00
Greg Johnston
5cacb57283 chore: new clippy warnings 2024-01-19 11:14:36 -05:00
Greg Johnston
b356d3cd28 ci: add regression test for #2190 2024-01-19 10:29:30 -05:00
Greg Johnston
ae1de88916 Revert "Better handling for trailing slashes. (#2154) (#2172)"
This reverts commit 1eaf886481.
2024-01-19 10:27:38 -05:00
Greg Johnston
67dd188358 ci: add regression test for matching main page correctly in router example 2024-01-19 10:26:58 -05:00
Joseph Cruz
1d4772251a fix: ci stopped detecting leptos or example changes (#2194) 2024-01-17 18:58:21 -05:00
benwis
98f18e7c31 release: version 0.5.6 2024-01-16 16:57:07 -08:00
Greg Johnston
3f34d9bb23 fix: doc comments breaking server functions (closes #2190) (#2191) 2024-01-16 15:31:29 -05:00
Greg Johnston
44db400f6b chore: fix spin-sdk dependency 2024-01-15 17:11:50 -05:00
Greg Johnston
3a5730800c v0.5.5 2024-01-15 17:10:49 -05:00
Sam Judelson
041b86e6e5 sso_auth_session example (#2117)
* example draft

* fmt

* db delete

* db

* oops clippy

* clippy 2

* - nightly ?

* fmt

* - cargo all features?
2024-01-15 10:48:22 -08:00
Greg Johnston
d71feada7e change: change all tracing levels to trace to reduce verbosity (#2176) 2024-01-13 08:19:12 -08:00
Cody Casterline
1eaf886481 Better handling for trailing slashes. (#2154) (#2172)
* retain trailing slashes in paths but leave matching trail-slash-insensitive

* fix: Allow trailing slashes to remain in leptos_path.

* Better handling for trailing slashes. (#2154)

This adds a trailing_slash option to <Router> and <Route>.

By default, this option is backward compatible with current Leptos
behavior, but users can opt into two new modes for handling trailing
slashes.

* cargo fmt

* Fix redirect routes for wildcard patterns.

* Clippy fixies

* (Re)Reduce the scope of PossibleBranchContext's internals.

* Test real code, not copied code.

* Test TrailingSlash redirects.

* Fixes and more tests for matching "" && "/".

This path is the exception to the rule and *should* be treated
as equivalent regardless of its trailing slash.

* cargo fmt

---------

Co-authored-by: Tadas Dailyda <tadas@dailyda.com>
2024-01-11 13:51:31 -08:00
dependabot[bot]
c7da3998ba chore(deps): bump tj-actions/changed-files in /.github/workflows (#2180)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 39 to 41.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v39...v41)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-11 16:04:21 -05:00
Luxalpa
10bbeea697 fix: remember router state (fixes #2164) (#2165) 2024-01-10 19:51:37 -05:00
webmstk
2d70229608 chore: add rust-toolchain.toml to examples (closes #2151) (#2161) 2024-01-07 15:29:54 -05:00
Paul Hansen
bbcef811f4 chore: remove dead code in actix tailwind example (#2160) 2024-01-07 15:29:15 -05:00
Simon Bihel
f5bf539148 fix: allow multiple SSRed Leptos apps on same server (closes #1806) (#2135) 2024-01-07 15:28:50 -05:00
Greg Johnston
855a3c65c0 chore: remove newly-detected unused tuple fields (#2169) 2024-01-06 18:25:20 -05:00
SleeplessOne1917
16cf3c4eaf feat: make IntoAttribute more flexible for Option<T: IntoAttribute> (#2130) 2023-12-30 13:10:07 -05:00
Greg Johnston
da533ad4e0 chore: clarify cargo-make and examples (see #2141) (#2150) 2023-12-30 08:14:23 -05:00
JackSpagnoli
b4a9db51be chore: fix broken tailwind example repo link (#2138) 2023-12-28 20:07:49 -05:00
Greg Johnston
15946c6136 fix: emit original token stream when there are syntax errors in #[component] or #[island] function signature (closes #2133) (#2134) 2023-12-25 14:30:31 -05:00
Greg Johnston
9f4c480725 docs: specify form for component generics (#2129) 2023-12-23 07:36:28 -05:00
Greg Johnston
74f9c3cd82 fix: <Transition/> fallback should show if client-rendered (closes #2123) (#2128) 2023-12-22 17:10:09 -05:00
martin frances
34fb39c976 chore: fix lifetime on example (#2125)
```bash
cd leptos/leptos_macro/example
cargo clippy
```

warning: the following explicit lifetimes could be elided: 'a
  --> src/lib.rs:41:20
   |
41 | fn TestMutCallback<'a, F>(mut callback: F, value: &'a str) -> impl IntoView
   |                    ^^                              ^^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
   = note: `#[warn(clippy::needless_lifetimes)]` on by default
help: elide the lifetimes
   |
41 - fn TestMutCallback<'a, F>(mut callback: F, value: &'a str) -> impl IntoView
41 + fn TestMutCallback<F>(mut callback: F, value: &str) -> impl IntoView
   |

warning: `example` (lib) generated 1 warning (run `cargo clippy --fix --lib -p example` to apply 1 suggestion)
2023-12-20 19:10:59 -05:00
martin frances
ea80a21a54 chore: remove duplicate itertools versions (#2124)
The root cause is the family of leptos modules requiring both versions 0.10.5 and 0.11.0
This PR will fix that. ( Also needs a bump to 0.12.0 )

```
warning: multiple versions for dependency `itertools`: 0.10.5, 0.11.0
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
note: the lint level is defined here
 --> src/lib.rs:4:9
  |
4 | #![warn(clippy::cargo)]
  |         ^^^^^^^^^^^^^
  = note: `#[warn(clippy::multiple_crate_versions)]` implied by `#[warn(clippy::cargo)]`
```
2023-12-20 19:10:00 -05:00
Greg Johnston
33590d487b chore: clean up warnings causing CI issues (#2119) 2023-12-18 08:15:46 -05:00
Rakshith Ravi
880002de31 fix: pass through doc comments for server fns (#2099) 2023-12-17 20:40:22 -05:00
Niklas Eicker
fb0a62f3f6 fix: support additional context for route generation (#2113) 2023-12-17 20:37:27 -05:00
Greg Johnston
a4bd7c4274 chore: don't warn when stabilized features are used (#2118) 2023-12-17 20:34:32 -05:00
NKID00
8122941c3c fix: let mount_to_body accept FnOnce closures (closes #2115) (#2116) 2023-12-17 20:28:18 -05:00
Gentle
21f4c27cfb chore: add nix-darwin support, update flake (#2106)
Co-authored-by: Gentle <ramon.klass@gmail.com>
2023-12-14 09:42:07 -05:00
Simon Richard
b578ec82d7 examples: change output names to clarify Tailwind examples (#2102) 2023-12-11 20:25:10 -05:00
jo!
50432e2651 examples: ergonomic improvements to session_auth_axum (#2057)
I've always hated the get_todos function and I
wanted to change it badly. Added a .env file
containing the db url for sqlx-cli, and cleaned
up with leptosfmt

Co-authored-by: j0lol <me@j0.lol>
2023-12-10 14:28:42 -05:00
Niclas Åhdén
fcc9242a63 docs: minor documentation corrections (#2098)
* Docs: Fix Body docs incorrectly referring to html

* Docs: Correct X/Z/Z to X/Y/Z in CONTRIBUTING
2023-12-10 14:24:16 -05:00
Greg Johnston
6014a70d0d fix: support complete URLs in <A/> and <Form/> (closes #2076) (#2096) 2023-12-01 19:20:43 -05:00
Trey Lowerison
ed61ea9dd2 feat: add support for placing attributes on server functions (#2093)
* fix: add support for placing attributes on server functions

Adding instrumentation to server functions is not straightforward (requires calling out to another ssr-only function which is instrumented). This commit adds all attributes on the server function to both the generated front end and back end functions. If those attributes are only desirable on the backend say, a user can always wrap their attribute in `#[cfg_attr(feature = "ssr", ..)]`.

* nit: formatting in example cargo
2023-12-01 15:36:52 -05:00
itowlson
9bbd881757 feat: support spawn_local on Spin WASI (#2066)
Signed-off-by: itowlson <ivan.towlson@fermyon.com>
2023-12-01 15:34:29 -05:00
Greg Johnston
8d68c34796 docs: point the book toward its new location with redirects (#2095) 2023-12-01 15:20:44 -05:00
Daniel Mantei
e8025705a4 docs: book restructuring and updates (#2052)
* move DX page under "Getting Started" section; add leptosfmt to DX page

* add a "community and leptos-* crates" page

* create folder for "getting_started"

* updates to 'getting started' chapter (feedback-based)

* clarify book structure + add necessary explanations

* address PR comments by @reedwoodruff

* update "getting started"

* address gbj's comments

* remove the term "universal" from book

* minor update

* formatting

* address reedwoodruff comment
2023-11-30 19:24:18 -05:00
blorbb
19711e16b6 feat: improved macro hygiene (#2084) 2023-11-29 07:47:18 -05:00
Alex Lazar
1272bd12f0 docs: use with!() macro in book and update formatting on Effect page (#2054) 2023-11-29 07:41:13 -05:00
martin frances
731b028b11 chore: Bump http from 0.2.8 to 0.2.11. (#2068) 2023-11-29 07:36:03 -05:00
sdutwsl
1a295bb3d6 docs: correct titile level for 04b_iteration.md (#2080) 2023-11-28 19:53:41 -05:00
Rockie Guo
9c44da2594 docs: minor fixes for some code examples in the book (#2077) 2023-11-28 19:53:26 -05:00
Alex Lazar
75c27e0b85 docs: fix book chapter 3.9 #3 (#2053)
* Fix book chapter 3.9 #3

* Add note about Layout and Content
2023-11-28 19:52:01 -05:00
Greg Johnston
b95a79240e v0.5.4 2023-11-28 18:46:51 -05:00
Alexis Fontaine
8e374efe8d fix: invalid attribute value for aria-current (#2089) 2023-11-28 15:23:16 -05:00
Greg Johnston
b578660624 docs: make it easy to see how to run each example in its README (#2085) 2023-11-28 11:47:56 -05:00
Greg Johnston
d6ee2a37f4 v0.5.3 2023-11-27 19:38:33 -05:00
Greg Johnston
18a92bbfd8 fix: improved rust-analyzer support in #[component] macro (#2075) 2023-11-27 19:37:43 -05:00
Greg Johnston
4e8c3accf2 fix: make prop serialization opt-in for devtools (closes #1952) (#2081) 2023-11-27 16:35:31 -05:00
Joseph Cruz
a8e25af523 ci(leptos): run ci on change instead of check (#2061)
* ci: run ci examples on leptos change

* chore(ci): simulate leptos source change

* ci(todo_app_sqlite_csr): increase retries

* ci: delete check examples workflow

* ci: rename ci examples workflow

* ci: run ci examples with stable toolchain

* chore(ci): remove simulated change

* ci: delete check stable workflow
2023-11-24 14:59:13 -05:00
Greg Johnston
d531848db5 fix: dispose previous route or outlet before rendering new one (closes #2070) (#2071) 2023-11-24 14:51:51 -05:00
hpepper
670f415565 docs: add instruction to install trunk to examples/README.md (#2064)
Co-authored-by: Henry Pepper <henry>
2023-11-24 14:06:02 -05:00
Greg Johnston
061213ca78 fix: correctly mark Trigger as clean when it is re-tracked (closes #1948, #2048) (#2059) 2023-11-22 09:29:25 -05:00
Greg Johnston
0ce4ee8a7a docs: add warning for nested Fn in attribute (see #2023) (#2045) 2023-11-22 07:35:20 -05:00
Greg Johnston
1cd6603da0 ci(examples): fix portal test (#2051) 2023-11-20 20:39:19 -05:00
Andrew Wheeler(Genusis)
453911e6fc examples: updated axum session to latest 0.9 in examples (#2049)
* updated axum_database_sessions to axum_session along with axum_sessions_auth to axum_session_auth

* updated to axum session 0.9
2023-11-20 20:33:31 -05:00
Greg Johnston
cb6267ad08 feat: <Provider/> component to fix context shadowing (closes #2038) (#2040) 2023-11-19 20:24:36 -05:00
Ken
4518d3c89f Have fetch example conform to docs guidance around using <ErrorBoundary> and <Transition> in conjunction (#2035)
* put `<ErrorBoundary>` inside `<Transition>`

* fix indentation
2023-11-18 08:24:30 -05:00
Greg Johnston
e47a619556 examples: add CSR with server functions example (closes #1975) (#2031) 2023-11-18 08:24:15 -05:00
Daniel Mantei
414f5fc393 docs: reorganize deployment section (#2036)
* Update mdbook-admonish book dependency

* Move "Optimizing Binary Size" to Deploy.. chapter

* Minor text updates to the Deployment section
2023-11-17 15:40:20 -05:00
martin frances
362e3bc603 chore: stop using std::fmt, instead used core::fmt. (#2033) 2023-11-17 15:36:13 -05:00
taohua
4d549f70c9 docs: fix misnamed form field in <Form/> example (#2024)
Co-authored-by: datewu <>
2023-11-17 15:27:06 -05:00
Chris
85dd726d43 docs: ActionForm examples for indexing into struct fields (#2017)
Co-authored-by: chrisp60 <gh@cperry.me>
2023-11-17 15:22:11 -05:00
blorbb
24febe11f3 feat: impl Default for TextProp (#2016) 2023-11-17 15:20:03 -05:00
Greg Johnston
64b1e9bed3 fix: use create_effect for <Portal/> to avoid hydration issues (closes #2010) (#2029) 2023-11-17 15:19:07 -05:00
Greg Johnston
68c91a732d fix: allow nested functions in Attribute (closes #2023) (#2027) 2023-11-15 11:00:15 -05:00
blorbb
8573f22d96 fix: re-export slice! macro (#2008) 2023-11-11 06:47:15 -05:00
Greg Johnston
61c7ff4256 docs: add note about context shadowing (closes #1986) (#2015) 2023-11-10 18:04:22 -05:00
Greg Johnston
860d887931 chore: remove duplicate benchmarks in leptos_reactive (#2014) 2023-11-10 15:53:32 -05:00
Chris
5e929a75fa feat: Action::new and Action::server (#1998) 2023-11-10 15:53:20 -05:00
Greg Johnston
d82cf0b76a docs: remove outdated APP_ENVIRONMENT variable (#2013) 2023-11-10 14:27:45 -05:00
Greg Johnston
cb7e07496a docs: fix CodeSandbox for resources (#2002) 2023-11-07 20:11:30 -05:00
Greg Johnston
17881c5c6e docs: fix chapter 10 CodeSandbox 2023-11-07 20:07:38 -05:00
Greg Johnston
2e816b26aa benchmarks: get benchmarks directory working with updated tachys 2023-11-07 20:03:35 -05:00
Gabriel Hansson
68d67c9e92 book: Fix <Body/> link in metadata.md (#1999) 2023-11-07 16:16:47 -05:00
Greg Johnston
0dea6fdcea fix: correctly reset island/not-island state of SSRed Suspense streaming into island (closes #1996) (#2000) 2023-11-07 16:16:27 -05:00
Greg Johnston
530dcff86a examples: remove incorrect CSR information for hackernews_js_fetch example (#1997) 2023-11-06 14:45:26 -05:00
Greg Johnston
9d9a4932b3 fix: run <ErrorBoundary/> in a child so siblings don't collide (closes #1987) (#1991) 2023-11-05 21:29:35 -05:00
Greg Johnston
bfb67d45e8 examples: fix style.css path (closes #1992) (#1994) 2023-11-05 21:29:17 -05:00
Greg Johnston
b1e8105442 fix: treat Suspense as containing a Set of resources, not a counter (closes Suspense only working with a single Resource (closes #1805, closes #1905) (#1985) 2023-11-04 11:03:36 -04:00
Greg Johnston
7aced17976 docs: clarify need to provide context to both rendering and server function handler (#1983) 2023-11-03 18:34:50 -04:00
Gabriel Hansson
191b40b2ac docs: point leptos_server docs.rs url to latest version. (#1982) 2023-11-03 17:05:42 -04:00
Gabriel Hansson
15ca5bec61 docs: fix <Transition/> url in 12_transition.md (#1980) 2023-11-03 17:00:26 -04:00
Gabriel Hansson
ba4d226004 docs: Fix 08_parent_child.md callback example code. (#1976) 2023-11-03 16:58:45 -04:00
Chris
3adfd334df fix: leptos_router::params_map! (#1973)
Fixing implementation comes with the benefit of knocking a crate out of
the deps tree (`common_macros`).
2023-11-02 16:29:50 -04:00
martin frances
d7ca5f2e96 chore: typed-builder and typed-builder-macro - bumped version numbers. (#1958) 2023-10-29 21:49:48 -04:00
Chris
67bdb3498f docs: switch feature flag stable to nightly (#1959) 2023-10-29 21:48:53 -04:00
Greg Johnston
9e9386b223 does this make clippy happy in CI? (#1965) 2023-10-29 21:48:33 -04:00
SleeplessOne1917
4029de2d42 feat: impl IntoAttribute for TextProp (#1925) 2023-10-27 17:10:09 -04:00
Greg Johnston
777095670e fix: add leptos_axum::build_static_routes (closes #1843) (#1855) 2023-10-27 17:09:52 -04:00
koopa
a11c6303e2 feat: allow arbitrary attributes for <A/> component (#1953) 2023-10-27 15:30:30 -04:00
Daniél Kerkmann
3394e316b7 docs: add ignoring #[server] macro for helix as well (#1951)
Update helix configuration for the newest version.
To be consistent, adding the `server` ignore entry to helix as well.
Also sorting the parameters alphabetically.
2023-10-27 13:55:00 -04:00
Ari Seyhun
4b0437394c feat: impl IntoAttribute for Cow<'static, str> (#1945) 2023-10-27 13:48:43 -04:00
Ari Seyhun
d10a566e48 feat: add new method to Trigger (#1935) 2023-10-27 13:48:15 -04:00
martin frances
e0cca3e7a3 workflows: bumped tj-actions/changed-files to @39. (#1942) 2023-10-27 13:47:56 -04:00
martin frances
0c8ab7c725 workflows: bump setup-node to version 4. (#1944) 2023-10-27 13:47:33 -04:00
Ari Seyhun
a2bef05a4b perf: IntoView and IntoAttribute for std::fmt::Arguments improvements (#1947)
* fix: use static str when possible in `std::fmt::Arguments` in views

* feat: impl `IntoAttribute` for `std::fmt::Arguments`
2023-10-27 13:42:27 -04:00
Greg Johnston
6361985fb1 fix: relax 'static bound on as_child_of_current_owner (#1955) 2023-10-27 13:20:34 -04:00
Greg Johnston
ad290f5ed2 chore: update README.md to remove note about 0.5 2023-10-24 22:12:12 -04:00
Greg Johnston
5f53a1459e v0.5.2 2023-10-24 21:03:29 -04:00
Greg Johnston
379623d548 chore: fix SSR tests (#1943) 2023-10-24 17:53:45 -04:00
Greg Johnston
db1113e5b3 fix: use separate key in hydration ID for router outlets (closes #1909) (#1939) 2023-10-24 15:42:30 -04:00
Greg Johnston
d943a50df1 fix: misaligned </head> tags in streaming responses (closes #1930) (#1932) 2023-10-24 15:42:07 -04:00
Greg Johnston
eb86899e08 chore: remove wee_alloc to make Dependabot happy (#1938) 2023-10-24 15:41:03 -04:00
Greg Johnston
e2842ede44 chore: fix broken doctests in leptos_reactive 2023-10-24 15:35:16 -04:00
Greg Johnston
fdd4b3d919 chore: cargo fmt 2023-10-24 15:01:33 -04:00
nikhilraojl
7771052db8 docs: clarify docs on resource source signal (#1918) 2023-10-24 14:29:09 -04:00
martin frances
d999ff857d chore: remove cargo doc lint warnings (#1936) 2023-10-24 14:28:01 -04:00
Sadra
30370a55e1 feat: add a slice!() macro (#1867) 2023-10-24 14:27:10 -04:00
koopa
a7330d61b6 feat: add replace prop to Form component (#1923) 2023-10-24 14:24:23 -04:00
Marc-Stefan Cassola
e2f6780de4 docs: added Callback to documentation and examples. (#1926)
* added Callback to documentation and examples.
Also reduced code duplication in Callback implementation.

* added back the closure event callback example
2023-10-24 14:14:51 -04:00
martin frances
05b4f8e617 chore: use .first() [not .get(0)] (#1929) 2023-10-23 21:02:42 -04:00
Greg Johnston
eb888029d1 docs: fix potential panic in 04b_iteration.md 2023-10-22 07:28:06 -04:00
Daniél Kerkmann
3e08486385 feat: Add local attribute for Await (#1922)
This PR adds the ability to use `create_local_resource` instead of
`create_resource`. This will run the create resource locally on the
system and therefore its result type does not need to be `Seriaziable`.

Closes #1567
2023-10-21 18:34:02 -04:00
Greg Johnston
12b0295906 chore: please clippy (#1924) 2023-10-21 18:33:21 -04:00
Greg Johnston
2756327f12 fix: add missing IntoView implementation for Oco<'static, str> 2023-10-21 16:02:14 -04:00
Greg Johnston
b8ca8b7849 docs: add chapter on nested reactivity and iteration (#1920) 2023-10-20 15:18:38 -04:00
Greg Johnston
6abdca0597 docs: better document default and wasm features on leptos_axum (closes #1872) (#1883) 2023-10-20 14:57:53 -04:00
Greg Johnston
bf14999eb2 fix: router should still scroll to hash even if path didn't change (closes #1907) (#1917) 2023-10-20 14:57:35 -04:00
Marc-Stefan Cassola
c87328f5cf feat: add directives with use: (#1821) 2023-10-19 16:15:36 -04:00
safx
9a70898b09 feat: optional named arguments for #[server] macro (#1904) 2023-10-19 16:07:43 -04:00
Greg Johnston
4a83ffca6f fix: try_update() and try_set() on Resource should not panic (closes #1915) (#1916) 2023-10-19 15:56:57 -04:00
Saikat Das
319017f03f docs: fix typo (#1910) 2023-10-19 09:00:30 -04:00
Greg Johnston
33e166a462 allow construction by making data public 2023-10-18 19:16:08 -04:00
Greg Johnston
8994154b23 fix: maintain hash when setting query signal (closes #1902) (#1908) 2023-10-17 20:28:57 -04:00
luoxiaozero
7b88df32d1 feat: add a target prop to the <A/> component (#1906) 2023-10-17 20:28:37 -04:00
PianoPrinter
0d6ddfb71e fix: properly handle trailing / in more routes (#1900) 2023-10-17 12:45:22 -04:00
Greg Johnston
4a4e16c206 chore: tweak tracing levels (#1901) 2023-10-17 12:44:37 -04:00
Henry Rovnyak
11f6a5d341 fix: remove Clone bound for SignalWith for Resource (#1895) 2023-10-16 14:37:38 -04:00
Greg Johnston
ad208ec473 fix: bug with client-side routing no longer working due to different origin (#1899) 2023-10-15 20:39:03 -04:00
Ari Seyhun
72ad1d7c68 feat: add new method to NodeRef (#1896) 2023-10-15 19:56:23 -04:00
Quan Hua
d6a9d2efdf docs: update deployment.md (#1898)
cargo-leptos@0.2.0 changes the file structure under target folder
2023-10-15 19:55:36 -04:00
Greg Johnston
8eed999611 fix: properly handle trailing / in splat routes (closes #1764) (#1890) 2023-10-14 08:37:31 -04:00
Azzam S.A
07f2cbfbba examples: rename Tailwind examples (#1875) 2023-10-13 16:20:26 -04:00
ymijorski
fc4dea6839 feat: allow custom attributes on leptos_meta components (#1874) 2023-10-13 15:30:48 -04:00
Greg Johnston
17b3300351 fix: ensure there's no reactive tracking in an on_cleanup (closes #1882) (#1889) 2023-10-12 07:36:07 -04:00
Greg Johnston
f3508cef36 feat: add reasonable fallback behavior for ActionForm in an island (#1888) 2023-10-11 18:59:49 -04:00
Greg Johnston
5c41d20421 Merge pull request #1887 from leptos-rs/1886
Fix failing `cargo make lint` for `hackernews_js_fetch`
2023-10-11 18:59:22 -04:00
Greg Johnston
53e16751a7 chore: clean up style and bring into line with other hackernews examples 2023-10-11 16:45:48 -04:00
Greg Johnston
18f7b56c03 fix: do not force target wasm32 for CI purposes 2023-10-11 16:45:36 -04:00
Greg Johnston
c6f51e6a09 docs: add some missing #[must_use] to avoid accidental () rendering (#1885) 2023-10-11 15:00:27 -04:00
dandante
971fb734de docs: fix Markdown in 02_getting_started.md (#1873) 2023-10-11 12:06:16 -04:00
luoxiaozero
200304402f feat: implement Default for RwSignal and StoredValue (#1877) 2023-10-11 12:05:05 -04:00
Greg Johnston
4baa75ccf0 fix: correctly untrack in .try_with_untracked (closes #1880) (#1881) 2023-10-11 12:04:16 -04:00
Greg Johnston
9af1c7e1a3 fix: hydration ID clash with Suspense > Outlet > Suspense (closes #1863) (#1864) 2023-10-09 16:22:43 -04:00
obioma
a302257129 docs: improvements in book - closes #1845 (#1856) 2023-10-09 16:21:09 -04:00
Marc-Stefan Cassola
4251f6c0f4 feat: add Portal component (#1820) 2023-10-09 16:18:52 -04:00
Markus Kohlhase
c080c2cbca fix: use placeholder in comments for empty component names (#1850) 2023-10-09 16:17:46 -04:00
Tyrone Tudehope
0676348bd4 docs: fix Prop-drilling example in Parent-Child Communication section (#1865) 2023-10-09 16:17:26 -04:00
Tyrone Tudehope
18ad7cde20 docs: Add missing argument name to WrapsChildren component (#1866) 2023-10-09 16:16:59 -04:00
Jesse He
b61d0553a0 docs: remove extra "```rust" and add closing bracket to Testing docs (#1870) 2023-10-09 16:16:43 -04:00
Greg Johnston
2a3b613230 docs: add islands guide/demo to the docs (#1861) 2023-10-07 13:10:49 -04:00
Greg Johnston
0d4862b238 feat: add extractor functions with better API than extract (closes #1755) (#1859) 2023-10-07 13:10:30 -04:00
hiraginoyuki
c7607f6fcc fix: documentation in leptos_reactive::Trigger (#1844) 2023-10-07 10:45:27 -04:00
Artur Corrêa Souza
29216b226f docs: clarify what "once per signal change" means (#1858) 2023-10-07 10:44:06 -04:00
Greg Johnston
32ba0ce4fb add awesome-leptos to README 2023-10-07 10:43:21 -04:00
Greg Johnston
c781b4e1c7 docs: update CodeSandboxes to 0.5 2023-10-06 14:20:01 -04:00
Greg Johnston
be2d014f08 v0.5.1 2023-10-06 09:40:23 -04:00
Jesse He
18cdf70864 docs: fix hidden #two 2023-10-06 07:31:23 -04:00
Greg Johnston
1be25f0f47 fix: clippy "needless lifetimes" warning (closes #1825) (#1852) 2023-10-06 07:29:34 -04:00
Greg Johnston
cc93651bc9 fix: panic during generate_route_list if you immediately dispatch an action (#1853) 2023-10-06 07:29:10 -04:00
Kevin Old
a7a1559e01 fix: update log debug to use get_untracked for logged in user to resolve client side error (#1834) 2023-10-05 21:34:58 -04:00
martin frances
15f08aaa30 chore: removed warning in build artefacts. (#1840)
```
The following actions uses node12 which is deprecated and will be forced to run
   on node16: actions-rs/toolchain@v1. For more info:
   https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
```

In other places @3 was being used, so for consitency I have bumped everything up to @4

-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
2023-10-05 21:15:01 -04:00
blorbb
d0295bae01 feat: support stored values in with! and update! (#1836) 2023-10-05 21:14:33 -04:00
Ben Wishovich
5220c37edd fix: make Async Mode return Content-Type header in Response (#1851) 2023-10-05 21:13:33 -04:00
Paul Wagener
4f649e020c feat: allow disposing of Signal & StoredValue (#1849) 2023-10-05 21:02:50 -04:00
Greg Johnston
e0d15c1a09 fix: correctly quote spread attributes in {..attrs} syntax (closes #1826) (#1831) 2023-10-02 18:02:49 -04:00
Greg Johnston
6f9c40b0a8 fix: correctly handle Suspense with local resources during hydration (closes #1823) (#1824) 2023-10-02 18:02:35 -04:00
Daniel Santana
a946a0181d fix: don't overwrite <Html/> props (closes #1828) 2023-10-02 13:46:20 -04:00
Marc-Stefan Cassola
6d44540ab3 feat: optional fallbacks for Show, Suspense, and Transition (#1817) 2023-10-02 08:29:21 -04:00
Sebastian Dobe
6a547cb9db docs: DX improvements: add section about jetbrains intellij-rust (#1804) 2023-10-02 08:26:35 -04:00
Tanguy
ac8dd7af67 fix: template! cfg condition (#1822) 2023-10-02 07:52:54 -04:00
Greg Johnston
0962f699e4 Merge pull request #1818 from leptos-rs/1816
Missing docs and `Copy` impl for `Callback`
2023-10-01 08:27:29 -04:00
Greg Johnston
fcd1028fb7 docs: missing module-level docs for Callback 2023-09-30 15:52:47 -04:00
Greg Johnston
dc429e33ff fix: missing Copy impl on Callback 2023-09-30 15:52:11 -04:00
Greg Johnston
6b40ca36a5 docs: fix For view prop name (closes #1813) (#1814) 2023-09-30 15:49:26 -04:00
Greg Johnston
d869bc6675 chore: clippy 2023-09-29 20:36:15 -04:00
Greg Johnston
d8aeb82949 cargo fmt 2023-09-29 20:35:39 -04:00
Greg Johnston
32e8213ebf v0.5.0 2023-09-29 17:13:56 -04:00
Greg Johnston
fa2be59895 feat: better error handling for ScopedFuture (#1810) 2023-09-29 17:12:56 -04:00
Sirius902
321c522fa5 fix: extra set of brackets in generate_head_metadata (#1811) 2023-09-29 17:12:46 -04:00
Greg Johnston
7378b8581a fix: broken Suspense when a resource loads immediately (closes #1805) (#1809) 2023-09-29 14:44:49 -04:00
Ben Wishovich
2d634364a9 feat: set Content-Type header for all Responses to text/html;charset="utf-8" (#1803) 2023-09-29 13:51:15 -04:00
Greg Johnston
f7adf6f73d examples: fix hackernews examples oops 2023-09-29 13:36:13 -04:00
martin frances
fb914e1a50 chore: bump outdated dependencies in leptos_macro (#1796)
-attribute-derive = { version = "0.6", features = ["syn-full"] }
+attribute-derive = { version = "0.8", features = ["syn-full"] }
-itertools = "0.10"
+itertools = "0.11"
2023-09-29 13:05:57 -04:00
Julien Scholz
772bb1d60c fix: improve rust-analyzer auto-completion (#1782) 2023-09-29 13:05:13 -04:00
Antonin Peronnet
bd4d2202ea feat: standardize on a Callback type that is Copy (#1795) 2023-09-29 13:04:53 -04:00
Greg Johnston
870808e63f feat: implement From<Fn() -> T> for Signal<T> (#1801) 2023-09-29 09:13:27 -04:00
Ben Wishovich
d7fff5a8ab fix: render_route error message and matching of non standard routes (#1799) 2023-09-29 09:10:59 -04:00
jquesada2016
609afce544 feat: Scoped Futures (#1761) 2023-09-28 15:20:18 -04:00
messense
181bcadbe2 feat(leptos_config): only enable toml feature for the config dependency (#1788) 2023-09-27 19:42:25 -04:00
Greg Johnston
3f2a9facf8 change: enable inline children for For by switching to children and bind: (#1773) 2023-09-26 14:24:02 -04:00
Saeed Andalib
c5c79234f1 docs: update working_with_signals.md (#1785)
Pulled the option number 2 out of the blockquote
2023-09-26 14:23:47 -04:00
Fangdun Tsai
de9fb5e382 chore(leptos_meta): enhance links in docs (#1783) 2023-09-25 20:34:11 -04:00
Greg Johnston
c9d132f007 change: use let: instead of bind: (#1774) 2023-09-25 20:33:36 -04:00
Greg Johnston
a1a9d41a7a updating SSR benchmarks to include tachys 2023-09-25 15:45:52 -04:00
Greg Johnston
73112c9faa Merge pull request #1779 from leptos-rs/docs-show
docs: fix `Show` docs reference to scope
2023-09-25 07:54:38 -04:00
Sean Aye
50678dafe1 feat: add JS Fetch integration support (#1554) 2023-09-25 07:51:25 -04:00
Greg Johnston
b1363a16ab docs: fix Show docs reference to scope 2023-09-23 12:46:41 -04:00
Greg Johnston
ae986e71fa change: only run create_local_resource in the browser (#1777) 2023-09-23 11:10:50 -04:00
Antonin Peronnet
0531831fe8 chore: add cargo-make and trunk in nix flake (#1763)
* add `cargo-make` dependency for nix
* add `trunk` dependency for nix
2023-09-23 11:10:24 -04:00
Greg Johnston
18eeee8e1f 0.5.0-rc3 2023-09-22 17:38:54 -04:00
Greg Johnston
d99269afac docs: error in view! macro if you use cx, (#1772) 2023-09-22 17:29:55 -04:00
Nico Burniske
38d1727e9c change: generate_route_list no longer async in any integration (#1485) 2023-09-22 15:42:58 -04:00
Greg Johnston
e0265252d7 fix: broken benchmarks (closes #1763) (#1771) 2023-09-22 15:41:44 -04:00
Fangdun Tsai
6cc92cee8d chore(leptos_hot_reload): apply lints suggestions (#1735) 2023-09-22 13:48:23 -04:00
Fangdun Tsai
1d392483b4 chore(leptos_marco): enhancement of document generation (#1768) 2023-09-22 13:32:58 -04:00
Village
3b864ac1a0 feat: Static Site Generation (#1649) 2023-09-22 13:32:09 -04:00
Danik Vitek
baa5ea83fa fix: reimplement Oco cloning (#1749) 2023-09-22 13:31:04 -04:00
Gabriel de Perthuis
d651400fa2 docs: better document the interaction of SsrModes with blocking resources (#1765)
Meant to address users making the same mistake as
https://github.com/leptos-rs/leptos/issues/1119
2023-09-22 12:58:28 -04:00
Fangdun Tsai
b729a658df chore(leptos_router): improve docs (#1769) 2023-09-22 12:56:49 -04:00
Gabriel de Perthuis
2c8f46466b feat: support default values for annotated server_fn arguments with #[server(default)] (#1762)
This allows form submission with checkbox inputs to work.
For example:

    let doit = create_server_action::<DoItSFn>();
    <ActionForm action=doit>
      <input type="checkbox" name="is_good" value="true"/>
      <input type="submit"/>
    </ActionForm>

    #[server(DoItSFn, "/api")]
    pub async fn doit(#[server(default)] is_good: bool) -> Result<(), ServerFnError> {}

If is_good is absent in the request to the server API,
`Default::default()` is used instead.
2023-09-20 20:43:20 -04:00
Greg Johnston
f2117b1186 fix: restore missing run_as_child 2023-09-20 19:37:39 -04:00
Greg Johnston
726cf47f17 Merge pull request #1758 from leptos-rs/sus2
Fix Suspense issues on subsequent navigations
2023-09-20 13:32:35 -04:00
Greg Johnston
1759a3e149 feat: correctly use_context between islands (#1747) 2023-09-19 21:16:47 -04:00
Fangdun Tsai
2374439cd8 chore(server_fn): improve docs in server_fn (#1734) 2023-09-19 21:16:30 -04:00
Greg Johnston
f85bfd31db fix: Transition double-rendering 2023-09-19 21:04:41 -04:00
Greg Johnston
43b58bfba9 Revert "fix: #1742 part 2 (Suspense running children a second time => extra animations)"
This reverts commit fafb6c01da.
2023-09-19 21:04:02 -04:00
Greg Johnston
fafb6c01da fix: #1742 part 2 (Suspense running children a second time => extra animations) 2023-09-19 10:32:25 -04:00
Greg Johnston
1bd47f34e5 feat: make Transition set_pending use #[prop(into)] (#1746) 2023-09-18 22:46:03 -04:00
Greg Johnston
661a038780 fix: Resource::with() (pt. 3!) — closes #1751 without breaking #1742 or #1711 (#1752) 2023-09-18 22:45:50 -04:00
Fangdun Tsai
e706a69139 chore(server_fn_macro): improve docs (#1733) 2023-09-18 20:48:47 -04:00
Greg Johnston
2b59ae18bc fix: Resource::with() pt. 2 — (closes #1742 without reopening #1711) (#1750) 2023-09-18 16:13:48 -04:00
Lukas Potthast
7d3e2a41b9 fix: Callback clone impls missing a generic (#1744) 2023-09-18 13:47:29 -04:00
Joseph Cruz
7ef57345ca fix(examples/error_boundary): ci error (#1739)
* fix(examples/build): maybe spawn client process

* docs(examples/error_boundary): add testing note
2023-09-17 20:38:03 -04:00
Greg Johnston
7e5169e66d 0.5.0-rc2 2023-09-15 20:06:56 -04:00
Greg Johnston
73a85b4955 feat: use attr: syntax rather than AdditionalAttributes (#1728) 2023-09-15 18:36:54 -04:00
Village
2c12256260 feat: allow component names to be paths (#1725) 2023-09-15 18:18:29 -04:00
Chris
a821abfb11 fix: relax bounds on LeptosRoutes (#1729) 2023-09-15 18:17:55 -04:00
Greg Johnston
20e5db22b8 fix: replace uses of create_effect internally with create_isomorphic_effect (closes #1709) (#1723) 2023-09-15 17:23:36 -04:00
Greg Johnston
54e8a536c4 fix: correctly register Resource::with() (closes #1711) (#1726) 2023-09-15 16:49:28 -04:00
Greg Johnston
afa67726c1 fix: document #[prop(default = ...)] as in Optional Props (closes #1710) (#1721) 2023-09-15 15:16:46 -04:00
Greg Johnston
1db3e9c686 feat: implement Serialize and Deserialize for Oco<_> (#1720) 2023-09-15 15:16:35 -04:00
blorbb
2fd6e0a2a8 feat: support move on with! macros (#1717) 2023-09-15 12:58:30 -04:00
Gabriel de Perthuis
af454c7643 docs: typo in table of contents (#1719) 2023-09-15 12:58:09 -04:00
Joseph Cruz
1a589fcf32 fix(examples/build): do not require stop to end trunk (#1713)
* fix(examples/build): let ctrl-c stop trunk

* doc(examples/build): add stop server hints
2023-09-14 17:07:16 -04:00
Joseph Cruz
af215d6ce8 fix: exclude markdown files from examples lists (#1716)
* fix(examples/gen-members): exclude markdown files

* fix(ci): exclude markdown files from examples list

* test(ci): simulate leptos change

* chore(ci) :remove simulated change
2023-09-14 16:58:46 -04:00
Greg Johnston
e9fef73f53 docs: note about 0.5 in book 2023-09-14 15:53:27 -04:00
Chris
7c9b118b2d docs: update out-of-date docs for component macro (#1696) 2023-09-14 13:47:04 -04:00
Cosmo Brain
5db2590bc6 feat: implement LeptosRoutes for &mut ServiceConfig in leptos_actix (#1706) 2023-09-13 20:56:03 -04:00
Lukas Potthast
dc1ba24470 fix: manual Clone and Debug impl for Callbacks (#1703) 2023-09-13 19:59:23 -04:00
Joseph Cruz
e384d53996 doc(examples): reference run instructions (#1705) 2023-09-13 19:57:50 -04:00
jquesada2016
946f9ff3e1 feat: impl From<HtmlElement<El>> for HtmlElement<AnyElement> (#1700) 2023-09-13 19:55:48 -04:00
Baptiste
8d690ac146 fix: IntoView impl for Rc<dyn Fn() -> impl IntoView> (#1698) 2023-09-13 19:55:08 -04:00
Greg Johnston
8245d77738 Merge pull request #1704 from leptos-rs/rc1-fixes
A few fixes to rc1
2023-09-13 16:51:19 -04:00
Greg Johnston
59c7684568 fix: warnings on hydrating () 2023-09-13 12:01:05 -04:00
Greg Johnston
a158e7f8bd fix: remove erroneous log 2023-09-13 12:00:56 -04:00
Joseph Cruz
c11c4b0e3e build(examples): make it easier to run examples (#1697)
* build(examples): support process management
* build(examples): manage trunk
* build(examples): manage cargo leptos
* doc(examples): add run instructions
2023-09-12 10:46:16 -04:00
Greg Johnston
fe42ac11a8 0.5.0-rc1 2023-09-11 21:08:14 -04:00
blorbb
00f8c9583d feat: with! macros (#1693) 2023-09-11 21:01:50 -04:00
Greg Johnston
a317874f93 change: run effects after a tick (#1680) 2023-09-11 21:01:35 -04:00
Greg Johnston
651356a9ec docs: add docs for #[island] macro (#1691) 2023-09-11 19:56:33 -04:00
Village
1c2327b2d6 feat: attr: and #[prop(attrs)] syntax for passing attributes down to components (#1628) 2023-09-10 15:19:53 -04:00
Michael Jarvis
8c3e0f23b0 docs: fix interlude_projecting_children.md (#1690) 2023-09-10 15:18:11 -04:00
martin frances
1719c0d352 chore: cleared "cargo doc" issue. (#1687)
warning: Rust code block is empty
   --> leptos_reactive/src/memo.rs:209:9
    |
209 |     /// ```
    |         ^^^
    |
    = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
help: mark blocks that do not contain Rust code as text
    |
209 |     /// ```text
    |            ++++
2023-09-10 15:17:36 -04:00
Greg Johnston
bb78f64cd5 fix: broken mount_to_body in CSR mode (#1688) 2023-09-10 13:23:32 -04:00
Greg Johnston
2fe5be2483 fix: restore deleted extract_with_state function (#1683) 2023-09-10 07:55:13 -04:00
martin frances
929fe08525 chore: remove ambiguity surrounding serde version numbers. (#1685)
These lint warnings.

warning: /home/martin/build/leptos/leptos/Cargo.toml: dependency (serde) specified without providing a local path, Git repository, version, or workspace dependency to use. This will be considered an error in future versions
warning: /home/martin/build/leptos/leptos/Cargo.toml: dependency (serde_json) specified without providing a local path, Git repository, version, or workspace dependency to use. This will be considered an error in future versions
2023-09-09 16:15:34 -04:00
Greg Johnston
66dfef8729 Merge pull request #1681 from leptos-rs/docs 2023-09-08 17:11:47 -04:00
Greg Johnston
238d61ce1e feat: experimental islands (#1660) 2023-09-08 16:33:00 -04:00
Greg Johnston
2fa2bf1706 docs: format 2023-09-08 16:27:50 -04:00
Greg Johnston
a07984be9e docs: add runtime warnings for mixing view! and builder in SSR mode (closes #1645) 2023-09-08 16:27:29 -04:00
Greg Johnston
e8a7086546 docs: add section on small DX wins (closes #1310) 2023-09-08 16:12:27 -04:00
Greg Johnston
23d48d4c0e docs: remove stray references to Scope (closes #1671) 2023-09-08 16:02:45 -04:00
Greg Johnston
3342faa039 docs: discuss #[component(transparent)] in router docs (closes #1627) 2023-09-08 15:57:02 -04:00
Greg Johnston
6c24061c82 docs: emphasize that you should only render <Routes/> once (closes #1552, #1620) 2023-09-08 15:48:41 -04:00
Greg Johnston
b9a1fb7743 examples: add note about potential for memory leaks with nested signals (#1675) 2023-09-08 15:28:18 -04:00
martin frances
3c3fc969ac chore: removed resolver link warning in example (#1677) 2023-09-08 14:47:14 -04:00
blorbb
c87212f2d7 chore: remove (most) syn 1 dependencies (#1670) 2023-09-08 14:46:38 -04:00
Baptiste
b3a4c95dad feat: Rc-backed ChildrenFn (#1669) 2023-09-08 07:44:50 -04:00
Greg Johnston
de44b1f91f Merge pull request #1673 from martinfrances107/router_version_bump
Router version bump
2023-09-08 07:43:47 -04:00
Greg Johnston
689022661d change: move logging macros into a logging module to avoid name conflicts with log and tracing (#1658) 2023-09-08 07:42:58 -04:00
Joseph Cruz
905d46a09d refactor(examples): extract client process tasks (#1665) (#1666)
* doc(test-report): report trunk and node

* refactor(examples): extract client process tasks

* chore(exaples): force ci
2023-09-08 07:31:55 -04:00
martinfrances107
5585f20940 chore: Bumped a few outdated packages.
-cached = { version = "0.44.0", optional = true }
+cached = { version = "0.45.0", optional = true }
-lru = { version = "0.10", optional = true }
+lru = { version = "0.11", optional = true }
2023-09-08 09:30:13 +01:00
martinfrances107
5c3ed3f018 Chore: Bump to actions/checkout@v4 2023-09-08 08:28:01 +01:00
Greg Johnston
03cabf6ea3 chore: create SECURITY.md 2023-09-06 21:19:33 -04:00
SleeplessOne1917
2798dc455f examples: use cargo-leptos Tailwind support in Tailwind examples (#1625) 2023-09-06 07:25:00 -04:00
Florian Wickert
db20be5576 fix: compare path components to detect active link in router (#1656) 2023-09-06 06:49:10 -04:00
Nya
495862e9f9 fix: custom events on components (#1648) 2023-09-04 13:27:33 -04:00
Joseph Cruz
2ca1c51fdc test(error_boundary): add e2e testing (#1651)
* test(error_boundary): open app

* test(error_boundary): click up arrow

* test(error_boundary): click down arrow

* test(error_boundary): type number

* test(error_boundary): clear number

* fix(build): clean trunk directories

* fix(test-report): detect unit tests

* ci(build): echo stop trunk
2023-09-04 13:25:44 -04:00
Greg Johnston
70e1ad41e2 Merge pull request #1579 from leptos-rs/rusty
feat: start adding some Rustier interfaces for reactive types
2023-09-04 13:23:18 -04:00
Greg Johnston
53ec7ed272 feat: add Effect::with_value_mut() 2023-09-04 11:14:07 -04:00
Greg Johnston
d98a577740 feat: add Rustier interfaces for reactive system types 2023-09-04 11:05:23 -04:00
jquesada2016
fd834f48c2 change: rename .derived_signal() and .mapped_signal_setter() methods (#1637) 2023-09-04 08:41:41 -04:00
Greg Johnston
7be65a37c6 fix: versioned resources never decrement Suspense (closes #1640) (#1641) 2023-09-03 20:21:16 -04:00
Banzobotic
3b5e2d86fb docs: clean up messy spacing left over from cx replacements (#1626) 2023-09-03 20:21:05 -04:00
jquesada2016
716b9fb50b feat: add .into_X_boxed() for classes, properties, and styles as for attributes 2023-09-03 20:18:49 -04:00
jquesada2016
006ca13797 chore: hide get_property (#1638) 2023-09-03 20:15:15 -04:00
Village
6e008343c8 feat: add component generics (#1636) 2023-09-03 20:09:50 -04:00
Greg Johnston
2ca24883ac fix: memoize Suspense readiness to avoid rerendering children/fallback (#1642) 2023-09-03 20:07:20 -04:00
Village
4a43983f4e feat: implement spreading attributes onto elements (#1619) 2023-09-01 20:52:15 -04:00
IcosaHedron
d9e83121c1 feat: add reload websocket configuration and enable env configuration (#1613) 2023-09-01 20:51:46 -04:00
Antonin Peronnet
f5b4b97c9b feat: Callback types to make it easier to accept (optional) callback props (#1596) 2023-09-01 20:51:32 -04:00
Gareth
bcfa430a40 docs: fix incorrect variable name (#1623) 2023-09-01 07:39:41 -04:00
Lawrence Qupty
7c51815cf5 docs: remove extra space (#1622) 2023-09-01 07:39:05 -04:00
Dmitry Pytaylo
fee2fb953b docs: fix typo (#1618) 2023-09-01 07:37:52 -04:00
Sadra M
8ecb7f59c4 docs: update references to server binary in dockerfile (#1617) 2023-09-01 07:37:24 -04:00
martin frances
b85cb9fb3b docs: clarify how many times derived signals are called (#1614) 2023-09-01 07:36:15 -04:00
Joseph Cruz
a631c5ca1c doc(examples): report fantoccini use (#1616) 2023-09-01 07:35:29 -04:00
Greg Johnston
bee9bd8f67 0.5.0-beta2 2023-08-29 21:23:59 -04:00
Greg Johnston
8d3874f8a9 cargo fmt 2023-08-29 21:19:24 -04:00
Einherjar
bade16d227 docs: discuss unique paths for #[server] functions (#1610) 2023-08-29 20:49:31 -04:00
Jon Cahill
e0a132bde3 fix: don't try to parse as JSON the result from a server function redirect (#1604) 2023-08-29 20:42:19 -04:00
Daniel Oliveira
4d7e1f4d26 feat: improve server function client side error handling (#1597)
Handle all error codes 401-499 in addition to the
400 and 500-599 that were already handled.

In addition, handle them all in the same way
and improve the error message.
2023-08-29 20:40:03 -04:00
Maneren
700eee6604 fix(macro/params): clippy warning (#1612) 2023-08-29 20:31:54 -04:00
Joseph Cruz
694ed61e4c fix(ci): add new webkit dependency (#1607) (#1608) 2023-08-28 11:08:47 -04:00
Joseph Cruz
d7330097ba chore(examples): improve cucumber support #1598 (#1599)
* chore(examples): add cucumber runner

* chore(examples): clean cargo recursively
2023-08-28 11:08:22 -04:00
Greg Johnston
c65a3a6ca3 docs: add docs for builder syntax (#1603) 2023-08-28 11:08:07 -04:00
Danik Vitek
793c191619 feat: Oco (Owned Clones Once) smart pointer (#1480) 2023-08-26 11:43:51 -04:00
Greg Johnston
6c3e2fe53e feat: update to typed-builder 0.16 (closes #1455) (#1590) 2023-08-26 10:10:42 -04:00
Greg Johnston
08c419e3ee fix: broken test with untrack in tracing props (#1593) 2023-08-26 09:20:14 -04:00
Greg Johnston
736f4185b5 Merge pull request #1588 from leptos-rs/1457
Some resource and transition fixes
2023-08-26 07:34:21 -04:00
Greg Johnston
9cc0fc8c49 fix: adjust tracing properties 2023-08-26 07:24:52 -04:00
Greg Johnston
8f067dcde7 chore: clear release-mode warnings 2023-08-25 17:16:00 -04:00
Greg Johnston
ad6eb58fe1 fix: <Transition/> fallback in CSR 2023-08-25 17:12:01 -04:00
Greg Johnston
3f3ab1c3c8 remove unnecessary parens 2023-08-25 16:49:26 -04:00
Greg Johnston
9adae32847 examples: improve hackernews behavior 2023-08-25 16:00:47 -04:00
Greg Johnston
b8098e7992 fix: <Transition/> fallback on non-initial page loads 2023-08-25 16:00:47 -04:00
Greg Johnston
bef4d0dd3b fix: resource loading signal pattern for subsequent hydration page loads 2023-08-25 16:00:47 -04:00
Matt Cuneo
a789100e22 feat: allow autoreload websocket connection to work outside of localhost (#1548)
* Updated client reloading to use window.location.protocol/host to determine websocket connection. Added optional config reload_external_port to provide further control of the client websocket connection. These changes allow reloading while accessing the served site from outside of localhost.
2023-08-25 15:54:22 -04:00
Greg Johnston
abeca70625 fix: correct logic for resource loading signal when read outside suspense (#1586) 2023-08-25 11:46:54 -04:00
rkuklik
cc293b1170 feat: generic event handler types to make it easier to create collections of event handlers (#1444) 2023-08-25 11:41:16 -04:00
Greg Johnston
8ab62c17c6 feat: add Fn traits for resources on nightly (#1587) 2023-08-25 11:20:29 -04:00
Joseph Cruz
cf14e857ca refactor(check-stable): use matrix (#1543) (#1583)
* refactor(check-stable): use matrix

* chore: simulate leptos change

* chore: remove simulated change
2023-08-25 10:30:00 -04:00
Greg Johnston
c322ef38fd feat: signal traits should take associated types instead of generics (#1578) 2023-08-25 10:29:24 -04:00
Greg Johnston
c9cc493063 fix: fourth argument to server functions (#1585) 2023-08-25 10:28:54 -04:00
Joseph Cruz
fb48f7f117 fix(counters_stable): restore wasm tests (#1581) (#1582) 2023-08-24 16:33:01 -04:00
尹吉峰
c344e54cf6 feat: return an Effect from create_effect that can be disposed (#1571) 2023-08-24 10:24:10 -04:00
Greg Johnston
7306ecccbc feat: make struct name and path optional for server functions (#1573) 2023-08-24 10:22:35 -04:00
Greg Johnston
b98174db7a feat: support passing signals directly as attributes, classes, styles, and props on stable (#1577) 2023-08-24 10:22:14 -04:00
Greg Johnston
e48f66694d fix: runtime disposal time in render_to_string_async (#1574) 2023-08-24 10:22:00 -04:00
Mark Catley
533fccd1d3 fix: nightly warning in server macro for lifetime (#1580)
On the latest lifetime we're getting the following warning in the server
macro:
 warning: `&` without an explicit lifetime name cannot be used here
   --> src/login.rs:19:1
    |
 19 | #[server(Login, "/api")]
    | ^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
    = note: this warning originates in the attribute macro `server` (in Nightly builds, run with -Z macro-backtrace for more info)
2023-08-24 06:30:13 -04:00
Greg Johnston
ec4bd7600f fix: suppress warning about non-reactivity when calling .refetch() (occurs in e.g., async blocks in actions) (#1576)
* fix: suppress warning about non-reactivity when calling `.refetch()` (occurs in e.g., async blocks in actions)

* fix: don't reenter reactivity if these are nested
2023-08-23 20:57:05 -04:00
Greg Johnston
65d4e98d38 fix: INFO is too high a level for this prop tracing (#1570) 2023-08-23 06:39:37 -04:00
Nathan Lapel
195b843840 feat: remove Clone requirement for slots in vectors (#1564) 2023-08-22 21:23:38 -04:00
Joseph Cruz
00ac66e450 refactor(verify-changed-examples): improve readability and runtime (#1556)
* refactor(workflows): split setup

* test((verify-changed-examples): simulate  change

* refactor(verify-changes-examples): inline os setup

* refactor(verify-changed-examples): skip w/o change

* chore(verify-changed-examples): remove simulated change

* refactor(verify-changed-examples): revert inline

* refactor(verify-changes-examples): extract example changed

* fix(verify-changed-examples): pull up example changed

* refactor(verify-change-examples): extract matrix

* refactor(verify-changed-examples): pass input

* refactor(verify-changed-examples): rename workflow

* ci(workflows): install chromedriver if needed

* fix(ci-changed-examples): pass input from json

* perf(run-cargo-make-task): maybe install chromedriver

* fix((run-cargo-make-task): maybe install chromedriver

* perf(run-cargo-make-task): maybe install playwrigh deps

* fix(run-cargo-make-task): maybe install playwrigh deps

* chore(suspsense_tests): retry e2e

* refactor(verify-changed-examples): rename calls

* refactor(run-cargo-make-test): remove playwright count
2023-08-22 21:22:13 -04:00
Joseph Cruz
351701036b refactor(workflows): extract calls (#1566)
* refactor(workflows): extract leptos changed

* refactor(workflows): rename matrix job

* refactor(workflows): extract examples matrix

* chore(workflows): simulate leptos change

* chore(workflows): remove simulated leptos change
2023-08-22 21:19:58 -04:00
Greg Johnston
2bead5dadd docs: note 0.4 vs 0.5 in README.md 2023-08-21 19:35:23 -04:00
Greg Johnston
dbc707adcd feat/change: adopt reactive ownership model and drop cx/Scope (#918) 2023-08-21 19:31:37 -04:00
Greg Johnston
5066242ef3 remove file accidentally included from islands branch 2023-08-20 19:52:47 -04:00
Greg Johnston
e9deff52a7 v0.4.9 2023-08-20 14:27:49 -04:00
Greg Johnston
eb3d9b8714 build(docs): only publish on new version tags (#1562) 2023-08-20 09:38:35 -04:00
luoxiaozero
18deb398ca feat: tracing support for component props (#1531) 2023-08-18 08:29:41 -04:00
Geert Stappers
d9abebb4be docs: add link to source code for book 2023-08-18 07:57:38 -04:00
Jonathan
a480db8b77 <Show/> update (#1557) 2023-08-18 07:50:26 -04:00
Greg Johnston
1f26b68d45 docs: inner_html in book 2023-08-16 21:31:06 -04:00
Greg Johnston
937501c61b docs: add note about #[component(transparent)] 2023-08-16 21:26:53 -04:00
Joseph Cruz
5523fb86fb perf(check-stable): only run on source change (#1542) 2023-08-15 06:20:01 -04:00
Joseph Cruz
7dcfcf8ca8 chore(test_examples): remove obsolete directory (#1540) 2023-08-15 06:19:36 -04:00
Joseph Cruz
087c68569a test(suspense-tests): add e2e tests (Closes #1519) (#1533)
* test(suspense-tests): add e2e tests (closes #1519)

test(suspense_tests): load nested

test(suspense_tests): load parallel

test(suspsense_tests): load nested inside

test(suspense_tests): load single

test(suspense_tests): load inside component

test(suspense_tests): load no resources

test(suspense_tests): click nested count

test(suspense_tests): click inside component count

test(suspense_tests): click nested inside count

test(suspense_tests): click single count

test(suspense_tests): click parallel counts

test(suspense_tests): click no resources count

refactor(suspense_tests): change view strategy

* fix(suspense_tests): let_unit_value
2023-08-15 06:19:20 -04:00
Milo Moisson
6abfdd2345 examples: on_cleanup misorder? in fetch examples (#1532)
* Update api.rs

* fix: second hackernews example
2023-08-15 06:18:38 -04:00
martin frances
cddd784e8d chore: fixed lint warning seen while running ``cargo doc`` (#1539)
"component" is both a module and a macro and so we must
disambiguate
2023-08-15 06:18:19 -04:00
Greg Johnston
f6978217fb docs: give a compile error when trying to put a child inside a self-closing HTML tag (closes #1535) (#1537) 2023-08-13 12:44:45 -04:00
Greg Johnston
aa58cedc15 Merge pull request #1529 from leptos-rs/docs-advanced-reactivity
Add advanced docs on reactive graph, and update testing docs
2023-08-11 13:52:08 -04:00
Greg Johnston
a0b0d72d19 docs: update testing section 2023-08-11 13:51:10 -04:00
Greg Johnston
fa8d0945e0 docs: add section on reactive graph internals 2023-08-11 13:36:27 -04:00
Greg Johnston
3ed49381e3 docs: expand on the need for prop:value (#1526) 2023-08-10 14:59:12 -04:00
Greg Johnston
8ec3fb95f0 docs: typos in NavigateOptions docs (#1525) 2023-08-09 20:44:39 -04:00
Greg Johnston
cc11430d16 docs: add use_navigate to router docs in guide (#1524) 2023-08-09 20:44:31 -04:00
Greg Johnston
0b650ee2dc Merge pull request #1523 from leptos-rs/more-docs
Additional random docs
2023-08-09 20:24:48 -04:00
Greg Johnston
4def35cb45 docs: add <Await/> 2023-08-09 20:24:04 -04:00
Greg Johnston
0e56f27e0d docs: add watch 2023-08-09 20:19:12 -04:00
Greg Johnston
bd8983f462 docs: expand docs on Axum State/FromRef pattern 2023-08-09 20:14:37 -04:00
Greg Johnston
7ef635d9cf docs: deployment 2023-08-09 20:09:54 -04:00
Joseph Cruz
19ea6fae6a test(todo_app_sqlite_axum): add e2e tests (#1514) (#1515)
* refactor(examples): pull up cargo leptos tasks

* test(todo_app_sqlite_axum): add e2e tests
2023-08-09 08:37:28 -04:00
Joseph Cruz
651a111db9 fix(suspense-tests): build errors (#1517) (#1518) 2023-08-09 08:36:25 -04:00
Danik Vitek
3a98bdb3c2 fix: use current pathname for create_query_signal (#1508) 2023-08-07 20:25:22 -04:00
Greg Johnston
f01b982cff fix: render empty dynamic text node in HTML as (closes #1382) (#1507) 2023-08-07 18:04:56 -04:00
Joseph Cruz
69dd96f76f test(todo_app_sqlite): add e2e tests (#1448) (#1467) 2023-08-07 17:51:24 -04:00
starmaker
329ae08e60 chore: enable stable support for rkyv feature (#1503) 2023-08-07 08:54:02 -04:00
Greg Johnston
1e13ad8fee perf: in hydration, reuse existing text node rather than destroying and remounting (#1506) 2023-08-07 08:34:10 -04:00
Geert Stappers
e0c9a9523a docs: typo
Signed-off-by: Geert Stappers <stappers@stappers.nl>
2023-08-04 10:56:51 -04:00
Mark Catley
0726a3034d examples: fix github links (#1493) 2023-08-04 07:55:04 -04:00
Greg Johnston
a88d047eff template refactor + snapshot tests (#1435) 2023-08-04 07:54:03 -04:00
mateusvmv
4001561987 fix: scoping of JS variable names in inline scripts (#1489) 2023-08-03 08:46:06 -04:00
Greg Johnston
2f860b37bd v0.4.8 2023-08-02 19:25:32 -04:00
Greg Johnston
b86009b9d0 fix: remove erroneous logging 2023-08-02 19:16:32 -04:00
Greg Johnston
54733e1b34 v0.4.7 2023-08-02 17:03:38 -04:00
Greg Johnston
56f01888b7 Merge pull request #1486 from leptos-rs/export-all-helpers
fix: correctly export all DOM helpers
2023-08-02 17:02:19 -04:00
Greg Johnston
8320f16716 chore: fix new clippy warnings 2023-08-02 16:05:42 -04:00
Greg Johnston
0b16e5992d fix: correctly export all DOM helpers 2023-08-02 14:41:54 -04:00
Danik Vitek
248beb4a55 docs: typo in docs for ServerFnErrorErr (#1477) 2023-08-01 14:27:39 -04:00
martin frances
c9f608d030 docs: fix doclink to Error (#1469) 2023-08-01 13:24:13 -04:00
Greg Johnston
f837d3e6a2 fix: correctly escape HTML in DynChild text nodes (closes #1475) (#1478) 2023-08-01 13:22:24 -04:00
Greg Johnston
8847d5fc42 fix: compile-time regression for deeply-nested component trees (#1476) 2023-07-31 14:23:09 -04:00
Greg Johnston
7819a6fac0 fix: properly replace text nodes in DynChild (closes #1456) (#1472) 2023-07-30 22:37:53 -04:00
Marco Inacio
c199185808 docs: README.md to reflect new version (#1470) 2023-07-30 11:52:09 -04:00
martin frances
e0b5738606 chore: document the magic number in FILTER_SHOW_COMMENT. (#1468) 2023-07-29 16:53:10 -04:00
Sebastian Dobe
f3e3880a57 fix: AnimatedShow - possible panic on cleanup (#1464) 2023-07-29 06:33:49 -04:00
Greg Johnston
d44b90c16d feat: allow mut in component props and suppress "needless lifetime" warning (closes #1458) (#1459) 2023-07-29 06:32:06 -04:00
Joseph Cruz
cc32a3e863 perf(examples): speed up the test-info report (#1446) (#1447) 2023-07-27 20:40:26 -04:00
Greg Johnston
5740c9b76b feat: add MaybeProp type (#1443) 2023-07-27 18:18:25 -04:00
Greg Johnston
80fa6ad3eb docs: fix typo in 23_ssr_modes.md (#1445) 2023-07-26 16:33:21 -04:00
Greg Johnston
7bc1ad2b4f fix: incorrect opening node for <Each/> in debug mode (closes #1168) (#1436) 2023-07-26 10:43:46 -04:00
Joseph Cruz
82a2fe7cbe fix(examples): unable to parse makefile (#1440) (#1441) 2023-07-26 10:43:20 -04:00
Bechma
40bf944957 docs: expand spawn_local documentation (#1433) 2023-07-25 11:42:48 -04:00
Greg Johnston
7ef7546fa9 v0.4.6 2023-07-25 06:08:53 -04:00
Greg Johnston
5e26e84d77 feat: allow feature-name flexibility when using server functions (#1427) 2023-07-25 06:07:52 -04:00
mforsb
e67bc2083a feat: add noscroll attribute to Form, ActionForm (#1432) 2023-07-25 06:07:37 -04:00
g-re-g
a3cb3f7f77 perf: use binary search for event and tag names in view macro (#1430) 2023-07-24 15:06:34 -04:00
Greg Johnston
daeb47e72e build(examples): update Makefiles for recent examples (#1431) 2023-07-24 12:02:30 -04:00
Joseph Cruz
8c5ab99fa7 build(examples): pull up compile tasks (#1417)
* build(examples): pull up compile tasks

* build(examples): set toolchain for compiles tasks

* build(examples): set toolchain for build and check

* build(examples): set toolchain of other examples
2023-07-24 11:35:34 -04:00
Greg Johnston
984a7388f1 fix: clear <title> correctly when navigating between pages (closes #1369) (#1428) 2023-07-24 11:25:28 -04:00
Greg Johnston
274b105676 docs: fix messed up component closing tags router docs 2023-07-24 11:24:58 -04:00
Greg Johnston
a689d1b4c0 docs: note on optional generic component props 2023-07-24 07:52:40 -04:00
Greg Johnston
1581e91317 docs: note on how to opt out of client-side routing 2023-07-24 07:52:29 -04:00
Andrew Grande
20f4034c1c docs: proofreading and fixing the links (#1425)
* Update 23_ssr_modes.md

Fixed grammar, added the section anchor links

* Fixed a broken link

The github link doesn't get properly rendered in the Leptos book site. Make the book work, 'break' the github link.

* Update 26_extractors.md

Fixed broken Axum links. Added an Axum extract function doc link for consistency (had Actix, but not Axum before)
2023-07-24 07:25:02 -04:00
Jason Hansen
9fb1c4b67c docs/warnings: fix warning message about updating a signal after it has been disposed (#1423)
* Remove "either" because it didn't make sense in the sentence
* Change "cause cause" to "not cause"
2023-07-24 07:24:06 -04:00
Ari Seyhun
2e559d6a06 feat: add create_query_signal for URL-synced signals (#1377) 2023-07-23 12:20:15 -04:00
Sebastian Dobe
71de6c395b feat: create a <AnimatedShow> component (closes #1370) (#1386) 2023-07-23 07:46:47 -04:00
Vladimir Motylenko
b09f9e4814 feat: Update rstml to v0.11.0 (#1416) 2023-07-23 07:46:33 -04:00
Greg Johnston
ec4bfb0e8a chore: resolve clippy incorrect_clone_impl_on_copy_type (closes #1401) (#1418) 2023-07-22 22:14:52 -04:00
Greg Johnston
39bf38d1e4 docs: CONTRIBUTING.md with helpful info re: CI (#1415) 2023-07-22 08:26:46 -04:00
Joshua Marsh
e6fd1379b8 docs: fix typo for WrapsChildren (#1402) 2023-07-22 08:26:36 -04:00
Doug A
1d9931a5a8 docs: typo in 01_basic_component.md (#1412)
typo fix
2023-07-22 08:24:30 -04:00
Greg Johnston
06164d34b5 docs: note about typed params on stable (#1414) 2023-07-22 08:23:05 -04:00
Joseph Cruz
f3de288e19 build(examples): make it easy to see which examples do what kind of testing (#1411)
* build(examples): list example projects with CI tests runners

* build(examples): add show all mode
2023-07-22 08:13:49 -04:00
Greg Johnston
62bf315059 fix: <use_/> as typed top-level element in view (#1410) 2023-07-21 10:07:34 -04:00
Greg Johnston
011c97e3a4 fix: closing element names wrong for svg::, math::, and use_ (closes #1403) (#1406) 2023-07-20 17:03:30 -04:00
Greg Johnston
2ca3d2c7a4 fix: RawText/unquoted text nodes in SSR (closes #1384) (#1407) 2023-07-20 17:03:19 -04:00
Greg Johnston
cc52c94348 docs/examples: use shorthand form for <Route/> views when possible (#1375) 2023-07-20 16:28:43 -04:00
Andrew Grande
4b8cc96dfa docs: typo in 16_routes.md
Fixed grammar
2023-07-20 16:13:25 -04:00
Greg Johnston
338d2ab839 Merge pull request #1379 from agilarity/lint-with-clippy
ci: lint with clippy
2023-07-20 14:15:16 -04:00
Greg Johnston
54fc6da24e feat: implement Resource::dispose() (#1393) 2023-07-20 14:14:49 -04:00
Andrew Grande
825b3fb858 chore: typo in README.md (#1399) 2023-07-20 14:00:43 -04:00
Andrew Grande
fd0212a142 docs: typo in 15_global_state.md (#1395)
Proofreading
2023-07-20 08:57:12 -04:00
Greg Johnston
3b397cb39c examples: remove random <form> (#1398) 2023-07-20 08:56:49 -04:00
martin frances
1e002c2c2f chore: Removed call to .into(), plus minor touch to docs. (#1396) 2023-07-20 08:07:31 -04:00
Greg Johnston
8f45daeca8 docs: correct docs for create_memo to reflect laziness (#1388) 2023-07-19 14:50:34 -04:00
Joseph Cruz
105ef989b7 ci: install clippy 2023-07-19 08:54:05 -04:00
Greg Johnston
9e7c31d1e4 docs: small issues (#1385) 2023-07-19 08:53:37 -04:00
Joseph Cruz
771dfa6b68 ci: lint with clippy 2023-07-19 08:44:36 -04:00
Joseph Cruz
fb52cfa73e fix: needless_raw_string_hashes 2023-07-19 08:43:57 -04:00
Ari Seyhun
b2c75d215b chore: remove unnecessary string allocation in TryFrom for Url (#1376) 2023-07-19 07:04:06 -04:00
Andrew Grande
951607de74 docs: typos
* Fixed wording

* Update ARCHITECTURE.md

Fixed superfluous whitespace
2023-07-19 07:03:50 -04:00
Joseph Cruz
122fd2bc74 fix: useless_conversion 2023-07-18 20:56:55 -04:00
Joseph Cruz
f102125d3c fix: needless_borrow 2023-07-18 20:56:55 -04:00
Joseph Cruz
14bda76b30 fix: needless_raw_string_hashes (allow) 2023-07-18 20:56:39 -04:00
Joseph Cruz
3af115a663 fix: maybe_misused_cfg 2023-07-18 20:56:39 -04:00
Joseph Cruz
a344804734 fix: incorrect_clone_impl_on_copy_type (allow) 2023-07-18 20:54:51 -04:00
Greg Johnston
c1c49ce53b v0.4.5 2023-07-18 14:02:56 -04:00
Joseph Cruz
d8eaa5c004 build: use cargo hack for clippy 2023-07-18 08:02:24 -04:00
Greg Johnston
e8aa9b24f1 fix: memory leak in leptos_axum (#1374) 2023-07-17 21:59:20 -04:00
Greg Johnston
3036cd223e v0.4.4 2023-07-17 17:33:44 -04:00
Greg Johnston
1ae5150b08 fix: release lock on stored values during update/set (#1373) 2023-07-17 14:19:03 -04:00
Greg Johnston
47148f2033 perf: exclude hydration code in CSR mode (#1372) 2023-07-17 12:20:33 -04:00
Sebastian Probst Eide
4d4d15436b fix: incorrect tree walker filter in hot reloading (closes #1355) (#1368) 2023-07-17 08:44:32 -04:00
Jack DeVries
7f4741b3a3 doc: add previews to backup CodeSandbox (#1169) 2023-07-17 08:40:30 -04:00
Hans Baker
85644a7c1c Fix broken link to example code in testing book page (#1365) 2023-07-16 20:00:56 -04:00
Greg Johnston
f40ae6af30 fix: correctly show fallback for Transition on first load even if not hydrating (#1362) 2023-07-16 15:19:51 -04:00
Greg Johnston
708e1a5aab docs: wasm-pack instructions missing --debug for Tailwind examples 2023-07-16 12:28:20 -04:00
Joseph Cruz
55613c9a31 ci(check-examples): only run on source change (#1356)
* ci(check-examples): only run on source change

* ci(check-examples):  simulate source change

* ci(check-examples): fix expression

* ci(check-examples): simulate source change

* ci(check-examples): test change against files

* ci(check-examples): adjust expression

* ci(check-examples): remove quotes

* ci(check-examples): use from json

* ci(check-examples): set output value

* ci(check-examples): remove simulated change
2023-07-15 19:09:54 -04:00
Joseph Cruz
e6590c7d31 ci(ci): only run on source change (#1357)
* ci(ci): only run on source change

* ci(ci): simulate source change

* ci(ci): remove simulated source change
2023-07-15 19:09:33 -04:00
Greg Johnston
5af2f4e98d docs/warning: fix <ActionForm/> docs and add runtime warning for incorrect encodings (#1360) 2023-07-15 19:09:03 -04:00
1490 changed files with 139502 additions and 48937 deletions

View File

@@ -29,11 +29,15 @@ Steps to reproduce the behavior:
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Next Steps**
- [ ] I will make a PR
- [ ] I would like to make a PR, but need help getting started
- [ ] I want someone else to take the time to fix this
- [ ] This is a low priority for me and is just shared for your information
**Additional context**
Add any other context about the problem here.

19
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
# Grouping all dependencies in one PR weekly
- package-ecosystem: cargo
directory: "/"
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 1
allow:
- dependency-type: "all"
groups:
rust-dependencies:
patterns:
- "*"

40
.github/workflows/autofix.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: autofix.ci
on:
pull_request:
# Running this workflow on main branch pushes requires write permission to apply changes.
# Leave it alone for future uses.
# push:
# branches: ["main"]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
DEBIAN_FRONTEND: noninteractive
jobs:
autofix:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with: {toolchain: "nightly-2025-04-16", components: "rustfmt, clippy", target: "wasm32-unknown-unknown", rustflags: ""}
- name: Install Glib
run: |
sudo apt-get update
sudo apt-get install -y libglib2.0-dev
- name: Install cargo-all-features
run: cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
- name: Install jq
run: sudo apt-get install jq
- name: Format the workspace
run: cargo fmt --all
- name: Clippy the workspace
run: cargo all-features clippy --allow-dirty --fix --lib --no-deps
- uses: autofix-ci/action@v1.3.2
if: ${{ always() }}
with:
fail-fast: false

View File

@@ -1,46 +0,0 @@
name: Check Examples
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
setup:
name: Get Examples
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install JQ Tool
uses: mbround18/install-jq@v1
- name: Set Matrix
id: set-matrix
run: |
examples=$(ls examples |
awk '{print "examples/" $0}' |
grep -v examples/README.md |
grep -v examples/Makefile.toml |
grep -v examples/cargo-make |
grep -v examples/gtk |
jq -R -s -c 'split("\n")[:-1]')
echo "Example Directories: $examples"
echo "matrix={\"directory\":$examples}" >> "$GITHUB_OUTPUT"
matrix-job:
name: Check
needs: [setup]
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
cargo_make_task: "check"

View File

@@ -1,46 +0,0 @@
name: Check stable
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
jobs:
test:
name: Check examples ${{ matrix.os }} (using rustc ${{ matrix.rust }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
rust:
- stable
os:
- ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt
- name: Add wasm32-unknown-unknown
run: rustup target add wasm32-unknown-unknown
- name: Setup cargo-make
uses: davidB/rust-cargo-make@v1
- name: Cargo generate-lockfile
run: cargo generate-lockfile
- uses: Swatinem/rust-cache@v2
- name: Run cargo check on all examples
run: cargo make --profile=github-actions check-stable

View File

@@ -1,38 +1,68 @@
name: CI
on:
push:
branches:
- main
- leptos_0.6
- leptos_0.8
pull_request:
branches:
- main
- leptos_0.6
- leptos_0.8
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
matrix-job:
name: CI
get-leptos-changed:
uses: ./.github/workflows/get-leptos-changed.yml
get-leptos-matrix:
uses: ./.github/workflows/get-leptos-matrix.yml
get-example-changed:
uses: ./.github/workflows/get-example-changed.yml
get-examples-matrix:
uses: ./.github/workflows/get-examples-matrix.yml
test-members:
name: CI (members)
needs: [get-leptos-changed, get-leptos-matrix]
if: needs.get-leptos-changed.outputs.leptos_changed == 'true'
strategy:
matrix:
directory:
[
integrations/actix,
integrations/axum,
integrations/viz,
integrations/utils,
leptos,
leptos_config,
leptos_dom,
leptos_hot_reload,
leptos_macro,
leptos_reactive,
leptos_server,
meta,
router,
server_fn,
server_fn/server_fn_macro_default,
server_fn_macro,
]
matrix: ${{ fromJSON(needs.get-leptos-matrix.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
cargo_make_task: "ci"
test-examples:
name: CI (examples)
needs: [test-members, get-examples-matrix]
if: ${{ success() }}
strategy:
matrix: ${{ fromJSON(needs.get-examples-matrix.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
test-only-examples:
name: CI (examples)
needs: [get-leptos-changed, get-example-changed]
if: needs.get-leptos-changed.outputs.leptos_changed != 'true' && needs.get-example-changed.outputs.example_changed == 'true'
strategy:
matrix: ${{ fromJSON(needs.get-example-changed.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
semver-check:
name: SemVer check (stable)
needs: [get-leptos-changed, test-members, test-examples]
if: ${{ success() && needs.get-leptos-changed.outputs.leptos_changed == 'true' && !contains(github.event.pull_request.labels.*.name, 'breaking') }}
runs-on: ubuntu-latest
steps:
- name: Install Glib
run: |
sudo apt-get update
sudo apt-get install -y libglib2.0-dev
- name: Checkout
uses: actions/checkout@v4
- name: Semver Checks
uses: obi1kenobi/cargo-semver-checks-action@v2

View File

@@ -0,0 +1,43 @@
name: Examples Changed Call
on:
workflow_call:
outputs:
example_changed:
description: "Example Changed"
value: ${{ jobs.get-example-changed.outputs.example_changed }}
# This is for test-only-examples workflow in ci.yml
matrix:
description: "Example Changed Directories"
value: ${{ jobs.get-example-changed.outputs.matrix }}
jobs:
get-example-changed:
name: Get Example Changed
runs-on: ubuntu-latest
outputs:
example_changed: ${{ steps.set-example-changed.outputs.example_changed }}
# This is for test-only-examples workflow in ci.yml
matrix: ${{ steps.set-example-changed.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get example files that changed
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: |
examples/**
!examples/cargo-make/**
!examples/Makefile.toml
!examples/*.md
- name: List example files that changed
run: echo '${{ steps.changed-files.outputs.all_changed_files }}'
- name: Install jq
run: sudo apt-get install jq
- name: Set example_changed
id: set-example-changed
run: |
echo "example_changed=${{ steps.changed-files.outputs.any_changed }}" >> "$GITHUB_OUTPUT"
# This is for test-only-examples workflow in ci.yml
echo "matrix={\"directory\": $(echo '${{ steps.changed-files.outputs.all_changed_files }}' | tr ' ' '\n' | awk -F'/' '{print $1 "/" $2}'| sort -u | jq -R -s -c 'split("\n") | .[:-1]')}" >> "$GITHUB_OUTPUT"

View File

@@ -0,0 +1,36 @@
name: Get Examples Matrix Call
on:
workflow_call:
outputs:
matrix:
description: "Matrix"
value: ${{ jobs.create.outputs.matrix }}
jobs:
create:
name: Create Examples Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
env:
# separate examples using "|" (vertical bar) char like "a|b|c".
# cargo-make should be excluded by default.
EXCLUDED_EXAMPLES: cargo-make
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install jq
run: sudo apt-get install jq
- name: Set Matrix
id: set-matrix
run: |
examples=$(ls -1d examples/*/ |
grep -vE "($EXCLUDED_EXAMPLES)" |
sed 's/\/$//' |
jq -R -s -c 'split("\n")[:-1]')
echo "Example Directories: $examples"
echo "matrix={\"directory\":$examples}" >> "$GITHUB_OUTPUT"
- name: Print Location Info
run: |
echo "Workspace: ${{ github.workspace }}"
pwd
ls | sort -u

View File

@@ -0,0 +1,35 @@
name: Get Leptos Changed Call
on:
workflow_call:
outputs:
leptos_changed:
description: "Leptos Changed"
value: ${{ jobs.create.outputs.leptos_changed }}
jobs:
create:
name: Detect Source Change
runs-on: ubuntu-latest
outputs:
leptos_changed: ${{ steps.set-source-changed.outputs.leptos_changed }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get source files that changed
id: changed-source
uses: tj-actions/changed-files@v46
with:
files_ignore: |
.*/**/*
cargo-make/**/*
examples/**/*
projects/**/*
benchmarks/**/*
docs/**/*
- name: List source files that changed
run: echo '${{ steps.changed-source.outputs.all_changed_files }}'
- name: Set leptos_changed
id: set-source-changed
run: |
echo "leptos_changed=${{ steps.changed-source.outputs.any_changed }}" >> "$GITHUB_OUTPUT"

32
.github/workflows/get-leptos-matrix.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Get Leptos Matrix Call
on:
workflow_call:
outputs:
matrix:
description: "Matrix"
value: ${{ jobs.create.outputs.matrix }}
jobs:
create:
name: Create Leptos Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install jq
run: sudo apt-get install jq
- name: Set Matrix
id: set-matrix
run: |
crates=$(cargo metadata --no-deps --quiet --format-version 1 |
jq -r '.packages[] | select(.name != "workspace") | .manifest_path| rtrimstr("/Cargo.toml")' |
sed "s|$(pwd)/||" |
jq -R -s -c 'split("\n")[:-1]')
echo "Leptos Directories: $crates"
echo "matrix={\"directory\":$crates}" >> "$GITHUB_OUTPUT"
- name: Print Location Info
run: |
echo "Workspace: ${{ github.workspace }}"
pwd
ls | sort -u

View File

@@ -1,7 +1,7 @@
name: Deploy book
on:
push:
paths: ['docs/book/**']
paths: ["docs/book/**"]
branches:
- main
@@ -9,29 +9,29 @@ jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write # To push a branch
pull-requests: write # To create a PR from that branch
contents: write # To push a branch
pull-requests: write # To create a PR from that branch
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install mdbook
run: |
mkdir mdbook
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.27/mdbook-v0.4.27-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Deploy GitHub Pages
run: |
cd docs/book
mdbook build
git worktree add gh-pages
git config user.name "Deploy book from CI"
git config user.email ""
cd gh-pages
# Delete the ref to avoid keeping history.
git update-ref -d refs/heads/gh-pages
rm -rf *
mv ../book/* .
git add .
git commit -m "Deploy book $GITHUB_SHA to gh-pages"
git push --force --set-upstream origin gh-pages
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install mdbook
run: |
mkdir mdbook
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.27/mdbook-v0.4.27-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Deploy GitHub Pages
run: |
cd docs/book
mdbook build
git worktree add gh-pages
git config user.name "Deploy book from CI"
git config user.email ""
cd gh-pages
# Delete the ref to avoid keeping history.
git update-ref -d refs/heads/gh-pages
rm -rf *
mv ../book/* .
git add .
git commit -m "Deploy book $GITHUB_SHA to gh-pages"
git push --force --set-upstream origin gh-pages

View File

@@ -1,95 +1,186 @@
name: Run Task
on:
workflow_call:
inputs:
directory:
required: true
type: string
cargo_make_task:
required: true
type: string
env:
CARGO_TERM_COLOR: always
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
DEBIAN_FRONTEND: noninteractive
RUSTFLAGS: ${{ inputs.erased_mode && '--cfg erase_components' || '' }}
LEPTOS_TAILWIND_VERSION: v4.0.14
LEPTOS_SASS_VERSION: 1.86.0
jobs:
test:
name: Run ${{ matrix.os }} (using rustc ${{ matrix.rust }})
runs-on: ${{ matrix.os }}
name: "Run (${{ matrix.toolchain }}) (erased_mode: ${{ matrix.erased_mode && 'enabled' || 'disabled' }})"
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- nightly
os:
- ubuntu-latest
toolchain: [stable, nightly-2025-04-16]
erased_mode: [true, false]
steps:
- name: Free Disk Space
run: |
echo "Disk space before cleanup:"
df -h
sudo rm -rf /usr/local/.ghcup
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/local/lib/node_modules
# following lines currenly not needed as it takes too much time
# the new isolated CI doesn't need much space to test libraries
#
# uncommet only if nneded
#
# sudo apt-get clean
# sudo apt-get purge -y '^ghc-.*' '^dotnet-.*' '^llvm-.*' '^mono-.*' '^php.*' '^ruby.*'
# sudo apt-get autoremove -y
# sudo apt-get clean
# sudo rm -rf "$AGENT_TOOLSDIRECTORY"
# docker system prune -af
# docker image prune -af
# docker volume prune -f
echo "Disk space after cleanup:"
df -h
# Setup environment
- name: Install playwright browser dependencies
- name: Install Glib
run: |
sudo apt-get update
sudo apt-get install libegl1 libvpx7 libevent-2.1-7 libopus0 libopengl0 libwoff1 libharfbuzz-icu0 libgstreamer-plugins-base1.0-0 libgstreamer-gl1.0-0 libhyphen0 libmanette-0.2-0 libgles2 gstreamer1.0-libav
- uses: actions/checkout@v3
sudo apt-get install -y libglib2.0-dev
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt
- name: Add wasm32-unknown-unknown
run: rustup target add wasm32-unknown-unknown
- name: Setup cargo-make
uses: davidB/rust-cargo-make@v1
- name: Cargo generate-lockfile
run: cargo generate-lockfile
- uses: Swatinem/rust-cache@v2
toolchain: ${{ matrix.toolchain }}
targets: wasm32-unknown-unknown
components: clippy,rustfmt
- name: Install binstall
uses: cargo-bins/cargo-binstall@main
- name: Install wasm-bindgen
run: cargo binstall wasm-bindgen-cli --no-confirm
- name: Install cargo-leptos
run: cargo binstall cargo-leptos --locked --no-confirm
- name: Install cargo-make
run: cargo binstall cargo-make --no-confirm
- name: Install nextest
run: cargo binstall cargo-nextest --no-confirm
- name: Install cargo-all-features
run: cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
# Part of direct-minimal-versions check
- name: Install cargo-hack
if: contains(matrix.toolchain, 'nightly')
uses: taiki-e/install-action@cargo-hack
# Part of direct-minimal-versions check
- name: Install cargo-minimal-versions
if: contains(matrix.toolchain, 'nightly')
uses: taiki-e/install-action@cargo-minimal-versions
- name: Install Trunk
uses: jetli/trunk-action@v0.4.0
with:
version: "latest"
if: contains(inputs.directory, 'examples')
run: cargo binstall trunk --no-confirm
- name: Print Trunk Version
if: contains(inputs.directory, 'examples')
run: trunk --version
- name: Install Node.js
uses: actions/setup-node@v3
if: contains(inputs.directory, 'examples')
uses: actions/setup-node@v4
with:
node-version: 18
- uses: pnpm/action-setup@v2
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
if: contains(inputs.directory, 'examples')
id: pnpm-install
with:
version: 8
run_install: false
- name: Get pnpm store directory
if: contains(inputs.directory, 'examples')
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
- uses: actions/cache@v4
if: contains(inputs.directory, 'examples')
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Maybe install chromedriver
if: contains(inputs.directory, 'examples')
run: |
project_makefile='${{inputs.directory}}/Makefile.toml'
webdriver_count=$(cat $project_makefile | grep "cargo-make/webdriver.toml" | wc -l)
if [ $webdriver_count -eq 1 ]; then
if ! command -v chromedriver &>/dev/null; then
echo chromedriver required
sudo apt-get update
sudo apt-get install chromium-chromedriver
else
echo chromedriver is already installed
fi
else
echo chromedriver is not required
fi
- name: Maybe install playwright browser dependencies
if: contains(inputs.directory, 'examples')
run: |
for pw_path in $(find '${{inputs.directory}}' -name playwright.config.ts)
do
pw_dir=$(dirname $pw_path)
if [ ! -v $pw_dir ]; then
echo "Playwright required in $pw_dir"
cd $pw_dir
pnpm dlx playwright install --with-deps
else
echo Playwright is not required
fi
done
- name: Install Deno
if: contains(inputs.directory, 'examples')
uses: denoland/setup-deno@v2
with:
deno-version: v1.x
- name: Maybe install gtk-rs dependencies
if: contains(inputs.directory, 'gtk')
run: |
sudo apt-get install -y libglib2.0-dev libgio2.0-cil-dev libgraphene-1.0-dev libcairo2-dev libpango1.0-dev libgtk-4-dev
- name: Install Tailwind and Sass dependencies
if: contains(inputs.directory, 'examples')
run: |
cd '${{ inputs.directory }}'
tailwindcss_version=$(echo "$LEPTOS_TAILWIND_VERSION" | sed 's/^v//')
sass_version="$LEPTOS_SASS_VERSION"
pnpm add "tailwindcss@$tailwindcss_version" "@tailwindcss/cli@$tailwindcss_version" "sass@$sass_version"
echo "Tailwind CSS version:"
./node_modules/.bin/tailwindcss --version
echo "Sass version:"
./node_modules/.bin/sass --version
# Run Cargo Make Task
- name: ${{ inputs.cargo_make_task }}
run: |
if [ "${{ inputs.directory }}" = "INTERNAL" ]; then
echo No verification required
else
cd ${{ inputs.directory }}
cargo make --profile=github-actions ${{ inputs.cargo_make_task }}
cd '${{ inputs.directory }}'
cargo make --no-workspace --profile=github-actions ci
# check the direct-minimal-versions on release
if [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
cargo make --no-workspace --profile=github-actions check-minimal-versions
fi
# Check if the counter_isomorphic can be built with leptos_debuginfo cfg flag in release mode
- name: ${{ inputs.cargo_make_task }} with --cfg=leptos_debuginfo
if: contains(inputs.directory, 'counter_isomorphic')
run: |
cd '${{ inputs.directory }}'
RUSTFLAGS="$RUSTFLAGS --cfg leptos_debuginfo" cargo leptos build --release
- name: Clean up ${{ inputs.directory }}
if: always()
run: |
cd '${{ inputs.directory }}'
cargo clean || true
rm -rf node_modules || true

View File

@@ -1,47 +0,0 @@
name: Verify All Examples
on:
workflow_dispatch:
push:
tags:
- v*
schedule:
# Run once a day at 3:00 AM EST
- cron: "0 8 * * *"
jobs:
setup:
name: Get Examples
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install JQ Tool
uses: mbround18/install-jq@v1
- name: Set Matrix
id: set-matrix
run: |
examples=$(ls examples |
awk '{print "examples/" $0}' |
grep -v examples/README.md |
grep -v examples/Makefile.toml |
grep -v examples/cargo-make |
grep -v examples/gtk |
jq -R -s -c 'split("\n")[:-1]')
echo "Example Directories: $examples"
echo "matrix={\"directory\":$examples}" >> "$GITHUB_OUTPUT"
matrix-job:
name: Verify
needs: [setup]
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
cargo_make_task: "verify-flow"

View File

@@ -1,71 +0,0 @@
name: Verify Changed Examples
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
setup:
name: Get Changes
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get all example files that changed
id: changed-files
uses: tj-actions/changed-files@v36
with:
files: |
examples
- name: List all example files that changed
run: echo '${{ steps.changed-files.outputs.all_changed_files }}'
- name: Get example project directories that changed
id: changed-dirs
uses: tj-actions/changed-files@v36
with:
dir_names: true
dir_names_max_depth: "2"
files: |
examples
!examples/cargo-make
!examples/gtk
!examples/Makefile.toml
!examples/README.md
json: true
quotepath: false
- name: List example project directories that changed
run: echo '${{ steps.changed-dirs.outputs.all_changed_files }}'
- name: Set Matrix
id: set-matrix
run: |
if [ ${{ steps.changed-files.outputs.any_changed }} == 'true' ]; then
# Create matrix with changed directories
echo "matrix={\"directory\":${{ steps.changed-dirs.outputs.all_changed_files }}}" >> "$GITHUB_OUTPUT"
else
# Create matrix with one item to prevent an empty vector error
echo "matrix={\"directory\":[\"INTERNAL\"]}" >> "$GITHUB_OUTPUT"
fi
matrix-job:
name: Verify
needs: [setup]
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
fail-fast: false
uses: ./.github/workflows/run-cargo-make-task.yml
with:
directory: ${{ matrix.directory }}
cargo_make_task: "verify-flow"

8
.gitignore vendored
View File

@@ -3,9 +3,15 @@ dist
pkg
comparisons
blob.rs
Cargo.lock
**/projects/**/Cargo.lock
**/examples/**/Cargo.lock
**/benchmarks/**/Cargo.lock
**/*.rs.bk
.DS_Store
.idea
.direnv
.envrc
.vscode
vendor
hash.txt

View File

@@ -220,8 +220,8 @@ for reference: they include large amounts of manual SSR route handling, etc.
## `cargo-leptos` helpers
`leptos_config` and `leptos_hot_reload` exist to support two different features
of `cargo-leptos`, namely its configuration and its view-patching/hot-
reloading features.
of `cargo-leptos`, namely its configuration and its view-patching/hot-reloading
features.
Its important to say that the main feature `cargo-leptos` remains its ability
to conveniently tie together different build tooling, compiling your app to

View File

@@ -62,7 +62,7 @@ are a few guidelines that will make it a better experience for everyone:
- If its an unsolicited PR not linked to an open issue, please include a
specific explanation for what its trying to achieve. For example: “When I
was trying to deploy my app under _circumstances X_, I found that the way
_function Z_ was implemented caused _issue Z_. This PR should fix that by
_function Y_ was implemented caused _issue Z_. This PR should fix that by
_solution._
- Our CI tests every PR against all the existing examples, sometimes requiring
compilation for both server and client side, etc. Its thorough but slow. If
@@ -70,6 +70,32 @@ are a few guidelines that will make it a better experience for everyone:
`cargo-make` and using `cargo make check && cargo make test && cargo make
check-examples`.
## Before Submitting a PR
We have a fairly extensive CI setup that runs both lints (like `rustfmt` and `clippy`)
and tests on PRs. You can run most of these locally if you have `cargo-make` installed.
Note that some of the `rustfmt` settings used require usage of the nightly compiler.
Formatting the code using the stable toolchain may result in a wrong code format and
subsequently CI errors.
Run `cargo +nightly fmt` if you want to keep the stable toolchain active.
You may want to let your IDE automatically use the `+nightly` parameter when a
"format on save" action is used.
If you added an example, make sure to add it to the list in `examples/Makefile.toml`.
From the root directory of the repo, run
- `cargo +nightly fmt`
- `cargo +nightly make check`
- `cargo +nightly make test`
- `cargo +nightly make check-examples`
- `cargo +nightly make --profile=github-actions ci`
If you modified an example:
- `cd examples/your_example`
- `cargo +nightly fmt -- --config-path ../..`
- `cargo +nightly make --profile=github-actions verify-flow`
## Architecture
See [ARCHITECTURE.md](./ARCHITECTURE.md).

4517
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +1,170 @@
[workspace]
resolver = "2"
members = [
# utilities
"oco",
"any_spawner",
"const_str_slice_concat",
"either_of",
"next_tuple",
"oco",
"or_poisoned",
# core
"hydration_context",
"leptos",
"leptos_dom",
"leptos_config",
"leptos_hot_reload",
"leptos_macro",
"leptos_reactive",
"leptos_server",
"reactive_graph",
"reactive_stores",
"reactive_stores_macro",
"server_fn",
"server_fn_macro",
"server_fn/server_fn_macro_default",
"tachys",
# integrations
"integrations/actix",
"integrations/axum",
"integrations/viz",
"integrations/utils",
# libraries
"meta",
"router",
"router_macro",
"any_error",
]
exclude = ["benchmarks", "examples"]
exclude = ["benchmarks", "examples", "projects"]
[workspace.package]
version = "0.4.3"
version = "0.8.2"
edition = "2021"
rust-version = "1.80"
[workspace.dependencies]
leptos = { path = "./leptos", version = "0.4.3" }
leptos_dom = { path = "./leptos_dom", version = "0.4.3" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.4.3" }
leptos_macro = { path = "./leptos_macro", version = "0.4.3" }
leptos_reactive = { path = "./leptos_reactive", version = "0.4.3" }
leptos_server = { path = "./leptos_server", version = "0.4.3" }
server_fn = { path = "./server_fn", version = "0.4.3" }
server_fn_macro = { path = "./server_fn_macro", version = "0.4.3" }
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.4.3" }
leptos_config = { path = "./leptos_config", version = "0.4.3" }
leptos_router = { path = "./router", version = "0.4.3" }
leptos_meta = { path = "./meta", version = "0.4.3" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.4.3" }
# members
throw_error = { path = "./any_error/", version = "0.3.0" }
any_spawner = { path = "./any_spawner/", version = "0.3.0" }
const_str_slice_concat = { path = "./const_str_slice_concat", version = "0.1" }
either_of = { path = "./either_of/", version = "0.1.5" }
hydration_context = { path = "./hydration_context", version = "0.3.0" }
leptos = { path = "./leptos", version = "0.8.2" }
leptos_config = { path = "./leptos_config", version = "0.8.2" }
leptos_dom = { path = "./leptos_dom", version = "0.8.2" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.8.2" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.8.2" }
leptos_macro = { path = "./leptos_macro", version = "0.8.2" }
leptos_router = { path = "./router", version = "0.8.2" }
leptos_router_macro = { path = "./router_macro", version = "0.8.2" }
leptos_server = { path = "./leptos_server", version = "0.8.2" }
leptos_meta = { path = "./meta", version = "0.8.2" }
next_tuple = { path = "./next_tuple", version = "0.1.0" }
oco_ref = { path = "./oco", version = "0.2.0" }
or_poisoned = { path = "./or_poisoned", version = "0.1.0" }
reactive_graph = { path = "./reactive_graph", version = "0.2.0" }
reactive_stores = { path = "./reactive_stores", version = "0.2.0" }
reactive_stores_macro = { path = "./reactive_stores_macro", version = "0.2.0" }
server_fn = { path = "./server_fn", version = "0.8.2" }
server_fn_macro = { path = "./server_fn_macro", version = "0.8.2" }
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.8.2" }
tachys = { path = "./tachys", version = "0.2.0" }
# members deps
itertools = { default-features = false, version = "0.14.0" }
convert_case = { default-features = false, version = "0.8.0" }
serde_json = { default-features = false, version = "1.0.140" }
trybuild = { default-features = false, version = "1.0.105" }
typed-builder = { default-features = false, version = "0.21.0" }
thiserror = { default-features = false, version = "2.0.12" }
wasm-bindgen = { default-features = false, version = "0.2.100" }
indexmap = { default-features = false, version = "2.9.0" }
rstml = { default-features = false, version = "0.12.1" }
rustc_version = { default-features = false, version = "0.4.1" }
guardian = { default-features = false, version = "1.3.0" }
rustc-hash = { default-features = false, version = "2.1.1" }
actix-web = { default-features = false, version = "4.11.0" }
tracing = { default-features = false, version = "0.1.41" }
slotmap = { default-features = false, version = "1.0.7" }
futures = { default-features = false, version = "0.3.31" }
dashmap = { default-features = false, version = "6.1.0" }
pin-project-lite = { default-features = false, version = "0.2.16" }
send_wrapper = { default-features = false, version = "0.6.0" }
tokio-test = { default-features = false, version = "0.4.4" }
html-escape = { default-features = false, version = "0.2.13" }
proc-macro-error2 = { default-features = false, version = "2.0.1" }
const_format = { default-features = false, version = "0.2.34" }
gloo-net = { default-features = false, version = "0.6.0" }
url = { default-features = false, version = "2.5.4" }
tokio = { default-features = false, version = "1.45.1" }
base64 = { default-features = false, version = "0.22.1" }
cfg-if = { default-features = false, version = "1.0.0" }
wasm-bindgen-futures = { default-features = false, version = "0.4.50" }
tower = { default-features = false, version = "0.5.2" }
proc-macro2 = { default-features = false, version = "1.0.95" }
serde = { default-features = false, version = "1.0.219" }
parking_lot = { default-features = false, version = "0.12.4" }
axum = { default-features = false, version = "0.8.4" }
serde_qs = { default-features = false, version = "0.15.0" }
syn = { default-features = false, version = "2.0.101" }
xxhash-rust = { default-features = false, version = "0.8.15" }
paste = { default-features = false, version = "1.0.15" }
quote = { default-features = false, version = "1.0.40" }
web-sys = { default-features = false, version = "0.3.77" }
js-sys = { default-features = false, version = "0.3.77" }
rand = { default-features = false, version = "0.9.1" }
serde-lite = { default-features = false, version = "0.5.0" }
tokio-tungstenite = { default-features = false, version = "0.26.2" }
serial_test = { default-features = false, version = "3.2.0" }
erased = { default-features = false, version = "0.1.2" }
glib = { default-features = false, version = "0.20.10" }
async-trait = { default-features = false, version = "0.1.88" }
typed-builder-macro = { default-features = false, version = "0.21.0" }
linear-map = { default-features = false, version = "1.2.0" }
anyhow = { default-features = false, version = "1.0.98" }
walkdir = { default-features = false, version = "2.5.0" }
actix-ws = { default-features = false, version = "0.3.0" }
tower-http = { default-features = false, version = "0.6.4" }
prettyplease = { default-features = false, version = "0.2.33" }
inventory = { default-features = false, version = "0.3.20" }
config = { default-features = false, version = "0.15.11" }
camino = { default-features = false, version = "1.1.9" }
ciborium = { default-features = false, version = "0.2.2" }
multer = { default-features = false, version = "3.1.0" }
leptos-spin-macro = { default-features = false, version = "0.2.0" }
sledgehammer_utils = { default-features = false, version = "0.3.1" }
sledgehammer_bindgen = { default-features = false, version = "0.6.0" }
wasm-streams = { default-features = false, version = "0.4.2" }
rkyv = { default-features = false, version = "0.8.10" }
temp-env = { default-features = false, version = "0.3.6" }
uuid = { default-features = false, version = "1.17.0" }
bytes = { default-features = false, version = "1.10.1" }
http = { default-features = false, version = "1.3.1" }
regex = { default-features = false, version = "1.11.1" }
drain_filter_polyfill = { default-features = false, version = "0.1.3" }
tempfile = { default-features = false, version = "3.20.0" }
futures-lite = { default-features = false, version = "2.6.0" }
log = { default-features = false, version = "0.4.27" }
percent-encoding = { default-features = false, version = "2.3.1" }
async-executor = { default-features = false, version = "1.13.2" }
const-str = { default-features = false, version = "0.6.2" }
http-body-util = { default-features = false, version = "0.1.3" }
hyper = { default-features = false, version = "1.6.0" }
postcard = { default-features = false, version = "1.1.1" }
rmp-serde = { default-features = false, version = "1.3.0" }
reqwest = { default-features = false, version = "0.12.18" }
tower-layer = { default-features = false, version = "0.3.3" }
attribute-derive = { default-features = false, version = "0.10.3" }
insta = { default-features = false, version = "1.43.1" }
codee = { default-features = false, version = "0.3.0" }
actix-http = { default-features = false, version = "3.11.0" }
wasm-bindgen-test = { default-features = false, version = "0.3.50" }
rustversion = { default-features = false, version = "1.0.21" }
getrandom = { default-features = false, version = "0.3.3" }
actix-files = { default-features = false, version = "0.6.6" }
async-lock = { default-features = false, version = "3.4.0" }
[profile.release]
codegen-units = 1
@@ -50,3 +173,10 @@ opt-level = 'z'
[workspace.metadata.cargo-all-features]
skip_feature_sets = [["csr", "ssr"], ["csr", "hydrate"], ["ssr", "hydrate"]]
max_combination_size = 2
[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(leptos_debuginfo)',
'cfg(erase_components)',
] }

View File

@@ -10,8 +10,8 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
workspace = false
clear = true
dependencies = [
{ name = "check", path = "examples/counter_without_macros" },
{ name = "check", path = "examples/counters_stable" },
{ name = "lint", path = "examples/counter_without_macros" },
{ name = "lint", path = "examples/counters_stable" },
]
[tasks.ci-examples]
@@ -20,6 +20,18 @@ cwd = "examples"
command = "cargo"
args = ["make", "ci-clean"]
[tasks.check-examples]
workspace = false
cwd = "examples"
command = "cargo"
args = ["make", "check-clean"]
[tasks.build-examples]
workspace = false
cwd = "examples"
command = "cargo"
args = ["make", "build-clean"]
[tasks.clean-examples]
workspace = false
cwd = "examples"

View File

@@ -5,20 +5,23 @@
[![crates.io](https://img.shields.io/crates/v/leptos.svg)](https://crates.io/crates/leptos)
[![docs.rs](https://docs.rs/leptos/badge.svg)](https://docs.rs/leptos)
![Crates.io MSRV](https://img.shields.io/crates/msrv/leptos)
[![Discord](https://img.shields.io/discord/1031524867910148188?color=%237289DA&label=discord)](https://discord.gg/YdRAhS7eQB)
[![Matrix](https://img.shields.io/badge/Matrix-leptos-grey?logo=matrix&labelColor=white&logoColor=black)](https://matrix.to/#/#leptos:matrix.org)
[Website](https://leptos.dev) | [Book](https://leptos-rs.github.io/leptos/) | [Docs.rs](https://docs.rs/leptos/latest/leptos/) | [Playground](https://codesandbox.io/p/sandbox/leptos-rtfggt?file=%2Fsrc%2Fmain.rs%3A1%2C1) | [Discord](https://discord.gg/YdRAhS7eQB)
You can find a list of useful libraries and example projects at [`awesome-leptos`](https://github.com/leptos-rs/awesome-leptos).
# Leptos
```rust
use leptos::*;
#[component]
pub fn SimpleCounter(cx: Scope, initial_value: i32) -> impl IntoView {
pub fn SimpleCounter(initial_value: i32) -> impl IntoView {
// create a reactive signal with the initial value
let (value, set_value) = create_signal(cx, initial_value);
let (value, set_value) = signal(initial_value);
// create event handlers for our buttons
// note that `value` and `set_value` are `Copy`, so it's super easy to move them into closures
@@ -27,21 +30,42 @@ pub fn SimpleCounter(cx: Scope, initial_value: i32) -> impl IntoView {
let increment = move |_| set_value.update(|value| *value += 1);
// create user interfaces with the declarative `view!` macro
view! { cx,
view! {
<div>
<button on:click=clear>"Clear"</button>
<button on:click=decrement>"-1"</button>
<button on:click=clear>Clear</button>
<button on:click=decrement>-1</button>
// text nodes can be quoted or unquoted
<span>"Value: " {value} "!"</span>
<button on:click=increment>"+1"</button>
<button on:click=increment>+1</button>
</div>
}
}
// Easy to use with Trunk (trunkrs.dev) or with a simple wasm-bindgen setup
pub fn main() {
mount_to_body(|cx| view! { cx, <SimpleCounter initial_value=3 /> })
// we also support a builder syntax rather than the JSX-like `view` macro
#[component]
pub fn SimpleCounterWithBuilder(initial_value: i32) -> impl IntoView {
use leptos::html::*;
let (value, set_value) = signal(initial_value);
let clear = move |_| set_value(0);
let decrement = move |_| set_value.update(|value| *value -= 1);
let increment = move |_| set_value.update(|value| *value += 1);
// the `view` macro above expands to this builder syntax
div().child((
button().on(ev::click, clear).child("Clear"),
button().on(ev::click, decrement).child("-1"),
span().child(("Value: ", value, "!")),
button().on(ev::click, increment).child("+1")
))
}
// Easy to use with Trunk (trunkrs.dev) or with a simple wasm-bindgen setup
pub fn main() {
mount_to_body(|| view! {
<SimpleCounter initial_value=3 />
})
}
```
## About the Framework
@@ -88,8 +112,6 @@ targets = ["wasm32-unknown-unknown"]
The `nightly` feature enables the function call syntax for accessing and setting signals, as opposed to `.get()` and `.set()`. This leads to a consistent mental model in which accessing a reactive value of any kind (a signal, memo, or derived signal) is always represented as a function call. This is only possible with nightly Rust and the `nightly` feature.
> Note: The `nightly` feature is present on the main branch version right now, but not in 0.3.x. For 0.3.x, nightly is the default and `stable` has a special feature.
## `cargo-leptos`
[`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos) is a build tool that's designed to make it easy to build apps that run on both the client and the server, with seamless integration. The best way to get started with a real Leptos project right now is to use `cargo-leptos` and our starter templates for [Actix](https://github.com/leptos-rs/start) or [Axum](https://github.com/leptos-rs/start-axum).
@@ -107,7 +129,7 @@ Open browser to [http://localhost:3000/](http://localhost:3000/).
### Whats up with the name?
_Leptos_ (λεπτός) is an ancient Greek word meaning “thin, light, refine, fine-grained.” To me, a classicist and not a dog owner, it evokes the lightweight reactive system that powers the framework. I've since learned the same word is at the root of the medical term “leptospirosis,” a blood infection that affects humans and animals... My bad. No dogs were harmed in the creation of this framework.
_Leptos_ (λεπτός) is an ancient Greek word meaning “thin, light, refined, fine-grained.” To me, a classicist and not a dog owner, it evokes the lightweight reactive system that powers the framework. I've since learned the same word is at the root of the medical term “leptospirosis,” a blood infection that affects humans and animals... My bad. No dogs were harmed in the creation of this framework.
### Is it production ready?
@@ -115,7 +137,7 @@ People usually mean one of three things by this question.
1. **Are the APIs stable?** i.e., will I have to rewrite my whole app from Leptos 0.1 to 0.2 to 0.3 to 0.4, or can I write it now and benefit from new features and updates as new versions come?
The APIs are basically settled. Were adding new features, but were very happy with where the type system and patterns have landed. I would not expect major breaking changes to your code to adapt to future releases. The sorts of breaking changes that we discuss are things like “Oh yeah, that function should probably take `cx` as its argument...” not major changes to the way you write your application.
The APIs are basically settled. Were adding new features, but were very happy with where the type system and patterns have landed. I would not expect major breaking changes to your code to adapt to future releases, in terms of architecture.
2. **Are there bugs?**
@@ -129,44 +151,34 @@ There are several people in the community using Leptos right now for internal ap
### Can I use this for native GUI?
Sure! Obviously the `view` macro is for generating DOM nodes but you can use the reactive system to drive native any GUI toolkit that uses the same kind of object-oriented, event-callback-based framework as the DOM pretty easily. The principles are the same:
Sure! Obviously the `view` macro is for generating DOM nodes but you can use the reactive system to drive any native GUI toolkit that uses the same kind of object-oriented, event-callback-based framework as the DOM pretty easily. The principles are the same:
- Use signals, derived signals, and memos to create your reactive system
- Create GUI widgets
- Use event listeners to update signals
- Create effects to update the UI
I've put together a [very simple GTK example](https://github.com/leptos-rs/leptos/blob/main/examples/gtk/src/main.rs) so you can see what I mean.
The 0.7 update originally set out to create a "generic rendering" approach that would allow us to reuse most of the same view logic to do all of the above. Unfortunately, this has had to be shelved for now due to difficulties encountered by the Rust compiler when building larger-scale applications with the number of generics spread throughout the codebase that this required. It's an approach I'm looking forward to exploring again in the future; feel free to reach out if you're interested in this kind of work.
### How is this different from Yew/Dioxus?
### How is this different from Yew?
On the surface level, these libraries may seem similar. Yew is, of course, the most mature Rust library for web UI development and has a huge ecosystem. Dioxus is similar in many ways, being heavily inspired by React. Here are some conceptual differences between Leptos and these frameworks:
Yew is the most-used library for Rust web UI development, but there are several differences between Yew and Leptos, in philosophy, approach, and performance.
- **VDOM vs. fine-grained:** Yew is built on the virtual DOM (VDOM) model: state changes cause components to re-render, generating a new virtual DOM tree. Yew diffs this against the previous VDOM, and applies those patches to the actual DOM. Component functions rerun whenever state changes. Leptos takes an entirely different approach. Components run once, creating (and returning) actual DOM nodes and setting up a reactive system to update those DOM nodes.
- **Performance:** This has huge performance implications: Leptos is simply much faster at both creating and updating the UI than Yew is. (Dioxus has made huge advances in performance with its recent 0.3 release, and is now roughly on par with Leptos.)
- **Mental model:** Adopting fine-grained reactivity also tends to simplify the mental model. There are no surprising component re-renders because there are no re-renders. You can call functions, create timeouts, etc. within the body of your component functions because they wont be re-run. You dont need to think about manual dependency tracking for effects; fine-grained reactivity tracks dependencies automatically.
- **Performance:** This has huge performance implications: Leptos is simply much faster at both creating and updating the UI than Yew is.
- **Server integration:** Yew was created in an era in which browser-rendered single-page apps (SPAs) were the dominant paradigm. While Leptos supports client-side rendering, it also focuses on integrating with the server side of your application via server functions and multiple modes of serving HTML, including out-of-order streaming.
### How is this different from Dioxus?
Like Leptos, Dioxus is a framework for building UIs using web technologies. However, there are significant differences in approach and features.
- **VDOM vs. fine-grained:** While Dioxus has a performant virtual DOM (VDOM), it still uses coarse-grained/component-scoped reactivity: changing a stateful value reruns the component function and diffs the old UI against the new one. Leptos components use a different mental model, creating (and returning) actual DOM nodes and setting up a reactive system to update those DOM nodes.
- **Web vs. desktop priorities:** Dioxus uses Leptos server functions in its fullstack mode, but does not have the same `<Suspense>`-based support for things like streaming HTML rendering, or share the same focus on holistic web performance. Leptos tends to prioritize holistic web performance (streaming HTML rendering, smaller WASM binary sizes, etc.), whereas Dioxus has an unparalleled experience when building desktop apps, because your application logic runs as a native Rust binary.
### How is this different from Sycamore?
Conceptually, these two frameworks are very similar: because both are built on fine-grained reactivity, most apps will end up looking very similar between the two, and Sycamore or Leptos apps will both look a lot like SolidJS apps, in the same way that Yew or Dioxus can look a lot like React.
Sycamore and Leptos are both heavily influenced by SolidJS. At this point, Leptos has a larger community and ecosystem and is more actively developed. Other differences:
There are some practical differences that make a significant difference:
- **Templating:** Leptos uses a JSX-like template format (built on [syn-rsx](https://github.com/stoically/syn-rsx)) for its `view` macro. Sycamore offers the choice of its own templating DSL or a builder syntax.
- **Server integration:** Leptos provides primitives that encourage HTML streaming and allow for easy async integration and RPC calls, even without WASM enabled, making it easy to opt into integrations between your frontend and backend code without pushing you toward any particular metaframework patterns.
- **Read-write segregation:** Leptos, like Solid, encourages read-write segregation between signal getters and setters, so you end up accessing signals with tuples like `let (count, set_count) = create_signal(cx, 0);` _(If you prefer or if it's more convenient for your API, you can use [`create_rw_signal`](https://docs.rs/leptos/latest/leptos/fn.create_rw_signal.html) to give a unified read/write signal.)_
- **Signals are functions:** In Leptos, you can call a signal to access it rather than calling a specific method (so, `count()` instead of `count.get()`) This creates a more consistent mental model: accessing a reactive value is always a matter of calling a function. For example:
```rust
let (count, set_count) = create_signal(cx, 0); // a signal
let double_count = move || count() * 2; // a derived signal
let memoized_count = create_memo(cx, move |_| count() * 3); // a memo
// all are accessed by calling them
assert_eq!(count(), 0);
assert_eq!(double_count(), 0);
assert_eq!(memoized_count(), 0);
// this function can accept any of those signals
fn do_work_on_signal(my_signal: impl Fn() -> i32) { ... }
```
- **Signals and scopes are `'static`:** Both Leptos and Sycamore ease the pain of moving signals in closures (in particular, event listeners) by making them `Copy`, to avoid the `{ let count = count.clone(); move |_| ... }` that's very familiar in Rust UI code. Sycamore does this by using bump allocation to tie the lifetimes of its signals to its scopes: since references are `Copy`, `&'a Signal<T>` can be moved into a closure. Leptos does this by using arena allocation and passing around indices: types like `ReadSignal<T>`, `WriteSignal<T>`, and `Memo<T>` are actually wrappers for indices into an arena. This means that both scopes and signals are both `Copy` and `'static` in Leptos, which means that they can be moved easily into closures without adding lifetime complexity.
- **Templating DSLs:** Sycamore uses a custom templating language for its views, while Leptos uses a JSX-like template format.
- **`'static` signals:** One of Leptoss main innovations was the creation of `Copy + 'static` signals, which have excellent ergonomics. Sycamore is in the process of adopting the same pattern, but this is not yet released.
- **Perseus vs. server functions:** The Perseus metaframework provides an opinionated way to build Sycamore apps that include server functionality. Leptos instead provides primitives like server functions in the core of the framework.

13
SECURITY.md Normal file
View File

@@ -0,0 +1,13 @@
# Security Policy
## Reporting a Vulnerability
To report a suspected security issue, please contact security@leptos.dev rather than opening
a public issue.
## Supported Versions
The most-recently-released version of the library is supported with security updates.
For example, if a security issue is discovered that affects 0.3.2 and all later releases,
a 0.4.x patch will be released but a new 0.3.x patch release will not be made. You should
plan to update to the latest version to receive any new features or bugfixes of any kind.

40
TODO.md Normal file
View File

@@ -0,0 +1,40 @@
- core examples
- [x] counter
- [x] counters
- [x] fetch
- [x] todomvc
- [x] error_boundary
- [x] parent\_child
- [x] on: on components
- [ ] router
- [ ] slots
- [ ] hackernews
- [ ] counter\_isomorphic
- [ ] todo\_app\_sqlite
- other ssr examples
- [ ] error boundary SSR
- reactivity
- Signal wrappers
- SignalDispose implementations on all Copy types
- untracked access warnings
- ErrorBoundary
- [ ] RenderHtml implementation
- [ ] Separate component?
- Suspense/Transition components?
- callbacks
- unsync StoredValue
- SSR
- escaping HTML correctly (attributes + text nodes)
- router
- nested routes
- trailing slashes
- \_meta package (and use in hackernews)
- integrations
- update tests
- hackernews example
- TODOs
- Suspense/Transition/Await components
- nicer routing components
- async routing (waiting for data to load before navigation)
- `<A>` component
- figure out rebuilding issues: list (needs new signal IDs) vs. regular rebuild

13
any_error/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "throw_error"
version = "0.3.0"
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"
repository = "https://github.com/leptos-rs/leptos"
description = "Utilities for wrapping, throwing, and catching errors."
rust-version.workspace = true
edition.workspace = true
[dependencies]
pin-project-lite = { workspace = true, default-features = true }

2
any_error/README.md Normal file
View File

@@ -0,0 +1,2 @@
A utility library for wrapping arbitrary errors, and for “throwing” errors in a way
that can be caught by user-defined error hooks.

160
any_error/src/lib.rs Normal file
View File

@@ -0,0 +1,160 @@
#![forbid(unsafe_code)]
#![deny(missing_docs)]
//! A utility library for wrapping arbitrary errors, and for “throwing” errors in a way
//! that can be caught by user-defined error hooks.
use std::{
cell::RefCell,
error,
fmt::{self, Display},
future::Future,
ops,
pin::Pin,
sync::Arc,
task::{Context, Poll},
};
/* Wrapper Types */
/// A generic wrapper for any error.
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct Error(Arc<dyn error::Error + Send + Sync>);
impl Error {
/// Converts the wrapper into the inner reference-counted error.
pub fn into_inner(self) -> Arc<dyn error::Error + Send + Sync> {
Arc::clone(&self.0)
}
}
impl ops::Deref for Error {
type Target = Arc<dyn error::Error + Send + Sync>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<T> From<T> for Error
where
T: error::Error + Send + Sync + 'static,
{
fn from(value: T) -> Self {
Error(Arc::new(value))
}
}
/// Implements behavior that allows for global or scoped error handling.
///
/// This allows for both "throwing" errors to register them, and "clearing" errors when they are no
/// longer valid. This is useful for something like a user interface, in which an error can be
/// "thrown" on some invalid user input, and later "cleared" if the user corrects the input.
/// Keeping a unique identifier for each error allows the UI to be updated accordingly.
pub trait ErrorHook: Send + Sync {
/// Handles the given error, returning a unique identifier.
fn throw(&self, error: Error) -> ErrorId;
/// Clears the error associated with the given identifier.
fn clear(&self, id: &ErrorId);
}
/// A unique identifier for an error. This is returned when you call [`throw`], which calls a
/// global error handler.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Default)]
pub struct ErrorId(usize);
impl Display for ErrorId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
impl From<usize> for ErrorId {
fn from(value: usize) -> Self {
Self(value)
}
}
thread_local! {
static ERROR_HOOK: RefCell<Option<Arc<dyn ErrorHook>>> = RefCell::new(None);
}
/// Resets the error hook to its previous state when dropped.
pub struct ResetErrorHookOnDrop(Option<Arc<dyn ErrorHook>>);
impl Drop for ResetErrorHookOnDrop {
fn drop(&mut self) {
ERROR_HOOK.with_borrow_mut(|this| *this = self.0.take())
}
}
/// Returns the current error hook.
pub fn get_error_hook() -> Option<Arc<dyn ErrorHook>> {
ERROR_HOOK.with_borrow(Clone::clone)
}
/// Sets the current thread-local error hook, which will be invoked when [`throw`] is called.
pub fn set_error_hook(hook: Arc<dyn ErrorHook>) -> ResetErrorHookOnDrop {
ResetErrorHookOnDrop(
ERROR_HOOK.with_borrow_mut(|this| Option::replace(this, hook)),
)
}
/// Invokes the error hook set by [`set_error_hook`] with the given error.
pub fn throw(error: impl Into<Error>) -> ErrorId {
ERROR_HOOK
.with_borrow(|hook| hook.as_ref().map(|hook| hook.throw(error.into())))
.unwrap_or_default()
}
/// Clears the given error from the current error hook.
pub fn clear(id: &ErrorId) {
ERROR_HOOK
.with_borrow(|hook| hook.as_ref().map(|hook| hook.clear(id)))
.unwrap_or_default()
}
pin_project_lite::pin_project! {
/// A [`Future`] that reads the error hook that is set when it is created, and sets this as the
/// current error hook whenever it is polled.
pub struct ErrorHookFuture<Fut> {
hook: Option<Arc<dyn ErrorHook>>,
#[pin]
inner: Fut
}
}
impl<Fut> ErrorHookFuture<Fut> {
/// Reads the current hook and wraps the given [`Future`], returning a new `Future` that will
/// set the error hook whenever it is polled.
pub fn new(inner: Fut) -> Self {
Self {
hook: ERROR_HOOK.with_borrow(Clone::clone),
inner,
}
}
}
impl<Fut> Future for ErrorHookFuture<Fut>
where
Fut: Future,
{
type Output = Fut::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let _hook = this
.hook
.as_ref()
.map(|hook| set_error_hook(Arc::clone(hook)));
this.inner.poll(cx)
}
}

47
any_spawner/Cargo.toml Normal file
View File

@@ -0,0 +1,47 @@
[package]
name = "any_spawner"
version = "0.3.0"
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"
repository = "https://github.com/leptos-rs/leptos"
description = "Spawn asynchronous tasks in an executor-independent way."
edition.workspace = true
[dependencies]
async-executor = { optional = true , workspace = true, default-features = true }
futures = { workspace = true, default-features = true }
glib = { optional = true , workspace = true, default-features = true }
thiserror = { workspace = true , default-features = true }
tokio = { optional = true, default-features = false, features = [
"rt",
] , workspace = true }
tracing = { optional = true , workspace = true, default-features = true }
wasm-bindgen-futures = { optional = true , workspace = true, default-features = true }
[dev-dependencies]
futures-lite = { default-features = false , workspace = true }
tokio = { default-features = false, features = [
"rt",
"macros",
"time",
] , workspace = true }
wasm-bindgen-test = { workspace = true, default-features = true }
serial_test = { workspace = true, default-features = true }
[features]
async-executor = ["dep:async-executor"]
tracing = ["dep:tracing"]
tokio = ["dep:tokio"]
glib = ["dep:glib"]
wasm-bindgen = ["dep:wasm-bindgen-futures"]
futures-executor = ["futures/thread-pool", "futures/executor"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.cargo-all-features]
denylist = ["tracing"]
max_combination_size = 2

View File

@@ -0,0 +1,4 @@
extend = [
{ path = "../cargo-make/main.toml" },
{ path = "../cargo-make/wasm-test.toml" },
]

26
any_spawner/README.md Normal file
View File

@@ -0,0 +1,26 @@
This crate makes it easier to write asynchronous code that is executor-agnostic, by providing a
utility that can be used to spawn tasks in a variety of executors.
It only supports single executor per program, but that executor can be set at runtime, anywhere
in your crate (or an application that depends on it).
This can be extended to support any executor or runtime that supports spawning [`Future`]s.
This is a least common denominator implementation in many ways. Limitations include:
- setting an executor is a one-time, global action
- no "join handle" or other result is returned from the spawn
- the `Future` must output `()`
```rust
use any_spawner::Executor;
Executor::init_futures_executor()
.expect("executor should only be initialized once");
// spawn a thread-safe Future
Executor::spawn(async { /* ... */ });
// spawn a Future that is !Send
Executor::spawn_local(async { /* ... */ });
```

514
any_spawner/src/lib.rs Normal file
View File

@@ -0,0 +1,514 @@
//! This crate makes it easier to write asynchronous code that is executor-agnostic, by providing a
//! utility that can be used to spawn tasks in a variety of executors.
//!
//! It only supports single executor per program, but that executor can be set at runtime, anywhere
//! in your crate (or an application that depends on it).
//!
//! This can be extended to support any executor or runtime that supports spawning [`Future`]s.
//!
//! This is a least common denominator implementation in many ways. Limitations include:
//! - setting an executor is a one-time, global action
//! - no "join handle" or other result is returned from the spawn
//! - the `Future` must output `()`
//!
//! ```no_run
//! use any_spawner::Executor;
//!
//! // make sure an Executor has been initialized with one of the init_ functions
//!
//! // spawn a thread-safe Future
//! Executor::spawn(async { /* ... */ });
//!
//! // spawn a Future that is !Send
//! Executor::spawn_local(async { /* ... */ });
//! ```
#![forbid(unsafe_code)]
#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use std::{future::Future, pin::Pin, sync::OnceLock};
use thiserror::Error;
/// A future that has been pinned.
pub type PinnedFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
/// A future that has been pinned.
pub type PinnedLocalFuture<T> = Pin<Box<dyn Future<Output = T>>>;
// Type alias for the spawn function pointer.
type SpawnFn = fn(PinnedFuture<()>);
// Type alias for the spawn_local function pointer.
type SpawnLocalFn = fn(PinnedLocalFuture<()>);
// Type alias for the poll_local function pointer.
type PollLocalFn = fn();
/// Holds the function pointers for the current global executor.
#[derive(Clone, Copy)]
struct ExecutorFns {
spawn: SpawnFn,
spawn_local: SpawnLocalFn,
poll_local: PollLocalFn,
}
// Use a single OnceLock to ensure atomic initialization of all functions.
static EXECUTOR_FNS: OnceLock<ExecutorFns> = OnceLock::new();
// No-op functions to use when an executor doesn't support a specific operation.
#[cfg(any(feature = "tokio", feature = "wasm-bindgen", feature = "glib"))]
#[cold]
#[inline(never)]
fn no_op_poll() {}
#[cfg(all(not(feature = "wasm-bindgen"), not(debug_assertions)))]
#[cold]
#[inline(never)]
fn no_op_spawn(_: PinnedFuture<()>) {
#[cfg(debug_assertions)]
eprintln!(
"Warning: Executor::spawn called, but no global 'spawn' function is \
configured (perhaps only spawn_local is supported, e.g., on wasm \
without threading?)."
);
}
// Wasm panics if you spawn without an executor
#[cfg(feature = "wasm-bindgen")]
#[cold]
#[inline(never)]
fn no_op_spawn(_: PinnedFuture<()>) {
panic!(
"Executor::spawn called, but no global 'spawn' function is configured."
);
}
#[cfg(not(debug_assertions))]
#[cold]
#[inline(never)]
fn no_op_spawn_local(_: PinnedLocalFuture<()>) {
panic!(
"Executor::spawn_local called, but no global 'spawn_local' function \
is configured."
);
}
/// Errors that can occur when using the executor.
#[derive(Error, Debug)]
pub enum ExecutorError {
/// The executor has already been set.
#[error("Global executor has already been set.")]
AlreadySet,
}
/// A global async executor that can spawn tasks.
pub struct Executor;
impl Executor {
/// Spawns a thread-safe [`Future`].
///
/// Uses the globally configured executor.
/// Panics if no global executor has been initialized.
#[inline(always)]
#[track_caller]
pub fn spawn(fut: impl Future<Output = ()> + Send + 'static) {
let pinned_fut = Box::pin(fut);
if let Some(fns) = EXECUTOR_FNS.get() {
(fns.spawn)(pinned_fut)
} else {
// No global executor set.
handle_uninitialized_spawn(pinned_fut);
}
}
/// Spawns a [`Future`] that cannot be sent across threads.
///
/// Uses the globally configured executor.
/// Panics if no global executor has been initialized.
#[inline(always)]
#[track_caller]
pub fn spawn_local(fut: impl Future<Output = ()> + 'static) {
let pinned_fut = Box::pin(fut);
if let Some(fns) = EXECUTOR_FNS.get() {
(fns.spawn_local)(pinned_fut)
} else {
// No global executor set.
handle_uninitialized_spawn_local(pinned_fut);
}
}
/// Waits until the next "tick" of the current async executor.
/// Respects the global executor.
#[inline(always)]
pub async fn tick() {
let (tx, rx) = futures::channel::oneshot::channel();
#[cfg(not(all(feature = "wasm-bindgen", target_family = "wasm")))]
Executor::spawn(async move {
_ = tx.send(());
});
#[cfg(all(feature = "wasm-bindgen", target_family = "wasm"))]
Executor::spawn_local(async move {
_ = tx.send(());
});
_ = rx.await;
}
/// Polls the global async executor.
///
/// Uses the globally configured executor.
/// Does nothing if the global executor does not support polling.
#[inline(always)]
pub fn poll_local() {
if let Some(fns) = EXECUTOR_FNS.get() {
(fns.poll_local)()
}
// If not initialized or doesn't support polling, do nothing gracefully.
}
}
impl Executor {
/// Globally sets the [`tokio`] runtime as the executor used to spawn tasks.
///
/// Returns `Err(_)` if a global executor has already been set.
///
/// Requires the `tokio` feature to be activated on this crate.
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
pub fn init_tokio() -> Result<(), ExecutorError> {
let executor_impl = ExecutorFns {
spawn: |fut| {
tokio::spawn(fut);
},
spawn_local: |fut| {
tokio::task::spawn_local(fut);
},
// Tokio doesn't have an explicit global poll function like LocalPool::run_until_stalled
poll_local: no_op_poll,
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
/// Globally sets the [`wasm-bindgen-futures`] runtime as the executor used to spawn tasks.
///
/// Returns `Err(_)` if a global executor has already been set.
///
/// Requires the `wasm-bindgen` feature to be activated on this crate.
#[cfg(feature = "wasm-bindgen")]
#[cfg_attr(docsrs, doc(cfg(feature = "wasm-bindgen")))]
pub fn init_wasm_bindgen() -> Result<(), ExecutorError> {
let executor_impl = ExecutorFns {
// wasm-bindgen-futures only supports spawn_local
spawn: no_op_spawn,
spawn_local: |fut| {
wasm_bindgen_futures::spawn_local(fut);
},
poll_local: no_op_poll,
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
/// Globally sets the [`glib`] runtime as the executor used to spawn tasks.
///
/// Returns `Err(_)` if a global executor has already been set.
///
/// Requires the `glib` feature to be activated on this crate.
#[cfg(feature = "glib")]
#[cfg_attr(docsrs, doc(cfg(feature = "glib")))]
pub fn init_glib() -> Result<(), ExecutorError> {
let executor_impl = ExecutorFns {
spawn: |fut| {
let main_context = glib::MainContext::default();
main_context.spawn(fut);
},
spawn_local: |fut| {
let main_context = glib::MainContext::default();
main_context.spawn_local(fut);
},
// Glib needs event loop integration, explicit polling isn't the standard model here.
poll_local: no_op_poll,
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
/// Globally sets the [`futures`] executor as the executor used to spawn tasks,
/// lazily creating a thread pool to spawn tasks into.
///
/// Returns `Err(_)` if a global executor has already been set.
///
/// Requires the `futures-executor` feature to be activated on this crate.
#[cfg(feature = "futures-executor")]
#[cfg_attr(docsrs, doc(cfg(feature = "futures-executor")))]
pub fn init_futures_executor() -> Result<(), ExecutorError> {
use futures::{
executor::{LocalPool, LocalSpawner, ThreadPool},
task::{LocalSpawnExt, SpawnExt},
};
use std::cell::RefCell;
// Keep the lazy-init ThreadPool and thread-local LocalPool for spawn_local impl
static THREAD_POOL: OnceLock<ThreadPool> = OnceLock::new();
thread_local! {
static LOCAL_POOL: RefCell<LocalPool> = RefCell::new(LocalPool::new());
// SPAWNER is derived from LOCAL_POOL, keep it for efficiency inside the closure
static SPAWNER: LocalSpawner = LOCAL_POOL.with(|pool| pool.borrow().spawner());
}
fn get_thread_pool() -> &'static ThreadPool {
THREAD_POOL.get_or_init(|| {
ThreadPool::new()
.expect("could not create futures executor ThreadPool")
})
}
let executor_impl = ExecutorFns {
spawn: |fut| {
get_thread_pool()
.spawn(fut)
.expect("failed to spawn future on ThreadPool");
},
spawn_local: |fut| {
// Use the thread_local SPAWNER derived from LOCAL_POOL
SPAWNER.with(|spawner| {
spawner
.spawn_local(fut)
.expect("failed to spawn local future");
});
},
poll_local: || {
// Use the thread_local LOCAL_POOL
LOCAL_POOL.with(|pool| {
// Use try_borrow_mut to prevent panic during re-entrant calls
if let Ok(mut pool) = pool.try_borrow_mut() {
pool.run_until_stalled();
}
// If already borrowed, we're likely in a nested poll, so do nothing.
});
},
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
/// Globally sets the [`async_executor`] executor as the executor used to spawn tasks,
/// lazily creating a thread pool to spawn tasks into.
///
/// Returns `Err(_)` if a global executor has already been set.
///
/// Requires the `async-executor` feature to be activated on this crate.
#[cfg(feature = "async-executor")]
#[cfg_attr(docsrs, doc(cfg(feature = "async-executor")))]
pub fn init_async_executor() -> Result<(), ExecutorError> {
use async_executor::{Executor as AsyncExecutor, LocalExecutor};
// Keep the lazy-init global Executor and thread-local LocalExecutor for spawn_local impl
static ASYNC_EXECUTOR: OnceLock<AsyncExecutor<'static>> =
OnceLock::new();
thread_local! {
static LOCAL_EXECUTOR_POOL: LocalExecutor<'static> = const { LocalExecutor::new() };
}
fn get_async_executor() -> &'static AsyncExecutor<'static> {
ASYNC_EXECUTOR.get_or_init(AsyncExecutor::new)
}
let executor_impl = ExecutorFns {
spawn: |fut| {
get_async_executor().spawn(fut).detach();
},
spawn_local: |fut| {
LOCAL_EXECUTOR_POOL.with(|pool| pool.spawn(fut).detach());
},
poll_local: || {
LOCAL_EXECUTOR_POOL.with(|pool| {
// try_tick polls the local executor without blocking
// This prevents issues if called recursively or from within a task.
pool.try_tick();
});
},
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
/// Globally sets a custom executor as the executor used to spawn tasks.
///
/// Requires the custom executor to be `Send + Sync` as it will be stored statically.
///
/// Returns `Err(_)` if a global executor has already been set.
pub fn init_custom_executor(
custom_executor: impl CustomExecutor + Send + Sync + 'static,
) -> Result<(), ExecutorError> {
// Store the custom executor instance itself to call its methods.
// Use Box for dynamic dispatch.
static CUSTOM_EXECUTOR_INSTANCE: OnceLock<
Box<dyn CustomExecutor + Send + Sync>,
> = OnceLock::new();
CUSTOM_EXECUTOR_INSTANCE
.set(Box::new(custom_executor))
.map_err(|_| ExecutorError::AlreadySet)?;
// Now set the ExecutorFns using the stored instance
let executor_impl = ExecutorFns {
spawn: |fut| {
// Unwrap is safe because we just set it successfully or returned Err.
CUSTOM_EXECUTOR_INSTANCE.get().unwrap().spawn(fut);
},
spawn_local: |fut| {
CUSTOM_EXECUTOR_INSTANCE.get().unwrap().spawn_local(fut);
},
poll_local: || {
CUSTOM_EXECUTOR_INSTANCE.get().unwrap().poll_local();
},
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
// If setting EXECUTOR_FNS fails (extremely unlikely race if called *concurrently*
// with another init_* after CUSTOM_EXECUTOR_INSTANCE was set), we technically
// leave CUSTOM_EXECUTOR_INSTANCE set but EXECUTOR_FNS not. This is an edge case,
// but the primary race condition is solved.
}
/// Sets a custom executor *for the current thread only*.
///
/// This overrides the global executor for calls to `spawn`, `spawn_local`, and `poll_local`
/// made *from the current thread*. It does not affect other threads or the global state.
///
/// The provided `custom_executor` must implement [`CustomExecutor`] and `'static`, but does
/// **not** need to be `Send` or `Sync`.
///
/// Returns `Err(ExecutorError::AlreadySet)` if a *local* executor has already been set
/// *for this thread*.
pub fn init_local_custom_executor(
custom_executor: impl CustomExecutor + 'static,
) -> Result<(), ExecutorError> {
// Store the custom executor instance itself to call its methods.
// Use Box for dynamic dispatch.
thread_local! {
static CUSTOM_EXECUTOR_INSTANCE: OnceLock<
Box<dyn CustomExecutor>,
> = OnceLock::new();
};
CUSTOM_EXECUTOR_INSTANCE.with(|this| {
this.set(Box::new(custom_executor))
.map_err(|_| ExecutorError::AlreadySet)
})?;
// Now set the ExecutorFns using the stored instance
let executor_impl = ExecutorFns {
spawn: |fut| {
// Unwrap is safe because we just set it successfully or returned Err.
CUSTOM_EXECUTOR_INSTANCE
.with(|this| this.get().unwrap().spawn(fut));
},
spawn_local: |fut| {
CUSTOM_EXECUTOR_INSTANCE
.with(|this| this.get().unwrap().spawn_local(fut));
},
poll_local: || {
CUSTOM_EXECUTOR_INSTANCE
.with(|this| this.get().unwrap().poll_local());
},
};
EXECUTOR_FNS
.set(executor_impl)
.map_err(|_| ExecutorError::AlreadySet)
}
}
/// A trait for custom executors.
/// Custom executors can be used to integrate with any executor that supports spawning futures.
///
/// If used with `init_custom_executor`, the implementation must be `Send + Sync + 'static`.
///
/// All methods can be called recursively. Implementors should be mindful of potential
/// deadlocks or excessive resource consumption if recursive calls are not handled carefully
/// (e.g., using `try_borrow_mut` or non-blocking polls within implementations).
pub trait CustomExecutor {
/// Spawns a future, usually on a thread pool.
fn spawn(&self, fut: PinnedFuture<()>);
/// Spawns a local future. May require calling `poll_local` to make progress.
fn spawn_local(&self, fut: PinnedLocalFuture<()>);
/// Polls the executor, if it supports polling. Implementations should ideally be
/// non-blocking or use mechanisms like `try_tick` or `try_borrow_mut` to handle
/// re-entrant calls safely.
fn poll_local(&self);
}
// Ensure CustomExecutor is object-safe
#[allow(dead_code)]
fn test_object_safety(_: Box<dyn CustomExecutor + Send + Sync>) {} // Added Send + Sync constraint here for global usage
/// Handles the case where `Executor::spawn` is called without an initialized executor.
#[cold] // Less likely path
#[inline(never)]
#[track_caller]
fn handle_uninitialized_spawn(_fut: PinnedFuture<()>) {
let caller = std::panic::Location::caller();
#[cfg(all(debug_assertions, feature = "tracing"))]
{
tracing::error!(
target: "any_spawner",
spawn_caller=%caller,
"Executor::spawn called before a global executor was initialized. Task dropped."
);
// Drop the future implicitly after logging
drop(_fut);
}
#[cfg(all(debug_assertions, not(feature = "tracing")))]
{
panic!(
"At {caller}, tried to spawn a Future with Executor::spawn() \
before a global executor was initialized."
);
}
// In release builds (without tracing), call the specific no-op function.
#[cfg(not(debug_assertions))]
{
no_op_spawn(_fut);
}
}
/// Handles the case where `Executor::spawn_local` is called without an initialized executor.
#[cold] // Less likely path
#[inline(never)]
#[track_caller]
fn handle_uninitialized_spawn_local(_fut: PinnedLocalFuture<()>) {
let caller = std::panic::Location::caller();
#[cfg(all(debug_assertions, feature = "tracing"))]
{
tracing::error!(
target: "any_spawner",
spawn_caller=%caller,
"Executor::spawn_local called before a global executor was initialized. \
Task likely dropped or panicked."
);
// Fall through to panic or no-op depending on build/target
}
#[cfg(all(debug_assertions, not(feature = "tracing")))]
{
panic!(
"At {caller}, tried to spawn a Future with \
Executor::spawn_local() before a global executor was initialized."
);
}
// In release builds (without tracing), call the specific no-op function (which usually panics).
#[cfg(not(debug_assertions))]
{
no_op_spawn_local(_fut);
}
}

View File

@@ -0,0 +1,24 @@
use any_spawner::{Executor, ExecutorError};
#[test]
fn test_already_set_error() {
struct SimpleExecutor;
impl any_spawner::CustomExecutor for SimpleExecutor {
fn spawn(&self, _fut: any_spawner::PinnedFuture<()>) {}
fn spawn_local(&self, _fut: any_spawner::PinnedLocalFuture<()>) {}
fn poll_local(&self) {}
}
// First initialization should succeed
Executor::init_custom_executor(SimpleExecutor)
.expect("First initialization failed");
// Second initialization should fail with AlreadySet error
let result = Executor::init_custom_executor(SimpleExecutor);
assert!(matches!(result, Err(ExecutorError::AlreadySet)));
// First local initialization should fail
let result = Executor::init_local_custom_executor(SimpleExecutor);
assert!(matches!(result, Err(ExecutorError::AlreadySet)));
}

View File

@@ -0,0 +1,74 @@
#![cfg(feature = "async-executor")]
use std::{
future::Future,
pin::Pin,
sync::{Arc, Mutex},
};
// A simple async executor for testing
struct TestExecutor {
tasks: Mutex<Vec<Pin<Box<dyn Future<Output = ()> + Send + 'static>>>>,
}
impl TestExecutor {
fn new() -> Self {
TestExecutor {
tasks: Mutex::new(Vec::new()),
}
}
fn spawn<F>(&self, future: F)
where
F: Future<Output = ()> + Send + 'static,
{
self.tasks.lock().unwrap().push(Box::pin(future));
}
fn run_all(&self) {
// Take all tasks out to process them
let tasks = self.tasks.lock().unwrap().drain(..).collect::<Vec<_>>();
// Use a basic future executor to run each task to completion
for mut task in tasks {
// Use futures-lite's block_on to complete the future
futures::executor::block_on(async {
unsafe {
let task_mut = Pin::new_unchecked(&mut task);
let _ = std::future::Future::poll(
task_mut,
&mut std::task::Context::from_waker(
futures::task::noop_waker_ref(),
),
);
}
});
}
}
}
#[test]
fn test_async_executor() {
let executor = Arc::new(TestExecutor::new());
let executor_clone = executor.clone();
// Create a spawner function that will use our test executor
let spawner = move |future| {
executor_clone.spawn(future);
};
// Prepare test data
let counter = Arc::new(Mutex::new(0));
let counter_clone = counter.clone();
// Use the spawner to spawn a task
spawner(async move {
*counter_clone.lock().unwrap() += 1;
});
// Run all tasks
executor.run_all();
// Check if the task completed correctly
assert_eq!(*counter.lock().unwrap(), 1);
}

View File

@@ -0,0 +1,63 @@
use any_spawner::Executor;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
#[test]
fn test_custom_executor() {
// Define a simple custom executor
struct TestExecutor {
spawn_called: Arc<AtomicBool>,
spawn_local_called: Arc<AtomicBool>,
poll_local_called: Arc<AtomicBool>,
}
impl any_spawner::CustomExecutor for TestExecutor {
fn spawn(&self, fut: any_spawner::PinnedFuture<()>) {
self.spawn_called.store(true, Ordering::SeqCst);
// Execute the future immediately (this works for simple test futures)
futures::executor::block_on(fut);
}
fn spawn_local(&self, fut: any_spawner::PinnedLocalFuture<()>) {
self.spawn_local_called.store(true, Ordering::SeqCst);
// Execute the future immediately
futures::executor::block_on(fut);
}
fn poll_local(&self) {
self.poll_local_called.store(true, Ordering::SeqCst);
}
}
let spawn_called = Arc::new(AtomicBool::new(false));
let spawn_local_called = Arc::new(AtomicBool::new(false));
let poll_local_called = Arc::new(AtomicBool::new(false));
let executor = TestExecutor {
spawn_called: spawn_called.clone(),
spawn_local_called: spawn_local_called.clone(),
poll_local_called: poll_local_called.clone(),
};
// Initialize with our custom executor
Executor::init_custom_executor(executor)
.expect("Failed to initialize custom executor");
// Test spawn
Executor::spawn(async {
// Simple task
});
assert!(spawn_called.load(Ordering::SeqCst));
// Test spawn_local
Executor::spawn_local(async {
// Simple local task
});
assert!(spawn_local_called.load(Ordering::SeqCst));
// Test poll_local
Executor::poll_local();
assert!(poll_local_called.load(Ordering::SeqCst));
}

View File

@@ -0,0 +1,56 @@
#![cfg(feature = "futures-executor")]
use any_spawner::{CustomExecutor, Executor, PinnedFuture, PinnedLocalFuture};
#[test]
fn can_create_custom_executor() {
use futures::{
executor::{LocalPool, LocalSpawner},
task::LocalSpawnExt,
};
use std::{
cell::RefCell,
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
};
thread_local! {
static LOCAL_POOL: RefCell<LocalPool> = RefCell::new(LocalPool::new());
static SPAWNER: LocalSpawner = LOCAL_POOL.with(|pool| pool.borrow().spawner());
}
struct CustomFutureExecutor;
impl CustomExecutor for CustomFutureExecutor {
fn spawn(&self, _fut: PinnedFuture<()>) {
panic!("not supported in this test");
}
fn spawn_local(&self, fut: PinnedLocalFuture<()>) {
SPAWNER.with(|spawner| {
spawner.spawn_local(fut).expect("failed to spawn future");
});
}
fn poll_local(&self) {
LOCAL_POOL.with(|pool| {
if let Ok(mut pool) = pool.try_borrow_mut() {
pool.run_until_stalled();
}
// If we couldn't borrow_mut, we're in a nested call to poll, so we don't need to do anything.
});
}
}
Executor::init_custom_executor(CustomFutureExecutor)
.expect("couldn't set executor");
let counter = Arc::new(AtomicUsize::new(0));
let counter_clone = Arc::clone(&counter);
Executor::spawn_local(async move {
counter_clone.store(1, Ordering::Release);
});
Executor::poll_local();
assert_eq!(counter.load(Ordering::Acquire), 1);
}

View File

@@ -0,0 +1,28 @@
#![cfg(feature = "tokio")]
use any_spawner::Executor;
use std::{
sync::{Arc, Mutex},
time::Duration,
};
#[tokio::test]
async fn test_executor_tick() {
// Initialize the tokio executor
Executor::init_tokio().expect("Failed to initialize tokio executor");
let value = Arc::new(Mutex::new(false));
let value_clone = value.clone();
// Spawn a task that sets the value after a tick
Executor::spawn(async move {
Executor::tick().await;
*value_clone.lock().unwrap() = true;
});
// Allow some time for the task to complete
tokio::time::sleep(Duration::from_millis(50)).await;
// Check that the value was set
assert!(*value.lock().unwrap());
}

View File

@@ -0,0 +1,44 @@
#![cfg(feature = "futures-executor")]
use any_spawner::Executor;
use futures::channel::oneshot;
use std::{
sync::{Arc, Mutex},
time::Duration,
};
#[test]
fn test_futures_executor() {
// Initialize the futures executor
Executor::init_futures_executor()
.expect("Failed to initialize futures executor");
let (tx, rx) = oneshot::channel();
let result = Arc::new(Mutex::new(None));
let result_clone = result.clone();
// Spawn a task
Executor::spawn(async move {
tx.send(84).expect("Failed to send value");
});
// Spawn a task that waits for the result
Executor::spawn(async move {
match rx.await {
Ok(val) => *result_clone.lock().unwrap() = Some(val),
Err(_) => panic!("Failed to receive value"),
}
});
// Poll a few times to ensure the task completes
for _ in 0..10 {
Executor::poll_local();
std::thread::sleep(Duration::from_millis(10));
if result.lock().unwrap().is_some() {
break;
}
}
assert_eq!(*result.lock().unwrap(), Some(84));
}

View File

@@ -0,0 +1,37 @@
#![cfg(feature = "futures-executor")]
use any_spawner::Executor;
// All tests in this file use the same executor.
#[test]
fn can_spawn_local_future() {
use std::rc::Rc;
let _ = Executor::init_futures_executor();
let rc = Rc::new(());
Executor::spawn_local(async {
_ = rc;
});
Executor::spawn(async {});
}
#[test]
fn can_make_local_progress() {
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
let _ = Executor::init_futures_executor();
let counter = Arc::new(AtomicUsize::new(0));
Executor::spawn_local({
let counter = Arc::clone(&counter);
async move {
assert_eq!(counter.fetch_add(1, Ordering::AcqRel), 0);
Executor::spawn_local(async {
// Should not crash
});
}
});
Executor::poll_local();
assert_eq!(counter.load(Ordering::Acquire), 1);
}

151
any_spawner/tests/glib.rs Normal file
View File

@@ -0,0 +1,151 @@
#![cfg(feature = "glib")]
use any_spawner::Executor;
use glib::{MainContext, MainLoop};
use serial_test::serial;
use std::{
cell::Cell,
future::Future,
rc::Rc,
sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
time::Duration,
};
// Helper to run a future to completion on a dedicated glib MainContext.
// Returns true if the future completed within the timeout, false otherwise.
fn run_on_glib_context<F>(fut: F)
where
F: Future<Output = ()> + Send + 'static,
{
let _ = Executor::init_glib();
let context = MainContext::default();
let main_loop = MainLoop::new(Some(&context), false);
let main_loop_clone = main_loop.clone();
Executor::spawn(async move {
fut.await;
main_loop_clone.quit();
});
main_loop.run();
}
// Helper to run a local (!Send) future on the glib context.
fn run_local_on_glib_context<F>(fut: F)
where
F: Future<Output = ()> + 'static,
{
let _ = Executor::init_glib();
let context = MainContext::default();
let main_loop = MainLoop::new(Some(&context), false);
let main_loop_clone = main_loop.clone();
Executor::spawn_local(async move {
fut.await;
main_loop_clone.quit();
});
main_loop.run();
}
// This test must run after a test that successfully initializes glib,
// or within its own process.
#[test]
#[serial]
fn test_glib_spawn() {
let success_flag = Arc::new(AtomicBool::new(false));
let flag_clone = success_flag.clone();
run_on_glib_context(async move {
// Simulate async work
futures_lite::future::yield_now().await;
flag_clone.store(true, Ordering::SeqCst);
// We need to give the spawned task time to run.
// The run_on_glib_context handles the main loop.
// We just need to ensure spawn happened correctly.
// Let's wait a tiny bit within the driving future to ensure spawn gets processed.
glib::timeout_future(Duration::from_millis(10)).await;
});
assert!(
success_flag.load(Ordering::SeqCst),
"Spawned future did not complete successfully"
);
}
// Similar conditions as test_glib_spawn regarding initialization state.
#[test]
#[serial]
fn test_glib_spawn_local() {
let success_flag = Rc::new(Cell::new(false));
let flag_clone = success_flag.clone();
run_local_on_glib_context(async move {
// Use Rc to make the future !Send
let non_send_data = Rc::new(Cell::new(10));
let data = non_send_data.get();
assert_eq!(data, 10, "Rc data should be accessible");
non_send_data.set(20); // Modify non-Send data
// Simulate async work
futures_lite::future::yield_now().await;
assert_eq!(
non_send_data.get(),
20,
"Rc data should persist modification"
);
flag_clone.set(true);
// Wait a tiny bit
glib::timeout_future(Duration::from_millis(10)).await;
});
assert!(
success_flag.get(),
"Spawned local future did not complete successfully"
);
}
// Test Executor::tick with glib backend
#[test]
#[serial]
fn test_glib_tick() {
run_on_glib_context(async {
let value = Arc::new(Mutex::new(false));
let value_clone = value.clone();
// Spawn a task that sets the value after a tick
Executor::spawn(async move {
Executor::tick().await;
*value_clone.lock().unwrap() = true;
});
// Allow some time for the task to complete
glib::timeout_future(Duration::from_millis(10)).await;
// Check that the value was set
assert!(*value.lock().unwrap());
});
}
// Test Executor::poll_local with glib backend (should be a no-op)
#[test]
#[serial]
fn test_glib_poll_local_is_no_op() {
// Ensure glib executor is initialized
let _ = Executor::init_glib();
// poll_local for glib is configured as a no-op
// Calling it should not panic or cause issues.
Executor::poll_local();
Executor::poll_local();
println!("Executor::poll_local called successfully (expected no-op).");
}

View File

@@ -0,0 +1,54 @@
use any_spawner::Executor;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
#[test]
fn test_local_custom_executor() {
// Define a thread-local custom executor
struct LocalTestExecutor {
spawn_called: Arc<AtomicBool>,
spawn_local_called: Arc<AtomicBool>,
}
impl any_spawner::CustomExecutor for LocalTestExecutor {
fn spawn(&self, fut: any_spawner::PinnedFuture<()>) {
self.spawn_called.store(true, Ordering::SeqCst);
futures::executor::block_on(fut);
}
fn spawn_local(&self, fut: any_spawner::PinnedLocalFuture<()>) {
self.spawn_local_called.store(true, Ordering::SeqCst);
futures::executor::block_on(fut);
}
fn poll_local(&self) {
// No-op for this test
}
}
let local_spawn_called = Arc::new(AtomicBool::new(false));
let local_spawn_local_called = Arc::new(AtomicBool::new(false));
let local_executor = LocalTestExecutor {
spawn_called: local_spawn_called.clone(),
spawn_local_called: local_spawn_local_called.clone(),
};
// Initialize a thread-local executor
Executor::init_local_custom_executor(local_executor)
.expect("Failed to initialize local custom executor");
// Test spawn - should use the thread-local executor
Executor::spawn(async {
// Simple task
});
assert!(local_spawn_called.load(Ordering::SeqCst));
// Test spawn_local - should use the thread-local executor
Executor::spawn_local(async {
// Simple local task
});
assert!(local_spawn_local_called.load(Ordering::SeqCst));
}

View File

@@ -0,0 +1,35 @@
#![cfg(feature = "tokio")]
use any_spawner::Executor;
use futures::channel::oneshot;
use std::sync::{Arc, Mutex};
#[tokio::test]
async fn test_multiple_tasks() {
Executor::init_tokio().expect("Failed to initialize tokio executor");
let counter = Arc::new(Mutex::new(0));
let tasks = 10;
let mut handles = Vec::new();
// Spawn multiple tasks that increment the counter
for _ in 0..tasks {
let counter_clone = counter.clone();
let (tx, rx) = oneshot::channel();
Executor::spawn(async move {
*counter_clone.lock().unwrap() += 1;
tx.send(()).expect("Failed to send completion signal");
});
handles.push(rx);
}
// Wait for all tasks to complete
for handle in handles {
handle.await.expect("Task failed");
}
// Verify that all tasks incremented the counter
assert_eq!(*counter.lock().unwrap(), tasks);
}

View File

@@ -0,0 +1,20 @@
#![cfg(feature = "tokio")]
use any_spawner::Executor;
use futures::channel::oneshot;
#[tokio::test]
async fn test_tokio_executor() {
// Initialize the tokio executor
Executor::init_tokio().expect("Failed to initialize tokio executor");
let (tx, rx) = oneshot::channel();
// Spawn a task that sends a value
Executor::spawn(async move {
tx.send(42).expect("Failed to send value");
});
// Wait for the spawned task to complete
assert_eq!(rx.await.unwrap(), 42);
}

View File

@@ -0,0 +1,88 @@
#![cfg(all(feature = "wasm-bindgen", target_family = "wasm"))]
use any_spawner::Executor;
use futures::channel::oneshot;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
async fn test_wasm_bindgen_spawn_local() {
// Initialize the wasm-bindgen executor
let _ = Executor::init_wasm_bindgen();
// Create a channel to verify the task completes
let (tx, rx) = oneshot::channel();
// Spawn a local task (wasm doesn't support sending futures between threads)
Executor::spawn_local(async move {
// Simulate some async work
Executor::tick().await;
tx.send(42).expect("Failed to send result");
});
// Wait for the task to complete
let result = rx.await.expect("Failed to receive result");
assert_eq!(result, 42);
}
#[wasm_bindgen_test]
async fn test_wasm_bindgen_tick() {
// Initialize the wasm-bindgen executor if not already initialized
let _ = Executor::init_wasm_bindgen();
let flag = Arc::new(AtomicBool::new(false));
let flag_clone = flag.clone();
// Spawn a task that will set the flag
Executor::spawn_local(async move {
flag_clone.store(true, Ordering::SeqCst);
});
// Wait for a tick, which should allow the spawned task to run
Executor::tick().await;
// Verify the flag was set
assert!(flag.load(Ordering::SeqCst));
}
#[wasm_bindgen_test]
async fn test_multiple_wasm_bindgen_tasks() {
// Initialize once for all tests
let _ = Executor::init_wasm_bindgen();
// Create channels for multiple tasks
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
// Spawn multiple tasks
Executor::spawn_local(async move {
tx1.send("task1").expect("Failed to send from task1");
});
Executor::spawn_local(async move {
tx2.send("task2").expect("Failed to send from task2");
});
// Wait for both tasks to complete
let (result1, result2) = futures::join!(rx1, rx2);
assert_eq!(result1.unwrap(), "task1");
assert_eq!(result2.unwrap(), "task2");
}
// This test verifies that spawn (not local) fails on wasm as expected
#[wasm_bindgen_test]
#[should_panic]
fn test_wasm_bindgen_spawn_errors() {
let _ = Executor::init_wasm_bindgen();
// Using should_panic to test that Executor::spawn panics in wasm
Executor::spawn(async {
// This should panic since wasm-bindgen doesn't support Send futures
});
}

View File

@@ -2,26 +2,36 @@
name = "benchmarks"
version = "0.1.0"
edition = "2021"
# std::sync::LazyLock is stabilized in Rust version 1.80.0
rust-version = "1.80.0"
[dependencies]
l021 = { package = "leptos", version = "0.2.1" }
leptos = { path = "../leptos", features = ["ssr"] }
sycamore = { version = "0.8", features = ["ssr"] }
yew = { git = "https://github.com/yewstack/yew", features = ["ssr"] }
tokio-test = "0.4"
miniserde = "0.1"
gloo = "0.8"
uuid = { version = "1", features = ["serde", "v4", "wasm-bindgen"] }
wasm-bindgen = "0.2"
lazy_static = "1"
log = "0.4"
strum = "0.24"
strum_macros = "0.24"
serde = { version = "1", features = ["derive", "rc"] }
serde_json = "1"
tera = "1"
reactive-signals = "0.1.0-alpha.4"
l0410 = { package = "leptos", version = "0.4.10", features = [
"nightly",
"ssr",
] }
leptos = { path = "../leptos", features = ["ssr", "nightly"] }
leptos_reactive = { path = "../leptos_reactive", features = ["ssr", "nightly"] }
tachydom = { git = "https://github.com/gbj/tachys", features = [
"nightly",
"leptos",
] }
tachy_maccy = { git = "https://github.com/gbj/tachys", features = ["nightly"] }
sycamore = { version = "0.8.0", features = ["ssr"] }
yew = { version = "0.20.0", features = ["ssr"] }
tokio-test = "0.4.0"
miniserde = "0.1.0"
gloo = "0.8.0"
uuid = { version = "1.0", features = ["serde", "v4", "wasm-bindgen"] }
wasm-bindgen = "0.2.100"
lazy_static = "1.0"
log = "0.4.0"
strum = "0.24.0"
strum_macros = "0.24.0"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
tera = "1.0"
[dependencies.web-sys]
version = "0.3"
version = "0.3.0"
features = ["Window", "Document", "HtmlElement", "HtmlInputElement"]

View File

@@ -2,6 +2,6 @@
extern crate test;
//åmod reactive;
//mod ssr;
mod reactive;
mod ssr;
mod todomvc;

View File

@@ -7,19 +7,16 @@ fn leptos_deep_creation(b: &mut Bencher) {
let runtime = create_runtime();
b.iter(|| {
create_scope(runtime, |cx| {
let signal = create_rw_signal(cx, 0);
let mut memos = Vec::<Memo<usize>>::new();
for _ in 0..1000usize {
let prev = memos.last().copied();
if let Some(prev) = prev {
memos.push(create_memo(cx, move |_| prev.get() + 1));
} else {
memos.push(create_memo(cx, move |_| signal.get() + 1));
}
let signal = create_rw_signal(0);
let mut memos = Vec::<Memo<usize>>::new();
for _ in 0..1000usize {
let prev = memos.last().copied();
if let Some(prev) = prev {
memos.push(create_memo(move |_| prev.get() + 1));
} else {
memos.push(create_memo(move |_| signal.get() + 1));
}
})
.dispose()
}
});
runtime.dispose();
@@ -31,20 +28,17 @@ fn leptos_deep_update(b: &mut Bencher) {
let runtime = create_runtime();
b.iter(|| {
create_scope(runtime, |cx| {
let signal = create_rw_signal(cx, 0);
let mut memos = Vec::<Memo<usize>>::new();
for _ in 0..1000usize {
if let Some(prev) = memos.last().copied() {
memos.push(create_memo(cx, move |_| prev.get() + 1));
} else {
memos.push(create_memo(cx, move |_| signal.get() + 1));
}
let signal = create_rw_signal(0);
let mut memos = Vec::<Memo<usize>>::new();
for _ in 0..1000usize {
if let Some(prev) = memos.last().copied() {
memos.push(create_memo(move |_| prev.get() + 1));
} else {
memos.push(create_memo(move |_| signal.get() + 1));
}
signal.set(1);
assert_eq!(memos[999].get(), 1001);
})
.dispose()
}
signal.set(1);
assert_eq!(memos[999].get(), 1001);
});
runtime.dispose();
@@ -56,17 +50,12 @@ fn leptos_narrowing_down(b: &mut Bencher) {
let runtime = create_runtime();
b.iter(|| {
create_scope(runtime, |cx| {
let sigs =
(0..1000).map(|n| create_signal(cx, n)).collect::<Vec<_>>();
let reads = sigs.iter().map(|(r, _)| *r).collect::<Vec<_>>();
let writes = sigs.iter().map(|(_, w)| *w).collect::<Vec<_>>();
let memo = create_memo(cx, move |_| {
reads.iter().map(|r| r.get()).sum::<i32>()
});
assert_eq!(memo(), 499500);
})
.dispose()
let sigs = (0..1000).map(|n| create_signal(n)).collect::<Vec<_>>();
let reads = sigs.iter().map(|(r, _)| *r).collect::<Vec<_>>();
let writes = sigs.iter().map(|(_, w)| *w).collect::<Vec<_>>();
let memo =
create_memo(move |_| reads.iter().map(|r| r.get()).sum::<i32>());
assert_eq!(memo(), 499500);
});
runtime.dispose();
@@ -78,16 +67,13 @@ fn leptos_fanning_out(b: &mut Bencher) {
let runtime = create_runtime();
b.iter(|| {
create_scope(runtime, |cx| {
let sig = create_rw_signal(cx, 0);
let memos = (0..1000)
.map(|_| create_memo(cx, move |_| sig.get()))
.collect::<Vec<_>>();
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 0);
sig.set(1);
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 1000);
})
.dispose()
let sig = create_rw_signal(0);
let memos = (0..1000)
.map(|_| create_memo(move |_| sig.get()))
.collect::<Vec<_>>();
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 0);
sig.set(1);
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 1000);
});
runtime.dispose();
@@ -98,143 +84,36 @@ fn leptos_narrowing_update(b: &mut Bencher) {
use leptos::*;
let runtime = create_runtime();
b.iter(|| {
create_scope(runtime, |cx| {
let acc = Rc::new(Cell::new(0));
let sigs =
(0..1000).map(|n| create_signal(cx, n)).collect::<Vec<_>>();
let reads = sigs.iter().map(|(r, _)| *r).collect::<Vec<_>>();
let writes = sigs.iter().map(|(_, w)| *w).collect::<Vec<_>>();
let memo = create_memo(cx, move |_| {
reads.iter().map(|r| r.get()).sum::<i32>()
});
assert_eq!(memo(), 499500);
create_isomorphic_effect(cx, {
let acc = Rc::clone(&acc);
move |_| {
acc.set(memo());
}
});
assert_eq!(acc.get(), 499500);
writes[1].update(|n| *n += 1);
writes[10].update(|n| *n += 1);
writes[100].update(|n| *n += 1);
assert_eq!(acc.get(), 499503);
assert_eq!(memo(), 499503);
})
.dispose()
});
runtime.dispose();
}
#[bench]
fn leptos_scope_creation_and_disposal(b: &mut Bencher) {
use leptos::*;
let runtime = create_runtime();
b.iter(|| {
let acc = Rc::new(Cell::new(0));
let disposers = (0..1000)
.map(|_| {
create_scope(runtime, {
let acc = Rc::clone(&acc);
move |cx| {
let (r, w) = create_signal(cx, 0);
create_isomorphic_effect(cx, {
move |_| {
acc.set(r());
}
});
w.update(|n| *n += 1);
}
})
})
.collect::<Vec<_>>();
for disposer in disposers {
disposer.dispose();
}
});
runtime.dispose();
}
#[bench]
fn rs_deep_update(b: &mut Bencher) {
use reactive_signals::{Scope, Signal, signal, runtimes::ClientRuntime, types::Func};
let sc = ClientRuntime::new_root_scope();
b.iter(|| {
let signal = signal!(sc, 0);
let mut memos = Vec::<Signal<Func<i32>, ClientRuntime>>::new();
for i in 0..1000usize {
let prev = memos.get(i.saturating_sub(1)).copied();
if let Some(prev) = prev {
memos.push(signal!(sc, move || prev.get() + 1))
} else {
memos.push(signal!(sc, move || signal.get() + 1))
}
}
signal.set(1);
assert_eq!(memos[999].get(), 1001);
});
}
#[bench]
fn rs_fanning_out(b: &mut Bencher) {
use reactive_signals::{Scope, Signal, signal, runtimes::ClientRuntime, types::Func};
let cx = ClientRuntime::new_root_scope();
b.iter(|| {
let sig = signal!(cx, 0);
let memos = (0..1000)
.map(|_| signal!(cx, move || sig.get()))
.collect::<Vec<_>>();
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 0);
sig.set(1);
assert_eq!(memos.iter().map(|m| m.get()).sum::<i32>(), 1000);
});
}
#[bench]
fn rs_narrowing_update(b: &mut Bencher) {
use reactive_signals::{Scope, Signal, signal, runtimes::ClientRuntime, types::Func};
let cx = ClientRuntime::new_root_scope();
b.iter(|| {
let acc = Rc::new(Cell::new(0));
let sigs =
(0..1000).map(|n| signal!(cx, n)).collect::<Vec<_>>();
let memo = signal!(cx, {
let sigs = sigs.clone();
move || {
sigs.iter().map(|r| r.get()).sum::<i32>()
}
});
assert_eq!(memo.get(), 499500);
signal!(cx, {
let sigs = (0..1000).map(|n| create_signal(n)).collect::<Vec<_>>();
let reads = sigs.iter().map(|(r, _)| *r).collect::<Vec<_>>();
let writes = sigs.iter().map(|(_, w)| *w).collect::<Vec<_>>();
let memo =
create_memo(move |_| reads.iter().map(|r| r.get()).sum::<i32>());
assert_eq!(memo(), 499500);
create_isomorphic_effect({
let acc = Rc::clone(&acc);
move || {
acc.set(memo.get());
move |_| {
acc.set(memo());
}
});
assert_eq!(acc.get(), 499500);
sigs[1].update(|n| *n += 1);
sigs[10].update(|n| *n += 1);
sigs[100].update(|n| *n += 1);
writes[1].update(|n| *n += 1);
writes[10].update(|n| *n += 1);
writes[100].update(|n| *n += 1);
assert_eq!(acc.get(), 499503);
assert_eq!(memo.get(), 499503);
assert_eq!(memo(), 499503);
});
runtime.dispose();
}
#[bench]
fn l021_deep_creation(b: &mut Bencher) {
use l021::*;
fn l0410_deep_creation(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -256,8 +135,8 @@ fn l021_deep_creation(b: &mut Bencher) {
}
#[bench]
fn l021_deep_update(b: &mut Bencher) {
use l021::*;
fn l0410_deep_update(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -281,8 +160,8 @@ fn l021_deep_update(b: &mut Bencher) {
}
#[bench]
fn l021_narrowing_down(b: &mut Bencher) {
use l021::*;
fn l0410_narrowing_down(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -304,8 +183,8 @@ fn l021_narrowing_down(b: &mut Bencher) {
}
#[bench]
fn l021_fanning_out(b: &mut Bencher) {
use leptos::*;
fn l0410_fanning_out(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -324,8 +203,8 @@ fn l021_fanning_out(b: &mut Bencher) {
runtime.dispose();
}
#[bench]
fn l021_narrowing_update(b: &mut Bencher) {
use l021::*;
fn l0410_narrowing_update(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -338,11 +217,11 @@ fn l021_narrowing_update(b: &mut Bencher) {
let memo = create_memo(cx, move |_| {
reads.iter().map(|r| r.get()).sum::<i32>()
});
assert_eq!(memo(), 499500);
assert_eq!(memo.get(), 499500);
create_isomorphic_effect(cx, {
let acc = Rc::clone(&acc);
move |_| {
acc.set(memo());
acc.set(memo.get());
}
});
assert_eq!(acc.get(), 499500);
@@ -352,7 +231,7 @@ fn l021_narrowing_update(b: &mut Bencher) {
writes[100].update(|n| *n += 1);
assert_eq!(acc.get(), 499503);
assert_eq!(memo(), 499503);
assert_eq!(memo.get(), 499503);
})
.dispose()
});
@@ -361,8 +240,8 @@ fn l021_narrowing_update(b: &mut Bencher) {
}
#[bench]
fn l021_scope_creation_and_disposal(b: &mut Bencher) {
use l021::*;
fn l0410_scope_creation_and_disposal(b: &mut Bencher) {
use l0410::*;
let runtime = create_runtime();
b.iter(|| {
@@ -375,7 +254,7 @@ fn l021_scope_creation_and_disposal(b: &mut Bencher) {
let (r, w) = create_signal(cx, 0);
create_isomorphic_effect(cx, {
move |_| {
acc.set(r());
acc.set(r.get());
}
});
w.update(|n| *n += 1);

View File

@@ -2,15 +2,14 @@ use test::Bencher;
#[bench]
fn leptos_ssr_bench(b: &mut Bencher) {
use leptos::*;
let r = create_runtime();
b.iter(|| {
use leptos::*;
leptos_dom::HydrationCtx::reset_id();
_ = create_scope(create_runtime(), |cx| {
leptos::leptos_dom::HydrationCtx::reset_id();
#[component]
fn Counter(cx: Scope, initial: i32) -> impl IntoView {
let (value, set_value) = create_signal(cx, initial);
fn Counter(initial: i32) -> impl IntoView {
let (value, set_value) = create_signal(initial);
view! {
cx,
<div>
<button on:click=move |_| set_value.update(|value| *value -= 1)>"-1"</button>
<span>"Value: " {move || value().to_string()} "!"</span>
@@ -19,8 +18,7 @@ fn leptos_ssr_bench(b: &mut Bencher) {
}
}
let rendered = view! {
cx,
let rendered = view! {
<main>
<h1>"Welcome to our benchmark page."</h1>
<p>"Here's some introductory text."</p>
@@ -28,14 +26,53 @@ fn leptos_ssr_bench(b: &mut Bencher) {
<Counter initial=2/>
<Counter initial=3/>
</main>
}.into_view(cx).render_to_string(cx);
}.into_view().render_to_string();
assert_eq!(
rendered,
"<main id=\"_0-1\"><h1 id=\"_0-2\">Welcome to our benchmark page.</h1><p id=\"_0-3\">Here&#x27;s some introductory text.</p><div id=\"_0-3-1\"><button id=\"_0-3-2\">-1</button><span id=\"_0-3-3\">Value: <!>1<!--hk=_0-3-4-->!</span><button id=\"_0-3-5\">+1</button></div><!--hk=_0-3-0--><div id=\"_0-3-5-1\"><button id=\"_0-3-5-2\">-1</button><span id=\"_0-3-5-3\">Value: <!>2<!--hk=_0-3-5-4-->!</span><button id=\"_0-3-5-5\">+1</button></div><!--hk=_0-3-5-0--><div id=\"_0-3-5-5-1\"><button id=\"_0-3-5-5-2\">-1</button><span id=\"_0-3-5-5-3\">Value: <!>3<!--hk=_0-3-5-5-4-->!</span><button id=\"_0-3-5-5-5\">+1</button></div><!--hk=_0-3-5-5-0--></main>"
);
});
"<main data-hk=\"0-0-0-1\"><h1 data-hk=\"0-0-0-2\">Welcome to our benchmark page.</h1><p data-hk=\"0-0-0-3\">Here&#x27;s some introductory text.</p><div data-hk=\"0-0-0-5\"><button data-hk=\"0-0-0-6\">-1</button><span data-hk=\"0-0-0-7\">Value: <!>1<!--hk=0-0-0-8-->!</span><button data-hk=\"0-0-0-9\">+1</button></div><!--hk=0-0-0-4--><div data-hk=\"0-0-0-11\"><button data-hk=\"0-0-0-12\">-1</button><span data-hk=\"0-0-0-13\">Value: <!>2<!--hk=0-0-0-14-->!</span><button data-hk=\"0-0-0-15\">+1</button></div><!--hk=0-0-0-10--><div data-hk=\"0-0-0-17\"><button data-hk=\"0-0-0-18\">-1</button><span data-hk=\"0-0-0-19\">Value: <!>3<!--hk=0-0-0-20-->!</span><button data-hk=\"0-0-0-21\">+1</button></div><!--hk=0-0-0-16--></main>" );
});
r.dispose();
}
#[bench]
fn tachys_ssr_bench(b: &mut Bencher) {
use leptos::{create_runtime, create_signal, SignalGet, SignalUpdate};
use tachy_maccy::view;
use tachydom::view::{Render, RenderHtml};
use tachydom::html::element::ElementChild;
use tachydom::html::attribute::global::ClassAttribute;
use tachydom::html::attribute::global::GlobalAttributes;
use tachydom::html::attribute::global::OnAttribute;
use tachydom::renderer::dom::Dom;
let rt = create_runtime();
b.iter(|| {
fn counter(initial: i32) -> impl Render<Dom> + RenderHtml<Dom> {
let (value, set_value) = create_signal(initial);
view! {
<div>
<button on:click=move |_| set_value.update(|value| *value -= 1)>"-1"</button>
<span>"Value: " {move || value().to_string()} "!"</span>
<button on:click=move |_| set_value.update(|value| *value += 1)>"+1"</button>
</div>
}
}
let rendered = view! {
<main>
<h1>"Welcome to our benchmark page."</h1>
<p>"Here's some introductory text."</p>
{counter(1)}
{counter(2)}
{counter(3)}
</main>
}.to_html();
assert_eq!(
rendered,
"<main><h1>Welcome to our benchmark page.</h1><p>Here's some introductory text.</p><div><button>-1</button><span>Value: <!>1<!>!</span><button>+1</button></div><div><button>-1</button><span>Value: <!>2<!>!</span><button>+1</button></div><div><button>-1</button><span>Value: <!>3<!>!</span><button>+1</button></div></main>"
);
});
rt.dispose();
}
#[bench]
@@ -55,13 +92,13 @@ fn tera_ssr_bench(b: &mut Bencher) {
{% endfor %}
</main>"#;
lazy_static::lazy_static! {
static ref TERA: Tera = {
let mut tera = Tera::default();
tera.add_raw_templates(vec![("template.html", TEMPLATE)]).unwrap();
tera
};
}
static LazyCell<TERA>: Tera = LazyLock::new(|| {
let mut tera = Tera::default();
tera.add_raw_templates(vec![("template.html", TEMPLATE)]).unwrap();
tera
});
#[derive(Serialize, Deserialize)]
struct Counter {

View File

@@ -1,7 +1,7 @@
pub use leptos::*;
use miniserde::*;
use web_sys::HtmlInputElement;
use wasm_bindgen::JsCast;
use web_sys::HtmlInputElement;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Todos(pub Vec<Todo>);
@@ -9,13 +9,13 @@ pub struct Todos(pub Vec<Todo>);
const STORAGE_KEY: &str = "todos-leptos";
impl Todos {
pub fn new(cx: Scope) -> Self {
pub fn new() -> Self {
Self(vec![])
}
pub fn new_with_1000(cx: Scope) -> Self {
pub fn new_with_1000() -> Self {
let todos = (0..1000)
.map(|id| Todo::new(cx, id, format!("Todo #{id}")))
.map(|id| Todo::new(id, format!("Todo #{id}")))
.collect();
Self(todos)
}
@@ -72,13 +72,17 @@ pub struct Todo {
}
impl Todo {
pub fn new(cx: Scope, id: usize, title: String) -> Self {
Self::new_with_completed(cx, id, title, false)
pub fn new(id: usize, title: String) -> Self {
Self::new_with_completed(id, title, false)
}
pub fn new_with_completed(cx: Scope, id: usize, title: String, completed: bool) -> Self {
let (title, set_title) = create_signal(cx, title);
let (completed, set_completed) = create_signal(cx, completed);
pub fn new_with_completed(
id: usize,
title: String,
completed: bool,
) -> Self {
let (title, set_title) = create_signal(title);
let (completed, set_completed) = create_signal(completed);
Self {
id,
title,
@@ -98,7 +102,7 @@ const ESCAPE_KEY: u32 = 27;
const ENTER_KEY: u32 = 13;
#[component]
pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
pub fn TodoMVC(todos: Todos) -> impl IntoView {
let mut next_id = todos
.0
.iter()
@@ -107,10 +111,10 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
.map(|last| last + 1)
.unwrap_or(0);
let (todos, set_todos) = create_signal(cx, todos);
provide_context(cx, set_todos);
let (todos, set_todos) = create_signal(todos);
provide_context(set_todos);
let (mode, set_mode) = create_signal(cx, Mode::All);
let (mode, set_mode) = create_signal(Mode::All);
let add_todo = move |ev: web_sys::KeyboardEvent| {
let target = event_target::<HtmlInputElement>(&ev);
@@ -120,7 +124,7 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
let title = event_target_value(&ev);
let title = title.trim();
if !title.is_empty() {
let new = Todo::new(cx, next_id, title.to_string());
let new = Todo::new(next_id, title.to_string());
set_todos.update(|t| t.add(new));
next_id += 1;
target.set_value("");
@@ -128,7 +132,7 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
}
};
let filtered_todos = create_memo::<Vec<Todo>>(cx, move |_| {
let filtered_todos = create_memo::<Vec<Todo>>(move |_| {
todos.with(|todos| match mode.get() {
Mode::All => todos.0.to_vec(),
Mode::Active => todos
@@ -148,7 +152,7 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
// effect to serialize to JSON
// this does reactive reads, so it will automatically serialize on any relevant change
create_effect(cx, move |_| {
create_effect(move |_| {
if let Ok(Some(storage)) = window().local_storage() {
let objs = todos
.get()
@@ -163,7 +167,7 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
}
});
view! { cx,
view! {
<main>
<section class="todoapp">
<header class="header">
@@ -188,8 +192,8 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
<For
each=filtered_todos
key=|todo| todo.id
view=move |cx, todo: Todo| {
view! { cx, <Todo todo=todo.clone()/> }
children=move |todo: Todo| {
view! { <Todo todo=todo.clone()/> }
}
/>
</ul>
@@ -236,14 +240,14 @@ pub fn TodoMVC(cx: Scope, todos: Todos) -> impl IntoView {
<p>"Part of " <a href="http://todomvc.com">"TodoMVC"</a></p>
</footer>
</main>
}.into_view(cx)
}.into_view()
}
#[component]
pub fn Todo(cx: Scope, todo: Todo) -> impl IntoView {
let (editing, set_editing) = create_signal(cx, false);
let set_todos = use_context::<WriteSignal<Todos>>(cx).unwrap();
//let input = NodeRef::new(cx);
pub fn Todo(todo: Todo) -> impl IntoView {
let (editing, set_editing) = create_signal(false);
let set_todos = use_context::<WriteSignal<Todos>>().unwrap();
//let input = NodeRef::new();
let save = move |value: &str| {
let value = value.trim();
@@ -255,7 +259,7 @@ pub fn Todo(cx: Scope, todo: Todo) -> impl IntoView {
set_editing(false);
};
view! { cx,
view! {
<li class="todo" class:editing=editing class:completed=move || (todo.completed)()>
<div class="view">
<input class="toggle" type="checkbox" prop:checked=move || (todo.completed)()/>
@@ -268,7 +272,7 @@ pub fn Todo(cx: Scope, todo: Todo) -> impl IntoView {
{move || {
editing()
.then(|| {
view! { cx,
view! {
<input
class="edit"
class:hidden=move || !(editing)()
@@ -319,8 +323,8 @@ pub struct TodoSerialized {
}
impl TodoSerialized {
pub fn into_todo(self, cx: Scope) -> Todo {
Todo::new_with_completed(cx, self.id, self.title, self.completed)
pub fn into_todo(self, ) -> Todo {
Todo::new_with_completed(self.id, self.title, self.completed)
}
}

View File

@@ -2,6 +2,7 @@ use test::Bencher;
mod leptos;
mod sycamore;
mod tachys;
mod tera;
mod yew;
@@ -12,18 +13,34 @@ fn leptos_todomvc_ssr(b: &mut Bencher) {
b.iter(|| {
use crate::todomvc::leptos::*;
let html = ::leptos::ssr::render_to_string(|cx| {
view! { cx, <TodoMVC todos=Todos::new(cx)/> }
let html = ::leptos::ssr::render_to_string(|| {
view! { <TodoMVC todos=Todos::new()/> }
});
assert!(html.len() > 1);
});
runtime.dispose();
}
#[bench]
fn tachys_todomvc_ssr(b: &mut Bencher) {
use ::leptos::*;
let runtime = create_runtime();
b.iter(|| {
use crate::todomvc::tachys::*;
use tachydom::view::{Render, RenderHtml};
let rendered = TodoMVC(Todos::new()).to_html();
assert_eq!(
rendered,
"<main><section class=\"todoapp\"><header class=\"header\"><h1>todos</h1><input placeholder=\"What needs to be done?\" autofocus class=\"new-todo\"></header><section class=\"main hidden\"><input id=\"toggle-all\" type=\"checkbox\" class=\"toggle-all\"><label for=\"toggle-all\">Mark all as complete</label><ul class=\"todo-list\"></ul></section><footer class=\"footer hidden\"><span class=\"todo-count\"><strong>0</strong><!> items<!> left</span><ul class=\"filters\"><li><a href=\"#/\" class=\"selected selected\">All</a></li><li><a href=\"#/active\" class=\"\">Active</a></li><li><a href=\"#/completed\" class=\"\">Completed</a></li></ul><button class=\"clear-completed hidden hidden\">Clear completed</button></footer></section><footer class=\"info\"><p>Double-click to edit a todo</p><p>Created by <a href=\"http://todomvc.com\">Greg Johnston</a></p><p>Part of <a href=\"http://todomvc.com\">TodoMVC</a></p></footer></main>" );
});
runtime.dispose();
}
#[bench]
fn sycamore_todomvc_ssr(b: &mut Bencher) {
use self::sycamore::*;
use ::sycamore::prelude::*;
use ::sycamore::*;
use ::sycamore::{prelude::*, *};
b.iter(|| {
_ = create_scope(|cx| {
@@ -42,8 +59,7 @@ fn sycamore_todomvc_ssr(b: &mut Bencher) {
#[bench]
fn yew_todomvc_ssr(b: &mut Bencher) {
use self::yew::*;
use ::yew::prelude::*;
use ::yew::ServerRenderer;
use ::yew::{prelude::*, ServerRenderer};
b.iter(|| {
tokio_test::block_on(async {
@@ -60,21 +76,33 @@ fn leptos_todomvc_ssr_with_1000(b: &mut Bencher) {
use self::leptos::*;
use ::leptos::*;
let html = ::leptos::ssr::render_to_string(|cx| {
let html = ::leptos::ssr::render_to_string(|| {
view! {
cx,
<TodoMVC todos=Todos::new_with_1000(cx)/>
<TodoMVC todos=Todos::new_with_1000()/>
}
});
assert!(html.len() > 1);
});
}
#[bench]
fn tachys_todomvc_ssr_with_1000(b: &mut Bencher) {
use ::leptos::*;
let runtime = create_runtime();
b.iter(|| {
use crate::todomvc::tachys::*;
use tachydom::view::{Render, RenderHtml};
let rendered = TodoMVC(Todos::new_with_1000()).to_html();
assert!(rendered.len() > 20_000)
});
runtime.dispose();
}
#[bench]
fn sycamore_todomvc_ssr_with_1000(b: &mut Bencher) {
use self::sycamore::*;
use ::sycamore::prelude::*;
use ::sycamore::*;
use ::sycamore::{prelude::*, *};
b.iter(|| {
_ = create_scope(|cx| {
@@ -93,8 +121,7 @@ fn sycamore_todomvc_ssr_with_1000(b: &mut Bencher) {
#[bench]
fn yew_todomvc_ssr_with_1000(b: &mut Bencher) {
use self::yew::*;
use ::yew::prelude::*;
use ::yew::ServerRenderer;
use ::yew::{prelude::*, ServerRenderer};
b.iter(|| {
tokio_test::block_on(async {
@@ -103,4 +130,19 @@ fn yew_todomvc_ssr_with_1000(b: &mut Bencher) {
assert!(rendered.len() > 1);
});
});
}
}
#[bench]
fn tera_todomvc_ssr(b: &mut Bencher) {
use ::leptos::*;
let runtime = create_runtime();
b.iter(|| {
use crate::todomvc::leptos::*;
let html = ::leptos::ssr::render_to_string(|| {
view! { <TodoMVC todos=Todos::new()/> }
});
assert!(html.len() > 1);
});
runtime.dispose();
}

View File

@@ -0,0 +1,333 @@
pub use leptos_reactive::*;
use miniserde::*;
use tachy_maccy::view;
use tachydom::{
html::{
attribute::global::{ClassAttribute, GlobalAttributes, OnAttribute},
element::ElementChild,
},
renderer::dom::Dom,
view::{keyed::keyed, Render, RenderHtml},
};
use wasm_bindgen::JsCast;
use web_sys::HtmlInputElement;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Todos(pub Vec<Todo>);
const STORAGE_KEY: &str = "todos-leptos";
impl Todos {
pub fn new() -> Self {
Self(vec![])
}
pub fn new_with_1000() -> Self {
let todos = (0..1000)
.map(|id| Todo::new(id, format!("Todo #{id}")))
.collect();
Self(todos)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn add(&mut self, todo: Todo) {
self.0.push(todo);
}
pub fn remove(&mut self, id: usize) {
self.0.retain(|todo| todo.id != id);
}
pub fn remaining(&self) -> usize {
self.0.iter().filter(|todo| !(todo.completed)()).count()
}
pub fn completed(&self) -> usize {
self.0.iter().filter(|todo| (todo.completed)()).count()
}
pub fn toggle_all(&self) {
// if all are complete, mark them all active instead
if self.remaining() == 0 {
for todo in &self.0 {
if todo.completed.get() {
(todo.set_completed)(false);
}
}
}
// otherwise, mark them all complete
else {
for todo in &self.0 {
(todo.set_completed)(true);
}
}
}
fn clear_completed(&mut self) {
self.0.retain(|todo| !todo.completed.get());
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Todo {
pub id: usize,
pub title: ReadSignal<String>,
pub set_title: WriteSignal<String>,
pub completed: ReadSignal<bool>,
pub set_completed: WriteSignal<bool>,
}
impl Todo {
pub fn new(id: usize, title: String) -> Self {
Self::new_with_completed(id, title, false)
}
pub fn new_with_completed(
id: usize,
title: String,
completed: bool,
) -> Self {
let (title, set_title) = create_signal(title);
let (completed, set_completed) = create_signal(completed);
Self {
id,
title,
set_title,
completed,
set_completed,
}
}
pub fn toggle(&self) {
self.set_completed
.update(|completed| *completed = !*completed);
}
}
const ESCAPE_KEY: u32 = 27;
const ENTER_KEY: u32 = 13;
pub fn TodoMVC(todos: Todos) -> impl Render<Dom> + RenderHtml<Dom> {
let mut next_id = todos
.0
.iter()
.map(|todo| todo.id)
.max()
.map(|last| last + 1)
.unwrap_or(0);
let (todos, set_todos) = create_signal(todos);
provide_context(set_todos);
let (mode, set_mode) = create_signal(Mode::All);
let add_todo = move |ev: web_sys::KeyboardEvent| {
todo!()
/* let target = event_target::<HtmlInputElement>(&ev);
ev.stop_propagation();
let key_code = ev.unchecked_ref::<web_sys::KeyboardEvent>().key_code();
if key_code == ENTER_KEY {
let title = event_target_value(&ev);
let title = title.trim();
if !title.is_empty() {
let new = Todo::new(next_id, title.to_string());
set_todos.update(|t| t.add(new));
next_id += 1;
target.set_value("");
}
} */
};
let filtered_todos = create_memo::<Vec<Todo>>(move |_| {
todos.with(|todos| match mode.get() {
Mode::All => todos.0.to_vec(),
Mode::Active => todos
.0
.iter()
.filter(|todo| !todo.completed.get())
.cloned()
.collect(),
Mode::Completed => todos
.0
.iter()
.filter(|todo| todo.completed.get())
.cloned()
.collect(),
})
});
// effect to serialize to JSON
// this does reactive reads, so it will automatically serialize on any relevant change
create_effect(move |_| {
()
/* if let Ok(Some(storage)) = window().local_storage() {
let objs = todos
.get()
.0
.iter()
.map(TodoSerialized::from)
.collect::<Vec<_>>();
let json = json::to_string(&objs);
if storage.set_item(STORAGE_KEY, &json).is_err() {
log::error!("error while trying to set item in localStorage");
}
} */
});
view! {
<main>
<section class="todoapp">
<header class="header">
<h1>"todos"</h1>
<input
class="new-todo"
placeholder="What needs to be done?"
autofocus
/>
</header>
<section class="main" class:hidden=move || todos.with(|t| t.is_empty())>
<input
id="toggle-all"
class="toggle-all"
r#type="checkbox"
//prop:checked=move || todos.with(|t| t.remaining() > 0)
on:input=move |_| set_todos.update(|t| t.toggle_all())
/>
<label r#for="toggle-all">"Mark all as complete"</label>
<ul class="todo-list">
{move || {
keyed(filtered_todos.get(), |todo| todo.id, Todo)
}}
</ul>
</section>
<footer class="footer" class:hidden=move || todos.with(|t| t.is_empty())>
<span class="todo-count">
<strong>{move || todos.with(|t| t.remaining().to_string())}</strong>
{move || if todos.with(|t| t.remaining()) == 1 { " item" } else { " items" }}
" left"
</span>
<ul class="filters">
<li>
<a
href="#/"
class="selected"
class:selected=move || mode() == Mode::All
>
"All"
</a>
</li>
<li>
<a href="#/active" class:selected=move || mode() == Mode::Active>
"Active"
</a>
</li>
<li>
<a href="#/completed" class:selected=move || mode() == Mode::Completed>
"Completed"
</a>
</li>
</ul>
<button
class="clear-completed hidden"
class:hidden=move || todos.with(|t| t.completed() == 0)
on:click=move |_| set_todos.update(|t| t.clear_completed())
>
"Clear completed"
</button>
</footer>
</section>
<footer class="info">
<p>"Double-click to edit a todo"</p>
<p>"Created by " <a href="http://todomvc.com">"Greg Johnston"</a></p>
<p>"Part of " <a href="http://todomvc.com">"TodoMVC"</a></p>
</footer>
</main>
}
}
pub fn Todo(todo: Todo) -> impl Render<Dom> + RenderHtml<Dom> {
let (editing, set_editing) = create_signal(false);
let set_todos = use_context::<WriteSignal<Todos>>().unwrap();
//let input = NodeRef::new();
let save = move |value: &str| {
let value = value.trim();
if value.is_empty() {
set_todos.update(|t| t.remove(todo.id));
} else {
(todo.set_title)(value.to_string());
}
set_editing(false);
};
view! {
<li class="todo" class:editing=editing class:completed=move || (todo.completed)()>
/* <div class="view">
<input class="toggle" r#type="checkbox"/>
<label on:dblclick=move |_| set_editing(true)>{move || todo.title.get()}</label>
<button
class="destroy"
on:click=move |_| set_todos.update(|t| t.remove(todo.id))
></button>
</div>
{move || {
editing()
.then(|| {
view! {
<input
class="edit"
class:hidden=move || !(editing)()
/>
}
})
}} */
</li>
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Active,
Completed,
All,
}
impl Default for Mode {
fn default() -> Self {
Mode::All
}
}
pub fn route(hash: &str) -> Mode {
match hash {
"/active" => Mode::Active,
"/completed" => Mode::Completed,
_ => Mode::All,
}
}
#[derive(Serialize, Deserialize)]
pub struct TodoSerialized {
pub id: usize,
pub title: String,
pub completed: bool,
}
impl TodoSerialized {
pub fn into_todo(self) -> Todo {
Todo::new_with_completed(self.id, self.title, self.completed)
}
}
impl From<&Todo> for TodoSerialized {
fn from(todo: &Todo) -> Self {
Self {
id: todo.id,
title: todo.title.get(),
completed: (todo.completed)(),
}
}
}

View File

@@ -55,7 +55,7 @@ static TEMPLATE: &str = r#"<main>
{% else %}
<li><a href="/">All</a></li>
{% endif %}
{% if mode_active %}
<li><a href="/active" class="selected">Active</a></li>
{% else %}
@@ -87,17 +87,17 @@ static TEMPLATE: &str = r#"<main>
</main>"#;
#[bench]
fn tera_todomvc(b: &mut Bencher) {
fn tera_todomvc_ssr(b: &mut Bencher) {
use serde::{Deserialize, Serialize};
use tera::*;
lazy_static::lazy_static! {
static ref TERA: Tera = {
static LazyLock<TERA>: Tera = LazyLock( || {
let mut tera = Tera::default();
tera.add_raw_templates(vec![("template.html", TEMPLATE)]).unwrap();
tera
};
}
});
#[derive(Serialize, Deserialize)]
struct Todo {
@@ -127,17 +127,17 @@ fn tera_todomvc(b: &mut Bencher) {
}
#[bench]
fn tera_todomvc_1000(b: &mut Bencher) {
fn tera_todomvc_ssr_1000(b: &mut Bencher) {
use serde::{Deserialize, Serialize};
use tera::*;
lazy_static::lazy_static! {
static ref TERA: Tera = {
let mut tera = Tera::default();
tera.add_raw_templates(vec![("template.html", TEMPLATE)]).unwrap();
tera
};
}
static TERA: LazyLock<Tera> = LazyLock::new(|| {
let mut tera = Tera::default();
tera.add_raw_templates(vec![("template.html", TEMPLATE)]).unwrap();
tera
});
#[derive(Serialize, Deserialize)]
struct Todo {
@@ -174,4 +174,4 @@ fn tera_todomvc_1000(b: &mut Bencher) {
let _ = TERA.render("template.html", &ctx).unwrap();
});
}
}

View File

@@ -0,0 +1,14 @@
[tasks.check-minimal-versions]
condition = { channels = ["nightly"] }
command = "cargo"
args = [
"all-features",
"minimal-versions",
"check",
"--ignore-private",
"--detach-path-deps",
"--direct",
]
install_script = '''
cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
'''

View File

@@ -1,7 +0,0 @@
[tasks.check]
alias = "check-all"
[tasks.check-all]
command = "cargo"
args = ["+nightly", "check-all-features"]
install_crate = "cargo-all-features"

View File

@@ -1,9 +1,20 @@
[tasks.pre-clippy]
env = { CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features -- -D warnings" }
[tasks.check-style]
dependencies = ["check-format-flow", "clippy-flow"]
[tasks.lint]
dependencies = ["check-format-flow", "clippy-each-feature"]
[tasks.check-format]
env = { LEPTOS_PROJECT_DIRECTORY = "../" }
args = ["fmt", "--", "--check", "--config-path", "${LEPTOS_PROJECT_DIRECTORY}"]
[tasks.clippy-each-feature]
command = "cargo"
args = [
"all-features",
"clippy",
"--no-deps",
"--",
"-D",
"clippy::print_stdout",
]
install_script = '''
cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
'''

View File

@@ -1,7 +1,7 @@
extend = [
{ path = "./check.toml" },
{ path = "./lint.toml" },
{ path = "./test.toml" },
{ path = "./lint.toml" },
{ path = "./test.toml" },
{ path = "./check-minimal-versions.toml" },
]
[env]
@@ -12,7 +12,4 @@ LEPTOS_OUTPUT_NAME = "ci" # allows examples to check/build without cargo-leptos
RUSTFLAGS = "-D warnings"
[tasks.ci]
dependencies = ["lint", "test"]
[tasks.lint]
dependencies = ["check-format-flow"]
dependencies = ["lint", "test-each-feature", "doctests"]

View File

@@ -1,7 +1,16 @@
[tasks.test]
alias = "test-all"
[tasks.test-all]
[tasks.test-each-feature]
env = { "NEXTEST_NO_TESTS" = "warn" }
command = "cargo"
args = ["+nightly", "test-all-features"]
install_crate = "cargo-all-features"
args = ["all-features", "nextest", "run", "--all-targets"]
install_script = '''
cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
'''
# This can be removed once doctests is supported in nextest
# https://github.com/nextest-rs/nextest/issues/16
[tasks.doctests]
command = "cargo"
args = ["all-features", "test", "--doc"]
install_script = '''
cargo install --git https://github.com/sabify/cargo-all-features --branch arbitrary-command-support
'''

View File

@@ -0,0 +1,7 @@
[tasks.post-test]
dependencies = ["test-wasm"]
[tasks.test-wasm]
env = { CARGO_MAKE_WASM_TEST_ARGS = "--headless --chrome --features=wasm-bindgen" }
command = "cargo"
args = ["make", "wasm-pack-test"]

View File

@@ -0,0 +1,12 @@
[package]
name = "const_str_slice_concat"
version = "0.1.0"
authors = ["Greg Johnston"]
license = "MIT"
readme = "../README.md"
repository = "https://github.com/leptos-rs/leptos"
description = "Utilities for const concatenation of string slices."
rust-version.workspace = true
edition.workspace = true
[dependencies]

View File

@@ -0,0 +1 @@
extend = { path = "../cargo-make/main.toml" }

View File

@@ -0,0 +1,139 @@
#![no_std]
#![forbid(unsafe_code)]
#![deny(missing_docs)]
//! Utilities for const concatenation of string slices.
pub(crate) const MAX_TEMPLATE_SIZE: usize = 4096;
/// Converts a zero-terminated buffer of bytes into a UTF-8 string.
pub const fn str_from_buffer(buf: &[u8; MAX_TEMPLATE_SIZE]) -> &str {
match core::ffi::CStr::from_bytes_until_nul(buf) {
Ok(cstr) => match cstr.to_str() {
Ok(str) => str,
Err(_) => panic!("TEMPLATE FAILURE"),
},
Err(_) => panic!("TEMPLATE FAILURE"),
}
}
/// Concatenates any number of static strings into a single array.
// credit to Rainer Stropek, "Constant fun," Rust Linz, June 2022
pub const fn const_concat(
strs: &'static [&'static str],
) -> [u8; MAX_TEMPLATE_SIZE] {
let mut buffer = [0; MAX_TEMPLATE_SIZE];
let mut position = 0;
let mut remaining = strs;
while let [current, tail @ ..] = remaining {
let x = current.as_bytes();
let mut i = 0;
// have it iterate over bytes manually, because, again,
// no mutable references in const fns
while i < x.len() {
buffer[position] = x[i];
position += 1;
i += 1;
}
remaining = tail;
}
buffer
}
/// Converts a zero-terminated buffer of bytes into a UTF-8 string with the given prefix.
pub const fn const_concat_with_prefix(
strs: &'static [&'static str],
prefix: &'static str,
suffix: &'static str,
) -> [u8; MAX_TEMPLATE_SIZE] {
let mut buffer = [0; MAX_TEMPLATE_SIZE];
let mut position = 0;
let mut remaining = strs;
while let [current, tail @ ..] = remaining {
let x = current.as_bytes();
let mut i = 0;
// have it iterate over bytes manually, because, again,
// no mutable references in const fns
while i < x.len() {
buffer[position] = x[i];
position += 1;
i += 1;
}
remaining = tail;
}
if buffer[0] == 0 {
buffer
} else {
let mut new_buf = [0; MAX_TEMPLATE_SIZE];
let prefix = prefix.as_bytes();
let suffix = suffix.as_bytes();
let mut position = 0;
let mut i = 0;
while i < prefix.len() {
new_buf[position] = prefix[i];
position += 1;
i += 1;
}
i = 0;
while i < buffer.len() {
if buffer[i] == 0 {
break;
}
new_buf[position] = buffer[i];
position += 1;
i += 1;
}
i = 0;
while i < suffix.len() {
new_buf[position] = suffix[i];
position += 1;
i += 1;
}
new_buf
}
}
/// Converts any number of strings into a UTF-8 string, separated by the given string.
pub const fn const_concat_with_separator(
strs: &[&str],
separator: &'static str,
) -> [u8; MAX_TEMPLATE_SIZE] {
let mut buffer = [0; MAX_TEMPLATE_SIZE];
let mut position = 0;
let mut remaining = strs;
while let [current, tail @ ..] = remaining {
let x = current.as_bytes();
let mut i = 0;
// have it iterate over bytes manually, because, again,
// no mutable references in const fns
while i < x.len() {
buffer[position] = x[i];
position += 1;
i += 1;
}
if !x.is_empty() {
let mut position = 0;
let separator = separator.as_bytes();
while i < separator.len() {
buffer[position] = separator[i];
position += 1;
i += 1;
}
}
remaining = tail;
}
buffer
}

View File

@@ -9,10 +9,10 @@ This document is intended as a running list of common issues, with example code
**Issue**: Sometimes you want to update a reactive signal in a way that depends on another signal.
```rust
let (a, set_a) = create_signal(cx, 0);
let (b, set_b) = create_signal(cx, false);
let (a, set_a) = create_signal(0);
let (b, set_b) = create_signal(false);
create_effect(cx, move |_| {
create_effect(move |_| {
if a() > 5 {
set_b(true);
}
@@ -24,7 +24,7 @@ This creates an inefficient chain of updates, and can easily lead to infinite lo
**Solution**: Follow the rule, _What can be derived, should be derived._ In this case, this has the benefit of massively reducing the code size, too!
```rust
let (a, set_a) = create_signal(cx, 0);
let (a, set_a) = create_signal(0);
let b = move || a () > 5;
```
@@ -34,19 +34,19 @@ Sometimes you have nested signals: for example, hash-map that can change over ti
```rust
#[component]
pub fn App(cx: Scope) -> impl IntoView {
let resources = create_rw_signal(cx, HashMap::new());
pub fn App() -> impl IntoView {
let resources = create_rw_signal(HashMap::new());
let update = move |id: usize| {
resources.update(|resources| {
resources
.entry(id)
.or_insert_with(|| create_rw_signal(cx, 0))
.or_insert_with(|| create_rw_signal(0))
.update(|amount| *amount += 1)
})
};
view! { cx,
view! {
<div>
<pre>{move || format!("{:#?}", resources.get().into_iter().map(|(id, resource)| (id, resource.get())).collect::<Vec<_>>())}</pre>
<button on:click=move |_| update(1)>"+"</button>
@@ -55,17 +55,17 @@ pub fn App(cx: Scope) -> impl IntoView {
}
```
Clicking the button twice will cause a panic, because of the nested signal *read*. Calling the `update` function on `resources` immediately takes out a mutable borrow on `resources`, then updates the `resource` signal—which re-runs the effect that reads from the signals, which tries to immutably access `resources` and panics. It's the nested update here which causes a problem, because the inner update triggers and effect that tries to read both signals while the outer is still updating.
Clicking the button twice will cause a panic, because of the nested signal _read_. Calling the `update` function on `resources` immediately takes out a mutable borrow on `resources`, then updates the `resource` signal—which re-runs the effect that reads from the signals, which tries to immutably access `resources` and panics. It's the nested update here which causes a problem, because the inner update triggers and effect that tries to read both signals while the outer is still updating.
You can fix this fairly easily by using the [`Scope::batch()`](https://docs.rs/leptos/latest/leptos/struct.Scope.html#method.batch) method:
You can fix this fairly easily by using the [`batch()`](https://docs.rs/leptos/latest/leptos/fn.batch.html) method:
```rust
let update = move |id: usize| {
cx.batch(move || {
batch(move || {
resources.update(|resources| {
resources
.entry(id)
.or_insert_with(|| create_rw_signal(cx, 0))
.or_insert_with(|| create_rw_signal(0))
.update(|amount| *amount += 1)
})
});
@@ -83,11 +83,11 @@ Many DOM attributes can be updated either by setting an attribute on the DOM nod
This means that in practice, attributes like `value` or `checked` on an `<input/>` element only update the _default_ value for the `<input/>`. If you want to reactively update the value, you should use `prop:value` instead to set the `value` property.
```rust
let (a, set_a) = create_signal(cx, "Starting value".to_string());
let (a, set_a) = create_signal("Starting value".to_string());
let on_input = move |ev| set_a(event_target_value(&ev));
view! {
cx,
// ❌ reactivity doesn't work as expected: typing only updates the default
// of each input, so if you start typing in the second input, it won't
// update the first one
@@ -97,11 +97,11 @@ view! {
```
```rust
let (a, set_a) = create_signal(cx, "Starting value".to_string());
let (a, set_a) = create_signal("Starting value".to_string());
let on_input = move |ev| set_a(event_target_value(&ev));
view! {
cx,
// ✅ works as intended by setting the value *property*
<input prop:value=a on:input=on_input />
<input prop:value=a on:input=on_input />

View File

@@ -1,14 +1,3 @@
This project contains the core of a new introductory guide to Leptos.
The Leptos book is now available at [https://book.leptos.dev](https://book.leptos.dev).
It is built using `mdbook`. You can view a local copy by installing `mdbook`
```bash
cargo install mdbook
```
and run the book with
```
mdbook serve
```
It should be available at `http://localhost:3000`.
The source code for the book has moved to [https://github.com/leptos-rs/book](https://github.com/leptos-rs/book). Please open issues or make PRs in that repository.

View File

@@ -1,2 +1,10 @@
[output.html]
additional-css = ["./mdbook-admonish.css"]
[output.html.playground]
runnable = false
[preprocessor]
[preprocessor.admonish]
command = "mdbook-admonish"
assets_version = "3.0.1" # do not edit: managed by `mdbook-admonish install`

View File

@@ -0,0 +1,345 @@
@charset "UTF-8";
:root {
--md-admonition-icon--admonish-note: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z'/></svg>");
--md-admonition-icon--admonish-abstract: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z'/></svg>");
--md-admonition-icon--admonish-info: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z'/></svg>");
--md-admonition-icon--admonish-tip: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17.66 11.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32-2.59 2.08-3.61 5.75-2.39 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5.14.6.41 1.2.71 1.73 1.08 1.73 2.95 2.97 4.96 3.22 2.14.27 4.43-.12 6.07-1.6 1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82 1.19-.28 1.9-1.16 2.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63 1.06.77 1 1.98 1.44 2.24 2.8.04.14.06.28.06.43.03.82-.33 1.72-.93 2.27z'/></svg>");
--md-admonition-icon--admonish-success: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m9 20.42-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42z'/></svg>");
--md-admonition-icon--admonish-question: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m15.07 11.25-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2 2 2 0 0 0-2 2H8a4 4 0 0 1 4-4 4 4 0 0 1 4 4 3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10c0-5.53-4.5-10-10-10z'/></svg>");
--md-admonition-icon--admonish-warning: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2 1 21z'/></svg>");
--md-admonition-icon--admonish-failure: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6.91 17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91z'/></svg>");
--md-admonition-icon--admonish-danger: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 15H6l7-14v8h5l-7 14v-8z'/></svg>");
--md-admonition-icon--admonish-bug: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 0 0-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z'/></svg>");
--md-admonition-icon--admonish-example: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 0 1 .75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z'/></svg>");
--md-admonition-icon--admonish-quote: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z'/></svg>");
--md-details-icon: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z'/></svg>");
}
:is(.admonition) {
display: flow-root;
margin: 1.5625em 0;
padding: 0 1.2rem;
color: var(--fg);
page-break-inside: avoid;
background-color: var(--bg);
border: 0 solid black;
border-inline-start-width: 0.4rem;
border-radius: 0.2rem;
box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1);
}
@media print {
:is(.admonition) {
box-shadow: none;
}
}
:is(.admonition) > * {
box-sizing: border-box;
}
:is(.admonition) :is(.admonition) {
margin-top: 1em;
margin-bottom: 1em;
}
:is(.admonition) > .tabbed-set:only-child {
margin-top: 0;
}
html :is(.admonition) > :last-child {
margin-bottom: 1.2rem;
}
a.admonition-anchor-link {
display: none;
position: absolute;
left: -1.2rem;
padding-right: 1rem;
}
a.admonition-anchor-link:link, a.admonition-anchor-link:visited {
color: var(--fg);
}
a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover {
text-decoration: none;
}
a.admonition-anchor-link::before {
content: "§";
}
:is(.admonition-title, summary.admonition-title) {
position: relative;
min-height: 4rem;
margin-block: 0;
margin-inline: -1.6rem -1.2rem;
padding-block: 0.8rem;
padding-inline: 4.4rem 1.2rem;
font-weight: 700;
background-color: rgba(68, 138, 255, 0.1);
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
display: flex;
}
:is(.admonition-title, summary.admonition-title) p {
margin: 0;
}
html :is(.admonition-title, summary.admonition-title):last-child {
margin-bottom: 0;
}
:is(.admonition-title, summary.admonition-title)::before {
position: absolute;
top: 0.625em;
inset-inline-start: 1.6rem;
width: 2rem;
height: 2rem;
background-color: #448aff;
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
-webkit-mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-size: contain;
content: "";
}
:is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link {
display: initial;
}
details.admonition > summary.admonition-title::after {
position: absolute;
top: 0.625em;
inset-inline-end: 1.6rem;
height: 2rem;
width: 2rem;
background-color: currentcolor;
mask-image: var(--md-details-icon);
-webkit-mask-image: var(--md-details-icon);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-size: contain;
content: "";
transform: rotate(0deg);
transition: transform 0.25s;
}
details[open].admonition > summary.admonition-title::after {
transform: rotate(90deg);
}
:is(.admonition):is(.admonish-note) {
border-color: #448aff;
}
:is(.admonish-note) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(68, 138, 255, 0.1);
}
:is(.admonish-note) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #448aff;
mask-image: var(--md-admonition-icon--admonish-note);
-webkit-mask-image: var(--md-admonition-icon--admonish-note);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-abstract, .admonish-summary, .admonish-tldr) {
border-color: #00b0ff;
}
:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(0, 176, 255, 0.1);
}
:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #00b0ff;
mask-image: var(--md-admonition-icon--admonish-abstract);
-webkit-mask-image: var(--md-admonition-icon--admonish-abstract);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-info, .admonish-todo) {
border-color: #00b8d4;
}
:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(0, 184, 212, 0.1);
}
:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #00b8d4;
mask-image: var(--md-admonition-icon--admonish-info);
-webkit-mask-image: var(--md-admonition-icon--admonish-info);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-tip, .admonish-hint, .admonish-important) {
border-color: #00bfa5;
}
:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(0, 191, 165, 0.1);
}
:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #00bfa5;
mask-image: var(--md-admonition-icon--admonish-tip);
-webkit-mask-image: var(--md-admonition-icon--admonish-tip);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-success, .admonish-check, .admonish-done) {
border-color: #00c853;
}
:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(0, 200, 83, 0.1);
}
:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #00c853;
mask-image: var(--md-admonition-icon--admonish-success);
-webkit-mask-image: var(--md-admonition-icon--admonish-success);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-question, .admonish-help, .admonish-faq) {
border-color: #64dd17;
}
:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(100, 221, 23, 0.1);
}
:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #64dd17;
mask-image: var(--md-admonition-icon--admonish-question);
-webkit-mask-image: var(--md-admonition-icon--admonish-question);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-warning, .admonish-caution, .admonish-attention) {
border-color: #ff9100;
}
:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(255, 145, 0, 0.1);
}
:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #ff9100;
mask-image: var(--md-admonition-icon--admonish-warning);
-webkit-mask-image: var(--md-admonition-icon--admonish-warning);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-failure, .admonish-fail, .admonish-missing) {
border-color: #ff5252;
}
:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(255, 82, 82, 0.1);
}
:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #ff5252;
mask-image: var(--md-admonition-icon--admonish-failure);
-webkit-mask-image: var(--md-admonition-icon--admonish-failure);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-danger, .admonish-error) {
border-color: #ff1744;
}
:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(255, 23, 68, 0.1);
}
:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #ff1744;
mask-image: var(--md-admonition-icon--admonish-danger);
-webkit-mask-image: var(--md-admonition-icon--admonish-danger);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-bug) {
border-color: #f50057;
}
:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(245, 0, 87, 0.1);
}
:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #f50057;
mask-image: var(--md-admonition-icon--admonish-bug);
-webkit-mask-image: var(--md-admonition-icon--admonish-bug);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-example) {
border-color: #7c4dff;
}
:is(.admonish-example) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(124, 77, 255, 0.1);
}
:is(.admonish-example) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #7c4dff;
mask-image: var(--md-admonition-icon--admonish-example);
-webkit-mask-image: var(--md-admonition-icon--admonish-example);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
:is(.admonition):is(.admonish-quote, .admonish-cite) {
border-color: #9e9e9e;
}
:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title) {
background-color: rgba(158, 158, 158, 0.1);
}
:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title)::before {
background-color: #9e9e9e;
mask-image: var(--md-admonition-icon--admonish-quote);
-webkit-mask-image: var(--md-admonition-icon--admonish-quote);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
.navy :is(.admonition) {
background-color: var(--sidebar-bg);
}
.ayu :is(.admonition),
.coal :is(.admonition) {
background-color: var(--theme-hover);
}
.rust :is(.admonition) {
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
}
.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited {
color: var(--sidebar-fg);
}

View File

@@ -1,20 +1,2 @@
# Introduction
This book is intended as an introduction to the [Leptos](https://github.com/leptos-rs/leptos) Web framework.
It will walk through the fundamental concepts you need to build applications,
beginning with a simple application rendered in the browser, and building toward a
full-stack application with server-side rendering and hydration.
The guide doesnt assume you know anything about fine-grained reactivity or the
details of modern Web frameworks. It does assume you are familiar with the Rust
programming language, HTML, CSS, and the DOM and basic Web APIs.
Leptos is most similar to frameworks like [Solid](https://www.solidjs.com) (JavaScript)
and [Sycamore](https://sycamore-rs.netlify.app/) (Rust). There are some similarities
to other frameworks like React (JavaScript), Svelte (JavaScript), Yew (Rust), and
Dioxus (Rust), so knowledge of one of those frameworks may also make it easier to
understand Leptos.
You can find more detailed docs for each part of the API at [Docs.rs](https://docs.rs/leptos/latest/leptos/).
**The guide is a work in progress.**
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/">
<link rel="canonical" href="https://book.leptos.dev/">

View File

@@ -1,84 +0,0 @@
# Getting Started
There are two basic paths to getting started with Leptos:
1. Client-side rendering with [Trunk](https://trunkrs.dev/)
2. Full-stack rendering with [`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos)
For the early examples, it will be easiest to begin with Trunk. Well introduce
`cargo-leptos` a little later in this series.
If you dont already have it installed, you can install Trunk by running
```bash
cargo install trunk
```
Create a basic Rust project
```bash
cargo init leptos-tutorial
```
`cd` into your new `leptos-tutorial` project and add `leptos` as a dependency
```bash
cargo add leptos --features=csr,nightly
```
Or you can leave off `nighly` if you're using stable Rust
```bash
cargo add leptos --features=csr
```
> Using `nightly` Rust, and the `nightly` feature in Leptos enables the function-call syntax for signal getters and setters that is used in most of this book.
>
> To use `nightly` Rust, you can run
>
> ```bash
> rustup toolchain install nightly
> rustup default nightly
> ```
>
> If youd rather use stable Rust with Leptos, you can do that too. In the guide and examples, youll just use the [`ReadSignal::get()`](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html#impl-SignalGet%3CT%3E-for-ReadSignal%3CT%3E) and [`WriteSignal::set()`](https://docs.rs/leptos/latest/leptos/struct.WriteSignal.html#impl-SignalGet%3CT%3E-for-ReadSignal%3CT%3E) methods instead of calling signal getters and setters as functions.
Make sure you've added the `wasm32-unknown-unknown` target so that Rust can compile your code to WebAssembly to run in the browser.
```bash
rustup target add wasm32-unknown-unknown
```
Create a simple `index.html` in the root of the `leptos-tutorial` directory
```html
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>
```
And add a simple “Hello, world!” to your `main.rs`
```rust
use leptos::*;
fn main() {
mount_to_body(|cx| view! { cx, <p>"Hello, world!"</p> })
}
```
Your directory structure should now look something like this
```
leptos_tutorial
├── src
│ └── main.rs
├── Cargo.toml
├── index.html
```
Now run `trunk serve --open` from the root of the `leptos-tutorial` directory.
Trunk should automatically compile your app and open it in your default browser.
If you make edits to `main.rs`, Trunk will recompile your source code and
live-reload the page.

View File

@@ -1,185 +1,2 @@
# Global State Management
So far, we've only been working with local state in components, and weve seen how to coordinate state between parent and child components. On occasion, there are times where people look for a more general solution for global state management that can work throughout an application.
In general, **you do not need this chapter.** The typical pattern is to compose your application out of components, each of which manages its own local state, not to store all state in a global structure. However, there are some cases (like theming, saving user settings, or sharing data between components in different parts of your UI) in which you may want to use some kind of global state management.
The three best approaches to global state are
1. Using the router to drive global state via the URL
2. Passing signals through context
3. Creating a global state struct and creating lenses into it with `create_slice`
## Option #1: URL as Global State
In many ways, the URL is actually the best way to store global state. It can be accessed from any component, anywhere in your tree. There are native HTML elements like `<form>` and `<a>` that exist solely to update the URL. And it persists across page reloads and between devices; you can share a URL with a friend or send it from your phone to your laptop and any state stored in it will be replicated.
The next few sections of the tutorial will be about the router, and well get much more into these topics.
But for now, we'll just look at options #2 and #3.
## Option #2: Passing Signals through Context
In the section on [parent-child communication](view/08_parent_child.md), we saw that you can use `provide_context` to pass signal from a parent component to a child, and `use_context` to read it in the child. But `provide_context` works across any distance. If you want to create a global signal that holds some piece of state, you can provide it and access it via context anywhere in the descendants of the component where you provide it.
A signal provided via context only causes reactive updates where it is read, not in any of the components in between, so it maintains the power of fine-grained reactive updates, even at a distance.
We start by creating a signal in the root of the app and providing it to
all its children and descendants using `provide_context`.
```rust
#[component]
fn App(cx: Scope) -> impl IntoView {
// here we create a signal in the root that can be consumed
// anywhere in the app.
let (count, set_count) = create_signal(cx, 0);
// we'll pass the setter to specific components,
// but provide the count itself to the whole app via context
provide_context(cx, count);
view! { cx,
// SetterButton is allowed to modify the count
<SetterButton set_count/>
// These consumers can only read from it
// But we could give them write access by passing `set_count` if we wanted
<FancyMath/>
<ListItems/>
}
}
```
`<SetterButton/>` is the kind of counter weve written several times now.
(See the sandbox below if you dont understand what I mean.)
`<FancyMath/>` and `<ListItems/>` both consume the signal were providing via
`use_context` and do something with it.
```rust
/// A component that does some "fancy" math with the global count
#[component]
fn FancyMath(cx: Scope) -> impl IntoView {
// here we consume the global count signal with `use_context`
let count = use_context::<ReadSignal<u32>>(cx)
// we know we just provided this in the parent component
.expect("there to be a `count` signal provided");
let is_even = move || count() & 1 == 0;
view! { cx,
<div class="consumer blue">
"The number "
<strong>{count}</strong>
{move || if is_even() {
" is"
} else {
" is not"
}}
" even."
</div>
}
}
```
Note that this same pattern can be applied to more complex state. If you have multiple fields you want to update independently, you can do that by providing some struct of signals:
```rust
#[derive(Copy, Clone, Debug)]
struct GlobalState {
count: RwSignal<i32>,
name: RwSignal<String>
}
impl GlobalState {
pub fn new(cx: Scope) -> Self {
Self {
count: create_rw_signal(cx, 0),
name: create_rw_signal(cx, "Bob".to_string())
}
}
}
#[component]
fn App(cx: Scope) -> impl IntoView {
provide_context(cx, GlobalState::new(cx));
// etc.
}
```
## Option #3: Create a Global State Struct and Slices
You may find it cumbersome to wrap each field of a structure in a separate signal like this. In some cases, it can be useful to create a plain struct with non-reactive fields, and then wrap that in a signal.
```rust
#[derive(Copy, Clone, Debug, Default)]
struct GlobalState {
count: i32,
name: String
}
#[component]
fn App(cx: Scope) -> impl IntoView {
provide_context(cx, create_rw_signal(GlobalState::default()));
// etc.
}
```
But theres a problem: because our whole state is wrapped in one signal, updating the value of one field will cause reactive updates in parts of the UI that only depend on the other.
```rust
let state = expect_context::<RwSignal<GlobalState>>(cx);
view! { cx,
<button on:click=move |_| state.update(|n| *n += 1)>"+1"</button>
<p>{move || state.with(|state| state.name.clone())}</p>
}
```
In this example, clicking the button will cause the text inside `<p>` to be updated, cloning `state.name` again! Because signals are the atomic unit of reactivity, updating any field of the signal triggers updates to everything that depends on the signal.
Theres a better way. You can use take fine-grained, reactive slices by using [`create_memo`](https://docs.rs/leptos/latest/leptos/fn.create_memo.html) or [`create_slice`](https://docs.rs/leptos/latest/leptos/fn.create_slice.html) (which uses `create_memo` but also provides a setter). “Memoizing” a value means creating a new reactive value which will only update when it changes. “Memoizing a slice” means creating a new reactive value which will only update when some field of the state struct updates.
Here, instead of reading from the state signal directly, we create “slices” of that state with fine-grained updates via `create_slice`. Each slice signal only updates when the particular piece of the larger struct it accesses updates. This means you can create a single root signal, and then take independent, fine-grained slices of it in different components, each of which can update without notifying the others of changes.
```rust
/// A component that updates the count in the global state.
#[component]
fn GlobalStateCounter(cx: Scope) -> impl IntoView {
let state = expect_context::<RwSignal<GlobalState>>(cx);
// `create_slice` lets us create a "lens" into the data
let (count, set_count) = create_slice(
cx,
// we take a slice *from* `state`
state,
// our getter returns a "slice" of the data
|state| state.count,
// our setter describes how to mutate that slice, given a new value
|state, n| state.count = n,
);
view! { cx,
<div class="consumer blue">
<button
on:click=move |_| {
set_count(count() + 1);
}
>
"Increment Global Count"
</button>
<br/>
<span>"Count is: " {count}</span>
</div>
}
}
```
Clicking this button only updates `state.count`, so if we create another slice
somewhere else that only takes `state.name`, clicking the button wont cause
that other slice to update. This allows you to combine the benefits of a top-down
data flow and of fine-grained reactive updates.
> **Note**: There are some significant drawbacks to this approach. Both signals and memos need to own their values, so a memo will need to clone the fields value on every change. The most natural way to manage state in a framework like Leptos is always to provide signals that are as locally-scoped and fine-grained as they can be, not to hoist everything up into global state. But when you _do_ need some kind of global state, `create_slice` can be a useful tool.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/1-basic-component-forked-8bte19?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A2%7D%5D&file=%2Fsrc%2Fmain.rs)
<iframe src="https://codesandbox.io/p/sandbox/1-basic-component-forked-8bte19?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A2%7D%5D&file=%2Fsrc%2Fmain.rs" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/15_global_state.html">
<link rel="canonical" href="https://book.leptos.dev/15_global_state.html">

View File

@@ -1,17 +1,21 @@
# Summary
- [Introduction](./01_introduction.md)
- [Getting Started](./02_getting_started.md)
- [Building User Interfaces](./view/README.md)
- [Getting Started](./getting_started/README.md)
- [Leptos DX](./getting_started/leptos_dx.md)
- [The Leptos Community and leptos-* Crates](./getting_started/community_crates.md)
- [Part 1: Building User Interfaces](./view/README.md)
- [A Basic Component](./view/01_basic_component.md)
- [Dynamic Attributes](./view/02_dynamic_attributes.md)
- [Components and Props](./view/03_components.md)
- [Iteration](./view/04_iteration.md)
- [Iterating over More Complex Data](./view/04b_iteration.md)
- [Forms and Inputs](./view/05_forms.md)
- [Control Flow](./view/06_control_flow.md)
- [Error Handling](./view/07_errors.md)
- [Parent-Child Communication](./view/08_parent_child.md)
- [Passing Children to Components](./view/09_component_children.md)
- [No Macros: The View Builder Syntax](./view/builder.md)
- [Reactivity](./reactivity/README.md)
- [Working with Signals](./reactivity/working_with_signals.md)
- [Responding to Changes with `create_effect`](./reactivity/14_create_effect.md)
@@ -32,7 +36,8 @@
- [`<Form/>`](./router/20_form.md)
- [Interlude: Styling](./interlude_styling.md)
- [Metadata](./metadata.md)
- [Server Side Rendering](./ssr/README.md)
- [Client-Side Rendering: Wrapping Up](./csr_wrapping_up.md)
- [Part 2: Server Side Rendering](./ssr/README.md)
- [`cargo-leptos`](./ssr/21_cargo_leptos.md)
- [The Life of a Page Load](./ssr/22_life_cycle.md)
- [Async Rendering and SSR “Modes”](./ssr/23_ssr_modes.md)
@@ -43,5 +48,9 @@
- [Responses and Redirects](./server/27_response.md)
- [Progressive Enhancement and Graceful Degradation](./progressive_enhancement/README.md)
- [`<ActionForm/>`s](./progressive_enhancement/action_form.md)
- [Deployment]()
- [Appendix: Optimizing WASM Binary Size](./appendix_binary_size.md)
- [Deployment](./deployment/README.md)
- [Optimizing WASM Binary Size](./deployment/binary_size.md)
- [Guide: Islands](./islands.md)
- [Appendix: How Does the Reactive System Work?](./appendix_reactive_graph.md)

View File

@@ -1,72 +0,0 @@
# Appendix: Optimizing WASM Binary Size
One of the primary downsides of deploying a Rust/WebAssembly frontend app is that splitting a WASM file into smaller chunks to be dynamically loaded is significantly more difficult than splitting a JavaScript bundle. There have been experiments like [`wasm-split`](https://emscripten.org/docs/optimizing/Module-Splitting.html) in the Emscripten ecosystem but at present theres no way to split and dynamically load a Rust/`wasm-bindgen` binary. This means that the whole WASM binary needs to be loaded before your app becomes interactive. Because the WASM format is designed for streaming compilation, WASM files are much faster to compile per kilobyte than JavaScript files. (For a deeper look, you can [read this great article from the Mozilla team](https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/) on streaming WASM compilation.)
Still, its important to ship the smallest WASM binary to users that you can, as it will reduce their network usage and make your app interactive as quickly as possible.
So what are some practical steps?
## Things to Do
1. Make sure youre looking at a release build. (Debug builds are much, much larger.)
2. Add a release profile for WASM that optimizes for size, not speed.
For a `cargo-leptos` project, for example, you can add this to your `Cargo.toml`:
```toml
[profile.wasm-release]
inherits = "release"
opt-level = 'z'
lto = true
codegen-units = 1
# ....
[package.metadata.leptos]
# ....
lib-profile-release = "wasm-release"
```
This will hyper-optimize the WASM for your release build for size, while keeping your server build optimized for speed. (For a pure client-rendered app without server considerations, just use the `[profile.wasm-release]` block as your `[profile.release]`.)
3. Always serve compressed WASM in production. WASM tends to compress very well, typically shrinking to less than 50% its uncompressed size, and its trivial to enable compression for static files being served from Actix or Axum.
4. If youre using nightly Rust, you can rebuild the standard library with this same profile rather than the prebuilt standard library thats distributed with the `wasm32-unknown-unknown` target.
To do this, create a file in your project at `.cargo/config.toml`
```toml
[unstable]
build-std = ["std", "panic_abort", "core", "alloc"]
build-std-features = ["panic_immediate_abort"]
```
Note that if you're using this with SSR too, the same Cargo profile will be applied. You'll need to explicitly specify your target:
```toml
[build]
target = "x86_64-unknown-linux-gnu" # or whatever
```
Also note that in some cases, the cfg feature `has_std` will not be set, which may cause build errors with some dependencies which check for `has_std`. You may fix any build errors due to this by adding:
```toml
[build]
rustflags = ["--cfg=has_std"]
```
And you'll need to add `panic = "abort"` to `[profile.release]` in `Cargo.toml`. Note that this applies the same `build-std` and panic settings to your server binary, which may not be desirable. Some further exploration is probably needed here.
5. One of the sources of binary size in WASM binaries can be `serde` serialization/deserialization code. Leptos uses `serde` by default to serialize and deserialize resources created with `create_resource`. You might try experimenting with the `miniserde` and `serde-lite` features, which allow you to use those crates for serialization and deserialization instead; each only implements a subset of `serde`s functionality, but typically optimizes for size over speed.
## Things to Avoid
There are certain crates that tend to inflate binary sizes. For example, the `regex` crate with its default features adds about 500kb to a WASM binary (largely because it has to pull in Unicode table data!) In a size-conscious setting, you might consider avoiding regexes in general, or even dropping down and calling browser APIs to use the built-in regex engine instead. (This is what `leptos_router` does on the few occasions it needs a regular expression.)
In general, Rusts commitment to runtime performance is sometimes at odds with a commitment to a small binary. For example, Rust monomorphizes generic functions, meaning it creates a distinct copy of the function for each generic type its called with. This is significantly faster than dynamic dispatch, but increases binary size. Leptos tries to balance runtime performance with binary size considerations pretty carefully; but you might find that writing code that uses many generics tends to increase binary size. For example, if you have a generic component with a lot of code in its body and call it with four different types, remember that the compiler could include four copies of that same code. Refactoring to use a concrete inner function or helper can often maintain performance and ergonomics while reducing binary size.
## A Final Thought
Remember that in a server-rendered app, JS bundle size/WASM binary size affects only _one_ thing: time to interactivity on the first load. This is very important to a good user experience—nobody wants to click a button three times and have it do nothing because the interactive code is still loading—but it is not the only important measure.
Its especially worth remembering that streaming in a single WASM binary means all subsequent navigations are nearly instantaneous, depending only on any additional data loading. Precisely because your WASM binary is _not_ bundle split, navigating to a new route does not require loading additional JS/WASM, as it does in nearly every JavaScript framework. Is this copium? Maybe. Or maybe its just an honest trade-off between the two approaches!
Always take the opportunity to optimize the low-hanging fruit in your application. And always test your app under real circumstances with real user network speeds and devices before making any heroic efforts.

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/appendix_reactive_graph.html">
<link rel="canonical" href="https://book.leptos.dev/appendix_reactive_graph.html">

View File

@@ -1,55 +1,2 @@
# Loading Data with Resources
A [Resource](https://docs.rs/leptos/latest/leptos/struct.Resource.html) is a reactive data structure that reflects the current state of an asynchronous task, allowing you to integrate asynchronous `Future`s into the synchronous reactive system. Rather than waiting for its data to load with `.await`, you transform the `Future` into a signal that returns `Some(T)` if it has resolved, and `None` if its still pending.
You do this by using the [`create_resource`](https://docs.rs/leptos/latest/leptos/fn.create_resource.html) function. This takes two arguments (other than the ubiquitous `cx`):
1. a source signal, which will generate a new `Future` whenever it changes
2. a fetcher function, which takes the data from that signal and returns a `Future`
Heres an example
```rust
// our source signal: some synchronous, local state
let (count, set_count) = create_signal(cx, 0);
// our resource
let async_data = create_resource(cx,
count,
// every time `count` changes, this will run
|value| async move {
log!("loading data from API");
load_data(value).await
},
);
```
To create a resource that simply runs once, you can pass a non-reactive, empty source signal:
```rust
let once = create_resource(cx, || (), |_| async move { load_data().await });
```
To access the value you can use `.read(cx)` or `.with(cx, |data| /* */)`. These work just like `.get()` and `.with()` on a signal—`read` clones the value and returns it, `with` applies a closure to it—but with two differences
1. For any `Resource<_, T>`, they always return `Option<T>`, not `T`: because its always possible that your resource is still loading.
2. They take a `Scope` argument. Youll see why in the next chapter, on `<Suspense/>`.
So, you can show the current state of a resource in your view:
```rust
let once = create_resource(cx, || (), |_| async move { load_data().await });
view! { cx,
<h1>"My Data"</h1>
{move || match once.read(cx) {
None => view! { cx, <p>"Loading..."</p> }.into_view(cx),
Some(data) => view! { cx, <ShowData data/> }.into_view(cx)
}}
}
```
Resources also provide a `refetch()` method that allows you to manually reload the data (for example, in response to a button click) and a `loading()` method that returns a `ReadSignal<bool>` indicating whether the resource is currently loading or not.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/10-async-resources-4z0qt3?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D)
<iframe src="https://codesandbox.io/p/sandbox/10-async-resources-4z0qt3?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/10_resources.html">
<link rel="canonical" href="https://book.leptos.dev/async/10_resources.html">

View File

@@ -1,74 +1,2 @@
# `<Suspense/>`
In the previous chapter, we showed how you can create a simple loading screen to show some fallback while a resource is loading.
```rust
let (count, set_count) = create_signal(cx, 0);
let a = create_resource(cx, count, |count| async move { load_a(count).await });
view! { cx,
<h1>"My Data"</h1>
{move || match once.read(cx) {
None => view! { cx, <p>"Loading..."</p> }.into_view(cx),
Some(data) => view! { cx, <ShowData data/> }.into_view(cx)
}}
}
```
But what if we have two resources, and want to wait for both of them?
```rust
let (count, set_count) = create_signal(cx, 0);
let (count2, set_count2) = create_signal(cx, 0);
let a = create_resource(cx, count, |count| async move { load_a(count).await });
let b = create_resource(cx, count2, |count| async move { load_b(count).await });
view! { cx,
<h1>"My Data"</h1>
{move || match (a.read(cx), b.read(cx)) {
(Some(a), Some(b)) => view! { cx,
<ShowA a/>
<ShowA b/>
}.into_view(cx),
_ => view! { cx, <p>"Loading..."</p> }.into_view(cx)
}}
}
```
Thats not _so_ bad, but its kind of annoying. What if we could invert the flow of control?
The [`<Suspense/>`](https://docs.rs/leptos/latest/leptos/fn.Suspense.html) component lets us do exactly that. You give it a `fallback` prop and children, one or more of which usually involves reading from a resource. Reading from a resource “under” a `<Suspense/>` (i.e., in one of its children) registers that resource with the `<Suspense/>`. If its still waiting for resources to load, it shows the `fallback`. When theyve all loaded, it shows the children.
```rust
let (count, set_count) = create_signal(cx, 0);
let (count2, set_count2) = create_signal(cx, 0);
let a = create_resource(cx, count, |count| async move { load_a(count).await });
let b = create_resource(cx, count2, |count| async move { load_b(count).await });
view! { cx,
<h1>"My Data"</h1>
<Suspense
fallback=move || view! { cx, <p>"Loading..."</p> }
>
<h2>"My Data"</h2>
<h3>"A"</h3>
{move || {
a.read(cx)
.map(|a| view! { cx, <ShowA a/> })
}}
<h3>"B"</h3>
{move || {
b.read(cx)
.map(|b| view! { cx, <ShowB b/> })
}}
</Suspense>
}
```
Every time one of the resources is reloading, the `"Loading..."` fallback will show again.
This inversion of the flow of control makes it easier to add or remove individual resources, as you dont need to handle the matching yourself. It also unlocks some massive performance improvements during server-side rendering, which well talk about during a later chapter.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/11-suspense-907niv?file=%2Fsrc%2Fmain.rs)
<iframe src="https://codesandbox.io/p/sandbox/11-suspense-907niv?file=%2Fsrc%2Fmain.rs" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/11_suspense.html">
<link rel="canonical" href="https://book.leptos.dev/async/11_suspense.html">

View File

@@ -1,11 +1,2 @@
# `<Transition/>`
Youll notice in the `<Suspense/>` example that if you keep reloading the data, it keeps flickering back to `"Loading..."`. Sometimes this is fine. For other times, theres [`<Transition/>`](https://docs.rs/leptos/latest/leptos/fn.Suspense.html).
`<Transition/>` behaves exactly the same as `<Suspense/>`, but instead of falling back every time, it only shows the fallback the first time. On all subsequent loads, it continues showing the old data until the new data are ready. This can be really handy to prevent the flickering effect, and to allow users to continue interacting with your application.
This example shows how you can create a simple tabbed contact list with `<Transition/>`. When you select a new tab, it continues showing the current contact until the new data loads. This can be a much better user experience than constantly falling back to a loading message.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/12-transition-sn38sd?selection=%5B%7B%22endColumn%22%3A15%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A15%2C%22startLineNumber%22%3A2%7D%5D&file=%2Fsrc%2Fmain.rs)
<iframe src="https://codesandbox.io/p/sandbox/12-transition-sn38sd?selection=%5B%7B%22endColumn%22%3A15%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A15%2C%22startLineNumber%22%3A2%7D%5D&file=%2Fsrc%2Fmain.rs" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/12_transition.html">
<link rel="canonical" href="https://book.leptos.dev/async/12_transition.html">

View File

@@ -1,96 +1,2 @@
# Mutating Data with Actions
Weve talked about how to load `async` data with resources. Resources immediately load data and work closely with `<Suspense/>` and `<Transition/>` components to show whether data is loading in your app. But what if you just want to call some arbitrary `async` function and keep track of what its doing?
Well, you could always use [`spawn_local`](https://docs.rs/leptos/latest/leptos/fn.spawn_local.html). This allows you to just spawn an `async` task in a synchronous environment by handing the `Future` off to the browser (or, on the server, Tokio or whatever other runtime youre using). But how do you know if its still pending? Well, you could just set a signal to show whether its loading, and another one to show the result...
All of this is true. Or you could use the final `async` primitive: [`create_action`](https://docs.rs/leptos/latest/leptos/fn.create_action.html).
Actions and resources seem similar, but they represent fundamentally different things. If youre trying to load data by running an `async` function, either once or when some other value changes, you probably want to use `create_resource`. If youre trying to occasionally run an `async` function in response to something like a user clicking a button, you probably want to use `create_action`.
Say we have some `async` function we want to run.
```rust
async fn add_todo_request(new_title: &str) -> Uuid {
/* do some stuff on the server to add a new todo */
}
```
`create_action` takes a reactive `Scope` and an `async` function that takes a reference to a single argument, which you could think of as its “input type.”
> The input is always a single type. If you want to pass in multiple arguments, you can do it with a struct or tuple.
>
> ```rust
> // if there's a single argument, just use that
> let action1 = create_action(cx, |input: &String| {
> let input = input.clone();
> async move { todo!() }
> });
>
> // if there are no arguments, use the unit type `()`
> let action2 = create_action(cx, |input: &()| async { todo!() });
>
> // if there are multiple arguments, use a tuple
> let action3 = create_action(cx,
> |input: &(usize, String)| async { todo!() }
> );
> ```
>
> Because the action function takes a reference but the `Future` needs to have a `'static` lifetime, youll usually need to clone the value to pass it into the `Future`. This is admittedly awkward but it unlocks some powerful features like optimistic UI. Well see a little more about that in future chapters.
So in this case, all we need to do to create an action is
```rust
let add_todo_action = create_action(cx, |input: &String| {
let input = input.to_owned();
async move { add_todo_request(&input).await }
});
```
Rather than calling `add_todo_action` directly, well call it with `.dispatch()`, as in
```rust
add_todo_action.dispatch("Some value".to_string());
```
You can do this from an event listener, a timeout, or anywhere; because `.dispatch()` isnt an `async` function, it can be called from a synchronous context.
Actions provide access to a few signals that synchronize between the asynchronous action youre calling and the synchronous reactive system:
```rust
let submitted = add_todo_action.input(); // RwSignal<Option<String>>
let pending = add_todo_action.pending(); // ReadSignal<bool>
let todo_id = add_todo_action.value(); // RwSignal<Option<Uuid>>
```
This makes it easy to track the current state of your request, show a loading indicator, or do “optimistic UI” based on the assumption that the submission will succeed.
```rust
let input_ref = create_node_ref::<Input>(cx);
view! { cx,
<form
on:submit=move |ev| {
ev.prevent_default(); // don't reload the page...
let input = input_ref.get().expect("input to exist");
add_todo_action.dispatch(input.value());
}
>
<label>
"What do you need to do?"
<input type="text"
node_ref=input_ref
/>
</label>
<button type="submit">"Add Todo"</button>
</form>
// use our loading state
<p>{move || pending().then("Loading...")}</p>
}
```
Now, theres a chance this all seems a little over-complicated, or maybe too restricted. I wanted to include actions here, alongside resources, as the missing piece of the puzzle. In a real Leptos app, youll actually most often use actions alongside server functions, [`create_server_action`](https://docs.rs/leptos/latest/leptos/fn.create_server_action.html), and the [`<ActionForm/>`](https://docs.rs/leptos_router/latest/leptos_router/fn.ActionForm.html) component to create really powerful progressively-enhanced forms. So if this primitive seems useless to you... Dont worry! Maybe it will make sense later. (Or check out our [`todo_app_sqlite`](https://github.com/leptos-rs/leptos/blob/main/examples/todo_app_sqlite/src/todo.rs) example now.)
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/10-async-resources-forked-hgpfp0?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A4%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A4%7D%5D&file=%2Fsrc%2Fmain.rs)
<iframe src="https://codesandbox.io/p/sandbox/10-async-resources-forked-hgpfp0?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A4%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A4%7D%5D&file=%2Fsrc%2Fmain.rs" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/13_action.html">
<link rel="canonical" href="https://book.leptos.dev/async/13_action.html">

View File

@@ -1,9 +1,2 @@
# Working with `async`
So far weve only been working with synchronous users interfaces: You provide some input,
the app immediately processes it and updates the interface. This is great, but is a tiny
subset of what web applications do. In particular, most web apps have to deal with some kind of asynchronous data loading, usually loading something from an API.
Asynchronous data is notoriously hard to integrate with the synchronous parts of your code. Leptos provides a cross-platform [`spawn_local`](https://docs.rs/leptos/latest/leptos/fn.spawn_local.html) function that makes it easy to run a `Future`, but theres much more to it than that.
In this chapter, well see how Leptos helps smooth out that process for you.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/index.html">
<link rel="canonical" href="https://book.leptos.dev/async/index.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/csr_wrapping_up.html">
<link rel="canonical" href="https://book.leptos.dev/csr_wrapping_up.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/deployment/index.html">
<link rel="canonical" href="https://book.leptos.dev/deployment/index.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/deployment/binary_size.html">
<link rel="canonical" href="https://book.leptos.dev/deployment/binary_size.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/index.html">
<link rel="canonical" href="https://book.leptos.dev/getting_started/index.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/community_crates.html">
<link rel="canonical" href="https://book.leptos.dev/getting_started/community_crates.html">

View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/leptos_dx.html">
<link rel="canonical" href="https://book.leptos.dev/getting_started/leptos_dx.html">

View File

@@ -1,177 +1,2 @@
# Projecting Children
As you build components you may occasionally find yourself wanting to “project” children through multiple layers of components.
## The Problem
Consider the following:
```rust
pub fn LoggedIn<F, IV>(cx: Scope, fallback: F, children: ChildrenFn) -> impl IntoView
where
F: Fn(Scope) -> IV + 'static,
IV: IntoView,
{
view! { cx,
<Suspense
fallback=|| ()
>
<Show
// check whether user is verified
// by reading from the resource
when=move || todo!()
fallback=fallback
>
{children(cx)}
</Show>
</Suspense>
}
}
```
This is pretty straightforward: when the user is logged in, we want to show `children`. If the user is not logged in, we want to show `fallback`. And while were waiting to find out, we just render `()`, i.e., nothing.
In other words, we want to pass the children of `<LoggedIn/>` _through_ the `<Suspense/>` component to become the children of the `<Show/>`. This is what I mean by “projection.”
This wont compile.
```
error[E0507]: cannot move out of `fallback`, a captured variable in an `Fn` closure
error[E0507]: cannot move out of `children`, a captured variable in an `Fn` closure
```
The problem here is that both `<Suspense/>` and `<Show/>` need to be able to construct their `children` multiple times. The first time you construct `<Suspense/>`s children, it would take ownership of `fallback` and `children` to move them into the invocation of `<Show/>`, but then they're not available for future `<Suspense/>` children construction.
## The Details
> Feel free to skip ahead to the solution.
If you want to really understand the issue here, it may help to look at the expanded `view` macro. Heres a cleaned-up version:
```rust
Suspense(
cx,
::leptos::component_props_builder(&Suspense)
.fallback(|| ())
.children({
// fallback and children are moved into this closure
Box::new(move |cx| {
{
// fallback and children captured here
leptos::Fragment::lazy(|| {
vec![
(Show(
cx,
::leptos::component_props_builder(&Show)
.when(|| true)
// but fallback is moved into Show here
.fallback(fallback)
// and children is moved into Show here
.children(children)
.build(),
)
.into_view(cx)),
]
})
}
})
})
.build(),
)
```
All components own their props; so the `<Show/>` in this case cant be called because it only has captured references to `fallback` and `children`.
## Solution
However, both `<Suspense/>` and `<Show/>` take `ChildrenFn`, i.e., their `children` should implement the `Fn` type so they can be called multiple times with only an immutable reference. This means we dont need to own `children` or `fallback`; we just need to be able to pass `'static` references to them.
We can solve this problem by using the [`store_value`](https://docs.rs/leptos/latest/leptos/fn.store_value.html) primitive. This essentially stores a value in the reactive system, handing ownership off to the framework in exchange for a reference that is, like signals, `Copy` and `'static`, which we can access or modify through certain methods.
In this case, its really simple:
```rust
pub fn LoggedIn<F, IV>(cx: Scope, fallback: F, children: ChildrenFn) -> impl IntoView
where
F: Fn(Scope) -> IV + 'static,
IV: IntoView,
{
let fallback = store_value(cx, fallback);
let children = store_value(cx, children);
view! { cx,
<Suspense
fallback=|| ()
>
<Show
when=|| todo!()
fallback=move |cx| fallback.with_value(|fallback| fallback(cx))
>
{children.with_value(|children| children(cx))}
</Show>
</Suspense>
}
}
```
At the top level, we store both `fallback` and `children` in the reactive scope owned by `LoggedIn`. Now we can simply move those references down through the other layers into the `<Show/>` component and call them there.
## A Final Note
Note that this works because `<Show/>` and `<Suspense/>` only need an immutable reference to their children (which `.with_value` can give it), not ownership.
In other cases, you may need to project owned props through a function that takes `ChildrenFn` and therefore needs to be called more than once. In this case, you may find the `clone:` helper in the`view` macro helpful.
Consider this example
```rust
#[component]
pub fn App(cx: Scope) -> impl IntoView {
let name = "Alice".to_string();
view! { cx,
<Outer>
<Inner>
<Inmost name=name.clone()/>
</Inner>
</Outer>
}
}
#[component]
pub fn Outer(cx: Scope, children: ChildrenFn) -> impl IntoView {
children(cx)
}
#[component]
pub fn Inner(cx: Scope, children: ChildrenFn) -> impl IntoView {
children(cx)
}
#[component]
pub fn Inmost(cx: Scope, name: String) -> impl IntoView {
view! { cx,
<p>{name}</p>
}
}
```
Even with `name=name.clone()`, this gives the error
```
cannot move out of `name`, a captured variable in an `Fn` closure
```
Its captured through multiple levels of children that need to run more than once, and theres no obvious way to clone it _into_ the children.
In this case, the `clone:` syntax comes in handy. Calling `clone:name` will clone `name` _before_ moving it into `<Inner/>`s children, which solves our ownership issue.
```rust
view! { cx,
<Outer>
<Inner clone:name>
<Inmost name=name.clone()/>
</Inner>
</Outer>
}
```
These issues can be a little tricky to understand or debug, because of the opacity of the `view` macro. But in general, they can always be solved.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/interlude_projecting_children.html">
<link rel="canonical" href="https://book.leptos.dev/interlude_projecting_children.html">

View File

@@ -1,112 +1,2 @@
# Interlude: Styling
Anyone creating a website or application soon runs into the question of styling. For a small app, a single CSS file is probably plenty to style your user interface. But as an application grows, many developers find that plain CSS becomes increasingly hard to manage.
Some frontend frameworks (like Angular, Vue, and Svelte) provide built-in ways to scope your CSS to particular components, making it easier to manage styles across a whole application without styles meant to modify one small component having a global effect. Other frameworks (like React or Solid) dont provide built-in CSS scoping, but rely on libraries in the ecosystem to do it for them. Leptos is in this latter camp: the framework itself has no opinions about CSS at all, but provides a few tools and primitives that allow others to build styling libraries.
Here are a few different approaches to styling your Leptos app, other than plain CSS.
## TailwindCSS: Utility-first CSS
[TailwindCSS](https://tailwindcss.com/) is a popular utility-first CSS library. It allows you to style your application by using inline utility classes, with a custom CLI tool that scans your files for Tailwind class names and bundles the necessary CSS.
This allows you to write components like this:
```rust
#[component]
fn Home(cx: Scope) -> impl IntoView {
let (count, set_count) = create_signal(cx, 0);
view! { cx,
<main class="my-0 mx-auto max-w-3xl text-center">
<h2 class="p-6 text-4xl">"Welcome to Leptos with Tailwind"</h2>
<p class="px-10 pb-10 text-left">"Tailwind will scan your Rust files for Tailwind class names and compile them into a CSS file."</p>
<button
class="bg-sky-600 hover:bg-sky-700 px-5 py-3 text-white rounded-lg"
on:click=move |_| set_count.update(|count| *count += 1)
>
{move || if count() == 0 {
"Click me!".to_string()
} else {
count().to_string()
}}
</button>
</main>
}
}
```
It can be a little complicated to set up the Tailwind integration at first, but you can check out our two examples of how to use Tailwind with a [client-side-rendered `trunk` application](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind_csr_trunk) or with a [server-rendered `cargo-leptos` application](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind). `cargo-leptos` also has some [built-in Tailwind support](https://github.com/leptos-rs/cargo-leptos#site-parameters) that you can use as an alternative to Tailwinds CLI.
## Stylers: Compile-time CSS Extraction
[Stylers](https://github.com/abishekatp/stylers) is a compile-time scoped CSS library that lets you declare scoped CSS in the body of your component. Stylers will extract this CSS at compile time into CSS files that you can then import into your app, which means that it doesnt add anything to the WASM binary size of your application.
This allows you to write components like this:
```rust
use stylers::style;
#[component]
pub fn App(cx: Scope) -> impl IntoView {
let styler_class = style! { "App",
#two{
color: blue;
}
div.one{
color: red;
content: raw_str(r#"\hello"#);
font: "1.3em/1.2" Arial, Helvetica, sans-serif;
}
div {
border: 1px solid black;
margin: 25px 50px 75px 100px;
background-color: lightblue;
}
h2 {
color: purple;
}
@media only screen and (max-width: 1000px) {
h3 {
background-color: lightblue;
color: blue
}
}
};
view! { cx, class = styler_class,
<div class="one">
<h1 id="two">"Hello"</h1>
<h2>"World"</h2>
<h2>"and"</h2>
<h3>"friends!"</h3>
</div>
}
}
```
## Styled: Runtime CSS Scoping
[Styled](https://github.com/eboody/styled) is a runtime scoped CSS library that integrates well with Leptos. It lets you declare scoped CSS in the body of your component function, and then applies those styles at runtime.
```rust
use styled::style;
#[component]
pub fn MyComponent(cx: Scope) -> impl IntoView {
let styles = style!(
div {
background-color: red;
color: white;
}
);
styled::view! { cx, styles,
<div>"This text should be red with white text."</div>
}
}
```
## Contributions Welcome
Leptos has no opinions on how you style your website or app, but were very happy to provide support to any tools youre trying to create to make it easier. If youre working on a CSS or styling approach that youd like to add to this list, please let us know!
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/interlude_styling.html">
<link rel="canonical" href="https://book.leptos.dev/interlude_styling.html">

2
docs/book/src/islands.md Normal file
View File

@@ -0,0 +1,2 @@
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/islands.html">
<link rel="canonical" href="https://book.leptos.dev/islands.html">

View File

@@ -1,49 +1,2 @@
# Metadata
So far, everything weve rendered has been inside the `<body>` of the HTML document. And this makes sense. After all, everything you can see on a web page lives inside the `<body>`.
However, there are plenty of occasions where you might want to update something inside the `<head>` of the document using the same reactive primitives and component patterns you use for your UI.
Thats where the [`leptos_meta`](https://docs.rs/leptos_meta/latest/leptos_meta/) package comes in.
## Metadata Components
`leptos_meta` provides special components that let you inject data from inside components anywhere in your application into the `<head>`:
[`<Title/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Title.html) allows you to set the documents title from any component. It also takes a `formatter` function that can be used to apply the same format to the title set by other pages. So, for example, if you put `<Title formatter=|text| format!("{text} — My Awesome Site")/>` in your `<App/>` component, and then `<Title text="Page 1"/>` and `<Title text="Page 2"/>` on your routes, youll get `Page 1 — My Awesome Site` and `Page 2 — My Awesome Site`.
[`<Link/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Link.html) takes the standard attributes of the `<link>` element.
[`<Stylesheet/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Stylesheet.html) creates a `<link rel="stylesheet">` with the `href` you give.
[`<Style/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Style.html) creates a `<style>` with the children you pass in (usually a string). You can use this to import some custom CSS from another file at compile time `<Style>{include_str!("my_route.css")}</Style>`.
[`<Meta/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Meta.html) lets you set `<meta>` tags with descriptions and other metadata.
## `<Script/>` and `<script>`
`leptos_meta` also provides a [`<Script/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Script.html) component, and its worth pausing here for a second. All of the other components weve considered inject `<head>`-only elements in the `<head>`. But a `<script>` can also be included in the body.
Theres a very simple way to determine whether you should use a capital-S `<Script/>` component or a lowercase-s `<script>` element: the `<Script/>` component will be rendered in the `<head>`, and the `<script>` element will be rendered wherever in the `<body>` of your user interface you put it in, alongside other normal HTML elements. These cause JavaScript to load and run at different times, so use whichever is appropriate to your needs.
## `<Body/>` and `<Html/>`
There are even a couple elements designed to make semantic HTML and styling easier. [`<Html/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Html.html) lets you set the `lang` and `dir` on your `<html>` tag from your application code. `<Html/>` and [`<Body/>`](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Html.html) both have `class` props that let you set their respective `class` attributes, which is sometimes needed by CSS frameworks for styling.
`<Body/>` and `<Html/>` both also have `attributes` props which can be used to set any number of additional attributes on them via the [`AdditionalAttributes`](https://docs.rs/leptos/latest/leptos/struct.AdditionalAttributes.html) type:
```rust
<Html
lang="he"
dir="rtl"
attributes=AdditionalAttributes::from(vec![("data-theme", "dark")])
/>
```
## Metadata and Server Rendering
Now, some of this is useful in any scenario, but some of it is especially important for search-engine optimization (SEO). Making sure you have things like appropriate `<title>` and `<meta>` tags is crucial. Modern search engine crawlers do handle client-side rendering, i.e., apps that are shipped as an empty `index.html` and rendered entirely in JS/WASM. But they prefer to receive pages in which your app has been rendered to actual HTML, with metadata in the `<head>`.
This is exactly what `leptos_meta` is for. And in fact, during server rendering, this is exactly what it does: collect all the `<head>` content youve declared by using its components throughout your application, and then inject it into the actual `<head>`.
But Im getting ahead of myself. We havent actually talked about server-side rendering yet. As a matter of fact... Lets do that next!
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/metadata.html">
<link rel="canonical" href="https://book.leptos.dev/metadata.html">

View File

@@ -1,36 +1,2 @@
# Progressive Enhancement (and Graceful Degradation)
Ive been driving around Boston for about fifteen years. If you dont know Boston, let me tell you: Massachusetts has some of the most aggressive drivers(and pedestrians!) in the world. Ive learned to practice whats sometimes called “defensive driving”: assuming that someones about to swerve in front of you at an intersection when you have the right of way, preparing for a pedestrian to cross into the street at any moment, and driving accordingly.
“Progressive enhancement” is the “defensive driving” of web design. Or really, thats “graceful degradation,” although theyre two sides of the same coin, or the same process, from two different directions.
**Progressive enhancement**, in this context, means beginning with a simple HTML site or application that works for any user who arrives at your page, and gradually enhancing it with layers of additional features: CSS for styling, JavaScript for interactivity, WebAssembly for Rust-powered interactivity; using particular Web APIs for a richer experience if theyre available and as needed.
**Graceful degradation** means handling failure gracefully when parts of that stack of enhancement *arent* available. Here are some sources of failure your users might encounter in your app:
- Their browser doesnt support WebAssembly because it needs to be updated.
- Their browser cant support WebAssembly because browser updates are limited to newer OS versions, which cant be installed on the device. (Looking at you, Apple.)
- They have WASM turned off for security or privacy reasons.
- They have JavaScript turned off for security or privacy reasons.
- JavaScript isnt supported on their device (for example, some accessibility devices only support HTML browsing)
- The JavaScript (or WASM) never arrived at their device because they walked outside and lost WiFi.
- They stepped onto a subway car after loading the initial page and subsequent navigations cant load data.
- ... and so on.
How much of your app still works if one of these holds true? Two of them? Three?
If the answer is something like “95%... okay, then 90%... okay, then 75%,” thats graceful degradation. If the answer is “my app shows a blank screen unless everything works correctly,” thats... rapid unscheduled disassembly.
**Graceful degradation is especially important for WASM apps,** because WASM is the newest and least-likely-to-be-supported of the four languages that run in the browser (HTML, CSS, JS, WASM).
Luckily, weve got some tools to help.
## Defensive Design
There are a few practices that can help your apps degrade more gracefully:
1. **Server-side rendering.** Without SSR, your app simply doesnt work without both JS and WASM loading. In some cases this may be appropriate (think internal apps gated behind a login) but in others its simply broken.
2. **Native HTML elements.** Use HTML elements that do the things that you want, without additional code: `<a>` for navigation (including to hashes within the page), `<details>` for an accordion, `<form>` to persist information in the URL, etc.
3. **URL-driven state.** The more of your global state is stored in the URL (as a route param or part of the query string), the more of the page can be generated during server rendering and updated by an `<a>` or a `<form>`, which means that not only navigations but state changes can work without JS/WASM.
4. **[`SsrMode::PartiallyBlocked` or `SsrMode::InOrder`](https://docs.rs/leptos_router/latest/leptos_router/enum.SsrMode.html).** Out-of-order streaming requires a small amount of inline JS, but can fail if 1) the connection is broken halfway through the response or 2) the clients device doesnt support JS. Async streaming will give a complete HTML page, but only after all resources load. In-order streaming begins showing pieces of the page sooner, in top-down order. “Partially-blocked” SSR builds on out-of-order streaming by replacing `<Suspense/>` fragments that read from blocking resources on the server. This adds marginally to the initial response time (because of the `O(n)` string replacement work), in exchange for a more complete initial HTML response. This can be a good choice for situations in which theres a clear distinction between “more important” and “less important” content, e.g., blog post vs. comments, or product info vs. reviews. If you choose to block on all the content, youve essentially recreated async rendering.
5. **Leaning on `<form>`s.** Theres been a bit of a `<form>` renaissance recently, and its no surprise. The ability of a `<form>` to manage complicated `POST` or `GET` requests in an easily-enhanced way makes it a powerful tool for graceful degradation. The example in [the `<Form/>` chapter](../router/20_form.md), for example, would work fine with no JS/WASM: because it uses a `<form method="GET">` to persist state in the URL, it works with pure HTML by making normal HTTP requests and then progressively enhances to use client-side navigations instead.
Theres one final feature of the framework that we havent seen yet, and which builds on this characteristic of forms to build powerful applications: the `<ActionForm/>`.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/progressive_enhancement/index.html">
<link rel="canonical" href="https://book.leptos.dev/progressive_enhancement/index.html">

View File

@@ -1,56 +1,2 @@
# `<ActionForm/>`
[`<ActionForm/>`](https://docs.rs/leptos_router/latest/leptos_router/fn.ActionForm.html) is a specialized `<Form/>` that takes a server action, and automatically dispatches it on form submission. This allows you to call a server function directly from a `<form>`, even without JS/WASM.
The process is simple:
1. Define a server function using the [`#[server]` macro](https://docs.rs/leptos/latest/leptos/attr.server.html) (see [Server Functions](../server/25_server_functions.md).)
2. Create an action using [`create_server_action`](https://docs.rs/leptos/latest/leptos/fn.create_server_action.html), specifying the type of the server function youve defined.
3. Create an `<ActionForm/>`, providing the server action in the `action` prop.
4. Pass the named arguments to the server function as form fields with the same names.
> **Note:** `<ActionForm/>` only works with the default URL-encoded `POST` encoding for server functions, to ensure graceful degradation/correct behavior as an HTML form.
```rust
#[server(AddTodo, "/api")]
pub async fn add_todo(title: String) -> Result<(), ServerFnError> {
todo!()
}
#[component]
fn AddTodo(cx: Scope) -> impl IntoView {
let add_todo = create_server_action::<AddTodo>(cx);
// holds the latest *returned* value from the server
let value = add_todo.value();
// check if the server has returned an error
let has_error = move || value.with(|val| matches!(val, Some(Err(_))));
view! { cx,
<ActionForm action=add_todo>
<label>
"Add a Todo"
// `title` matches the `title` argument to `add_todo`
<input type="text" name="title"/>
</label>
<input type="submit" value="Add"/>
</ActionForm>
}
}
```
Its really that easy. With JS/WASM, your form will submit without a page reload, storing its most recent submission in the `.input()` signal of the action, its pending status in `.pending()`, and so on. (See the [`Action`](https://docs.rs/leptos/latest/leptos/struct.Action.html) docs for a refresher, if you need.) Without JS/WASM, your form will submit with a page reload. If you call a `redirect` function (from `leptos_axum` or `leptos_actix`) it will redirect to the correct page. By default, it will redirect back to the page youre currently on. The power of HTML, HTTP, and isomorphic rendering mean that your `<ActionForm/>` simply works, even with no JS/WASM.
## Client-Side Validation
Because the `<ActionForm/>` is just a `<form>`, it fires a `submit` event. You can use either HTML validation, or your own client-side validation logic in an `on:submit`. Just call `ev.prevent_default()` to prevent submission.
The [`FromFormData`](https://docs.rs/leptos_router/latest/leptos_router/trait.FromFormData.html) trait can be helpful here, for attempting to parse your server functions data type from the submitted form.
```rust
let on_submit = move |ev| {
let data = AddTodo::from_event(&ev);
// silly example of validation: if the todo is "nope!", nope it
if data.is_err() || data.unwrap().title == "nope!" {
// ev.prevent_default() will prevent form submission
ev.prevent_default();
}
}
```
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/progressive_enhancement/action_form.html">
<link rel="canonical" href="https://book.leptos.dev/progressive_enhancement/action_form.html">

View File

@@ -1,114 +1,2 @@
# Responding to Changes with `create_effect`
Weve made it this far without having mentioned half of the reactive system: effects.
Reactivity works in two halves: updating individual reactive values (“signals”) notifies the pieces of code that depend on them (“effects”) that they need to run again. These two halves of the reactive system are inter-dependent. Without effects, signals can change within the reactive system but never be observed in a way that interacts with the outside world. Without signals, effects run once but never again, as theres no observable value to subscribe to. Effects are quite literally “side effects” of the reactive system: they exist to synchronize the reactive system with the non-reactive world outside it.
Hidden behind the whole reactive DOM renderer that weve seen so far is a function called `create_effect`.
[`create_effect`](https://docs.rs/leptos_reactive/latest/leptos_reactive/fn.create_effect.html) takes a function as its argument. It immediately runs the function. If you access any reactive signal inside that function, it registers the fact that the effect depends on that signal with the reactive runtime. Whenever one of the signals that the effect depends on changes, the effect runs again.
```rust
let (a, set_a) = create_signal(cx, 0);
let (b, set_b) = create_signal(cx, 0);
create_effect(cx, move |_| {
// immediately prints "Value: 0" and subscribes to `a`
log::debug!("Value: {}", a());
});
```
The effect function is called with an argument containing whatever value it returned the last time it ran. On the initial run, this is `None`.
By default, effects **do not run on the server**. This means you can call browser-specific APIs within the effect function without causing issues. If you need an effect to run on the server, use [`create_isomorphic_effect`](https://docs.rs/leptos_reactive/latest/leptos_reactive/fn.create_isomorphic_effect.html).
## Autotracking and Dynamic Dependencies
If youre familiar with a framework like React, you might notice one key difference. React and similar frameworks typically require you to pass a “dependency array,” an explicit set of variables that determine when the effect should rerun.
Because Leptos comes from the tradition of synchronous reactive programming, we dont need this explicit dependency list. Instead, we automatically track dependencies depending on which signals are accessed within the effect.
This has two effects (no pun intended). Dependencies are:
1. **Automatic**: You dont need to maintain a dependency list, or worry about what should or shouldnt be included. The framework simply tracks which signals might cause the effect to rerun, and handles it for you.
2. **Dynamic**: The dependency list is cleared and updated every time the effect runs. If your effect contains a conditional (for example), only signals that are used in the current branch are tracked. This means that effects rerun the absolute minimum number of times.
> If this sounds like magic, and if you want a deep dive into how automatic dependency tracking works, [check out this video](https://www.youtube.com/watch?v=GWB3vTWeLd4). (Apologies for the low volume!)
## Effects as Zero-Cost-ish Abstraction
While theyre not a “zero-cost abstraction” in the most technical sense—they require some additional memory use, exist at runtime, etc.—at a higher level, from the perspective of whatever expensive API calls or other work youre doing within them, effects are a zero-cost abstraction. They rerun the absolute minimum number of times necessary, given how youve described them.
Imagine that Im creating some kind of chat software, and I want people to be able to display their full name, or just their first name, and to notify the server whenever their name changes:
```rust
let (first, set_first) = create_signal(cx, String::new());
let (last, set_last) = create_signal(cx, String::new());
let (use_last, set_use_last) = create_signal(cx, true);
// this will add the name to the log
// any time one of the source signals changes
create_effect(cx, move |_| {
log(
cx,
if use_last() {
format!("{} {}", first(), last())
} else {
first()
},
)
});
```
If `use_last` is `true`, effect should rerun whenever `first`, `last`, or `use_last` changes. But if I toggle `use_last` to `false`, a change in `last` will never cause the full name to change. In fact, `last` will be removed from the dependency list until `use_last` toggles again. This saves us from sending multiple unnecessary requests to the API if I change `last` multiple times while `use_last` is still `false`.
## To `create_effect`, or not to `create_effect`?
Effects are intended to run _side-effects_ of the system, not to synchronize state _within_ the system. In other words: dont write to signals within effects.
If you need to define a signal that depends on the value of other signals, use a derived signal or [`create_memo`](https://docs.rs/leptos_reactive/latest/leptos_reactive/fn.create_memo.html).
If you need to synchronize some reactive value with the non-reactive world outside—like a web API, the console, the filesystem, or the DOM—create an effect.
> If youre curious for more information about when you should and shouldnt use `create_effect`, [check out this video](https://www.youtube.com/watch?v=aQOFJQ2JkvQ) for a more in-depth consideration!
## Effects and Rendering
Weve managed to get this far without mentioning effects because theyre built into the Leptos DOM renderer. Weve seen that you can create a signal and pass it into the `view` macro, and it will update the relevant DOM node whenever the signal changes:
```rust
let (count, set_count) = create_signal(cx, 0);
view! { cx,
<p>{count}</p>
}
```
This works because the framework essentially creates an effect wrapping this update. You can imagine Leptos translating this view into something like this:
```rust
let (count, set_count) = create_signal(cx, 0);
// create a DOM element
let p = create_element("p");
// create an effect to reactively update the text
create_effect(cx, move |prev_value| {
// first, access the signals value and convert it to a string
let text = count().to_string();
// if this is different from the previous value, update the node
if prev_value != Some(text) {
p.set_text_content(&text);
}
// return this value so we can memoize the next update
text
});
```
Every time `count` is updated, this effect wil rerun. This is what allows reactive, fine-grained updates to the DOM.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/serene-thompson-40974n?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A2%7D%5D)
<iframe src="https://codesandbox.io/p/sandbox/serene-thompson-40974n?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A2%7D%5D" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/14_create_effect.html">
<link rel="canonical" href="https://book.leptos.dev/reactivity/14_create_effect.html">

View File

@@ -1,5 +1,2 @@
# Reactivity
Leptos is built on top of a fine-grained reactive system, designed to run expensive side effects (like rendering something in a browser, or making a network request) as infrequently as possible in response to change, reactive values.
So far weve seen signals in action. These chapters will go into a bit more depth, and look at effects, which are the other half of the story.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/index.html">
<link rel="canonical" href="https://book.leptos.dev/reactivity/index.html">

View File

@@ -1,76 +1,2 @@
# Interlude: Reactivity and Functions
One of our core contributors said to me recently: “I never used closures this often
until I started using Leptos.” And its true. Closures are at the heart of any Leptos
application. It sometimes looks a little silly:
```rust
// a signal holds a value, and can be updated
let (count, set_count) = create_signal(cx, 0);
// a derived signal is a function that accesses other signals
let double_count = move || count() * 2;
let count_is_odd = move || count() & 1 == 1;
let text = move || if count_is_odd() {
"odd"
} else {
"even"
};
// an effect automatically tracks the signals it depends on
// and reruns when they change
create_effect(cx, move |_| {
log!("text = {}", text());
});
view! { cx,
<p>{move || text().to_uppercase()}</p>
}
```
Closures, closures everywhere!
But why?
## Functions and UI Frameworks
Functions are at the heart of every UI framework. And this makes perfect sense. Creating a user interface is basically divided into two phases:
1. initial rendering
2. updates
In a web framework, the framework does some kind of initial rendering. Then it hands control back over to the browser. When certain events fire (like a mouse click) or asynchronous tasks finish (like an HTTP request finishing), the browser wakes the framework back up to update something. The framework runs some kind of code to update your user interface, and goes back asleep until the browser wakes it up again.
The key phrase here is “runs some kind of code.” The natural way to “run some kind of code” at an arbitrary point in time—in Rust or in any other programming language—is to call a function. And in fact every UI framework is based on rerunning some kind of function over and over:
1. virtual DOM (VDOM) frameworks like React, Yew, or Dioxus rerun a component or render function over and over, to generate a virtual DOM tree that can be reconciled with the previous result to patch the DOM
2. compiled frameworks like Angular and Svelte divide your component templates into “create” and “update” functions, rerunning the update function when they detect a change to the components state
3. in fine-grained reactive frameworks like SolidJS, Sycamore, or Leptos, _you_ define the functions that rerun
Thats what all our components are doing.
Take our typical `<SimpleCounter/>` example in its simplest form:
```rust
#[component]
pub fn SimpleCounter(cx: Scope) -> impl IntoView {
let (value, set_value) = create_signal(cx, 0);
let increment = move |_| set_value.update(|value| *value += 1);
view! { cx,
<button on:click=increment>
{value}
</button>
}
}
```
The `SimpleCounter` function itself runs once. The `value` signal is created once. The framework hands off the `increment` function to the browser as an event listener. When you click the button, the browser calls `increment`, which updates `value` via `set_value`. And that updates the single text node represented in our view by `{value}`.
Closures are key to reactivity. They provide the framework with the ability to rerun the smallest possible unit of your application in responsive to a change.
So remember two things:
1. Your component function is a setup function, not a render function: it only runs once.
2. For values in your view template to be reactive, they must be functions: either signals (which implement the `Fn` traits) or closures.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/interlude_functions.html">
<link rel="canonical" href="https://book.leptos.dev/reactivity/interlude_functions.html">

View File

@@ -1,106 +1,2 @@
# Working with Signals
So far weve used some simple examples of [`create_signal`](https://docs.rs/leptos/latest/leptos/fn.create_signal.html), which returns a [`ReadSignal`](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html) getter and a [`WriteSignal`](https://docs.rs/leptos/latest/leptos/struct.WriteSignal.html) setter.
## Getting and Setting
There are four basic signal operations:
1. [`.get()`](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html#impl-SignalGet%3CT%3E-for-ReadSignal%3CT%3E) clones the current value of the signal and tracks any future changes to the value reactively.
2. [`.with()`](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html#impl-SignalWith%3CT%3E-for-ReadSignal%3CT%3E) takes a function, which receives the current value of the signal by reference (`&T`), and tracks any future changes.
3. [`.set()`](https://docs.rs/leptos/latest/leptos/struct.WriteSignal.html#impl-SignalSet%3CT%3E-for-WriteSignal%3CT%3E) replaces the current value of the signal and notifies any subscribers that they need to update.
4. [`.update()`](https://docs.rs/leptos/latest/leptos/struct.WriteSignal.html#impl-SignalUpdate%3CT%3E-for-WriteSignal%3CT%3E) takes a function, which receives a mutable reference to the current value of the signal (`&mut T`), and notifies any subscribers that they need to update. (`.update()` doesnt return the value returned by the closure, but you can use [`.try_update()`](https://docs.rs/leptos/latest/leptos/trait.SignalUpdate.html#tymethod.try_update) if you need to; for example, if youre removing an item from a `Vec<_>` and want the removed item.)
Calling a `ReadSignal` as a function is syntax sugar for `.get()`. Calling a `WriteSignal` as a function is syntax sugar for `.set()`. So
```rust
let (count, set_count) = create_signal(cx, 0);
set_count(1);
log!(count());
```
is the same as
```rust
let (count, set_count) = create_signal(cx, 0);
set_count.set(1);
log!(count.get());
```
You might notice that `.get()` and `.set()` can be implemented in terms of `.with()` and `.update()`. In other words, `count.get()` is identical with `count.with(|n| n.clone())`, and `count.set(1)` is implemented by doing `count.update(|n| *n = 1)`.
But of course, `.get()` and `.set()` (or the plain function-call forms!) are much nicer syntax.
However, there are some very good use cases for `.with()` and `.update()`.
For example, consider a signal that holds a `Vec<String>`.
```rust
let (names, set_names) = create_signal(cx, Vec::new());
if names().is_empty() {
set_names(vec!["Alice".to_string()]);
}
```
In terms of logic, this is simple enough, but its hiding some significant inefficiencies. Remember that `names().is_empty()` is sugar for `names.get().is_empty()`, which clones the value (its `names.with(|n| n.clone()).is_empty()`). This means we clone the whole `Vec<String>`, run `is_empty()`, and then immediately throw away the clone.
Likewise, `set_names` replaces the value with a whole new `Vec<_>`. This is fine, but we might as well just mutate the original `Vec<_>` in place.
```rust
let (names, set_names) = create_signal(cx, Vec::new());
if names.with(|names| names.is_empty()) {
set_names.update(|names| names.push("Alice".to_string()));
}
```
Now our function simply takes `names` by reference to run `is_empty()`, avoiding that clone.
And if you have Clippy on, or if you have sharp eyes, you may notice we can make this even neater:
```rust
if names.with(Vec::is_empty) {
// ...
}
```
After all, `.with()` simply takes a function that takes the value by reference. Since `Vec::is_empty` takes `&self`, we can pass it in directly and avoid the unncessary closure.
## Making signals depend on each other
Often people ask about situations in which some signal needs to change based on some other signals value. There are three good ways to do this, and one thats less than ideal but okay under controlled circumstances.
### Good Options
**1) B is a function of A.** Create a signal for A and a derived signal or memo for B.
```rust
let (count, set_count) = create_signal(cx, 1);
let derived_signal_double_count = move || count() * 2;
let memoized_double_count = create_memo(cx, move |_| count() * 2);
```
> For guidance on whether to use a derived signal or a memo, see the docs for [`create_memo`](https://docs.rs/leptos/latest/leptos/fn.create_memo.html)
>
**2) C is a function of A and some other thing B.** Create signals for A and B and a derived signal or memo for C.
```rust
let (first_name, set_first_name) = create_signal(cx, "Bridget".to_string());
let (last_name, set_last_name) = create_signal(cx, "Jones".to_string());
let full_name = move || format!("{} {}", first_name(), last_name());
```
**3) A and B are independent signals, but sometimes updated at the same time.** When you make the call to update A, make a separate call to update B.
```rust
let (age, set_age) = create_signal(cx, 32);
let (favorite_number, set_favorite_number) = create_signal(cx, 42);
// use this to handle a click on a `Clear` button
let clear_handler = move |_| {
set_age(0);
set_favorite_number(0);
};
```
### If you really must...
**4) Create an effect to write to B whenever A changes.** This is officially discouraged, for several reasons:
a) It will always be less efficient, as it means every time A updates you do two full trips through the reactive process. (You set A, which causes the effect to run, as well as any other effects that depend on A. Then you set B, which causes any effects that depend on B to run.)
b) It increases your chances of accidentally creating things like infinite loops or over-re-running effects. This is the kind of ping-ponging, reactive spaghetti code that was common in the early 2010s and that we try to avoid with things like read-write segregation and discouraging writing to signals from effects.
In most situations, its best to rewrite things such that theres a clear, top-down data flow based on derived signals or memos. But this isnt the end of the world.
> Im intentionally not providing an example here. Read the [`create_effect`](https://docs.rs/leptos/latest/leptos/fn.create_effect.html) docs to figure out how this would work.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/working_with_signals.html">
<link rel="canonical" href="https://book.leptos.dev/reactivity/working_with_signals.html">

View File

@@ -1,101 +1,2 @@
# Defining Routes
## Getting Started
Its easy to get started with the router.
First things first, make sure youve added the `leptos_router` package to your dependencies.
> Its important that the router is a separate package from `leptos` itself. This means that everything in the router can be defined in user-land code. If you want to create your own router, or use no router, youre completely free to do that!
And import the relevant types from the router, either with something like
```rust
use leptos_router::{Route, RouteProps, Router, RouterProps, Routes, RoutesProps};
```
or simply
```rust
use leptos_router::*;
```
## Providing the `<Router/>`
Routing behavior is provided by the [`<Router/>`](https://docs.rs/leptos_router/latest/leptos_router/fn.Router.html) component. This should usually be somewhere near the root of your application, the rest of the app.
> You shouldnt try to use multiple `<Router/>`s in your app. Remember that the router drives global state: if you have multiple routers, which ones decides what to do when the URL changes?
Lets start with a simple `<App/>` component using the router:
```rust
use leptos::*;
use leptos_router::*;
#[component]
pub fn App(cx: Scope) -> impl IntoView {
view! { cx,
<Router>
<nav>
/* ... */
</nav>
<main>
/* ... */
</main>
</Router>
}
}
```
## Defining `<Routes/>`
The [`<Routes/>`](https://docs.rs/leptos_router/latest/leptos_router/fn.Routes.html) component is where you define all the routes to which a user can navigate in your application. Each possible route is defined by a [`<Route/>`](https://docs.rs/leptos_router/latest/leptos_router/fn.Route.html) component.
You should place the `<Routes/>` component at the location within your app where you want routes to be rendered. Everything outside `<Routes/>` will be present on every page, so you can leave things like a navigation bar or menu outside the `<Routes/>`.
```rust
use leptos::*;
use leptos_router::*;
#[component]
pub fn App(cx: Scope) -> impl IntoView {
view! { cx,
<Router>
<nav>
/* ... */
</nav>
<main>
// all our routes will appear inside <main>
<Routes>
/* ... */
</Routes>
</main>
</Router>
}
}
```
Individual routes are defined by providing children to `<Routes/>` with the `<Route/>` component. `<Route/>` takes a `path` and a `view`. When the current location matches `path`, the `view` will be created and displayed.
The `path` can include
- a static path (`/users`),
- dynamic, named parameters beginning with a colon (`/:id`),
- and/or a wildcard beginning with an asterisk (`/user/*any`)
The `view` is a function that takes a `Scope` and returns a view.
```rust
<Routes>
<Route path="/" view=|cx| view! { cx, <Home/> }/>
<Route path="/users" view=|cx| view! { cx, <Users/> }/>
<Route path="/users/:id" view=|cx| view! { cx, <UserProfile/> }/>
<Route path="/*any" view=|cx| view! { cx, <NotFound/> }/>
</Routes>
```
> The router scores each route to see how good a match it is, so you can define your routes in any order.
Now if you navigate to `/` or to `/users` youll get the home page or the `<Users/>`. If you go to `/users/3` or `/blahblah` youll get a user profile or your 404 page (`<NotFound/>`). On every navigation, the router determines which `<Route/>` should be matched, and therefore what content should be displayed where the `<Routes/>` component is defined.
Simple enough?
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/16_routes.html">
<link rel="canonical" href="https://book.leptos.dev/router/16_routes.html">

View File

@@ -1,172 +1,2 @@
# Nested Routing
We just defined the following set of routes:
```rust
<Routes>
<Route path="/" view=|cx| view! { cx, <Home /> }/>
<Route path="/users" view=|cx| view! { cx, <Users /> }/>
<Route path="/users/:id" view=|cx| view! { cx, <UserProfile /> }/>
<Route path="/*any" view=|cx| view! { cx, <NotFound /> }/>
</Routes>
```
Theres a certain amount of duplication here: `/users` and `/users/:id`. This is fine for a small app, but you can probably already tell it wont scale well. Wouldnt it be nice if we could nest these routes?
Well... you can!
```rust
<Routes>
<Route path="/" view=|cx| view! { cx, <Home /> }/>
<Route path="/users" view=|cx| view! { cx, <Users /> }>
<Route path=":id" view=|cx| view! { cx, <UserProfile /> }/>
</Route>
<Route path="/*any" view=|cx| view! { cx, <NotFound /> }/>
</Routes>
```
But wait. Weve just subtly changed what our application does.
The next section is one of the most important in this entire routing section of the guide. Read it carefully, and feel free to ask questions if theres anything you dont understand.
# Nested Routes as Layout
Nested routes are a form of layout, not a method of route definition.
Let me put that another way: The goal of defining nested routes is not primarily to avoid repeating yourself when typing out the paths in your route definitions. It is actually to tell the router to display multiple `<Route/>`s on the page at the same time, side by side.
Lets look back at our practical example.
```rust
<Routes>
<Route path="/users" view=|cx| view! { cx, <Users /> }/>
<Route path="/users/:id" view=|cx| view! { cx, <UserProfile /> }/>
</Routes>
```
This means:
- If I go to `/users`, I get the `<Users/>` component.
- If I go to `/users/3`, I get the `<UserProfile/>` component (with the parameter `id` set to `3`; more on that later)
Lets say I use nested routes instead:
```rust
<Routes>
<Route path="/users" view=|cx| view! { cx, <Users /> }>
<Route path=":id" view=|cx| view! { cx, <UserProfile /> }/>
</Route>
</Routes>
```
This means:
- If I go to `/users/3`, the path matches two `<Route/>`s: `<Users/>` and `<UserProfile/>`.
- If I go to `/users`, the path is not matched.
I actually need to add a fallback route
```rust
<Routes>
<Route path="/users" view=|cx| view! { cx, <Users /> }>
<Route path=":id" view=|cx| view! { cx, <UserProfile /> }/>
<Route path="" view=|cx| view! { cx, <NoUser /> }/>
</Route>
</Routes>
```
Now:
- If I go to `/users/3`, the path matches `<Users/>` and `<UserProfile/>`.
- If I go to `/users`, the path matches `<Users/>` and `<NoUser/>`.
When I use nested routes, in other words, each **path** can match multiple **routes**: each URL can render the views provided by multiple `<Route/>` components, at the same time, on the same page.
This may be counter-intuitive, but its very powerful, for reasons youll hopefully see in a few minutes.
## Why Nested Routing?
Why bother with this?
Most web applications contain levels of navigation that correspond to different parts of the layout. For example, in an email app you might have a URL like `/contacts/greg`, which shows a list of contacts on the left of the screen, and contact details for Greg on the right of the screen. The contact list and the contact details should always appear on the screen at the same time. If theres no contact selected, maybe you want to show a little instructional text.
You can easily define this with nested routes
```rust
<Routes>
<Route path="/contacts" view=|cx| view! { cx, <ContactList/> }>
<Route path=":id" view=|cx| view! { cx, <ContactInfo/> }/>
<Route path="" view=|cx| view! { cx,
<p>"Select a contact to view more info."</p>
}/>
</Route>
</Routes>
```
You can go even deeper. Say you want to have tabs for each contacts address, email/phone, and your conversations with them. You can add _another_ set of nested routes inside `:id`:
```rust
<Routes>
<Route path="/contacts" view=|cx| view! { cx, <ContactList/> }>
<Route path=":id" view=|cx| view! { cx, <ContactInfo/> }>
<Route path="" view=|cx| view! { cx, <EmailAndPhone/> }/>
<Route path="address" view=|cx| view! { cx, <Address/> }/>
<Route path="messages" view=|cx| view! { cx, <Messages/> }/>
</Route>
<Route path="" view=|cx| view! { cx,
<p>"Select a contact to view more info."</p>
}/>
</Route>
</Routes>
```
> The main page of the [Remix website](https://remix.run/), a React framework from the creators of React Router, has a great visual example if you scroll down, with three levels of nested routing: Sales > Invoices > an invoice.
## `<Outlet/>`
Parent routes do not automatically render their nested routes. After all, they are just components; they dont know exactly where they should render their children, and “just stick it at the end of the parent component” is not a great answer.
Instead, you tell a parent component where to render any nested components with an `<Outlet/>` component. The `<Outlet/>` simply renders one of two things:
- if there is no nested route that has been matched, it shows nothing
- if there is a nested route that has been matched, it shows its `view`
Thats all! But its important to know and to remember, because its a common source of “Why isnt this working?” frustration. If you dont provide an `<Outlet/>`, the nested route wont be displayed.
```rust
#[component]
pub fn ContactList(cx: Scope) -> impl IntoView {
let contacts = todo!();
view! { cx,
<div style="display: flex">
// the contact list
<For each=contacts
key=|contact| contact.id
view=|cx, contact| todo!()
>
// the nested child, if any
// dont forget this!
<Outlet/>
</div>
}
}
```
## Nested Routing and Performance
All of this is nice, conceptually, but again—whats the big deal?
Performance.
In a fine-grained reactive library like Leptos, its always important to do the least amount of rendering work you can. Because were working with real DOM nodes and not diffing a virtual DOM, we want to “rerender” components as infrequently as possible. Nested routing makes this extremely easy.
Imagine my contact list example. If I navigate from Greg to Alice to Bob and back to Greg, the contact information needs to change on each navigation. But the `<ContactList/>` should never be rerendered. Not only does this save on rendering performance, it also maintains state in the UI. For example, if I have a search bar at the top of `<ContactList/>`, navigating from Greg to Alice to Bob wont clear the search.
In fact, in this case, we dont even need to rerender the `<Contact/>` component when moving between contacts. The router will just reactively update the `:id` parameter as we navigate, allowing us to make fine-grained updates. As we navigate between contacts, well update single text nodes to change the contacts name, address, and so on, without doing _any_ additional rerendering.
> This sandbox includes a couple features (like nested routing) discussed in this section and the previous one, and a couple well cover in the rest of this chapter. The router is such an integrated system that it makes sense to provide a single example, so dont be surprised if theres anything you dont understand.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D)
<iframe src="https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/17_nested_routing.html">
<link rel="canonical" href="https://book.leptos.dev/router/17_nested_routing.html">

View File

@@ -1,79 +1,2 @@
# Params and Queries
Static paths are useful for distinguishing between different pages, but almost every application wants to pass data through the URL at some point.
There are two ways you can do this:
1. named route **params** like `id` in `/users/:id`
2. named route **queries** like `q` in `/search?q=Foo`
Because of the way URLs are built, you can access the query from _any_ `<Route/>` view. You can access route params from the `<Route/>` that defines them or any of its nested children.
Accessing params and queries is pretty simple with a couple of hooks:
- [`use_query`](https://docs.rs/leptos_router/latest/leptos_router/fn.use_query.html) or [`use_query_map`](https://docs.rs/leptos_router/latest/leptos_router/fn.use_query_map.html)
- [`use_params`](https://docs.rs/leptos_router/latest/leptos_router/fn.use_params.html) or [`use_params_map`](https://docs.rs/leptos_router/latest/leptos_router/fn.use_query_map.html)
Each of these comes with a typed option (`use_query` and `use_params`) and an untyped option (`use_query_map` and `use_params_map`).
The untyped versions hold a simple key-value map. To use the typed versions, derive the [`Params`](https://docs.rs/leptos_router/0.2.3/leptos_router/trait.Params.html) trait on a struct.
> `Params` is a very lightweight trait to convert a flat key-value map of strings into a struct by applying `FromStr` to each field. Because of the flat structure of route params and URL queries, its significantly less flexible than something like `serde`; it also adds much less weight to your binary.
```rust
use leptos::*;
use leptos_router::*;
#[derive(Params)]
struct ContactParams {
id: usize
}
#[derive(Params)]
struct ContactSearch {
q: String
}
```
> Note: The `Params` derive macro is located at `leptos::Params`, and the `Params` trait is at `leptos_router::Params`. If you avoid using glob imports like `use leptos::*;`, make sure youre importing the right one for the derive macro.
Now we can use them in a component. Imagine a URL that has both params and a query, like `/contacts/:id?q=Search`.
The typed versions return `Memo<Result<T, _>>`. Its a Memo so it reacts to changes in the URL. Its a `Result` because the params or query need to be parsed from the URL, and may or may not be valid.
```rust
let params = use_params::<ContactParams>(cx);
let query = use_query::<ContactSearch>(cx);
// id: || -> usize
let id = move || {
params.with(|params| {
params
.map(|params| params.id)
.unwrap_or_default()
})
};
```
The untyped versions return `Memo<ParamsMap>`. Again, its memo to react to changes in the URL. [`ParamsMap`](https://docs.rs/leptos_router/0.2.3/leptos_router/struct.ParamsMap.html) behaves a lot like any other map type, with a `.get()` method that returns `Option<&String>`.
```rust
let params = use_params_map(cx);
let query = use_query_map(cx);
// id: || -> Option<String>
let id = move || {
params.with(|params| params.get("id").cloned())
};
```
This can get a little messy: deriving a signal that wraps an `Option<_>` or `Result<_>` can involve a couple steps. But its worth doing this for two reasons:
1. Its correct, i.e., it forces you to consider the cases, “What if the user doesnt pass a value for this query field? What if they pass an invalid value?”
2. Its performant. Specifically, when you navigate between different paths that match the same `<Route/>` with only params or the query changing, you can get fine-grained updates to different parts of your app without rerendering. For example, navigating between different contacts in our contact-list example does a targeted update to the name field (and eventually contact info) without needing to replace or rerender the wrapping `<Contact/>`. This is what fine-grained reactivity is for.
> This is the same example from the previous section. The router is such an integrated system that it makes sense to provide a single example highlighting multiple features, even if we havent explained them all yet.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D)
<iframe src="https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/18_params_and_queries.html">
<link rel="canonical" href="https://book.leptos.dev/router/18_params_and_queries.html">

View File

@@ -1,23 +1,2 @@
# The `<A/>` Component
Client-side navigation works perfectly fine with ordinary HTML `<a>` elements. The router adds a listener that handles every click on a `<a>` element and tries to handle it on the client side, i.e., without doing another round trip to the server to request HTML. This is what enables the snappy “single-page app” navigations youre probably familiar with from most modern web apps.
The router will bail out of handling an `<a>` click under a number of situations
- the click event has had `prevent_default()` called on it
- the <kbd>Meta</kbd>, <kbd>Alt</kbd>, <kbd>Ctrl</kbd>, or <kbd>Shift</kbd> keys were held during click
- the `<a>` has a `target` or `download` attribute, or `rel="external"`
- the link has a different origin from the current location
In other words, the router will only try to do a client-side navigation when its pretty sure it can handle it, and it will upgrade every `<a>` element to get this special behavior.
The router also provides an [`<A>`](https://docs.rs/leptos_router/latest/leptos_router/fn.A.html) component, which does two additional things:
1. Correctly resolves relative nested routes. Relative routing with ordinary `<a>` tags can be tricky. For example, if you have a route like `/post/:id`, `<A href="1">` will generate the correct relative route, but `<a href="1">` likely will not (depending on where it appears in your view.) `<A/>` resolves routes relative to the path of the nested route within which it appears.
2. Sets the `aria-current` attribute to `page` if this link is the active link (i.e., its a link to the page youre on). This is helpful for accessibility and for styling. For example, if you want to set the link a different color if its a link to the page youre currently on, you can match this attribute with a CSS selector.
> Once again, this is the same example. Check out the relative `<A/>` components, and take a look at the CSS in `index.html` to see the ARIA-based styling.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D)
<iframe src="https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/19_a.html">
<link rel="canonical" href="https://book.leptos.dev/router/19_a.html">

View File

@@ -1,67 +1,2 @@
# The `<Form/>` Component
Links and forms sometimes seem completely unrelated. But, in fact, they work in very similar ways.
In plain HTML, there are three ways to navigate to another page:
1. An `<a>` element that links to another page: Navigates to the URL in its `href` attribute with the `GET` HTTP method.
2. A `<form method="GET">`: Navigates to the URL in its `action` attribute with the `GET` HTTP method and the form data from its inputs encoded in the URL query string.
3. A `<form method="POST">`: Navigates to the URL in its `action` attribute with the `POST` HTTP method and the form data from its inputs encoded in the body of the request.
Since we have a client-side router, we can do client-side link navigations without reloading the page, i.e., without a full round-trip to the server and back. It makes sense that we can do client-side form navigations in the same way.
The router provides a [`<Form>`](https://docs.rs/leptos_router/latest/leptos_router/fn.Form.html) component, which works like the HTML `<form>` element, but uses client-side navigations instead of full page reloads. `<Form/>` works with both `GET` and `POST` requests. With `method="GET"`, it will navigate to the URL encoded in the form data. With `method="POST"` it will make a `POST` request and handle the servers response.
`<Form/>` provides the basis for some components like `<ActionForm/>` and `<MultiActionForm/>` that well see in later chapters. But it also enables some powerful patterns of its own.
For example, imagine that you want to create a search field that updates search results in real time as the user searches, without a page reload, but that also stores the search in the URL so a user can copy and paste it to share results with someone else.
It turns out that the patterns weve learned so far make this easy to implement.
```rust
async fn fetch_results() {
// some async function to fetch our search results
}
#[component]
pub fn FormExample(cx: Scope) -> impl IntoView {
// reactive access to URL query strings
let query = use_query_map(cx);
// search stored as ?q=
let search = move || query().get("q").cloned().unwrap_or_default();
// a resource driven by the search string
let search_results = create_resource(cx, search, fetch_results);
view! { cx,
<Form method="GET" action="">
<input type="search" name="search" value=search/>
<input type="submit"/>
</Form>
<Transition fallback=move || ()>
/* render search results */
</Transition>
}
}
```
Whenever you click `Submit`, the `<Form/>` will “navigate” to `?q={search}`. But because this navigation is done on the client side, theres no page flicker or reload. The URL query string changes, which triggers `search` to update. Because `search` is the source signal for the `search_results` resource, this triggers `search_results` to reload its resource. The `<Transition/>` continues displaying the current search results until the new ones have loaded. When they are complete, it switches to displaying the new result.
This is a great pattern. The data flow is extremely clear: all data flows from the URL to the resource into the UI. The current state of the application is stored in the URL, which means you can refresh the page or text the link to a friend and it will show exactly what youre expecting. And once we introduce server rendering, this pattern will prove to be really fault-tolerant, too: because it uses a `<form>` element and URLs under the hood, it actually works really well without even loading your WASM on the client.
We can actually take it a step further and do something kind of clever:
```rust
view! { cx,
<Form method="GET" action="">
<input type="search" name="search" value=search
oninput="this.form.requestSubmit()"
/>
</Form>
}
```
Youll notice that this version drops the `Submit` button. Instead, we add an `oninput` attribute to the input. Note that this is _not_ `on:input`, which would listen for the `input` event and run some Rust code. Without the colon, `oninput` is the plain HTML attribute. So the string is actually a JavaScript string. `this.form` gives us the form the input is attached to. `requestSubmit()` fires the `submit` event on the `<form>`, which is caught by `<Form/>` just as if we had clicked a `Submit` button. Now the form will “navigate” on every keystroke or input to keep the URL (and therefore the search) perfectly in sync with the users input as they type.
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/16-router-forked-hrrt3h?file=%2Fsrc%2Fmain.rs)
<iframe src="https://codesandbox.io/p/sandbox/16-router-forked-hrrt3h?file=%2Fsrc%2Fmain.rs" width="100%" height="1000px" style="max-height: 100vh"></iframe>
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/20_form.html">
<link rel="canonical" href="https://book.leptos.dev/router/20_form.html">

View File

@@ -1,23 +1,2 @@
# Routing
## The Basics
Routing drives most websites. A router is the answer to the question, “Given this URL, what should appear on the page?”
A URL consists of many parts. For example, the URL `https://my-cool-blog.com/blog/search?q=Search#results` consists of
- a _scheme_: `https`
- a _domain_: `my-cool-blog.com`
- a **path**: `/blog/search`
- a **query** (or **search**): `?q=Search`
- a _hash_: `#results`
The Leptos Router works with the path and query (`/blog/search?q=Search`). Given this piece of the URL, what should the app render on the page?
## The Philosophy
In most cases, the path should drive what is displayed on the page. From the users perspective, for most applications, most major changes in the state of the app should be reflected in the URL. If you copy and paste the URL and open it in another tab, you should find yourself more or less in the same place.
In this sense, the router is really at the heart of the global state management for your application. More than anything else, it drives what is displayed on the page.
The router handles most of this work for you by mapping the current location to particular components.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/index.html">
<link rel="canonical" href="https://book.leptos.dev/router/index.html">

View File

@@ -1,124 +1,2 @@
# Server Functions
If youre creating anything beyond a toy app, youll need to run code on the server all the time: reading from or writing to a database that only runs on the server, running expensive computations using libraries you dont want to ship down to the client, accessing APIs that need to be called from the server rather than the client for CORS reasons or because you need a secret API key thats stored on the server and definitely shouldnt be shipped down to a users browser.
Traditionally, this is done by separating your server and client code, and by setting up something like a REST API or GraphQL API to allow your client to fetch and mutate data on the server. This is fine, but it requires you to write and maintain your code in multiple separate places (client-side code for fetching, server-side functions to run), as well as creating a third thing to manage, which is the API contract between the two.
Leptos is one of a number of modern frameworks that introduce the concept of **server functions**. Server functions have two key characteristics:
1. Server functions are **co-located** with your component code, so that you can organize your work by feature, not by technology. For example, you might have a “dark mode” feature that should persist a users dark/light mode preference across sessions, and be applied during server rendering so theres no flicker. This requires a component that needs to be interactive on the client, and some work to be done on the server (setting a cookie, maybe even storing a user in a database.) Traditionally, this feature might end up being split between two different locations in your code, one in your “frontend” and one in your “backend.” With server functions, youll probably just write them both in one `dark_mode.rs` and forget about it.
2. Server functions are **isomorphic**, i.e., they can be called either from the server or the browser. This is done by generating code differently for the two platforms. On the server, a server function simply runs. In the browser, the server functions body is replaced with a stub that actually makes a fetch request to the server, serializing the arguments into the request and deserializing the return value from the response. But on either end, the function can simply be called: you can create an `add_todo` function that writes to your database, and simply call it from a click handler on a button in the browser!
## Using Server Functions
Actually, I kind of like that example. What would it look like? Its pretty simple, actually.
```rust
// todo.rs
#[server(AddTodo, "/api")]
pub async fn add_todo(title: String) -> Result<(), ServerFnError> {
let mut conn = db().await?;
match sqlx::query("INSERT INTO todos (title, completed) VALUES ($1, false)")
.bind(title)
.execute(&mut conn)
.await
{
Ok(_row) => Ok(()),
Err(e) => Err(ServerFnError::ServerError(e.to_string())),
}
}
#[component]
pub fn BusyButton(cx: Scope) -> impl IntoView {
view! {
cx,
<button on:click=move |_| {
spawn_local(async {
add_todo("So much to do!".to_string()).await;
});
}>
"Add Todo"
</button>
}
}
```
Youll notice a couple things here right away:
- Server functions can use server-only dependencies, like `sqlx`, and can access server-only resources, like our database.
- Server functions are `async`. Even if they only did synchronous work on the server, the function signature would still need to be `async`, because calling them from the browser _must_ be asynchronous.
- Server functions return `Result<T, ServerFnError>`. Again, even if they only do infallible work on the server, this is true, because `ServerFnError`s variants include the various things that can be wrong during the process of making a network request.
- Server functions can be called from the client. Take a look at our click handler. This is code that will _only ever_ run on the client. But it can call the function `add_todo` (using `spawn_local` to run the `Future`) as if it were an ordinary async function:
```rust
move |_| {
spawn_local(async {
add_todo("So much to do!".to_string()).await;
});
}
```
- Server functions are top-level functions defined with `fn`. Unlike event listeners, derived signals, and most everything else in Leptos, they are not closures! As `fn` calls, they have no access to the reactive state of your app or anything else that is not passed in as an argument. And again, this makes perfect sense: When you make a request to the server, the server doesnt have access to client state unless you send it explicitly. (Otherwise wed have to serialize the whole reactive system and send it across the wire with every request, which—while it served classic ASP for a while—is a really bad idea.)
- Server function arguments and return values both need to be serializable with `serde`. Again, hopefully this makes sense: while function arguments in general dont need to be serialized, calling a server function from the browser means serializing the arguments and sending them over HTTP.
There are a few things to note about the way you define a server function, too.
- Server functions are created by using the [`#[server]` macro](https://docs.rs/leptos_server/latest/leptos_server/index.html#server) to annotate a top-level function, which can be defined anywhere.
- We provide the macro a type name. The type name is used internally as a container to hold, serialize, and deserialize the arguments.
- We provide the macro a path. This is a prefix for the path at which well mount a server function handler on our server. (See examples for [Actix](https://github.com/leptos-rs/leptos/blob/main/examples/todo_app_sqlite/src/main.rs#L44) and [Axum](https://github.com/leptos-rs/leptos/blob/598523cd9d0d775b017cb721e41ebae9349f01e2/examples/todo_app_sqlite_axum/src/main.rs#L51).)
- Youll need to have `serde` as a dependency with the `derive` featured enabled for the macro to work properly. You can easily add it to `Cargo.toml` with `cargo add serde --features=derive`.
## Server Function Encodings
By default, the server function call is a `POST` request that serializes the arguments as URL-encoded form data in the body of the request. (This means that server functions can be called from HTML forms, which well see in a future chapter.) But there are a few other methods supported. Optionally, we can provide another argument to the `#[server]` macro to specify an alternate encoding:
```rust
#[server(AddTodo, "/api", "Url")]
#[server(AddTodo, "/api", "GetJson")]
#[server(AddTodo, "/api", "Cbor")]
#[server(AddTodo, "/api", "GetCbor")]
```
The four options use different combinations of HTTP verbs and encoding methods:
| Name | Method | Request | Response |
| ----------------- | ------ | ----------- | -------- |
| **Url** (default) | POST | URL encoded | JSON |
| **GetJson** | GET | URL encoded | JSON |
| **Cbor** | POST | CBOR | CBOR |
| **GetCbor** | GET | URL encoded | CBOR |
In other words, you have two choices:
- `GET` or `POST`? This has implications for things like browser or CDN caching; while `POST` requests should not be cached, `GET` requests can be.
- Plain text (arguments sent with URL/form encoding, results sent as JSON) or a binary format (CBOR, encoded as a base64 string)?
**But remember**: Leptos will handle all the details of this encoding and decoding for you. When you use a server function, it looks just like calling any other asynchronous function!
> **Why not `PUT` or `DELETE`? Why URL/form encoding, and not JSON?**
>
> These are reasonable questions. Much of the web is built on REST API patterns that encourage the use of semantic HTTP methods like `DELETE` to delete an item from a database, and many devs are accustomed to sending data to APIs in the JSON format.
>
> The reason we use `POST` or `GET` with URL-encoded data by default is the `<form>` support. For better or for worse, HTML forms dont support `PUT` or `DELETE`, and they dont support sending JSON. This means that if you use anything but a `GET` or `POST` request with URL-encoded data, it can only work once WASM has loaded. As well see [in a later chapter](../progressive_enhancement), this isnt always a great idea.
>
> The CBOR encoding is suported for historical reasons; an earlier version of server functions used a URL encoding that didnt support nested objects like structs or vectors as server function arguments, which CBOR did. But note that the CBOR forms encounter the same issue as `PUT`, `DELETE`, or JSON: they do not degrade gracefully if the WASM version of your app is not available.
## An Important Note on Security
Server functions are a cool technology, but its very important to remember. **Server functions are not magic; theyre syntax sugar for defining a public API.** The _body_ of a server function is never made public; its just part of your server binary. But the server function is a publicly accessible API endpoint, and its return value is just a JSON or similar blob. You should _never_ return something sensitive from a server function.
## Integrating Server Functions with Leptos
So far, everything Ive said is actually framework agnostic. (And in fact, the Leptos server function crate has been integrated into Dioxus as well!) Server functions are simply a way of defining a function-like RPC call that leans on Web standards like HTTP requests and URL encoding.
But in a way, they also provide the last missing primitive in our story so far. Because a server function is just a plain Rust async function, it integrates perfectly with the async Leptos primitives we discussed [earlier](../async/README.md). So you can easily integrate your server functions with the rest of your applications:
- Create **resources** that call the server function to load data from the server
- Read these resources under `<Suspense/>` or `<Transition/>` to enable streaming SSR and fallback states while data loads.
- Create **actions** that call the server function to mutate data on the server
The final section of this book will make this a little more concrete by introducing patterns that use progressively-enhanced HTML forms to run these server actions.
But in the next few chapters, well actually take a look at some of the details of what you might want to do with your server functions, including the best ways to integrate with the powerful extractors provided by the Actix and Axum server frameworks.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/25_server_functions.html">
<link rel="canonical" href="https://book.leptos.dev/server/25_server_functions.html">

View File

@@ -1,73 +1,2 @@
# Extractors
The server functions we looked at in the last chapter showed how to run code on the server, and integrate it with the user interface youre rendering in the browser. But they didnt show you much about how to actually use your server to its full potential.
## Server Frameworks
We call Leptos a “full-stack” framework, but “full-stack” is always a misnomer (after all, it never means everything from the browser to your power company.) For us, “full stack” means that your Leptos app can run in the browser, and can run on the server, and can integrate the two, drawing together the unique features available in each; as weve seen in the book so far, a button click on the browser can drive a database read on the server, both written in the same Rust module. But Leptos itself doesnt provide the server (or the database, or the operating system, or the firmware, or the electrical cables...)
Instead, Leptos provides integrations for the two most popular Rust web server frameworks, Actix Web ([`leptos_actix`](https://docs.rs/leptos_actix/latest/leptos_actix/)) and Axum ([`leptos_axum`](https://docs.rs/leptos_actix/latest/leptos_axum/)). Weve built integrations with each servers router so that you can simply plug your Leptos app into an existing server with `.leptos_routes()`, and easily handle server function calls.
> If havent seen our [Actix](https://github.com/leptos-rs/start) and [Axum](https://github.com/leptos-rs/start-axum) templates, nows a good time to check them out.
## Using Extractors
Both Actix and Axum handlers are built on the same powerful idea of **extractors**. Extractors “extract” typed data from an HTTP request, allowing you to access server-specific data easily.
Leptos provides `extract` helper functions to let you use these extractors directly in your server functions, with a convenient syntax very similar to handlers for each framework.
### Actix Extractors
The [`extract` function in `leptos_actix`](https://docs.rs/leptos_actix/latest/leptos_actix/fn.extract.html) takes a handler function as its argument. The handler follows similar rules to an Actix handler: it is an async function that receives arguments that will be extracted from the request and returns some value. The handler function receives that extracted data as its arguments, and can do further `async` work on them inside the body of the `async move` block. It returns whatever value you return back out into the server function.
```rust
#[server(ActixExtract, "/api")]
pub async fn actix_extract(cx: Scope) -> Result<String, ServerFnError> {
use leptos_actix::extract;
use actix_web::dev::ConnectionInfo;
use actix_web::web::{Data, Query};
extract(cx,
|search: Query<Search>, connection: ConnectionInfo| async move {
format!(
"search = {}\nconnection = {:?}",
search.q,
connection
)
},
)
.await
}
```
## Axum Extractors
The syntax for the `leptos_axum::extract` function is very similar. (**Note**: This is available on the git main branch, but has not been released as of writing.) Note that Axum extractors return a `Result`, so youll need to add something to handle the error case.
```rust
#[server(AxumExtract, "/api")]
pub async fn axum_extract(cx: Scope) -> Result<String, ServerFnError> {
use axum::{extract::Query, http::Method};
use leptos_axum::extract;
extract(cx, |method: Method, res: Query<MyQuery>| async move {
format!("{method:?} and {}", res.q)
},
)
.await
.map_err(|e| ServerFnError::ServerError("Could not extract method and query...".to_string()))
}
```
These are relatively simple examples accessing basic data from the server. But you can use extractors to access things like headers, cookies, database connection pools, and more, using the exact same `extract()` pattern.
> Note: For now, the Axum `extract` function only supports extractors for which the state is `()`, i.e., you can't yet use it to extract `State(_)`. You can access `State(_)` by using a custom handler that extracts the state and then provides it via context. [Click here for an example](https://github.com/leptos-rs/leptos/blob/a5f73b441c079f9138102b3a7d8d4828f045448c/examples/session_auth_axum/src/main.rs#L91-L92).
## A Note about Data-Loading Patterns
Because Actix and (especially) Axum are built on the idea of a single round-trip HTTP request and response, you typically run extractors near the “top” of your application (i.e., before you start rendering) and use the extracted data to determine how that should be rendered. Before you render a `<button>`, you load all the data your app could need. And any given route handler needs to know all the data that will need to be extracted by that route.
But Leptos integrates both the client and the server, and its important to be able to refresh small pieces of your UI with new data from the server without forcing a full reload of all the data. So Leptos likes to push data loading “down” in your application, as far towards the leaves of your user interface as possible. When you click a `<button>`, it can refresh just the data it needs. This is exactly what server functions are for: they give you granular access to data to be loaded and reloaded.
The `extract()` functions let you combine both models by using extractors in your server functions. You get access to the full power of route extractors, while decentralizing knowledge of what needs to be extracted down to your individual components. This makes it easier to refactor and reorganize routes: you dont need to specify all the data a route needs up front.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/26_extractors.html">
<link rel="canonical" href="https://book.leptos.dev/server/26_extractors.html">

View File

@@ -1,74 +1,2 @@
# Responses and Redirects
Extractors provide an easy way to access request data inside server functions. Leptos also provides a way to modify the HTTP response, using the `ResponseOptions` type (see docs for [Actix](https://docs.rs/leptos_actix/latest/leptos_actix/struct.ResponseOptions.html) or [Axum](https://docs.rs/leptos_axum/latest/leptos_axum/struct.ResponseOptions.html)) types and the `redirect` helper function (see docs for [Actix](https://docs.rs/leptos_actix/latest/leptos_actix/fn.redirect.html) or [Axum](https://docs.rs/leptos_axum/latest/leptos_axum/fn.redirect.html)).
## `ResponseOptions`
`ResponseOptions` is provided via context during the initial server rendering response and during any subsequent server function call. It allows you to easily set the status code for the HTTP response, or to add headers to the HTTP response, e.g., to set cookies.
```rust
#[server(TeaAndCookies)]
pub async fn tea_and_cookies(cx: Scope) -> Result<(), ServerFnError> {
use actix_web::{cookie::Cookie, http::header, http::header::HeaderValue};
use leptos_actix::ResponseOptions;
// pull ResponseOptions from context
let response = expect_context::<ResponseOptions>(cx);
// set the HTTP status code
response.set_status(StatusCode::IM_A_TEAPOT);
// set a cookie in the HTTP response
let mut cookie = Cookie::build("biscuits", "yes").finish();
if let Ok(cookie) = HeaderValue::from_str(&cookie.to_string()) {
res.insert_header(header::SET_COOKIE, cookie);
}
}
```
## `redirect`
One common modification to an HTTP response is to redirect to another page. The Actix and Axum integrations provide a `redirect` function to make this easy to do. `redirect` simply sets an HTTP status code of `302 Found` and sets the `Location` header.
Heres a simplified example from our [`session_auth_axum` example](https://github.com/leptos-rs/leptos/blob/a5f73b441c079f9138102b3a7d8d4828f045448c/examples/session_auth_axum/src/auth.rs#L154-L181).
```rust
#[server(Login, "/api")]
pub async fn login(
cx: Scope,
username: String,
password: String,
remember: Option<String>,
) -> Result<(), ServerFnError> {
// pull the DB pool and auth provider from context
let pool = pool(cx)?;
let auth = auth(cx)?;
// check whether the user exists
let user: User = User::get_from_username(username, &pool)
.await
.ok_or_else(|| {
ServerFnError::ServerError("User does not exist.".into())
})?;
// check whether the user has provided the correct password
match verify(password, &user.password)? {
// if the password is correct...
true => {
// log the user in
auth.login_user(user.id);
auth.remember_user(remember.is_some());
// and redirect to the home page
leptos_axum::redirect(cx, "/");
Ok(())
}
// if not, return an error
false => Err(ServerFnError::ServerError(
"Password does not match.".to_string(),
)),
}
}
```
This server function can then be used from your application. This `redirect` works well with the progressively-enhanced `<ActionForm/>` component: without JS/WASM, the server response will redirect because of the status code and header. With JS/WASM, the `<ActionForm/>` will detect the redirect in the server function response, and use client-side navigation to redirect to the new page.
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/27_response.html">
<link rel="canonical" href="https://book.leptos.dev/server/27_response.html">

Some files were not shown because too many files have changed in this diff Show More