From d77cf0196b65486a35b9d1a02aaaed6faafbf8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=8A=E6=AC=A7?= Date: Tue, 17 Dec 2024 16:27:02 +0800 Subject: [PATCH] Prepare for 0.22 release (#3750) * Update CHANGELOG https://github.com/yewstack/yew/actions/runs/11314974928/job/31465588862 * Add items. * Write blog. * Archive the documents. * Add author. * Update SSR document. * Fix typo. * Add simplified Chinese translation. * Update package.json * Sync documents * Add traditional Chinese translation. * Sync documents * Add Japanese translation. * Sync documents * Fix typo by `fmt:write`. * Fix typo by `write-translations`. * Apply suggestions from code review * Fix typo. * #3769 in changelog --------- Co-authored-by: Elina --- CHANGELOG.md | 53 ++ examples/wasi_ssr_module/README.md | 4 +- tools/benchmark-hooks/package-lock.json | 151 ++++- tools/benchmark-hooks/package.json | 7 +- tools/benchmark-struct/package-lock.json | 151 ++++- tools/benchmark-struct/package.json | 7 +- website/blog/2024-10-14-release-0-22.md | 40 ++ website/blog/authors.yml | 10 +- .../docs/advanced-topics/optimizations.mdx | 2 +- ...rendering.md => server-side-rendering.mdx} | 3 +- website/docs/concepts/agents.mdx | 2 +- .../concepts/basic-web-technologies/css.mdx | 4 +- .../concepts/basic-web-technologies/html.mdx | 2 +- .../basic-web-technologies/wasm-bindgen.mdx | 7 +- .../basic-web-technologies/web-sys.mdx | 1 - .../function-components/properties.mdx | 5 - website/docs/concepts/html/events.mdx | 2 +- website/docs/concepts/html/lists.mdx | 2 +- website/docs/concepts/router.mdx | 2 +- website/i18n/ja/code.json | 19 - .../current/advanced-topics/children.mdx | 307 +++++++++ .../current/advanced-topics/how-it-works.mdx | 39 +- .../current/advanced-topics/immutable.mdx | 19 + .../current/advanced-topics/optimizations.mdx | 179 ++--- .../current/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 92 ++- .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 287 +++++--- .../struct-components/properties.mdx | 136 ++-- .../struct-components/refs.mdx | 53 +- .../struct-components/scope.mdx | 70 ++ .../current/concepts/agents.mdx | 64 +- .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 210 ++++++ .../current/concepts/contexts.mdx | 188 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 106 +++ .../hooks/introduction.mdx | 50 ++ .../function-components/introduction.mdx | 65 ++ .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../current/concepts/html/classes.mdx | 122 ++++ .../current/concepts/html/components.mdx | 158 +++-- .../concepts/html/conditional-rendering.mdx | 73 ++ .../current/concepts/html/elements.mdx | 437 +++--------- .../current/concepts/html/events.mdx | 542 +++++++++++++++ .../current/concepts/html/fragments.mdx | 42 ++ .../current/concepts/html/introduction.mdx | 212 +++++- .../current/concepts/html/lists.mdx | 137 ++-- .../html/literals-and-expressions.mdx | 29 +- .../current/concepts/router.mdx | 508 ++++++++++++-- .../current/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 191 +++--- .../current/getting-started/editor-setup.mdx | 157 +++++ .../current/getting-started/examples.mdx | 23 +- .../current/getting-started/introduction.mdx | 44 ++ .../current/more/css.mdx | 29 +- .../current/more/debugging.mdx | 102 ++- .../current/more/deployment.mdx | 45 ++ .../current/more/roadmap.mdx | 49 +- .../current/more/testing.mdx | 22 +- .../current/tutorial/index.mdx | 584 ++++++++++++++++ .../version-0.18.0.json | 36 - .../version-0.19.0.json | 52 -- .../version-0.22.json | 86 +++ .../version-0.22/advanced-topics/children.mdx | 307 +++++++++ .../advanced-topics/how-it-works.mdx | 39 ++ .../advanced-topics/immutable.mdx | 19 + .../advanced-topics/optimizations.mdx | 112 ++++ .../version-0.22/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 85 +++ .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 273 ++++++++ .../struct-components/properties.mdx | 134 ++++ .../struct-components/refs.mdx | 51 ++ .../struct-components/scope.mdx | 70 ++ .../version-0.22/concepts/agents.mdx | 56 ++ .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 210 ++++++ .../version-0.22/concepts/contexts.mdx | 188 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 106 +++ .../hooks/introduction.mdx | 50 ++ .../function-components/introduction.mdx | 65 ++ .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../version-0.22/concepts/html/classes.mdx | 122 ++++ .../version-0.22/concepts/html/components.mdx | 124 ++++ .../concepts/html/conditional-rendering.mdx | 73 ++ .../version-0.22/concepts/html/elements.mdx | 138 ++++ .../version-0.22/concepts/html/events.mdx | 542 +++++++++++++++ .../version-0.22/concepts/html/fragments.mdx | 42 ++ .../concepts/html/introduction.mdx | 208 ++++++ .../version-0.22/concepts/html/lists.mdx | 119 ++++ .../html/literals-and-expressions.mdx | 71 ++ .../version-0.22/concepts/router.mdx | 461 +++++++++++++ .../version-0.22/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 149 +++++ .../getting-started/editor-setup.mdx | 157 +++++ .../version-0.22/getting-started/examples.mdx | 17 + .../getting-started/introduction.mdx | 44 ++ .../version-0.22/more/css.mdx | 27 + .../version-0.22/more/debugging.mdx | 98 +++ .../version-0.22/more/deployment.mdx | 45 ++ .../version-0.22/more/roadmap.mdx | 44 ++ .../version-0.22/more/testing.mdx | 24 + .../version-0.22/tutorial/index.mdx | 584 ++++++++++++++++ website/i18n/zh-Hans/code.json | 19 - .../current.json | 22 +- .../current/advanced-topics/children.mdx | 308 +++++++++ .../current/advanced-topics/how-it-works.mdx | 36 +- .../current/advanced-topics/immutable.mdx | 19 + .../current/advanced-topics/optimizations.mdx | 159 +++-- .../current/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 84 ++- .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 264 +++++--- .../struct-components/properties.mdx | 132 +++- .../struct-components/refs.mdx | 50 +- .../struct-components/scope.mdx | 70 ++ .../current/concepts/agents.mdx | 56 +- .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 212 ++++++ .../current/concepts/contexts.mdx | 189 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 157 ++--- .../hooks/introduction.mdx | 50 ++ .../function-components/introduction.mdx | 62 +- .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../current/concepts/html/classes.mdx | 122 ++++ .../current/concepts/html/components.mdx | 148 +++-- .../concepts/html/conditional-rendering.mdx | 73 ++ .../current/concepts/html/elements.mdx | 326 +++------ .../current/concepts/html/events.mdx | 546 +++++++++++++++ .../current/concepts/html/fragments.mdx | 42 ++ .../current/concepts/html/introduction.mdx | 206 +++++- .../current/concepts/html/lists.mdx | 138 ++-- .../html/literals-and-expressions.mdx | 32 +- .../current/concepts/router.mdx | 460 ++++++++++++- .../current/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 172 +++-- .../current/getting-started/editor-setup.mdx | 159 +++++ .../current/getting-started/examples.mdx | 24 +- .../current/getting-started/introduction.mdx | 44 ++ .../current/more/css.mdx | 28 +- .../current/more/debugging.mdx | 98 ++- .../current/more/deployment.mdx | 45 ++ .../current/more/roadmap.mdx | 57 +- .../current/more/testing.mdx | 23 +- .../current/tutorial/index.mdx | 584 ++++++++++++++++ .../version-0.18.0.json | 36 - .../version-0.19.0.json | 52 -- .../version-0.22.json | 86 +++ .../version-0.22/advanced-topics/children.mdx | 308 +++++++++ .../advanced-topics/how-it-works.mdx | 39 ++ .../advanced-topics/immutable.mdx | 19 + .../advanced-topics/optimizations.mdx | 112 ++++ .../version-0.22/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 85 +++ .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 272 ++++++++ .../struct-components/properties.mdx | 134 ++++ .../struct-components/refs.mdx | 51 ++ .../struct-components/scope.mdx | 70 ++ .../version-0.22/concepts/agents.mdx | 56 ++ .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 212 ++++++ .../version-0.22/concepts/contexts.mdx | 189 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 106 +++ .../hooks/introduction.mdx | 50 ++ .../function-components/introduction.mdx | 65 ++ .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../version-0.22/concepts/html/classes.mdx | 122 ++++ .../version-0.22/concepts/html/components.mdx | 124 ++++ .../concepts/html/conditional-rendering.mdx | 73 ++ .../version-0.22/concepts/html/elements.mdx | 138 ++++ .../version-0.22/concepts/html/events.mdx | 546 +++++++++++++++ .../version-0.22/concepts/html/fragments.mdx | 42 ++ .../concepts/html/introduction.mdx | 208 ++++++ .../version-0.22/concepts/html/lists.mdx | 119 ++++ .../html/literals-and-expressions.mdx | 71 ++ .../version-0.22/concepts/router.mdx | 461 +++++++++++++ .../version-0.22/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 149 +++++ .../getting-started/editor-setup.mdx | 159 +++++ .../version-0.22/getting-started/examples.mdx | 17 + .../getting-started/introduction.mdx | 44 ++ .../version-0.22/more/css.mdx | 27 + .../version-0.22/more/debugging.mdx | 98 +++ .../version-0.22/more/deployment.mdx | 45 ++ .../version-0.22/more/roadmap.mdx | 44 ++ .../version-0.22/more/testing.mdx | 24 + .../version-0.22/tutorial/index.mdx | 584 ++++++++++++++++ website/i18n/zh-Hant/code.json | 19 - .../current/advanced-topics/children.mdx | 308 +++++++++ .../current/advanced-topics/how-it-works.mdx | 38 +- .../current/advanced-topics/immutable.mdx | 19 + .../current/advanced-topics/optimizations.mdx | 142 ++-- .../current/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 84 ++- .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 268 +++++--- .../struct-components/properties.mdx | 124 +++- .../struct-components/refs.mdx | 55 +- .../struct-components/scope.mdx | 70 ++ .../current/concepts/agents.mdx | 57 +- .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 212 ++++++ .../current/concepts/contexts.mdx | 189 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 106 +++ .../hooks/introduction.mdx | 52 ++ .../function-components/introduction.mdx | 65 ++ .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../current/concepts/html/classes.mdx | 122 ++++ .../current/concepts/html/components.mdx | 152 +++-- .../concepts/html/conditional-rendering.mdx | 73 ++ .../current/concepts/html/elements.mdx | 326 +++------ .../current/concepts/html/events.mdx | 546 +++++++++++++++ .../current/concepts/html/fragments.mdx | 42 ++ .../current/concepts/html/introduction.mdx | 206 +++++- .../current/concepts/html/lists.mdx | 138 ++-- .../html/literals-and-expressions.mdx | 34 +- .../current/concepts/router.mdx | 498 ++++++++++++-- .../current/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 184 ++--- .../current/getting-started/editor-setup.mdx | 159 +++++ .../current/getting-started/examples.mdx | 24 +- .../current/getting-started/introduction.mdx | 44 ++ .../current/more/css.mdx | 28 +- .../current/more/debugging.mdx | 98 ++- .../current/more/deployment.mdx | 45 ++ .../current/more/roadmap.mdx | 50 +- .../current/more/testing.mdx | 23 +- .../current/tutorial/index.mdx | 584 ++++++++++++++++ .../version-0.18.0.json | 36 - .../version-0.19.0.json | 52 -- .../version-0.22.json | 86 +++ .../version-0.22/advanced-topics/children.mdx | 308 +++++++++ .../advanced-topics/how-it-works.mdx | 39 ++ .../advanced-topics/immutable.mdx | 19 + .../advanced-topics/optimizations.mdx | 112 ++++ .../version-0.22/advanced-topics/portals.mdx | 48 ++ .../advanced-topics/server-side-rendering.mdx | 184 +++++ .../struct-components/callbacks.mdx | 85 +++ .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 28 + .../struct-components/lifecycle.mdx | 273 ++++++++ .../struct-components/properties.mdx | 134 ++++ .../struct-components/refs.mdx | 51 ++ .../struct-components/scope.mdx | 70 ++ .../version-0.22/concepts/agents.mdx | 56 ++ .../concepts/basic-web-technologies/css.mdx | 99 +++ .../concepts/basic-web-technologies/html.mdx | 75 +++ .../concepts/basic-web-technologies/js.mdx | 50 ++ .../basic-web-technologies/wasm-bindgen.mdx | 177 +++++ .../basic-web-technologies/web-sys.mdx | 212 ++++++ .../version-0.22/concepts/contexts.mdx | 189 ++++++ .../function-components/callbacks.mdx | 73 ++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 106 +++ .../hooks/introduction.mdx | 52 ++ .../function-components/introduction.mdx | 65 ++ .../function-components/node-refs.mdx | 17 + .../function-components/properties.mdx | 339 ++++++++++ .../function-components/pure-components.mdx | 34 + .../concepts/function-components/state.mdx | 26 + .../version-0.22/concepts/html/classes.mdx | 122 ++++ .../version-0.22/concepts/html/components.mdx | 124 ++++ .../concepts/html/conditional-rendering.mdx | 73 ++ .../version-0.22/concepts/html/elements.mdx | 138 ++++ .../version-0.22/concepts/html/events.mdx | 546 +++++++++++++++ .../version-0.22/concepts/html/fragments.mdx | 42 ++ .../concepts/html/introduction.mdx | 208 ++++++ .../version-0.22/concepts/html/lists.mdx | 119 ++++ .../html/literals-and-expressions.mdx | 71 ++ .../version-0.22/concepts/router.mdx | 461 +++++++++++++ .../version-0.22/concepts/suspense.mdx | 146 ++++ .../getting-started/build-a-sample-app.mdx | 149 +++++ .../getting-started/editor-setup.mdx | 159 +++++ .../version-0.22/getting-started/examples.mdx | 17 + .../getting-started/introduction.mdx | 44 ++ .../version-0.22/more/css.mdx | 27 + .../version-0.22/more/debugging.mdx | 98 +++ .../version-0.22/more/deployment.mdx | 45 ++ .../version-0.22/more/roadmap.mdx | 44 ++ .../version-0.22/more/testing.mdx | 24 + .../version-0.22/tutorial/index.mdx | 584 ++++++++++++++++ website/package-lock.json | 7 +- website/package.json | 3 +- .../version-0.22/advanced-topics/children.mdx | 318 +++++++++ .../advanced-topics/how-it-works.mdx | 74 +++ .../advanced-topics/immutable.mdx | 24 + .../advanced-topics/optimizations.mdx | 163 +++++ .../version-0.22/advanced-topics/portals.mdx | 64 ++ .../advanced-topics/server-side-rendering.mdx | 251 +++++++ .../struct-components/callbacks.mdx | 86 +++ .../advanced-topics/struct-components/hoc.mdx | 82 +++ .../struct-components/introduction.mdx | 32 + .../struct-components/lifecycle.mdx | 305 +++++++++ .../struct-components/properties.mdx | 145 ++++ .../struct-components/refs.mdx | 55 ++ .../struct-components/scope.mdx | 81 +++ .../version-0.22/concepts/agents.mdx | 64 ++ .../concepts/basic-web-technologies/css.mdx | 101 +++ .../concepts/basic-web-technologies/html.mdx | 79 +++ .../concepts/basic-web-technologies/js.mdx | 53 ++ .../basic-web-technologies/wasm-bindgen.mdx | 243 +++++++ .../basic-web-technologies/web-sys.mdx | 244 +++++++ .../version-0.22/concepts/contexts.mdx | 196 ++++++ .../function-components/callbacks.mdx | 74 +++ .../concepts/function-components/children.mdx | 37 ++ .../function-components/communication.mdx | 11 + .../concepts/function-components/generics.mdx | 44 ++ .../hooks/custom-hooks.mdx | 113 ++++ .../hooks/introduction.mdx | 52 ++ .../function-components/introduction.mdx | 76 +++ .../function-components/node-refs.mdx | 21 + .../function-components/properties.mdx | 356 ++++++++++ .../function-components/pure-components.mdx | 39 ++ .../concepts/function-components/state.mdx | 26 + .../version-0.22/concepts/html/classes.mdx | 127 ++++ .../version-0.22/concepts/html/components.mdx | 125 ++++ .../concepts/html/conditional-rendering.mdx | 73 ++ .../version-0.22/concepts/html/elements.mdx | 145 ++++ .../version-0.22/concepts/html/events.mdx | 601 +++++++++++++++++ .../version-0.22/concepts/html/fragments.mdx | 43 ++ .../concepts/html/introduction.mdx | 222 +++++++ .../version-0.22/concepts/html/lists.mdx | 125 ++++ .../html/literals-and-expressions.mdx | 71 ++ .../version-0.22/concepts/router.mdx | 506 ++++++++++++++ .../version-0.22/concepts/suspense.mdx | 164 +++++ .../getting-started/build-a-sample-app.mdx | 158 +++++ .../getting-started/editor-setup.mdx | 160 +++++ .../version-0.22/getting-started/examples.mdx | 17 + .../getting-started/introduction.mdx | 53 ++ .../yew-agent/from-0_0_0-to-0_1_0.mdx | 7 + .../yew-agent/from-0_1_0-to-0_2_0.mdx | 23 + .../yew-router/from-0_15_0-to-0_16_0.mdx | 9 + .../yew-router/from-0_16_0-to-0_17_0.mdx | 12 + .../yew/from-0_18_0-to-0_19_0.mdx | 139 ++++ .../yew/from-0_19_0-to-0_20_0.mdx | 84 +++ .../yew/from-0_20_0-to-0_21_0.mdx | 71 ++ .../versioned_docs/version-0.22/more/css.mdx | 30 + .../version-0.22/more/debugging.mdx | 100 +++ .../version-0.22/more/deployment.mdx | 45 ++ .../version-0.22/more/roadmap.mdx | 44 ++ .../version-0.22/more/testing.mdx | 25 + .../version-0.22/tutorial/index.mdx | 626 ++++++++++++++++++ .../version-0.22-sidebars.json | 180 +++++ 406 files changed, 44669 insertions(+), 3005 deletions(-) create mode 100644 website/blog/2024-10-14-release-0-22.md rename website/docs/advanced-topics/{server-side-rendering.md => server-side-rendering.mdx} (99%) create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/contexts.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/children.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/communication.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/generics.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/properties.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/html/classes.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/html/events.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/html/fragments.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/suspense.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/getting-started/editor-setup.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/getting-started/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/more/deployment.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/current/tutorial/index.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22.json create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/children.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/immutable.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/optimizations.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/portals.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/agents.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/contexts.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/children.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/communication.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/generics.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/properties.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/state.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/classes.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/components.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/elements.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/events.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/fragments.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/lists.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/router.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/concepts/suspense.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/getting-started/editor-setup.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/getting-started/examples.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/getting-started/introduction.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/more/css.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/more/debugging.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/more/deployment.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/more/roadmap.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/more/testing.mdx create mode 100644 website/i18n/ja/docusaurus-plugin-content-docs/version-0.22/tutorial/index.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/contexts.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/children.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/communication.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/generics.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/properties.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/html/classes.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/html/events.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/html/fragments.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/suspense.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/getting-started/editor-setup.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/getting-started/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/more/deployment.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/tutorial/index.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22.json create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/children.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/immutable.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/optimizations.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/portals.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/agents.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/contexts.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/children.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/communication.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/generics.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/properties.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/state.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/classes.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/components.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/elements.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/events.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/fragments.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/lists.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/router.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/concepts/suspense.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/getting-started/editor-setup.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/getting-started/examples.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/getting-started/introduction.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/more/css.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/more/debugging.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/more/deployment.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/more/roadmap.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/more/testing.mdx create mode 100644 website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-0.22/tutorial/index.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/contexts.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/children.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/communication.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/generics.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/properties.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/html/classes.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/html/events.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/html/fragments.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/suspense.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/getting-started/editor-setup.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/getting-started/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/more/deployment.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/tutorial/index.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22.json create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/children.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/how-it-works.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/immutable.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/optimizations.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/portals.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/server-side-rendering.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/hoc.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/properties.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/refs.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/advanced-topics/struct-components/scope.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/agents.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/css.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/html.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/js.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/contexts.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/callbacks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/children.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/communication.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/generics.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/hooks/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/node-refs.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/properties.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/pure-components.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/function-components/state.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/classes.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/components.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/conditional-rendering.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/elements.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/events.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/fragments.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/lists.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/html/literals-and-expressions.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/router.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/concepts/suspense.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/getting-started/build-a-sample-app.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/getting-started/editor-setup.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/getting-started/examples.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/getting-started/introduction.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/more/css.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/more/debugging.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/more/deployment.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/more/roadmap.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/more/testing.mdx create mode 100644 website/i18n/zh-Hant/docusaurus-plugin-content-docs/version-0.22/tutorial/index.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/children.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/how-it-works.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/immutable.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/optimizations.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/portals.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/server-side-rendering.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/callbacks.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/hoc.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/introduction.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/lifecycle.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/properties.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/refs.mdx create mode 100644 website/versioned_docs/version-0.22/advanced-topics/struct-components/scope.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/agents.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/basic-web-technologies/css.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/basic-web-technologies/html.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/basic-web-technologies/js.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/basic-web-technologies/wasm-bindgen.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/contexts.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/callbacks.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/children.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/communication.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/generics.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/hooks/custom-hooks.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/hooks/introduction.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/introduction.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/node-refs.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/properties.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/pure-components.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/function-components/state.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/classes.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/components.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/conditional-rendering.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/elements.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/events.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/fragments.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/introduction.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/lists.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/html/literals-and-expressions.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/router.mdx create mode 100644 website/versioned_docs/version-0.22/concepts/suspense.mdx create mode 100644 website/versioned_docs/version-0.22/getting-started/build-a-sample-app.mdx create mode 100644 website/versioned_docs/version-0.22/getting-started/editor-setup.mdx create mode 100644 website/versioned_docs/version-0.22/getting-started/examples.mdx create mode 100644 website/versioned_docs/version-0.22/getting-started/introduction.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew-agent/from-0_0_0-to-0_1_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew-agent/from-0_1_0-to-0_2_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew-router/from-0_15_0-to-0_16_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew-router/from-0_16_0-to-0_17_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew/from-0_18_0-to-0_19_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew/from-0_19_0-to-0_20_0.mdx create mode 100644 website/versioned_docs/version-0.22/migration-guides/yew/from-0_20_0-to-0_21_0.mdx create mode 100644 website/versioned_docs/version-0.22/more/css.mdx create mode 100644 website/versioned_docs/version-0.22/more/debugging.mdx create mode 100644 website/versioned_docs/version-0.22/more/deployment.mdx create mode 100644 website/versioned_docs/version-0.22/more/roadmap.mdx create mode 100644 website/versioned_docs/version-0.22/more/testing.mdx create mode 100644 website/versioned_docs/version-0.22/tutorial/index.mdx create mode 100644 website/versioned_sidebars/version-0.22-sidebars.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a620e82c..5cbae59c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,58 @@ # Changelog +## ✨ yew **0.22.0** *(2024-10-14)* + +#### Changelog + +## 🛠 Fixes + + - Fix: Hydratation of empty lists next to components.. [[@WorldSEnder](https://github.com/WorldSEnder), [#3630](https://github.com/yewstack/yew/pull/3630)] +silenced non-normalised element name warnings for SVG elements [@Tim Kurdov](https://github.com/its-the-shrimp), [#3769](https://github.com/yewstack/yew/pull/3769)] + +## ⚡️ Features + + - Raise MSRV to 1.76. [[@Elina](https://github.com/ranile), [#3693](https://github.com/yewstack/yew/pull/3693)] + - Add `inert` to the boolean attributes list. [[@Tomoaki Kawada](https://github.com/kawadakk), [#3678](https://github.com/yewstack/yew/pull/3678)] + - Namespace support for `VRaw`.. [[@Finn Bear](https://github.com/finnbear), [#3640](https://github.com/yewstack/yew/pull/3640)] + - Add generic type hints to boxed hooks. [[@Michael Meyer](https://github.com/Ichmed), [#3633](https://github.com/yewstack/yew/pull/3633)] + - add the methods and From impls. [[@Tim Kurdov](https://github.com/its-the-shrimp), [#3519](https://github.com/yewstack/yew/pull/3519)] + - Add IntoPropValue impl for converting to VList. [[@Muhammad Hamza](https://github.com/ranile), [#3444](https://github.com/yewstack/yew/pull/3444)] + - Add CallbackRef that takes ref in argument instead of value. [[@Cecile Tonglet](https://github.com/cecton), [#3419](https://github.com/yewstack/yew/pull/3419)] + - Remove the dependency on `boolinator`. [[@Tim Kurdov](https://github.com/its-the-shrimp), [#3420](https://github.com/yewstack/yew/pull/3420)] + - Allow import of layout_test into 3rd party crates. [[@rollo-b2c2](https://github.com/rollo-b2c2), [#3463](https://github.com/yewstack/yew/pull/3463)] + - Add WASI support for server-side rendering. [[@langyo](https://github.com/langyo), [#3534](https://github.com/yewstack/yew/pull/3534)] + +## 🚨 Breaking changes + + - Add use_ref. [[@Alex Parrill](https://github.com/ColonelThirtyTwo), [#3548](https://github.com/yewstack/yew/pull/3548)] + - Allow setting JsValue as properties. [[@Elina](https://github.com/ranile), [#3458](https://github.com/yewstack/yew/pull/3458)] + - Remove deprecated `class=(...)` syntax. [[@Tim Kurdov](https://github.com/its-the-shrimp), [#3497](https://github.com/yewstack/yew/pull/3497)] + - Remove ToHtml trait. [[@Elina](https://github.com/ranile), [#3453](https://github.com/yewstack/yew/pull/3453)] + - Make Html (VNode) cheap to clone. [[@Cecile Tonglet](https://github.com/cecton), [#3431](https://github.com/yewstack/yew/pull/3431)] + +## ✨ yew-router **0.19.0** *(2024-10-14)* + +#### Changelog + +## 🛠 Fixes + + - Fix CI. [[@Tomoaki Kawada](https://github.com/kawadakk), [#3679](https://github.com/yewstack/yew/pull/3679)] + +## ⚡️ Features + + - Raise MSRV to 1.76. [[@Elina](https://github.com/ranile), [#3693](https://github.com/yewstack/yew/pull/3693)] + +## ✨ yew-agent **0.4.0** *(2024-10-14)* + +#### Changelog + +## ⚡️ Features + + - Raise MSRV to 1.76. [[@Elina](https://github.com/ranile), [#3693](https://github.com/yewstack/yew/pull/3693)] + - Agent: Avoiding clone of WorkerBridge and WorkerProviderState. [[@Shihpin Tseng](https://github.com/deftsp), [#3435](https://github.com/yewstack/yew/pull/3435)] + +---- + ## ✨ yew **0.21.0** *(2023-09-23)* #### Changelog diff --git a/examples/wasi_ssr_module/README.md b/examples/wasi_ssr_module/README.md index 51fbceeb0..a92ac9857 100644 --- a/examples/wasi_ssr_module/README.md +++ b/examples/wasi_ssr_module/README.md @@ -9,7 +9,7 @@ It depends on [wasmtime](https://wasmtime.dev)'s WASI preview2. To build the example, run the following command from the root of the repository: ```bash -cargo build --manifest-path examples/wasi_ssr_module/Cargo.toml --target wasm32-wasi --release +cargo build --manifest-path examples/wasi_ssr_module/Cargo.toml --target wasm32-wasip1 --release ``` ## Running @@ -17,7 +17,7 @@ cargo build --manifest-path examples/wasi_ssr_module/Cargo.toml --target wasm32- > Note: This example requires the wasmtime CLI to be installed. See [wasmtime's installation instructions](https://docs.wasmtime.dev/cli-install.html) for more information. ```bash -wasmtime target/wasm32-wasi/release/wasi_ssr_module.wasm +wasmtime target/wasm32-wasip1/release/wasi_ssr_module.wasm ``` > Note: If your wasmtime CLI throws an error that it says some imports like `__wbindgen_placeholder__::__wbindgen_xxx` is invalid, try to run `cargo update`. See issue [rustwasm/gloo#411](https://github.com/rustwasm/gloo/pull/411#discussion_r1421219033). diff --git a/tools/benchmark-hooks/package-lock.json b/tools/benchmark-hooks/package-lock.json index 4699b4eb7..f42488b21 100644 --- a/tools/benchmark-hooks/package-lock.json +++ b/tools/benchmark-hooks/package-lock.json @@ -1,13 +1,16 @@ { - "name": "js-framework-benchmark-non-keyed-yew-hooks", + "name": "js-framework-benchmark-keyed-yew-hooks", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "js-framework-benchmark-non-keyed-yew-hooks", + "name": "js-framework-benchmark-keyed-yew-hooks", "version": "1.0.0", "license": "ISC", + "dependencies": { + "js-framework-benchmark-keyed-yew-hooks": "file:" + }, "devDependencies": { "cpr": "^3.0.1", "rimraf": "^2.6.3" @@ -98,6 +101,10 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/js-framework-benchmark-keyed-yew-hooks": { + "resolved": "", + "link": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -242,6 +249,146 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "js-framework-benchmark-keyed-yew-hooks": { + "version": "file:", + "requires": { + "cpr": "^3.0.1", + "js-framework-benchmark-keyed-yew-hooks": "file:", + "rimraf": "^2.6.3" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cpr": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cpr/-/cpr-3.0.1.tgz", + "integrity": "sha512-Xch4PXQ/KC8lJ+KfJ9JI6eG/nmppLrPPWg5Q+vh65Qr9EjuJEubxh/H/Le1TmCZ7+Xv7iJuNRqapyOFZB+wsxA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.5", + "minimist": "^1.2.0", + "mkdirp": "~0.5.1", + "rimraf": "^2.5.4" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/tools/benchmark-hooks/package.json b/tools/benchmark-hooks/package.json index 14ba90be5..be71ad962 100644 --- a/tools/benchmark-hooks/package.json +++ b/tools/benchmark-hooks/package.json @@ -20,7 +20,10 @@ "url": "https://github.com/krausest/js-framework-benchmark.git" }, "devDependencies": { - "rimraf": "^2.6.3", - "cpr": "^3.0.1" + "cpr": "^3.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "js-framework-benchmark-keyed-yew-hooks": "file:" } } diff --git a/tools/benchmark-struct/package-lock.json b/tools/benchmark-struct/package-lock.json index ad757df6b..5943ccfff 100644 --- a/tools/benchmark-struct/package-lock.json +++ b/tools/benchmark-struct/package-lock.json @@ -1,13 +1,16 @@ { - "name": "js-framework-benchmark-non-keyed-yew", + "name": "js-framework-benchmark-keyed-yew", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "js-framework-benchmark-non-keyed-yew", + "name": "js-framework-benchmark-keyed-yew", "version": "1.0.0", "license": "ISC", + "dependencies": { + "js-framework-benchmark-keyed-yew": "file:" + }, "devDependencies": { "cpr": "^3.0.1", "rimraf": "^2.6.3" @@ -98,6 +101,10 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/js-framework-benchmark-keyed-yew": { + "resolved": "", + "link": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -242,6 +249,146 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "js-framework-benchmark-keyed-yew": { + "version": "file:", + "requires": { + "cpr": "^3.0.1", + "js-framework-benchmark-keyed-yew": "file:", + "rimraf": "^2.6.3" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cpr": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cpr/-/cpr-3.0.1.tgz", + "integrity": "sha512-Xch4PXQ/KC8lJ+KfJ9JI6eG/nmppLrPPWg5Q+vh65Qr9EjuJEubxh/H/Le1TmCZ7+Xv7iJuNRqapyOFZB+wsxA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.5", + "minimist": "^1.2.0", + "mkdirp": "~0.5.1", + "rimraf": "^2.5.4" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/tools/benchmark-struct/package.json b/tools/benchmark-struct/package.json index db741af2e..007c520e2 100644 --- a/tools/benchmark-struct/package.json +++ b/tools/benchmark-struct/package.json @@ -20,7 +20,10 @@ "url": "https://github.com/krausest/js-framework-benchmark.git" }, "devDependencies": { - "rimraf": "^2.6.3", - "cpr": "^3.0.1" + "cpr": "^3.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "js-framework-benchmark-keyed-yew": "file:" } } diff --git a/website/blog/2024-10-14-release-0-22.md b/website/blog/2024-10-14-release-0-22.md new file mode 100644 index 000000000..bb1461739 --- /dev/null +++ b/website/blog/2024-10-14-release-0-22.md @@ -0,0 +1,40 @@ +--- +title: Announcing Yew 0.22 +authors: [langyo] +--- + + + +## What's new + +### SSR on WASI + +Before Yew 0.22, server-side rendering (SSR) was only possible on the native target. With Yew 0.22, you can now render your Yew application on the WebAssembly System Interface (WASI) target. + +Since the old SSR implementation will create new tasks directly in the asynchronous context directly (based on `prokio`). It only allowed in a multi-threaded environment that it is not compatible with WASI. So the new version added a dedicated one for a single-threaded environment that rendering function to support single-threaded scenes. + +Learn more at [Server-side rendering example on WASI environment](https://github.com/yewstack/yew/tree/master/examples/wasi_ssr_module/src/main.rs) + +## Call for Contributors + +The Yew project thrives on community involvement, and we welcome contributors with open arms. Whether you're an experienced Rust developer or just starting your journey, there are plenty of ways to get involved and make a meaningful impact on Yew's growth. + +Here are some areas where you can contribute: + +- **Code Contributions:** If you're passionate about web development with Rust, consider contributing code to Yew. Whether it's fixing bugs, adding new features, or improving documentation, your code can help make Yew even better. + +- **Documentation:** Clear and comprehensive documentation is vital for any project's success. You can contribute by improving documentation, writing tutorials, or creating examples that help others understand and use Yew effectively. + +- **Testing and Bug Reporting:** Testing Yew and reporting bugs you encounter is a valuable contribution. Your feedback helps us identify and fix issues, ensuring a more stable framework for everyone. + +- **Community Support:** Join discussions, chat rooms (we have our own Discord and Matrix!), or social media to assist other developers using Yew. Sharing your knowledge and helping others solve problems is a fantastic way to contribute. + +Contributing to open-source projects like Yew is not only a way to give back to the community but also an excellent opportunity to learn, collaborate, and enhance your skills. + +To get started, check out the Yew GitHub repository and the contribution guidelines. Your contributions are highly appreciated and play a crucial role in shaping the future of Yew. Join us in this exciting journey! + +## Thanks! + +Many people came together to create Yew 0.22. We couldn't have done it without all of you. Thanks! + +See [the full changelog](https://github.com/yewstack/yew/blob/master/CHANGELOG.md) diff --git a/website/blog/authors.yml b/website/blog/authors.yml index bf967286a..0843c3eaf 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -1,5 +1,11 @@ hamza: name: Muhammad Hamza title: Maintainer of Yew - url: https://github.com/hamza1311 - image_url: https://github.com/hamza1311.png + url: https://github.com/ranile + image_url: https://github.com/ranile.png + +langyo: + name: langyo + title: Contributor of Yew + url: https://github.com/langyo + image_url: https://github.com/langyo.png diff --git a/website/docs/advanced-topics/optimizations.mdx b/website/docs/advanced-topics/optimizations.mdx index 9aef595c9..8252b9e22 100644 --- a/website/docs/advanced-topics/optimizations.mdx +++ b/website/docs/advanced-topics/optimizations.mdx @@ -155,7 +155,7 @@ Note: `wasm-pack` combines optimization for Rust and Wasm code. `wasm-bindgen` i | wasm-bindgen + wasm-opt -Os | 116KB | | wasm-pack | 99 KB | -## Further reading: +## Further reading - [The Rust Book's chapter on smart pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) - [Information from the Rust Wasm Book about reducing binary sizes](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size) diff --git a/website/docs/advanced-topics/server-side-rendering.md b/website/docs/advanced-topics/server-side-rendering.mdx similarity index 99% rename from website/docs/advanced-topics/server-side-rendering.md rename to website/docs/advanced-topics/server-side-rendering.mdx index c68c3b362..0458fe447 100644 --- a/website/docs/advanced-topics/server-side-rendering.md +++ b/website/docs/advanced-topics/server-side-rendering.mdx @@ -186,8 +186,7 @@ fn App() -> Html { fn main() { let renderer = Renderer::::new(); - // hydrates everything under body element, removes trailing - // elements (if any). + // 直接在 body 元素下注水,并移除可能有的任何尾随元素。 renderer.hydrate(); } ``` diff --git a/website/docs/concepts/agents.mdx b/website/docs/concepts/agents.mdx index dc35203fa..2b59ee47b 100644 --- a/website/docs/concepts/agents.mdx +++ b/website/docs/concepts/agents.mdx @@ -55,7 +55,7 @@ A dispatcher allows uni-directional communication between a component and an age ## Overhead Agents use web workers \(i.e. Private and Public\). They incur a serialization overhead on the -messages they send and receive. Agents use [bincode](https://github.com/servo/bincode) to communicate +messages they send and receive. Agents use [bincode](https://github.com/bincode-org/bincode) to communicate with other threads, so the cost is substantially higher than just calling a function. ## Further reading diff --git a/website/docs/concepts/basic-web-technologies/css.mdx b/website/docs/concepts/basic-web-technologies/css.mdx index 49eafe971..94d30038d 100644 --- a/website/docs/concepts/basic-web-technologies/css.mdx +++ b/website/docs/concepts/basic-web-technologies/css.mdx @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem' Yew does not natively provide a CSS-in-Rust solution but helps with styling by providing programmatic ways to interact with the HTML `class` attribute. -## Classes +## `classes!` macro The `classes!` macro and associated `Classes` struct simplify the use of HTML classes: @@ -87,7 +87,7 @@ We will expand upon this concept in [more CSS](../../more/css). ## Inline Styles -Currently Yew does not provide any special help with inline styles specified via the `styles` attribute, +Currently Yew does not provide any special help with inline styles specified via the `style` attribute, but you can use it like any other HTML attribute: ```rust diff --git a/website/docs/concepts/basic-web-technologies/html.mdx b/website/docs/concepts/basic-web-technologies/html.mdx index a2070935e..cf3ed1b89 100644 --- a/website/docs/concepts/basic-web-technologies/html.mdx +++ b/website/docs/concepts/basic-web-technologies/html.mdx @@ -1,6 +1,6 @@ --- title: 'HTML with html!' -description: 'Its HTML but not quite!' +description: 'It is HTML but not quite!' comment: 'Keep this file as short and simple as possible. Its purpose is to ease the reader into components in Yew instead of providing proper API docs' --- diff --git a/website/docs/concepts/basic-web-technologies/wasm-bindgen.mdx b/website/docs/concepts/basic-web-technologies/wasm-bindgen.mdx index e34c895ca..0fb431b17 100644 --- a/website/docs/concepts/basic-web-technologies/wasm-bindgen.mdx +++ b/website/docs/concepts/basic-web-technologies/wasm-bindgen.mdx @@ -50,7 +50,6 @@ use wasm_bindgen::prelude::*; // correctness of these annotations! #[wasm_bindgen] extern "C" { - // Use `js_namespace` here to bind `console.log(..)` instead of just // `log(..)` #[wasm_bindgen(js_namespace = console)] @@ -98,12 +97,12 @@ These implementations allow you to call a method from `A` on an instance of `C` it was `&B` or `&A`. It is important to note that every single type imported using `#[wasm-bindgen]` has the same root type, -you can think of it as the `A` in the example above, this type is [`JsValue`](#jsvalue) which has +you can think of it as the `A` in the example above, this type is [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) which has its section below. _[extends section in The `wasm-bindgen` Guide](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/extends.html)_ -### [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) {#jsvalue} +### [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) This is a representation of an object owned by JavaScript, this is a root catch-all type for `wasm-bindgen`. Any type that comes from `wasm-bindgen` is a `JsValue` and this is because JavaScript does not have @@ -117,7 +116,7 @@ being imported as to whether an exception (panic) will be raised if that value i _[`JsValue` documentation](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html)._ -### [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) {#JsCast} +### [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) Rust has a strong type system and JavaScript...doesn't 😞. For Rust to maintain these strong types but still be convenient, the WebAssembly group came up with a pretty neat trait `JsCast`. diff --git a/website/docs/concepts/basic-web-technologies/web-sys.mdx b/website/docs/concepts/basic-web-technologies/web-sys.mdx index 392eb2d52..a8fa90abf 100644 --- a/website/docs/concepts/basic-web-technologies/web-sys.mdx +++ b/website/docs/concepts/basic-web-technologies/web-sys.mdx @@ -69,7 +69,6 @@ fn inheritance_of_text_area(text_area: HtmlTextAreaElement) { // The AsRef implementations allow you to treat the HtmlTextAreaElement // as an &EventTarget. - let event_target: &EventTarget = text_area.as_ref(); } diff --git a/website/docs/concepts/function-components/properties.mdx b/website/docs/concepts/function-components/properties.mdx index 2927004e8..02c3f469b 100644 --- a/website/docs/concepts/function-components/properties.mdx +++ b/website/docs/concepts/function-components/properties.mdx @@ -78,11 +78,6 @@ fn App() -> Html { ```rust use yew::{function_component, html, Html}; - - - - - #[function_component] fn HelloWorld() -> Html { html! { "Hello world" } diff --git a/website/docs/concepts/html/events.mdx b/website/docs/concepts/html/events.mdx index 23c0532d7..5ec6c64ab 100644 --- a/website/docs/concepts/html/events.mdx +++ b/website/docs/concepts/html/events.mdx @@ -107,7 +107,7 @@ pub enum Msg { ### Using `JsCast` The [`wasm-bindgen`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/index.html) crate has -a useful trait; [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) +a useful trait: [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html), which allows us to hop and skip our way to the type we want, as long as it implements `JsCast`. We can do this cautiously, which involves some runtime checks and failure types like `Option` and `Result`, or we can do it dangerously. diff --git a/website/docs/concepts/html/lists.mdx b/website/docs/concepts/html/lists.mdx index 6dca5da6c..0795f9aff 100644 --- a/website/docs/concepts/html/lists.mdx +++ b/website/docs/concepts/html/lists.mdx @@ -83,7 +83,7 @@ html! { We have [Keyed list](https://github.com/yewstack/yew/tree/master/examples/keyed_list) example that lets you test the performance improvements, but here is a rough rundown: -1. Go to [Keyed list](https://github.com/yewstack/yew/tree/master/examples/keyed_list) hosted demo +1. Go to [Keyed list hosted demo](https://examples.yew.rs/keyed_list) 2. Add 500 elements. 3. Disable keys. 4. Reverse the list. diff --git a/website/docs/concepts/router.mdx b/website/docs/concepts/router.mdx index 75613394c..17c404f41 100644 --- a/website/docs/concepts/router.mdx +++ b/website/docs/concepts/router.mdx @@ -190,7 +190,7 @@ routes. Except you supply a `to` attribute instead of a `href`. An example usage Struct variants work as expected too: ```rust ,ignore - to={Route::Post { id: "new-yew-release".to_string() }}>{ "Yew v0.19 out now!" }> + to={Route::Post { id: "new-yew-release".to_string() }}>{ "Yew!" }> ``` #### Navigator API diff --git a/website/i18n/ja/code.json b/website/i18n/ja/code.json index 35d8cde51..6eac56132 100644 --- a/website/i18n/ja/code.json +++ b/website/i18n/ja/code.json @@ -123,10 +123,6 @@ "message": "サイドバーを隠す", "description": "The title attribute for collapse button of doc sidebar" }, - "theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel": { - "message": "Toggle the collapsible sidebar category '{label}'", - "description": "The ARIA label to toggle the collapsible sidebar category" - }, "theme.docs.tagDocListPageTitle.nDocsTagged": { "message": "One doc tagged|{count} docs tagged", "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" @@ -207,10 +203,6 @@ "message": "light mode", "description": "The name for the light color mode" }, - "theme.docs.DocCard.categoryDescription": { - "message": "{count} items", - "description": "The default description for a category card in the generated index about how many items this category includes" - }, "theme.docs.versionBadge.label": { "message": "Version: {versionLabel}" }, @@ -230,9 +222,6 @@ "message": "Toggle word wrap", "description": "The title attribute for toggle word wrapping button of code block lines" }, - "theme.SearchBar.noResultsText": { - "message": "No results" - }, "theme.SearchBar.seeAll": { "message": "See all results" }, @@ -308,14 +297,6 @@ "message": "Collapse sidebar category '{label}'", "description": "The ARIA label to collapse the sidebar category" }, - "theme.unlistedContent.title": { - "message": "Unlisted page", - "description": "The unlisted content banner title" - }, - "theme.unlistedContent.message": { - "message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.", - "description": "The unlisted content banner message" - }, "theme.SearchPage.inputPlaceholder": { "message": "検索するキーワードを入力してください", "description": "The placeholder for search page input" diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx new file mode 100644 index 000000000..21be4a958 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/children.mdx @@ -0,0 +1,307 @@ +--- +title: '子コンポーネント' +--- + +:::caution + +`Children` をチェックおよび操作すると、アプリケーションで驚くべきかつ説明が難しい動作が発生することがよくあります。これにより、エッジケースが発生し、通常は予期しない結果が生じる可能性があります。`Children` を操作しようとする場合は、他の方法を検討する必要があります。 + +Yew は、子コンポーネントのプロパティの型として `Html` を使用することをサポートしています。`Children` または `ChildrenRenderer` が必要ない場合は、子コンポーネントとして `Html` を使用することをお勧めします。これは `Children` の欠点がなく、パフォーマンスのオーバーヘッドも低くなります。 + +::: + +## 一般的な使用法 + +_ほとんどの場合、_ コンポーネントに子コンポーネントを持たせる場合、子コンポーネントの型を気にする必要はありません。この場合、以下の例で十分です。 + +````rust +use yew::{html, Component, Context, Html, Properties}; + +#[derive(Properties, PartialEq)] +pub struct ListProps { + #[prop_or_default] + pub children: Html, +} + +pub struct List; + +impl Component for List { + type Message = (); + type Properties = ListProps; + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + html! { +
+ {ctx.props().children.clone()} +
+ } + } +} + +## 高度な使用法 + +### 型指定された子コンポーネント + +特定のタイプのコンポーネントを子コンポーネントとして渡したい場合は、`yew::html::ChildrenWithProps` を使用できます。 + +```rust +use yew::{html, ChildrenWithProps, Component, Context, Html, Properties}; + +pub struct Item; + +impl Component for Item { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, _ctx: &Context) -> Html { + html! { + { "item" } + } + } +} + +#[derive(Properties, PartialEq)] +pub struct ListProps { + #[prop_or_default] + pub children: ChildrenWithProps, +} + +pub struct List; + +impl Component for List { + type Message = (); + type Properties = ListProps; + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + html! { +
+ { for ctx.props().children.iter() } +
+ } + } +} +```` + +## プロパティを持つネストされた子コンポーネント + +コンポーネントがその子コンポーネントを型指定している場合、ネストされたコンポーネントのプロパティにアクセスして変更することができます。 + +```rust +use std::rc::Rc; +use yew::prelude::*; + +#[derive(Clone, PartialEq, Properties)] +pub struct ListItemProps { + value: String, +} + +#[function_component] +fn ListItem(props: &ListItemProps) -> Html { + let ListItemProps { value } = props.clone(); + html! { + + {value} + + } +} + +#[derive(PartialEq, Properties)] +pub struct Props { + pub children: ChildrenWithProps, +} + +#[function_component] +fn List(props: &Props) -> Html { + let modified_children = props.children.iter().map(|mut item| { + let mut props = Rc::make_mut(&mut item.props); + props.value = format!("item-{}", props.value); + item + }); + html! { for modified_children } +} + +html! { + + + + + +}; +``` + +### 列挙型の子コンポーネント + +もちろん、時には子コンポーネントをいくつかの異なるコンポーネントに制限する必要がある場合があります。そのような場合には、Yewについてさらに深く理解する必要があります。 + +ここでは、より良いエルゴノミクスを提供するために [`derive_more`](https://github.com/JelteF/derive_more) を使用しています。使用したくない場合は、各バリアントに対して手動で `From` を実装することができます。 + +```rust +use yew::{ + html, html::ChildrenRenderer, virtual_dom::VChild, Component, + Context, Html, Properties, +}; + +pub struct Primary; + +impl Component for Primary { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, _ctx: &Context) -> Html { + html! { + { "Primary" } + } + } +} + +pub struct Secondary; + +impl Component for Secondary { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, _ctx: &Context) -> Html { + html! { + { "Secondary" } + } + } +} + +#[derive(Clone, derive_more::From, PartialEq)] +pub enum Item { + Primary(VChild), + Secondary(VChild), +} + +// 現在、`Into` を実装して、yew が `Item` をどのようにレンダリングするかを知ることができるようにします。 +#[allow(clippy::from_over_into)] +impl Into for Item { + fn into(self) -> Html { + match self { + Self::Primary(child) => child.into(), + Self::Secondary(child) => child.into(), + } + } +} + +#[derive(Properties, PartialEq)] +pub struct ListProps { + #[prop_or_default] + pub children: ChildrenRenderer, +} + +pub struct List; + +impl Component for List { + type Message = (); + type Properties = ListProps; + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + html! { +
+ { for ctx.props().children.iter() } +
+ } + } +} +``` + +### オプションの型の子コンポーネント + +特定の型の単一のオプションの子コンポーネントを持つこともできます: + +```rust +use yew::{ + html, html_nested, virtual_dom::VChild, Component, + Context, Html, Properties +}; + +pub struct PageSideBar; + +impl Component for PageSideBar { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, _ctx: &Context) -> Html { + html! { + { "sidebar" } + } + } +} + +#[derive(Properties, PartialEq)] +pub struct PageProps { + #[prop_or_default] + pub sidebar: Option>, +} + +struct Page; + +impl Component for Page { + type Message = (); + type Properties = PageProps; + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + html! { +
+ { ctx.props().sidebar.clone().map(Html::from).unwrap_or_default() } + // ... ページ内容 +
+ } + } +} + +// ページコンポーネントはサイドバーを含むかどうかを選択できます: + +pub fn render_page(with_sidebar: bool) -> Html { + if with_sidebar { + // サイドバーを含むページ + html! { + + }} /> + } + } else { + // サイドバーを含まないページ + html! { + + } + } +} +``` + +## さらに読む + +- このパターンの実際の例については、yew-router のソースコードを参照してください。より高度な例については、yew リポジトリの[関連する例のリスト](https://github.com/yewstack/yew/tree/master/examples/nested_list)を参照してください。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/how-it-works.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/how-it-works.mdx index c0a15e943..44acf7c19 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/how-it-works.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/how-it-works.mdx @@ -1,8 +1,39 @@ --- -title: How it works -description: Low level details about the framework +title: '仕組み' +description: 'フレームワークの低レベルの詳細について' --- -# 低レベルなライブラリの中身 +# 基本ライブラリの内部詳細 -コンポーネントのライフサイクルの状態機械、VDOM の異なるアルゴリズム +## `html!` マクロの内部 + +`html!` マクロは、HTMLに似たカスタム構文で記述されたコードを有効なRustコードに変換します。このマクロを使用することはYewアプリケーションの開発に必須ではありませんが、推奨されています。このマクロが生成するコードはYewのパブリックライブラリAPIを使用しており、希望すれば直接使用することもできます。いくつかのメソッドは意図的に文書化されていないため、誤用を避けるために注意が必要です。`yew-macro`の各更新により、生成されるコードはより効率的になり、`html!`構文をほとんど(または全く)変更することなく破壊的な変更を処理できるようになります。 + +`html!` マクロを使用すると、宣言的なスタイルでコードを記述できるため、UIレイアウトコードはページのHTMLに非常に似たものになります。アプリケーションがよりインタラクティブになり、コードベースが大きくなるにつれて、この方法はますます有用になります。DOM 操作のすべてのコードを手動で記述するのに比べて、マクロがこれらすべてを処理してくれます。 + +`html!` マクロの使用は非常に魔法のように感じるかもしれませんが、隠すべきものは何もありません。その仕組みに興味がある場合は、プログラム内の `html!` マクロ呼び出しを展開してみてください。`cargo expand` という便利なコマンドがあり、Rustマクロの展開を確認できます。`cargo expand` はデフォルトで `cargo` に含まれていないため、まだインストールしていない場合は `cargo install cargo-expand` を使用してインストールする必要があります。[Rust-Analyzer](https://rust-analyzer.github.io/) も[IDEからマクロ出力を取得するメカニズム](https://rust-analyzer.github.io/manual.html#expand-macro-recursively)を提供しています。 + +`html!` マクロの出力は通常非常に簡潔です!これは特徴です:機械生成のコードは時々アプリケーション内の他のコードと衝突することがあります。問題を防ぐために、`proc_macro` は「衛生」ルールに従っています。いくつかの例を以下に示します: + +1. Yewパッケージを正しく参照するために、マクロ生成コードでは `::yew::` を使用し、直接 `yew::` を使用しません。これは `::alloc::vec::Vec::new()` を呼び出すのと同じ理由です。 +2. トレイトメソッド名の衝突を避けるために、`` を使用して正しいトレイトメンバーを使用していることを確認します。 + +## 仮想 DOM とは? + +DOM(「ドキュメントオブジェクトモデル」)は、ブラウザによって管理されるHTMLコンテンツの表現です。「仮想」 DOM は、単にメモリ内の DOM のコピーです。仮想 DOM を管理することで、メモリのオーバーヘッドが増加しますが、ブラウザAPIの使用を回避または遅延させることでバッチ処理と高速な読み取りを実現できます。 + +メモリ内に DOM のコピーを持つことは、宣言的UIを使用するライブラリの使用を促進するのに役立ちます。ユーザーイベントに基づいて DOM を変更するための特定のコードが必要な場合とは異なり、ライブラリは一般的な方法を使用して DOM の「差分」を行うことができます。Yewコンポーネントが更新され、そのレンダリング方法を変更したい場合、Yewライブラリは仮想 DOM の2番目のコピーを構築し、現在画面上に表示されている内容をミラーリングする仮想 DOM と直接比較します。両者の「差分」は増分更新に分解され、ブラウザAPIと共に適用されます。更新が適用されると、古い仮想 DOM のコピーは破棄され、新しいコピーが将来の差分チェックのために保存されます。 + +この「差分」アルゴリズムは、時間の経過とともに最適化され、複雑なアプリケーションのパフォーマンスを向上させることができます。YewアプリケーションはWebAssemblyを介して実行されるため、Yewは将来的により複雑なアルゴリズムを採用する上で競争力を持つと信じています。 + +Yewの仮想 DOM はブラウザの DOM と完全に一対一対応しているわけではありません。DOM 要素を整理するための「リスト」や「コンポーネント」も含まれています。リストは単に要素の順序付きリストである場合もありますが、より強力な場合もあります。各リスト要素に「キー」注釈を追加することで、アプリケーション開発者はリストが変更されたときに差分更新の計算に必要な作業量を最小限に抑えるための追加の最適化をYewに提供できます。同様に、コンポーネントは再レンダリングが必要かどうかを示すカスタムロジックを提供し、パフォーマンスを向上させるのに役立ちます。 + +## Yewスケジューラとコンポーネントスコープのイベントループ + +_貢献ドキュメント - `yew::scheduler` と `yew::html::scope` の仕組みを詳しく説明_ + +## さらなる読み物 + +- [Rustのマクロに関する詳細情報](https://doc.rust-lang.org/stable/book/ch19-06-macros.html) +- [`cargo-expand` に関する詳細情報](https://github.com/dtolnay/cargo-expand) +- [`yew::virtual_dom` のAPIドキュメント](https://docs.rs/yew/*/yew/virtual_dom/index.html) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx new file mode 100644 index 000000000..f05917a13 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/immutable.mdx @@ -0,0 +1,19 @@ +--- +title: 'イミュータブルタイプ' +description: 'Yew のイミュータブルデータ構造' +--- + +## イミュータブルタイプとは? + +これらのタイプは、インスタンス化はできるが値を変更することはできないタイプです。値を更新するには、新しい値をインスタンス化する必要があります。 + +## なぜイミュータブルタイプを使用するのですか? + +React と同様に、プロパティは祖先から子孫に伝播されます。これは、各コンポーネントが更新されるたびにプロパティが存在する必要があることを意味します。したがって、プロパティは理想的には簡単にクローンできるべきです。これを実現するために、通常は `Rc` にラップします。 + +イミュータブルタイプは、コンポーネント間でプロパティの値を低コストでクローンできるため、プロパティの値を保持するのに最適です。 + +## さらに読む + +- [イミュータブルの例](https://github.com/yewstack/yew/tree/master/examples/immutable) +- [Crate `implicit-clone`](https://docs.rs/implicit-clone/) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/optimizations.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/optimizations.mdx index d9db08c0f..cd1f40f9f 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/optimizations.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/optimizations.mdx @@ -1,171 +1,112 @@ --- -title: Optimizations -description: Make your app faster +title: '最適化とベストプラクティス' +sidebar_label: Optimizations +description: 'アプリケーションのパフォーマンスを最適化する' --- -# 最適化とベストプラクティス +## スマートポインタの使用 -## neq_assign +**注意:このセクションで使用されている用語に混乱がある場合は、Rustのマニュアルにある[スマートポインタに関する章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)が役立ちます。** -親コンポーネントから props を受け取った際、`change`メソッドが呼ばれます。 -これはコンポーネントの状態を更新することができるのに加え、コンポーネントが props が変わった際に再レンダリングするかどうかを決める -`ShouldRender`という真偽値を返すことができます。 +再レンダリング時に大量のデータをクローンしてpropsを作成するのを避けるために、スマートポインタを使用してデータ自体ではなくデータへの参照のみをクローンすることができます。propsや子コンポーネントに関連データの参照を渡すことで、データを変更する必要がある子コンポーネントでデータをクローンするのを避けることができます。`Rc::make_mut`を使用してデータをクローンし、変更するための可変参照を取得できます。 -再レンダリングはコストがかかるもので、もし避けられるのであれば避けるべきです。 -一般的なルールとして props が実際に変化した際にのみ再レンダリングすれば良いでしょう。 -以下のコードブロックはこのルールを表しており、props が前と変わったときに`true`を返します。 +これにより、`Component::changed`でのpropの変更がコンポーネントの再レンダリングを必要とするかどうかを判断する際にさらに利点があります。これは、データの値ではなくポインタのアドレス(つまり、データがマシンメモリに格納されている場所)を比較できるためです。2つのポインタが同じデータを指している場合、それらが指しているデータの値は同じでなければなりません。逆は必ずしも真ではないことに注意してください!2つのポインタアドレスが異なる場合でも、基になるデータは同じである可能性があります。この場合、基になるデータを比較する必要があります。 -```rust -use yew::ShouldRender; +この比較を行うには、`PartialEq`(データを比較する際に自動的に使用される等価演算子`==`)ではなく、`Rc::ptr_eq`を使用する必要があります。Rustのドキュメントには、`Rc::ptr_eq`に関する[詳細](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.ptr_eq)があります。 -#[derive(PartialEq)] -struct ExampleProps; +この最適化は、`Copy`を実装していないデータ型に最も有用です。データを安価にコピーできる場合、それをスマートポインタの後ろに置く必要はありません。`Vec`、`HashMap`、`String`などのデータ集約型の構造体に対して、スマートポインタを使用することでパフォーマンスの向上が見込まれます。 -struct Example { - props: ExampleProps, -}; +この最適化は、子コンポーネントが値を更新しない場合に最も効果的であり、親コンポーネントがほとんど更新されない場合にさらに効果的です。これにより、`Rc<_>`は純粋なコンポーネントでpropsの値をラップするのに適した選択肢となります。 -impl Example { - fn change(&mut self, props: ExampleProps) -> ShouldRender { - if self.props != props { - self.props = props; - true - } else { - false - } - } -} -``` +ただし、子コンポーネントでデータを自分でクローンする必要がない限り、この最適化は無駄であり、不要な参照カウントのコストを追加するだけです。Yewのpropsはすでに参照カウントされており、内部でデータのクローンは行われません。 -しかし我々は先に進んでいけます! -この 6 行のボイラープレードは`PartialEq`を実装したものにトレイトとブランケットを用いることで 1 行のコードへと落とし込むことができます。 -[こちら](https://docs.rs/yewtil/*/yewtil/trait.NeqAssign.html)にて`yewtil`クレートの`NewAssign`トレイトを見てみてください。 +## レンダリング関数 -## 効果的にスマートポインタを使う - -**注意: このセクションで使われている用語がわからなければ Rust book は -[スマートポインタについての章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) -があり、非常に有用です。** - -再レンダリングの際に props を作るデータを大量にコピーしないために、スマートポインタを用いてデータ自体ではなくデータへの参照だけを -コピーできます。 -props や子コンポーネントで関連するデータに実データではなく参照を渡すと、子コンポーネントでデータを変更する必要がなければ -データのコピーを避けることができます。 -その際、`Rc::make_mut`によって変更したいデータの変更可能な参照を得ることができます。 - -これにより、props が変更されたときにコンポーネントが再レンダリングされるかどうかを決めるかで`Component::change`に更なる恩恵があります。 -なぜなら、データの値を比較する代わりに元々のポインタのアドレス (つまりデータが保管されている機械のメモリの場所) を比較できるためです。 -2 つのポインターが同じデータを指す場合、それらのデータの値は同じでなければならないのです。 -ただし、その逆は必ずしも成り立たないことに注意してください! -もし 2 つのポインタが異なるのであれば、そのデータは同じである可能性があります。 -この場合はデータを比較するべきでしょう。 - -この比較においては`PartialEq`ではなく`Rc::ptr_eq`を使う必要があります。 -`PartialEq`は等価演算子`==`を使う際に自動的に使われます。 -Rust のドキュメントには[`Rc::ptr_eq`についてより詳しく書いてあります](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.ptr_eq)。 - -この最適化は`Copy`を実装していないデータの型に対して極めて有効なものです。 -もしデータを簡単に変更できるのであれば、スマートポインタに取り換える必要はありません。 -しかし`Vec`や`HashMap`、`String`などのような重たいデータの構造体に対してはスマートポインタを使うことで -パフォーマンスを改善することができるでしょう。 - -この最適化は値がまだ一度も子によって更新されていない場合に極めて有効で、親からほとんど更新されない場合においてもかなり有効です。 -これにより、`Rc<_>s`が純粋なコンポーネントに対してプロパティの値をラップする良い一手となります。 - -## View 関数 - -コードの可読性の理由から`html!`の部分を関数へと移植するのは意味があります。 -これは、インデントを減らすのでコードを読みやすくするだけでなく、良いデザインパターンを産むことにも繋がるのです。 -これらの関数は複数箇所で呼ばれて書くべきコード量を減らせるため、分解可能なアプリケーションを作ることができるのです。 +コードの可読性のために、`html!`の一部の繰り返しコードを専用の分割関数に移行することは通常意味があります。これにより、コードが読みやすくなり、インデントが減り、良いデザインパターンを奨励します。特に、複数の場所で呼び出すことができるこれらの関数を使用して、コード量を減らすことができます。 ## 純粋なコンポーネント -純粋なコンポーネントは状態を変化せず、ただ中身を表示してメッセージを普通の変更可能なコンポーネントへ渡すコンポーネントのことです。 -View 関数との違いとして、純粋なコンポーネントは式の構文\(`{some_view_function()}`\)ではなく -コンポーネントの構文\(``\)を使うことで`html!`マクロの中で呼ばれる点、 -そして実装次第で記憶され (つまり、一度関数が呼ばれれば値は"保存"され、 -同じ引数でもう一度呼ばれても値を再計算する必要がなく最初に関数が呼ばれたときの保存された値を返すことができる)、 -先述の`neq_assign`ロジックを使う別々の props で再レンダリングを避けられる点があります。 +純粋なコンポーネントは、その状態を変更せず、コンテンツを表示し、メッセージを通常の可変コンポーネントに伝播するコンポーネントです。これらは、`html!`マクロ内でコンポーネント構文(``)を使用する点でビュー関数とは異なり、実装に応じてメモ化される可能性があります(これは、一度関数が呼び出されると、その値が「保存」されることを意味し、同じパラメータで複数回呼び出された場合、その値を再計算する必要がなく、最初の関数呼び出しから保存された値を返すだけです)。Yewは内部でpropsを比較するため、propsが変更された場合にのみUIを再レンダリングします。 -Yew は純粋な関数やコンポーネントをサポートしていませんが、外部のクレートを用いることで実現できます。 +## ワークスペースを使用してコンパイル時間を短縮する -## 関数型コンポーネント (a.k.a フック) +Yewの最大の欠点は、コンパイルにかかる時間が長いことです。プロジェクトのコンパイルにかかる時間は、`html!`マクロに渡されるコードの量に関連しているようです。小規模なプロジェクトでは問題にならないようですが、大規模なアプリケーションでは、コンパイラがアプリケーションのために行う作業量を最小限に抑えるためにコードを複数のクレートに分割することが理にかなっています。 -関数型コンポーネントはまだ開発中です! -開発状況については[プロジェクトボード](https://github.com/yewstack/yew/projects/3)に詳しく書いてあります。 +1つの方法として、メインクレートがルーティング/ページ選択を処理し、各ページごとに異なるクレートを作成することが考えられます。各ページは異なるコンポーネントまたは`Html`を生成する大きな関数である可能性があります。アプリケーションの異なる部分を含むクレート間で共有されるコードは、プロジェクトが依存する別のクレートに格納できます。理想的には、すべてのコードを再コンパイルするのではなく、メインクレートと1つのページクレートのみを再コンパイルすることになります。最悪の場合、「共通」クレートで何かを編集した場合、すべての依存コードを再コンパイルする必要があり、元の状態に戻ります。 -## キー付き DOM ノード +メインクレートが重すぎる場合や、深くネストされたページ(例:別のページ上にレンダリングされるページ)を迅速に反復したい場合は、メインページの簡略化された実装を作成し、作業中のコンポーネントを追加でレンダリングするためにサンプルクレートを使用できます。 -## ワークスペースでコンパイル時間を減らす +## バイナリサイズの縮小 -間違いなく Yew を使う上での最大の欠点はコンパイルに時間がかかる点です。 -プロジェクトのコンパイルにかかる時間は`html!`マクロに渡されるコードの量に関係しています。 -これは小さなプロジェクトにはそこまで問題ないようですが、大きなアプリではコードを複数クレートに分割することでアプリに変更が加られた際に -コンパイラの作業量を減らすのが有効です。 +- Rustコードの最適化 +- `cargo.toml`(リリースプロファイルの定義) +- `wasm-opt` を使用してwasmコードを最適化 -一つ可能なやり方として、ルーティングとページ洗濯を担当するメインのクレートを作り、それぞれのページに対して別のクレートを作ることです。 -そうして各ページは異なるコンポーネントか、`Html`を生成する大きな関数となります。 -アプリの異なる部分を含むクレート同士で共有されるコードはプロジェクト全体で依存する分離したクレートに保存されます。 -理想的には 1 回のコンパイルでコード全てを再ビルドせずメインのクレートかどれかのページのクレートを再ビルドするだけにすることです。 -最悪なのは、"共通"のクレートを編集して、はじめに戻ってくることです: -共有のクレートに依存している全てのコード、恐らく全てのコードをコンパイルすることです。 - -もしメインのクレートが重たすぎる、もしくは深くネストしたページ (例えば別ページのトップでレンダリングされるページ) -で速く繰り返したい場合、クレートの例を用いてメインページの実装をシンプルにしたりトップで動かしているコンポーネントをレンダリングできます。 - -## バイナリサイズを小さくする - -- Rust のコードを最適化する -- `cargo.toml` \( release profile を定義 \) -- `wasm-opt`を用いて wasm のコードを最適化する - -**注意: バイナリサイズを小さくするのについては[Rust Wasm Book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)に詳しく書いてあります。** +**注意:バイナリサイズの縮小に関する詳細は、[Rust Wasmマニュアル](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)を参照してください。** ### Cargo.toml -`Cargo.toml`で`[profile.release]`のセクションに設定を書き込むことでリリースビルドを小さくすることが可能です。 +リリースビルドをより小さくするために、`Cargo.toml`の`[profile.release]`セクションで利用可能な設定を使用して構成できます。 -```text +```toml, title=Cargo.toml [profile.release] -# バイナリに含むコードを少なくする +# バイナリサイズを小さくする panic = 'abort' -# コードベース全体での最適化 ( 良い最適化だがビルドが遅くなる) +# コード全体を最適化する(最適化は良くなるが、ビルド速度は遅くなる) codegen-units = 1 -# サイズの最適化( よりアグレッシブに ) +# サイズを最適化する(より積極的なアプローチ) opt-level = 'z' -# サイズの最適化 +# サイズを最適化する # opt-level = 's' -# プログラム全体の分析によるリンク時最適化 +# プログラム全体の解析を使用してリンク時に最適化 lto = true ``` +### 開発版 Cargo 設定 + +Rust と cargo の実験的な開発版機能から追加の利点を得ることもできます。`trunk` の開発版ツールチェーンを使用するには、`RUSTUP_TOOLCHAIN="nightly"` 環境変数を設定します。その後、`.cargo/config.toml` で不安定な rustc 機能を構成できます。不安定機能のドキュメント、特に[`build-std`]および[`build-std-features`]に関する部分を参照して、設定方法を確認してください。 + +```toml, title=".cargo/config.toml" +[unstable] +# rust-srcコンポーネントが必要です。`rustup +nightly component add rust-src` +build-std = ["std", "panic_abort"] +build-std-features = ["panic_immediate_abort"] +``` + +[不安定な機能のリスト]: https://doc.rust-lang.org/cargo/reference/unstable.html +[`build-std`]: https://doc.rust-lang.org/cargo/reference/unstable.html#build-std +[`build-std-features`]: https://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features + +:::caution +開発版のRustコンパイラには、[この例](https://github.com/yewstack/yew/issues/2696)のようなバグが含まれている可能性があるため、定期的に監視し調整する必要があります。これらの実験的なオプションを使用する際は注意が必要です。 +::: + ### wasm-opt -更に`wasm`のコードのサイズを最適化することができます。 +さらに、`wasm` コードのサイズを最適化することができます。 -The Rust Wasm Book には Wasm バイナリのサイズを小さくすることについてのセクションがあります: -[Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html) +Rust Wasm マニュアルには、Wasm バイナリファイルのサイズを縮小する方法に関するセクションがあります:[.wasm サイズの縮小](https://rustwasm.github.io/book/game-of-life/code-size.html) -- `wasm-pack`でデフォルトの`wasm`のコードをリリースビルド時に最適化する -- `wasm-opt`によって直接`wasm`ファイルを最適化する +- `wasm-pack` を使用すると、デフォルトでリリースビルドの `wasm` コードが最適化されます +- `wasm` ファイルに直接 `wasm-opt` を使用する ```text wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm ``` -#### yew/examples/にある例を小さなサイズでビルドする +#### yew/examples/ の 'minimal' サンプルのビルドサイズ -注意: `wasm-pack`は Rust と Wasm のコードへの最適化を組み合わせます。`wasm-bindgen`はこの例では Rust のサイズ最適化を用いていません。 +注意:`wasm-pack` は Rust と Wasm コードの最適化を組み合わせています。この例では、`wasm-bindgen` は Rust のサイズ最適化を行っていません。 -| 使用したツール | サイズ | +| ツールチェーン | サイズ | | :-------------------------- | :----- | | wasm-bindgen | 158KB | | wasm-bindgen + wasm-opt -Os | 116KB | | wasm-pack | 99 KB | -## 参考文献: +## さらに読む -- [The Rust Book のスマートポインタに関する章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) -- [the Rust Wasm Book でのバイナリサイズを小さくすることについて](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size) -- [Rust profiles についてのドキュメント](https://doc.rust-lang.org/cargo/reference/profiles.html) +- [Rust マニュアルのスマート ポインターに関する章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) +- [Rust Wasm マニュアルのコードサイズの縮小に関する章](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size) +- [Rust プロファイルに関するドキュメント](https://doc.rust-lang.org/cargo/reference/profiles.html) - [binaryen プロジェクト](https://github.com/WebAssembly/binaryen) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx new file mode 100644 index 000000000..2b4a84619 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/portals.mdx @@ -0,0 +1,48 @@ +--- +title: 'ポータル (Portals)' +description: 'コンテンツをDOMツリー外のノードにレンダリングする' +--- + +## ポータルとは? + +ポータル (Portal) は、子要素を親コンポーネントのDOM階層外のDOMノードにレンダリングする方法を提供します。`yew::create_portal(child, host)` は `Html` 値を返し、`child` を `host` 要素の子要素としてレンダリングしますが、親コンポーネントの階層下ではありません。 + +## 使用方法 + +ポータルの典型的な用途には、モーダルダイアログやホバーカード、さらに技術的な用途として、要素の [`shadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot) の内容を制御すること、スタイルシートを周囲のドキュメントの `` に添付すること、`` の中央の `` 要素に参照される要素を収集することなどがあります。 + +`yew::create_portal` は低レベルの構成要素であることに注意してください。ライブラリはこれを使用してより高レベルのAPIを実装し、その後アプリケーションはこれらのAPIを使用できます。例えば、ここでは `children` を `yew` 以外の要素にレンダリングするシンプルなモーダルダイアログを示します。この要素は `id="modal_host"` で識別されます。 + +```rust +use yew::prelude::*; + +#[derive(Properties, PartialEq)] +pub struct ModalProps { + #[prop_or_default] + pub children: Html, +} + +#[function_component] +fn Modal(props: &ModalProps) -> Html { + let modal_host = gloo::utils::document() + .get_element_by_id("modal_host") + .expect("Expected to find a #modal_host element"); + + create_portal( + props.children.clone(), + modal_host.into(), + ) +} +``` + +## イベント処理 + +ポータル内部の要素で発生するイベントは、仮想DOMのバブリングに従います。つまり、ポータルが要素の子要素としてレンダリングされる場合、その要素上のイベントリスナーは、ポータル内部から発生するイベントをキャプチャします。たとえポータルが実際のDOM内の無関係な位置にその内容をレンダリングしていてもです。 + +これにより、開発者は使用しているコンポーネントがポータルを使用して実装されているかどうかを気にする必要がなくなります。いずれにせよ、その子要素上で発生するイベントはバブリングします。 + +既知の問題として、ポータルから **閉じた** シャドウルートへのイベントは2回分配されます。1回はシャドウルート内部の要素に対して、もう1回はホスト要素自体に対してです。**開いた** シャドウルートは正常に動作しますので、これが影響する場合は、いつでもバグレポートを提出してください。 + +## さらなる読み物 + +- [ポータルの例](https://github.com/yewstack/yew/tree/master/examples/portals) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx new file mode 100644 index 000000000..910cd926a --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/server-side-rendering.mdx @@ -0,0 +1,184 @@ +--- +title: 'サーバーサイドレンダリング' +description: 'Yewコンポーネントをサーバーサイドでレンダリングする。' +--- + +# サーバーサイドレンダリング (Server-Side Rendering) + +デフォルトでは、Yewコンポーネントはクライアントサイドでレンダリングされます。ユーザーがウェブサイトにアクセスすると、サーバーは実際のコンテンツを含まない骨組みのHTMLファイルとWebAssemblyパッケージをブラウザに送信します。すべてのコンテンツはクライアントサイドでWebAssemblyパッケージによってレンダリングされます。これをクライアントサイドレンダリングと呼びます。 + +この方法はほとんどのウェブサイトにとって有効ですが、いくつかの注意点があります: + +1. ユーザーはWebAssemblyパッケージがダウンロードされ、初期レンダリングが完了するまで何も表示されません。これにより、ネットワークが遅い場合にユーザーエクスペリエンスが悪化する可能性があります。 +2. 一部の検索エンジンは動的にレンダリングされたウェブページのコンテンツをサポートしておらず、サポートしている検索エンジンでも通常は動的なウェブサイトのランキングが低くなります。 + +これらの問題を解決するために、ウェブサイトをサーバーサイドでレンダリングすることができます。 + +## 動作原理 + +Yewはページをサーバーサイドでレンダリングするための `ServerRenderer` を提供しています。 + +Yewコンポーネントをサーバーサイドでレンダリングするには、`ServerRenderer::::new()` を使用してレンダラーを作成し、`renderer.render().await` を呼び出して `` を `String` としてレンダリングします。 + +```rust +use yew::prelude::*; +use yew::ServerRenderer; + +#[function_component] +fn App() -> Html { + html! {
{"Hello, World!"}
} +} + +// この例が CI の WASM 環境で動作することを保証するために `flavor = "current_thread"` を使用しています。 +// マルチスレッドを使用したい場合は、デフォルトの `#[tokio::main]` マクロを使用できます。 +#[tokio::main(flavor = "current_thread")] +async fn no_main() { + let renderer = ServerRenderer::::new(); + + let rendered = renderer.render().await; + + // プリント:
Hello, World!
+ println!("{}", rendered); +} +``` + +## コンポーネントのライフサイクル + +クライアントサイドレンダリングとは異なり、サーバーサイドレンダリング時のコンポーネントのライフサイクルは異なります。 + +コンポーネントが最初に `Html` として正常にレンダリングされるまで、`use_effect`(および `use_effect_with`)以外のすべてのフックは正常に動作します。 + +:::caution ブラウザインターフェースは利用できません! + +`web_sys` などのブラウザ関連のインターフェースは、サーバーサイドレンダリング時には利用できません。これらを使用しようとすると、アプリケーションがクラッシュします。このロジックは `use_effect` または `use_effect_with` に隔離する必要があります。これらはサーバーサイドレンダリング時には実行されないためです。 + +::: + +:::danger 構造化コンポーネント + +サーバーサイドレンダリング時に構造化コンポーネントを使用することは可能ですが、クライアントサイドの安全なロジック(関数コンポーネントの `use_effect` フックなど)とライフサイクルイベントの間には明確な境界がなく、ライフサイクルイベントの呼び出し順序もクライアントとは異なります。 + +さらに、構造化コンポーネントは、すべての子コンポーネントがレンダリングされ `destroy` メソッドが呼び出されるまでメッセージを受け取り続けます。開発者は、コンポーネントに渡される可能性のあるメッセージがブラウザインターフェースを呼び出すロジックにリンクされないようにする必要があります。 + +サーバーサイドレンダリングをサポートするアプリケーションを設計する際は、特別な理由がない限り、関数コンポーネントを使用することをお勧めします。 + +::: + +## サーバーサイドレンダリング中のデータ取得 + +データ取得はサーバーサイドレンダリングとハイドレーション(hydration)中の難点の一つです。 + +従来の方法では、コンポーネントがレンダリングされるとすぐに利用可能になります(仮想DOMを出力してレンダリングします)。コンポーネントがデータを取得する必要がない場合、この方法は有効です。しかし、コンポーネントがレンダリング時にデータを取得しようとするとどうなるでしょうか? + +以前は、Yewにはコンポーネントがまだデータを取得しているかどうかを検出するメカニズムがありませんでした。データ取得クライアントは、初期レンダリング中に何が要求されたかを検出し、要求が完了した後に再レンダリングをトリガーするソリューションを実装する責任がありました。サーバーはこのプロセスを繰り返し、応答を返す前にレンダリング中に追加の保留中の要求がないことを確認します。 + +これは、コンポーネントを繰り返しレンダリングするため、CPUリソースを浪費するだけでなく、データクライアントは、サーバー側で取得したデータをハイドレーション中に利用可能にする方法を提供する必要があり、初期レンダリングで返される仮想DOMがサーバーサイドレンダリングのDOMツリーと一致することを保証する必要があります。これは実現が難しい場合があります。 + +Yewは、`` を使用してこの問題を解決する異なるアプローチを採用しています。 + +`` は特別なコンポーネントで、クライアント側で使用する場合、コンポーネントがデータを取得(保留)している間にフォールバックUIを表示し、データ取得が完了した後に通常のUIに戻る方法を提供します。 + +アプリケーションがサーバーサイドレンダリングされると、Yewはコンポーネントが保留状態でなくなるまで待機し、それを文字列バッファにシリアル化します。 + +ハイドレーション中、`` コンポーネント内の要素は、すべての子コンポーネントが保留状態でなくなるまでハイドレーションされません。 + +この方法により、開発者はサーバーサイドレンダリングに対応したクライアント非依存のアプリケーションを簡単に構築し、データ取得を行うことができます。 + +## SSR ハイドレーション + +## サーバーサイドレンダリングハイドレーション(SSR Hydration) + +ハイドレーションは、Yewアプリケーションをサーバー側で生成されたHTMLファイルに接続するプロセスです。デフォルトでは、`ServerRender` はハイドレーション可能なHTML文字列を出力し、追加情報を含んでハイドレーションを容易にします。`Renderer::hydrate` メソッドを呼び出すと、Yewは最初からレンダリングするのではなく、アプリケーションが生成した仮想DOMとサーバーレンダラーが生成したHTML文字列を調整します。 + +:::caution + +`ServerRenderer` が作成したHTMLマークアップを正常にハイドレーションするためには、クライアントはSSRに使用されたレイアウトと完全に一致する仮想DOMレイアウトを生成する必要があります。要素を含まないコンポーネントも含めてです。特定の実装でのみ使用されるコンポーネントがある場合は、`PhantomComponent` を使用して追加のコンポーネントの位置を埋めることを検討してください。 +::: + +:::warning + +SSR出力(静的HTML)をブラウザが初期レンダリングした後、実際のDOMが期待されるDOMと一致する場合にのみ、ハイドレーションは成功します。HTMLが規格に準拠していない場合、ハイドレーションは失敗する可能性があります。ブラウザは不正なHTMLのDOM構造を変更する可能性があり、実際のDOMが期待されるDOMと異なることがあります。例えば、[`` のない `` がある場合、ブラウザはDOMに `` を追加する可能性があります](https://github.com/yewstack/yew/issues/2684)。 +::: + +## ハイドレーション中のコンポーネントライフサイクル + +ハイドレーション中、コンポーネントは作成後に2回連続してレンダリングされます。すべてのエフェクトは2回目のレンダリングが完了した後に呼び出されます。コンポーネントのレンダリング関数に副作用がないことを確認することが重要です。状態を変更したり、追加のレンダリングをトリガーしたりしないようにしてください。現在、状態を変更したり追加のレンダリングをトリガーしたりするコンポーネントがある場合は、それらを `use_effect` フックに移動してください。 + +ハイドレーション中、構造化コンポーネントを使用してサーバーサイドレンダリングを行うことができます。ビュー関数はレンダリング関数の前に複数回呼び出されます。レンダリング関数が呼び出されるまで、DOMは未接続と見なされ、`rendered()` メソッドが呼び出される前にレンダリングノードにアクセスすることを防ぐ必要があります。 + +## 例 + +```rust ,ignore +use yew::prelude::*; +use yew::Renderer; + +#[function_component] +fn App() -> Html { + html! {
{"Hello, World!"}
} +} + +fn main() { + let renderer = Renderer::::new(); + + // body 要素の下のすべてのコンテンツをハイドレーションし、末尾の要素を削除します(存在する場合)。 + renderer.hydrate(); +} +``` + +例: [simple_ssr](https://github.com/yewstack/yew/tree/master/examples/simple_ssr) +例: [ssr_router](https://github.com/yewstack/yew/tree/master/examples/ssr_router) + +## シングルスレッドモード + +Yewは `yew::LocalServerRenderer` を使用してシングルスレッドでのサーバーサイドレンダリングをサポートしています。このモードはWASIのようなシングルスレッド環境に適しています。 + +```rust +// Rustc 1.78以降では、`wasm32-wasip1` または `wasm32-wasip2` ターゲットを使用してビルドします。 +// 古いバージョンのRustc(1.84以前)を使用している場合は、`wasm32-wasi` ターゲットを使用してビルドすることもできます。 +// 詳細については、https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html を参照してください。 + +use yew::prelude::*; +use yew::LocalServerRenderer; + +#[function_component] +fn App() -> Html { + use yew_router::prelude::*; + + html! { + <> +

{"Yew WASI SSR demo"}

+ + } +} + +pub async fn render() -> String { + let renderer = LocalServerRenderer::::new(); + let html_raw = renderer.render().await; + + let mut body = String::new(); + body.push_str(""); + body.push_str("
"); + body.push_str(&html_raw); + body.push_str("
"); + body.push_str(""); + + body +} + +#[tokio::main(flavor = "current_thread")] +async fn main() { + println!("{}", render().await); +} +``` + +例: [wasi_ssr_module](https://github.com/yewstack/yew/tree/master/examples/wasi_ssr_module) + +:::note +`wasm32-unknown-unknown` ターゲットを使用してSSRアプリケーションをビルドする場合、`not_browser_env` 機能フラグを使用して、Yew内部のブラウザ固有のAPIへのアクセスを無効にすることができます。これは、Cloudflare Workerのようなサーバーレスプラットフォームで非常に便利です。 +::: + +:::caution + +サーバーサイドレンダリングは現在実験的な機能です。バグを見つけた場合は、[GitHubで報告してください](https://github.com/yewstack/yew/issues/new?assignees=&labels=bug&template=bug_report.md&title=)。 + +::: diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/callbacks.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/callbacks.mdx index 7799426a3..17dc93b32 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/callbacks.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/callbacks.mdx @@ -1,35 +1,85 @@ --- -title: Callbacks -description: ComponentLink and Callbacks +title: 'コールバック関数 (Callbacks)' --- -”リンク”コンポーネントはコンポーネントがコールバックを登録できて自身を更新することができるメカニズムです。 +## コールバック関数 (Callbacks) -## ComponentLink API +コールバック関数は、Yew でサービス、エージェント、および親コンポーネントと通信するために使用されます。内部的には、それらの型は `Rc` に包まれた `Fn` に過ぎず、クローンを許可します。 -### callback +それらには `emit` 関数があり、その `` 型を引数として取り、それをターゲットが期待するメッセージに変換します。親コンポーネントのコールバック関数が子コンポーネントに props として提供される場合、子コンポーネントはその `update` ライフサイクルフックでコールバック関数の `emit` 関数を呼び出して、メッセージを親コンポーネントに送信できます。`html!` マクロで props として提供されるクロージャまたは関数は、自動的にコールバック関数に変換されます。 -実行時にコンポーネントの更新メカニズムにメッセージを送信するコールバックを登録します。 -これは、渡されたクロージャから返されるメッセージで `send_self` を呼び出します。 -`Fn(IN) -> Vec`が渡され、`Callback`が返されます。 +シンプルなコールバック関数の使用例は次のようになります: -### send_message +```rust +use yew::{html, Component, Context, Html}; -現在のループが終了した直後にコンポーネントにメッセージを送信し、別の更新ループを開始します。 +enum Msg { + Clicked, +} -### send_message_batch +struct Comp; -実行時に一度に多数のメッセージを一括して送信するコールバックを登録します。 -メッセージによってコンポーネントが再レンダリングされる場合、バッチ内のすべてのメッセージが処理された後、コンポーネントは再レンダリングされます。 -`Fn(IN) -> COMP::Message`が渡され、`Callback`が返されます。 +impl Component for Comp { -## コールバック + type Message = Msg; + type Properties = (); -_\(This might need its own short page.\)_ + fn create(_ctx: &Context) -> Self { + Self + } -コールバックは、Yew 内のサービス、エージェント、親コンポーネントとの通信に使われます。 -これらは単に `Fn` を `Rc` でラップしただけであり、クローンを作成できるようにするためのものです。 + fn view(&self, ctx: &Context) -> Html { + // highlight-next-line + let onclick = ctx.link().callback(|_| Msg::Clicked); + html! { + // highlight-next-line + + } + } +} +``` -これらの関数には `emit` 関数があり、`` 型を引数に取り、それをアドレスが欲しいメッセージに変換します。 -親からのコールバックが子コンポーネントに props で提供されている場合、子は `update` ライフサイクルフックで `emit` をコールバックに呼び出して親にメッセージを返すことができます。 -マクロ内で props として提供されたクロージャや関数は自動的にコールバックに変換されます。 +この関数を `callback` に渡す場合、常に1つの引数を持つ必要があります。例えば、`onclick` ハンドラは `MouseEvent` 型の引数を受け取る関数である必要があります。その後、ハンドラはコンポーネントにどのタイプのメッセージを送信するかを決定できます。このメッセージは無条件に次の更新サイクルにスケジュールされます。 + +更新を引き起こす必要がないコールバック関数が必要な場合は、`batch_callback` を使用してください。 + +```rust +use yew::{events::KeyboardEvent, html, Component, Context, Html}; + +enum Msg { + Submit, +} + +struct Comp; + +impl Component for Comp { + + type Message = Msg; + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + // highlight-start + let onkeypress = ctx.link().batch_callback(|event: KeyboardEvent| { + if event.key() == "Enter" { + Some(Msg::Submit) + } else { + None + } + }); + + html! { + + } + // highlight-end + } +} +``` + +## 関連例 + +- [Counter](https://github.com/yewstack/yew/tree/master/examples/counter) +- [Timer](https://github.com/yewstack/yew/tree/master/examples/timer) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx new file mode 100644 index 000000000..bc8d30434 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/hoc.mdx @@ -0,0 +1,82 @@ +--- +title: '高階コンポーネント' +--- + +いくつかの状況では、構造コンポーネントは特定の機能(例えば Suspense)を直接サポートしていないか、または特定の機能を使用するために大量のボイラープレートコードが必要です(例えば Context)。 + +このような場合、高階コンポーネントの関数コンポーネントを作成することをお勧めします。 + +## 高階コンポーネントの定義 + +高階コンポーネントは、新しい HTML を追加せず、他のコンポーネントをラップして追加機能を提供するコンポーネントです。 + +### 例 + +Context(コンテキスト)フックを使用し、それを構造コンポーネントに渡す例 + +```rust +use yew::prelude::*; + +#[derive(Clone, Debug, PartialEq)] +struct Theme { + foreground: String, + background: String, +} + +#[function_component] +pub fn App() -> Html { + let ctx = use_state(|| Theme { + foreground: "#000000".to_owned(), + background: "#eeeeee".to_owned(), + }); + + html! { + context={(*ctx).clone()}> + + > + } +} + +// highlight-start +#[function_component] +pub fn ThemedButtonHOC() -> Html { + let theme = use_context::().expect("no ctx found"); + + html! {} +} +// highlight-end + +#[derive(Properties, PartialEq)] +pub struct Props { + pub theme: Theme, +} + +struct ThemedButtonStructComponent; + +impl Component for ThemedButtonStructComponent { + type Message = (); + type Properties = Props; + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + let theme = &ctx.props().theme; + html! { + + } + } +} + + + + +``` diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx new file mode 100644 index 000000000..fedf3c692 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/introduction.mdx @@ -0,0 +1,28 @@ +--- +title: '紹介' +description: 'Yew のコンポーネント' +--- + +## コンポーネントとは? + +コンポーネントは Yew の構成要素です。内部状態を管理し、要素を DOM にレンダリングできます。`Component` トレイトを実装することでコンポーネントを作成します。 + +## コンポーネントマークアップの作成 + +Yew は仮想 DOM を使用して要素を DOM にレンダリングします。仮想 DOM ツリーは `html!` マクロを使用して構築できます。`html!` の構文は HTML に似ていますが、同じではありません。ルールもより厳格です。また、条件付きレンダリングやイテレータを使用したリストのレンダリングなどの強力な機能も提供します。 + +:::info +[`html!` マクロ、その使用方法、および構文についてさらに詳しく知る](concepts/html/introduction.mdx) +::: + +## コンポーネントにデータを渡す + +Yew コンポーネントは _props_ を使用して親コンポーネントと子コンポーネント間で通信します。親コンポーネントは任意のデータを props として子コンポーネントに渡すことができます。Props は HTML 属性に似ていますが、任意の Rust 型を props として渡すことができます。 + +:::info +[props についてさらに詳しく知る](advanced-topics/struct-components/properties.mdx) +::: + +:::info +親/子通信以外の通信には、[コンテキスト](../../concepts/contexts.mdx) を使用してください +::: diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/lifecycle.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/lifecycle.mdx index 274c3d815..9007bb653 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/lifecycle.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/lifecycle.mdx @@ -1,175 +1,248 @@ --- -title: Introduction -description: Components and their lifecycle hooks +title: 'ライフサイクル' +description: 'コンポーネントとそのライフサイクルフック' --- -## コンポーネントとは? - -コンポーネントは Yew を構成するブロックです。 -コンポーネントは状態を管理し、自身を DOM へレンダリングすることができます。 -コンポーネントはライフサイクルの機能がある`Component`トレイトを実装することによって作られます。 +`Component` トレイトには、実装する必要がある多くのメソッドがあります。Yew はコンポーネントのライフサイクルのさまざまな段階でこれらのメソッドを呼び出します。 ## ライフサイクル -:::important contribute -`Contribute to our docs:` [Add a diagram of the component lifecycle](https://github.com/yewstack/docs/issues/22) +:::important ドキュメントの改善 +`ドキュメントに貢献する:` [カスタムライフサイクルを持つコンポーネントの例を追加](https://github.com/yewstack/yew/issues/1915) ::: -## ライフサイクルのメソッド +## ライフサイクルメソッド ### Create -コンポーネントが作られると、`ComponentLink`と同様に親コンポーネントからプロパティを受け取ります。 -プロパティはコンポーネントの状態を初期化するのに使われ、"link"はコールバックを登録したりコンポーネントにメッセージを送るのに使われます。 - -props と link をコンポーネント構造体に格納するのが一般的です。 -例えば: +コンポーネントが作成されるとき、それは親コンポーネントからプロパティを受け取り、それらは `create` メソッドに渡される `Context` に保存されます。これらのプロパティはコンポーネントの状態を初期化するために使用でき、"link" はコールバックを登録したり、コンポーネントにメッセージを送信したりするために使用できます。 ```rust -pub struct MyComponent { - props: Props, - link: ComponentLink, -} +use yew::{Component, Context, html, Html, Properties}; + +#[derive(PartialEq, Properties)] +pub struct Props; + +pub struct MyComponent; impl Component for MyComponent { + type Message = (); type Properties = Props; - // ... - fn create(props: Self::Properties, link: ComponentLink) -> Self { - MyComponent { props, link } + // highlight-start + fn create(ctx: &Context) -> Self { + MyComponent } + // highlight-end - // ... -} -``` - -### View - -コンポーネントは`view()`メソッドによってレイアウトを宣言します。 -Yew は`html!`マクロによって HTML と SVG ノード、リスナー、子コンポーネントを宣言できます。 -マクロは React の JSX のような動きをしますが、JavaScript の代わりに Rust の式を用います。 - -```rust -impl Component for MyComponent { - // ... - - fn view(&self) -> Html { - let onclick = self.link.callback(|_| Msg::Click); + fn view(&self, _ctx: &Context) -> Html { html! { - + // 具体的な実装 } } } ``` -使い方については[`html!`ガイド](concepts/html/introduction.mdx)をご確認ください。 +### View + +`view` メソッドは、コンポーネントがDOMにどのようにレンダリングされるべきかを記述することを可能にします。Rust関数を使用してHTMLに似たコードを書くことは非常に混乱する可能性があるため、Yewは`html!`マクロを提供しています。これにより、HTMLおよびSVGノードを宣言し(およびそれらに属性とイベントリスナーを追加し)、子コンポーネントを便利にレンダリングする方法が提供されます。このマクロは、ReactのJSXに似ています(プログラミング言語の違いを除いて)。一つの違いは、YewがSvelteのようなプロパティの簡略化された構文を提供している点です。ここでは、`{onclick}`とだけ書くことができ、`onclick={onclick}`と書く必要はありません。 + +```rust +use yew::{Component, Context, html, Html, Properties}; + +enum Msg { + Click, +} + +#[derive(PartialEq, Properties)] +struct Props { + button_text: String, +} + +struct MyComponent; + +impl Component for MyComponent { + type Message = Msg; + type Properties = Props; + + fn create(_ctx: &Context) -> Self { + Self + } + + // highlight-start + fn view(&self, ctx: &Context) -> Html { + let onclick = ctx.link().callback(|_| Msg::Click); + html! { + + } + } + // highlight-end +} +``` + +使用方法の詳細については、[html! ガイド](concepts/html/introduction.mdx) を参照してください。 ### Rendered -`rendered()`コンポーネントのライフサイクルのメソッドは`view()`が処理されたて Yew がコンポーネントをレンダリングした後、 -ブラウザがページを更新する前に呼ばれます。 -コンポーネントは、コンポーネントが要素をレンダリングした後にのみ実行できるアクションを実行するため、このメソッドを実装したい場合があります。 -コンポーネントが初めてレンダリングされたかどうかは `first_render` パラメータで確認できます。 +`rendered` コンポーネントライフサイクルメソッドは、`view` が呼び出され、Yew がその結果を DOM にレンダリングした後、ブラウザがページを更新する前に呼び出されます。このメソッドは、コンポーネントが要素をレンダリングした後にのみ完了できる操作を実行したい場合に非常に便利です。また、`first_render` という名前のパラメーターがあり、この関数が最初のレンダリング時に呼び出されたか、後続のレンダリング時に呼び出されたかを判断するために使用できます。 ```rust -use stdweb::web::html_element::InputElement; -use stdweb::web::IHtmlElement; -use yew::prelude::*; +use web_sys::HtmlInputElement; +use yew::{ + Component, Context, html, Html, NodeRef, +}; pub struct MyComponent { node_ref: NodeRef, } impl Component for MyComponent { - // ... + type Message = (); + type Properties = (); - fn view(&self) -> Html { + fn create(_ctx: &Context) -> Self { + Self { + node_ref: NodeRef::default(), + } + } + + fn view(&self, ctx: &Context) -> Html { html! { } } - fn rendered(&mut self, first_render: bool) { + // highlight-start + fn rendered(&mut self, _ctx: &Context, first_render: bool) { if first_render { - if let Some(input) = self.node_ref.try_into::() { + if let Some(input) = self.node_ref.cast::() { input.focus(); } } } + // highlight-end } ``` :::tip note -ライフサイクルメソッドは実装の必要がなく、デフォルトでは何もしません。 +このライフサイクルメソッドは実装する必要はなく、デフォルトでは何も実行しません。 ::: ### Update -コンポーネントは動的で、非同期メッセージを受信するために登録することができます。 -ライフサイクルメソッド `update()` はメッセージごとに呼び出されます。 -これにより、コンポーネントはメッセージが何であったかに基づいて自身を更新し、自身を再レンダリングする必要があるかどうかを判断することができます。 -メッセージは、HTML 要素リスナーによってトリガーされたり、子コンポーネント、エージェント、サービス、または Futures によって送信されたりします。 +コンポーネントとの通信は主にメッセージを通じて行われ、これらのメッセージは `update` ライフサイクルメソッドによって処理されます。これにより、コンポーネントはメッセージに基づいて自身を更新し、再レンダリングが必要かどうかを判断できます。メッセージはイベントリスナー、子コンポーネント、エージェント、サービス、またはフューチャーによって送信されることがあります。 -`update()`がどのようなのかについての例は以下の通りです: +以下は `update` の実装例です: ```rust +use yew::{Component, Context, html, Html}; + +// highlight-start pub enum Msg { SetInputEnabled(bool) } +// highlight-end -impl Component for MyComponent { - type Message = Msg; - - // ... - - fn update(&mut self, msg: Self::Message) -> ShouldRender { - match msg { - Msg::SetInputEnabled(enabled) => { - if self.input_enabled != enabled { - self.input_enabled = enabled; - true // Re-render - } else { - false - } - } - } - } +struct MyComponent { + input_enabled: bool, } -``` -### Change - -コンポーネントは親によって再レンダリングされることがあります。 -このような場合、新しいプロパティを受け取り、再レンダリングを選択する可能性があります。 -この設計では、プロパティを変更することで、親から子へのコンポーネントの通信が容易になります。 - -典型的な実装例は以下の通りです: - -```rust impl Component for MyComponent { - // ... + // highlight-next-line + type Message = Msg; + type Properties = (); - fn change(&mut self, props: Self::Properties) -> ShouldRender { - if self.props != props { - self.props = props; - true - } else { - false + fn create(_ctx: &Context) -> Self { + Self { + input_enabled: false, } } + + // highlight-start + fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { + match msg { + Msg::SetInputEnabled(enabled) => { + if self.input_enabled != enabled { + self.input_enabled = enabled; + true // 再レンダリング + } else { + false + } + } + } + } + // highlight-end + + fn view(&self, _ctx: &Context) -> Html { + html! { + // 具体的な実装 + } + } + } ``` +### Changed + +コンポーネントは親コンポーネントによって再レンダリングされることがあります。この場合、新しいプロパティを受け取り、再レンダリングが必要になることがあります。この設計により、プロパティの値を変更するだけで親子コンポーネント間の通信が促進されます。プロパティが変更されると、デフォルトの実装によりコンポーネントが再レンダリングされます。 + ### Destroy -コンポーネントが DOM からアンマウントされた後、Yew は `destroy()` ライフサイクルメソッドを呼び出し、必要なクリーンアップ操作をサポートします。 -このメソッドはオプションで、デフォルトでは何もしません。 +コンポーネントがDOMからアンマウントされると、Yewは`destroy`ライフサイクルメソッドを呼び出します。コンポーネントが破棄される前にクリーンアップ操作を実行する必要がある場合に便利です。このメソッドはオプションであり、デフォルトでは何も実行しません。 -## Associated Types +### 無限ループ -`Component`トレイトは 2 つの関連型があります: `Message`と`Properties`です。 +Yewのライフサイクルメソッドでは無限ループが発生する可能性がありますが、それは各レンダリング後に同じコンポーネントを更新し、その更新が再レンダリングを要求する場合にのみ発生します。 + +以下は簡単な例です: ```rust +use yew::{Context, Component, Html}; + +struct Comp; + +impl Component for Comp { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn update(&mut self, _ctx: &Context, _msg: Self::Message) -> bool { + // どのメッセージでも常に再レンダリングを要求します + true + } + + fn view(&self, _ctx: &Context) -> Html { + // レンダリングする内容は重要ではありません + Html::default() + } + + fn rendered(&mut self, ctx: &Context, _first_render: bool) { + // この新しいメッセージを使用してコンポーネントを更新するように要求します + ctx.link().send_message(()); + } +} +``` + +ここで何が起こっているのか見てみましょう: + +1. `create` 関数を使用してコンポーネントを作成します。 +2. `view` メソッドを呼び出して、Yew がブラウザの DOM にレンダリングする内容を知ることができます。 +3. `rendered` メソッドを呼び出し、`Context` リンクを使用して更新メッセージをスケジュールします。 +4. Yew がレンダリングフェーズを完了します。 +5. Yew はスケジュールされたイベントをチェックし、更新メッセージキューが空でないことを確認してメッセージを処理します。 +6. `update` メソッドを呼び出し、変更が発生し、コンポーネントが再レンダリングする必要があることを示す `true` を返します。 +7. ステップ2に戻ります。 + +`rendered` メソッドで更新をスケジュールすることは依然として可能であり、これは通常便利ですが、その際にはこのループをどのように終了させるかを考慮してください。 + +## 関連タイプ + +`Component` トレイトには、`Message` と `Properties` の2つの関連タイプがあります。 + +```rust ,ignore impl Component for MyComponent { type Message = Msg; type Properties = Props; @@ -178,21 +251,23 @@ impl Component for MyComponent { } ``` -`Message`はコンポーネントによって処理され、何らかの副作用を引き起こすことができるさまざまなメッセージを表します。 -例えば、API リクエストをトリガーしたり、UI コンポーネントの外観を切り替えたりする `Click` メッセージがあります。 -コンポーネントのモジュールで `Msg` という名前の列挙型を作成し、それをコンポーネントのメッセージ型として使用するのが一般的です。 -"message"を"msg"と省略するのも一般的です。 +`Message` タイプは、イベントが発生した後にコンポーネントにメッセージを送信するために使用されます。例えば、ユーザーがボタンをクリックしたり、ページをスクロールしたりしたときに何かを実行したい場合があります。コンポーネントは通常、複数のイベントに応答する必要があるため、`Message` タイプは通常、処理するイベントごとにバリアントを持つ列挙型です。 + +コードベースを整理する際には、`Message` タイプの定義をコンポーネントを定義する同じモジュールに含めるのが賢明です。メッセージタイプの命名に一貫した命名規則を採用することが役立つ場合があります。一つのオプション(唯一のオプションではありませんが)は、タイプを `ComponentNameMsg` と命名することです。例えば、コンポーネントが `Homepage` と名付けられている場合、タイプを `HomepageMsg` と命名することができます。 ```rust enum Msg { Click, + FormInput(String) } ``` -`Properties`は、親からコンポーネントに渡される情報を表します。 -この型は Properties trait を実装していなければならず\(通常はこれを派生させることで\)、特定のプロパティが必須かオプションかを指定することができます。 -この型は、コンポーネントの作成・更新時に使用されます。 -コンポーネントのモジュール内に `Props` という構造体を作成し、それをコンポーネントの `Properties` 型として使用するのが一般的です。 -”Properties”を"props"に短縮するのが一般的です。 -Props は親コンポーネントから継承されるので、アプリケーションのルートコンポーネントは通常`()`型の`Properties`を持ちます。 -ルートコンポーネントのプロパティを指定したい場合は、`App::mount_with_props`メソッドを利用します。 +`Properties` は、親コンポーネントからコンポーネントに渡される情報を表します。この型は `Properties` トレイトを実装する必要があり(通常はそれを派生させる)、特定のプロパティが必須かオプションかを指定できます。コンポーネントの作成および更新時にこの型が使用されます。コンポーネントのモジュール内で `Props` という名前の構造体を作成し、それをコンポーネントの `Properties` 型として使用するのが一般的な方法です。通常、"properties" は "props" と略されます。プロパティは親コンポーネントから渡されるため、アプリケーションのルートコンポーネントは通常、`Properties` 型として `()` を持ちます。ルートコンポーネントにプロパティを指定する場合は、`App::mount_with_props` メソッドを使用します。 + +:::info +[プロパティに関する詳細はこちら](./properties) +::: + +## ライフサイクルコンテキスト + +すべてのコンポーネントライフサイクルメソッドは、コンテキストオブジェクトを受け取ります。このオブジェクトは、コンポーネントのスコープへの参照を提供し、コンポーネントにメッセージを送信したり、コンポーネントに渡されたプロパティを取得したりすることができます。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/properties.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/properties.mdx index 560f9c1e6..b4518bba3 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/properties.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/properties.mdx @@ -1,52 +1,52 @@ --- -title: Properties -description: Parent to child communication +title: 'プロパティ (Props)' +description: '親子コンポーネント間の通信' --- -プロパティは、子コンポーネントと親コンポーネントが互いに通信できるようにします。 +プロパティ (Properties) は、子コンポーネントと親コンポーネントの間で通信を可能にします。各コンポーネントには、親コンポーネントから渡される内容を記述するための関連プロパティ型があります。理論的には、これは `Properties` トレイトを実装した任意の型である可能性がありますが、実際には、各フィールドがプロパティを表す構造体であるべきです。 -## マクロの継承 +## 派生マクロ -`Properties`を自分で実装しようとせず、代わりに`#[derive(Properties)]`を使ってください。 +`Properties` トレイトを自分で実装する必要はありません。`#[derive(Properties)]` を使用して実装を自動生成できます。`Properties` を派生する型は `PartialEq` も実装する必要があります。 -:::note -`Properties`を継承した型は`Clone`を実装していなければいけません。 -これは`#[derive(Properties, Clone)`か`Clone`を手で実装することで可能です。 +### フィールド属性 + +`Properties` を派生する際、デフォルトではすべてのフィールドが必須です。以下の属性を使用すると、他の値が設定されていない限り、プロパティに初期値を提供できます。 + +:::tip +プロパティは Rustdoc によって生成されたドキュメントには表示されません。プロパティのドキュメント文字列には、そのプロパティがオプションであるかどうか、または特別なデフォルト値があるかどうかを記載する必要があります。 ::: -### 必要な属性 +#### `#[prop_or_default]` -デフォルトでは、`Properties` を導出する構造体内のフィールドは必須です。 -フィールドが欠落していて `html!` マクロでコンポーネントが作成された場合、コンパイラエラーが返されます。 -オプションのプロパティを持つフィールドについては、`#[prop_or_default]` 属性を使用して、prop が指定されていない場合はその型のデフォルト値を使用します。 -値を指定するには `#[prop_or(value)]` 属性を用います。 -ここで value はプロパティのデフォルト値、あるいは代わりに `#[prop_or_else(function)]` を使用して、`function` はデフォルト値を返します。 -例えば、ブール値のデフォルトを `true` とするには、属性 `#[prop_or(true)]` を使用します。オプションのプロパティでは、デフォルト値 `None` を持つ `Option` 列挙型を使うのが一般的です。 +フィールド型のデフォルト値を使用してプロパティ値を初期化します。これは `Default` トレイトを使用します。 -### PartialEq +#### `#[prop_or(value)]` -もし可能なら props で `PartialEq` を継承するのが良いかもしれません。 -`PartialEq`を使うことで、不必要な再レンダリングを避けることができます -(これについては、**最適化とベストプラクティス**のセクションで説明しています)。 +`value` を使用してプロパティ値を初期化します。`value` はフィールド型を返す任意の式である可能性があります。例えば、ブールプロパティをデフォルトで `true` にするには、属性 `#[prop_or(true)]` を使用します。 -## プロパティを使用する際のメモリと速度のオーバーヘッド +#### `#[prop_or_else(function)]` -`Compoenent::view`ではコンポーネントの状態への参照を取り、それを使って `Html` を作成します。 -しかし、プロパティは自身の値です。 -つまり、それらを作成して子コンポーネントに渡すためには、`view` 関数で提供される参照を所有する必要があるのです。 -これは所有する値を取得するためにコンポーネントに渡される参照を暗黙のうちにクローンすることで行われます。 +`function` を呼び出してプロパティ値を初期化します。`function` は `FnMut() -> T` のシグネチャを持つ必要があります。ここで、`T` はフィールド型です。 -これは、各コンポーネントが親から受け継いだ状態の独自のコピーを持っていることを意味し、コンポーネントを再レンダリングするときはいつでも、再レンダリングしたコンポーネントのすべての子コンポーネントの props がクローンされなければならないことを意味します。 +## `PartialEq` -このことの意味するところは、もしそうでなければ*大量の*データ \(10KB もあるような文字列\) を props として渡してしまうのであれば、子コンポーネントを親が呼び出す `Html` を返す関数にすることを考えた方がいいかもしれないということです。 +`Properties` は `PartialEq` を実装する必要があります。これにより、Yew はそれらを比較し、変更があった場合に `changed` メソッドを呼び出すことができます。 -props を介して渡されたデータを変更する必要がない場合は、実際のデータそのものではなく、データへの参照カウントされたポインタのみが複製されるように `Rc` でラップすることができます。 +## Properties のパフォーマンスオーバーヘッド + +内部プロパティは参照カウントされたポインタに基づいて格納されます。これにより、コンポーネントツリーに渡されるプロパティにはポインタのみが渡され、プロパティ全体をクローンすることによる高価なパフォーマンスオーバーヘッドを回避できます。 + +:::tip +`AttrValue` を使用してください。これは、クローンが必要な String やその他の類似の型を使用せずに済むようにするために提供されているカスタムプロパティ値型です。 +::: ## 例 ```rust -use std::rc::Rc; use yew::Properties; +/// virtual_dom から AttrValue をインポート +use yew::virtual_dom::AttrValue; #[derive(Clone, PartialEq)] pub enum LinkColor { @@ -57,28 +57,78 @@ pub enum LinkColor { Purple, } -impl Default for LinkColor { - fn default() -> Self { - // The link color will be blue unless otherwise specified. - LinkColor::Blue - } +fn create_default_link_color() -> LinkColor { + LinkColor::Blue } -#[derive(Properties, Clone, PartialEq)] +#[derive(Properties, PartialEq)] pub struct LinkProps { - /// The link must have a target. - href: String, - /// If the link text is huge, this will make copying the string much cheaper. - /// This isn't usually recommended unless performance is known to be a problem. - text: Rc, - /// Color of the link. - #[prop_or_default] + /// リンクにはターゲットが必要です + href: AttrValue, + /// また、String ではなく AttrValue を使用していることに注意してください + text: AttrValue, + /// リンクの色、デフォルトは `Blue` + #[prop_or_else(create_default_link_color)] color: LinkColor, - /// The view function will not specify a size if this is None. + /// 値が None の場合、ビュー関数はサイズを指定しません #[prop_or_default] size: Option, - /// When the view function doesn't specify active, it defaults to true. + /// ビュー関数がアクティブを指定しない場合、デフォルトは true #[prop_or(true)] active: bool, } ``` + +## Props マクロ + +`yew::props!` マクロを使用すると、`html!` マクロと同じ方法でプロパティを構築できます。 + +このマクロは構造体の式と同じ構文を使用しますが、属性や基本式 (`Foo { ..base }`) を使用することはできません。型パスはプロパティ (`path::to::Props`) に直接指すことも、コンポーネントの関連プロパティ (`MyComp::Properties`) に指すこともできます。 + +```rust +use yew::{props, Properties, virtual_dom::AttrValue}; + +#[derive(Clone, PartialEq)] +pub enum LinkColor { + Blue, + Red, + Green, + Black, + Purple, +} + +fn create_default_link_color() -> LinkColor { + LinkColor::Blue +} + +#[derive(Properties, PartialEq)] +pub struct LinkProps { + /// リンクにはターゲットが必要です + href: AttrValue, + /// また、String ではなく AttrValue を使用していることに注意してください + text: AttrValue, + /// リンクの色、デフォルトは `Blue` + #[prop_or_else(create_default_link_color)] + color: LinkColor, + /// 値が None の場合、ビュー関数はサイズを指定しません + #[prop_or_default] + size: Option, + /// ビュー関数がアクティブを指定しない場合、デフォルトは true + #[prop_or(true)] + active: bool, +} + +impl LinkProps { + /// この関数は href と text を String として受け取ります + /// `AttrValue::from` を使用してそれらを `AttrValue` に変換できます + pub fn new_link_with_size(href: String, text: String, size: u32) -> Self { + // highlight-start + props! {LinkProps { + href: AttrValue::from(href), + text: AttrValue::from(text), + size, + }} + // highlight-end + } +} +``` diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/refs.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/refs.mdx index bfaf178cc..d1902c420 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/refs.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/refs.mdx @@ -1,24 +1,51 @@ --- -title: Refs -description: Out-of-band DOM access +title: '参照 (Refs)' +description: 'DOM への越境アクセスを実現する' --- -`ref`は、任意の HTML 要素やコンポーネントの内部で、割り当てられている DOM`Element`を取得するために使用することができます。 -これは、`view` ライフサイクルメソッドの外で DOM に変更を加えるために使用できます。 +`ref` キーワードは、任意の HTML 要素やコンポーネントに使用して、その要素に付随する DOM `Element` を取得できます。これにより、`view` ライフサイクルメソッドの外で DOM を変更することができます。 -これは、キャンバスの要素を取得したり、ページの異なるセクションにスクロールしたりするのに便利です。 +これは、canvas 要素を取得したり、ページの異なる部分にスクロールしたりするのに便利です。例えば、コンポーネントの `rendered` メソッドで `NodeRef` を使用すると、`view` からレンダリングされた後に canvas 要素に描画呼び出しを行うことができます。 -構文は以下の通りです: +構文は次のとおりです: ```rust -// In create -self.node_ref = NodeRef::default(); +use web_sys::Element; +use yew::{html, Component, Context, Html, NodeRef}; -// In view -html! { -
+struct Comp { + node_ref: NodeRef, } -// In update -let has_attributes = self.node_ref.try_into::().has_attributes(); +impl Component for Comp { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self { + // highlight-next-line + node_ref: NodeRef::default(), + } + } + + fn view(&self, _ctx: &Context) -> Html { + html! { + // highlight-next-line +
+ } + } + + fn rendered(&mut self, _ctx: &Context, _first_render: bool) { + // highlight-start + let has_attributes = self.node_ref + .cast::() + .unwrap() + .has_attributes(); + // highlight-end + } +} ``` + +## 関連例 + +- [ノード参照](https://github.com/yewstack/yew/tree/master/examples/node_refs) diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx new file mode 100644 index 000000000..89ec3fb79 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/advanced-topics/struct-components/scope.mdx @@ -0,0 +1,70 @@ +--- +title: 'スコープ' +description: 'コンポーネントのスコープ' +--- + +## コンポーネントの `Scope<_>` インターフェース + +`Scope` は、メッセージを介してコールバックを作成し、自身を更新するメカニズムです。コンポーネントに渡されるコンテキストオブジェクトで `link()` を呼び出すことで、その参照を取得します。 + +### `send_message` + +この関数は、コンポーネントにメッセージを送信できます。メッセージは `update` メソッドによって処理され、コンポーネントが再レンダリングするかどうかを決定します。 + +### `send_message_batch` + +この関数は、コンポーネントに複数のメッセージを同時に送信できます。これは `send_message` に似ていますが、任意のメッセージが `update` メソッドで `true` を返す場合、バッチ内のすべてのメッセージの処理が完了した後にコンポーネントが再レンダリングされます。 + +指定された引数ベクターが空の場合、この関数は何も実行しません。 + +### `callback` + +コールバックを作成し、実行時にコンポーネントにメッセージを送信します。内部的には、提供されたクロージャが返すメッセージを使用して `send_message` を呼び出します。 + +```rust +use yew::{html, Component, Context, Html}; + +enum Msg { + Text(String), +} + +struct Comp; + +impl Component for Comp { + + type Message = Msg; + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + // テキストを受け取り、それを `Msg::Text` メッセージバリアントとしてコンポーネントに送信するコールバックを作成します。 + // highlight-next-line + let cb = ctx.link().callback(|text: String| Msg::Text(text)); + + // 上の行は冗長であり、より明確にするために次のように簡略化できます: + // highlight-next-line + let cb = ctx.link().callback(Msg::Text); + + // `Msg::Text("Hello World!")` をコンポーネントに送信します。 + // highlight-next-line + cb.emit("Hello World!".to_owned()); + + html! { + // ここに HTML を配置 + } + } +} +``` + +### `batch_callback` + +バッチメッセージを送信するコールバックを作成します。このメソッドに渡されるクロージャはメッセージを返す必要はありません。代わりに、クロージャは `Vec` または `Option` を返すことができます。ここで、`Msg` はコンポーネントのメッセージタイプです。 + +`Vec` はバッチメッセージとして扱われ、内部的に `send_message_batch` を使用します。 + +`Option` は値が `Some` の場合に `send_message` を呼び出します。値が `None` の場合は何も実行しません。これは、更新が不要な場合に使用できます。 + +これは、これらの型に対してのみ実装された `SendAsMessage` トレイトを使用して実現されています。独自の型に対して `SendAsMessage` を実装することで、`batch_callback` でそれらを使用できるようになります。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/agents.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/agents.mdx index efe31f8ef..eb422c9ad 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/agents.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/agents.mdx @@ -1,56 +1,56 @@ --- -title: Agents -description: Yew's Actor System +title: 'エージェント (Agents)' +description: 'Yew のエージェントシステム' --- -エージェントは Angular の[サービス](https://angular.io/guide/architecture-services)に似ており\(ただし依存性インジェクションはありません\)、 -[アクターモデル](https://en.wikipedia.org/wiki/Actor_model)を提供します。 -エージェントはコンポーネント階層のどこに位置するかに関わらず、コンポーネント間でメッセージをルーティングしたり、共有状態を作成したり、UI をレンダリングするメインスレッドから計算量の多いタスクをオフロードするために使用することができます。 -また、Yew アプリケーションがタブをまたいで通信できるようにするためのエージェントのサポートも\(将来的には\)計画されています。 +import useBaseUrl from '@docusaurus/useBaseUrl' +import ThemedImage from '@theme/ThemedImage' -エージェントが並行に動くように Yew は[web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)を使用しています。 +エージェント (Agents) は、タスクを Web Workers にオフロードする方法です。 + +エージェントが並行して動作できるようにするために、Yew は [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) を使用します。 ## ライフサイクル -![エージェントのライフサイクル](https://user-images.githubusercontent.com/42674621/79125224-b6481d80-7d95-11ea-8e6a-ab9b52d1d8ac.png) + + + ## エージェントの種類 -### Reaches +### 範囲 -- Context - Context エージェントのインスタンスは、常に最大 1 つ存在します。 - Bridges は、UI スレッド上で既にスポーンされたエージェントをスポーンするか、接続します。 - これは、コンポーネントまたは他のエージェント間の状態を調整するために使用することができます。 - このエージェントに Bridges が接続されていない場合、このエージェントは消滅します。 +- 公開 - 任意の時点で、公開エージェントのインスタンスは最大で1つだけです。ブリッジはWeb Worker内でエージェントを生成するか、既に生成されたエージェントに接続します。ブリッジがこのエージェントに接続されていない場合、エージェントは消滅します。 -- Job - 新しいブリッジごとに UI スレッド上で新しいエージェントをスポーンします。 - これは、ブラウザと通信する共有されているが独立した動作をコンポーネントの外に移動させるのに適しています。 - (TODO 確認) タスクが完了すると、エージェントは消えます。 +- 私有 - 新しいブリッジごとにWeb Worker内で新しいエージェントを生成します。これは、ブラウザと通信する共有だが独立した動作をコンポーネントから移動するのに適しています。接続されたブリッジが破棄されると、エージェントは消滅します。 -- Public - Context と同じですが、独自の web worker で動作します。 +- グローバル \(WIP\) -- Private - Job と同じですが、独自の web worker で動作します。 +## エージェントとコンポーネント間の通信 -- Global \(WIP\) +### 通信ブリッジ (Bridges) -## エージェントとコンポーネントのやり取り +通信ブリッジ(ブリッジ)は、コンポーネントとエージェント間の通信チャネルです。これにより、コンポーネントはエージェントにメッセージを送信し、エージェントからのメッセージを受信できます。 -### Bridges +`use_bridge` フックは、関数コンポーネント内でブリッジを作成する機能も提供します。 -Bridge は、エージェントとコンポーネント間の双方向通信を可能にします。 -また、Bridge はエージェント同士の通信を可能にします。 +### ディスパッチャー (Dispatchers) -### Dispatchers - -Dispatcher は、コンポーネントとエージェント間の一方向通信を可能にします。 -Dispatcher は、コンポーネントがエージェントにメッセージを送信することを可能にします。 +ディスパッチャー(ディスパッチャー)は、コンポーネントとエージェント間の一方向通信を可能にし、コンポーネントがこの方法でエージェントにメッセージを送信します。 ## オーバーヘッド -独自の独立した web worker(プライベートとパブリック)にあるエージェントは、送受信するメッセージにシリアライズするオーバーヘッドが発生します。 -他のスレッドとの通信には[bincode](https://github.com/servo/bincode)を使用するので、関数を呼び出すよりもコストはかなり高くなります。 -計算コストがメッセージの受け渡しコストを上回る場合を除き、ロジックを UI スレッドエージェント\(Job または Context\)に格納する必要があります。 +エージェントはWeb Workers(つまり、私有および公開)を使用します。メッセージの送受信時にシリアル化オーバーヘッドが発生します。エージェントは [bincode](https://github.com/bincode-org/bincode) を使用して他のスレッドと通信するため、コストは関数を呼び出すだけの場合よりもはるかに高くなります。 -## 参考資料 +## さらなる読み物 -- [web_worker_fib](https://github.com/yewstack/yew/tree/master/examples/web_worker_fib)の例でコンポーネントがどのようにエージェントと通信させているかがわかります。 +- [web_worker_fib](https://github.com/yewstack/yew/tree/master/examples/web_worker_fib) の例は、コンポーネントがエージェントにメッセージを送信し、エージェントからのメッセージを受信する方法を示しています。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx new file mode 100644 index 000000000..fbad27e3d --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/css.mdx @@ -0,0 +1,99 @@ +--- +title: 'classes! マクロを使用して CSS クラスを処理する' +description: '便利なマクロを使用して CSS クラスを処理する' +comment: 'ファイルを短くシンプルに保つようにしてください。これは、読者が Yew のコンポーネントをより理解しやすくするためであり、正確な API ドキュメントを提供するためではありません。' +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +Yew はネイティブの CSS-in-Rust ソリューションを提供していませんが、HTML の `class` 属性とプログラム的に対話する方法を提供することでスタイルを支援します。 + +## `classes!` マクロ + +`classes!` マクロと関連する `Classes` 構造体は、HTML クラスの使用を簡素化します: + + + + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +
+ + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +
+ + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +
+ + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + + + + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +
+ + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +
+ + +詳細な CSS に関する内容は[こちらのドキュメント](../../more/css)をご覧ください。 + +## インラインスタイル + +現在、Yew は `style` 属性を使用して指定されたインラインスタイルを処理するための特別な支援ツールを提供していませんが、他の HTML 属性と同様に処理することができます: + +```rust +use yew::{classes, html}; + +html! { +
+}; +``` + +詳細な CSS に関する内容は[こちらのドキュメント](../../more/css)をご覧ください。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx new file mode 100644 index 000000000..1747d272b --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/html.mdx @@ -0,0 +1,75 @@ +--- +title: 'html! マクロを使用してHTMLを処理する' +description: 'これはHTMLですが、完全にそうではありません!' +comment: 'ファイルを短く簡潔に保つようにしてください。これは、読者がYewのコンポーネントをより簡単に理解できるようにするためであり、正確なAPIドキュメントを提供するためではありません。' +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +`html!` マクロを使用して、HTML に似た式を記述できます。Yew はバックグラウンドでそれを DOM を表現する Rust コードに変換します。 + +```rust +use yew::prelude::*; + +let my_header: Html = html! { + Girl in a jacket +}; +``` + +フォーマットされた式と同様に、波括弧を使用して周囲のコンテキストの値を HTML に埋め込むことができます: + +```rust +use yew::prelude::*; + +let header_text = "Hello world".to_string(); +let header_html: Html = html! { +

{header_text}

+}; + +let count: usize = 5; +let counter_html: Html = html! { +

{"My age is: "}{count}

+}; + +let combined_html: Html = html! { +
{header_html}{counter_html}
+}; +``` + +`html!` を使用する際の重要なルールの 1 つは、1 つのラッピングノードしか返せないということです。複数の要素のリストをレンダリングするために、`html!` は空のタグ(フラグメント)の使用を許可しています。空のタグは名前のないタグで、それ自体は HTML 要素を生成しません。 + + + + +```rust , compile_fail +use yew::html; + +// エラー:ルート HTML 要素は1つだけ許可されています +html! { + +
+

