Skip to content

Commit

Permalink
Merge pull request #156 from sabify/html_direction
Browse files Browse the repository at this point in the history
fix: change html direction based on selected language
  • Loading branch information
Baptistemontan authored Nov 6, 2024
2 parents 2c92517 + 38df898 commit 32cdf5f
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 138 deletions.
14 changes: 10 additions & 4 deletions docs/book/src/usage/02_context.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ The `I18nContextProvider` component accept multiple props, all optionnal (except

- `children`: obviously
- `set_lang_attr_on_html`: should or not set the "lang" attribute on the root `<html>` element (default to true)
- `set_dir_attr_on_html`: should or not set the "dir" attribute on the root `<html>` element (default to true)
- `enable_cookie`: should set a cookie to keep track of the locale when page reload (default to true) (do nothing without the "cookie" feature)
- `cookie_name`: give a custom name to the cookie (default to the crate default value) (do nothing without the "cookie" feature or if `enable_cookie` is false)
- `cookie_options`: options for the cookie, the value is of type `leptos_use::UseCookieOptions<Locale>` (default to `Default::default`)
Expand Down Expand Up @@ -150,16 +151,20 @@ fn MyI18nProvider(
);
provide_context(i18n);
let lang = move || i18n.get_locale().as_str();
let dir = move || i18n.get_locale().direction().as_str();
view! {
<Html lang />
<Html
attr:lang=lang
attr:dir=dir
/>
{children}
}
}
```

## "lang" html attribute
## "lang" and "dir" html attributes

You may want to add a "lang" attribute on a html element such that
You may want to add a "lang" or/and "dir" attribute on a html element such that

```html
<div lang="fr"></div>
Expand All @@ -177,4 +182,5 @@ view! {
}
```

And it will set the "lang" attribute for you on the `<div>` element !
And it will set the "lang" and "dir" attributes for you on the `<div>` element !
_note_ : use directives don't work on the server, so don't rely on this for server side rendering.
170 changes: 85 additions & 85 deletions leptos_i18n/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ leptos = { workspace = true }
leptos_meta = { version = "=0.7.0-rc0" }
leptos_router = { version = "=0.7.0-rc0" }
leptos-use = { version = "=0.14.0-gamma1", default-features = false, features = [
"use_locales",
"use_cookie",
"use_locales",
"use_cookie",
] }
codee = "0.2"
# icu = { version = "1.5", features = ["sync"] }
Expand All @@ -42,7 +42,7 @@ default-struct-builder = "0.5"

# FIXME:
tower = { version = "0.4.13", default-features = false, optional = true, features = [
"util",
"util",
] }
leptos_server = { version = "=0.7.0-rc0", optional = true }
server_fn = { version = "=0.7.0-rc0", optional = true }
Expand All @@ -51,51 +51,51 @@ server_fn_macro = { version = "=0.7.0-rc0", optional = true }
[features]
default = ["cookie", "json_files", "icu_compiled_data"]
icu_compiled_data = [
"icu_plurals?/compiled_data",
"icu_datetime?/compiled_data",
"icu_calendar?/compiled_data",
"icu_list?/compiled_data",
"icu_decimal?/compiled_data",
"leptos_i18n_macro/icu_compiled_data",
"icu_plurals?/compiled_data",
"icu_datetime?/compiled_data",
"icu_calendar?/compiled_data",
"icu_list?/compiled_data",
"icu_decimal?/compiled_data",
"leptos_i18n_macro/icu_compiled_data",
]
plurals = ["dep:icu_plurals", "dep:icu_provider", "leptos_i18n_macro/plurals"]
format_datetime = [
"dep:icu_datetime",
"dep:icu_calendar",
"dep:icu_provider",
"leptos_i18n_macro/format_datetime",
"dep:icu_datetime",
"dep:icu_calendar",
"dep:icu_provider",
"leptos_i18n_macro/format_datetime",
]
format_list = [
"dep:icu_list",
"dep:icu_provider",
"leptos_i18n_macro/format_list",
"dep:icu_list",
"dep:icu_provider",
"leptos_i18n_macro/format_list",
]
format_nums = [
"dep:icu_decimal",
"dep:fixed_decimal",
"dep:icu_provider",
"leptos_i18n_macro/format_nums",
"dep:icu_decimal",
"dep:fixed_decimal",
"dep:icu_provider",
"leptos_i18n_macro/format_nums",
]
actix = ["ssr", "leptos-use/actix"]
axum = ["ssr", "leptos-use/axum", "dep:tower"]
hydrate = [
"leptos/hydrate",
"leptos_i18n_macro/hydrate",
"dep:js-sys",
"dep:serde-wasm-bindgen",
"leptos/hydrate",
"leptos_i18n_macro/hydrate",
"dep:js-sys",
"dep:serde-wasm-bindgen",
]
csr = ["leptos/csr", "leptos_i18n_macro/csr"]
cookie = []
experimental-islands = [
"leptos/experimental-islands",
"leptos_i18n_macro/experimental-islands",
"leptos/experimental-islands",
"leptos_i18n_macro/experimental-islands",
]
ssr = [
"leptos/ssr",
"leptos_meta/ssr",
"leptos-use/ssr",
"leptos_router/ssr",
"leptos_i18n_macro/ssr",
"leptos/ssr",
"leptos_meta/ssr",
"leptos-use/ssr",
"leptos_router/ssr",
"leptos_i18n_macro/ssr",
# FIXME:
"dep:leptos_server",
"dep:server_fn",
Expand All @@ -104,10 +104,10 @@ ssr = [
nightly = ["leptos/nightly", "leptos_i18n_macro/nightly"]

dynamic_load = [
"leptos_i18n_macro/dynamic_load",
"dep:async-once-cell",
"dep:futures",
"dep:noop-waker",
"leptos_i18n_macro/dynamic_load",
"dep:async-once-cell",
"dep:futures",
"dep:noop-waker",
]


Expand All @@ -123,61 +123,61 @@ track_locale_files = ["leptos_i18n_macro/track_locale_files"]

[package.metadata.cargo-all-features]
denylist = [
# Always exclude:
"ssr", # Should always be enabled via a server integration rather than directly
"yaml_files", # See leptos_i18n_macro manifest to see why "yaml_files" and other formats are in deny list and JSON is always included
"json5_files",
"nightly", # Requires a nightly toolchain
# Always exclude:
"ssr", # Should always be enabled via a server integration rather than directly
"yaml_files", # See leptos_i18n_macro manifest to see why "yaml_files" and other formats are in deny list and JSON is always included
"json5_files",
"nightly", # Requires a nightly toolchain

# Only passed through to `leptos_i18n_macros`, exclude to save time:
"serde",
"suppress_key_warnings",
"track_locale_files",
"show_keys_only",
# Only passed through to `leptos_i18n_macros`, exclude to save time:
"serde",
"suppress_key_warnings",
"track_locale_files",
"show_keys_only",
]
skip_feature_sets = [
# Axum and Actix features are incompatible with each other
[
"axum",
"actix",
],
# Axum and Actix features are incompatible with each other
[
"axum",
"actix",
],

# Only one of `hydrate`, (`axum`, `actix`), `csr` should be enabled in a single crate, exclude to save time:
[
"actix",
"hydrate",
],
[
"axum",
"hydrate",
],
[
"axum",
"actix",
],
[
"actix",
"csr",
],
[
"axum",
"csr",
],
[
"hydrate",
"csr",
],
[
"dynamic_load",
"csr",
],
# Only one of `hydrate`, (`axum`, `actix`), `csr` should be enabled in a single crate, exclude to save time:
[
"actix",
"hydrate",
],
[
"axum",
"hydrate",
],
[
"axum",
"actix",
],
[
"actix",
"csr",
],
[
"axum",
"csr",
],
[
"hydrate",
"csr",
],
[
"dynamic_load",
"csr",
],
]
# see leptos_i18n_macro manifest to see why "yaml_files" and other formats are in deny list and JSON is always included
always_include_features = [
"json_files",
"icu_compiled_data",
"plurals",
"format_datetime",
"format_list",
"format_nums",
"json_files",
"icu_compiled_data",
"plurals",
"format_datetime",
"format_list",
"format_nums",
]
40 changes: 22 additions & 18 deletions leptos_i18n/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
use codee::string::FromToStringCodec;
use core::marker::PhantomData;
use leptos::tachys::{
html::directive::IntoDirective, reactive_graph::OwnedView, view::any_view::AnyView,
use leptos::{
children,
prelude::*,
tachys::{html::directive::IntoDirective, reactive_graph::OwnedView},
};
use leptos::{children, either::Either, prelude::*};
use leptos_meta::{provide_meta_context, Html};
use leptos_use::UseCookieOptions;
use std::borrow::Cow;
Expand Down Expand Up @@ -103,6 +104,8 @@ impl<L: Locale, S: Scope<L>> IntoDirective<(leptos::tachys::renderer::types::Ele
Effect::new(move || {
let locale = this.get_locale();
let _ = el.set_attribute("lang", locale.as_str());
let dir = locale.direction();
let _ = el.set_attribute("dir", dir.as_str());
});
}

Expand Down Expand Up @@ -413,9 +416,7 @@ fn embed_translations<L: Locale>(
reg_ctx: crate::fetch_translations::RegisterCtx<L>,
) -> impl IntoView {
let translations = reg_ctx.to_array();
view! {
<script inner_html=translations />
}
view! { <script inner_html=translations /> }
}

macro_rules! fill_options {
Expand All @@ -440,6 +441,7 @@ macro_rules! fill_options {
#[track_caller]
fn provide_i18n_context_component_inner<L: Locale, Chil: IntoView>(
set_lang_attr_on_html: Option<bool>,
set_dir_attr_on_html: Option<bool>,
enable_cookie: Option<bool>,
cookie_name: Option<Cow<str>>,
cookie_options: Option<CookieOptions<L>>,
Expand All @@ -463,25 +465,24 @@ fn provide_i18n_context_component_inner<L: Locale, Chil: IntoView>(
let embed_translations = move || embed_translations(reg_ctx.clone());
#[cfg(not(all(feature = "dynamic_load", any(feature = "ssr", feature = "hydrate"))))]
let embed_translations = view! { <script /> };
if set_lang_attr_on_html.unwrap_or(true) {
let lang = move || i18n.get_locale().as_str();
Either::Left(view! {
<Html attr:lang=lang />
{children}
{embed_translations}
})
} else {
Either::Right(view! {
{children}
{embed_translations}
})
let lang = set_lang_attr_on_html
.unwrap_or(true)
.then_some(move || i18n.get_locale().as_str());
let dir = set_dir_attr_on_html
.unwrap_or(true)
.then_some(move || i18n.get_locale().direction().as_str());
view! {
<Html attr:lang=lang attr:dir=dir />
{children}
{embed_translations}
}
}

#[doc(hidden)]
#[track_caller]
pub fn provide_i18n_context_component<L: Locale, Chil: IntoView>(
set_lang_attr_on_html: Option<bool>,
set_dir_attr_on_html: Option<bool>,
enable_cookie: Option<bool>,
cookie_name: Option<Cow<str>>,
cookie_options: Option<CookieOptions<L>>,
Expand All @@ -490,6 +491,7 @@ pub fn provide_i18n_context_component<L: Locale, Chil: IntoView>(
) -> impl IntoView {
provide_i18n_context_component_inner(
set_lang_attr_on_html,
set_dir_attr_on_html,
enable_cookie,
cookie_name,
cookie_options,
Expand All @@ -502,12 +504,14 @@ pub fn provide_i18n_context_component<L: Locale, Chil: IntoView>(
#[track_caller]
pub fn provide_i18n_context_component_island<L: Locale>(
set_lang_attr_on_html: Option<bool>,
set_dir_attr_on_html: Option<bool>,
enable_cookie: Option<bool>,
cookie_name: Option<Cow<str>>,
children: children::Children,
) -> impl IntoView {
provide_i18n_context_component_inner::<L, AnyView>(
set_lang_attr_on_html,
set_dir_attr_on_html,
enable_cookie,
cookie_name,
None,
Expand Down
2 changes: 1 addition & 1 deletion leptos_i18n/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub mod display;

pub use macro_helpers::formatting;

pub use locale_traits::{Locale, LocaleKeys};
pub use locale_traits::{Direction, Locale, LocaleKeys};

pub use context::{use_i18n_context, I18nContext};

Expand Down
Loading

0 comments on commit 32cdf5f

Please sign in to comment.