use super::DatetimeLocaleStrings;
use leptos::prelude::*;
use orbital_base_components::{DatetimeFormat, DatetimeTimezone, OrbitalDateTime};
use orbital_macros::component_doc;
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Locale(pub String);
impl Locale {
pub fn new(tag: impl Into<String>) -> Self {
Self(tag.into())
}
}
impl From<&str> for Locale {
fn from(tag: &str) -> Self {
Self(tag.to_string())
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct DatetimeLocaleContext {
pub locale: Locale,
pub strings: DatetimeLocaleStrings,
pub default_format: DatetimeFormat,
pub default_timezone: DatetimeTimezone,
pub reference_date: OrbitalDateTime,
}
impl Default for DatetimeLocaleContext {
fn default() -> Self {
let locale = Locale::from("en-US");
Self {
strings: DatetimeLocaleStrings::for_tag(&locale.0),
locale,
default_format: DatetimeFormat::default(),
default_timezone: DatetimeTimezone::Local,
reference_date: OrbitalDateTime::utc_now(DatetimeTimezone::Local).start_of_day(),
}
}
}
#[derive(Clone)]
struct DatetimeLocaleInjection(Memo<DatetimeLocaleContext>);
fn default_locale_signal() -> Signal<Locale> {
Signal::from(Locale::from("en-US"))
}
fn default_format_signal() -> Signal<DatetimeFormat> {
Signal::from(DatetimeFormat::default())
}
fn default_timezone_signal() -> Signal<DatetimeTimezone> {
Signal::from(DatetimeTimezone::Local)
}
fn default_reference_date_signal() -> Signal<OrbitalDateTime> {
Signal::from(OrbitalDateTime::utc_now(DatetimeTimezone::Local).start_of_day())
}
#[component_doc(
category = "Calendar & Time",
preview_slug = "datetime-locale",
preview_label = "Datetime Locale",
preview_icon = icondata::AiGlobalOutlined,
)]
#[component]
pub fn DatetimeLocale(
#[prop(default = default_locale_signal())]
locale: Signal<Locale>,
#[prop(default = default_format_signal())]
default_format: Signal<DatetimeFormat>,
#[prop(default = default_timezone_signal())]
default_timezone: Signal<DatetimeTimezone>,
#[prop(default = default_reference_date_signal())]
reference_date: Signal<OrbitalDateTime>,
children: Children,
) -> impl IntoView {
let context = Memo::new(move |_| {
let tag = locale.get();
DatetimeLocaleContext {
locale: tag.clone(),
strings: DatetimeLocaleStrings::for_tag(&tag.0),
default_format: default_format.get(),
default_timezone: default_timezone.get(),
reference_date: reference_date.get(),
}
});
provide_context(DatetimeLocaleInjection(context));
children()
}
pub fn use_datetime_locale() -> DatetimeLocaleContext {
use_context::<DatetimeLocaleInjection>()
.map(|injection| injection.0.get())
.unwrap_or_default()
}
pub fn use_default_timezone() -> DatetimeTimezone {
use_datetime_locale().default_timezone
}
pub fn use_datetime_locale_strings() -> DatetimeLocaleStrings {
use_datetime_locale().strings
}
pub fn use_reference_date() -> OrbitalDateTime {
use_datetime_locale().reference_date
}