├── src ├── card │ ├── media.rs │ ├── actions.rs │ ├── buttons.rs │ └── primary_action.rs ├── date_picker.rs ├── time_picker.rs ├── utils │ ├── mod.rs │ └── weak_component_link.rs ├── tabs │ ├── mod.rs │ ├── tab_icon.rs │ ├── tab.rs │ └── tab_bar.rs ├── list │ ├── action_detail.rs │ ├── graphic_type.rs │ ├── selected_detail.rs │ ├── list_index.rs │ ├── request_selected.rs │ ├── check_list_item.rs │ ├── radio_list_item.rs │ └── list_item.rs ├── text_inputs │ ├── text_field_type.rs │ ├── mod.rs │ ├── validity_state.rs │ ├── textfield.rs │ └── textarea.rs ├── icon.rs ├── drawer │ ├── drawer_title.rs │ ├── drawer_header.rs │ ├── drawer_subtitle.rs │ └── drawer_app_content.rs ├── top_app_bar │ ├── title.rs │ ├── action_items.rs │ └── navigation_icon.rs ├── icon_button_toggle │ ├── on_icon.rs │ └── off_icon.rs ├── menu │ └── models.rs ├── icon_button.rs ├── form_field.rs ├── fab.rs ├── tooltip.rs ├── button.rs ├── dialog │ └── dialog_action.rs ├── linear_progress.rs ├── image_list.rs ├── banner.rs ├── top_app_bar_fixed.rs ├── icon_button_toggle.rs ├── radio.rs ├── checkbox.rs ├── card.rs ├── switch.rs ├── circular_progress_four_color.rs ├── circular_progress.rs ├── slider.rs ├── top_app_bar.rs ├── gaugechart.rs ├── datatable.rs ├── piechart.rs ├── radarchart.rs ├── linechart.rs ├── barchart.rs ├── list.rs ├── chip.rs ├── snackbar.rs └── lib.rs ├── .cargo └── config ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── general-questions.md │ ├── feature_request.md │ └── bug_report.md ├── codecov.yml └── workflows │ ├── audit.yaml │ ├── tests.yml │ └── coverage.yaml ├── CONTRIBUTORS.md ├── CHANGELOG.md ├── .gitignore ├── TODO.md ├── SECURITY.md ├── Cargo.toml └── CODE_OF_CONDUCT.md /src/card/media.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/date_picker.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/time_picker.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/card/actions.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/card/buttons.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/card/primary_action.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod weak_component_link; 2 | pub use weak_component_link::*; 3 | -------------------------------------------------------------------------------- /src/tabs/mod.rs: -------------------------------------------------------------------------------- 1 | mod tab; 2 | pub use tab::*; 3 | 4 | mod tab_bar; 5 | pub use tab_bar::*; 6 | 7 | mod tab_icon; 8 | pub use tab_icon::*; 9 | -------------------------------------------------------------------------------- /.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | 4 | [target.'cfg(target_arch = "wasm32")'] 5 | runner = 'wasm-bindgen-test-runner' -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: dudochkin 4 | liberapay: dudochkin 5 | open_collective: dudochkin -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general-questions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General Questions 3 | about: Any other issues 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "diff, flags, files" 3 | require_changes: true 4 | 5 | coverage: 6 | status: 7 | project: 8 | default: 9 | informational: true 10 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | YEW Components contributors (sorted alphabetically) 2 | ============================================ 3 | 4 | * **[Victor Dudochkin](https://github.com/dudochkin.victor)** 5 | 6 | * Core development 7 | 8 | 9 | 10 | **[Full contributors list](https://github.com/angular-rust/yew-components/contributors).** -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Package vX.X.X (YYYY-MM-DD) 4 | 5 | ### Improved 6 | 7 | - A here your changes 8 | 9 | ### Added 10 | 11 | - A here your changes 12 | 13 | ### Fixed 14 | 15 | - A here your changes 16 | 17 | ### Improvement 18 | 19 | - A here your changes 20 | 21 | ### Removed 22 | 23 | - A here your changes 24 | 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | /refs 13 | -------------------------------------------------------------------------------- /.github/workflows/audit.yaml: -------------------------------------------------------------------------------- 1 | name: Security audit 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '0 0 * * 0' 9 | 10 | jobs: 11 | security_audit: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions-rs/audit-check@v1 16 | with: 17 | token: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea to YMC maintainers 4 | title: "[Feature Request]" 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### What is the feature ? 11 | *Detailed feature descrption* 12 | 13 | ### (Optional) Why this feature is useful and how people would use the feature ? 14 | *Explain why this feature is important* 15 | 16 | ### (Optional) Additional Information 17 | *More details are appreciated:)* 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: About unexpected behaviors 4 | title: "[BUG] " 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | Describe what is expected, what you actually get. 12 | It would be nice to have screenshot or result image uploaded 13 | 14 | **To Reproduce** 15 | Some minimal reproduce code is highly recommended 16 | 17 | **Version Information** 18 | Please give us what version you are using. If you are pulling `YMC` directly from git repo, please mention this as well 19 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ## From Spec 2 | 3 | - [ ] Dividers 4 | - [ ] Backdrop 5 | - [ ] Sheets 6 | - [ ] Time pickers 7 | - [ ] Date pickers 8 | 9 | ## From Vuetify 10 | 11 | - [ ] Stepper 12 | - [ ] Treeview 13 | - [ ] Rating 14 | - [ ] Color Picker 15 | - [ ] Parallax 16 | - [ ] Pagination 17 | - [ ] Overlays 18 | - [ ] Groups 19 | - [ ] Button Group 20 | - [ ] Chip Group 21 | - [ ] Item Group 22 | - [ ] ListItem Group 23 | - [ ] Side Group 24 | - [ ] Windows 25 | - [ ] Grid System 26 | - [ ] TimeLine 27 | - [ ] Selects 28 | - [ ] Footers 29 | - [ ] Expansion Panel 30 | - [ ] Carousel 31 | - [ ] Calendar 32 | - [ ] BreadCrumbs 33 | - [ ] Badges 34 | - [ ] Avatars 35 | - [ ] Allerts 36 | -------------------------------------------------------------------------------- /src/list/action_detail.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::list::ListIndex; 5 | use js_sys::Object; 6 | use wasm_bindgen::prelude::*; 7 | use wasm_bindgen::JsCast; 8 | 9 | /// The `ActionDetail` type 10 | /// 11 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-2) 12 | #[derive(Debug)] 13 | pub struct ActionDetail { 14 | index: ListIndex, 15 | } 16 | 17 | impl From for ActionDetail { 18 | fn from(value: JsValue) -> Self { 19 | // let detail = value.unchecked_into::(); 20 | // let index = ListIndex::from(detail.index()); 21 | // Self { index } 22 | unimplemented!() 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | If you believe you have found a security vulnerability in Angular Rust, we encourage you to let us know right away. We will investigate all legitimate reports and do our best to quickly fix the problem. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | To report a security vulnerability, please create a Github issue [here](https://github.com/angular-rust/yew-components/issues/new). 8 | 9 | If you can, please include the following details: 10 | * An MCVE (minimum complete verifiable example) – this is a short code snippet which demonstrates the error in the 11 | the simplest possible (or just a simple) way. 12 | * Which versions of Angular Rust the vulnerability is present in 13 | * What effects the vulnerability has and how serious the vulnerability is -------------------------------------------------------------------------------- /src/list/graphic_type.rs: -------------------------------------------------------------------------------- 1 | /// Equivalent to typescript type 2 | /// `'avatar'|'icon'|'medium'|'large'|'control'|null` 3 | /// 4 | /// See `GraphicType` [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-item-1) 5 | #[derive(Clone, Debug)] 6 | pub enum GraphicType { 7 | Avatar, 8 | Icon, 9 | Medium, 10 | Large, 11 | Control, 12 | Null, 13 | } 14 | 15 | impl ToString for GraphicType { 16 | fn to_string(&self) -> String { 17 | use GraphicType::*; 18 | match self { 19 | Avatar => "avatar", 20 | Icon => "icon", 21 | Medium => "medium", 22 | Large => "large", 23 | Control => "control", 24 | Null => "null", 25 | } 26 | .to_string() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/text_inputs/text_field_type.rs: -------------------------------------------------------------------------------- 1 | /// The `TextFieldType` type 2 | #[derive(Debug, Clone)] 3 | pub enum TextFieldType { 4 | Text, 5 | Search, 6 | Tel, 7 | Url, 8 | Email, 9 | Password, 10 | Date, 11 | Month, 12 | Week, 13 | Time, 14 | DatetimeLocal, 15 | Number, 16 | Color, 17 | } 18 | 19 | impl ToString for TextFieldType { 20 | fn to_string(&self) -> String { 21 | use TextFieldType::*; 22 | match self { 23 | Text => "text", 24 | Search => "search", 25 | Tel => "tel", 26 | Url => "url", 27 | Email => "email", 28 | Password => "password", 29 | Date => "date", 30 | Month => "month", 31 | Week => "week", 32 | Time => "time", 33 | DatetimeLocal => "datetime-local", 34 | Number => "number", 35 | Color => "color", 36 | } 37 | .to_string() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout repository 12 | uses: actions/checkout@v2 13 | 14 | - name: Install Rust 15 | uses: actions-rs/toolchain@v1 16 | with: 17 | toolchain: nightly 18 | target: wasm32-unknown-unknown 19 | override: true 20 | profile: minimal 21 | default: true 22 | 23 | - name: Build 24 | run: cargo build --verbose 25 | - name: Install test runner 26 | run: cargo install wasm-bindgen-cli 27 | - name: Run tests 28 | run: cargo test --verbose 29 | 30 | clippy_check: 31 | 32 | runs-on: ubuntu-latest 33 | 34 | steps: 35 | - name: Checkout repository 36 | uses: actions/checkout@v2 37 | 38 | - name: Install Rust 39 | uses: actions-rs/toolchain@v1 40 | with: 41 | toolchain: nightly 42 | target: wasm32-unknown-unknown 43 | override: true 44 | profile: minimal 45 | default: true 46 | 47 | - run: rustup component add clippy 48 | - uses: actions-rs/clippy-check@v1 49 | with: 50 | token: ${{ secrets.GITHUB_TOKEN }} 51 | args: --all-features 52 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yaml: -------------------------------------------------------------------------------- 1 | name: Test coverage 2 | 3 | #on: 4 | # push: 5 | # branches: 6 | # - main 7 | # pull_request: 8 | 9 | on: [push, pull_request] 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | RUST_BACKTRACE: full 14 | 15 | jobs: 16 | coverage: 17 | name: Coverage 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v2 22 | 23 | - name: Install Rust 24 | uses: actions-rs/toolchain@v1 25 | with: 26 | toolchain: nightly 27 | target: wasm32-unknown-unknown 28 | override: true 29 | profile: minimal 30 | default: true 31 | 32 | - name: Restore cache 33 | uses: Swatinem/rust-cache@v1 34 | 35 | - name: Run cargo-tarpaulin 36 | uses: actions-rs/tarpaulin@v0.1 37 | with: 38 | args: '--all-features --run-types Doctests,Tests' 39 | timeout: 120 40 | 41 | - name: Upload to codecov.io 42 | uses: codecov/codecov-action@239febf655bba88b16ff5dea1d3135ea8663a1f9 43 | with: 44 | token: ${{ secrets.CODECOV_TOKEN }} 45 | 46 | - name: Archive code coverage results 47 | uses: actions/upload-artifact@v2 48 | with: 49 | name: code-coverage-report 50 | path: cobertura.xml 51 | retention-days: 30 52 | -------------------------------------------------------------------------------- /src/list/selected_detail.rs: -------------------------------------------------------------------------------- 1 | use crate::list::ListIndex; 2 | use js_sys::Object; 3 | use wasm_bindgen::prelude::*; 4 | use wasm_bindgen::JsCast; 5 | 6 | /// The `RequestSelectedDetail` type 7 | /// 8 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-2) 9 | #[derive(Debug)] 10 | pub struct SelectedDetail { 11 | pub index: ListIndex, 12 | pub diff: Option, 13 | } 14 | 15 | /// Type for [`SelectedDetail::diff`] 16 | /// 17 | /// See `**` [here on documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-2). 18 | #[derive(Debug)] 19 | pub struct IndexDiff { 20 | pub added: Vec, 21 | pub removed: Vec, 22 | } 23 | 24 | impl From for SelectedDetail { 25 | fn from(value: JsValue) -> Self { 26 | // let detail = value.unchecked_into::(); 27 | // let index = ListIndex::from(detail.index()); 28 | 29 | // let diff = if detail.diff().is_undefined() { 30 | // None 31 | // } else { 32 | // let diff = detail.diff(); 33 | // Some(IndexDiff { 34 | // added: diff.added(), 35 | // removed: diff.removed(), 36 | // }) 37 | // }; 38 | // Self { index, diff } 39 | unimplemented!() 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/list/list_index.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use wasm_bindgen::{JsCast, JsValue}; 3 | 4 | /// The `MWCListIndex` type 5 | /// 6 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-1) 7 | #[derive(Debug)] 8 | pub enum ListIndex { 9 | /// Provided when `multi` prop is set to `true` on the component 10 | /// 11 | /// `None` denotes value os `-1` 12 | Single(Option), 13 | /// Provided when `multi` prop is set to `false` (default) on the component 14 | Multi(HashSet), 15 | } 16 | 17 | impl From for ListIndex { 18 | fn from(val: JsValue) -> Self { 19 | if let Ok(set) = val.clone().dyn_into::() { 20 | let indices = set 21 | .values() 22 | .into_iter() 23 | .filter_map(|item| item.ok()) 24 | .filter_map(|value| value.as_f64()) 25 | .map(|num| num as usize) 26 | .collect(); 27 | ListIndex::Multi(indices) 28 | } else if let Some(value) = val.as_f64() { 29 | #[allow(clippy::float_cmp)] 30 | ListIndex::Single(if value != -1.0 { 31 | Some(value as usize) 32 | } else { 33 | None 34 | }) 35 | } else { 36 | panic!("This should never happen") 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/icon.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | use yew::prelude::*; 3 | 4 | pub struct Icon { 5 | link: ComponentLink, 6 | // label: String, 7 | // onsignal: Callback<()>, 8 | } 9 | 10 | /// Props for [`Icon`] 11 | /// 12 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/icon#propertiesattributes) 13 | #[derive(Clone, PartialEq, Properties)] 14 | pub struct IconProps { 15 | #[prop_or_default] 16 | pub children: Children, 17 | } 18 | 19 | impl Component for Icon { 20 | type Message = (); 21 | type Properties = IconProps; 22 | 23 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 24 | Self { 25 | link, 26 | // label: props.label, 27 | // onsignal: props.onsignal, 28 | } 29 | } 30 | 31 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 32 | // match msg { 33 | // Msg::Clicked => { 34 | // // self.onsignal.emit(()); 35 | // } 36 | // } 37 | false 38 | } 39 | 40 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 41 | // self.label = props.label; 42 | // self.onsignal = props.onsignal; 43 | true 44 | } 45 | 46 | fn view(&self) -> Html { 47 | 48 | // 51 | 52 | // { props.children.clone() } 53 | html! { 54 | { "favorite" } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/list/request_selected.rs: -------------------------------------------------------------------------------- 1 | use crate::event_details_into; 2 | use gloo::events::EventListener; 3 | use js_sys::Object; 4 | use wasm_bindgen::prelude::*; 5 | use web_sys::Element; 6 | use yew::prelude::*; 7 | 8 | /// Type for [`RequestSelectedDetail::source`] 9 | pub enum RequestSelectedSource { 10 | Interaction, 11 | Property, 12 | } 13 | 14 | /// The `RequestSelectedDetail` type 15 | /// 16 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-item-2) 17 | pub struct RequestSelectedDetail { 18 | pub selected: bool, 19 | pub source: RequestSelectedSource, 20 | } 21 | 22 | pub fn request_selected_listener( 23 | node_ref: &NodeRef, 24 | callback: Callback, 25 | ) -> EventListener { 26 | let element = node_ref.cast::().unwrap(); 27 | EventListener::new(&element, "request-selected", move |event| { 28 | // let selected_detail = event_details_into::(event); 29 | // let selected_detail = RequestSelectedDetail { 30 | // selected: selected_detail.selected(), 31 | // source: match selected_detail.source().as_str() { 32 | // "interaction" => RequestSelectedSource::Interaction, 33 | // "property" => RequestSelectedSource::Property, 34 | // val => { 35 | // panic!(format!( 36 | // "Invalid `source` value {} received. This should never happen", 37 | // val 38 | // )) 39 | // } 40 | // }, 41 | // }; 42 | // callback.emit(selected_detail); 43 | unimplemented!() 44 | }) 45 | } 46 | -------------------------------------------------------------------------------- /src/utils/weak_component_link.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | use std::ops::Deref; 3 | use std::rc::Rc; 4 | use yew::html::{Component, ComponentLink}; 5 | 6 | pub struct WeakComponentLink(Rc>>>); 7 | 8 | impl Clone for WeakComponentLink { 9 | fn clone(&self) -> Self { 10 | WeakComponentLink(self.0.clone()) 11 | } 12 | } 13 | 14 | impl Default for WeakComponentLink { 15 | fn default() -> Self { 16 | WeakComponentLink(Rc::new(RefCell::new(None))) 17 | } 18 | } 19 | 20 | impl Deref for WeakComponentLink { 21 | type Target = Rc>>>; 22 | 23 | fn deref(&self) -> &Self::Target { 24 | &self.0 25 | } 26 | } 27 | 28 | impl PartialEq for WeakComponentLink { 29 | fn eq(&self, other: &WeakComponentLink) -> bool { 30 | Rc::ptr_eq(&self.0, &other.0) 31 | } 32 | } 33 | 34 | // OLD 35 | // pub struct WeakComponentLink(Rc>>>); 36 | 37 | // impl Clone for WeakComponentLink { 38 | // fn clone(&self) -> Self { 39 | // Self(Rc::clone(&self.0)) 40 | // } 41 | // } 42 | 43 | // impl Default for WeakComponentLink { 44 | // fn default() -> Self { 45 | // Self(Rc::default()) 46 | // } 47 | // } 48 | 49 | // impl Deref for WeakComponentLink { 50 | // type Target = Rc>>>; 51 | 52 | // fn deref(&self) -> &Self::Target { 53 | // &self.0 54 | // } 55 | // } 56 | 57 | // impl PartialEq for WeakComponentLink { 58 | // fn eq(&self, other: &Self) -> bool { 59 | // Rc::ptr_eq(&self.0, &other.0) 60 | // } 61 | // } -------------------------------------------------------------------------------- /src/tabs/tab_icon.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "icon"; 7 | 8 | /// Props for [`TabIcon`] 9 | #[derive(Properties, Clone)] 10 | pub struct TabIconProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines title for [`Tab`][crate::Tab]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct TabIcon { 20 | props: TabIconProps, 21 | } 22 | 23 | impl Component for TabIcon { 24 | type Message = (); 25 | type Properties = TabIconProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", "title"); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/drawer/drawer_title.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "title"; 7 | 8 | /// Props for [`DrawerTitle`] 9 | #[derive(Properties, Clone)] 10 | pub struct DrawerTitleProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines title for [`Drawer`][crate::Drawer]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct DrawerTitle { 20 | props: DrawerTitleProps, 21 | } 22 | 23 | impl Component for DrawerTitle { 24 | type Message = (); 25 | type Properties = DrawerTitleProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", "title"); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/drawer/drawer_header.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "header"; 7 | 8 | /// Props for [`DrawerHeader`] 9 | #[derive(Properties, Clone)] 10 | pub struct DrawerHeaderProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines header for [`Drawer`][crate::Drawer]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct DrawerHeader { 20 | props: DrawerHeaderProps, 21 | } 22 | 23 | impl Component for DrawerHeader { 24 | type Message = (); 25 | type Properties = DrawerHeaderProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", SLOT); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/top_app_bar/title.rs: -------------------------------------------------------------------------------- 1 | use yew::prelude::*; 2 | 3 | const SLOT: &str = "title"; 4 | 5 | /// Props for [`TopAppBarTitle`] 6 | #[derive(Properties, Clone)] 7 | pub struct TopAppBarTitleProps { 8 | pub children: Children, 9 | } 10 | 11 | /// Defines header for [`TopAppBar`][crate::TopAppBar] or 12 | /// [`TopAppBarFixed`][crate::TopAppBarFixed]. 13 | /// 14 | /// If the child passed is an element (a `VTag`), then it is modified to include 15 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 16 | /// containing said attributes. 17 | pub struct TopAppBarTitle { 18 | props: TopAppBarTitleProps, 19 | } 20 | 21 | impl Component for TopAppBarTitle { 22 | type Message = (); 23 | type Properties = TopAppBarTitleProps; 24 | 25 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 26 | Self { props } 27 | } 28 | 29 | fn update(&mut self, _msg: Self::Message) -> bool { 30 | false 31 | } 32 | 33 | fn change(&mut self, props: Self::Properties) -> bool { 34 | self.props = props; 35 | true 36 | } 37 | 38 | fn view(&self) -> Html { 39 | // let children = self 40 | // .props 41 | // .children 42 | // .iter() 43 | // .map(|child| { 44 | // match child { 45 | // Html::VTag(mut vtag) => { 46 | // vtag.add_attribute("slot", SLOT); 47 | // Html::VTag(vtag) 48 | // } 49 | // _ => { 50 | // html! { 51 | // 52 | // { child } 53 | // 54 | // } 55 | // } 56 | // } 57 | // }) 58 | // .collect::(); 59 | 60 | // html! { 61 | // { children } 62 | // } 63 | unimplemented!() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/drawer/drawer_subtitle.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "subtitle"; 7 | 8 | /// Props for [`DrawerSubtitle`] 9 | #[derive(Properties, Clone)] 10 | pub struct DrawerSubtitleProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines sub title for [`Drawer`][crate::Drawer]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct DrawerSubtitle { 20 | props: DrawerSubtitleProps, 21 | } 22 | 23 | impl Component for DrawerSubtitle { 24 | type Message = (); 25 | type Properties = DrawerSubtitleProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", "subtitle"); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/drawer/drawer_app_content.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "appContent"; 7 | 8 | /// Props for [`DrawerAppContent`] 9 | #[derive(Properties, Clone)] 10 | pub struct DrawerAppContentProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines `appContent` for [`Drawer`][crate::Drawer]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct DrawerAppContent { 20 | props: DrawerAppContentProps, 21 | } 22 | 23 | impl Component for DrawerAppContent { 24 | type Message = (); 25 | type Properties = DrawerAppContentProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", "appContent"); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/top_app_bar/action_items.rs: -------------------------------------------------------------------------------- 1 | use yew::prelude::*; 2 | 3 | const SLOT: &str = "actionItems"; 4 | 5 | /// Props for [`TopAppBarActionItems`] 6 | #[derive(Properties, Clone)] 7 | pub struct TopAppBarActionItemsProps { 8 | pub children: Children, 9 | } 10 | 11 | /// Defines header for [`TopAppBar`][crate::TopAppBar] or 12 | /// [`TopAppBarFixed`][crate::TopAppBarFixed]. 13 | /// 14 | /// If the child passed is an element (a `VTag`), then it is modified to include 15 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 16 | /// containing said attributes. 17 | pub struct TopAppBarActionItems { 18 | props: TopAppBarActionItemsProps, 19 | } 20 | 21 | impl Component for TopAppBarActionItems { 22 | type Message = (); 23 | type Properties = TopAppBarActionItemsProps; 24 | 25 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 26 | Self { props } 27 | } 28 | 29 | fn update(&mut self, _msg: Self::Message) -> bool { 30 | false 31 | } 32 | 33 | fn change(&mut self, props: Self::Properties) -> bool { 34 | self.props = props; 35 | true 36 | } 37 | 38 | fn view(&self) -> Html { 39 | // let children = self 40 | // .props 41 | // .children 42 | // .iter() 43 | // .map(|child| { 44 | // match child { 45 | // Html::VTag(mut vtag) => { 46 | // vtag.add_attribute("slot", SLOT); 47 | // Html::VTag(vtag) 48 | // } 49 | // _ => { 50 | // html! { 51 | // 52 | // { child } 53 | // 54 | // } 55 | // } 56 | // } 57 | // }) 58 | // .collect::(); 59 | 60 | // html! { 61 | // { children } 62 | // } 63 | unimplemented!() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/icon_button_toggle/on_icon.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "onIcon"; 7 | 8 | /// Props for [`OnIconButtonToggle`] 9 | #[derive(Properties, Clone)] 10 | pub struct OnIconButtonToggleProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines header for [`IconButtonToggle`][crate::IconButtonToggle]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct OnIconButtonToggle { 20 | props: OnIconButtonToggleProps, 21 | } 22 | 23 | impl Component for OnIconButtonToggle { 24 | type Message = (); 25 | type Properties = OnIconButtonToggleProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", SLOT); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/icon_button_toggle/off_icon.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use yew::prelude::*; 5 | 6 | const SLOT: &str = "offIcon"; 7 | 8 | /// Props for [`OffIconButtonToggle`] 9 | #[derive(Properties, Clone)] 10 | pub struct OffIconButtonToggleProps { 11 | pub children: Children, 12 | } 13 | 14 | /// Defines header for [`IconButtonToggle`][crate::IconButtonToggle]. 15 | /// 16 | /// If the child passed is an element (a `VTag`), then it is modified to include 17 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 18 | /// containing said attributes. 19 | pub struct OffIconButtonToggle { 20 | props: OffIconButtonToggleProps, 21 | } 22 | 23 | impl Component for OffIconButtonToggle { 24 | type Message = (); 25 | type Properties = OffIconButtonToggleProps; 26 | 27 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 28 | Self { props } 29 | } 30 | 31 | fn update(&mut self, _msg: Self::Message) -> bool { 32 | false 33 | } 34 | 35 | fn change(&mut self, props: Self::Properties) -> bool { 36 | self.props = props; 37 | true 38 | } 39 | 40 | fn view(&self) -> Html { 41 | // let children = self 42 | // .props 43 | // .children 44 | // .iter() 45 | // .map(|child| { 46 | // match child { 47 | // Html::VTag(mut vtag) => { 48 | // vtag.add_attribute("slot", SLOT); 49 | // Html::VTag(vtag) 50 | // } 51 | // _ => { 52 | // html! { 53 | // 54 | // { child } 55 | // 56 | // } 57 | // } 58 | // } 59 | // }) 60 | // .collect::(); 61 | 62 | // html! { 63 | // { children } 64 | // } 65 | unimplemented!() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/top_app_bar/navigation_icon.rs: -------------------------------------------------------------------------------- 1 | use yew::prelude::*; 2 | 3 | const SLOT: &str = "navigationIcon"; 4 | 5 | /// Props for [`TopAppBarNavigationIcon`] 6 | #[derive(Properties, Clone)] 7 | pub struct TopAppBarNavigationIconProps { 8 | pub children: Children, 9 | } 10 | 11 | /// Defines header for [`TopAppBar`][crate::TopAppBar] or 12 | /// [`TopAppBarFixed`][crate::TopAppBarFixed]. 13 | /// 14 | /// If the child passed is an element (a `VTag`), then it is modified to include 15 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 16 | /// containing said attributes. 17 | pub struct TopAppBarNavigationIcon { 18 | props: TopAppBarNavigationIconProps, 19 | } 20 | 21 | impl Component for TopAppBarNavigationIcon { 22 | type Message = (); 23 | type Properties = TopAppBarNavigationIconProps; 24 | 25 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 26 | Self { props } 27 | } 28 | 29 | fn update(&mut self, _msg: Self::Message) -> bool { 30 | false 31 | } 32 | 33 | fn change(&mut self, props: Self::Properties) -> bool { 34 | self.props = props; 35 | true 36 | } 37 | 38 | fn view(&self) -> Html { 39 | // let children = self 40 | // .props 41 | // .children 42 | // .iter() 43 | // .map(|child| { 44 | // match child { 45 | // Html::VTag(mut vtag) => { 46 | // vtag.add_attribute("slot", SLOT); 47 | // Html::VTag(vtag) 48 | // } 49 | // _ => { 50 | // html! { 51 | // 52 | // { child } 53 | // 54 | // } 55 | // } 56 | // } 57 | // }) 58 | // .collect::(); 59 | 60 | // html! { 61 | // { children } 62 | // } 63 | unimplemented!() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/menu/models.rs: -------------------------------------------------------------------------------- 1 | /// The `Corner` type 2 | /// 3 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/menu#propertiesattributes) 4 | #[derive(Clone)] 5 | pub enum Corner { 6 | TopLeft, 7 | TopRight, 8 | BottomLeft, 9 | BottomRight, 10 | TopStart, 11 | TopEnd, 12 | BottomStart, 13 | BottomEnd, 14 | } 15 | 16 | impl ToString for Corner { 17 | fn to_string(&self) -> String { 18 | use Corner::*; 19 | match self { 20 | TopLeft => "TOP_LEFT", 21 | TopRight => "TOP_RIGHT", 22 | BottomLeft => "BOTTOM_LEFT", 23 | BottomRight => "BOTTOM_RIGHT", 24 | TopStart => "TOP_START", 25 | TopEnd => "TOP_END ", 26 | BottomStart => "BOTTOM_START", 27 | BottomEnd => "BOTTOM_END", 28 | } 29 | .to_string() 30 | } 31 | } 32 | 33 | /// The `MenuCorner` type 34 | /// 35 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/menu#propertiesattributes) 36 | #[derive(Clone)] 37 | pub enum MenuCorner { 38 | Start, 39 | End, 40 | } 41 | 42 | impl ToString for MenuCorner { 43 | fn to_string(&self) -> String { 44 | use MenuCorner::*; 45 | match self { 46 | Start => "START", 47 | End => "END", 48 | } 49 | .to_string() 50 | } 51 | } 52 | 53 | /// The `DefaultFocusState` type 54 | /// 55 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/menu#propertiesattributes) 56 | #[derive(Clone)] 57 | pub enum DefaultFocusState { 58 | None, 59 | ListRoot, 60 | FirstItem, 61 | LastItem, 62 | } 63 | 64 | impl ToString for DefaultFocusState { 65 | fn to_string(&self) -> String { 66 | use DefaultFocusState::*; 67 | match self { 68 | None => "NONE", 69 | ListRoot => "LIST_ROOT", 70 | FirstItem => "FIRST_ITEM", 71 | LastItem => "LAST_ITEM", 72 | } 73 | .to_string() 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/icon_button.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | use yew::prelude::*; 3 | 4 | pub struct IconButton { 5 | link: ComponentLink, 6 | label: String, 7 | // onsignal: Callback<()>, 8 | } 9 | 10 | pub enum Msg { 11 | Clicked, 12 | } 13 | 14 | /// Props for [`IconButton`] 15 | /// 16 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/icon-button#propertiesattributes) 17 | #[derive(Clone, PartialEq, Properties)] 18 | pub struct IconButtonProps { 19 | #[prop_or_default] 20 | pub label: String, 21 | #[prop_or_default] 22 | pub icon: String, 23 | #[prop_or_default] 24 | pub disabled: bool, 25 | #[prop_or_default] 26 | pub children: Children, 27 | } 28 | 29 | // label=props.label 30 | // icon=props.icon 31 | // disabled=props.disabled 32 | // { props.children.clone() } 33 | 34 | impl Component for IconButton { 35 | type Message = Msg; 36 | type Properties = IconButtonProps; 37 | 38 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 39 | Self { 40 | link, 41 | label: props.label, 42 | // onsignal: props.onsignal, 43 | } 44 | } 45 | 46 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 47 | match msg { 48 | Msg::Clicked => { 49 | // self.onsignal.emit(()); 50 | } 51 | } 52 | false 53 | } 54 | 55 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 56 | self.label = props.label; 57 | // self.onsignal = props.onsignal; 58 | true 59 | } 60 | 61 | fn view(&self) -> Html { 62 | // html! { 63 | // 66 | // } 67 | html! { 68 | 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/form_field.rs: -------------------------------------------------------------------------------- 1 | use super::to_option; 2 | use wasm_bindgen::prelude::*; 3 | use yew::prelude::*; 4 | 5 | pub struct Formfield { 6 | link: ComponentLink, 7 | // label: String, 8 | // onsignal: Callback<()>, 9 | } 10 | 11 | /// Props for [`Formfield`] 12 | /// 13 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/formfield#propertiesattributes) 14 | #[derive(Clone, PartialEq, Properties)] 15 | pub struct FormfieldProps { 16 | pub children: Children, 17 | #[prop_or_default] 18 | pub label: String, 19 | #[prop_or_default] 20 | pub align_end: bool, 21 | #[prop_or_default] 22 | pub space_between: bool, 23 | #[prop_or_default] 24 | pub nowrap: bool, 25 | } 26 | 27 | // label=props.label 28 | // alignEnd?=to_option(props.align_end) 29 | // spaceBetween?=to_option(props.space_between) 30 | // nowrap?=to_option(props.nowrap) 31 | // >{ props.children.clone() } 32 | 33 | impl Component for Formfield { 34 | type Message = (); 35 | type Properties = FormfieldProps; 36 | 37 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 38 | Self { 39 | link, 40 | // label: props.label, 41 | // onsignal: props.onsignal, 42 | } 43 | } 44 | 45 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 46 | // match msg { 47 | // Msg::Clicked => { 48 | // // self.onsignal.emit(()); 49 | // } 50 | // } 51 | false 52 | } 53 | 54 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 55 | // self.label = props.label; 56 | // self.onsignal = props.onsignal; 57 | true 58 | } 59 | 60 | fn view(&self) -> Html { 61 | // onclick=self.link.callback(|_| Msg::Clicked)> 62 | // { &self.label } 63 | // { props.children.clone() } 64 | html! { 65 | 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/text_inputs/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | #[cfg(feature = "textfield")] 5 | mod textfield; 6 | #[cfg(feature = "textfield")] 7 | pub use textfield::*; 8 | 9 | #[cfg(any(feature = "textfield", feature = "textarea"))] 10 | pub(crate) mod validity_state; 11 | #[cfg(any(feature = "textfield", feature = "textarea"))] 12 | pub use validity_state::ValidityState; 13 | 14 | #[cfg(any(feature = "textfield", feature = "textarea"))] 15 | pub(crate) mod text_field_type; 16 | #[cfg(any(feature = "textfield", feature = "textarea"))] 17 | pub use text_field_type::*; 18 | 19 | #[cfg(feature = "textarea")] 20 | mod textarea; 21 | #[cfg(feature = "textarea")] 22 | pub use textarea::*; 23 | 24 | #[cfg(any(feature = "textfield", feature = "textarea"))] 25 | pub use web_sys::ValidityState as NativeValidityState; 26 | 27 | use std::rc::Rc; 28 | 29 | use gloo::events::EventListener; 30 | use wasm_bindgen::{JsCast, JsValue}; 31 | use web_sys::{Element, Event, InputEvent}; 32 | use yew::{Callback, InputData, NodeRef}; 33 | 34 | #[cfg(any(feature = "textfield", feature = "textarea"))] 35 | pub(crate) type ValidityTransformFn = dyn Fn(String, NativeValidityState) -> ValidityState; 36 | 37 | #[cfg(any(feature = "textfield", feature = "textarea"))] 38 | #[derive(Clone)] 39 | /// Owned function for validity props 40 | pub struct ValidityTransform(pub(crate) Rc); 41 | 42 | #[cfg(any(feature = "textfield", feature = "textarea"))] 43 | impl ValidityTransform { 44 | pub(crate) fn new ValidityState + 'static>( 45 | func: F, 46 | ) -> ValidityTransform { 47 | ValidityTransform(Rc::new(func)) 48 | } 49 | } 50 | 51 | fn set_on_input_handler( 52 | node_ref: &NodeRef, 53 | callback: Callback, 54 | convert: impl Fn((InputEvent, JsValue)) -> InputData + 'static, 55 | ) -> EventListener { 56 | let element = node_ref.cast::().unwrap(); 57 | EventListener::new(&element, "input", move |event: &Event| { 58 | let js_value = JsValue::from(event); 59 | 60 | let input_event = js_value 61 | .clone() 62 | .dyn_into::() 63 | .expect("could not convert to `InputEvent`"); 64 | 65 | callback.emit(convert((input_event, js_value))) 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /src/fab.rs: -------------------------------------------------------------------------------- 1 | use super::to_option; 2 | use wasm_bindgen::prelude::*; 3 | use yew::prelude::*; 4 | 5 | pub struct Fab { 6 | link: ComponentLink, 7 | label: String, 8 | // onsignal: Callback<()>, 9 | } 10 | 11 | pub enum Msg { 12 | Clicked, 13 | } 14 | 15 | /// Props for [`Fab`] 16 | /// 17 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/fab#propertiesattributes) 18 | #[derive(Clone, PartialEq, Properties)] 19 | pub struct FabProps { 20 | #[prop_or_default] 21 | pub icon: String, 22 | #[prop_or_default] 23 | pub label: String, 24 | #[prop_or_default] 25 | pub mini: bool, 26 | #[prop_or_default] 27 | pub reduced_touch_target: bool, 28 | #[prop_or_default] 29 | pub extended: bool, 30 | #[prop_or_default] 31 | pub show_icon_at_end: bool, 32 | #[prop_or_default] 33 | pub children: Children, 34 | } 35 | 36 | // label=props.label 37 | // icon=props.icon 38 | // mini?=to_option(props.mini) 39 | // reducedTouchTarget?=to_option(props.reduced_touch_target) 40 | // extended?=to_option(props.extended) 41 | // showIconAtEnd?=to_option(props.show_icon_at_end) 42 | 43 | impl Component for Fab { 44 | type Message = Msg; 45 | type Properties = FabProps; 46 | 47 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 48 | Self { 49 | link, 50 | label: props.label, 51 | // onsignal: props.onsignal, 52 | } 53 | } 54 | 55 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 56 | match msg { 57 | Msg::Clicked => { 58 | // self.onsignal.emit(()); 59 | } 60 | } 61 | false 62 | } 63 | 64 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 65 | self.label = props.label; 66 | // self.onsignal = props.onsignal; 67 | true 68 | } 69 | 70 | fn view(&self) -> Html { 71 | // onclick=self.link.callback(|_| Msg::Clicked)> 72 | // { &self.label } 73 | // { props.children.clone() } 74 | html! { 75 | 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/tooltip.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | pub struct Tooltip { 10 | link: ComponentLink, 11 | label: String, 12 | // onsignal: Callback<()>, 13 | } 14 | 15 | pub enum Msg { 16 | Clicked, 17 | } 18 | 19 | /// Props for [`Button`] 20 | /// 21 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 22 | #[derive(Clone, PartialEq, Properties)] 23 | pub struct TooltipProps { 24 | pub label: String, 25 | #[prop_or_default] 26 | pub icon: Option, 27 | #[prop_or_default] 28 | pub raised: bool, 29 | #[prop_or_default] 30 | pub unelevated: bool, 31 | #[prop_or_default] 32 | pub outlined: bool, 33 | #[prop_or_default] 34 | pub dense: bool, 35 | #[prop_or_default] 36 | pub disabled: bool, 37 | #[prop_or_default] 38 | pub trailing_icon: bool, 39 | // #[prop_or_default] 40 | // pub onsignal: Callback<()>, 41 | } 42 | 43 | // label=props.label 44 | // icon?=props.icon.as_ref() 45 | // raised?=to_option(props.raised) 46 | // unelevated?=to_option(props.unelevated) 47 | // outlined?=to_option(props.outlined) 48 | // dense?=to_option(props.dense) 49 | // trailingIcon?=to_option(props.trailing_icon) 50 | // disabled=props.disabled 51 | 52 | impl Component for Tooltip { 53 | type Message = Msg; 54 | type Properties = TooltipProps; 55 | 56 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 57 | Self { 58 | link, 59 | label: props.label, 60 | // onsignal: props.onsignal, 61 | } 62 | } 63 | 64 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 65 | match msg { 66 | Msg::Clicked => { 67 | // self.onsignal.emit(()); 68 | } 69 | } 70 | false 71 | } 72 | 73 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 74 | self.label = props.label; 75 | // self.onsignal = props.onsignal; 76 | true 77 | } 78 | 79 | fn view(&self) -> Html { 80 | html! { 81 | 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/button.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | pub struct Button { 10 | props: ButtonProps, 11 | link: ComponentLink, 12 | } 13 | 14 | pub enum Msg { 15 | Clicked, 16 | } 17 | 18 | /// Props for [`Button`] 19 | /// 20 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 21 | #[derive(Clone, PartialEq, Properties)] 22 | pub struct ButtonProps { 23 | pub label: String, 24 | #[prop_or_default] 25 | pub icon: Option, 26 | #[prop_or_default] 27 | pub raised: bool, 28 | #[prop_or_default] 29 | pub unelevated: bool, 30 | #[prop_or_default] 31 | pub outlined: bool, 32 | #[prop_or_default] 33 | pub dense: bool, 34 | #[prop_or_default] 35 | pub disabled: bool, 36 | #[prop_or_default] 37 | pub trailing_icon: bool, 38 | #[prop_or_default] 39 | pub onclick: Callback<()>, 40 | } 41 | 42 | // label=props.label 43 | // icon?=props.icon.as_ref() 44 | // raised?=to_option(props.raised) 45 | // unelevated?=to_option(props.unelevated) 46 | // outlined?=to_option(props.outlined) 47 | // dense?=to_option(props.dense) 48 | // trailingIcon?=to_option(props.trailing_icon) 49 | // disabled=props.disabled 50 | 51 | impl Component for Button { 52 | type Message = Msg; 53 | type Properties = ButtonProps; 54 | 55 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 56 | Self { 57 | link, 58 | props, 59 | } 60 | } 61 | 62 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 63 | match msg { 64 | Msg::Clicked => { 65 | self.props.onclick.emit(()); 66 | } 67 | } 68 | false 69 | } 70 | 71 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 72 | if self.props != props { 73 | self.props = props; 74 | true 75 | } else { 76 | false 77 | } 78 | } 79 | 80 | fn view(&self) -> Html { 81 | html! { 82 | 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/dialog/dialog_action.rs: -------------------------------------------------------------------------------- 1 | use yew::prelude::*; 2 | 3 | /// Dialog action type. 4 | #[derive(Clone)] 5 | pub enum ActionType { 6 | /// Binds `to slot` of `primaryAction` 7 | Primary, 8 | /// Binds `to slot` of `secondaryAction` 9 | Secondary, 10 | } 11 | 12 | impl ToString for ActionType { 13 | fn to_string(&self) -> String { 14 | match self { 15 | ActionType::Primary => "primaryAction", 16 | ActionType::Secondary => "secondaryAction", 17 | } 18 | .to_string() 19 | } 20 | } 21 | 22 | /// Props for [`DialogAction`] 23 | #[derive(Properties, Clone)] 24 | pub struct ActionProps { 25 | pub action_type: ActionType, 26 | #[prop_or_default] 27 | pub action: Option, 28 | pub children: Children, 29 | } 30 | 31 | /// Defines actions for [`Dialog`][crate::Dialog]. 32 | /// 33 | /// If the child passed is an element (a `VTag`), then it is modified to include 34 | /// the appropriate attributes. Otherwise, the child is wrapped in a `span` 35 | /// containing said attributes. 36 | pub struct DialogAction { 37 | props: ActionProps, 38 | } 39 | 40 | impl Component for DialogAction { 41 | type Message = (); 42 | type Properties = ActionProps; 43 | 44 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 45 | Self { props } 46 | } 47 | 48 | fn update(&mut self, _msg: Self::Message) -> bool { 49 | false 50 | } 51 | 52 | fn change(&mut self, props: Self::Properties) -> bool { 53 | self.props = props; 54 | true 55 | } 56 | 57 | fn view(&self) -> Html { 58 | // let children = self.props.children.iter().map(|child| { 59 | // match child { 60 | // Html::VTag(mut vtag) => { 61 | // vtag.add_attribute("slot", self.props.action_type.to_string()); 62 | // if let Some(action) = self.props.action.as_ref() { 63 | // vtag.add_attribute("dialogAction", action.to_owned()); 64 | // } 65 | // Html::VTag(vtag) 66 | // } 67 | // _ => html! { 68 | // 69 | // { child } 70 | // 71 | // } 72 | // } 73 | // }).collect::(); 74 | 75 | // html! { 76 | // { children } 77 | // } 78 | unimplemented!() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/list/check_list_item.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::list::request_selected::request_selected_listener; 5 | use crate::list::{GraphicType, RequestSelectedDetail}; 6 | use crate::to_option; 7 | use gloo::events::EventListener; 8 | use wasm_bindgen::prelude::*; 9 | use yew::prelude::*; 10 | 11 | 12 | /// The `check-list-item` component 13 | /// 14 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#checklist) 15 | pub struct CheckListItem { 16 | props: CheckListItemProps, 17 | node_ref: NodeRef, 18 | request_selected_listener: Option, 19 | } 20 | 21 | /// Props for [`CheckListItem`] 22 | /// 23 | /// Documentation for [properties](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-check-list-item) 24 | /// and [events](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-check-list-item-1) 25 | #[derive(Debug, Properties, Clone)] 26 | pub struct CheckListItemProps { 27 | #[prop_or_default] 28 | pub left: bool, 29 | #[prop_or(GraphicType::Control)] 30 | pub graphic: GraphicType, 31 | #[prop_or_default] 32 | pub disabled: bool, 33 | #[prop_or_default] 34 | pub on_request_selected: Callback, 35 | pub children: Children, 36 | } 37 | 38 | impl Component for CheckListItem { 39 | type Message = (); 40 | type Properties = CheckListItemProps; 41 | 42 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 43 | // CheckListItem::ensure_loaded(); 44 | // Self { 45 | // props, 46 | // node_ref: NodeRef::default(), 47 | // request_selected_listener: None, 48 | // } 49 | unimplemented!() 50 | } 51 | 52 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 53 | false 54 | } 55 | 56 | fn change(&mut self, props: Self::Properties) -> bool { 57 | self.props = props; 58 | true 59 | } 60 | 61 | fn view(&self) -> Html { 62 | // left?=to_option(self.props.left) 63 | // graphic=self.props.graphic.to_string() 64 | // disabled=self.props.disabled 65 | // ref=self.node_ref.clone() 66 | // >{ self.props.children.clone() } 67 | 68 | unimplemented!() 69 | } 70 | 71 | fn rendered(&mut self, first_render: bool) { 72 | if first_render { 73 | self.request_selected_listener = Some(request_selected_listener( 74 | &self.node_ref, 75 | self.props.on_request_selected.clone(), 76 | )); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/list/radio_list_item.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::list::request_selected::request_selected_listener; 5 | use crate::list::{GraphicType, RequestSelectedDetail}; 6 | use crate::to_option; 7 | use gloo::events::EventListener; 8 | use wasm_bindgen::prelude::*; 9 | use yew::prelude::*; 10 | 11 | /// The `list-item` Component 12 | /// 13 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-radio-list-item) 14 | pub struct RadioListItem { 15 | props: RadioListItemProps, 16 | node_ref: NodeRef, 17 | request_selected_listener: Option, 18 | } 19 | 20 | /// Props for [`RadioListItem`] 21 | /// 22 | /// Documentation [properties](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-radio-list-item-1) 23 | /// and [events](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-radio-list-item-2) 24 | #[derive(Debug, Properties, Clone)] 25 | pub struct RadioListItemProps { 26 | #[prop_or_default] 27 | pub left: bool, 28 | #[prop_or_default] 29 | pub group: Option, 30 | #[prop_or(GraphicType::Control)] 31 | pub graphic: GraphicType, 32 | /// Binds to `request-selected` event on `list-item`. 33 | #[prop_or_default] 34 | pub on_request_selected: Callback, 35 | pub children: Children, 36 | } 37 | 38 | impl Component for RadioListItem { 39 | type Message = (); 40 | type Properties = RadioListItemProps; 41 | 42 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 43 | // RadioListItem::ensure_loaded(); 44 | // Self { 45 | // props, 46 | // node_ref: NodeRef::default(), 47 | // request_selected_listener: None, 48 | // } 49 | unimplemented!() 50 | } 51 | 52 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 53 | false 54 | } 55 | 56 | fn change(&mut self, props: Self::Properties) -> bool { 57 | self.props = props; 58 | true 59 | } 60 | 61 | fn view(&self) -> Html { 62 | // left?=to_option(self.props.left) 63 | // graphic=self.props.graphic.to_string() 64 | // group=self.props.group.as_ref().unwrap_or(&"null".to_string()) 65 | // ref=self.node_ref.clone() 66 | // >{ self.props.children.clone() } 67 | 68 | unimplemented!() 69 | } 70 | 71 | fn rendered(&mut self, first_render: bool) { 72 | if first_render { 73 | self.request_selected_listener = Some(request_selected_listener( 74 | &self.node_ref, 75 | self.props.on_request_selected.clone(), 76 | )); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/linear_progress.rs: -------------------------------------------------------------------------------- 1 | use super::to_option; 2 | use wasm_bindgen::prelude::*; 3 | use yew::prelude::*; 4 | 5 | pub struct LinearProgress { 6 | link: ComponentLink, 7 | // label: String, 8 | // onsignal: Callback<()>, 9 | } 10 | 11 | /// Props for [`LinearProgress`] 12 | /// 13 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/linear-progress#propertiesattributes) 14 | #[derive(Clone, PartialEq, Properties)] 15 | pub struct LinearProgressProps { 16 | #[prop_or_default] 17 | pub indeterminate: bool, 18 | #[prop_or_default] 19 | pub progress: f32, 20 | #[prop_or_default] 21 | pub buffer: f32, 22 | #[prop_or_default] 23 | pub reverse: bool, 24 | #[prop_or_default] 25 | pub closed: bool, 26 | } 27 | 28 | impl Component for LinearProgress { 29 | type Message = (); 30 | type Properties = LinearProgressProps; 31 | 32 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 33 | Self { 34 | link, 35 | // label: props.label, 36 | // onsignal: props.onsignal, 37 | } 38 | } 39 | 40 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 41 | // match msg { 42 | // Msg::Clicked => { 43 | // // self.onsignal.emit(()); 44 | // } 45 | // } 46 | false 47 | } 48 | 49 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 50 | // self.label = props.label; 51 | // self.onsignal = props.onsignal; 52 | true 53 | } 54 | 55 | 56 | // indeterminate?=to_option(props.indeterminate) 57 | // progress=props.progress 58 | // buffer=props.buffer 59 | // reverse?=to_option(props.reverse) 60 | // closed?=to_option(props.closed) 61 | 62 | fn view(&self) -> Html { 63 | // onclick=self.link.callback(|_| Msg::Clicked)> 64 | // { &self.label } 65 | // { props.children.clone() } 66 | html! { 67 |
68 |
69 |
70 |
71 |
72 |
73 | 74 |
75 |
76 | 77 |
78 |
79 | } 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ymc" 3 | version = "0.1.0" 4 | authors = ["Victor Dudochkin "] 5 | readme = "README.md" 6 | homepage = "https://angular-rust.github.io/yew-components" 7 | repository = "https://github.com/angular-rust/yew-components" 8 | documentation = "https://docs.rs/ymc" 9 | description = "Materail Components for YEW" 10 | keywords = ["wasm", "web", "material", "yew", "material-components"] 11 | categories = ["wasm", "web-programming", "gui"] 12 | edition = "2018" 13 | license = "MPL-2.0" 14 | 15 | [badges] 16 | maintenance = { status = "actively-developed" } 17 | 18 | [features] 19 | banner = [] 20 | button = [] 21 | barchart = ["ux-animate", "ux-dataflow", "ux-charts"] 22 | card = [] 23 | charts = ["barchart", "gaugechart", "linechart", "piechart", "radarchart"] 24 | checkbox = [] 25 | chips = [] 26 | circular-progress-four-color = [] 27 | circular-progress = [] 28 | data-table = [] 29 | dialog = [] 30 | drawer = [] 31 | fab = [] 32 | formfield = [] 33 | gaugechart = ["ux-animate", "ux-dataflow", "ux-charts"] 34 | icon-button-toggle = [] 35 | icon-button = [] 36 | icon = [] 37 | image-list = [] 38 | linechart = ["ux-animate", "ux-dataflow", "ux-charts"] 39 | linear-progress = [] 40 | list = [] 41 | menu = [] 42 | piechart = ["ux-animate", "ux-dataflow", "ux-charts"] 43 | radarchart = ["ux-animate", "ux-dataflow", "ux-charts"] 44 | radio = [] 45 | select = [] 46 | slider = [] 47 | snackbar = [] 48 | switch = [] 49 | tabs = [] 50 | textarea = [] 51 | textfield = [] 52 | tooltip = [] 53 | top-app-bar-fixed = [] 54 | top-app-bar = [] 55 | full = [ 56 | "banner", 57 | "button", 58 | "card", 59 | "charts", 60 | "checkbox", 61 | "chips", 62 | "circular-progress-four-color", 63 | "circular-progress", 64 | "data-table", 65 | "dialog", 66 | "drawer", 67 | "fab", 68 | "formfield", 69 | "icon-button-toggle", 70 | "icon-button", 71 | "icon", 72 | "image-list", 73 | "linear-progress", 74 | "list", 75 | "menu", 76 | "radio", 77 | "select", 78 | "slider", 79 | "snackbar", 80 | "switch", 81 | "tabs", 82 | "textarea", 83 | "textfield", 84 | "tooltip", 85 | "top-app-bar-fixed", 86 | "top-app-bar", 87 | ] 88 | default = ["full"] 89 | 90 | [dependencies] 91 | wasm-bindgen = "0.2" 92 | wasm-bindgen-futures = "0.4" 93 | wasm-logger = "0.2" 94 | gloo = "0.2" 95 | js-sys = "0.3" 96 | log = "0.4" 97 | wee_alloc = { version = "0.4", optional = true } 98 | yew = "0.17" 99 | yew-router = "0.14" 100 | 101 | ux-dataflow = { version = "0.1.1", optional = true } 102 | ux-animate = { version = "0.1.3", optional = true } 103 | ux-charts = { version = "0.1.2", optional = true } 104 | 105 | [dev-dependencies] 106 | wasm-bindgen-test = "0.3" 107 | doc-comment = "0.3" 108 | 109 | [dependencies.web-sys] 110 | version = "0.3" 111 | features = [ 112 | 'KeyboardEvent', 113 | "ValidityState", 114 | "CustomEvent", 115 | "Node", 116 | "Element", 117 | "HtmlElement", 118 | "Window", 119 | "Document", 120 | "HtmlCanvasElement", 121 | ] 122 | -------------------------------------------------------------------------------- /src/image_list.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | pub struct ImageList { 10 | link: ComponentLink, 11 | label: String, 12 | // onsignal: Callback<()>, 13 | } 14 | 15 | pub enum Msg { 16 | Clicked, 17 | } 18 | 19 | /// Props for [`ImageList`] 20 | /// 21 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 22 | #[derive(Clone, PartialEq, Properties)] 23 | pub struct ImageListProps { 24 | pub label: String, 25 | #[prop_or_default] 26 | pub icon: Option, 27 | #[prop_or_default] 28 | pub raised: bool, 29 | #[prop_or_default] 30 | pub unelevated: bool, 31 | #[prop_or_default] 32 | pub outlined: bool, 33 | #[prop_or_default] 34 | pub dense: bool, 35 | #[prop_or_default] 36 | pub disabled: bool, 37 | #[prop_or_default] 38 | pub trailing_icon: bool, 39 | // #[prop_or_default] 40 | // pub onsignal: Callback<()>, 41 | } 42 | 43 | // label=props.label 44 | // icon?=props.icon.as_ref() 45 | // raised?=to_option(props.raised) 46 | // unelevated?=to_option(props.unelevated) 47 | // outlined?=to_option(props.outlined) 48 | // dense?=to_option(props.dense) 49 | // trailingIcon?=to_option(props.trailing_icon) 50 | // disabled=props.disabled 51 | 52 | impl Component for ImageList { 53 | type Message = Msg; 54 | type Properties = ImageListProps; 55 | 56 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 57 | Self { 58 | link, 59 | label: props.label, 60 | // onsignal: props.onsignal, 61 | } 62 | } 63 | 64 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 65 | match msg { 66 | Msg::Clicked => { 67 | // self.onsignal.emit(()); 68 | } 69 | } 70 | false 71 | } 72 | 73 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 74 | self.label = props.label; 75 | // self.onsignal = props.onsignal; 76 | true 77 | } 78 | 79 | fn view(&self) -> Html { 80 | // html! { 81 | // 84 | // } 85 | html! { 86 |
    87 |
  • 88 |
    89 | 90 |
    91 |
    92 | { "Text label" } 93 |
    94 |
  • 95 |