+ +}; +``` + +
+ + +```rust +use yew::html; + +// 修正:HTML 空のタグを使用してラップする +html! { + <> +
+

+ +}; +``` + +
+
+ +詳細については、[HTML の詳細](concepts/html/introduction.mdx)を参照してください。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx new file mode 100644 index 000000000..64d8cf9c8 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/js.mdx @@ -0,0 +1,50 @@ +--- +title: 'JavaScript と Rust' +description: 'Rust で JavaScript を使用する' +comment: 'ファイルを簡潔に保つようにしてください。これは、読者が Yew のコンポーネントをより理解しやすくするためのものであり、正確な API ドキュメントを提供するためのものではありません。' +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +> Yew は、再利用可能な UI 部分に必要なすべてのコンテンツを1か所に集める一方で、必要に応じて基盤技術へのアクセスも維持します。 + +今日現在、WebAssembly は DOM との相互作用を完全にはサポートしていません。これは、Yew でも時々 JavaScript の呼び出しに依存することを意味します。次に、関係するライブラリの概要を示します。 + +## wasm-bindgen + +[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) は、JavaScript と Rust 関数の間に呼び出しの橋を架けるライブラリとツールです。 + +彼らの[ドキュメント](https://rustwasm.github.io/docs/wasm-bindgen/)と私たちの[クイックガイド](./wasm-bindgen.mdx)を強くお勧めします。 + +## web-sys + +[`web-sys` crate](https://crates.io/crates/web-sys) は Web API のバインディングを提供し、Rust で処理され安全な方法で JavaScript コードを書くことを可能にします。 + +例: + + + + +```js +let document = window.document +``` + + + + + +```rust ,no_run +use wasm_bindgen::UnwrapThrowExt; +use web_sys::window; + +let document = window() + .expect_throw("window is undefined") + .document() + .expect_throw("document is undefined"); +``` + + + + +繰り返しになりますが、彼らの[ドキュメント](https://rustwasm.github.io/docs/wasm-bindgen/)と私たちの[クイックガイド](./web-sys.mdx)を強くお勧めします。 diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx new file mode 100644 index 000000000..a07cd5b33 --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/wasm-bindgen.mdx @@ -0,0 +1,177 @@ +--- +title: 'wasm-bindgen' +sidebar_label: wasm-bindgen +--- + +[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) は、JavaScript と Rust 関数の間に呼び出しブリッジを作成するためのライブラリおよびツールです。これは [Rust と WebAssembly ワーキンググループ](https://rustwasm.github.io/) によって Rust で構築されました。 + +Yew は `wasm-bindgen` を使用して、いくつかのクレートを介してブラウザと対話します: + +- [`js-sys`](https://crates.io/crates/js-sys) +- [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen) +- [`wasm-bindgen-futures`](https://crates.io/crates/wasm-bindgen-futures) +- [`web-sys`](https://crates.io/crates/web-sys) + +このセクションでは、これらのクレートをより抽象的なレベルから探求し、Yew での `wasm-bindgen` API の理解と使用を容易にします。`wasm-bindgen` および関連するクレートに関する詳細なガイドについては、[`wasm-bindgen` ガイド](https://rustwasm.github.io/docs/wasm-bindgen/) を参照してください。 + +上記のクレートのドキュメントについては、[`wasm-bindgen docs.rs`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/index.html) を参照してください。 + +:::tip +`wasm-bindgen` doc.rs 検索を使用して、`wasm-bindgen` を使用してインポートされたブラウザ API および JavaScript タイプを見つけます。 +::: + +## [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen) + +このクレートは、上記の他のクレートに多くの構成要素を提供します。このセクションでは、`wasm-bindgen` クレートの主要な領域の 2 つ、つまりマクロと、何度も目にするタイプ/トレイトのいくつかについてのみ説明します。 + +### `#[wasm_bindgen]` マクロ + +`#[wasm_bindgen]` マクロは Rust と JavaScript の間のインターフェースを提供し、両者の間で変換を行うシステムを提供します。このマクロの使用はより高度であり、外部の JavaScript ライブラリを使用する場合を除いて使用しないでください。`js-sys` および `web-sys` クレートは、組み込みの JavaScript タイプおよびブラウザ API に対して `wasm-bindgen` 定義を提供します。 + +`#[wasm-bindgen]` マクロを使用して、特定のバージョンの [`console.log`](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) 関数をインポートする簡単な例を見てみましょう。 + +```rust ,no_run +use wasm_bindgen::prelude::*; + +// まず、`web_sys` を使用せずに `console.log` を手動でバインドしてみましょう。 +// ここでは、手動で `#[wasm_bindgen]` アノテーションを書きます。プログラムの正確性はこれらのアノテーションの正確性に依存します! +#[wasm_bindgen] +extern "C" { + // ここで `js_namespace` を使用して `console.log(..)` をバインドします。`log(..)` だけではありません。 + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); + + // `console.log` は多態的なので、複数のシグネチャを使用してバインドできます。 + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_u32(a: u32); + + // 複数の引数も可能です! + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_many(a: &str, b: &str); +} + +// インポートされた関数を使用します! +log("Hello from Rust!"); +log_u32(42); +log_many("Logging", "many values!"); +``` + +_この例は、[1.2 `wasm-bindgen` ガイドの console.log を使用する](https://rustwasm.github.io/docs/wasm-bindgen/examples/console-log.html) に基づいています。_ + +### 継承のシミュレーション + +JavaScript クラス間の継承は、JavaScript 言語のコア機能であり、DOM(ドキュメントオブジェクトモデル)はそれを中心に設計されています。`wasm-bindgen` を使用して型をインポートする際にも、それらの継承関係を記述する属性を追加できます。 + +Rust では、この継承関係は [`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html) と [`AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) トレイトを使用して表現されます。ここで例を挙げると役立つかもしれません。例えば、`A`、`B`、`C` という 3 つの型があり、`C` が `B` を拡張し、`B` が `A` を拡張しているとします。 + +これらの型をインポートする際、`#[wasm-bindgen]` マクロは次のように `Deref` と `AsRef` トレイトを実装します: + +- `C` は `B` に `Deref` できます +- `B` は `A` に `Deref` できます +- `C` は `B` に `AsRef` できます +- `C` と `B` はどちらも `A` に `AsRef` できます + +これらの実装により、`C` のインスタンスで `A` のメソッドを呼び出したり、`C` を `&B` または `&A` として使用したりできます。 + +注意すべき点は、`#[wasm-bindgen]` を使用してインポートされたすべての型には同じルート型があり、それを上記の例の `A` と見なすことができるということです。この型は [`JsValue`](#jsvalue) であり、以下にそのセクションがあります。 + +_[`wasm-bindgen` ガイドの extends セクション](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/extends.html)_ + +### [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) + +これは JavaScript が所有するオブジェクトの表現であり、`wasm-bindgen` のルートキャプチャ型です。`wasm-bindgen` からの任意の型は `JsValue` です。これは、JavaScript には強い型システムがないため、変数 `x` を受け取る任意の関数がその型を定義しないため、`x` は有効な JavaScript 値である可能性があるためです。したがって `JsValue` です。`JsValue` を受け取るインポート関数や型を使用している場合、技術的には任意のインポート値が有効です。 + +`JsValue` は関数で受け取ることができますが、その関数は特定の型のみを受け取る可能性があり、それがパニックを引き起こす可能性があります。したがって、元の `wasm-bindgen` API を使用する場合は、インポートされた JavaScript のドキュメントを確認して、その値が特定の型でない場合に例外(パニック)を引き起こすかどうかを確認してください。 + +_[`JsValue` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html)_ + +### [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) + +Rust には強い型システムがありますが、JavaScript にはありません😞。Rust がこれらの強い型を維持しながらも便利であるために、WebAssembly ワーキンググループは非常に巧妙な機能 `JsCast` を提案しました。これは、ある JavaScript "型" から別の "型" への変換を支援するものです。これは曖昧に聞こえますが、ある型が別の型であることがわかっている場合、`JsCast` の関数を使用してある型から別の型にジャンプできます。`web-sys`、`wasm_bindgen`、`js-sys` を使用する際にこの機能を理解しておくと便利です。これらのクレートから多くの型が `JsCast` を実装していることに気付くでしょう。 + +`JsCast` はチェック付きとチェックなしの変換メソッドを提供します。したがって、実行時にオブジェクトがどの型であるかわからない場合は、変換を試みることができ、失敗する可能性のある型として [`Option`](https://doc.rust-lang.org/std/option/enum.Option.html) や [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html) を返します。 + +一般的な例は [`web-sys`](./web-sys.mdx) で、イベントのターゲットを取得しようとする場合です。ターゲット要素が何であるかを知っているかもしれませんが、[`web_sys::Event`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Event.html) API は常に [`Option`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.target) を返します。 +その要素型に変換する必要があり、そのメソッドを呼び出すことができます。 + +```rust +// このトレイトを最初にインポートする必要があります +use wasm_bindgen::JsCast; +use web_sys::{Event, EventTarget, HtmlInputElement, HtmlSelectElement}; + +fn handle_event(event: Event) { + let target: EventTarget = event + .target() + .expect("I'm sure this event has a target!"); + + // もしかしたらターゲットは選択要素かもしれませんか? + if let Some(select_element) = target.dyn_ref::() { + // 別のことをする + return; + } + + // それが選択要素でないことが確実であれば、入力要素であることが確実です! + let input_element: HtmlInputElement = target.unchecked_into(); +} +``` + +[`dyn_ref`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_ref) メソッドはチェック付きの変換であり、`Option<&T>` を返します。これは、変換が失敗した場合に元の型を再度使用できることを意味し、`None` を返します。 [`dyn_into`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_into) メソッドは `self` を消費し、Rust の `into` メソッドの規約に従い、`Result` 型を返します。変換が失敗した場合、元の `Self` 値は `Err` に返されます。再試行するか、元の型で他の操作を行うことができます。 + +_[`JsCast` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html)._ + +### [`Closure`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/closure/struct.Closure.html) + +`Closure` 型は、Rust のクロージャを JavaScript に渡す方法を提供します。健全性の理由から、JavaScript に渡されるクロージャは `'static` ライフタイムを持つ必要があります。 + +この型は「ハンドル」であり、破棄されると、それが参照する JS クロージャを無効にします。`Closure` が破棄された後、JS 内のクロージャの使用はすべて例外を引き起こします。 + +`Closure` は、[`&js_sys::Function`](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Function.html) 型を受け取る `js-sys` または `web-sys` API を使用する際に一般的に使用されます。Yew で `Closure` を使用する例は、[Events](../html/events.mdx) ページの[Using `Closure` セクション](../html/events.mdx#using-closure-verbose) にあります。 + +_[`Closure` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/closure/struct.Closure.html)._ + +## [`js-sys`](https://crates.io/crates/js-sys) + +`js-sys` クレートは、JavaScript の標準組み込みオブジェクトのバインディング/インポートを提供します。これには、それらのメソッドやプロパティが含まれます。 + +これは Web API を含みません。Web API は [`web-sys`](./web-sys.mdx) の役割です! + +_[`js-sys` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/js_sys/index.html)._ + +## [`wasm-bindgen-futures`](https://crates.io/crates/wasm-bindgen-futures) + +`wasm-bindgen-futures` クレートは、JavaScript の Promise 型を Rust の [`Future`](https://doc.rust-lang.org/stable/std/future/trait.Future.html) として扱うためのブリッジを提供し、Rust の Future を JavaScript の Promise に変換するユーティリティを含みます。Rust(wasm)で非同期または他のブロッキング作業を処理する際に役立ち、JavaScript のイベントや JavaScript I/O プリミティブと対話する能力を提供します。 + +現在、このクレートには3つの主要なインターフェースがあります: + +1. [`JsFuture`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/struct.JsFuture.html) - + [`Promise`](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Promise.html) を使用して構築された型で、`Future>` として使用できます。`Promise` が解決されると、この `Future` は `Ok` に解決され、`Promise` が拒否されると `Err` に解決され、それぞれ `Promise` の解決または拒否の値を含みます。 + +2. [`future_to_promise`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/fn.future_to_promise.html) - + Rust の `Future>` を JavaScript の `Promise` に変換します。Future の結果は、JavaScript 内の解決または拒否された `Promise` に変換されます。 + +3. [`spawn_local`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/fn.spawn_local.html) - + 現在のスレッドで `Future` を生成します。これは、Rust 内で Future を実行する最良の方法であり、JavaScript に送信するのではなく、Rust 内で実行します。 + +_[`wasm-bindgen-futures` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/index.html)._ + +### [`spawn_local`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/fn.spawn_local.html) + +`spawn_local` は、非同期 API を使用するライブラリを使用する際に、Yew で `wasm-bindgen-futures` クレートの最も一般的に使用される部分です。 + +```rust ,no_run +use web_sys::console; +use wasm_bindgen_futures::spawn_local; + +async fn my_async_fn() -> String { String::from("Hello") } + +spawn_local(async { + let mut string = my_async_fn().await; + string.push_str(", world!"); + // "Hello, world!" を出力します + console::log_1(&string.into()); +}); +``` + +Yew はいくつかの API に futures のサポートを追加しており、特に `async` ブロックを受け入れる `callback_future` を作成できることが注目されます。これは内部的に `spawn_local` を使用しています。 + +_[`spawn_local` ドキュメント](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/fn.spawn_local.html)._ diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx new file mode 100644 index 000000000..6f5f1ca9e --- /dev/null +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/basic-web-technologies/web-sys.mdx @@ -0,0 +1,210 @@ +--- +title: 'web-sys' +description: 'web-sys クレートは Web API のバインディングを提供します。' +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + +[`web-sys` クレート](https://crates.io/crates/web-sys) は Web API のバインディングを提供します。これはブラウザの WebIDL から生成されるため、名前が長くなったり、型が曖昧になったりすることがあります。 + +## `web-sys` の特性 (features) + +`web-sys` クレートで全ての特性を有効にすると、Wasm アプリケーションに多くの冗長性が追加される可能性があります。この問題を解決するために、ほとんどの型は特性を有効にすることで制御され、アプリケーションに必要な型だけを含めることができます。Yew は `web-sys` のいくつかの特性を有効にし、その公開 API でいくつかの型を公開しています。通常、`web-sys` を依存関係として追加する必要があります。 + +## `web-sys` の継承 + +[継承のシミュレーション](./wasm-bindgen.mdx#simulating-inheritance)のセクションでは、Rust が通常 JavaScript の継承をシミュレートする方法を提供していることがわかります。これは `web-sys` で非常に重要です。ある型にどのようなメソッドがあるかを理解するためには、その継承を理解する必要があります。 + +このセクションでは、特定の要素を見て、Rust で [`Deref::deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html#tymethod.deref) を呼び出して、その値が [`JsValue`](./wasm-bindgen.mdx#jsvalue) になるまでの継承をリストします。 + +```rust +use std::ops::Deref; +use web_sys::{ + Element, + EventTarget, + HtmlElement, + HtmlTextAreaElement, + Node, +}; + +fn inheritance_of_text_area(text_area: HtmlTextAreaElement) { + // HtmlTextAreaElement は HTML の