diff --git a/.gitignore b/.gitignore
index d311e0cf..e0e82dec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
**/log/*.log*
**/local.*.toml
**/local.toml
+workdir
diff --git a/Cargo.lock b/Cargo.lock
index ad273146..27c4a241 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1560,7 +1560,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pagetop"
-version = "0.0.56"
+version = "0.0.57"
dependencies = [
"actix-files",
"actix-session",
@@ -1590,7 +1590,7 @@ dependencies = [
[[package]]
name = "pagetop-build"
-version = "0.0.11"
+version = "0.0.12"
dependencies = [
"grass",
"static-files",
@@ -1598,7 +1598,7 @@ dependencies = [
[[package]]
name = "pagetop-macros"
-version = "0.0.13"
+version = "0.0.14"
dependencies = [
"proc-macro-crate",
"proc-macro-error",
diff --git a/Cargo.toml b/Cargo.toml
index 8c5912b2..fa090e35 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pagetop"
-version = "0.0.56"
+version = "0.0.57"
edition = "2021"
description = """\
diff --git a/README.md b/README.md
index 1dba1342..117da733 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,20 @@ requirements and application scenarios through actions, components, packages, an
# ⚡️ Quick start
+The simplest PageTop application looks like this:
+
+```rust
+use pagetop::prelude::*;
+
+#[pagetop::main]
+async fn main() -> std::io::Result<()> {
+ Application::new().run()?.await
+}
+```
+
+This provides a default homepage at `http://localhost:8088` using the default configuration. To
+customize the service, you can define a PageTop package like this:
+
```rust
use pagetop::prelude::*;
@@ -53,8 +67,8 @@ async fn main() -> std::io::Result<()> {
}
```
-This program features a `HelloWorld` package, providing a service that serves a greeting web page
-accessible via `http://localhost:8088` under default settings.
+This program defines a custom `HelloWorld` package to serve a page at the root path (`/`) displaying
+a "Hello World!" message inside an HTML `
` element.
# 📂 Helpers
diff --git a/build.rs b/build.rs
index 8151d84c..85e02e02 100644
--- a/build.rs
+++ b/build.rs
@@ -1,7 +1,7 @@
use pagetop_build::StaticFilesBundle;
fn main() -> std::io::Result<()> {
- StaticFilesBundle::from_dir("./static/assets", None)
+ StaticFilesBundle::from_dir("./static", None)
.with_name("assets")
.build()
}
diff --git a/config/common.toml b/config/common.toml
index 900872d6..d6b30e57 100644
--- a/config/common.toml
+++ b/config/common.toml
@@ -1,5 +1,6 @@
[app]
name = "Samples"
+#language = "es-ES"
[log]
tracing = "Debug"
diff --git a/docs/predefined-settings.toml b/config/predefined-settings.toml
similarity index 100%
rename from docs/predefined-settings.toml
rename to config/predefined-settings.toml
diff --git a/helpers/pagetop-build/Cargo.toml b/helpers/pagetop-build/Cargo.toml
index 3ec289c1..94324cec 100644
--- a/helpers/pagetop-build/Cargo.toml
+++ b/helpers/pagetop-build/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pagetop-build"
-version = "0.0.11"
+version = "0.0.12"
edition = "2021"
description = """\
diff --git a/helpers/pagetop-macros/Cargo.toml b/helpers/pagetop-macros/Cargo.toml
index 6289eb51..978c8316 100644
--- a/helpers/pagetop-macros/Cargo.toml
+++ b/helpers/pagetop-macros/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pagetop-macros"
-version = "0.0.13"
+version = "0.0.14"
edition = "2021"
description = """\
diff --git a/src/base/action/page.rs b/src/base/action/page.rs
index fdbff4ac..9c89e2d1 100644
--- a/src/base/action/page.rs
+++ b/src/base/action/page.rs
@@ -1,5 +1,5 @@
-mod before_prepare_body;
-pub use before_prepare_body::*;
+mod before_render_body;
+pub use before_render_body::*;
-mod after_prepare_body;
-pub use after_prepare_body::*;
+mod after_render_body;
+pub use after_render_body::*;
diff --git a/src/base/action/page/after_prepare_body.rs b/src/base/action/page/after_render_body.rs
similarity index 65%
rename from src/base/action/page/after_prepare_body.rs
rename to src/base/action/page/after_render_body.rs
index 9eb2f397..81a89d87 100644
--- a/src/base/action/page/after_prepare_body.rs
+++ b/src/base/action/page/after_render_body.rs
@@ -1,21 +1,21 @@
use crate::prelude::*;
-pub type FnAfterPrepareBody = fn(page: &mut Page);
+pub type FnAfterRenderBody = fn(page: &mut Page);
-pub struct AfterPrepareBody {
- f: FnAfterPrepareBody,
+pub struct AfterRenderBody {
+ f: FnAfterRenderBody,
weight: Weight,
}
-impl ActionTrait for AfterPrepareBody {
+impl ActionTrait for AfterRenderBody {
fn weight(&self) -> Weight {
self.weight
}
}
-impl AfterPrepareBody {
- pub fn new(f: FnAfterPrepareBody) -> Self {
- AfterPrepareBody { f, weight: 0 }
+impl AfterRenderBody {
+ pub fn new(f: FnAfterRenderBody) -> Self {
+ AfterRenderBody { f, weight: 0 }
}
pub fn with_weight(mut self, value: Weight) -> Self {
diff --git a/src/base/action/page/before_prepare_body.rs b/src/base/action/page/before_render_body.rs
similarity index 64%
rename from src/base/action/page/before_prepare_body.rs
rename to src/base/action/page/before_render_body.rs
index c1ea5beb..e0a9d770 100644
--- a/src/base/action/page/before_prepare_body.rs
+++ b/src/base/action/page/before_render_body.rs
@@ -1,21 +1,21 @@
use crate::prelude::*;
-pub type FnBeforePrepareBody = fn(page: &mut Page);
+pub type FnBeforeRenderBody = fn(page: &mut Page);
-pub struct BeforePrepareBody {
- f: FnBeforePrepareBody,
+pub struct BeforeRenderBody {
+ f: FnBeforeRenderBody,
weight: Weight,
}
-impl ActionTrait for BeforePrepareBody {
+impl ActionTrait for BeforeRenderBody {
fn weight(&self) -> Weight {
self.weight
}
}
-impl BeforePrepareBody {
- pub fn new(f: FnBeforePrepareBody) -> Self {
- BeforePrepareBody { f, weight: 0 }
+impl BeforeRenderBody {
+ pub fn new(f: FnBeforeRenderBody) -> Self {
+ BeforeRenderBody { f, weight: 0 }
}
pub fn with_weight(mut self, value: Weight) -> Self {
diff --git a/src/base/component.rs b/src/base/component.rs
index 14bfd84d..93b22fa1 100644
--- a/src/base/component.rs
+++ b/src/base/component.rs
@@ -1,201 +1,11 @@
-use crate::core::component::{AssetsOp, Context};
-use crate::html::{JavaScript, StyleSheet};
-use crate::{AutoDefault, Weight};
+mod html;
+pub use html::Html;
-use std::fmt;
-
-// Context parameters.
-pub const PARAM_BASE_WEIGHT: &str = "base.weight";
-pub const PARAM_BASE_INCLUDE_ICONS: &str = "base.include.icon";
-pub const PARAM_BASE_INCLUDE_FLEX_ASSETS: &str = "base.include.flex";
-pub const PARAM_BASE_INCLUDE_MENU_ASSETS: &str = "base.include.menu";
-
-pub(crate) fn add_base_assets(cx: &mut Context) {
- let weight = cx.get_param::(PARAM_BASE_WEIGHT).unwrap_or(-90);
-
- cx.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/root.css")
- .with_version("0.0.1")
- .with_weight(weight),
- ))
- .set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/looks.css")
- .with_version("0.0.2")
- .with_weight(weight),
- ))
- .set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/buttons.css")
- .with_version("0.0.2")
- .with_weight(weight),
- ));
-
- if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_ICONS) {
- cx.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/icons.min.css")
- .with_version("1.11.1")
- .with_weight(weight),
- ));
- }
-
- if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_FLEX_ASSETS) {
- cx.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/flex.css")
- .with_version("0.0.1")
- .with_weight(weight),
- ));
- }
-
- if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_MENU_ASSETS) {
- cx.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/menu.css")
- .with_version("0.0.1")
- .with_weight(weight),
- ))
- .set_assets(AssetsOp::AddJavaScript(
- JavaScript::defer("/base/js/menu.js")
- .with_version("0.0.1")
- .with_weight(weight),
- ));
- }
-}
-
-// *************************************************************************************************
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub enum BreakPoint {
- #[default]
- None, // Does not apply. Rest initially assume 1 pixel = 0.0625rem
- SM, // @media screen and [ (max-width: 35.5rem) <= 568px < (min-width: 35.5625rem) ]
- MD, // @media screen and [ (max-width: 48rem) <= 768px < (min-width: 48.0625rem) ]
- LG, // @media screen and [ (max-width: 62rem) <= 992px < (min-width: 62.0625rem) ]
- XL, // @media screen and [ (max-width: 80rem) <= 1280px < (min-width: 80.0625rem) ]
- X2L, // @media screen and [ (max-width: 90rem) <= 1440px < (min-width: 90.0625rem) ]
- X3L, // @media screen and [ (max-width: 120rem) <= 1920px < (min-width: 120.0625rem) ]
- X2K, // @media screen and [ (max-width: 160rem) <= 2560px < (min-width: 160.0625rem) ]
-}
-
-#[rustfmt::skip]
-impl fmt::Display for BreakPoint {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- BreakPoint::None => write!(f, "bp__none"),
- BreakPoint::SM => write!(f, "bp__sm"),
- BreakPoint::MD => write!(f, "bp__md"),
- BreakPoint::LG => write!(f, "bp__lg"),
- BreakPoint::XL => write!(f, "bp__xl"),
- BreakPoint::X2L => write!(f, "bp__x2l"),
- BreakPoint::X3L => write!(f, "bp__x3l"),
- BreakPoint::X2K => write!(f, "bp__x2k"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum StyleBase {
- #[default]
- Default,
- Info,
- Success,
- Warning,
- Danger,
- Light,
- Dark,
- Link,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for StyleBase {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- StyleBase::Default => write!(f, "style__default"),
- StyleBase::Info => write!(f, "style__info"),
- StyleBase::Success => write!(f, "style__success"),
- StyleBase::Warning => write!(f, "style__warning"),
- StyleBase::Danger => write!(f, "style__danger"),
- StyleBase::Light => write!(f, "style__light"),
- StyleBase::Dark => write!(f, "style__dark"),
- StyleBase::Link => write!(f, "style__link"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum FontSize {
- ExtraLarge,
- XxLarge,
- XLarge,
- Large,
- Medium,
- #[default]
- Normal,
- Small,
- XSmall,
- XxSmall,
- ExtraSmall,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for FontSize {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- FontSize::ExtraLarge => write!(f, "fs__x3l"),
- FontSize::XxLarge => write!(f, "fs__x2l"),
- FontSize::XLarge => write!(f, "fs__xl"),
- FontSize::Large => write!(f, "fs__l"),
- FontSize::Medium => write!(f, "fs__m"),
- FontSize::Normal => write!(f, ""),
- FontSize::Small => write!(f, "fs__s"),
- FontSize::XSmall => write!(f, "fs__xs"),
- FontSize::XxSmall => write!(f, "fs__x2s"),
- FontSize::ExtraSmall => write!(f, "fs__x3s"),
- }
- }
-}
-
-// *************************************************************************************************
-
-pub mod flex;
-
-mod basic;
-pub use basic::*;
+mod fluent;
+pub use fluent::Fluent;
mod error403;
pub use error403::Error403;
mod error404;
pub use error404::Error404;
-
-mod heading;
-pub use heading::{Heading, HeadingSize, HeadingType};
-
-mod paragraph;
-pub use paragraph::Paragraph;
-
-mod icon;
-pub use icon::Icon;
-
-mod button;
-pub use button::{Button, ButtonTarget};
-
-mod image;
-pub use image::{Image, ImageSize};
-
-mod block;
-pub use block::Block;
-
-mod branding;
-pub use branding::Branding;
-
-mod powered_by;
-pub use powered_by::{PoweredBy, PoweredByLogo};
-
-pub mod menu;
-pub use menu::Menu;
-
-pub mod form;
-pub use form::{Form, FormMethod};
diff --git a/src/base/component/basic.rs b/src/base/component/basic.rs
deleted file mode 100644
index 51ce6c9d..00000000
--- a/src/base/component/basic.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod html;
-pub use html::Html;
-
-mod fluent;
-pub use fluent::Fluent;
diff --git a/src/base/component/block.rs b/src/base/component/block.rs
deleted file mode 100644
index 59d22ed8..00000000
--- a/src/base/component/block.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Block {
- id : OptionId,
- classes: OptionClasses,
- style : StyleBase,
- title : OptionTranslated,
- mixed : MixedComponents,
-}
-
-impl ComponentTrait for Block {
- fn new() -> Self {
- Block::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(
- ClassesOp::Prepend,
- ["block__container".to_string(), self.style().to_string()].join(" "),
- );
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let block_body = self.components().render(cx);
-
- if block_body.is_empty() {
- return PrepareMarkup::None;
- }
-
- let id = cx.required_id::(self.id());
-
- PrepareMarkup::With(html! {
- div id=(id) class=[self.classes().get()] {
- @if let Some(title) = self.title().using(cx.langid()) {
- h2 class="block__title" { (title) }
- }
- div class="block__content" { (block_body) }
- }
- })
- }
-}
-
-impl Block {
- // Block BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_style(&mut self, style: StyleBase) -> &mut Self {
- self.style = style;
- self
- }
-
- #[fn_builder]
- pub fn set_title(&mut self, title: L10n) -> &mut Self {
- self.title.set_value(title);
- self
- }
-
- #[fn_builder]
- pub fn set_components(&mut self, op: AnyOp) -> &mut Self {
- self.mixed.set_value(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_component(mut self, component: impl ComponentTrait) -> Self {
- self.mixed.set_value(AnyOp::Add(AnyComponent::with(component)));
- self
- }
-
- // Block GETTERS.
-
- pub fn style(&self) -> &StyleBase {
- &self.style
- }
-
- pub fn title(&self) -> &OptionTranslated {
- &self.title
- }
-
- pub fn components(&self) -> &MixedComponents {
- &self.mixed
- }
-}
diff --git a/src/base/component/branding.rs b/src/base/component/branding.rs
deleted file mode 100644
index 08ba8b01..00000000
--- a/src/base/component/branding.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Branding {
- id : OptionId,
- #[default(_code = "global::SETTINGS.app.name.to_owned()")]
- app_name : String,
- slogan : OptionTranslated,
- logo : OptionComponent,
- #[default(_code = "|_| \"/\"")]
- frontpage: FnContextualPath,
-}
-
-impl ComponentTrait for Branding {
- fn new() -> Self {
- Branding::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let logo = self.logo().render(cx);
- let home = self.frontpage()(cx);
- let title = &L10n::l("site_home").using(cx.langid());
- PrepareMarkup::With(html! {
- div id=[self.id()] class="branding__container" {
- div class="branding__content" {
- @if !logo.is_empty() {
- a class="branding__logo" href=(home) title=[title] rel="home" {
- (logo)
- }
- }
- div class="branding__text" {
- a class="branding__name" href=(home) title=[title] rel="home" {
- (self.app_name())
- }
- @if let Some(slogan) = self.slogan().using(cx.langid()) {
- div class="branding__slogan" {
- (slogan)
- }
- }
- }
- }
- }
- })
- }
-}
-
-impl Branding {
- // Branding BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_app_name(&mut self, app_name: impl Into) -> &mut Self {
- self.app_name = app_name.into();
- self
- }
-
- #[fn_builder]
- pub fn set_slogan(&mut self, slogan: L10n) -> &mut Self {
- self.slogan.set_value(slogan);
- self
- }
-
- #[fn_builder]
- pub fn set_logo(&mut self, logo: Option) -> &mut Self {
- self.logo.set_value(logo);
- self
- }
-
- #[fn_builder]
- pub fn set_frontpage(&mut self, frontpage: FnContextualPath) -> &mut Self {
- self.frontpage = frontpage;
- self
- }
-
- // Branding GETTERS.
-
- pub fn app_name(&self) -> &String {
- &self.app_name
- }
-
- pub fn slogan(&self) -> &OptionTranslated {
- &self.slogan
- }
-
- pub fn logo(&self) -> &OptionComponent {
- &self.logo
- }
-
- pub fn frontpage(&self) -> &FnContextualPath {
- &self.frontpage
- }
-}
diff --git a/src/base/component/button.rs b/src/base/component/button.rs
deleted file mode 100644
index 2215a4bb..00000000
--- a/src/base/component/button.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-use crate::prelude::*;
-
-#[derive(AutoDefault)]
-pub enum ButtonTarget {
- #[default]
- Default,
- Blank,
- Parent,
- Top,
- Context(String),
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Button {
- id : OptionId,
- classes : OptionClasses,
- style : StyleBase,
- font_size : FontSize,
- left_icon : OptionComponent,
- right_icon: OptionComponent,
- href : OptionString,
- html : OptionTranslated,
- target : ButtonTarget,
-}
-
-impl ComponentTrait for Button {
- fn new() -> Self {
- Button::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(
- ClassesOp::Prepend,
- [
- "button__tap".to_string(),
- self.style().to_string(),
- self.font_size().to_string(),
- ]
- .join(" "),
- );
- }
-
- #[rustfmt::skip]
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let target = match &self.target() {
- ButtonTarget::Default => None,
- ButtonTarget::Blank => Some("_blank"),
- ButtonTarget::Parent => Some("_parent"),
- ButtonTarget::Top => Some("_top"),
- ButtonTarget::Context(name) => Some(name.as_str()),
- };
- PrepareMarkup::With(html! {
- a
- id=[self.id()]
- class=[self.classes().get()]
- href=[self.href().get()]
- target=[target]
- {
- (self.left_icon().render(cx))
- span { (self.html().escaped(cx.langid())) }
- (self.right_icon().render(cx))
- }
- })
- }
-}
-
-impl Button {
- pub fn anchor(href: impl Into, html: L10n) -> Self {
- Button::default().with_href(href).with_html(html)
- }
-
- // Button BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_style(&mut self, style: StyleBase) -> &mut Self {
- self.style = style;
- self
- }
-
- #[fn_builder]
- pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self {
- self.font_size = font_size;
- self
- }
-
- #[fn_builder]
- pub fn set_left_icon(&mut self, icon: Option) -> &mut Self {
- self.left_icon.set_value(icon);
- self
- }
-
- #[fn_builder]
- pub fn set_right_icon(&mut self, icon: Option) -> &mut Self {
- self.right_icon.set_value(icon);
- self
- }
-
- #[fn_builder]
- pub fn set_href(&mut self, href: impl Into) -> &mut Self {
- self.href.set_value(href);
- self
- }
-
- #[fn_builder]
- pub fn set_html(&mut self, html: L10n) -> &mut Self {
- self.html.set_value(html);
- self
- }
-
- #[fn_builder]
- pub fn set_target(&mut self, target: ButtonTarget) -> &mut Self {
- self.target = target;
- self
- }
-
- // Button GETTERS.
-
- pub fn style(&self) -> &StyleBase {
- &self.style
- }
-
- pub fn font_size(&self) -> &FontSize {
- &self.font_size
- }
-
- pub fn left_icon(&self) -> &OptionComponent {
- &self.left_icon
- }
-
- pub fn right_icon(&self) -> &OptionComponent {
- &self.right_icon
- }
-
- pub fn href(&self) -> &OptionString {
- &self.href
- }
-
- pub fn html(&self) -> &OptionTranslated {
- &self.html
- }
-
- pub fn target(&self) -> &ButtonTarget {
- &self.target
- }
-}
diff --git a/src/base/component/flex.rs b/src/base/component/flex.rs
deleted file mode 100644
index 0b732dcd..00000000
--- a/src/base/component/flex.rs
+++ /dev/null
@@ -1,311 +0,0 @@
-mod container;
-pub use container::Container;
-
-mod item;
-pub use item::Item;
-
-use crate::prelude::*;
-
-use std::fmt;
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Direction {
- #[default]
- Default,
- Row(BreakPoint),
- RowReverse(BreakPoint),
- Column(BreakPoint),
- ColumnReverse(BreakPoint),
-}
-
-#[rustfmt::skip]
-impl fmt::Display for Direction {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Direction::Default => write!(f, "flex__row {}", BreakPoint::default()),
- Direction::Row(bp) => write!(f, "flex__row {bp}"),
- Direction::RowReverse(bp) => write!(f, "flex__row flex__reverse {bp}"),
- Direction::Column(bp) => write!(f, "flex__col {bp}"),
- Direction::ColumnReverse(bp) => write!(f, "flex__col flex__reverse {bp}"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Wrap {
- #[default]
- Default,
- NoWrap,
- Wrap(ContentAlign),
- WrapReverse(ContentAlign),
-}
-
-#[rustfmt::skip]
-impl fmt::Display for Wrap {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Wrap::Default => write!(f, ""),
- Wrap::NoWrap => write!(f, "flex__nowrap"),
- Wrap::Wrap(a) => write!(f, "flex__wrap {a}"),
- Wrap::WrapReverse(a) => write!(f, "flex__wrap-reverse {a}"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum ContentAlign {
- #[default]
- Default,
- Start,
- End,
- Center,
- Stretch,
- SpaceBetween,
- SpaceAround,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for ContentAlign {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ContentAlign::Default => write!(f, ""),
- ContentAlign::Start => write!(f, "flex__align-start"),
- ContentAlign::End => write!(f, "flex__align-end"),
- ContentAlign::Center => write!(f, "flex__align-center"),
- ContentAlign::Stretch => write!(f, "flex__align-stretch"),
- ContentAlign::SpaceBetween => write!(f, "flex__align-space-between"),
- ContentAlign::SpaceAround => write!(f, "flex__align-space-around"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Justify {
- #[default]
- Default,
- Start,
- End,
- Center,
- SpaceBetween,
- SpaceAround,
- SpaceEvenly,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for Justify {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Justify::Default => write!(f, ""),
- Justify::Start => write!(f, "flex__justify-start"),
- Justify::End => write!(f, "flex__justify-end"),
- Justify::Center => write!(f, "flex__justify-center"),
- Justify::SpaceBetween => write!(f, "flex__justify-space-between"),
- Justify::SpaceAround => write!(f, "flex__justify-space-around"),
- Justify::SpaceEvenly => write!(f, "flex__justify-space-evenly"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Align {
- #[default]
- Default,
- Start,
- End,
- Center,
- Stretch,
- Baseline,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for Align {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Align::Default => write!(f, ""),
- Align::Start => write!(f, "flex__start"),
- Align::End => write!(f, "flex__end"),
- Align::Center => write!(f, "flex__center"),
- Align::Stretch => write!(f, "flex__stretch"),
- Align::Baseline => write!(f, "flex__baseline"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Gap {
- #[default]
- Default,
- Row(unit::Value),
- Column(unit::Value),
- Distinct(unit::Value, unit::Value),
- Both(unit::Value),
-}
-
-#[rustfmt::skip]
-impl fmt::Display for Gap {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Gap::Default => write!(f, ""),
- Gap::Row(r) => write!(f, "row-gap: {r};"),
- Gap::Column(c) => write!(f, "column-gap: {c};"),
- Gap::Distinct(r, c) => write!(f, "gap: {r} {c};"),
- Gap::Both(v) => write!(f, "gap: {v};"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Grow {
- #[default]
- Default,
- Is1,
- Is2,
- Is3,
- Is4,
- Is5,
- Is6,
- Is7,
- Is8,
- Is9,
-}
-
-impl fmt::Display for Grow {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Grow::Default => write!(f, ""),
- Grow::Is1 => write!(f, "flex__grow-1"),
- Grow::Is2 => write!(f, "flex__grow-2"),
- Grow::Is3 => write!(f, "flex__grow-3"),
- Grow::Is4 => write!(f, "flex__grow-4"),
- Grow::Is5 => write!(f, "flex__grow-5"),
- Grow::Is6 => write!(f, "flex__grow-6"),
- Grow::Is7 => write!(f, "flex__grow-7"),
- Grow::Is8 => write!(f, "flex__grow-8"),
- Grow::Is9 => write!(f, "flex__grow-9"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Shrink {
- #[default]
- Default,
- Is1,
- Is2,
- Is3,
- Is4,
- Is5,
- Is6,
- Is7,
- Is8,
- Is9,
-}
-
-impl fmt::Display for Shrink {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Shrink::Default => write!(f, ""),
- Shrink::Is1 => write!(f, "flex__shrink-1"),
- Shrink::Is2 => write!(f, "flex__shrink-2"),
- Shrink::Is3 => write!(f, "flex__shrink-3"),
- Shrink::Is4 => write!(f, "flex__shrink-4"),
- Shrink::Is5 => write!(f, "flex__shrink-5"),
- Shrink::Is6 => write!(f, "flex__shrink-6"),
- Shrink::Is7 => write!(f, "flex__shrink-7"),
- Shrink::Is8 => write!(f, "flex__shrink-8"),
- Shrink::Is9 => write!(f, "flex__shrink-9"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Size {
- #[default]
- Default,
- Percent10,
- Percent20,
- Percent25,
- Percent33,
- Percent40,
- Percent50,
- Percent60,
- Percent66,
- Percent75,
- Percent80,
- Percent90,
-}
-
-impl fmt::Display for Size {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Size::Default => write!(f, ""),
- Size::Percent10 => write!(f, "flex__size-10"),
- Size::Percent20 => write!(f, "flex__size-20"),
- Size::Percent25 => write!(f, "flex__size-25"),
- Size::Percent33 => write!(f, "flex__size-33"),
- Size::Percent40 => write!(f, "flex__size-40"),
- Size::Percent50 => write!(f, "flex__size-50"),
- Size::Percent60 => write!(f, "flex__size-60"),
- Size::Percent66 => write!(f, "flex__size-66"),
- Size::Percent75 => write!(f, "flex__size-75"),
- Size::Percent80 => write!(f, "flex__size-80"),
- Size::Percent90 => write!(f, "flex__size-90"),
- }
- }
-}
-
-// *************************************************************************************************
-
-#[derive(AutoDefault)]
-pub enum Offset {
- #[default]
- Default,
- Offset10,
- Offset20,
- Offset25,
- Offset33,
- Offset40,
- Offset50,
- Offset60,
- Offset66,
- Offset75,
- Offset80,
- Offset90,
-}
-
-impl fmt::Display for Offset {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Offset::Default => write!(f, ""),
- Offset::Offset10 => write!(f, "flex__offset-10"),
- Offset::Offset20 => write!(f, "flex__offset-20"),
- Offset::Offset25 => write!(f, "flex__offset-25"),
- Offset::Offset33 => write!(f, "flex__offset-33"),
- Offset::Offset40 => write!(f, "flex__offset-40"),
- Offset::Offset50 => write!(f, "flex__offset-50"),
- Offset::Offset60 => write!(f, "flex__offset-60"),
- Offset::Offset66 => write!(f, "flex__offset-66"),
- Offset::Offset75 => write!(f, "flex__offset-75"),
- Offset::Offset80 => write!(f, "flex__offset-80"),
- Offset::Offset90 => write!(f, "flex__offset-90"),
- }
- }
-}
diff --git a/src/base/component/flex/container.rs b/src/base/component/flex/container.rs
deleted file mode 100644
index 0b095c30..00000000
--- a/src/base/component/flex/container.rs
+++ /dev/null
@@ -1,212 +0,0 @@
-use crate::prelude::*;
-
-#[derive(AutoDefault)]
-pub enum ContainerType {
- #[default]
- Default,
- Header,
- Main,
- Section,
- Article,
- Footer,
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Container {
- id : OptionId,
- classes : OptionClasses,
- container_type: ContainerType,
- direction : flex::Direction,
- flex_wrap : flex::Wrap,
- flex_justify : flex::Justify,
- flex_align : flex::Align,
- flex_gap : flex::Gap,
- items : MixedComponents,
-}
-
-impl ComponentTrait for Container {
- fn new() -> Self {
- Container::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, cx: &mut Context) {
- self.set_classes(
- ClassesOp::Prepend,
- [
- "flex__container".to_string(),
- self.direction().to_string(),
- self.wrap().to_string(),
- self.justify().to_string(),
- self.align().to_string(),
- ]
- .join(" "),
- );
-
- cx.set_param::(PARAM_BASE_INCLUDE_FLEX_ASSETS, &true);
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let output = self.items().render(cx);
- if output.is_empty() {
- return PrepareMarkup::None;
- }
-
- let gap = match self.gap() {
- flex::Gap::Default => None,
- _ => Some(self.gap().to_string()),
- };
- match self.container_type() {
- ContainerType::Default => PrepareMarkup::With(html! {
- div id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- ContainerType::Header => PrepareMarkup::With(html! {
- header id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- ContainerType::Main => PrepareMarkup::With(html! {
- main id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- ContainerType::Section => PrepareMarkup::With(html! {
- section id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- ContainerType::Article => PrepareMarkup::With(html! {
- article id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- ContainerType::Footer => PrepareMarkup::With(html! {
- footer id=[self.id()] class=[self.classes().get()] style=[gap] {
- (output)
- }
- }),
- }
- }
-}
-
-impl Container {
- pub fn header() -> Self {
- Container {
- container_type: ContainerType::Header,
- ..Default::default()
- }
- }
-
- pub fn main() -> Self {
- Container {
- container_type: ContainerType::Main,
- ..Default::default()
- }
- }
-
- pub fn section() -> Self {
- Container {
- container_type: ContainerType::Section,
- ..Default::default()
- }
- }
-
- pub fn article() -> Self {
- Container {
- container_type: ContainerType::Article,
- ..Default::default()
- }
- }
-
- pub fn footer() -> Self {
- Container {
- container_type: ContainerType::Footer,
- ..Default::default()
- }
- }
-
- // Container BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_direction(&mut self, direction: flex::Direction) -> &mut Self {
- self.direction = direction;
- self
- }
-
- #[fn_builder]
- pub fn set_wrap(&mut self, wrap: flex::Wrap) -> &mut Self {
- self.flex_wrap = wrap;
- self
- }
-
- #[fn_builder]
- pub fn set_justify(&mut self, justify: flex::Justify) -> &mut Self {
- self.flex_justify = justify;
- self
- }
-
- #[fn_builder]
- pub fn set_align(&mut self, align: flex::Align) -> &mut Self {
- self.flex_align = align;
- self
- }
-
- #[fn_builder]
- pub fn set_gap(&mut self, gap: flex::Gap) -> &mut Self {
- self.flex_gap = gap;
- self
- }
-
- #[fn_builder]
- pub fn set_items(&mut self, op: TypedOp) -> &mut Self {
- self.items.set_typed(op);
- self
- }
-
- pub fn add_item(mut self, item: flex::Item) -> Self {
- self.items.set_value(AnyOp::Add(AnyComponent::with(item)));
- self
- }
-
- // Container GETTERS.
-
- pub fn container_type(&self) -> &ContainerType {
- &self.container_type
- }
-
- pub fn direction(&self) -> &flex::Direction {
- &self.direction
- }
-
- pub fn wrap(&self) -> &flex::Wrap {
- &self.flex_wrap
- }
-
- pub fn justify(&self) -> &flex::Justify {
- &self.flex_justify
- }
-
- pub fn align(&self) -> &flex::Align {
- &self.flex_align
- }
-
- pub fn gap(&self) -> &flex::Gap {
- &self.flex_gap
- }
-
- pub fn items(&self) -> &MixedComponents {
- &self.items
- }
-}
diff --git a/src/base/component/flex/item.rs b/src/base/component/flex/item.rs
deleted file mode 100644
index b1ec3073..00000000
--- a/src/base/component/flex/item.rs
+++ /dev/null
@@ -1,200 +0,0 @@
-use crate::prelude::*;
-
-#[derive(AutoDefault)]
-pub enum ItemType {
- #[default]
- Default,
- Region,
- Wrapper,
- Bundle,
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Item {
- id : OptionId,
- classes : OptionClasses,
- item_type : ItemType,
- flex_grow : flex::Grow,
- flex_shrink: flex::Shrink,
- flex_size : flex::Size,
- flex_offset: flex::Offset,
- flex_align : flex::Align,
- mixed : MixedComponents,
-}
-
-impl ComponentTrait for Item {
- fn new() -> Self {
- Item::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(
- ClassesOp::Prepend,
- [
- "flex__item".to_string(),
- self.grow().to_string(),
- self.shrink().to_string(),
- self.size().to_string(),
- self.offset().to_string(),
- self.align().to_string(),
- ]
- .join(" "),
- );
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let (output, region) = match self.item_type() {
- ItemType::Region => (
- self.components().render(cx),
- if let Some(id) = self.id() {
- cx.prepare_region(id)
- } else {
- Markup::default()
- },
- ),
- _ => (self.components().render(cx), Markup::default()),
- };
- if output.is_empty() && region.is_empty() {
- return PrepareMarkup::None;
- }
- match self.item_type() {
- ItemType::Default => PrepareMarkup::With(html! {
- div id=[self.id()] class=[self.classes().get()] {
- div class="flex__content" {
- (output)
- }
- }
- }),
- ItemType::Region => PrepareMarkup::With(html! {
- div id=[self.id()] class=[self.classes().get()] {
- div class="flex__content flex__region" {
- (region)
- (output)
- }
- }
- }),
- ItemType::Wrapper => PrepareMarkup::With(html! {
- div id=[self.id()] class=[self.classes().get()] {
- (output)
- }
- }),
- ItemType::Bundle => PrepareMarkup::With(html! {
- (output)
- }),
- }
- }
-}
-
-impl Item {
- pub fn region() -> Self {
- Item {
- item_type: ItemType::Region,
- ..Default::default()
- }
- }
-
- pub fn wrapper() -> Self {
- Item {
- item_type: ItemType::Wrapper,
- ..Default::default()
- }
- }
-
- pub fn bundle() -> Self {
- Item {
- item_type: ItemType::Bundle,
- ..Default::default()
- }
- }
-
- pub fn with(component: impl ComponentTrait) -> Self {
- Item::default().add_component(component)
- }
-
- // Item BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_grow(&mut self, grow: flex::Grow) -> &mut Self {
- self.flex_grow = grow;
- self
- }
-
- #[fn_builder]
- pub fn set_shrink(&mut self, shrink: flex::Shrink) -> &mut Self {
- self.flex_shrink = shrink;
- self
- }
-
- #[fn_builder]
- // Ensures the item occupies the exact specified width, neither growing nor shrinking,
- // regardless of the available space in the container or the size of other items.
- pub fn set_size(&mut self, size: flex::Size) -> &mut Self {
- self.flex_size = size;
- self
- }
-
- #[fn_builder]
- pub fn set_offset(&mut self, offset: flex::Offset) -> &mut Self {
- self.flex_offset = offset;
- self
- }
-
- #[fn_builder]
- pub fn set_align(&mut self, align: flex::Align) -> &mut Self {
- self.flex_align = align;
- self
- }
-
- #[fn_builder]
- pub fn set_components(&mut self, op: AnyOp) -> &mut Self {
- self.mixed.set_value(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_component(mut self, component: impl ComponentTrait) -> Self {
- self.mixed.set_value(AnyOp::Add(AnyComponent::with(component)));
- self
- }
-
- // Item GETTERS.
-
- pub fn item_type(&self) -> &ItemType {
- &self.item_type
- }
-
- pub fn grow(&self) -> &flex::Grow {
- &self.flex_grow
- }
-
- pub fn shrink(&self) -> &flex::Shrink {
- &self.flex_shrink
- }
-
- pub fn size(&self) -> &flex::Size {
- &self.flex_size
- }
-
- pub fn offset(&self) -> &flex::Offset {
- &self.flex_offset
- }
-
- pub fn align(&self) -> &flex::Align {
- &self.flex_align
- }
-
- pub fn components(&self) -> &MixedComponents {
- &self.mixed
- }
-}
diff --git a/src/base/component/basic/fluent.rs b/src/base/component/fluent.rs
similarity index 100%
rename from src/base/component/basic/fluent.rs
rename to src/base/component/fluent.rs
diff --git a/src/base/component/form.rs b/src/base/component/form.rs
deleted file mode 100644
index bb5dd943..00000000
--- a/src/base/component/form.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-mod form_main;
-pub use form_main::{Form, FormMethod};
-
-mod input;
-pub use input::{Input, InputType};
-
-mod hidden;
-pub use hidden::Hidden;
-
-mod date;
-pub use date::Date;
-
-mod action_button;
-pub use action_button::{ActionButton, ActionButtonType};
diff --git a/src/base/component/form/action_button.rs b/src/base/component/form/action_button.rs
deleted file mode 100644
index cadbe391..00000000
--- a/src/base/component/form/action_button.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-use crate::prelude::*;
-
-use std::fmt;
-
-#[derive(AutoDefault)]
-pub enum ActionButtonType {
- #[default]
- Submit,
- Reset,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for ActionButtonType {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ActionButtonType::Submit => write!(f, "submit"),
- ActionButtonType::Reset => write!(f, "reset"),
- }
- }
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct ActionButton {
- classes : OptionClasses,
- button_type: ActionButtonType,
- style : StyleBase,
- font_size : FontSize,
- left_icon : OptionComponent,
- right_icon : OptionComponent,
- name : OptionString,
- value : OptionTranslated,
- autofocus : OptionString,
- disabled : OptionString,
-}
-
-impl ComponentTrait for ActionButton {
- fn new() -> Self {
- ActionButton::submit()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(
- ClassesOp::Prepend,
- [
- "button__tap".to_string(),
- self.style().to_string(),
- self.font_size().to_string(),
- ]
- .join(" "),
- );
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let id = self.name().get().map(|name| concat_string!("edit-", name));
- PrepareMarkup::With(html! {
- button
- type=(self.button_type().to_string())
- id=[id]
- class=[self.classes().get()]
- name=[self.name().get()]
- value=[self.value().using(cx.langid())]
- autofocus=[self.autofocus().get()]
- disabled=[self.disabled().get()]
- {
- (self.left_icon().render(cx))
- span { (self.value().escaped(cx.langid())) }
- (self.right_icon().render(cx))
- }
- })
- }
-}
-
-impl ActionButton {
- pub fn submit() -> Self {
- ActionButton {
- button_type: ActionButtonType::Submit,
- style: StyleBase::Default,
- value: OptionTranslated::new(L10n::l("button_submit")),
- ..Default::default()
- }
- }
-
- pub fn reset() -> Self {
- ActionButton {
- button_type: ActionButtonType::Reset,
- style: StyleBase::Info,
- value: OptionTranslated::new(L10n::l("button_reset")),
- ..Default::default()
- }
- }
-
- // Button BUILDER.
-
- #[fn_builder]
- pub fn set_style(&mut self, style: StyleBase) -> &mut Self {
- self.style = style;
- self
- }
-
- #[fn_builder]
- pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self {
- self.font_size = font_size;
- self
- }
-
- #[fn_builder]
- pub fn set_left_icon(&mut self, icon: Option) -> &mut Self {
- self.left_icon.set_value(icon);
- self
- }
-
- #[fn_builder]
- pub fn set_right_icon(&mut self, icon: Option) -> &mut Self {
- self.right_icon.set_value(icon);
- self
- }
-
- #[fn_builder]
- pub fn set_name(&mut self, name: &str) -> &mut Self {
- self.name.set_value(name);
- self
- }
-
- #[fn_builder]
- pub fn set_value(&mut self, value: L10n) -> &mut Self {
- self.value.set_value(value);
- self
- }
-
- #[fn_builder]
- pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self {
- self.autofocus
- .set_value(if toggle { "autofocus" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_disabled(&mut self, toggle: bool) -> &mut Self {
- self.disabled
- .set_value(if toggle { "disabled" } else { "" });
- self
- }
-
- // Button GETTERS.
-
- pub fn button_type(&self) -> &ActionButtonType {
- &self.button_type
- }
-
- pub fn style(&self) -> &StyleBase {
- &self.style
- }
-
- pub fn font_size(&self) -> &FontSize {
- &self.font_size
- }
-
- pub fn left_icon(&self) -> &OptionComponent {
- &self.left_icon
- }
-
- pub fn right_icon(&self) -> &OptionComponent {
- &self.right_icon
- }
-
- pub fn name(&self) -> &OptionString {
- &self.name
- }
-
- pub fn value(&self) -> &OptionTranslated {
- &self.value
- }
-
- pub fn autofocus(&self) -> &OptionString {
- &self.autofocus
- }
-
- pub fn disabled(&self) -> &OptionString {
- &self.disabled
- }
-}
diff --git a/src/base/component/form/date.rs b/src/base/component/form/date.rs
deleted file mode 100644
index 859a2e86..00000000
--- a/src/base/component/form/date.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Date {
- classes : OptionClasses,
- name : OptionString,
- value : OptionString,
- label : OptionString,
- placeholder : OptionString,
- autofocus : OptionString,
- autocomplete: OptionString,
- disabled : OptionString,
- readonly : OptionString,
- required : OptionString,
- help_text : OptionString,
-}
-
-impl ComponentTrait for Date {
- fn new() -> Self {
- Date::default().with_classes(ClassesOp::Add, "form-item form-type-date")
- }
-
- fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
- let id = self.name().get().map(|name| concat_string!("edit-", name));
- PrepareMarkup::With(html! {
- div class=[self.classes().get()] {
- @if let Some(label) = self.label().get() {
- label class="form-label" for=[&id] {
- (label) " "
- @if self.required().get().is_some() {
- span
- class="form-required"
- title="Este campo es obligatorio." { "*" } " "
- }
- }
- }
- input
- type="date"
- id=[id]
- class="form-control"
- name=[self.name().get()]
- value=[self.value().get()]
- placeholder=[self.placeholder().get()]
- autofocus=[self.autofocus().get()]
- autocomplete=[self.autocomplete().get()]
- readonly=[self.readonly().get()]
- required=[self.required().get()]
- disabled=[self.disabled().get()] {}
- @if let Some(help_text) = self.help_text().get() {
- div class="form-text" { (help_text) }
- }
- }
- })
- }
-}
-
-impl Date {
- // Date BUILDER.
-
- #[fn_builder]
- pub fn set_name(&mut self, name: &str) -> &mut Self {
- self.name.set_value(name);
- self
- }
-
- #[fn_builder]
- pub fn set_value(&mut self, value: &str) -> &mut Self {
- self.value.set_value(value);
- self
- }
-
- #[fn_builder]
- pub fn set_label(&mut self, label: &str) -> &mut Self {
- self.label.set_value(label);
- self
- }
-
- #[fn_builder]
- pub fn set_placeholder(&mut self, placeholder: &str) -> &mut Self {
- self.placeholder.set_value(placeholder);
- self
- }
-
- #[fn_builder]
- pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self {
- self.autofocus
- .set_value(if toggle { "autofocus" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_autocomplete(&mut self, toggle: bool) -> &mut Self {
- self.autocomplete.set_value(if toggle { "" } else { "off" });
- self
- }
-
- #[fn_builder]
- pub fn set_disabled(&mut self, toggle: bool) -> &mut Self {
- self.disabled
- .set_value(if toggle { "disabled" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_readonly(&mut self, toggle: bool) -> &mut Self {
- self.readonly
- .set_value(if toggle { "readonly" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_required(&mut self, toggle: bool) -> &mut Self {
- self.required
- .set_value(if toggle { "required" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_help_text(&mut self, help_text: &str) -> &mut Self {
- self.help_text.set_value(help_text);
- self
- }
-
- // Date GETTERS.
-
- pub fn name(&self) -> &OptionString {
- &self.name
- }
-
- pub fn value(&self) -> &OptionString {
- &self.value
- }
-
- pub fn label(&self) -> &OptionString {
- &self.label
- }
-
- pub fn placeholder(&self) -> &OptionString {
- &self.placeholder
- }
-
- pub fn autofocus(&self) -> &OptionString {
- &self.autofocus
- }
-
- pub fn autocomplete(&self) -> &OptionString {
- &self.autocomplete
- }
-
- pub fn disabled(&self) -> &OptionString {
- &self.disabled
- }
-
- pub fn readonly(&self) -> &OptionString {
- &self.readonly
- }
-
- pub fn required(&self) -> &OptionString {
- &self.required
- }
-
- pub fn help_text(&self) -> &OptionString {
- &self.help_text
- }
-}
diff --git a/src/base/component/form/form_main.rs b/src/base/component/form/form_main.rs
deleted file mode 100644
index b630571c..00000000
--- a/src/base/component/form/form_main.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use crate::prelude::*;
-
-#[derive(AutoDefault)]
-pub enum FormMethod {
- #[default]
- Post,
- Get,
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Form {
- id : OptionId,
- classes: OptionClasses,
- action : OptionString,
- charset: OptionString,
- method : FormMethod,
- mixed : MixedComponents,
-}
-
-impl ComponentTrait for Form {
- fn new() -> Self {
- Form::default()
- .with_classes(ClassesOp::Add, "form")
- .with_charset("UTF-8")
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let method = match self.method() {
- FormMethod::Post => Some("post".to_owned()),
- FormMethod::Get => None,
- };
- PrepareMarkup::With(html! {
- form
- id=[self.id()]
- class=[self.classes().get()]
- action=[self.action().get()]
- method=[method]
- accept-charset=[self.charset().get()]
- {
- div { (self.elements().render(cx)) }
- }
- })
- }
-}
-
-impl Form {
- // Form BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_action(&mut self, action: &str) -> &mut Self {
- self.action.set_value(action);
- self
- }
-
- #[fn_builder]
- pub fn set_charset(&mut self, charset: &str) -> &mut Self {
- self.charset.set_value(charset);
- self
- }
-
- #[fn_builder]
- pub fn set_method(&mut self, method: FormMethod) -> &mut Self {
- self.method = method;
- self
- }
-
- #[fn_builder]
- pub fn set_elements(&mut self, op: AnyOp) -> &mut Self {
- self.mixed.set_value(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_element(mut self, element: impl ComponentTrait) -> Self {
- self.mixed.set_value(AnyOp::Add(AnyComponent::with(element)));
- self
- }
-
- // Form GETTERS.
-
- pub fn action(&self) -> &OptionString {
- &self.action
- }
-
- pub fn charset(&self) -> &OptionString {
- &self.charset
- }
-
- pub fn method(&self) -> &FormMethod {
- &self.method
- }
-
- pub fn elements(&self) -> &MixedComponents {
- &self.mixed
- }
-}
diff --git a/src/base/component/form/hidden.rs b/src/base/component/form/hidden.rs
deleted file mode 100644
index 66bfccb9..00000000
--- a/src/base/component/form/hidden.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Hidden {
- name : OptionName,
- value : OptionString,
-}
-
-impl ComponentTrait for Hidden {
- fn new() -> Self {
- Hidden::default()
- }
-
- fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
- let id = self.name().get().map(|name| concat_string!("value-", name));
- PrepareMarkup::With(html! {
- input type="hidden" id=[id] name=[self.name().get()] value=[self.value().get()] {}
- })
- }
-}
-
-impl Hidden {
- pub fn set(name: &str, value: &str) -> Self {
- Hidden::default().with_name(name).with_value(value)
- }
-
- // Hidden BUILDER.
-
- #[fn_builder]
- pub fn set_name(&mut self, name: &str) -> &mut Self {
- self.name.set_value(name);
- self
- }
-
- #[fn_builder]
- pub fn set_value(&mut self, value: &str) -> &mut Self {
- self.value.set_value(value);
- self
- }
-
- // Hidden GETTERS.
-
- pub fn name(&self) -> &OptionName {
- &self.name
- }
-
- pub fn value(&self) -> &OptionString {
- &self.value
- }
-}
diff --git a/src/base/component/form/input.rs b/src/base/component/form/input.rs
deleted file mode 100644
index a59d77c8..00000000
--- a/src/base/component/form/input.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-use crate::prelude::*;
-
-#[derive(AutoDefault)]
-pub enum InputType {
- #[default]
- Textfield,
- Password,
- Search,
- Email,
- Telephone,
- Url,
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Input {
- classes : OptionClasses,
- input_type : InputType,
- name : OptionName,
- value : OptionString,
- label : OptionTranslated,
- size : Option,
- minlength : Option,
- maxlength : Option,
- placeholder : OptionString,
- autofocus : OptionString,
- autocomplete: OptionString,
- disabled : OptionString,
- readonly : OptionString,
- required : OptionString,
- help_text : OptionTranslated,
-}
-
-impl ComponentTrait for Input {
- fn new() -> Self {
- Input::default()
- .with_classes(ClassesOp::Add, "form-item form-type-textfield")
- .with_size(Some(60))
- .with_maxlength(Some(128))
- }
-
- #[rustfmt::skip]
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let type_input = match self.input_type() {
- InputType::Textfield => "text",
- InputType::Password => "password",
- InputType::Search => "search",
- InputType::Email => "email",
- InputType::Telephone => "tel",
- InputType::Url => "url",
- };
- let id = self.name().get().map(|name| concat_string!("edit-", name));
- PrepareMarkup::With(html! {
- div class=[self.classes().get()] {
- @if let Some(label) = self.label().using(cx.langid()) {
- label class="form-label" for=[&id] {
- (label) " "
- @if self.required().get().is_some() {
- span
- class="form-required"
- title="Este campo es obligatorio." { "*" } " "
- }
- }
- }
- input
- type=(type_input)
- id=[id]
- class="form-control"
- name=[self.name().get()]
- value=[self.value().get()]
- size=[self.size()]
- minlength=[self.minlength()]
- maxlength=[self.maxlength()]
- placeholder=[self.placeholder().get()]
- autofocus=[self.autofocus().get()]
- autocomplete=[self.autocomplete().get()]
- readonly=[self.readonly().get()]
- required=[self.required().get()]
- disabled=[self.disabled().get()] {}
- @if let Some(description) = self.help_text().using(cx.langid()) {
- div class="form-text" { (description) }
- }
- }
- })
- }
-}
-
-impl Input {
- pub fn textfield() -> Self {
- Input::default()
- }
-
- pub fn password() -> Self {
- let mut input = Input::default().with_classes(
- ClassesOp::Replace("form-type-textfield".to_owned()),
- "form-type-password",
- );
- input.input_type = InputType::Password;
- input
- }
-
- pub fn search() -> Self {
- let mut input = Input::default().with_classes(
- ClassesOp::Replace("form-type-textfield".to_owned()),
- "form-type-search",
- );
- input.input_type = InputType::Search;
- input
- }
-
- pub fn email() -> Self {
- let mut input = Input::default().with_classes(
- ClassesOp::Replace("form-type-textfield".to_owned()),
- "form-type-email",
- );
- input.input_type = InputType::Email;
- input
- }
-
- pub fn telephone() -> Self {
- let mut input = Input::default().with_classes(
- ClassesOp::Replace("form-type-textfield".to_owned()),
- "form-type-telephone",
- );
- input.input_type = InputType::Telephone;
- input
- }
-
- pub fn url() -> Self {
- let mut input = Input::default().with_classes(
- ClassesOp::Replace("form-type-textfield".to_owned()),
- "form-type-url",
- );
- input.input_type = InputType::Url;
- input
- }
-
- // Input BUILDER.
-
- #[fn_builder]
- pub fn set_name(&mut self, name: &str) -> &mut Self {
- if let Some(previous) = self.name.get() {
- self.set_classes(ClassesOp::Remove, concat_string!("form-item-", previous));
- }
- self.set_classes(ClassesOp::Add, concat_string!("form-item-", name));
- self.name.set_value(name);
- self
- }
-
- #[fn_builder]
- pub fn set_value(&mut self, value: &str) -> &mut Self {
- self.value.set_value(value);
- self
- }
-
- #[fn_builder]
- pub fn set_label(&mut self, label: L10n) -> &mut Self {
- self.label.set_value(label);
- self
- }
-
- #[fn_builder]
- pub fn set_size(&mut self, size: Option) -> &mut Self {
- self.size = size;
- self
- }
-
- #[fn_builder]
- pub fn set_minlength(&mut self, minlength: Option) -> &mut Self {
- self.minlength = minlength;
- self
- }
-
- #[fn_builder]
- pub fn set_maxlength(&mut self, maxlength: Option) -> &mut Self {
- self.maxlength = maxlength;
- self
- }
-
- #[fn_builder]
- pub fn set_placeholder(&mut self, placeholder: &str) -> &mut Self {
- self.placeholder.set_value(placeholder);
- self
- }
-
- #[fn_builder]
- pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self {
- self.autofocus
- .set_value(if toggle { "autofocus" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_autocomplete(&mut self, toggle: bool) -> &mut Self {
- self.autocomplete.set_value(if toggle { "" } else { "off" });
- self
- }
-
- #[fn_builder]
- pub fn set_disabled(&mut self, toggle: bool) -> &mut Self {
- self.disabled
- .set_value(if toggle { "disabled" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_readonly(&mut self, toggle: bool) -> &mut Self {
- self.readonly
- .set_value(if toggle { "readonly" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_required(&mut self, toggle: bool) -> &mut Self {
- self.required
- .set_value(if toggle { "required" } else { "" });
- self
- }
-
- #[fn_builder]
- pub fn set_help_text(&mut self, help_text: L10n) -> &mut Self {
- self.help_text.set_value(help_text);
- self
- }
-
- // Input GETTERS.
-
- pub fn input_type(&self) -> &InputType {
- &self.input_type
- }
-
- pub fn name(&self) -> &OptionName {
- &self.name
- }
-
- pub fn value(&self) -> &OptionString {
- &self.value
- }
-
- pub fn label(&self) -> &OptionTranslated {
- &self.label
- }
-
- pub fn size(&self) -> Option {
- self.size
- }
-
- pub fn minlength(&self) -> Option {
- self.minlength
- }
-
- pub fn maxlength(&self) -> Option {
- self.maxlength
- }
-
- pub fn placeholder(&self) -> &OptionString {
- &self.placeholder
- }
-
- pub fn autofocus(&self) -> &OptionString {
- &self.autofocus
- }
-
- pub fn autocomplete(&self) -> &OptionString {
- &self.autocomplete
- }
-
- pub fn disabled(&self) -> &OptionString {
- &self.disabled
- }
-
- pub fn readonly(&self) -> &OptionString {
- &self.readonly
- }
-
- pub fn required(&self) -> &OptionString {
- &self.required
- }
-
- pub fn help_text(&self) -> &OptionTranslated {
- &self.help_text
- }
-}
diff --git a/src/base/component/heading.rs b/src/base/component/heading.rs
deleted file mode 100644
index 7cb3b594..00000000
--- a/src/base/component/heading.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-use crate::prelude::*;
-
-use std::fmt;
-
-#[derive(AutoDefault)]
-pub enum HeadingType {
- #[default]
- H1,
- H2,
- H3,
- H4,
- H5,
- H6,
-}
-
-#[derive(AutoDefault)]
-pub enum HeadingSize {
- ExtraLarge,
- XxLarge,
- XLarge,
- Large,
- Medium,
- #[default]
- Normal,
- Subtitle,
-}
-
-#[rustfmt::skip]
-impl fmt::Display for HeadingSize {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- HeadingSize::ExtraLarge => write!(f, "heading__title-x3l"),
- HeadingSize::XxLarge => write!(f, "heading__title-x2l"),
- HeadingSize::XLarge => write!(f, "heading__title-xl"),
- HeadingSize::Large => write!(f, "heading__title-l"),
- HeadingSize::Medium => write!(f, "heading__title-m"),
- HeadingSize::Normal => write!(f, ""),
- HeadingSize::Subtitle => write!(f, "heading__subtitle"),
- }
- }
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Heading {
- id : OptionId,
- classes : OptionClasses,
- heading_type: HeadingType,
- size : HeadingSize,
- text : OptionTranslated,
-}
-
-impl ComponentTrait for Heading {
- fn new() -> Self {
- Heading::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(ClassesOp::Add, self.size().to_string());
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let id = self.id();
- let classes = self.classes().get();
- let text = self.text().escaped(cx.langid());
- PrepareMarkup::With(html! { @match &self.heading_type() {
- HeadingType::H1 => h1 id=[id] class=[classes] { (text) },
- HeadingType::H2 => h2 id=[id] class=[classes] { (text) },
- HeadingType::H3 => h3 id=[id] class=[classes] { (text) },
- HeadingType::H4 => h4 id=[id] class=[classes] { (text) },
- HeadingType::H5 => h5 id=[id] class=[classes] { (text) },
- HeadingType::H6 => h6 id=[id] class=[classes] { (text) },
- }})
- }
-}
-
-impl Heading {
- pub fn h1(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H1)
- .with_text(text)
- }
-
- pub fn h2(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H2)
- .with_text(text)
- }
-
- pub fn h3(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H3)
- .with_text(text)
- }
-
- pub fn h4(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H4)
- .with_text(text)
- }
-
- pub fn h5(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H5)
- .with_text(text)
- }
-
- pub fn h6(text: L10n) -> Self {
- Heading::default()
- .with_heading_type(HeadingType::H6)
- .with_text(text)
- }
-
- // Heading BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_heading_type(&mut self, heading_type: HeadingType) -> &mut Self {
- self.heading_type = heading_type;
- self
- }
-
- #[fn_builder]
- pub fn set_size(&mut self, size: HeadingSize) -> &mut Self {
- self.size = size;
- self
- }
-
- #[fn_builder]
- pub fn set_text(&mut self, text: L10n) -> &mut Self {
- self.text.set_value(text);
- self
- }
-
- // Paragraph GETTERS.
-
- pub fn heading_type(&self) -> &HeadingType {
- &self.heading_type
- }
-
- pub fn size(&self) -> &HeadingSize {
- &self.size
- }
-
- pub fn text(&self) -> &OptionTranslated {
- &self.text
- }
-}
diff --git a/src/base/component/basic/html.rs b/src/base/component/html.rs
similarity index 100%
rename from src/base/component/basic/html.rs
rename to src/base/component/html.rs
diff --git a/src/base/component/icon.rs b/src/base/component/icon.rs
deleted file mode 100644
index 7e0a6a1e..00000000
--- a/src/base/component/icon.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Icon {
- classes : OptionClasses,
- icon_name: OptionString,
- font_size: FontSize,
-}
-
-impl ComponentTrait for Icon {
- fn new() -> Self {
- Icon::default()
- }
-
- #[rustfmt::skip]
- fn setup_before_prepare(&mut self, cx: &mut Context) {
- if let Some(icon_name) = self.icon_name().get() {
- self.set_classes(ClassesOp::Prepend,
- concat_string!("bi-", icon_name, " ", self.font_size().to_string()),
- );
- cx.set_param::(PARAM_BASE_INCLUDE_ICONS, &true);
- }
- }
-
- fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
- match self.icon_name().get() {
- None => PrepareMarkup::None,
- _ => PrepareMarkup::With(html! { i class=[self.classes().get()] {} }),
- }
- }
-}
-
-impl Icon {
- pub fn with(icon_name: impl Into) -> Self {
- Icon::default().with_icon_name(icon_name)
- }
-
- // Icon BUILDER.
-
- #[fn_builder]
- pub fn set_icon_name(&mut self, name: impl Into) -> &mut Self {
- self.icon_name.set_value(name);
- self
- }
-
- #[fn_builder]
- pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self {
- self.font_size = font_size;
- self
- }
-
- // Icon GETTERS.
-
- pub fn icon_name(&self) -> &OptionString {
- &self.icon_name
- }
-
- pub fn font_size(&self) -> &FontSize {
- &self.font_size
- }
-}
diff --git a/src/base/component/image.rs b/src/base/component/image.rs
deleted file mode 100644
index dcf2c625..00000000
--- a/src/base/component/image.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use crate::prelude::*;
-
-const IMG_FLUID: &str = "img__fluid";
-const IMG_FIXED: &str = "img__fixed";
-
-#[derive(AutoDefault)]
-pub enum ImageSize {
- #[default]
- Auto,
- Size(u16, u16),
- Width(u16),
- Height(u16),
- Both(u16),
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Image {
- id : OptionId,
- classes: OptionClasses,
- source : OptionString,
- size : ImageSize,
-}
-
-impl ComponentTrait for Image {
- fn new() -> Self {
- Image::default().with_classes(ClassesOp::Add, IMG_FLUID)
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
- let (width, height) = match self.size() {
- ImageSize::Auto => (None, None),
- ImageSize::Size(width, height) => (Some(width), Some(height)),
- ImageSize::Width(width) => (Some(width), None),
- ImageSize::Height(height) => (None, Some(height)),
- ImageSize::Both(value) => (Some(value), Some(value)),
- };
- PrepareMarkup::With(html! {
- img
- src=[self.source().get()]
- id=[self.id()]
- class=[self.classes().get()]
- width=[width]
- height=[height] {}
- })
- }
-}
-
-impl Image {
- pub fn with(source: &str) -> Self {
- Image::default()
- .with_source(source)
- .with_classes(ClassesOp::Add, IMG_FLUID)
- }
-
- pub fn fixed(source: &str) -> Self {
- Image::default()
- .with_source(source)
- .with_classes(ClassesOp::Add, IMG_FIXED)
- }
-
- pub fn pagetop() -> Self {
- Image::default()
- .with_source("/base/pagetop-logo.svg")
- .with_classes(ClassesOp::Add, IMG_FIXED)
- .with_size(ImageSize::Size(64, 64))
- }
-
- // Image BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_source(&mut self, source: &str) -> &mut Self {
- self.source.set_value(source);
- self
- }
-
- #[fn_builder]
- pub fn set_size(&mut self, size: ImageSize) -> &mut Self {
- self.size = size;
- self
- }
-
- // Image GETTERS.
-
- pub fn source(&self) -> &OptionString {
- &self.source
- }
-
- pub fn size(&self) -> &ImageSize {
- &self.size
- }
-}
diff --git a/src/base/component/menu.rs b/src/base/component/menu.rs
deleted file mode 100644
index 34ab59fe..00000000
--- a/src/base/component/menu.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-mod menu_main;
-pub use menu_main::Menu;
-
-mod item;
-pub use item::{Item, ItemType};
-
-mod submenu;
-pub use submenu::Submenu;
-
-mod megamenu;
-pub use megamenu::Megamenu;
-
-mod group;
-pub use group::Group;
-
-mod element;
-pub use element::{Element, ElementType};
diff --git a/src/base/component/menu/element.rs b/src/base/component/menu/element.rs
deleted file mode 100644
index 5c39f7ea..00000000
--- a/src/base/component/menu/element.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-use crate::prelude::*;
-
-use super::Submenu;
-
-type Content = TypedComponent;
-type SubmenuItems = TypedComponent;
-
-#[derive(AutoDefault)]
-pub enum ElementType {
- #[default]
- Void,
- Html(Content),
- Submenu(SubmenuItems),
-}
-
-// Element.
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Element {
- element_type: ElementType,
-}
-
-impl ComponentTrait for Element {
- fn new() -> Self {
- Element::default()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- match self.element_type() {
- ElementType::Void => PrepareMarkup::None,
- ElementType::Html(content) => PrepareMarkup::With(html! {
- (content.render(cx))
- }),
- ElementType::Submenu(submenu) => PrepareMarkup::With(html! {
- (submenu.render(cx))
- }),
- }
- }
-}
-
-impl Element {
- pub fn html(content: Html) -> Self {
- Element {
- element_type: ElementType::Html(Content::with(content)),
- }
- }
-
- pub fn submenu(submenu: Submenu) -> Self {
- Element {
- element_type: ElementType::Submenu(SubmenuItems::with(submenu)),
- }
- }
-
- // Element GETTERS.
-
- pub fn element_type(&self) -> &ElementType {
- &self.element_type
- }
-}
diff --git a/src/base/component/menu/group.rs b/src/base/component/menu/group.rs
deleted file mode 100644
index d3b8a33d..00000000
--- a/src/base/component/menu/group.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use crate::prelude::*;
-
-use super::Element;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Group {
- id : OptionId,
- elements: MixedComponents,
-}
-
-impl ComponentTrait for Group {
- fn new() -> Self {
- Group::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- PrepareMarkup::With(html! {
- div id=[self.id()] class="menu-group" {
- (self.elements().render(cx))
- }
- })
- }
-}
-
-impl Group {
- // Group BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_elements(&mut self, op: TypedOp) -> &mut Self {
- self.elements.set_typed(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_element(mut self, element: Element) -> Self {
- self.elements.set_value(AnyOp::Add(AnyComponent::with(element)));
- self
- }
-
- // Group GETTERS.
-
- pub fn elements(&self) -> &MixedComponents {
- &self.elements
- }
-}
diff --git a/src/base/component/menu/item.rs b/src/base/component/menu/item.rs
deleted file mode 100644
index e59899b0..00000000
--- a/src/base/component/menu/item.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-use crate::prelude::*;
-
-use super::{Megamenu, Submenu};
-
-type Label = L10n;
-type Content = TypedComponent;
-type SubmenuItems = TypedComponent;
-type MegamenuGroups = TypedComponent;
-
-#[derive(AutoDefault)]
-pub enum ItemType {
- #[default]
- Void,
- Label(Label),
- Link(Label, FnContextualPath),
- LinkBlank(Label, FnContextualPath),
- Html(Content),
- Submenu(Label, SubmenuItems),
- Megamenu(Label, MegamenuGroups),
-}
-
-// Item.
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Item {
- item_type : ItemType,
- description: OptionTranslated,
- left_icon : OptionComponent,
- right_icon : OptionComponent,
-}
-
-impl ComponentTrait for Item {
- fn new() -> Self {
- Item::default()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let description = self.description.using(cx.langid());
-
- let left_icon = self.left_icon().render(cx);
- let right_icon = self.right_icon().render(cx);
-
- match self.item_type() {
- ItemType::Void => PrepareMarkup::None,
- ItemType::Label(label) => PrepareMarkup::With(html! {
- li class="menu__label" {
- span title=[description] {
- (left_icon)
- (label.escaped(cx.langid()))
- (right_icon)
- }
- }
- }),
- ItemType::Link(label, path) => PrepareMarkup::With(html! {
- li class="menu__link" {
- a href=(path(cx)) title=[description] {
- (left_icon)
- (label.escaped(cx.langid()))
- (right_icon)
- }
- }
- }),
- ItemType::LinkBlank(label, path) => PrepareMarkup::With(html! {
- li class="menu__link" {
- a href=(path(cx)) title=[description] target="_blank" {
- (left_icon)
- (label.escaped(cx.langid()))
- (right_icon)
- }
- }
- }),
- ItemType::Html(content) => PrepareMarkup::With(html! {
- li class="menu__html" {
- (content.render(cx))
- }
- }),
- ItemType::Submenu(label, submenu) => PrepareMarkup::With(html! {
- li class="menu__children" {
- a href="#" title=[description] {
- (left_icon)
- (label.escaped(cx.langid())) i class="menu__icon bi-chevron-down" {}
- }
- div class="menu__subs" {
- (submenu.render(cx))
- }
- }
- }),
- ItemType::Megamenu(label, megamenu) => PrepareMarkup::With(html! {
- li class="menu__children" {
- a href="#" title=[description] {
- (left_icon)
- (label.escaped(cx.langid())) i class="menu__icon bi-chevron-down" {}
- }
- div class="menu__subs menu__mega" {
- (megamenu.render(cx))
- }
- }
- }),
- }
- }
-}
-
-impl Item {
- pub fn label(label: L10n) -> Self {
- Item {
- item_type: ItemType::Label(label),
- ..Default::default()
- }
- }
-
- pub fn link(label: L10n, path: FnContextualPath) -> Self {
- Item {
- item_type: ItemType::Link(label, path),
- ..Default::default()
- }
- }
-
- pub fn link_blank(label: L10n, path: FnContextualPath) -> Self {
- Item {
- item_type: ItemType::LinkBlank(label, path),
- ..Default::default()
- }
- }
-
- pub fn html(content: Html) -> Self {
- Item {
- item_type: ItemType::Html(Content::with(content)),
- ..Default::default()
- }
- }
-
- pub fn submenu(label: L10n, submenu: Submenu) -> Self {
- Item {
- item_type: ItemType::Submenu(label, SubmenuItems::with(submenu)),
- ..Default::default()
- }
- }
-
- pub fn megamenu(label: L10n, megamenu: Megamenu) -> Self {
- Item {
- item_type: ItemType::Megamenu(label, MegamenuGroups::with(megamenu)),
- ..Default::default()
- }
- }
-
- // Item BUILDER.
-
- #[fn_builder]
- pub fn set_description(&mut self, text: L10n) -> &mut Self {
- self.description.set_value(text);
- self
- }
-
- #[fn_builder]
- pub fn set_left_icon(&mut self, icon: Option) -> &mut Self {
- self.left_icon.set_value(icon);
- self
- }
-
- #[fn_builder]
- pub fn set_right_icon(&mut self, icon: Option) -> &mut Self {
- self.right_icon.set_value(icon);
- self
- }
-
- // Item GETTERS.
-
- pub fn item_type(&self) -> &ItemType {
- &self.item_type
- }
-
- pub fn description(&self) -> &OptionTranslated {
- &self.description
- }
-
- pub fn left_icon(&self) -> &OptionComponent {
- &self.left_icon
- }
-
- pub fn right_icon(&self) -> &OptionComponent {
- &self.right_icon
- }
-}
diff --git a/src/base/component/menu/megamenu.rs b/src/base/component/menu/megamenu.rs
deleted file mode 100644
index 5a21ddd5..00000000
--- a/src/base/component/menu/megamenu.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use crate::prelude::*;
-
-use super::Group;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Megamenu {
- id : OptionId,
- groups: MixedComponents,
-}
-
-impl ComponentTrait for Megamenu {
- fn new() -> Self {
- Megamenu::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- PrepareMarkup::With(html! {
- div id=[self.id()] class="menu__groups" {
- (self.groups().render(cx))
- }
- })
- }
-}
-
-impl Megamenu {
- // Megamenu BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_groups(&mut self, op: TypedOp) -> &mut Self {
- self.groups.set_typed(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_group(mut self, group: Group) -> Self {
- self.groups.set_value(AnyOp::Add(AnyComponent::with(group)));
- self
- }
-
- // Megamenu GETTERS.
-
- pub fn groups(&self) -> &MixedComponents {
- &self.groups
- }
-}
diff --git a/src/base/component/menu/menu_main.rs b/src/base/component/menu/menu_main.rs
deleted file mode 100644
index 94d51d8d..00000000
--- a/src/base/component/menu/menu_main.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use crate::prelude::*;
-
-use super::Item;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Menu {
- id : OptionId,
- items: MixedComponents,
-}
-
-impl ComponentTrait for Menu {
- fn new() -> Self {
- Menu::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- cx.set_param::(PARAM_BASE_INCLUDE_MENU_ASSETS, &true);
- cx.set_param::(PARAM_BASE_INCLUDE_ICONS, &true);
-
- PrepareMarkup::With(html! {
- div id=[self.id()] class="menu__container" {
- div class="menu__content" {
- div class="menu__main" {
- div class="menu__overlay" {}
- nav class="menu__nav" {
- div class="menu__header" {
- button type="button" class="menu__arrow" {
- i class="bi-chevron-left" {}
- }
- div class="menu__title" {}
- button type="button" class="menu__close" {
- i class="bi-x" {}
- }
- }
- ul class="menu__section" {
- (self.items().render(cx))
- }
- }
- }
- button
- type="button"
- class="menu__trigger"
- title=[L10n::l("menu_toggle").using(cx.langid())]
- {
- span {} span {} span {}
- }
- }
- }
- })
- }
-}
-
-impl Menu {
- // Menu BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_items(&mut self, op: TypedOp- ) -> &mut Self {
- self.items.set_typed(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_item(mut self, item: Item) -> Self {
- self.items.set_value(AnyOp::Add(AnyComponent::with(item)));
- self
- }
-
- // Menu GETTERS.
-
- pub fn items(&self) -> &MixedComponents {
- &self.items
- }
-}
diff --git a/src/base/component/menu/submenu.rs b/src/base/component/menu/submenu.rs
deleted file mode 100644
index 4e5e91df..00000000
--- a/src/base/component/menu/submenu.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-use crate::prelude::*;
-
-use super::Item;
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct Submenu {
- id : OptionId,
- title: OptionTranslated,
- items: MixedComponents,
-}
-
-impl ComponentTrait for Submenu {
- fn new() -> Self {
- Submenu::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- PrepareMarkup::With(html! {
- div id=[self.id()] class="menu__items" {
- @if let Some(title) = self.title().using(cx.langid()) {
- h4 class="menu__title" { (title) }
- }
- ul {
- (self.items().render(cx))
- }
- }
- })
- }
-}
-
-impl Submenu {
- // Submenu BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_title(&mut self, title: L10n) -> &mut Self {
- self.title.set_value(title);
- self
- }
-
- #[fn_builder]
- pub fn set_items(&mut self, op: TypedOp
- ) -> &mut Self {
- self.items.set_typed(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_item(mut self, item: Item) -> Self {
- self.items.set_value(AnyOp::Add(AnyComponent::with(item)));
- self
- }
-
- // Submenu GETTERS.
-
- pub fn title(&self) -> &OptionTranslated {
- &self.title
- }
-
- pub fn items(&self) -> &MixedComponents {
- &self.items
- }
-}
diff --git a/src/base/component/paragraph.rs b/src/base/component/paragraph.rs
deleted file mode 100644
index 9beeefa8..00000000
--- a/src/base/component/paragraph.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use crate::prelude::*;
-
-#[rustfmt::skip]
-#[derive(AutoDefault, ComponentClasses)]
-pub struct Paragraph {
- id : OptionId,
- classes : OptionClasses,
- font_size: FontSize,
- mixed : MixedComponents,
-}
-
-impl ComponentTrait for Paragraph {
- fn new() -> Self {
- Paragraph::default()
- }
-
- fn id(&self) -> Option {
- self.id.get()
- }
-
- fn setup_before_prepare(&mut self, _cx: &mut Context) {
- self.set_classes(ClassesOp::Prepend, self.font_size().to_string());
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- PrepareMarkup::With(html! {
- p
- id=[self.id()]
- class=[self.classes().get()]
- {
- (self.components().render(cx))
- }
- })
- }
-}
-
-impl Paragraph {
- pub fn with(component: impl ComponentTrait) -> Self {
- Paragraph::default().add_component(component)
- }
-
- pub fn fluent(l10n: L10n) -> Self {
- Paragraph::default().add_component(Fluent::with(l10n))
- }
-
- // Paragraph BUILDER.
-
- #[fn_builder]
- pub fn set_id(&mut self, id: impl Into) -> &mut Self {
- self.id.set_value(id);
- self
- }
-
- #[fn_builder]
- pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self {
- self.font_size = font_size;
- self
- }
-
- #[fn_builder]
- pub fn set_components(&mut self, op: AnyOp) -> &mut Self {
- self.mixed.set_value(op);
- self
- }
-
- #[rustfmt::skip]
- pub fn add_component(mut self, component: impl ComponentTrait) -> Self {
- self.mixed.set_value(AnyOp::Add(AnyComponent::with(component)));
- self
- }
-
- // Paragraph GETTERS.
-
- pub fn font_size(&self) -> &FontSize {
- &self.font_size
- }
-
- pub fn components(&self) -> &MixedComponents {
- &self.mixed
- }
-}
diff --git a/src/base/component/powered_by.rs b/src/base/component/powered_by.rs
deleted file mode 100644
index 62c7b76b..00000000
--- a/src/base/component/powered_by.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-use crate::prelude::*;
-
-use std::convert::Into;
-
-#[derive(Default, Eq, PartialEq)]
-pub enum PoweredByLogo {
- #[default]
- None,
- Color,
- LineDark,
- LineLight,
- LineRGB(u8, u8, u8),
-}
-
-#[rustfmt::skip]
-#[derive(AutoDefault)]
-pub struct PoweredBy {
- copyright: Option,
- logo : PoweredByLogo,
-}
-
-impl ComponentTrait for PoweredBy {
- fn new() -> Self {
- let year = Utc::now().format("%Y").to_string();
- let c = concat_string!(year, " © ", global::SETTINGS.app.name);
- PoweredBy {
- copyright: Some(c),
- ..Default::default()
- }
- }
-
- fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
- let poweredby_pagetop = L10n::l("poweredby_pagetop")
- .with_arg(
- "pagetop_link",
- "PageTop",
- )
- .escaped(cx.langid());
-
- let pagetop_logo = match self.logo() {
- PoweredByLogo::None => html! {},
- PoweredByLogo::Color => self.logo_color(cx),
- PoweredByLogo::LineDark => self.logo_line(10, 11, 9, cx),
- PoweredByLogo::LineLight => self.logo_line(255, 255, 255, cx),
- PoweredByLogo::LineRGB(r, g, b) => self.logo_line(*r, *g, *b, cx),
- };
-
- PrepareMarkup::With(html! {
- div id=[self.id()] class="poweredby__container" {
- @if let Some(c) = self.copyright() {
- span class="poweredby__copyright" { (c) "." } " "
- }
- span class="poweredby__pagetop" { (poweredby_pagetop) " " (pagetop_logo) }
- }
- })
- }
-}
-
-impl PoweredBy {
- // PoweredBy BUILDER.
-
- #[fn_builder]
- pub fn set_copyright(&mut self, copyright: Option>) -> &mut Self {
- self.copyright = copyright.map(Into::into);
- self
- }
-
- #[fn_builder]
- pub fn set_logo(&mut self, logo: PoweredByLogo) -> &mut Self {
- self.logo = logo;
- self
- }
-
- // PoweredBy GETTERS.
-
- pub fn copyright(&self) -> &Option {
- &self.copyright
- }
-
- pub fn logo(&self) -> &PoweredByLogo {
- &self.logo
- }
-
- // PoweredBy PRIVATE.
-
- fn logo_color(&self, cx: &mut Context) -> Markup {
- let logo_txt = &L10n::l("pagetop_logo").using(cx.langid());
- html! {
- span class="poweredby__logo" aria-label=[logo_txt] {
- img src="/base/pagetop-logo.svg" alt=[logo_txt] {}
- }
- }
- }
-
- fn logo_line(&self, r: u8, g: u8, b: u8, cx: &mut Context) -> Markup {
- let logo_txt = L10n::l("pagetop_logo").using(cx.langid());
- let logo_rgb = format!("rgb({r},{g},{b})");
- html! {
- span class="poweredby__logo" aria-label=[logo_txt] {
- svg viewBox="0 0 1614 1614" xmlns="http://www.w3.org/2000/svg" role="img" {
- path fill=(logo_rgb) d="M 1573,357 L 1415,357 C 1400,357 1388,369 1388,383 L 1388,410 1335,410 1335,357 C 1335,167 1181,13 992,13 L 621,13 C 432,13 278,167 278,357 L 278,410 225,410 225,383 C 225,369 213,357 198,357 L 40,357 C 25,357 13,369 13,383 L 13,648 C 13,662 25,674 40,674 L 198,674 C 213,674 225,662 225,648 L 225,621 278,621 278,1256 C 278,1446 432,1600 621,1600 L 992,1600 C 1181,1600 1335,1446 1335,1256 L 1335,621 1388,621 1388,648 C 1388,662 1400,674 1415,674 L 1573,674 C 1588,674 1600,662 1600,648 L 1600,383 C 1600,369 1588,357 1573,357 L 1573,357 1573,357 Z M 66,410 L 172,410 172,621 66,621 66,410 66,410 Z M 1282,357 L 1282,488 C 1247,485 1213,477 1181,464 L 1196,437 C 1203,425 1199,409 1186,401 1174,394 1158,398 1150,411 L 1133,440 C 1105,423 1079,401 1056,376 L 1075,361 C 1087,352 1089,335 1079,324 1070,313 1054,311 1042,320 L 1023,335 C 1000,301 981,263 967,221 L 1011,196 C 1023,189 1028,172 1021,160 1013,147 997,143 984,150 L 953,168 C 945,136 941,102 940,66 L 992,66 C 1152,66 1282,197 1282,357 L 1282,357 1282,357 Z M 621,66 L 674,66 674,225 648,225 C 633,225 621,237 621,251 621,266 633,278 648,278 L 674,278 674,357 648,357 C 633,357 621,369 621,383 621,398 633,410 648,410 L 674,410 674,489 648,489 C 633,489 621,501 621,516 621,530 633,542 648,542 L 664,542 C 651,582 626,623 600,662 583,653 563,648 542,648 469,648 410,707 410,780 410,787 411,794 412,801 388,805 361,806 331,806 L 331,357 C 331,197 461,66 621,66 L 621,66 621,66 Z M 621,780 C 621,824 586,859 542,859 498,859 463,824 463,780 463,736 498,701 542,701 586,701 621,736 621,780 L 621,780 621,780 Z M 225,463 L 278,463 278,569 225,569 225,463 225,463 Z M 992,1547 L 621,1547 C 461,1547 331,1416 331,1256 L 331,859 C 367,859 400,858 431,851 454,888 495,912 542,912 615,912 674,853 674,780 674,747 662,718 642,695 675,645 706,594 720,542 L 780,542 C 795,542 807,530 807,516 807,501 795,489 780,489 L 727,489 727,410 780,410 C 795,410 807,398 807,383 807,369 795,357 780,357 L 727,357 727,278 780,278 C 795,278 807,266 807,251 807,237 795,225 780,225 L 727,225 727,66 887,66 C 889,111 895,155 905,196 L 869,217 C 856,224 852,240 859,253 864,261 873,266 882,266 887,266 891,265 895,263 L 921,248 C 937,291 958,331 983,367 L 938,403 C 926,412 925,429 934,440 939,447 947,450 954,450 960,450 966,448 971,444 L 1016,408 C 1043,438 1074,465 1108,485 L 1084,527 C 1076,539 1081,555 1093,563 1098,565 1102,566 1107,566 1116,566 1125,561 1129,553 L 1155,509 C 1194,527 1237,538 1282,541 L 1282,1256 C 1282,1416 1152,1547 992,1547 L 992,1547 992,1547 Z M 1335,463 L 1388,463 1388,569 1335,569 1335,463 1335,463 Z M 1441,410 L 1547,410 1547,621 1441,621 1441,410 1441,410 Z" {}
- path fill=(logo_rgb) d="M 1150,1018 L 463,1018 C 448,1018 436,1030 436,1044 L 436,1177 C 436,1348 545,1468 701,1468 L 912,1468 C 1068,1468 1177,1348 1177,1177 L 1177,1044 C 1177,1030 1165,1018 1150,1018 L 1150,1018 1150,1018 Z M 912,1071 L 1018,1071 1018,1124 912,1124 912,1071 912,1071 Z M 489,1071 L 542,1071 542,1124 489,1124 489,1071 489,1071 Z M 701,1415 L 700,1415 C 701,1385 704,1352 718,1343 731,1335 759,1341 795,1359 802,1363 811,1363 818,1359 854,1341 882,1335 895,1343 909,1352 912,1385 913,1415 L 912,1415 701,1415 701,1415 701,1415 Z M 1124,1177 C 1124,1296 1061,1384 966,1408 964,1365 958,1320 922,1298 894,1281 856,1283 807,1306 757,1283 719,1281 691,1298 655,1320 649,1365 647,1408 552,1384 489,1296 489,1177 L 569,1177 C 583,1177 595,1165 595,1150 L 595,1071 859,1071 859,1150 C 859,1165 871,1177 886,1177 L 1044,1177 C 1059,1177 1071,1165 1071,1150 L 1071,1071 1124,1071 1124,1177 1124,1177 1124,1177 Z" {}
- path fill=(logo_rgb) d="M 1071,648 C 998,648 939,707 939,780 939,853 998,912 1071,912 1144,912 1203,853 1203,780 1203,707 1144,648 1071,648 L 1071,648 1071,648 Z M 1071,859 C 1027,859 992,824 992,780 992,736 1027,701 1071,701 1115,701 1150,736 1150,780 1150,824 1115,859 1071,859 L 1071,859 1071,859 Z" {}
- }
- }
- }
- }
-}
diff --git a/src/base/package.rs b/src/base/package.rs
index 1b0fa82b..7b633f33 100644
--- a/src/base/package.rs
+++ b/src/base/package.rs
@@ -1,2 +1,133 @@
-mod welcome;
-pub use welcome::Welcome;
+use crate::prelude::*;
+
+pub struct Welcome;
+
+impl PackageTrait for Welcome {
+ fn name(&self) -> L10n {
+ L10n::l("welcome_package_name")
+ }
+
+ fn description(&self) -> L10n {
+ L10n::l("welcome_package_description")
+ }
+
+ fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
+ scfg.route("/", service::web::get().to(homepage));
+ }
+}
+
+async fn homepage(request: HttpRequest) -> ResultPage {
+ Page::new(request)
+ .with_title(L10n::l("welcome_page"))
+ .with_assets(AssetsOp::Theme("Basic"))
+ .with_assets(AssetsOp::AddStyleSheet(StyleSheet::inline("styles", r##"
+ body {
+ background-color: #f3d060;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ font-size: 20px;
+ }
+ .skip__to_content {
+ display: none;
+ }
+ .wrapper {
+ max-width: 1200px;
+ width: 100%;
+ margin: 0 auto;
+ padding: 0;
+ }
+ .container {
+ padding: 0 16px;
+ }
+ .title {
+ font-size: clamp(3rem, 10vw, 10rem);
+ letter-spacing: -0.05em;
+ line-height: 1.2;
+ margin: 0;
+ }
+ .subtitle {
+ font-size: clamp(1.8rem, 2vw, 3rem);
+ letter-spacing: -0.02em;
+ line-height: 1.2;
+ margin: 0;
+ }
+ .powered {
+ margin: .5em 0 1em;
+ }
+ .box-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: stretch;
+ gap: 1.5em;
+ }
+ .box {
+ flex: 1 1 280px;
+ border: 3px solid #25282a;
+ box-shadow: 5px 5px 0px #25282a;
+ box-sizing: border-box;
+ padding: 0 16px;
+ }
+ footer {
+ margin-top: 5em;
+ font-size: 14px;
+ font-weight: 500;
+ color: #a5282c;
+ }
+ "##)))
+ .with_component(Html::with(html! {
+ div class="wrapper" {
+ div class="container" {
+ h1 class="title" { (L10n::l("welcome_title").markup()) }
+
+ p class="subtitle" {
+ (L10n::l("welcome_intro").with_arg("app", format!(
+ "{}",
+ &global::SETTINGS.app.name
+ )).markup())
+ }
+ p class="powered" {
+ (L10n::l("welcome_powered").with_arg("pagetop", format!(
+ "{}",
+ "https://crates.io/crates/pagetop", "PageTop"
+ )).markup())
+ }
+
+ h2 { (L10n::l("welcome_page").markup()) }
+
+ div class="box-container" {
+ section class="box" style="background-color: #5eb0e5;" {
+ h3 {
+ (L10n::l("welcome_subtitle")
+ .with_arg("app", &global::SETTINGS.app.name)
+ .markup())
+ }
+ p { (L10n::l("welcome_text1").markup()) }
+ p { (L10n::l("welcome_text2").markup()) }
+ }
+ section class="box" style="background-color: #aee1cd;" {
+ h3 {
+ (L10n::l("welcome_pagetop_title").markup())
+ }
+ p { (L10n::l("welcome_pagetop_text1").markup()) }
+ p { (L10n::l("welcome_pagetop_text2").markup()) }
+ p { (L10n::l("welcome_pagetop_text3").markup()) }
+ }
+ section class="box" style="background-color: #ebebe3;" {
+ h3 {
+ (L10n::l("welcome_issues_title").markup())
+ }
+ p { (L10n::l("welcome_issues_text1").markup()) }
+ p {
+ (L10n::l("welcome_issues_text2")
+ .with_arg("app", &global::SETTINGS.app.name)
+ .markup())
+ }
+ }
+ }
+
+ footer { "[ " (L10n::l("welcome_have_fun").markup()) " ]" }
+ }
+ }
+ }))
+ .render()
+}
diff --git a/src/base/package/welcome.rs b/src/base/package/welcome.rs
deleted file mode 100644
index 7b633f33..00000000
--- a/src/base/package/welcome.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use crate::prelude::*;
-
-pub struct Welcome;
-
-impl PackageTrait for Welcome {
- fn name(&self) -> L10n {
- L10n::l("welcome_package_name")
- }
-
- fn description(&self) -> L10n {
- L10n::l("welcome_package_description")
- }
-
- fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
- scfg.route("/", service::web::get().to(homepage));
- }
-}
-
-async fn homepage(request: HttpRequest) -> ResultPage {
- Page::new(request)
- .with_title(L10n::l("welcome_page"))
- .with_assets(AssetsOp::Theme("Basic"))
- .with_assets(AssetsOp::AddStyleSheet(StyleSheet::inline("styles", r##"
- body {
- background-color: #f3d060;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
- font-size: 20px;
- }
- .skip__to_content {
- display: none;
- }
- .wrapper {
- max-width: 1200px;
- width: 100%;
- margin: 0 auto;
- padding: 0;
- }
- .container {
- padding: 0 16px;
- }
- .title {
- font-size: clamp(3rem, 10vw, 10rem);
- letter-spacing: -0.05em;
- line-height: 1.2;
- margin: 0;
- }
- .subtitle {
- font-size: clamp(1.8rem, 2vw, 3rem);
- letter-spacing: -0.02em;
- line-height: 1.2;
- margin: 0;
- }
- .powered {
- margin: .5em 0 1em;
- }
- .box-container {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- align-items: stretch;
- gap: 1.5em;
- }
- .box {
- flex: 1 1 280px;
- border: 3px solid #25282a;
- box-shadow: 5px 5px 0px #25282a;
- box-sizing: border-box;
- padding: 0 16px;
- }
- footer {
- margin-top: 5em;
- font-size: 14px;
- font-weight: 500;
- color: #a5282c;
- }
- "##)))
- .with_component(Html::with(html! {
- div class="wrapper" {
- div class="container" {
- h1 class="title" { (L10n::l("welcome_title").markup()) }
-
- p class="subtitle" {
- (L10n::l("welcome_intro").with_arg("app", format!(
- "{}",
- &global::SETTINGS.app.name
- )).markup())
- }
- p class="powered" {
- (L10n::l("welcome_powered").with_arg("pagetop", format!(
- "{}",
- "https://crates.io/crates/pagetop", "PageTop"
- )).markup())
- }
-
- h2 { (L10n::l("welcome_page").markup()) }
-
- div class="box-container" {
- section class="box" style="background-color: #5eb0e5;" {
- h3 {
- (L10n::l("welcome_subtitle")
- .with_arg("app", &global::SETTINGS.app.name)
- .markup())
- }
- p { (L10n::l("welcome_text1").markup()) }
- p { (L10n::l("welcome_text2").markup()) }
- }
- section class="box" style="background-color: #aee1cd;" {
- h3 {
- (L10n::l("welcome_pagetop_title").markup())
- }
- p { (L10n::l("welcome_pagetop_text1").markup()) }
- p { (L10n::l("welcome_pagetop_text2").markup()) }
- p { (L10n::l("welcome_pagetop_text3").markup()) }
- }
- section class="box" style="background-color: #ebebe3;" {
- h3 {
- (L10n::l("welcome_issues_title").markup())
- }
- p { (L10n::l("welcome_issues_text1").markup()) }
- p {
- (L10n::l("welcome_issues_text2")
- .with_arg("app", &global::SETTINGS.app.name)
- .markup())
- }
- }
- }
-
- footer { "[ " (L10n::l("welcome_have_fun").markup()) " ]" }
- }
- }
- }))
- .render()
-}
diff --git a/src/base/theme.rs b/src/base/theme.rs
index 7b9b442f..c07ffc56 100644
--- a/src/base/theme.rs
+++ b/src/base/theme.rs
@@ -1,8 +1,11 @@
-mod basic;
-pub use basic::Basic;
+use crate::prelude::*;
-mod chassis;
-pub use chassis::Chassis;
+pub struct Basic;
-mod inception;
-pub use inception::Inception;
+impl PackageTrait for Basic {
+ fn theme(&self) -> Option {
+ Some(&Basic)
+ }
+}
+
+impl ThemeTrait for Basic {}
diff --git a/src/base/theme/basic.rs b/src/base/theme/basic.rs
deleted file mode 100644
index c07ffc56..00000000
--- a/src/base/theme/basic.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use crate::prelude::*;
-
-pub struct Basic;
-
-impl PackageTrait for Basic {
- fn theme(&self) -> Option {
- Some(&Basic)
- }
-}
-
-impl ThemeTrait for Basic {}
diff --git a/src/base/theme/chassis.rs b/src/base/theme/chassis.rs
deleted file mode 100644
index b59b1ce9..00000000
--- a/src/base/theme/chassis.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use crate::prelude::*;
-
-pub struct Chassis;
-
-impl PackageTrait for Chassis {
- fn name(&self) -> L10n {
- L10n::n("Chassis")
- }
-
- fn theme(&self) -> Option {
- Some(&Chassis)
- }
-}
-
-impl ThemeTrait for Chassis {
- fn after_prepare_body(&self, page: &mut Page) {
- page.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/normalize.min.css")
- .with_version("8.0.1")
- .with_weight(-90),
- ))
- .set_assets(AssetsOp::AddBaseAssets)
- .set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/chassis.css")
- .with_version("0.0.1")
- .with_weight(-90),
- ));
- }
-}
diff --git a/src/base/theme/inception.rs b/src/base/theme/inception.rs
deleted file mode 100644
index 13f257fc..00000000
--- a/src/base/theme/inception.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use crate::prelude::*;
-
-pub struct Inception;
-
-impl PackageTrait for Inception {
- fn name(&self) -> L10n {
- L10n::n("Inception")
- }
-
- fn theme(&self) -> Option {
- Some(&Inception)
- }
-}
-
-impl ThemeTrait for Inception {
- fn after_prepare_body(&self, page: &mut Page) {
- page.set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/normalize.min.css")
- .with_version("8.0.1")
- .with_weight(-90),
- ))
- .set_assets(AssetsOp::AddBaseAssets)
- .set_assets(AssetsOp::AddStyleSheet(
- StyleSheet::from("/base/css/inception.css")
- .with_version("0.0.1")
- .with_weight(-90),
- ));
- }
-}
diff --git a/src/core/component.rs b/src/core/component.rs
index af116771..5a02ee0e 100644
--- a/src/core/component.rs
+++ b/src/core/component.rs
@@ -1,5 +1,5 @@
mod context;
-pub use context::{AssetsOp, Context, ParamError};
+pub use context::{AssetsOp, Context, ErrorParam};
pub type FnContextualPath = fn(cx: &Context) -> &str;
mod definition;
@@ -8,7 +8,7 @@ pub use definition::{ComponentBase, ComponentTrait};
mod classes;
pub use classes::{ComponentClasses, ComponentClassesOp};
-mod mixed;
-pub use mixed::MixedComponents;
-pub use mixed::{AnyComponent, AnyOp};
-pub use mixed::{TypedComponent, TypedOp};
+mod children;
+pub use children::Children;
+pub use children::{ChildComponent, ChildOp};
+pub use children::{TypedComponent, TypedOp};
diff --git a/src/core/component/mixed.rs b/src/core/component/children.rs
similarity index 60%
rename from src/core/component/mixed.rs
rename to src/core/component/children.rs
index e93444bb..9a5db05b 100644
--- a/src/core/component/mixed.rs
+++ b/src/core/component/children.rs
@@ -5,20 +5,20 @@ use crate::{fn_builder, TypeId};
use std::sync::{Arc, RwLock};
#[derive(Clone)]
-pub struct AnyComponent(Arc>);
+pub struct ChildComponent(Arc>);
-impl AnyComponent {
+impl ChildComponent {
pub fn with(component: impl ComponentTrait) -> Self {
- AnyComponent(Arc::new(RwLock::new(component)))
+ ChildComponent(Arc::new(RwLock::new(component)))
}
- // AnyComponent RENDER.
+ // ChildComponent RENDER.
pub fn render(&self, cx: &mut Context) -> Markup {
self.0.write().unwrap().render(cx)
}
- // AnyComponent HELPERS.
+ // ChildComponent HELPERS.
fn type_id(&self) -> TypeId {
self.0.read().unwrap().type_id()
@@ -52,20 +52,20 @@ impl TypedComponent {
// TypedComponent HELPERS.
- fn to_any(&self) -> AnyComponent {
- AnyComponent(self.0.clone())
+ fn to_child(&self) -> ChildComponent {
+ ChildComponent(self.0.clone())
}
}
// *************************************************************************************************
-pub enum AnyOp {
- Add(AnyComponent),
- InsertAfterId(&'static str, AnyComponent),
- InsertBeforeId(&'static str, AnyComponent),
- Prepend(AnyComponent),
+pub enum ChildOp {
+ Add(ChildComponent),
+ InsertAfterId(&'static str, ChildComponent),
+ InsertBeforeId(&'static str, ChildComponent),
+ Prepend(ChildComponent),
RemoveById(&'static str),
- ReplaceById(&'static str, AnyComponent),
+ ReplaceById(&'static str, ChildComponent),
Reset,
}
@@ -80,37 +80,37 @@ pub enum TypedOp {
}
#[derive(Clone, Default)]
-pub struct MixedComponents(Vec);
+pub struct Children(Vec);
-impl MixedComponents {
+impl Children {
pub fn new() -> Self {
- MixedComponents::default()
+ Children::default()
}
- pub fn with(any: AnyComponent) -> Self {
- MixedComponents::default().with_value(AnyOp::Add(any))
+ pub fn with(child: ChildComponent) -> Self {
+ Children::default().with_value(ChildOp::Add(child))
}
- pub(crate) fn merge(mixes: &[Option<&MixedComponents>]) -> Self {
- let mut opt = MixedComponents::default();
+ pub(crate) fn merge(mixes: &[Option<&Children>]) -> Self {
+ let mut opt = Children::default();
for m in mixes.iter().flatten() {
opt.0.append(&mut m.0.clone());
}
opt
}
- // MixedComponents BUILDER.
+ // Children BUILDER.
#[fn_builder]
- pub fn set_value(&mut self, op: AnyOp) -> &mut Self {
+ pub fn set_value(&mut self, op: ChildOp) -> &mut Self {
match op {
- AnyOp::Add(any) => self.add(any),
- AnyOp::InsertAfterId(id, any) => self.insert_after_id(id, any),
- AnyOp::InsertBeforeId(id, any) => self.insert_before_id(id, any),
- AnyOp::Prepend(any) => self.prepend(any),
- AnyOp::RemoveById(id) => self.remove_by_id(id),
- AnyOp::ReplaceById(id, any) => self.replace_by_id(id, any),
- AnyOp::Reset => self.reset(),
+ ChildOp::Add(any) => self.add(any),
+ ChildOp::InsertAfterId(id, any) => self.insert_after_id(id, any),
+ ChildOp::InsertBeforeId(id, any) => self.insert_before_id(id, any),
+ ChildOp::Prepend(any) => self.prepend(any),
+ ChildOp::RemoveById(id) => self.remove_by_id(id),
+ ChildOp::ReplaceById(id, any) => self.replace_by_id(id, any),
+ ChildOp::Reset => self.reset(),
};
self
}
@@ -118,41 +118,41 @@ impl MixedComponents {
#[fn_builder]
pub fn set_typed(&mut self, op: TypedOp) -> &mut Self {
match op {
- TypedOp::Add(typed) => self.add(typed.to_any()),
- TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.to_any()),
- TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.to_any()),
- TypedOp::Prepend(typed) => self.prepend(typed.to_any()),
+ TypedOp::Add(typed) => self.add(typed.to_child()),
+ TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.to_child()),
+ TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.to_child()),
+ TypedOp::Prepend(typed) => self.prepend(typed.to_child()),
TypedOp::RemoveById(id) => self.remove_by_id(id),
- TypedOp::ReplaceById(id, typed) => self.replace_by_id(id, typed.to_any()),
+ TypedOp::ReplaceById(id, typed) => self.replace_by_id(id, typed.to_child()),
TypedOp::Reset => self.reset(),
};
self
}
#[inline]
- fn add(&mut self, any: AnyComponent) {
- self.0.push(any);
+ fn add(&mut self, child: ChildComponent) {
+ self.0.push(child);
}
#[inline]
- fn insert_after_id(&mut self, id: &str, any: AnyComponent) {
+ fn insert_after_id(&mut self, id: &str, child: ChildComponent) {
match self.0.iter().position(|c| c.id() == id) {
- Some(index) => self.0.insert(index + 1, any),
- _ => self.0.push(any),
+ Some(index) => self.0.insert(index + 1, child),
+ _ => self.0.push(child),
};
}
#[inline]
- fn insert_before_id(&mut self, id: &str, any: AnyComponent) {
+ fn insert_before_id(&mut self, id: &str, child: ChildComponent) {
match self.0.iter().position(|c| c.id() == id) {
- Some(index) => self.0.insert(index, any),
- _ => self.0.insert(0, any),
+ Some(index) => self.0.insert(index, child),
+ _ => self.0.insert(0, child),
};
}
#[inline]
- fn prepend(&mut self, any: AnyComponent) {
- self.0.insert(0, any);
+ fn prepend(&mut self, child: ChildComponent) {
+ self.0.insert(0, child);
}
#[inline]
@@ -163,10 +163,10 @@ impl MixedComponents {
}
#[inline]
- fn replace_by_id(&mut self, id: &str, any: AnyComponent) {
+ fn replace_by_id(&mut self, id: &str, child: ChildComponent) {
for c in &mut self.0 {
if c.id() == id {
- *c = any;
+ *c = child;
break;
}
}
@@ -177,7 +177,7 @@ impl MixedComponents {
self.0.clear();
}
- // MixedComponents GETTERS.
+ // Children GETTERS.
pub fn len(&self) -> usize {
self.0.len()
@@ -187,21 +187,21 @@ impl MixedComponents {
self.0.is_empty()
}
- pub fn get_by_id(&self, id: impl Into) -> Option<&AnyComponent> {
+ pub fn get_by_id(&self, id: impl Into) -> Option<&ChildComponent> {
let id = id.into();
self.0.iter().find(|c| c.id() == id)
}
- pub fn iter_by_id(&self, id: impl Into) -> impl Iterator
- {
+ pub fn iter_by_id(&self, id: impl Into) -> impl Iterator
- {
let id = id.into();
self.0.iter().filter(move |&c| c.id() == id)
}
- pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator
- {
+ pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator
- {
self.0.iter().filter(move |&c| c.type_id() == type_id)
}
- // MixedComponents RENDER.
+ // Children RENDER.
pub fn render(&self, cx: &mut Context) -> Markup {
html! {
diff --git a/src/core/component/context.rs b/src/core/component/context.rs
index 439afb05..45bdcb87 100644
--- a/src/core/component/context.rs
+++ b/src/core/component/context.rs
@@ -1,8 +1,7 @@
-use crate::base::component::add_base_assets;
use crate::concat_string;
-use crate::core::component::AnyOp;
+use crate::core::component::ChildOp;
use crate::core::theme::all::{theme_by_short_name, DEFAULT_THEME};
-use crate::core::theme::{ComponentsInRegions, ThemeRef};
+use crate::core::theme::{ChildrenInRegions, ThemeRef};
use crate::html::{html, Markup};
use crate::html::{Assets, Favicon, JavaScript, StyleSheet};
use crate::locale::{LanguageIdentifier, DEFAULT_LANGID};
@@ -28,26 +27,24 @@ pub enum AssetsOp {
// JavaScripts.
AddJavaScript(JavaScript),
RemoveJavaScript(&'static str),
- // Add assets to properly use base components.
- AddBaseAssets,
}
#[derive(Debug)]
-pub enum ParamError {
+pub enum ErrorParam {
NotFound,
ParseError(String),
}
-impl fmt::Display for ParamError {
+impl fmt::Display for ErrorParam {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- ParamError::NotFound => write!(f, "Parameter not found"),
- ParamError::ParseError(e) => write!(f, "Parse error: {e}"),
+ ErrorParam::NotFound => write!(f, "Parameter not found"),
+ ErrorParam::ParseError(e) => write!(f, "Parse error: {e}"),
}
}
}
-impl Error for ParamError {}
+impl Error for ErrorParam {}
#[rustfmt::skip]
pub struct Context {
@@ -58,7 +55,7 @@ pub struct Context {
favicon : Option,
stylesheet: Assets,
javascript: Assets,
- regions : ComponentsInRegions,
+ regions : ChildrenInRegions,
params : HashMap<&'static str, String>,
id_counter: usize,
}
@@ -74,7 +71,7 @@ impl Context {
favicon : None,
stylesheet: Assets::::new(),
javascript: Assets::::new(),
- regions : ComponentsInRegions::default(),
+ regions : ChildrenInRegions::default(),
params : HashMap::<&str, String>::new(),
id_counter: 0,
}
@@ -114,16 +111,12 @@ impl Context {
AssetsOp::RemoveJavaScript(path) => {
self.javascript.remove(path);
}
- // Add assets to properly use base components.
- AssetsOp::AddBaseAssets => {
- add_base_assets(self);
- }
}
self
}
- pub fn set_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self {
- self.regions.set_components(region, op);
+ pub fn set_in_region(&mut self, region: &'static str, op: ChildOp) -> &mut Self {
+ self.regions.set_in_region(region, op);
self
}
@@ -150,32 +143,32 @@ impl Context {
self.layout
}
- pub fn regions(&self) -> &ComponentsInRegions {
+ pub fn regions(&self) -> &ChildrenInRegions {
&self.regions
}
- pub fn get_param(&self, key: &'static str) -> Result {
+ pub fn get_param(&self, key: &'static str) -> Result {
self.params
.get(key)
- .ok_or(ParamError::NotFound)
- .and_then(|v| T::from_str(v).map_err(|_| ParamError::ParseError(v.clone())))
+ .ok_or(ErrorParam::NotFound)
+ .and_then(|v| T::from_str(v).map_err(|_| ErrorParam::ParseError(v.clone())))
}
- // Context PREPARE.
+ // Context RENDER.
- pub(crate) fn prepare_assets(&mut self) -> Markup {
+ pub fn render_assets(&mut self) -> Markup {
html! {
@if let Some(favicon) = &self.favicon {
- (favicon.prepare())
+ (favicon.render())
}
- (self.stylesheet.prepare())
- (self.javascript.prepare())
+ (self.stylesheet.render())
+ (self.javascript.render())
}
}
- pub(crate) fn prepare_region(&mut self, region: impl Into) -> Markup {
+ pub fn render_region(&mut self, region: impl Into) -> Markup {
self.regions
- .all_components(self.theme, region.into().as_str())
+ .all_in_region(self.theme, ®ion.into())
.render(self)
}
diff --git a/src/core/package/all.rs b/src/core/package/all.rs
index e41d62df..301d3a02 100644
--- a/src/core/package/all.rs
+++ b/src/core/package/all.rs
@@ -129,8 +129,6 @@ pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
m.configure_service(scfg);
}
include_files_service!(
- scfg,
- assets => "/",
- [&global::SETTINGS.dev.pagetop_project_dir, "static/assets"]
+ scfg, assets => "/", [&global::SETTINGS.dev.pagetop_project_dir, "static"]
);
}
diff --git a/src/core/theme.rs b/src/core/theme.rs
index 1925071a..adb99d59 100644
--- a/src/core/theme.rs
+++ b/src/core/theme.rs
@@ -2,7 +2,7 @@ mod definition;
pub use definition::{ThemeRef, ThemeTrait};
mod regions;
-pub(crate) use regions::ComponentsInRegions;
+pub(crate) use regions::ChildrenInRegions;
pub use regions::InRegion;
pub(crate) mod all;
diff --git a/src/core/theme/definition.rs b/src/core/theme/definition.rs
index 6f474516..01e1cb04 100644
--- a/src/core/theme/definition.rs
+++ b/src/core/theme/definition.rs
@@ -1,80 +1,20 @@
-use crate::base::component::*;
-use crate::core::component::{ComponentBase, ComponentTrait};
use crate::core::package::PackageTrait;
-use crate::html::{html, PrepareMarkup};
+use crate::global;
+use crate::html::{html, Markup};
use crate::locale::L10n;
use crate::response::page::Page;
-use crate::{concat_string, global};
pub type ThemeRef = &'static dyn ThemeTrait;
/// Los temas deben implementar este "trait".
pub trait ThemeTrait: PackageTrait + Send + Sync {
- #[rustfmt::skip]
fn regions(&self) -> Vec<(&'static str, L10n)> {
- vec![
- ("header", L10n::l("header")),
- ("pagetop", L10n::l("pagetop")),
- ("sidebar_left", L10n::l("sidebar_left")),
- ("content", L10n::l("content")),
- ("sidebar_right", L10n::l("sidebar_right")),
- ("footer", L10n::l("footer")),
- ]
+ vec![("content", L10n::l("content"))]
}
- #[allow(unused_variables)]
- fn before_prepare_body(&self, page: &mut Page) {}
-
- fn prepare_body(&self, page: &mut Page) -> PrepareMarkup {
- let skip_to_id = page.body_skip_to().get().unwrap_or("content".to_owned());
-
- PrepareMarkup::With(html! {
- body id=[page.body_id().get()] class=[page.body_classes().get()] {
- @if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
- div class="skip__to_content" {
- a href=(concat_string!("#", skip_to_id)) { (skip) }
- }
- }
- (flex::Container::new()
- .with_id("body__wrapper")
- .with_direction(flex::Direction::Column(BreakPoint::None))
- .with_align(flex::Align::Center)
- .add_item(flex::Item::region().with_id("header"))
- .add_item(flex::Item::region().with_id("pagetop"))
- .add_item(
- flex::Item::with(
- flex::Container::new()
- .with_direction(flex::Direction::Row(BreakPoint::None))
- .add_item(
- flex::Item::region()
- .with_id("sidebar_left")
- .with_grow(flex::Grow::Is1),
- )
- .add_item(
- flex::Item::region()
- .with_id("content")
- .with_grow(flex::Grow::Is3),
- )
- .add_item(
- flex::Item::region()
- .with_id("sidebar_right")
- .with_grow(flex::Grow::Is1),
- ),
- )
- .with_id("flex__wrapper"),
- )
- .add_item(flex::Item::region().with_id("footer"))
- .render(page.context()))
- }
- })
- }
-
- #[allow(unused_variables)]
- fn after_prepare_body(&self, page: &mut Page) {}
-
- fn prepare_head(&self, page: &mut Page) -> PrepareMarkup {
+ fn render_head(&self, page: &mut Page) -> Markup {
let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no";
- PrepareMarkup::With(html! {
+ html! {
head {
meta charset="utf-8";
@@ -98,37 +38,22 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
meta property=(property) content=(content) {}
}
- (page.context().prepare_assets())
+ (page.context().render_assets())
}
- })
+ }
}
- /*
- fn prepare_page_body(&self, page: &mut Page) -> PrepareMarkup {
- PrepareMarkup::With(html! {
+
+ #[allow(unused_variables)]
+ fn before_render_body(&self, page: &mut Page) {}
+
+ fn render_body(&self, page: &mut Page) -> Markup {
+ html! {
body id=[page.body_id().get()] class=[page.body_classes().get()] {
- (page.body_content().render())
+ (page.context().render_region("content"))
}
- })
+ }
}
- fn error_403(&self, request: service::HttpRequest) -> Page {
- Page::new(request)
- .with_title(L10n::n("Error FORBIDDEN"))
- .with_body(PrepareMarkup::With(html! {
- div {
- h1 { ("FORBIDDEN ACCESS") }
- }
- }))
- }
-
- fn error_404(&self, request: service::HttpRequest) -> Page {
- Page::new(request)
- .with_title(L10n::n("Error RESOURCE NOT FOUND"))
- .with_body(PrepareMarkup::With(html! {
- div {
- h1 { ("RESOURCE NOT FOUND") }
- }
- }))
- }
- */
+ #[allow(unused_variables)]
+ fn after_render_body(&self, page: &mut Page) {}
}
diff --git a/src/core/theme/regions.rs b/src/core/theme/regions.rs
index da2e24ff..7e8128c5 100644
--- a/src/core/theme/regions.rs
+++ b/src/core/theme/regions.rs
@@ -1,40 +1,44 @@
-use crate::core::component::{AnyComponent, AnyOp, MixedComponents};
+use crate::core::component::{ChildComponent, ChildOp, Children};
use crate::core::theme::ThemeRef;
use crate::{fn_builder, AutoDefault, TypeId};
use std::collections::HashMap;
use std::sync::{LazyLock, RwLock};
-static THEME_REGIONS: LazyLock>> =
+static THEME_REGIONS: LazyLock>> =
LazyLock::new(|| RwLock::new(HashMap::new()));
-static COMMON_REGIONS: LazyLock> =
- LazyLock::new(|| RwLock::new(ComponentsInRegions::default()));
+static COMMON_REGIONS: LazyLock> =
+ LazyLock::new(|| RwLock::new(ChildrenInRegions::default()));
#[derive(AutoDefault)]
-pub struct ComponentsInRegions(HashMap<&'static str, MixedComponents>);
+pub struct ChildrenInRegions(HashMap<&'static str, Children>);
-impl ComponentsInRegions {
- pub fn new(region: &'static str, any: AnyComponent) -> Self {
- ComponentsInRegions::default().with_components(region, AnyOp::Add(any))
+impl ChildrenInRegions {
+ pub fn new() -> Self {
+ ChildrenInRegions::default()
+ }
+
+ pub fn with(region: &'static str, child: ChildComponent) -> Self {
+ ChildrenInRegions::default().with_in_region(region, ChildOp::Add(child))
}
#[fn_builder]
- pub fn set_components(&mut self, region: &'static str, op: AnyOp) -> &mut Self {
+ pub fn set_in_region(&mut self, region: &'static str, op: ChildOp) -> &mut Self {
if let Some(region) = self.0.get_mut(region) {
region.set_value(op);
} else {
- self.0.insert(region, MixedComponents::new().with_value(op));
+ self.0.insert(region, Children::new().with_value(op));
}
self
}
- pub fn all_components(&self, theme: ThemeRef, region: &str) -> MixedComponents {
+ pub fn all_in_region(&self, theme: ThemeRef, region: &str) -> Children {
let common = COMMON_REGIONS.read().unwrap();
if let Some(r) = THEME_REGIONS.read().unwrap().get(&theme.type_id()) {
- MixedComponents::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)])
+ Children::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)])
} else {
- MixedComponents::merge(&[common.0.get(region), self.0.get(region)])
+ Children::merge(&[common.0.get(region), self.0.get(region)])
}
}
}
@@ -46,26 +50,26 @@ pub enum InRegion {
}
impl InRegion {
- pub fn add(&self, any: AnyComponent) -> &Self {
+ pub fn add(&self, child: ChildComponent) -> &Self {
match self {
InRegion::Content => {
COMMON_REGIONS
.write()
.unwrap()
- .set_components("content", AnyOp::Add(any));
+ .set_in_region("content", ChildOp::Add(child));
}
InRegion::Named(name) => {
COMMON_REGIONS
.write()
.unwrap()
- .set_components(name, AnyOp::Add(any));
+ .set_in_region(name, ChildOp::Add(child));
}
InRegion::OfTheme(region, theme) => {
let mut regions = THEME_REGIONS.write().unwrap();
if let Some(r) = regions.get_mut(&theme.type_id()) {
- r.set_components(region, AnyOp::Add(any));
+ r.set_in_region(region, ChildOp::Add(child));
} else {
- regions.insert(theme.type_id(), ComponentsInRegions::new(region, any));
+ regions.insert(theme.type_id(), ChildrenInRegions::with(region, child));
}
}
}
diff --git a/src/html/assets.rs b/src/html/assets.rs
index 4c8f27ce..c8b8f1b9 100644
--- a/src/html/assets.rs
+++ b/src/html/assets.rs
@@ -10,7 +10,7 @@ pub trait AssetsTrait {
fn weight(&self) -> Weight;
- fn prepare(&self) -> Markup;
+ fn render(&self) -> Markup;
}
#[derive(AutoDefault)]
@@ -41,12 +41,12 @@ impl Assets {
self
}
- pub fn prepare(&mut self) -> Markup {
+ pub fn render(&mut self) -> Markup {
let assets = &mut self.0;
assets.sort_by_key(AssetsTrait::weight);
html! {
@for a in assets {
- (a.prepare())
+ (a.render())
}
}
}
diff --git a/src/html/assets/favicon.rs b/src/html/assets/favicon.rs
index 068efcb4..366da4ff 100644
--- a/src/html/assets/favicon.rs
+++ b/src/html/assets/favicon.rs
@@ -83,7 +83,7 @@ impl Favicon {
// Favicon PREPARE.
- pub(crate) fn prepare(&self) -> Markup {
+ pub(crate) fn render(&self) -> Markup {
html! {
@for item in &self.0 {
(item)
diff --git a/src/html/assets/javascript.rs b/src/html/assets/javascript.rs
index 672ab3e0..76d84673 100644
--- a/src/html/assets/javascript.rs
+++ b/src/html/assets/javascript.rs
@@ -36,7 +36,7 @@ impl AssetsTrait for JavaScript {
self.weight
}
- fn prepare(&self) -> Markup {
+ fn render(&self) -> Markup {
match &self.source {
Source::From(path) => html! {
script src=(concat_string!(path, self.prefix, self.version)) {};
diff --git a/src/html/assets/stylesheet.rs b/src/html/assets/stylesheet.rs
index 11dde4ef..5dd65a97 100644
--- a/src/html/assets/stylesheet.rs
+++ b/src/html/assets/stylesheet.rs
@@ -38,7 +38,7 @@ impl AssetsTrait for StyleSheet {
self.weight
}
- fn prepare(&self) -> Markup {
+ fn render(&self) -> Markup {
match &self.source {
Source::From(path) => html! {
link
diff --git a/src/lib.rs b/src/lib.rs
index ad7b24f7..a5369718 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,7 +53,7 @@
//! ```
//! This program implements a package named `HelloWorld` with one service that returns a web page
//! that greets the world whenever it is accessed from the browser at `http://localhost:8088` (using
-//! the [default configuration settings](`config::Server`)). You can find this code in the `PageTop`
+//! the [default configuration settings](`global::Server`)). You can find this code in the `PageTop`
//! [examples repository](https://github.com/manuelcillero/pagetop/tree/latest/examples).
//!
//! # 🧩 Dependency Management
@@ -79,22 +79,14 @@ pub use concat_string::concat_string;
/// Enables flexible identifier concatenation in macros, allowing new items with pasted identifiers.
pub use paste::paste;
-pub use pagetop_macros::{fn_builder, main, test, AutoDefault, ComponentClasses};
+pub use pagetop_macros::{fn_builder, html, main, test, AutoDefault, ComponentClasses};
-// *************************************************************************************************
-// GLOBAL.
-// *************************************************************************************************
-
-pub use static_files::Resource as StaticResource;
-
-pub type HashMapResources = std::collections::HashMap<&'static str, StaticResource>;
+pub type StaticResources = std::collections::HashMap<&'static str, static_files::Resource>;
pub use std::any::TypeId;
pub type Weight = i8;
-include_locales!(LOCALES_PAGETOP);
-
// API *********************************************************************************************
// Useful functions and macros.
diff --git a/src/locale.rs b/src/locale.rs
index 513c7f70..6cc79c9f 100644
--- a/src/locale.rs
+++ b/src/locale.rs
@@ -1,21 +1,19 @@
//! Localization (L10n).
//!
-//! PageTop uses the [Fluent](https://www.projectfluent.org/) set of specifications for application
-//! localization.
+//! PageTop uses the [Fluent](https://www.projectfluent.org/) specifications for application
+//! localization, leveraging the [fluent-templates](https://docs.rs/fluent-templates/) crate to
+//! integrate translation resources directly into the application binary.
//!
//! # Fluent Syntax (FTL)
//!
//! The format used to describe the translation resources used by Fluent is called
-//! [FTL](https://www.projectfluent.org/fluent/guide/). FTL is designed to be easy to read while
-//! simultaneously allowing the representation of complex natural language concepts to address
-//! gender, plurals, conjugations, and others.
+//! [FTL](https://www.projectfluent.org/fluent/guide/). FTL is designed to be both readable and
+//! expressive, enabling complex natural language constructs like gender, plurals, and conjugations.
//!
//! # Fluent Resources
//!
-//! PageTop utilizes [fluent-templates](https://docs.rs/fluent-templates/) to integrate localization
-//! resources into the application binary. The following example groups files and subfolders from
-//! *src/locale* that have a valid [Unicode Language Identifier](https://docs.rs/unic-langid/) and
-//! assigns them to their corresponding identifier:
+//! Localization resources are organized in the *src/locale* directory, with subdirectories for
+//! each valid [Unicode Language Identifier](https://docs.rs/unic-langid/):
//!
//! ```text
//! src/locale/
@@ -69,13 +67,13 @@
//! # How to apply localization in your code
//!
//! Once you have created your FTL resource directory, use the
-//! [`static_locales!`](crate::static_locales) macro to integrate them into your module or
+//! [`include_locales!`](crate::include_locales) macro to integrate them into your module or
//! application. If your resources are located in the `"src/locale"` directory, simply declare:
//!
//! ```
//! use pagetop::prelude::*;
//!
-//! static_locales!(LOCALES_SAMPLE);
+//! include_locales!(LOCALES_SAMPLE);
//! ```
//!
//! But if they are in another directory, then you can use:
@@ -83,14 +81,14 @@
//! ```
//! use pagetop::prelude::*;
//!
-//! static_locales!(LOCALES_SAMPLE in "path/to/locale");
+//! include_locales!(LOCALES_SAMPLE from "path/to/locale");
//! ```
use crate::html::{Markup, PreEscaped};
-use crate::{global, kv, AutoDefault, LOCALES_PAGETOP};
+use crate::{global, kv, AutoDefault};
pub use fluent_templates;
-pub use unic_langid::LanguageIdentifier;
+pub use unic_langid::{CharacterDirection, LanguageIdentifier};
use fluent_templates::Loader;
use fluent_templates::StaticLoader as Locales;
@@ -102,45 +100,61 @@ use std::sync::LazyLock;
use std::fmt;
-const LANGUAGE_SET_FAILURE: &str = "language_set_failure";
-
+/// A mapping between language codes (e.g., "en-US") and their corresponding [`LanguageIdentifier`]
+/// and locale key names.
static LANGUAGES: LazyLock> = LazyLock::new(|| {
kv![
- "en" => (langid!("en-US"), "English"),
- "en-GB" => (langid!("en-GB"), "English (British)"),
- "en-US" => (langid!("en-US"), "English (United States)"),
- "es" => (langid!("es-ES"), "Spanish"),
- "es-ES" => (langid!("es-ES"), "Spanish (Spain)"),
+ "en" => ( langid!("en-US"), "english" ),
+ "en-GB" => ( langid!("en-GB"), "english_british" ),
+ "en-US" => ( langid!("en-US"), "english_united_states" ),
+ "es" => ( langid!("es-ES"), "spanish" ),
+ "es-ES" => ( langid!("es-ES"), "spanish_spain" ),
]
});
-static FALLBACK_LANGID: LazyLock = LazyLock::new(|| langid!("en-US"));
+pub static FALLBACK_LANGID: LazyLock = LazyLock::new(|| langid!("en-US"));
/// Sets the application's default
/// [Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)
/// through `SETTINGS.app.language`.
-pub static DEFAULT_LANGID: LazyLock<&LanguageIdentifier> = LazyLock::new(|| {
- langid_for(global::SETTINGS.app.language.as_str()).unwrap_or(&FALLBACK_LANGID)
-});
+pub static DEFAULT_LANGID: LazyLock<&LanguageIdentifier> =
+ LazyLock::new(|| langid_for(&global::SETTINGS.app.language).unwrap_or(&FALLBACK_LANGID));
-pub fn langid_for(language: impl Into) -> Result<&'static LanguageIdentifier, String> {
- let language = language.into();
- match LANGUAGES.get(language.as_str()) {
- Some((langid, _)) => Ok(langid),
- None => {
- if language.is_empty() {
- Ok(&FALLBACK_LANGID)
- } else {
- Err(format!(
- "No langid for Unicode Language Identifier \"{language}\".",
- ))
- }
+pub enum LangError {
+ EmptyLang,
+ UnknownLang(String),
+}
+
+impl fmt::Display for LangError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ LangError::EmptyLang => write!(f, "The language identifier is empty."),
+ LangError::UnknownLang(lang) => write!(f, "Unknown language identifier: {lang}"),
}
}
}
+pub fn langid_for(language: impl Into) -> Result<&'static LanguageIdentifier, LangError> {
+ let language = language.into();
+ if language.is_empty() {
+ return Err(LangError::EmptyLang);
+ }
+ // Attempt to match the full language code (e.g., "es-MX").
+ if let Some(langid) = LANGUAGES.get(&language).map(|(langid, _)| langid) {
+ return Ok(langid);
+ }
+ // Fallback to the base language if no sublocale is found (e.g., "es").
+ if let Some((base_lang, _)) = language.split_once('-') {
+ if let Some(langid) = LANGUAGES.get(base_lang).map(|(langid, _)| langid) {
+ return Ok(langid);
+ }
+ }
+ Err(LangError::UnknownLang(language))
+}
+
#[macro_export]
-/// Defines a set of localization elements and local translation texts.
+/// Defines a set of localization elements and local translation texts, removing Unicode isolating
+/// marks around arguments to improve readability and compatibility in certain rendering contexts.
macro_rules! include_locales {
( $LOCALES:ident $(, $core_locales:literal)? ) => {
$crate::locale::fluent_templates::static_loader! {
@@ -153,7 +167,7 @@ macro_rules! include_locales {
};
}
};
- ( $LOCALES:ident in $dir_locales:literal $(, $core_locales:literal)? ) => {
+ ( $LOCALES:ident from $dir_locales:literal $(, $core_locales:literal)? ) => {
$crate::locale::fluent_templates::static_loader! {
static $LOCALES = {
locales: $dir_locales,
@@ -166,6 +180,8 @@ macro_rules! include_locales {
};
}
+include_locales!(LOCALES_PAGETOP);
+
#[derive(AutoDefault)]
enum L10nOp {
#[default]
@@ -177,7 +193,8 @@ enum L10nOp {
#[derive(AutoDefault)]
pub struct L10n {
op: L10nOp,
- locales: Option<&'static Locales>,
+ #[default(&LOCALES_PAGETOP)]
+ locales: &'static Locales,
args: HashMap,
}
@@ -192,7 +209,6 @@ impl L10n {
pub fn l(key: impl Into) -> Self {
L10n {
op: L10nOp::Translate(key.into()),
- locales: Some(&LOCALES_PAGETOP),
..Default::default()
}
}
@@ -200,7 +216,7 @@ impl L10n {
pub fn t(key: impl Into, locales: &'static Locales) -> Self {
L10n {
op: L10nOp::Translate(key.into()),
- locales: Some(locales),
+ locales,
..Default::default()
}
}
@@ -210,37 +226,44 @@ impl L10n {
self
}
+ pub fn with_args(mut self, args: HashMap) -> Self {
+ for (k, v) in args {
+ self.args.insert(k, v);
+ }
+ self
+ }
+
+ pub fn get(&self) -> Option {
+ self.using(&DEFAULT_LANGID)
+ }
+
pub fn using(&self, langid: &LanguageIdentifier) -> Option {
match &self.op {
L10nOp::None => None,
L10nOp::Text(text) => Some(text.to_owned()),
- L10nOp::Translate(key) => match self.locales {
- Some(locales) => {
- if self.args.is_empty() {
- locales.try_lookup(langid, key)
- } else {
- locales.try_lookup_with_args(
- langid,
- key,
- &self
- .args
- .iter()
- .fold(HashMap::new(), |mut args, (key, value)| {
- args.insert(key.to_string(), value.to_owned().into());
- args
- }),
- )
- }
+ L10nOp::Translate(key) => {
+ if self.args.is_empty() {
+ self.locales.try_lookup(langid, key)
+ } else {
+ self.locales.try_lookup_with_args(
+ langid,
+ key,
+ &self.args.iter().fold(HashMap::new(), |mut args, (k, v)| {
+ args.insert(k.to_string(), v.to_owned().into());
+ args
+ }),
+ )
}
- None => None,
- },
+ }
}
}
+ /// Escapes translated text using the default language identifier.
pub fn markup(&self) -> Markup {
- PreEscaped(self.using(&DEFAULT_LANGID).unwrap_or_default())
+ PreEscaped(self.get().unwrap_or_default())
}
+ /// Escapes translated text using the specified language identifier.
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
PreEscaped(self.using(langid).unwrap_or_default())
}
@@ -248,43 +271,11 @@ impl L10n {
impl fmt::Display for L10n {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match &self.op {
- L10nOp::None => write!(f, ""),
- L10nOp::Text(text) => write!(f, "{text}"),
- L10nOp::Translate(key) => {
- if let Some(locales) = self.locales {
- write!(
- f,
- "{}",
- if self.args.is_empty() {
- locales.lookup(
- match key.as_str() {
- LANGUAGE_SET_FAILURE => &FALLBACK_LANGID,
- _ => &DEFAULT_LANGID,
- },
- key,
- )
- } else {
- locales.lookup_with_args(
- match key.as_str() {
- LANGUAGE_SET_FAILURE => &FALLBACK_LANGID,
- _ => &DEFAULT_LANGID,
- },
- key,
- &self
- .args
- .iter()
- .fold(HashMap::new(), |mut args, (key, value)| {
- args.insert(key.to_string(), value.to_owned().into());
- args
- }),
- )
- }
- )
- } else {
- write!(f, "Unknown localization {key}")
- }
- }
- }
+ let content = match &self.op {
+ L10nOp::None => "".to_string(),
+ L10nOp::Text(text) => text.clone(),
+ L10nOp::Translate(key) => self.get().unwrap_or_else(|| format!("No <{}>", key)),
+ };
+ write!(f, "{content}")
}
}
diff --git a/src/locale/en-US/base.ftl b/src/locale/en-US/base.ftl
deleted file mode 100644
index 9ec4803b..00000000
--- a/src/locale/en-US/base.ftl
+++ /dev/null
@@ -1,13 +0,0 @@
-# Branding component.
-site_home = Home
-
-# PoweredBy component.
-poweredby_pagetop = Powered by {$pagetop_link}
-pagetop_logo = PageTop logo
-
-# Menu component.
-menu_toggle = Toggle menu visibility
-
-# Form components.
-button_submit = Submit
-button_reset = Reset
diff --git a/src/locale/en-US/theme.ftl b/src/locale/en-US/theme.ftl
index 6b3cb0e8..fd7f228d 100644
--- a/src/locale/en-US/theme.ftl
+++ b/src/locale/en-US/theme.ftl
@@ -1,8 +1 @@
-header = Header
-pagetop = Page Top
content = Content
-sidebar_left = Sidebar Left
-sidebar_right = Sidebar Right
-footer = Footer
-
-skip_to_content = Skip to main content (Press Enter)
diff --git a/src/locale/es-ES/base.ftl b/src/locale/es-ES/base.ftl
deleted file mode 100644
index 953d891c..00000000
--- a/src/locale/es-ES/base.ftl
+++ /dev/null
@@ -1,13 +0,0 @@
-# Branding component.
-site_home = Inicio
-
-# PoweredBy component.
-poweredby_pagetop = Funciona con {$pagetop_link}
-pagetop_logo = Logotipo de PageTop
-
-# Menu component.
-menu_toggle = Alternar visibilidad del menú
-
-# Form components.
-button_submit = Enviar
-button_reset = Reiniciar
diff --git a/src/locale/es-ES/theme.ftl b/src/locale/es-ES/theme.ftl
index fb5caacd..c2026c6f 100644
--- a/src/locale/es-ES/theme.ftl
+++ b/src/locale/es-ES/theme.ftl
@@ -1,8 +1 @@
-header = Cabecera
-pagetop = Superior
content = Contenido
-sidebar_left = Barra lateral izquierda
-sidebar_right = Barra lateral derecha
-footer = Pie
-
-skip_to_content = Ir al contenido principal (Pulsar Intro)
diff --git a/src/prelude.rs b/src/prelude.rs
index 1a3efc92..9d0d465f 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -4,7 +4,7 @@
pub use crate::{concat_string, fn_builder, html, main, paste, test};
-pub use crate::{AutoDefault, ComponentClasses, HashMapResources, TypeId, Weight};
+pub use crate::{AutoDefault, ComponentClasses, StaticResources, TypeId, Weight};
// MACROS.
diff --git a/src/response/page.rs b/src/response/page.rs
index c3e268b5..340bd0c7 100644
--- a/src/response/page.rs
+++ b/src/response/page.rs
@@ -4,8 +4,8 @@ pub use error::ErrorPage;
pub use actix_web::Result as ResultPage;
use crate::base::action;
-use crate::core::component::{AnyComponent, AnyOp, ComponentTrait};
use crate::core::component::{AssetsOp, Context};
+use crate::core::component::{ChildComponent, ChildOp, ComponentTrait};
use crate::fn_builder;
use crate::html::{html, Markup, DOCTYPE};
use crate::html::{ClassesOp, OptionClasses, OptionId, OptionTranslated};
@@ -98,14 +98,14 @@ impl Page {
}
#[fn_builder]
- pub fn set_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self {
- self.context.set_regions(region, op);
+ pub fn set_in_region(&mut self, region: &'static str, op: ChildOp) -> &mut Self {
+ self.context.set_in_region(region, op);
self
}
pub fn with_component(mut self, component: impl ComponentTrait) -> Self {
self.context
- .set_regions("content", AnyOp::Add(AnyComponent::with(component)));
+ .set_in_region("content", ChildOp::Add(ChildComponent::with(component)));
self
}
@@ -115,7 +115,7 @@ impl Page {
component: impl ComponentTrait,
) -> Self {
self.context
- .set_regions(region, AnyOp::Add(AnyComponent::with(component)));
+ .set_in_region(region, ChildOp::Add(ChildComponent::with(component)));
self
}
@@ -156,26 +156,26 @@ impl Page {
// Page RENDER.
pub fn render(&mut self) -> ResultPage {
- // Theme operations before preparing the page body.
- self.context.theme().before_prepare_body(self);
+ // Theme-specific operations before rendering the page body.
+ self.context.theme().before_render_body(self);
- // Packages actions before preparing the page body.
- action::page::BeforePrepareBody::dispatch(self);
+ // Execute package actions before rendering the page body.
+ action::page::BeforeRenderBody::dispatch(self);
- // Prepare page body.
- let body = self.context.theme().prepare_body(self);
+ // Render the page body.
+ let body = self.context.theme().render_body(self);
- // Theme operations after preparing the page body.
- self.context.theme().after_prepare_body(self);
+ // Theme-specific operations after rendering the page body.
+ self.context.theme().after_render_body(self);
- // Packages actions after preparing the page body.
- action::page::AfterPrepareBody::dispatch(self);
+ // Execute package actions after rendering the page body.
+ action::page::AfterRenderBody::dispatch(self);
- // Prepare page head.
- let head = self.context.theme().prepare_head(self);
+ // Render the page head.
+ let head = self.context.theme().render_head(self);
- // Render the page.
- let lang = self.context.langid().language.as_str();
+ // Render the full page with language and direction attributes.
+ let lang = &self.context.langid().language;
let dir = match self.context.langid().character_direction() {
CharacterDirection::LTR => "ltr",
CharacterDirection::RTL => "rtl",
@@ -184,8 +184,8 @@ impl Page {
Ok(html! {
(DOCTYPE)
html lang=(lang) dir=(dir) {
- (head.render())
- (body.render())
+ (head)
+ (body)
}
})
}
diff --git a/static/base/css/basic.css b/static/base/css/basic.css
deleted file mode 100644
index caccc2c9..00000000
--- a/static/base/css/basic.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.skip__to_content {
- display: none;
-}
diff --git a/static/base/css/buttons.css b/static/base/css/buttons.css
deleted file mode 100644
index b53588d6..00000000
--- a/static/base/css/buttons.css
+++ /dev/null
@@ -1,1265 +0,0 @@
-.button__tap {
- cursor: pointer;
- text-align: center;
- display: inline-block;
- text-decoration: none;
- border: 1px solid transparent;
- border-radius: var(--val-border-radius);
- padding: var(--val-gap-0-35) var(--val-gap-0-75);
- transition: background-color .15s ease-in-out;
- white-space: nowrap;
- user-select: none;
-}
-.button__tap > span {
- margin: 0 var(--val-gap-0-5);
-}
-
-.button__tap.style__default {
- color: var(--val-color--white);
- background-color: var(--val-color--primary);
-}
-.button__tap.style__default:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--primary-dark);
-}
-.button__tap.style__default:active,
-.button__tap.style__default:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--primary-light);
-}
-
-.button__tap.style__info:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--info-dark);
-}
-.button__tap.style__info:active,
-.button__tap.style__info:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--info-light);
-}
-
-.button__tap.style__success:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--success-dark);
-}
-.button__tap.style__success:active,
-.button__tap.style__success:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--success-light);
-}
-
-.button__tap.style__warning:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--warning-dark);
-}
-.button__tap.style__warning:active,
-.button__tap.style__warning:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--warning-light);
-}
-
-.button__tap.style__danger:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--danger-dark);
-}
-.button__tap.style__danger:active,
-.button__tap.style__danger:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--danger-light);
-}
-
-.button__tap.style__light:hover {
- color: var(--val-color--text);
- background-color: var(--val-color--light-dark);
-}
-.button__tap.style__light:active,
-.button__tap.style__light:disabled {
- color: var(--val-color--text);
- background-color: var(--val-color--light-light);
-}
-
-.button__tap.style__dark:hover {
- color: var(--val-color--white);
- background-color: var(--val-color--dark-dark);
-}
-.button__tap.style__dark:active,
-.button__tap.style__dark:disabled {
- color: var(--val-color--white);
- background-color: var(--val-color--dark-light);
-}
-
-/*
-.button strong {
- color: inherit
-}
-
-.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small {
- height: 1.5em;
- width: 1.5em
-}
-
-.button .icon:first-child:not(:last-child) {
- margin-left: calc(-.5em - 1px);
- margin-right: .25em
-}
-
-.button .icon:last-child:not(:first-child) {
- margin-left: .25em;
- margin-right: calc(-.5em - 1px)
-}
-
-.button .icon:first-child:last-child {
- margin-left: calc(-.5em - 1px);
- margin-right: calc(-.5em - 1px)
-}
-
-.button__tap.is-hovered,.button:hover {
- border-color: #b5b5b5;
- color: #363636
-}
-
-.button__tap.is-focused,.button:focus {
- border-color: #485fc7;
- color: #363636
-}
-
-.button__tap.is-focused:not(:active),.button:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(72,95,199,.25)
-}
-
-.button__tap.is-active,.button:active {
- border-color: #4a4a4a;
- color: #363636
-}
-
-.button__tap.is-text {
- background-color: transparent;
- border-color: transparent;
- color: #4a4a4a;
- text-decoration: underline
-}
-
-.button__tap.is-text.is-focused,.button__tap.is-text.is-hovered,.button__tap.is-text:focus,.button__tap.is-text:hover {
- background-color: #f5f5f5;
- color: #363636
-}
-
-.button__tap.is-text.is-active,.button__tap.is-text:active {
- background-color: #e8e8e8;
- color: #363636
-}
-
-.button__tap.is-text[disabled],fieldset[disabled] .button__tap.is-text {
- background-color: transparent;
- border-color: transparent;
- box-shadow: none
-}
-
-.button__tap.is-ghost {
- background: 0 0;
- border-color: transparent;
- color: #485fc7;
- text-decoration: none
-}
-
-.button__tap.is-ghost.is-hovered,.button__tap.is-ghost:hover {
- color: #485fc7;
- text-decoration: underline
-}
-
-.button__tap.is-white {
- background-color: #fff;
- border-color: transparent;
- color: #0a0a0a
-}
-
-.button__tap.is-white.is-hovered,.button__tap.is-white:hover {
- background-color: #f9f9f9;
- border-color: transparent;
- color: #0a0a0a
-}
-
-.button__tap.is-white.is-focused,.button__tap.is-white:focus {
- border-color: transparent;
- color: #0a0a0a
-}
-
-.button__tap.is-white.is-focused:not(:active),.button__tap.is-white:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(255,255,255,.25)
-}
-
-.button__tap.is-white.is-active,.button__tap.is-white:active {
- background-color: #f2f2f2;
- border-color: transparent;
- color: #0a0a0a
-}
-
-.button__tap.is-white[disabled],fieldset[disabled] .button__tap.is-white {
- background-color: #fff;
- border-color: #fff;
- box-shadow: none
-}
-
-.button__tap.is-white.is-inverted {
- background-color: #0a0a0a;
- color: #fff
-}
-
-.button__tap.is-white.is-inverted.is-hovered,.button__tap.is-white.is-inverted:hover {
- background-color: #000
-}
-
-.button__tap.is-white.is-inverted[disabled],fieldset[disabled] .button__tap.is-white.is-inverted {
- background-color: #0a0a0a;
- border-color: transparent;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-white.is-loading::after {
- border-color: transparent transparent #0a0a0a #0a0a0a!important
-}
-
-.button__tap.is-white.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-white.is-outlined.is-focused,.button__tap.is-white.is-outlined.is-hovered,.button__tap.is-white.is-outlined:focus,.button__tap.is-white.is-outlined:hover {
- background-color: #fff;
- border-color: #fff;
- color: #0a0a0a
-}
-
-.button__tap.is-white.is-outlined.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-white.is-outlined.is-loading.is-focused::after,.button__tap.is-white.is-outlined.is-loading.is-hovered::after,.button__tap.is-white.is-outlined.is-loading:focus::after,.button__tap.is-white.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #0a0a0a #0a0a0a!important
-}
-
-.button__tap.is-white.is-outlined[disabled],fieldset[disabled] .button__tap.is-white.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-white.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #0a0a0a;
- color: #0a0a0a
-}
-
-.button__tap.is-white.is-inverted.is-outlined.is-focused,.button__tap.is-white.is-inverted.is-outlined.is-hovered,.button__tap.is-white.is-inverted.is-outlined:focus,.button__tap.is-white.is-inverted.is-outlined:hover {
- background-color: #0a0a0a;
- color: #fff
-}
-
-.button__tap.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-white.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-white.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-white.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #0a0a0a;
- box-shadow: none;
- color: #0a0a0a
-}
-
-.button__tap.is-black {
- background-color: #0a0a0a;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-black.is-hovered,.button__tap.is-black:hover {
- background-color: #040404;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-black.is-focused,.button__tap.is-black:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-black.is-focused:not(:active),.button__tap.is-black:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(10,10,10,.25)
-}
-
-.button__tap.is-black.is-active,.button__tap.is-black:active {
- background-color: #000;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-black[disabled],fieldset[disabled] .button__tap.is-black {
- background-color: #0a0a0a;
- border-color: #0a0a0a;
- box-shadow: none
-}
-
-.button__tap.is-black.is-inverted {
- background-color: #fff;
- color: #0a0a0a
-}
-
-.button__tap.is-black.is-inverted.is-hovered,.button__tap.is-black.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-black.is-inverted[disabled],fieldset[disabled] .button__tap.is-black.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #0a0a0a
-}
-
-.button__tap.is-black.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-black.is-outlined {
- background-color: transparent;
- border-color: #0a0a0a;
- color: #0a0a0a
-}
-
-.button__tap.is-black.is-outlined.is-focused,.button__tap.is-black.is-outlined.is-hovered,.button__tap.is-black.is-outlined:focus,.button__tap.is-black.is-outlined:hover {
- background-color: #0a0a0a;
- border-color: #0a0a0a;
- color: #fff
-}
-
-.button__tap.is-black.is-outlined.is-loading::after {
- border-color: transparent transparent #0a0a0a #0a0a0a!important
-}
-
-.button__tap.is-black.is-outlined.is-loading.is-focused::after,.button__tap.is-black.is-outlined.is-loading.is-hovered::after,.button__tap.is-black.is-outlined.is-loading:focus::after,.button__tap.is-black.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-black.is-outlined[disabled],fieldset[disabled] .button__tap.is-black.is-outlined {
- background-color: transparent;
- border-color: #0a0a0a;
- box-shadow: none;
- color: #0a0a0a
-}
-
-.button__tap.is-black.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-black.is-inverted.is-outlined.is-focused,.button__tap.is-black.is-inverted.is-outlined.is-hovered,.button__tap.is-black.is-inverted.is-outlined:focus,.button__tap.is-black.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #0a0a0a
-}
-
-.button__tap.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-black.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-black.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #0a0a0a #0a0a0a!important
-}
-
-.button__tap.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-black.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-light {
- background-color: #f5f5f5;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-hovered,.button__tap.is-light:hover {
- background-color: #eee;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-focused,.button__tap.is-light:focus {
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-focused:not(:active),.button__tap.is-light:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(245,245,245,.25)
-}
-
-.button__tap.is-light.is-active,.button__tap.is-light:active {
- background-color: #e8e8e8;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light[disabled],fieldset[disabled] .button__tap.is-light {
- background-color: #f5f5f5;
- border-color: #f5f5f5;
- box-shadow: none
-}
-
-.button__tap.is-light.is-inverted {
- background-color: rgba(0,0,0,.7);
- color: #f5f5f5
-}
-
-.button__tap.is-light.is-inverted.is-hovered,.button__tap.is-light.is-inverted:hover {
- background-color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-inverted[disabled],fieldset[disabled] .button__tap.is-light.is-inverted {
- background-color: rgba(0,0,0,.7);
- border-color: transparent;
- box-shadow: none;
- color: #f5f5f5
-}
-
-.button__tap.is-light.is-loading::after {
- border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important
-}
-
-.button__tap.is-light.is-outlined {
- background-color: transparent;
- border-color: #f5f5f5;
- color: #f5f5f5
-}
-
-.button__tap.is-light.is-outlined.is-focused,.button__tap.is-light.is-outlined.is-hovered,.button__tap.is-light.is-outlined:focus,.button__tap.is-light.is-outlined:hover {
- background-color: #f5f5f5;
- border-color: #f5f5f5;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-outlined.is-loading::after {
- border-color: transparent transparent #f5f5f5 #f5f5f5!important
-}
-
-.button__tap.is-light.is-outlined.is-loading.is-focused::after,.button__tap.is-light.is-outlined.is-loading.is-hovered::after,.button__tap.is-light.is-outlined.is-loading:focus::after,.button__tap.is-light.is-outlined.is-loading:hover::after {
- border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important
-}
-
-.button__tap.is-light.is-outlined[disabled],fieldset[disabled] .button__tap.is-light.is-outlined {
- background-color: transparent;
- border-color: #f5f5f5;
- box-shadow: none;
- color: #f5f5f5
-}
-
-.button__tap.is-light.is-inverted.is-outlined {
- background-color: transparent;
- border-color: rgba(0,0,0,.7);
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-light.is-inverted.is-outlined.is-focused,.button__tap.is-light.is-inverted.is-outlined.is-hovered,.button__tap.is-light.is-inverted.is-outlined:focus,.button__tap.is-light.is-inverted.is-outlined:hover {
- background-color: rgba(0,0,0,.7);
- color: #f5f5f5
-}
-
-.button__tap.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-light.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-light.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #f5f5f5 #f5f5f5!important
-}
-
-.button__tap.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-light.is-inverted.is-outlined {
- background-color: transparent;
- border-color: rgba(0,0,0,.7);
- box-shadow: none;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-dark {
- background-color: #363636;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-dark.is-hovered,.button__tap.is-dark:hover {
- background-color: #2f2f2f;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-dark.is-focused,.button__tap.is-dark:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-dark.is-focused:not(:active),.button__tap.is-dark:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(54,54,54,.25)
-}
-
-.button__tap.is-dark.is-active,.button__tap.is-dark:active {
- background-color: #292929;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-dark[disabled],fieldset[disabled] .button__tap.is-dark {
- background-color: #363636;
- border-color: #363636;
- box-shadow: none
-}
-
-.button__tap.is-dark.is-inverted {
- background-color: #fff;
- color: #363636
-}
-
-.button__tap.is-dark.is-inverted.is-hovered,.button__tap.is-dark.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-dark.is-inverted[disabled],fieldset[disabled] .button__tap.is-dark.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #363636
-}
-
-.button__tap.is-dark.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-dark.is-outlined {
- background-color: transparent;
- border-color: #363636;
- color: #363636
-}
-
-.button__tap.is-dark.is-outlined.is-focused,.button__tap.is-dark.is-outlined.is-hovered,.button__tap.is-dark.is-outlined:focus,.button__tap.is-dark.is-outlined:hover {
- background-color: #363636;
- border-color: #363636;
- color: #fff
-}
-
-.button__tap.is-dark.is-outlined.is-loading::after {
- border-color: transparent transparent #363636 #363636!important
-}
-
-.button__tap.is-dark.is-outlined.is-loading.is-focused::after,.button__tap.is-dark.is-outlined.is-loading.is-hovered::after,.button__tap.is-dark.is-outlined.is-loading:focus::after,.button__tap.is-dark.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-dark.is-outlined[disabled],fieldset[disabled] .button__tap.is-dark.is-outlined {
- background-color: transparent;
- border-color: #363636;
- box-shadow: none;
- color: #363636
-}
-
-.button__tap.is-dark.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-dark.is-inverted.is-outlined.is-focused,.button__tap.is-dark.is-inverted.is-outlined.is-hovered,.button__tap.is-dark.is-inverted.is-outlined:focus,.button__tap.is-dark.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #363636
-}
-
-.button__tap.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #363636 #363636!important
-}
-
-.button__tap.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-dark.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-*/
-/*
-.style__default[disabled],fieldset[disabled] .style__default {
- background-color: #00d1b2;
- border-color: #00d1b2;
- box-shadow: none
-}
-
-.style__default.is-inverted {
- background-color: #fff;
- color: #00d1b2
-}
-
-.style__default.is-inverted.is-hovered,.style__default.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.style__default.is-inverted[disabled],fieldset[disabled] .style__default.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #00d1b2
-}
-
-.style__default.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.style__default.is-outlined {
- background-color: transparent;
- border-color: #00d1b2;
- color: #00d1b2
-}
-
-.style__default.is-outlined.is-focused,.style__default.is-outlined.is-hovered,.style__default.is-outlined:focus,.style__default.is-outlined:hover {
- background-color: #00d1b2;
- border-color: #00d1b2;
- color: #fff
-}
-
-.style__default.is-outlined.is-loading::after {
- border-color: transparent transparent #00d1b2 #00d1b2!important
-}
-
-.style__default.is-outlined.is-loading.is-focused::after,.style__default.is-outlined.is-loading.is-hovered::after,.style__default.is-outlined.is-loading:focus::after,.style__default.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.style__default.is-outlined[disabled],fieldset[disabled] .style__default.is-outlined {
- background-color: transparent;
- border-color: #00d1b2;
- box-shadow: none;
- color: #00d1b2
-}
-
-.style__default.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.style__default.is-inverted.is-outlined.is-focused,.style__default.is-inverted.is-outlined.is-hovered,.style__default.is-inverted.is-outlined:focus,.style__default.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #00d1b2
-}
-
-.style__default.is-inverted.is-outlined.is-loading.is-focused::after,.style__default.is-inverted.is-outlined.is-loading.is-hovered::after,.style__default.is-inverted.is-outlined.is-loading:focus::after,.style__default.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #00d1b2 #00d1b2!important
-}
-
-.style__default.is-inverted.is-outlined[disabled],fieldset[disabled] .style__default.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.style__default.is-light {
- background-color: #ebfffc;
- color: #00947e
-}
-
-.style__default.is-light.is-hovered,.style__default.is-light:hover {
- background-color: #defffa;
- border-color: transparent;
- color: #00947e
-}
-
-.style__default.is-light.is-active,.style__default.is-light:active {
- background-color: #d1fff8;
- border-color: transparent;
- color: #00947e
-}
-
-.button__tap.is-link {
- background-color: #485fc7;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-link.is-hovered,.button__tap.is-link:hover {
- background-color: #3e56c4;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-link.is-focused,.button__tap.is-link:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-link.is-focused:not(:active),.button__tap.is-link:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(72,95,199,.25)
-}
-
-.button__tap.is-link.is-active,.button__tap.is-link:active {
- background-color: #3a51bb;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-link[disabled],fieldset[disabled] .button__tap.is-link {
- background-color: #485fc7;
- border-color: #485fc7;
- box-shadow: none
-}
-
-.button__tap.is-link.is-inverted {
- background-color: #fff;
- color: #485fc7
-}
-
-.button__tap.is-link.is-inverted.is-hovered,.button__tap.is-link.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-link.is-inverted[disabled],fieldset[disabled] .button__tap.is-link.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #485fc7
-}
-
-.button__tap.is-link.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-link.is-outlined {
- background-color: transparent;
- border-color: #485fc7;
- color: #485fc7
-}
-
-.button__tap.is-link.is-outlined.is-focused,.button__tap.is-link.is-outlined.is-hovered,.button__tap.is-link.is-outlined:focus,.button__tap.is-link.is-outlined:hover {
- background-color: #485fc7;
- border-color: #485fc7;
- color: #fff
-}
-
-.button__tap.is-link.is-outlined.is-loading::after {
- border-color: transparent transparent #485fc7 #485fc7!important
-}
-
-.button__tap.is-link.is-outlined.is-loading.is-focused::after,.button__tap.is-link.is-outlined.is-loading.is-hovered::after,.button__tap.is-link.is-outlined.is-loading:focus::after,.button__tap.is-link.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-link.is-outlined[disabled],fieldset[disabled] .button__tap.is-link.is-outlined {
- background-color: transparent;
- border-color: #485fc7;
- box-shadow: none;
- color: #485fc7
-}
-
-.button__tap.is-link.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-link.is-inverted.is-outlined.is-focused,.button__tap.is-link.is-inverted.is-outlined.is-hovered,.button__tap.is-link.is-inverted.is-outlined:focus,.button__tap.is-link.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #485fc7
-}
-
-.button__tap.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-link.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-link.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #485fc7 #485fc7!important
-}
-
-.button__tap.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-link.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-link.is-light {
- background-color: #eff1fa;
- color: #3850b7
-}
-
-.button__tap.is-link.is-light.is-hovered,.button__tap.is-link.is-light:hover {
- background-color: #e6e9f7;
- border-color: transparent;
- color: #3850b7
-}
-
-.button__tap.is-link.is-light.is-active,.button__tap.is-link.is-light:active {
- background-color: #dce0f4;
- border-color: transparent;
- color: #3850b7
-}
-
-.button__tap.is-info {
- background-color: #3e8ed0;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-info.is-hovered,.button__tap.is-info:hover {
- background-color: #3488ce;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-info.is-focused,.button__tap.is-info:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-info.is-focused:not(:active),.button__tap.is-info:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(62,142,208,.25)
-}
-
-.button__tap.is-info.is-active,.button__tap.is-info:active {
- background-color: #3082c5;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-info[disabled],fieldset[disabled] .button__tap.is-info {
- background-color: #3e8ed0;
- border-color: #3e8ed0;
- box-shadow: none
-}
-
-.button__tap.is-info.is-inverted {
- background-color: #fff;
- color: #3e8ed0
-}
-
-.button__tap.is-info.is-inverted.is-hovered,.button__tap.is-info.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-info.is-inverted[disabled],fieldset[disabled] .button__tap.is-info.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #3e8ed0
-}
-
-.button__tap.is-info.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-info.is-outlined {
- background-color: transparent;
- border-color: #3e8ed0;
- color: #3e8ed0
-}
-
-.button__tap.is-info.is-outlined.is-focused,.button__tap.is-info.is-outlined.is-hovered,.button__tap.is-info.is-outlined:focus,.button__tap.is-info.is-outlined:hover {
- background-color: #3e8ed0;
- border-color: #3e8ed0;
- color: #fff
-}
-
-.button__tap.is-info.is-outlined.is-loading::after {
- border-color: transparent transparent #3e8ed0 #3e8ed0!important
-}
-
-.button__tap.is-info.is-outlined.is-loading.is-focused::after,.button__tap.is-info.is-outlined.is-loading.is-hovered::after,.button__tap.is-info.is-outlined.is-loading:focus::after,.button__tap.is-info.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-info.is-outlined[disabled],fieldset[disabled] .button__tap.is-info.is-outlined {
- background-color: transparent;
- border-color: #3e8ed0;
- box-shadow: none;
- color: #3e8ed0
-}
-
-.button__tap.is-info.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-info.is-inverted.is-outlined.is-focused,.button__tap.is-info.is-inverted.is-outlined.is-hovered,.button__tap.is-info.is-inverted.is-outlined:focus,.button__tap.is-info.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #3e8ed0
-}
-
-.button__tap.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-info.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-info.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #3e8ed0 #3e8ed0!important
-}
-
-.button__tap.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-info.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-info.is-light {
- background-color: #eff5fb;
- color: #296fa8
-}
-
-.button__tap.is-info.is-light.is-hovered,.button__tap.is-info.is-light:hover {
- background-color: #e4eff9;
- border-color: transparent;
- color: #296fa8
-}
-
-.button__tap.is-info.is-light.is-active,.button__tap.is-info.is-light:active {
- background-color: #dae9f6;
- border-color: transparent;
- color: #296fa8
-}
-
-.button__tap.is-success {
- background-color: #48c78e;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-success.is-hovered,.button__tap.is-success:hover {
- background-color: #3ec487;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-success.is-focused,.button__tap.is-success:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-success.is-focused:not(:active),.button__tap.is-success:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(72,199,142,.25)
-}
-
-.button__tap.is-success.is-active,.button__tap.is-success:active {
- background-color: #3abb81;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-success[disabled],fieldset[disabled] .button__tap.is-success {
- background-color: #48c78e;
- border-color: #48c78e;
- box-shadow: none
-}
-
-.button__tap.is-success.is-inverted {
- background-color: #fff;
- color: #48c78e
-}
-
-.button__tap.is-success.is-inverted.is-hovered,.button__tap.is-success.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-success.is-inverted[disabled],fieldset[disabled] .button__tap.is-success.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #48c78e
-}
-
-.button__tap.is-success.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-success.is-outlined {
- background-color: transparent;
- border-color: #48c78e;
- color: #48c78e
-}
-
-.button__tap.is-success.is-outlined.is-focused,.button__tap.is-success.is-outlined.is-hovered,.button__tap.is-success.is-outlined:focus,.button__tap.is-success.is-outlined:hover {
- background-color: #48c78e;
- border-color: #48c78e;
- color: #fff
-}
-
-.button__tap.is-success.is-outlined.is-loading::after {
- border-color: transparent transparent #48c78e #48c78e!important
-}
-
-.button__tap.is-success.is-outlined.is-loading.is-focused::after,.button__tap.is-success.is-outlined.is-loading.is-hovered::after,.button__tap.is-success.is-outlined.is-loading:focus::after,.button__tap.is-success.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-success.is-outlined[disabled],fieldset[disabled] .button__tap.is-success.is-outlined {
- background-color: transparent;
- border-color: #48c78e;
- box-shadow: none;
- color: #48c78e
-}
-
-.button__tap.is-success.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-success.is-inverted.is-outlined.is-focused,.button__tap.is-success.is-inverted.is-outlined.is-hovered,.button__tap.is-success.is-inverted.is-outlined:focus,.button__tap.is-success.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #48c78e
-}
-
-.button__tap.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-success.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-success.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #48c78e #48c78e!important
-}
-
-.button__tap.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-success.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-success.is-light {
- background-color: #effaf5;
- color: #257953
-}
-
-.button__tap.is-success.is-light.is-hovered,.button__tap.is-success.is-light:hover {
- background-color: #e6f7ef;
- border-color: transparent;
- color: #257953
-}
-
-.button__tap.is-success.is-light.is-active,.button__tap.is-success.is-light:active {
- background-color: #dcf4e9;
- border-color: transparent;
- color: #257953
-}
-
-.button__tap.is-warning {
- background-color: #ffe08a;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-hovered,.button__tap.is-warning:hover {
- background-color: #ffdc7d;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-focused,.button__tap.is-warning:focus {
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-focused:not(:active),.button__tap.is-warning:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(255,224,138,.25)
-}
-
-.button__tap.is-warning.is-active,.button__tap.is-warning:active {
- background-color: #ffd970;
- border-color: transparent;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning[disabled],fieldset[disabled] .button__tap.is-warning {
- background-color: #ffe08a;
- border-color: #ffe08a;
- box-shadow: none
-}
-
-.button__tap.is-warning.is-inverted {
- background-color: rgba(0,0,0,.7);
- color: #ffe08a
-}
-
-.button__tap.is-warning.is-inverted.is-hovered,.button__tap.is-warning.is-inverted:hover {
- background-color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-inverted[disabled],fieldset[disabled] .button__tap.is-warning.is-inverted {
- background-color: rgba(0,0,0,.7);
- border-color: transparent;
- box-shadow: none;
- color: #ffe08a
-}
-
-.button__tap.is-warning.is-loading::after {
- border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important
-}
-
-.button__tap.is-warning.is-outlined {
- background-color: transparent;
- border-color: #ffe08a;
- color: #ffe08a
-}
-
-.button__tap.is-warning.is-outlined.is-focused,.button__tap.is-warning.is-outlined.is-hovered,.button__tap.is-warning.is-outlined:focus,.button__tap.is-warning.is-outlined:hover {
- background-color: #ffe08a;
- border-color: #ffe08a;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-outlined.is-loading::after {
- border-color: transparent transparent #ffe08a #ffe08a!important
-}
-
-.button__tap.is-warning.is-outlined.is-loading.is-focused::after,.button__tap.is-warning.is-outlined.is-loading.is-hovered::after,.button__tap.is-warning.is-outlined.is-loading:focus::after,.button__tap.is-warning.is-outlined.is-loading:hover::after {
- border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important
-}
-
-.button__tap.is-warning.is-outlined[disabled],fieldset[disabled] .button__tap.is-warning.is-outlined {
- background-color: transparent;
- border-color: #ffe08a;
- box-shadow: none;
- color: #ffe08a
-}
-
-.button__tap.is-warning.is-inverted.is-outlined {
- background-color: transparent;
- border-color: rgba(0,0,0,.7);
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-inverted.is-outlined.is-focused,.button__tap.is-warning.is-inverted.is-outlined.is-hovered,.button__tap.is-warning.is-inverted.is-outlined:focus,.button__tap.is-warning.is-inverted.is-outlined:hover {
- background-color: rgba(0,0,0,.7);
- color: #ffe08a
-}
-
-.button__tap.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #ffe08a #ffe08a!important
-}
-
-.button__tap.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-warning.is-inverted.is-outlined {
- background-color: transparent;
- border-color: rgba(0,0,0,.7);
- box-shadow: none;
- color: rgba(0,0,0,.7)
-}
-
-.button__tap.is-warning.is-light {
- background-color: #fffaeb;
- color: #946c00
-}
-
-.button__tap.is-warning.is-light.is-hovered,.button__tap.is-warning.is-light:hover {
- background-color: #fff6de;
- border-color: transparent;
- color: #946c00
-}
-
-.button__tap.is-warning.is-light.is-active,.button__tap.is-warning.is-light:active {
- background-color: #fff3d1;
- border-color: transparent;
- color: #946c00
-}
-
-.button__tap.is-danger {
- background-color: #f14668;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-danger.is-hovered,.button__tap.is-danger:hover {
- background-color: #f03a5f;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-danger.is-focused,.button__tap.is-danger:focus {
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-danger.is-focused:not(:active),.button__tap.is-danger:focus:not(:active) {
- box-shadow: 0 0 0 .125em rgba(241,70,104,.25)
-}
-
-.button__tap.is-danger.is-active,.button__tap.is-danger:active {
- background-color: #ef2e55;
- border-color: transparent;
- color: #fff
-}
-
-.button__tap.is-danger[disabled],fieldset[disabled] .button__tap.is-danger {
- background-color: #f14668;
- border-color: #f14668;
- box-shadow: none
-}
-
-.button__tap.is-danger.is-inverted {
- background-color: #fff;
- color: #f14668
-}
-
-.button__tap.is-danger.is-inverted.is-hovered,.button__tap.is-danger.is-inverted:hover {
- background-color: #f2f2f2
-}
-
-.button__tap.is-danger.is-inverted[disabled],fieldset[disabled] .button__tap.is-danger.is-inverted {
- background-color: #fff;
- border-color: transparent;
- box-shadow: none;
- color: #f14668
-}
-
-.button__tap.is-danger.is-loading::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-danger.is-outlined {
- background-color: transparent;
- border-color: #f14668;
- color: #f14668
-}
-
-.button__tap.is-danger.is-outlined.is-focused,.button__tap.is-danger.is-outlined.is-hovered,.button__tap.is-danger.is-outlined:focus,.button__tap.is-danger.is-outlined:hover {
- background-color: #f14668;
- border-color: #f14668;
- color: #fff
-}
-
-.button__tap.is-danger.is-outlined.is-loading::after {
- border-color: transparent transparent #f14668 #f14668!important
-}
-
-.button__tap.is-danger.is-outlined.is-loading.is-focused::after,.button__tap.is-danger.is-outlined.is-loading.is-hovered::after,.button__tap.is-danger.is-outlined.is-loading:focus::after,.button__tap.is-danger.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #fff #fff!important
-}
-
-.button__tap.is-danger.is-outlined[disabled],fieldset[disabled] .button__tap.is-danger.is-outlined {
- background-color: transparent;
- border-color: #f14668;
- box-shadow: none;
- color: #f14668
-}
-
-.button__tap.is-danger.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- color: #fff
-}
-
-.button__tap.is-danger.is-inverted.is-outlined.is-focused,.button__tap.is-danger.is-inverted.is-outlined.is-hovered,.button__tap.is-danger.is-inverted.is-outlined:focus,.button__tap.is-danger.is-inverted.is-outlined:hover {
- background-color: #fff;
- color: #f14668
-}
-
-.button__tap.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading:hover::after {
- border-color: transparent transparent #f14668 #f14668!important
-}
-
-.button__tap.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-danger.is-inverted.is-outlined {
- background-color: transparent;
- border-color: #fff;
- box-shadow: none;
- color: #fff
-}
-
-.button__tap.is-danger.is-light {
- background-color: #feecf0;
- color: #cc0f35
-}
-
-.button__tap.is-danger.is-light.is-hovered,.button__tap.is-danger.is-light:hover {
- background-color: #fde0e6;
- border-color: transparent;
- color: #cc0f35
-}
-
-.button__tap.is-danger.is-light.is-active,.button__tap.is-danger.is-light:active {
- background-color: #fcd4dc;
- border-color: transparent;
- color: #cc0f35
-}
-*/
\ No newline at end of file
diff --git a/static/base/css/chassis.css b/static/base/css/chassis.css
deleted file mode 100644
index 1cc2f5dc..00000000
--- a/static/base/css/chassis.css
+++ /dev/null
@@ -1,356 +0,0 @@
-html {
- background-color: white;
- padding: 1px 3px;
-}
-body {
- padding: 1px 3px;
-}
-div {
- padding: 1px 3px;
- margin: 5px;
-}
-h1, h2, h3, h4,h5, h6, p {
- background-color: snow;
-}
-* * {
- outline: 5px solid rgba(255,0,0,.1);
-}
-* * * {
- outline: 3px dashed rgba(255,0,0,.4);
-}
-* * * * {
- outline: 2px dotted rgba(255,0,0,.6);
-}
-* * * * * {
- outline: 1px dotted rgba(255,0,0,.9);
-}
-* * * * * * {
- outline-color: gray;
-}
-
-*::before, *::after {
- background: #faa;
- border-radius: 3px;
- font: normal normal 400 10px/1.2 monospace;
- vertical-align: middle;
- padding: 1px 3px;
- margin: 0 3px;
-}
-*::before {
- content: "(";
-}
-*::after {
- content: ")";
-}
-
-a::before { content: ""; }
-a::after { content: ""; }
-abbr::before { content: ""; }
-abbr::after { content: ""; }
-acronym::before { content: ""; }
-acronym::after { content: ""; }
-address::before { content: ""; }
-address::after { content: ""; }
-applet::before { content: ""; }
-area::before { content: ""; }
-area::after { content: ""; }
-article::before { content: ""; }
-article::after { content: ""; }
-aside::before { content: ""; }
-audio::before { content: ""; }
-
-b::before { content: ""; }
-b::after { content: ""; }
-base::before { content: ""; }
-base::after { content: ""; }
-basefont::before { content: ""; }
-basefont::after { content: ""; }
-bdi::before { content: ""; }
-bdi::after { content: ""; }
-bdo::before { content: ""; }
-bdo::after { content: ""; }
-bgsound::before { content: ""; }
-bgsound::after { content: ""; }
-big::before { content: ""; }
-big::after { content: ""; }
-blink::before { content: ""; }
-blockquote::before { content: "
"; }
-blockquote::after { content: "
"; }
-body::before { content: ""; }
-body::after { content: ""; }
-br::before { content: "
"; }
-br::after { content: ""; }
-button::before { content: ""; }
-
-caption::before { content: ""; }
-caption::after { content: ""; }
-canvas::before { content: ""; }
-center::before { content: ""; }
-center::after { content: ""; }
-cite::before { content: ""; }
-cite::after { content: ""; }
-code::before { content: ""; }
-code::after { content: ""; }
-col::before { content: ""; }
-col::after { content: ""; }
-colgroup::before { content: ""; }
-colgroup::after { content: ""; }
-command::before { content: ""; }
-command::after { content: ""; }
-content::before { content: ""; }
-content::after { content: ""; }
-
-data::before { content: ""; }
-data::after { content: ""; }
-datalist::before { content: ""; }
-dd::before { content: ""; }
-dd::after { content: ""; }
-del::before { content: ""; }
-del::after { content: ""; }
-details::before { content: ""; }
-details::after { content: " "; }
-dfn::before { content: ""; }
-dfn::after { content: ""; }
-dialog::before { content: ""; }
-dir::before { content: ""; }
-dir::after { content: ""; }
-div::before { content: ""; }
-div::after { content: "
"; }
-dl::before { content: ""; }
-dl::after { content: "
"; }
-dt::before { content: ""; }
-dt::after { content: ""; }
-
-element::before { content: ""; }
-element::after { content: ""; }
-em::before { content: ""; }
-em::after { content: ""; }
-embed::before { content: ""; }
-
-fieldset::before { content: ""; }
-figcaption::before { content: ""; }
-figcaption::after { content: ""; }
-figure::before { content: ""; }
-figure::after { content: ""; }
-font::before { content: ""; }
-font::after { content: ""; }
-footer::before { content: ""; }
-form::before { content: ""; }
-frame::before { content: ""; }
-frame::after { content: ""; }
-frameset::before { content: ""; }
-
-h1::before { content: ""; }
-h1::after { content: "
"; }
-h2::before { content: ""; }
-h2::after { content: "
"; }
-h3::before { content: ""; }
-h3::after { content: "
"; }
-h4::before { content: ""; }
-h4::after { content: "
"; }
-h5::before { content: ""; }
-h5::after { content: "
"; }
-h6::before { content: ""; }
-h6::after { content: "
"; }
-head::before { content: ""; }
-head::after { content: ""; }
-header::before { content: ""; }
-header::after { content: ""; }
-hgroup::before { content: ""; }
-hgroup::after { content: ""; }
-hr::before { content: "
"; }
-hr::after { content: ""; }
-html::before { content: ""; }
-html::after { content: ""; }
-
-i::before { content: ""; }
-i::after { content: ""; }
-iframe::before { content: ""; }
-image::before { content: ""; }
-image::after { content: ""; }
-img::before { content: "
"; }
-img::after { content: ""; }
-input::before { content: ""; }
-input::after { content: ""; }
-ins::before { content: ""; }
-ins::after { content: ""; }
-isindex::before { content: ""; }
-isindex::after { content: ""; }
-
-kbd::before { content: ""; }
-kbd::after { content: ""; }
-keygen::before { content: ""; }
-keygen::after { content: ""; }
-
-label::before { content: ""; }
-legend::before { content: ""; }
-li::before { content: ""; }
-li::after { content: ""; }
-link::before { content: ""; }
-link::after { content: ""; }
-listing::before { content: ""; }
-listing::after { content: ""; }
-
-main::before { content: ""; }
-main::after { content: ""; }
-map::before { content: ""; }
-mark::before { content: ""; }
-mark::after { content: ""; }
-marquee::before { content: ""; }
-menu::before { content: ""; }
-menuitem::before { content: ""; }
-meta::before { content: ""; }
-meta::after { content: ""; }
-meter::before { content: ""; }
-meter::after { content: ""; }
-multicol::before { content: ""; }
-multicol::after { content: ""; }
-
-nav::before { content: ""; }
-nextid::before { content: ""; }
-nextid::after { content: ""; }
-nobr::before { content: ""; }
-nobr::after { content: ""; }
-noembed::before { content: ""; }
-noembed::after { content: ""; }
-noframes::before { content: ""; }
-noframes::after { content: ""; }
-noscript::before { content: ""; }
-
-object::before { content: ""; }
-ol::before { content: ""; }
-ol::after { content: "
"; }
-optgroup::before { content: ""; }
-option::before { content: ""; }
-output::before { content: ""; }
-
-p::before { content: ""; }
-p::after { content: "
"; }
-param::before { content: ""; }
-param::after { content: ""; }
-picture::before { content: ""; }
-picture::after { content: ""; }
-plaintext::before { content: ""; }
-plaintext::after { content: ""; }
-pre::before { content: ""; }
-pre::after { content: ""; }
-progress::before { content: ""; }
-
-q::before { content: ""; }
-q::after { content: "
"; }
-
-rb::before { content: ""; }
-rb::after { content: ""; }
-rp::before { content: ""; }
-rt::before { content: ""; }
-rtc::before { content: ""; }
-ruby::before { content: ""; }
-ruby::after { content: ""; }
-
-s::before { content: ""; }
-s::after { content: ""; }
-samp::before { content: ""; }
-samp::after { content: ""; }
-script::before { content: ""; }
-section::before { content: ""; }
-section::after { content: ""; }
-select::before { content: ""; }
-shadow::before { content: ""; }
-shadow::after { content: ""; }
-slot::before { content: ""; }
-slot::after { content: ""; }
-small::before { content: ""; }
-small::after { content: ""; }
-source::before { content: ""; }
-source::after { content: ""; }
-spacer::before { content: ""; }
-spacer::after { content: ""; }
-span::before { content: ""; }
-span::after { content: ""; }
-strike::before { content: ""; }
-strike::after { content: ""; }
-strong::before { content: ""; }
-strong::after { content: ""; }
-style::before { content: "details-1
\ No newline at end of file
diff --git a/static/base/images/header.svg b/static/base/images/header.svg
deleted file mode 100644
index 060757ee..00000000
--- a/static/base/images/header.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/static/base/images/issues.jpg b/static/base/images/issues.jpg
deleted file mode 100644
index ab0ee60a..00000000
Binary files a/static/base/images/issues.jpg and /dev/null differ
diff --git a/static/base/images/pagetop.png b/static/base/images/pagetop.png
deleted file mode 100644
index 71242a86..00000000
Binary files a/static/base/images/pagetop.png and /dev/null differ
diff --git a/static/base/images/welcome.jpg b/static/base/images/welcome.jpg
deleted file mode 100644
index 05d89e33..00000000
Binary files a/static/base/images/welcome.jpg and /dev/null differ
diff --git a/static/base/js/menu.js b/static/base/js/menu.js
deleted file mode 100644
index 0565f194..00000000
--- a/static/base/js/menu.js
+++ /dev/null
@@ -1,94 +0,0 @@
-function menu__showChildren(nav, children) {
- let submenu = children[0].querySelector('.menu__subs');
- submenu.classList.add('active');
- submenu.style.animation = 'slideLeft 0.5s ease forwards';
-
- let title = children[0].querySelector('i').parentNode.childNodes[0].textContent;
- nav.querySelector('.menu__title').innerHTML = title;
- nav.querySelector('.menu__header').classList.add('active');
-}
-
-function menu__hideChildren(nav, children) {
- let submenu = children[0].querySelector('.menu__subs');
- submenu.style.animation = 'slideRight 0.5s ease forwards';
- setTimeout(() => {
- submenu.classList.remove('active');
- submenu.style.removeProperty('animation');
- }, 300);
-
- children.shift();
- if (children.length > 0) {
- let title = children[0].querySelector('i').parentNode.childNodes[0].textContent;
- nav.querySelector('.menu__title').innerHTML = title;
- } else {
- nav.querySelector('.menu__header').classList.remove('active');
- nav.querySelector('.menu__title').innerHTML = '';
- }
-}
-
-function menu__toggle(nav, overlay) {
- nav.classList.toggle('active');
- overlay.classList.toggle('active');
-}
-
-function menu__reset(menu, nav, overlay) {
- menu__toggle(nav, overlay);
- setTimeout(() => {
- nav.querySelector('.menu__header').classList.remove('active');
- nav.querySelector('.menu__title').innerHTML = '';
- menu.querySelectorAll('.menu__subs').forEach(submenu => {
- submenu.classList.remove('active');
- submenu.style.removeProperty('animation');
- });
- }, 300);
- return [];
-}
-
-document.querySelectorAll('.menu__container').forEach(menu => {
-
- let menuChildren = [];
- const menuNav = menu.querySelector('.menu__nav');
- const menuOverlay = menu.querySelector('.menu__overlay');
-
- menu.querySelector('.menu__section').addEventListener('click', (e) => {
- if (menuNav.classList.contains('active')) {
- let target = e.target.closest('.menu__children');
- if (target && target != menuChildren[0]) {
- menuChildren.unshift(target);
- menu__showChildren(menuNav, menuChildren);
- }
- }
- });
-
- menu.querySelector('.menu__arrow').addEventListener('click', () => {
- menu__hideChildren(menuNav, menuChildren);
- });
-
- menu.querySelector('.menu__close').addEventListener('click', () => {
- menuChildren = menu__reset(menu, menuNav, menuOverlay);
- });
-
- menu.querySelectorAll('.menu__link > a[target="_blank"]').forEach(link => {
- link.addEventListener('click', (e) => {
- menuChildren = menu__reset(menu, menuNav, menuOverlay);
- e.target.blur();
- });
- });
-
- menu.querySelector('.menu__trigger').addEventListener('click', () => {
- menu__toggle(menuNav, menuOverlay);
- });
-
- menuOverlay.addEventListener('click', () => {
- menu__toggle(menuNav, menuOverlay);
- });
-
- window.onresize = function () {
- if (menuNav.classList.contains('active')) {
- var fontSizeRoot = parseFloat(getComputedStyle(document.documentElement).fontSize);
- if (this.innerWidth >= 62 * fontSizeRoot) {
- menuChildren = menu__reset(menu, menuNav, menuOverlay);
- }
- }
- };
-});
diff --git a/static/base/pagetop-logo.svg b/static/base/pagetop-logo.svg
deleted file mode 100644
index 3666bf3a..00000000
--- a/static/base/pagetop-logo.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/static/assets/favicon.ico b/static/favicon.ico
similarity index 100%
rename from static/assets/favicon.ico
rename to static/favicon.ico