96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/banner.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | pub struct Banner { 10 | link: ComponentLink, 11 | label: String, 12 | // onsignal: Callback<()>, 13 | } 14 | 15 | pub enum Msg { 16 | Clicked, 17 | } 18 | 19 | /// Props for [`Banner`] 20 | /// 21 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 22 | #[derive(Clone, PartialEq, Properties)] 23 | pub struct BannerProps { 24 | pub label: String, 25 | #[prop_or_default] 26 | pub icon: Option, 27 | #[prop_or_default] 28 | pub raised: bool, 29 | #[prop_or_default] 30 | pub unelevated: bool, 31 | #[prop_or_default] 32 | pub outlined: bool, 33 | #[prop_or_default] 34 | pub dense: bool, 35 | #[prop_or_default] 36 | pub disabled: bool, 37 | #[prop_or_default] 38 | pub trailing_icon: bool, 39 | // #[prop_or_default] 40 | // pub onsignal: Callback<()>, 41 | } 42 | 43 | // label=props.label 44 | // icon?=props.icon.as_ref() 45 | // raised?=to_option(props.raised) 46 | // unelevated?=to_option(props.unelevated) 47 | // outlined?=to_option(props.outlined) 48 | // dense?=to_option(props.dense) 49 | // trailingIcon?=to_option(props.trailing_icon) 50 | // disabled=props.disabled 51 | 52 | impl Component for Banner { 53 | type Message = Msg; 54 | type Properties = BannerProps; 55 | 56 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 57 | Self { 58 | link, 59 | label: props.label, 60 | // onsignal: props.onsignal, 61 | } 62 | } 63 | 64 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 65 | match msg { 66 | Msg::Clicked => { 67 | // self.onsignal.emit(()); 68 | } 69 | } 70 | false 71 | } 72 | 73 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 74 | self.label = props.label; 75 | // self.onsignal = props.onsignal; 76 | true 77 | } 78 | 79 | fn view(&self) -> Html { 80 | html! { 81 | 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/top_app_bar_fixed.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::to_option; 5 | #[doc(inline)] 6 | 7 | pub use crate::top_app_bar::{ 8 | TopAppBarActionItems, TopAppBarNavigationIcon, TopAppBarTitle, 9 | }; 10 | 11 | use gloo::events::EventListener; 12 | use wasm_bindgen::prelude::*; 13 | use web_sys::Element; 14 | use yew::prelude::*; 15 | 16 | /// The `top-app-bar-fixed` component 17 | /// 18 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar-fixed) 19 | pub struct TopAppBarFixed { 20 | props: TopAppBarFixedProps, 21 | node_ref: NodeRef, 22 | nav_listener: Option, 23 | } 24 | 25 | /// Props for [`TopAppBarFixed`] 26 | /// 27 | /// Documentation: 28 | /// 29 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar-fixed#propertiesattributes) 30 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar-fixed#events) 31 | #[derive(Clone, PartialEq, Properties)] 32 | pub struct TopAppBarFixedProps { 33 | pub children: Children, 34 | #[prop_or_default] 35 | pub center_title: bool, 36 | #[prop_or_default] 37 | pub dense: bool, 38 | #[prop_or_default] 39 | pub prominent: bool, 40 | /// Binds to `MDCTopAppBar:nav` 41 | /// 42 | /// See events docs to learn more. 43 | #[prop_or_default] 44 | pub onnavigationiconclick: Callback<()>, 45 | } 46 | 47 | impl Component for TopAppBarFixed { 48 | type Message = (); 49 | type Properties = TopAppBarFixedProps; 50 | 51 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 52 | // TopAppBarFixed::ensure_loaded(); 53 | // Self { 54 | // props, 55 | // node_ref: NodeRef::default(), 56 | // nav_listener: None, 57 | // } 58 | unimplemented!() 59 | } 60 | 61 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 62 | false 63 | } 64 | 65 | fn change(&mut self, props: Self::Properties) -> bool { 66 | if self.props != props { 67 | self.props = props; 68 | true 69 | } else { 70 | false 71 | } 72 | } 73 | 74 | fn view(&self) -> Html { 75 | // centerTitle?=to_option(self.props.center_title) 76 | // dense?=to_option(self.props.dense) 77 | // prominent?=to_option(self.props.prominent) 78 | // ref=self.node_ref.clone() 79 | // >{ self.props.children.clone() } 80 | 81 | unimplemented!() 82 | } 83 | 84 | fn rendered(&mut self, first_render: bool) { 85 | if first_render { 86 | let callback = self.props.onnavigationiconclick.clone(); 87 | let element = self.node_ref.cast::().unwrap(); 88 | 89 | self.nav_listener = Some(EventListener::new( 90 | &element, 91 | "MDCTopAppBar:nav", 92 | move |_| { 93 | callback.emit(()); 94 | }, 95 | )); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/icon_button_toggle.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | mod off_icon; 5 | mod on_icon; 6 | 7 | pub use off_icon::*; 8 | pub use on_icon::*; 9 | 10 | use super::to_option; 11 | use gloo::events::EventListener; 12 | use wasm_bindgen::prelude::*; 13 | use web_sys::Node; 14 | use yew::prelude::*; 15 | 16 | /// The `icon-button-toggle` component 17 | /// 18 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/icon-button-toggle) 19 | pub struct IconButtonToggle { 20 | props: IconButtonToggleProps, 21 | node_ref: NodeRef, 22 | change_listener: Option, 23 | } 24 | 25 | /// Props for [`IconButtonToggle`] 26 | /// 27 | /// Documentation: 28 | /// 29 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/icon-button-toggle#propertiesattributes) 30 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/icon-button-toggle#events) 31 | #[derive(Clone, PartialEq, Properties)] 32 | pub struct IconButtonToggleProps { 33 | #[prop_or_default] 34 | pub on: bool, 35 | #[prop_or_default] 36 | pub on_icon: String, 37 | #[prop_or_default] 38 | pub off_icon: String, 39 | #[prop_or_default] 40 | pub label: String, 41 | #[prop_or_default] 42 | pub disabled: bool, 43 | /// Binds to `MDCIconButtonToggle:change`. 44 | /// 45 | /// Callback's parameter is the `isOn` value passed 46 | /// 47 | /// See events docs to learn more. 48 | #[prop_or_default] 49 | pub onchange: Callback, 50 | #[prop_or_default] 51 | pub children: Children, 52 | } 53 | 54 | impl Component for IconButtonToggle { 55 | type Message = (); 56 | type Properties = IconButtonToggleProps; 57 | 58 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 59 | // IconButtonToggle::ensure_loaded(); 60 | Self { 61 | props, 62 | node_ref: NodeRef::default(), 63 | change_listener: None, 64 | } 65 | } 66 | 67 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 68 | false 69 | } 70 | 71 | fn change(&mut self, props: Self::Properties) -> bool { 72 | if self.props != props { 73 | self.props = props; 74 | true 75 | } else { 76 | false 77 | } 78 | } 79 | 80 | fn view(&self) -> Html { 81 | // on?=to_option(self.props.on) 82 | // onIcon=self.props.on_icon 83 | // offIcon=self.props.off_icon 84 | // label=self.props.label 85 | // disabled=self.props.disabled 86 | // ref=self.node_ref.clone() 87 | // > { self.props.children.clone() } 88 | 89 | unimplemented!() 90 | } 91 | 92 | fn rendered(&mut self, first_render: bool) { 93 | // if first_render { 94 | // let element = self.node_ref.cast::().unwrap(); 95 | 96 | // let callback = self.props.onchange.clone(); 97 | // self.change_listener = Some(EventListener::new( 98 | // &element.clone(), 99 | // "MDCIconButtonToggle:change", 100 | // move |_| callback.emit(element.on()), 101 | // )); 102 | // } 103 | unimplemented!() 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/tabs/tab.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::{event_details_into, to_option}; 5 | use gloo::events::EventListener; 6 | use js_sys::Object; 7 | use wasm_bindgen::prelude::*; 8 | use web_sys::Element; 9 | use yew::prelude::*; 10 | 11 | /// The `tab` component 12 | /// 13 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/tab) 14 | pub struct Tab { 15 | props: TabProps, 16 | node_ref: NodeRef, 17 | interacted_listener: Option, 18 | } 19 | 20 | /// Props for `Tab` 21 | /// 22 | /// Documentation [properties](https://github.com/material-components/material-components-web-components/tree/master/packages/tab#propertiesattributes) 23 | /// and [events](https://github.com/material-components/material-components-web-components/tree/master/packages/tab#events) 24 | #[derive(Debug, Properties, Clone)] 25 | pub struct TabProps { 26 | #[prop_or_default] 27 | pub label: String, 28 | #[prop_or_default] 29 | pub icon: String, 30 | #[prop_or_default] 31 | pub has_image_icon: bool, 32 | #[prop_or_default] 33 | pub indicator_icon: String, 34 | #[prop_or_default] 35 | pub is_fading_indicator: bool, 36 | #[prop_or_default] 37 | pub min_width: bool, 38 | #[prop_or_default] 39 | pub is_min_width_indicator: bool, 40 | #[prop_or_default] 41 | pub stacked: bool, 42 | /// Binds to `MDCTab:interacted` event on `tab` 43 | /// 44 | /// See events docs to learn more. 45 | #[prop_or_default] 46 | pub oninteracted: Callback, 47 | #[prop_or_default] 48 | pub children: Children, 49 | } 50 | 51 | impl Component for Tab { 52 | type Message = (); 53 | type Properties = TabProps; 54 | 55 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 56 | // Tab::ensure_loaded(); 57 | Self { 58 | props, 59 | node_ref: NodeRef::default(), 60 | interacted_listener: None, 61 | } 62 | } 63 | 64 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 65 | false 66 | } 67 | 68 | fn change(&mut self, props: Self::Properties) -> bool { 69 | self.props = props; 70 | true 71 | } 72 | 73 | fn view(&self) -> Html { 74 | // label=self.props.label 75 | // icon=self.props.icon 76 | // hasImageIcon?=to_option(self.props.has_image_icon) 77 | // indicatorIcon=self.props.indicator_icon 78 | // isFadingIndicator?=to_option(self.props.is_fading_indicator) 79 | // minWidth?=to_option(self.props.min_width) 80 | // isMinWidthIndicator?=to_option(self.props.is_min_width_indicator) 81 | // stacked?=to_option(self.props.stacked) 82 | // ref=self.node_ref.clone() 83 | // >{ self.props.children.clone() } 84 | 85 | unimplemented!() 86 | } 87 | 88 | fn rendered(&mut self, first_render: bool) { 89 | // if first_render { 90 | // let element = self.node_ref.cast::().unwrap(); 91 | 92 | // let on_interacted = self.props.oninteracted.clone(); 93 | // self.interacted_listener = Some(EventListener::new( 94 | // &element, 95 | // "MDCTab:interacted", 96 | // move |event| { 97 | // let detail = event_details_into::(event); 98 | // on_interacted.emit(detail.tab_id()); 99 | // }, 100 | // )); 101 | // } 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/radio.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::to_option; 5 | use gloo::events::EventListener; 6 | use wasm_bindgen::prelude::*; 7 | use web_sys::Node; 8 | use yew::prelude::*; 9 | 10 | /// The `radio` component 11 | /// 12 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/radio) 13 | pub struct Radio { 14 | props: RadioProps, 15 | node_ref: NodeRef, 16 | change_listener: Option, 17 | } 18 | 19 | /// Props for [`Radio`] 20 | /// 21 | /// Documentation: 22 | /// 23 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/radio#propertiesattributes) 24 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/radio#events) 25 | #[derive(Clone, PartialEq, Properties)] 26 | pub struct RadioProps { 27 | #[prop_or_default] 28 | pub checked: bool, 29 | #[prop_or_default] 30 | pub disabled: bool, 31 | #[prop_or_default] 32 | pub name: String, 33 | #[prop_or_default] 34 | pub value: String, 35 | #[prop_or_default] 36 | pub global: bool, 37 | #[prop_or_default] 38 | pub reduced_touch_target: bool, 39 | /// Binds to `change`. 40 | /// 41 | /// Callback's parameter of type denotes if the radio is checked or not. 42 | /// 43 | /// See events docs to learn more. 44 | #[prop_or_default] 45 | pub onchange: Callback, 46 | } 47 | 48 | impl Component for Radio { 49 | type Message = (); 50 | type Properties = RadioProps; 51 | 52 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 53 | // Radio::ensure_loaded(); 54 | Self { 55 | props, 56 | node_ref: NodeRef::default(), 57 | change_listener: None, 58 | } 59 | } 60 | 61 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 62 | false 63 | } 64 | 65 | fn change(&mut self, props: Self::Properties) -> bool { 66 | if self.props != props { 67 | self.props = props; 68 | true 69 | } else { 70 | false 71 | } 72 | } 73 | 74 | fn view(&self) -> Html { 75 | // disabled=self.props.disabled 76 | // name=self.props.name 77 | // value=self.props.value 78 | // global?=to_option(self.props.global) 79 | // reducedTouchTarget?=to_option(self.props.reduced_touch_target) 80 | // ref=self.node_ref.clone() 81 | 82 | // checked=true 83 | html! { 84 |
85 | 86 |
87 |
88 |
89 |
90 |
91 |
92 | } 93 | } 94 | 95 | fn rendered(&mut self, first_render: bool) { 96 | // let element = self.node_ref.cast::().unwrap(); 97 | // element.set_checked(self.props.checked); 98 | 99 | // if first_render { 100 | // let callback = self.props.onchange.clone(); 101 | // self.change_listener = 102 | // Some(EventListener::new(&element.clone(), "change", move |_| { 103 | // callback.emit(element.checked()); 104 | // })); 105 | // } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/checkbox.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::to_option; 5 | use gloo::events::EventListener; 6 | use wasm_bindgen::prelude::*; 7 | use web_sys::{Element, Node}; 8 | use yew::prelude::*; 9 | 10 | /// The `checkbox` component 11 | /// 12 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/checkbox) 13 | pub struct Checkbox { 14 | props: CheckboxProps, 15 | node_ref: NodeRef, 16 | change_listener: Option, 17 | } 18 | 19 | /// Props for [`Checkbox`] 20 | /// 21 | /// Documentation: 22 | /// 23 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/checkbox#propertiesattributes) 24 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/checkbox#events) 25 | #[derive(Clone, PartialEq, Properties)] 26 | pub struct CheckboxProps { 27 | #[prop_or_default] 28 | pub checked: bool, 29 | #[prop_or_default] 30 | pub indeterminate: bool, 31 | #[prop_or_default] 32 | pub disabled: bool, 33 | #[prop_or_default] 34 | pub value: String, 35 | #[prop_or_default] 36 | pub reduced_touch_target: bool, 37 | /// Binds to `change` event on `checkbox` 38 | /// 39 | /// See events docs to learn more. 40 | #[prop_or_default] 41 | pub onchange: Callback, 42 | } 43 | 44 | impl Component for Checkbox { 45 | type Message = (); 46 | type Properties = CheckboxProps; 47 | 48 | fn create(props: Self::Properties, _link: ComponentLink) -> Self { 49 | // Checkbox::ensure_loaded(); 50 | Self { 51 | props, 52 | node_ref: NodeRef::default(), 53 | change_listener: None, 54 | } 55 | } 56 | 57 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 58 | false 59 | } 60 | 61 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 62 | if self.props != props { 63 | self.props = props; 64 | true 65 | } else { 66 | false 67 | } 68 | } 69 | 70 | // indeterminate?=to_option(self.props.indeterminate) 71 | // disabled=self.props.disabled 72 | // value=self.props.value 73 | // reducedTouchTarget?=to_option(self.props.reduced_touch_target) 74 | // ref=self.node_ref.clone() 75 | 76 | fn view(&self) -> Html { 77 | 78 | html! { 79 |
80 | 83 |
84 | 85 | 87 | 88 |
89 |
90 |
91 |
92 | } 93 | } 94 | 95 | fn rendered(&mut self, first_render: bool) { 96 | // let element = self.node_ref.cast::().unwrap(); 97 | // if self.props.checked { 98 | // element.set_checked(self.props.checked); 99 | // } 100 | // if first_render { 101 | // let callback = self.props.onchange.clone(); 102 | // let target = self.node_ref.cast::().unwrap(); 103 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 104 | // callback.emit(element.checked()); 105 | // })); 106 | // } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/list/list_item.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::list::request_selected::request_selected_listener; 5 | use crate::list::{GraphicType, RequestSelectedDetail}; 6 | use crate::{to_option, to_option_string}; 7 | use gloo::events::EventListener; 8 | use wasm_bindgen::prelude::*; 9 | use yew::prelude::*; 10 | 11 | /// The `list-item` Component 12 | /// 13 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-item) 14 | pub struct ListItem { 15 | props: ListItemProps, 16 | node_ref: NodeRef, 17 | request_selected_listener: Option, 18 | } 19 | 20 | /// Props for [`ListItem`] 21 | /// 22 | /// Documentation [properties](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-item-1) 23 | /// and [events](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-item-2) 24 | #[derive(Debug, Properties, Clone)] 25 | pub struct ListItemProps { 26 | #[prop_or_default] 27 | pub value: String, 28 | #[prop_or_default] 29 | pub group: bool, 30 | #[prop_or(- 1)] 31 | pub tabindex: i32, 32 | #[prop_or_default] 33 | pub disabled: bool, 34 | #[prop_or_default] 35 | pub twoline: bool, 36 | #[prop_or_default] 37 | pub activated: bool, 38 | #[prop_or(GraphicType::Null)] 39 | pub graphic: GraphicType, 40 | #[prop_or_default] 41 | pub multiple_graphics: bool, 42 | #[prop_or_default] 43 | pub has_meta: bool, 44 | #[prop_or_default] 45 | pub noninteractive: bool, 46 | #[prop_or_default] 47 | pub selected: bool, 48 | /// Binds to `request-selected` event on `list-item`. 49 | #[prop_or_default] 50 | pub on_request_selected: Callback, 51 | #[prop_or_default] 52 | pub children: Children, 53 | } 54 | 55 | impl Component for ListItem { 56 | type Message = (); 57 | type Properties = ListItemProps; 58 | 59 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 60 | // ListItem::ensure_loaded(); 61 | Self { 62 | props, 63 | node_ref: NodeRef::default(), 64 | request_selected_listener: None, 65 | } 66 | } 67 | 68 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 69 | false 70 | } 71 | 72 | fn change(&mut self, props: Self::Properties) -> bool { 73 | self.props = props; 74 | true 75 | } 76 | 77 | fn view(&self) -> Html { 78 | // value?=to_option_string(&self.props.value) 79 | // group?=to_option(self.props.group) 80 | // tabindex=self.props.tabindex 81 | // disabled=self.props.disabled 82 | // twoline?=to_option(self.props.twoline) 83 | // activated?=to_option(self.props.activated) 84 | // graphic=self.props.graphic.to_string() 85 | // multipleGraphics?=to_option(self.props.multiple_graphics) 86 | // hasMeta?=to_option(self.props.has_meta) 87 | // noninteractive?=to_option(self.props.noninteractive) 88 | // selected=self.props.selected 89 | // ref=self.node_ref.clone() 90 | // >{ self.props.children.clone() } 91 | 92 | html!{ 93 |
  • 94 | 95 | { &self.props.value } 96 |
  • 97 | } 98 | } 99 | 100 | fn rendered(&mut self, first_render: bool) { 101 | // if first_render { 102 | // self.request_selected_listener = Some(request_selected_listener( 103 | // &self.node_ref, 104 | // self.props.on_request_selected.clone(), 105 | // )); 106 | // } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/card.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | mod actions; 10 | mod buttons; 11 | mod media; 12 | mod primary_action; 13 | 14 | pub use actions::*; 15 | pub use buttons::*; 16 | pub use media::*; 17 | pub use primary_action::*; 18 | 19 | pub struct Card { 20 | link: ComponentLink, 21 | label: String, 22 | // onsignal: Callback<()>, 23 | } 24 | 25 | pub enum Msg { 26 | Clicked, 27 | } 28 | 29 | /// Props for [`Card`] 30 | /// 31 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 32 | #[derive(Clone, PartialEq, Properties)] 33 | pub struct CardProps { 34 | pub label: String, 35 | #[prop_or_default] 36 | pub icon: Option, 37 | #[prop_or_default] 38 | pub raised: bool, 39 | #[prop_or_default] 40 | pub unelevated: bool, 41 | #[prop_or_default] 42 | pub outlined: bool, 43 | #[prop_or_default] 44 | pub dense: bool, 45 | #[prop_or_default] 46 | pub disabled: bool, 47 | #[prop_or_default] 48 | pub trailing_icon: bool, 49 | // #[prop_or_default] 50 | // pub onsignal: Callback<()>, 51 | } 52 | 53 | // label=props.label 54 | // icon?=props.icon.as_ref() 55 | // raised?=to_option(props.raised) 56 | // unelevated?=to_option(props.unelevated) 57 | // outlined?=to_option(props.outlined) 58 | // dense?=to_option(props.dense) 59 | // trailingIcon?=to_option(props.trailing_icon) 60 | // disabled=props.disabled 61 | 62 | impl Component for Card { 63 | type Message = Msg; 64 | type Properties = CardProps; 65 | 66 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 67 | Self { 68 | link, 69 | label: props.label, 70 | // onsignal: props.onsignal, 71 | } 72 | } 73 | 74 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 75 | match msg { 76 | Msg::Clicked => { 77 | // self.onsignal.emit(()); 78 | } 79 | } 80 | false 81 | } 82 | 83 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 84 | self.label = props.label; 85 | // self.onsignal = props.onsignal; 86 | true 87 | } 88 | 89 | fn view(&self) -> Html { 90 | html! { 91 |
    92 |
    93 |
    94 |
    { "Title" }
    95 |
    96 |
    97 |
    98 |
    99 | 103 | 107 |
    108 |
    109 | 110 | 111 |
    112 |
    113 |
    114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/switch.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use gloo::events::EventListener; 5 | use wasm_bindgen::prelude::*; 6 | use web_sys::Node; 7 | use yew::prelude::*; 8 | 9 | /// The `switch` component 10 | /// 11 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/switch) 12 | pub struct Switch { 13 | props: SwitchProps, 14 | link: ComponentLink, 15 | change_listener: Option, 16 | } 17 | 18 | pub enum Msg { 19 | Clicked 20 | } 21 | 22 | /// Props for [`Switch`] 23 | /// 24 | /// Documentation: 25 | /// 26 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/switch#propertiesattributes) 27 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/switch#events) 28 | #[derive(Clone, PartialEq, Properties)] 29 | pub struct SwitchProps { 30 | #[prop_or_default] 31 | pub checked: bool, 32 | #[prop_or_default] 33 | pub disabled: bool, 34 | /// Binds to `change` event on `switch` 35 | /// 36 | /// See events docs to learn more. 37 | #[prop_or_default] 38 | pub onchange: Callback, 39 | } 40 | 41 | impl Component for Switch { 42 | type Message = Msg; 43 | type Properties = SwitchProps; 44 | 45 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 46 | // Switch::ensure_loaded(); 47 | Self { 48 | link, 49 | props, 50 | change_listener: None, 51 | } 52 | } 53 | 54 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 55 | // info!("Switch update!"); 56 | match msg { 57 | Msg::Clicked => { 58 | if self.props.checked { 59 | self.props.checked = false; 60 | } else { 61 | self.props.checked = true; 62 | } 63 | return true; 64 | } 65 | } 66 | 67 | // false 68 | } 69 | 70 | fn change(&mut self, props: Self::Properties) -> bool { 71 | if self.props != props { 72 | self.props = props; 73 | true 74 | } else { 75 | false 76 | } 77 | } 78 | 79 | fn view(&self) -> Html { 80 | // disabled=self.props.disabled 81 | // ref=self.node_ref.clone() 82 | 83 | html! { 84 |
    85 |
    86 |
    87 |
    88 | 89 |
    90 |
    91 | } 92 | } 93 | 94 | fn rendered(&mut self, first_render: bool) { 95 | // info!("Switch rendered!"); 96 | // let element = self.node_ref.cast::().unwrap(); 97 | // // element.set_checked(self.props.checked); 98 | 99 | // if first_render { 100 | // let callback = self.props.onchange.clone(); 101 | // self.change_listener = 102 | // Some(EventListener::new(&element.clone(), "change", move |_| { 103 | // callback.emit(element.checked()); 104 | // })); 105 | // } 106 | } 107 | } 108 | 109 | impl Switch { 110 | fn classes(&self) -> String { 111 | if self.props.checked { 112 | "mdc-switch mdc-switch--checked".into() 113 | } else { 114 | "mdc-switch mdc-switch".into() 115 | } 116 | } 117 | } 118 | 119 | // aria-checked=true 120 | // /** Class used for a switch that is in the "checked" (on) position. */ 121 | // CHECKED: 'mdc-switch--checked', 122 | // /** Class used for a switch that is disabled. */ 123 | // DISABLED: 'mdc-switch--disabled', -------------------------------------------------------------------------------- /src/circular_progress_four_color.rs: -------------------------------------------------------------------------------- 1 | use super::to_option; 2 | use wasm_bindgen::prelude::*; 3 | use yew::prelude::*; 4 | 5 | pub struct CircularProgressFourColor { 6 | link: ComponentLink, 7 | // label: String, 8 | // onsignal: Callback<()>, 9 | } 10 | 11 | /// Props for [`CircularProgressFourColor`] 12 | /// 13 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/circular-progress-four-color#propertiesattributes) 14 | #[derive(Clone, PartialEq, Properties)] 15 | pub struct CircularProgressFourColorProps { 16 | #[prop_or_default] 17 | pub indeterminate: bool, 18 | #[prop_or_default] 19 | pub progress: f32, 20 | #[prop_or_default] 21 | pub density: u32, 22 | #[prop_or_default] 23 | pub closed: bool, 24 | } 25 | 26 | // indeterminate?=to_option(props.indeterminate) 27 | // progress=props.progress 28 | // density=props.density 29 | // closed?=to_option(props.closed) 30 | 31 | impl Component for CircularProgressFourColor { 32 | type Message = (); 33 | type Properties = CircularProgressFourColorProps; 34 | 35 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 36 | Self { 37 | link, 38 | // label: props.label, 39 | // onsignal: props.onsignal, 40 | } 41 | } 42 | 43 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 44 | // match msg { 45 | // Msg::Clicked => { 46 | // // self.onsignal.emit(()); 47 | // } 48 | // } 49 | false 50 | } 51 | 52 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 53 | // self.label = props.label; 54 | // self.onsignal = props.onsignal; 55 | true 56 | } 57 | 58 | fn view(&self) -> Html { 59 | // onclick=self.link.callback(|_| Msg::Clicked)> 60 | // { &self.label } 61 | // { props.children.clone() } 62 | html! { 63 |
    64 |
    65 | 66 | 67 | 68 | 69 |
    70 |
    71 |
    72 |
    73 | 74 | 75 | 76 |
    77 |
    78 | 79 | 80 | 81 |
    82 |
    83 | 84 | 85 | 86 |
    87 |
    88 |
    89 |
    90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/circular_progress.rs: -------------------------------------------------------------------------------- 1 | use super::to_option; 2 | use wasm_bindgen::prelude::*; 3 | use yew::prelude::*; 4 | 5 | pub struct CircularProgress { 6 | link: ComponentLink, 7 | // label: String, 8 | // onsignal: Callback<()>, 9 | } 10 | 11 | /// Props for [`CircularProgress`] 12 | /// 13 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/circular-progress#propertiesattributes) 14 | #[derive(Clone, PartialEq, Properties)] 15 | pub struct CircularProgressProps { 16 | #[prop_or_default] 17 | pub indeterminate: bool, 18 | #[prop_or_default] 19 | pub progress: f32, 20 | #[prop_or_default] 21 | pub density: u32, 22 | #[prop_or_default] 23 | pub closed: bool, 24 | } 25 | 26 | // indeterminate?=to_option(props.indeterminate) 27 | // progress=props.progress 28 | // density=props.density 29 | // closed?=to_option(props.closed) 30 | 31 | impl Component for CircularProgress { 32 | type Message = (); 33 | type Properties = CircularProgressProps; 34 | 35 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 36 | Self { 37 | link, 38 | // label: props.label, 39 | // onsignal: props.onsignal, 40 | } 41 | } 42 | 43 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 44 | // match msg { 45 | // Msg::Clicked => { 46 | // // self.onsignal.emit(()); 47 | // } 48 | // } 49 | false 50 | } 51 | 52 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 53 | // self.label = props.label; 54 | // self.onsignal = props.onsignal; 55 | true 56 | } 57 | 58 | fn view(&self) -> Html { 59 | // onclick=self.link.callback(|_| Msg::Clicked)> 60 | // { &self.label } 61 | // { props.children.clone() } 62 | html! { 63 |
    64 |
    65 | 66 | 67 | 68 | 69 |
    70 |
    71 |
    72 |
    73 | 74 | 75 | 76 |
    77 |
    78 | 79 | 80 | 81 |
    82 |
    83 | 84 | 85 | 86 |
    87 |
    88 |
    89 |
    90 | } 91 | } 92 | } 93 | 94 | // 95 | // 97 | // -------------------------------------------------------------------------------- /src/slider.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::to_option; 5 | use gloo::events::EventListener; 6 | use wasm_bindgen::prelude::*; 7 | use wasm_bindgen::JsCast; 8 | use web_sys::{CustomEvent, Element}; 9 | use yew::prelude::*; 10 | 11 | 12 | /// The `snackbar` component 13 | /// 14 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/slider) 15 | pub struct Slider { 16 | props: SliderProps, 17 | node_ref: NodeRef, 18 | input_listener: Option, 19 | change_listener: Option, 20 | } 21 | 22 | /// Props for [`Slider`] 23 | /// 24 | /// Documentation: 25 | /// 26 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/slider#propertiesattributes) 27 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/slider#events) 28 | #[derive(Clone, PartialEq, Properties)] 29 | pub struct SliderProps { 30 | #[prop_or(0)] 31 | pub value: u32, 32 | #[prop_or(0)] 33 | pub min: u32, 34 | #[prop_or(100)] 35 | pub max: u32, 36 | #[prop_or(0)] 37 | pub step: u32, 38 | #[prop_or(false)] 39 | pub pin: bool, 40 | #[prop_or(false)] 41 | pub markers: bool, 42 | /// Binds to input on `slider` 43 | /// Type passed to callback is `CustomEvent` because `Slider` is 44 | /// undocumented See: 45 | #[prop_or_default] 46 | pub oninput: Callback, 47 | /// Binds to change on `slider` 48 | /// Type passed to callback is `CustomEvent` because `Slider` is 49 | /// undocumented See: 50 | #[prop_or_default] 51 | pub onchange: Callback, 52 | } 53 | 54 | impl Component for Slider { 55 | type Message = (); 56 | type Properties = SliderProps; 57 | 58 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 59 | // Slider::ensure_loaded(); 60 | Self { 61 | props, 62 | node_ref: NodeRef::default(), 63 | input_listener: None, 64 | change_listener: None, 65 | } 66 | } 67 | 68 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 69 | false 70 | } 71 | 72 | fn change(&mut self, props: Self::Properties) -> bool { 73 | if self.props != props { 74 | self.props = props; 75 | true 76 | } else { 77 | false 78 | } 79 | } 80 | 81 | fn view(&self) -> Html { 82 | // value=self.props.value 83 | // min=self.props.min 84 | // max=self.props.max 85 | // step=self.props.step 86 | // pin?=to_option(self.props.pin) 87 | // markers?=to_option(self.props.markers) 88 | // ref=self.node_ref.clone() 89 | 90 | html! { 91 |
    92 | 93 |
    94 |
    95 |
    96 |
    97 |
    98 |
    99 |
    100 |
    101 |
    102 |
    103 | } 104 | } 105 | 106 | fn rendered(&mut self, first_render: bool) { 107 | // if first_render { 108 | // let element = self.node_ref.cast::().unwrap(); 109 | 110 | // let oninput = self.props.oninput.clone(); 111 | // self.input_listener = Some(EventListener::new(&element, "input", move |event| { 112 | // oninput.emit(JsValue::from(event).unchecked_into::()) 113 | // })); 114 | 115 | // let onchange = self.props.onchange.clone(); 116 | // self.change_listener = Some(EventListener::new(&element, "change", move |event| { 117 | // onchange.emit(JsValue::from(event).unchecked_into::()) 118 | // })); 119 | // } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/top_app_bar.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | mod action_items; 5 | mod navigation_icon; 6 | mod title; 7 | 8 | pub use action_items::*; 9 | pub use navigation_icon::*; 10 | pub use title::*; 11 | 12 | use super::to_option; 13 | use gloo::events::EventListener; 14 | use wasm_bindgen::prelude::*; 15 | use web_sys::Element; 16 | use yew::prelude::*; 17 | 18 | /// The `top-app-bar` component 19 | /// 20 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar) 21 | pub struct TopAppBar { 22 | link: ComponentLink, 23 | props: TopAppBarProps, 24 | nav_listener: Option, 25 | } 26 | 27 | pub enum Msg { 28 | Nav, 29 | } 30 | 31 | /// Props for [`TopAppBar`] 32 | /// 33 | /// Documentation: 34 | /// 35 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar#propertiesattributes) 36 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/top-app-bar#events) 37 | #[derive(Clone, PartialEq, Properties)] 38 | pub struct TopAppBarProps { 39 | #[prop_or_default] 40 | pub children: Children, 41 | #[prop_or_default] 42 | pub center_title: bool, 43 | #[prop_or_default] 44 | pub dense: bool, 45 | #[prop_or_default] 46 | pub prominent: bool, 47 | /// Binds to `MDCTopAppBar:nav` 48 | /// 49 | /// See events docs to learn more. 50 | #[prop_or_default] 51 | pub onnavigation: Callback<()>, 52 | } 53 | 54 | impl Component for TopAppBar { 55 | type Message = Msg; 56 | type Properties = TopAppBarProps; 57 | 58 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 59 | // TopAppBar::ensure_loaded(); 60 | Self { 61 | link, 62 | props, 63 | nav_listener: None, 64 | } 65 | } 66 | 67 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 68 | match msg { 69 | Msg::Nav => { 70 | self.props.onnavigation.emit(()); 71 | } 72 | } 73 | false 74 | } 75 | 76 | fn change(&mut self, props: Self::Properties) -> bool { 77 | if self.props != props { 78 | self.props = props; 79 | true 80 | } else { 81 | false 82 | } 83 | } 84 | 85 | fn view(&self) -> Html { 86 | // centerTitle?=to_option(self.props.center_title) 87 | // dense?=to_option(self.props.dense) 88 | // prominent?=to_option(self.props.prominent) 89 | // ref=self.node_ref.clone() 90 | // > 91 | // { self.props.children.clone() } 92 | 93 | html! { 94 |
    95 |
    96 |
    97 | 98 | { "Page title" } 99 |
    100 | 105 |
    106 |
    107 | } 108 | } 109 | 110 | fn rendered(&mut self, first_render: bool) { 111 | // if first_render { 112 | // let callback = self.props.onnavigationiconclick.clone(); 113 | // let element = self.node_ref.cast::().unwrap(); 114 | 115 | // self.nav_listener = Some(EventListener::new( 116 | // &element, 117 | // "MDCTopAppBar:nav", 118 | // move |_| { 119 | // callback.emit(()); 120 | // }, 121 | // )); 122 | // } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/text_inputs/validity_state.rs: -------------------------------------------------------------------------------- 1 | use js_sys::Object; 2 | use wasm_bindgen::prelude::*; 3 | use wasm_bindgen::JsCast; 4 | 5 | // impl Default for ValidityStateJS { 6 | // fn default() -> Self { 7 | // Object::new().unchecked_into() 8 | // } 9 | // } 10 | 11 | /// Rust type for validity props 12 | pub struct ValidityState { 13 | bad_input: bool, 14 | custom_error: bool, 15 | pattern_mismatch: bool, 16 | range_overflow: bool, 17 | range_underflow: bool, 18 | too_long: bool, 19 | too_short: bool, 20 | type_mismatch: bool, 21 | valid: bool, 22 | value_missing: bool, 23 | } 24 | 25 | impl ValidityState { 26 | /// Creates a new `ValidityState`. 27 | /// 28 | /// All the fields except `valid` is set to false except `valid`, which is 29 | /// set to `true` 30 | pub fn new() -> Self { 31 | Self { 32 | bad_input: false, 33 | custom_error: false, 34 | pattern_mismatch: false, 35 | range_overflow: false, 36 | range_underflow: false, 37 | too_long: false, 38 | too_short: false, 39 | type_mismatch: false, 40 | valid: true, 41 | value_missing: false, 42 | } 43 | } 44 | 45 | pub fn bad_input(&self) -> bool { 46 | self.bad_input 47 | } 48 | pub fn custom_error(&self) -> bool { 49 | self.custom_error 50 | } 51 | pub fn pattern_mismatch(&self) -> bool { 52 | self.pattern_mismatch 53 | } 54 | pub fn range_overflow(&self) -> bool { 55 | self.range_overflow 56 | } 57 | pub fn range_underflow(&self) -> bool { 58 | self.range_underflow 59 | } 60 | pub fn too_long(&self) -> bool { 61 | self.too_long 62 | } 63 | pub fn too_short(&self) -> bool { 64 | self.too_short 65 | } 66 | pub fn type_mismatch(&self) -> bool { 67 | self.type_mismatch 68 | } 69 | pub fn valid(&self) -> bool { 70 | self.valid 71 | } 72 | pub fn value_missing(&self) -> bool { 73 | self.value_missing 74 | } 75 | 76 | pub fn set_bad_input(&mut self, value: bool) -> &mut Self { 77 | self.bad_input = value; 78 | self 79 | } 80 | pub fn set_custom_error(&mut self, value: bool) -> &mut Self { 81 | self.custom_error = value; 82 | self 83 | } 84 | pub fn set_pattern_mismatch(&mut self, value: bool) -> &mut Self { 85 | self.pattern_mismatch = value; 86 | self 87 | } 88 | pub fn set_range_overflow(&mut self, value: bool) -> &mut Self { 89 | self.range_overflow = value; 90 | self 91 | } 92 | pub fn set_range_underflow(&mut self, value: bool) -> &mut Self { 93 | self.range_underflow = value; 94 | self 95 | } 96 | pub fn set_too_long(&mut self, value: bool) -> &mut Self { 97 | self.too_long = value; 98 | self 99 | } 100 | pub fn set_too_short(&mut self, value: bool) -> &mut Self { 101 | self.too_short = value; 102 | self 103 | } 104 | pub fn set_type_mismatch(&mut self, value: bool) -> &mut Self { 105 | self.type_mismatch = value; 106 | self 107 | } 108 | pub fn set_valid(&mut self, value: bool) -> &mut Self { 109 | self.valid = value; 110 | self 111 | } 112 | pub fn set_value_missing(&mut self, value: bool) -> &mut Self { 113 | self.value_missing = value; 114 | self 115 | } 116 | } 117 | 118 | // impl From for ValidityStateJS { 119 | // fn from(validity_state: ValidityState) -> Self { 120 | // let validity_state_js = ValidityStateJS::default(); 121 | // validity_state_js.set_bad_input(validity_state.bad_input()); 122 | // validity_state_js.set_custom_error(validity_state.custom_error()); 123 | // validity_state_js.set_pattern_mismatch(validity_state.pattern_mismatch()); 124 | // validity_state_js.set_range_overflow(validity_state.range_overflow()); 125 | // validity_state_js.set_range_underflow(validity_state.range_underflow()); 126 | // validity_state_js.set_too_long(validity_state.too_long()); 127 | // validity_state_js.set_too_short(validity_state.too_short()); 128 | // validity_state_js.set_type_mismatch(validity_state.type_mismatch()); 129 | // validity_state_js.set_valid(validity_state.valid()); 130 | // validity_state_js.set_value_missing(validity_state.value_missing()); 131 | // validity_state_js 132 | // } 133 | // } 134 | 135 | impl Default for ValidityState { 136 | fn default() -> Self { 137 | Self::new() 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/tabs/tab_bar.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use crate::event_details_into; 5 | use gloo::events::EventListener; 6 | use js_sys::Object; 7 | use wasm_bindgen::prelude::*; 8 | use web_sys::Element; 9 | use yew::prelude::*; 10 | 11 | 12 | /// The `tab-bar` component 13 | /// 14 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/tab-bar) 15 | pub struct TabBar { 16 | props: TabBarProps, 17 | node_ref: NodeRef, 18 | activated_listener: Option, 19 | } 20 | 21 | /// Props for `TabBar`. 22 | /// 23 | /// Documentation [properties](https://github.com/material-components/material-components-web-components/tree/master/packages/tab-bar#propertiesattributes) 24 | /// and [events](https://github.com/material-components/material-components-web-components/tree/master/packages/tab-bar#events) 25 | #[derive(Debug, Properties, Clone)] 26 | pub struct TabBarProps { 27 | #[prop_or_default] 28 | pub active_index: u32, 29 | /// Binds to `MDCTabBar:activated` event on `tab` 30 | /// 31 | /// See events docs to learn more. 32 | #[prop_or_default] 33 | pub onactivated: Callback, 34 | #[prop_or_default] 35 | pub children: Children, 36 | } 37 | 38 | impl Component for TabBar { 39 | type Message = (); 40 | type Properties = TabBarProps; 41 | 42 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 43 | // TabBar::ensure_loaded(); 44 | Self { 45 | props, 46 | node_ref: NodeRef::default(), 47 | activated_listener: None, 48 | } 49 | } 50 | 51 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 52 | false 53 | } 54 | 55 | fn change(&mut self, props: Self::Properties) -> bool { 56 | self.props = props; 57 | true 58 | } 59 | 60 | fn view(&self) -> Html { 61 | // activeIndex=self.props.active_index 62 | // ref=self.node_ref.clone() 63 | // >{ self.props.children.clone() } 64 | 65 | html! { 66 |
    67 |
    68 |
    69 |
    70 | 80 | 90 |
    91 |
    92 |
    93 |
    94 | } 95 | } 96 | 97 | fn rendered(&mut self, first_render: bool) { 98 | // if first_render { 99 | // let element = self.node_ref.cast::().unwrap(); 100 | 101 | // let on_activated = self.props.onactivated.clone(); 102 | // self.activated_listener = Some(EventListener::new( 103 | // &element, 104 | // "MDCTabBar:activated", 105 | // move |event| { 106 | // let detail = event_details_into::(event); 107 | // on_activated.emit(detail.index()); 108 | // }, 109 | // )); 110 | // } 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/gaugechart.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use animate::Canvas; 7 | use charts::{Chart, GaugeChart as GaugeChartComponent, GaugeChartOptions}; 8 | use dataflow::*; 9 | use wasm_bindgen::prelude::*; 10 | use wasm_bindgen::JsCast; 11 | use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement}; 12 | use yew::prelude::*; 13 | 14 | pub struct GaugeChart { 15 | props: GaugeChartProps, 16 | link: ComponentLink, 17 | node_ref: NodeRef, 18 | } 19 | 20 | pub enum Msg { 21 | Clicked, 22 | } 23 | 24 | /// Props for [`GaugeChart`] 25 | /// 26 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 27 | #[derive(Clone, PartialEq, Properties)] 28 | pub struct GaugeChartProps { 29 | pub label: String, 30 | #[prop_or_default] 31 | pub icon: Option, 32 | #[prop_or_default] 33 | pub raised: bool, 34 | #[prop_or_default] 35 | pub unelevated: bool, 36 | #[prop_or_default] 37 | pub outlined: bool, 38 | #[prop_or_default] 39 | pub dense: bool, 40 | #[prop_or_default] 41 | pub disabled: bool, 42 | #[prop_or_default] 43 | pub trailing_icon: bool, 44 | #[prop_or_default] 45 | pub onclick: Callback<()>, 46 | } 47 | 48 | // label=props.label 49 | // icon?=props.icon.as_ref() 50 | // raised?=to_option(props.raised) 51 | // unelevated?=to_option(props.unelevated) 52 | // outlined?=to_option(props.outlined) 53 | // dense?=to_option(props.dense) 54 | // trailingIcon?=to_option(props.trailing_icon) 55 | // disabled=props.disabled 56 | 57 | impl Component for GaugeChart { 58 | type Message = Msg; 59 | type Properties = GaugeChartProps; 60 | 61 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 62 | Self { 63 | link, 64 | props, 65 | node_ref: NodeRef::default(), 66 | } 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Clicked => { 72 | self.props.onclick.emit(()); 73 | } 74 | } 75 | false 76 | } 77 | 78 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 79 | if self.props != props { 80 | self.props = props; 81 | true 82 | } else { 83 | false 84 | } 85 | } 86 | 87 | fn view(&self) -> Html { 88 | html! { 89 | 90 | } 91 | } 92 | 93 | fn rendered(&mut self, first_render: bool) { 94 | let canvas = self.node_ref.cast::().unwrap(); 95 | let cr: CanvasRenderingContext2d = canvas 96 | .get_context("2d") 97 | .unwrap() 98 | .unwrap() 99 | .dyn_into() 100 | .unwrap(); 101 | 102 | let stream = create_stream(); 103 | 104 | let mut options: GaugeChartOptions = Default::default(); 105 | options.labels = Some(Default::default()); 106 | options.title.text = Some("Gauge Chart Demo"); 107 | 108 | let mut chart = GaugeChartComponent::new(options); 109 | chart.set_stream(stream); 110 | 111 | chart.resize(800., 400.); 112 | 113 | let ctx = Canvas::new(&cr); // overhead 114 | chart.draw(&ctx); 115 | // let element = self.node_ref.cast::().unwrap(); 116 | // if self.props.checked { 117 | // element.set_checked(self.props.checked); 118 | // } 119 | // if first_render { 120 | // let callback = self.props.onchange.clone(); 121 | // let target = self.node_ref.cast::().unwrap(); 122 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 123 | // callback.emit(element.checked()); 124 | // })); 125 | // } 126 | } 127 | } 128 | 129 | fn create_stream() -> DataStream<'static, &'static str, i32> { 130 | let metadata = vec![ 131 | Channel { 132 | name: "Browser", 133 | tag: 0, 134 | visible: true, 135 | }, 136 | Channel { 137 | name: "Share", 138 | tag: 1, 139 | visible: true, 140 | }, 141 | ]; 142 | 143 | let mut frames = vec![DataFrame { 144 | metric: "Memory", 145 | data: [(0, 25)].iter().cloned().collect(), 146 | }]; 147 | 148 | frames.push(DataFrame { 149 | metric: "CPU", 150 | data: [(0, 75)].iter().cloned().collect(), 151 | }); 152 | 153 | frames.push(DataFrame { 154 | metric: "Disk", 155 | data: [(0, 40)].iter().cloned().collect(), 156 | }); 157 | 158 | DataStream::new(metadata, frames) 159 | } 160 | -------------------------------------------------------------------------------- /src/datatable.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use wasm_bindgen::prelude::*; 7 | use yew::prelude::*; 8 | 9 | pub struct DataTable { 10 | link: ComponentLink, 11 | label: String, 12 | // onsignal: Callback<()>, 13 | } 14 | 15 | pub enum Msg { 16 | Clicked, 17 | } 18 | 19 | /// Props for [`DataTable`] 20 | /// 21 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 22 | #[derive(Clone, PartialEq, Properties)] 23 | pub struct DataTableProps { 24 | pub label: String, 25 | #[prop_or_default] 26 | pub icon: Option, 27 | #[prop_or_default] 28 | pub raised: bool, 29 | #[prop_or_default] 30 | pub unelevated: bool, 31 | #[prop_or_default] 32 | pub outlined: bool, 33 | #[prop_or_default] 34 | pub dense: bool, 35 | #[prop_or_default] 36 | pub disabled: bool, 37 | #[prop_or_default] 38 | pub trailing_icon: bool, 39 | // #[prop_or_default] 40 | // pub onsignal: Callback<()>, 41 | } 42 | 43 | // label=props.label 44 | // icon?=props.icon.as_ref() 45 | // raised?=to_option(props.raised) 46 | // unelevated?=to_option(props.unelevated) 47 | // outlined?=to_option(props.outlined) 48 | // dense?=to_option(props.dense) 49 | // trailingIcon?=to_option(props.trailing_icon) 50 | // disabled=props.disabled 51 | 52 | impl Component for DataTable { 53 | type Message = Msg; 54 | type Properties = DataTableProps; 55 | 56 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 57 | Self { 58 | link, 59 | label: props.label, 60 | // onsignal: props.onsignal, 61 | } 62 | } 63 | 64 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 65 | match msg { 66 | Msg::Clicked => { 67 | // self.onsignal.emit(()); 68 | } 69 | } 70 | false 71 | } 72 | 73 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 74 | self.label = props.label; 75 | // self.onsignal = props.onsignal; 76 | true 77 | } 78 | 79 | fn view(&self) -> Html { 80 | html! { 81 |
    82 |
    83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
    { "Dessert" }{ "Carbs (g)" }{ "Protein (g)" }{ "Comments" }
    { "Frozen yogurt" }{ "24" }{ "4.0" }{ "Super tasty" }
    { "Ice cream sandwich" }{ "37" }{ "4.33333333333" }{ "I like ice cream more" }
    { "Eclair" }{ "24" }{ "6.0" }{ "New filing flavor" }
    113 |
    114 |
    115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/piechart.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use animate::Canvas; 7 | use charts::{Chart, PieChart as PieChartComponent, PieChartOptions}; 8 | use dataflow::*; 9 | use wasm_bindgen::prelude::*; 10 | use wasm_bindgen::JsCast; 11 | use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement}; 12 | use yew::prelude::*; 13 | 14 | pub struct PieChart { 15 | props: PieChartProps, 16 | link: ComponentLink, 17 | node_ref: NodeRef, 18 | } 19 | 20 | pub enum Msg { 21 | Clicked, 22 | } 23 | 24 | /// Props for [`PieChart`] 25 | /// 26 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 27 | #[derive(Clone, PartialEq, Properties)] 28 | pub struct PieChartProps { 29 | pub label: String, 30 | #[prop_or_default] 31 | pub icon: Option, 32 | #[prop_or_default] 33 | pub raised: bool, 34 | #[prop_or_default] 35 | pub unelevated: bool, 36 | #[prop_or_default] 37 | pub outlined: bool, 38 | #[prop_or_default] 39 | pub dense: bool, 40 | #[prop_or_default] 41 | pub disabled: bool, 42 | #[prop_or_default] 43 | pub trailing_icon: bool, 44 | #[prop_or_default] 45 | pub onclick: Callback<()>, 46 | } 47 | 48 | // label=props.label 49 | // icon?=props.icon.as_ref() 50 | // raised?=to_option(props.raised) 51 | // unelevated?=to_option(props.unelevated) 52 | // outlined?=to_option(props.outlined) 53 | // dense?=to_option(props.dense) 54 | // trailingIcon?=to_option(props.trailing_icon) 55 | // disabled=props.disabled 56 | 57 | impl Component for PieChart { 58 | type Message = Msg; 59 | type Properties = PieChartProps; 60 | 61 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 62 | Self { 63 | link, 64 | props, 65 | node_ref: NodeRef::default(), 66 | } 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Clicked => { 72 | self.props.onclick.emit(()); 73 | } 74 | } 75 | false 76 | } 77 | 78 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 79 | if self.props != props { 80 | self.props = props; 81 | true 82 | } else { 83 | false 84 | } 85 | } 86 | 87 | fn view(&self) -> Html { 88 | html! { 89 | 90 | } 91 | } 92 | 93 | fn rendered(&mut self, first_render: bool) { 94 | let canvas = self.node_ref.cast::().unwrap(); 95 | let cr: CanvasRenderingContext2d = canvas 96 | .get_context("2d") 97 | .unwrap() 98 | .unwrap() 99 | .dyn_into() 100 | .unwrap(); 101 | 102 | let stream = create_stream(); 103 | 104 | let mut options: PieChartOptions = Default::default(); 105 | 106 | options.channel.labels.enabled = true; 107 | options.channel.counterclockwise = true; 108 | options.channel.labels.enabled = true; 109 | options.channel.start_angle = 90. + 10. * 360.; 110 | options.pie_hole = 0.5; 111 | options.title.text = Some("Pie Chart Demo"); 112 | 113 | let mut chart = PieChartComponent::new(options); 114 | chart.set_stream(stream); 115 | 116 | chart.resize(800., 400.); 117 | 118 | let ctx = Canvas::new(&cr); // overhead 119 | chart.draw(&ctx); 120 | // let element = self.node_ref.cast::().unwrap(); 121 | // if self.props.checked { 122 | // element.set_checked(self.props.checked); 123 | // } 124 | // if first_render { 125 | // let callback = self.props.onchange.clone(); 126 | // let target = self.node_ref.cast::().unwrap(); 127 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 128 | // callback.emit(element.checked()); 129 | // })); 130 | // } 131 | } 132 | } 133 | 134 | fn create_stream() -> DataStream<'static, &'static str, i32> { 135 | let metadata = vec![ 136 | Channel { 137 | name: "Browser", 138 | tag: 0, 139 | visible: true, 140 | }, 141 | Channel { 142 | name: "Share", 143 | tag: 1, 144 | visible: true, 145 | }, 146 | ]; 147 | 148 | let mut frames = vec![DataFrame { 149 | metric: "Chrome", 150 | data: [(0, 35)].iter().cloned().collect(), 151 | }]; 152 | 153 | frames.push(DataFrame { 154 | metric: "Firefox", 155 | data: [(0, 20)].iter().cloned().collect(), 156 | }); 157 | 158 | frames.push(DataFrame { 159 | metric: "IE", 160 | data: [(0, 30)].iter().cloned().collect(), 161 | }); 162 | 163 | frames.push(DataFrame { 164 | metric: "Opera", 165 | data: [(0, 5)].iter().cloned().collect(), 166 | }); 167 | 168 | frames.push(DataFrame { 169 | metric: "Safari", 170 | data: [(0, 8)].iter().cloned().collect(), 171 | }); 172 | 173 | frames.push(DataFrame { 174 | metric: "Other", 175 | data: [(0, 2)].iter().cloned().collect(), 176 | }); 177 | 178 | DataStream::new(metadata, frames) 179 | } 180 | -------------------------------------------------------------------------------- /src/radarchart.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use animate::Canvas; 7 | use charts::{Chart, RadarChart as RadarChartComponent, RadarChartOptions}; 8 | use dataflow::*; 9 | use wasm_bindgen::prelude::*; 10 | use wasm_bindgen::JsCast; 11 | use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement}; 12 | use yew::prelude::*; 13 | 14 | pub struct RadarChart { 15 | props: RadarChartProps, 16 | link: ComponentLink, 17 | node_ref: NodeRef, 18 | } 19 | 20 | pub enum Msg { 21 | Clicked, 22 | } 23 | 24 | /// Props for [`RadarChart`] 25 | /// 26 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 27 | #[derive(Clone, PartialEq, Properties)] 28 | pub struct RadarChartProps { 29 | pub label: String, 30 | #[prop_or_default] 31 | pub icon: Option, 32 | #[prop_or_default] 33 | pub raised: bool, 34 | #[prop_or_default] 35 | pub unelevated: bool, 36 | #[prop_or_default] 37 | pub outlined: bool, 38 | #[prop_or_default] 39 | pub dense: bool, 40 | #[prop_or_default] 41 | pub disabled: bool, 42 | #[prop_or_default] 43 | pub trailing_icon: bool, 44 | #[prop_or_default] 45 | pub onclick: Callback<()>, 46 | } 47 | 48 | // label=props.label 49 | // icon?=props.icon.as_ref() 50 | // raised?=to_option(props.raised) 51 | // unelevated?=to_option(props.unelevated) 52 | // outlined?=to_option(props.outlined) 53 | // dense?=to_option(props.dense) 54 | // trailingIcon?=to_option(props.trailing_icon) 55 | // disabled=props.disabled 56 | 57 | impl Component for RadarChart { 58 | type Message = Msg; 59 | type Properties = RadarChartProps; 60 | 61 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 62 | Self { 63 | link, 64 | props, 65 | node_ref: NodeRef::default(), 66 | } 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Clicked => { 72 | self.props.onclick.emit(()); 73 | } 74 | } 75 | false 76 | } 77 | 78 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 79 | if self.props != props { 80 | self.props = props; 81 | true 82 | } else { 83 | false 84 | } 85 | } 86 | 87 | fn view(&self) -> Html { 88 | html! { 89 | 90 | } 91 | } 92 | 93 | fn rendered(&mut self, first_render: bool) { 94 | let canvas = self.node_ref.cast::().unwrap(); 95 | let cr: CanvasRenderingContext2d = canvas 96 | .get_context("2d") 97 | .unwrap() 98 | .unwrap() 99 | .dyn_into() 100 | .unwrap(); 101 | 102 | let stream = create_stream(); 103 | 104 | let mut options: RadarChartOptions = Default::default(); 105 | options.channel.labels = Some(Default::default()); 106 | options.title.text = Some("Radar Chart Demo"); 107 | 108 | let mut chart = RadarChartComponent::new(options); 109 | chart.set_stream(stream); 110 | 111 | chart.resize(800., 400.); 112 | 113 | let ctx = Canvas::new(&cr); // overhead 114 | chart.draw(&ctx); 115 | // let element = self.node_ref.cast::().unwrap(); 116 | // if self.props.checked { 117 | // element.set_checked(self.props.checked); 118 | // } 119 | // if first_render { 120 | // let callback = self.props.onchange.clone(); 121 | // let target = self.node_ref.cast::().unwrap(); 122 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 123 | // callback.emit(element.checked()); 124 | // })); 125 | // } 126 | } 127 | } 128 | 129 | fn create_stream() -> DataStream<'static, &'static str, i32> { 130 | let metadata = vec![ 131 | Channel { 132 | name: "Series 1", 133 | tag: 0, 134 | visible: true, 135 | }, 136 | Channel { 137 | name: "New Series", 138 | tag: 1, 139 | visible: true, 140 | }, 141 | ]; 142 | 143 | // Zero stream tag is allways metric 144 | let mut frames = vec![DataFrame { 145 | metric: "Monday", 146 | data: [(0, 11), (1, 16)].iter().cloned().collect(), 147 | }]; 148 | 149 | frames.push(DataFrame { 150 | metric: "Tuesday", 151 | data: [(0, 19), (1, 15)].iter().cloned().collect(), 152 | }); 153 | 154 | frames.push(DataFrame { 155 | metric: "Wednesday", 156 | data: [(0, 7), (1, 14)].iter().cloned().collect(), 157 | }); 158 | 159 | frames.push(DataFrame { 160 | metric: "Thursday", 161 | data: [(0, 17), (1, 12)].iter().cloned().collect(), 162 | }); 163 | 164 | frames.push(DataFrame { 165 | metric: "Friday", 166 | data: [(0, 17), (1, 10)].iter().cloned().collect(), 167 | }); 168 | 169 | frames.push(DataFrame { 170 | metric: "Saturday", 171 | data: [(0, 18), (1, 9)].iter().cloned().collect(), 172 | }); 173 | 174 | frames.push(DataFrame { 175 | metric: "Sunday", 176 | data: [(0, 15), (1, 14)].iter().cloned().collect(), 177 | }); 178 | 179 | DataStream::new(metadata, frames) 180 | } -------------------------------------------------------------------------------- /src/linechart.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use animate::Canvas; 7 | use charts::{Chart, LineChart as LineChartComponent, LineChartOptions}; 8 | use dataflow::*; 9 | use wasm_bindgen::prelude::*; 10 | use wasm_bindgen::JsCast; 11 | use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement}; 12 | use yew::prelude::*; 13 | 14 | pub struct LineChart { 15 | props: LineChartProps, 16 | link: ComponentLink, 17 | node_ref: NodeRef, 18 | } 19 | 20 | pub enum Msg { 21 | Clicked, 22 | } 23 | 24 | /// Props for [`LineChart`] 25 | /// 26 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 27 | #[derive(Clone, PartialEq, Properties)] 28 | pub struct LineChartProps { 29 | pub label: String, 30 | #[prop_or_default] 31 | pub icon: Option, 32 | #[prop_or_default] 33 | pub raised: bool, 34 | #[prop_or_default] 35 | pub unelevated: bool, 36 | #[prop_or_default] 37 | pub outlined: bool, 38 | #[prop_or_default] 39 | pub dense: bool, 40 | #[prop_or_default] 41 | pub disabled: bool, 42 | #[prop_or_default] 43 | pub trailing_icon: bool, 44 | #[prop_or_default] 45 | pub onclick: Callback<()>, 46 | } 47 | 48 | // label=props.label 49 | // icon?=props.icon.as_ref() 50 | // raised?=to_option(props.raised) 51 | // unelevated?=to_option(props.unelevated) 52 | // outlined?=to_option(props.outlined) 53 | // dense?=to_option(props.dense) 54 | // trailingIcon?=to_option(props.trailing_icon) 55 | // disabled=props.disabled 56 | 57 | impl Component for LineChart { 58 | type Message = Msg; 59 | type Properties = LineChartProps; 60 | 61 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 62 | Self { 63 | link, 64 | props, 65 | node_ref: NodeRef::default(), 66 | } 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Clicked => { 72 | self.props.onclick.emit(()); 73 | } 74 | } 75 | false 76 | } 77 | 78 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 79 | if self.props != props { 80 | self.props = props; 81 | true 82 | } else { 83 | false 84 | } 85 | } 86 | 87 | fn view(&self) -> Html { 88 | html! { 89 | 90 | } 91 | } 92 | 93 | fn rendered(&mut self, first_render: bool) { 94 | let canvas = self.node_ref.cast::().unwrap(); 95 | let cr: CanvasRenderingContext2d = canvas 96 | .get_context("2d") 97 | .unwrap() 98 | .unwrap() 99 | .dyn_into() 100 | .unwrap(); 101 | 102 | let stream = create_stream(); 103 | 104 | let mut options: LineChartOptions = Default::default(); 105 | options.channel.labels = Some(Default::default()); 106 | options.channel.fill_opacity = 0.25; 107 | options.yaxis.min_interval = Some(2.); 108 | options.title.text = Some("Line Chart Demo"); 109 | 110 | let mut chart = LineChartComponent::new(options); 111 | chart.set_stream(stream); 112 | 113 | chart.resize(800., 400.); 114 | 115 | let ctx = Canvas::new(&cr); // overhead 116 | chart.draw(&ctx); 117 | // let element = self.node_ref.cast::().unwrap(); 118 | // if self.props.checked { 119 | // element.set_checked(self.props.checked); 120 | // } 121 | // if first_render { 122 | // let callback = self.props.onchange.clone(); 123 | // let target = self.node_ref.cast::().unwrap(); 124 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 125 | // callback.emit(element.checked()); 126 | // })); 127 | // } 128 | } 129 | } 130 | 131 | fn create_stream() -> DataStream<'static, &'static str, i32> { 132 | let metadata = vec![ 133 | Channel { 134 | name: "Series 1", 135 | tag: 0, 136 | visible: true, 137 | }, 138 | Channel { 139 | name: "Series 2", 140 | tag: 1, 141 | visible: true, 142 | }, 143 | Channel { 144 | name: "Series 3", 145 | tag: 2, 146 | visible: true, 147 | }, 148 | ]; 149 | 150 | // Zero stream tag is allways metric 151 | let mut frames = vec![DataFrame { 152 | metric: "Monday", 153 | data: [(0, 1), (1, 3), (2, 5)].iter().cloned().collect(), 154 | }]; 155 | 156 | frames.push(DataFrame { 157 | metric: "Tuesday", 158 | data: [(0, 3), (1, 4), (2, 6)].iter().cloned().collect(), 159 | }); 160 | 161 | frames.push(DataFrame { 162 | metric: "Wednesday", 163 | data: [(0, 4), (1, 3), (2, 1)].iter().cloned().collect(), 164 | }); 165 | 166 | frames.push(DataFrame { 167 | metric: "Thursday", 168 | data: [(1, 5), (2, 1)].iter().cloned().collect(), 169 | }); 170 | 171 | frames.push(DataFrame { 172 | metric: "Friday", 173 | data: [(0, 3), (1, 4), (2, 2)].iter().cloned().collect(), 174 | }); 175 | 176 | frames.push(DataFrame { 177 | metric: "Saturday", 178 | data: [(0, 5), (1, 10), (2, 4)].iter().cloned().collect(), 179 | }); 180 | 181 | frames.push(DataFrame { 182 | metric: "Sunday", 183 | data: [(0, 4), (1, 12), (2, 8)].iter().cloned().collect(), 184 | }); 185 | 186 | DataStream::new(metadata, frames) 187 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | * Accepting and using the preferred gender pronouns of all people who have specified them involved in the project. 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement by emailing 64 | `dudochkin.victor@gmail.com`. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 121 | 122 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 123 | enforcement ladder](https://github.com/mozilla/diversity). 124 | 125 | [homepage]: https://www.contributor-covenant.org 126 | 127 | For answers to common questions about this code of conduct, see the FAQ at 128 | https://www.contributor-covenant.org/faq. Translations are available at 129 | https://www.contributor-covenant.org/translations. -------------------------------------------------------------------------------- /src/barchart.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::to_option; 6 | use animate::Canvas; 7 | use charts::{BarChart as BarChartComponent, BarChartOptions, Chart}; 8 | use dataflow::*; 9 | use wasm_bindgen::prelude::*; 10 | use wasm_bindgen::JsCast; 11 | use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement}; 12 | use yew::prelude::*; 13 | 14 | pub struct BarChart { 15 | props: BarChartProps, 16 | link: ComponentLink, 17 | node_ref: NodeRef, 18 | } 19 | 20 | pub enum Msg { 21 | Clicked, 22 | } 23 | 24 | /// Props for [`BarChart`] 25 | /// 26 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 27 | #[derive(Clone, PartialEq, Properties)] 28 | pub struct BarChartProps { 29 | pub label: String, 30 | #[prop_or_default] 31 | pub icon: Option, 32 | #[prop_or_default] 33 | pub raised: bool, 34 | #[prop_or_default] 35 | pub unelevated: bool, 36 | #[prop_or_default] 37 | pub outlined: bool, 38 | #[prop_or_default] 39 | pub dense: bool, 40 | #[prop_or_default] 41 | pub disabled: bool, 42 | #[prop_or_default] 43 | pub trailing_icon: bool, 44 | #[prop_or_default] 45 | pub onclick: Callback<()>, 46 | } 47 | 48 | // label=props.label 49 | // icon?=props.icon.as_ref() 50 | // raised?=to_option(props.raised) 51 | // unelevated?=to_option(props.unelevated) 52 | // outlined?=to_option(props.outlined) 53 | // dense?=to_option(props.dense) 54 | // trailingIcon?=to_option(props.trailing_icon) 55 | // disabled=props.disabled 56 | 57 | impl Component for BarChart { 58 | type Message = Msg; 59 | type Properties = BarChartProps; 60 | 61 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 62 | Self { 63 | link, 64 | props, 65 | node_ref: NodeRef::default(), 66 | } 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Clicked => { 72 | self.props.onclick.emit(()); 73 | } 74 | } 75 | false 76 | } 77 | 78 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 79 | if self.props != props { 80 | self.props = props; 81 | true 82 | } else { 83 | false 84 | } 85 | } 86 | 87 | fn view(&self) -> Html { 88 | html! { 89 | 90 | } 91 | } 92 | 93 | fn rendered(&mut self, first_render: bool) { 94 | let canvas = self.node_ref.cast::().unwrap(); 95 | let cr: CanvasRenderingContext2d = canvas 96 | .get_context("2d") 97 | .unwrap() 98 | .unwrap() 99 | .dyn_into() 100 | .unwrap(); 101 | 102 | let stream = create_stream(); 103 | 104 | let mut options: BarChartOptions = Default::default(); 105 | options.channel.labels = Some(Default::default()); 106 | // options.xaxis.crosshair = Some(Default::default()); // enable crosshair 107 | options.xaxis.labels.max_rotation = 90; 108 | options.xaxis.labels.min_rotation = 0; 109 | options.yaxis.min_value = Some(0); 110 | options.yaxis.min_interval = Some(2.); 111 | 112 | let mut chart = BarChartComponent::new(options); 113 | chart.set_stream(stream); 114 | 115 | chart.resize(800., 400.); 116 | 117 | let ctx = Canvas::new(&cr); // overhead 118 | chart.draw(&ctx); 119 | 120 | // let element = self.node_ref.cast::().unwrap(); 121 | // if self.props.checked { 122 | // element.set_checked(self.props.checked); 123 | // } 124 | // if first_render { 125 | // let callback = self.props.onchange.clone(); 126 | // let target = self.node_ref.cast::().unwrap(); 127 | // self.change_listener = Some(EventListener::new(&target, "change", move |_| { 128 | // callback.emit(element.checked()); 129 | // })); 130 | // } 131 | } 132 | } 133 | 134 | fn create_stream() -> DataStream<'static, &'static str, i32> { 135 | let metadata = vec![ 136 | Channel { 137 | name: "Series 1", 138 | tag: 0, 139 | visible: true, 140 | }, 141 | Channel { 142 | name: "Series 2", 143 | tag: 1, 144 | visible: true, 145 | }, 146 | Channel { 147 | name: "Series 3", 148 | tag: 2, 149 | visible: true, 150 | }, 151 | ]; 152 | 153 | // Zero stream tag is allways metric 154 | let mut frames = vec![DataFrame { 155 | metric: "Monday", 156 | data: [(0, 1), (1, 3), (2, 5)].iter().cloned().collect(), 157 | }]; 158 | 159 | frames.push(DataFrame { 160 | metric: "Tuesday", 161 | data: [(0, 3), (1, 4), (2, 6)].iter().cloned().collect(), 162 | }); 163 | 164 | frames.push(DataFrame { 165 | metric: "Wednesday", 166 | data: [(0, 4), (1, 3), (2, 1)].iter().cloned().collect(), 167 | }); 168 | 169 | // let skip one stream flow 170 | frames.push(DataFrame { 171 | metric: "Thursday", 172 | data: [(1, 5), (2, 1)].iter().cloned().collect(), 173 | }); 174 | 175 | frames.push(DataFrame { 176 | metric: "Friday", 177 | data: [(0, 3), (1, 4), (2, 2)].iter().cloned().collect(), 178 | }); 179 | 180 | frames.push(DataFrame { 181 | metric: "Saturday", 182 | data: [(0, 5), (1, 10), (2, 4)].iter().cloned().collect(), 183 | }); 184 | 185 | frames.push(DataFrame { 186 | metric: "Sunday", 187 | data: [(0, 4), (1, 12), (2, 8)].iter().cloned().collect(), 188 | }); 189 | 190 | DataStream::new(metadata, frames) 191 | } -------------------------------------------------------------------------------- /src/list.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | mod list_item; 5 | pub use list_item::*; 6 | 7 | mod check_list_item; 8 | pub use check_list_item::*; 9 | 10 | mod radio_list_item; 11 | pub use radio_list_item::*; 12 | 13 | mod list_index; 14 | pub use list_index::ListIndex; 15 | 16 | mod selected_detail; 17 | pub use selected_detail::{IndexDiff, SelectedDetail}; 18 | 19 | mod action_detail; 20 | pub use action_detail::ActionDetail; 21 | 22 | mod request_selected; 23 | pub use request_selected::{RequestSelectedDetail, RequestSelectedSource}; 24 | 25 | mod graphic_type; 26 | pub use graphic_type::GraphicType; 27 | 28 | use super::{event_into_details, to_option, WeakComponentLink}; 29 | use gloo::events::EventListener; 30 | use wasm_bindgen::prelude::*; 31 | use web_sys::Node; 32 | use yew::prelude::*; 33 | 34 | /// The `list` component 35 | /// 36 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/list) 37 | pub struct List { 38 | props: ListProps, 39 | node_ref: NodeRef, 40 | action_listener: Option, 41 | selected_listener: Option, 42 | } 43 | 44 | /// Props for [`List`] 45 | /// 46 | /// Documentation: 47 | /// 48 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-1) 49 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/list#mwc-list-2) 50 | #[derive(Clone, PartialEq, Properties)] 51 | pub struct ListProps { 52 | #[prop_or_default] 53 | pub activatable: bool, 54 | #[prop_or_default] 55 | pub root_tabbable: bool, 56 | #[prop_or_default] 57 | pub multi: bool, 58 | #[prop_or_default] 59 | pub wrap_focus: bool, 60 | #[prop_or_default] 61 | pub item_roles: Option, 62 | #[prop_or_default] 63 | pub inner_role: Option, 64 | #[prop_or_default] 65 | pub noninteractive: bool, 66 | /// Binds to `action` event on `list` 67 | #[prop_or_default] 68 | pub onaction: Callback, 69 | /// Binds to `selected` event `list` 70 | #[prop_or_default] 71 | pub onselected: Callback, 72 | /// [`WeakComponentLink`] for `List` which provides the following methods 73 | /// - ```toggle(&self, index: usize, force: bool)``` 74 | /// - ```get_focused_item_index(&self) -> usize``` 75 | /// - ```focus_item_at_index(&self, index: usize)``` 76 | /// 77 | /// See [`WeakComponentLink`] documentation for more information 78 | #[prop_or_default] 79 | pub list_link: WeakComponentLink, 80 | #[prop_or_default] 81 | pub children: Children, 82 | } 83 | 84 | impl Component for List { 85 | type Message = (); 86 | type Properties = ListProps; 87 | 88 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 89 | // props.list_link.borrow_mut().replace(link); 90 | // List::ensure_loaded(); 91 | Self { 92 | props, 93 | node_ref: NodeRef::default(), 94 | action_listener: None, 95 | selected_listener: None, 96 | } 97 | } 98 | 99 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 100 | false 101 | } 102 | 103 | fn change(&mut self, props: Self::Properties) -> bool { 104 | if self.props != props { 105 | self.props = props; 106 | true 107 | } else { 108 | false 109 | } 110 | } 111 | 112 | fn view(&self) -> Html { 113 | // activatable?=to_option(self.props.activatable) 114 | // rootTabbable?=to_option(self.props.root_tabbable) 115 | // multi?=to_option(self.props.multi) 116 | // wrapFocus?=to_option(self.props.wrap_focus) 117 | // itemRoles=self.props.item_roles.as_ref().unwrap_or(&"null".to_string()) 118 | // innerRole=self.props.inner_role.as_ref().unwrap_or(&"null".to_string()) 119 | // noninteractive?=to_option(self.props.noninteractive) 120 | // ref=self.node_ref.clone() 121 | // { self.props.children.clone() } 122 | 123 | html! { 124 |
      125 | { self.view_items() } 126 |
    127 | } 128 | } 129 | 130 | fn rendered(&mut self, first_render: bool) { 131 | // if first_render { 132 | // let list = self.node_ref.cast::().unwrap(); 133 | 134 | // let onselected = self.props.onselected.clone(); 135 | // self.selected_listener = Some(EventListener::new(&list, "selected", move |event| { 136 | // let val = SelectedDetail::from(event_into_details(event)); 137 | // onselected.emit(val); 138 | // })); 139 | 140 | // let onaction = self.props.onaction.clone(); 141 | // self.action_listener = Some(EventListener::new(&list.clone(), "action", move |_| { 142 | // let val: JsValue = list.index(); 143 | // let index = ListIndex::from(val); 144 | // onaction.emit(index); 145 | // })); 146 | // } 147 | } 148 | } 149 | 150 | impl List { 151 | fn view_items(&self) -> Html { 152 | html! {{ 153 | for self.props.children.iter().enumerate().map(|(i, mut c)| { 154 | c 155 | }) 156 | }} 157 | } 158 | } 159 | 160 | impl WeakComponentLink { 161 | /// Binds to `toggle` method. 162 | /// 163 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 164 | pub fn toggle(&self, index: usize, force: bool) { 165 | // let list = (*self.borrow().as_ref().unwrap().get_component().unwrap()) 166 | // .node_ref 167 | // .cast::() 168 | // .unwrap(); 169 | // list.toggle(index, force) 170 | } 171 | 172 | /// Binds to `getFocusedItemIndex` method. 173 | /// 174 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 175 | pub fn get_focused_item_index(&self) -> usize { 176 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 177 | // .node_ref 178 | // .cast::() 179 | // .unwrap() 180 | // .get_focused_item_index() 181 | unimplemented!() 182 | } 183 | 184 | /// Binds to `focusItemAtIndex` method. 185 | /// 186 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 187 | pub fn focus_item_at_index(&self, index: usize) { 188 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 189 | // .node_ref 190 | // .cast::() 191 | // .unwrap() 192 | // .focus_item_at_index(index) 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/chip.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | #![allow(unused_imports)] 4 | 5 | use super::{event_into_details, to_option, WeakComponentLink}; 6 | use gloo::events::EventListener; 7 | use wasm_bindgen::prelude::*; 8 | use web_sys::Node; 9 | use yew::prelude::*; 10 | 11 | pub struct Chip { 12 | link: ComponentLink, 13 | label: String, 14 | // onsignal: Callback<()>, 15 | } 16 | 17 | pub enum Msg { 18 | Clicked, 19 | } 20 | 21 | /// Props for [`Chip`] 22 | /// 23 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 24 | #[derive(Debug, Properties, Clone)] 25 | pub struct ChipProps { 26 | pub label: String, 27 | #[prop_or_default] 28 | pub icon: Option, 29 | #[prop_or_default] 30 | pub raised: bool, 31 | #[prop_or_default] 32 | pub unelevated: bool, 33 | #[prop_or_default] 34 | pub outlined: bool, 35 | #[prop_or_default] 36 | pub dense: bool, 37 | #[prop_or_default] 38 | pub disabled: bool, 39 | #[prop_or_default] 40 | pub trailing_icon: bool, 41 | // #[prop_or_default] 42 | // pub onsignal: Callback<()>, 43 | } 44 | 45 | // label=props.label 46 | // icon?=props.icon.as_ref() 47 | // raised?=to_option(props.raised) 48 | // unelevated?=to_option(props.unelevated) 49 | // outlined?=to_option(props.outlined) 50 | // dense?=to_option(props.dense) 51 | // trailingIcon?=to_option(props.trailing_icon) 52 | // disabled=props.disabled 53 | 54 | impl Component for Chip { 55 | type Message = Msg; 56 | type Properties = ChipProps; 57 | 58 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 59 | Self { 60 | link, 61 | label: props.label, 62 | // onsignal: props.onsignal, 63 | } 64 | } 65 | 66 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 67 | match msg { 68 | Msg::Clicked => { 69 | // self.onsignal.emit(()); 70 | } 71 | } 72 | false 73 | } 74 | 75 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 76 | self.label = props.label; 77 | // self.onsignal = props.onsignal; 78 | true 79 | } 80 | 81 | fn view(&self) -> Html { 82 | html! { 83 |
    84 |
    85 | 86 | 87 | { &self.label } 88 | 89 | 90 |
    91 | } 92 | } 93 | } 94 | 95 | // chips 96 | 97 | 98 | pub struct Chips { 99 | props: ChipsProps, 100 | node_ref: NodeRef, 101 | action_listener: Option, 102 | selected_listener: Option, 103 | } 104 | 105 | /// Props for [`Chips`] 106 | /// 107 | /// [Documentation for properties](https://github.com/material-components/material-components-web-components/tree/master/packages/button#propertiesattributes) 108 | #[derive(Clone, PartialEq, Properties)] 109 | pub struct ChipsProps { 110 | #[prop_or_default] 111 | pub activatable: bool, 112 | #[prop_or_default] 113 | pub root_tabbable: bool, 114 | #[prop_or_default] 115 | pub multi: bool, 116 | #[prop_or_default] 117 | pub wrap_focus: bool, 118 | #[prop_or_default] 119 | pub item_roles: Option, 120 | #[prop_or_default] 121 | pub inner_role: Option, 122 | #[prop_or_default] 123 | pub noninteractive: bool, 124 | /// Binds to `action` event on `list` 125 | // #[prop_or_default] 126 | // pub onaction: Callback, 127 | // /// Binds to `selected` event `list` 128 | // #[prop_or_default] 129 | // pub onselected: Callback, 130 | /// [`WeakComponentLink`] for `List` which provides the following methods 131 | /// - ```toggle(&self, index: usize, force: bool)``` 132 | /// - ```get_focused_item_index(&self) -> usize``` 133 | /// - ```focus_item_at_index(&self, index: usize)``` 134 | /// 135 | /// See [`WeakComponentLink`] documentation for more information 136 | #[prop_or_default] 137 | pub list_link: WeakComponentLink, 138 | #[prop_or_default] 139 | pub children: Children, 140 | } 141 | 142 | // label=props.label 143 | // icon?=props.icon.as_ref() 144 | // raised?=to_option(props.raised) 145 | // unelevated?=to_option(props.unelevated) 146 | // outlined?=to_option(props.outlined) 147 | // dense?=to_option(props.dense) 148 | // trailingIcon?=to_option(props.trailing_icon) 149 | // disabled=props.disabled 150 | 151 | impl Component for Chips { 152 | type Message = Msg; 153 | type Properties = ChipsProps; 154 | 155 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 156 | Self { 157 | props, 158 | node_ref: NodeRef::default(), 159 | action_listener: None, 160 | selected_listener: None, 161 | } 162 | } 163 | 164 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 165 | match msg { 166 | Msg::Clicked => { 167 | // self.onsignal.emit(()); 168 | } 169 | } 170 | false 171 | } 172 | 173 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 174 | if self.props != props { 175 | self.props = props; 176 | true 177 | } else { 178 | false 179 | } 180 | } 181 | 182 | fn view(&self) -> Html { 183 | html! { 184 |
    185 | { self.view_items() } 186 |
    187 | } 188 | } 189 | } 190 | 191 | impl Chips { 192 | fn view_items(&self) -> Html { 193 | html! {{ 194 | for self.props.children.iter().enumerate().map(|(i, mut c)| { 195 | c 196 | }) 197 | }} 198 | } 199 | } 200 | 201 | impl WeakComponentLink { 202 | /// Binds to `toggle` method. 203 | /// 204 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 205 | pub fn toggle(&self, index: usize, force: bool) { 206 | // let list = (*self.borrow().as_ref().unwrap().get_component().unwrap()) 207 | // .node_ref 208 | // .cast::() 209 | // .unwrap(); 210 | // list.toggle(index, force) 211 | } 212 | 213 | /// Binds to `getFocusedItemIndex` method. 214 | /// 215 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 216 | pub fn get_focused_item_index(&self) -> usize { 217 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 218 | // .node_ref 219 | // .cast::() 220 | // .unwrap() 221 | // .get_focused_item_index() 222 | unimplemented!() 223 | } 224 | 225 | /// Binds to `focusItemAtIndex` method. 226 | /// 227 | /// See [here](https://github.com/material-components/material-components-web-components/tree/master/packages/list#methods) for details 228 | pub fn focus_item_at_index(&self, index: usize) { 229 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 230 | // .node_ref 231 | // .cast::() 232 | // .unwrap() 233 | // .focus_item_at_index(index) 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/snackbar.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::{event_into_details, to_option, WeakComponentLink}; 5 | use gloo::events::EventListener; 6 | use js_sys::Object; 7 | use wasm_bindgen::prelude::*; 8 | use wasm_bindgen::JsCast; 9 | use web_sys::Node; 10 | use yew::prelude::*; 11 | 12 | /// The `snackbar` component 13 | /// 14 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/snackbar) 15 | pub struct Snackbar { 16 | props: SnackbarProps, 17 | node_ref: NodeRef, 18 | opening_listener: Option, 19 | opened_listener: Option, 20 | closing_listener: Option, 21 | closed_listener: Option, 22 | } 23 | 24 | /// Props for [`Snackbar`] 25 | /// 26 | /// Documentation: 27 | /// 28 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/snackbar#propertiesattributes) 29 | /// - [Events](https://github.com/material-components/material-components-web-components/tree/master/packages/snackbar#events) 30 | #[derive(Clone, PartialEq, Properties)] 31 | pub struct SnackbarProps { 32 | #[prop_or_default] 33 | pub open: bool, 34 | #[prop_or(5000)] 35 | pub timeout_ms: i32, 36 | #[prop_or_default] 37 | pub close_on_escape: bool, 38 | #[prop_or_default] 39 | pub label_text: String, 40 | #[prop_or_default] 41 | pub stacked: bool, 42 | #[prop_or_default] 43 | pub leading: bool, 44 | /// Binds to `MDCSnackbar:opening` event 45 | /// 46 | /// See events docs to learn more. 47 | #[prop_or_default] 48 | pub onopening: Callback<()>, 49 | /// Binds to `MDCSnackbar:opened` event 50 | /// 51 | /// See events docs to learn more. 52 | #[prop_or_default] 53 | pub onopened: Callback<()>, 54 | /// Binds to `MDCSnackbar:` event 55 | /// 56 | /// The argument passed to callback corresponds to `reason` parameter of the 57 | /// event 58 | /// 59 | /// See events docs to learn more. 60 | #[prop_or_default] 61 | pub onclosing: Callback>, 62 | /// Binds to `closing` event 63 | /// 64 | /// The argument passed to callback corresponds to `reason` parameter of the 65 | /// event 66 | /// 67 | /// See events docs to learn more. 68 | #[prop_or_default] 69 | pub onclosed: Callback>, 70 | /// [`WeakComponentLink`] for `List` which provides the following methods 71 | /// - ```show(&self)``` 72 | /// - ```close(&self, reason: &str)``` 73 | /// 74 | /// See [`WeakComponentLink`] documentation for more information 75 | #[prop_or_default] 76 | pub snackbar_link: WeakComponentLink, 77 | #[prop_or_default] 78 | pub children: Children, 79 | } 80 | 81 | impl Component for Snackbar { 82 | type Message = (); 83 | type Properties = SnackbarProps; 84 | 85 | fn create(props: Self::Properties, link: ComponentLink) -> Self { 86 | // props.snackbar_link.borrow_mut().replace(link); 87 | // Snackbar::ensure_loaded(); 88 | Self { 89 | props, 90 | node_ref: NodeRef::default(), 91 | opening_listener: None, 92 | opened_listener: None, 93 | closing_listener: None, 94 | closed_listener: None, 95 | } 96 | } 97 | 98 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 99 | false 100 | } 101 | 102 | fn change(&mut self, props: Self::Properties) -> bool { 103 | if self.props != props { 104 | self.props = props; 105 | true 106 | } else { 107 | false 108 | } 109 | } 110 | 111 | fn view(&self) -> Html { 112 | // timeoutMs=self.props.timeout_ms 113 | // closeOnEscape=self.props.close_on_escape 114 | // labelText=self.props.label_text 115 | // stacked?=to_option(self.props.stacked) 116 | // leading?=to_option(self.props.leading) 117 | // ref=self.node_ref.clone() 118 | // >{ self.props.children.clone() } 119 | 120 | html! { 121 |
    122 |
    123 |
    124 | { "Can't send photo. Retry in 5 seconds." } 125 |
    126 |
    127 | 131 |
    132 |
    133 |
    134 | } 135 | } 136 | 137 | fn rendered(&mut self, first_render: bool) { 138 | // let element = self.node_ref.cast::().unwrap(); 139 | // element.set_open(self.props.open); 140 | 141 | // if first_render { 142 | // let on_opening = self.props.onopening.clone(); 143 | // self.opening_listener = Some(EventListener::new( 144 | // &element, 145 | // "MDCSnackbar:opening", 146 | // move |_| { 147 | // on_opening.emit(()); 148 | // }, 149 | // )); 150 | 151 | // let on_opened = self.props.onopened.clone(); 152 | // self.opened_listener = Some(EventListener::new( 153 | // &element, 154 | // "MDCSnackbar:opened", 155 | // move |_| { 156 | // on_opened.emit(()); 157 | // }, 158 | // )); 159 | 160 | // let on_closing = self.props.onclosing.clone(); 161 | // self.closing_listener = Some(EventListener::new( 162 | // &element, 163 | // "MDCSnackbar:closing", 164 | // move |event| { 165 | // on_closing.emit(event_into_details_reason(event)); 166 | // }, 167 | // )); 168 | 169 | // let on_closed = self.props.onclosed.clone(); 170 | // self.closed_listener = Some(EventListener::new( 171 | // &element, 172 | // "MDCSnackbar:closed", 173 | // move |event| { 174 | // on_closed.emit(event_into_details_reason(event)); 175 | // }, 176 | // )); 177 | // } 178 | } 179 | } 180 | 181 | impl WeakComponentLink { 182 | pub fn show(&self) { 183 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 184 | // .node_ref 185 | // .cast::() 186 | // .unwrap() 187 | // .show() 188 | unimplemented!() 189 | } 190 | 191 | pub fn close(&self, reason: &str) { 192 | // (*self.borrow().as_ref().unwrap().get_component().unwrap()) 193 | // .node_ref 194 | // .cast::() 195 | // .unwrap() 196 | // .close(&JsValue::from_str(reason)) 197 | unimplemented!() 198 | } 199 | } 200 | 201 | fn event_into_details_reason(event: &Event) -> Option { 202 | // let details: JsValue = event_into_details(event); 203 | // if details.is_undefined() { 204 | // None 205 | // } else { 206 | // Some(details.unchecked_into::().reason()) 207 | // } 208 | unimplemented!() 209 | } 210 | -------------------------------------------------------------------------------- /src/text_inputs/textfield.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | #![allow(dead_code)] 3 | 4 | use super::set_on_input_handler; 5 | use crate::text_inputs::{ 6 | // validity_state::ValidityStateJS, 7 | TextFieldType, ValidityState, ValidityTransform, 8 | }; 9 | use crate::{to_option, to_option_string}; 10 | use gloo::events::EventListener; 11 | use wasm_bindgen::prelude::*; 12 | use wasm_bindgen::JsCast; 13 | use web_sys::Node; 14 | use web_sys::ValidityState as NativeValidityState; 15 | use yew::prelude::*; 16 | 17 | 18 | /// The `textfield` component 19 | /// 20 | /// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/textfield) 21 | pub struct TextField { 22 | props: TextFieldProps, 23 | node_ref: NodeRef, 24 | // validity_transform_closure: 25 | // Option ValidityStateJS>>, 26 | input_listener: Option, 27 | } 28 | 29 | /// Props for [`TextField`] 30 | /// 31 | /// Documentation: 32 | /// 33 | /// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/textfield#propertiesattributes) 34 | #[derive(Properties, Clone)] 35 | pub struct TextFieldProps { 36 | #[prop_or_default] 37 | pub open: bool, 38 | #[prop_or_default] 39 | pub value: String, 40 | #[prop_or(TextFieldType::Text)] 41 | pub field_type: TextFieldType, 42 | #[prop_or_default] 43 | pub label: String, 44 | #[prop_or_default] 45 | pub placeholder: String, 46 | #[prop_or_default] 47 | pub prefix: String, 48 | #[prop_or_default] 49 | pub suffix: String, 50 | #[prop_or_default] 51 | pub icon: String, 52 | #[prop_or_default] 53 | pub icon_trailing: String, 54 | #[prop_or_default] 55 | pub disabled: bool, 56 | #[prop_or_default] 57 | pub char_counter: bool, 58 | #[prop_or_default] 59 | pub outlined: bool, 60 | #[prop_or_default] 61 | pub helper: String, 62 | #[prop_or_default] 63 | pub helper_persistent: bool, 64 | #[prop_or_default] 65 | pub required: bool, 66 | #[prop_or_default] 67 | pub max_length: String, 68 | #[prop_or_default] 69 | pub validation_message: String, 70 | #[prop_or_default] 71 | pub pattern: String, 72 | /// Type: `number | string` so I'll leave it as a string 73 | #[prop_or_default] 74 | pub min: String, 75 | /// Type: `number | string` so I'll leave it as a string 76 | #[prop_or_default] 77 | pub max: String, 78 | // What you doing... 79 | #[prop_or_default] 80 | pub size: Option, 81 | // ...step size 82 | #[prop_or_default] 83 | pub step: Option, 84 | #[prop_or_default] 85 | pub auto_validate: bool, 86 | // #[prop_or_default] 87 | // pub validity_transform: Option, 88 | #[prop_or_default] 89 | pub validate_on_initial_render: bool, 90 | #[prop_or_default] 91 | pub oninput: Callback, 92 | #[prop_or_default] 93 | pub name: String, 94 | } 95 | 96 | impl Component for TextField { 97 | type Message = (); 98 | type Properties = TextFieldProps; 99 | 100 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 101 | // TextField::ensure_loaded(); 102 | Self { 103 | props, 104 | node_ref: NodeRef::default(), 105 | // validity_transform_closure: None, 106 | input_listener: None, 107 | } 108 | } 109 | 110 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 111 | false 112 | } 113 | 114 | fn change(&mut self, props: Self::Properties) -> bool { 115 | self.props = props; 116 | true 117 | } 118 | 119 | fn view(&self) -> Html { 120 | // open=self.props.open 121 | // label?=to_option_string(&self.props.label) 122 | // placeholder?=to_option_string(&self.props.placeholder) 123 | // prefix?=to_option_string(&self.props.prefix) 124 | // suffix?=to_option_string(&self.props.suffix) 125 | // icon?=to_option_string(&self.props.icon) 126 | // iconTrailing?=to_option_string(&self.props.icon_trailing) 127 | // disabled=self.props.disabled 128 | // charCounter?=to_option(self.props.char_counter) 129 | // outlined?=to_option(self.props.outlined) 130 | // helper?=to_option_string(&self.props.helper) 131 | // helperPersistent?=to_option(self.props.helper_persistent) 132 | // required=self.props.required 133 | // maxLength?=to_option_string(&self.props.max_length) 134 | // validationMessage?=to_option_string(&self.props.validation_message) 135 | // pattern?=to_option_string(&self.props.pattern) 136 | // min?=to_option_string(&self.props.min) 137 | // max?=to_option_string(&self.props.max) 138 | // size?=self.props.size //.map_or("null".to_string(), |v| v.to_string()) 139 | // step?=self.props.step //.map_or("null".to_string(), |v| v.to_string()) 140 | // autoValidate?=to_option(self.props.auto_validate) 141 | // validateOnInitialRender?=to_option(self.props.validate_on_initial_render) 142 | // name?=to_option_string(&self.props.name) 143 | // ref=self.node_ref.clone() 144 | 145 | html! { 146 | 152 | } 153 | } 154 | 155 | fn rendered(&mut self, first_render: bool) { 156 | // if first_render { 157 | // self.input_listener = Some(set_on_input_handler( 158 | // &self.node_ref, 159 | // self.props.oninput.clone(), 160 | // |(input_event, detail)| { 161 | // InputData { 162 | // value: detail 163 | // .unchecked_into::() 164 | // .target() 165 | // .value(), 166 | // event: input_event, 167 | // } 168 | // }, 169 | // )); 170 | 171 | // let element = self.node_ref.cast::().unwrap(); 172 | // element.set_type(&JsValue::from(&self.props.field_type.to_string())); 173 | // element.set_value(&JsValue::from(&self.props.value)); 174 | 175 | // let this = self.node_ref.cast::().unwrap(); 176 | // if let Some(transform) = self.props.validity_transform.clone() { 177 | // self.validity_transform_closure = Some(Closure::wrap(Box::new( 178 | // move |s: String, v: NativeValidityState| -> ValidityStateJS { 179 | // transform.0(s, v).into() 180 | // }, 181 | // ) 182 | // as Box ValidityStateJS>)); 183 | // this.set_validity_transform(&self.validity_transform_closure.as_ref().unwrap()); 184 | // } 185 | // } 186 | } 187 | } 188 | 189 | impl TextField { 190 | pub fn validity_transform ValidityState + 'static>( 191 | func: F, 192 | ) -> ValidityTransform { 193 | ValidityTransform::new(func) 194 | } 195 | } 196 | 197 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![recursion_limit = "1024"] 2 | #![allow(unused_variables)] 3 | #![allow(dead_code)] 4 | #![allow(unused_imports)] 5 | 6 | #![doc(html_root_url = "/docs")] 7 | 8 | //! A Material components library for [Yew](https://yew.rs). It wrpas around [Material Web Components](https://github.com/material-components/material-components-web-components) exposing Yew components. 9 | //! 10 | //! Example usage: 11 | //! ```rust 12 | //! use yew::html; 13 | //! use yew_material::Button; 14 | //! 15 | //! html! { 16 | //!