├── .github ├── FUNDING.yml └── workflows │ └── release.yml ├── .gitignore ├── LICENSE ├── README.md ├── assets └── diagram-alert.svg ├── birdie_snapshots ├── tween_in_back.accepted ├── tween_in_bounce.accepted ├── tween_in_circ.accepted ├── tween_in_cubic.accepted ├── tween_in_elastic.accepted ├── tween_in_expo.accepted ├── tween_in_out_back.accepted ├── tween_in_out_bounce.accepted ├── tween_in_out_circ.accepted ├── tween_in_out_cubic.accepted ├── tween_in_out_elastic.accepted ├── tween_in_out_expo.accepted ├── tween_in_out_quadratic.accepted ├── tween_in_out_quartic.accepted ├── tween_in_out_quint.accepted ├── tween_in_out_sine.accepted ├── tween_in_quadratic.accepted ├── tween_in_quartic.accepted ├── tween_in_quint.accepted ├── tween_in_sine.accepted ├── tween_linear.accepted ├── tween_out_back.accepted ├── tween_out_bounce.accepted ├── tween_out_circ.accepted ├── tween_out_cubic.accepted ├── tween_out_elastic.accepted ├── tween_out_expo.accepted ├── tween_out_quadratic.accepted ├── tween_out_quartic.accepted ├── tween_out_quint.accepted └── tween_out_sine.accepted ├── gleam.toml ├── manifest.toml ├── pages └── components.md ├── priv └── static │ └── lustre_ui.css ├── src ├── dom.ffi.mjs ├── lustre │ └── ui │ │ ├── accordion.css │ │ ├── accordion.gleam │ │ ├── alert.css │ │ ├── alert.gleam │ │ ├── badge.css │ │ ├── badge.gleam │ │ ├── breadcrumb.css │ │ ├── breadcrumb.gleam │ │ ├── button.css │ │ ├── button.gleam │ │ ├── card.css │ │ ├── card.gleam │ │ ├── checkbox.css │ │ ├── checkbox.gleam │ │ ├── colour.gleam │ │ ├── combobox.css │ │ ├── combobox.gleam │ │ ├── data │ │ └── bidict.gleam │ │ ├── divider.css │ │ ├── divider.gleam │ │ ├── input.css │ │ ├── input.gleam │ │ ├── primitives │ │ ├── collapse.css │ │ ├── collapse.gleam │ │ ├── icon.css │ │ ├── icon.gleam │ │ ├── popover.css │ │ ├── popover.gleam │ │ └── reset.css │ │ ├── reveal.gleam │ │ ├── theme.gleam │ │ ├── ticker.gleam │ │ └── tween.gleam └── scheduler.ffi.mjs └── test ├── build.gleam ├── lustre └── ui │ └── tween_test.gleam └── lustre_ui_test.gleam /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [hayleigh-dot-dev] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | tags: ["v*"] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3.1.0 13 | - uses: erlef/setup-beam@v1.16.0 14 | with: 15 | otp-version: "27.0" 16 | rebar3-version: "3" 17 | gleam-version: "1.5.1" 18 | 19 | - run: | 20 | version="v$(cat gleam.toml | grep -m 1 "version" | sed -r "s/version *= *\"([[:digit:].]+)\"/\1/")" 21 | if [ "$version" != "${{ github.ref_name }}" ]; then 22 | echo "tag '${{ github.ref_name }}' does not match the version in gleam.toml" 23 | echo "expected a tag name 'v$version'" 24 | exit 1 25 | fi 26 | name: check version 27 | 28 | - run: gleam format --check 29 | 30 | - run: gleam test 31 | 32 | - run: gleam publish -y 33 | env: 34 | HEXPM_USER: ${{ secrets.HEX_USERNAME }} 35 | HEXPM_PASS: ${{ secrets.HEX_PASSWORD }} 36 | 37 | - uses: softprops/action-gh-release@v1 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.beam 2 | *.ez 3 | build 4 | erl_crash.dump 5 | node_modules 6 | example/index.html 7 | example/priv 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023 Lustre Labs SRL. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in the 5 | Software without restriction, including without limitation the rights to use, 6 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 7 | Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Lustre UI

2 | 3 |
4 | A thoughtfully designed UI library for Lustre. 5 |
6 | 7 |
8 | 9 |
10 | 11 | Available on Hex 13 | 14 |
15 | 16 |
17 |

18 | 19 | Lustre 20 | 21 | | 22 | 23 | Discord 24 | 25 |

