diff --git a/Cargo.toml b/Cargo.toml index e838835..87170ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ uuid = { version = "^1", features = [ 'macro-diagnostics', 'serde', ] } -yuuka = "^0.3" +yuuka = "^0.4" log = "^0.4" env_logger = "^0.11" diff --git a/packages/components/src/data/mod.rs b/packages/components/src/data/mod.rs index 8df1b58..ecd9f47 100644 --- a/packages/components/src/data/mod.rs +++ b/packages/components/src/data/mod.rs @@ -1,7 +1,9 @@ pub mod block; pub mod media; pub mod paragraph; +pub mod typography; pub use block::*; pub use media::*; pub use paragraph::*; +pub use typography::*; diff --git a/packages/components/src/data/paragraph/mod.rs b/packages/components/src/data/paragraph/mod.rs index 7603834..0ee67d1 100644 --- a/packages/components/src/data/paragraph/mod.rs +++ b/packages/components/src/data/paragraph/mod.rs @@ -2,18 +2,14 @@ mod affix; mod badge; mod chip; -mod rich; -mod typography; - mod avatar; mod icon; +mod rich; pub use affix::Affix; pub use badge::Badge; pub use chip::Chip; -pub use rich::Rich; -pub use typography::*; - pub use avatar::Avatar; pub use icon::Icon; +pub use rich::Rich; diff --git a/packages/components/src/data/paragraph/typography/baseline.rs b/packages/components/src/data/typography/baseline.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/baseline.rs rename to packages/components/src/data/typography/baseline.rs diff --git a/packages/components/src/data/paragraph/typography/bold.rs b/packages/components/src/data/typography/bold.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/bold.rs rename to packages/components/src/data/typography/bold.rs diff --git a/packages/components/src/data/paragraph/typography/code.rs b/packages/components/src/data/typography/code.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/code.rs rename to packages/components/src/data/typography/code.rs diff --git a/packages/components/src/data/paragraph/typography/delete.rs b/packages/components/src/data/typography/delete.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/delete.rs rename to packages/components/src/data/typography/delete.rs diff --git a/packages/components/src/data/paragraph/typography/direction.rs b/packages/components/src/data/typography/direction.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/direction.rs rename to packages/components/src/data/typography/direction.rs diff --git a/packages/components/src/data/paragraph/typography/italic.rs b/packages/components/src/data/typography/italic.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/italic.rs rename to packages/components/src/data/typography/italic.rs diff --git a/packages/components/src/data/paragraph/typography/mark.rs b/packages/components/src/data/typography/mark.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/mark.rs rename to packages/components/src/data/typography/mark.rs diff --git a/packages/components/src/data/paragraph/typography/mod.rs b/packages/components/src/data/typography/mod.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/mod.rs rename to packages/components/src/data/typography/mod.rs diff --git a/packages/components/src/data/paragraph/typography/quote.rs b/packages/components/src/data/typography/quote.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/quote.rs rename to packages/components/src/data/typography/quote.rs diff --git a/packages/components/src/data/paragraph/typography/ruby.rs b/packages/components/src/data/typography/ruby.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/ruby.rs rename to packages/components/src/data/typography/ruby.rs diff --git a/packages/components/src/data/paragraph/typography/sizing.rs b/packages/components/src/data/typography/sizing.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/sizing.rs rename to packages/components/src/data/typography/sizing.rs diff --git a/packages/components/src/data/paragraph/typography/split.rs b/packages/components/src/data/typography/split.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/split.rs rename to packages/components/src/data/typography/split.rs diff --git a/packages/components/src/data/paragraph/typography/underline.rs b/packages/components/src/data/typography/underline.rs similarity index 100% rename from packages/components/src/data/paragraph/typography/underline.rs rename to packages/components/src/data/typography/underline.rs diff --git a/packages/components/src/navigation/aside/nav/bottom.rs b/packages/components/src/navigation/aside/bottom_nav.rs similarity index 100% rename from packages/components/src/navigation/aside/nav/bottom.rs rename to packages/components/src/navigation/aside/bottom_nav.rs diff --git a/packages/components/src/navigation/aside/mod.rs b/packages/components/src/navigation/aside/mod.rs index b3a245a..3fe54bf 100644 --- a/packages/components/src/navigation/aside/mod.rs +++ b/packages/components/src/navigation/aside/mod.rs @@ -1,12 +1,14 @@ +pub mod bottom_nav; pub mod breadcrumb; -pub mod nav; +pub mod top_nav; pub mod pagination; pub mod steps; pub mod tabs; +pub use bottom_nav::BottomNav; pub use breadcrumb::Breadcrumb; -pub use nav::{BottomNav, TopNav}; +pub use top_nav::TopNav; pub use pagination::Pagination; pub use steps::Steps; diff --git a/packages/components/src/navigation/aside/nav/mod.rs b/packages/components/src/navigation/aside/nav/mod.rs deleted file mode 100644 index b1f4526..0000000 --- a/packages/components/src/navigation/aside/nav/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod bottom; -mod top; - -pub use bottom::BottomNav; -pub use top::TopNav; diff --git a/packages/components/src/navigation/aside/nav/top.rs b/packages/components/src/navigation/aside/top_nav.rs similarity index 100% rename from packages/components/src/navigation/aside/nav/top.rs rename to packages/components/src/navigation/aside/top_nav.rs diff --git a/packages/theme/src/types/component.rs b/packages/theme/src/types/component.rs index 84c692b..fefaa68 100644 --- a/packages/theme/src/types/component.rs +++ b/packages/theme/src/types/component.rs @@ -1,10 +1,20 @@ +use anyhow::{anyhow, Result}; +use once_cell::sync::Lazy; +use std::str::FromStr; + use serde::{Deserialize, Serialize}; +use strum::{Display, EnumIter, EnumString, IntoEnumIterator}; use yuuka::derive_enum; derive_enum!( - #[derive(PartialEq, Serialize, Deserialize)] + #[derive(PartialEq, Copy, Serialize, Deserialize, Display, EnumIter)] + #[macros_recursive(strum(serialize_all = "snake_case"))] pub enum ComponentType { + #[derive(EnumString)] + #[strum(prefix = "container/")] Container(enum Container { + #[derive] + #[strum(prefix = "container/layout/")] Layout(enum Layout { Aside, Container, @@ -12,6 +22,8 @@ derive_enum!( Header, Footer, }), + #[derive] + #[strum(prefix = "container/place/")] Place(enum Place { Column, Row, @@ -20,6 +32,8 @@ derive_enum!( Divider, Skeleton, }), + #[derive] + #[strum(prefix = "container/system/")] System(enum System { Flex, Anchor, @@ -31,7 +45,11 @@ derive_enum!( Breakpoint, }) }), + #[derive(EnumString)] + #[strum(prefix = "data/")] Data(enum Data { + #[derive] + #[strum(prefix = "data/display/")] Block(enum Block { List, Progress, @@ -42,52 +60,65 @@ derive_enum!( Collapse, Masonry, }), + #[derive] + #[strum(prefix = "data/media/")] Media(enum Media { Image, Charts, Scene, }), + #[derive] + #[strum(prefix = "data/paragraph/")] Paragraph(enum Paragraph { - Typography(enum Typography { - Sub, - Sup, - Bold, - Code, - Sample, - Delete, - IsolateDirection, - OverrideDirection, - Italic, - Mark, - BlockQuote, - Quote, - Ruby, - Size, - Sizing, - Divider, - Split, - Underline, - }), Rich, Affix, Avatar, Badge, Chip, Icon, - }) + }), + #[derive] + #[strum(prefix = "data/typography/")] + Typography(enum Typography { + Sub, + Sup, + Bold, + Code, + Sample, + Delete, + IsolateDirection, + OverrideDirection, + Italic, + Mark, + BlockQuote, + Quote, + Ruby, + Sizing, + Divider, + Split, + Underline, + }), }), + #[derive(EnumString)] + #[strum(prefix = "form/")] Form(enum Form { + #[derive] + #[strum(prefix = "form/button/")] Button(enum Button { Button, IconButton, ButtonGroup, Tag, }), + #[derive] + #[strum(prefix = "form/input/")] Input(enum Input { Text, TextArea, Rich, }), + #[derive] + #[strum(prefix = "form/picker/")] Picker(enum Picker { Color, File, @@ -95,6 +126,8 @@ derive_enum!( Time, DateTime, }), + #[derive] + #[strum(prefix = "form/selector/")] Selector(enum Selector { MultiSelect, CheckBox, @@ -106,17 +139,21 @@ derive_enum!( Rating, }), }), + #[derive(EnumString)] + #[strum(prefix = "navigation/")] Navigation(enum Navigation { + #[derive] + #[strum(prefix = "navigation/aside/")] Aside(enum Aside { - Nav(enum Nav { - TopNav, - BottomNav, - }), + TopNav, + BottomNav, Breadcrumb, Pagination, Steps, Tabs, }), + #[derive] + #[strum(prefix = "navigation/modal/")] Modal(enum Modal { Drawer, Menu, @@ -129,3 +166,42 @@ derive_enum!( }) } ); + +macro_rules! iter_component_type { + ($ty: ident, $parent: ident) => { + $ty::iter() + .map(|x| (ComponentType::$parent($parent::$ty(x)), x.to_string())) + .collect::>() + }; +} + +static MAPPER: Lazy> = Lazy::new(|| { + [ + iter_component_type!(Layout, Container), + iter_component_type!(Place, Container), + iter_component_type!(System, Container), + iter_component_type!(Block, Data), + iter_component_type!(Media, Data), + iter_component_type!(Paragraph, Data), + iter_component_type!(Typography, Data), + iter_component_type!(Button, Form), + iter_component_type!(Input, Form), + iter_component_type!(Picker, Form), + iter_component_type!(Selector, Form), + iter_component_type!(Aside, Navigation), + iter_component_type!(Modal, Navigation), + ] + .concat() +}); + +impl FromStr for ComponentType { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if let Some((ty, _)) = MAPPER.iter().find(|(_, x)| x == &s) { + Ok(*ty) + } else { + Err(anyhow!("Invalid component type")) + } + } +} diff --git a/website/examples/dev/render.rs b/website/examples/dev/render.rs index 546abaa..85a52b6 100644 --- a/website/examples/dev/render.rs +++ b/website/examples/dev/render.rs @@ -32,7 +32,7 @@ pub async fn route() -> Result { get(move |Path(id): Path| async move { html(format!("/guide/{}", id)).await }), ) .route( - "/component/:id", + "/component/*id", get(move |Path(id): Path| async move { html(format!("/component/{}", id)).await }), ); diff --git a/website/src/app.rs b/website/src/app.rs index 972937d..9472671 100644 --- a/website/src/app.rs +++ b/website/src/app.rs @@ -19,9 +19,9 @@ pub enum Routes { #[at("/guide/:id")] #[component(Guide)] Guide { id: String }, - #[at("/component/:id")] + #[at("/component/*id")] #[component(Component)] - Component { id: String }, + Component { id: ComponentType }, #[not_found] #[at("/404")] diff --git a/website/src/pages/component.rs b/website/src/pages/component.rs index dd7cf37..92c267e 100644 --- a/website/src/pages/component.rs +++ b/website/src/pages/component.rs @@ -2,12 +2,12 @@ use stylist::yew::styled_component; use yew::prelude::*; use hikari_components::form::Button; -use hikari_theme::types::ColorType; +use hikari_theme::types::{ColorType, ComponentType}; #[derive(Properties, Debug, PartialEq)] pub struct Props { #[prop_or_default] - pub id: String, + pub id: ComponentType, } #[styled_component] @@ -15,7 +15,7 @@ pub fn Component(props: &Props) -> Html { html! { <>

{"Component"}

-

{format!("Component {}", props.id)}

+

{format!("Component {:?}", props.id)}