├── .envrc ├── .github └── workflows │ ├── build.yml │ ├── check-links.yml │ ├── deploy.yml │ ├── elm-review.yml │ └── test-docs.yml ├── .gitignore ├── .gitmodules ├── .versionrc.json ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── babel.config.js ├── bin ├── apply-patches.sh ├── check-links.sh ├── make-patches.sh ├── test-docs.hs └── test-docs.sh ├── demo ├── Makefile ├── elm.json ├── images │ ├── buttons_180px.svg │ ├── cards_180px.svg │ ├── checkbox_180px.svg │ ├── chips_180px.svg │ ├── data_table_180px.svg │ ├── dialog_180px.svg │ ├── drawer_180px.svg │ ├── elevation_180px.svg │ ├── floating_action_button_180px.svg │ ├── fonts_180px.svg │ ├── form_field_180px.svg │ ├── ic_code_24px.svg │ ├── ic_component_24px_white.svg │ ├── ic_drive_document_24px.svg │ ├── ic_material_design_24px.svg │ ├── ic_switch_24px.svg │ ├── ic_theme_24px.svg │ ├── icon_button_180px.svg │ ├── image_list_180px.svg │ ├── layout_grid_180px.svg │ ├── linear_progress_180px.svg │ ├── list_180px.svg │ ├── mdc_web_48dp.png │ ├── menu_180px.svg │ ├── photos │ │ ├── 2x3 │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ └── 8.jpg │ │ └── 3x2 │ │ │ ├── 1.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ ├── 15.jpg │ │ │ ├── 16.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ └── 9.jpg │ ├── radio_180px.svg │ ├── ripple_180px.svg │ ├── slider_180px.svg │ ├── snackbar_180px.svg │ ├── switch_180px.svg │ ├── tabs_180px.svg │ └── top_app_bar_180px.svg ├── page.html ├── review │ ├── elm.json │ └── src │ │ └── ReviewConfig.elm └── src │ ├── Demo │ ├── Buttons.elm │ ├── Cards.elm │ ├── CatalogPage.elm │ ├── Checkbox.elm │ ├── Chips.elm │ ├── CircularProgress.elm │ ├── DataTable.elm │ ├── DenseTopAppBar.elm │ ├── Dialog.elm │ ├── DismissibleDrawer.elm │ ├── Drawer.elm │ ├── DrawerPage.elm │ ├── Elevation.elm │ ├── ElmLogo.elm │ ├── Fabs.elm │ ├── FixedTopAppBar.elm │ ├── Helper │ │ └── ResourceLink.elm │ ├── IconButton.elm │ ├── ImageList.elm │ ├── LayoutGrid.elm │ ├── LinearProgress.elm │ ├── Lists.elm │ ├── Menus.elm │ ├── ModalDrawer.elm │ ├── PermanentDrawer.elm │ ├── ProminentTopAppBar.elm │ ├── RadioButtons.elm │ ├── Ripple.elm │ ├── Selects.elm │ ├── ShortCollapsedTopAppBar.elm │ ├── ShortTopAppBar.elm │ ├── Slider.elm │ ├── Snackbar.elm │ ├── StandardTopAppBar.elm │ ├── Startpage.elm │ ├── Switch.elm │ ├── TabBar.elm │ ├── TextFields.elm │ ├── Theme.elm │ ├── TopAppBar.elm │ ├── TopAppBarPage.elm │ ├── Typography.elm │ └── Url.elm │ └── Main.elm ├── elm.json ├── examples ├── simple-counter │ ├── Makefile │ ├── elm.json │ ├── page.html │ ├── shell.nix │ └── src │ │ └── Main.elm └── theming │ ├── .gitignore │ ├── .sassrc.json │ ├── README.md │ ├── elm.json │ ├── package-lock.json │ ├── package.json │ └── src │ ├── Main.elm │ ├── index.html │ ├── index.scss │ └── index.ts ├── package-lock.json ├── package.json ├── review ├── elm.json └── src │ └── ReviewConfig.elm ├── shell.nix ├── src ├── Material │ ├── Button.elm │ ├── Button │ │ └── Internal.elm │ ├── Card.elm │ ├── Checkbox.elm │ ├── Checkbox │ │ └── Internal.elm │ ├── Chip │ │ ├── Action.elm │ │ ├── Action │ │ │ └── Internal.elm │ │ ├── Choice.elm │ │ ├── Choice │ │ │ └── Internal.elm │ │ ├── Filter.elm │ │ ├── Filter │ │ │ └── Internal.elm │ │ ├── Input.elm │ │ └── Input │ │ │ └── Internal.elm │ ├── ChipSet │ │ ├── Action.elm │ │ ├── Choice.elm │ │ ├── Filter.elm │ │ └── Input.elm │ ├── CircularProgress.elm │ ├── DataTable.elm │ ├── Dialog.elm │ ├── Drawer │ │ ├── Dismissible.elm │ │ ├── Modal.elm │ │ └── Permanent.elm │ ├── Elevation.elm │ ├── Fab.elm │ ├── Fab │ │ └── Extended.elm │ ├── FormField.elm │ ├── HelperText.elm │ ├── Icon.elm │ ├── IconButton.elm │ ├── IconButton │ │ └── Internal.elm │ ├── IconToggle.elm │ ├── ImageList.elm │ ├── ImageList │ │ ├── Item.elm │ │ └── Item │ │ │ └── Internal.elm │ ├── LayoutGrid.elm │ ├── LinearProgress.elm │ ├── List.elm │ ├── List │ │ ├── Divider.elm │ │ ├── Item.elm │ │ └── Item │ │ │ └── Internal.elm │ ├── Menu.elm │ ├── Radio.elm │ ├── Ripple.elm │ ├── Select.elm │ ├── Select │ │ ├── Icon.elm │ │ ├── Icon │ │ │ └── Internal.elm │ │ ├── Item.elm │ │ └── Item │ │ │ └── Internal.elm │ ├── Slider.elm │ ├── Snackbar.elm │ ├── Switch.elm │ ├── Tab.elm │ ├── Tab │ │ └── Internal.elm │ ├── TabBar.elm │ ├── TextArea.elm │ ├── TextField.elm │ ├── TextField │ │ ├── Icon.elm │ │ └── Icon │ │ │ └── Internal.elm │ ├── Theme.elm │ ├── TopAppBar.elm │ └── Typography.elm └── Testing │ └── Browser.elm ├── tsconfig.json └── webpack.config.js /.envrc: -------------------------------------------------------------------------------- 1 | use nix 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules : true 16 | - uses: cachix/install-nix-action@v12 17 | - run: nix-shell --run "make release" 18 | env: 19 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 20 | -------------------------------------------------------------------------------- /.github/workflows/check-links.yml: -------------------------------------------------------------------------------- 1 | name: check-links 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: Check links 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules : true 16 | - uses: cachix/install-nix-action@v12 17 | - run: nix-shell --run "make build-pages" 18 | env: 19 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 20 | - run: nix-shell --run "sh bin/check-links.sh" 21 | env: 22 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 23 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | on: 3 | push: 4 | branches: 5 | master 6 | 7 | jobs: 8 | build: 9 | name: Deploy to gh-pages 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | submodules : true 15 | - uses: cachix/install-nix-action@v12 16 | - run: nix-shell --run "make build-pages" 17 | env: 18 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 19 | - uses: peaceiris/actions-gh-pages@v3 20 | with: 21 | github_token: ${{ secrets.GITHUB_TOKEN }} 22 | force_orphan: true 23 | user_name: 'github-actions[bot]' 24 | user_email: 'github-actions[bot]@users.noreply.github.com' 25 | -------------------------------------------------------------------------------- /.github/workflows/elm-review.yml: -------------------------------------------------------------------------------- 1 | name: elm-review 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: Elm-review library and demo 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules : true 16 | - uses: cachix/install-nix-action@v12 17 | - run: nix-shell --run "make do-review" 18 | env: 19 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 20 | -------------------------------------------------------------------------------- /.github/workflows/test-docs.yml: -------------------------------------------------------------------------------- 1 | name: test-docs 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: Test documentation code examples 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules : true 16 | - uses: cachix/install-nix-action@v12 17 | - run: nix-shell --run "sh bin/test-docs.sh" 18 | env: 19 | NIX_PATH: nixpkgs=https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | demo.js 3 | dist 4 | docs.json 5 | *.d.ts 6 | elm.js 7 | elm-stuff 8 | public 9 | *.js.map 10 | node_modules 11 | src/**/component.js 12 | src/**/foundation.js 13 | src/*/*.patch 14 | src/*/*.ts.orig 15 | src/*/util.js 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "material-components-web"] 2 | path = material-components-web 3 | url = git@github.com:aforemny/material-components-web.git 4 | -------------------------------------------------------------------------------- /.versionrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bumpFiles": [ 3 | { 4 | "filename": "package.json", 5 | "type": "json" 6 | }, 7 | { 8 | "filename": "package-lock.json", 9 | "type": "json" 10 | }, 11 | { 12 | "filename": "elm.json", 13 | "type": "json" 14 | } 15 | ], 16 | "packageFiles": [ 17 | { 18 | "filename": "elm.json", 19 | "type": "json" 20 | } 21 | ], 22 | "tagPrefix": "" 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019-2020 Alexander Foremny 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MODE = production 2 | 3 | 4 | all: build-pages 5 | 6 | 7 | build-npm: node_modules 8 | mkdir -p dist 9 | (cd material-components-web && make) 10 | cp material-components-web/build/material-components-web-elm.css dist/ 11 | cp material-components-web/build/material-components-web-elm.css.map dist/ 12 | cp material-components-web/build/material-components-web-elm.js dist/ 13 | cp material-components-web/build/material-components-web-elm.js.map dist/ 14 | cp material-components-web/build/material-components-web-elm.min.css dist/ 15 | cp material-components-web/build/material-components-web-elm.min.css.map dist/ 16 | cp material-components-web/build/material-components-web-elm.min.js dist/ 17 | 18 | 19 | build-pages: build-npm build-demo 20 | mkdir -p public 21 | rsync --delete -r demo/images public 22 | cp demo/page.html public/index.html 23 | cp demo/demo.js public 24 | cp dist/material-components-web-elm.js public 25 | cp dist/material-components-web-elm.js.map public 26 | cp dist/material-components-web-elm.min.js public 27 | cp dist/material-components-web-elm.css public 28 | cp dist/material-components-web-elm.css.map public 29 | cp dist/material-components-web-elm.min.css public 30 | cp dist/material-components-web-elm.min.css.map public 31 | 32 | 33 | build-demo: 34 | (cd demo && make) 35 | 36 | 37 | build-examples: 38 | (cd examples/simple-counter && make) 39 | 40 | 41 | build-docs: src/**/*.elm 42 | elm make --docs=docs.json 43 | 44 | 45 | do-review: node_modules 46 | elm-review 47 | (cd demo && ../node_modules/.bin/elm-review) 48 | 49 | 50 | do-checks: node_modules 51 | bash bin/check-links.sh 52 | bash bin/test-docs.sh 53 | 54 | 55 | commit-pages: build-pages 56 | (cd public && git add . && git commit -m 'Update' && git push) 57 | 58 | 59 | docs: node_modules 60 | elm-doc-preview --port 8001 61 | 62 | 63 | release: distclean build-pages build-examples build-docs do-review do-checks 64 | 65 | 66 | node_modules: 67 | npm install 68 | 69 | 70 | clean: 71 | find src -name "*.d.ts" | xargs rm -f 72 | find src -name "component.js" | xargs rm -f 73 | find src -name "*.js.map" | xargs rm -f 74 | find src -name "*.patch" | xargs rm -f 75 | find src -name "*.ts.orig" | xargs rm -f 76 | rm -rf dist public 77 | rm -f docs.json 78 | (cd demo && make clean) 79 | (cd examples/simple-counter && make clean) 80 | (cd material-components-web && make clean) 81 | 82 | 83 | distclean: clean 84 | rm -rf elm-stuff node_modules 85 | (cd demo && make distclean) 86 | (cd examples/simple-counter && make distclean) 87 | (cd material-components-web && make distclean) 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![build](https://github.com/aforemny/material-components-web-elm/workflows/build/badge.svg) 2 | 3 | # Material Components for Elm 4 | 5 | A [Material Design](https://material.io/design) framework. 6 | 7 | This library is based on [Material Components for the 8 | web](https://github.com/material-components/material-components-web) (MDC Web). 9 | 10 | 11 | ## Important links 12 | 13 | - Getting Started Guide (TODO) 14 | - [Demo](https://aforemny.github.io/material-components-web-elm) 15 | 16 | 17 | ## Quick start 18 | 19 | This package relies upon JavaScript and CSS that need to be included in your 20 | project separately. As a result, this library will _not_ work with e.g. `elm 21 | reactor`. Instead you will need to use either a HTML file or a bundler, such as 22 | webpack. 23 | 24 | 25 | ### Using HTML 26 | 27 | You should [compile your Elm program to 28 | JavaScript](https://guide.elm-lang.org/install/elm.html#elm-make) and include 29 | it in a custom HTML document. From that HTML document, you have to include the 30 | following assets to use this library. 31 | 32 | Please make sure that the last two assets match this library's version (ie. 33 | 9.1.0) exactly. 34 | 35 | ```html 36 | 37 | 38 | 39 | ``` 40 | 41 | Refer to the [simple counter 42 | example](https://github.com/aforemny/material-components-web-elm/blob/master/examples/simple-counter) 43 | for a minimal starting point, specifically to the files 44 | [`src/Main.elm`](https://github.com/aforemny/material-components-web-elm/blob/master/examples/simple-counter/src/Main.elm) 45 | and 46 | [`page.html`](https://github.com/aforemny/material-components-web-elm/blob/master/examples/simple-counter/page.html). 47 | 48 | 49 | ### Using a bundler 50 | 51 | Install the JavaScript and CSS assets via npm: 52 | 53 | ```sh 54 | $ npm install --save material-components-web-elm@9.1.0 55 | ``` 56 | 57 | Then in your `index.js` add the following imports: 58 | 59 | ```js 60 | require("material-components-web-elm/dist/material-components-web-elm.js"); 61 | require("material-components-web-elm/dist/material-components-web-elm.css"); 62 | ``` 63 | 64 | 65 | ## Contributions 66 | 67 | Please [share your 68 | experience](https://github.com/aforemny/material-components-web-elm/issues) 69 | using this library! Use GitHub to [report bugs or ask 70 | questions](https://github.com/aforemny/material-components-web-elm/issues), 71 | too. 72 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const presets = [[ 2 | "@babel/env", 3 | { 4 | targets: { 5 | browsers: ["last 2 versions", "ie >= 11"] 6 | }, 7 | useBuiltIns: "usage", 8 | corejs: "2", 9 | } 10 | ]]; 11 | 12 | module.exports = { presets }; 13 | -------------------------------------------------------------------------------- /bin/apply-patches.sh: -------------------------------------------------------------------------------- 1 | for fn in src/*/{foundation,component,util}.patch; do 2 | file=$(basename $fn .patch) 3 | dir=$(dirname $fn) 4 | component=$(basename $dir) 5 | case $(basename $dir) in 6 | "text-field") 7 | component="textfield" 8 | ;; 9 | "chip") 10 | component="chips/chip" 11 | ;; 12 | "chip-set") 13 | component="chips/chip-set" 14 | ;; 15 | *) 16 | ;; 17 | esac 18 | cp material-components-web/packages/mdc-$component/$file.ts $dir/$file.ts 19 | patch -p0 <$fn 20 | done 21 | -------------------------------------------------------------------------------- /bin/check-links.sh: -------------------------------------------------------------------------------- 1 | fetch=$(mktemp fetch.XXXXXX.js) 2 | 3 | cat > "$fetch" < { 10 | 11 | const root = process.argv[2]; 12 | const urls = process.argv.slice(3); 13 | const app = connect().use(serveStatic("./public")); 14 | const server = http.createServer(app); 15 | await new Promise((resolve, reject) => server.listen(8080, () => resolve())); 16 | 17 | const browser = await puppeteer.launch({ 18 | headless: true, 19 | executablePath: process.env.CHROMIUM_PATH 20 | }); 21 | let errors = []; 22 | 23 | for (url of urls) { 24 | const page = await browser.newPage(); 25 | await page.goto(url); 26 | if (await page.\$eval("body", node => !!node.innerText.match(/404/))) { 27 | errors.push(url); 28 | } 29 | } 30 | 31 | for (error of errors) { 32 | console.log(error); 33 | } 34 | 35 | await browser.close(); 36 | await new Promise((resolve, reject) => server.close(() => resolve())); 37 | 38 | process.exit(errors.length === 0 ? 0 : 1); 39 | })(); 40 | EOF 41 | 42 | find src -name "*.elm" \ 43 | | xargs grep -h -o -E '\((https://aforemny.github.io/material-components-web-elm.*)\)' \ 44 | | sed 's/[()]//g' \ 45 | | sort \ 46 | | uniq \ 47 | | sed 's@.*#@http://localhost:8080/#@' \ 48 | | xargs node "$fetch" ./public 49 | 50 | code="$?" 51 | 52 | rm -f "$fetch" 53 | 54 | exit $code 55 | -------------------------------------------------------------------------------- /bin/make-patches.sh: -------------------------------------------------------------------------------- 1 | set -ex 2 | 3 | for fn in src/*/{foundation,component,util}.ts; do 4 | file=$(basename $fn .ts) 5 | dir=$(dirname $fn) 6 | component=$(basename $dir) 7 | case $(basename $dir) in 8 | "text-field") 9 | component="textfield" 10 | ;; 11 | "chip") 12 | component="chips/chip" 13 | ;; 14 | "chip-set") 15 | component="chips/chip-set" 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | cp material-components-web/packages/mdc-$component/$file.ts $dir/$file.ts.orig 21 | diff -rupN $dir/$file.ts.orig $dir/$file.ts > $dir/$file.patch || true 22 | rm $dir/$file.ts.orig 23 | done 24 | -------------------------------------------------------------------------------- /bin/test-docs.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE ScopedTypeVariables #-} 3 | 4 | import Control.Exception 5 | import Data.List 6 | import System.IO 7 | import System.IO.Temp 8 | import System.Process 9 | import Text.Pandoc.JSON 10 | import qualified Data.Text as T 11 | 12 | 13 | main = toJSONFilter testDocs 14 | 15 | 16 | data CodeException = CodeException String deriving Show 17 | 18 | 19 | instance Exception CodeException 20 | 21 | 22 | testDocs (CodeBlock meta@(_, ["scss"], _) code) = pure (CodeBlock meta code) 23 | 24 | testDocs (CodeBlock meta code') = 25 | CodeBlock meta . T.pack <$> try [trySnippet, tryFull, tryDefinition] 26 | where 27 | code = T.unpack code' 28 | try (f:fs) = catch (compile f) (\(_::IOError) -> continue fs) 29 | continue [] = throw (CodeException code) 30 | continue fs = try fs 31 | compile f = withTempFile "." "XXXXXX.elm" (f code) 32 | 33 | testDocs x = pure x 34 | 35 | 36 | tryFull code tempFile h = do 37 | writePrelude h 38 | hPutStrLn h (noImports code) 39 | hClose h 40 | compile tempFile 41 | 42 | 43 | tryDefinition code tempFile h = do 44 | writePrelude h 45 | hPutStrLn h "main = text \"\"" 46 | hPutStrLn h (noImports code) 47 | hClose h 48 | compile tempFile 49 | 50 | 51 | trySnippet code tempFile h = do 52 | writePrelude h 53 | hPutStrLn h "type ActionButtonClicked a = ActionButtonClicked a" 54 | hPutStrLn h "type CardClicked = CardClicked" 55 | hPutStrLn h "type Clicked = Clicked" 56 | hPutStrLn h "type Dismissed a = Dismissed a" 57 | hPutStrLn h "type FabClicked = FabClicked" 58 | hPutStrLn h "type Interacted = Interacted" 59 | hPutStrLn h "type OpenChanged a = OpenChanged a" 60 | hPutStrLn h "" 61 | hPutStrLn h "main = text \"\"" 62 | hPutStrLn h "" 63 | hPutStrLn h "typecheck =" 64 | hPutStrLn h (indent (noImports code)) 65 | hClose h 66 | compile tempFile 67 | 68 | 69 | compile file = do 70 | sh ("elm make --output /dev/null " ++ file ++ " 2>/dev/null") 71 | 72 | 73 | sh cmd = 74 | readCreateProcess (shell cmd) "" 75 | 76 | 77 | indent = 78 | unlines . map (" "++) . lines 79 | 80 | 81 | noImports = 82 | unlines . filter (not . isPrefixOf "import ") . lines 83 | 84 | 85 | writePrelude h = do 86 | hPutStrLn h "module Main exposing (main)" 87 | hPutStrLn h "" 88 | hPutStrLn h "import Html.Attributes exposing (style, class)" 89 | hPutStrLn h "import Html.Events" 90 | hPutStrLn h "import Html exposing (Html, text)" 91 | hPutStrLn h "import Svg.Attributes" 92 | hPutStrLn h "" 93 | hPutStrLn h "import Material.Button as Button" 94 | hPutStrLn h "import Material.Card as Card" 95 | hPutStrLn h "import Material.Checkbox as Checkbox" 96 | hPutStrLn h "import Material.Chip.Action as ActionChip" 97 | hPutStrLn h "import Material.Chip.Choice as ChoiceChip" 98 | hPutStrLn h "import Material.Chip.Filter as FilterChip" 99 | hPutStrLn h "import Material.Chip.Input as InputChip" 100 | hPutStrLn h "import Material.ChipSet.Action as ActionChipSet" 101 | hPutStrLn h "import Material.ChipSet.Choice as ChoiceChipSet" 102 | hPutStrLn h "import Material.ChipSet.Filter as FilterChipSet" 103 | hPutStrLn h "import Material.ChipSet.Input as InputChipSet" 104 | hPutStrLn h "import Material.CircularProgress as CircularProgress" 105 | hPutStrLn h "import Material.DataTable as DataTable" 106 | hPutStrLn h "import Material.Dialog as Dialog" 107 | hPutStrLn h "import Material.Drawer.Dismissible as DismissibleDrawer" 108 | hPutStrLn h "import Material.Drawer.Modal as ModalDrawer" 109 | hPutStrLn h "import Material.Drawer.Permanent as PermanentDrawer" 110 | hPutStrLn h "import Material.Elevation as Elevation" 111 | hPutStrLn h "import Material.Fab as Fab" 112 | hPutStrLn h "import Material.Fab.Extended as ExtendedFab" 113 | hPutStrLn h "import Material.FormField as FormField" 114 | hPutStrLn h "import Material.HelperText as HelperText" 115 | hPutStrLn h "import Material.Icon as Icon" 116 | hPutStrLn h "import Material.IconButton as IconButton" 117 | hPutStrLn h "import Material.IconToggle as IconToggle" 118 | hPutStrLn h "import Material.ImageList as ImageList" 119 | hPutStrLn h "import Material.ImageList.Item as ImageListItem" 120 | hPutStrLn h "import Material.LayoutGrid as LayoutGrid" 121 | hPutStrLn h "import Material.LinearProgress as LinearProgress" 122 | hPutStrLn h "import Material.List as List" 123 | hPutStrLn h "import Material.List.Divider as ListDivider" 124 | hPutStrLn h "import Material.List.Item as ListItem" 125 | hPutStrLn h "import Material.Menu as Menu" 126 | hPutStrLn h "import Material.Radio as Radio" 127 | hPutStrLn h "import Material.Ripple as Ripple" 128 | hPutStrLn h "import Material.Select as Select" 129 | hPutStrLn h "import Material.Select.Icon as SelectIcon" 130 | hPutStrLn h "import Material.Select.Item as SelectItem" 131 | hPutStrLn h "import Material.Slider as Slider" 132 | hPutStrLn h "import Material.Snackbar as Snackbar" 133 | hPutStrLn h "import Material.Switch as Switch" 134 | hPutStrLn h "import Material.Tab as Tab" 135 | hPutStrLn h "import Material.TabBar as TabBar" 136 | hPutStrLn h "import Material.TextArea as TextArea" 137 | hPutStrLn h "import Material.TextField as TextField" 138 | hPutStrLn h "import Material.TextField.Icon as TextFieldIcon" 139 | hPutStrLn h "import Material.Theme as Theme" 140 | hPutStrLn h "import Material.TopAppBar as TopAppBar" 141 | hPutStrLn h "import Material.Typography as Typography" 142 | hPutStrLn h "" 143 | hPutStrLn h "import Testing.Browser as Browser" 144 | hPutStrLn h "" 145 | -------------------------------------------------------------------------------- /bin/test-docs.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | to_markdown=$(cat < /dev/null 18 | done 19 | -------------------------------------------------------------------------------- /demo/Makefile: -------------------------------------------------------------------------------- 1 | build: src/*.elm src/**/*.elm 2 | elm make src/Main.elm --output demo.js 3 | 4 | clean: 5 | rm -f demo.js 6 | 7 | distclean: clean 8 | rm -rf elm-stuff 9 | -------------------------------------------------------------------------------- /demo/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src", 5 | "../src" 6 | ], 7 | "elm-version": "0.19.1", 8 | "dependencies": { 9 | "direct": { 10 | "elm/browser": "1.0.2", 11 | "elm/core": "1.0.5", 12 | "elm/html": "1.0.0", 13 | "elm/json": "1.1.3", 14 | "elm/svg": "1.0.1", 15 | "elm/url": "1.0.0", 16 | "elm/virtual-dom": "1.0.3" 17 | }, 18 | "indirect": { 19 | "elm/regex": "1.0.0", 20 | "elm/time": "1.0.0" 21 | } 22 | }, 23 | "test-dependencies": { 24 | "direct": {}, 25 | "indirect": {} 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo/images/buttons_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | buttons_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | BUTTON 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /demo/images/checkbox_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /demo/images/data_table_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/images/dialog_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dialog_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Lorem ipsum dolor sit amet, 55 | consectetur adipisicing elit, sed 56 | do eiusmod tempor incididunt 57 | ut labore et dolore magna wirl 58 | aliqua. Up exlaborum incididunt 59 | 60 | 61 | 62 | 63 | 64 | 65 | Dialog Header 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /demo/images/drawer_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | drawer_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /demo/images/elevation_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | elevation_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /demo/images/fonts_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fonts_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | A 17 | z 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /demo/images/ic_code_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/images/ic_component_24px_white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demo/images/ic_drive_document_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/images/ic_material_design_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/images/ic_switch_24px.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/images/ic_theme_24px.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/images/layout_grid_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | layout_grid_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo/images/linear_progress_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linear_progress_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /demo/images/mdc_web_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/mdc_web_48dp.png -------------------------------------------------------------------------------- /demo/images/photos/2x3/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/1.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/2.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/3.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/4.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/5.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/6.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/7.jpg -------------------------------------------------------------------------------- /demo/images/photos/2x3/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/2x3/8.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/1.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/10.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/11.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/12.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/13.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/14.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/15.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/16.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/2.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/3.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/4.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/5.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/6.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/7.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/8.jpg -------------------------------------------------------------------------------- /demo/images/photos/3x2/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aforemny/material-components-web-elm/6dba973861131c8cc59cae6f7e8d0af80c892283/demo/images/photos/3x2/9.jpg -------------------------------------------------------------------------------- /demo/images/radio_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | radio_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /demo/images/ripple_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ripple_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /demo/images/snackbar_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | snackbar_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Greyhound divisively he 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /demo/images/top_app_bar_180px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | top_app_bar_180px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Top App Bar 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /demo/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Material Components for Elm 7 | 8 | 9 | 10 | 11 | 14 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /demo/review/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src" 5 | ], 6 | "elm-version": "0.19.1", 7 | "dependencies": { 8 | "direct": { 9 | "elm/core": "1.0.5", 10 | "elm/json": "1.1.3", 11 | "elm/project-metadata-utils": "1.0.2", 12 | "jfmengels/elm-review": "2.5.3", 13 | "jfmengels/review-unused": "2.1.5", 14 | "stil4m/elm-syntax": "7.2.7" 15 | }, 16 | "indirect": { 17 | "elm/html": "1.0.0", 18 | "elm/parser": "1.1.0", 19 | "elm/random": "1.0.0", 20 | "elm/time": "1.0.0", 21 | "elm/virtual-dom": "1.0.3", 22 | "elm-community/list-extra": "8.5.1", 23 | "elm-explorations/test": "1.2.2", 24 | "miniBill/elm-unicode": "1.0.2", 25 | "rtfeldman/elm-hex": "1.0.0", 26 | "stil4m/structured-writer": "1.0.3" 27 | } 28 | }, 29 | "test-dependencies": { 30 | "direct": { 31 | "elm-explorations/test": "1.2.2" 32 | }, 33 | "indirect": {} 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /demo/review/src/ReviewConfig.elm: -------------------------------------------------------------------------------- 1 | module ReviewConfig exposing (config) 2 | 3 | import NoUnused.CustomTypeConstructors 4 | import NoUnused.Dependencies 5 | import NoUnused.Exports 6 | import NoUnused.Modules 7 | import NoUnused.Variables 8 | import Review.Rule exposing (Rule) 9 | 10 | 11 | config : List Rule 12 | config = 13 | [ -- NoUnused.CustomTypeConstructors.rule [] 14 | -- , NoUnused.Dependencies.rule 15 | -- , NoUnused.Exports.rule 16 | -- , NoUnused.Modules.rule 17 | NoUnused.Variables.rule 18 | ] 19 | -------------------------------------------------------------------------------- /demo/src/Demo/Checkbox.elm: -------------------------------------------------------------------------------- 1 | module Demo.Checkbox exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Browser.Dom 4 | import Demo.CatalogPage exposing (CatalogPage) 5 | import Dict exposing (Dict) 6 | import Html exposing (Html, text) 7 | import Html.Attributes exposing (style) 8 | import Material.Button as Button 9 | import Material.Checkbox as Checkbox 10 | import Material.Typography as Typography 11 | import Task 12 | 13 | 14 | type alias Model = 15 | { checkboxes : Dict String Checkbox.State } 16 | 17 | 18 | defaultModel : Model 19 | defaultModel = 20 | { checkboxes = 21 | Dict.fromList 22 | [ ( "checked-hero-checkbox", Checkbox.checked ) 23 | , ( "unchecked-hero-checkbox", Checkbox.unchecked ) 24 | , ( "unchecked-checkbox", Checkbox.unchecked ) 25 | , ( "checked-checkbox", Checkbox.checked ) 26 | ] 27 | } 28 | 29 | 30 | type Msg 31 | = Changed String 32 | | Focus String 33 | | Focused (Result Browser.Dom.Error ()) 34 | 35 | 36 | update : Msg -> Model -> ( Model, Cmd Msg ) 37 | update msg model = 38 | case msg of 39 | Changed index -> 40 | let 41 | checkboxes = 42 | Dict.update index 43 | (\state -> 44 | if state == Just Checkbox.checked then 45 | Just Checkbox.unchecked 46 | 47 | else 48 | Just Checkbox.checked 49 | ) 50 | model.checkboxes 51 | in 52 | ( { model | checkboxes = checkboxes }, Cmd.none ) 53 | 54 | Focus id -> 55 | ( model, Task.attempt Focused (Browser.Dom.focus id) ) 56 | 57 | Focused _ -> 58 | ( model, Cmd.none ) 59 | 60 | 61 | view : Model -> CatalogPage Msg 62 | view model = 63 | { title = "Checkbox" 64 | , prelude = "Checkboxes allow the user to select multiple options from a set." 65 | , resources = 66 | { materialDesignGuidelines = Just "https://material.io/go/design-checkboxes" 67 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Checkbox" 68 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-checkbox" 69 | } 70 | , hero = heroCheckboxes model 71 | , content = 72 | [ Html.h3 [ Typography.subtitle1 ] [ text "Unchecked" ] 73 | , checkbox "unchecked-checkbox" model [] 74 | , Html.h3 [ Typography.subtitle1 ] [ text "Indeterminate" ] 75 | , checkbox "indeterminate-checkbox" model [] 76 | , Html.h3 [ Typography.subtitle1 ] [ text "Checked" ] 77 | , checkbox "checked-checkbox" model [] 78 | , Html.h3 [ Typography.subtitle1 ] [ text "Focus Checkbox" ] 79 | , focusCheckbox 80 | ] 81 | } 82 | 83 | 84 | heroCheckboxes : Model -> List (Html Msg) 85 | heroCheckboxes model = 86 | [ checkbox "checked-hero-checkbox" model heroMargin 87 | , checkbox "unchecked-hero-checkbox" model heroMargin 88 | ] 89 | 90 | 91 | checkbox : String -> Model -> List (Html.Attribute Msg) -> Html Msg 92 | checkbox index model attributes = 93 | let 94 | state = 95 | Dict.get index model.checkboxes 96 | |> Maybe.withDefault Checkbox.indeterminate 97 | in 98 | Checkbox.checkbox 99 | (Checkbox.config 100 | |> Checkbox.setState (Just state) 101 | |> Checkbox.setOnChange (Changed index) 102 | |> Checkbox.setAttributes attributes 103 | ) 104 | 105 | 106 | focusCheckbox : Html Msg 107 | focusCheckbox = 108 | Html.div [] 109 | [ Checkbox.checkbox 110 | (Checkbox.config 111 | |> Checkbox.setAttributes [ Html.Attributes.id "my-checkbox" ] 112 | ) 113 | , text "\u{00A0}" 114 | , Button.raised (Button.config |> Button.setOnClick (Focus "my-checkbox")) 115 | "Focus" 116 | ] 117 | 118 | 119 | heroMargin : List (Html.Attribute msg) 120 | heroMargin = 121 | [ style "margin" "8px 16px" ] 122 | -------------------------------------------------------------------------------- /demo/src/Demo/CircularProgress.elm: -------------------------------------------------------------------------------- 1 | module Demo.CircularProgress exposing (Model, Msg, defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (text) 5 | import Html.Attributes 6 | import Material.CircularProgress as CircularProgress 7 | import Material.Typography as Typography 8 | 9 | 10 | type alias Model = 11 | {} 12 | 13 | 14 | defaultModel : Model 15 | defaultModel = 16 | {} 17 | 18 | 19 | type Msg 20 | = NoOp 21 | 22 | 23 | update : Msg -> Model -> ( Model, Cmd Msg ) 24 | update msg model = 25 | ( model, Cmd.none ) 26 | 27 | 28 | view : Model -> CatalogPage Msg 29 | view model = 30 | { title = "Circular Progress Indicator" 31 | , prelude = "Progress indicators display the length of a process or express an unspecified wait time." 32 | , resources = 33 | { materialDesignGuidelines = 34 | Just "https://material.io/go/design-progress-indicators" 35 | , documentation = 36 | Just 37 | "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-CircularProgress" 38 | , sourceCode = 39 | Just 40 | "https://github.com/material-components/material-components-web/tree/master/packages/mdc-circular-progress" 41 | } 42 | , hero = [ CircularProgress.determinate CircularProgress.config { progress = 0.67 } ] 43 | , content = 44 | [ Html.h3 [ Typography.subtitle1 ] [ text "Large" ] 45 | , CircularProgress.indeterminate 46 | (CircularProgress.config 47 | |> CircularProgress.setSize CircularProgress.large 48 | ) 49 | , Html.h3 [ Typography.subtitle1 ] [ text "Medium" ] 50 | , CircularProgress.indeterminate 51 | (CircularProgress.config 52 | |> CircularProgress.setSize CircularProgress.medium 53 | ) 54 | , Html.h3 [ Typography.subtitle1 ] [ text "Small" ] 55 | , CircularProgress.indeterminate 56 | (CircularProgress.config 57 | |> CircularProgress.setSize CircularProgress.small 58 | ) 59 | , Html.h3 [ Typography.subtitle1 ] [ text "Four Colored" ] 60 | , CircularProgress.indeterminate 61 | (CircularProgress.config 62 | |> CircularProgress.setFourColored True 63 | ) 64 | , Html.node "style" 65 | [ Html.Attributes.type_ "text/css" ] 66 | [ text 67 | """ 68 | .mdc-circular-progress__color-1 69 | .mdc-circular-progress__indeterminate-circle-graphic { 70 | stroke: #000; } 71 | .mdc-circular-progress__color-2 72 | .mdc-circular-progress__indeterminate-circle-graphic { 73 | stroke: #f00; } 74 | .mdc-circular-progress__color-3 75 | .mdc-circular-progress__indeterminate-circle-graphic { 76 | stroke: #0f0; } 77 | .mdc-circular-progress__color-4 78 | .mdc-circular-progress__indeterminate-circle-graphic { 79 | stroke: #00f; } 80 | """ 81 | ] 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /demo/src/Demo/DenseTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.DenseTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Html exposing (text) 5 | import Material.IconButton as IconButton 6 | import Material.TopAppBar as TopAppBar 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> TopAppBarPage Msg 28 | view model = 29 | { fixedAdjust = TopAppBar.denseFixedAdjust 30 | , topAppBar = 31 | TopAppBar.regular (TopAppBar.config |> TopAppBar.setDense True) 32 | [ TopAppBar.row [] 33 | [ TopAppBar.section 34 | [ TopAppBar.alignStart ] 35 | [ IconButton.iconButton 36 | (IconButton.config 37 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 38 | ) 39 | (IconButton.icon "menu") 40 | , Html.span [ TopAppBar.title ] [ text "Dense" ] 41 | ] 42 | , TopAppBar.section 43 | [ TopAppBar.alignEnd ] 44 | [ IconButton.iconButton 45 | (IconButton.config 46 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 47 | ) 48 | (IconButton.icon "file_download") 49 | , IconButton.iconButton 50 | (IconButton.config 51 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 52 | ) 53 | (IconButton.icon "print") 54 | , IconButton.iconButton 55 | (IconButton.config 56 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 57 | ) 58 | (IconButton.icon "bookmark") 59 | ] 60 | ] 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/Demo/DismissibleDrawer.elm: -------------------------------------------------------------------------------- 1 | module Demo.DismissibleDrawer exposing 2 | ( Model 3 | , Msg(..) 4 | , defaultModel 5 | , update 6 | , view 7 | ) 8 | 9 | import Demo.DrawerPage as DrawerPage exposing (DrawerPage) 10 | import Material.Drawer.Dismissible as DismissibleDrawer 11 | 12 | 13 | type alias Model = 14 | { open : Bool 15 | , selectedIndex : Int 16 | } 17 | 18 | 19 | defaultModel : Model 20 | defaultModel = 21 | { open = False 22 | , selectedIndex = 0 23 | } 24 | 25 | 26 | type Msg 27 | = ToggleDrawer 28 | | CloseDrawer 29 | | SetSelectedIndex Int 30 | 31 | 32 | update : Msg -> Model -> Model 33 | update msg model = 34 | case msg of 35 | ToggleDrawer -> 36 | { model | open = not model.open } 37 | 38 | CloseDrawer -> 39 | { model | open = False } 40 | 41 | SetSelectedIndex index -> 42 | { model | selectedIndex = index } 43 | 44 | 45 | view : Model -> DrawerPage Msg 46 | view model = 47 | { title = "Dismissible Drawer" 48 | , drawer = 49 | DismissibleDrawer.drawer 50 | (DismissibleDrawer.config 51 | |> DismissibleDrawer.setOpen model.open 52 | |> DismissibleDrawer.setOnClose CloseDrawer 53 | ) 54 | (DrawerPage.drawerBody SetSelectedIndex model.selectedIndex) 55 | , onMenuClick = Just ToggleDrawer 56 | , scrim = Nothing 57 | } 58 | -------------------------------------------------------------------------------- /demo/src/Demo/Drawer.elm: -------------------------------------------------------------------------------- 1 | module Demo.Drawer exposing 2 | ( Model 3 | , Msg(..) 4 | , defaultModel 5 | , update 6 | , view 7 | ) 8 | 9 | import Demo.CatalogPage exposing (CatalogPage) 10 | import Html exposing (Html, text) 11 | import Html.Attributes exposing (style) 12 | import Material.Drawer.Permanent as PermanentDrawer 13 | import Material.Icon as Icon 14 | import Material.List as List 15 | import Material.List.Item as ListItem 16 | import Material.Typography as Typography 17 | 18 | 19 | type alias Model = 20 | {} 21 | 22 | 23 | defaultModel : Model 24 | defaultModel = 25 | {} 26 | 27 | 28 | type Msg 29 | = NoOp 30 | 31 | 32 | update : Msg -> Model -> Model 33 | update msg model = 34 | model 35 | 36 | 37 | view : Model -> CatalogPage Msg 38 | view model = 39 | { title = "Drawer" 40 | , prelude = "The navigation drawer slides in from the left and contains the navigation destinations for your app." 41 | , resources = 42 | { materialDesignGuidelines = Just "https://material.io/go/design-navigation-drawer" 43 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Drawer" 44 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-drawer" 45 | } 46 | , hero = heroDrawer 47 | , content = 48 | [ iframe "Permanent" "#permanent-drawer" 49 | , iframe "Dismissible" "#dismissible-drawer" 50 | , iframe "Modal" "#modal-drawer" 51 | ] 52 | } 53 | 54 | 55 | heroDrawer : List (Html msg) 56 | heroDrawer = 57 | let 58 | listItem ( activated, icon, label ) = 59 | ListItem.listItem 60 | (ListItem.config 61 | |> ListItem.setSelected 62 | (if activated then 63 | Just ListItem.activated 64 | 65 | else 66 | Nothing 67 | ) 68 | |> ListItem.setAttributes [ Html.Attributes.href "#drawer" ] 69 | ) 70 | [ ListItem.graphic [] [ Icon.icon [] icon ] 71 | , text label 72 | ] 73 | in 74 | [ PermanentDrawer.drawer PermanentDrawer.config 75 | [ PermanentDrawer.header [] 76 | [ Html.h3 [ PermanentDrawer.title ] [ text "Title" ] 77 | , Html.h6 [ PermanentDrawer.subtitle ] [ text "Subtitle" ] 78 | ] 79 | , PermanentDrawer.content [] 80 | [ List.list List.config 81 | (listItem ( True, "inbox", "Inbox" )) 82 | (List.map listItem 83 | [ ( False, "star", "Star" ) 84 | , ( False, "send", "Sent Mail" ) 85 | , ( False, "drafts", "Drafts" ) 86 | ] 87 | ) 88 | ] 89 | ] 90 | ] 91 | 92 | 93 | iframe : String -> String -> Html msg 94 | iframe label url = 95 | Html.div 96 | [ style "display" "inline-block" 97 | , style "-ms-flex" "1 1 80%" 98 | , style "flex" "1 1 80%" 99 | , style "-ms-flex-pack" "distribute" 100 | , style "justify-content" "space-around" 101 | , style "min-height" "400px" 102 | , style "min-width" "400px" 103 | , style "padding" "15px" 104 | ] 105 | [ Html.div [] 106 | [ Html.a 107 | [ Html.Attributes.href url 108 | , Html.Attributes.target "_blank" 109 | ] 110 | [ Html.h3 [ Typography.subtitle1 ] [ text label ] ] 111 | ] 112 | , Html.iframe 113 | [ Html.Attributes.src url 114 | , style "height" "400px" 115 | , style "width" "100vw" 116 | , style "max-width" "780px" 117 | ] 118 | [] 119 | ] 120 | -------------------------------------------------------------------------------- /demo/src/Demo/Elevation.elm: -------------------------------------------------------------------------------- 1 | module Demo.Elevation exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (Html, text) 5 | import Html.Attributes exposing (class, style) 6 | import Material.Elevation as Elevation 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> CatalogPage Msg 28 | view model = 29 | { title = "Elevation" 30 | , prelude = "Elevation is the relative depth, or distance, between two surfaces along the z-axis." 31 | , resources = 32 | { materialDesignGuidelines = Just "https://material.io/go/design-elevation" 33 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Elevation" 34 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-elevation" 35 | } 36 | , hero = heroElevation 37 | , content = 38 | [ Html.div demoContainer 39 | [ Html.div (Elevation.z0 :: demoSurface) [ text "0dp" ] 40 | , Html.div (Elevation.z1 :: demoSurface) [ text "1dp" ] 41 | , Html.div (Elevation.z2 :: demoSurface) [ text "2dp" ] 42 | , Html.div (Elevation.z3 :: demoSurface) [ text "3dp" ] 43 | , Html.div (Elevation.z4 :: demoSurface) [ text "4dp" ] 44 | , Html.div (Elevation.z5 :: demoSurface) [ text "5dp" ] 45 | , Html.div (Elevation.z6 :: demoSurface) [ text "6dp" ] 46 | , Html.div (Elevation.z7 :: demoSurface) [ text "7dp" ] 47 | , Html.div (Elevation.z8 :: demoSurface) [ text "8dp" ] 48 | , Html.div (Elevation.z9 :: demoSurface) [ text "9dp" ] 49 | , Html.div (Elevation.z10 :: demoSurface) [ text "10dp" ] 50 | , Html.div (Elevation.z11 :: demoSurface) [ text "11dp" ] 51 | , Html.div (Elevation.z12 :: demoSurface) [ text "12dp" ] 52 | , Html.div (Elevation.z13 :: demoSurface) [ text "13dp" ] 53 | , Html.div (Elevation.z14 :: demoSurface) [ text "14dp" ] 54 | , Html.div (Elevation.z15 :: demoSurface) [ text "15dp" ] 55 | , Html.div (Elevation.z16 :: demoSurface) [ text "16dp" ] 56 | , Html.div (Elevation.z17 :: demoSurface) [ text "17dp" ] 57 | , Html.div (Elevation.z18 :: demoSurface) [ text "18dp" ] 58 | , Html.div (Elevation.z19 :: demoSurface) [ text "19dp" ] 59 | , Html.div (Elevation.z20 :: demoSurface) [ text "20dp" ] 60 | , Html.div (Elevation.z21 :: demoSurface) [ text "21dp" ] 61 | , Html.div (Elevation.z22 :: demoSurface) [ text "22dp" ] 62 | , Html.div (Elevation.z23 :: demoSurface) [ text "23dp" ] 63 | , Html.div (Elevation.z24 :: demoSurface) [ text "24dp" ] 64 | ] 65 | ] 66 | } 67 | 68 | 69 | heroElevation : List (Html msg) 70 | heroElevation = 71 | [ Html.div (Elevation.z0 :: heroSurface) [ text "Flat 0dp" ] 72 | , Html.div (Elevation.z8 :: heroSurface) [ text "Raised 8dp" ] 73 | , Html.div (Elevation.z16 :: heroSurface) [ text "Raised 16dp" ] 74 | ] 75 | 76 | 77 | heroSurface : List (Html.Attribute msg) 78 | heroSurface = 79 | [ style "display" "-ms-inline-flexbox" 80 | , style "display" "inline-flex" 81 | , style "-ms-flex-pack" "distribute" 82 | , style "justify-content" "space-around" 83 | , style "min-height" "100px" 84 | , style "min-width" "200px" 85 | , style "-ms-flex-align" "center" 86 | , style "align-items" "center" 87 | , style "width" "120px" 88 | , style "height" "48px" 89 | , style "margin" "24px" 90 | , style "background-color" "#212121" 91 | , style "color" "#f0f0f0" 92 | ] 93 | 94 | 95 | demoContainer : List (Html.Attribute msg) 96 | demoContainer = 97 | [ class "elevation-demo-container" 98 | , style "display" "flex" 99 | , style "flex-flow" "row wrap" 100 | , style "justify-content" "space-between" 101 | ] 102 | 103 | 104 | demoSurface : List (Html.Attribute msg) 105 | demoSurface = 106 | [ style "display" "-ms-inline-flexbox" 107 | , style "display" "inline-flex" 108 | , style "-ms-flex-pack" "distribute" 109 | , style "justify-content" "space-around" 110 | , style "min-height" "100px" 111 | , style "min-width" "200px" 112 | , style "margin" "15px" 113 | , style "-ms-flex-align" "center" 114 | , style "align-items" "center" 115 | ] 116 | -------------------------------------------------------------------------------- /demo/src/Demo/ElmLogo.elm: -------------------------------------------------------------------------------- 1 | module Demo.ElmLogo exposing (elmLogo) 2 | 3 | import Svg exposing (Svg) 4 | import Svg.Attributes 5 | 6 | 7 | elmLogo : List (Svg msg) 8 | elmLogo = 9 | [ Svg.polygon 10 | [ Svg.Attributes.fill "#5A6378" 11 | , Svg.Attributes.points "0,2 48,50 0,98" 12 | ] 13 | [] 14 | , Svg.polygon 15 | [ Svg.Attributes.fill "#7FD13B" 16 | , Svg.Attributes.points 17 | "2,0 25.585786437626904,23.585786437626904 71.58578643762691,23.585786437626904 48,0" 18 | ] 19 | [] 20 | , Svg.polygon 21 | [ Svg.Attributes.fill "#7FD13B" 22 | , Svg.Attributes.points 23 | "2,0 25.585786437626904,23.585786437626904 71.58578643762691,23.585786437626904 48,0" 24 | ] 25 | [] 26 | , Svg.polygon 27 | [ Svg.Attributes.fill "#F0AD00" 28 | , Svg.Attributes.points 29 | "28.414213562373096,26.414213562373096 71.58578643762691,26.414213562373096 50,48" 30 | ] 31 | [] 32 | , Svg.polygon 33 | [ Svg.Attributes.fill "#60B5CC" 34 | , Svg.Attributes.points "52,0 100,0 100,48" 35 | ] 36 | [] 37 | , Svg.polygon 38 | [ Svg.Attributes.fill "#F0AD00" 39 | , Svg.Attributes.points "100,52 77,75 100,98" 40 | ] 41 | [] 42 | , Svg.polygon 43 | [ Svg.Attributes.fill "#60B5CC" 44 | , Svg.Attributes.points "2,100 50,52 98,100" 45 | ] 46 | [] 47 | , Svg.polygon 48 | [ Svg.Attributes.fill "#7FD13B" 49 | , Svg.Attributes.points "52,50 75,27 98,50 75,73" 50 | ] 51 | [] 52 | ] 53 | -------------------------------------------------------------------------------- /demo/src/Demo/FixedTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.FixedTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Html exposing (text) 5 | import Material.IconButton as IconButton 6 | import Material.TopAppBar as TopAppBar 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> TopAppBarPage Msg 28 | view model = 29 | { fixedAdjust = TopAppBar.fixedAdjust 30 | , topAppBar = 31 | TopAppBar.regular (TopAppBar.config |> TopAppBar.setFixed True) 32 | [ TopAppBar.row [] 33 | [ TopAppBar.section 34 | [ TopAppBar.alignStart ] 35 | [ IconButton.iconButton 36 | (IconButton.config 37 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 38 | ) 39 | (IconButton.icon "menu") 40 | , Html.span [ TopAppBar.title ] [ text "Fixed" ] 41 | ] 42 | , TopAppBar.section 43 | [ TopAppBar.alignEnd ] 44 | [ IconButton.iconButton 45 | (IconButton.config 46 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 47 | ) 48 | (IconButton.icon "file_download") 49 | , IconButton.iconButton 50 | (IconButton.config 51 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 52 | ) 53 | (IconButton.icon "print") 54 | , IconButton.iconButton 55 | (IconButton.config 56 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 57 | ) 58 | (IconButton.icon "bookmark") 59 | ] 60 | ] 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/Demo/Helper/ResourceLink.elm: -------------------------------------------------------------------------------- 1 | module Demo.Helper.ResourceLink exposing (view) 2 | 3 | import Html exposing (text) 4 | import Html.Attributes exposing (class) 5 | import Material.List.Item as ListItem exposing (ListItem) 6 | 7 | 8 | view : 9 | { link : String 10 | , title : String 11 | , icon : String 12 | , altText : String 13 | } 14 | -> ListItem msg 15 | view { link, title, icon, altText } = 16 | ListItem.listItem 17 | (ListItem.config 18 | |> ListItem.setAttributes 19 | [ Html.Attributes.href link 20 | , Html.Attributes.target "_blank" 21 | ] 22 | ) 23 | [ ListItem.graphic [] 24 | [ Html.img 25 | [ class "resources-icon" 26 | , Html.Attributes.src icon 27 | , Html.Attributes.alt altText 28 | ] 29 | [] 30 | ] 31 | , text title 32 | ] 33 | -------------------------------------------------------------------------------- /demo/src/Demo/ImageList.elm: -------------------------------------------------------------------------------- 1 | module Demo.ImageList exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (Html, text) 5 | import Html.Attributes exposing (style) 6 | import Material.ImageList as ImageList 7 | import Material.ImageList.Item as ImageListItem exposing (ImageListItem) 8 | import Material.Typography as Typography 9 | 10 | 11 | type alias Model = 12 | {} 13 | 14 | 15 | defaultModel : Model 16 | defaultModel = 17 | {} 18 | 19 | 20 | type Msg 21 | = NoOp 22 | 23 | 24 | update : Msg -> Model -> Model 25 | update msg model = 26 | model 27 | 28 | 29 | view : Model -> CatalogPage Msg 30 | view model = 31 | { title = "Image List" 32 | , prelude = "Image lists display a collection of images in an organized grid." 33 | , resources = 34 | { materialDesignGuidelines = Just "https://material.io/go/design-image-list" 35 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-ImageList" 36 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-image-list" 37 | } 38 | , hero = 39 | [ ImageList.imageList 40 | (ImageList.config 41 | |> ImageList.setAttributes [ style "width" "300px" ] 42 | ) 43 | (List.repeat 15 imageListHeroItem) 44 | ] 45 | , content = 46 | [ Html.h3 47 | [ Typography.subtitle1 ] 48 | [ text "Standard Image List with Text Protection" ] 49 | , standardImageList 50 | , Html.h3 51 | [ Typography.subtitle1 ] 52 | [ text "Masonry Image List" ] 53 | , masonryImageList 54 | ] 55 | } 56 | 57 | 58 | standardImageList : Html msg 59 | standardImageList = 60 | ImageList.imageList 61 | (ImageList.config 62 | |> ImageList.setWithTextProtection True 63 | |> ImageList.setAttributes [ style "max-width" "900px" ] 64 | ) 65 | (List.map standardItem standardImages) 66 | 67 | 68 | masonryImageList : Html msg 69 | masonryImageList = 70 | ImageList.imageList 71 | (ImageList.config 72 | |> ImageList.setMasonry True 73 | |> ImageList.setAttributes 74 | [ style "max-width" "900px" 75 | , style "column-count" "5" 76 | , style "column-gap" "16px" 77 | ] 78 | ) 79 | (List.map masonryItem masonryImages) 80 | 81 | 82 | imageListHeroItem : ImageListItem msg 83 | imageListHeroItem = 84 | ImageListItem.imageListItem 85 | (ImageListItem.config 86 | |> ImageListItem.setAttributes 87 | [ style "width" "calc(100% / 5 - 4.2px)" 88 | , style "margin" "2px" 89 | ] 90 | ) 91 | "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAABNJREFUCB1jZGBg+A/EDEwgAgQADigBA//q6GsAAAAASUVORK5CYII%3D" 92 | 93 | 94 | standardItem : String -> ImageListItem msg 95 | standardItem url = 96 | -- TODO: 97 | -- ImageList.imageAspectContainer 98 | -- [ style "padding-bottom" "66.66667%" ] 99 | ImageListItem.imageListItem 100 | (ImageListItem.config 101 | |> ImageListItem.setLabel (Just "Text label") 102 | |> ImageListItem.setAttributes 103 | [ style "width" "calc(100% / 5 - 4.2px)" 104 | , style "margin" "2px" 105 | ] 106 | ) 107 | url 108 | 109 | 110 | masonryItem : String -> ImageListItem msg 111 | masonryItem url = 112 | ImageListItem.imageListItem 113 | (ImageListItem.config 114 | |> ImageListItem.setLabel (Just "Text label") 115 | |> ImageListItem.setAttributes [ style "margin-bottom" "16px" ] 116 | ) 117 | url 118 | 119 | 120 | standardImages : List String 121 | standardImages = 122 | [ "images/photos/3x2/1.jpg" 123 | , "images/photos/3x2/2.jpg" 124 | , "images/photos/3x2/3.jpg" 125 | , "images/photos/3x2/4.jpg" 126 | , "images/photos/3x2/5.jpg" 127 | , "images/photos/3x2/6.jpg" 128 | , "images/photos/3x2/7.jpg" 129 | , "images/photos/3x2/8.jpg" 130 | , "images/photos/3x2/9.jpg" 131 | , "images/photos/3x2/10.jpg" 132 | , "images/photos/3x2/11.jpg" 133 | , "images/photos/3x2/12.jpg" 134 | , "images/photos/3x2/13.jpg" 135 | , "images/photos/3x2/14.jpg" 136 | , "images/photos/3x2/15.jpg" 137 | ] 138 | 139 | 140 | masonryImages : List String 141 | masonryImages = 142 | [ "images/photos/3x2/16.jpg" 143 | , "images/photos/2x3/1.jpg" 144 | , "images/photos/3x2/1.jpg" 145 | , "images/photos/2x3/2.jpg" 146 | , "images/photos/2x3/3.jpg" 147 | , "images/photos/3x2/2.jpg" 148 | , "images/photos/2x3/4.jpg" 149 | , "images/photos/3x2/3.jpg" 150 | , "images/photos/2x3/5.jpg" 151 | , "images/photos/3x2/4.jpg" 152 | , "images/photos/2x3/6.jpg" 153 | , "images/photos/3x2/5.jpg" 154 | , "images/photos/2x3/7.jpg" 155 | , "images/photos/3x2/6.jpg" 156 | , "images/photos/3x2/7.jpg" 157 | ] 158 | -------------------------------------------------------------------------------- /demo/src/Demo/LayoutGrid.elm: -------------------------------------------------------------------------------- 1 | module Demo.LayoutGrid exposing 2 | ( Model 3 | , Msg(..) 4 | , defaultModel 5 | , update 6 | , view 7 | ) 8 | 9 | import Demo.CatalogPage exposing (CatalogPage) 10 | import Html exposing (Html, text) 11 | import Html.Attributes exposing (style) 12 | import Material.LayoutGrid as LayoutGrid 13 | import Material.Typography as Typography 14 | 15 | 16 | type alias Model = 17 | {} 18 | 19 | 20 | defaultModel : Model 21 | defaultModel = 22 | {} 23 | 24 | 25 | type Msg 26 | = NoOp 27 | 28 | 29 | update : Msg -> Model -> Model 30 | update msg model = 31 | model 32 | 33 | 34 | view : Model -> CatalogPage Msg 35 | view model = 36 | { title = "Layout Grid" 37 | , prelude = "Material design’s responsive UI is based on a 12-column grid layout." 38 | , resources = 39 | { materialDesignGuidelines = Nothing 40 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-LayoutGrid" 41 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-layout-grid" 42 | } 43 | , hero = heroGrid 44 | , content = 45 | [ Html.h3 [ Typography.subtitle1 ] [ text "Columns" ] 46 | , columnsGrid 47 | , Html.h3 [ Typography.subtitle1 ] [ text "Grid Left Alignment" ] 48 | , Html.p 49 | [ Typography.body1 ] 50 | [ text "This requires a max-width on the top-level grid element." ] 51 | , leftAlignedGrid 52 | , Html.h3 [ Typography.subtitle1 ] [ text "Grid Right Alignment" ] 53 | , Html.p 54 | [ Typography.body1 ] 55 | [ text "This requires a max-width on the top-level grid element." ] 56 | , rightAlignedGrid 57 | , Html.h3 [ Typography.subtitle1 ] [ text "Cell Alignment" ] 58 | , Html.p 59 | [ Typography.body1 ] 60 | [ text "Cell alignment requires a cell height smaller than the inner height of the grid." ] 61 | , cellAlignmentGrid 62 | ] 63 | } 64 | 65 | 66 | demoGrid : List (Html.Attribute msg) -> List (Html msg) -> Html msg 67 | demoGrid options = 68 | LayoutGrid.layoutGrid 69 | (style "background" "rgba(0,0,0,.2)" 70 | :: style "min-width" "360px" 71 | :: options 72 | ) 73 | 74 | 75 | demoCell : List (Html.Attribute msg) -> Html msg 76 | demoCell options = 77 | LayoutGrid.cell 78 | (style "background" "rgba(0,0,0,.2)" 79 | :: style "height" "100px" 80 | :: options 81 | ) 82 | [] 83 | 84 | 85 | heroGrid : List (Html msg) 86 | heroGrid = 87 | [ demoGrid [] [ LayoutGrid.inner [] (List.repeat 3 (demoCell [])) ] ] 88 | 89 | 90 | columnsGrid : Html msg 91 | columnsGrid = 92 | demoGrid [] 93 | [ LayoutGrid.inner [] 94 | [ demoCell [ LayoutGrid.span6 ] 95 | , demoCell [ LayoutGrid.span3 ] 96 | , demoCell [ LayoutGrid.span2 ] 97 | , demoCell [ LayoutGrid.span1 ] 98 | , demoCell [ LayoutGrid.span3 ] 99 | , demoCell [ LayoutGrid.span1 ] 100 | , demoCell [ LayoutGrid.span8 ] 101 | ] 102 | ] 103 | 104 | 105 | leftAlignedGrid : Html msg 106 | leftAlignedGrid = 107 | demoGrid 108 | [ LayoutGrid.alignLeft 109 | , style "max-width" "800px" 110 | ] 111 | [ LayoutGrid.inner [] 112 | [ demoCell [] 113 | , demoCell [] 114 | , demoCell [] 115 | ] 116 | ] 117 | 118 | 119 | rightAlignedGrid : Html msg 120 | rightAlignedGrid = 121 | demoGrid 122 | [ LayoutGrid.alignRight 123 | , style "max-width" "800px" 124 | ] 125 | [ LayoutGrid.inner [] (List.repeat 3 (demoCell [])) 126 | ] 127 | 128 | 129 | cellAlignmentGrid : Html msg 130 | cellAlignmentGrid = 131 | let 132 | innerHeight = 133 | [ style "min-height" "200px" ] 134 | 135 | cellHeight = 136 | style "max-height" "50px" 137 | in 138 | demoGrid 139 | [ style "min-height" "200px" 140 | ] 141 | [ LayoutGrid.inner innerHeight 142 | [ demoCell [ LayoutGrid.alignTop, cellHeight ] 143 | , demoCell [ LayoutGrid.alignMiddle, cellHeight ] 144 | , demoCell [ LayoutGrid.alignBottom, cellHeight ] 145 | ] 146 | ] 147 | -------------------------------------------------------------------------------- /demo/src/Demo/LinearProgress.elm: -------------------------------------------------------------------------------- 1 | module Demo.LinearProgress exposing (Model, Msg, defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (text) 5 | import Html.Attributes 6 | import Material.LinearProgress as LinearProgress 7 | import Material.Typography as Typography 8 | 9 | 10 | type alias Model = 11 | {} 12 | 13 | 14 | defaultModel : Model 15 | defaultModel = 16 | {} 17 | 18 | 19 | type Msg 20 | = NoOp 21 | 22 | 23 | update : Msg -> Model -> Model 24 | update msg model = 25 | model 26 | 27 | 28 | view : Model -> CatalogPage Msg 29 | view model = 30 | { title = "Linear Progress Indicator" 31 | , prelude = "Progress indicators display the length of a process or express an unspecified wait time." 32 | , resources = 33 | { materialDesignGuidelines = Just "https://material.io/go/design-progress-indicators" 34 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-LinearProgress" 35 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-linear-progress" 36 | } 37 | , hero = 38 | [ LinearProgress.determinate LinearProgress.config { progress = 0.5 } ] 39 | , content = 40 | [ Html.h3 [ Typography.subtitle1 ] [ text "Determinate" ] 41 | , LinearProgress.determinate LinearProgress.config { progress = 0.5 } 42 | , Html.h3 [ Typography.subtitle1 ] [ text "Buffered" ] 43 | , LinearProgress.buffered LinearProgress.config 44 | { progress = 0.5, buffered = 0.75 } 45 | , Html.h3 [ Typography.subtitle1 ] [ text "Indeterminate" ] 46 | , LinearProgress.indeterminate 47 | (LinearProgress.config 48 | |> LinearProgress.setAttributes [ Html.Attributes.dir "rtl" ] 49 | ) 50 | , Html.h3 [ Typography.subtitle1 ] [ text "Right to Left Localized" ] 51 | , Html.h4 [ Typography.subtitle1 ] [ text "Determinate" ] 52 | , LinearProgress.determinate 53 | (LinearProgress.config 54 | |> LinearProgress.setAttributes [ Html.Attributes.dir "rtl" ] 55 | ) 56 | { progress = 0.5 } 57 | , Html.h4 [ Typography.subtitle1 ] [ text "Buffered" ] 58 | , LinearProgress.buffered 59 | (LinearProgress.config 60 | |> LinearProgress.setAttributes [ Html.Attributes.dir "rtl" ] 61 | ) 62 | { progress = 0.5, buffered = 0.75 } 63 | , Html.h4 [ Typography.subtitle1 ] [ text "Indeterminate" ] 64 | , LinearProgress.indeterminate 65 | (LinearProgress.config 66 | |> LinearProgress.setAttributes [ Html.Attributes.dir "rtl" ] 67 | ) 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /demo/src/Demo/ModalDrawer.elm: -------------------------------------------------------------------------------- 1 | module Demo.ModalDrawer exposing 2 | ( Model 3 | , Msg(..) 4 | , defaultModel 5 | , update 6 | , view 7 | ) 8 | 9 | import Demo.DrawerPage as DrawerPage exposing (DrawerPage) 10 | import Material.Drawer.Modal as ModalDrawer 11 | 12 | 13 | type alias Model = 14 | { open : Bool 15 | , selectedIndex : Int 16 | } 17 | 18 | 19 | defaultModel : Model 20 | defaultModel = 21 | { open = False 22 | , selectedIndex = 0 23 | } 24 | 25 | 26 | type Msg 27 | = OpenDrawer 28 | | CloseDrawer 29 | | SetSelectedIndex Int 30 | 31 | 32 | update : Msg -> Model -> Model 33 | update msg model = 34 | case msg of 35 | OpenDrawer -> 36 | { model | open = True } 37 | 38 | CloseDrawer -> 39 | { model | open = False } 40 | 41 | SetSelectedIndex index -> 42 | { model | selectedIndex = index } 43 | 44 | 45 | view : Model -> DrawerPage Msg 46 | view model = 47 | { title = "Modal Drawer" 48 | , drawer = 49 | ModalDrawer.drawer 50 | (ModalDrawer.config 51 | |> ModalDrawer.setOpen model.open 52 | |> ModalDrawer.setOnClose CloseDrawer 53 | ) 54 | (DrawerPage.drawerBody SetSelectedIndex model.selectedIndex) 55 | , scrim = Just (ModalDrawer.scrim [] []) 56 | , onMenuClick = Just OpenDrawer 57 | } 58 | -------------------------------------------------------------------------------- /demo/src/Demo/PermanentDrawer.elm: -------------------------------------------------------------------------------- 1 | module Demo.PermanentDrawer exposing (Model, Msg, defaultModel, update, view) 2 | 3 | import Demo.DrawerPage as DrawerPage exposing (DrawerPage) 4 | import Material.Drawer.Permanent as PermanentDrawer 5 | 6 | 7 | type alias Model = 8 | { selectedIndex : Int } 9 | 10 | 11 | defaultModel : Model 12 | defaultModel = 13 | { selectedIndex = 0 } 14 | 15 | 16 | type Msg 17 | = SetSelectedIndex Int 18 | 19 | 20 | update : Msg -> Model -> Model 21 | update msg model = 22 | case msg of 23 | SetSelectedIndex index -> 24 | { model | selectedIndex = index } 25 | 26 | 27 | view : Model -> DrawerPage Msg 28 | view model = 29 | { title = "Permanent Drawer" 30 | , drawer = 31 | PermanentDrawer.drawer PermanentDrawer.config 32 | (DrawerPage.drawerBody SetSelectedIndex model.selectedIndex) 33 | , scrim = Nothing 34 | , onMenuClick = Nothing 35 | } 36 | -------------------------------------------------------------------------------- /demo/src/Demo/ProminentTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.ProminentTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Html exposing (text) 5 | import Material.IconButton as IconButton 6 | import Material.TopAppBar as TopAppBar 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> TopAppBarPage Msg 28 | view model = 29 | { fixedAdjust = TopAppBar.prominentFixedAdjust 30 | , topAppBar = 31 | TopAppBar.prominent TopAppBar.config 32 | [ TopAppBar.row [] 33 | [ TopAppBar.section 34 | [ TopAppBar.alignStart ] 35 | [ IconButton.iconButton 36 | (IconButton.config 37 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 38 | ) 39 | (IconButton.icon "menu") 40 | , Html.span [ TopAppBar.title ] [ text "Prominent" ] 41 | ] 42 | , TopAppBar.section 43 | [ TopAppBar.alignEnd ] 44 | [ IconButton.iconButton 45 | (IconButton.config 46 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 47 | ) 48 | (IconButton.icon "file_download") 49 | , IconButton.iconButton 50 | (IconButton.config 51 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 52 | ) 53 | (IconButton.icon "print") 54 | , IconButton.iconButton 55 | (IconButton.config 56 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 57 | ) 58 | (IconButton.icon "bookmark") 59 | ] 60 | ] 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/Demo/RadioButtons.elm: -------------------------------------------------------------------------------- 1 | module Demo.RadioButtons exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Browser.Dom 4 | import Demo.CatalogPage exposing (CatalogPage) 5 | import Dict exposing (Dict) 6 | import Html exposing (Html, text) 7 | import Html.Attributes exposing (style) 8 | import Material.Button as Button 9 | import Material.FormField as FormField 10 | import Material.Radio as Radio 11 | import Material.Typography as Typography 12 | import Task 13 | 14 | 15 | type alias Model = 16 | { radios : Dict String String } 17 | 18 | 19 | defaultModel : Model 20 | defaultModel = 21 | { radios = 22 | Dict.fromList 23 | [ ( "hero", "radio-buttons-hero-radio-1" ) 24 | , ( "example", "radio-buttons-example-radio-1" ) 25 | ] 26 | } 27 | 28 | 29 | type Msg 30 | = Set String String 31 | | Focus String 32 | | Focused (Result Browser.Dom.Error ()) 33 | 34 | 35 | update : Msg -> Model -> ( Model, Cmd Msg ) 36 | update msg model = 37 | case msg of 38 | Set group index -> 39 | ( { model | radios = Dict.insert group index model.radios }, Cmd.none ) 40 | 41 | Focus id -> 42 | ( model, Task.attempt Focused (Browser.Dom.focus id) ) 43 | 44 | Focused _ -> 45 | ( model, Cmd.none ) 46 | 47 | 48 | isSelected : String -> String -> Model -> Bool 49 | isSelected group index model = 50 | Dict.get group model.radios 51 | |> Maybe.map ((==) index) 52 | |> Maybe.withDefault False 53 | 54 | 55 | view : Model -> CatalogPage Msg 56 | view model = 57 | { title = "Radio Button" 58 | , prelude = "Buttons communicate an action a user can take. They are typically placed throughout your UI, in places like dialogs, forms, cards, and toolbars." 59 | , resources = 60 | { materialDesignGuidelines = Just "https://material.io/go/design-radio-buttons" 61 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Radio" 62 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-radio" 63 | } 64 | , hero = [ heroRadioGroup model ] 65 | , content = 66 | [ Html.h3 [ Typography.subtitle1 ] [ text "Radio Buttons" ] 67 | , exampleRadioGroup model 68 | , Html.h3 [ Typography.subtitle1 ] [ text "Focus Radio Button" ] 69 | , focusRadio 70 | ] 71 | } 72 | 73 | 74 | heroRadio : Model -> String -> String -> Html Msg 75 | heroRadio model group index = 76 | Radio.radio 77 | (Radio.config 78 | |> Radio.setChecked (isSelected group index model) 79 | |> Radio.setOnChange (Set group index) 80 | |> Radio.setAttributes [ style "margin" "0 10px" ] 81 | ) 82 | 83 | 84 | heroRadioGroup : Model -> Html Msg 85 | heroRadioGroup model = 86 | Html.div [] 87 | [ heroRadio model "hero" "radio-buttons-hero-radio-1" 88 | , heroRadio model "hero" "radio-buttons-hero-radio-2" 89 | ] 90 | 91 | 92 | radio : Model -> String -> String -> String -> Html Msg 93 | radio model group index label = 94 | FormField.formField 95 | (FormField.config 96 | |> FormField.setLabel (Just label) 97 | |> FormField.setFor (Just index) 98 | |> FormField.setOnClick (Set group index) 99 | |> FormField.setAttributes [ style "margin" "0 10px" ] 100 | ) 101 | [ Radio.radio 102 | (Radio.config 103 | |> Radio.setChecked (isSelected group index model) 104 | |> Radio.setOnChange (Set group index) 105 | ) 106 | ] 107 | 108 | 109 | exampleRadioGroup : Model -> Html Msg 110 | exampleRadioGroup model = 111 | Html.div [] 112 | [ radio model "example" "radio-buttons-example-radio-1" "Radio 1" 113 | , radio model "example" "radio-buttons-example-radio-2" "Radio 2" 114 | ] 115 | 116 | 117 | focusRadio : Html Msg 118 | focusRadio = 119 | Html.div [] 120 | [ Radio.radio 121 | (Radio.config |> Radio.setAttributes [ Html.Attributes.id "my-radio" ]) 122 | , text "\u{00A0}" 123 | , Button.raised 124 | (Button.config |> Button.setOnClick (Focus "my-radio")) 125 | "Focus" 126 | ] 127 | -------------------------------------------------------------------------------- /demo/src/Demo/Ripple.elm: -------------------------------------------------------------------------------- 1 | module Demo.Ripple exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (text) 5 | import Html.Attributes exposing (class, style) 6 | import Material.Elevation as Elevation 7 | import Material.Ripple as Ripple 8 | import Material.Typography as Typography 9 | 10 | 11 | type alias Model = 12 | {} 13 | 14 | 15 | defaultModel : Model 16 | defaultModel = 17 | {} 18 | 19 | 20 | type Msg 21 | = NoOp 22 | 23 | 24 | update : Msg -> Model -> Model 25 | update msg model = 26 | model 27 | 28 | 29 | view : Model -> CatalogPage Msg 30 | view model = 31 | { title = "Ripple" 32 | , prelude = "Ripples are visual representations used to communicate the status of a component or interactive element." 33 | , resources = 34 | { materialDesignGuidelines = Just "https://material.io/go/design-states" 35 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Ripple" 36 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-ripple" 37 | } 38 | , hero = [ Html.div demoBox [ text "Click here!", Ripple.bounded Ripple.config ] ] 39 | , content = 40 | [ Html.h3 [ Typography.subtitle1 ] [ text "Bounded Ripple" ] 41 | , Html.div demoBox 42 | [ text "Interact with me!" 43 | , Ripple.bounded Ripple.config 44 | ] 45 | , Html.h3 [ Typography.subtitle1 ] [ text "Unbounded Ripple" ] 46 | , Html.div demoIcon 47 | [ text "favorite" 48 | , Ripple.unbounded Ripple.config 49 | ] 50 | , Html.h3 [ Typography.subtitle1 ] [ text "Theme Color: Primary" ] 51 | , Html.div demoBox 52 | [ text "Primary" 53 | , Ripple.bounded (Ripple.config |> Ripple.setColor (Just Ripple.primary)) 54 | ] 55 | , Html.h3 [ Typography.subtitle1 ] [ text "Theme Color: Secondary" ] 56 | , Html.div demoBox 57 | [ text "Secondary" 58 | , Ripple.bounded (Ripple.config |> Ripple.setColor (Just Ripple.accent)) 59 | ] 60 | ] 61 | } 62 | 63 | 64 | demoBox : List (Html.Attribute msg) 65 | demoBox = 66 | [ style "display" "flex" 67 | , style "align-items" "center" 68 | , style "justify-content" "center" 69 | , style "width" "200px" 70 | , style "height" "100px" 71 | , style "padding" "1rem" 72 | , style "cursor" "pointer" 73 | , style "user-select" "none" 74 | , style "background-color" "#fff" 75 | , style "overflow" "hidden" 76 | , style "position" "relative" 77 | , Elevation.z2 78 | , Html.Attributes.tabindex 0 79 | ] 80 | 81 | 82 | demoIcon : List (Html.Attribute msg) 83 | demoIcon = 84 | [ class "material-icons" 85 | , style "width" "24px" 86 | , style "height" "24px" 87 | , style "padding" "12px" 88 | , style "cursor" "pointer" 89 | , style "border-radius" "50%" 90 | , style "position" "relative" 91 | , Html.Attributes.tabindex 0 92 | ] 93 | -------------------------------------------------------------------------------- /demo/src/Demo/ShortCollapsedTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.ShortCollapsedTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Material.IconButton as IconButton 5 | import Material.TopAppBar as TopAppBar 6 | 7 | 8 | type alias Model = 9 | {} 10 | 11 | 12 | defaultModel : Model 13 | defaultModel = 14 | {} 15 | 16 | 17 | type Msg 18 | = NoOp 19 | 20 | 21 | update : Msg -> Model -> Model 22 | update msg model = 23 | model 24 | 25 | 26 | view : Model -> TopAppBarPage Msg 27 | view model = 28 | { fixedAdjust = TopAppBar.shortFixedAdjust 29 | , topAppBar = 30 | TopAppBar.shortCollapsed TopAppBar.config 31 | [ TopAppBar.row [] 32 | [ TopAppBar.section 33 | [ TopAppBar.alignStart ] 34 | [ IconButton.iconButton 35 | (IconButton.config 36 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 37 | ) 38 | (IconButton.icon "menu") 39 | ] 40 | , TopAppBar.section 41 | [ TopAppBar.alignEnd ] 42 | [ IconButton.iconButton 43 | (IconButton.config 44 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 45 | ) 46 | (IconButton.icon "file_download") 47 | ] 48 | ] 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /demo/src/Demo/ShortTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.ShortTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Html exposing (text) 5 | import Material.IconButton as IconButton 6 | import Material.TopAppBar as TopAppBar 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> TopAppBarPage Msg 28 | view model = 29 | { fixedAdjust = TopAppBar.shortFixedAdjust 30 | , topAppBar = 31 | TopAppBar.short TopAppBar.config 32 | [ TopAppBar.row [] 33 | [ TopAppBar.section 34 | [ TopAppBar.alignStart ] 35 | [ IconButton.iconButton 36 | (IconButton.config 37 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 38 | ) 39 | (IconButton.icon "menu") 40 | , Html.span [ TopAppBar.title ] [ text "Short" ] 41 | ] 42 | , TopAppBar.section 43 | [ TopAppBar.alignEnd ] 44 | [ IconButton.iconButton 45 | (IconButton.config 46 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 47 | ) 48 | (IconButton.icon "file_download") 49 | ] 50 | ] 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /demo/src/Demo/Slider.elm: -------------------------------------------------------------------------------- 1 | module Demo.Slider exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Browser.Dom 4 | import Demo.CatalogPage exposing (CatalogPage) 5 | import Dict exposing (Dict) 6 | import Html exposing (Html, text) 7 | import Html.Attributes 8 | import Material.Button as Button 9 | import Material.Slider as Slider 10 | import Material.Typography as Typography 11 | import Task 12 | 13 | 14 | type alias Model = 15 | { sliders : Dict String Float } 16 | 17 | 18 | defaultModel : Model 19 | defaultModel = 20 | { sliders = 21 | Dict.fromList 22 | [ ( "hero-slider", 25 ) 23 | , ( "continuous-slider", 25 ) 24 | , ( "discrete-slider", 25 ) 25 | , ( "discrete-slider-with-tick-marks", 25 ) 26 | ] 27 | } 28 | 29 | 30 | type Msg 31 | = Changed String Float 32 | | Focus String 33 | | Focused (Result Browser.Dom.Error ()) 34 | 35 | 36 | update : Msg -> Model -> ( Model, Cmd Msg ) 37 | update msg model = 38 | case msg of 39 | Changed id value -> 40 | ( { model | sliders = Dict.insert id value model.sliders }, Cmd.none ) 41 | 42 | Focus id -> 43 | ( model, Task.attempt Focused (Browser.Dom.focus id) ) 44 | 45 | Focused _ -> 46 | ( model, Cmd.none ) 47 | 48 | 49 | view : Model -> CatalogPage Msg 50 | view model = 51 | { title = "Slider" 52 | , prelude = "Sliders let users select from a range of values by moving the slider thumb." 53 | , resources = 54 | { materialDesignGuidelines = Just "https://material.io/go/design-sliders" 55 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Slider" 56 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-slider" 57 | } 58 | , hero = [ heroSlider model ] 59 | , content = 60 | [ Html.h3 [ Typography.subtitle1 ] [ text "Continuous" ] 61 | , continuousSlider model 62 | , Html.h3 [ Typography.subtitle1 ] [ text "Discrete" ] 63 | , discreteSlider model 64 | , Html.h3 [ Typography.subtitle1 ] [ text "Discrete with Markers" ] 65 | , discreteSliderWithMarkers model 66 | , Html.h3 [ Typography.subtitle1 ] [ text "Focus Slider" ] 67 | , focusSlider model 68 | ] 69 | } 70 | 71 | 72 | heroSlider : Model -> Html Msg 73 | heroSlider model = 74 | let 75 | id = 76 | "hero-slider" 77 | in 78 | Slider.slider 79 | (Slider.config 80 | |> Slider.setValue (Maybe.withDefault 0 (Dict.get id model.sliders)) 81 | |> Slider.setOnInput (Changed id) 82 | ) 83 | 84 | 85 | continuousSlider : Model -> Html Msg 86 | continuousSlider model = 87 | let 88 | id = 89 | "continuous-slider" 90 | in 91 | Slider.slider 92 | (Slider.config 93 | |> Slider.setValue (Maybe.withDefault 0 (Dict.get id model.sliders)) 94 | |> Slider.setOnInput (Changed id) 95 | |> Slider.setMin 0 96 | |> Slider.setMax 50 97 | ) 98 | 99 | 100 | discreteSlider : Model -> Html Msg 101 | discreteSlider model = 102 | let 103 | id = 104 | "discrete-slider" 105 | in 106 | Slider.slider 107 | (Slider.config 108 | |> Slider.setValue (Maybe.withDefault 0 (Dict.get id model.sliders)) 109 | |> Slider.setOnInput (Changed id) 110 | |> Slider.setDiscrete True 111 | |> Slider.setMin 0 112 | |> Slider.setMax 50 113 | |> Slider.setStep 1 114 | ) 115 | 116 | 117 | discreteSliderWithMarkers : Model -> Html Msg 118 | discreteSliderWithMarkers model = 119 | let 120 | id = 121 | "discrete-slider-with-markers" 122 | in 123 | Slider.slider 124 | (Slider.config 125 | |> Slider.setValue (Maybe.withDefault 0 (Dict.get id model.sliders)) 126 | |> Slider.setOnInput (Changed id) 127 | |> Slider.setDiscrete True 128 | |> Slider.setMin 0 129 | |> Slider.setMax 50 130 | |> Slider.setStep 10 131 | |> Slider.setDisplayMarkers True 132 | ) 133 | 134 | 135 | focusSlider : Model -> Html Msg 136 | focusSlider model = 137 | let 138 | id = 139 | "my-slider" 140 | in 141 | Html.div [] 142 | [ Slider.slider 143 | (Slider.config 144 | |> Slider.setValue 145 | (Maybe.withDefault 0 (Dict.get id model.sliders)) 146 | |> Slider.setOnInput (Changed id) 147 | |> Slider.setAttributes [ Html.Attributes.id id ] 148 | ) 149 | , text "\u{00A0}" 150 | , Button.raised 151 | (Button.config |> Button.setOnClick (Focus id)) 152 | "Focus" 153 | ] 154 | -------------------------------------------------------------------------------- /demo/src/Demo/Snackbar.elm: -------------------------------------------------------------------------------- 1 | module Demo.Snackbar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (Html, text) 5 | import Html.Attributes exposing (class, style) 6 | import Material.Button as Button 7 | import Material.Snackbar as Snackbar 8 | import Platform.Cmd exposing (Cmd) 9 | 10 | 11 | type alias Model = 12 | { queue : Snackbar.Queue Msg } 13 | 14 | 15 | defaultModel : Model 16 | defaultModel = 17 | { queue = Snackbar.initialQueue } 18 | 19 | 20 | type Msg 21 | = ShowBaseline 22 | | ShowLeading 23 | | ShowStacked 24 | | SnackbarClosed Snackbar.MessageId 25 | | Click Snackbar.MessageId 26 | 27 | 28 | update : Msg -> Model -> ( Model, Cmd Msg ) 29 | update msg model = 30 | case msg of 31 | ShowBaseline -> 32 | ( { model | queue = Snackbar.addMessage baselineMessage model.queue } 33 | , Cmd.none 34 | ) 35 | 36 | ShowLeading -> 37 | ( { model | queue = Snackbar.addMessage leadingMessage model.queue } 38 | , Cmd.none 39 | ) 40 | 41 | ShowStacked -> 42 | ( { model | queue = Snackbar.addMessage stackedMessage model.queue } 43 | , Cmd.none 44 | ) 45 | 46 | SnackbarClosed messageId -> 47 | ( { model | queue = Snackbar.close messageId model.queue }, Cmd.none ) 48 | 49 | Click messageId -> 50 | ( model, Cmd.none ) 51 | 52 | 53 | baselineMessage : Snackbar.Message Msg 54 | baselineMessage = 55 | Snackbar.message "Can't send photo. Retry in 5 seconds." 56 | |> Snackbar.setActionButton (Just "Retry") 57 | |> Snackbar.setOnActionButtonClick Click 58 | |> Snackbar.setActionIcon (Just (Snackbar.icon "close")) 59 | 60 | 61 | leadingMessage : Snackbar.Message Msg 62 | leadingMessage = 63 | Snackbar.message "Your photo has been archived." 64 | |> Snackbar.setLeading True 65 | |> Snackbar.setActionButton (Just "Undo") 66 | |> Snackbar.setOnActionButtonClick Click 67 | |> Snackbar.setActionIcon (Just (Snackbar.icon "close")) 68 | 69 | 70 | stackedMessage : Snackbar.Message Msg 71 | stackedMessage = 72 | Snackbar.message "This item already has the label \"travel\". You can add a new label." 73 | |> Snackbar.setStacked True 74 | |> Snackbar.setActionButton (Just "Add a new label") 75 | |> Snackbar.setOnActionButtonClick Click 76 | |> Snackbar.setActionIcon (Just (Snackbar.icon "close")) 77 | 78 | 79 | view : Model -> CatalogPage Msg 80 | view model = 81 | { title = "Snackbar" 82 | , prelude = "Snackbars provide brief feedback about an operation through a message at the bottom of the screen." 83 | , resources = 84 | { materialDesignGuidelines = Just "https://material.io/go/design-snackbar" 85 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Snackbar" 86 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-snackbar" 87 | } 88 | , hero = [ heroMessage ] 89 | , content = 90 | [ Button.raised 91 | (Button.config 92 | |> Button.setOnClick ShowBaseline 93 | |> Button.setAttributes buttonMargin 94 | ) 95 | "Baseline" 96 | , text " " 97 | , Button.raised 98 | (Button.config 99 | |> Button.setOnClick ShowLeading 100 | |> Button.setAttributes buttonMargin 101 | ) 102 | "Leading" 103 | , text " " 104 | , Button.raised 105 | (Button.config 106 | |> Button.setOnClick ShowStacked 107 | |> Button.setAttributes buttonMargin 108 | ) 109 | "Stacked" 110 | , Snackbar.snackbar 111 | (Snackbar.config { onClosed = SnackbarClosed } 112 | |> Snackbar.setCloseOnEscape True 113 | ) 114 | model.queue 115 | ] 116 | } 117 | 118 | 119 | buttonMargin : List (Html.Attribute msg) 120 | buttonMargin = 121 | [ style "margin" "14px" ] 122 | 123 | 124 | heroMessage : Html msg 125 | heroMessage = 126 | Html.div 127 | [ class "mdc-snackbar mdc-snackbar--open" 128 | , style "position" "relative" 129 | , style "left" "0" 130 | , style "transform" "none" 131 | ] 132 | [ Html.div 133 | [ class "mdc-snackbar__surface" ] 134 | [ Html.div 135 | [ class "mdc-snackbar__label" 136 | , style "color" "hsla(0,0%,100%,.87)" 137 | , Html.Attributes.attribute "role" "status" 138 | , Html.Attributes.attribute "aria-live" "polite" 139 | ] 140 | [ text "Can't send photo. Retry in 5 seconds." ] 141 | , Html.div 142 | [ class "mdc-snackbar__actions" ] 143 | [ Html.button 144 | [ class "mdc-button" 145 | , class "mdc-snackbar__action" 146 | , Html.Attributes.type_ "button" 147 | ] 148 | [ text "Retry" ] 149 | , Html.button 150 | [ class "mdc-icon-button" 151 | , class "mdc-snackbar__dismiss" 152 | , class "material-icons" 153 | ] 154 | [ text "close" ] 155 | ] 156 | ] 157 | ] 158 | -------------------------------------------------------------------------------- /demo/src/Demo/StandardTopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.StandardTopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.TopAppBarPage exposing (TopAppBarPage) 4 | import Html exposing (text) 5 | import Material.IconButton as IconButton 6 | import Material.TopAppBar as TopAppBar 7 | 8 | 9 | type alias Model = 10 | {} 11 | 12 | 13 | defaultModel : Model 14 | defaultModel = 15 | {} 16 | 17 | 18 | type Msg 19 | = NoOp 20 | 21 | 22 | update : Msg -> Model -> Model 23 | update msg model = 24 | model 25 | 26 | 27 | view : Model -> TopAppBarPage Msg 28 | view model = 29 | { fixedAdjust = TopAppBar.fixedAdjust 30 | , topAppBar = 31 | TopAppBar.regular TopAppBar.config 32 | [ TopAppBar.row [] 33 | [ TopAppBar.section 34 | [ TopAppBar.alignStart ] 35 | [ IconButton.iconButton 36 | (IconButton.config 37 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 38 | ) 39 | (IconButton.icon "menu") 40 | , Html.span [ TopAppBar.title ] [ text "Standard" ] 41 | ] 42 | , TopAppBar.section 43 | [ TopAppBar.alignEnd ] 44 | [ IconButton.iconButton 45 | (IconButton.config 46 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 47 | ) 48 | (IconButton.icon "file_download") 49 | , IconButton.iconButton 50 | (IconButton.config 51 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 52 | ) 53 | (IconButton.icon "print") 54 | , IconButton.iconButton 55 | (IconButton.config 56 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 57 | ) 58 | (IconButton.icon "bookmark") 59 | ] 60 | ] 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/Demo/Switch.elm: -------------------------------------------------------------------------------- 1 | module Demo.Switch exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Browser.Dom 4 | import Demo.CatalogPage exposing (CatalogPage) 5 | import Dict exposing (Dict) 6 | import Html exposing (Html, text) 7 | import Html.Attributes 8 | import Material.Button as Button 9 | import Material.FormField as FormField 10 | import Material.Switch as Switch 11 | import Material.Typography as Typography 12 | import Task 13 | 14 | 15 | type alias Model = 16 | { switches : Dict String Bool } 17 | 18 | 19 | defaultModel : Model 20 | defaultModel = 21 | { switches = Dict.fromList [ ( "hero-switch", True ) ] } 22 | 23 | 24 | type Msg 25 | = Toggle String 26 | | Focus String 27 | | Focused (Result Browser.Dom.Error ()) 28 | 29 | 30 | update : Msg -> Model -> ( Model, Cmd Msg ) 31 | update msg model = 32 | case msg of 33 | Toggle id -> 34 | ( { model 35 | | switches = 36 | Dict.update id 37 | (\state -> Just (not (Maybe.withDefault False state))) 38 | model.switches 39 | } 40 | , Cmd.none 41 | ) 42 | 43 | Focus id -> 44 | ( model, Task.attempt Focused (Browser.Dom.focus id) ) 45 | 46 | Focused _ -> 47 | ( model, Cmd.none ) 48 | 49 | 50 | isChecked : String -> Model -> Bool 51 | isChecked id model = 52 | Maybe.withDefault False (Dict.get id model.switches) 53 | 54 | 55 | view : Model -> CatalogPage Msg 56 | view model = 57 | { title = "Switch" 58 | , prelude = "Switches communicate an action a user can take. They are typically placed throughout your UI, in places like dialogs, forms, cards, and toolbars." 59 | , resources = 60 | { materialDesignGuidelines = Just "https://material.io/go/design-switches" 61 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Switch" 62 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-switch" 63 | } 64 | , hero = heroSwitch model 65 | , content = 66 | [ Html.h3 [ Typography.subtitle1 ] [ text "Switch" ] 67 | , demoSwitch model 68 | , Html.h3 [ Typography.subtitle1 ] [ text "Focus Switch" ] 69 | , focusSwitch model 70 | ] 71 | } 72 | 73 | 74 | heroSwitch : Model -> List (Html Msg) 75 | heroSwitch model = 76 | let 77 | id = 78 | "hero-switch" 79 | in 80 | [ FormField.formField 81 | (FormField.config 82 | |> FormField.setLabel (Just "off/on") 83 | |> FormField.setFor (Just id) 84 | |> FormField.setOnClick (Toggle id) 85 | ) 86 | [ Switch.switch 87 | (Switch.config 88 | |> Switch.setChecked (isChecked id model) 89 | |> Switch.setOnChange (Toggle id) 90 | ) 91 | ] 92 | ] 93 | 94 | 95 | demoSwitch : Model -> Html Msg 96 | demoSwitch model = 97 | let 98 | id = 99 | "demo-switch" 100 | in 101 | FormField.formField 102 | (FormField.config 103 | |> FormField.setLabel (Just "off/on") 104 | |> FormField.setFor (Just id) 105 | |> FormField.setOnClick (Toggle id) 106 | ) 107 | [ Switch.switch 108 | (Switch.config 109 | |> Switch.setChecked (isChecked id model) 110 | |> Switch.setOnChange (Toggle id) 111 | ) 112 | ] 113 | 114 | 115 | focusSwitch : Model -> Html Msg 116 | focusSwitch model = 117 | let 118 | id = 119 | "my-switch" 120 | in 121 | Html.div [] 122 | [ FormField.formField 123 | (FormField.config 124 | |> FormField.setLabel (Just "off/on") 125 | |> FormField.setFor (Just id) 126 | |> FormField.setOnClick (Toggle id) 127 | |> FormField.setAttributes [ Html.Attributes.id "my-form-field" ] 128 | ) 129 | [ Switch.switch 130 | (Switch.config 131 | |> Switch.setChecked (isChecked id model) 132 | |> Switch.setOnChange (Toggle id) 133 | |> Switch.setAttributes [ Html.Attributes.id id ] 134 | ) 135 | ] 136 | , text "\u{00A0}" 137 | , Button.raised 138 | (Button.config |> Button.setOnClick (Focus "my-switch")) 139 | "Focus switch" 140 | , Button.raised 141 | (Button.config |> Button.setOnClick (Focus "my-form-field")) 142 | "Focus form field" 143 | ] 144 | -------------------------------------------------------------------------------- /demo/src/Demo/TopAppBar.elm: -------------------------------------------------------------------------------- 1 | module Demo.TopAppBar exposing (Model, Msg(..), defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Demo.Url as Url exposing (Url) 5 | import Html exposing (Html, text) 6 | import Html.Attributes exposing (style) 7 | import Material.IconButton as IconButton 8 | import Material.TopAppBar as TopAppBar 9 | import Material.Typography as Typography 10 | 11 | 12 | type alias Model = 13 | {} 14 | 15 | 16 | defaultModel : Model 17 | defaultModel = 18 | {} 19 | 20 | 21 | type Msg 22 | = NoOp 23 | 24 | 25 | update : Msg -> Model -> Model 26 | update msg model = 27 | model 28 | 29 | 30 | view : Model -> CatalogPage Msg 31 | view model = 32 | { title = "Top App Bar" 33 | , prelude = "Top App Bars are a container for items such as application title, navigation icon, and action items." 34 | , resources = 35 | { materialDesignGuidelines = Just "https://material.io/go/design-app-bar-top" 36 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-TopAppBar" 37 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-top-app-bar" 38 | } 39 | , hero = 40 | [ Html.div 41 | [ style "width" "480px" 42 | , style "height" "72px" 43 | ] 44 | [ TopAppBar.regular 45 | (TopAppBar.config |> TopAppBar.setAttributes [ style "position" "static" ]) 46 | [ TopAppBar.section 47 | [ TopAppBar.alignStart ] 48 | [ IconButton.iconButton 49 | (IconButton.config 50 | |> IconButton.setAttributes [ TopAppBar.navigationIcon ] 51 | ) 52 | (IconButton.icon "menu") 53 | , Html.span [ TopAppBar.title ] [ text "Title" ] 54 | ] 55 | , TopAppBar.section 56 | [ TopAppBar.alignEnd ] 57 | [ IconButton.iconButton 58 | (IconButton.config 59 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 60 | ) 61 | (IconButton.icon "file_download") 62 | , IconButton.iconButton 63 | (IconButton.config 64 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 65 | ) 66 | (IconButton.icon "print") 67 | , IconButton.iconButton 68 | (IconButton.config 69 | |> IconButton.setAttributes [ TopAppBar.actionItem ] 70 | ) 71 | (IconButton.icon "more_vert") 72 | ] 73 | ] 74 | ] 75 | ] 76 | , content = 77 | [ Html.div 78 | [ style "display" "-ms-flexbox" 79 | , style "display" "flex" 80 | , style "-ms-flex-wrap" "wrap" 81 | , style "flex-wrap" "wrap" 82 | , style "min-height" "200px" 83 | ] 84 | [ iframe "Standard" Url.StandardTopAppBar 85 | , iframe "Fixed" Url.FixedTopAppBar 86 | , iframe "Dense" Url.DenseTopAppBar 87 | , iframe "Prominent" Url.ProminentTopAppBar 88 | , iframe "Short" Url.ShortTopAppBar 89 | , iframe "Short - Always Collapsed" Url.ShortCollapsedTopAppBar 90 | ] 91 | ] 92 | } 93 | 94 | 95 | iframe : String -> Url -> Html msg 96 | iframe title url = 97 | let 98 | stringUrl = 99 | Url.toString url 100 | in 101 | Html.div 102 | [ style "display" "inline-block" 103 | , style "-ms-flex" "1 1 45%" 104 | , style "flex" "1 1 45%" 105 | , style "-ms-flex-pack" "distribute" 106 | , style "justify-content" "space-around" 107 | , style "min-height" "200px" 108 | , style "min-width" "400px" 109 | , style "padding" "15px" 110 | ] 111 | [ Html.div [] 112 | [ Html.a 113 | [ Html.Attributes.href stringUrl 114 | , Html.Attributes.target "_blank" 115 | ] 116 | [ Html.h3 [ Typography.subtitle1 ] [ text title ] 117 | ] 118 | ] 119 | , Html.iframe 120 | [ style "width" "100%" 121 | , style "height" "200px" 122 | , Html.Attributes.src stringUrl 123 | ] 124 | [] 125 | ] 126 | -------------------------------------------------------------------------------- /demo/src/Demo/TopAppBarPage.elm: -------------------------------------------------------------------------------- 1 | module Demo.TopAppBarPage exposing (TopAppBarPage, view) 2 | 3 | import Html exposing (Html, text) 4 | import Html.Attributes exposing (style) 5 | import Material.Typography as Typography 6 | 7 | 8 | type alias TopAppBarPage msg = 9 | { fixedAdjust : Html.Attribute msg 10 | , topAppBar : Html msg 11 | } 12 | 13 | 14 | view : (msg -> topMsg) -> TopAppBarPage msg -> Html topMsg 15 | view lift { topAppBar, fixedAdjust } = 16 | Html.map lift <| 17 | Html.div 18 | [ style "height" "200vh" 19 | , Typography.typography 20 | ] 21 | [ topAppBar 22 | , Html.div [ fixedAdjust ] 23 | (List.repeat 4 (Html.p [] [ text demoParagraph ])) 24 | ] 25 | 26 | 27 | demoParagraph : String 28 | demoParagraph = 29 | """ 30 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 31 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim 32 | veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 33 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate 34 | velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat 35 | cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id 36 | est laborum. 37 | """ 38 | -------------------------------------------------------------------------------- /demo/src/Demo/Typography.elm: -------------------------------------------------------------------------------- 1 | module Demo.Typography exposing (Model, Msg, defaultModel, update, view) 2 | 3 | import Demo.CatalogPage exposing (CatalogPage) 4 | import Html exposing (text) 5 | import Material.Typography as Typography 6 | 7 | 8 | type alias Model = 9 | {} 10 | 11 | 12 | defaultModel : Model 13 | defaultModel = 14 | {} 15 | 16 | 17 | type Msg 18 | = NoOp 19 | 20 | 21 | update : Msg -> Model -> Model 22 | update msg model = 23 | model 24 | 25 | 26 | view : Model -> CatalogPage Msg 27 | view model = 28 | { title = "Typography" 29 | , prelude = "Roboto is the standard typeface on Android and Chrome." 30 | , resources = 31 | { materialDesignGuidelines = Just "https://material.io/go/design-typography" 32 | , documentation = Just "https://package.elm-lang.org/packages/aforemny/material-components-web-elm/latest/Material-Typography" 33 | , sourceCode = Just "https://github.com/material-components/material-components-web/tree/master/packages/mdc-typography" 34 | } 35 | , hero = [ Html.h1 [ Typography.headline1 ] [ text "Typography" ] ] 36 | , content = 37 | [ Html.h1 [ Typography.headline1 ] [ text "Headline 1" ] 38 | , Html.h2 [ Typography.headline2 ] [ text "Headline 2" ] 39 | , Html.h3 [ Typography.headline3 ] [ text "Headline 3" ] 40 | , Html.h4 [ Typography.headline4 ] [ text "Headline 4" ] 41 | , Html.h5 [ Typography.headline5 ] [ text "Headline 5" ] 42 | , Html.h6 [ Typography.headline6 ] [ text "Headline 6" ] 43 | , Html.h6 [ Typography.subtitle1 ] [ text "Subtitle 1" ] 44 | , Html.h6 [ Typography.subtitle2 ] [ text "Subtitle 2" ] 45 | , Html.p [ Typography.body1 ] [ text body1Paragraph ] 46 | , Html.p [ Typography.body2 ] [ text body2Paragraph ] 47 | , Html.div [ Typography.button ] [ text "Button text" ] 48 | , Html.div [ Typography.caption ] [ text "Caption text" ] 49 | , Html.div [ Typography.overline ] [ text "Overline text" ] 50 | ] 51 | } 52 | 53 | 54 | body1Paragraph = 55 | "Body 1. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur unde suscipit, quam beatae rerum inventore consectetur, neque doloribus, cupiditate numquam dignissimos laborum fugiat deleniti? Eum quasi quidem quibusdam." 56 | 57 | 58 | body2Paragraph = 59 | "Body 2. Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate aliquid ad quas sunt voluptatum officia dolorum cumque, possimus nihil molestias sapiente necessitatibus dolor saepe inventore, soluta id accusantium voluptas beatae." 60 | -------------------------------------------------------------------------------- /elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "package", 3 | "name": "aforemny/material-components-web-elm", 4 | "summary": "Material Components for Elm", 5 | "license": "MIT", 6 | "version": "9.1.0", 7 | "exposed-modules": { 8 | "Material": [ 9 | "Material.Button", 10 | "Material.Card", 11 | "Material.Checkbox", 12 | "Material.Chip.Action", 13 | "Material.Chip.Choice", 14 | "Material.Chip.Filter", 15 | "Material.Chip.Input", 16 | "Material.ChipSet.Action", 17 | "Material.ChipSet.Choice", 18 | "Material.ChipSet.Filter", 19 | "Material.ChipSet.Input", 20 | "Material.CircularProgress", 21 | "Material.DataTable", 22 | "Material.Dialog", 23 | "Material.Drawer.Dismissible", 24 | "Material.Drawer.Modal", 25 | "Material.Drawer.Permanent", 26 | "Material.Elevation", 27 | "Material.Fab", 28 | "Material.Fab.Extended", 29 | "Material.FormField", 30 | "Material.HelperText", 31 | "Material.Icon", 32 | "Material.IconButton", 33 | "Material.IconToggle", 34 | "Material.ImageList", 35 | "Material.ImageList.Item", 36 | "Material.LayoutGrid", 37 | "Material.LinearProgress", 38 | "Material.List", 39 | "Material.List.Divider", 40 | "Material.List.Item", 41 | "Material.Menu", 42 | "Material.Radio", 43 | "Material.Ripple", 44 | "Material.Select", 45 | "Material.Select.Icon", 46 | "Material.Select.Item", 47 | "Material.Slider", 48 | "Material.Snackbar", 49 | "Material.Switch", 50 | "Material.Tab", 51 | "Material.TabBar", 52 | "Material.TextArea", 53 | "Material.TextField", 54 | "Material.TextField.Icon", 55 | "Material.Theme", 56 | "Material.TopAppBar", 57 | "Material.Typography" 58 | ] 59 | }, 60 | "elm-version": "0.19.0 <= v < 0.20.0", 61 | "dependencies": { 62 | "elm/core": "1.0.5 <= v < 2.0.0", 63 | "elm/html": "1.0.0 <= v < 2.0.0", 64 | "elm/json": "1.1.3 <= v < 2.0.0", 65 | "elm/svg": "1.0.1 <= v < 2.0.0", 66 | "elm/virtual-dom": "1.0.3 <= v < 2.0.0" 67 | }, 68 | "test-dependencies": {} 69 | } 70 | -------------------------------------------------------------------------------- /examples/simple-counter/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | elm make --optimize src/Main.elm --output elm.js 3 | 4 | clean: 5 | rm -f elm.js 6 | 7 | distclean: clean 8 | rm -rf elm-stuff 9 | -------------------------------------------------------------------------------- /examples/simple-counter/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src", 5 | "../../src" 6 | ], 7 | "elm-version": "0.19.1", 8 | "dependencies": { 9 | "direct": { 10 | "elm/browser": "1.0.2", 11 | "elm/core": "1.0.5", 12 | "elm/html": "1.0.0", 13 | "elm/json": "1.1.3", 14 | "elm/svg": "1.0.1", 15 | "elm/virtual-dom": "1.0.3" 16 | }, 17 | "indirect": { 18 | "elm/regex": "1.0.0", 19 | "elm/time": "1.0.0", 20 | "elm/url": "1.0.0" 21 | } 22 | }, 23 | "test-dependencies": { 24 | "direct": {}, 25 | "indirect": {} 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/simple-counter/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/simple-counter/shell.nix: -------------------------------------------------------------------------------- 1 | ../../shell.nix -------------------------------------------------------------------------------- /examples/simple-counter/src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (main) 2 | 3 | import Browser 4 | import Html exposing (Html, text) 5 | import Material.Button as Button 6 | import Material.Typography as Typography 7 | 8 | 9 | type alias Model = 10 | { count : Int } 11 | 12 | 13 | initialModel : Model 14 | initialModel = 15 | { count = 0 } 16 | 17 | 18 | type Msg 19 | = Increment 20 | | Decrement 21 | 22 | 23 | update : Msg -> Model -> Model 24 | update msg model = 25 | case msg of 26 | Increment -> 27 | { model | count = model.count + 1 } 28 | 29 | Decrement -> 30 | { model | count = model.count - 1 } 31 | 32 | 33 | view : Model -> Html Msg 34 | view model = 35 | Html.div [ Typography.typography ] 36 | [ Button.raised (Button.config |> Button.setOnClick Increment) "+1" 37 | , Html.div [] [ text <| String.fromInt model.count ] 38 | , Button.raised (Button.config |> Button.setOnClick Decrement) "-1" 39 | ] 40 | 41 | 42 | main : Program () Model Msg 43 | main = 44 | Browser.sandbox 45 | { init = initialModel 46 | , view = view 47 | , update = update 48 | } 49 | -------------------------------------------------------------------------------- /examples/theming/.gitignore: -------------------------------------------------------------------------------- 1 | .parcel-cache 2 | -------------------------------------------------------------------------------- /examples/theming/.sassrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "includePaths": [ "node_modules" ] 3 | } 4 | -------------------------------------------------------------------------------- /examples/theming/README.md: -------------------------------------------------------------------------------- 1 | # theming 2 | 3 | ## resources 4 | 5 | - [mdc-theme#readme](https://github.com/material-components/material-components-web/tree/master/packages/mdc-theme#readme) 6 | 7 | ## run the example 8 | 9 | ``` 10 | $ npm ci 11 | $ parcel src/index.html 12 | ``` 13 | 14 | ## steps 15 | 16 | - remove `material-components-web-elm` CSS resource from index.html 17 | - install material-components-web in the matching version 18 | - **note** due to an upstream bug, currently you would install material-components-web@13.0.0 instead of @11.0.0 19 | - configure sass support in your bundler 20 | - you might have to include `node_modules` in its include path 21 | - use `@material/theme` before including material-component-web's SCSS sources 22 | -------------------------------------------------------------------------------- /examples/theming/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src" 5 | ], 6 | "elm-version": "0.19.1", 7 | "dependencies": { 8 | "direct": { 9 | "aforemny/material-components-web-elm": "9.1.0", 10 | "elm/browser": "1.0.2", 11 | "elm/core": "1.0.5", 12 | "elm/html": "1.0.0" 13 | }, 14 | "indirect": { 15 | "elm/json": "1.1.3", 16 | "elm/regex": "1.0.0", 17 | "elm/svg": "1.0.1", 18 | "elm/time": "1.0.0", 19 | "elm/url": "1.0.0", 20 | "elm/virtual-dom": "1.0.3" 21 | } 22 | }, 23 | "test-dependencies": { 24 | "direct": {}, 25 | "indirect": {} 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/theming/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "theming", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "@parcel/transformer-elm": "^2.2.1", 12 | "@parcel/transformer-sass": "^2.2.1", 13 | "elm": "^0.19.1-5", 14 | "material-components-web": "^13.0.0", 15 | "parcel": "^2.2.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/theming/src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (main) 2 | 3 | import Browser 4 | import Html exposing (Html, text) 5 | import Material.Button as Button 6 | import Material.Typography as Typography 7 | 8 | 9 | type alias Model = 10 | { count : Int } 11 | 12 | 13 | initialModel : Model 14 | initialModel = 15 | { count = 0 } 16 | 17 | 18 | type Msg 19 | = Increment 20 | | Decrement 21 | 22 | 23 | update : Msg -> Model -> Model 24 | update msg model = 25 | case msg of 26 | Increment -> 27 | { model | count = model.count + 1 } 28 | 29 | Decrement -> 30 | { model | count = model.count - 1 } 31 | 32 | 33 | view : Model -> Html Msg 34 | view model = 35 | Html.div [ Typography.typography ] 36 | [ Button.raised (Button.config |> Button.setOnClick Increment) "+1" 37 | , Html.div [] [ text <| String.fromInt model.count ] 38 | , Button.raised (Button.config |> Button.setOnClick Decrement) "-1" 39 | ] 40 | 41 | 42 | main : Program () Model Msg 43 | main = 44 | Browser.sandbox 45 | { init = initialModel 46 | , view = view 47 | , update = update 48 | } 49 | -------------------------------------------------------------------------------- /examples/theming/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | theming 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/theming/src/index.scss: -------------------------------------------------------------------------------- 1 | @use "@material/theme" with ( 2 | $primary: #fcb8ab, 3 | $secondary: #feeae6, 4 | $on-primary: #442b2d, 5 | $on-secondary: #442b2d, 6 | ); 7 | @use "material-components-web/material-components-web"; 8 | -------------------------------------------------------------------------------- /examples/theming/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Elm } from "./Main.elm"; 2 | 3 | Elm.Main.init({ node: document.querySelector('main') }) 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "material-components-web-elm", 3 | "version": "9.1.0", 4 | "description": "Material Components for Elm", 5 | "author": "Alexander Foremny ", 6 | "license": "MIT", 7 | "repository": "https://github.com/aforemny/material-components-web-elm", 8 | "files": [ 9 | "dist" 10 | ], 11 | "devDependencies": { 12 | "connect": "^3.7.0", 13 | "elm-doc-preview": "^3.0.4", 14 | "elm-json": "^0.2.10", 15 | "elm-review": "^2.6.1", 16 | "puppeteer-core": "^8.0.0", 17 | "serve-static": "^1.14.1", 18 | "standard-version": "^9.3.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /review/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src" 5 | ], 6 | "elm-version": "0.19.1", 7 | "dependencies": { 8 | "direct": { 9 | "elm/core": "1.0.5", 10 | "elm/json": "1.1.3", 11 | "elm/project-metadata-utils": "1.0.2", 12 | "jfmengels/elm-review": "2.5.3", 13 | "jfmengels/review-unused": "2.1.5", 14 | "stil4m/elm-syntax": "7.2.7" 15 | }, 16 | "indirect": { 17 | "elm/html": "1.0.0", 18 | "elm/parser": "1.1.0", 19 | "elm/random": "1.0.0", 20 | "elm/time": "1.0.0", 21 | "elm/virtual-dom": "1.0.3", 22 | "elm-community/list-extra": "8.5.1", 23 | "elm-explorations/test": "1.2.2", 24 | "miniBill/elm-unicode": "1.0.2", 25 | "rtfeldman/elm-hex": "1.0.0", 26 | "stil4m/structured-writer": "1.0.3" 27 | } 28 | }, 29 | "test-dependencies": { 30 | "direct": { 31 | "elm-explorations/test": "1.2.2" 32 | }, 33 | "indirect": {} 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /review/src/ReviewConfig.elm: -------------------------------------------------------------------------------- 1 | module ReviewConfig exposing (config) 2 | 3 | import NoUnused.CustomTypeConstructors 4 | import NoUnused.Dependencies 5 | import NoUnused.Exports 6 | import NoUnused.Modules 7 | import NoUnused.Variables 8 | import Review.Rule exposing (Rule) 9 | 10 | 11 | config : List Rule 12 | config = 13 | [ -- NoUnused.CustomTypeConstructors.rule [] 14 | -- , NoUnused.Dependencies.rule 15 | -- , NoUnused.Exports.rule 16 | -- , NoUnused.Modules.rule 17 | NoUnused.Variables.rule 18 | ] 19 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import 2 | (builtins.fetchTarball 3 | "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-21.11.tar.gz") 4 | { } 5 | }: 6 | with pkgs; 7 | mkShell { 8 | buildInputs = [ 9 | chromium 10 | elmPackages.elm 11 | elmPackages.elm-format 12 | elmPackages.elm-json 13 | (ghc.withPackages (pkgs: [ pkgs.pandoc ])) 14 | nodejs 15 | python3 16 | ]; 17 | shellHook = '' 18 | export PATH=./node_modules/.bin:$PATH 19 | export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true 20 | export CHROMIUM_PATH=${chromium}/bin/chromium 21 | export PUPPETEER_PRODUCT=firefox 22 | ''; 23 | } 24 | -------------------------------------------------------------------------------- /src/Material/Button/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Button.Internal exposing (Config(..), Icon(..), Menu(..)) 2 | 3 | import Html exposing (Html) 4 | import Material.List.Item exposing (ListItem) 5 | import Material.Menu as Menu 6 | import Svg exposing (Svg) 7 | 8 | 9 | type Config msg 10 | = Config 11 | { icon : Maybe Icon 12 | , trailingIcon : Bool 13 | , disabled : Bool 14 | , dense : Bool 15 | , href : Maybe String 16 | , target : Maybe String 17 | , additionalAttributes : List (Html.Attribute msg) 18 | , onClick : Maybe msg 19 | , touch : Bool 20 | , menu : Maybe (Menu msg) 21 | } 22 | 23 | 24 | type Icon 25 | = Icon 26 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 27 | , attributes : List (Html.Attribute Never) 28 | , nodes : List (Html Never) 29 | } 30 | | SvgIcon 31 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 32 | , attributes : List (Svg.Attribute Never) 33 | , nodes : List (Svg Never) 34 | } 35 | 36 | 37 | type Menu msg 38 | = Menu (Menu.Config msg) (ListItem msg) (List (ListItem msg)) 39 | -------------------------------------------------------------------------------- /src/Material/Checkbox/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Checkbox.Internal exposing (Config(..), State(..)) 2 | 3 | import Html 4 | 5 | 6 | type Config msg 7 | = Config 8 | { state : Maybe State 9 | , disabled : Bool 10 | , additionalAttributes : List (Html.Attribute msg) 11 | , onChange : Maybe msg 12 | , touch : Bool 13 | } 14 | 15 | 16 | type State 17 | = Unchecked 18 | | Checked 19 | | Indeterminate 20 | -------------------------------------------------------------------------------- /src/Material/Chip/Action/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Chip.Action.Internal exposing (Chip(..), Config(..), Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Config msg 8 | = Config 9 | { icon : Maybe Icon 10 | , additionalAttributes : List (Html.Attribute msg) 11 | , onClick : Maybe msg 12 | } 13 | 14 | 15 | type Chip msg 16 | = Chip (Config msg) String 17 | 18 | 19 | type Icon 20 | = Icon 21 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 22 | , attributes : List (Html.Attribute Never) 23 | , nodes : List (Html Never) 24 | } 25 | | SvgIcon 26 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 27 | , attributes : List (Svg.Attribute Never) 28 | , nodes : List (Svg Never) 29 | } 30 | -------------------------------------------------------------------------------- /src/Material/Chip/Choice/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Chip.Choice.Internal exposing (Chip(..), Config(..), Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Config msg 8 | = Config 9 | { icon : Maybe Icon 10 | , additionalAttributes : List (Html.Attribute msg) 11 | } 12 | 13 | 14 | type Chip a msg 15 | = Chip (Config msg) a 16 | 17 | 18 | type Icon 19 | = Icon 20 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 21 | , attributes : List (Html.Attribute Never) 22 | , nodes : List (Html Never) 23 | } 24 | | SvgIcon 25 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 26 | , attributes : List (Svg.Attribute Never) 27 | , nodes : List (Svg Never) 28 | } 29 | -------------------------------------------------------------------------------- /src/Material/Chip/Filter/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Chip.Filter.Internal exposing (Chip(..), Config(..), Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Config msg 8 | = Config 9 | { icon : Maybe Icon 10 | , selected : Bool 11 | , additionalAttributes : List (Html.Attribute msg) 12 | , onChange : Maybe msg 13 | } 14 | 15 | 16 | type Chip msg 17 | = Chip (Config msg) String 18 | 19 | 20 | type Icon 21 | = Icon 22 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 23 | , attributes : List (Html.Attribute Never) 24 | , nodes : List (Html Never) 25 | } 26 | | SvgIcon 27 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 28 | , attributes : List (Svg.Attribute Never) 29 | , nodes : List (Svg Never) 30 | } 31 | -------------------------------------------------------------------------------- /src/Material/Chip/Input/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Chip.Input.Internal exposing (Chip(..), Config(..), Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Config msg 8 | = Config 9 | { leadingIcon : Maybe Icon 10 | , trailingIcon : Maybe Icon 11 | , additionalAttributes : List (Html.Attribute msg) 12 | , onClick : Maybe msg 13 | , onDelete : Maybe msg 14 | } 15 | 16 | 17 | type Chip msg 18 | = Chip (Config msg) String 19 | 20 | 21 | type Icon 22 | = Icon 23 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 24 | , attributes : List (Html.Attribute Never) 25 | , nodes : List (Html Never) 26 | } 27 | | SvgIcon 28 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 29 | , attributes : List (Svg.Attribute Never) 30 | , nodes : List (Svg Never) 31 | } 32 | -------------------------------------------------------------------------------- /src/Material/ChipSet/Action.elm: -------------------------------------------------------------------------------- 1 | module Material.ChipSet.Action exposing (chipSet) 2 | 3 | {-| Action chips offer actions related to primary content. They should appear 4 | dynamically and contextually in a UI. 5 | 6 | An alternative to action chips are [buttons](Material-Button), which should 7 | appear persistently and consistently. 8 | 9 | 10 | # Table of Contents 11 | 12 | - [Resources](#resources) 13 | - [Basic Usage](#basic-usage) 14 | - [Action Chip Set](#action-chip-set) 15 | 16 | 17 | # Resources 18 | 19 | - [Demo: Chips](https://aforemny.github.io/material-components-web-elm/#chips) 20 | - [Material Design Guidelines: Chips](https://material.io/go/design-chips) 21 | - [MDC Web: Chips](https://github.com/material-components/material-components-web/tree/master/packages/mdc-chips) 22 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-chips#sass-mixins) 23 | 24 | 25 | # Basic Usage 26 | 27 | import Material.Chip.Action as ActionChip 28 | import Material.ChipSet.Action as ActionChipSet 29 | 30 | type Msg 31 | = ChipClicked String 32 | 33 | main = 34 | ActionChipSet.chipSet [] 35 | (ActionChip.chip 36 | (ActionChip.config 37 | |> ActionChip.setOnClick 38 | (ChipClicked "Chip One") 39 | ) 40 | "Chip One" 41 | ) 42 | [ ActionChip.chip ActionChip.config "Chip Two" 43 | ] 44 | 45 | 46 | # Action Chip Set 47 | 48 | @docs chipSet 49 | 50 | -} 51 | 52 | import Html exposing (Html, text) 53 | import Html.Attributes exposing (class) 54 | import Html.Events 55 | import Json.Decode as Decode 56 | import Material.Chip.Action.Internal as Chip exposing (Chip(..), Icon(..)) 57 | import Svg.Attributes 58 | 59 | 60 | {-| Chip set view function 61 | -} 62 | chipSet : List (Html.Attribute msg) -> Chip msg -> List (Chip msg) -> Html msg 63 | chipSet additionalAttributes firstChip otherChips = 64 | Html.node "mdc-chip-set" 65 | (chipSetCs :: gridRole :: additionalAttributes) 66 | (List.map chip (firstChip :: otherChips)) 67 | 68 | 69 | chipSetCs : Html.Attribute msg 70 | chipSetCs = 71 | class "mdc-chip-set" 72 | 73 | 74 | gridRole : Html.Attribute msg 75 | gridRole = 76 | Html.Attributes.attribute "role" "grid" 77 | 78 | 79 | chip : Chip msg -> Html msg 80 | chip (Chip ((Chip.Config { additionalAttributes }) as config_) label) = 81 | Html.div [ class "mdc-touch-target-wrapper" ] 82 | [ Html.node "mdc-chip" 83 | (List.filterMap identity 84 | [ chipCs 85 | , chipTouchCs 86 | , rowRole 87 | , interactionHandler config_ 88 | ] 89 | ++ additionalAttributes 90 | ) 91 | (List.filterMap identity 92 | [ rippleElt 93 | , leadingIconElt config_ 94 | , primaryActionElt label 95 | ] 96 | ) 97 | ] 98 | 99 | 100 | chipCs : Maybe (Html.Attribute msg) 101 | chipCs = 102 | Just (class "mdc-chip") 103 | 104 | 105 | chipTextCs : Html.Attribute msg 106 | chipTextCs = 107 | class "mdc-chip__text" 108 | 109 | 110 | chipTouchCs : Maybe (Html.Attribute msg) 111 | chipTouchCs = 112 | Just (class "mdc-chip--touch") 113 | 114 | 115 | chipPrimaryActionCs : Html.Attribute msg 116 | chipPrimaryActionCs = 117 | class "mdc-chip__primary-action" 118 | 119 | 120 | buttonRole : Html.Attribute msg 121 | buttonRole = 122 | Html.Attributes.attribute "role" "button" 123 | 124 | 125 | rowRole : Maybe (Html.Attribute msg) 126 | rowRole = 127 | Just (Html.Attributes.attribute "role" "row") 128 | 129 | 130 | gridcellRole : Html.Attribute msg 131 | gridcellRole = 132 | Html.Attributes.attribute "role" "gridcell" 133 | 134 | 135 | interactionHandler : Chip.Config msg -> Maybe (Html.Attribute msg) 136 | interactionHandler (Chip.Config { onClick }) = 137 | Maybe.map (Html.Events.on "MDCChip:interaction" << Decode.succeed) onClick 138 | 139 | 140 | rippleElt : Maybe (Html msg) 141 | rippleElt = 142 | Just (Html.div [ class "mdc-chip__ripple" ] []) 143 | 144 | 145 | leadingIconElt : Chip.Config msg -> Maybe (Html msg) 146 | leadingIconElt (Chip.Config { icon }) = 147 | Maybe.map (Html.map never) <| 148 | case icon of 149 | Just (Icon { node, attributes, nodes }) -> 150 | Just <| 151 | node 152 | (class "mdc-chip__icon mdc-chip__icon--leading" 153 | :: attributes 154 | ) 155 | nodes 156 | 157 | Just (SvgIcon { node, attributes, nodes }) -> 158 | Just <| 159 | node 160 | (Svg.Attributes.class "mdc-chip__icon mdc-chip__icon--leading" 161 | :: attributes 162 | ) 163 | nodes 164 | 165 | Nothing -> 166 | Nothing 167 | 168 | 169 | primaryActionElt : String -> Maybe (Html msg) 170 | primaryActionElt label = 171 | Just <| 172 | Html.span [ chipPrimaryActionCs, gridcellRole ] 173 | (List.filterMap identity [ textElt label, touchElt ]) 174 | 175 | 176 | textElt : String -> Maybe (Html msg) 177 | textElt label = 178 | Just (Html.span [ chipTextCs, buttonRole ] [ text label ]) 179 | 180 | 181 | touchElt : Maybe (Html msg) 182 | touchElt = 183 | Just (Html.div [ class "mdc-chip__touch" ] []) 184 | -------------------------------------------------------------------------------- /src/Material/Drawer/Permanent.elm: -------------------------------------------------------------------------------- 1 | module Material.Drawer.Permanent exposing 2 | ( Config, config 3 | , setAttributes 4 | , drawer, content 5 | , header, title, subtitle 6 | ) 7 | 8 | {-| The drawer is used to organize access to destinations and 9 | other functionality on an app. 10 | 11 | 12 | # Table of Contents 13 | 14 | - [Resources](#resources) 15 | - [Basic Usage](#basic-usage) 16 | - [Configuration](#configuration) 17 | - [Configuration Options](#configuration-options) 18 | - [Permanent Drawer](#permanent-drawer) 19 | - [Drawer with Header](#drawer-with-header) 20 | 21 | 22 | # Resources 23 | 24 | - [Demo: Drawers](https://aforemny.github.io/material-components-web-elm/#drawer) 25 | - [Material Design Guidelines: Navigation Drawer](https://material.io/go/design-navigation-drawer) 26 | - [MDC Web: List](https://github.com/material-components/material-components-web/tree/master/packages/mdc-drawer) 27 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-drawer#sass-mixins) 28 | 29 | 30 | # Basic Usage 31 | 32 | import Html exposing (Html, text) 33 | import Html.Attributes exposing (style) 34 | import Material.Drawer.Permanent as PermanentDrawer 35 | import Material.List as List 36 | import Material.ListItem as ListItem 37 | 38 | main = 39 | Html.div 40 | [ style "display" "flex" 41 | , style "flex-flow" "row nowrap" 42 | ] 43 | [ PermanentDrawer.drawer PermanentDrawer.config 44 | [ PermanentDrawer.content [] 45 | [ List.list List.config 46 | (ListItem.listItem ListItem.config 47 | [ text "Home" ] 48 | ) 49 | [ ListItem.listItem ListItem.config 50 | [ text "Log out" ] 51 | ] 52 | ] 53 | ] 54 | , Html.div [] [ text "Main Content" ] 55 | ] 56 | 57 | 58 | # Configuration 59 | 60 | @docs Config, config 61 | 62 | 63 | ## Configuration Options 64 | 65 | @docs setAttributes 66 | 67 | 68 | # Permanent Drawer 69 | 70 | @docs drawer, content 71 | 72 | 73 | # Drawer with Header 74 | 75 | Drawers can contain a header element which will not scroll with the rest of the 76 | drawer content. Things like account switchers and titles should live in the 77 | header element. 78 | 79 | @docs header, title, subtitle 80 | 81 | -} 82 | 83 | import Html exposing (Html) 84 | import Html.Attributes exposing (class) 85 | 86 | 87 | {-| Configuration of a permanent drawer 88 | -} 89 | type Config msg 90 | = Config { additionalAttributes : List (Html.Attribute msg) } 91 | 92 | 93 | {-| Default configuration of a permanent drawer 94 | -} 95 | config : Config msg 96 | config = 97 | Config { additionalAttributes = [] } 98 | 99 | 100 | {-| Specify additional attributes 101 | -} 102 | setAttributes : List (Html.Attribute msg) -> Config msg -> Config msg 103 | setAttributes additionalAttributes (Config config_) = 104 | Config { config_ | additionalAttributes = additionalAttributes } 105 | 106 | 107 | {-| Permanent drawer view function 108 | -} 109 | drawer : Config msg -> List (Html msg) -> Html msg 110 | drawer (Config { additionalAttributes }) nodes = 111 | Html.div 112 | (List.filterMap identity [ rootCs ] ++ additionalAttributes) 113 | nodes 114 | 115 | 116 | {-| Drawer content 117 | -} 118 | content : List (Html.Attribute msg) -> List (Html msg) -> Html msg 119 | content attributes nodes = 120 | Html.div (class "mdc-drawer__content" :: attributes) nodes 121 | 122 | 123 | {-| Drawer header view function 124 | 125 | PermanentDrawer.drawer PermanentDrawer.config 126 | [ PermanentDrawer.header [] 127 | [ Html.h3 [ PermanentDrawer.title ] 128 | [ text "Title" ] 129 | , Html.h6 [ PermanentDrawer.subtitle ] 130 | [ text "Subtitle" ] 131 | ] 132 | , PermanentDrawer.content [] [] 133 | ] 134 | 135 | -} 136 | header : List (Html.Attribute msg) -> List (Html msg) -> Html msg 137 | header additionalAttributes nodes = 138 | Html.div (class "mdc-drawer__header" :: additionalAttributes) nodes 139 | 140 | 141 | {-| Attribute to mark the title text element of the drawer header 142 | -} 143 | title : Html.Attribute msg 144 | title = 145 | class "mdc-drawer__title" 146 | 147 | 148 | {-| Attribute to mark the subtitle text element of the drawer header 149 | -} 150 | subtitle : Html.Attribute msg 151 | subtitle = 152 | class "mdc-drawer__subtitle" 153 | 154 | 155 | rootCs : Maybe (Html.Attribute msg) 156 | rootCs = 157 | Just (class "mdc-drawer") 158 | -------------------------------------------------------------------------------- /src/Material/Elevation.elm: -------------------------------------------------------------------------------- 1 | module Material.Elevation exposing 2 | ( z0, z1, z2, z3, z4, z5, z6, z7, z8 3 | , z9, z10, z11, z12, z13, z14, z15, z16 4 | , z17, z18, z19, z20, z21, z22, z23, z24 5 | ) 6 | 7 | {-| Shadows provide important visual cues about objects’ depth and directional 8 | movement. They are the only visual cue indicating the amount of separation 9 | between surfaces. An object’s elevation determines the appearance of its 10 | shadow. The elevation values are mapped out in a "z-space" and range from 0 11 | (flush with the surface) to 24dp (most elevated). 12 | 13 | 14 | # Table of Contents 15 | 16 | - [Resources](#resources) 17 | - [Basic Usage](#basic-usage) 18 | - [Elevation](#elevation) 19 | 20 | 21 | # Resources 22 | 23 | - [Demo: Elevations](https://aforemny.github.io/material-components-web-elm/#elevation) 24 | - [Material Design Guidelines: Shadows & elevation](https://material.io/go/design-elevation) 25 | - [MDC Web: Elevation](https://github.com/material-components/material-components-web/tree/master/packages/mdc-elevation) 26 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-elevation#sass-mixins-variables-and-functions) 27 | 28 | 29 | # Basic Usage 30 | 31 | import Material.Elevation as Elevation 32 | 33 | main = 34 | Html.div [ Elevation.z8 ] [ text "Elevation" ] 35 | 36 | 37 | # Elevation 38 | 39 | @docs z0, z1, z2, z3, z4, z5, z6, z7, z8 40 | @docs z9, z10, z11, z12, z13, z14, z15, z16 41 | @docs z17, z18, z19, z20, z21, z22, z23, z24 42 | 43 | -} 44 | 45 | import Html 46 | import Html.Attributes exposing (class) 47 | 48 | 49 | {-| 0dp elevation (no elevation) 50 | -} 51 | z0 : Html.Attribute msg 52 | z0 = 53 | z 0 54 | 55 | 56 | {-| 1dp elevation 57 | -} 58 | z1 : Html.Attribute msg 59 | z1 = 60 | z 1 61 | 62 | 63 | {-| 2dp elevation 64 | -} 65 | z2 : Html.Attribute msg 66 | z2 = 67 | z 2 68 | 69 | 70 | {-| 3dp elevation 71 | -} 72 | z3 : Html.Attribute msg 73 | z3 = 74 | z 3 75 | 76 | 77 | {-| 4dp elevation 78 | -} 79 | z4 : Html.Attribute msg 80 | z4 = 81 | z 4 82 | 83 | 84 | {-| 5dp elevation 85 | -} 86 | z5 : Html.Attribute msg 87 | z5 = 88 | z 5 89 | 90 | 91 | {-| 6dp elevation 92 | -} 93 | z6 : Html.Attribute msg 94 | z6 = 95 | z 6 96 | 97 | 98 | {-| 7dp elevation 99 | -} 100 | z7 : Html.Attribute msg 101 | z7 = 102 | z 7 103 | 104 | 105 | {-| 8dp elevation 106 | -} 107 | z8 : Html.Attribute msg 108 | z8 = 109 | z 8 110 | 111 | 112 | {-| 9dp elevation 113 | -} 114 | z9 : Html.Attribute msg 115 | z9 = 116 | z 9 117 | 118 | 119 | {-| 10dp elevation 120 | -} 121 | z10 : Html.Attribute msg 122 | z10 = 123 | z 10 124 | 125 | 126 | {-| 11dp elevation 127 | -} 128 | z11 : Html.Attribute msg 129 | z11 = 130 | z 11 131 | 132 | 133 | {-| 12dp elevation 134 | -} 135 | z12 : Html.Attribute msg 136 | z12 = 137 | z 12 138 | 139 | 140 | {-| 13dp elevation 141 | -} 142 | z13 : Html.Attribute msg 143 | z13 = 144 | z 13 145 | 146 | 147 | {-| 14dp elevation 148 | -} 149 | z14 : Html.Attribute msg 150 | z14 = 151 | z 14 152 | 153 | 154 | {-| 15dp elevation 155 | -} 156 | z15 : Html.Attribute msg 157 | z15 = 158 | z 15 159 | 160 | 161 | {-| 16dp elevation 162 | -} 163 | z16 : Html.Attribute msg 164 | z16 = 165 | z 16 166 | 167 | 168 | {-| 17dp elevation 169 | -} 170 | z17 : Html.Attribute msg 171 | z17 = 172 | z 17 173 | 174 | 175 | {-| 18dp elevation 176 | -} 177 | z18 : Html.Attribute msg 178 | z18 = 179 | z 18 180 | 181 | 182 | {-| 19dp elevation 183 | -} 184 | z19 : Html.Attribute msg 185 | z19 = 186 | z 19 187 | 188 | 189 | {-| 20dp elevation 190 | -} 191 | z20 : Html.Attribute msg 192 | z20 = 193 | z 20 194 | 195 | 196 | {-| 21dp elevation 197 | -} 198 | z21 : Html.Attribute msg 199 | z21 = 200 | z 21 201 | 202 | 203 | {-| 22dp elevation 204 | -} 205 | z22 : Html.Attribute msg 206 | z22 = 207 | z 22 208 | 209 | 210 | {-| 23dp elevation 211 | -} 212 | z23 : Html.Attribute msg 213 | z23 = 214 | z 23 215 | 216 | 217 | {-| 24dp elevation 218 | -} 219 | z24 : Html.Attribute msg 220 | z24 = 221 | z 24 222 | 223 | 224 | z : Int -> Html.Attribute msg 225 | z n = 226 | class ("mdc-elevation--z" ++ String.fromInt n) 227 | -------------------------------------------------------------------------------- /src/Material/FormField.elm: -------------------------------------------------------------------------------- 1 | module Material.FormField exposing 2 | ( Config, config 3 | , setOnClick 4 | , setLabel, setAlignEnd 5 | , setFor 6 | , setAttributes 7 | , formField 8 | ) 9 | 10 | {-| FormField aligns a form field (for example, a checkbox) with 11 | its label and makes it RTL-aware. It also activates a ripple effect upon 12 | interacting with the label. 13 | 14 | 15 | # Table of Contents 16 | 17 | - [Resources](#resources) 18 | - [Basic Usage](#basic-usage) 19 | - [Configuration](#configuration) 20 | - [Configuration Options](#configuration-options) 21 | - [Form Field](#form-field) 22 | - [Label Position](#label-position) 23 | - [Focus a Form Field](#focus-a-form-field) 24 | 25 | 26 | # Resources 27 | 28 | - [Demo: Checkbox](https://aforemny.github.io/material-components-web-elm/#checkbox) 29 | - [MDC Web: Form Field](https://github.com/material-components/material-components-web/tree/master/packages/mdc-form-field) 30 | 31 | 32 | # Basic Usage 33 | 34 | import Material.Checkbox as Checkbox 35 | import Material.FormField as FormField 36 | 37 | main = 38 | FormField.formField 39 | (FormField.config 40 | |> FormField.setLabel (Just "My checkbox") 41 | ) 42 | [ Checkbox.checkbox Checkbox.config ] 43 | 44 | 45 | # Configuration 46 | 47 | @docs Config, config 48 | 49 | 50 | ## Configuration Options 51 | 52 | @docs setOnClick 53 | @docs setLabel, setAlignEnd 54 | @docs setFor 55 | @docs setAttributes 56 | 57 | 58 | # Form Field 59 | 60 | @docs formField 61 | 62 | 63 | # Label Position 64 | 65 | If you want to position the label after the form field's control, set its 66 | `setAlignEnd` configuration option to `True`. 67 | 68 | FormField.formField 69 | (FormField.config |> FormField.setAlignEnd True) 70 | [ Checkbox.checkbox Checkbox.config ] 71 | 72 | 73 | # Focus a Form Field 74 | 75 | You may programatically focus a formfield by assigning an id attribute to it 76 | and use `Browser.Dom.focus`. 77 | 78 | FormField.formField 79 | (FormField.config 80 | |> FormField.setAttributes [ Html.Attributes.id "my-form-field" ] 81 | ) 82 | [] 83 | 84 | -} 85 | 86 | import Html exposing (Html, text) 87 | import Html.Attributes exposing (class) 88 | import Html.Events 89 | 90 | 91 | {-| Configuration of a form field 92 | -} 93 | type Config msg 94 | = Config 95 | { label : Maybe String 96 | , for : Maybe String 97 | , alignEnd : Bool 98 | , additionalAttributes : List (Html.Attribute msg) 99 | , onClick : Maybe msg 100 | } 101 | 102 | 103 | {-| Specify a form field's label 104 | -} 105 | setLabel : Maybe String -> Config msg -> Config msg 106 | setLabel label (Config config_) = 107 | Config { config_ | label = label } 108 | 109 | 110 | {-| Specify a form field label's HTML5 for attribute 111 | -} 112 | setFor : Maybe String -> Config msg -> Config msg 113 | setFor for (Config config_) = 114 | Config { config_ | for = for } 115 | 116 | 117 | {-| Specify whether the form field's label is positioned after its control 118 | 119 | This is usefile for, say, checkboxes. 120 | 121 | -} 122 | setAlignEnd : Bool -> Config msg -> Config msg 123 | setAlignEnd alignEnd (Config config_) = 124 | Config { config_ | alignEnd = alignEnd } 125 | 126 | 127 | {-| Specify additional attributes 128 | -} 129 | setAttributes : List (Html.Attribute msg) -> Config msg -> Config msg 130 | setAttributes additionalAttributes (Config config_) = 131 | Config { config_ | additionalAttributes = additionalAttributes } 132 | 133 | 134 | {-| Specify a message when the user clicks on the label 135 | -} 136 | setOnClick : msg -> Config msg -> Config msg 137 | setOnClick onClick (Config config_) = 138 | Config { config_ | onClick = Just onClick } 139 | 140 | 141 | {-| Default configuration of a form field 142 | -} 143 | config : Config msg 144 | config = 145 | Config 146 | { label = Nothing 147 | , for = Nothing 148 | , alignEnd = False 149 | , additionalAttributes = [] 150 | , onClick = Nothing 151 | } 152 | 153 | 154 | {-| Form field view function 155 | -} 156 | formField : Config msg -> List (Html msg) -> Html msg 157 | formField ((Config { additionalAttributes }) as config_) nodes = 158 | Html.node "mdc-form-field" 159 | (List.filterMap identity 160 | [ rootCs 161 | , alignEndCs config_ 162 | ] 163 | ++ additionalAttributes 164 | ) 165 | (nodes ++ [ labelElt config_ ]) 166 | 167 | 168 | rootCs : Maybe (Html.Attribute msg) 169 | rootCs = 170 | Just (class "mdc-form-field") 171 | 172 | 173 | alignEndCs : Config msg -> Maybe (Html.Attribute msg) 174 | alignEndCs (Config { alignEnd }) = 175 | if alignEnd then 176 | Just (class "mdc-form-field--align-end") 177 | 178 | else 179 | Nothing 180 | 181 | 182 | forAttr : Config msg -> Maybe (Html.Attribute msg) 183 | forAttr (Config { for }) = 184 | Maybe.map Html.Attributes.for for 185 | 186 | 187 | clickHandler : Config msg -> Maybe (Html.Attribute msg) 188 | clickHandler (Config { onClick }) = 189 | Maybe.map Html.Events.onClick onClick 190 | 191 | 192 | labelElt : Config msg -> Html msg 193 | labelElt ((Config { label }) as config_) = 194 | Html.label 195 | (List.filterMap identity 196 | [ forAttr config_ 197 | , clickHandler config_ 198 | ] 199 | ) 200 | [ text (Maybe.withDefault "" label) ] 201 | -------------------------------------------------------------------------------- /src/Material/Icon.elm: -------------------------------------------------------------------------------- 1 | module Material.Icon exposing (icon) 2 | 3 | {-| Icon renders a Material Icon. 4 | 5 | 6 | # Table of Contents 7 | 8 | - [Resources](#resources) 9 | - [Basic Usage](#basic-usage) 10 | - [Icon](#icon) 11 | 12 | 13 | # Resources 14 | 15 | - [Material Icons](https://material.io/tools/icons/) 16 | 17 | 18 | # Basic Usage 19 | 20 | import Material.Icon as Icon 21 | 22 | main = 23 | Icon.icon [] "favorite" 24 | 25 | 26 | # Icon 27 | 28 | @docs icon 29 | 30 | -} 31 | 32 | import Html exposing (Html, text) 33 | import Html.Attributes exposing (class) 34 | 35 | 36 | {-| Icon view function 37 | -} 38 | icon : List (Html.Attribute msg) -> String -> Html msg 39 | icon additionalAttributes iconName = 40 | Html.i (class "material-icons" :: additionalAttributes) [ text iconName ] 41 | -------------------------------------------------------------------------------- /src/Material/IconButton/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.IconButton.Internal exposing (Config(..), Icon(..), Menu(..)) 2 | 3 | import Html exposing (Html) 4 | import Material.List.Item exposing (ListItem) 5 | import Material.Menu as Menu 6 | import Svg exposing (Svg) 7 | 8 | 9 | type Config msg 10 | = Config 11 | { disabled : Bool 12 | , href : Maybe String 13 | , target : Maybe String 14 | , label : Maybe String 15 | , additionalAttributes : List (Html.Attribute msg) 16 | , onClick : Maybe msg 17 | , menu : Maybe (Menu msg) 18 | } 19 | 20 | 21 | type Icon 22 | = Icon 23 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 24 | , attributes : List (Html.Attribute Never) 25 | , nodes : List (Html Never) 26 | } 27 | | SvgIcon 28 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 29 | , attributes : List (Svg.Attribute Never) 30 | , nodes : List (Svg Never) 31 | } 32 | 33 | 34 | type Menu msg 35 | = Menu (Menu.Config msg) (ListItem msg) (List (ListItem msg)) 36 | -------------------------------------------------------------------------------- /src/Material/ImageList/Item/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.ImageList.Item.Internal exposing (Config(..), ImageListItem(..)) 2 | 3 | import Html 4 | 5 | 6 | type Config msg 7 | = Config 8 | { label : Maybe String 9 | , href : Maybe String 10 | , additionalAttributes : List (Html.Attribute msg) 11 | , image : String 12 | , imageNode : Maybe (List (Html.Attribute msg)) 13 | } 14 | 15 | 16 | type ImageListItem msg 17 | = ImageListItem (Config msg) 18 | -------------------------------------------------------------------------------- /src/Material/List/Item/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.List.Item.Internal exposing 2 | ( Config(..) 3 | , ListItem(..) 4 | , Selection(..) 5 | ) 6 | 7 | import Html exposing (Html) 8 | 9 | 10 | type Config msg 11 | = Config 12 | { disabled : Bool 13 | , selection : Maybe Selection 14 | , href : Maybe String 15 | , target : Maybe String 16 | , additionalAttributes : List (Html.Attribute msg) 17 | , onClick : Maybe msg 18 | , ripples : Bool 19 | , interactive : Bool 20 | } 21 | 22 | 23 | type Selection 24 | = Selected 25 | | Activated 26 | 27 | 28 | type ListItem msg 29 | = ListItem (Config msg -> Html msg) (Config msg) 30 | | ListItemDivider (Html msg) 31 | | ListGroupSubheader (Html msg) 32 | -------------------------------------------------------------------------------- /src/Material/Select/Icon.elm: -------------------------------------------------------------------------------- 1 | module Material.Select.Icon exposing 2 | ( Icon, icon 3 | , customIcon 4 | , svgIcon 5 | , setOnInteraction 6 | , setDisabled 7 | ) 8 | 9 | {-| Select icons can either be leading or trailing icons, and can be purely 10 | cosmetic or can be interacted with. 11 | 12 | 13 | # Table of Contents 14 | 15 | - [Resources](#resources) 16 | - [Basic Usage](#basic-usage) 17 | - [Icon](#icon) 18 | - [Custom Icon](#custom-icon) 19 | - [SVG Icon](#svg-icon) 20 | - [Interactive Icon](#interactive-icon) 21 | - [Disabled Icon](#disabled-icon) 22 | 23 | 24 | # Resources 25 | 26 | - [Demo: Select](https://aforemny.github.io/material-components-web-elm/#select) 27 | - [Material Design Guidelines: Text Fields](https://material.io/components/text-fields/) 28 | - [MDC Web: Textfield](https://github.com/material-components/material-components-web/tree/master/packages/mdc-select) 29 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-select#sass-mixins) 30 | 31 | 32 | # Basic Usage 33 | 34 | import Material.Select as Select 35 | import Material.Select.Icon as SelectIcon 36 | import Material.Select.Item as SelectItem 37 | 38 | type Msg 39 | = Interacted 40 | 41 | main = 42 | Select.filled 43 | (Select.config 44 | |> Select.setLeadingIcon 45 | (Just (SelectIcon.icon "favorite")) 46 | ) 47 | (SelectItem.selectItem 48 | (SelectItem.config { value = "" }) 49 | "" 50 | ) 51 | [] 52 | 53 | 54 | # Icon 55 | 56 | This library natively supports [Material Icons](https://material.io/icons). 57 | However, you may also include SVG or custom icons such as FontAwesome. 58 | 59 | @docs Icon, icon 60 | 61 | 62 | # Custom Icon 63 | 64 | @docs customIcon 65 | 66 | 67 | # SVG Icon 68 | 69 | @docs svgIcon 70 | 71 | 72 | # Interactive Icon 73 | 74 | To be able to interact with an icon, set its `setOnInteraction` configuration 75 | option to the message that should be dispatched. 76 | 77 | @docs setOnInteraction 78 | 79 | 80 | # Disabled Icon 81 | 82 | To disable an icon, set its `setDisabled` configuration option to `True`. 83 | 84 | @docs setDisabled 85 | 86 | -} 87 | 88 | import Html exposing (Html, text) 89 | import Html.Attributes exposing (class) 90 | import Material.Select.Icon.Internal exposing (Icon(..)) 91 | import Svg exposing (Svg) 92 | 93 | 94 | {-| Icon type 95 | -} 96 | type alias Icon msg = 97 | Material.Select.Icon.Internal.Icon msg 98 | 99 | 100 | {-| Material Icon 101 | 102 | Select.filled 103 | (Select.config 104 | |> Select.setLeadingIcon 105 | (Just (SelectIcon.icon "favorite")) 106 | ) 107 | 108 | -} 109 | icon : String -> Icon msg 110 | icon iconName = 111 | customIcon Html.i [ class "material-icons" ] [ text iconName ] 112 | 113 | 114 | {-| Custom icon 115 | 116 | Select.filled 117 | (Select.config 118 | |> Select.setLeadingIcon 119 | (Just 120 | (SelectIcon.customIcon Html.i 121 | [ class "fab fa-font-awesome" ] 122 | [] 123 | ) 124 | ) 125 | ) 126 | 127 | -} 128 | customIcon : 129 | (List (Html.Attribute msg) -> List (Html msg) -> Html msg) 130 | -> List (Html.Attribute msg) 131 | -> List (Html msg) 132 | -> Icon msg 133 | customIcon node attributes nodes = 134 | Icon 135 | { node = node 136 | , attributes = attributes 137 | , nodes = nodes 138 | , onInteraction = Nothing 139 | , disabled = False 140 | } 141 | 142 | 143 | {-| SVG icon 144 | 145 | Select.filled 146 | (Select.config 147 | |> Select.setLeadingIcon 148 | (Just 149 | (SelectIcon.svgIcon 150 | [ Svg.Attributes.viewBox "…" ] 151 | [-- … 152 | ] 153 | ) 154 | ) 155 | ) 156 | 157 | -} 158 | svgIcon : List (Svg.Attribute msg) -> List (Svg msg) -> Icon msg 159 | svgIcon attributes nodes = 160 | SvgIcon 161 | { node = Svg.svg 162 | , attributes = attributes 163 | , nodes = nodes 164 | , onInteraction = Nothing 165 | , disabled = False 166 | } 167 | 168 | 169 | {-| Specify a message when the user interacts with the icon 170 | 171 | SelectIcon.icon "favorite" 172 | |> SelectIcon.setOnInteraction Interacted 173 | 174 | -} 175 | setOnInteraction : msg -> Icon msg -> Icon msg 176 | setOnInteraction onInteraction icon_ = 177 | case icon_ of 178 | Icon data -> 179 | Icon { data | onInteraction = Just onInteraction } 180 | 181 | SvgIcon data -> 182 | SvgIcon { data | onInteraction = Just onInteraction } 183 | 184 | 185 | {-| Specify an icon to be disabled 186 | 187 | Disabled icons cannot be interacted with and have no visual interaction 188 | effect. 189 | 190 | SelectIcon.icon "favorite" 191 | |> SelectIcon.setDisabled True 192 | 193 | -} 194 | setDisabled : Bool -> Icon msg -> Icon msg 195 | setDisabled disabled icon_ = 196 | case icon_ of 197 | Icon data -> 198 | Icon { data | disabled = disabled } 199 | 200 | SvgIcon data -> 201 | SvgIcon { data | disabled = disabled } 202 | -------------------------------------------------------------------------------- /src/Material/Select/Icon/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Select.Icon.Internal exposing (Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Icon msg 8 | = Icon 9 | { node : List (Html.Attribute msg) -> List (Html msg) -> Html msg 10 | , attributes : List (Html.Attribute msg) 11 | , nodes : List (Html msg) 12 | , onInteraction : Maybe msg 13 | , disabled : Bool 14 | } 15 | | SvgIcon 16 | { node : List (Svg.Attribute msg) -> List (Svg msg) -> Html msg 17 | , attributes : List (Svg.Attribute msg) 18 | , nodes : List (Svg msg) 19 | , onInteraction : Maybe msg 20 | , disabled : Bool 21 | } 22 | -------------------------------------------------------------------------------- /src/Material/Select/Item.elm: -------------------------------------------------------------------------------- 1 | module Material.Select.Item exposing 2 | ( Config, config 3 | , setDisabled 4 | , setAttributes 5 | , SelectItem, selectItem 6 | ) 7 | 8 | {-| Select provides a single-option select menus. 9 | 10 | This module concerns the select items. If you are looking for the select container, 11 | refer to [Material.Select](Material-Select). 12 | 13 | 14 | # Table of Contents 15 | 16 | - [Resources](#resources) 17 | - [Basic Usage](#basic-usage) 18 | - [Configuration](#configuration) 19 | - [Configuration Options](#configuration-options) 20 | - [Select Item](#select-item) 21 | - [Disabled Select Item](#disabled-select-item) 22 | 23 | 24 | # Resources 25 | 26 | - [Demo: Selects](https://aforemny.github.io/material-components-web-elm/#select) 27 | - [Material Design Guidelines: Text Fields](https://material.io/go/design-text-fields) 28 | - [MDC Web: Select](https://github.com/material-components/material-components-web/tree/master/packages/mdc-select) 29 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-select#sass-mixins) 30 | 31 | 32 | # Basic Usage 33 | 34 | import Material.Select as Select 35 | import Material.Select.Item as SelectItem 36 | 37 | type Msg 38 | = ValueChanged String 39 | 40 | main = 41 | Select.filled 42 | (Select.config 43 | |> Select.setLabel (Just "Fruit") 44 | |> Select.setSelected (Just "") 45 | |> Select.setOnChange ValueChanged 46 | ) 47 | (SelectItem.selectItem 48 | (SelectItem.config { value = "" }) 49 | "" 50 | ) 51 | [ SelectItem.selectItem 52 | (SelectItem.config { value = "Apple" }) 53 | "Apple" 54 | ] 55 | 56 | 57 | # Configuration 58 | 59 | @docs Config, config 60 | 61 | 62 | ## Configuration Options 63 | 64 | @docs setDisabled 65 | @docs setAttributes 66 | 67 | 68 | # Select Item 69 | 70 | @docs SelectItem, selectItem 71 | 72 | 73 | # Disabled Select Item 74 | 75 | Select items may be disabled by setting their `setDisabled` configuration option 76 | to `True`. 77 | 78 | SelectItem.selectItem 79 | (SelectItem.config { value = "Apple" } 80 | |> SelectItem.setDisabled True 81 | ) 82 | "Apple" 83 | 84 | -} 85 | 86 | import Html 87 | import Material.Select.Item.Internal exposing (Config(..), SelectItem(..)) 88 | 89 | 90 | {-| Configuration of a select item 91 | -} 92 | type alias Config a msg = 93 | Material.Select.Item.Internal.Config a msg 94 | 95 | 96 | {-| Default configuration of a select item 97 | -} 98 | config : { value : a } -> Config a msg 99 | config { value } = 100 | Config 101 | { value = value 102 | , disabled = False 103 | , additionalAttributes = [] 104 | } 105 | 106 | 107 | {-| Specify whether a select item should be disabled 108 | 109 | Disabled select items cannot be interacted with and have not visual interaction 110 | effect. 111 | 112 | -} 113 | setDisabled : Bool -> Config a msg -> Config a msg 114 | setDisabled disabled (Config config_) = 115 | Config { config_ | disabled = disabled } 116 | 117 | 118 | {-| Specify additional attributes 119 | -} 120 | setAttributes : List (Html.Attribute msg) -> Config a msg -> Config a msg 121 | setAttributes additionalAttributes (Config config_) = 122 | Config { config_ | additionalAttributes = additionalAttributes } 123 | 124 | 125 | {-| Select item type 126 | -} 127 | type alias SelectItem a msg = 128 | Material.Select.Item.Internal.SelectItem a msg 129 | 130 | 131 | {-| Select item constructor 132 | -} 133 | selectItem : Config a msg -> String -> SelectItem a msg 134 | selectItem = 135 | SelectItem 136 | -------------------------------------------------------------------------------- /src/Material/Select/Item/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Select.Item.Internal exposing (Config(..), SelectItem(..)) 2 | 3 | import Html 4 | 5 | 6 | type Config a msg 7 | = Config 8 | { value : a 9 | , disabled : Bool 10 | , additionalAttributes : List (Html.Attribute msg) 11 | } 12 | 13 | 14 | type SelectItem a msg 15 | = SelectItem (Config a msg) String 16 | -------------------------------------------------------------------------------- /src/Material/Tab/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.Tab.Internal exposing 2 | ( Config(..) 3 | , Content 4 | , Icon(..) 5 | , Tab(..) 6 | ) 7 | 8 | import Html exposing (Html) 9 | import Svg exposing (Svg) 10 | 11 | 12 | type Config msg 13 | = Config 14 | { active : Bool 15 | , additionalAttributes : List (Html.Attribute msg) 16 | , onClick : Maybe msg 17 | , content : Content 18 | } 19 | 20 | 21 | type alias Content = 22 | { label : String 23 | , icon : Maybe Icon 24 | } 25 | 26 | 27 | type Tab msg 28 | = Tab (Config msg) 29 | 30 | 31 | type Icon 32 | = Icon 33 | { node : List (Html.Attribute Never) -> List (Html Never) -> Html Never 34 | , attributes : List (Html.Attribute Never) 35 | , nodes : List (Html Never) 36 | } 37 | | SvgIcon 38 | { node : List (Svg.Attribute Never) -> List (Svg Never) -> Svg Never 39 | , attributes : List (Svg.Attribute Never) 40 | , nodes : List (Svg Never) 41 | } 42 | -------------------------------------------------------------------------------- /src/Material/TextField/Icon/Internal.elm: -------------------------------------------------------------------------------- 1 | module Material.TextField.Icon.Internal exposing (Icon(..)) 2 | 3 | import Html exposing (Html) 4 | import Svg exposing (Svg) 5 | 6 | 7 | type Icon msg 8 | = Icon 9 | { node : List (Html.Attribute msg) -> List (Html msg) -> Html msg 10 | , attributes : List (Html.Attribute msg) 11 | , nodes : List (Html msg) 12 | , onInteraction : Maybe msg 13 | , disabled : Bool 14 | } 15 | | SvgIcon 16 | { node : List (Svg.Attribute msg) -> List (Svg msg) -> Html msg 17 | , attributes : List (Svg.Attribute msg) 18 | , nodes : List (Svg msg) 19 | , onInteraction : Maybe msg 20 | , disabled : Bool 21 | } 22 | -------------------------------------------------------------------------------- /src/Material/Typography.elm: -------------------------------------------------------------------------------- 1 | module Material.Typography exposing 2 | ( headline1, headline2, headline3, headline4, headline5, headline6 3 | , body1, body2 4 | , subtitle1, subtitle2 5 | , caption, button, overline 6 | , typography 7 | ) 8 | 9 | {-| Material Design's text sizes and styles were developed to balance content 10 | density and reading comfort under typical usage conditions. 11 | 12 | 13 | # Table of Contents 14 | 15 | - [Resources](#resources) 16 | - [Basic Usage](#basic-usage) 17 | - [Typography Variants](#typography-variants) 18 | 19 | 20 | # Resources 21 | 22 | - [Demo: Typography](https://aforemny.github.io/material-components-web-elm/#typography) 23 | - [Material Design Guidelines: Typography](https://material.io/go/design-typography) 24 | - [MDC Web: Typography](https://github.com/material-components/material-components-web/tree/master/packages/mdc-typography) 25 | - [Sass Mixins (MDC Web)](https://github.com/material-components/material-components-web/tree/master/packages/mdc-typography#sass-variables-and-mixins) 26 | 27 | 28 | # Basic Usage 29 | 30 | For typography to work best, it is necessary to set the font to Roboto. This is 31 | archieved by the `mdc-typography` class, and we recommend to set it globally to 32 | the root of your page. 33 | 34 | import Material.Typography as Typography 35 | 36 | Html.h1 [ Typography.headline1 ] [ text "Headline" ] 37 | 38 | 39 | # Typography Variants 40 | 41 | Typography elements come in the following thirteen variants. 42 | 43 | @docs headline1, headline2, headline3, headline4, headline5, headline6 44 | @docs body1, body2 45 | @docs subtitle1, subtitle2 46 | @docs caption, button, overline 47 | @docs typography 48 | 49 | -} 50 | 51 | import Html 52 | import Html.Attributes exposing (class) 53 | 54 | 55 | {-| Sets the font to Roboto 56 | -} 57 | typography : Html.Attribute msg 58 | typography = 59 | class "mdc-typography" 60 | 61 | 62 | {-| Sets font properties as Headline 1 63 | -} 64 | headline1 : Html.Attribute msg 65 | headline1 = 66 | class "mdc-typography--headline1" 67 | 68 | 69 | {-| Sets font properties as Headline 2 70 | -} 71 | headline2 : Html.Attribute msg 72 | headline2 = 73 | class "mdc-typography--headline2" 74 | 75 | 76 | {-| Sets font properties as Headline 3 77 | -} 78 | headline3 : Html.Attribute msg 79 | headline3 = 80 | class "mdc-typography--headline3" 81 | 82 | 83 | {-| Sets font properties as Headline 4 84 | -} 85 | headline4 : Html.Attribute msg 86 | headline4 = 87 | class "mdc-typography--headline4" 88 | 89 | 90 | {-| Sets font properties as Headline 5 91 | -} 92 | headline5 : Html.Attribute msg 93 | headline5 = 94 | class "mdc-typography--headline5" 95 | 96 | 97 | {-| Sets font properties as Headline 6 98 | -} 99 | headline6 : Html.Attribute msg 100 | headline6 = 101 | class "mdc-typography--headline6" 102 | 103 | 104 | {-| Sets font properties as Subtitle 1 105 | -} 106 | subtitle1 : Html.Attribute msg 107 | subtitle1 = 108 | class "mdc-typography--subtitle1" 109 | 110 | 111 | {-| Sets font properties as Subtitle 2 112 | -} 113 | subtitle2 : Html.Attribute msg 114 | subtitle2 = 115 | class "mdc-typography--subtitle2" 116 | 117 | 118 | {-| Sets font properties as Body 1 119 | -} 120 | body1 : Html.Attribute msg 121 | body1 = 122 | class "mdc-typography--body1" 123 | 124 | 125 | {-| Sets font properties as Body 2 126 | -} 127 | body2 : Html.Attribute msg 128 | body2 = 129 | class "mdc-typography--body2" 130 | 131 | 132 | {-| Sets font properties as Caption 133 | -} 134 | caption : Html.Attribute msg 135 | caption = 136 | class "mdc-typography--caption" 137 | 138 | 139 | {-| Sets font properties as Button 140 | -} 141 | button : Html.Attribute msg 142 | button = 143 | class "mdc-typography--button" 144 | 145 | 146 | {-| Sets font properties as Overline 147 | -} 148 | overline : Html.Attribute msg 149 | overline = 150 | class "mdc-typography--overline" 151 | -------------------------------------------------------------------------------- /src/Testing/Browser.elm: -------------------------------------------------------------------------------- 1 | -- Dummy implementation of Browser.sandbox for `./bin/test-docs.hs` for module 2 | -- Material.Snackbar 3 | 4 | 5 | module Testing.Browser exposing (sandbox) 6 | 7 | import Html exposing (Html) 8 | 9 | 10 | sandbox : 11 | { init : model 12 | , view : model -> Html msg 13 | , update : msg -> model -> model 14 | } 15 | -> Program () model msg 16 | sandbox r = 17 | (\() -> sandbox r) () 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "downlevelIteration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "lib": ["es5", "es6", "dom"], 9 | "moduleResolution": "node", 10 | "newLine": "lf", 11 | "noEmitOnError": false, 12 | "noErrorTruncation": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noStrictGenericChecks": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "preserveConstEnums": true, 18 | "pretty": true, 19 | "skipLibCheck": true, 20 | "sourceMap": true, 21 | "strict": true, 22 | "stripInternal": true, 23 | "target": "es5", 24 | "types": [] 25 | }, 26 | "exclude": [ 27 | "material-components-web" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 3 | 4 | module.exports = 5 | [ 6 | /* 7 | "button", 8 | "card", 9 | "checkbox", 10 | "chip", 11 | "chip-set", 12 | "dialog", 13 | "drawer", 14 | "enhanced-select", 15 | "fab", 16 | "form-field", 17 | "icon", 18 | "icon-button", 19 | "image-list", 20 | "layout-grid", 21 | "linear-progress", 22 | "list", 23 | "list-item", 24 | "menu", 25 | "radio", 26 | "ripple", 27 | "select", 28 | "slider", 29 | "snackbar", 30 | "switch", 31 | "tab-bar", 32 | "text-field", 33 | "top-app-bar", 34 | */ 35 | "material-components-web-elm", 36 | ].map(name => ({ 37 | entry: { 38 | [`${name}`]: `./src/${name}.js`, 39 | [`${name}.min`]: `./src/${name}.js` 40 | }, 41 | devtool: "source-map", 42 | output: { 43 | path: path.resolve(__dirname, "dist"), 44 | filename: name === "material-components-web-elm" ? `[name].js` : `mdc-[name].js` 45 | }, 46 | module: { 47 | rules: [ 48 | { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }, 49 | { test: /\.ts$/, exclude: /node_modules/, loader: "ts-loader" } 50 | ] 51 | }, 52 | optimization: { 53 | minimize: true, 54 | minimizer: [new UglifyJsPlugin({ 55 | include: /\.min\.js$/, 56 | sourceMap: true 57 | })] 58 | }, 59 | })); 60 | --------------------------------------------------------------------------------