26 |
27 | 28 |
29 | Built with ❤︎ by 30 | Hayleigh Thompson 31 |
32 | 33 | --- 34 | 35 | ## Features 36 | 37 | - A set of **thoughtfully designed** and **accessible** components that have been 38 | written with idiomatic Gleam and CSS in mind. 39 | 40 | - A customisable **theme system** to tweak colours, spacing, and typography to 41 | fit your brand. 42 | 43 | ## Philosophy 44 | 45 | Many of Lustre's users are backend or fullstack developers with less interest or 46 | experience in frontend development. Lustre UI is primarily designed with those 47 | folks in mind, and has two main goals: 48 | 49 | - Make it easy to build good-looking, accessible UIs without needing to know 50 | much about CSS or design. 51 | 52 | - Encourage well-structured semantic HTML and avoid div soup. 53 | 54 | To achieve this, Lustre UI is _opinionated_ on many aspects of the visual design. 55 | For folks that don't want to worry about design, this is a feature not a bug, but 56 | for users looking for a flexible "headless" UI library you will find that many 57 | aspects of each component's styles are customisable through CSS variables. 58 | 59 | ## Installation 60 | 61 | > **Note**: Lustre UI is currently in pre-release and under active development. 62 | > If you have any feedback or suggestions, please open an issue or reach out on 63 | > the [Gleam discord](https://discord.gg/Fm8Pwmy). 64 | 65 | Lustre UI is published on [Hex](https://hex.pm/packages/lustre_ui). To use it in 66 | your project with Gleam: 67 | 68 | ```sh 69 | gleam add lustre_ui@1.0.0-rc.1 70 | ``` 71 | 72 | Ensure the required CSS is rendered in your apps by serving the stylesheet found 73 | in the `priv/static` directory of this package! 74 | 75 | ## Support 76 | 77 | Lustre is mostly built by just me, [Hayleigh](https://github.com/hayleigh-dot-dev), 78 | around two jobs. If you'd like to support my work, you can [sponsor me on GitHub](https://github.com/sponsors/hayleigh-dot-dev). 79 | 80 | Contributions are also very welcome! If you've spotted a bug, or would like to 81 | suggest a feature, please open an issue or a pull request. 82 | 83 | ## Reads 84 | 85 | - https://www.aha.io/engineering/articles/web-components-and-implicit-slot-names 86 | - https://www.abeautifulsite.net/posts/dynamic-slots/ 87 | - https://thomaswilburn.github.io/wc-book/sd-slots.html 88 | - https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/ 89 | -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_back.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Back 4 | --- 5 | ◍ 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 | ◍◍◍◍ ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_bounce.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Bounce 4 | --- 5 | ◍◍ 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 | ◍◍ ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_circ.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Circ 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_cubic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in cubic 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_elastic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Elastic 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍◍◍◍◍◍◍◍◍ ◍◍ ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_expo.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Expo 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_back.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Back 4 | --- 5 | ◍◍◍ 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 | ◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_bounce.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Bounce 4 | --- 5 | ◍ ◍◍◍ 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 | ◍◍◍ ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_circ.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Circ 4 | --- 5 | ◍◍◍◍◍ 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 | ◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_cubic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out cubic 4 | --- 5 | ◍◍◍◍◍◍ 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 | ◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_elastic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Elastic 4 | --- 5 | ◍◍◍◍◍◍◍◍◍ 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 | ◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_expo.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Expo 4 | --- 5 | ◍◍◍◍◍◍◍◍◍ 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 | ◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_quadratic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out quadratic 4 | --- 5 | ◍◍◍ 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 | ◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_quartic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out quartic 4 | --- 5 | ◍◍◍◍◍◍◍◍ 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 | ◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_quint.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out Quint 4 | --- 5 | ◍◍◍◍◍◍◍◍◍ 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 | ◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_out_sine.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in out sine 4 | --- 5 | ◍◍◍ 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 | ◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_quadratic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in quadratic 4 | --- 5 | ◍ 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 | ◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_quartic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in quartic 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_quint.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in Quint 4 | --- 5 | ◍ 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 | ◍◍◍◍◍◍◍◍◍◍◍◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_in_sine.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween in sine 4 | --- 5 | ◍ 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 | ◍◍◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_linear.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween linear 4 | --- 5 | ◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_back.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Back 4 | --- 5 | ◍ ◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_bounce.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Bounce 4 | --- 5 | ◍ ◍◍ 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 | ◍◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_circ.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Circ 4 | --- 5 | ◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_cubic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out cubic 4 | --- 5 | ◍◍◍◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_elastic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Elastic 4 | --- 5 | ◍ ◍◍ ◍◍◍◍◍◍◍◍◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_expo.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Expo 4 | --- 5 | ◍◍◍◍◍◍◍◍◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_quadratic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out quadratic 4 | --- 5 | ◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_quartic.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out quartic 4 | --- 5 | ◍◍◍◍◍◍◍◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_quint.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out Quint 4 | --- 5 | ◍◍◍◍◍◍◍◍◍◍◍◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /birdie_snapshots/tween_out_sine.accepted: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.6 3 | title: Tween out sine 4 | --- 5 | ◍◍◍◍ 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 | ◍ -------------------------------------------------------------------------------- /gleam.toml: -------------------------------------------------------------------------------- 1 | name = "lustre_ui" 2 | version = "1.0.0-rc.1" 3 | description = "A collection of components and design tokens for building Lustre apps." 4 | target = "javascript" 5 | 6 | licences = ["MIT"] 7 | repository = { type = "github", user = "lustre-labs", repo = "lustre_ui" } 8 | links = [ 9 | { title = "Website", href = "https://lustre.build" }, 10 | { title = "Sponsor", href = "https://github.com/sponsors/hayleigh-dot-dev" }, 11 | ] 12 | 13 | internal_modules = [ 14 | "lustre_ui", 15 | "lustre/ui/data/*", 16 | "lustre/ui/internals/*", 17 | "lustre/ui/primitives/*", 18 | ] 19 | 20 | [dependencies] 21 | gleam_community_colour = ">= 1.4.0 and < 2.0.0" 22 | gleam_community_maths = ">= 1.1.1 and < 2.0.0" 23 | gleam_stdlib = ">= 0.40.0 and < 2.0.0" 24 | lustre = ">= 4.5.0 and < 5.0.0" 25 | decipher = ">= 1.2.1 and < 2.0.0" 26 | gleam_json = ">= 2.0.0 and < 3.0.0" 27 | 28 | [dev-dependencies] 29 | birdie = ">= 1.1.6 and < 2.0.0" 30 | gleeunit = "~> 1.0" 31 | globlin = ">= 2.0.2 and < 3.0.0" 32 | simplifile = ">= 2.2.0 and < 3.0.0" 33 | -------------------------------------------------------------------------------- /manifest.toml: -------------------------------------------------------------------------------- 1 | # This file was generated by Gleam 2 | # You typically do not need to edit this file 3 | 4 | packages = [ 5 | { name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" }, 6 | { name = "birdie", version = "1.2.4", build_tools = ["gleam"], requirements = ["argv", "edit_distance", "filepath", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_stdlib", "justin", "rank", "simplifile", "trie_again"], otp_app = "birdie", source = "hex", outer_checksum = "769AE13AB5B5B84E724E9966037DCCB5BD63B2F43C52EF80B4BF3351F64E469E" }, 7 | { name = "birl", version = "1.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "5C66647D62BCB11FE327E7A6024907C4A17954EF22865FE0940B54A852446D01" }, 8 | { name = "decipher", version = "1.2.1", build_tools = ["gleam"], requirements = ["birl", "gleam_json", "gleam_stdlib", "stoiridh_version"], otp_app = "decipher", source = "hex", outer_checksum = "4F82516A5FF09BD7DF352DE38F1691C2254508066152F5DEA8665B216A9C9909" }, 9 | { name = "edit_distance", version = "2.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "edit_distance", source = "hex", outer_checksum = "A1E485C69A70210223E46E63985FA1008B8B2DDA9848B7897469171B29020C05" }, 10 | { name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" }, 11 | { name = "glance", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "E155BA1A787FD11827048355021C0390D2FE9A518485526F631A9D472858CC6D" }, 12 | { name = "gleam_community_ansi", version = "1.4.1", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "4CD513FC62523053E62ED7BAC2F36136EC17D6A8942728250A9A00A15E340E4B" }, 13 | { name = "gleam_community_colour", version = "1.4.1", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "386CB9B01B33371538672EEA8A6375A0A0ADEF41F17C86DDCB81C92AD00DA610" }, 14 | { name = "gleam_community_maths", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_maths", source = "hex", outer_checksum = "6C4ED7BC7E7DF6977719B5F2CFE717EE8280D1CF6EA81D55FD9953758C7FD14E" }, 15 | { name = "gleam_erlang", version = "0.33.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "A1D26B80F01901B59AABEE3475DD4C18D27D58FA5C897D922FCB9B099749C064" }, 16 | { name = "gleam_json", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "0A57FB5666E695FD2BEE74C0428A98B0FC11A395D2C7B4CDF5E22C5DD32C74C6" }, 17 | { name = "gleam_otp", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "E9ED3DF7E7285DA0C440F46AE8236ADC8475E8CCBEE4899BF09A8468DA3F9187" }, 18 | { name = "gleam_regexp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "A3655FDD288571E90EE9C4009B719FEF59FA16AFCDF3952A76A125AF23CF1592" }, 19 | { name = "gleam_stdlib", version = "0.46.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "53940A91251A6BE9AEBB959D46E1CB45B510551D81342A52213850947732D4AB" }, 20 | { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, 21 | { name = "glexer", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "25E87F25706749E40C3CDC72D2E52AEA12260B23D14FD9E09A1B524EF393485E" }, 22 | { name = "globlin", version = "2.0.3", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib"], otp_app = "globlin", source = "hex", outer_checksum = "923BC16814DF95C4BB28111C266F0B873499480E6E125D5A16DBDF732E62CEB4" }, 23 | { name = "justin", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "justin", source = "hex", outer_checksum = "7FA0C6DB78640C6DC5FBFD59BF3456009F3F8B485BF6825E97E1EB44E9A1E2CD" }, 24 | { name = "lustre", version = "4.6.3", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "BDF833368F6C8F152F948D5B6A79866E9881CB80CB66C0685B3327E7DCBFB12F" }, 25 | { name = "ranger", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "B8F3AFF23A3A5B5D9526B8D18E7C43A7DFD3902B151B97EC65397FE29192B695" }, 26 | { name = "rank", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "rank", source = "hex", outer_checksum = "5660E361F0E49CBB714CC57CC4C89C63415D8986F05B2DA0C719D5642FAD91C9" }, 27 | { name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" }, 28 | { name = "stoiridh_version", version = "0.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "stoiridh_version", source = "hex", outer_checksum = "EEF8ADAB9755BD33EB202F169376F1A7797AEF90823FDCA671D8590D04FBF56B" }, 29 | { name = "trie_again", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "trie_again", source = "hex", outer_checksum = "5B19176F52B1BD98831B57FDC97BD1F88C8A403D6D8C63471407E78598E27184" }, 30 | ] 31 | 32 | [requirements] 33 | birdie = { version = ">= 1.1.6 and < 2.0.0" } 34 | decipher = { version = ">= 1.2.1 and < 2.0.0" } 35 | gleam_community_colour = { version = ">= 1.4.0 and < 2.0.0" } 36 | gleam_community_maths = { version = ">= 1.1.1 and < 2.0.0" } 37 | gleam_json = { version = ">= 2.0.0 and < 3.0.0" } 38 | gleam_stdlib = { version = ">= 0.40.0 and < 2.0.0" } 39 | gleeunit = { version = "~> 1.0" } 40 | globlin = { version = ">= 2.0.2 and < 3.0.0" } 41 | lustre = { version = ">= 4.5.0 and < 5.0.0" } 42 | simplifile = { version = ">= 2.2.0 and < 3.0.0" } 43 | -------------------------------------------------------------------------------- /pages/components.md: -------------------------------------------------------------------------------- 1 | # How we use components 2 | 3 | Some parts of Lustre UI use Lustre's component system to hide state and logic 4 | from the rest of your application. This can be an effective way to reduce 5 | boilerplate and manage complexity, but it might also challenge how you're used to 6 | thinking about Lustre applications. 7 | 8 | The rest of this doc will explain how we use components in Lustre UI and what you 9 | need to do to make sure things are working correctly. 10 | 11 | ## Knowing when something is a component 12 | 13 | Your view function in a Lustre application always has to return `Element(msg)` so 14 | it can be difficult to work out at a glance when something is a component or not. 15 | In Lustre UI we follow a convention where modules that contain components will 16 | *always* have at least two exports: 17 | 18 | - a `name` constant that is the name of the component, like 19 | `pub const name: String = "lustre-ui-collapse"`. 20 | 21 | - a `register` function that registers the custom element in the browser. More 22 | on that in a moment. 23 | 24 | If a module does _not_ define these two exports, then it is not defining a 25 | component. 26 | 27 | Some modules might _use_ components without defining them directly. In those 28 | cases the module will always return a `register` function to register any of the 29 | components it depends on. This function will behave slightly differently to the 30 | individual register functions, and _will not fail_ if a component has already 31 | been defined. 32 | 33 | ## Components must be registered 34 | 35 | If you are using Lustre UI in a browser-based Lustre application, you must 36 | remember to register any components you use _before_ you try to render them. 37 | 38 | 39 | Lustre's components are built on top of the Web Component standards and appear as 40 | real HTML elements in the DOM. 41 | 42 | ## Components are always controlled 43 | 44 | Native HTML elements like `` or `