git.iko.soy/typeable/elm-ui
on 47ad492 help sign in
.github/ISSUE_TEMPLATE/bug-unexpected-behavior-report.mddeleted−21
since splitsnapshots
unifiedsplit
@@ -1,21 +0,0 @@
1−---
2−name: Bug/Unexpected behavior report
3−about: Capture any unexpected behavior or bugs you've found with this library
4−
5−---
6−
7−**Welcome!**
8−
9−If you can, please put together a [Short, Self Contained, Correct, Example](http://sscce.org/) of what you're encountering. It really helps if the example is as succinct as possible.
10−
11−Here's a basic template in [ellie](https://www.ellie-app.com/3fhCyrxjLw3a1) to get you started!
12−
13−**Expected behavior**
14−A clear and concise description of what you expected to happen.
15−
16−**Versions**
17− - OS: [e.g. iOS]
18− - Browser [e.g. chrome, safari]
19− - Browser Version
20− - Elm Version
21− - Elm UI Version [e.g. ]
.github/workflows/docs-preview.ymldeleted−36
@@ -1,36 +0,0 @@
1−# This is a basic workflow to help you get started with Actions
2−
3−name: Documentation
4−
5−# Controls when the action will run. Triggers the workflow on push or pull request
6−# events but only for the master branch
7−on:
8− push:
9− branches: [ master ]
10− pull_request:
11− branches: [ master ]
12−
13−# A workflow run is made up of one or more jobs that can run sequentially or in parallel
14−jobs:
15− # This workflow contains a single job called "build"
16− build:
17− # The type of runner that the job will run on
18− runs-on: ubuntu-latest
19−
20−
21− # Steps represent a sequence of tasks that will be executed as part of the job
22− steps:
23− # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
24− - uses: actions/checkout@v2
25−
26− - name: Setup node
27− uses: actions/setup-node@v1
28− with:
29− node-version: 10
30−
31− - name: Install
32− run: npm install
33−
34− # Runs a single command using the runners shell
35− - name: Run a one-line script
36− run: npm run test-doc-preview
.github/workflows/label-issues-from-body.ymldeleted−14
@@ -1,14 +0,0 @@
1−name: "Label issue from body keyword"
2−on:
3− issues:
4− types: [opened, edited]
5−
6−jobs:
7− test:
8− runs-on: ubuntu-latest
9− steps:
10− - uses: Naturalclar/issue-action@v1.0.0
11− with:
12− keywords: '["https://ellie-app.com/"]'
13− labels: '["has-ellie"]'
14− github-token: "${{ secrets.GITHUB_TOKEN }}"
.github/workflows/label-issues-from-comments.ymldeleted−59
@@ -1,59 +0,0 @@
1−name: "Label issue from comment keyword"
2−on:
3− issue_comment:
4− types: [created, edited]
5−
6−jobs:
7− test:
8− runs-on: ubuntu-latest
9− steps:
10− - uses: Amwam/issue-comment-action@v1.3.1
11− with:
12− keywords: '["#bug"]'
13− labels: '["bug"]'
14− github-token: "${{ secrets.GITHUB_TOKEN }}"
15− - uses: Amwam/issue-comment-action@v1.3.1
16− with:
17− keywords: '["#feature-suggestion"]'
18− labels: '["feature-suggestion"]'
19− github-token: "${{ secrets.GITHUB_TOKEN }}"
20− - uses: Amwam/issue-comment-action@v1.3.1
21− with:
22− keywords: '["#has-ellie", "https://ellie-app.com/"]'
23− labels: '["has-ellie"]'
24− github-token: "${{ secrets.GITHUB_TOKEN }}"
25− - uses: Amwam/issue-comment-action@v1.3.1
26− with:
27− keywords: '["#no-ellie"]'
28− labels: '["no-ellie"]'
29− github-token: "${{ secrets.GITHUB_TOKEN }}"
30− - uses: Amwam/issue-comment-action@v1.3.1
31− with:
32− keywords: '["#has-test"]'
33− labels: '["has-test"]'
34− github-token: "${{ secrets.GITHUB_TOKEN }}"
35− - uses: Amwam/issue-comment-action@v1.3.1
36− with:
37− keywords: '["#pain-point"]'
38− labels: '["pain-point"]'
39− github-token: "${{ secrets.GITHUB_TOKEN }}"
40− - uses: Amwam/issue-comment-action@v1.3.1
41− with:
42− keywords: '["#test-incorrectly-passing"]'
43− labels: '["test-incorrectly-passing"]'
44− github-token: "${{ secrets.GITHUB_TOKEN }}"
45− - uses: Amwam/issue-comment-action@v1.3.1
46− with:
47− keywords: '["#test-not-compiling"]'
48− labels: '["test-not-compiling"]'
49− github-token: "${{ secrets.GITHUB_TOKEN }}"
50− - uses: Amwam/issue-comment-action@v1.3.1
51− with:
52− keywords: '["#test-failing"]'
53− labels: '["test-failing"]'
54− github-token: "${{ secrets.GITHUB_TOKEN }}"
55− - uses: Amwam/issue-comment-action@v1.3.1
56− with:
57− keywords: '["#unexpected"]'
58− labels: '["unexpected"]'
59− github-token: "${{ secrets.GITHUB_TOKEN }}"
.github/workflows/tests.ymldeleted−43
@@ -1,43 +0,0 @@
1−name: Test Suite
2−
3−on:
4− push:
5− branches: [ master ]
6− pull_request:
7− branches: [ master ]
8−
9−
10−jobs:
11− testing:
12− runs-on: ubuntu-latest
13−
14− steps:
15− - uses: actions/checkout@v2
16−
17− - name: Setup node
18− uses: actions/setup-node@v1
19− with:
20− node-version: 10
21−
22− - uses: actions/cache@v1
23− with:
24− path: ~/.npm
25− key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
26− restore-keys: |
27− ${{ runner.os }}-node-
28−
29− - name: Install
30− run: npm ci
31−
32− - name: Elm test suite
33− run: npm run test
34−
35− - uses: webfactory/ssh-agent@v0.2.0
36− with:
37− ssh-private-key: ${{ secrets.ELM_UI_TESTING_SSH_PRIVATE_KEY }}
38−
39− - name: Rendering test suite on saucelabs
40− run: npm run test-render-sauce-automated -- --build=2.0.0 --name=development
41− env:
42− SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
43− SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
.gitignore+1−14
@@ -12,17 +12,4 @@ tests/html-generation/rendered/
12env
12env
13elm.js
13elm.js
14
14
15−examples/temporary/
15+examples/temporary/
16−
17−.vscode
18−
19−
20−sauce.env
21−
22−__pycache__
23−node_modules
24−benchmarks/tmp
25−benchmarks/results
26−tests/tmp
27−
28−tmp
notes/CHANGES-FROM-STYLE-ELEMENTS.md → CHANGES-FROM-STYLE-ELEMENTS.mdrenamed+11−8
@@ -1,7 +1,10 @@
1# Compared to Style Elements
1# Compared to Style Elements
2
2
3+
3This was a MAJOR rewrite of Style Elements.
4This was a MAJOR rewrite of Style Elements.
4
5
6+
7+
5* **Major Performance improvement** - Style Elements v5 is much faster than v4 due to a better rendering strategy and generating very minimal html. The rewritten architecture also allows me to explore a few other optimizations, so things may get even faster than they are now.
8* **Major Performance improvement** - Style Elements v5 is much faster than v4 due to a better rendering strategy and generating very minimal html. The rewritten architecture also allows me to explore a few other optimizations, so things may get even faster than they are now.
6
9
7* **Lazy is here!** - It works with no weird caveats.
10* **Lazy is here!** - It works with no weird caveats.
@@ -51,16 +54,16 @@ My current thinking is that you have 2 really powerful methods of capturing your
512. **Capture your colors, font sizes, etc.** Create a `Style` module that captures the **values** you use for your styling. Keep your colors there, as well as values for spacing, font names, and font sizes all in one place. You should consider using a scaling function for things like spacing and fontsizes.
542. **Capture your colors, font sizes, etc.** Create a `Style` module that captures the **values** you use for your styling. Keep your colors there, as well as values for spacing, font names, and font sizes all in one place. You should consider using a scaling function for things like spacing and fontsizes.
52
55
53
56
54−## Element.Region
57+## Element.Area
55
58
56−The `Element.Region` module is now how you can do accessibility markup.
59+The `Element.Area` module is now how you can do accessibility markup.
57
60
58You can do this by adding an area notation to an element's attributes.
61You can do this by adding an area notation to an element's attributes.
59
62
60```elm
63```elm
61−import Element.Region as Region
64+import Element.Area as Area
62
65
63−row [ Region.navigation ]
66+row [ Area.navigation ]
64 [ --..my navigation links
67 [ --..my navigation links
65 ]
68 ]
66
69
@@ -68,7 +71,7 @@ row [ Region.navigation ]
68Or you can make something an `<h1>`
71Or you can make something an `<h1>`
69
72
70```
73```
71−el [ Region.heading 1 ] (text "Super important stuff")
74+el [ Area.heading 1 ] (text "Super important stuff")
72
75
73```
76```
74
77
@@ -108,7 +111,7 @@ Also of note, is that if something is `center`, then it will truly be in the cen
108
111
109**When/WhenJust** - `when` and `whenJust` are removed, though you can easily make a convenience function for yourself! I wanted the library to place an emphasis on common elm constructs instead of library-specific ones. As far as shortcuts, they don't actually save you much anyway.
112**When/WhenJust** - `when` and `whenJust` are removed, though you can easily make a convenience function for yourself! I wanted the library to place an emphasis on common elm constructs instead of library-specific ones. As far as shortcuts, they don't actually save you much anyway.
110
113
111−**Full, Spacer** - `full` and `spacer` have been removed in order to follow the libraries priority of explicitness. `full` would override the parents padding, while `spacer` would override the parent's `spacing`. Both can be achieved with the more common primitives of `row`, `column` and `spacing`, and potentially some nesting of layouts.
114+**Full, Spacer** - `full` and `spacer` have been removed in order to follow the libraries priority of explicitness. `full` would override the parents padding, while `spacer` would override the parent's `spacing`. Both can be achieved with the more common primities of `row`, `column` and `spacing`, and potentially some nesting of layouts.
112
115
113
116
114
117
@@ -116,7 +119,7 @@ Also of note, is that if something is `center`, then it will truly be in the cen
116
119
117- `Font.weight` has been removed in favor of `Font.extraBold`, `Font.regular`, `Font.light`, etc. All weights from 100 - 900 are represented.
120- `Font.weight` has been removed in favor of `Font.extraBold`, `Font.regular`, `Font.light`, etc. All weights from 100 - 900 are represented.
118- `Background.image` and `Background.fittedImage` will place a centered background image, instead of anchoring at the top left.
121- `Background.image` and `Background.fittedImage` will place a centered background image, instead of anchoring at the top left.
119−- `fill |> minimum 20 |> maximum 200` is now present for `minWidth`, `maxWidth`, `minHeight` and `maxHeight` behavior. It works like fill, but with an optional top and lower bound.
122+- `fillBetween { min : Maybe Int, max : Maybe Int}` is now present for `min/max height/width` behavior. It works like fill, but with an optional top and lower bound.
120- `transparent` - Set an element as transparent. It will take up space, but otherwise be transparent and unclickable.
123- `transparent` - Set an element as transparent. It will take up space, but otherwise be transparent and unclickable.
121- `alpha` can now be set for an element.
124- `alpha` can now be set for an element.
122- `attribute` has been renamed `htmlAttribute` to better convey what it's used for.
125- `attribute` has been renamed `htmlAttribute` to better convey what it's used for.
@@ -129,7 +132,7 @@ Also of note, is that if something is `center`, then it will truly be in the cen
129
132
130The default logic has been made more consistent and hopefully more intuitive.
133The default logic has been made more consistent and hopefully more intuitive.
131
134
132−All elements start with `width/height shrink`, which means that they are the size of their contents.
135+Al elements start with `width/height shrink`, which means that they are the size of their contents.
133
136
134
137
135# PseudoClass Support
138# PseudoClass Support
CONTRIBUTING.mddeleted−25
@@ -1,25 +0,0 @@
1−# Contributing to Elm UI
2−
3−Welcome!
4−
5−First, if you have a question about how to do something with the library, join `#elm-ui` on the [Elm Slack](https://elmlang.herokuapp.com/)! There are usually a number of people who are willing to help out, myself included.
6−
7−That's the place to ask questions, try there first.
8−
9−A few notes about my design process for `elm-ui`.
10−
11−I don't usually accept PRs that add features. Mainly this is because there is a bunch of design thought and research that needs to be done before a feature can be added.
12−
13−So, here are some other ways you can help if you so desire!
14−
15−# Bugs and Unexpected Things
16−
17−If you run into unexpected behavior, I definitely want to hear about it. Put together a [Short, Self Contained, Correct, Example](http://sscce.org/) of what you're encountering. It really helps if the example is as succinct as possible.
18−
19−Here's a basic template in [ellie](https://ellie-app.com/3fhCyrxjLw3a1) to get you started!
20−
21−# Research
22−
23−One of the more challenging parts of the project like this is gathering information.
24−
25−If you know of good resources about accessibility, internationalization, design, or [any of the topics listed in the research folder](https://github.com/mdgriffith/elm-ui/tree/master/notes/research), send them my way either via PR to those documents or on slack.
CSS-LOOKUP.md+1−1
@@ -15,4 +15,4 @@ CSS | Style Elements | Description
15`margin` | __N/A__ Instead, check out `padding` and `spacing` | `margin` in CSS was designed to fight with `padding`. This library was designed to minimize override logic and properties that fight with each other in order to create a layout language that is predictable and easy to think about. The result is that in style elements, there's generally only *one place* where an effect can happen.
15`margin` | __N/A__ Instead, check out `padding` and `spacing` | `margin` in CSS was designed to fight with `padding`. This library was designed to minimize override logic and properties that fight with each other in order to create a layout language that is predictable and easy to think about. The result is that in style elements, there's generally only *one place* where an effect can happen.
16`:hover`, `:focus`, `:active` | `mouseOver`, `focused`, `mouseDown` | Only certain styles are allowed to be in a pseudo state. They have the type `Attr decorative msg`, which means they can be either an `Attribute` or a `Decoration`.
16`:hover`, `:focus`, `:active` | `mouseOver`, `focused`, `mouseDown` | Only certain styles are allowed to be in a pseudo state. They have the type `Attr decorative msg`, which means they can be either an `Attribute` or a `Decoration`.
17`<form>` | __N/a__ | __Elm__ already has a mechanism for submiting data to a server, namely the `Http` package. There has been some mention that the `form` element might be beneficial accessibility-wise, which I'm definitely open to hearing about!
17`<form>` | __N/a__ | __Elm__ already has a mechanism for submiting data to a server, namely the `Http` package. There has been some mention that the `form` element might be beneficial accessibility-wise, which I'm definitely open to hearing about!
18−`onSubmit` | __N/A__ | Similar to `<form>`, there is no `onSubmit` behavior. Likely if you're attempting to capture some of the keybaord related behavior of `onSubmit`, you're likely better just crafting a keyboard event handler in the first place!
18+`onSubmit` | __N/A__ | Similar to `<form>`, there is no `onSubmit` behavior. Likely if you're attempting to capture some of the keybaord related behavior of `onSubmit`, you're likely better just crafting a keyboard even handler in the first place!
LICENSE+1−1
@@ -1,4 +1,4 @@
1−Copyright (c) 2020, Matthew Griffith
1+Copyright (c) 2018, Matthew Griffith
2All rights reserved.
2All rights reserved.
3
3
4Redistribution and use in source and binary forms, with or without
4Redistribution and use in source and binary forms, with or without
README.md+9−30
@@ -1,8 +1,3 @@
1−![](https://github.com/mdgriffith/elm-ui/workflows/Test%20Suite/badge.svg)
2−
3−
4−Check out the talk that goes with the library, [Building a Better Design Toolkit](https://www.youtube.com/watch?v=Ie-gqwSHQr0&t=2s)
5−
6# A New Language for Layout and Interface
1# A New Language for Layout and Interface
7
2
8CSS and HTML are actually quite difficult to use when you're trying to do the layout and styling of a web page.
3CSS and HTML are actually quite difficult to use when you're trying to do the layout and styling of a web page.
@@ -19,24 +14,19 @@ This means:
19* **Layout and style are explicit and easy to modify.** CSS and HTML as tools for a layout language are hard to modify because there's no central place that represents your layout. You're generally forced to bounce back and forth between multiple definitions in multiple files in order to adjust layout, even though it's probably the most common thing you'll do.
14* **Layout and style are explicit and easy to modify.** CSS and HTML as tools for a layout language are hard to modify because there's no central place that represents your layout. You're generally forced to bounce back and forth between multiple definitions in multiple files in order to adjust layout, even though it's probably the most common thing you'll do.
20
15
21
16
22−[Try this live example on Ellie!](https://ellie-app.com/7Cw4VCyr3RGa1)
23−
24```elm
17```elm
25−module Main exposing (..)
26−
27−import Element exposing (Element, el, text, row, alignRight, fill, width, rgb255, spacing, centerY, padding)
18+import Element exposing (Element, el, text, row, alignRight, rgb)
28import Element.Background as Background
19import Element.Background as Background
29import Element.Border as Border
20import Element.Border as Border
30−import Element.Font as Font
31
21
32
22
33main =
23main =
34 Element.layout []
24 Element.layout []
35− myRowOfStuff
25+ myElement
26+
36
27
37−myRowOfStuff : Element msg
38myRowOfStuff =
28myRowOfStuff =
39− row [ width fill, centerY, spacing 30 ]
29+ row [ width fill ]
40 [ myElement
30 [ myElement
41 , myElement
31 , myElement
42 , el [ alignRight ] myElement
32 , el [ alignRight ] myElement
@@ -46,32 +36,21 @@ myRowOfStuff =
46myElement : Element msg
36myElement : Element msg
47myElement =
37myElement =
48 el
38 el
49− [ Background.color (rgb255 240 0 245)
39+ [ Background.color (rgb 0.2 0.3 0.3)
50− , Font.color (rgb255 255 255 255)
40+ , Border.color (rgb 0.2 0.4 0.3)
51− , Border.rounded 3
52− , padding 30
53 ]
41 ]
54− (text "stylish!")
42+ (text "You've made a stylish element!")
55```
43```
56
44
57−# Join the Elm UI Slack!
58
45
59−First, if you have a question about how to do something with the library, join `#elm-ui` on the [Elm Slack](https://elmlang.herokuapp.com/)! There are usually a number of people who are willing to help out, myself included.
60
46
61−## History
62
47
63−The work is based off of a rewrite of the [Style Elements](https://github.com/mdgriffith/style-elements) library. A lot of that work was originally released under the [Stylish Elephants](https://github.com/mdgriffith/stylish-elephants) project.
48+## History
64
49
65−## Community Cookbook
50+The work is based off of a rewrite of the [Style Elements](https://github.com/mdgriffith/style-elements) library. A lot of that work was orignally released under the [Stylish Elephants](https://github.com/mdgriffith/stylish-elephants) project.
66
51
67−The community around `elm-ui` is maintaining a collection of examples called the [elm-ui-cookbook](https://github.com/rofrol/elm-ui-cookbook). If you are just starting out with `elm-ui`, or get stuck on specific things, this can be a great resource.
68
52
69−## Notes
70
53
71−Make sure to have `<!DOCTYPE html>` on top of your application; otherwise, things might get messed up in some browsers.
72
54
73−## Contributing
74
55
75−Want to help out fixing bugs or reporting issues?
76
56
77−Please add issues you find, and if you want to verify code you want to contribute, please read how to run the tests [here](https://github.com/mdgriffith/elm-ui/blob/master/notes/RUNNING_TESTS.md).
benchmarks/elm.jsondeleted−34
@@ -1,34 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− "src",
5− "../src"
6− ],
7− "elm-version": "0.19.1",
8− "dependencies": {
9− "direct": {
10− "avh4/elm-color": "1.0.0",
11− "elm/browser": "1.0.1",
12− "elm/core": "1.0.2",
13− "elm/html": "1.0.0",
14− "elm/json": "1.1.3",
15− "elm/time": "1.0.0",
16− "elm/virtual-dom": "1.0.2",
17− "terezka/line-charts": "2.0.0"
18− },
19− "indirect": {
20− "debois/elm-dom": "1.3.0",
21− "elm/parser": "1.1.0",
22− "elm/svg": "1.0.1",
23− "elm/url": "1.0.0",
24− "justinmimbs/date": "3.1.2",
25− "justinmimbs/time-extra": "1.1.0",
26− "myrho/elm-round": "1.0.4",
27− "ryannhg/date-format": "2.3.0"
28− }
29− },
30− "test-dependencies": {
31− "direct": {},
32− "indirect": {}
33− }
34−}
benchmarks/micro/Suite.elmdeleted−330
@@ -1,330 +0,0 @@
1−module Suite exposing (main)
2−
3−import Benchmark exposing (Benchmark)
4−import Benchmark.Runner exposing (BenchmarkProgram, program)
5−import Dict
6−import Element exposing (..)
7−import Element.Background as Background
8−import Element.Font as Font
9−import Html
10−import Html.Attributes
11−import Internal.Flag as Flag
12−import Internal.Model as Internal
13−import Json.Encode
14−import Set
15−
16−
17−dict : Benchmark
18−dict =
19− let
20− dest =
21− Dict.singleton "a" 1
22− in
23− Benchmark.describe "dictionary"
24− [ Benchmark.benchmark "get" (\_ -> Dict.get "a" dest)
25− , Benchmark.benchmark "insert" (\_ -> Dict.insert "b" 2 dest)
26− ]
27−
28−
29−main : BenchmarkProgram
30−main =
31− program <|
32− Benchmark.describe "sample"
33− [ --dict
34− -- , deduplications
35− -- renderPipeline
36− gatheringAttributes
37−
38− -- flagOperations
39− ]
40−
41−
42−flagOperations =
43− Benchmark.describe "Flag Operations"
44− [ Benchmark.benchmark "check if present" <|
45− \_ ->
46− Flag.present Flag.height Flag.none
47− , Benchmark.benchmark "add to flagt" <|
48− \_ ->
49− Flag.add Flag.height Flag.none
50− ]
51−
52−
53−gatheringAttributes =
54− Benchmark.describe "Gathering Attributes"
55− [ Benchmark.benchmark "existing - gatherAttrRecursive" <|
56− \_ ->
57− Internal.gatherAttrRecursive
58− (Internal.contextClasses Internal.AsEl)
59− Internal.Generic
60− Flag.none
61− Internal.Untransformed
62− []
63− []
64− Internal.NoNearbyChildren
65− [ Element.width Element.shrink
66− , Element.height Element.shrink
67− ]
68− , Benchmark.benchmark "Simple list filterMap" <|
69− \_ ->
70− List.filterMap
71− identity
72− [ Just "thing"
73− , Just "other width"
74− ]
75− , Benchmark.benchmark "Simple list map" <|
76− \_ ->
77− List.map
78− identity
79− [ Just "thing"
80− , Just "other width"
81− ]
82− , Benchmark.benchmark "Foldl base speed" <|
83− \_ ->
84− List.foldl
85− (::)
86− [ Just "thing"
87− , Just "other width"
88− ]
89− , Benchmark.benchmark "Recursive" <|
90− \_ ->
91− recurse
92− (::)
93− [ Just "thing"
94− , Just "other width"
95− ]
96− , Benchmark.benchmark "foldl - new record each iteration" <|
97− \_ ->
98− List.foldl flipFoldl
99− { attributes = "class"
100− , styles = []
101− , node = "Node"
102− , children = Nothing
103− , has = Flag.none
104− }
105− -- we reverse first because we have to for the attr api.
106− (List.reverse
107− [ Just "thing"
108− , Just "other width"
109− ]
110− )
111− , Benchmark.benchmark "foldl - update" <|
112− \_ ->
113− List.foldl flipFoldlUpdate
114− { attributes = "class"
115− , styles = []
116− , node = "Node"
117− , children = Nothing
118− , has = Flag.none
119− }
120− -- we reverse first because we have to for the attr api.
121− (List.reverse
122− [ Just "thing"
123− , Just "other width"
124− ]
125− )
126− , Benchmark.benchmark "String Concatenation" <|
127− \_ ->
128− "This"
129− ++ "this"
130− ++ "this"
131− ++ "this"
132− ++ "this"
133− ++ "this"
134− ++ "this"
135− ++ "this"
136− , Benchmark.benchmark "List String Concatenation" <|
137− \_ ->
138− String.concat
139− [ "This"
140− , "this"
141− , "this"
142− , "this"
143− , "this"
144− , "this"
145− , "this"
146− , "this"
147− ]
148− ]
149−
150−
151−flipFoldl result found =
152− { attributes = "class" ++ found.attributes
153− , styles = Just 1 :: found.styles
154− , node = found.node
155− , children = Nothing
156− , has = Flag.add Flag.height found.has
157− }
158−
159−
160−flipFoldlUpdate result found =
161− { found
162− | attributes = "class" ++ found.attributes
163− , styles = Just 1 :: found.styles
164− , has = Flag.add Flag.height found.has
165− }
166−
167−
168−recurse fn ls =
169− case ls of
170− [] ->
171− []
172−
173− fst :: remain ->
174− fn fst (recurse fn remain)
175−
176−
177−deduplications =
178− Benchmark.describe "deduplications"
179− [ Benchmark.benchmark "fold - dedup, String concat"
180− (\_ ->
181− String.join ":" (foldDedup largeList)
182− )
183− , Benchmark.benchmark "fold - dedup"
184− (\_ ->
185− foldDedup largeList
186− )
187− , Benchmark.benchmark "fold - dedup - Int"
188− (\_ ->
189− foldDedup largeListInt
190− )
191− , Benchmark.benchmark "Json encode"
192− (\_ ->
193− Json.Encode.object largeListJson
194− )
195− ]
196−
197−
198−foldDedup list =
199− let
200− dedup ( name, val ) ( cache, ls ) =
201− if Set.member name cache then
202− ( cache, ls )
203−
204− else
205− ( Set.insert name cache, val :: ls )
206− in
207− List.foldl dedup ( Set.empty, [] ) list
208− |> Tuple.second
209−
210−
211−largeListInt =
212− List.range 1 10000
213− |> List.map
214− (\i ->
215− let
216− wrappingI =
217− modBy 50 i
218− in
219− ( wrappingI, "elem-" ++ String.fromInt wrappingI )
220− )
221−
222−
223−largeList =
224− List.range 1 10000
225− |> List.map
226− (\i ->
227− let
228− wrappingI =
229− modBy 50 i
230− in
231− ( "elem-" ++ String.fromInt wrappingI, "elem-" ++ String.fromInt wrappingI )
232− )
233−
234−
235−largeListJson =
236− List.range 1 10000
237− |> List.map
238− (\i ->
239− let
240− wrappingI =
241− modBy 50 i
242− in
243− ( "elem-" ++ String.fromInt wrappingI, Json.Encode.string ("elem-" ++ String.fromInt wrappingI) )
244− )
245−
246−
247−renderPipeline =
248− [ Benchmark.benchmark "build 2000 elements"
249− (\_ ->
250− elements 0 twoThousand
251− )
252− , Benchmark.benchmark "build 2000 html"
253− (\_ ->
254− html 0 twoThousand
255− )
256− ]
257−
258−
259−twoThousand =
260− List.range 0 2000
261−
262−
263−elements i count =
264− Element.layout []
265− (Element.column [ spacing 8, centerX ]
266− (List.map (viewEl i) count)
267− )
268−
269−
270−viewEl selectedIndex index =
271− el
272− [ Background.color
273− (if selectedIndex == index then
274− pink
275−
276− else
277− white
278− )
279− , Font.color
280− (if selectedIndex /= index then
281− pink
282−
283− else
284− white
285− )
286− , padding 24
287− , width (px 500)
288− , height (px 70)
289− ]
290− (if selectedIndex == index then
291− text "selected"
292−
293− else
294− text "Hello!"
295− )
296−
297−
298−white =
299− rgb 1 1 1
300−
301−
302−pink =
303− rgb255 240 0 245
304−
305−
306−html i count =
307− Html.div []
308− [ Html.div []
309− (List.map (viewHtmlElement i) count)
310− ]
311−
312−
313−viewHtmlElement selectedIndex index =
314− Html.div
315− [ Html.Attributes.class
316− (if selectedIndex == index then
317− "white"
318−
319− else
320− "pink"
321− )
322− ]
323− [ Html.div []
324− [ if selectedIndex == index then
325− Html.text "selected"
326−
327− else
328− Html.text "Hello!"
329− ]
330− ]
benchmarks/micro/elm.jsondeleted−30
@@ -1,30 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− ".",
5− "../../src"
6− ],
7− "elm-version": "0.19.0",
8− "dependencies": {
9− "direct": {
10− "elm/browser": "1.0.1",
11− "elm/core": "1.0.2",
12− "elm/html": "1.0.0",
13− "elm/json": "1.1.3",
14− "elm/time": "1.0.0",
15− "elm/virtual-dom": "1.0.2",
16− "elm-explorations/benchmark": "1.0.1"
17− },
18− "indirect": {
19− "BrianHicks/elm-trend": "2.1.2",
20− "Skinney/murmur3": "2.0.8",
21− "elm/regex": "1.0.0",
22− "elm/url": "1.0.0",
23− "mdgriffith/style-elements": "5.0.1"
24− }
25− },
26− "test-dependencies": {
27− "direct": {},
28− "indirect": {}
29− }
30−}
benchmarks/runtime/benchPage.jsdeleted−146
@@ -1,146 +0,0 @@
1−const path = require('path');
2−
3−async function benchPage(page, file) {
4− const client = await page.target().createCDPSession();
5− await client.send('Performance.enable');
6− // await page.tracing.start({ path: 'trace.json' });
7− await page.goto('file://' + path.resolve(file))
8−
9− await page.waitFor(5000);
10− // await page.tracing.stop();
11− const metrics = await client.send('Performance.getMetrics');
12−
13− const startMetrics = await page.metrics()
14− await page.evaluate(() => { window.elmRefresh() })
15− await page.waitFor(1500);
16− const endMetrics = await page.metrics()
17−
18− await page.evaluate(() => { window.elmStartAnim() })
19− await sleep(5000)
20− await page.evaluate(() => { window.elmStopAnim() })
21− await page.waitFor(2000);
22− const finalMetrics = await page.metrics()
23− const frames = await page.evaluate(x => {
24− return Promise.resolve(window.metrics);
25− }, {});
26− return {
27− name: frames.name,
28− link: 'file://' + path.resolve(file),
29− perf: extract(metrics),
30− afterRefresh: {
31− RecalcStyleDuration: endMetrics.RecalcStyleDuration - startMetrics.RecalcStyleDuration,
32− LayoutDuration: endMetrics.LayoutDuration - startMetrics.LayoutDuration,
33− ScriptDuration: endMetrics.ScriptDuration - startMetrics.ScriptDuration,
34− JSHeapUsedSize: endMetrics.JSHeapUsedSize - startMetrics.JSHeapUsedSize
35− },
36− afterAnimation: {
37− RecalcStyleDuration: finalMetrics.RecalcStyleDuration - endMetrics.RecalcStyleDuration,
38− LayoutDuration: finalMetrics.LayoutDuration - endMetrics.LayoutDuration,
39− ScriptDuration: finalMetrics.ScriptDuration - endMetrics.ScriptDuration,
40− JSHeapUsedSize: finalMetrics.JSHeapUsedSize - endMetrics.JSHeapUsedSize
41− },
42− frames: summarize(frames.frames),
43− }
44−}
45−
46−function summarize(frames) {
47− return {
48− count: frames.length,
49− median: median(frames),
50− mode: mode(frames),
51− avg: average(frames),
52− fps: 1000 / median(frames),
53− min: minimum(frames),
54− max: maximum(frames)
55− }
56−}
57−
58−const keep = ["Timestamp", "Nodes", "LayoutDuration", "RecalcStyleDuration", "ScriptDuration", "JSHeapUsedSize", "FirstMeaningfulPaint", "DomContentLoaded", "NavigationStart"]
59−
60−
61−function extract(metrics) {
62− var ext = {}
63− metrics.metrics.forEach((item) => {
64− if (keep.indexOf(item.name) >= 0) {
65− ext[item.name] = item.value
66− }
67− })
68− ext.TimeToFirstPaintMS = 1000 * (ext.FirstMeaningfulPaint - ext.DomContentLoaded)
69− return ext
70−}
71−
72−function mode(array) {
73− if (array.length == 0)
74− return null;
75− var modeMap = {};
76− var maxEl = array[0], maxCount = 1;
77− for (var i = 0; i < array.length; i++) {
78− var el = array[i];
79− if (modeMap[el] == null)
80− modeMap[el] = 1;
81− else
82− modeMap[el]++;
83− if (modeMap[el] > maxCount) {
84− maxEl = el;
85− maxCount = modeMap[el];
86− }
87− }
88− return maxEl;
89−}
90−
91−function minimum(values) {
92− var m = null
93− for (var i = 0; i < values.length; i++) {
94− if (m == null) {
95− m = values[i]
96− } else if (values[i] < m) {
97− m = values[i]
98− }
99− }
100− return m
101−}
102−
103−
104−function maximum(values) {
105− var m = null
106− for (var i = 0; i < values.length; i++) {
107− if (m == null) {
108− m = values[i]
109− } else if (values[i] > m) {
110− m = values[i]
111− }
112− }
113− return m
114−}
115−
116−
117−function average(values) {
118− var total = 0;
119− for (var i = 0; i < values.length; i++) {
120− total += values[i];
121− }
122− return total / values.length;
123−}
124−
125−function median(values) {
126− if (values.length === 0) return 0;
127−
128− values.sort(function (a, b) {
129− return a - b;
130− });
131−
132− var half = Math.floor(values.length / 2);
133−
134− if (values.length % 2)
135− return values[half];
136−
137− return (values[half - 1] + values[half]) / 2.0;
138−}
139−
140−
141−function sleep(ms) {
142− return new Promise(resolve => {
143− setTimeout(resolve, ms)
144− })
145−}
146−module.exports = benchPage;
benchmarks/runtime/index.jsdeleted−176
@@ -1,176 +0,0 @@
1−const puppeteer = require('puppeteer');
2−const benchPage = require('./benchPage');
3−const chalk = require('chalk');
4−var compileToString = require("node-elm-compiler").compileToString;
5−const fs = require('fs');
6−
7−
8−
9−
10−
11−function write_entrypoint(item) {
12−
13− const entrypoint = `module Main exposing (main)
14−import ${item.module}
15−import Benchmark.Render
16−
17−main = Benchmark.Render.toProgram ${item.module}.${item.value}
18−`
19− fs.writeFileSync('./benchmarks/tmp/Main.elm', entrypoint);
20−}
21−
22−async function compile_and_embed(config) {
23− var template = fs.readFileSync(config.template)
24− // we embed the compiled js to avoid having to start a server to read the app.
25− await compileToString(config.elm, config.elmOptions).then(function (compiled_elm_code) {
26− const compiled = eval(`\`${template}\``)
27− fs.writeFileSync(config.target, compiled)
28− });
29−}
30−
31−
32−function regroupResults(results) {
33− var regrouped = {}
34−
35− for (var i = 0; i < results.length; i++) {
36− if (results[i].group) {
37−
38− var reorged = {
39− name: results[i].name
40− , link: results[i].link
41− , count: results[i].count
42− , fps: results[i].frames.fps
43− , timeToFirstPaintMS: results[i].perf.TimeToFirstPaintMS
44− , nodes: results[i].perf.Nodes
45− , coldRender: {
46− layoutSeconds: results[i].perf.LayoutDuration
47− , recalcStyleSeconds: results[i].perf.RecalcStyleDuration
48− , scriptDurationSeconds: results[i].perf.ScriptDuration
49−
50− }
51− , warmRender: {
52− layoutSeconds: results[i].afterRefresh.LayoutDuration
53− , recalcStyleSeconds: results[i].afterRefresh.RecalcStyleDuration
54− , scriptDurationSeconds: results[i].afterRefresh.ScriptDuration
55−
56− }
57− , extendedRender: {
58− layoutSeconds: results[i].afterAnimation.LayoutDuration
59− , recalcStyleSeconds: results[i].afterAnimation.RecalcStyleDuration
60− , scriptDurationSeconds: results[i].afterAnimation.ScriptDuration
61−
62− }
63−
64− }
65− if (results[i].group in regrouped) {
66− regrouped[results[i].group].results.push(reorged)
67− } else {
68− regrouped[results[i].group] = { results: [reorged], name: results[i].group }
69− }
70− }
71− }
72− return Object.values(regrouped)
73−}
74−
75−
76−var contain = [{ module: "Contain", group: "html", count: 1024, value: "viewHtml8192" }
77− , { module: "Contain", group: "contain", count: 128, value: "viewHtmlContain8192" }]
78−
79−
80−async function writeResults(allResults, resultsDir, name) {
81−
82− if (!fs.existsSync(resultsDir)) {
83− fs.mkdirSync(resultsDir);
84− }
85− var results = JSON.stringify(allResults)
86− var template = fs.readFileSync("./benchmarks/runtime/template/viewResults.html")
87− // we embed the compiled js to avoid having to start a server to read the app.
88− await compileToString(["./src/View/Results.elm"], { optimize: true, cwd: "./benchmarks" }).then(function (compiled_elm_code) {
89− const compiled = eval(`\`${template}\``)
90− fs.writeFileSync(`./${resultsDir}/${name}/index.html`, compiled)
91− });
92−
93− // fs.writeFileSync(`./${resultsDir}/1.1.1-candidate-optimized.json`, results)
94−}
95−
96−
97−(async () => {
98− const browser = await puppeteer.launch();
99−
100−
101− var instances = [
102− { module: "ManyElements", group: "elmUI", count: 1024, value: "elmUI1024" }
103− , { module: "ManyElements", group: "elmUI", count: 128, value: "elmUI128" }
104− , { module: "ManyElements", group: "elmUI", count: 2048, value: "elmUI2048" }
105− , { module: "ManyElements", group: "elmUI", count: 24, value: "elmUI24" }
106− , { module: "ManyElements", group: "elmUI", count: 4096, value: "elmUI4096" }
107− , { module: "ManyElements", group: "elmUI", count: 8192, value: "elmUI8192" }
108− , { module: "ManyElements", group: "elmUIVCSS", count: 1024, value: "elmUIVCSS1024" }
109− , { module: "ManyElements", group: "elmUIVCSS", count: 2048, value: "elmUIVCSS2048" }
110− , { module: "ManyElements", group: "elmUIVCSS", count: 24, value: "elmUIVCSS24" }
111− , { module: "ManyElements", group: "elmUIVCSS", count: 4096, value: "elmUIVCSS4096" }
112− , { module: "ManyElements", group: "elmUIVCSS", count: 8192, value: "elmUIVCSS8192" }
113− , { module: "ManyElements", group: "viewHtml", count: 1024, value: "viewHtml1024" }
114− , { module: "ManyElements", group: "viewHtml", count: 2048, value: "viewHtml2048" }
115− , { module: "ManyElements", group: "viewHtml", count: 24, value: "viewHtml24" }
116− , { module: "ManyElements", group: "viewHtml", count: 4096, value: "viewHtml4096" }
117− , { module: "ManyElements", group: "viewHtml", count: 8192, value: "viewHtml8192" }
118− , { module: "ManyElements", group: "viewInline", count: 1024, value: "viewInline1024" }
119− , { module: "ManyElements", group: "viewInline", count: 2048, value: "viewInline2048" }
120− , { module: "ManyElements", group: "viewInline", count: 24, value: "viewInline24" }
121− , { module: "ManyElements", group: "viewInline", count: 4096, value: "viewInline4096" }
122− , { module: "ManyElements", group: "viewInline", count: 8192, value: "viewInline8192" }
123− ]
124−
125−
126− var dir = "tmp"
127− if (!fs.existsSync(dir)) {
128− fs.mkdirSync(dir);
129− }
130−
131− var dir = "./benchmarks/tmp"
132− if (!fs.existsSync(dir)) {
133− fs.mkdirSync(dir);
134− }
135−
136− var allResults = []
137− const resultsDir = "benchmarks/results"
138− const resultName = "1.2-cand"
139−
140− if (!fs.existsSync(`./${resultsDir}/${resultName}/instances/`)) {
141− fs.mkdirSync(`./${resultsDir}/${resultName}/instances/`, { recursive: true });
142− }
143−
144− console.log(`Beginning benchmark for ${resultName} →`)
145−
146− for (var i = 0; i < instances.length; i++) {
147− var item = instances[i]
148− write_entrypoint(item)
149− const test_file = `${resultsDir}/${resultName}/instances/${item.value}.html`
150− var template = fs.readFileSync("./benchmarks/runtime/template/run.html")
151− var cssom = fs.readFileSync("./experiments/virtual-css/cssom.js")
152− // we embed the compiled js to avoid having to start a server to read the app.
153− await compileToString(["tmp/Main.elm"], { optimize: true, cwd: "./benchmarks" }).then(function (compiled_elm_code) {
154− const compiled = eval(`\`${template}\``)
155− fs.writeFileSync(test_file, compiled)
156− });
157−
158− const page = await browser.newPage();
159− const results = await benchPage(page, test_file);
160− results.group = item.group
161− results.count = item.count
162− await page.close()
163− // console.log(results)
164− console.log(" Benchmark of " + chalk.green(`${item.module}.${item.value}`) + " complete")
165− allResults.push(results)
166− }
167− await browser.close();
168−
169− allResults = regroupResults(allResults)
170−
171− writeResults(allResults, resultsDir, resultName)
172− console.log()
173− console.log("Benchmark complete")
174− console.log(" → " + chalk.green(`${resultsDir}/${resultName}/index.html`))
175−
176−})();
benchmarks/runtime/template/run.htmldeleted−57
@@ -1,57 +0,0 @@
1−<!DOCTYPE HTML>
2−<html>
3−<head>
4− <meta charset="UTF-8">
5− <title>Main</title>
6− <script>
7− ${cssom}
8− </script>
9− <script>
10− ${compiled_elm_code}
11− </script>
12− <style>
13− .box {
14− width: 400px;
15− height: 50px;
16− border: solid thick;
17− }
18− .pink {
19− background-color: pink;
20− }
21− .white {
22− background-color: white;
23− }
24− .contain {
25− contain: strict;
26− }
27− </style>
28−</head>
29−
30−<body>
31− <div id="elm"></div>
32− <script>
33− var app = Elm.Main.init({
34− node: document.getElementById('elm')
35− });
36−
37− window.metrics = []
38− app.ports.elmToWorld.subscribe(function(fromElm){
39− window.metrics = fromElm
40− })
41−
42− function elmRefresh(){
43− app.ports.worldToElm.send({tag: "Refresh"})
44− }
45− function elmStartAnim(){
46− app.ports.worldToElm.send({tag: "StartAnim"})
47− }
48− function elmStopAnim(){
49− app.ports.worldToElm.send({tag: "StopAnim"})
50− }
51− window.elmRefresh = elmRefresh;
52− window.elmStartAnim = elmStartAnim;
53− window.elmStopAnim = elmStopAnim;
54−
55− </script>
56−</body>
57−</html>
benchmarks/runtime/template/viewResults.htmldeleted−24
@@ -1,24 +0,0 @@
1−<!DOCTYPE HTML>
2−<html>
3−<head>
4− <meta charset="UTF-8">
5− <title>Results</title>
6− <script>
7− ${compiled_elm_code}
8− </script>
9−</head>
10−
11−<body>
12− <div id="elm"></div>
13− <script>
14− const results = ${results}
15−
16− var app = Elm.View.Results.init({
17− node: document.getElementById('elm')
18− });
19−
20− app.ports.worldToElm.send(results)
21−
22− </script>
23−</body>
24−</html>
benchmarks/src/Baseline.elmdeleted−31
@@ -1,31 +0,0 @@
1−module Baseline exposing (bench)
2−
3−{-| -}
4−
5−import Benchmark.Render
6−import Html
7−
8−
9−type Msg
10− = Refresh
11− | Tick Float
12−
13−
14−bench : Benchmark.Render.Benchmark Int Msg
15−bench =
16− { name = "Baseline"
17− , init = 0
18− , view =
19− \i ->
20− Html.text (String.fromInt i)
21− , update =
22− \msg model ->
23− case msg of
24− Refresh ->
25− model + 1
26−
27− Tick i ->
28− model + 1
29− , tick = Tick
30− , refresh = Refresh
31− }
benchmarks/src/Benchmark/Render.elmdeleted−148
@@ -1,148 +0,0 @@
1−port module Benchmark.Render exposing (Benchmark, toProgram)
2−
3−{-| This is the rendering harness. The actual cases are in `src`.
4−-}
5−
6−import Browser
7−import Browser.Events
8−import Html exposing (Html)
9−import Html.Attributes as Attr
10−import Html.Events as Events
11−import Json.Decode as Decode
12−import Json.Encode as Encode
13−import Time
14−
15−
16−type alias Benchmark model msg =
17− { name : String
18− , init : model
19− , view : model -> Html Msg
20− , update : msg -> model -> model
21− , tick : Float -> msg
22− , refresh : msg
23− }
24−
25−
26−type alias Model model =
27− { model : model
28− , animating : Bool
29− , frames : List Float
30− }
31−
32−
33−type Msg
34− = Tick Float
35− | Refresh
36− | Received Encode.Value
37− | StartAnim
38− | StopAnim
39−
40−
41−toProgram : Benchmark model msg -> Program () (Model model) Msg
42−toProgram render =
43− Browser.document
44− { init =
45− \() ->
46− ( { model = render.init
47− , animating = False
48− , frames = []
49− }
50− , Cmd.none
51− )
52− , view =
53− \model ->
54− { title = render.name
55− , body =
56− [ Html.div
57− [ Attr.style "display" "flex"
58− , Attr.style "flex-direction" "row"
59− ]
60− [ Html.button [ Events.onClick Refresh ] [ Html.text "Refresh" ]
61− , Html.button [ Events.onClick StartAnim ] [ Html.text "StartAnim" ]
62− , Html.button [ Events.onClick StopAnim ] [ Html.text "StopAnim" ]
63− ]
64− , render.view model.model
65− ]
66− }
67− , update =
68− update render
69− , subscriptions =
70− \model ->
71− Sub.batch
72− [ worldToElm Received
73− , if model.animating then
74− Browser.Events.onAnimationFrameDelta Tick
75−
76− else
77− Sub.none
78− ]
79− }
80−
81−
82−update : Benchmark model msg -> Msg -> Model model -> ( Model model, Cmd Msg )
83−update render msg model =
84− case msg of
85− StartAnim ->
86− ( { model | animating = True }
87− , Cmd.none
88− )
89−
90− StopAnim ->
91− ( { model | animating = False }
92− , elmToWorld (encodeMetrics render.name model.frames)
93− )
94−
95− Refresh ->
96− ( { model | model = render.update render.refresh model.model }
97− , Cmd.none
98− )
99−
100− Tick time ->
101− ( { model
102− | model = render.update (render.tick time) model.model
103− , frames = time :: model.frames
104− }
105− , Cmd.none
106− )
107−
108− Received json ->
109− case Decode.decodeValue outsideMsg json of
110− Err err ->
111− ( model, Cmd.none )
112−
113− Ok newMsg ->
114− update render newMsg model
115−
116−
117−outsideMsg =
118− Decode.field "tag" Decode.string
119− |> Decode.andThen
120− (\tag ->
121− case tag of
122− "Refresh" ->
123− Decode.succeed Refresh
124−
125− "StartAnim" ->
126− Decode.succeed StartAnim
127−
128− "StopAnim" ->
129− Decode.succeed StopAnim
130−
131− _ ->
132− Decode.fail "Unknown incoming msg"
133− )
134−
135−
136−encodeMetrics name frames =
137− Encode.object
138− [ ( "name", Encode.string name )
139− , ( "frames"
140− , Encode.list Encode.float frames
141− )
142− ]
143−
144−
145−port worldToElm : (Encode.Value -> msg) -> Sub msg
146−
147−
148−port elmToWorld : Encode.Value -> Cmd msg
benchmarks/src/Contain.elmdeleted−159
@@ -1,159 +0,0 @@
1−module Contain exposing
2− ( viewHtml8192
3− , viewHtmlContain8192
4− )
5−
6−{-| -}
7−
8−import Benchmark.Render
9−import Element exposing (..)
10−import Element.Background as Background
11−import Element.Font as Font
12−import Element.Keyed
13−import Html
14−import Html.Attributes
15−import Internal.Model as Internal
16−
17−
18−type alias Model =
19− { index : Int
20− , numberOfElements : Int
21− , elements : List Int
22− }
23−
24−
25−type Msg
26− = Refresh
27− | Tick Float
28−
29−
30−viewHtml8192 : Benchmark.Render.Benchmark Model Msg
31−viewHtml8192 =
32− viewHtml "viewHtml8192" 8192
33−
34−
35−viewHtmlContain8192 : Benchmark.Render.Benchmark Model Msg
36−viewHtmlContain8192 =
37− viewHtmlContain "viewHtmlContain8192" 8192
38−
39−
40−white =
41− rgb 1 1 1
42−
43−
44−pink =
45− rgb255 240 0 245
46−
47−
48−{-| -}
49−viewHtml : String -> Int -> Benchmark.Render.Benchmark Model Msg
50−viewHtml name count =
51− { name = name
52− , init =
53− { index = 0
54− , numberOfElements = count
55− , elements = List.range 0 (count - 1)
56− }
57− , view =
58− \model ->
59− Html.div []
60− [ Html.div []
61− (List.map (viewHtmlElement model.index) model.elements)
62− ]
63− , update =
64− \msg model ->
65− case msg of
66− Refresh ->
67− if model.index > model.numberOfElements then
68− { model | index = 0 }
69−
70− else
71− { model | index = model.index + 1 }
72−
73− Tick i ->
74− if model.index > model.numberOfElements then
75− { model | index = 0 }
76−
77− else
78− { model | index = model.index + 1 }
79− , tick = Tick
80− , refresh = Refresh
81− }
82−
83−
84−viewHtmlElement selectedIndex index =
85− Html.div
86− [ Html.Attributes.class "box"
87− , Html.Attributes.class
88− (if selectedIndex == index then
89− "white"
90−
91− else
92− "pink"
93− )
94− ]
95− [ Html.div []
96− [ if selectedIndex == index then
97− Html.text "selected"
98−
99− else
100− Html.text "Hello!"
101− ]
102− ]
103−
104−
105−{-| -}
106−viewHtmlContain : String -> Int -> Benchmark.Render.Benchmark Model Msg
107−viewHtmlContain name count =
108− { name = name
109− , init =
110− { index = 0
111− , numberOfElements = count
112− , elements = List.range 0 (count - 1)
113− }
114− , view =
115− \model ->
116− Html.div []
117− [ Html.div []
118− (List.map (viewHtmlElementContain model.index) model.elements)
119− ]
120− , update =
121− \msg model ->
122− case msg of
123− Refresh ->
124− if model.index > model.numberOfElements then
125− { model | index = 0 }
126−
127− else
128− { model | index = model.index + 1 }
129−
130− Tick i ->
131− if model.index > model.numberOfElements then
132− { model | index = 0 }
133−
134− else
135− { model | index = model.index + 1 }
136− , tick = Tick
137− , refresh = Refresh
138− }
139−
140−
141−viewHtmlElementContain selectedIndex index =
142− Html.div
143− [ Html.Attributes.class "box contain"
144− , Html.Attributes.class
145− (if selectedIndex == index then
146− "white"
147−
148− else
149− "pink"
150− )
151− ]
152− [ Html.div []
153− [ if selectedIndex == index then
154− Html.text "selected"
155−
156− else
157− Html.text "Hello!"
158− ]
159− ]
benchmarks/src/ManyElements.elmdeleted−516
@@ -1,516 +0,0 @@
1−module ManyElements exposing
2− ( elmUI1024
3− , elmUI128
4− , elmUI2048
5− , elmUI24
6− , elmUI256
7− , elmUI4096
8− , elmUI512
9− , elmUI64
10− , elmUI8192
11− , elmUIVCSS1024
12− , elmUIVCSS128
13− , elmUIVCSS2048
14− , elmUIVCSS24
15− , elmUIVCSS256
16− , elmUIVCSS4096
17− , elmUIVCSS512
18− , elmUIVCSS64
19− , elmUIVCSS8192
20− , viewHtml1024
21− , viewHtml128
22− , viewHtml2048
23− , viewHtml24
24− , viewHtml256
25− , viewHtml4096
26− , viewHtml512
27− , viewHtml64
28− , viewHtml8192
29− , viewInline1024
30− , viewInline128
31− , viewInline2048
32− , viewInline24
33− , viewInline256
34− , viewInline4096
35− , viewInline512
36− , viewInline64
37− , viewInline8192
38− )
39−
40−{-| -}
41−
42−import Benchmark.Render
43−import Element exposing (..)
44−import Element.Background as Background
45−import Element.Font as Font
46−import Element.Keyed
47−import Html
48−import Html.Attributes
49−import Internal.Model as Internal
50−
51−
52−
53−{- START BENCHMARKS -}
54−
55−
56−elmUI24 : Benchmark.Render.Benchmark Model Msg
57−elmUI24 =
58− elmUI "elmUI24" 24
59−
60−
61−elmUI64 : Benchmark.Render.Benchmark Model Msg
62−elmUI64 =
63− elmUI "elmUI64" 64
64−
65−
66−elmUI128 : Benchmark.Render.Benchmark Model Msg
67−elmUI128 =
68− elmUI "elmUI128" 128
69−
70−
71−elmUI256 : Benchmark.Render.Benchmark Model Msg
72−elmUI256 =
73− elmUI "elmUI256" 256
74−
75−
76−elmUI512 : Benchmark.Render.Benchmark Model Msg
77−elmUI512 =
78− elmUI "elmUI512" 512
79−
80−
81−elmUI1024 : Benchmark.Render.Benchmark Model Msg
82−elmUI1024 =
83− elmUI "elmUI1024" 1024
84−
85−
86−elmUI2048 : Benchmark.Render.Benchmark Model Msg
87−elmUI2048 =
88− elmUI "elmUI2048" 2048
89−
90−
91−elmUI4096 : Benchmark.Render.Benchmark Model Msg
92−elmUI4096 =
93− elmUI "elmUI4096" 4096
94−
95−
96−elmUI8192 : Benchmark.Render.Benchmark Model Msg
97−elmUI8192 =
98− elmUI "elmUI8192" 8192
99−
100−
101−
102−{- Elm UI VirtualCSS -}
103−
104−
105−elmUIVCSS24 : Benchmark.Render.Benchmark Model Msg
106−elmUIVCSS24 =
107− elmUIVCSS "elmUIVCSS24" 24
108−
109−
110−elmUIVCSS64 : Benchmark.Render.Benchmark Model Msg
111−elmUIVCSS64 =
112− elmUIVCSS "elmUIVCSS64" 64
113−
114−
115−elmUIVCSS128 : Benchmark.Render.Benchmark Model Msg
116−elmUIVCSS128 =
117− elmUIVCSS "elmUIVCSS128" 128
118−
119−
120−elmUIVCSS256 : Benchmark.Render.Benchmark Model Msg
121−elmUIVCSS256 =
122− elmUIVCSS "elmUIVCSS256" 256
123−
124−
125−elmUIVCSS512 : Benchmark.Render.Benchmark Model Msg
126−elmUIVCSS512 =
127− elmUIVCSS "elmUIVCSS512" 512
128−
129−
130−elmUIVCSS1024 : Benchmark.Render.Benchmark Model Msg
131−elmUIVCSS1024 =
132− elmUIVCSS "elmUIVCSS1024" 1024
133−
134−
135−elmUIVCSS2048 : Benchmark.Render.Benchmark Model Msg
136−elmUIVCSS2048 =
137− elmUIVCSS "elmUIVCSS2048" 2048
138−
139−
140−elmUIVCSS4096 : Benchmark.Render.Benchmark Model Msg
141−elmUIVCSS4096 =
142− elmUIVCSS "elmUIVCSS4096" 4096
143−
144−
145−elmUIVCSS8192 : Benchmark.Render.Benchmark Model Msg
146−elmUIVCSS8192 =
147− elmUIVCSS "elmUIVCSS8192" 8192
148−
149−
150−
151−{- Normal Html -}
152−
153−
154−viewHtml24 : Benchmark.Render.Benchmark Model Msg
155−viewHtml24 =
156− viewHtml "viewHtml24" 24
157−
158−
159−viewHtml64 : Benchmark.Render.Benchmark Model Msg
160−viewHtml64 =
161− viewHtml "viewHtml64" 64
162−
163−
164−viewHtml128 : Benchmark.Render.Benchmark Model Msg
165−viewHtml128 =
166− viewHtml "viewHtml128" 128
167−
168−
169−viewHtml256 : Benchmark.Render.Benchmark Model Msg
170−viewHtml256 =
171− viewHtml "viewHtml256" 256
172−
173−
174−viewHtml512 : Benchmark.Render.Benchmark Model Msg
175−viewHtml512 =
176− viewHtml "viewHtml512" 512
177−
178−
179−viewHtml1024 : Benchmark.Render.Benchmark Model Msg
180−viewHtml1024 =
181− viewHtml "viewHtml1024" 1024
182−
183−
184−viewHtml2048 : Benchmark.Render.Benchmark Model Msg
185−viewHtml2048 =
186− viewHtml "viewHtml2048" 2048
187−
188−
189−viewHtml4096 : Benchmark.Render.Benchmark Model Msg
190−viewHtml4096 =
191− viewHtml "viewHtml4096" 4096
192−
193−
194−viewHtml8192 : Benchmark.Render.Benchmark Model Msg
195−viewHtml8192 =
196− viewHtml "viewHtml8192" 8192
197−
198−
199−
200−{- Inline Html -}
201−
202−
203−viewInline24 : Benchmark.Render.Benchmark Model Msg
204−viewInline24 =
205− viewInline "viewInline24" 24
206−
207−
208−viewInline64 : Benchmark.Render.Benchmark Model Msg
209−viewInline64 =
210− viewInline "viewInline64" 64
211−
212−
213−viewInline128 : Benchmark.Render.Benchmark Model Msg
214−viewInline128 =
215− viewInline "viewInline128" 128
216−
217−
218−viewInline256 : Benchmark.Render.Benchmark Model Msg
219−viewInline256 =
220− viewInline "viewInline256" 256
221−
222−
223−viewInline512 : Benchmark.Render.Benchmark Model Msg
224−viewInline512 =
225− viewInline "viewInline512" 512
226−
227−
228−viewInline1024 : Benchmark.Render.Benchmark Model Msg
229−viewInline1024 =
230− viewInline "viewInline1024" 1024
231−
232−
233−viewInline2048 : Benchmark.Render.Benchmark Model Msg
234−viewInline2048 =
235− viewInline "viewInline2048" 2048
236−
237−
238−viewInline4096 : Benchmark.Render.Benchmark Model Msg
239−viewInline4096 =
240− viewInline "viewInline4096" 4096
241−
242−
243−viewInline8192 : Benchmark.Render.Benchmark Model Msg
244−viewInline8192 =
245− viewInline "viewInline8192" 8192
246−
247−
248−
249−{- END BENCHMARKS -}
250−
251−
252−type alias Model =
253− { index : Int
254− , numberOfElements : Int
255− , elements : List Int
256− }
257−
258−
259−type Msg
260− = Refresh
261− | Tick Float
262−
263−
264−{-| -}
265−elmUIVCSS : String -> Int -> Benchmark.Render.Benchmark Model Msg
266−elmUIVCSS name count =
267− { name = name
268− , init =
269− { index = 0
270− , numberOfElements = count
271− , elements = List.range 0 (count - 1)
272− }
273− , view =
274− \model ->
275− Element.layoutWith
276− { options =
277− [ Internal.RenderModeOption
278− Internal.WithVirtualCss
279− ]
280− }
281− []
282− (Element.column [ spacing 8, centerX ]
283− (List.map (viewEl model.index) model.elements)
284− )
285− , update =
286− \msg model ->
287− case msg of
288− Refresh ->
289− if model.index > model.numberOfElements then
290− { model | index = 0 }
291−
292− else
293− { model | index = model.index + 1 }
294−
295− Tick i ->
296− if model.index > model.numberOfElements then
297− { model | index = 0 }
298−
299− else
300− { model | index = model.index + 1 }
301− , tick = Tick
302− , refresh = Refresh
303− }
304−
305−
306−{-| -}
307−elmUI : String -> Int -> Benchmark.Render.Benchmark Model Msg
308−elmUI name count =
309− { name = name
310− , init =
311− { index = 0
312− , numberOfElements = count
313− , elements = List.range 0 (count - 1)
314− }
315− , view =
316− \model ->
317− Element.layout []
318− (Element.column [ spacing 8, centerX ]
319− (List.map (viewEl model.index) model.elements)
320− )
321− , update =
322− \msg model ->
323− case msg of
324− Refresh ->
325− if model.index > model.numberOfElements then
326− { model | index = 0 }
327−
328− else
329− { model | index = model.index + 1 }
330−
331− Tick i ->
332− if model.index > model.numberOfElements then
333− { model | index = 0 }
334−
335− else
336− { model | index = model.index + 1 }
337− , tick = Tick
338− , refresh = Refresh
339− }
340−
341−
342−viewEl selectedIndex index =
343− el
344− [ Background.color
345− (if selectedIndex == index then
346− pink
347−
348− else
349− white
350− )
351− , Font.color
352− (if selectedIndex /= index then
353− pink
354−
355− else
356− white
357− )
358− , padding 24
359− , width (px 500)
360− , height (px 70)
361− ]
362− (if selectedIndex == index then
363− text "selected"
364−
365− else
366− text "Hello!"
367− )
368−
369−
370−white =
371− rgb 1 1 1
372−
373−
374−pink =
375− rgb255 240 0 245
376−
377−
378−pinkish i =
379− rgb255 (wrap255 (i + 240)) 0 245
380−
381−
382−wrap255 i =
383− if i > 255 then
384− 0
385−
386− else if i < 0 then
387− 0
388−
389− else
390− i
391−
392−
393−{-| -}
394−viewHtml : String -> Int -> Benchmark.Render.Benchmark Model Msg
395−viewHtml name count =
396− { name = name
397− , init =
398− { index = 0
399− , numberOfElements = count
400− , elements = List.range 0 (count - 1)
401− }
402− , view =
403− \model ->
404− Html.div []
405− [ Html.div []
406− (List.map (viewHtmlElement model.index) model.elements)
407− ]
408− , update =
409− \msg model ->
410− case msg of
411− Refresh ->
412− if model.index > model.numberOfElements then
413− { model | index = 0 }
414−
415− else
416− { model | index = model.index + 1 }
417−
418− Tick i ->
419− if model.index > model.numberOfElements then
420− { model | index = 0 }
421−
422− else
423− { model | index = model.index + 1 }
424− , tick = Tick
425− , refresh = Refresh
426− }
427−
428−
429−viewHtmlElement selectedIndex index =
430− Html.div
431− [ Html.Attributes.class
432− (if selectedIndex == index then
433− "white"
434−
435− else
436− "pink"
437− )
438− ]
439− [ Html.div []
440− [ if selectedIndex == index then
441− Html.text "selected"
442−
443− else
444− Html.text "Hello!"
445− ]
446− ]
447−
448−
449−{-| -}
450−viewInline : String -> Int -> Benchmark.Render.Benchmark Model Msg
451−viewInline name count =
452− { name = name
453− , init =
454− { index = 0
455− , numberOfElements = count
456− , elements = List.range 0 (count - 1)
457− }
458− , view =
459− \model ->
460− Html.div []
461− [ Html.div []
462− (List.map (viewInlineHtmlElement model.index) model.elements)
463− ]
464− , update =
465− \msg model ->
466− case msg of
467− Refresh ->
468− if model.index > model.numberOfElements then
469− { model | index = 0 }
470−
471− else
472− { model | index = model.index + 1 }
473−
474− Tick i ->
475− if model.index > model.numberOfElements then
476− { model | index = 0 }
477−
478− else
479− { model | index = model.index + 1 }
480− , tick = Tick
481− , refresh = Refresh
482− }
483−
484−
485−viewInlineHtmlElement selectedIndex index =
486− Html.div
487− (if selectedIndex == index then
488− [ Html.Attributes.style "background-color" (renderColor (wrap255 (index + 240)) 0 245)
489− , Html.Attributes.style "color" "white"
490− , Html.Attributes.style "padding" "24"
491− ]
492−
493− else
494− [ Html.Attributes.style "background-color" "white"
495− , Html.Attributes.style "color" (renderColor (wrap255 (index + 240)) 0 245)
496− , Html.Attributes.style "padding" "24"
497− ]
498− )
499− [ Html.div []
500− [ if selectedIndex == index then
501− Html.text "selected"
502−
503− else
504− Html.text "Hello!"
505− ]
506− ]
507−
508−
509−renderColor r g b =
510− "rgb("
511− ++ String.fromInt r
512− ++ ","
513− ++ String.fromInt g
514− ++ ","
515− ++ String.fromInt b
516− ++ ")"
benchmarks/src/View/Results.elmdeleted−379
@@ -1,379 +0,0 @@
1−port module View.Results exposing (main)
2−
3−import Browser
4−import Color
5−import Html
6−import Html.Attributes as Attr exposing (class)
7−import LineChart as LineChart
8−import LineChart.Area as Area
9−import LineChart.Axis as Axis
10−import LineChart.Axis.Intersection as Intersection
11−import LineChart.Axis.Line as AxisLine
12−import LineChart.Axis.Range as Range
13−import LineChart.Axis.Ticks as Ticks
14−import LineChart.Axis.Title as Title
15−import LineChart.Colors as Colors
16−import LineChart.Container as Container
17−import LineChart.Dots as Dots
18−import LineChart.Events as Events
19−import LineChart.Grid as Grid
20−import LineChart.Interpolation as Interpolation
21−import LineChart.Junk as Junk exposing (..)
22−import LineChart.Legends as Legends
23−import LineChart.Line as Line
24−
25−
26−row children =
27− Html.div
28− [ Attr.style "display" "flex"
29− , Attr.style "flex-direction" "row"
30− ]
31− children
32−
33−
34−column children =
35− Html.div
36− [ Attr.style "display" "flex"
37− , Attr.style "flex-direction" "column"
38− ]
39− children
40−
41−
42−main =
43− Browser.document
44− { init =
45− \() ->
46− ( { data = [] }
47− , Cmd.none
48− )
49− , view =
50− \model ->
51− { title = "Results"
52− , body =
53− [ Html.div
54− [ class "container" ]
55− [ column
56− [ Html.h2 [] [ Html.text "Benchmarked Pages" ]
57− , row (List.map viewLinks model.data)
58− ]
59− , row
60− [ -- viewNodes model.data
61− viewFps model.data
62− , viewTimeToPaint model.data
63− ]
64− , row
65− [ column
66− (List.map
67− (\data ->
68− viewRenderBreakdown
69− { get = .coldRender
70− , getCount = .count
71− , name = data.name
72− , flavor = "Cold render"
73− , range = ( 0, 1.2 )
74− }
75− (List.sortBy .count data.results)
76− )
77− model.data
78− )
79− , column
80− (List.map
81− (\data ->
82− viewRenderBreakdown
83− { get = .warmRender
84− , getCount = .count
85− , name = data.name
86− , flavor = "Warm render"
87− , range = ( 0, 1.2 )
88− }
89− (List.sortBy .count data.results)
90− )
91− model.data
92− )
93− , column
94− (List.map
95− (\data ->
96− viewRenderBreakdown
97− { get = .extendedRender
98− , getCount = .count
99− , name = data.name
100− , flavor = "Long Animation"
101− , range = ( 0, 5 )
102− }
103− (List.sortBy .count data.results)
104− )
105− model.data
106− )
107− ]
108− ]
109− ]
110− }
111− , update =
112− update
113− , subscriptions =
114− \model ->
115− Sub.batch
116− [ worldToElm Received
117− ]
118− }
119−
120−
121−type Msg
122− = Received (List Data)
123−
124−
125−update : Msg -> Model -> ( Model, Cmd Msg )
126−update msg model =
127− case msg of
128− Received data ->
129− ( { data = data }, Cmd.none )
130−
131−
132−viewLinks data =
133− column
134− (Html.h1 [] [ Html.text data.name ]
135− :: (data.results
136− |> List.sortBy .link
137− |> List.map viewSingleLink
138− )
139− )
140−
141−
142−viewSingleLink result =
143− Html.a
144− [ Attr.href result.link
145− , Attr.style "padding-right" "30px"
146− ]
147− [ Html.text result.name ]
148−
149−
150−
151−-- DATA
152−
153−
154−port worldToElm : (List Data -> msg) -> Sub msg
155−
156−
157−type alias Model =
158− { data : List Data }
159−
160−
161−type alias Data =
162− { name : String
163− , results : List Render
164− }
165−
166−
167−type alias Render =
168− { name : String
169− , count : Float
170− , fps : Float
171− , timeToFirstPaintMS : Float
172− , nodes : Float
173− , link : String
174− , coldRender :
175− Breakdown
176− , warmRender :
177− Breakdown
178− , extendedRender :
179− Breakdown
180− }
181−
182−
183−type alias Breakdown =
184− { layoutSeconds : Float
185− , recalcStyleSeconds : Float
186− , scriptDurationSeconds : Float
187− }
188−
189−
190−
191−-- Different Views
192−
193−
194−getColor i =
195− case i of
196− 0 ->
197− Colors.green
198−
199− 1 ->
200− Colors.blue
201−
202− 2 ->
203− Colors.pink
204−
205− _ ->
206− Colors.gold
207−
208−
209−getShape i =
210− Dots.triangle
211−
212−
213−graphWidth =
214− 800
215−
216−
217−graphHeight =
218− 500
219−
220−
221−container =
222− Container.styled "line-chart-1"
223− [ ( "font-family", "monospace" )
224− , ( "flex-shrink", "0" )
225− ]
226−
227−
228−viewFps : List Data -> Html.Html msg
229−viewFps datums =
230− LineChart.viewCustom
231− { y = Axis.default graphHeight "FPS" .fps
232− , x = Axis.default graphWidth "Base Count" .count
233− , container = container
234− , interpolation =
235− -- Try out these different configs!
236− -- Interpolation.linear
237− Interpolation.monotone
238−
239− -- Interpolation.stepped
240− , intersection = Intersection.default
241− , legends = Legends.default
242− , events = Events.default
243− , junk = Junk.default
244− , grid = Grid.default
245− , area = Area.default
246− , line = Line.default
247− , dots = Dots.default
248− }
249− (List.indexedMap viewResult datums)
250−
251−
252−viewResult i data =
253− LineChart.line (getColor i) (getShape i) data.name (List.sortBy .count data.results)
254−
255−
256−viewTimeToPaint : List Data -> Html.Html msg
257−viewTimeToPaint datums =
258− LineChart.viewCustom
259− { y = Axis.default graphHeight "First Paint" (max 0 << .timeToFirstPaintMS)
260− , x = Axis.default graphWidth "Base Count" .count
261− , container = container
262− , interpolation =
263− -- Try out these different configs!
264− -- Interpolation.linear
265− Interpolation.monotone
266−
267− -- Interpolation.stepped
268− , intersection = Intersection.default
269− , legends = Legends.default
270− , events = Events.default
271− , junk = Junk.default
272− , grid = Grid.default
273− , area = Area.default
274− , line = Line.default
275− , dots = Dots.default
276− }
277− (List.indexedMap viewResult datums)
278−
279−
280−viewNodes : List Data -> Html.Html msg
281−viewNodes datums =
282− LineChart.viewCustom
283− { y = Axis.default graphHeight "Nodes" .nodes
284− , x = Axis.default graphWidth "Base Count" .count
285− , container = container
286− , interpolation =
287− -- Try out these different configs!
288− -- Interpolation.linear
289− Interpolation.monotone
290−
291− -- Interpolation.stepped
292− , intersection = Intersection.default
293− , legends = Legends.default
294− , events = Events.default
295− , junk = Junk.default
296− , grid = Grid.default
297− , area = Area.default
298− , line = Line.default
299− , dots = Dots.default
300− }
301− (List.indexedMap viewResult datums)
302−
303−
304−viewRenderBreakdown :
305− { get : Render -> Breakdown
306− , getCount : Render -> Float
307− , name : String
308− , flavor : String
309− , range : ( Float, Float )
310− }
311− -> List Render
312− -> Html.Html msg
313−viewRenderBreakdown { get, getCount, name, flavor, range } results =
314− Html.div []
315− [ Html.h2 [] [ Html.text (name ++ ", " ++ flavor) ]
316− , LineChart.viewCustom
317− { y =
318− Axis.custom
319− { title = Title.default (name ++ "(s)")
320− , variable = Just << .seconds
321− , pixels = graphHeight
322− , range = Range.window (Tuple.first range) (Tuple.second range)
323− , axisLine = AxisLine.full Colors.black
324− , ticks = Ticks.default
325− }
326− , x = Axis.default graphWidth "Base Count" .count
327− , container = container
328− , interpolation =
329− -- Try out these different configs!
330− -- Interpolation.linear
331− Interpolation.monotone
332−
333− -- Interpolation.stepped
334− , intersection = Intersection.default
335− , legends = Legends.default
336− , events = Events.default
337− , junk = Junk.default
338− , grid = Grid.default
339− , area = Area.stacked 0.5
340− , line = Line.default
341− , dots = Dots.default
342− }
343− [ LineChart.line (getColor 0)
344− (getShape 0)
345− "Layout"
346− (List.map
347− (\x ->
348− { seconds = .layoutSeconds (get x)
349− , count = getCount x
350− }
351− )
352− results
353− )
354− , LineChart.line (getColor 1)
355− (getShape 1)
356− "RecalcStyle"
357− (List.map
358− (\x ->
359− { seconds =
360− .recalcStyleSeconds (get x)
361− , count = getCount x
362− }
363− )
364− results
365− )
366− , LineChart.line (getColor 2)
367− (getShape 2)
368− "Script"
369− (List.map
370− (\x ->
371− { seconds =
372− .scriptDurationSeconds (get x)
373− , count = getCount x
374− }
375− )
376− results
377− )
378− ]
379− ]
elm.json+3−5
@@ -3,7 +3,7 @@
3 "name": "mdgriffith/elm-ui",
3 "name": "mdgriffith/elm-ui",
4 "summary": "Layout and style that's easy to refactor, all without thinking about CSS.",
4 "summary": "Layout and style that's easy to refactor, all without thinking about CSS.",
5 "license": "BSD-3-Clause",
5 "license": "BSD-3-Clause",
6− "version": "1.1.8",
6+ "version": "1.0.0",
7 "exposed-modules": [
7 "exposed-modules": [
8 "Element",
8 "Element",
9 "Element.Input",
9 "Element.Input",
@@ -22,7 +22,5 @@
22 "elm/json": "1.0.0 <= v < 2.0.0",
22 "elm/json": "1.0.0 <= v < 2.0.0",
23 "elm/virtual-dom": "1.0.0 <= v < 2.0.0"
23 "elm/virtual-dom": "1.0.0 <= v < 2.0.0"
24 },
24 },
25− "test-dependencies": {
25+ "test-dependencies": {}
26− "elm-explorations/test": "1.2.2 <= v < 2.0.0"
27− }
28−}
26+}
examples/Basic.elm+1−1
@@ -1,4 +1,4 @@
1−module Basic exposing (..)
1+module Main exposing (..)
2
2
3{-| -}
3{-| -}
4
4
examples/Form.elm+4−12
@@ -1,4 +1,4 @@
1−module Form exposing (..)
1+module Main exposing (..)
2
2
3{-| -}
3{-| -}
4
4
@@ -80,14 +80,7 @@ view model =
80 [ Font.size 20
80 [ Font.size 20
81 ]
81 ]
82 <|
82 <|
83− Element.column
83+ Element.column [ width (px 800), height shrink, centerY, centerX, spacing 36, padding 10, explain Debug.todo ]
84− [ width (px 800)
85− , height shrink
86− , centerY
87− , centerX
88− , spacing 36
89− , padding 10
90− ]
91 [ el
84 [ el
92 [ Region.heading 1
85 [ Region.heading 1
93 , alignLeft
86 , alignLeft
@@ -124,7 +117,7 @@ view model =
124 , onChange = \new -> Update { model | username = new }
117 , onChange = \new -> Update { model | username = new }
125 , label = Input.labelAbove [ Font.size 14 ] (text "Username")
118 , label = Input.labelAbove [ Font.size 14 ] (text "Username")
126 }
119 }
127− , Input.currentPassword [ spacing 12 ]
120+ , Input.currentPassword [ spacing 12, width shrink ]
128 { text = model.password
121 { text = model.password
129 , placeholder = Nothing
122 , placeholder = Nothing
130 , onChange = \new -> Update { model | password = new }
123 , onChange = \new -> Update { model | password = new }
@@ -200,8 +193,7 @@ view model =
200 , Border.color darkBlue
193 , Border.color darkBlue
201 , paddingXY 32 16
194 , paddingXY 32 16
202 , Border.rounded 3
195 , Border.rounded 3
203−
204− -- , width fill
196+ , width fill
205 ]
197 ]
206 { onPress = Nothing
198 { onPress = Nothing
207 , label = Element.text "Place your lunch order!"
199 , label = Element.text "Place your lunch order!"
examples/Table.elm+1−1
@@ -1,4 +1,4 @@
1−module Table exposing (..)
1+module Main exposing (..)
2
2
3{-| -}
3{-| -}
4
4
examples/elm.json+22−19
@@ -1,22 +1,25 @@
1{
1{
2− "type": "application",
2+ "type": "application",
3− "source-directories": [".", "../src/"],
3+ "source-directories": [
4+ ".",
5+ "../src/"
6+ ],
4− "elm-version": "0.19.1",
7+ "elm-version": "0.19.0",
5− "dependencies": {
8+ "dependencies": {
6− "direct": {
9+ "direct": {
7− "elm/browser": "1.0.0",
10+ "elm/browser": "1.0.0",
8− "elm/core": "1.0.0",
11+ "elm/core": "1.0.0",
9− "elm/html": "1.0.0",
12+ "elm/html": "1.0.0",
10− "elm/json": "1.0.0",
13+ "elm/json": "1.0.0",
11− "elm/virtual-dom": "1.0.0"
14+ "elm/virtual-dom": "1.0.0"
15+ },
16+ "indirect": {
17+ "elm/time": "1.0.0",
18+ "elm/url": "1.0.0"
19+ }
12 },
20 },
13− "indirect": {
21+ "test-dependencies": {
14− "elm/time": "1.0.0",
22+ "direct": {},
15− "elm/url": "1.0.0"
23+ "indirect": {}
16 }
24 }
17− },
18− "test-dependencies": {
19− "direct": {},
20− "indirect": {}
21− }
22−}
25+}
experiments/font-adjustment-updated/FontAdjustment.elmdeleted−545
@@ -1,545 +0,0 @@
1−module Main exposing (main)
2−
3−{-| Line Height as its specified through CSS doesn't make a whole lot of sense typographically.
4−
5−We also run into issues with sizing a font. The font size generally refers to the full type size (from the top of ascendors to the bottom of descenders)
6−
7−However, sometimes we might want to size things from the top of the Capital to the baseline.
8−
9−Or from the top of the x-height to the baseline.
10−
11−The main place this shows up is for dropped capitals, and for text on buttons.
12−
13−-}
14−
15−import Browser
16−import Element exposing (..)
17−import Element.Background as Background
18−import Element.Border as Border
19−import Element.Font as Font
20−import Element.Input as Input
21−import Element.Lazy
22−import Html
23−import Html.Attributes
24−
25−
26−type alias FontAdjustment =
27− { lineHeight : Float
28− , capital : Line
29− , lowercase : Line
30− , baseline : Line
31− , descender : Line
32− }
33−
34−
35−type alias Line =
36− Float
37−
38−
39−type Msg
40− = UpdateAdjustment FontAdjustment
41−
42−
43−edges =
44− { top = 0
45− , right = 0
46− , bottom = 0
47− , left = 0
48− }
49−
50−
51−garamond =
52− let
53− default =
54− { capital = 1.09
55− , lowercase = 0.81
56− , baseline = 0.385
57− , descender = 0.095
58− , lineHeight = 1.5
59− }
60− in
61− { adjustment =
62− default
63− , converted =
64− convertAdjustment default
65− , font =
66− { url = Just "https://fonts.googleapis.com/css?family=EB+Garamond"
67− , name = "EB Garamond"
68− , variants = []
69− , adjustment =
70− { capital = default.capital
71− , lowercase = default.lowercase
72− , baseline = default.baseline
73− , descender = default.descender
74− }
75− }
76− }
77−
78−
79−catamaran =
80− let
81− default =
82− { capital = 1.15
83− , lowercase = 0.96
84− , baseline = 0.465
85− , descender = 0.245
86− , lineHeight = 1.5
87− }
88− in
89− { adjustment =
90− default
91− , converted =
92− convertAdjustment default
93− , font =
94− { url = Just "https://fonts.googleapis.com/css?family=Catamaran"
95− , name = "Catamaran"
96− , variants = []
97− , adjustment =
98− { capital = default.capital
99− , lowercase = default.lowercase
100− , baseline = default.baseline
101− , descender = default.descender
102− }
103− }
104− }
105−
106−
107−poiret =
108− let
109− default =
110− { capital = 1.12
111− , lowercase = 0.82
112− , baseline = 0.365
113− , descender = 0.18
114− , lineHeight = 1.5
115− }
116− in
117− { adjustment =
118− default
119− , converted =
120− convertAdjustment default
121− , font =
122− { url = Just "https://fonts.googleapis.com/css?family=Poiret+One"
123− , name = "Poiret One"
124− , variants = []
125− , adjustment =
126− { capital = default.capital
127− , lowercase = default.lowercase
128− , baseline = default.baseline
129− , descender = default.descender
130− }
131− }
132− }
133−
134−
135−roboto =
136− let
137− default =
138− { capital = 1.115
139− , lowercase = 0.93
140− , baseline = 0.4
141− , descender = 0.19
142− , lineHeight = 1.5
143− }
144− in
145− { adjustment =
146− default
147− , converted =
148− convertAdjustment default
149− , font =
150− { url = Just "https://fonts.googleapis.com/css?family=Roboto"
151− , name = "Roboto"
152− , adjustment =
153− { capital = default.capital
154− , lowercase = default.lowercase
155− , baseline = default.baseline
156− , descender = default.descender
157− }
158− , variants = []
159− }
160− }
161−
162−
163−init =
164− -- catamaran
165− garamond
166−
167−
168−
169−-- poiret
170−-- roboto
171−
172−
173−update msg model =
174− case msg of
175− UpdateAdjustment adj ->
176− let
177− font =
178− model.font
179− in
180− { model
181− | adjustment = adj
182− , converted = convertAdjustment adj
183− , font =
184− { font
185− | adjustment =
186− { capital = adj.capital
187− , lowercase = adj.lowercase
188− , baseline = adj.baseline
189− , descender = adj.descender
190− }
191− }
192− }
193−
194−
195−main =
196− Browser.sandbox
197− { init = init
198− , update = update
199− , view = view
200− }
201−
202−
203−view model =
204− Element.layout
205− [ above (html (Html.node "style" [] [ Html.text """
206−.lh-15 .t {
207− line-height: 1.5;
208−}
209−
210−.lh-norm .t {
211− line-height: normal;
212−}
213−
214− """ ]))
215− , Background.color (rgba 1 1 1 1)
216− , padding 100
217− , Font.color (rgba 0 0 0 1)
218− , Font.family
219− [ -- Font.external
220− -- { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
221− -- , name = "EB Garamond"
222− -- }
223− -- Font.external
224− -- { url = "https://fonts.googleapis.com/css?family=Catamaran"
225− -- , name = "Catamaran"
226− -- }
227− Font.with
228− model.font
229− , Font.sansSerif
230− ]
231− ]
232− <|
233− column [ width fill, height fill, spacing 128 ]
234− [ adjustor 120 model.adjustment
235− , adjusted 120 model.converted
236− ]
237−
238−
239−style name val =
240− htmlAttribute (Html.Attributes.style name val)
241−
242−
243−class name =
244− htmlAttribute (Html.Attributes.class name)
245−
246−
247−charcoal =
248− rgb 0.7 0.7 0.7
249−
250−
251−adjustor size adjustment =
252− let
253− labels =
254− [ viewAdjustment "Type Height" adjustment.capital size 180 adjustment.lineHeight (\capital -> { adjustment | capital = capital })
255− , viewAdjustment "Lowercase Height" adjustment.lowercase size 60 adjustment.lineHeight (\lowercase -> { adjustment | lowercase = lowercase })
256− , viewAdjustment "Baseline" adjustment.baseline size 120 adjustment.lineHeight (\baseline -> { adjustment | baseline = baseline })
257− , viewAdjustment "Descender" adjustment.descender size 0 adjustment.lineHeight (\descender -> { adjustment | descender = descender })
258− ]
259− in
260− el
261− ([ centerX
262− , centerY
263− , Background.color (rgb 0 0.8 0.9)
264− , class "lh-15"
265− , style "line-height" (String.fromFloat adjustment.lineHeight)
266− , onRight
267− (el
268− [ centerY
269− , width (px 40)
270−
271− -- , height (px (round (toFloat size * (1 / 1.5))))
272− , height (px size)
273− , Background.color (rgb 0.9 0.8 0)
274− ]
275− none
276− )
277− , Font.size size
278− ]
279− ++ labels
280− )
281− (text "Typography")
282−
283−
284−adjusted size adjustment =
285− column
286− [ spacing 48
287− , centerX
288− , centerY
289− ]
290− [ el
291− [ Font.size 32 ]
292− (text "New Adjustments in Els")
293− , row
294− [ Font.size 85
295− , padding 80
296− , spacing 48
297− ]
298− [ el
299− [ Font.size 95
300− , Font.full
301− , Background.color (rgb 0 0.8 0.9)
302− , above (el [ Font.size 24, moveUp 6 ] (text "full height"))
303− , onLeft <|
304− el
305− [ centerY
306− , width (px 40)
307− , height (px 95)
308− , Background.color (rgb 0.9 0.8 0)
309− ]
310− none
311− ]
312− (text "Typography")
313− , el
314− [ Font.sizeByCapital
315− , Font.size 85
316− , Background.color (rgb 0 0.8 0.9)
317− , above (el [ Font.size 24, moveUp 6 ] (text "corrected capital"))
318− , onLeft <|
319− el
320− [ centerY
321− , width (px 40)
322− , height (px 85)
323− , Background.color (rgb 0.9 0.8 0)
324− ]
325− none
326− ]
327− (text "Typography")
328− ]
329− , el [ Font.size 32 ] (text "Standard Defaults in CSS")
330− , row
331− [ spacing 32
332− , Font.size 120
333− ]
334− [ el
335− [ Background.color (rgb 0 0.8 0.9)
336− , style "line-height" "normal"
337− , class "lh-norm"
338− , above (el [ Font.size 12 ] (text "line-height: normal"))
339− ]
340− (text "Typography")
341− , el
342− [ Background.color (rgb 0 0.8 0.9)
343− , style "line-height" "1"
344− , above (el [ Font.size 12 ] (text "line-height: 1"))
345− ]
346− (text "Typography")
347− ]
348− , row [ spacing 120 ]
349− [ paragraph
350− [ Font.size 25
351− , spacing 5
352− , width (px 200)
353− , Background.color
354− (rgb 0 0.8 0.9)
355− , above (el [ Font.size 32, moveUp 32 ] (text "Normal Paragraphs"))
356− ]
357− [ el [ Font.size 55, alignLeft, Background.color (rgb 0.9 0.8 0) ] (text "L")
358− , text "orem Ipsum is simply dummy text of the printing and typesetting industry."
359− ]
360− , paragraph
361− [ Font.size 45
362− , spacing 10
363− , width (px 600)
364− , inFront
365− (el
366− [ width (px 100)
367− , height (px 5)
368− , moveDown 45
369− , alignRight
370− , Background.color (rgba 0.9 0.8 0.2 0.5)
371− ]
372− none
373− )
374− , inFront
375− (el
376− [ width (px 100)
377− , height (px 45)
378− , alignRight
379− , Background.color (rgba 0 0 0 0.5)
380− ]
381− none
382− )
383− , Background.color
384− (rgb 0 0.8 0.9)
385− , above
386− (el [ Font.size 32, moveUp 32 ] (text "Corrected Paragraphs"))
387− ]
388− [ el
389− [ Font.size 100
390− , alignLeft
391− , Background.color (rgb 0.9 0.8 0)
392− , Font.sizeByCapital
393− ]
394− (text "C")
395− , text "ontrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32."
396− ]
397− ]
398− ]
399−
400−
401−corrected converted label =
402− el
403− [ Background.color (rgb 0 0.8 0.9)
404− , style "display" "block"
405− , above (el [ Font.size 12, moveUp 6 ] (text label))
406− , style "line-height" (String.fromFloat converted.height)
407− , below
408− (column [ Font.size 12, spacing 5, moveDown 10 ]
409− [ text ("height: " ++ String.left 5 (String.fromFloat converted.height))
410− , text ("vertical: " ++ String.left 5 (String.fromFloat converted.vertical))
411− ]
412− )
413− ]
414− (el
415− [ style "display" "inline-block"
416− , style "line-height" (String.fromFloat converted.height)
417− , style "vertical-align" (String.fromFloat converted.vertical ++ "em")
418− ]
419− (text "Typography")
420− )
421−
422−
423−convertAdjustment adjustment =
424− let
425− base =
426− adjustment.lineHeight
427−
428− normalDescender =
429− (adjustment.lineHeight - 1)
430− / 2
431−
432− oldMiddle =
433− adjustment.lineHeight / 2
434−
435− newCapitalMiddle =
436− ((ascender - newBaseline) / 2) + newBaseline
437−
438− newFullMiddle =
439− ((ascender - descender) / 2) + descender
440−
441− lines =
442− [ adjustment.capital
443− , adjustment.baseline
444− , adjustment.descender
445− , adjustment.lowercase
446− ]
447−
448− ascender =
449− Maybe.withDefault adjustment.capital (List.maximum lines)
450−
451− descender =
452− Maybe.withDefault adjustment.descender (List.minimum lines)
453−
454− newBaseline =
455− lines
456− |> List.filter (\x -> x /= descender)
457− |> List.minimum
458− |> Maybe.withDefault adjustment.baseline
459−
460− capitalVertical =
461− (oldMiddle - newCapitalMiddle) * 2
462−
463− fullVertical =
464− (oldMiddle - newFullMiddle) * 2
465− in
466− { full =
467− { vertical = fullVertical
468− , height =
469− (ascender - descender)
470− - abs fullVertical
471− }
472− , capital =
473− { vertical = capitalVertical
474− , height = (ascender - newBaseline) - abs capitalVertical
475− }
476− }
477−
478−
479−viewAdjustment label adjustment size left lineHeight updateWith =
480− let
481− fullHeight =
482− toFloat size * 1.5
483− in
484− onLeft
485− (el
486− [ moveLeft left
487− , height (px (round (toFloat size * lineHeight)))
488− ]
489− <|
490− Input.slider
491− [ Font.size 24
492− , Element.behindContent
493− (Element.el
494− [ Element.width (Element.px 1)
495− , Element.height Element.fill
496− , Element.centerY
497− , Background.color charcoal
498− , Border.rounded 2
499− ]
500− Element.none
501− )
502− , height (px (round fullHeight))
503− , width (px 1)
504− , spacing 0
505− , Background.color charcoal
506− , below (el [ centerX ] (text (String.fromFloat adjustment)))
507− , onRight
508− (el
509− [ height (px 0)
510− , width (px 800)
511− , moveRight 10
512− , alignBottom
513− , moveUp (fullHeight * (adjustment / lineHeight))
514− , Border.color (rgb 0 0 0)
515− , Border.dashed
516− , Border.widthEach
517− { top = 1
518− , right = 0
519− , bottom = 0
520− , left = 0
521− }
522− ]
523− none
524− )
525− ]
526− { label = Input.labelHidden "font adjustment"
527− , max = lineHeight
528− , min = 0
529− , onChange =
530− \x ->
531− UpdateAdjustment
532− (updateWith x)
533− , step = Just 0.005
534− , thumb =
535− Input.thumb
536− [ Element.width (Element.px 16)
537− , Element.height (Element.px 16)
538− , Border.rounded 8
539− , Border.width 1
540− , Border.color (Element.rgb 0.5 0.5 0.5)
541− , Background.color (Element.rgb 1 1 1)
542− ]
543− , value = adjustment
544− }
545− )
experiments/font-adjustment-updated/elm.jsondeleted−25
@@ -1,25 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− ".",
5− "../../src/"
6− ],
7− "elm-version": "0.19.0",
8− "dependencies": {
9− "direct": {
10− "elm/browser": "1.0.0",
11− "elm/core": "1.0.0",
12− "elm/html": "1.0.0",
13− "elm/json": "1.0.0",
14− "elm/virtual-dom": "1.0.0"
15− },
16− "indirect": {
17− "elm/time": "1.0.0",
18− "elm/url": "1.0.0"
19− }
20− },
21− "test-dependencies": {
22− "direct": {},
23− "indirect": {}
24− }
25−}
experiments/font-adjustment/FontAdjustment.elmdeleted−365
@@ -1,365 +0,0 @@
1−module Main exposing (main)
2−
3−{-| Line Height as its specified through CSS doesn't make a whole lot of sense typographically.
4−
5−We also run into issues with sizing a font. The font size generally refers to the full type size (from the top of ascendors to the bottom of descenders)
6−
7−However, sometimes we might want to size things from the top of the Capital to the baseline.
8−
9−Or from the top of the x-height to the baseline.
10−
11−The main place this shows up is for dropped capitals, and for text on buttons.
12−
13−-}
14−
15−import Browser
16−import Element exposing (..)
17−import Element.Background as Background
18−import Element.Border as Border
19−import Element.Font as Font
20−import Element.Input as Input
21−import Element.Lazy
22−import Html.Attributes
23−
24−
25−type alias FontAdjustment =
26− { lineHeight : Float
27− , capital : Line
28− , lowercase : Line
29− , baseline : Line
30− , descender : Line
31− }
32−
33−
34−type alias Line =
35− Float
36−
37−
38−type Msg
39− = UpdateAdjustment FontAdjustment
40−
41−
42−edges =
43− { top = 0
44− , right = 0
45− , bottom = 0
46− , left = 0
47− }
48−
49−
50−default =
51− { capital = 1.15
52− , lowercase = 0.96
53− , baseline = 0.465
54− , descender = 0.245
55− , lineHeight = 1.5
56− }
57−
58−
59−init =
60− { adjustment =
61− default
62− , converted =
63− convertAdjustment default
64− }
65−
66−
67−update msg model =
68− case msg of
69− UpdateAdjustment adj ->
70− { model
71− | adjustment = adj
72− , converted = convertAdjustment adj
73− }
74−
75−
76−main =
77− Browser.sandbox
78− { init = init
79− , update = update
80− , view = view
81− }
82−
83−
84−view model =
85− Element.layout
86− [ Background.color (rgba 1 1 1 1)
87− , Font.color (rgba 0 0 0 1)
88− , Font.family
89− [ -- Font.external
90− -- { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
91− -- , name = "EB Garamond"
92− -- }
93− Font.external
94− { url = "https://fonts.googleapis.com/css?family=Catamaran"
95− , name = "Catamaran"
96− }
97− , Font.sansSerif
98− ]
99− ]
100− <|
101− column [ width fill, height fill, spacing 128 ]
102− [ adjustor 120 model.adjustment
103− , adjusted 120 model.converted
104− ]
105−
106−
107−style name val =
108− htmlAttribute (Html.Attributes.style name val)
109−
110−
111−fontSize pixels lineHeight up =
112− [ Font.size pixels
113−
114− -- , htmlAttribute (Html.Attributes.style "line-height" lineHeight)
115− -- , Background.color (rgb 0 0.8 0.9)
116− -- , onLeft
117− -- (el
118− -- [ Background.color (rgb 0 0 0)
119− -- , width (px 20)
120− -- , height (px pixels)
121− -- , moveUp up
122− -- ]
123− -- none
124− -- )
125− ]
126−
127−
128−charcoal =
129− rgb 0.7 0.7 0.7
130−
131−
132−adjustor size adjustment =
133− let
134− labels =
135− [ viewAdjustment "Type Height" adjustment.capital size 180 adjustment.lineHeight (\capital -> { adjustment | capital = capital })
136− , viewAdjustment "Lowercase Height" adjustment.lowercase size 60 adjustment.lineHeight (\lowercase -> { adjustment | lowercase = lowercase })
137− , viewAdjustment "Baseline" adjustment.baseline size 120 adjustment.lineHeight (\baseline -> { adjustment | baseline = baseline })
138− , viewAdjustment "Descender" adjustment.descender size 0 adjustment.lineHeight (\descender -> { adjustment | descender = descender })
139− ]
140− in
141− el
142− ([ centerX
143− , centerY
144− , Background.color (rgb 0 0.8 0.9)
145− , style "line-height" (String.fromFloat adjustment.lineHeight)
146− , onRight
147− (el
148− [ centerY
149− , width (px 40)
150−
151− -- , height (px (round (toFloat size * (1 / 1.5))))
152− , height (px size)
153− , Background.color (rgb 0.9 0.8 0)
154− ]
155− none
156− )
157− , Font.size size
158− ]
159− ++ labels
160− )
161− (text "Typography")
162−
163−
164−adjusted size adjustment =
165− column
166− [ spacing 48
167− , centerX
168− , centerY
169− ]
170− [ row
171− [ spacing 32
172− , Font.size 120
173− , above (text "hi")
174− ]
175− [ el
176− [ Background.color (rgb 0 0.8 0.9)
177− , style "line-height" "normal"
178− , above (el [ Font.size 12 ] (text "line-height: normal"))
179− ]
180− (text "Typography")
181− , el
182− [ Background.color (rgb 0 0.8 0.9)
183− , style "line-height" "1"
184− , above (el [ Font.size 12 ] (text "line-height: 1"))
185− ]
186− (text "Typography")
187− ]
188− , row
189− [ spacing 32
190− , Font.size 120
191− ]
192− [ corrected adjustment.full "corrected"
193− , corrected adjustment.capital "corrected capital"
194− ]
195− , paragraph [ Font.size 25, spacing 5, width (px 200) ]
196− [ el [ Font.size 55, alignLeft ] (text "L")
197− , text "orem Ipsum is simply dummy text of the printing and typesetting industry."
198− ]
199− ]
200−
201−
202−corrected converted label =
203− el
204− [ Background.color (rgb 0 0.8 0.9)
205− , style "display" "block"
206− , above (el [ Font.size 12, moveUp 6 ] (text label))
207− , style "line-height" (String.fromFloat converted.height)
208− , below
209− (column [ Font.size 12, spacing 5, moveDown 10 ]
210− [ text ("height: " ++ String.left 5 (String.fromFloat converted.height))
211− , text ("vertical: " ++ String.left 5 (String.fromFloat converted.vertical))
212− ]
213− )
214− ]
215− (el
216− [ style "display" "inline-block"
217− , style "line-height" (String.fromFloat converted.height)
218− , style "vertical-align" (String.fromFloat converted.vertical ++ "em")
219− ]
220− (text "Typography")
221− )
222−
223−
224−convertAdjustment adjustment =
225− let
226− base =
227− adjustment.lineHeight
228−
229− normalDescender =
230− (adjustment.lineHeight - 1)
231− / 2
232−
233− oldMiddle =
234− adjustment.lineHeight / 2
235−
236− newCapitalMiddle =
237− ((ascender - newBaseline) / 2) + newBaseline
238−
239− newFullMiddle =
240− ((ascender - descender) / 2) + descender
241−
242− lines =
243− [ adjustment.capital
244− , adjustment.baseline
245− , adjustment.descender
246− , adjustment.lowercase
247− ]
248−
249− ascender =
250− Maybe.withDefault adjustment.capital (List.maximum lines)
251−
252− descender =
253− Maybe.withDefault adjustment.descender (List.minimum lines)
254−
255− newBaseline =
256− lines
257− |> List.filter (\x -> x /= descender)
258− |> List.minimum
259− |> Maybe.withDefault adjustment.baseline
260−
261− capitalVertical =
262− (oldMiddle - newCapitalMiddle) * 2
263−
264− fullVertical =
265− (oldMiddle - newFullMiddle) * 2
266− in
267− { full =
268− { vertical = fullVertical
269− , height =
270− (ascender - descender)
271− - abs fullVertical
272− }
273− , capital =
274− { vertical = capitalVertical
275− , height = (ascender - newBaseline) - abs capitalVertical
276− }
277− }
278−
279−
280−viewAdjustment label adjustment size left lineHeight updateWith =
281− let
282− fullHeight =
283− toFloat size * 1.5
284− in
285− onLeft
286− (el
287− [ moveLeft left
288−
289− -- , moveUp (0.125 * toFloat size)
290− , height (px (round (toFloat size * lineHeight)))
291− ]
292− <|
293− Input.slider
294− [ Font.size 24
295− , Element.behindContent
296− (Element.el
297− [ Element.width (Element.px 1)
298− , Element.height Element.fill
299− , Element.centerY
300− , Background.color charcoal
301− , Border.rounded 2
302− ]
303− Element.none
304− )
305− , height (px (round fullHeight))
306− , width (px 1)
307− , spacing 0
308− , Background.color charcoal
309− , below (el [ centerX ] (text (String.fromFloat adjustment)))
310− , onRight
311− (el
312− [ height (px 0)
313− , width (px 800)
314− , moveRight 10
315− , alignBottom
316− , moveUp (fullHeight * (adjustment / lineHeight))
317− , Border.color (rgb 0 0 0)
318− , Border.dashed
319− , Border.widthEach
320− { top = 1
321− , right = 0
322− , bottom = 0
323− , left = 0
324− }
325− ]
326− none
327− )
328− ]
329− { label = Input.labelAbove [ Font.size 18 ] (text "")
330− , max = lineHeight
331− , min = 0
332− , onChange =
333− \x ->
334− UpdateAdjustment
335− (updateWith x)
336− , step = Just 0.005
337− , thumb =
338− Input.thumb
339− [ Element.width (Element.px 16)
340− , Element.height (Element.px 16)
341− , Border.rounded 8
342− , Border.width 1
343− , Border.color (Element.rgb 0.5 0.5 0.5)
344− , Background.color (Element.rgb 1 1 1)
345−
346− -- , onRight
347− -- (el
348− -- [ height (px 0)
349− -- , width (px 1200)
350− -- , moveDown 8
351− -- , Border.color (rgb 0 0 0)
352− -- , Border.dashed
353− -- , Border.widthEach
354− -- { top = 1
355− -- , right = 0
356− -- , bottom = 0
357− -- , left = 0
358− -- }
359− -- ]
360− -- none
361− -- )
362− ]
363− , value = adjustment
364− }
365− )
experiments/font-adjustment/elm.jsondeleted−25
@@ -1,25 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− ".",
5− "../../src/"
6− ],
7− "elm-version": "0.19.0",
8− "dependencies": {
9− "direct": {
10− "elm/browser": "1.0.0",
11− "elm/core": "1.0.0",
12− "elm/html": "1.0.0",
13− "elm/json": "1.0.0",
14− "elm/virtual-dom": "1.0.0"
15− },
16− "indirect": {
17− "elm/time": "1.0.0",
18− "elm/url": "1.0.0"
19− }
20− },
21− "test-dependencies": {
22− "direct": {},
23− "indirect": {}
24− }
25−}
experiments/virtual-css/Main.elmdeleted−46
@@ -1,46 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Events as Events
7−import Element.Font as Font
8−import Html
9−import Internal.Model as Internal
10−
11−
12−main =
13− Browser.sandbox
14− { init = 0
15− , update = update
16− , view = view
17− }
18−
19−
20−update msg model =
21− case msg of
22− Click ->
23− model + 1
24−
25−
26−type Msg
27− = Click
28−
29−
30−view model =
31− Element.layoutWith
32− { options =
33− [ Internal.RenderModeOption
34− Internal.WithVirtualCss
35− ]
36− }
37− [ Events.onClick Click ]
38− (el
39− [ padding 10
40− , Background.color (rgb 0 0 0.8)
41− , Font.color (rgb 1 1 1)
42− , centerX
43− , centerY
44− ]
45− (text ("hello!" ++ String.fromInt model))
46− )
experiments/virtual-css/Makefiledeleted−1
@@ -1 +0,0 @@
1−elm-live Main.elm --open --start-page=test.html -- --output=elm.js
experiments/virtual-css/cssom.jsdeleted−47
@@ -1,47 +0,0 @@
1−(function () {
2− var ruleCache = new Set()
3−
4− function createStyleNode() {
5− const node = document.createElement('style')
6− // Without it, IE will have a broken source order specificity if we
7− // insert rules after we insert the style tag.
8− // It seems to kick-off the source order specificity algorithm.
9− node.textContent = '\n'
10− document.head.appendChild(node);
11− return node
12− }
13−
14− var staticSheet = createStyleNode();
15− var sheet = createStyleNode().sheet;
16−
17− function sync_static(newStyleString) {
18− staticSheet.textContent = newStyleString
19− }
20−
21− function sync(newStyles) {
22− Object.keys(newStyles).forEach((key) => {
23− if (!ruleCache.has(key)) {
24− const newRule = newStyles[key]
25− for (var i = 0; i < newRule.length; i++) {
26− sheet.insertRule(newRule[i])
27− }
28− ruleCache.add(key)
29− }
30− });
31− }
32−
33− class CssRulesNode extends HTMLElement {
34− set rules(rules) {
35− sync(rules);
36− }
37− }
38− customElements.define('elm-ui-rules', CssRulesNode);
39−
40− class CssStaticRulesNode extends HTMLElement {
41− set rules(rules) {
42− sync_static(rules);
43− }
44− }
45− customElements.define('elm-ui-static-rules', CssStaticRulesNode);
46−
47−}())
experiments/virtual-css/test.htmldeleted−18
@@ -1,18 +0,0 @@
1−<!DOCTYPE HTML>
2−<html>
3−<head>
4− <meta charset="UTF-8">
5− <title>Main</title>
6− <script src="cssom.js"></script>
7− <script src="elm.js"></script>
8−</head>
9−
10−<body>
11− <div id="elm"></div>
12− <script>
13− var app = Elm.Main.init({
14− node: document.getElementById('elm')
15− });
16− </script>
17−</body>
18−</html>
experiments/workspace/Basic.elmdeleted−233
@@ -1,233 +0,0 @@
1−module Main exposing (main)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−
9−
10−box =
11− el [ height (px 30), width (px 200), Background.color (rgb 0 0.8 0.9) ] none
12−
13−
14−main =
15− Element.layout
16− [ Background.color (rgba 1 1 1 1)
17− , Font.color (rgba 1 1 1 1)
18− , Font.size 64
19− , Font.family
20− [ Font.external
21− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
22− , name = "EB Garamond"
23− }
24− , Font.sansSerif
25− ]
26− ]
27− <|
28− column
29− [ spacing 40
30− , Background.color (rgb 1 1 1)
31− , centerX
32− , inFront
33− (el
34− [ Background.color (rgb 1 0 0)
35− , width (px 20)
36− , height (px 20)
37− ]
38− (text "in front of everything")
39− )
40− , behindContent
41− (el
42− [ Background.color (rgb 0.5 0.7 0)
43− , Font.color (rgb 1 1 1)
44− , moveDown 30
45− ]
46− (text "hi there")
47− )
48− ]
49− [ el
50− [ Background.color (rgba 0 0.9 0.8 1)
51− , Font.color (rgb 0 0 0)
52− , behindContent
53− (el
54− [ Background.color (rgb 0.9 0.9 0)
55− , Font.color (rgb 1 1 1)
56− ]
57− (text "hi there")
58− )
59− , inFront
60− (el [ Background.color (rgb 0.9 0.9 0.5) ] (text "in front of stuff, behind one"))
61−
62− -- , Font.sizeByCapital
63− -- , Font.variant Font.smallCaps
64− -- , Font.variant Font.ligatures
65− -- , Font.variant Font.diagonalFractions
66− ]
67− (text "Quality 1st Hello stylish friend! ofl 123456 1/3")
68− , row
69− [ Background.color (rgba 0 0.9 0.8 1)
70− , Font.color (rgb 0 0 0)
71− , spacing 87
72− , behindContent
73− (el [ Background.color (rgb 0.9 0.9 0), Font.color (rgb 1 1 1) ] (text "hi there"))
74− , inFront
75− (el [ Background.color (rgb 0.9 0.9 0.5) ] (text "yo"))
76−
77− -- , Font.sizeByCapital
78− -- , Font.variant Font.smallCaps
79− -- , Font.variant Font.ligatures
80− -- , Font.variant Font.diagonalFractions
81− ]
82− [ text "Quality 1st Hello stylish friend! ofl 123456 1/3"
83− ]
84− , el
85− [ Background.color (rgb 0.1 0.1 0.1)
86− , width (px 200)
87− , height (px 200)
88−
89− -- , below
90− -- (el
91− -- [ Background.color (rgb 1 0 0)
92− -- , width (px 20)
93− -- , height (px 20)
94− -- , moveDown 30
95− -- ]
96− -- none
97− -- )
98− , below
99− (el
100− [ Background.color (rgb 0.1 0.1 0.6)
101− , width (px 150)
102− , height (px 150)
103−
104− -- , alignBottom
105− ]
106− none
107− )
108− ]
109− none
110− , el
111− [ Background.color (rgb 0.1 0.1 0.1)
112− , width (px 200)
113− , height (px 200)
114− , above
115− (el
116− [ Background.color (rgb 1 0 0)
117− , width (px 20)
118− , height (px 20)
119−
120− -- , moveUp 30
121− ]
122− none
123− )
124− , onRight
125− (el
126− [ Background.color (rgb 1 0 0)
127− , width (px 20)
128− , height fill
129−
130− -- , moveUp 30
131− ]
132− none
133− )
134−
135− -- , inFront
136− -- (el
137− -- [ Background.color (rgb 0.1 0.1 0.6)
138− -- , width (px 150)
139− -- , height (px 150)
140− -- ]
141− -- none
142− -- )
143− -- , above
144− -- (el
145− -- [ Background.color (rgb 1 0 0)
146− -- , width (px 20)
147− -- , height (px 20)
148− -- , moveUp 30
149− -- ]
150− -- none
151− -- )
152− ]
153− none
154− , el
155− [ Background.color (rgb 0.1 0.1 0.1)
156− , width (px 200)
157− , height (px 200)
158− , below
159− (el
160− [ Background.color (rgb 1 0 0)
161− , width fill
162− , height (px 20)
163− ]
164− none
165− )
166− , above
167− (el
168− [ Background.color (rgb 1 0 0)
169− , width fill
170− , height (px 20)
171− ]
172− none
173− )
174− , onLeft
175− (el
176− [ Background.color (rgb 1 0 0)
177− , width (px 20)
178− , height fill
179− ]
180− none
181− )
182− , onRight
183− (el
184− [ Background.color (rgb 1 0 0)
185− , width (px 20)
186− , height fill
187− ]
188− none
189− )
190− ]
191− none
192− , el
193− [ Background.color (rgb 0.1 0.1 0.1)
194− , width (px 200)
195− , height (px 200)
196− , inFront
197− (el
198− [ Background.color (rgb 1 0 0)
199− , width fill
200− , height fill
201− ]
202− none
203− )
204− ]
205− none
206− ]
207−
208−
209−
210−-- row
211−-- [ --width (px 420)
212−-- padding 0
213−-- , spacing 20
214−-- , Background.color (rgb 0.2 0.2 0.3)
215−-- ]
216−-- [ box
217−-- , box
218−-- , box
219−-- -- , box
220−-- -- , box
221−-- ]
222−-- wrappedRow
223−-- [ width (px 420)
224−-- , padding 10
225−-- , spacing 20
226−-- , Background.color (rgb 0.2 0.2 0.3)
227−-- ]
228−-- [ box
229−-- , box
230−-- , box
231−-- , box
232−-- , box
233−-- ]
experiments/workspace/Form.elmdeleted−234
@@ -1,234 +0,0 @@
1−module Main exposing (Form, Lunch(..), Msg(..), blue, darkBlue, grey, init, main, red, update, view, white)
2−
3−{-| -}
4−
5−import Browser
6−import Element exposing (..)
7−import Element.Background as Background
8−import Element.Border as Border
9−import Element.Font as Font
10−import Element.Input as Input
11−import Element.Region as Region
12−import Html.Attributes
13−
14−
15−white =
16− Element.rgb 1 1 1
17−
18−
19−grey =
20− Element.rgb 0.9 0.9 0.9
21−
22−
23−blue =
24− Element.rgb 0 0 0.8
25−
26−
27−red =
28− Element.rgb 0.8 0 0
29−
30−
31−darkBlue =
32− Element.rgb 0 0 0.9
33−
34−
35−main =
36− Browser.sandbox
37− { init = init
38− , view = view
39− , update = update
40− }
41−
42−
43−init =
44− { username = ""
45− , password = ""
46− , agreeTOS = False
47− , comment = "Extra hot sauce?\n\n\nYes pls"
48− , lunch = Gyro
49− , spiciness = 2
50− }
51−
52−
53−type alias Form =
54− { username : String
55− , password : String
56− , agreeTOS : Bool
57− , comment : String
58− , lunch : Lunch
59− , spiciness : Float
60− }
61−
62−
63−type Msg
64− = Update Form
65−
66−
67−update msg model =
68− case Debug.log "msg" msg of
69− Update new ->
70− new
71−
72−
73−id i =
74− htmlAttribute (Html.Attributes.id i)
75−
76−
77−type Lunch
78− = Burrito
79− | Taco
80− | Gyro
81−
82−
83−view model =
84− Element.layout
85− [ Font.size 20
86− ]
87− <|
88− Element.column
89− [ width (px 800)
90− , height shrink
91− , centerY
92− , centerX
93− , spacing 36
94− , padding 10
95− ]
96− [ el
97− [ Region.heading 1
98− , alignLeft
99− , Font.size 36
100− ]
101− (text "Welcome to the Stylish Elephants Lunch Emporium")
102− , Input.radio
103− [ spacing 12
104− , alpha 0.5
105− , id "radio-1"
106− ]
107− { selected = Just model.lunch
108− , onChange = \new -> Update { model | lunch = new }
109− , label =
110− -- Input.labelHidden "Just a label"
111− Input.labelAbove
112− [ Font.size 14
113− , paddingXY 0 12
114− ]
115− (text "What would you like for lunch?")
116− , options =
117− [ Input.option Gyro (text "Gyro")
118− , Input.option Burrito (text "Burrito")
119− , Input.option Taco (text "Taco")
120− ]
121− }
122− , Input.text
123− [ spacing 12
124− , id "text-1"
125− ]
126− { text = model.username
127− , placeholder =
128− Just
129− (Input.placeholder
130− [ focused
131− [ moveUp 30 ]
132− ]
133− (text "Placeholder Label")
134− )
135− , onChange = \new -> Update { model | username = new }
136− , label =
137− Input.labelHidden "Just a label"
138−
139− -- Input.labelBelow
140− -- [ Font.size 14
141− -- , focused
142− -- [ moveUp 30 ]
143− -- ]
144− -- (text "Username")
145− }
146− , Input.currentPassword [ spacing 12, width shrink ]
147− { text = model.password
148− , placeholder = Nothing
149− , onChange = \new -> Update { model | password = new }
150− , label = Input.labelAbove [ Font.size 14 ] (text "Password")
151− , show = False
152− }
153− , Input.multiline
154− [ height
155− (shrink
156− |> maximum 400
157− )
158− , spacing 12
159− , id "multiline-1"
160− ]
161− { text = model.comment
162− , placeholder = Just (Input.placeholder [] (text "Extra hot sauce?\n\n\nYes pls"))
163− , onChange = \new -> Update { model | comment = new }
164− , label =
165− -- Input.labelAbove [ Font.size 14 ] (text "Leave a comment!")
166− Input.labelHidden "Just a label"
167− , spellcheck = False
168− }
169− , Input.checkbox [ id "checkbox-1" ]
170− { checked = model.agreeTOS
171− , onChange = \new -> Update { model | agreeTOS = new }
172− , icon = Input.defaultCheckbox
173− , label =
174− -- Input.labelRight [] (text "Agree to Terms of Service")
175− Input.labelHidden "Just a label"
176− }
177− , Input.slider
178− [ Element.height (Element.px 30)
179− , Element.behindContent
180− (Element.el
181− [ Element.width Element.fill
182− , Element.height (Element.px 2)
183− , Element.centerY
184− , Background.color grey
185− , Border.rounded 2
186− ]
187− Element.none
188− )
189− ]
190− { onChange = \new -> Update { model | spiciness = new }
191− , label = Input.labelAbove [] (text ("Spiciness: " ++ String.fromFloat model.spiciness))
192− , min = 0
193− , max = 3.2
194− , step = Nothing
195− , value = model.spiciness
196− , thumb =
197− Input.defaultThumb
198− }
199− , --el [height (px 300), width (px 30)] <|
200− Input.slider
201− [ Element.width (Element.px 40)
202− , Element.height (Element.px 80)
203− , Element.behindContent
204− (Element.el
205− [ Element.height Element.fill
206− , Element.width (Element.px 2)
207− , Element.centerX
208− , Background.color grey
209− , Border.rounded 2
210− ]
211− Element.none
212− )
213− ]
214− { onChange = \new -> Update { model | spiciness = new }
215− , label = Input.labelAbove [] (text ("Spiciness: " ++ String.fromFloat model.spiciness))
216− , min = 0
217− , max = 3.2
218− , step = Nothing
219− , value = model.spiciness
220− , thumb =
221− Input.defaultThumb
222− }
223− , Input.button
224− [-- Background.color blue
225− -- , Font.color white
226− -- , Border.color darkBlue
227− -- , paddingXY 32 16
228− -- , Border.rounded 3
229− -- , width fill
230− ]
231− { onPress = Nothing
232− , label = Element.text "Place your lunch order!"
233− }
234− ]
experiments/workspace/Scrollbars.elmdeleted−204
@@ -1,204 +0,0 @@
1−module Main exposing (main)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−
9−
10−box =
11− el [ height (px 30), width (px 200), Background.color (rgb 0 0.8 0.9) ] none
12−
13−
14−main =
15− Element.layout
16− [ Background.color (rgba 1 1 1 1)
17− , Font.color (rgba 1 1 1 1)
18− , Font.size 64
19−
20− -- , Font.italic
21− , Font.family
22− [ Font.external
23− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
24− , name = "EB Garamond"
25− }
26−
27− -- Font.with
28− -- { url = Just "https://fonts.googleapis.com/css?family=EB+Garamond"
29− -- , name = "EB Garamond"
30− -- , adjustment =
31− -- { capital = 1.09
32− -- , lowercase = 0.81
33− -- , baseline = 0.385
34− -- , descender = 0.095
35− -- }
36− -- , variants =
37− -- [ Font.swash 1
38− -- , Font.smallCaps
39− -- -- , Font.diagonalFractions
40− -- -- , Font.ordinal
41− -- -- , Font.ligatures
42− -- ]
43− -- }
44− -- Font.with
45− -- { url = Just "https://fonts.googleapis.com/css?family=Raleway"
46− -- , name = "Raleway"
47− -- , adjustment =
48− -- { capital = 1.09
49− -- , lowercase = 0.81
50− -- , baseline = 0.385
51− -- , descender = 0.095
52− -- }
53− -- , variants =
54− -- [ Font.swash 2
55− -- , Font.ordinal
56− -- , Font.ligatures
57− -- -- , Font.small
58− -- ]
59− -- }
60− , Font.sansSerif
61− ]
62− ]
63− <|
64− column
65− [ spacing 20
66− , Background.color (rgb 1 1 1)
67− , inFront
68− (el
69− [ Background.color (rgb 1 0 0)
70− , width (px 20)
71− , height (px 20)
72− ]
73− none
74− )
75− , behindContent
76− (el
77− [ Background.color (rgb 0.5 0.7 0)
78− , Font.color (rgb 1 1 1)
79− , moveDown 30
80− ]
81− (text "hi there")
82− )
83− ]
84− [ el
85− [ Background.color (rgba 0 0.9 0.8 1)
86− , Font.color (rgb 0 0 0)
87− , behindContent
88− (el
89− [ Background.color (rgb 0.9 0.9 0)
90− , Font.color (rgb 1 1 1)
91− ]
92− (text "hi there")
93− )
94− , inFront
95− (el [ Background.color (rgb 0.9 0.9 0.5) ] (text "yo"))
96−
97− -- , Font.sizeByCapital
98− -- , Font.variant Font.smallCaps
99− -- , Font.variant Font.ligatures
100− -- , Font.variant Font.diagonalFractions
101− ]
102− (text "Quality 1st Hello stylish friend! ofl 123456 1/3")
103− , el
104− [ Background.color (rgba 0 0.9 0.8 1)
105− , Font.color (rgb 0 0 0)
106− , behindContent
107− (el [ Background.color (rgb 0.9 0.9 0), Font.color (rgb 1 1 1) ] (text "hi there"))
108− , inFront
109− (el [ Background.color (rgb 0.9 0.9 0.5) ] (text "yo"))
110−
111− -- , Font.sizeByCapital
112− -- , Font.variant Font.smallCaps
113− -- , Font.variant Font.ligatures
114− -- , Font.variant Font.diagonalFractions
115− ]
116− (text "Quality 1st Hello stylish friend! ofl 123456 1/3")
117− , el
118− [ Background.color (rgb 0.1 0.1 0.1)
119− , width (px 200)
120− , height (px 200)
121−
122− -- , below
123− -- (el
124− -- [ Background.color (rgb 1 0 0)
125− -- , width (px 20)
126− -- , height (px 20)
127− -- , moveDown 30
128− -- ]
129− -- none
130− -- )
131− , below
132− (el
133− [ Background.color (rgb 0.1 0.1 0.6)
134− , width (px 150)
135− , height (px 150)
136−
137− -- , alignBottom
138− ]
139− none
140− )
141− ]
142− none
143− , el
144− [ Background.color (rgb 0.1 0.1 0.1)
145− , width (px 200)
146− , height (px 200)
147− , onRight
148− (el
149− [ Background.color (rgb 1 0 0)
150− , width (px 20)
151− , height fill
152−
153− -- , moveUp 30
154− ]
155− none
156− )
157−
158− -- , inFront
159− -- (el
160− -- [ Background.color (rgb 0.1 0.1 0.6)
161− -- , width (px 150)
162− -- , height (px 150)
163− -- ]
164− -- none
165− -- )
166− -- , above
167− -- (el
168− -- [ Background.color (rgb 1 0 0)
169− -- , width (px 20)
170− -- , height (px 20)
171− -- , moveUp 30
172− -- ]
173− -- none
174− -- )
175− ]
176− none
177− ]
178−
179−
180−
181−-- row
182−-- [ --width (px 420)
183−-- padding 0
184−-- , spacing 20
185−-- , Background.color (rgb 0.2 0.2 0.3)
186−-- ]
187−-- [ box
188−-- , box
189−-- , box
190−-- -- , box
191−-- -- , box
192−-- ]
193−-- wrappedRow
194−-- [ width (px 420)
195−-- , padding 10
196−-- , spacing 20
197−-- , Background.color (rgb 0.2 0.2 0.3)
198−-- ]
199−-- [ box
200−-- , box
201−-- , box
202−-- , box
203−-- , box
204−-- ]
experiments/workspace/Table.elmdeleted−65
@@ -1,65 +0,0 @@
1−module Main exposing (..)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−import Element.Input
9−import Element.Lazy
10−
11−
12−type alias Person =
13− { firstName : String
14− , lastName : String
15− }
16−
17−
18−persons : List Person
19−persons =
20− [ { firstName = "David"
21− , lastName = "Bowie"
22− }
23− , { firstName = "Florence"
24− , lastName = "Welch"
25− }
26− ]
27−
28−
29−main =
30− Element.layout
31− [ Background.color (rgba 0 0 0 1)
32− , Font.color (rgba 1 1 1 1)
33− , Font.italic
34− , Font.size 32
35− , Font.family
36− [ Font.external
37− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
38− , name = "EB Garamond"
39− }
40− , Font.sansSerif
41− ]
42− ]
43− <|
44− Element.table
45− [ Element.centerX
46− , Element.centerY
47− , Element.spacing 5
48− , Element.padding 10
49− ]
50− { data = persons
51− , columns =
52− [ { header = Element.text "First Name"
53− , width = px 200
54− , view =
55− \person ->
56− Element.text person.firstName
57− }
58− , { header = Element.text "Last Name"
59− , width = fill
60− , view =
61− \person ->
62− Element.text person.lastName
63− }
64− ]
65− }
experiments/workspace/elm.jsondeleted−25
@@ -1,25 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− ".",
5− "../src/"
6− ],
7− "elm-version": "0.19.0",
8− "dependencies": {
9− "direct": {
10− "elm/browser": "1.0.0",
11− "elm/core": "1.0.0",
12− "elm/html": "1.0.0",
13− "elm/json": "1.0.0",
14− "elm/virtual-dom": "1.0.0"
15− },
16− "indirect": {
17− "elm/time": "1.0.0",
18− "elm/url": "1.0.0"
19− }
20− },
21− "test-dependencies": {
22− "direct": {},
23− "indirect": {}
24− }
25−}
notes/BENCHMARKS.mddeleted−20
@@ -1,20 +0,0 @@
1−# Render Benchmark
2−
3−```bash
4−# In root directory
5−yarn install
6−yarn bench
7−```
8−
9−We're interested in overall rendering performance. Right now that means measuring:
10−
11−1. Speed for first paint.
12−2. Rerender speed.
13−3. FPS for extended animations.
14−
15−## Some notes about results.
16−
17−- For the extended animation graph, you see it tops out at a certain point. That's when the rendering pipeline is maxed out and it's now going below 60fps.
18−
19−- The html and inline style cases are **not really** directly comparable to the `elm-ui` stuff because they're not buying you the same thing (which is really write-able, maintainable layouts.) However they're nice to see because they're the current limit of elm's rendering.
20−
notes/RUNNING_TESTS.mddeleted−65
@@ -1,65 +0,0 @@
1−# Elm UI Test Suite
2−
3−There are two types of tests for Elm UI. The normal kind, which are located in `tests/suite/`
4−
5−These can be run using [`elm-test`](https://github.com/elm-explorations/test) and can be run via
6−
7−```bash
8−# in the root elm-ui directory
9−yarn install # or npm install
10−yarn run test # or npm run test
11−```
12−
13−**Note** you need to be at the `elm-ui` root dir.
14−
15−# Layout Testing
16−
17−`elm-ui` also needs to ensure that all layouts work as expected on all browsers.
18−
19−In order to do this, we need a different testing environment.
20−
21−So, the tests in `elm-ui/tests-rendering/src/Tests` will render output, then harvest bounding boxes form the browser, and run the test on the resulting data.
22−
23−Run this locally via:
24−
25−```bash
26−npm install
27−npm run test-render
28−```
29−
30−**Note** if you run this, it runs by default in headless chrome, so you won't see a browser actually open. Ideally you'll just see something like this:
31−
32−```
33−Compiling tests
34−Done compiling
35−Running locally on Chrome...
36−Local Chrome -> All 18029 tests passed
37−```
38−
39−That's right. We have 18,029 tests. Woohoo!
40−
41−# Running on Sauce Labs
42−
43−In order to automate some of this stuff, this test can be run on Sauce Labs.
44−
45−If you have an account, you'll need to create a `elm-ui/sauce.env` file, which has the following fields:
46−
47−```
48−export SAUCE_ACCESS_KEY={your key}
49−export SAUCE_USERNAME={your username}
50−```
51−
52−You can then run.
53−
54−```bash
55−npm run test-render-sauce
56−```
57−
58−**Note**: The compiled `elm-ui` test needs to be made public somewhere in order for this to work. At the moment it's at my github.io account, though something more permanenet might be set up.
59−
60−
61−# Sauce Labs References
62−
63−https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
64−https://wiki.saucelabs.com/display/DOCS/Sauce+Labs+Basics
65−https://github.com/saucelabs-sample-test-frameworks/Python-Pytest-Selenium
notes/classifying-issues.mddeleted−29
@@ -1,29 +0,0 @@
1−# Classifying Issues
2−
3−
4−One of the first things we want to do is to keep our issues categorized.
5−
6−If you add a comment to an issue that references a label, that label will be assigned to that issue! (e.g. `#has-ellie` will add the `has-ellie` label.)
7−
8−[Here's one that I categorized](https://github.com/mdgriffith/elm-ui/issues/201)
9−
10−[Labels are described here](https://github.com/mdgriffith/elm-ui/labels)
11−
12−- **Feature Suggestions** - `#feature-suggestion` - This issue describes a feature suggestion. Tagging it with `#feature-suggestion` is all that needs to happen.
13−
14−- **Pain Point** - `#pain-point` - This is an issue that descrbes a challenge someone is facing, but makes not direct suggestion about how it should be solved. Here's a good example, [unable to applly text overflow ellipses](https://github.com/mdgriffith/elm-ui/issues/112).
15−
16−- **Bug** - `#bug` - The issue that's being described is potentially a bug. It may not be totally obvious what the fix is.
17− - **Has Ellie** - `#has-ellie` - Every bug described should have an ellie showing the problem, even if it's sorta trivial.
18− - **No Ellie** - If it's a bug, but has been checked for ellies and has no ellie, flag it as `#no-ellie`.
19− - **Has Test** - `#has-test` - Once we have an ellie for the problem, we want a version of that code in the codebase so I can easily take a look.
20− - The thing to do is to open a PR that copies that ellie into the [`tests-rendering/cases/open`](https://github.com/mdgriffith/elm-ui/tree/master/tests-rendering/cases/open) directory. Give it a succinct, human name.
21− - Rename the `Element.*` imports as `Testable.Element.*`
22− - Add a link to the issue, the title of the issue, and the body of the issue to the module comment. [Here's an example](https://github.com/mdgriffith/elm-ui/tree/master/tests-rendering/cases/open/InFrontSize.elm)
23− - Test is compiling - Optionally you can see if the test is compiling by first `cd tests-rendering` and then running `elm-live cases/open/{The file}.elm --open --dir=view -- --output=view/elm.js --debug`
24− - If it does not compile, flag the issue as `#test-not-compiling`. Don't worry about fixing it unless it's really obvious what needs to happen.
25− - Check if the test passes. Do that by opening `tests-rendering/cases/view/view.html` after running the above compilation. If it says all passes, likely you should flag the issue as `#test-incorrectly-passing`.
26− - If it's failing, you can flag as `#test-failing`
27−
28−
29−
notes/discussion/ColorWithoutAlpha.API.mddeleted−135
@@ -1,135 +0,0 @@
1−# API sketch for separating out alpha from Color
2−
3−**Motivation**
4−
5−If we separate out alpha from the core color type, we can
6−
7−1. Have a unified `Color` type that works in all contexts, including in webGL situations where transparency may be handled differently, or not at all.
8−
9−2. Encourage people to use actual color mixing functions where possible and to enumerate their colors concretely.
10− - The point here is that color mixing is situation dependent. Why not just mix a color explicitly in a way where you know it looks good?
11−
12−3. With a totally opaque color type, we can calculate contrast for accessibility evaluation easily. An alpha channel means we'd have to emulate browser mixing to do that, which I'm not sure is consistent.
13−
14−Ultimately I want the position of `elm-ui` to be something like the following:
15−
16−1. `rgb`(both value based and hex) is more of an interop format than a color space you'd actually want to modify things in. Think, when have you ever thought "oh, just bump the red channel down a bit and you'll be good"?
17−
18− - As an interop format, it means it's what you're going to be copying from tools or receiving from a designer.
19− - These tools generally have the ability to mix things properly.
20− - By mixing things concretely, designers have more control over their ultimate design.
21−
22−2. Transparency in most of these cases is still necessary or at the least convenient. It's not too difficult to treat that separately than the identity of a color value.
23−
24−3. Ultimately we want to encourage people to use a colorspace like [HSLuv](https://package.elm-lang.org/packages/kuon/elm-hsluv/latest/). Basically any of the colorspaces that are based in [CIEXYZ colorspace](https://en.wikipedia.org/wiki/CIE_1931_color_space). They're much easier to use. - May not really seem related to alpha channels, but the idea is that doing things like `lightening` a color is much easier in these other colorspaces.
25−
26−## Element.Font
27−
28− Font.color : Color -> Attribute msg
29−
30− -- Tempted to drop this one.
31− -- People could still have transparent text using `Element.opacity`
32− -- if they really want it
33− Font.opacity : Float -> Attribute msg
34−
35− Font.shadow :
36− { offset : (Float, Float)
37− , blur : Float
38− , color : Color
39− , opacity : Float
40− } -> Attribute msg
41−
42−## Element.Background
43−
44− Background.color : Color -> Attribute
45−
46− -- background opacity is commonly used when we have some text
47− -- over an image background.
48− Background.opacity : Float -> Attribute
49−
50−For gradients, we can have opacity as a separate set of steps.
51−This actually makes it _easier_ to do something like a rainbow that linearly fades away. We don't have to figure out the exact opacity that the 5th color has.
52−
53− Background.gradient :
54− { angle : Float
55− , colors : List Color
56− , opacity : List Float
57− }
58−
59−Do you ever have a gradient with more than two alpha steps?
60−Maybe you'd actually like to adjust the falloff curve instead of have it be linear?
61−Maybe there's an even better way to represent this?
62−
63− Will eventually want to cover radial gradients, but a similar approach to the above is likely easy.
64−
65−Took a look at [background blend modes](https://developer.mozilla.org/en-US/docs/Web/CSS/background-blend-mode), which can be used to dynamically color images, like the [header image here](https://professional-rentals.com/).
66−
67−The blend modes are influenced by background or element opacity.
68−
69−In that way, we could have something like
70−
71− Background.blend 0.5 color
72−
73−Which would set a color mode and set the background opacity. I'd need to play around with it, but seems kinda cool!
74−
75−## Element.Border
76−
77−Sometimes a transparent border is used as a placeholder, and then we change a color on `mouseOver`. This is to avoid layout movement in the resulting animation.
78−
79− Border.color : Color -> Attribute
80−
81− Border.opacity : Float -> Attribute
82−
83− Border.shadow :
84− { offset : (Float, Float)
85− , size : Float
86− , blur : Float
87− , color : Color
88− , opacity : Float
89− }
90−
91− Border.manyShadows :
92− List
93− { offset : (Float, Float)
94− , blur : Float
95− , color : Color
96− , opacity : Float
97− } -> Attribute msg
98−
99− Border.innerShadow
100− { offset : ( Float, Float )
101− , size : Float
102− , blur : Float
103− , color : Color
104− , opacity : Float
105− }
106−
107−# Discussion and Usecases
108−
109−The main question about binding alpha with color is:
110−
111− Is the identity of this color an identity about the color and it's ability to mix. Knowing that it's ability to mix in this case is not great.
112−
113−Or would you want to set these things explicitly and independently of each other?
114−
115−## Tinting and shading (i.e. lightening and darkening)
116−
117−_Note_ - not sure what package would house these functions.
118−
119−We usually get in the habit of using alpha for an ad-hoc lightener/darkener.
120−This can easily be replicated with functions that actually operate on colors in elm.
121−
122− Color.lighten 0.3 color
123−
124−With the idea that this function should use the luminance from CIELUV instead of lightness from hsl.
125−
126−## Mixing two colors
127−
128−We also use alpha as an ad hoc way to mix two colors (i.e. [turn a font subtley green on a green background](https://medium.com/refactoring-ui/7-practical-tips-for-cheating-at-design-40c736799886#9cdf).
129−
130− el
131− [ Background.color bg
132− -- explicitly mix the two!
133− , Font.color (Color.mix 0.2 white bg)
134− ]
135− (text "Howdy")
notes/discussion/ColorWithoutAlpha.mddeleted−67
@@ -1,67 +0,0 @@
1−# A Design for Color without Alpha
2−
3−Color is hard!
4−
5−I've spent a decade and a half in web development and only now feel like I have some sort of handle on it.
6−
7−What I've learned basically comes down to the fact that the two color spaces we're used to dealing with (`rgb` and `hsl`), are not actually that great for thinking about color. Which is unfortunate.
8−
9−So, what can we use instead?
10−
11−Research on color perception in the 1920's led to the development of the [CIEXYZ colorspace](https://en.wikipedia.org/wiki/CIE_1931_color_space), which describes color in a way that is much closer to how humans perceive color. Essentially they were able to model constants in their equations that literally represent some of the built-in values we have as humans to perceive color.
12−
13−How crazy is that?
14−
15−(Skipping over the fact that there is variation in how people perceive color.)
16−
17−There are a number of color spaces that are based on this initial research, including CIELAB(generally recommended for print), and CIELUV(generally recommended for light). They are essentailly different ways to talk about the same color space. Sorta like polar coordinates(r,θ) and cartesian coordiantes (x,y) can both represent a point.
18−
19−The `L` in the above acronyms represents `Luminance`.
20−
21−This is one of the really cool parts. Two colors that have the same `Luminance`, will be equally "bright" to the human eye.
22−
23−You might be thinking "well, what about the `lightness` channel in `HSL`, huh?". Turns out it's not really based on anything!
24−
25−Here are two hsl colors with the same lightness:
26−![](http://lea.verou.me/wp-content/uploads/2020/04/image-4.png)
27−
28−Do they look like the same "brightness"?
29−
30−Unfortunately the L in HSL stands for Lies and we've been misled all along.
31−
32−[This whole article on color spaces is worth a read if you got the time](http://lea.verou.me/2020/04/lch-colors-in-css-what-why-and-how/)
33−
34−
35−Ok, so, luminance is really cool.
36−
37−With a real `Luminance` factor you can
38− 1. Generate palettes of colors that work together in a consistent manner.
39− 2. Automatically know the difference in luminance between two colors. Guess what that is. It's a contrast calculation! Like for accessibility! How nice would that be if it was X - Y as opposed to some crazy math?
40− 3. Get an intuition for how colors will interact with each other.
41− 4. Generate gradients that aren't unexpectedly broken. (I have some examples of this, I'll dig them up later)
42− 5. Animate colors consistently. Animating in rgb or hsl will cause color animation to look awful in different ways.
43−
44−It really is a better world.
45−
46−Ok, so how do we get there and what does this mean for elm-ui?
47−
48−
49−# Elm UI stuff
50−
51−The above knowledge is hard won. Many people are not aware that there are better colorspaces than rgb and hsl.
52−
53−Color is hard. In many cases, it will remain hard until people get a nice introduction to something based on CIEXYZ.
54−
55−In elm, [we have a package for HSLuv](
56−https://package.elm-lang.org/packages/kuon/elm-hsluv/latest/), which you can use right now. It's great.
57−
58−However! We have one confouding factor, which is that we're used to bundling an `alpha` value with our colors.
59−
60−The same math that makes rgb and hsl less than great is used to blend colors via alpha.
61−
62−By bundling alpha with color, we're encouranging people to blend colors in an ad-hoc way when we could be providing them avenues to easily do it the right way. We have a whole programming language, we're not confined to only CSS anymore.
63−
64−However! Frontend development also involves talking to designers. Designers usually provide rgb, hsl, or a hex version of rgb.
65−
66−I now sorta view these as *interop formats*.
67−
notes/discussion/Internationalization.mddeleted−13
@@ -1,13 +0,0 @@
1−# Internationalization
2−
3−What are the concerns that `elm-ui` should handle in order to properly support internationalization in an app?
4−
5−# Right-to-Left and Left-to-Right Languages
6−
7−[This talk from Strange Loop is an amazing overview of the concerns for RtL and LtR languages.](https://www.youtube.com/watch?v=xpumLsaAWGw&t=3s) Turns out it can get super crazy!
8−
9−It's also interesting because one of the design decisions in `elm-ui` is to support concrete directions like `alignLeft` and `alignRight` instead of `align-conten: flex-start`.
10−
11−
12−
13−
notes/discussion/PaletteGroups.mddeleted−132
@@ -1,132 +0,0 @@
1−# Mini Palette Experiment
2−
3−`elm-ui` currently implements most things such as layout and style as attributes on a element. These are intended to be explicit so that visiting an element will give you all the information you need to understand how an element is shown.
4−
5−However, this can also mean that Elements gather a lot of attributes and in the effort of capturing a consistent design language you may find yourself repeating a lot of combinations of attributes.
6−
7−Previously a construct like `mix : List (Attribute msg) -> Attribute msg` has been proposed as a way to make things easier, however that opens up a large design space. Developers then have to make the difficult decision about what attributes to group together. That decision is It also would allow intermixing of event handlers with style and layout, which seems weird.
8−
9−As an alternative, we could have specific groupings of attributes that are allowed. Done right, this may solve the problem of the dev having to worry about proper groupings and push them towards thinking of their design as a cohesive whole.
10−
11−My intuition says that these groupings will fall along the lines of the current module organization. Here are the helper functions that come to mind. These would be in addition to everything we already have.
12−
13−
14−## Spacing Palette
15−
16−```elm
17−Element.spaceWith :
18− { padding :
19− { top : Int
20− , right : Int
21− , bottom : Int
22− , left : Int
23− }
24− , spacing :
25− { x : Int
26− , y : Int
27− }
28− } -> Attribute msg
29−```
30−
31−## Color Palette
32−
33−It might be a little weird to have a color grouping, but my gut says it probably makes sense.
34−
35−By binding background and text color together, we can know all of our background and text color combinations, making it easier to verify and specifiy a minimum contrast for accessibility.
36−
37−```elm
38−Element.colors :
39− { background : Color
40− , text : Color
41− , border : Color
42− } -> Attribute msg
43−```
44−
45−## Font Palette
46−
47−```elm
48−Element.Font.with :
49− { typeface : String
50− , fallback : List String
51− , scale : Scale
52− -- adjustments is a new thing that's coming that will allow more precise font sizing.
53− , adjustments : Maybe Font.Adjustment
54− -- These are variations like `slash zero`
55− , variations : List Font.Variation
56− } -> (Option, Attribute msg)
57−
58−type Scale
59− = Single Int
60− | Triple
61− { small : Int
62− , normal : Int
63− , large : Int
64− }
65− | Fluid (windowSize -> Scale)
66−
67−
68−
69−
70−-- Usage
71−
72−(titleFont, title) =
73− Font.with
74− { typeface = "EB Garamond"
75− , fallback =
76− [ "georgia"
77− , "serif"
78− ]
79− , scale =
80− Font.Triple
81− { small = 12
82− , normal = 16
83− , large = 32
84− }
85− , adjustments = Nothing
86− , variations = []
87− }
88−
89−
90−view =
91− Element.layoutWith { options = [ titleFont ] } <|
92− el
93− [ title.large
94− ]
95− (text "I am a large title font")
96−
97−
98−```
99−
100−## Border Model
101−
102−```elm
103−Element.Border.with :
104− { width : Int
105− , style : Border.Style
106− , rounded :
107− { topLeft : Int
108− , topRight : Int
109− , bottomLeft : Int
110− , bottomRight : Int
111− }
112− }
113−```
114−
115−
116−## Shadow Model
117−
118−This might mean breaking out shadows into their own module.
119−
120−```elm
121−Element.Shadow.stack : List Shadow -> Attribute msg
122−```
123−
124−
125−# General Questions
126−
127−So, here are the questions I have:
128−
129−- If you have a current codebase with `elm-ui`, would this simplify things at all? Is there a way you can quantify it(most elements I have would have half as many attributes)?
130−- Are there alternate groupings that you've come across?
131−
132−
notes/implementation/NEARBY.mddeleted−24
@@ -1,24 +0,0 @@
1−# Rendering Order
2−
3−Nearby elements such as `below`, `above`, and `inFront` are rendered after the other children of the `Element. `behindContent` is rendered before.
4−
5−This is so:
6−
7−- `inFront` doesn't need a special `z-index` to work. This can increase performance because too many `z-index` overrides means shipping more layers to the gpu.
8−- Nearby elements higher up in the DOM hierarchy will be on top of elements lower in the hierarchy. `inFront` on a higher element should be on top of `inFront` elements on a lower element.
9−- Allows nearby elements to be affected by `focused` for `Input`, because they can be reached by a sibling selector. `.focuesed:focus ~ .focusable-style {}`
10−
11−
12−
13−# Desired Behavior of Nearby Elements
14−
15−
16−
17−- `inFront` on an element will be in front of all children.
18− - if there's an `inFront` attached to a child, it will be beneath the parent's `inFront`
19−- `behindContent`, likewise, will always be between the background and the element's children.
20−- `onLeft`, `onRight`, `above`, and `below` will be in front of any element they overlap with.
21− - if an element has an `inFront` and it's neighbor has an `onLeft`, then the `onLeft` element will be on top of the `inFront`.
22−- if `onLeft`, `onRight`, `above`, and `below` on separate elements overlap, source order wins:
23− - in a row, the one attached to the element farthest to the right wins.
24− - in a column, the one attached to the element farthest down wins.
notes/research/Accessiblity.mddeleted−9
@@ -1,9 +0,0 @@
1−# Accessibility Resources
2−
3−What are good resources that cover effective techniques for accessibility?
4−
5−This can be talks, articles, papers, blogposts, whatever.
6−
7−Ideally the list here should include a link and a brief description of what's interesting about the resource.
8−
9−**TODO**
notes/research/Compatibility-Android.mddeleted−12
@@ -1,12 +0,0 @@
1−# Android Compatibity
2−
3−I'd love to know how easy or difficlt it would be to use `elm-ui`'s API to generate Android layouts.
4−
5−This document is here to track any research that people want to do into the subject. The idea would be to link to specific Android documentation and/or describe an approach for each concept.
6−
7−
8−Full API coverage would be wonderful, though to here's a good place to start.
9−
10−- Row/Column
11−- Nearby's
12−- Spacing/Padding
notes/research/Compatibility-iOS.mddeleted−12
@@ -1,12 +0,0 @@
1−# iOS API Compatibility
2−
3−I'd love to know how easy or difficlt it would be to use `elm-ui`'s API to generate iOS layouts.
4−
5−This document is here to track any research that people want to do into the subject. The idea would be to link to specific iOS documentation and/or describe an approach for each concept.
6−
7−
8−Full API coverage would be wonderful, though to here's a good place to start.
9−
10−- Row/Column
11−- Nearby's
12−- Spacing/Padding
notes/research/Internationalization.mddeleted−10
@@ -1,10 +0,0 @@
1−# Internationalization Resources
2−
3−What are good resources that cover effective internationalization techniques?
4−
5−This can be talks, articles, papers, blogposts, whatever.
6−
7−Ideally the list here should include a link and a brief description of what's interesting about the resource.
8−
9−- [How supporting Right-to-Left can expose your bad UX](https://www.youtube.com/watch?v=xpumLsaAWGw&t=3s) - A wonderful talk on Right-to-Left support and how it's not as obvious as it may seem.
10− - [dir property](https://www.w3.org/International/questions/qa-html-dir)
package-lock.jsondeleted−1235
@@ -1,1235 +0,0 @@
1−{
2− "name": "elm-ui-testing",
3− "version": "1.0.0",
4− "lockfileVersion": 1,
5− "requires": true,
6− "dependencies": {
7− "ajv": {
8− "version": "6.12.0",
9− "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
10− "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
11− "requires": {
12− "fast-deep-equal": "^3.1.1",
13− "fast-json-stable-stringify": "^2.0.0",
14− "json-schema-traverse": "^0.4.1",
15− "uri-js": "^4.2.2"
16− }
17− },
18− "ansi-styles": {
19− "version": "3.2.1",
20− "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
21− "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
22− "requires": {
23− "color-convert": "^1.9.0"
24− }
25− },
26− "anymatch": {
27− "version": "3.1.1",
28− "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
29− "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
30− "requires": {
31− "normalize-path": "^3.0.0",
32− "picomatch": "^2.0.4"
33− }
34− },
35− "asn1": {
36− "version": "0.2.4",
37− "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
38− "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
39− "requires": {
40− "safer-buffer": "~2.1.0"
41− }
42− },
43− "assert-plus": {
44− "version": "1.0.0",
45− "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
46− "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
47− },
48− "asynckit": {
49− "version": "0.4.0",
50− "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
51− "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
52− },
53− "aws-sign2": {
54− "version": "0.7.0",
55− "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
56− "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
57− },
58− "aws4": {
59− "version": "1.9.1",
60− "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
61− "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
62− },
63− "balanced-match": {
64− "version": "1.0.0",
65− "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
66− "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
67− },
68− "bcrypt-pbkdf": {
69− "version": "1.0.2",
70− "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
71− "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
72− "requires": {
73− "tweetnacl": "^0.14.3"
74− }
75− },
76− "binary": {
77− "version": "0.3.0",
78− "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
79− "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
80− "requires": {
81− "buffers": "~0.1.1",
82− "chainsaw": "~0.1.0"
83− }
84− },
85− "binary-extensions": {
86− "version": "2.0.0",
87− "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
88− "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow=="
89− },
90− "binwrap": {
91− "version": "0.2.2",
92− "resolved": "https://registry.npmjs.org/binwrap/-/binwrap-0.2.2.tgz",
93− "integrity": "sha512-Y+Wvypk3JhH5GPZAvlwJAWOVH/OsOhQMSj37vySuWHwQivoALplPxfBA8b973rFJI7OS+O+1YmmYXIiEXVMAcw==",
94− "requires": {
95− "mustache": "^3.0.1",
96− "request": "^2.88.0",
97− "request-promise": "^4.2.4",
98− "tar": "^4.4.10",
99− "unzip-stream": "^0.3.0"
100− }
101− },
102− "bluebird": {
103− "version": "3.7.2",
104− "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
105− "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
106− },
107− "brace-expansion": {
108− "version": "1.1.11",
109− "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
110− "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
111− "requires": {
112− "balanced-match": "^1.0.0",
113− "concat-map": "0.0.1"
114− }
115− },
116− "braces": {
117− "version": "3.0.2",
118− "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
119− "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
120− "requires": {
121− "fill-range": "^7.0.1"
122− }
123− },
124− "buffers": {
125− "version": "0.1.1",
126− "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
127− "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
128− },
129− "caseless": {
130− "version": "0.12.0",
131− "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
132− "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
133− },
134− "chainsaw": {
135− "version": "0.1.0",
136− "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
137− "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
138− "requires": {
139− "traverse": ">=0.3.0 <0.4"
140− }
141− },
142− "chalk": {
143− "version": "2.4.2",
144− "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
145− "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
146− "requires": {
147− "ansi-styles": "^3.2.1",
148− "escape-string-regexp": "^1.0.5",
149− "supports-color": "^5.3.0"
150− },
151− "dependencies": {
152− "has-flag": {
153− "version": "3.0.0",
154− "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
155− "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
156− },
157− "supports-color": {
158− "version": "5.5.0",
159− "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
160− "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
161− "requires": {
162− "has-flag": "^3.0.0"
163− }
164− }
165− }
166− },
167− "chokidar": {
168− "version": "3.3.0",
169− "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
170− "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
171− "requires": {
172− "anymatch": "~3.1.1",
173− "braces": "~3.0.2",
174− "fsevents": "~2.1.1",
175− "glob-parent": "~5.1.0",
176− "is-binary-path": "~2.1.0",
177− "is-glob": "~4.0.1",
178− "normalize-path": "~3.0.0",
179− "readdirp": "~3.2.0"
180− }
181− },
182− "chownr": {
183− "version": "1.1.4",
184− "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
185− "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
186− },
187− "color-convert": {
188− "version": "1.9.3",
189− "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
190− "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
191− "requires": {
192− "color-name": "1.1.3"
193− }
194− },
195− "color-name": {
196− "version": "1.1.3",
197− "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
198− "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
199− },
200− "combined-stream": {
201− "version": "1.0.8",
202− "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
203− "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
204− "requires": {
205− "delayed-stream": "~1.0.0"
206− }
207− },
208− "commander": {
209− "version": "2.20.0",
210− "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
211− "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
212− },
213− "concat-map": {
214− "version": "0.0.1",
215− "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
216− "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
217− },
218− "core-util-is": {
219− "version": "1.0.2",
220− "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
221− "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
222− },
223− "cross-spawn": {
224− "version": "6.0.5",
225− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
226− "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
227− "requires": {
228− "nice-try": "^1.0.4",
229− "path-key": "^2.0.1",
230− "semver": "^5.5.0",
231− "shebang-command": "^1.2.0",
232− "which": "^1.2.9"
233− }
234− },
235− "dashdash": {
236− "version": "1.14.1",
237− "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
238− "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
239− "requires": {
240− "assert-plus": "^1.0.0"
241− }
242− },
243− "delayed-stream": {
244− "version": "1.0.0",
245− "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
246− "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
247− },
248− "ecc-jsbn": {
249− "version": "0.1.2",
250− "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
251− "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
252− "requires": {
253− "jsbn": "~0.1.0",
254− "safer-buffer": "^2.1.0"
255− }
256− },
257− "elm": {
258− "version": "0.19.1-3",
259− "resolved": "https://registry.npmjs.org/elm/-/elm-0.19.1-3.tgz",
260− "integrity": "sha512-6y36ewCcVmTOx8lj7cKJs3bhI5qMfoVEigePZ9PhEUNKpwjjML/pU2u2YSpHVAznuCcojoF6KIsrS1Ci7GtVaQ==",
261− "requires": {
262− "request": "^2.88.0"
263− }
264− },
265− "elm-test": {
266− "version": "0.19.1-revision2",
267− "resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.1-revision2.tgz",
268− "integrity": "sha512-zVs2mVeyIE+K9y7/8b333h5xRMDWAoqbBDm7ThLDhyTi7ICxeL3t5uOS4KZCrRk9+4sP6+voSbcBlgr46Q+GiQ==",
269− "requires": {
270− "chalk": "3.0.0",
271− "chokidar": "3.3.0",
272− "cross-spawn": "7.0.1",
273− "elmi-to-json": "1.3.0",
274− "find-parent-dir": "^0.3.0",
275− "firstline": "2.0.2",
276− "fs-extra": "8.1.0",
277− "glob": "7.1.6",
278− "lodash": "4.17.15",
279− "minimist": "^1.2.0",
280− "murmur-hash-js": "1.0.0",
281− "node-elm-compiler": "5.0.4",
282− "split": "1.0.1",
283− "supports-color": "7.1.0",
284− "temp": "0.9.1",
285− "which": "2.0.1",
286− "xmlbuilder": "^13.0.2"
287− },
288− "dependencies": {
289− "ansi-styles": {
290− "version": "4.2.1",
291− "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
292− "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
293− "requires": {
294− "@types/color-name": "^1.1.1",
295− "color-convert": "^2.0.1"
296− },
297− "dependencies": {
298− "@types/color-name": {
299− "version": "1.1.1",
300− "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
301− "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
302− }
303− }
304− },
305− "chalk": {
306− "version": "3.0.0",
307− "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
308− "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
309− "requires": {
310− "ansi-styles": "^4.1.0",
311− "supports-color": "^7.1.0"
312− }
313− },
314− "color-convert": {
315− "version": "2.0.1",
316− "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
317− "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
318− "requires": {
319− "color-name": "~1.1.4"
320− }
321− },
322− "color-name": {
323− "version": "1.1.4",
324− "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
325− "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
326− },
327− "cross-spawn": {
328− "version": "7.0.1",
329− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
330− "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
331− "requires": {
332− "path-key": "^3.1.0",
333− "shebang-command": "^2.0.0",
334− "which": "^2.0.1"
335− },
336− "dependencies": {
337− "path-key": {
338− "version": "3.1.1",
339− "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
340− "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
341− },
342− "shebang-command": {
343− "version": "2.0.0",
344− "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
345− "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
346− "requires": {
347− "shebang-regex": "^3.0.0"
348− }
349− }
350− }
351− },
352− "find-elm-dependencies": {
353− "version": "2.0.2",
354− "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.2.tgz",
355− "integrity": "sha512-nM5UCbccD1G8CGK2GsM7ykG3ksOAl9E+34jiDfl07CAl2OPnLpBVWY2hlxEmIkSBfdJjSopEowWHrO0cI8RhxQ==",
356− "requires": {
357− "firstline": "1.2.0",
358− "lodash": "4.17.15"
359− },
360− "dependencies": {
361− "firstline": {
362− "version": "1.2.0",
363− "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.0.tgz",
364− "integrity": "sha1-yfSIbn9/vwr8EtcZQdzgaxkq6gU="
365− }
366− }
367− },
368− "firstline": {
369− "version": "2.0.2",
370− "resolved": "https://registry.npmjs.org/firstline/-/firstline-2.0.2.tgz",
371− "integrity": "sha512-8KcmfI0jgSECnzdhucm0i7vrwef3BWwgjimW2YkRC5eSFwjb5DibVoA0YvgkYwwxuJi9c+7M7X3b3lX8o9B6wg=="
372− },
373− "lodash": {
374− "version": "4.17.15",
375− "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
376− "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
377− },
378− "node-elm-compiler": {
379− "version": "5.0.4",
380− "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.4.tgz",
381− "integrity": "sha512-VQsT8QSierYGkHzRed+b4MnccQVF1+qPHunE8jBoU7jD6YpuRqCDPzEoC2zfyEJS80qVnlMZrqobLnyjzX9lJg==",
382− "requires": {
383− "cross-spawn": "6.0.5",
384− "find-elm-dependencies": "2.0.2",
385− "lodash": "4.17.15",
386− "temp": "^0.9.0"
387− },
388− "dependencies": {
389− "cross-spawn": {
390− "version": "6.0.5",
391− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
392− "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
393− "requires": {
394− "nice-try": "^1.0.4",
395− "path-key": "^2.0.1",
396− "semver": "^5.5.0",
397− "shebang-command": "^1.2.0",
398− "which": "^1.2.9"
399− }
400− },
401− "nice-try": {
402− "version": "1.0.5",
403− "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
404− "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
405− },
406− "path-key": {
407− "version": "2.0.1",
408− "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
409− "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
410− },
411− "semver": {
412− "version": "5.7.1",
413− "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
414− "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
415− },
416− "shebang-command": {
417− "version": "1.2.0",
418− "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
419− "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
420− "requires": {
421− "shebang-regex": "^1.0.0"
422− }
423− },
424− "shebang-regex": {
425− "version": "1.0.0",
426− "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
427− "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
428− },
429− "which": {
430− "version": "1.3.1",
431− "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
432− "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
433− "requires": {
434− "isexe": "^2.0.0"
435− }
436− }
437− }
438− },
439− "supports-color": {
440− "version": "7.1.0",
441− "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
442− "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
443− "requires": {
444− "has-flag": "^4.0.0"
445− }
446− },
447− "temp": {
448− "version": "0.9.1",
449− "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz",
450− "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==",
451− "requires": {
452− "rimraf": "~2.6.2"
453− }
454− },
455− "which": {
456− "version": "2.0.1",
457− "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz",
458− "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==",
459− "requires": {
460− "isexe": "^2.0.0"
461− }
462− }
463− }
464− },
465− "elmi-to-json": {
466− "version": "1.3.0",
467− "resolved": "https://registry.npmjs.org/elmi-to-json/-/elmi-to-json-1.3.0.tgz",
468− "integrity": "sha512-6m1D5/Pb5pUrSOOBgRG3fE2mK19nhmLgZ16jj2KWTVIhT+0GIBuDI1iV0Fee27CZH790J7uMcdGWJ7fnVvpsKg==",
469− "requires": {
470− "binwrap": "0.2.2"
471− }
472− },
473− "escape-string-regexp": {
474− "version": "1.0.5",
475− "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
476− "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
477− },
478− "extend": {
479− "version": "3.0.2",
480− "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
481− "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
482− },
483− "extsprintf": {
484− "version": "1.3.0",
485− "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
486− "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
487− },
488− "fast-deep-equal": {
489− "version": "3.1.1",
490− "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
491− "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
492− },
493− "fast-json-stable-stringify": {
494− "version": "2.1.0",
495− "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
496− "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
497− },
498− "fill-range": {
499− "version": "7.0.1",
500− "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
501− "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
502− "requires": {
503− "to-regex-range": "^5.0.1"
504− }
505− },
506− "find-elm-dependencies": {
507− "version": "2.0.2",
508− "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.2.tgz",
509− "integrity": "sha512-nM5UCbccD1G8CGK2GsM7ykG3ksOAl9E+34jiDfl07CAl2OPnLpBVWY2hlxEmIkSBfdJjSopEowWHrO0cI8RhxQ==",
510− "requires": {
511− "firstline": "1.2.0",
512− "lodash": "4.17.15"
513− }
514− },
515− "find-parent-dir": {
516− "version": "0.3.0",
517− "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
518− "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ="
519− },
520− "firstline": {
521− "version": "1.2.0",
522− "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.0.tgz",
523− "integrity": "sha1-yfSIbn9/vwr8EtcZQdzgaxkq6gU="
524− },
525− "forever-agent": {
526− "version": "0.6.1",
527− "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
528− "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
529− },
530− "form-data": {
531− "version": "2.3.3",
532− "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
533− "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
534− "requires": {
535− "asynckit": "^0.4.0",
536− "combined-stream": "^1.0.6",
537− "mime-types": "^2.1.12"
538− }
539− },
540− "fs-extra": {
541− "version": "8.1.0",
542− "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
543− "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
544− "requires": {
545− "graceful-fs": "^4.2.0",
546− "jsonfile": "^4.0.0",
547− "universalify": "^0.1.0"
548− }
549− },
550− "fs-minipass": {
551− "version": "1.2.7",
552− "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
553− "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
554− "requires": {
555− "minipass": "^2.6.0"
556− }
557− },
558− "fs.realpath": {
559− "version": "1.0.0",
560− "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
561− "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
562− },
563− "fsevents": {
564− "version": "2.1.2",
565− "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
566− "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
567− "optional": true
568− },
569− "getpass": {
570− "version": "0.1.7",
571− "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
572− "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
573− "requires": {
574− "assert-plus": "^1.0.0"
575− }
576− },
577− "glob": {
578− "version": "7.1.6",
579− "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
580− "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
581− "requires": {
582− "fs.realpath": "^1.0.0",
583− "inflight": "^1.0.4",
584− "inherits": "2",
585− "minimatch": "^3.0.4",
586− "once": "^1.3.0",
587− "path-is-absolute": "^1.0.0"
588− }
589− },
590− "glob-parent": {
591− "version": "5.1.0",
592− "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
593− "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
594− "requires": {
595− "is-glob": "^4.0.1"
596− }
597− },
598− "graceful-fs": {
599− "version": "4.2.3",
600− "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
601− "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
602− },
603− "har-schema": {
604− "version": "2.0.0",
605− "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
606− "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
607− },
608− "har-validator": {
609− "version": "5.1.3",
610− "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
611− "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
612− "requires": {
613− "ajv": "^6.5.5",
614− "har-schema": "^2.0.0"
615− }
616− },
617− "has-flag": {
618− "version": "4.0.0",
619− "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
620− "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
621− },
622− "http-signature": {
623− "version": "1.2.0",
624− "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
625− "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
626− "requires": {
627− "assert-plus": "^1.0.0",
628− "jsprim": "^1.2.2",
629− "sshpk": "^1.7.0"
630− }
631− },
632− "immediate": {
633− "version": "3.0.6",
634− "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
635− "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
636− },
637− "inflight": {
638− "version": "1.0.6",
639− "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
640− "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
641− "requires": {
642− "once": "^1.3.0",
643− "wrappy": "1"
644− }
645− },
646− "inherits": {
647− "version": "2.0.4",
648− "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
649− "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
650− },
651− "is-binary-path": {
652− "version": "2.1.0",
653− "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
654− "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
655− "requires": {
656− "binary-extensions": "^2.0.0"
657− }
658− },
659− "is-extglob": {
660− "version": "2.1.1",
661− "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
662− "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
663− },
664− "is-glob": {
665− "version": "4.0.1",
666− "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
667− "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
668− "requires": {
669− "is-extglob": "^2.1.1"
670− }
671− },
672− "is-number": {
673− "version": "7.0.0",
674− "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
675− "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
676− },
677− "is-typedarray": {
678− "version": "1.0.0",
679− "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
680− "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
681− },
682− "isarray": {
683− "version": "1.0.0",
684− "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
685− "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
686− },
687− "isexe": {
688− "version": "2.0.0",
689− "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
690− "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
691− },
692− "isstream": {
693− "version": "0.1.2",
694− "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
695− "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
696− },
697− "jsbn": {
698− "version": "0.1.1",
699− "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
700− "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
701− },
702− "json-schema": {
703− "version": "0.2.3",
704− "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
705− "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
706− },
707− "json-schema-traverse": {
708− "version": "0.4.1",
709− "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
710− "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
711− },
712− "json-stringify-safe": {
713− "version": "5.0.1",
714− "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
715− "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
716− },
717− "jsonfile": {
718− "version": "4.0.0",
719− "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
720− "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
721− "requires": {
722− "graceful-fs": "^4.1.6"
723− }
724− },
725− "jsprim": {
726− "version": "1.4.1",
727− "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
728− "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
729− "requires": {
730− "assert-plus": "1.0.0",
731− "extsprintf": "1.3.0",
732− "json-schema": "0.2.3",
733− "verror": "1.10.0"
734− }
735− },
736− "jszip": {
737− "version": "3.4.0",
738− "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz",
739− "integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==",
740− "requires": {
741− "lie": "~3.3.0",
742− "pako": "~1.0.2",
743− "readable-stream": "~2.3.6",
744− "set-immediate-shim": "~1.0.1"
745− }
746− },
747− "lie": {
748− "version": "3.3.0",
749− "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
750− "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
751− "requires": {
752− "immediate": "~3.0.5"
753− }
754− },
755− "lodash": {
756− "version": "4.17.15",
757− "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
758− "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
759− },
760− "mime-db": {
761− "version": "1.43.0",
762− "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
763− "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
764− },
765− "mime-types": {
766− "version": "2.1.26",
767− "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
768− "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
769− "requires": {
770− "mime-db": "1.43.0"
771− }
772− },
773− "minimatch": {
774− "version": "3.0.4",
775− "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
776− "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
777− "requires": {
778− "brace-expansion": "^1.1.7"
779− }
780− },
781− "minimist": {
782− "version": "1.2.4",
783− "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.4.tgz",
784− "integrity": "sha512-wTiNDqe4D2rbTJGZk1qcdZgFtY0/r+iuE6GDT7V0/+Gu5MLpIDm4+CssDECR79OJs/OxLPXMzdxy153b5Qy3hg=="
785− },
786− "minipass": {
787− "version": "2.9.0",
788− "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
789− "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
790− "requires": {
791− "safe-buffer": "^5.1.2",
792− "yallist": "^3.0.0"
793− }
794− },
795− "minizlib": {
796− "version": "1.3.3",
797− "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
798− "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
799− "requires": {
800− "minipass": "^2.9.0"
801− }
802− },
803− "mkdirp": {
804− "version": "0.5.5",
805− "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
806− "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
807− "requires": {
808− "minimist": "^1.2.5"
809− },
810− "dependencies": {
811− "minimist": {
812− "version": "1.2.5",
813− "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
814− "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
815− }
816− }
817− },
818− "murmur-hash-js": {
819− "version": "1.0.0",
820− "resolved": "https://registry.npmjs.org/murmur-hash-js/-/murmur-hash-js-1.0.0.tgz",
821− "integrity": "sha1-UEEEkmnJZjPIZjhpYLL0KJ515bA="
822− },
823− "mustache": {
824− "version": "3.2.1",
825− "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz",
826− "integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA=="
827− },
828− "nice-try": {
829− "version": "1.0.5",
830− "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
831− "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
832− },
833− "node-elm-compiler": {
834− "version": "5.0.4",
835− "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.4.tgz",
836− "integrity": "sha512-VQsT8QSierYGkHzRed+b4MnccQVF1+qPHunE8jBoU7jD6YpuRqCDPzEoC2zfyEJS80qVnlMZrqobLnyjzX9lJg==",
837− "requires": {
838− "cross-spawn": "6.0.5",
839− "find-elm-dependencies": "2.0.2",
840− "lodash": "4.17.15",
841− "temp": "^0.9.0"
842− }
843− },
844− "normalize-path": {
845− "version": "3.0.0",
846− "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
847− "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
848− },
849− "oauth-sign": {
850− "version": "0.9.0",
851− "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
852− "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
853− },
854− "once": {
855− "version": "1.4.0",
856− "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
857− "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
858− "requires": {
859− "wrappy": "1"
860− }
861− },
862− "os-tmpdir": {
863− "version": "1.0.2",
864− "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
865− "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
866− },
867− "pako": {
868− "version": "1.0.11",
869− "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
870− "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
871− },
872− "path-is-absolute": {
873− "version": "1.0.1",
874− "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
875− "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
876− },
877− "path-key": {
878− "version": "2.0.1",
879− "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
880− "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
881− },
882− "performance-now": {
883− "version": "2.1.0",
884− "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
885− "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
886− },
887− "picomatch": {
888− "version": "2.2.1",
889− "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
890− "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA=="
891− },
892− "process-nextick-args": {
893− "version": "2.0.1",
894− "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
895− "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
896− },
897− "psl": {
898− "version": "1.7.0",
899− "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
900− "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ=="
901− },
902− "punycode": {
903− "version": "2.1.1",
904− "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
905− "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
906− },
907− "qs": {
908− "version": "6.5.2",
909− "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
910− "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
911− },
912− "readable-stream": {
913− "version": "2.3.7",
914− "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
915− "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
916− "requires": {
917− "core-util-is": "~1.0.0",
918− "inherits": "~2.0.3",
919− "isarray": "~1.0.0",
920− "process-nextick-args": "~2.0.0",
921− "safe-buffer": "~5.1.1",
922− "string_decoder": "~1.1.1",
923− "util-deprecate": "~1.0.1"
924− },
925− "dependencies": {
926− "safe-buffer": {
927− "version": "5.1.2",
928− "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
929− "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
930− }
931− }
932− },
933− "readdirp": {
934− "version": "3.2.0",
935− "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
936− "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
937− "requires": {
938− "picomatch": "^2.0.4"
939− }
940− },
941− "request": {
942− "version": "2.88.2",
943− "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
944− "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
945− "requires": {
946− "aws-sign2": "~0.7.0",
947− "aws4": "^1.8.0",
948− "caseless": "~0.12.0",
949− "combined-stream": "~1.0.6",
950− "extend": "~3.0.2",
951− "forever-agent": "~0.6.1",
952− "form-data": "~2.3.2",
953− "har-validator": "~5.1.3",
954− "http-signature": "~1.2.0",
955− "is-typedarray": "~1.0.0",
956− "isstream": "~0.1.2",
957− "json-stringify-safe": "~5.0.1",
958− "mime-types": "~2.1.19",
959− "oauth-sign": "~0.9.0",
960− "performance-now": "^2.1.0",
961− "qs": "~6.5.2",
962− "safe-buffer": "^5.1.2",
963− "tough-cookie": "~2.5.0",
964− "tunnel-agent": "^0.6.0",
965− "uuid": "^3.3.2"
966− }
967− },
968− "request-promise": {
969− "version": "4.2.5",
970− "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
971− "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
972− "requires": {
973− "bluebird": "^3.5.0",
974− "request-promise-core": "1.1.3",
975− "stealthy-require": "^1.1.1",
976− "tough-cookie": "^2.3.3"
977− }
978− },
979− "request-promise-core": {
980− "version": "1.1.3",
981− "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
982− "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
983− "requires": {
984− "lodash": "^4.17.15"
985− }
986− },
987− "rimraf": {
988− "version": "2.6.3",
989− "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
990− "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
991− "requires": {
992− "glob": "^7.1.3"
993− }
994− },
995− "safe-buffer": {
996− "version": "5.2.0",
997− "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
998− "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
999− },
1000− "safer-buffer": {
1001− "version": "2.1.2",
1002− "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1003− "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1004− },
1005− "selenium-webdriver": {
1006− "version": "4.0.0-alpha.7",
1007− "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.7.tgz",
1008− "integrity": "sha512-D4qnTsyTr91jT8f7MfN+OwY0IlU5+5FmlO5xlgRUV6hDEV8JyYx2NerdTEqDDkNq7RZDYc4VoPALk8l578RBHw==",
1009− "requires": {
1010− "jszip": "^3.2.2",
1011− "rimraf": "^2.7.1",
1012− "tmp": "0.0.30"
1013− },
1014− "dependencies": {
1015− "rimraf": {
1016− "version": "2.7.1",
1017− "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
1018− "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
1019− "requires": {
1020− "glob": "^7.1.3"
1021− }
1022− }
1023− }
1024− },
1025− "semver": {
1026− "version": "5.7.1",
1027− "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1028− "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
1029− },
1030− "set-immediate-shim": {
1031− "version": "1.0.1",
1032− "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
1033− "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
1034− },
1035− "shebang-command": {
1036− "version": "1.2.0",
1037− "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1038− "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1039− "requires": {
1040− "shebang-regex": "^1.0.0"
1041− },
1042− "dependencies": {
1043− "shebang-regex": {
1044− "version": "1.0.0",
1045− "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1046− "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
1047− }
1048− }
1049− },
1050− "shebang-regex": {
1051− "version": "3.0.0",
1052− "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1053− "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
1054− },
1055− "split": {
1056− "version": "1.0.1",
1057− "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
1058− "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
1059− "requires": {
1060− "through": "2"
1061− }
1062− },
1063− "sshpk": {
1064− "version": "1.16.1",
1065− "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
1066− "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
1067− "requires": {
1068− "asn1": "~0.2.3",
1069− "assert-plus": "^1.0.0",
1070− "bcrypt-pbkdf": "^1.0.0",
1071− "dashdash": "^1.12.0",
1072− "ecc-jsbn": "~0.1.1",
1073− "getpass": "^0.1.1",
1074− "jsbn": "~0.1.0",
1075− "safer-buffer": "^2.0.2",
1076− "tweetnacl": "~0.14.0"
1077− }
1078− },
1079− "stealthy-require": {
1080− "version": "1.1.1",
1081− "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
1082− "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
1083− },
1084− "string_decoder": {
1085− "version": "1.1.1",
1086− "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1087− "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1088− "requires": {
1089− "safe-buffer": "~5.1.0"
1090− },
1091− "dependencies": {
1092− "safe-buffer": {
1093− "version": "5.1.2",
1094− "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1095− "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
1096− }
1097− }
1098− },
1099− "tar": {
1100− "version": "4.4.13",
1101− "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
1102− "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
1103− "requires": {
1104− "chownr": "^1.1.1",
1105− "fs-minipass": "^1.2.5",
1106− "minipass": "^2.8.6",
1107− "minizlib": "^1.2.1",
1108− "mkdirp": "^0.5.0",
1109− "safe-buffer": "^5.1.2",
1110− "yallist": "^3.0.3"
1111− }
1112− },
1113− "temp": {
1114− "version": "0.9.1",
1115− "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz",
1116− "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==",
1117− "requires": {
1118− "rimraf": "~2.6.2"
1119− }
1120− },
1121− "through": {
1122− "version": "2.3.8",
1123− "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1124− "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
1125− },
1126− "tmp": {
1127− "version": "0.0.30",
1128− "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
1129− "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
1130− "requires": {
1131− "os-tmpdir": "~1.0.1"
1132− }
1133− },
1134− "to-regex-range": {
1135− "version": "5.0.1",
1136− "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1137− "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1138− "requires": {
1139− "is-number": "^7.0.0"
1140− }
1141− },
1142− "tough-cookie": {
1143− "version": "2.5.0",
1144− "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
1145− "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
1146− "requires": {
1147− "psl": "^1.1.28",
1148− "punycode": "^2.1.1"
1149− }
1150− },
1151− "traverse": {
1152− "version": "0.3.9",
1153− "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
1154− "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
1155− },
1156− "tunnel-agent": {
1157− "version": "0.6.0",
1158− "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1159− "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1160− "requires": {
1161− "safe-buffer": "^5.0.1"
1162− }
1163− },
1164− "tweetnacl": {
1165− "version": "0.14.5",
1166− "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1167− "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
1168− },
1169− "universalify": {
1170− "version": "0.1.2",
1171− "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
1172− "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
1173− },
1174− "unzip-stream": {
1175− "version": "0.3.0",
1176− "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.0.tgz",
1177− "integrity": "sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==",
1178− "requires": {
1179− "binary": "^0.3.0",
1180− "mkdirp": "^0.5.1"
1181− }
1182− },
1183− "uri-js": {
1184− "version": "4.2.2",
1185− "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1186− "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1187− "requires": {
1188− "punycode": "^2.1.0"
1189− }
1190− },
1191− "util-deprecate": {
1192− "version": "1.0.2",
1193− "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1194− "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
1195− },
1196− "uuid": {
1197− "version": "3.4.0",
1198− "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
1199− "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
1200− },
1201− "verror": {
1202− "version": "1.10.0",
1203− "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1204− "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1205− "requires": {
1206− "assert-plus": "^1.0.0",
1207− "core-util-is": "1.0.2",
1208− "extsprintf": "^1.2.0"
1209− }
1210− },
1211− "which": {
1212− "version": "1.3.1",
1213− "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1214− "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1215− "requires": {
1216− "isexe": "^2.0.0"
1217− }
1218− },
1219− "wrappy": {
1220− "version": "1.0.2",
1221− "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1222− "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
1223− },
1224− "xmlbuilder": {
1225− "version": "13.0.2",
1226− "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
1227− "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
1228− },
1229− "yallist": {
1230− "version": "3.1.1",
1231− "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
1232− "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
1233− }
1234− }
1235−}
package.jsondeleted−34
@@ -1,34 +0,0 @@
1−{
2− "name": "elm-ui-testing",
3− "version": "1.0.0",
4− "description": "Run the Elm UI benchmarks and render tests",
5− "main": "index.js",
6− "scripts": {
7− "test": "elm-test",
8− "view-test": "node tests-rendering/automation/view.js",
9− "test-render": "node tests-rendering/automation/run.js --chrome",
10− "test-render-sauce": "source sauce.env; node tests-rendering/automation/run.js --sauce --headless",
11− "test-render-sauce-automated": "node tests-rendering/automation/run.js --sauce --headless",
12− "test-doc-preview": "bash tests-rendering/automation/doc-preview.sh",
13− "bench": "node benchmarks/runtime/index.js",
14− "list-issues": "hub issue -f \"%i,%U,%t,'%L'%n\" > issues.csv"
15− },
16− "repository": {
17− "type": "git",
18− "url": "git+https://github.com/mdgriffith/elm-ui.git"
19− },
20− "author": "Matthew Griffith <mdg.griffith@gmail.com> (http://mechanical-elephant.com/)",
21− "license": "ISC",
22− "bugs": {
23− "url": "https://github.com/mdgriffith/elm-ui/issues"
24− },
25− "homepage": "https://github.com/mdgriffith/elm-ui#readme",
26− "dependencies": {
27− "chalk": "^2.4.2",
28− "commander": "^2.20.0",
29− "elm": "^0.19.1-3",
30− "elm-test": "^0.19.1-revision2",
31− "node-elm-compiler": "^5.0.4",
32− "selenium-webdriver": "^4.0.0-alpha.7"
33− }
34−}
src/Element.elm+105−204
@@ -27,45 +27,43 @@ module Element exposing
27{-|
27{-|
28
28
29
29
30−# Basic Elements
30+## Basic Elements
31
31
32@docs Element, none, text, el
32@docs Element, none, text, el
33
33
34
34
35−# Rows and Columns
35+## Rows and Columns
36
36
37−When we want more than one child on an element, we want to be _specific_ about how they will be laid out.
37+Rows and columns are the most common layouts.
38−
39−So, the common ways to do that would be `row` and `column`.
40
38
41@docs row, wrappedRow, column
39@docs row, wrappedRow, column
42
40
43
41
44−# Text Layout
42+## Text Layout
45
43
46−Text layout needs some specific considerations.
44+Text needs it's own layout primitives.
47
45
48@docs paragraph, textColumn
46@docs paragraph, textColumn
49
47
50
48
51−# Data Table
49+## Data Table
52
50
53@docs Column, table, IndexedColumn, indexedTable
51@docs Column, table, IndexedColumn, indexedTable
54
52
55
53
56−# Size
54+## Size
57
55
58@docs Attribute, width, height, Length, px, shrink, fill, fillPortion, maximum, minimum
56@docs Attribute, width, height, Length, px, shrink, fill, fillPortion, maximum, minimum
59
57
60
58
61−# Debugging
59+## Debugging
62
60
63@docs explain
61@docs explain
64
62
65
63
66−# Padding and Spacing
64+## Padding and Spacing
67
65
68−There's no concept of margin in `elm-ui`, instead we have padding and spacing.
66+There's no concept of margin in `style-elements`, instead we have padding and spacing.
69
67
70Padding is the distance between the outer edge and the content, and spacing is the space between children.
68Padding is the distance between the outer edge and the content, and spacing is the space between children.
71
69
@@ -81,14 +79,12 @@ Here's what we can expect:
81
79
82![Three boxes spaced 7 pixels apart. There's a 10 pixel distance from the edge of the parent to the boxes.](https://mdgriffith.gitbooks.io/style-elements/content/assets/spacing-400.png)
80![Three boxes spaced 7 pixels apart. There's a 10 pixel distance from the edge of the parent to the boxes.](https://mdgriffith.gitbooks.io/style-elements/content/assets/spacing-400.png)
83
81
84−**Note** `spacing` set on a `paragraph`, will set the pixel spacing between lines.
85−
86@docs padding, paddingXY, paddingEach
82@docs padding, paddingXY, paddingEach
87
83
88@docs spacing, spacingXY, spaceEvenly
84@docs spacing, spacingXY, spaceEvenly
89
85
90
86
91−# Alignment
87+## Alignment
92
88
93Alignment can be used to align an `Element` within another `Element`.
89Alignment can be used to align an `Element` within another `Element`.
94
90
@@ -105,11 +101,9 @@ If alignment is set on elements in a layout such as `row`, then the element will
105
101
106will result in a layout like
102will result in a layout like
107
103
108− |-|-| |-| |-|
104+ |-|-| |-| |-|
109
105
110−Where there are two elements on the left, one on the right, and one in the center of the space between the elements on the left and right.
106+Where there are two elements on the left, one in the center, and one on the right.
111−
112−**Note** For text alignment, check out `Element.Font`!
113
107
114@docs centerX, centerY, alignLeft, alignRight, alignTop, alignBottom
108@docs centerX, centerY, alignLeft, alignRight, alignTop, alignBottom
115
109
@@ -191,7 +185,11 @@ The main technique for responsiveness is to store window size information in you
191
185
192Install the `Browser` package, and set up a subscription for [`Browser.Events.onResize`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize).
186Install the `Browser` package, and set up a subscription for [`Browser.Events.onResize`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize).
193
187
188+You'll also need to retrieve the initial window size. You can either run the following task:
189+
190+ Task.perform (\size -> WindowResize { width = size.width, height = size.height }) Window.size
191+
194−You'll also need to retrieve the initial window size. You can either use [`Browser.Dom.getViewport`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Dom#getViewport) or pass in `window.innerWidth` and `window.innerHeight` as flags to your program, which is the preferred way. This requires minor setup on the JS side, but allows you to avoid the state where you don't have window info.
192+Or pass in `window.innerWidth` and `window.innerHeight` as flags to your program, which is the preferred way. This requires minor setup on the JS side, but allows you to avoid the state where you don't have window info.
195
193
196@docs Device, DeviceClass, Orientation, classifyDevice
194@docs Device, DeviceClass, Orientation, classifyDevice
197
195
@@ -297,7 +295,7 @@ fromRgb255 clr =
297 clr.alpha
295 clr.alpha
298
296
299
297
300−{-| Deconstruct a `Color` into its rgb channels.
298+{-| Deconstruct a `Color` into it's rgb channels.
301-}
299-}
302toRgb :
300toRgb :
303 Color
301 Color
@@ -315,18 +313,19 @@ toRgb (Internal.Rgba r g b a) =
315 }
313 }
316
314
317
315
318−{-| The basic building block of your layout.
316+{-| The basic building block of your layout. Here we create a
319
317
320− howdy : Element msg
318+ import Element
321− howdy =
319+
320+ view =
322− Element.el [] (Element.text "Howdy!")
321+ Element.el [] (Element.text "Hello!")
323
322
324-}
323-}
325type alias Element msg =
324type alias Element msg =
326 Internal.Element msg
325 Internal.Element msg
327
326
328
327
329−{-| An attribute that can be attached to an `Element`
328+{-| Standard attribute which cannot be a decoration.
330-}
329-}
331type alias Attribute msg =
330type alias Attribute msg =
332 Internal.Attribute () msg
331 Internal.Attribute () msg
@@ -379,7 +378,7 @@ px =
379 Internal.Px
378 Internal.Px
380
379
381
380
382−{-| Shrink an element to fit its contents.
381+{-| Shrink an element to fit it's contents.
383-}
382-}
384shrink : Length
383shrink : Length
385shrink =
384shrink =
@@ -455,6 +454,9 @@ layoutWith { options } attrs child =
455 [ classes.root
454 [ classes.root
456 , classes.any
455 , classes.any
457 , classes.single
456 , classes.single
457+
458+ -- , classes.contentCenterX
459+ -- , classes.contentCenterY
458 ]
460 ]
459 )
461 )
460 :: (Internal.rootStyle ++ attrs)
462 :: (Internal.rootStyle ++ attrs)
@@ -467,11 +469,11 @@ type alias Option =
467 Internal.Option
469 Internal.Option
468
470
469
471
470−{-| Elm UI embeds two StyleSheets, one that is constant, and one that changes dynamically based on styles collected from the elements being rendered.
472+{-| Style elements embeds two StyleSheets, one that is constant, and one that changes dynamically based on styles collected from the elments being rendered.
471
473
472This option will stop the static/constant stylesheet from rendering.
474This option will stop the static/constant stylesheet from rendering.
473
475
474−If you're embedding multiple elm-ui `layout` elements, you need to guarantee that only one is rendering the static style sheet and that it's above all the others in the DOM tree.
476+Make sure to render the constant/static stylesheet at least once on your page!
475
477
476-}
478-}
477noStaticStyleSheet : Option
479noStaticStyleSheet : Option
@@ -532,7 +534,7 @@ forceHover =
532 Internal.HoverOption Internal.ForceHover
534 Internal.HoverOption Internal.ForceHover
533
535
534
536
535−{-| When you want to render exactly nothing.
537+{-| Nothing to see here!
536-}
538-}
537none : Element msg
539none : Element msg
538none =
540none =
@@ -553,19 +555,20 @@ text content =
553
555
554{-| The basic building block of your layout.
556{-| The basic building block of your layout.
555
557
556−You can think of an `el` as a `div`, but it can only have one child.
558+You can think of an `el` as a `div`, but it can only hae one child.
557
559
558If you want multiple children, you'll need to use something like `row` or `column`
560If you want multiple children, you'll need to use something like `row` or `column`
559
561
560− import Element exposing (Element, rgb)
562+ import Color exposing (blue, darkBlue)
563+ import Element exposing (Element)
561 import Element.Background as Background
564 import Element.Background as Background
562 import Element.Border as Border
565 import Element.Border as Border
563
566
564 myElement : Element msg
567 myElement : Element msg
565 myElement =
568 myElement =
566 Element.el
569 Element.el
567− [ Background.color (rgb 0 0.5 0)
570+ [ Background.color blue
568− , Border.color (rgb 0 0.7 0)
571+ , Border.color darkBlue
569 ]
572 ]
570 (Element.text "You've made a stylish element!")
573 (Element.text "You've made a stylish element!")
571
574
@@ -582,7 +585,8 @@ el attrs child =
582 (Internal.Unkeyed [ child ])
585 (Internal.Unkeyed [ child ])
583
586
584
587
588+{-| If you want a row of elements, use `row`!
585−{-| -}
589+-}
586row : List (Attribute msg) -> List (Element msg) -> Element msg
590row : List (Attribute msg) -> List (Element msg) -> Element msg
587row attrs children =
591row attrs children =
588 Internal.element
592 Internal.element
@@ -614,8 +618,7 @@ column attrs children =
614 (Internal.Unkeyed children)
618 (Internal.Unkeyed children)
615
619
616
620
617−{-| Same as `row`, but will wrap if it takes up too much horizontal space.
618−-}
621+{-| -}
619wrappedRow : List (Attribute msg) -> List (Element msg) -> Element msg
622wrappedRow : List (Attribute msg) -> List (Element msg) -> Element msg
620wrappedRow attrs children =
623wrappedRow attrs children =
621 let
624 let
@@ -645,33 +648,20 @@ wrappedRow attrs children =
645 newPadding =
648 newPadding =
646 case padded of
649 case padded of
647 Just (Internal.Padding name t r b l) ->
650 Just (Internal.Padding name t r b l) ->
648− if r >= (toFloat x / 2) && b >= (toFloat y / 2) then
651+ if r >= x && b >= y then
649− let
650− newTop =
651− t - (toFloat y / 2)
652−
653− newRight =
654− r - (toFloat x / 2)
655−
656− newBottom =
657− b - (toFloat y / 2)
658−
659− newLeft =
660− l - (toFloat x / 2)
661− in
662 Just <|
652 Just <|
663− Internal.StyleClass Flag.padding
653+ Internal.StyleClass
654+ Flag.padding
664 (Internal.PaddingStyle
655 (Internal.PaddingStyle
665− (Internal.paddingNameFloat
656+ (Internal.paddingName t
666− newTop
657+ (r - x)
667− newRight
658+ (b - y)
668− newBottom
659+ l
669− newLeft
670 )
660 )
671− newTop
661+ t
672− newRight
662+ (r - x)
673− newBottom
663+ (b - y)
674− newLeft
664+ l
675 )
665 )
676
666
677 else
667 else
@@ -701,13 +691,6 @@ wrappedRow attrs children =
701
691
702 Nothing ->
692 Nothing ->
703 -- Not enough space in padding to compensate for spacing
693 -- Not enough space in padding to compensate for spacing
704− let
705− halfX =
706− negate (toFloat x / 2)
707−
708− halfY =
709− negate (toFloat y / 2)
710− in
711 Internal.element
694 Internal.element
712 Internal.asEl
695 Internal.asEl
713 Internal.div
696 Internal.div
@@ -724,28 +707,9 @@ wrappedRow attrs children =
724 ++ classes.wrapped
707 ++ classes.wrapped
725 )
708 )
726 :: Internal.Attr
709 :: Internal.Attr
727− (Html.Attributes.style "margin"
710+ (Html.Attributes.style "margin-bottom" (String.fromInt (negate y) ++ "px"))
728− (String.fromFloat halfY
711+ :: width fill
729− ++ "px"
712+ :: height fill
730− ++ " "
731− ++ String.fromFloat halfX
732− ++ "px"
733− )
734− )
735− :: Internal.Attr
736− (Html.Attributes.style "width"
737− ("calc(100% + "
738− ++ String.fromInt x
739− ++ "px)"
740− )
741− )
742− :: Internal.Attr
743− (Html.Attributes.style "height"
744− ("calc(100% + "
745− ++ String.fromInt y
746− ++ "px)"
747− )
748− )
749 :: Internal.StyleClass Flag.spacing (Internal.SpacingStyle spaceName x y)
713 :: Internal.StyleClass Flag.spacing (Internal.SpacingStyle spaceName x y)
750 :: []
714 :: []
751 )
715 )
@@ -767,7 +731,7 @@ type alias Todo =
767 el
731 el
768 [ Element.explain Debug.todo
732 [ Element.explain Debug.todo
769 ]
733 ]
770− (text "Help, I'm being debugged!")
734+ (text "Help! I'm being debugged!")
771
735
772-}
736-}
773explain : Todo -> Attribute msg
737explain : Todo -> Attribute msg
@@ -956,11 +920,11 @@ tableHelper attrs config =
956 }
920 }
957
921
958 InternalColumn col ->
922 InternalColumn col ->
923+ { cursor
959− { elements =
924+ | elements =
960− onGrid cursor.row cursor.column (col.view cell)
925+ onGrid cursor.row cursor.column (col.view cell)
961− :: cursor.elements
926+ :: cursor.elements
962− , column = cursor.column + 1
927+ , column = cursor.column + 1
963− , row = cursor.row
964 }
928 }
965
929
966 build columns rowData cursor =
930 build columns rowData cursor =
@@ -970,9 +934,9 @@ tableHelper attrs config =
970 cursor
934 cursor
971 columns
935 columns
972 in
936 in
973− { elements = newCursor.elements
937+ { newCursor
974− , row = cursor.row + 1
938+ | row = cursor.row + 1
975− , column = 1
939+ , column = 1
976 }
940 }
977
941
978 children =
942 children =
@@ -1001,22 +965,21 @@ tableHelper attrs config =
1001 children.elements
965 children.elements
1002
966
1003 Just renderedHeaders ->
967 Just renderedHeaders ->
1004− renderedHeaders ++ List.reverse children.elements
968+ renderedHeaders ++ children.elements
1005 )
969 )
1006 )
970 )
1007
971
1008
972
1009{-| A paragraph will layout all children as wrapped, inline elements.
973{-| A paragraph will layout all children as wrapped, inline elements.
1010
974
1011− import Element exposing (el, paragraph, text)
975+ import Element
1012 import Element.Font as Font
976 import Element.Font as Font
1013
977
1014− view =
1015− paragraph []
978+ Element.paragraph []
1016− [ text "lots of text ...."
979+ [ text "lots of text ...."
1017− , el [ Font.bold ] (text "this is bold")
980+ , el [ Font.bold ] (text "this is bold")
1018− , text "lots of text ...."
981+ , text "lots of text ...."
1019− ]
982+ ]
1020
983
1021This is really useful when you want to markup text by having some parts be bold, or some be links, or whatever you so desire.
984This is really useful when you want to markup text by having some parts be bold, or some be links, or whatever you so desire.
1022
985
@@ -1024,25 +987,23 @@ Also, if a child element has `alignLeft` or `alignRight`, then it will be moved
1024
987
1025This makes it particularly easy to do something like a [dropped capital](https://en.wikipedia.org/wiki/Initial).
988This makes it particularly easy to do something like a [dropped capital](https://en.wikipedia.org/wiki/Initial).
1026
989
1027− import Element exposing (alignLeft, el, padding, paragraph, text)
990+ import Element
1028 import Element.Font as Font
991 import Element.Font as Font
1029
992
1030− view =
1031− paragraph []
993+ Element.paragraph []
1032− [ el
994+ [ el
1033− [ alignLeft
995+ [ alignLeft
1034− , padding 5
996+ , padding 5
1035− ]
997+ , Font.lineHeight 1
1036− (text "S")
1037− , text "o much text ...."
1038 ]
998 ]
999+ (text "S")
1000+ , text "o much text ...."
1001+ ]
1039
1002
1040Which will look something like
1003Which will look something like
1041
1004
1042![A paragraph where the first letter is twice the height of the others](https://mdgriffith.gitbooks.io/style-elements/content/assets/Screen%20Shot%202017-08-25%20at%209.41.52%20PM.png)
1005![A paragraph where the first letter is twice the height of the others](https://mdgriffith.gitbooks.io/style-elements/content/assets/Screen%20Shot%202017-08-25%20at%209.41.52%20PM.png)
1043
1006
1044−**Note** `spacing` on a paragraph will set the pixel spacing between lines.
1045−
1046-}
1007-}
1047paragraph : List (Attribute msg) -> List (Element msg) -> Element msg
1008paragraph : List (Attribute msg) -> List (Element msg) -> Element msg
1048paragraph attrs children =
1009paragraph attrs children =
@@ -1165,8 +1126,6 @@ link attrs { url, label } =
1165 (classes.contentCenterX
1126 (classes.contentCenterX
1166 ++ " "
1127 ++ " "
1167 ++ classes.contentCenterY
1128 ++ classes.contentCenterY
1168− ++ " "
1169− ++ classes.link
1170 )
1129 )
1171 :: attrs
1130 :: attrs
1172 )
1131 )
@@ -1190,13 +1149,7 @@ newTabLink attrs { url, label } =
1190 :: Internal.Attr (Html.Attributes.target "_blank")
1149 :: Internal.Attr (Html.Attributes.target "_blank")
1191 :: width shrink
1150 :: width shrink
1192 :: height shrink
1151 :: height shrink
1193− :: Internal.htmlClass
1194− (classes.contentCenterX
1152+ :: Internal.htmlClass (classes.contentCenterX ++ " " ++ classes.contentCenterY)
1195− ++ " "
1196− ++ classes.contentCenterY
1197− ++ " "
1198− ++ classes.link
1199− )
1200 :: attrs
1153 :: attrs
1201 )
1154 )
1202 (Internal.Unkeyed [ label ])
1155 (Internal.Unkeyed [ label ])
@@ -1251,42 +1204,28 @@ downloadAs attrs { url, filename, label } =
1251 (Internal.Unkeyed [ label ])
1204 (Internal.Unkeyed [ label ])
1252
1205
1253
1206
1254−
1255−{- NEARBYS -}
1256−
1257−
1258−createNearby : Internal.Location -> Element msg -> Attribute msg
1259−createNearby loc element =
1260− case element of
1261− Internal.Empty ->
1262− Internal.NoAttribute
1263−
1264− _ ->
1265− Internal.Nearby loc element
1266−
1267−
1268{-| -}
1207{-| -}
1269below : Element msg -> Attribute msg
1208below : Element msg -> Attribute msg
1270below element =
1209below element =
1271− createNearby Internal.Below element
1210+ Internal.Nearby Internal.Below element
1272
1211
1273
1212
1274{-| -}
1213{-| -}
1275above : Element msg -> Attribute msg
1214above : Element msg -> Attribute msg
1276above element =
1215above element =
1277− createNearby Internal.Above element
1216+ Internal.Nearby Internal.Above element
1278
1217
1279
1218
1280{-| -}
1219{-| -}
1281onRight : Element msg -> Attribute msg
1220onRight : Element msg -> Attribute msg
1282onRight element =
1221onRight element =
1283− createNearby Internal.OnRight element
1222+ Internal.Nearby Internal.OnRight element
1284
1223
1285
1224
1286{-| -}
1225{-| -}
1287onLeft : Element msg -> Attribute msg
1226onLeft : Element msg -> Attribute msg
1288onLeft element =
1227onLeft element =
1289− createNearby Internal.OnLeft element
1228+ Internal.Nearby Internal.OnLeft element
1290
1229
1291
1230
1292{-| This will place an element in front of another.
1231{-| This will place an element in front of another.
@@ -1296,14 +1235,14 @@ onLeft element =
1296-}
1235-}
1297inFront : Element msg -> Attribute msg
1236inFront : Element msg -> Attribute msg
1298inFront element =
1237inFront element =
1299− createNearby Internal.InFront element
1238+ Internal.Nearby Internal.InFront element
1300
1239
1301
1240
1302{-| This will place an element between the background and the content of an element.
1241{-| This will place an element between the background and the content of an element.
1303-}
1242-}
1304behindContent : Element msg -> Attribute msg
1243behindContent : Element msg -> Attribute msg
1305behindContent element =
1244behindContent element =
1306− createNearby Internal.Behind element
1245+ Internal.Nearby Internal.Behind element
1307
1246
1308
1247
1309{-| -}
1248{-| -}
@@ -1324,8 +1263,7 @@ scale n =
1324 Internal.TransformComponent Flag.scale (Internal.Scale ( n, n, 1 ))
1263 Internal.TransformComponent Flag.scale (Internal.Scale ( n, n, 1 ))
1325
1264
1326
1265
1327−{-| Angle is given in radians. [Here are some conversion functions if you want to use another unit.](https://package.elm-lang.org/packages/elm/core/latest/Basics#degrees)
1328−-}
1266+{-| -}
1329rotate : Float -> Attr decorative msg
1267rotate : Float -> Attr decorative msg
1330rotate angle =
1268rotate angle =
1331 Internal.TransformComponent Flag.rotate (Internal.Rotate ( 0, 0, 1 ) angle)
1269 Internal.TransformComponent Flag.rotate (Internal.Rotate ( 0, 0, 1 ) angle)
@@ -1358,11 +1296,7 @@ moveLeft x =
1358{-| -}
1296{-| -}
1359padding : Int -> Attribute msg
1297padding : Int -> Attribute msg
1360padding x =
1298padding x =
1361− let
1362− f =
1363− toFloat x
1364− in
1365− Internal.StyleClass Flag.padding (Internal.PaddingStyle ("p-" ++ String.fromInt x) f f f f)
1299+ Internal.StyleClass Flag.padding (Internal.PaddingStyle ("p-" ++ String.fromInt x) x x x x)
1366
1300
1367
1301
1368{-| Set horizontal and vertical padding.
1302{-| Set horizontal and vertical padding.
@@ -1370,27 +1304,16 @@ padding x =
1370paddingXY : Int -> Int -> Attribute msg
1304paddingXY : Int -> Int -> Attribute msg
1371paddingXY x y =
1305paddingXY x y =
1372 if x == y then
1306 if x == y then
1373− let
1374− f =
1375− toFloat x
1376− in
1377− Internal.StyleClass Flag.padding (Internal.PaddingStyle ("p-" ++ String.fromInt x) f f f f)
1307+ Internal.StyleClass Flag.padding (Internal.PaddingStyle ("p-" ++ String.fromInt x) x x x x)
1378
1308
1379 else
1309 else
1380− let
1381− xFloat =
1382− toFloat x
1383−
1384− yFloat =
1385− toFloat y
1386− in
1387 Internal.StyleClass Flag.padding
1310 Internal.StyleClass Flag.padding
1388 (Internal.PaddingStyle
1311 (Internal.PaddingStyle
1389 ("p-" ++ String.fromInt x ++ "-" ++ String.fromInt y)
1312 ("p-" ++ String.fromInt x ++ "-" ++ String.fromInt y)
1390− yFloat
1313+ y
1391− xFloat
1314+ x
1392− yFloat
1315+ y
1393− xFloat
1316+ x
1394 )
1317 )
1395
1318
1396
1319
@@ -1405,32 +1328,22 @@ paddingXY x y =
1405
1328
1406And then just do
1329And then just do
1407
1330
1408− paddingEach { edges | right = 5 }
1331+ paddingEach { edges | right 5 }
1409
1332
1410-}
1333-}
1411paddingEach : { top : Int, right : Int, bottom : Int, left : Int } -> Attribute msg
1334paddingEach : { top : Int, right : Int, bottom : Int, left : Int } -> Attribute msg
1412paddingEach { top, right, bottom, left } =
1335paddingEach { top, right, bottom, left } =
1413 if top == right && top == bottom && top == left then
1336 if top == right && top == bottom && top == left then
1414− let
1415− topFloat =
1416− toFloat top
1417− in
1418− Internal.StyleClass Flag.padding
1419− (Internal.PaddingStyle ("p-" ++ String.fromInt top)
1337+ Internal.StyleClass Flag.padding (Internal.PaddingStyle ("p-" ++ String.fromInt top) top top top top)
1420− topFloat
1421− topFloat
1422− topFloat
1423− topFloat
1424− )
1425
1338
1426 else
1339 else
1427 Internal.StyleClass Flag.padding
1340 Internal.StyleClass Flag.padding
1428 (Internal.PaddingStyle
1341 (Internal.PaddingStyle
1429 (Internal.paddingName top right bottom left)
1342 (Internal.paddingName top right bottom left)
1430− (toFloat top)
1343+ top
1431− (toFloat right)
1344+ right
1432− (toFloat bottom)
1345+ bottom
1433− (toFloat left)
1346+ left
1434 )
1347 )
1435
1348
1436
1349
@@ -1473,7 +1386,7 @@ alignRight =
1473{-| -}
1386{-| -}
1474spaceEvenly : Attribute msg
1387spaceEvenly : Attribute msg
1475spaceEvenly =
1388spaceEvenly =
1476− Internal.Class Flag.spacing Internal.Style.classes.spaceEvenly
1389+ Internal.Class Flag.xAlign (.spaceEvenly Internal.Style.classes)
1477
1390
1478
1391
1479{-| -}
1392{-| -}
@@ -1505,7 +1418,7 @@ transparent on =
1505
1418
1506{-| A capped value between 0.0 and 1.0, where 0.0 is transparent and 1.0 is fully opaque.
1419{-| A capped value between 0.0 and 1.0, where 0.0 is transparent and 1.0 is fully opaque.
1507
1420
1508−Semantically equivalent to html opacity.
1421+Semantically equavalent to html opacity.
1509
1422
1510-}
1423-}
1511alpha : Float -> Attr decorative msg
1424alpha : Float -> Attr decorative msg
@@ -1595,29 +1508,17 @@ type Orientation
1595
1508
1596
1509
1597{-| Takes in a Window.Size and returns a device profile which can be used for responsiveness.
1510{-| Takes in a Window.Size and returns a device profile which can be used for responsiveness.
1598−
1599−If you have more detailed concerns around responsiveness, it probably makes sense to copy this function into your codebase and modify as needed.
1600−
1601-}
1511-}
1602classifyDevice : { window | height : Int, width : Int } -> Device
1512classifyDevice : { window | height : Int, width : Int } -> Device
1603classifyDevice window =
1513classifyDevice window =
1604− -- Tested in this ellie:
1605− -- https://ellie-app.com/68QM7wLW8b9a1
1606 { class =
1514 { class =
1607− let
1608− longSide =
1609− max window.width window.height
1610−
1611− shortSide =
1612− min window.width window.height
1613− in
1614− if shortSide < 600 then
1515+ if window.width <= 600 then
1615 Phone
1516 Phone
1616
1517
1617− else if longSide <= 1200 then
1518+ else if window.width > 600 && window.width <= 1200 then
1618 Tablet
1519 Tablet
1619
1520
1620− else if longSide > 1200 && longSide <= 1920 then
1521+ else if window.width > 1200 && window.width <= 1800 then
1621 Desktop
1522 Desktop
1622
1523
1623 else
1524 else
@@ -1634,7 +1535,7 @@ classifyDevice window =
1634{-| When designing it's nice to use a modular scale to set spacial rythms.
1535{-| When designing it's nice to use a modular scale to set spacial rythms.
1635
1536
1636 scaled =
1537 scaled =
1637− Element.modular 16 1.25
1538+ Scale.modular 16 1.25
1638
1539
1639A modular scale starts with a number, and multiplies it by a ratio a number of times.
1540A modular scale starts with a number, and multiplies it by a ratio a number of times.
1640Then, when setting font sizes you can use:
1541Then, when setting font sizes you can use:
src/Element/Background.elm+12−6
@@ -1,7 +1,13 @@
1−module Element.Background exposing
1+module Element.Background
2+ exposing
3+ ( color
2− ( color, gradient
4+ , gradient
3− , image, uncropped, tiled, tiledX, tiledY
5+ , image
6+ , tiled
7+ , tiledX
8+ , tiledY
9+ , uncropped
4− )
10+ )
5
11
6{-|
12{-|
7
13
@@ -12,7 +18,7 @@ module Element.Background exposing
12
18
13@docs image, uncropped, tiled, tiledX, tiledY
19@docs image, uncropped, tiled, tiledX, tiledY
14
20
15−**Note** if you want more control over a background image than is provided here, you should try just using a normal `Element.image` with something like `Element.behindContent`.
21+**Note** if you want more control over a background image than is provided here, you should try just using a normal `Element.image` with something like `Element.behind`.
16
22
17-}
23-}
18
24
@@ -35,7 +41,7 @@ image src =
35 Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") center / cover no-repeat"))
41 Internal.Attr (VirtualDom.style "background" ("url(\"" ++ src ++ "\") center / cover no-repeat"))
36
42
37
43
38−{-| A centered background image that keeps its natural proportions, but scales to fit the space.
44+{-| A centered background image that keeps it's natural propostions, but scales to fit the space.
39-}
45-}
40uncropped : String -> Attribute msg
46uncropped : String -> Attribute msg
41uncropped src =
47uncropped src =
src/Element/Border.elm+37−97
@@ -1,10 +1,19 @@
1−module Element.Border exposing
1+module Element.Border
2+ exposing
2− ( color
3+ ( color
3− , width, widthXY, widthEach
4− , solid, dashed, dotted
4+ , dashed
5− , rounded, roundEach
5+ , dotted
6+ , glow
7+ , innerGlow
6− , glow, innerGlow, shadow, innerShadow
8+ , innerShadow
9+ , roundEach
10+ , rounded
11+ , shadow
12+ , solid
13+ , width
14+ , widthEach
15+ , widthXY
7− )
16+ )
8
17
9{-|
18{-|
10
19
@@ -41,81 +50,38 @@ import Internal.Style as Style exposing (classes)
41{-| -}
50{-| -}
42color : Color -> Attr decorative msg
51color : Color -> Attr decorative msg
43color clr =
52color clr =
44− Internal.StyleClass
45− Flag.borderColor
46− (Internal.Colored
47− ("bc-" ++ Internal.formatColorClass clr)
53+ Internal.StyleClass Flag.borderColor (Internal.Colored ("border-color-" ++ Internal.formatColorClass clr) "border-color" clr)
48− "border-color"
49− clr
50− )
51
54
52
55
53{-| -}
56{-| -}
54width : Int -> Attribute msg
57width : Int -> Attribute msg
55width v =
58width v =
56− Internal.StyleClass
59+ Internal.StyleClass Flag.borderWidth (Internal.Single ("border-" ++ String.fromInt v) "border-width" (String.fromInt v ++ "px"))
57− Flag.borderWidth
58− (Internal.BorderWidth
59− ("b-" ++ String.fromInt v)
60− v
61− v
62− v
63− v
64− )
65
60
66
61
67{-| Set horizontal and vertical borders.
62{-| Set horizontal and vertical borders.
68-}
63-}
69widthXY : Int -> Int -> Attribute msg
64widthXY : Int -> Int -> Attribute msg
70widthXY x y =
65widthXY x y =
71− Internal.StyleClass
66+ Internal.StyleClass Flag.borderWidth (Internal.Single ("border-" ++ String.fromInt x ++ "-" ++ String.fromInt y) "border-width" (String.fromInt y ++ "px " ++ String.fromInt x ++ "px"))
72− Flag.borderWidth
73− (Internal.BorderWidth
74− ("b-"
75− ++ String.fromInt x
76− ++ "-"
77− ++ String.fromInt y
78− )
79− y
80− x
81− y
82− x
83− )
84
67
85
68
86{-| -}
69{-| -}
87−widthEach :
70+widthEach : { bottom : Int, left : Int, right : Int, top : Int } -> Attribute msg
88− { bottom : Int
89− , left : Int
90− , right : Int
91− , top : Int
92− }
93− -> Attribute msg
94widthEach { bottom, top, left, right } =
71widthEach { bottom, top, left, right } =
95− if top == bottom && left == right then
96− if top == right then
97− width top
98−
99− else
100− widthXY left top
101−
102− else
103− Internal.StyleClass Flag.borderWidth
72+ Internal.StyleClass Flag.borderWidth
104− (Internal.BorderWidth
73+ (Internal.Single ("border-" ++ String.fromInt top ++ "-" ++ String.fromInt right ++ String.fromInt bottom ++ "-" ++ String.fromInt left)
105− ("b-"
74+ "border-width"
106− ++ String.fromInt top
75+ (String.fromInt top
107− ++ "-"
76+ ++ "px "
108− ++ String.fromInt right
109− ++ "-"
110− ++ String.fromInt bottom
111− ++ "-"
112− ++ String.fromInt left
113− )
114− top
115− right
77+ ++ String.fromInt right
78+ ++ "px "
116− bottom
79+ ++ String.fromInt bottom
117− left
80+ ++ "px "
81+ ++ String.fromInt left
82+ ++ "px"
118 )
83 )
84+ )
119
85
120
86
121
87
@@ -148,34 +114,14 @@ dotted =
148-}
114-}
149rounded : Int -> Attribute msg
115rounded : Int -> Attribute msg
150rounded radius =
116rounded radius =
151− Internal.StyleClass
117+ Internal.StyleClass Flag.borderRound (Internal.Single ("border-radius-" ++ String.fromInt radius) "border-radius" (String.fromInt radius ++ "px"))
152− Flag.borderRound
153− (Internal.Single
154− ("br-" ++ String.fromInt radius)
155− "border-radius"
156− (String.fromInt radius ++ "px")
157− )
158
118
159
119
160{-| -}
120{-| -}
161−roundEach :
121+roundEach : { topLeft : Int, topRight : Int, bottomLeft : Int, bottomRight : Int } -> Attribute msg
162− { topLeft : Int
163− , topRight : Int
164− , bottomLeft : Int
165− , bottomRight : Int
166− }
167− -> Attribute msg
168roundEach { topLeft, topRight, bottomLeft, bottomRight } =
122roundEach { topLeft, topRight, bottomLeft, bottomRight } =
169 Internal.StyleClass Flag.borderRound
123 Internal.StyleClass Flag.borderRound
170− (Internal.Single
124+ (Internal.Single ("border-radius-" ++ String.fromInt topLeft ++ "-" ++ String.fromInt topRight ++ String.fromInt bottomLeft ++ "-" ++ String.fromInt bottomRight)
171− ("br-"
172− ++ String.fromInt topLeft
173− ++ "-"
174− ++ String.fromInt topRight
175− ++ String.fromInt bottomLeft
176− ++ "-"
177− ++ String.fromInt bottomRight
178− )
179 "border-radius"
125 "border-radius"
180 (String.fromInt topLeft
126 (String.fromInt topLeft
181 ++ "px "
127 ++ "px "
@@ -231,10 +177,7 @@ shadow almostShade =
231 }
177 }
232 in
178 in
233 Internal.StyleClass Flag.shadows <|
179 Internal.StyleClass Flag.shadows <|
234− Internal.Single
235− (Internal.boxShadowClass shade)
236− "box-shadow"
237− (Internal.formatBoxShadow shade)
180+ Internal.Single (Internal.boxShadowName shade) "box-shadow" (Internal.formatBoxShadow shade)
238
181
239
182
240{-| -}
183{-| -}
@@ -256,10 +199,7 @@ innerShadow almostShade =
256 }
199 }
257 in
200 in
258 Internal.StyleClass Flag.shadows <|
201 Internal.StyleClass Flag.shadows <|
259− Internal.Single
260− (Internal.boxShadowClass shade)
261− "box-shadow"
262− (Internal.formatBoxShadow shade)
202+ Internal.Single (Internal.boxShadowName shade) "box-shadow" (Internal.formatBoxShadow shade)
263
203
264
204
265
205
src/Element/Events.elm+18−11
@@ -1,13 +1,21 @@
1−module Element.Events exposing
1+module Element.Events
2− ( onClick, onDoubleClick, onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, onMouseMove
2+ exposing
3− , onFocus, onLoseFocus
3+ ( onClick
4− -- , onClickCoords
4+ -- , onClickCoords
5− -- , onClickPageCoords
5+ -- , onClickPageCoords
6− -- , onClickScreenCoords
6+ -- , onClickScreenCoords
7− -- , onMouseCoords
7+ , onDoubleClick
8+ , onFocus
9+ , onLoseFocus
10+ -- , onMouseCoords
11+ , onMouseDown
12+ , onMouseEnter
13+ , onMouseLeave
14+ , onMouseMove
8− -- , onMousePageCoords
15+ -- , onMousePageCoords
9− -- , onMouseScreenCoords
16+ -- , onMouseScreenCoords
17+ , onMouseUp
10− )
18+ )
11
19
12{-|
20{-|
13
21
@@ -30,7 +38,6 @@ import Json.Decode as Json
30import VirtualDom
38import VirtualDom
31
39
32
40
33−
34-- MOUSE EVENTS
41-- MOUSE EVENTS
35
42
36
43
src/Element/Font.elm+58−251
@@ -1,22 +1,46 @@
1−module Element.Font exposing
1+module Element.Font
2− ( color, size
2+ exposing
3− , family, Font, typeface, serif, sansSerif, monospace
3+ ( Font
4− , external
4+ , alignLeft
5− , alignLeft, alignRight, center, justify, letterSpacing, wordSpacing
5+ , alignRight
6− , underline, strike, italic, unitalicized
6+ , bold
7− , heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
7+ , center
8− , Variant, variant, variantList, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, feature, indexed
8+ , color
9+ , external
10+ , extraBold
11+ , extraLight
12+ , family
13+ , glow
14+ , hairline
15+ , heavy
16+ , italic
17+ , justify
18+ , letterSpacing
19+ , light
20+ , medium
21+ , monospace
22+ , regular
23+ , sansSerif
24+ , semiBold
25+ , serif
9− , glow, shadow
26+ , shadow
27+ , size
28+ , strike
29+ , typeface
30+ , underline
31+ , unitalicized
32+ , wordSpacing
10− )
33+ )
11
34
12{-|
35{-|
13
36
37+ import Color exposing (blue)
14 import Element
38 import Element
15 import Element.Font as Font
39 import Element.Font as Font
16
40
17 view =
41 view =
18 Element.el
42 Element.el
19− [ Font.color (Element.rgb 0 0 1)
43+ [ Font.color blue
20 , Font.size 18
44 , Font.size 18
21 , Font.family
45 , Font.family
22 [ Font.typeface "Open Sans"
46 [ Font.typeface "Open Sans"
@@ -25,9 +49,7 @@ module Element.Font exposing
25 ]
49 ]
26 (Element.text "Woohoo, I'm stylish text")
50 (Element.text "Woohoo, I'm stylish text")
27
51
28−**Note:** `Font.color`, `Font.size`, and `Font.family` are inherited, meaning you can set them at the top of your view and all subsequent nodes will have that value.
52+**Note**: `Font.color`, `Font.size`, and `Font.family` are inherited, meaning you can set them at the top of your view and all subsequent nodes will have that value.
29−
30−**Other Note:** If you're looking for something like `line-height`, it's handled by `Element.spacing` on a `paragraph`.
31
53
32@docs color, size
54@docs color, size
33
55
@@ -38,6 +60,23 @@ module Element.Font exposing
38
60
39@docs external
61@docs external
40
62
63+`Font.external` can be used to import font files. Let's say you found a neat font on <http://fonts.google.com>:
64+
65+ import Element
66+ import Element.Font as Font
67+
68+ view =
69+ Element.el
70+ [ Font.family
71+ [ Font.external
72+ { name = "Roboto"
73+ , url = "https://fonts.googleapis.com/css?family=Roboto"
74+ }
75+ , Font.sansSerif
76+ ]
77+ ]
78+ (Element.text "Woohoo, I'm stylish text")
79+
41
80
42## Alignment and Spacing
81## Alignment and Spacing
43
82
@@ -54,11 +93,6 @@ module Element.Font exposing
54@docs heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
93@docs heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
55
94
56
95
57−## Variants
58−
59−@docs Variant, variant, variantList, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, feature, indexed
60−
61−
62## Shadows
96## Shadows
63
97
64@docs glow, shadow
98@docs glow, shadow
@@ -79,13 +113,7 @@ type alias Font =
79{-| -}
113{-| -}
80color : Color -> Attr decorative msg
114color : Color -> Attr decorative msg
81color fontColor =
115color fontColor =
82− Internal.StyleClass
83− Flag.fontColor
84− (Internal.Colored
85− ("fc-" ++ Internal.formatColorClass fontColor)
116+ Internal.StyleClass Flag.fontColor (Internal.Colored ("fc-" ++ Internal.formatColorClass fontColor) "color" fontColor)
86− "color"
87− fontColor
88− )
89
117
90
118
91{-|
119{-|
@@ -105,12 +133,7 @@ color fontColor =
105-}
133-}
106family : List Font -> Attribute msg
134family : List Font -> Attribute msg
107family families =
135family families =
108− Internal.StyleClass
109− Flag.fontFamily
110− (Internal.FontFamily
111− (List.foldl Internal.renderFontClassName "ff-" families)
136+ Internal.StyleClass Flag.fontFamily <| Internal.FontFamily (List.foldl Internal.renderFontClassName "ff-" families) families
112− families
113− )
114
137
115
138
116{-| -}
139{-| -}
@@ -138,61 +161,6 @@ typeface =
138
161
139
162
140{-| -}
163{-| -}
141−type alias Adjustment =
142− { capital : Float
143− , lowercase : Float
144− , baseline : Float
145− , descender : Float
146− }
147−
148−
149−{-| -}
150−with :
151− { name : String
152− , adjustment : Maybe Adjustment
153− , variants : List Variant
154− }
155− -> Font
156−with =
157− Internal.FontWith
158−
159−
160−{-| -}
161−sizeByCapital : Attribute msg
162−sizeByCapital =
163− Internal.htmlClass classes.sizeByCapital
164−
165−
166−{-| -}
167−full : Attribute msg
168−full =
169− Internal.htmlClass classes.fullSize
170−
171−
172−{-| **Note** it's likely that `Font.external` will cause a flash on your page on loading.
173−
174−To bypass this, import your fonts using a separate stylesheet and just use `Font.typeface`.
175−
176−It's likely that `Font.external` will be removed or redesigned in the future to avoid the flashing.
177−
178−`Font.external` can be used to import font files. Let's say you found a neat font on <http://fonts.google.com>:
179−
180− import Element
181− import Element.Font as Font
182−
183− view =
184− Element.el
185− [ Font.family
186− [ Font.external
187− { name = "Roboto"
188− , url = "https://fonts.googleapis.com/css?family=Roboto"
189− }
190− , Font.sansSerif
191− ]
192− ]
193− (Element.text "Woohoo, I'm stylish text")
194−
195−-}
196external : { url : String, name : String } -> Font
164external : { url : String, name : String } -> Font
197external { url, name } =
165external { url, name } =
198 Internal.ImportFont name url
166 Internal.ImportFont name url
@@ -346,10 +314,10 @@ shadow :
346 -> Attr decorative msg
314 -> Attr decorative msg
347shadow shade =
315shadow shade =
348 Internal.StyleClass Flag.txtShadows <|
316 Internal.StyleClass Flag.txtShadows <|
349− Internal.Single (Internal.textShadowClass shade) "text-shadow" (Internal.formatTextShadow shade)
317+ Internal.Single (Internal.textShadowName shade) "text-shadow" (Internal.formatTextShadow shade)
350
318
351
319
352−{-| A glow is just a simplified shadow.
320+{-| A glow is just a simplified shadow
353-}
321-}
354glow : Color -> Float -> Attr decorative msg
322glow : Color -> Float -> Attr decorative msg
355glow clr i =
323glow clr i =
@@ -361,165 +329,4 @@ glow clr i =
361 }
329 }
362 in
330 in
363 Internal.StyleClass Flag.txtShadows <|
331 Internal.StyleClass Flag.txtShadows <|
364− Internal.Single (Internal.textShadowClass shade) "text-shadow" (Internal.formatTextShadow shade)
332+ Internal.Single (Internal.textShadowName shade) "text-shadow" (Internal.formatTextShadow shade)
365−
366−
367−
368−{- Variants -}
369−
370−
371−{-| -}
372−type alias Variant =
373− Internal.Variant
374−
375−
376−{-| You can use this to set a single variant on an element itself such as:
377−
378− el
379− [ Font.variant Font.smallCaps
380− ]
381− (text "rendered with smallCaps")
382−
383−**Note** These will **not** stack. If you want multiple variants, you should use `Font.variantList`.
384−
385−-}
386−variant : Variant -> Attribute msg
387−variant var =
388− case var of
389− Internal.VariantActive name ->
390− Internal.Class Flag.fontVariant ("v-" ++ name)
391−
392− Internal.VariantOff name ->
393− Internal.Class Flag.fontVariant ("v-" ++ name ++ "-off")
394−
395− Internal.VariantIndexed name index ->
396− Internal.StyleClass Flag.fontVariant <|
397− Internal.Single ("v-" ++ name ++ "-" ++ String.fromInt index)
398− "font-feature-settings"
399− ("\"" ++ name ++ "\" " ++ String.fromInt index)
400−
401−
402−isSmallCaps x =
403− case x of
404− Internal.VariantActive feat ->
405− feat == "smcp"
406−
407− _ ->
408− False
409−
410−
411−{-| -}
412−variantList : List Variant -> Attribute msg
413−variantList vars =
414− let
415− features =
416− vars
417− |> List.map Internal.renderVariant
418−
419− hasSmallCaps =
420− List.any isSmallCaps vars
421−
422− name =
423− if hasSmallCaps then
424− vars
425− |> List.map Internal.variantName
426− |> String.join "-"
427− |> (\x -> x ++ "-sc")
428−
429− else
430− vars
431− |> List.map Internal.variantName
432− |> String.join "-"
433−
434− featureString =
435− String.join ", " features
436− in
437− Internal.StyleClass Flag.fontVariant <|
438− Internal.Style ("v-" ++ name)
439− [ Internal.Property "font-feature-settings" featureString
440− , Internal.Property "font-variant"
441− (if hasSmallCaps then
442− "small-caps"
443−
444− else
445− "normal"
446− )
447− ]
448−
449−
450−{-| [Small caps](https://en.wikipedia.org/wiki/Small_caps) are rendered using uppercase glyphs, but at the size of lowercase glyphs.
451−-}
452−smallCaps : Variant
453−smallCaps =
454− Internal.VariantActive "smcp"
455−
456−
457−{-| Add a slash when rendering `0`
458−-}
459−slashedZero : Variant
460−slashedZero =
461− Internal.VariantActive "zero"
462−
463−
464−{-| -}
465−ligatures : Variant
466−ligatures =
467− Internal.VariantActive "liga"
468−
469−
470−{-| Oridinal markers like `1st` and `2nd` will receive special glyphs.
471−-}
472−ordinal : Variant
473−ordinal =
474− Internal.VariantActive "ordn"
475−
476−
477−{-| Number figures will each take up the same space, allowing them to be easily aligned, such as in tables.
478−-}
479−tabularNumbers : Variant
480−tabularNumbers =
481− Internal.VariantActive "tnum"
482−
483−
484−{-| Render fractions with the numerator stacked on top of the denominator.
485−-}
486−stackedFractions : Variant
487−stackedFractions =
488− Internal.VariantActive "afrc"
489−
490−
491−{-| Render fractions
492−-}
493−diagonalFractions : Variant
494−diagonalFractions =
495− Internal.VariantActive "frac"
496−
497−
498−{-| -}
499−swash : Int -> Variant
500−swash =
501− Internal.VariantIndexed "swsh"
502−
503−
504−{-| Set a feature by name and whether it should be on or off.
505−
506−Feature names are four-letter names as defined in the [OpenType specification](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist).
507−
508−-}
509−feature : String -> Bool -> Variant
510−feature name on =
511− if on then
512− Internal.VariantIndexed name 1
513−
514− else
515− Internal.VariantIndexed name 0
516−
517−
518−{-| A font variant might have multiple versions within the font.
519−
520−In these cases we need to specify the index of the version we want.
521−
522−-}
523−indexed : String -> Int -> Variant
524−indexed name on =
525− Internal.VariantIndexed name on
src/Element/Input.elm+509−940
@@ -1,186 +1,68 @@
1−module Element.Input exposing
1+module Element.Input
2− ( focusedOnLoad
2+ exposing
3+ ( Label
4+ , Option
5+ , OptionState(..)
6+ , Placeholder
7+ , Thumb
3− , button
8+ , button
9+ , checkbox
10+ , currentPassword
4− , checkbox, defaultCheckbox
11+ , defaultCheckbox
12+ , defaultThumb
13+ , email
14+ , focusedOnLoad
15+ , labelAbove
16+ , labelBelow
17+ , labelLeft
18+ , labelRight
5− , text, multiline
19+ , multiline
6− , Placeholder, placeholder
20+ , newPassword
7− , username, newPassword, currentPassword, email, search, spellChecked
21+ , option
8− , slider, Thumb, thumb, defaultThumb
22+ , optionWith
9− , radio, radioRow, Option, option, optionWith, OptionState(..)
23+ , placeholder
10− , Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
24+ , radio
11− )
25+ , radioRow
12−
26+ , search
13−{-| Input elements have a lot of constraints!
27+ , slider
14−
28+ , spellChecked
15−We want all of our input elements to:
29+ , text
16−
30+ , thumb
17− - _Always be accessible_
31+ , username
18− - _Behave intuitively_
32+ )
19− - _Be completely restyleable_
20−
21−While these three goals may seem pretty obvious, Html and CSS have made it surprisingly difficult to achieve!
22−
23−And incredibly difficult for developers to remember all the tricks necessary to make things work. If you've every tried to make a `<textarea>` be the height of it's content or restyle a radio button while maintaining accessibility, you may be familiar.
24−
25−This module is intended to be accessible by default. You shouldn't have to wade through docs, articles, and books to find out [exactly how accessible your html actually is](https://www.powermapper.com/tests/screen-readers/aria/index.html).
26−
27−
28−# Focus Styling
29−
30−All Elements can be styled on focus by using [`Element.focusStyle`](Element#focusStyle) to set a global focus style or [`Element.focused`](Element#focused) to set a focus style individually for an element.
31−
32−@docs focusedOnLoad
33−
34
33
35−# Buttons
34+{-|
36
35
37@docs button
36@docs button
38
37
39−
40−# Checkboxes
41−
42−A checkbox requires you to store a `Bool` in your model.
43−
44−This is also the first input element that has a [`required label`](#Label).
45−
46− import Element exposing (text)
47− import Element.Input as Input
48−
49− type Msg
50− = GuacamoleChecked Bool
51−
52− view model =
53− Input.checkbox []
54− { onChange = GuacamoleChecked
55− , icon = Input.defaultCheckbox
56− , checked = model.guacamole
57− , label =
58− Input.labelRight []
59− (text "Do you want Guacamole?")
60− }
61−
62@docs checkbox, defaultCheckbox
38@docs checkbox, defaultCheckbox
63
39
64
40
65−# Text
41+## Text Input
66−
67−@docs text, multiline
68−
69−@docs Placeholder, placeholder
70−
71
42
72−## Text with autofill
43+@docs text, Placeholder, placeholder, username, newPassword, currentPassword, email, search, spellChecked
73
44
74−If we want to play nicely with a browser's ability to autofill a form, we need to be able to give it a hint about what we're expecting.
75
45
76−The following inputs are very similar to `Input.text`, but they give the browser a hint to allow autofill to work correctly.
46+## Multiline Text
77
47
78−@docs username, newPassword, currentPassword, email, search, spellChecked
48+@docs multiline
79
49
80
50
81−# Sliders
51+## Slider
82−
83−A slider is great for choosing between a range of numerical values.
84−
85− - **thumb** - The icon that you click and drag to change the value.
86− - **track** - The line behind the thumb denoting where you can slide to.
87
52
88@docs slider, Thumb, thumb, defaultThumb
53@docs slider, Thumb, thumb, defaultThumb
89
54
90
55
91−# Radio Selection
56+## Radio Buttons
92−
93−The fact that we still call this a radio selection is fascinating. I can't remember the last time I actually used an honest-to-goodness button on a radio. Chalk it up along with the floppy disk save icon or the word [Dashboard](https://en.wikipedia.org/wiki/Dashboard).
94−
95−Perhaps a better name would be `Input.chooseOne`, because this allows you to select one of a set of options!
96−
97−Nevertheless, here we are. Here's how you put one together
98−
99− Input.radio
100− [ padding 10
101− , spacing 20
102− ]
103− { onChange = ChooseLunch
104− , selected = Just model.lunch
105− , label = Input.labelAbove [] (text "Lunch")
106− , options =
107− [ Input.option Burrito (text "Burrito")
108− , Input.option Taco (text "Taco!")
109− , Input.option Gyro (text "Gyro")
110− ]
111− }
112−
113−**Note** we're using `Input.option`, which will render the default radio icon you're probably used to. If you want compeltely custom styling, use `Input.optionWith`!
114
57
115@docs radio, radioRow, Option, option, optionWith, OptionState
58@docs radio, radioRow, Option, option, optionWith, OptionState
116
59
117
60
118−# Labels
61+## Labels
119−
120−Every input has a required `Label`.
121−
122−@docs Label, labelAbove, labelBelow, labelLeft, labelRight, labelHidden
123−
124−
125−# Form Elements
126−
127−You might be wondering where something like `<form>` is.
128−
129−What I've found is that most people who want `<form>` usually want it for the [implicit submission behavior](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission) or to be clearer, they want to do something when the `Enter` key is pressed.
130−
131−Instead of implicit submission behavior, [try making an `onEnter` event handler like in this Ellie Example](https://ellie-app.com/5X6jBKtxzdpa1). Then everything is explicit!
132−
133−And no one has to look up obtuse html documentation to understand the behavior of their code :).
134−
135−
136−# File Inputs
137−
138−Presently, elm-ui does not expose a replacement for `<input type="file">`; in the meantime, an `Input.button` and `elm/file`'s `File.Select` may meet your needs.
139−
140
62
141−# Disabling Inputs
63+@docs Label, labelAbove, labelBelow, labelLeft, labelRight
142
64
143−You also might be wondering how to disable an input.
65+@docs focusedOnLoad
144−
145−Disabled inputs can be a little problematic for user experience, and doubly so for accessibility. This is because it's now your priority to inform the user _why_ some field is disabled.
146−
147−If an input is truly disabled, meaning it's not focusable or doesn't send off a `Msg`, you actually lose your ability to help the user out! For those wary about accessibility [this is a big problem.](https://ux.stackexchange.com/questions/103239/should-disabled-elements-be-focusable-for-accessibility-purposes)
148−
149−Here are some alternatives to think about that don't involve explicitly disabling an input.
150−
151−**Disabled Buttons** - Change the `Msg` it fires, the text that is rendered, and optionally set a `Region.description` which will be available to screen readers.
152−
153− import Element.Input as Input
154− import Element.Region as Region
155−
156− myButton ready =
157− if ready then
158− Input.button
159− [ Background.color blue
160− ]
161− { onPress =
162− Just SaveButtonPressed
163− , label =
164− text "Save blog post"
165− }
166−
167− else
168− Input.button
169− [ Background.color grey
170− , Region.description
171− "A publish date is required before saving a blogpost."
172− ]
173− { onPress =
174− Just DisabledSaveButtonPressed
175− , label =
176− text "Save Blog "
177− }
178−
179−Consider showing a hint if `DisabledSaveButtonPressed` is sent.
180−
181−For other inputs such as `Input.text`, consider simply rendering it in a normal `paragraph` or `el` if it's not editable.
182−
183−Alternatively, see if it's reasonable to _not_ display an input if you'd normally disable it. Is there an option where it's only visible when it's editable?
184
66
185-}
67-}
186
68
@@ -225,112 +107,48 @@ placeholder =
225 Placeholder
107 Placeholder
226
108
227
109
228−type LabelLocation
110+{-| Every input has a required `label`.
229− = OnRight
230− | OnLeft
231− | Above
232− | Below
233−
234−
235−{-| -}
111+-}
236type Label msg
112type Label msg
237− = Label LabelLocation (List (Attribute msg)) (Element msg)
113+ = Label Internal.Location (List (Attribute msg)) (Element msg)
238− | HiddenLabel String
239−
240−
241−isStacked : Label msg -> Bool
242−isStacked label =
243− case label of
244− Label loc _ _ ->
245− case loc of
246− OnRight ->
247− False
248−
249− OnLeft ->
250− False
251−
252− Above ->
253− True
254−
255− Below ->
256− True
257−
258− HiddenLabel _ ->
259− True
260
114
261
115
262{-| -}
116{-| -}
263labelRight : List (Attribute msg) -> Element msg -> Label msg
117labelRight : List (Attribute msg) -> Element msg -> Label msg
264labelRight =
118labelRight =
265− Label OnRight
119+ Label Internal.OnRight
266
120
267
121
268{-| -}
122{-| -}
269labelLeft : List (Attribute msg) -> Element msg -> Label msg
123labelLeft : List (Attribute msg) -> Element msg -> Label msg
270labelLeft =
124labelLeft =
271− Label OnLeft
125+ Label Internal.OnLeft
272
126
273
127
274{-| -}
128{-| -}
275labelAbove : List (Attribute msg) -> Element msg -> Label msg
129labelAbove : List (Attribute msg) -> Element msg -> Label msg
276labelAbove =
130labelAbove =
277− Label Above
131+ Label Internal.Above
278
132
279
133
280{-| -}
134{-| -}
281labelBelow : List (Attribute msg) -> Element msg -> Label msg
135labelBelow : List (Attribute msg) -> Element msg -> Label msg
282labelBelow =
136labelBelow =
283− Label Below
137+ Label Internal.Below
284−
285−
286−{-| Sometimes you may need to have a label which is not visible, but is still accessible to screen readers.
287−
288−Seriously consider a visible label before using this.
289−
290−The situations where a hidden label makes sense:
291−
292− - A searchbar with a `search` button right next to it.
293− - A `table` of inputs where the header gives the label.
294−
295−Basically, a hidden label works when there are other contextual clues that sighted people can pick up on.
296−
297−-}
298−labelHidden : String -> Label msg
299−labelHidden =
300− HiddenLabel
301−
302−
303−hiddenLabelAttribute label =
304− case label of
305− HiddenLabel textLabel ->
306− Internal.Describe (Internal.Label textLabel)
307−
308− Label _ _ _ ->
309− Internal.NoAttribute
310
138
311
139
312{-| A standard button.
140{-| A standard button.
313
141
314−The `onPress` handler will be fired either `onClick` or when the element is focused and the `Enter` key has been pressed.
142+The `onPress` handler will be fired either `onClick` or when the element is focused and the enter key has been pressed.
315
143
316− import Element exposing (rgb255, text)
317− import Element.Background as Background
318 import Element.Input as Input
144 import Element.Input as Input
319
145
320− blue =
321− Element.rgb255 238 238 238
322−
323− myButton =
324− Input.button
146+ Input.button []
325− [ Background.color blue
326− , Element.focused
327− [ Background.color purple ]
328− ]
329− { onPress = Just ClickMsg
147+ { onPress = Just ClickMsg
330− , label = text "My Button"
148+ , label = text "My Button"
331− }
149+ }
332
150
333−**Note** If you have an icon button but want it to be accessible, consider adding a [`Region.description`](Element-Region#description), which will describe the button to screen readers.
151+`onPress` takes a `Maybe msg`. If you provide the value `Nothing`, then the button will be disabled.
334
152
335-}
153-}
336button :
154button :
@@ -350,15 +168,9 @@ button attrs { onPress, label } =
350 Internal.div
168 Internal.div
351 (Element.width Element.shrink
169 (Element.width Element.shrink
352 :: Element.height Element.shrink
170 :: Element.height Element.shrink
353− :: Internal.htmlClass
354− (classes.contentCenterX
171+ :: Internal.htmlClass classes.contentCenterX
355− ++ " "
356− ++ classes.contentCenterY
172+ :: Internal.htmlClass classes.contentCenterY
357− ++ " "
358− ++ classes.seButton
173+ :: Internal.htmlClass classes.seButton
359− ++ " "
360− ++ classes.noTextSelection
361− )
362 :: Element.pointer
174 :: Element.pointer
363 :: focusDefault attrs
175 :: focusDefault attrs
364 :: Internal.Describe Internal.Button
176 :: Internal.Describe Internal.Button
@@ -369,17 +181,7 @@ button attrs { onPress, label } =
369
181
370 Just msg ->
182 Just msg ->
371 Events.onClick msg
183 Events.onClick msg
372− :: onKeyLookup
184+ :: onEnter msg
373− (\code ->
374− if code == enter then
375− Just msg
376−
377− else if code == space then
378− Just msg
379−
380− else
381− Nothing
382− )
383 :: attrs
185 :: attrs
384 )
186 )
385 )
187 )
@@ -389,7 +191,6 @@ button attrs { onPress, label } =
389focusDefault attrs =
191focusDefault attrs =
390 if List.any hasFocusStyle attrs then
192 if List.any hasFocusStyle attrs then
391 Internal.NoAttribute
193 Internal.NoAttribute
392−
393 else
194 else
394 Internal.htmlClass "focusable"
195 Internal.htmlClass "focusable"
395
196
@@ -412,14 +213,7 @@ type alias Checkbox msg =
412 }
213 }
413
214
414
215
415−{-|
216+{-| -}
416−
417− - **onChange** - The `Msg` to send.
418− - **icon** - The checkbox icon to show. This can be whatever you'd like, but `Input.defaultCheckbox` is included to get you started.
419− - **checked** - The current checked state.
420− - **label** - The [`Label`](#Label) for this checkbox
421−
422−-}
423checkbox :
217checkbox :
424 List (Attribute msg)
218 List (Attribute msg)
425 ->
219 ->
@@ -432,49 +226,34 @@ checkbox :
432checkbox attrs { label, icon, checked, onChange } =
226checkbox attrs { label, icon, checked, onChange } =
433 let
227 let
434 attributes =
228 attributes =
435− [ if isHiddenLabel label then
436− Internal.NoAttribute
437−
438− else
439− Element.spacing
229+ Element.spacing 6
440− 6
441− , Internal.Attr (Html.Events.onClick (onChange (not checked)))
230+ :: [ Internal.Attr (Html.Events.onClick (onChange (not checked)))
442− , Region.announce
231+ , Region.announce
443− , onKeyLookup <|
232+ , onKeyLookup <|
444− \code ->
233+ \code ->
445− if code == enter then
234+ if code == enter then
446− Just <| onChange (not checked)
235+ Just <| onChange (not checked)
447−
448− else if code == space then
236+ else if code == space then
449− Just <| onChange (not checked)
237+ Just <| onChange (not checked)
450−
451− else
238+ else
452− Nothing
239+ Nothing
453− , tabindex 0
240+ ]
454− , Element.pointer
455− , Element.alignLeft
456− , Element.width Element.fill
241+ ++ (tabindex 0 :: Element.pointer :: Element.alignLeft :: Element.width Element.fill :: attrs)
457− ]
458− ++ attrs
459 in
242 in
460− applyLabel
243+ applyLabel attributes
461− (Internal.Attr (Html.Attributes.attribute "role" "checkbox")
462− :: Internal.Attr
463− (Html.Attributes.attribute "aria-checked" <|
464− if checked then
465− "true"
466−
467− else
468− "false"
469− )
470− :: hiddenLabelAttribute label
471− :: attributes
472− )
473 label
244 label
474 (Internal.element
245 (Internal.element
475 Internal.asEl
246 Internal.asEl
476 Internal.div
247 Internal.div
248+ [ Internal.Attr <|
249+ Html.Attributes.attribute "role" "checkbox"
250+ , Internal.Attr <|
251+ Html.Attributes.attribute "aria-checked" <|
252+ if checked then
253+ "true"
254+ else
255+ "false"
477− [ Element.centerY
256+ , Element.centerY
478 , Element.height Element.fill
257 , Element.height Element.fill
479 , Element.width Element.shrink
258 , Element.width Element.shrink
480 ]
259 ]
@@ -513,7 +292,6 @@ defaultThumb =
513
292
514 Input.slider
293 Input.slider
515 [ Element.height (Element.px 30)
294 [ Element.height (Element.px 30)
516−
517 -- Here is where we're creating/styling the "track"
295 -- Here is where we're creating/styling the "track"
518 , Element.behindContent
296 , Element.behindContent
519 (Element.el
297 (Element.el
@@ -527,9 +305,7 @@ defaultThumb =
527 )
305 )
528 ]
306 ]
529 { onChange = AdjustValue
307 { onChange = AdjustValue
530− , label =
531− Input.labelAbove []
532− (text "My Slider Value")
308+ , label = Input.labelAbove [] (text "My Slider Value")
533 , min = 0
309 , min = 0
534 , max = 75
310 , max = 75
535 , step = Nothing
311 , step = Nothing
@@ -538,7 +314,7 @@ defaultThumb =
538 Input.defaultThumb
314 Input.defaultThumb
539 }
315 }
540
316
541−`Element.behindContent` is used to render the track of the slider. Without it, no track would be rendered. The `thumb` is the icon that you can move around.
317+The `thumb` is the icon that you can move around.
542
318
543The slider can be vertical or horizontal depending on the width/height of the slider.
319The slider can be vertical or horizontal depending on the width/height of the slider.
544
320
@@ -546,7 +322,7 @@ The slider can be vertical or horizontal depending on the width/height of the sl
546 - `height (px someHeight)` and `width (px someWidth)` where `someHeight` > `someWidth` will also do it.
322 - `height (px someHeight)` and `width (px someWidth)` where `someHeight` > `someWidth` will also do it.
547 - otherwise, the slider will be horizontal.
323 - otherwise, the slider will be horizontal.
548
324
549−**Note** If you want a slider for an `Int` value:
325+**Note:** If you want a slider for an `Int` value:
550
326
551 - set `step` to be `Just 1`, or some other whole value
327 - set `step` to be `Just 1`, or some other whole value
552 - `value = toFloat model.myInt`
328 - `value = toFloat model.myInt`
@@ -658,34 +434,9 @@ slider attributes input =
658 ]
434 ]
659 in
435 in
660 applyLabel
436 applyLabel
661− [ if isHiddenLabel input.label then
662− Internal.NoAttribute
663−
664− else
665− Element.spacingXY spacingX spacingY
437+ [ Element.spacingXY spacingX spacingY
666 , Region.announce
438 , Region.announce
667− , Element.width
439+ , Element.width Element.fill
668− (case trackWidth of
669− Nothing ->
670− Element.fill
671−
672− Just (Internal.Px _) ->
673− Element.shrink
674−
675− Just x ->
676− x
677− )
678− , Element.height
679− (case trackHeight of
680− Nothing ->
681− Element.shrink
682−
683− Just (Internal.Px _) ->
684− Element.shrink
685−
686− Just x ->
687− x
688− )
689 ]
440 ]
690 input.label
441 input.label
691 (Element.row
442 (Element.row
@@ -697,8 +448,7 @@ slider attributes input =
697 [ Internal.element
448 [ Internal.element
698 Internal.asEl
449 Internal.asEl
699 (Internal.NodeName "input")
450 (Internal.NodeName "input")
700− [ hiddenLabelAttribute input.label
701− , Internal.StyleClass Flag.active
451+ [ Internal.StyleClass Flag.active
702 (Internal.Style
452 (Internal.Style
703 ("input[type=\"range\"]." ++ className ++ "::-moz-range-thumb")
453 ("input[type=\"range\"]." ++ className ++ "::-moz-range-thumb")
704 thumbShadowStyle
454 thumbShadowStyle
@@ -713,7 +463,7 @@ slider attributes input =
713 ("input[type=\"range\"]." ++ className ++ "::-ms-thumb")
463 ("input[type=\"range\"]." ++ className ++ "::-ms-thumb")
714 thumbShadowStyle
464 thumbShadowStyle
715 )
465 )
716− , Internal.Attr (Html.Attributes.class (className ++ " ui-slide-bar focusable-parent"))
466+ , Internal.Attr (Html.Attributes.class (className ++ " focusable-parent"))
717 , Internal.Attr
467 , Internal.Attr
718 (Html.Events.onInput
468 (Html.Events.onInput
719 (\str ->
469 (\str ->
@@ -753,19 +503,16 @@ slider attributes input =
753 , if vertical then
503 , if vertical then
754 Internal.Attr <|
504 Internal.Attr <|
755 Html.Attributes.attribute "orient" "vertical"
505 Html.Attributes.attribute "orient" "vertical"
756−
757 else
506 else
758 Internal.NoAttribute
507 Internal.NoAttribute
759 , Element.width <|
508 , Element.width <|
760 if vertical then
509 if vertical then
761 Maybe.withDefault (Element.px 20) trackHeight
510 Maybe.withDefault (Element.px 20) trackHeight
762−
763 else
511 else
764 Maybe.withDefault Element.fill trackWidth
512 Maybe.withDefault Element.fill trackWidth
765 , Element.height <|
513 , Element.height <|
766 if vertical then
514 if vertical then
767 Maybe.withDefault Element.fill trackWidth
515 Maybe.withDefault Element.fill trackWidth
768−
769 else
516 else
770 Maybe.withDefault (Element.px 20) trackHeight
517 Maybe.withDefault (Element.px 20) trackHeight
771 ]
518 ]
@@ -779,10 +526,9 @@ slider attributes input =
779 -- This is after `attributes` because the thumb should be in front of everything.
526 -- This is after `attributes` because the thumb should be in front of everything.
780 ++ [ Element.behindContent <|
527 ++ [ Element.behindContent <|
781 if vertical then
528 if vertical then
782− viewVerticalThumb factor (Internal.htmlClass "focusable-thumb" :: thumbAttributes) trackWidth
529+ viewVerticalThumb factor thumbAttributes trackWidth
783−
784 else
530 else
785− viewHorizontalThumb factor (Internal.htmlClass "focusable-thumb" :: thumbAttributes) trackHeight
531+ viewHorizontalThumb factor thumbAttributes trackHeight
786 ]
532 ]
787 )
533 )
788 Element.none
534 Element.none
@@ -855,551 +601,296 @@ type alias Text msg =
855 }
601 }
856
602
857
603
604+type Padding
605+ = Padding Int Int Int Int
606+
607+
858−{-| -}
608+{-|
609+
610+ attributes
611+
612+ <parent>
613+ attribute::width/height fill
614+ attribtue::alignment
615+ attribute::spacing
616+ attribute::fontsize/family/lineheight
617+ <el-wrapper>
618+ attribute::nearby(placeholder)
619+ attribute::width/height fill
620+ inFront ->
621+ placeholder
622+ attribute::padding
623+
624+
625+ <input>
626+ textarea ->
627+ special height for height-content
628+ attribtue::padding
629+ attribute::lineHeight
630+ attributes
631+ <label>
632+
633+-}
859textHelper : TextInput -> List (Attribute msg) -> Text msg -> Element msg
634textHelper : TextInput -> List (Attribute msg) -> Text msg -> Element msg
860textHelper textInput attrs textOptions =
635textHelper textInput attrs textOptions =
861 let
636 let
862− withDefaults =
637+ attributes =
863− defaultTextBoxStyle ++ attrs
638+ Element.width Element.fill :: (defaultTextBoxStyle ++ attrs)
639+
640+ behavior =
641+ [ Internal.Attr (Html.Events.onInput textOptions.onChange) ]
864
642
865− redistributed =
643+ noNearbys =
866− redistribute (textInput.type_ == TextArea)
644+ List.filter (not << forNearby) attributes
867− (isStacked textOptions.label)
868− withDefaults
869
645
870− onlySpacing attr =
646+ forNearby attr =
871 case attr of
647 case attr of
872− Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
648+ Internal.Nearby _ _ ->
873 True
649 True
874
650
875 _ ->
651 _ ->
876 False
652 False
877
653
878− getPadding attr =
654+ ( inputNode, inputAttrs, inputChildren ) =
879− case attr of
880− Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
881− -- The - 3 is here to prevent accidental triggering of scrollbars
882− -- when things are off by a pixel or two.
883− -- (or at least when the browser *thinks* it's off by a pixel or two)
884− Just
885− { top = max 0 (floor (t - 3))
886− , right = max 0 (floor (r - 3))
887− , bottom = max 0 (floor (b - 3))
888− , left = max 0 (floor (l - 3))
889− }
890−
891− _ ->
892− Nothing
893−
894− heightConstrained =
895 case textInput.type_ of
655 case textInput.type_ of
896 TextInputNode inputType ->
656 TextInputNode inputType ->
897− False
657+ ( "input"
898−
658+ , [ value textOptions.text
899− TextArea ->
659+ , Internal.Attr (Html.Attributes.type_ inputType)
900− withDefaults
660+ , spellcheck textInput.spellchecked
901− |> List.filterMap getHeight
661+ , Internal.htmlClass classes.inputText
902− |> List.reverse
903− |> List.head
904− |> Maybe.map isConstrained
905− |> Maybe.withDefault False
906−
907− parentPadding =
908− withDefaults
909− |> List.filterMap getPadding
910− |> List.reverse
911− |> List.head
912− |> Maybe.withDefault
913− { top = 0
914− , right = 0
915− , bottom = 0
916− , left = 0
917− }
918−
919− inputElement =
920− Internal.element
921− Internal.asEl
922− (case textInput.type_ of
662+ , case textInput.autofill of
923− TextInputNode inputType ->
663+ Nothing ->
924− Internal.NodeName "input"
664+ Internal.NoAttribute
925
665
926− TextArea ->
666+ Just fill ->
927− Internal.NodeName "textarea"
667+ autofill fill
928− )
668+ ]
929− ((case textInput.type_ of
669+ ++ noNearbys
930− TextInputNode inputType ->
670+ , []
931− -- Note: Due to a weird edgecase in...Edge...
671+ )
932− -- `type` needs to come _before_ `value`
933− -- More reading: https://github.com/mdgriffith/elm-ui/pull/94/commits/4f493a27001ccc3cf1f2baa82e092c35d3811876
934− [ Internal.Attr (Html.Attributes.type_ inputType)
935− , Internal.htmlClass classes.inputText
936− ]
937
672
938− TextArea ->
673+ TextArea ->
939− [ Element.clip
674+ let
940− , Element.height Element.fill
675+ { maybePadding, heightContent, maybeSpacing, adjustedAttributes } =
941− , Internal.htmlClass classes.inputMultiline
676+ attributes
942− , calcMoveToCompensateForPadding withDefaults
677+ |> List.foldr
943−
678+ (\attr found ->
944− -- The only reason we do this padding trick is so that when the user clicks in the padding,
679+ case attr of
945− -- that the cursor will reset correctly.
680+ Internal.Describe _ ->
946− -- This could probably be combined with the above `calcMoveToCompensateForPadding`
681+ found
947− , Element.paddingEach parentPadding
682+
948− , Internal.Attr (Html.Attributes.style "margin" (renderBox (negateBox parentPadding)))
683+ Internal.Height val ->
949− , Internal.Attr (Html.Attributes.style "box-sizing" "content-box")
684+ case found.heightContent of
950− ]
685+ Nothing ->
951− )
686+ case val of
952− ++ [ value textOptions.text
687+ Internal.Content ->
953− , Internal.Attr (Html.Events.onInput textOptions.onChange)
688+ { found
954− , hiddenLabelAttribute textOptions.label
689+ | heightContent = Just val
690+ , adjustedAttributes = attr :: found.adjustedAttributes
691+ }
692+
693+ _ ->
694+ { found | heightContent = Just val }
695+
696+ Just i ->
697+ found
698+
699+ Internal.StyleClass _ (Internal.PaddingStyle _ t r b l) ->
700+ case found.maybePadding of
701+ Nothing ->
702+ { found
703+ | maybePadding = Just (Padding t r b l)
704+ , adjustedAttributes = found.adjustedAttributes
705+ }
706+
707+ _ ->
708+ found
709+
710+ Internal.StyleClass _ (Internal.SpacingStyle _ x y) ->
711+ case found.maybeSpacing of
712+ Nothing ->
713+ { found
714+ | maybeSpacing = Just y
715+ , adjustedAttributes = attr :: found.adjustedAttributes
716+ }
717+
718+ _ ->
719+ found
720+
721+ _ ->
722+ { found | adjustedAttributes = attr :: found.adjustedAttributes }
723+ )
724+ { maybePadding = Nothing
725+ , heightContent = Nothing
726+ , maybeSpacing = Nothing
727+ , adjustedAttributes = []
728+ }
729+
730+ -- NOTE: This is where default text spacing is set
731+ spacing =
732+ Maybe.withDefault 5 maybeSpacing
733+ in
734+ ( "textarea"
955− , spellcheck textInput.spellchecked
735+ , [ spellcheck textInput.spellchecked
736+ , Internal.htmlClass classes.inputMultiline
956− , Maybe.map autofill textInput.autofill
737+ , Maybe.map autofill textInput.autofill
957 |> Maybe.withDefault Internal.NoAttribute
738 |> Maybe.withDefault Internal.NoAttribute
958− ]
739+ , case maybePadding of
959− ++ redistributed.input
740+ Nothing ->
960− )
961− (Internal.Unkeyed [])
741+ Internal.NoAttribute
962
742
963− wrappedInput =
743+ Just (Padding t r b l) ->
964− case textInput.type_ of
744+ Element.paddingEach
965− TextArea ->
745+ { top = max 0 (t - (spacing // 2))
966− -- textarea with height-content means that
746+ , bottom = max 0 (b - (spacing // 2))
967− -- the input element is rendered `inFront` with a transparent background
747+ , left = l
968− -- Then the input text is rendered as the space filling element.
748+ , right = r
969− Internal.element
749+ }
970− Internal.asEl
750+ , case heightContent of
971− Internal.div
751+ Nothing ->
972− ((if heightConstrained then
973− (::) Element.scrollbarY
974−
975− else
976− identity
977− )
978− [ Element.width Element.fill
979− , if List.any hasFocusStyle withDefaults then
980 Internal.NoAttribute
752 Internal.NoAttribute
981
753
982− else
754+ Just Internal.Content ->
983− Internal.htmlClass classes.focusedWithin
755+ let
984− , Internal.htmlClass classes.inputMultilineWrapper
756+ newlineCount =
985− ]
757+ String.lines textOptions.text
986− ++ redistributed.parent
758+ |> List.length
987− )
759+ |> (\x ->
988− (Internal.Unkeyed
989− [ Internal.element
990− Internal.asParagraph
991− Internal.div
992− (Element.width Element.fill
993− :: Element.height Element.fill
994− :: Element.inFront inputElement
995− :: Internal.htmlClass classes.inputMultilineParent
996− :: redistributed.wrapper
997− )
998− (Internal.Unkeyed
999− (if textOptions.text == "" then
760+ if x < 1 then
1000− case textOptions.placeholder of
761+ 1
762+ else
763+ x
764+ )
765+
766+ heightValue count =
767+ case maybePadding of
1001 Nothing ->
768 Nothing ->
1002− -- Without this, firefox will make the text area lose focus
769+ "calc(" ++ String.fromInt count ++ "em + " ++ String.fromInt ((count - 1) * spacing) ++ "px) !important"
1003− -- if the input is empty and you mash the keyboard
770+
1004− [ Element.text "\u{00A0}"
771+ Just (Padding t r b l) ->
1005− ]
772+ "calc(" ++ String.fromInt count ++ "em + " ++ String.fromInt ((t + b) + ((count - 1) * spacing)) ++ "px) !important"
1006−
773+ in
1007− Just place ->
774+ Internal.StyleClass Flag.height
1008− [ renderPlaceholder place
775+ (Internal.Single ("textarea-height-" ++ String.fromInt newlineCount)
1009− []
776+ "height"
1010− (textOptions.text == "")
777+ (heightValue newlineCount)
1011− ]
1012−
1013− else
1014− [ Internal.unstyled
1015− (Html.span [ Html.Attributes.class classes.inputMultilineFiller ]
1016− -- We append a non-breaking space to the end of the content so that newlines don't get chomped.
1017− [ Html.text (textOptions.text ++ "\u{00A0}")
1018− ]
1019− )
1020− ]
1021 )
778 )
1022− )
1023− ]
1024− )
1025−
1026− TextInputNode inputType ->
1027− Internal.element
1028− Internal.asEl
1029− Internal.div
1030− (Element.width Element.fill
1031− :: (if List.any hasFocusStyle withDefaults then
1032− Internal.NoAttribute
1033−
1034− else
1035− Internal.htmlClass classes.focusedWithin
1036− )
1037− :: List.concat
1038− [ redistributed.parent
1039− , case textOptions.placeholder of
1040− Nothing ->
1041− []
1042−
1043− Just place ->
1044− [ Element.behindContent
1045− (renderPlaceholder place redistributed.cover (textOptions.text == ""))
1046− ]
1047− ]
1048− )
1049− (Internal.Unkeyed [ inputElement ])
1050− in
1051− applyLabel
1052− (Internal.Class Flag.cursor classes.cursorText
1053− :: (if isHiddenLabel textOptions.label then
1054− Internal.NoAttribute
1055−
1056− else
1057− Element.spacing
1058− 5
1059− )
1060− :: Region.announce
1061− :: redistributed.fullParent
1062− )
1063− textOptions.label
1064− wrappedInput
1065
779
780+ Just x ->
781+ Internal.Height x
782+ ]
783+ ++ adjustedAttributes
784+ , [ Internal.unstyled (Html.text textOptions.text) ]
785+ )
1066
786
1067−getHeight attr =
787+ attributesFromChild =
788+ Internal.get attributes <|
789+ \attr ->
1068− case attr of
790+ case attr of
1069− Internal.Height h ->
791+ Internal.Width (Internal.Fill _) ->
1070− Just h
792+ True
1071
793
1072− _ ->
794+ Internal.Height (Internal.Fill _) ->
1073− Nothing
795+ True
1074
796
797+ Internal.AlignX _ ->
798+ True
1075
799
1076−negateBox box =
800+ Internal.AlignY _ ->
1077− { top = negate box.top
801+ True
1078− , right = negate box.right
1079− , bottom = negate box.bottom
1080− , left = negate box.left
1081− }
1082
802
803+ Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
804+ True
1083
805
1084−renderBox { top, right, bottom, left } =
806+ Internal.StyleClass _ (Internal.FontSize _) ->
1085− String.fromInt top
807+ True
1086− ++ "px "
1087− ++ String.fromInt right
1088− ++ "px "
1089− ++ String.fromInt bottom
1090− ++ "px "
1091− ++ String.fromInt left
1092− ++ "px"
1093
808
809+ Internal.StyleClass _ (Internal.FontFamily _ _) ->
810+ True
1094
811
1095−renderPlaceholder (Placeholder placeholderAttrs placeholderEl) forPlaceholder on =
812+ _ ->
1096− Element.el
813+ False
1097− (forPlaceholder
1098− ++ [ Font.color charcoal
1099− , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
1100− , Element.clip
1101− , Border.color (Element.rgba 0 0 0 0)
1102− , Background.color (Element.rgba 0 0 0 0)
1103− , Element.height Element.fill
1104− , Element.width Element.fill
1105− , Element.alpha
1106− (if on then
1107− 1
1108
814
1109− else
815+ nearbys =
1110− 0
816+ Internal.get attributes <|
1111− )
817+ \attr ->
1112− ]
818+ case attr of
1113− ++ placeholderAttrs
819+ Internal.Nearby _ _ ->
1114− )
820+ True
1115− placeholderEl
1116
821
822+ _ ->
823+ False
1117
824
1118−{-| Because textareas are now shadowed, where they're rendered twice,
825+ inputPadding =
1119−we to move the literal text area up because spacing is based on line height.
826+ Internal.get attributes <|
1120−-}
827+ \attr ->
1121−calcMoveToCompensateForPadding : List (Attribute msg) -> Attribute msg
1122−calcMoveToCompensateForPadding attrs =
1123− let
1124− gatherSpacing attr found =
1125− case attr of
1126− Internal.StyleClass _ (Internal.SpacingStyle _ x y) ->
1127− case found of
828+ case attr of
1128− Nothing ->
829+ Internal.StyleClass _ (Internal.PaddingStyle _ _ _ _ _) ->
1129− Just y
830+ True
1130
831
1131 _ ->
832 _ ->
1132− found
833+ False
1133
834
1134− _ ->
835+ inputElement =
1135− found
836+ Internal.element
837+ Internal.asEl
838+ Internal.div
839+ (Element.width Element.fill
840+ :: List.concat
841+ [ nearbys
842+ , case textOptions.placeholder of
843+ Nothing ->
844+ []
845+
846+ Just (Placeholder placeholderAttrs placeholderEl) ->
847+ [ Element.inFront
848+ (Element.el
849+ (defaultTextPadding
850+ :: noNearbys
851+ ++ [ Font.color charcoal
852+ , Internal.htmlClass (classes.noTextSelection ++ " " ++ classes.passPointerEvents)
853+ , Border.color (Element.rgba 0 0 0 0)
854+ , Background.color (Element.rgba 0 0 0 0)
855+ , Element.height Element.fill
856+ , Element.width Element.fill
857+ , Element.alpha
858+ (if textOptions.text == "" then
859+ 1
860+ else
861+ 0
862+ )
863+ ]
864+ ++ placeholderAttrs
865+ )
866+ placeholderEl
867+ )
868+ ]
869+ ]
870+ )
871+ (Internal.Unkeyed
872+ [ Internal.element
873+ Internal.asEl
874+ (Internal.NodeName inputNode)
875+ (List.concat
876+ [ [ focusDefault attrs
877+ ]
878+ , inputAttrs
879+ , behavior
880+ ]
881+ )
882+ (Internal.Unkeyed inputChildren)
883+ ]
884+ )
1136 in
885 in
1137− case List.foldr gatherSpacing Nothing attrs of
886+ applyLabel
1138− Nothing ->
887+ (Internal.Class Flag.cursor classes.cursorText
1139− Internal.NoAttribute
888+ :: Element.spacing 5
1140−
889+ :: Region.announce
1141− Just vSpace ->
890+ :: attributesFromChild
1142− Element.moveUp (toFloat (floor (toFloat vSpace / 2)))
891+ )
1143−
892+ textOptions.label
1144−
893+ inputElement
1145−{-| Given the list of attributes provided to `Input.multiline` or `Input.text`,
1146−
1147−redistribute them to the parent, the input, or the cover.
1148−
1149− - fullParent -> Wrapper around label and input
1150− - parent -> parent of wrapper
1151− - wrapper -> the element that is here to take up space.
1152− - cover -> things like placeholders or text areas which are layered on top of input.
1153− - input -> actual input element
1154−
1155−-}
1156−redistribute :
1157− Bool
1158− -> Bool
1159− -> List (Attribute msg)
1160− ->
1161− { fullParent : List (Attribute msg)
1162− , parent : List (Attribute msg)
1163− , wrapper : List (Attribute msg)
1164− , input : List (Attribute msg)
1165− , cover : List (Attribute msg)
1166− }
1167−redistribute isMultiline stacked attrs =
1168− List.foldl (redistributeOver isMultiline stacked)
1169− { fullParent = []
1170− , parent = []
1171− , input = []
1172− , cover = []
1173− , wrapper = []
1174− }
1175− attrs
1176− |> (\redist ->
1177− { parent = List.reverse redist.parent
1178− , fullParent = List.reverse redist.fullParent
1179− , wrapper = List.reverse redist.wrapper
1180− , input = List.reverse redist.input
1181− , cover = List.reverse redist.cover
1182− }
1183− )
1184−
1185−
1186−isFill len =
1187− case len of
1188− Internal.Fill _ ->
1189− True
1190−
1191− Internal.Content ->
1192− False
1193−
1194− Internal.Px _ ->
1195− False
1196−
1197− Internal.Min _ l ->
1198− isFill l
1199−
1200− Internal.Max _ l ->
1201− isFill l
1202−
1203−
1204−isShrink len =
1205− case len of
1206− Internal.Content ->
1207− True
1208−
1209− Internal.Px _ ->
1210− False
1211−
1212− Internal.Fill _ ->
1213− False
1214−
1215− Internal.Min _ l ->
1216− isShrink l
1217−
1218− Internal.Max _ l ->
1219− isShrink l
1220−
1221−
1222−isConstrained len =
1223− case len of
1224− Internal.Content ->
1225− False
1226−
1227− Internal.Px _ ->
1228− True
1229−
1230− Internal.Fill _ ->
1231− True
1232−
1233− Internal.Min _ l ->
1234− isConstrained l
1235−
1236− Internal.Max _ l ->
1237− True
1238−
1239−
1240−isPixel len =
1241− case len of
1242− Internal.Content ->
1243− False
1244−
1245− Internal.Px _ ->
1246− True
1247−
1248− Internal.Fill _ ->
1249− False
1250−
1251− Internal.Min _ l ->
1252− isPixel l
1253−
1254− Internal.Max _ l ->
1255− isPixel l
1256−
1257−
1258−{-| isStacked means that the label is above or below
1259−-}
1260−redistributeOver isMultiline stacked attr els =
1261− case attr of
1262− Internal.Nearby _ _ ->
1263− { els | parent = attr :: els.parent }
1264−
1265− Internal.Width width ->
1266− if isFill width then
1267− { els
1268− | fullParent = attr :: els.fullParent
1269− , parent = attr :: els.parent
1270− , input = attr :: els.input
1271− }
1272−
1273− else if stacked then
1274− { els
1275− | fullParent = attr :: els.fullParent
1276− }
1277−
1278− else
1279− { els
1280− | parent = attr :: els.parent
1281− }
1282−
1283− Internal.Height height ->
1284− if not stacked then
1285− { els
1286− | fullParent = attr :: els.fullParent
1287− , parent = attr :: els.parent
1288− }
1289−
1290− else if isFill height then
1291− { els
1292− | fullParent = attr :: els.fullParent
1293− , parent = attr :: els.parent
1294− }
1295−
1296− else if isPixel height then
1297− { els | parent = attr :: els.parent }
1298−
1299− else
1300− { els
1301− | parent = attr :: els.parent
1302− }
1303−
1304− Internal.AlignX _ ->
1305− { els | fullParent = attr :: els.fullParent }
1306−
1307− Internal.AlignY _ ->
1308− { els | fullParent = attr :: els.fullParent }
1309−
1310− Internal.StyleClass _ (Internal.SpacingStyle _ _ _) ->
1311− { els
1312− | fullParent = attr :: els.fullParent
1313− , parent = attr :: els.parent
1314− , input = attr :: els.input
1315− , wrapper = attr :: els.wrapper
1316− }
1317−
1318− Internal.StyleClass cls (Internal.PaddingStyle pad t r b l) ->
1319− if isMultiline then
1320− { els
1321− | parent = attr :: els.parent
1322− , cover = attr :: els.cover
1323− }
1324−
1325− else
1326− let
1327− newHeight =
1328− Element.htmlAttribute
1329− (Html.Attributes.style
1330− "height"
1331− ("calc(1.0em + " ++ String.fromFloat (2 * min t b) ++ "px)")
1332− )
1333−
1334− newLineHeight =
1335− Element.htmlAttribute
1336− (Html.Attributes.style
1337− "line-height"
1338− ("calc(1.0em + " ++ String.fromFloat (2 * min t b) ++ "px)")
1339− )
1340−
1341− newTop =
1342− t - min t b
1343−
1344− newBottom =
1345− b - min t b
1346−
1347− reducedVerticalPadding =
1348− Internal.StyleClass Flag.padding
1349− (Internal.PaddingStyle
1350− (Internal.paddingNameFloat
1351− newTop
1352− r
1353− newBottom
1354− l
1355− )
1356− newTop
1357− r
1358− newBottom
1359− l
1360− )
1361− in
1362− { els
1363− | parent = reducedVerticalPadding :: els.parent
1364− , input = newHeight :: newLineHeight :: els.input
1365− , cover = attr :: els.cover
1366− }
1367−
1368− Internal.StyleClass _ (Internal.BorderWidth _ _ _ _ _) ->
1369− { els
1370− | parent = attr :: els.parent
1371− , cover = attr :: els.cover
1372− }
1373−
1374− Internal.StyleClass _ (Internal.Transform _) ->
1375− { els
1376− | parent = attr :: els.parent
1377− , cover = attr :: els.cover
1378− }
1379−
1380− Internal.StyleClass _ (Internal.FontSize _) ->
1381− { els | fullParent = attr :: els.fullParent }
1382−
1383− Internal.StyleClass _ (Internal.FontFamily _ _) ->
1384− { els | fullParent = attr :: els.fullParent }
1385−
1386− Internal.StyleClass flag cls ->
1387− { els | parent = attr :: els.parent }
1388−
1389− Internal.NoAttribute ->
1390− els
1391−
1392− Internal.Attr a ->
1393− { els | input = attr :: els.input }
1394−
1395− Internal.Describe _ ->
1396− { els | input = attr :: els.input }
1397−
1398− Internal.Class _ _ ->
1399− { els | parent = attr :: els.parent }
1400−
1401− Internal.TransformComponent _ _ ->
1402− { els | input = attr :: els.input }
1403
894
1404
895
1405{-| -}
896{-| -}
@@ -1420,8 +911,7 @@ text =
1420 }
911 }
1421
912
1422
913
1423−{-| If spell checking is available, this input will be spellchecked.
1424−-}
914+{-| -}
1425spellChecked :
915spellChecked :
1426 List (Attribute msg)
916 List (Attribute msg)
1427 ->
917 ->
@@ -1461,7 +951,7 @@ search =
1461
951
1462It's `newPassword` instead of just `password` because it gives the browser a hint on what type of password input it is.
952It's `newPassword` instead of just `password` because it gives the browser a hint on what type of password input it is.
1463
953
1464−A password takes all the arguments a normal `Input.text` would, and also **show**, which will remove the password mask (e.g. `****` vs `pass1234`)
954+A password takes all the arguments a normal `Input.text` would, and also `show`, which will remove the password mask (e.g. `****` vs `pass1234`)
1465
955
1466-}
956-}
1467newPassword :
957newPassword :
@@ -1480,7 +970,6 @@ newPassword attrs pass =
1480 TextInputNode <|
970 TextInputNode <|
1481 if pass.show then
971 if pass.show then
1482 "text"
972 "text"
1483−
1484 else
973 else
1485 "password"
974 "password"
1486 , spellchecked = False
975 , spellchecked = False
@@ -1511,7 +1000,6 @@ currentPassword attrs pass =
1511 TextInputNode <|
1000 TextInputNode <|
1512 if pass.show then
1001 if pass.show then
1513 "text"
1002 "text"
1514−
1515 else
1003 else
1516 "password"
1004 "password"
1517 , spellchecked = False
1005 , spellchecked = False
@@ -1561,13 +1049,7 @@ email =
1561 }
1049 }
1562
1050
1563
1051
1564−{-| A multiline text input.
1565−
1566−By default it will have a minimum height of one line and resize based on it's contents.
1567−
1568−Use `Element.spacing` to change its line-height.
1569−
1570−-}
1052+{-| -}
1571multiline :
1053multiline :
1572 List (Attribute msg)
1054 List (Attribute msg)
1573 ->
1055 ->
@@ -1593,27 +1075,9 @@ multiline attrs multi =
1593 }
1075 }
1594
1076
1595
1077
1596−isHiddenLabel label =
1597− case label of
1598− HiddenLabel _ ->
1599− True
1600−
1601− _ ->
1602− False
1603−
1604−
1605applyLabel : List (Attribute msg) -> Label msg -> Element msg -> Element msg
1078applyLabel : List (Attribute msg) -> Label msg -> Element msg -> Element msg
1606applyLabel attrs label input =
1079applyLabel attrs label input =
1607 case label of
1080 case label of
1608− HiddenLabel labelText ->
1609− -- NOTE: This means that the label is applied outside of this function!
1610− -- It would be nice to unify this logic, but it's a little tricky
1611− Internal.element
1612− Internal.asColumn
1613− (Internal.NodeName "label")
1614− attrs
1615− (Internal.Unkeyed [ input ])
1616−
1617 Label position labelAttrs labelChild ->
1081 Label position labelAttrs labelChild ->
1618 let
1082 let
1619 labelElement =
1083 labelElement =
@@ -1624,36 +1088,51 @@ applyLabel attrs label input =
1624 (Internal.Unkeyed [ labelChild ])
1088 (Internal.Unkeyed [ labelChild ])
1625 in
1089 in
1626 case position of
1090 case position of
1627− Above ->
1091+ Internal.Above ->
1628 Internal.element
1092 Internal.element
1629 Internal.asColumn
1093 Internal.asColumn
1630 (Internal.NodeName "label")
1094 (Internal.NodeName "label")
1631− (Internal.htmlClass classes.inputLabel :: attrs)
1095+ attrs
1632 (Internal.Unkeyed [ labelElement, input ])
1096 (Internal.Unkeyed [ labelElement, input ])
1633
1097
1634− Below ->
1098+ Internal.Below ->
1635 Internal.element
1099 Internal.element
1636 Internal.asColumn
1100 Internal.asColumn
1637 (Internal.NodeName "label")
1101 (Internal.NodeName "label")
1638− (Internal.htmlClass classes.inputLabel :: attrs)
1102+ attrs
1639 (Internal.Unkeyed [ input, labelElement ])
1103 (Internal.Unkeyed [ input, labelElement ])
1640
1104
1641− OnRight ->
1105+ Internal.OnRight ->
1642 Internal.element
1106 Internal.element
1643 Internal.asRow
1107 Internal.asRow
1644 (Internal.NodeName "label")
1108 (Internal.NodeName "label")
1645− (Internal.htmlClass classes.inputLabel :: attrs)
1109+ attrs
1646 (Internal.Unkeyed [ input, labelElement ])
1110 (Internal.Unkeyed [ input, labelElement ])
1647
1111
1648− OnLeft ->
1112+ Internal.OnLeft ->
1649 Internal.element
1113 Internal.element
1650 Internal.asRow
1114 Internal.asRow
1651 (Internal.NodeName "label")
1115 (Internal.NodeName "label")
1652− (Internal.htmlClass classes.inputLabel :: attrs)
1116+ attrs
1653 (Internal.Unkeyed [ labelElement, input ])
1117 (Internal.Unkeyed [ labelElement, input ])
1654
1118
1119+ Internal.InFront ->
1120+ Internal.element
1121+ Internal.asRow
1122+ (Internal.NodeName "label")
1123+ attrs
1124+ (Internal.Unkeyed [ labelElement, input ])
1655
1125
1126+ Internal.Behind ->
1127+ Internal.element
1128+ Internal.asRow
1129+ (Internal.NodeName "label")
1130+ attrs
1131+ (Internal.Unkeyed [ labelElement, input ])
1132+
1133+
1134+{-| Add choices to your radio and select menus.
1656−{-| -}
1135+-}
1657type Option value msg
1136type Option value msg
1658 = Option value (OptionState -> Element msg)
1137 = Option value (OptionState -> Element msg)
1659
1138
@@ -1665,21 +1144,45 @@ type OptionState
1665 | Selected
1144 | Selected
1666
1145
1667
1146
1668−{-| Add a choice to your radio element. This will be rendered with the default radio icon.
1669−-}
1147+{-| -}
1670option : value -> Element msg -> Option value msg
1148option : value -> Element msg -> Option value msg
1671option val txt =
1149option val txt =
1672 Option val (defaultRadioOption txt)
1150 Option val (defaultRadioOption txt)
1673
1151
1674
1152
1675−{-| Customize exactly what your radio option should look like in different states.
1676−-}
1153+{-| -}
1677optionWith : value -> (OptionState -> Element msg) -> Option value msg
1154optionWith : value -> (OptionState -> Element msg) -> Option value msg
1678optionWith val view =
1155optionWith val view =
1679 Option val view
1156 Option val view
1680
1157
1681
1158
1682−{-| -}
1159+{-|
1160+
1161+ Input.radio
1162+ [ padding 10
1163+ , spacing 20
1164+ ]
1165+ { onChange = ChooseLunch
1166+ , selected = Just model.lunch
1167+ , label = Input.labelAbove (text "Lunch")
1168+ , options =
1169+ [ Input.styledChoice Burrito <|
1170+ \selected ->
1171+ Element.row
1172+ [ spacing 5 ]
1173+ [ el None [] <|
1174+ if selected then
1175+ text ":D"
1176+ else
1177+ text ":("
1178+ , text "burrito"
1179+ ]
1180+ , Input.option Taco (text "Taco!")
1181+ , Input.option Gyro (text "Gyro")
1182+ ]
1183+ }
1184+
1185+-}
1683radio :
1186radio :
1684 List (Attribute msg)
1187 List (Attribute msg)
1685 ->
1188 ->
@@ -1790,7 +1293,6 @@ radioHelper orientation attrs input =
1790 status =
1293 status =
1791 if Just val == input.selected then
1294 if Just val == input.selected then
1792 Selected
1295 Selected
1793−
1794 else
1296 else
1795 Idle
1297 Idle
1796 in
1298 in
@@ -1821,11 +1323,11 @@ radioHelper orientation attrs input =
1821 optionArea =
1323 optionArea =
1822 case orientation of
1324 case orientation of
1823 Row ->
1325 Row ->
1824− row (hiddenLabelAttribute input.label :: attrs)
1326+ row attrs
1825 (List.map renderOption input.options)
1327 (List.map renderOption input.options)
1826
1328
1827 Column ->
1329 Column ->
1828− column (hiddenLabelAttribute input.label :: attrs)
1330+ column attrs
1829 (List.map renderOption input.options)
1331 (List.map renderOption input.options)
1830
1332
1831 prevNext =
1333 prevNext =
@@ -1854,7 +1356,6 @@ radioHelper orientation attrs input =
1854 NotFound ->
1356 NotFound ->
1855 if Just val == input.selected then
1357 if Just val == input.selected then
1856 ( BeforeFound, prev, nxt )
1358 ( BeforeFound, prev, nxt )
1857−
1858 else
1359 else
1859 ( found, val, nxt )
1360 ( found, val, nxt )
1860
1361
@@ -1864,6 +1365,88 @@ radioHelper orientation attrs input =
1864 AfterFound ->
1365 AfterFound ->
1865 ( found, prev, nxt )
1366 ( found, prev, nxt )
1866
1367
1368+ inputVisible =
1369+ List.isEmpty <|
1370+ Internal.get attrs <|
1371+ \attr ->
1372+ case attr of
1373+ Internal.StyleClass _ (Internal.Transparency _ _) ->
1374+ True
1375+
1376+ Internal.Class _ "hidden" ->
1377+ True
1378+
1379+ _ ->
1380+ False
1381+
1382+ labelVisible =
1383+ case input.label of
1384+ Label _ labelAttrs _ ->
1385+ List.isEmpty <|
1386+ Internal.get labelAttrs <|
1387+ \attr ->
1388+ case attr of
1389+ Internal.StyleClass _ (Internal.Transparency _ _) ->
1390+ True
1391+
1392+ Internal.Class _ "hidden" ->
1393+ True
1394+
1395+ _ ->
1396+ False
1397+
1398+ hideIfEverythingisInvisible =
1399+ if not labelVisible && not inputVisible then
1400+ let
1401+ pseudos =
1402+ List.filterMap
1403+ (\attr ->
1404+ case attr of
1405+ Internal.StyleClass _ style ->
1406+ case style of
1407+ Internal.PseudoSelector pseudo styles ->
1408+ let
1409+ transparent =
1410+ List.filter forTransparency styles
1411+
1412+ forTransparency psuedoStyle =
1413+ case psuedoStyle of
1414+ Internal.Transparency _ _ ->
1415+ True
1416+
1417+ _ ->
1418+ False
1419+
1420+ flag =
1421+ case pseudo of
1422+ Internal.Hover ->
1423+ Flag.hover
1424+
1425+ Internal.Focus ->
1426+ Flag.focus
1427+
1428+ Internal.Active ->
1429+ Flag.active
1430+ in
1431+ case transparent of
1432+ [] ->
1433+ Nothing
1434+
1435+ _ ->
1436+ Just <| Internal.StyleClass flag <| Internal.PseudoSelector pseudo transparent
1437+
1438+ _ ->
1439+ Nothing
1440+
1441+ _ ->
1442+ Nothing
1443+ )
1444+ attrs
1445+ in
1446+ Internal.StyleClass Flag.transparency (Internal.Transparency "transparent" 1.0) :: pseudos
1447+ else
1448+ []
1449+
1867 events =
1450 events =
1868 Internal.get
1451 Internal.get
1869 attrs
1452 attrs
@@ -1901,16 +1484,12 @@ radioHelper orientation attrs input =
1901 \code ->
1484 \code ->
1902 if code == leftArrow then
1485 if code == leftArrow then
1903 Just (input.onChange prev)
1486 Just (input.onChange prev)
1904−
1905 else if code == upArrow then
1487 else if code == upArrow then
1906 Just (input.onChange prev)
1488 Just (input.onChange prev)
1907−
1908 else if code == rightArrow then
1489 else if code == rightArrow then
1909 Just (input.onChange next)
1490 Just (input.onChange next)
1910−
1911 else if code == downArrow then
1491 else if code == downArrow then
1912 Just (input.onChange next)
1492 Just (input.onChange next)
1913−
1914 else if code == space then
1493 else if code == space then
1915 case input.selected of
1494 case input.selected of
1916 Nothing ->
1495 Nothing ->
@@ -1918,13 +1497,12 @@ radioHelper orientation attrs input =
1918
1497
1919 _ ->
1498 _ ->
1920 Nothing
1499 Nothing
1921−
1922 else
1500 else
1923 Nothing
1501 Nothing
1924 )
1502 )
1925 ]
1503 ]
1926 ++ events
1504 ++ events
1927− -- ++ hideIfEverythingisInvisible
1505+ ++ hideIfEverythingisInvisible
1928 )
1506 )
1929 input.label
1507 input.label
1930 optionArea
1508 optionArea
@@ -2056,7 +1634,6 @@ onKey desiredCode msg =
2056 decode code =
1634 decode code =
2057 if code == desiredCode then
1635 if code == desiredCode then
2058 Json.succeed msg
1636 Json.succeed msg
2059−
2060 else
1637 else
2061 Json.fail "Not the enter key"
1638 Json.fail "Not the enter key"
2062
1639
@@ -2105,11 +1682,7 @@ onKeyLookup lookup =
2105 Json.field "key" Json.string
1682 Json.field "key" Json.string
2106 |> Json.andThen decode
1683 |> Json.andThen decode
2107 in
1684 in
2108− -- We generally want these attached to the keydown event becaues it allows us to prevent default on things like spacebar scrolling the page.
2109− -- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role
2110− Internal.Attr <|
1685+ Internal.Attr <| Html.Events.on "keyup" isKey
2111− Html.Events.preventDefaultOn "keydown"
2112− (Json.map (\fired -> ( fired, True )) isKey)
2113
1686
2114
1687
2115{-| -}
1688{-| -}
@@ -2124,6 +1697,17 @@ onFocusIn msg =
2124 Internal.Attr <| Html.Events.on "focusin" (Json.succeed msg)
1697 Internal.Attr <| Html.Events.on "focusin" (Json.succeed msg)
2125
1698
2126
1699
1700+type_ : String -> Attribute msg
1701+type_ =
1702+ Internal.Attr << Html.Attributes.type_
1703+
1704+
1705+
1706+-- checked : Bool -> Attribute msg
1707+-- checked =
1708+-- Internal.Attr << Html.Attributes.checked
1709+
1710+
2127selected : Bool -> Attribute msg
1711selected : Bool -> Attribute msg
2128selected =
1712selected =
2129 Internal.Attr << Html.Attributes.selected
1713 Internal.Attr << Html.Attributes.selected
@@ -2164,11 +1748,7 @@ autofill =
2164 Internal.Attr << Html.Attributes.attribute "autocomplete"
1748 Internal.Attr << Html.Attributes.attribute "autocomplete"
2165
1749
2166
1750
2167−{-| Attach this attribute to any `Input` that you would like to be automatically focused when the page loads.
2168−
2169−You should only have a maximum of one per page.
2170−
2171−-}
1751+{-| -}
2172focusedOnLoad : Attribute msg
1752focusedOnLoad : Attribute msg
2173focusedOnLoad =
1753focusedOnLoad =
2174 Internal.Attr <| Html.Attributes.autofocus True
1754 Internal.Attr <| Html.Attributes.autofocus True
@@ -2185,9 +1765,7 @@ defaultTextBoxStyle =
2185 , Border.color darkGrey
1765 , Border.color darkGrey
2186 , Background.color white
1766 , Background.color white
2187 , Border.width 1
1767 , Border.width 1
2188− , Element.spacing 5
1768+ , Element.spacing 3
2189− , Element.width Element.fill
2190− , Element.height Element.shrink
2191 ]
1769 ]
2192
1770
2193
1771
@@ -2196,17 +1774,12 @@ defaultTextPadding =
2196 Element.paddingXY 12 12
1774 Element.paddingXY 12 12
2197
1775
2198
1776
2199−{-| The blue default checked box icon.
2200−
2201−You'll likely want to make your own checkbox at some point that fits your design.
2202−
2203−-}
1777+{-| -}
2204defaultCheckbox : Bool -> Element msg
1778defaultCheckbox : Bool -> Element msg
2205defaultCheckbox checked =
1779defaultCheckbox checked =
2206 Element.el
1780 Element.el
2207 [ Internal.htmlClass "focusable"
1781 [ Internal.htmlClass "focusable"
2208− , Element.width
1782+ , Element.width (Element.px 14)
2209− (Element.px 14)
2210 , Element.height (Element.px 14)
1783 , Element.height (Element.px 14)
2211 , Font.color white
1784 , Font.color white
2212 , Element.centerY
1785 , Element.centerY
@@ -2216,34 +1789,31 @@ defaultCheckbox checked =
2216 , Border.color <|
1789 , Border.color <|
2217 if checked then
1790 if checked then
2218 Element.rgb (59 / 255) (153 / 255) (252 / 255)
1791 Element.rgb (59 / 255) (153 / 255) (252 / 255)
2219−
2220 else
1792 else
2221 Element.rgb (211 / 255) (211 / 255) (211 / 255)
1793 Element.rgb (211 / 255) (211 / 255) (211 / 255)
2222− , Border.shadow
1794+ , Border.shadow <|
2223 { offset = ( 0, 0 )
1795 { offset = ( 0, 0 )
2224 , blur = 1
1796 , blur = 1
2225 , size = 1
1797 , size = 1
2226 , color =
1798 , color =
2227 if checked then
1799 if checked then
2228 Element.rgba (238 / 255) (238 / 255) (238 / 255) 0
1800 Element.rgba (238 / 255) (238 / 255) (238 / 255) 0
2229−
2230 else
1801 else
2231 Element.rgb (238 / 255) (238 / 255) (238 / 255)
1802 Element.rgb (238 / 255) (238 / 255) (238 / 255)
2232 }
1803 }
2233 , Background.color <|
1804 , Background.color <|
2234 if checked then
1805 if checked then
2235 Element.rgb (59 / 255) (153 / 255) (252 / 255)
1806 Element.rgb (59 / 255) (153 / 255) (252 / 255)
2236−
2237 else
1807 else
2238 white
1808 white
2239 , Border.width <|
1809 , Border.width <|
2240 if checked then
1810 if checked then
2241 0
1811 0
2242−
2243 else
1812 else
2244 1
1813 1
2245− , Element.inFront
1814+ ]
1815+ (if checked then
2246− (Element.el
1816+ Element.el
2247 [ Border.color white
1817 [ Border.color white
2248 , Element.height (Element.px 6)
1818 , Element.height (Element.px 6)
2249 , Element.width (Element.px 9)
1819 , Element.width (Element.px 9)
@@ -2251,7 +1821,6 @@ defaultCheckbox checked =
2251 , Element.centerX
1821 , Element.centerX
2252 , Element.centerY
1822 , Element.centerY
2253 , Element.moveUp 1
1823 , Element.moveUp 1
2254− , Element.transparent (not checked)
2255 , Border.widthEach
1824 , Border.widthEach
2256 { top = 0
1825 { top = 0
2257 , left = 2
1826 , left = 2
@@ -2260,6 +1829,6 @@ defaultCheckbox checked =
2260 }
1829 }
2261 ]
1830 ]
2262 Element.none
1831 Element.none
2263− )
1832+ else
2264− ]
2265− Element.none
1833+ Element.none
1834+ )
src/Element/Keyed.elm+11−14
@@ -1,4 +1,4 @@
1−module Element.Keyed exposing (el, column, row)
1+module Element.Keyed exposing (column, el, row)
2
2
3{-| Notes from the `Html.Keyed` on how keyed works:
3{-| Notes from the `Html.Keyed` on how keyed works:
4
4
@@ -20,7 +20,7 @@ This means if a key is changed between renders, then the diffing step will be sk
20
20
21-}
21-}
22
22
23−import Element exposing (Attribute, Element, fill, height, shrink, width)
23+import Element exposing (Attribute, Element, fill, height, width)
24import Internal.Model as Internal
24import Internal.Model as Internal
25import Internal.Style exposing (classes)
25import Internal.Style exposing (classes)
26
26
@@ -31,8 +31,8 @@ el attrs child =
31 Internal.element
31 Internal.element
32 Internal.asEl
32 Internal.asEl
33 Internal.div
33 Internal.div
34− (width shrink
34+ (width Element.shrink
35− :: height shrink
35+ :: height Element.shrink
36 :: attrs
36 :: attrs
37 )
37 )
38 (Internal.Keyed [ child ])
38 (Internal.Keyed [ child ])
@@ -44,9 +44,9 @@ row attrs children =
44 Internal.element
44 Internal.element
45 Internal.asRow
45 Internal.asRow
46 Internal.div
46 Internal.div
47− (Internal.htmlClass (classes.contentLeft ++ " " ++ classes.contentCenterY)
47+ (Internal.htmlClass classes.contentLeft
48+ :: Internal.htmlClass classes.contentCenterY
48− :: width shrink
49+ :: width fill
49− :: height shrink
50 :: attrs
50 :: attrs
51 )
51 )
52 (Internal.Keyed children)
52 (Internal.Keyed children)
@@ -58,13 +58,10 @@ column attrs children =
58 Internal.element
58 Internal.element
59 Internal.asColumn
59 Internal.asColumn
60 Internal.div
60 Internal.div
61− (Internal.htmlClass
61+ (Internal.htmlClass classes.contentTop
62− (classes.contentTop
63− ++ " "
64− ++ classes.contentLeft
62+ :: Internal.htmlClass classes.contentLeft
65− )
66− :: height shrink
63+ :: height fill
67− :: width shrink
64+ :: width fill
68 :: attrs
65 :: attrs
69 )
66 )
70 (Internal.Keyed children)
67 (Internal.Keyed children)
src/Element/Region.elm+14−14
@@ -1,12 +1,16 @@
1−module Element.Region exposing
1+module Element.Region
2+ exposing
3+ ( announce
4+ , announceUrgently
5+ , aside
6+ , description
7+ , footer
8+ , heading
2− ( mainContent, navigation, heading, aside, footer
9+ , mainContent
3− , description
10+ , navigation
4− , announce, announceUrgently
5− )
11+ )
6−
12+
7−{-| This module is meant to make accessibility easy!
8−
9−These are sign posts that accessibility software like screen readers can use to navigate your app.
13+{-| This module is meant to make accessibility easy! They're sign posts that accessibility software like screen readers can use to navigate your app.
10
14
11All you have to do is add them to elements in your app where you see fit.
15All you have to do is add them to elements in your app where you see fit.
12
16
@@ -101,11 +105,7 @@ announce =
101 Internal.Describe LivePolite
105 Internal.Describe LivePolite
102
106
103
107
104−{-| Adds an `aria-label`, which is used by accessibility software to identity otherwise unlabeled elements.
105−
106−A common use for this would be to label buttons that only have an icon.
107−
108−-}
108+{-| -}
109description : String -> Attribute msg
109description : String -> Attribute msg
110description =
110description =
111 Internal.Describe << Internal.Label
111 Internal.Describe << Internal.Label
src/Internal/Flag.elm+1−66
@@ -1,60 +1,4 @@
1−module Internal.Flag exposing
1+module Internal.Flag exposing (..)
2− ( Field(..)
3− , Flag(..)
4− , active
5− , add
6− , alignBottom
7− , alignRight
8− , behind
9− , bgColor
10− , bgGradient
11− , bgImage
12− , borderColor
13− , borderRound
14− , borderStyle
15− , borderWidth
16− , centerX
17− , centerY
18− , cursor
19− , flag
20− , focus
21− , fontAlignment
22− , fontColor
23− , fontFamily
24− , fontSize
25− , fontVariant
26− , fontWeight
27− , gridPosition
28− , gridTemplate
29− , height
30− , heightBetween
31− , heightContent
32− , heightFill
33− , heightTextAreaContent
34− , hover
35− , letterSpacing
36− , merge
37− , moveX
38− , moveY
39− , none
40− , overflow
41− , padding
42− , present
43− , rotate
44− , scale
45− , shadows
46− , spacing
47− , transparency
48− , txtShadows
49− , value
50− , width
51− , widthBetween
52− , widthContent
53− , widthFill
54− , wordSpacing
55− , xAlign
56− , yAlign
57− )
58
2
59{-| -}
3{-| -}
60
4
@@ -123,7 +67,6 @@ flag i =
123 if i > 31 then
67 if i > 31 then
124 Second
68 Second
125 (Bitwise.shiftLeftBy (i - 32) 1)
69 (Bitwise.shiftLeftBy (i - 32) 1)
126−
127 else
70 else
128 Flag
71 Flag
129 (Bitwise.shiftLeftBy i 1)
72 (Bitwise.shiftLeftBy i 1)
@@ -315,11 +258,3 @@ heightBetween =
315
258
316behind =
259behind =
317 flag 46
260 flag 46
318−
319−
320−heightTextAreaContent =
321− flag 47
322−
323−
324−fontVariant =
325− flag 48
src/Internal/Grid.elm+1−7
@@ -1,4 +1,4 @@
1−module Internal.Grid exposing (Around, Layout(..), PositionedElement, RelativePosition(..), build, createGrid, getWidth, relative)
1+module Internal.Grid exposing (..)
2
2
3{-| Relative positioning within a grid.
3{-| Relative positioning within a grid.
4
4
@@ -80,12 +80,10 @@ createGrid ( spacingX, spacingY ) nearby =
80 [ 1
80 [ 1
81 , if Nothing == nearby.above then
81 , if Nothing == nearby.above then
82 0
82 0
83−
84 else
83 else
85 1
84 1
86 , if Nothing == nearby.below then
85 , if Nothing == nearby.below then
87 0
86 0
88−
89 else
87 else
90 1
88 1
91 ]
89 ]
@@ -95,12 +93,10 @@ createGrid ( spacingX, spacingY ) nearby =
95 [ 1
93 [ 1
96 , if Nothing == nearby.left then
94 , if Nothing == nearby.left then
97 0
95 0
98−
99 else
96 else
100 1
97 1
101 , if Nothing == nearby.right then
98 , if Nothing == nearby.right then
102 0
99 0
103−
104 else
100 else
105 1
101 1
106 ]
102 ]
@@ -111,7 +107,6 @@ createGrid ( spacingX, spacingY ) nearby =
111 , primary = 1
107 , primary = 1
112 , below = 2
108 , below = 2
113 }
109 }
114−
115 else
110 else
116 { above = 1
111 { above = 1
117 , primary = 2
112 , primary = 2
@@ -124,7 +119,6 @@ createGrid ( spacingX, spacingY ) nearby =
124 , primary = 1
119 , primary = 1
125 , right = 2
120 , right = 2
126 }
121 }
127−
128 else
122 else
129 { left = 1
123 { left = 1
130 , primary = 2
124 , primary = 2
src/Internal/Model.elm+666−1369
@@ -1,109 +1,4 @@
1−module Internal.Model exposing
1+module Internal.Model exposing (..)
2− ( Aligned(..)
3− , Angle
4− , Attribute(..)
5− , Axis(..)
6− , Children(..)
7− , Color(..)
8− , Description(..)
9− , Element(..)
10− , EmbedStyle(..)
11− , FocusStyle
12− , Font(..)
13− , Gathered
14− , HAlign(..)
15− , HoverSetting(..)
16− , LayoutContext(..)
17− , Length(..)
18− , Location(..)
19− , NearbyChildren(..)
20− , NodeName(..)
21− , Option(..)
22− , OptionRecord
23− , Padding(..)
24− , Property(..)
25− , PseudoClass(..)
26− , RenderMode(..)
27− , Shadow
28− , Spacing(..)
29− , Style(..)
30− , TransformComponent(..)
31− , Transformation(..)
32− , VAlign(..)
33− , Variant(..)
34− , XYZ
35− , addNodeName
36− , addWhen
37− , alignXName
38− , alignYName
39− , asColumn
40− , asEl
41− , asGrid
42− , asParagraph
43− , asRow
44− , asTextColumn
45− , boxShadowClass
46− , columnClass
47− , composeTransformation
48− , contextClasses
49− , createElement
50− , defaultOptions
51− , div
52− , element
53− , embedKeyed
54− , embedWith
55− , extractSpacingAndPadding
56− , filter
57− , finalizeNode
58− , floatClass
59− , focusDefaultStyle
60− , formatBoxShadow
61− , formatColor
62− , formatColorClass
63− , formatDropShadow
64− , formatTextShadow
65− , gatherAttrRecursive
66− , get
67− , getHeight
68− , getSpacing
69− , getStyleName
70− , getWidth
71− , gridClass
72− , htmlClass
73− , isContent
74− , lengthClassName
75− , map
76− , mapAttr
77− , mapAttrFromStyle
78− , noStyleSheet
79− , onlyStyles
80− , optionsToRecord
81− , paddingName
82− , paddingNameFloat
83− , pageClass
84− , paragraphClass
85− , reduceRecursive
86− , reduceStyles
87− , reduceStylesRecursive
88− , removeNever
89− , renderFontClassName
90− , renderHeight
91− , renderRoot
92− , renderVariant
93− , renderWidth
94− , rootStyle
95− , rowClass
96− , singleClass
97− , spacingName
98− , tag
99− , textShadowClass
100− , toHtml
101− , toStyleSheet
102− , transformClass
103− , unstyled
104− , unwrapDecorations
105− , variantName
106− )
107
2
108{-| -}
3{-| -}
109
4
@@ -112,7 +7,7 @@ import Html.Attributes
112import Html.Keyed
7import Html.Keyed
113import Internal.Flag as Flag exposing (Flag)
8import Internal.Flag as Flag exposing (Flag)
114import Internal.Style exposing (classes, dot)
9import Internal.Style exposing (classes, dot)
115−import Json.Encode as Encode
10+import Json.Encode as Json
116import Set exposing (Set)
11import Set exposing (Set)
117import VirtualDom
12import VirtualDom
118
13
@@ -173,8 +68,7 @@ type Style
173 | Single String String String
68 | Single String String String
174 | Colored String String Color
69 | Colored String String Color
175 | SpacingStyle String Int Int
70 | SpacingStyle String Int Int
176− | BorderWidth String Int Int Int Int
177− | PaddingStyle String Float Float Float Float
71+ | PaddingStyle String Int Int Int Int
178 | GridTemplateStyle
72 | GridTemplateStyle
179 { spacing : ( Length, Length )
73 { spacing : ( Length, Length )
180 , columns : List Length
74 , columns : List Length
@@ -205,86 +99,12 @@ type PseudoClass
205 | Active
99 | Active
206
100
207
101
208−{-| -}
209−type alias Adjustment =
210− { capital : Float
211− , lowercase : Float
212− , baseline : Float
213− , descender : Float
214− }
215−
216−
217type Font
102type Font
218 = Serif
103 = Serif
219 | SansSerif
104 | SansSerif
220 | Monospace
105 | Monospace
221 | Typeface String
106 | Typeface String
222 | ImportFont String String
107 | ImportFont String String
223− | FontWith
224− { name : String
225− , adjustment : Maybe Adjustment
226− , variants : List Variant
227− }
228−
229−
230−type Variant
231− = VariantActive String
232− | VariantOff String
233− | VariantIndexed String Int
234−
235−
236−renderVariant var =
237− case var of
238− VariantActive name ->
239− "\"" ++ name ++ "\""
240−
241− VariantOff name ->
242− "\"" ++ name ++ "\" 0"
243−
244− VariantIndexed name index ->
245− "\"" ++ name ++ "\" " ++ String.fromInt index
246−
247−
248−variantName var =
249− case var of
250− VariantActive name ->
251− name
252−
253− VariantOff name ->
254− name ++ "-0"
255−
256− VariantIndexed name index ->
257− name ++ "-" ++ String.fromInt index
258−
259−
260−renderVariants typeface =
261− case typeface of
262− FontWith font ->
263− Just (String.join ", " (List.map renderVariant font.variants))
264−
265− _ ->
266− Nothing
267−
268−
269−isSmallCaps var =
270− case var of
271− VariantActive name ->
272− name == "smcp"
273−
274− VariantOff name ->
275− False
276−
277− VariantIndexed name index ->
278− name == "smcp" && index == 1
279−
280−
281−hasSmallCaps typeface =
282− case typeface of
283− FontWith font ->
284− List.any isSmallCaps font.variants
285−
286− _ ->
287− False
288
108
289
109
290type Property
110type Property
@@ -372,13 +192,6 @@ type NodeName
372 | Embedded String String
192 | Embedded String String
373
193
374
194
375−type NearbyChildren msg
376− = NoNearbyChildren
377− | ChildrenBehind (List (Html.Html msg))
378− | ChildrenInFront (List (Html.Html msg))
379− | ChildrenBehindAndInFront (List (Html.Html msg)) (List (Html.Html msg))
380−
381−
382div =
195div =
383 Generic
196 Generic
384
197
@@ -387,7 +200,7 @@ type alias Gathered msg =
387 { node : NodeName
200 { node : NodeName
388 , attributes : List (VirtualDom.Attribute msg)
201 , attributes : List (VirtualDom.Attribute msg)
389 , styles : List Style
202 , styles : List Style
390− , children : NearbyChildren msg
203+ , children : List (VirtualDom.Node msg)
391 , has : Flag.Field
204 , has : Flag.Field
392 }
205 }
393
206
@@ -455,17 +268,13 @@ finalizeNode has node attributes children embedMode parentContext =
455 Embedded nodeName internal ->
268 Embedded nodeName internal ->
456 VirtualDom.node nodeName
269 VirtualDom.node nodeName
457 attributes
270 attributes
458− [ createNode internal
459− [ Html.Attributes.class
460− (classes.any ++ " " ++ classes.single)
271+ [ createNode internal [ Html.Attributes.class (classes.any ++ " " ++ classes.single) ]
461− ]
462 ]
272 ]
463 in
273 in
464 case parentContext of
274 case parentContext of
465 AsRow ->
275 AsRow ->
466 if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
276 if Flag.present Flag.widthFill has && not (Flag.present Flag.widthBetween has) then
467 html
277 html
468−
469 else if Flag.present Flag.alignRight has then
278 else if Flag.present Flag.alignRight has then
470 Html.u
279 Html.u
471 [ Html.Attributes.class
280 [ Html.Attributes.class
@@ -479,7 +288,6 @@ finalizeNode has node attributes children embedMode parentContext =
479 )
288 )
480 ]
289 ]
481 [ html ]
290 [ html ]
482−
483 else if Flag.present Flag.centerX has then
291 else if Flag.present Flag.centerX has then
484 Html.s
292 Html.s
485 [ Html.Attributes.class
293 [ Html.Attributes.class
@@ -493,14 +301,12 @@ finalizeNode has node attributes children embedMode parentContext =
493 )
301 )
494 ]
302 ]
495 [ html ]
303 [ html ]
496−
497 else
304 else
498 html
305 html
499
306
500 AsColumn ->
307 AsColumn ->
501 if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
308 if Flag.present Flag.heightFill has && not (Flag.present Flag.heightBetween has) then
502 html
309 html
503−
504 else if Flag.present Flag.centerY has then
310 else if Flag.present Flag.centerY has then
505 Html.s
311 Html.s
506 [ Html.Attributes.class
312 [ Html.Attributes.class
@@ -513,7 +319,6 @@ finalizeNode has node attributes children embedMode parentContext =
513 )
319 )
514 ]
320 ]
515 [ html ]
321 [ html ]
516−
517 else if Flag.present Flag.alignBottom has then
322 else if Flag.present Flag.alignBottom has then
518 Html.u
323 Html.u
519 [ Html.Attributes.class
324 [ Html.Attributes.class
@@ -526,7 +331,6 @@ finalizeNode has node attributes children embedMode parentContext =
526 )
331 )
527 ]
332 ]
528 [ html ]
333 [ html ]
529−
530 else
334 else
531 html
335 html
532
336
@@ -535,45 +339,47 @@ finalizeNode has node attributes children embedMode parentContext =
535
339
536
340
537embedWith static opts styles children =
341embedWith static opts styles children =
538− let
539− dynamicStyleSheet =
540− styles
541− |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
542− |> Tuple.second
543− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
544− -- |> sortedReduce
545− |> toStyleSheet opts
546− in
547 if static then
342 if static then
548− staticRoot opts
343+ staticRoot
549− :: dynamicStyleSheet
344+ :: (styles
345+ |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
346+ |> Tuple.second
347+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
348+ -- |> sortedReduce
349+ |> toStyleSheet opts
350+ )
550 :: children
351 :: children
551−
552 else
352 else
553− dynamicStyleSheet
353+ (styles
354+ |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
355+ |> Tuple.second
356+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
357+ -- |> sortedReduce
358+ |> toStyleSheet opts
359+ )
554 :: children
360 :: children
555
361
556
362
557embedKeyed static opts styles children =
363embedKeyed static opts styles children =
558− let
559− dynamicStyleSheet =
560− styles
561− |> List.foldl reduceStyles ( Set.empty, renderFocusStyle opts.focus )
562− |> Tuple.second
563− -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
564− -- |> sortedReduce
565− |> toStyleSheet opts
566− in
567 if static then
364 if static then
568− ( "static-stylesheet", staticRoot opts )
365+ ( "static-stylesheet", staticRoot )
569 :: ( "dynamic-stylesheet"
366 :: ( "dynamic-stylesheet"
570− , dynamicStyleSheet
367+ , styles
368+ |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
369+ |> Tuple.second
370+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
371+ -- |> sortedReduce
372+ |> toStyleSheet opts
571 )
373 )
572 :: children
374 :: children
573−
574 else
375 else
575 ( "dynamic-stylesheet"
376 ( "dynamic-stylesheet"
576− , dynamicStyleSheet
377+ , styles
378+ |> List.foldl reduceStyles ( Set.empty, [ renderFocusStyle opts.focus ] )
379+ |> Tuple.second
380+ -- |> reduceStylesRecursive Set.empty [ ]) --renderFocusStyle opts.focus ]
381+ -- |> sortedReduce
382+ |> toStyleSheet opts
577 )
383 )
578 :: children
384 :: children
579
385
@@ -591,7 +397,6 @@ reduceStylesRecursive cache found styles =
591 in
397 in
592 if Set.member styleName cache then
398 if Set.member styleName cache then
593 reduceStylesRecursive cache found remaining
399 reduceStylesRecursive cache found remaining
594−
595 else
400 else
596 reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
401 reduceStylesRecursive (Set.insert styleName cache) (head :: found) remaining
597
402
@@ -604,7 +409,6 @@ reduceStyles style (( cache, existing ) as nevermind) =
604 in
409 in
605 if Set.member styleName cache then
410 if Set.member styleName cache then
606 nevermind
411 nevermind
607−
608 else
412 else
609 ( Set.insert styleName cache
413 ( Set.insert styleName cache
610 , style :: existing
414 , style :: existing
@@ -630,7 +434,6 @@ reduceRecursiveCalcName found styles =
630 headOfList :: other :: remaining ->
434 headOfList :: other :: remaining ->
631 if headOfList /= other then
435 if headOfList /= other then
632 reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
436 reduceRecursiveCalcName (headOfList :: found) (other :: remaining)
633−
634 else
437 else
635 reduceRecursiveCalcName found (other :: remaining)
438 reduceRecursiveCalcName found (other :: remaining)
636
439
@@ -647,7 +450,6 @@ reduceRecursive found styles =
647 ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
450 ( headOfListName, headOfList ) :: ( otherName, other ) :: remaining ->
648 if headOfListName /= otherName then
451 if headOfListName /= otherName then
649 reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
452 reduceRecursive (headOfList :: found) (( otherName, other ) :: remaining)
650−
651 else
453 else
652 reduceRecursive found (( otherName, other ) :: remaining)
454 reduceRecursive found (( otherName, other ) :: remaining)
653
455
@@ -872,7 +674,6 @@ skippable flag style =
872
674
873 _ ->
675 _ ->
874 False
676 False
875−
876 else
677 else
877 case style of
678 case style of
878 FontSize i ->
679 FontSize i ->
@@ -889,16 +690,7 @@ skippable flag style =
889 False
690 False
890
691
891
692
892−gatherAttrRecursive :
693+gatherAttrRecursive : String -> NodeName -> Flag.Field -> Transformation -> List Style -> List (VirtualDom.Attribute msg) -> List (VirtualDom.Node msg) -> List (Attribute aligned msg) -> Gathered msg
893− String
894− -> NodeName
895− -> Flag.Field
896− -> Transformation
897− -> List Style
898− -> List (VirtualDom.Attribute msg)
899− -> NearbyChildren msg
900− -> List (Attribute aligned msg)
901− -> Gathered msg
902gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
694gatherAttrRecursive classes node has transform styles attrs children elementAttrs =
903 case elementAttrs of
695 case elementAttrs of
904 [] ->
696 [] ->
@@ -927,7 +719,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
927 Class flag exactClassName ->
719 Class flag exactClassName ->
928 if Flag.present flag has then
720 if Flag.present flag has then
929 gatherAttrRecursive classes node has transform styles attrs children remaining
721 gatherAttrRecursive classes node has transform styles attrs children remaining
930−
931 else
722 else
932 gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
723 gatherAttrRecursive (exactClassName ++ " " ++ classes) node (Flag.add flag has) transform styles attrs children remaining
933
724
@@ -937,7 +728,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
937 StyleClass flag style ->
728 StyleClass flag style ->
938 if Flag.present flag has then
729 if Flag.present flag has then
939 gatherAttrRecursive classes node has transform styles attrs children remaining
730 gatherAttrRecursive classes node has transform styles attrs children remaining
940−
941 else if skippable flag style then
731 else if skippable flag style then
942 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
732 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
943 node
733 node
@@ -947,7 +737,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
947 attrs
737 attrs
948 children
738 children
949 remaining
739 remaining
950−
951 else
740 else
952 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
741 gatherAttrRecursive (getStyleName style ++ " " ++ classes)
953 node
742 node
@@ -971,7 +760,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
971 Width width ->
760 Width width ->
972 if Flag.present Flag.width has then
761 if Flag.present Flag.width has then
973 gatherAttrRecursive classes node has transform styles attrs children remaining
762 gatherAttrRecursive classes node has transform styles attrs children remaining
974−
975 else
763 else
976 case width of
764 case width of
977 Px px ->
765 Px px ->
@@ -1004,7 +792,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1004 attrs
792 attrs
1005 children
793 children
1006 remaining
794 remaining
1007−
1008 else
795 else
1009 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
796 gatherAttrRecursive (classes ++ " " ++ Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion)
1010 node
797 node
@@ -1032,7 +819,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1032 in
819 in
1033 gatherAttrRecursive (classes ++ " " ++ newClass)
820 gatherAttrRecursive (classes ++ " " ++ newClass)
1034 node
821 node
1035− (Flag.merge addToFlags (Flag.add Flag.width has))
822+ (Flag.merge addToFlags has)
1036 transform
823 transform
1037 (newStyles ++ styles)
824 (newStyles ++ styles)
1038 attrs
825 attrs
@@ -1042,7 +829,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1042 Height height ->
829 Height height ->
1043 if Flag.present Flag.height has then
830 if Flag.present Flag.height has then
1044 gatherAttrRecursive classes node has transform styles attrs children remaining
831 gatherAttrRecursive classes node has transform styles attrs children remaining
1045−
1046 else
832 else
1047 case height of
833 case height of
1048 Px px ->
834 Px px ->
@@ -1053,7 +839,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1053 name =
839 name =
1054 "height-px-" ++ val
840 "height-px-" ++ val
1055 in
841 in
1056− gatherAttrRecursive (Internal.Style.classes.heightExact ++ " " ++ name ++ " " ++ classes)
842+ gatherAttrRecursive (name ++ " " ++ classes)
1057 node
843 node
1058 (Flag.add Flag.height has)
844 (Flag.add Flag.height has)
1059 transform
845 transform
@@ -1082,7 +868,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1082 attrs
868 attrs
1083 children
869 children
1084 remaining
870 remaining
1085−
1086 else
871 else
1087 gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
872 gatherAttrRecursive (classes ++ " " ++ (Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion))
1088 node
873 node
@@ -1110,7 +895,7 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1110 in
895 in
1111 gatherAttrRecursive (classes ++ " " ++ newClass)
896 gatherAttrRecursive (classes ++ " " ++ newClass)
1112 node
897 node
1113− (Flag.merge addToFlags (Flag.add Flag.height has))
898+ (Flag.merge addToFlags has)
1114 transform
899 transform
1115 (newStyles ++ styles)
900 (newStyles ++ styles)
1116 attrs
901 attrs
@@ -1134,23 +919,26 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1134 Heading i ->
919 Heading i ->
1135 if i <= 1 then
920 if i <= 1 then
1136 gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
921 gatherAttrRecursive classes (addNodeName "h1" node) has transform styles attrs children remaining
1137−
1138 else if i < 7 then
922 else if i < 7 then
1139 gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
923 gatherAttrRecursive classes (addNodeName ("h" ++ String.fromInt i) node) has transform styles attrs children remaining
1140−
1141 else
924 else
1142 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
925 gatherAttrRecursive classes (addNodeName "h6" node) has transform styles attrs children remaining
1143
926
1144 Paragraph ->
927 Paragraph ->
1145− -- previously we rendered a <p> tag, though apparently this invalidates the html if it has <div>s inside.
928+ let
1146− -- Since we can't guaranteee that there are no divs, we need another strategy.
929+ newNode =
1147− -- While it's not documented in many places, there apparently is a paragraph aria role
930+ case node of
1148− -- https://github.com/w3c/aria/blob/11f85f41a5b621fdbe85fc9bcdcd270e653a48ba/common/script/roleInfo.js
931+ Generic ->
1149− -- Though we'll need to wait till it gets released in an official wai-aria spec to use it.
932+ NodeName "p"
1150− -- If it's used at the moment, then Lighthouse complains (likely rightfully) that role paragraph is not recognized.
933+
934+ NodeName name ->
935+ NodeName name
936+
937+ Embedded x y ->
938+ Embedded x y
939+ in
1151− gatherAttrRecursive
940+ gatherAttrRecursive classes
1152− classes
941+ newNode
1153− node
1154 has
942 has
1155 transform
943 transform
1156 styles
944 styles
@@ -1185,21 +973,78 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1185
973
1186 Styled styled ->
974 Styled styled ->
1187 styles ++ styled.styles
975 styles ++ styled.styles
976+
977+ nearbyElement =
978+ Html.div
979+ [ Html.Attributes.class <|
980+ case location of
981+ Above ->
982+ String.join " "
983+ [ Internal.Style.classes.any
984+ , Internal.Style.classes.single
985+ , Internal.Style.classes.above
986+ ]
987+
988+ Below ->
989+ String.join " "
990+ [ Internal.Style.classes.any
991+ , Internal.Style.classes.single
992+ , Internal.Style.classes.below
993+ ]
994+
995+ OnRight ->
996+ String.join " "
997+ [ Internal.Style.classes.any
998+ , Internal.Style.classes.single
999+ , Internal.Style.classes.onRight
1000+ ]
1001+
1002+ OnLeft ->
1003+ String.join " "
1004+ [ Internal.Style.classes.any
1005+ , Internal.Style.classes.single
1006+ , Internal.Style.classes.onLeft
1007+ ]
1008+
1009+ InFront ->
1010+ String.join " "
1011+ [ Internal.Style.classes.any
1012+ , Internal.Style.classes.single
1013+ , Internal.Style.classes.inFront
1014+ ]
1015+
1016+ Behind ->
1017+ String.join " "
1018+ [ Internal.Style.classes.any
1019+ , Internal.Style.classes.single
1020+ , Internal.Style.classes.behind
1021+ ]
1022+ ]
1023+ [ case elem of
1024+ Empty ->
1025+ VirtualDom.text ""
1026+
1027+ Text str ->
1028+ textElement str
1029+
1030+ Unstyled html ->
1031+ html asEl
1032+
1033+ Styled styled ->
1034+ styled.html NoStyleSheet asEl
1035+ ]
1036+
1037+ newClasses =
1038+ if location == Behind then
1039+ Internal.Style.classes.hasBehind ++ " " ++ classes
1040+ else
1041+ classes
1188 in
1042 in
1189− gatherAttrRecursive
1043+ gatherAttrRecursive newClasses node has transform newStyles attrs (nearbyElement :: children) remaining
1190− classes
1191− node
1192− has
1193− transform
1194− newStyles
1195− attrs
1196− (addNearbyElement location elem children)
1197− remaining
1198
1044
1199 AlignX x ->
1045 AlignX x ->
1200 if Flag.present Flag.xAlign has then
1046 if Flag.present Flag.xAlign has then
1201 gatherAttrRecursive classes node has transform styles attrs children remaining
1047 gatherAttrRecursive classes node has transform styles attrs children remaining
1202−
1203 else
1048 else
1204 gatherAttrRecursive (alignXName x ++ " " ++ classes)
1049 gatherAttrRecursive (alignXName x ++ " " ++ classes)
1205 node
1050 node
@@ -1226,7 +1071,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1226 AlignY y ->
1071 AlignY y ->
1227 if Flag.present Flag.yAlign has then
1072 if Flag.present Flag.yAlign has then
1228 gatherAttrRecursive classes node has transform styles attrs children remaining
1073 gatherAttrRecursive classes node has transform styles attrs children remaining
1229−
1230 else
1074 else
1231 gatherAttrRecursive (alignYName y ++ " " ++ classes)
1075 gatherAttrRecursive (alignYName y ++ " " ++ classes)
1232 node
1076 node
@@ -1250,106 +1094,6 @@ gatherAttrRecursive classes node has transform styles attrs children elementAttr
1250 remaining
1094 remaining
1251
1095
1252
1096
1253−addNearbyElement location elem existing =
1254− let
1255− nearby =
1256− nearbyElement location elem
1257− in
1258− case existing of
1259− NoNearbyChildren ->
1260− case location of
1261− Behind ->
1262− ChildrenBehind [ nearby ]
1263−
1264− _ ->
1265− ChildrenInFront [ nearby ]
1266−
1267− ChildrenBehind existingBehind ->
1268− case location of
1269− Behind ->
1270− ChildrenBehind (nearby :: existingBehind)
1271−
1272− _ ->
1273− ChildrenBehindAndInFront existingBehind [ nearby ]
1274−
1275− ChildrenInFront existingInFront ->
1276− case location of
1277− Behind ->
1278− ChildrenBehindAndInFront [ nearby ] existingInFront
1279−
1280− _ ->
1281− ChildrenInFront (nearby :: existingInFront)
1282−
1283− ChildrenBehindAndInFront existingBehind existingInFront ->
1284− case location of
1285− Behind ->
1286− ChildrenBehindAndInFront (nearby :: existingBehind) existingInFront
1287−
1288− _ ->
1289− ChildrenBehindAndInFront existingBehind (nearby :: existingInFront)
1290−
1291−
1292−nearbyElement location elem =
1293− Html.div
1294− [ Html.Attributes.class <|
1295− case location of
1296− Above ->
1297− String.join " "
1298− [ Internal.Style.classes.nearby
1299− , Internal.Style.classes.single
1300− , Internal.Style.classes.above
1301− ]
1302−
1303− Below ->
1304− String.join " "
1305− [ Internal.Style.classes.nearby
1306− , Internal.Style.classes.single
1307− , Internal.Style.classes.below
1308− ]
1309−
1310− OnRight ->
1311− String.join " "
1312− [ Internal.Style.classes.nearby
1313− , Internal.Style.classes.single
1314− , Internal.Style.classes.onRight
1315− ]
1316−
1317− OnLeft ->
1318− String.join " "
1319− [ Internal.Style.classes.nearby
1320− , Internal.Style.classes.single
1321− , Internal.Style.classes.onLeft
1322− ]
1323−
1324− InFront ->
1325− String.join " "
1326− [ Internal.Style.classes.nearby
1327− , Internal.Style.classes.single
1328− , Internal.Style.classes.inFront
1329− ]
1330−
1331− Behind ->
1332− String.join " "
1333− [ Internal.Style.classes.nearby
1334− , Internal.Style.classes.single
1335− , Internal.Style.classes.behind
1336− ]
1337− ]
1338− [ case elem of
1339− Empty ->
1340− VirtualDom.text ""
1341−
1342− Text str ->
1343− textElement str
1344−
1345− Unstyled html ->
1346− html asEl
1347−
1348− Styled styled ->
1349− styled.html NoStyleSheet asEl
1350− ]
1351−
1352−
1353renderWidth w =
1097renderWidth w =
1354 case w of
1098 case w of
1355 Px px ->
1099 Px px ->
@@ -1370,7 +1114,6 @@ renderWidth w =
1370 , Internal.Style.classes.widthFill
1114 , Internal.Style.classes.widthFill
1371 , []
1115 , []
1372 )
1116 )
1373−
1374 else
1117 else
1375 ( Flag.add Flag.widthFill Flag.none
1118 ( Flag.add Flag.widthFill Flag.none
1376 , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
1119 , Internal.Style.classes.widthFillPortion ++ " width-fill-" ++ String.fromInt portion
@@ -1436,7 +1179,7 @@ renderHeight h =
1436 "height-px-" ++ val
1179 "height-px-" ++ val
1437 in
1180 in
1438 ( Flag.none
1181 ( Flag.none
1439− , Internal.Style.classes.heightExact ++ " " ++ name
1182+ , name
1440 , [ Single name "height" (val ++ "px") ]
1183 , [ Single name "height" (val ++ "px") ]
1441 )
1184 )
1442
1185
@@ -1452,14 +1195,13 @@ renderHeight h =
1452 , Internal.Style.classes.heightFill
1195 , Internal.Style.classes.heightFill
1453 , []
1196 , []
1454 )
1197 )
1455−
1456 else
1198 else
1457 ( Flag.add Flag.heightFill Flag.none
1199 ( Flag.add Flag.heightFill Flag.none
1458 , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1200 , Internal.Style.classes.heightFillPortion ++ " height-fill-" ++ String.fromInt portion
1459 , [ Single
1201 , [ Single
1460 (Internal.Style.classes.any
1202 (Internal.Style.classes.any
1461 ++ "."
1203 ++ "."
1462− ++ Internal.Style.classes.column
1204+ ++ Internal.Style.classes.row
1463 ++ " > "
1205 ++ " > "
1464 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1206 ++ (Internal.Style.dot <| "height-fill-" ++ String.fromInt portion)
1465 )
1207 )
@@ -1478,9 +1220,7 @@ renderHeight h =
1478 Single
1220 Single
1479 cls
1221 cls
1480 "min-height"
1222 "min-height"
1481− -- This needs to be !important because we're using `min-height: min-content`
1482− -- to correct for safari's incorrect implementation of flexbox.
1483− (String.fromInt minSize ++ "px !important")
1223+ (String.fromInt minSize ++ "px")
1484
1224
1485 ( newFlag, newAttrs, newStyle ) =
1225 ( newFlag, newAttrs, newStyle ) =
1486 renderHeight len
1226 renderHeight len
@@ -1558,7 +1298,7 @@ element : LayoutContext -> NodeName -> List (Attribute aligned msg) -> Children
1558element context node attributes children =
1298element context node attributes children =
1559 attributes
1299 attributes
1560 |> List.reverse
1300 |> List.reverse
1561− |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] NoNearbyChildren
1301+ |> gatherAttrRecursive (contextClasses context) node Flag.none untransformed [] [] []
1562 |> createElement context children
1302 |> createElement context children
1563
1303
1564
1304
@@ -1566,6 +1306,13 @@ untransformed =
1566 Untransformed
1306 Untransformed
1567
1307
1568
1308
1309+
1310+-- space =
1311+-- VirtualDom.text " "
1312+-- keyedSpace =
1313+-- ( " ", space )
1314+
1315+
1569createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1316createElement : LayoutContext -> Children (Element msg) -> Gathered msg -> Element msg
1570createElement context children rendered =
1317createElement context children rendered =
1571 let
1318 let
@@ -1576,7 +1323,6 @@ createElement context children rendered =
1576 ( html context :: htmls
1323 ( html context :: htmls
1577 , existingStyles
1324 , existingStyles
1578 )
1325 )
1579−
1580 else
1326 else
1581 ( html context :: htmls
1327 ( html context :: htmls
1582 , existingStyles
1328 , existingStyles
@@ -1587,16 +1333,13 @@ createElement context children rendered =
1587 ( styled.html NoStyleSheet context :: htmls
1333 ( styled.html NoStyleSheet context :: htmls
1588 , if List.isEmpty existingStyles then
1334 , if List.isEmpty existingStyles then
1589 styled.styles
1335 styled.styles
1590−
1591 else
1336 else
1592 styled.styles ++ existingStyles
1337 styled.styles ++ existingStyles
1593 )
1338 )
1594−
1595 else
1339 else
1596 ( styled.html NoStyleSheet context :: htmls
1340 ( styled.html NoStyleSheet context :: htmls
1597 , if List.isEmpty existingStyles then
1341 , if List.isEmpty existingStyles then
1598 styled.styles
1342 styled.styles
1599−
1600 else
1343 else
1601 styled.styles ++ existingStyles
1344 styled.styles ++ existingStyles
1602 )
1345 )
@@ -1607,33 +1350,33 @@ createElement context children rendered =
1607 -- Same if it's a column or row with one child and width-content, height-content
1350 -- Same if it's a column or row with one child and width-content, height-content
1608 -- interferes with css grid
1351 -- interferes with css grid
1609 -- Maybe we could unpack text elements in a paragraph as well,
1352 -- Maybe we could unpack text elements in a paragraph as well,
1610− -- however, embedded elements that are larger than the line height will overlap with exisitng text.
1353+ -- however embedded style elements that are larger than the line height will overlap with exisitng text.
1611 -- I don't think that's what we want.
1354 -- I don't think that's what we want.
1612− -- if
1355+ if
1613− -- context
1356+ context
1614− -- == asEl
1357+ == asEl
1615− -- || context
1358+ || context
1616− -- == asParagraph
1359+ == asParagraph
1617− -- then
1360+ then
1618− -- ( VirtualDom.text
1361+ ( VirtualDom.text
1619− -- (if context == asParagraph then
1362+ (if context == asParagraph then
1620− -- str
1363+ str ++ " "
1621− -- else
1364+ else
1622− -- str
1365+ str
1623− -- )
1366+ )
1624− -- :: htmls
1367+ :: htmls
1625− -- , existingStyles
1368+ , existingStyles
1626− -- )
1369+ )
1627− -- else
1370+ else
1628− ( (if context == asEl then
1629− textElementFill str
1630−
1631− else
1632− textElement str
1371+ ( textElement
1372+ (if context == asParagraph then
1373+ str ++ " "
1374+ else
1375+ str
1633− )
1376+ )
1634− :: htmls
1377+ :: htmls
1635− , existingStyles
1378+ , existingStyles
1636− )
1379+ )
1637
1380
1638 Empty ->
1381 Empty ->
1639 ( htmls, existingStyles )
1382 ( htmls, existingStyles )
@@ -1645,7 +1388,6 @@ createElement context children rendered =
1645 ( ( key, html context ) :: htmls
1388 ( ( key, html context ) :: htmls
1646 , existingStyles
1389 , existingStyles
1647 )
1390 )
1648−
1649 else
1391 else
1650 ( ( key, html context ) :: htmls
1392 ( ( key, html context ) :: htmls
1651 , existingStyles
1393 , existingStyles
@@ -1657,16 +1399,13 @@ createElement context children rendered =
1657 :: htmls
1399 :: htmls
1658 , if List.isEmpty existingStyles then
1400 , if List.isEmpty existingStyles then
1659 styled.styles
1401 styled.styles
1660−
1661 else
1402 else
1662 styled.styles ++ existingStyles
1403 styled.styles ++ existingStyles
1663 )
1404 )
1664−
1665 else
1405 else
1666 ( ( key, styled.html NoStyleSheet context ) :: htmls
1406 ( ( key, styled.html NoStyleSheet context ) :: htmls
1667 , if List.isEmpty existingStyles then
1407 , if List.isEmpty existingStyles then
1668 styled.styles
1408 styled.styles
1669−
1670 else
1409 else
1671 styled.styles ++ existingStyles
1410 styled.styles ++ existingStyles
1672 )
1411 )
@@ -1675,30 +1414,35 @@ createElement context children rendered =
1675 -- TEXT OPTIMIZATION
1414 -- TEXT OPTIMIZATION
1676 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1415 -- You can have raw text if the element is an el, and has `width-content` and `height-content`
1677 -- Same if it's a column or row with one child and width-content, height-content
1416 -- Same if it's a column or row with one child and width-content, height-content
1678− -- if
1417+ if
1679− -- context
1418+ context
1680− -- == asEl
1419+ == asEl
1681− -- || context
1420+ || context
1682− -- == asParagraph
1421+ == asParagraph
1683− -- then
1422+ then
1684− -- ( ( key
1423+ ( ( key
1685− -- , VirtualDom.text
1424+ , VirtualDom.text
1425+ (if context == asParagraph then
1686− -- str
1426+ str ++ " "
1427+ else
1428+ str
1687− -- )
1429+ )
1430+ )
1688− -- :: htmls
1431+ :: htmls
1689− -- , existingStyles
1432+ , existingStyles
1690− -- )
1433+ )
1691− -- else
1434+ else
1692− ( ( key
1435+ ( ( key
1693− , if context == asEl then
1694− textElementFill str
1695−
1696− else
1697− textElement str
1436+ , textElement
1437+ (if context == asParagraph then
1438+ str ++ " "
1439+ else
1440+ str
1441+ )
1698− )
1442+ )
1699− :: htmls
1443+ :: htmls
1700− , existingStyles
1444+ , existingStyles
1701− )
1445+ )
1702
1446
1703 Empty ->
1447 Empty ->
1704 ( htmls, existingStyles )
1448 ( htmls, existingStyles )
@@ -1711,7 +1455,6 @@ createElement context children rendered =
1711 newStyles =
1455 newStyles =
1712 if List.isEmpty styles then
1456 if List.isEmpty styles then
1713 rendered.styles
1457 rendered.styles
1714−
1715 else
1458 else
1716 rendered.styles ++ styles
1459 rendered.styles ++ styles
1717 in
1460 in
@@ -1721,9 +1464,7 @@ createElement context children rendered =
1721 (finalizeNode rendered.has
1464 (finalizeNode rendered.has
1722 rendered.node
1465 rendered.node
1723 rendered.attributes
1466 rendered.attributes
1724− (Keyed
1725− (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1467+ (Keyed <| List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed)
1726− )
1727 NoStyleSheet
1468 NoStyleSheet
1728 )
1469 )
1729
1470
@@ -1731,13 +1472,7 @@ createElement context children rendered =
1731 Styled
1472 Styled
1732 { styles = allStyles
1473 { styles = allStyles
1733 , html =
1474 , html =
1734− finalizeNode
1475+ finalizeNode rendered.has rendered.node rendered.attributes (Keyed (List.map (\x -> ( "nearby-elements-pls", x )) rendered.children ++ keyed))
1735− rendered.has
1736− rendered.node
1737− rendered.attributes
1738− (Keyed
1739− (addKeyedChildren "nearby-element-pls" keyed rendered.children)
1740− )
1741 }
1476 }
1742
1477
1743 Unkeyed unkeyedChildren ->
1478 Unkeyed unkeyedChildren ->
@@ -1747,65 +1482,26 @@ createElement context children rendered =
1747 newStyles =
1482 newStyles =
1748 if List.isEmpty styles then
1483 if List.isEmpty styles then
1749 rendered.styles
1484 rendered.styles
1750−
1751 else
1485 else
1752 rendered.styles ++ styles
1486 rendered.styles ++ styles
1753 in
1487 in
1754 case newStyles of
1488 case newStyles of
1755 [] ->
1489 [] ->
1756 Unstyled
1490 Unstyled
1757− (finalizeNode
1491+ (finalizeNode rendered.has
1758− rendered.has
1759 rendered.node
1492 rendered.node
1760 rendered.attributes
1493 rendered.attributes
1761− (Unkeyed (addChildren unkeyed rendered.children))
1494+ (Unkeyed <| rendered.children ++ unkeyed)
1762 NoStyleSheet
1495 NoStyleSheet
1763 )
1496 )
1764
1497
1765 allStyles ->
1498 allStyles ->
1766 Styled
1499 Styled
1767 { styles = allStyles
1500 { styles = allStyles
1768− , html =
1501+ , html = finalizeNode rendered.has rendered.node rendered.attributes (Unkeyed (rendered.children ++ unkeyed))
1769− finalizeNode
1770− rendered.has
1771− rendered.node
1772− rendered.attributes
1773− (Unkeyed (addChildren unkeyed rendered.children))
1774 }
1502 }
1775
1503
1776
1504
1777−addChildren existing nearbyChildren =
1778− case nearbyChildren of
1779− NoNearbyChildren ->
1780− existing
1781−
1782− ChildrenBehind behind ->
1783− behind ++ existing
1784−
1785− ChildrenInFront inFront ->
1786− existing ++ inFront
1787−
1788− ChildrenBehindAndInFront behind inFront ->
1789− behind ++ existing ++ inFront
1790−
1791−
1792−addKeyedChildren key existing nearbyChildren =
1793− case nearbyChildren of
1794− NoNearbyChildren ->
1795− existing
1796−
1797− ChildrenBehind behind ->
1798− List.map (\x -> ( key, x )) behind ++ existing
1799−
1800− ChildrenInFront inFront ->
1801− existing ++ List.map (\x -> ( key, x )) inFront
1802−
1803− ChildrenBehindAndInFront behind inFront ->
1804− List.map (\x -> ( key, x )) behind
1805− ++ existing
1806− ++ List.map (\x -> ( key, x )) inFront
1807−
1808−
1809unit =
1505unit =
1810 0
1506 0
1811
1507
@@ -1817,26 +1513,13 @@ defaultOptions =
1817 }
1513 }
1818
1514
1819
1515
1820−staticRoot : OptionRecord -> VirtualDom.Node msg
1516+staticRoot =
1821−staticRoot opts =
1822− case opts.mode of
1823− Layout ->
1824− -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
1825− VirtualDom.node "div"
1826− []
1827− [ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ] ]
1517+ VirtualDom.node "style" [] [ VirtualDom.text Internal.Style.rules ]
1828−
1829− NoStaticStyleSheet ->
1830− VirtualDom.text ""
1831−
1832− WithVirtualCss ->
1833− VirtualDom.node "elm-ui-static-rules" [ VirtualDom.property "rules" (Encode.string Internal.Style.rules) ] []
1834
1518
1835
1519
1836addWhen ifThis x to =
1520addWhen ifThis x to =
1837 if ifThis then
1521 if ifThis then
1838 x :: to
1522 x :: to
1839−
1840 else
1523 else
1841 to
1524 to
1842
1525
@@ -1867,21 +1550,18 @@ filter attrs =
1867 Width width ->
1550 Width width ->
1868 if Set.member "width" has then
1551 if Set.member "width" has then
1869 ( found, has )
1552 ( found, has )
1870−
1871 else
1553 else
1872 ( x :: found, Set.insert "width" has )
1554 ( x :: found, Set.insert "width" has )
1873
1555
1874 Height height ->
1556 Height height ->
1875 if Set.member "height" has then
1557 if Set.member "height" has then
1876 ( found, has )
1558 ( found, has )
1877−
1878 else
1559 else
1879 ( x :: found, Set.insert "height" has )
1560 ( x :: found, Set.insert "height" has )
1880
1561
1881 Describe description ->
1562 Describe description ->
1882 if Set.member "described" has then
1563 if Set.member "described" has then
1883 ( found, has )
1564 ( found, has )
1884−
1885 else
1565 else
1886 ( x :: found, Set.insert "described" has )
1566 ( x :: found, Set.insert "described" has )
1887
1567
@@ -1891,21 +1571,18 @@ filter attrs =
1891 AlignX _ ->
1571 AlignX _ ->
1892 if Set.member "align-x" has then
1572 if Set.member "align-x" has then
1893 ( found, has )
1573 ( found, has )
1894−
1895 else
1574 else
1896 ( x :: found, Set.insert "align-x" has )
1575 ( x :: found, Set.insert "align-x" has )
1897
1576
1898 AlignY _ ->
1577 AlignY _ ->
1899 if Set.member "align-y" has then
1578 if Set.member "align-y" has then
1900 ( found, has )
1579 ( found, has )
1901−
1902 else
1580 else
1903 ( x :: found, Set.insert "align-y" has )
1581 ( x :: found, Set.insert "align-y" has )
1904
1582
1905 TransformComponent _ _ ->
1583 TransformComponent _ _ ->
1906 if Set.member "transform" has then
1584 if Set.member "transform" has then
1907 ( found, has )
1585 ( found, has )
1908−
1909 else
1586 else
1910 ( x :: found, Set.insert "transform" has )
1587 ( x :: found, Set.insert "transform" has )
1911 )
1588 )
@@ -1913,21 +1590,6 @@ filter attrs =
1913 attrs
1590 attrs
1914
1591
1915
1592
1916−isContent len =
1917− case len of
1918− Content ->
1919− True
1920−
1921− Max _ l ->
1922− isContent l
1923−
1924− Min _ l ->
1925− isContent l
1926−
1927− _ ->
1928− False
1929−
1930−
1931get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1593get : List (Attribute aligned msg) -> (Attribute aligned msg -> Bool) -> List (Attribute aligned msg)
1932get attrs isAttr =
1594get attrs isAttr =
1933 attrs
1595 attrs
@@ -1936,7 +1598,6 @@ get attrs isAttr =
1936 (\x found ->
1598 (\x found ->
1937 if isAttr x then
1599 if isAttr x then
1938 x :: found
1600 x :: found
1939−
1940 else
1601 else
1941 found
1602 found
1942 )
1603 )
@@ -1948,7 +1609,7 @@ type Spacing
1948
1609
1949
1610
1950type Padding
1611type Padding
1951− = Padding String Float Float Float Float
1612+ = Padding String Int Int Int Int
1952
1613
1953
1614
1954extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
1615extractSpacingAndPadding : List (Attribute aligned msg) -> ( Maybe Padding, Maybe Spacing )
@@ -2044,44 +1705,35 @@ getHeight attrs =
2044 Nothing
1705 Nothing
2045
1706
2046
1707
2047−textElementClasses : String
2048−textElementClasses =
2049− classes.any
2050− ++ " "
2051− ++ classes.text
2052− ++ " "
2053− ++ classes.widthContent
2054− ++ " "
2055− ++ classes.heightContent
2056−
2057−
2058textElement : String -> VirtualDom.Node msg
1708textElement : String -> VirtualDom.Node msg
2059textElement str =
1709textElement str =
2060 Html.div
1710 Html.div
2061 [ Html.Attributes.class
1711 [ Html.Attributes.class
2062− textElementClasses
1712+ (String.join " "
1713+ [ classes.any
1714+ , classes.text
1715+ , classes.widthContent
1716+ , classes.heightContent
1717+ ]
1718+ )
2063 ]
1719 ]
2064 [ Html.text str ]
1720 [ Html.text str ]
2065
1721
2066
1722
2067−textElementFillClasses : String
2068−textElementFillClasses =
2069− classes.any
2070− ++ " "
2071− ++ classes.text
2072− ++ " "
2073− ++ classes.widthFill
2074− ++ " "
2075− ++ classes.heightFill
2076−
2077−
2078textElementFill : String -> VirtualDom.Node msg
1723textElementFill : String -> VirtualDom.Node msg
2079textElementFill str =
1724textElementFill str =
2080− Html.div
1725+ VirtualDom.node "div"
2081− [ Html.Attributes.class
1726+ [ VirtualDom.property "className"
2082− textElementFillClasses
1727+ (Json.string <|
1728+ String.join " "
1729+ [ classes.any
1730+ , classes.text
1731+ , classes.widthFill
1732+ , classes.heightFill
1733+ ]
1734+ )
2083 ]
1735 ]
2084− [ Html.text str ]
1736+ [ VirtualDom.text str ]
2085
1737
2086
1738
2087type Children x
1739type Children x
@@ -2089,6 +1741,10 @@ type Children x
2089 | Keyed (List ( String, x ))
1741 | Keyed (List ( String, x ))
2090
1742
2091
1743
1744+
1745+-- toHtml : OptionRecord -> Element msg -> VirtualDom.Node msg
1746+
1747+
2092toHtml mode el =
1748toHtml mode el =
2093 case el of
1749 case el of
2094 Unstyled html ->
1750 Unstyled html ->
@@ -2124,7 +1780,8 @@ renderRoot optionList attributes child =
2124
1780
2125
1781
2126type RenderMode
1782type RenderMode
1783+ = Viewport
2127− = Layout
1784+ | Layout
2128 | NoStaticStyleSheet
1785 | NoStaticStyleSheet
2129 | WithVirtualCss
1786 | WithVirtualCss
2130
1787
@@ -2173,8 +1830,10 @@ rootStyle =
2173 , SansSerif
1830 , SansSerif
2174 ]
1831 ]
2175 in
1832 in
2176− [ StyleClass Flag.bgColor (Colored ("bg-" ++ formatColorClass (Rgba 1 1 1 0)) "background-color" (Rgba 1 1 1 0))
1833+ [ StyleClass Flag.bgColor (Colored ("bg-color-" ++ formatColorClass (Rgba 1 1 1 1)) "background-color" (Rgba 1 1 1 1))
2177− , StyleClass Flag.fontColor (Colored ("fc-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
1834+ , StyleClass Flag.fontColor (Colored ("font-color-" ++ formatColorClass (Rgba 0 0 0 1)) "color" (Rgba 0 0 0 1))
1835+
1836+ -- , StyleClass Flag.fontSize (Single "font-size-20" "font-size" "20px")
2178 , StyleClass Flag.fontSize (FontSize 20)
1837 , StyleClass Flag.fontSize (FontSize 20)
2179 , StyleClass Flag.fontFamily <|
1838 , StyleClass Flag.fontFamily <|
2180 FontFamily (List.foldl renderFontClassName "font-" families)
1839 FontFamily (List.foldl renderFontClassName "font-" families)
@@ -2206,49 +1865,14 @@ renderFontClassName font current =
2206 |> String.toLower
1865 |> String.toLower
2207 |> String.words
1866 |> String.words
2208 |> String.join "-"
1867 |> String.join "-"
2209−
2210− FontWith { name } ->
2211− name
2212− |> String.toLower
2213− |> String.words
2214− |> String.join "-"
2215 )
1868 )
2216
1869
2217
1870
2218renderFocusStyle :
1871renderFocusStyle :
2219 FocusStyle
1872 FocusStyle
2220− -> List Style
1873+ -> Style
2221renderFocusStyle focus =
1874renderFocusStyle focus =
2222− [ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
2223− (List.filterMap identity
2224− [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2225− , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
2226− , Maybe.map
2227− (\shadow ->
2228− Property "box-shadow"
2229− (formatBoxShadow
2230− { color = shadow.color
2231− , offset =
2232− shadow.offset
2233− |> Tuple.mapFirst toFloat
2234− |> Tuple.mapSecond toFloat
2235− , inset = False
2236− , blur =
2237− toFloat shadow.blur
2238− , size =
2239− toFloat shadow.size
2240− }
2241− )
2242− )
2243− focus.shadow
2244− , Just <| Property "outline" "none"
2245− ]
2246− )
2247− , Style
2248− ((Internal.Style.dot classes.any ++ ":focus .focusable, ")
2249− ++ (Internal.Style.dot classes.any ++ ".focusable:focus, ")
1875+ Style (Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
2250− ++ (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb")
2251− )
2252 (List.filterMap identity
1876 (List.filterMap identity
2253 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
1877 [ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
2254 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
1878 , Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
@@ -2271,7 +1895,6 @@ renderFocusStyle focus =
2271 , Just <| Property "outline" "none"
1895 , Just <| Property "outline" "none"
2272 ]
1896 ]
2273 )
1897 )
2274− ]
2275
1898
2276
1899
2277focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
1900focusDefaultStyle : { backgroundColor : Maybe Color, borderColor : Maybe Color, shadow : Maybe Shadow }
@@ -2283,7 +1906,7 @@ focusDefaultStyle =
2283 { color =
1906 { color =
2284 Rgba (155 / 255) (203 / 255) 1 1
1907 Rgba (155 / 255) (203 / 255) 1 1
2285 , offset = ( 0, 0 )
1908 , offset = ( 0, 0 )
2286− , blur = 0
1909+ , blur = 3
2287 , size = 3
1910 , size = 3
2288 }
1911 }
2289 }
1912 }
@@ -2351,734 +1974,497 @@ optionsToRecord options =
2351 options
1974 options
2352
1975
2353
1976
2354−toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
1977+renderFont : List Font -> String
2355−toStyleSheet options styleSheet =
1978+renderFont families =
2356− case options.mode of
2357− Layout ->
2358− -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2359− VirtualDom.node "div"
2360− []
2361− [ VirtualDom.node "style"
2362− []
2363− [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2364− ]
2365−
2366− NoStaticStyleSheet ->
2367− -- wrap the style node in a div to prevent `Dark Reader` from blowin up the dom.
2368− VirtualDom.node "div"
2369− []
2370− [ VirtualDom.node "style"
2371− []
2372− [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2373− ]
2374−
2375− WithVirtualCss ->
2376− VirtualDom.node "elm-ui-rules"
2377− [ VirtualDom.property "rules"
2378− (encodeStyles options styleSheet)
2379− ]
2380− []
2381−
2382−
2383−renderTopLevelValues rules =
2384 let
1979 let
2385− withImport font =
1980+ fontName font =
2386 case font of
1981 case font of
2387− ImportFont _ url ->
1982+ Serif ->
2388− Just ("@import url('" ++ url ++ "');")
1983+ "serif"
2389−
2390− -- FontWith with ->
2391− -- case with.url of
2392− -- Just x ->
2393− -- Just ("@import url('" ++ x ++ "');")
2394− -- Nothing ->
2395− -- Nothing
2396− _ ->
2397− Nothing
2398−
2399− allNames =
2400− List.map Tuple.first rules
2401−
2402− fontImports ( name, typefaces ) =
2403− let
2404− imports =
2405− String.join "\n" (List.filterMap withImport typefaces)
2406− in
2407− imports
2408−
2409− fontAdjustments ( name, typefaces ) =
2410− case typefaceAdjustment typefaces of
2411− Nothing ->
2412− String.join ""
2413− (List.map (renderNullAdjustmentRule name) allNames)
2414
1984
2415− Just adjustment ->
1985+ SansSerif ->
2416− String.join ""
1986+ "sans-serif"
2417− (List.map (renderFontAdjustmentRule name adjustment) allNames)
2418− in
2419− String.join "\n" (List.map fontImports rules)
2420− ++ String.join "\n" (List.map fontAdjustments rules)
2421
1987
1988+ Monospace ->
1989+ "monospace"
2422
1990
2423−renderNullAdjustmentRule fontToAdjust otherFontName =
1991+ Typeface name ->
2424− let
1992+ "\"" ++ name ++ "\""
2425− name =
2426− if fontToAdjust == otherFontName then
2427− fontToAdjust
2428
1993
2429− else
1994+ ImportFont name url ->
2430− otherFontName ++ " ." ++ fontToAdjust
1995+ "\"" ++ name ++ "\""
2431 in
1996 in
1997+ families
1998+ |> List.map fontName
2432− String.join " "
1999+ |> String.join ", "
2433− [ bracket
2434− ("."
2435− ++ name
2436− ++ "."
2437− ++ classes.sizeByCapital
2438− ++ ", "
2439− ++ "."
2440− ++ name
2441− ++ " ."
2442− ++ classes.sizeByCapital
2443− )
2444− [ ( "line-height", "1" )
2445− ]
2446− , bracket
2447− ("."
2448− ++ name
2449− ++ "."
2450− ++ classes.sizeByCapital
2451− ++ "> ."
2452− ++ Internal.Style.classes.text
2453− ++ ", ."
2454− ++ name
2455− ++ " ."
2456− ++ classes.sizeByCapital
2457− ++ " > ."
2458− ++ Internal.Style.classes.text
2459− )
2460− [ ( "vertical-align", "0" )
2461− , ( "line-height", "1" )
2462− ]
2463− ]
2464−
2465−
2466−fontRule name modifier ( parentAdj, textAdjustment ) =
2467− [ bracket
2468− ("."
2469− ++ name
2470− ++ "."
2471− ++ modifier
2472− ++ ", "
2473− ++ "."
2474− ++ name
2475− ++ " ."
2476− ++ modifier
2477− )
2478− parentAdj
2479− , bracket
2480− ("."
2481− ++ name
2482− ++ "."
2483− ++ modifier
2484− ++ "> ."
2485− ++ Internal.Style.classes.text
2486− ++ ", ."
2487− ++ name
2488− ++ " ."
2489− ++ modifier
2490− ++ " > ."
2491− ++ Internal.Style.classes.text
2492− )
2493− textAdjustment
2494− ]
2495
2000
2496
2001
2497−renderFontAdjustmentRule fontToAdjust ( full, capital ) otherFontName =
2002+toStyleSheet : OptionRecord -> List Style -> VirtualDom.Node msg
2498− let
2003+toStyleSheet options styleSheet =
2499− name =
2004+ VirtualDom.node "style" [] [ VirtualDom.text (toStyleSheetString options styleSheet) ]
2500− if fontToAdjust == otherFontName then
2501− fontToAdjust
2502−
2503− else
2504− otherFontName ++ " ." ++ fontToAdjust
2505− in
2506− String.join " "
2507− (fontRule name classes.sizeByCapital capital ++ fontRule name classes.fullSize full)
2508
2005
2509
2006
2510−bracket selector rules =
2007+toStyleSheetString : OptionRecord -> List Style -> String
2008+toStyleSheetString options stylesheet =
2511 let
2009 let
2512− renderPair ( name, val ) =
2010+ renderTopLevels rule =
2513− name ++ ": " ++ val ++ ";"
2011+ case rule of
2514− in
2012+ FontFamily name typefaces ->
2515− selector ++ " {" ++ String.join "" (List.map renderPair rules) ++ "}"
2013+ let
2014+ getImports font =
2015+ case font of
2016+ ImportFont _ url ->
2017+ Just ("@import url('" ++ url ++ "');")
2516
2018
2019+ _ ->
2020+ Nothing
2021+ in
2022+ typefaces
2023+ |> List.filterMap getImports
2024+ |> String.join "\n"
2025+ |> Just
2517
2026
2518−fontAdjustmentRules converted =
2027+ _ ->
2519− ( [ ( "display", "block" )
2028+ Nothing
2520− ]
2521− , [ ( "display", "inline-block" )
2522− , ( "line-height", String.fromFloat converted.height )
2523− , ( "vertical-align", String.fromFloat converted.vertical ++ "em" )
2524− , ( "font-size", String.fromFloat converted.size ++ "em" )
2525− ]
2526− )
2527
2029
2030+ renderProps force (Property key val) existing =
2031+ if force then
2032+ existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2033+ else
2034+ existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2528
2035
2529−typefaceAdjustment typefaces =
2036+ renderStyle maybePseudo selector props =
2530− List.foldl
2531− (\face found ->
2532− case found of
2037+ case maybePseudo of
2533 Nothing ->
2038 Nothing ->
2534− case face of
2039+ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}"
2535− FontWith with ->
2536− case with.adjustment of
2537− Nothing ->
2538− found
2539−
2540− Just adjustment ->
2541− Just
2542− ( fontAdjustmentRules
2543− (.full (convertAdjustment adjustment))
2544− , fontAdjustmentRules
2545− (.capital (convertAdjustment adjustment))
2546− )
2547−
2548− _ ->
2549− found
2550−
2551− Just _ ->
2552− found
2553− )
2554− Nothing
2555− typefaces
2556−
2557−
2558−fontName font =
2559− case font of
2560− Serif ->
2561− "serif"
2562−
2563− SansSerif ->
2564− "sans-serif"
2565−
2566− Monospace ->
2567− "monospace"
2568−
2569− Typeface name ->
2570− "\"" ++ name ++ "\""
2571−
2572− ImportFont name url ->
2573− "\"" ++ name ++ "\""
2574−
2575− FontWith { name } ->
2576− "\"" ++ name ++ "\""
2577−
2578−
2579−topLevelValue rule =
2580− case rule of
2581− FontFamily name typefaces ->
2582− Just ( name, typefaces )
2583
2040
2584− _ ->
2041+ Just pseudo ->
2585− Nothing
2042+ case pseudo of
2586−
2043+ Hover ->
2587−
2044+ case options.hover of
2588−renderProps force (Property key val) existing =
2045+ NoHover ->
2589− if force then
2046+ ""
2590− existing ++ "\n " ++ key ++ ": " ++ val ++ " !important;"
2591
2047
2592− else
2048+ ForceHover ->
2593− existing ++ "\n " ++ key ++ ": " ++ val ++ ";"
2049+ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}"
2594−
2595−
2596−encodeStyles options stylesheet =
2597− stylesheet
2598− |> List.map
2599− (\style ->
2600− let
2601− styled =
2602− renderStyleRule options style Nothing
2603− in
2604− ( getStyleName style, Encode.list Encode.string styled )
2605− )
2606− |> Encode.object
2607
2050
2051+ AllowHover ->
2052+ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2608
2053
2609−toStyleSheetString : OptionRecord -> List Style -> String
2054+ Focus ->
2610−toStyleSheetString options stylesheet =
2611− let
2055+ let
2612− combine style rendered =
2056+ renderedProps =
2613− { rules = rendered.rules ++ renderStyleRule options style Nothing
2614− , topLevel =
2615− case topLevelValue style of
2616− Nothing ->
2617− rendered.topLevel
2618−
2619− Just topLevel ->
2620− topLevel :: rendered.topLevel
2621− }
2622− in
2623− case List.foldl combine { topLevel = [], rules = [] } stylesheet of
2624− { topLevel, rules } ->
2625− renderTopLevelValues topLevel ++ String.concat rules
2626−
2627−
2628−renderStyle : OptionRecord -> Maybe PseudoClass -> String -> List Property -> List String
2629−renderStyle options maybePseudo selector props =
2630− case maybePseudo of
2631− Nothing ->
2632− [ selector ++ "{" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2057+ List.foldl (renderProps False) "" props
2058+ in
2059+ String.join "\n"
2060+ [ selector
2061+ ++ "-fs:focus {"
2062+ ++ renderedProps
2063+ ++ "\n}"
2064+ , "."
2065+ ++ classes.any
2066+ ++ ":focus ~ "
2067+ ++ selector
2068+ ++ "-fs:not(.focus) {"
2069+ ++ renderedProps
2070+ ++ "\n}"
2071+ , "."
2072+ ++ classes.any
2073+ ++ ":focus "
2074+ ++ selector
2075+ ++ "-fs {"
2076+ ++ renderedProps
2077+ ++ "\n}"
2078+ , ".focusable-parent:focus ~ "
2079+ ++ "."
2080+ ++ classes.any
2081+ ++ " "
2082+ ++ selector
2083+ ++ "-fs {"
2084+ ++ renderedProps
2085+ ++ "\n}"
2086+ ]
2633
2087
2634− Just pseudo ->
2088+ Active ->
2635− case pseudo of
2089+ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}"
2636− Hover ->
2637− case options.hover of
2638− NoHover ->
2639− []
2640
2090
2641− ForceHover ->
2091+ renderStyleRule rule maybePseudo =
2642− [ selector ++ "-hv {" ++ List.foldl (renderProps True) "" props ++ "\n}" ]
2092+ case rule of
2093+ Style selector props ->
2094+ renderStyle maybePseudo selector props
2643
2095
2644− AllowHover ->
2096+ Shadows name prop ->
2645− [ selector ++ "-hv:hover {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2097+ renderStyle
2098+ maybePseudo
2099+ ("." ++ name)
2100+ [ Property "box-shadow" prop
2101+ ]
2646
2102
2647− Focus ->
2103+ Transparency name transparency ->
2648 let
2104 let
2649− renderedProps =
2105+ opacity =
2650− List.foldl (renderProps False) "" props
2106+ (1 - transparency)
2107+ |> min 1
2108+ |> max 0
2651 in
2109 in
2652− [ selector ++ "-fs:focus {" ++ renderedProps ++ "\n}"
2110+ renderStyle
2653− , ("." ++ classes.any ++ ":focus " ++ selector ++ "-fs {")
2111+ maybePseudo
2654− ++ renderedProps
2655− ++ "\n}"
2656− , (selector ++ "-fs:focus-within {")
2657− ++ renderedProps
2658− ++ "\n}"
2659− , (".ui-slide-bar:focus + " ++ Internal.Style.dot classes.any ++ " .focusable-thumb" ++ selector ++ "-fs {")
2660− ++ renderedProps
2661− ++ "\n}"
2662− ]
2663−
2664− Active ->
2665− [ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]
2666−
2667−
2668−renderStyleRule : OptionRecord -> Style -> Maybe PseudoClass -> List String
2669−renderStyleRule options rule maybePseudo =
2670− case rule of
2671− Style selector props ->
2672− renderStyle options maybePseudo selector props
2673−
2674− Shadows name prop ->
2675− renderStyle options
2676− maybePseudo
2677− ("." ++ name)
2112+ ("." ++ name)
2678− [ Property "box-shadow" prop
2679− ]
2680−
2681− Transparency name transparency ->
2682− let
2683− opacity =
2684− (1 - transparency)
2685− |> min 1
2686− |> max 0
2687− in
2688− renderStyle options
2689− maybePseudo
2690− ("." ++ name)
2691− [ Property "opacity" (String.fromFloat opacity)
2113+ [ Property "opacity" (String.fromFloat opacity)
2692− ]
2693−
2694− FontSize i ->
2695− renderStyle options
2696− maybePseudo
2697− (".font-size-" ++ String.fromInt i)
2698− [ Property "font-size" (String.fromInt i ++ "px")
2699− ]
2114+ ]
2700
2115
2701− FontFamily name typefaces ->
2116+ FontSize i ->
2702− let
2117+ renderStyle
2703− features =
2118+ maybePseudo
2704− typefaces
2119+ (".font-size-" ++ String.fromInt i)
2705− |> List.filterMap renderVariants
2706− |> String.join ", "
2707−
2708− families =
2709− [ Property "font-family"
2120+ [ Property "font-size" (String.fromInt i ++ "px")
2710− (typefaces
2121+ ]
2711− |> List.map fontName
2712− |> String.join ", "
2713− )
2714− , Property "font-feature-settings" features
2715− , Property "font-variant"
2716− (if List.any hasSmallCaps typefaces then
2717− "small-caps"
2718
2122
2719− else
2123+ FontFamily name typefaces ->
2720− "normal"
2721− )
2722− ]
2723− in
2724− renderStyle options
2124+ renderStyle
2725− maybePseudo
2125+ maybePseudo
2726− ("." ++ name)
2126+ ("." ++ name)
2727− families
2127+ [ Property "font-family" (renderFont typefaces)
2128+ ]
2728
2129
2729− Single class prop val ->
2130+ Single class prop val ->
2730− renderStyle options
2131+ renderStyle
2731− maybePseudo
2132+ maybePseudo
2732− ("." ++ class)
2133+ ("." ++ class)
2733− [ Property prop val
2134+ [ Property prop val
2734− ]
2135+ ]
2735
2136
2736− Colored class prop color ->
2137+ Colored class prop color ->
2737− renderStyle options
2138+ renderStyle
2738− maybePseudo
2139+ maybePseudo
2739− ("." ++ class)
2140+ ("." ++ class)
2740− [ Property prop (formatColor color)
2141+ [ Property prop (formatColor color)
2741− ]
2142+ ]
2742
2143
2743− SpacingStyle cls x y ->
2144+ SpacingStyle cls x y ->
2744− let
2145+ let
2745− class =
2146+ class =
2746− "." ++ cls
2147+ "." ++ cls
2747
2148
2748− halfX =
2149+ xPx =
2749− String.fromFloat (toFloat x / 2) ++ "px"
2150+ String.fromInt x ++ "px"
2750
2151
2751− halfY =
2152+ yPx =
2752− String.fromFloat (toFloat y / 2) ++ "px"
2153+ String.fromInt y ++ "px"
2753
2154
2754− xPx =
2155+ row =
2755− String.fromInt x ++ "px"
2156+ "." ++ Internal.Style.classes.row
2756
2157
2757− yPx =
2158+ wrappedRow =
2758− String.fromInt y ++ "px"
2159+ "." ++ Internal.Style.classes.wrapped ++ row
2759
2160
2760− row =
2161+ column =
2761− "." ++ Internal.Style.classes.row
2162+ "." ++ Internal.Style.classes.column
2762
2163
2763− wrappedRow =
2164+ page =
2764− "." ++ Internal.Style.classes.wrapped ++ row
2165+ "." ++ Internal.Style.classes.page
2765
2166
2766− column =
2167+ paragraph =
2767− "." ++ Internal.Style.classes.column
2168+ "." ++ Internal.Style.classes.paragraph
2768
2169
2769− page =
2170+ left =
2770− "." ++ Internal.Style.classes.page
2171+ "." ++ Internal.Style.classes.alignLeft
2771
2172
2772− paragraph =
2173+ right =
2773− "." ++ Internal.Style.classes.paragraph
2174+ "." ++ Internal.Style.classes.alignRight
2774
2175
2775− left =
2176+ any =
2776− "." ++ Internal.Style.classes.alignLeft
2177+ "." ++ Internal.Style.classes.any
2777
2178
2778− right =
2179+ single =
2779− "." ++ Internal.Style.classes.alignRight
2180+ "." ++ Internal.Style.classes.single
2181+ in
2182+ String.concat
2183+ [ renderStyle maybePseudo (class ++ row ++ " > " ++ any) [ Property "margin-right" xPx ]
2780
2184
2781− any =
2185+ -- margins don't apply to last element of normal, unwrapped rows
2782− "." ++ Internal.Style.classes.any
2186+ , renderStyle maybePseudo (class ++ row ++ " > " ++ any ++ ":last-child") [ Property "margin" "0" ]
2783
2187
2784− single =
2785− "." ++ Internal.Style.classes.single
2786− in
2787− List.concat
2788− [ renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ " + " ++ any) [ Property "margin-left" xPx ]
2789−
2790− -- margins don't apply to last element of normal, unwrapped rows
2791− -- , renderStyle options maybePseudo (class ++ row ++ " > " ++ any ++ ":first-child") [ Property "margin" "0" ]
2792− -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2188+ -- For wrapped rows, margins always apply because we handle "canceling out" the other margins manually in the element.
2793− , renderStyle options
2794− maybePseudo
2189+ , renderStyle maybePseudo
2795− (class ++ wrappedRow ++ " > " ++ any)
2190+ (class ++ wrappedRow ++ " > " ++ any)
2796− [ Property "margin" (halfY ++ " " ++ halfX)
2191+ [ Property "margin" ("0 " ++ xPx ++ " " ++ yPx ++ " 0")
2192+ ]
2193+ , renderStyle maybePseudo
2194+ (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2195+ [ Property "margin-right" "0"
2797− ]
2196+ ]
2798
2197
2799− -- , renderStyle options maybePseudo
2800− -- (class ++ wrappedRow ++ " > " ++ any ++ ":last-child")
2801− -- [ Property "margin-right" "0"
2802− -- ]
2803− -- columns
2198+ -- columns
2804− , renderStyle options maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2199+ , renderStyle maybePseudo (class ++ column ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2805− , renderStyle options maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2200+ , renderStyle maybePseudo (class ++ page ++ " > " ++ any ++ " + " ++ any) [ Property "margin-top" yPx ]
2806− , renderStyle options maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2201+ , renderStyle maybePseudo (class ++ page ++ " > " ++ left) [ Property "margin-right" xPx ]
2807− , renderStyle options maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2202+ , renderStyle maybePseudo (class ++ page ++ " > " ++ right) [ Property "margin-left" xPx ]
2808− , renderStyle options
2203+ , renderStyle
2809− maybePseudo
2204+ maybePseudo
2810− (class ++ paragraph)
2205+ (class ++ paragraph)
2811− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2206+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2812− ]
2207+ ]
2813− , renderStyle options
2208+ , renderStyle
2814− maybePseudo
2209+ maybePseudo
2815− ("textarea" ++ any ++ class)
2210+ ("textarea" ++ class)
2816− [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2211+ [ Property "line-height" ("calc(1em + " ++ String.fromInt y ++ "px)")
2817− , Property "height" ("calc(100% + " ++ String.fromInt y ++ "px)")
2818− ]
2212+ ]
2819
2213
2820− -- , renderStyle options
2214+ -- , renderStyle
2821− -- maybePseudo
2215+ -- maybePseudo
2822− -- (class ++ paragraph ++ " > " ++ any)
2216+ -- (class ++ paragraph ++ " > " ++ any)
2823− -- [ Property "margin-right" xPx
2217+ -- [ Property "margin-right" xPx
2824− -- , Property "margin-bottom" yPx
2218+ -- , Property "margin-bottom" yPx
2825− -- ]
2219+ -- ]
2826− , renderStyle options
2220+ , renderStyle
2827− maybePseudo
2221+ maybePseudo
2828− (class ++ paragraph ++ " > " ++ left)
2222+ (class ++ paragraph ++ " > " ++ left)
2829− [ Property "margin-right" xPx
2223+ [ Property "margin-right" xPx
2830− ]
2224+ ]
2831− , renderStyle options
2225+ , renderStyle
2832− maybePseudo
2226+ maybePseudo
2833− (class ++ paragraph ++ " > " ++ right)
2227+ (class ++ paragraph ++ " > " ++ right)
2834− [ Property "margin-left" xPx
2228+ [ Property "margin-left" xPx
2835− ]
2229+ ]
2836− , renderStyle options
2230+ , renderStyle
2837− maybePseudo
2231+ maybePseudo
2838− (class ++ paragraph ++ "::after")
2232+ (class ++ paragraph ++ "::after")
2839− [ Property "content" "''"
2233+ [ Property "content" "''"
2840− , Property "display" "block"
2234+ , Property "display" "block"
2841− , Property "height" "0"
2235+ , Property "height" "0"
2842− , Property "width" "0"
2236+ , Property "width" "0"
2843− , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2237+ , Property "margin-top" (String.fromInt (-1 * (y // 2)) ++ "px")
2844− ]
2238+ ]
2845− , renderStyle options
2239+ , renderStyle
2846− maybePseudo
2240+ maybePseudo
2847− (class ++ paragraph ++ "::before")
2241+ (class ++ paragraph ++ "::before")
2848− [ Property "content" "''"
2242+ [ Property "content" "''"
2849− , Property "display" "block"
2243+ , Property "display" "block"
2850− , Property "height" "0"
2244+ , Property "height" "0"
2851− , Property "width" "0"
2245+ , Property "width" "0"
2852− , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2246+ , Property "margin-bottom" (String.fromInt (-1 * (y // 2)) ++ "px")
2853− ]
2247+ ]
2854− ]
2248+ ]
2855
2249
2856− PaddingStyle cls top right bottom left ->
2250+ PaddingStyle cls top right bottom left ->
2857− let
2251+ let
2858− class =
2252+ class =
2859− "."
2253+ "."
2860− ++ cls
2254+ ++ cls
2861− in
2255+ in
2862− renderStyle options
2256+ renderStyle
2863− maybePseudo
2257+ maybePseudo
2864− class
2258+ class
2865− [ Property "padding"
2259+ [ Property "padding"
2866− (String.fromFloat top
2260+ (String.fromInt top
2867− ++ "px "
2261+ ++ "px "
2868− ++ String.fromFloat right
2262+ ++ String.fromInt right
2869− ++ "px "
2263+ ++ "px "
2870− ++ String.fromFloat bottom
2264+ ++ String.fromInt bottom
2871− ++ "px "
2265+ ++ "px "
2872− ++ String.fromFloat left
2266+ ++ String.fromInt left
2873− ++ "px"
2267+ ++ "px"
2874− )
2268+ )
2875− ]
2269+ ]
2876
2270
2877− BorderWidth cls top right bottom left ->
2271+ GridTemplateStyle template ->
2878− let
2272+ let
2879− class =
2273+ class =
2880− "."
2274+ ".grid-rows-"
2881− ++ cls
2275+ ++ String.join "-" (List.map lengthClassName template.rows)
2276+ ++ "-cols-"
2277+ ++ String.join "-" (List.map lengthClassName template.columns)
2278+ ++ "-space-x-"
2279+ ++ lengthClassName (Tuple.first template.spacing)
2280+ ++ "-space-y-"
2281+ ++ lengthClassName (Tuple.second template.spacing)
2282+
2283+ ySpacing =
2284+ toGridLength (Tuple.second template.spacing)
2285+
2286+ xSpacing =
2287+ toGridLength (Tuple.first template.spacing)
2288+
2289+ toGridLength x =
2290+ toGridLengthHelper Nothing Nothing x
2291+
2292+ toGridLengthHelper minimum maximum x =
2293+ case x of
2294+ Px px ->
2295+ String.fromInt px ++ "px"
2296+
2297+ Content ->
2298+ case ( minimum, maximum ) of
2299+ ( Nothing, Nothing ) ->
2300+ "max-content"
2301+
2302+ ( Just minSize, Nothing ) ->
2303+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2304+
2305+ ( Nothing, Just maxSize ) ->
2306+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2307+
2308+ ( Just minSize, Just maxSize ) ->
2309+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2310+
2311+ Fill i ->
2312+ case ( minimum, maximum ) of
2313+ ( Nothing, Nothing ) ->
2314+ String.fromInt i ++ "fr"
2315+
2316+ ( Just minSize, Nothing ) ->
2317+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2318+
2319+ ( Nothing, Just maxSize ) ->
2320+ "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2321+
2322+ ( Just minSize, Just maxSize ) ->
2323+ "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2324+
2325+ Min m len ->
2326+ toGridLengthHelper (Just m) maximum len
2327+
2328+ Max m len ->
2329+ toGridLengthHelper minimum (Just m) len
2330+
2331+ msColumns =
2332+ template.columns
2333+ |> List.map toGridLength
2334+ |> String.join ySpacing
2335+ |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2336+
2337+ msRows =
2338+ template.columns
2339+ |> List.map toGridLength
2340+ |> String.join ySpacing
2341+ |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2342+
2343+ base =
2344+ class ++ "{" ++ msColumns ++ msRows ++ "}"
2345+
2346+ columns =
2347+ template.columns
2348+ |> List.map toGridLength
2349+ |> String.join " "
2350+ |> (\x -> "grid-template-columns: " ++ x ++ ";")
2351+
2352+ rows =
2353+ template.rows
2354+ |> List.map toGridLength
2355+ |> String.join " "
2356+ |> (\x -> "grid-template-rows: " ++ x ++ ";")
2357+
2358+ gapX =
2359+ "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2360+
2361+ gapY =
2362+ "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2363+
2364+ modernGrid =
2365+ class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2366+
2367+ supports =
2368+ "@supports (display:grid) {" ++ modernGrid ++ "}"
2882− in
2369+ in
2883− renderStyle options
2370+ base ++ supports
2884− maybePseudo
2885− class
2886− [ Property "border-width"
2887− (String.fromInt top
2888− ++ "px "
2889− ++ String.fromInt right
2890− ++ "px "
2891− ++ String.fromInt bottom
2892− ++ "px "
2893− ++ String.fromInt left
2894− ++ "px"
2895− )
2896− ]
2897
2371
2898− GridTemplateStyle template ->
2372+ GridPosition position ->
2899− let
2373+ let
2900− class =
2374+ class =
2901− ".grid-rows-"
2375+ ".grid-pos-"
2902− ++ String.join "-" (List.map lengthClassName template.rows)
2376+ ++ String.fromInt position.row
2377+ ++ "-"
2378+ ++ String.fromInt position.col
2903− ++ "-cols-"
2379+ ++ "-"
2904− ++ String.join "-" (List.map lengthClassName template.columns)
2380+ ++ String.fromInt position.width
2905− ++ "-space-x-"
2381+ ++ "-"
2906− ++ lengthClassName (Tuple.first template.spacing)
2382+ ++ String.fromInt position.height
2907− ++ "-space-y-"
2383+
2908− ++ lengthClassName (Tuple.second template.spacing)
2384+ msPosition =
2909−
2385+ String.join " "
2910− ySpacing =
2386+ [ "-ms-grid-row: "
2911− toGridLength (Tuple.second template.spacing)
2387+ ++ String.fromInt position.row
2912−
2388+ ++ ";"
2913− xSpacing =
2389+ , "-ms-grid-row-span: "
2914− toGridLength (Tuple.first template.spacing)
2390+ ++ String.fromInt position.height
2915−
2391+ ++ ";"
2916− toGridLength x =
2392+ , "-ms-grid-column: "
2917− toGridLengthHelper Nothing Nothing x
2393+ ++ String.fromInt position.col
2918−
2394+ ++ ";"
2919− toGridLengthHelper minimum maximum x =
2395+ , "-ms-grid-column-span: "
2920− case x of
2396+ ++ String.fromInt position.width
2921− Px px ->
2397+ ++ ";"
2398+ ]
2399+
2400+ base =
2401+ class ++ "{" ++ msPosition ++ "}"
2402+
2403+ modernPosition =
2404+ String.join " "
2405+ [ "grid-row: "
2922− String.fromInt px ++ "px"
2406+ ++ String.fromInt position.row
2923−
2407+ ++ " / "
2924− Content ->
2408+ ++ String.fromInt (position.row + position.height)
2925− case ( minimum, maximum ) of
2409+ ++ ";"
2926− ( Nothing, Nothing ) ->
2410+ , "grid-column: "
2927− "max-content"
2928−
2929− ( Just minSize, Nothing ) ->
2930− "minmax(" ++ String.fromInt minSize ++ "px, " ++ "max-content)"
2411+ ++ String.fromInt position.col
2931−
2412+ ++ " / "
2932− ( Nothing, Just maxSize ) ->
2413+ ++ String.fromInt (position.col + position.width)
2933− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2414+ ++ ";"
2934−
2415+ ]
2935− ( Just minSize, Just maxSize ) ->
2416+
2936− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2417+ modernGrid =
2937−
2418+ class ++ "{" ++ modernPosition ++ "}"
2938− Fill i ->
2419+
2939− case ( minimum, maximum ) of
2420+ supports =
2940− ( Nothing, Nothing ) ->
2421+ "@supports (display:grid) {" ++ modernGrid ++ "}"
2941− String.fromInt i ++ "fr"
2422+ in
2942−
2423+ base ++ supports
2943− ( Just minSize, Nothing ) ->
2944− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt i ++ "fr" ++ "fr)"
2945−
2946− ( Nothing, Just maxSize ) ->
2947− "minmax(max-content, " ++ String.fromInt maxSize ++ "px)"
2948−
2949− ( Just minSize, Just maxSize ) ->
2950− "minmax(" ++ String.fromInt minSize ++ "px, " ++ String.fromInt maxSize ++ "px)"
2951−
2952− Min m len ->
2953− toGridLengthHelper (Just m) maximum len
2954−
2955− Max m len ->
2956− toGridLengthHelper minimum (Just m) len
2957−
2958− msColumns =
2959− template.columns
2960− |> List.map toGridLength
2961− |> String.join ySpacing
2962− |> (\x -> "-ms-grid-columns: " ++ x ++ ";")
2963−
2964− msRows =
2965− template.columns
2966− |> List.map toGridLength
2967− |> String.join ySpacing
2968− |> (\x -> "-ms-grid-rows: " ++ x ++ ";")
2969−
2970− base =
2971− class ++ "{" ++ msColumns ++ msRows ++ "}"
2972−
2973− columns =
2974− template.columns
2975− |> List.map toGridLength
2976− |> String.join " "
2977− |> (\x -> "grid-template-columns: " ++ x ++ ";")
2978
2424
2979− rows =
2425+ PseudoSelector class styles ->
2980− template.rows
2426+ let
2981− |> List.map toGridLength
2427+ renderPseudoRule style =
2428+ renderStyleRule style (Just class)
2429+ in
2430+ List.map renderPseudoRule styles
2982 |> String.join " "
2431 |> String.join " "
2983− |> (\x -> "grid-template-rows: " ++ x ++ ";")
2984−
2985− gapX =
2986− "grid-column-gap:" ++ toGridLength (Tuple.first template.spacing) ++ ";"
2987
2432
2988− gapY =
2433+ Transform transform ->
2989− "grid-row-gap:" ++ toGridLength (Tuple.second template.spacing) ++ ";"
2990−
2991− modernGrid =
2992− class ++ "{" ++ columns ++ rows ++ gapX ++ gapY ++ "}"
2993−
2994− supports =
2995− "@supports (display:grid) {" ++ modernGrid ++ "}"
2996− in
2997− [ base
2998− , supports
2999− ]
3000−
3001− GridPosition position ->
3002− let
2434+ let
3003− class =
2435+ val =
3004− ".grid-pos-"
2436+ transformValue transform
3005− ++ String.fromInt position.row
3006− ++ "-"
3007− ++ String.fromInt position.col
3008− ++ "-"
3009− ++ String.fromInt position.width
3010− ++ "-"
3011− ++ String.fromInt position.height
3012−
3013− msPosition =
3014− String.join " "
3015− [ "-ms-grid-row: "
3016− ++ String.fromInt position.row
3017− ++ ";"
3018− , "-ms-grid-row-span: "
3019− ++ String.fromInt position.height
3020− ++ ";"
3021− , "-ms-grid-column: "
3022− ++ String.fromInt position.col
3023− ++ ";"
3024− , "-ms-grid-column-span: "
3025− ++ String.fromInt position.width
3026− ++ ";"
3027− ]
3028−
3029− base =
3030− class ++ "{" ++ msPosition ++ "}"
3031−
3032− modernPosition =
3033− String.join " "
3034− [ "grid-row: "
3035− ++ String.fromInt position.row
3036− ++ " / "
3037− ++ String.fromInt (position.row + position.height)
3038− ++ ";"
3039− , "grid-column: "
3040− ++ String.fromInt position.col
3041− ++ " / "
3042− ++ String.fromInt (position.col + position.width)
3043− ++ ";"
3044− ]
3045−
3046− modernGrid =
3047− class ++ "{" ++ modernPosition ++ "}"
3048−
3049− supports =
3050− "@supports (display:grid) {" ++ modernGrid ++ "}"
3051− in
3052− [ base
3053− , supports
3054− ]
3055
2437
3056− PseudoSelector class styles ->
2438+ class =
3057− let
2439+ transformClass transform
3058− renderPseudoRule style =
3059− renderStyleRule options style (Just class)
3060− in
2440+ in
3061− List.concatMap renderPseudoRule styles
2441+ case ( class, val ) of
2442+ ( Just cls, Just v ) ->
2443+ renderStyle
2444+ maybePseudo
2445+ ("." ++ cls)
2446+ [ Property "transform"
2447+ v
2448+ ]
3062
2449
3063− Transform transform ->
2450+ _ ->
3064− let
2451+ ""
3065− val =
3066− transformValue transform
3067
2452
3068− class =
2453+ combine style rendered =
3069− transformClass transform
2454+ { rendered
3070− in
2455+ | rules = rendered.rules ++ renderStyleRule style Nothing
3071− case ( class, val ) of
2456+ , topLevel =
3072− ( Just cls, Just v ) ->
2457+ case renderTopLevels style of
3073− renderStyle options
2458+ Nothing ->
3074− maybePseudo
2459+ rendered.topLevel
3075− ("." ++ cls)
3076− [ Property "transform"
3077− v
3078− ]
3079
2460
3080− _ ->
2461+ Just topLevel ->
3081− []
2462+ rendered.topLevel ++ topLevel
2463+ }
2464+ in
2465+ case List.foldl combine { rules = "", topLevel = "" } stylesheet of
2466+ { topLevel, rules } ->
2467+ topLevel ++ rules
3082
2468
3083
2469
3084lengthClassName : Length -> String
2470lengthClassName : Length -> String
@@ -3118,12 +2504,12 @@ formatTextShadow shadow =
3118 ]
2504 ]
3119
2505
3120
2506
3121−textShadowClass shadow =
2507+textShadowName shadow =
3122 String.concat
2508 String.concat
3123 [ "txt"
2509 [ "txt"
3124− , floatClass (Tuple.first shadow.offset) ++ "px"
2510+ , String.fromFloat (Tuple.first shadow.offset) ++ "px"
3125− , floatClass (Tuple.second shadow.offset) ++ "px"
2511+ , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3126− , floatClass shadow.blur ++ "px"
2512+ , String.fromFloat shadow.blur ++ "px"
3127 , formatColorClass shadow.color
2513 , formatColorClass shadow.color
3128 ]
2514 ]
3129
2515
@@ -3133,7 +2519,6 @@ formatBoxShadow shadow =
3133 List.filterMap identity
2519 List.filterMap identity
3134 [ if shadow.inset then
2520 [ if shadow.inset then
3135 Just "inset"
2521 Just "inset"
3136−
3137 else
2522 else
3138 Nothing
2523 Nothing
3139 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
2524 , Just <| String.fromFloat (Tuple.first shadow.offset) ++ "px"
@@ -3144,17 +2529,16 @@ formatBoxShadow shadow =
3144 ]
2529 ]
3145
2530
3146
2531
3147−boxShadowClass shadow =
2532+boxShadowName shadow =
3148 String.concat <|
2533 String.concat <|
3149 [ if shadow.inset then
2534 [ if shadow.inset then
3150 "box-inset"
2535 "box-inset"
3151−
3152 else
2536 else
3153 "box-"
2537 "box-"
3154− , floatClass (Tuple.first shadow.offset) ++ "px"
2538+ , String.fromFloat (Tuple.first shadow.offset) ++ "px"
3155− , floatClass (Tuple.second shadow.offset) ++ "px"
2539+ , String.fromFloat (Tuple.second shadow.offset) ++ "px"
3156− , floatClass shadow.blur ++ "px"
2540+ , String.fromFloat shadow.blur ++ "px"
3157− , floatClass shadow.size ++ "px"
2541+ , String.fromFloat shadow.size ++ "px"
3158 , formatColorClass shadow.color
2542 , formatColorClass shadow.color
3159 ]
2543 ]
3160
2544
@@ -3199,17 +2583,6 @@ paddingName top right bottom left =
3199 ++ String.fromInt left
2583 ++ String.fromInt left
3200
2584
3201
2585
3202−paddingNameFloat top right bottom left =
3203− "pad-"
3204− ++ floatClass top
3205− ++ "-"
3206− ++ floatClass right
3207− ++ "-"
3208− ++ floatClass bottom
3209− ++ "-"
3210− ++ floatClass left
3211−
3212−
3213getStyleName : Style -> String
2586getStyleName : Style -> String
3214getStyleName style =
2587getStyleName style =
3215 case style of
2588 case style of
@@ -3240,9 +2613,6 @@ getStyleName style =
3240 PaddingStyle cls top right bottom left ->
2613 PaddingStyle cls top right bottom left ->
3241 cls
2614 cls
3242
2615
3243− BorderWidth cls top right bottom left ->
3244− cls
3245−
3246 GridTemplateStyle template ->
2616 GridTemplateStyle template ->
3247 "grid-rows-"
2617 "grid-rows-"
3248 ++ String.join "-" (List.map lengthClassName template.rows)
2618 ++ String.join "-" (List.map lengthClassName template.rows)
@@ -3475,76 +2845,3 @@ onlyStyles attr =
3475
2845
3476 _ ->
2846 _ ->
3477 Nothing
2847 Nothing
3478−
3479−
3480−
3481−{- Font Adjustments -}
3482−
3483−
3484−convertAdjustment adjustment =
3485− let
3486− lineHeight =
3487− 1.5
3488−
3489− base =
3490− lineHeight
3491−
3492− normalDescender =
3493− (lineHeight - 1)
3494− / 2
3495−
3496− oldMiddle =
3497− lineHeight / 2
3498−
3499− newCapitalMiddle =
3500− ((ascender - newBaseline) / 2) + newBaseline
3501−
3502− newFullMiddle =
3503− ((ascender - descender) / 2) + descender
3504−
3505− lines =
3506− [ adjustment.capital
3507− , adjustment.baseline
3508− , adjustment.descender
3509− , adjustment.lowercase
3510− ]
3511−
3512− ascender =
3513− Maybe.withDefault adjustment.capital (List.maximum lines)
3514−
3515− descender =
3516− Maybe.withDefault adjustment.descender (List.minimum lines)
3517−
3518− newBaseline =
3519− lines
3520− |> List.filter (\x -> x /= descender)
3521− |> List.minimum
3522− |> Maybe.withDefault adjustment.baseline
3523−
3524− capitalVertical =
3525− 1 - ascender
3526−
3527− capitalSize =
3528− 1 / (ascender - newBaseline)
3529−
3530− fullSize =
3531− 1 / (ascender - descender)
3532−
3533− fullVertical =
3534− 1 - ascender
3535−
3536− -- (oldMiddle - newFullMiddle) * 2
3537− in
3538− { full =
3539− adjust fullSize (ascender - descender) fullVertical
3540− , capital =
3541− adjust capitalSize (ascender - newBaseline) capitalVertical
3542− }
3543−
3544−
3545−adjust size height vertical =
3546− { vertical = vertical
3547− , height =
3548− height / size
3549− , size = size
3550− }
src/Internal/Style.elm+197−367
@@ -10,7 +10,6 @@ type Class
10type Rule
10type Rule
11 = Prop String String
11 = Prop String String
12 | Child String (List Rule)
12 | Child String (List Rule)
13− | AllChildren String (List Rule)
14 | Supports ( String, String ) (List ( String, String ))
13 | Supports ( String, String ) (List ( String, String ))
15 | Descriptor String (List Rule)
14 | Descriptor String (List Rule)
16 | Adjacent String (List Rule)
15 | Adjacent String (List Rule)
@@ -149,12 +148,10 @@ classes =
149 , widthFillPortion = "wfp"
148 , widthFillPortion = "wfp"
150 , heightFill = "hf"
149 , heightFill = "hf"
151 , heightContent = "hc"
150 , heightContent = "hc"
152− , heightExact = "he"
153 , heightFillPortion = "hfp"
151 , heightFillPortion = "hfp"
154 , seButton = "sbt"
152 , seButton = "sbt"
155
153
156 -- nearby elements
154 -- nearby elements
157− , nearby = "nb"
158 , above = "a"
155 , above = "a"
159 , below = "b"
156 , below = "b"
160 , onRight = "or"
157 , onRight = "or"
@@ -206,7 +203,6 @@ classes =
206
203
207 -- , hoverOpaque = "hover-opaque"
204 -- , hoverOpaque = "hover-opaque"
208 , focus = "fcs"
205 , focus = "fcs"
209− , focusedWithin = "focus-within"
210
206
211 -- , focusOpaque = "focus-opaque"
207 -- , focusOpaque = "focus-opaque"
212 , active = "atv"
208 , active = "atv"
@@ -227,8 +223,6 @@ classes =
227 , borderSolid = "bs"
223 , borderSolid = "bs"
228
224
229 -- text weight
225 -- text weight
230− , sizeByCapital = "cap"
231− , fullSize = "fs"
232 , textThin = "w1"
226 , textThin = "w1"
233 , textExtraLight = "w2"
227 , textExtraLight = "w2"
234 , textLight = "w3"
228 , textLight = "w3"
@@ -254,13 +248,6 @@ classes =
254 -- inputText
248 -- inputText
255 , inputText = "it"
249 , inputText = "it"
256 , inputMultiline = "iml"
250 , inputMultiline = "iml"
257− , inputMultilineParent = "imlp"
258− , inputMultilineFiller = "imlf"
259− , inputMultilineWrapper = "implw"
260− , inputLabel = "lbl"
261−
262− -- link
263− , link = "lnk"
264 }
251 }
265
252
266
253
@@ -562,15 +549,6 @@ renderRules (Intermediate parent) rulesToRender =
562 :: rendered.others
549 :: rendered.others
563 }
550 }
564
551
565− AllChildren child childRules ->
566− { rendered
567− | others =
568− renderRules
569− (emptyIntermediate (parent.selector ++ " " ++ child) "")
570− childRules
571− :: rendered.others
572− }
573−
574 Descriptor descriptor descriptorRules ->
552 Descriptor descriptor descriptorRules ->
575 { rendered
553 { rendered
576 | others =
554 | others =
@@ -699,30 +677,18 @@ overrides =
699 ++ dot classes.any
677 ++ dot classes.any
700 ++ dot classes.container
678 ++ dot classes.container
701 ++ " { flex-basis: auto !important; }}"
679 ++ " { flex-basis: auto !important; }}"
702− ++ inputTextReset
680+ ++ sliderOverrides
703− ++ sliderReset
704− ++ trackReset
705− ++ thumbReset
706 ++ explainer
681 ++ explainer
707
682
708
683
709−inputTextReset =
684+sliderOverrides =
710 """
685 """
711−input[type="search"],
712−input[type="search"]::-webkit-search-decoration,
713−input[type="search"]::-webkit-search-cancel-button,
714−input[type="search"]::-webkit-search-results-button,
715−input[type="search"]::-webkit-search-results-decoration {
716− -webkit-appearance:none;
717−}
718−"""
719
686
720−
687+/* General Input Reset */
721−sliderReset =
722− """
723input[type=range] {
688input[type=range] {
724− -webkit-appearance: none;
689+ -webkit-appearance: none; /* Hides the slider so that custom slider can be made */
690+ /* width: 100%; Specific width is required for Firefox. */
725− background: transparent;
691+ background: transparent; /* Otherwise white in Chrome */
726 position:absolute;
692 position:absolute;
727 left:0;
693 left:0;
728 top:0;
694 top:0;
@@ -732,11 +698,8 @@ input[type=range] {
732 height: 100%;
698 height: 100%;
733 opacity: 0;
699 opacity: 0;
734}
700}
735−"""
736
701
737−
702+/* Hide all syling for track */
738−trackReset =
739− """
740input[type=range]::-moz-range-track {
703input[type=range]::-moz-range-track {
741 background: transparent;
704 background: transparent;
742 cursor: pointer;
705 cursor: pointer;
@@ -749,11 +712,8 @@ input[type=range]::-webkit-slider-runnable-track {
749 background: transparent;
712 background: transparent;
750 cursor: pointer;
713 cursor: pointer;
751}
714}
752−"""
753−
754
715
755−thumbReset =
716+/* Thumbs */
756− """
757input[type=range]::-webkit-slider-thumb {
717input[type=range]::-webkit-slider-thumb {
758 -webkit-appearance: none;
718 -webkit-appearance: none;
759 opacity: 0.5;
719 opacity: 0.5;
@@ -822,36 +782,7 @@ commonValues =
822 Class (".p-" ++ String.fromInt i) [ Prop "padding" (String.fromInt i ++ "px") ]
782 Class (".p-" ++ String.fromInt i) [ Prop "padding" (String.fromInt i ++ "px") ]
823 )
783 )
824 (List.range 0 24)
784 (List.range 0 24)
825−
826− -- Common Font Variants
827− , [ Class ".v-smcp"
828− [ Prop "font-variant" "small-caps"
829− ]
830− , Class ".v-smcp-off"
831− [ Prop "font-variant" "normal"
832− ]
833− ]
834−
835− -- , fontVariant "smcp"
836− , fontVariant "zero"
837− , fontVariant "onum"
838− , fontVariant "liga"
839− , fontVariant "dlig"
840− , fontVariant "ordn"
841− , fontVariant "tnum"
842− , fontVariant "afrc"
843− , fontVariant "frac"
844− ]
845−
846−
847−fontVariant var =
848− [ Class (".v-" ++ var)
849− [ Prop "font-feature-settings" ("\"" ++ var ++ "\"")
850− ]
851− , Class (".v-" ++ var ++ "-off")
852− [ Prop "font-feature-settings" ("\"" ++ var ++ "\" 0")
853 ]
785 ]
854− ]
855
786
856
787
857rules : String
788rules : String
@@ -860,99 +791,6 @@ rules =
860 ++ renderCompact (baseSheet ++ commonValues)
791 ++ renderCompact (baseSheet ++ commonValues)
861
792
862
793
863−elDescription =
864− [ Prop "display" "flex"
865− , Prop "flex-direction" "column"
866− , Prop "white-space" "pre"
867− , Descriptor (dot classes.hasBehind)
868− [ Prop "z-index" "0"
869− , Child (dot classes.behind)
870− [ Prop "z-index" "-1"
871− ]
872− ]
873− , Descriptor (dot classes.seButton)
874− -- Special default for text in a button.
875− -- This is overridden is they put the text inside an `el`
876− [ Child (dot classes.text)
877− [ Descriptor (dot classes.heightFill)
878− [ Prop "flex-grow" "0"
879− ]
880− , Descriptor (dot classes.widthFill)
881− [ Prop "align-self" "auto !important"
882− ]
883− ]
884− ]
885− , Child (dot classes.heightContent)
886− [ Prop "height" "auto"
887− ]
888− , Child (dot classes.heightFill)
889− [ Prop "flex-grow" "100000"
890− ]
891− , Child (dot classes.widthFill)
892− [ -- alignLeft, alignRight, centerX are overridden by width.
893− -- Prop "align-self" "stretch !important"
894− Prop "width" "100%"
895− ]
896− , Child (dot classes.widthFillPortion)
897− [ Prop "width" "100%"
898− ]
899− , Child (dot classes.widthContent)
900− [ Prop "align-self" "flex-start"
901− ]
902−
903− -- , Child (dot classes.widthFill)
904− -- [ Prop "align-self" "stretch"
905− -- , Descriptor (dot classes.alignedHorizontally)
906− -- [ Prop "width" "100%"
907− -- ]
908− -- ]
909− , describeAlignment <|
910− \alignment ->
911− case alignment of
912− Top ->
913− ( [ Prop "justify-content" "flex-start" ]
914− , [ Prop "margin-bottom" "auto !important"
915− , Prop "margin-top" "0 !important"
916− ]
917− )
918−
919− Bottom ->
920− ( [ Prop "justify-content" "flex-end" ]
921− , [ Prop "margin-top" "auto !important"
922− , Prop "margin-bottom" "0 !important"
923− ]
924− )
925−
926− Right ->
927− ( [ Prop "align-items" "flex-end" ]
928− , [ Prop "align-self" "flex-end" ]
929− )
930−
931− Left ->
932− ( [ Prop "align-items" "flex-start" ]
933− , [ Prop "align-self" "flex-start" ]
934− )
935−
936− CenterX ->
937− ( [ Prop "align-items" "center" ]
938− , [ Prop "align-self" "center"
939− ]
940− )
941−
942− CenterY ->
943− ( [ -- Prop "justify-content" "center"
944− Child (dot classes.any)
945− [ Prop "margin-top" "auto"
946− , Prop "margin-bottom" "auto"
947− ]
948− ]
949− , [ Prop "margin-top" "auto !important"
950− , Prop "margin-bottom" "auto !important"
951− ]
952− )
953− ]
954−
955−
956baseSheet =
794baseSheet =
957 [ Class "html,body"
795 [ Class "html,body"
958 [ Prop "height" "100%"
796 [ Prop "height" "100%"
@@ -961,18 +799,6 @@ baseSheet =
961 ]
799 ]
962 , Class (dot classes.any ++ dot classes.single ++ dot classes.imageContainer)
800 , Class (dot classes.any ++ dot classes.single ++ dot classes.imageContainer)
963 [ Prop "display" "block"
801 [ Prop "display" "block"
964− , Descriptor (dot classes.heightFill)
965− [ Child "img"
966− [ Prop "max-height" "100%"
967− , Prop "object-fit" "cover"
968− ]
969− ]
970− , Descriptor (dot classes.widthFill)
971− [ Child "img"
972− [ Prop "max-width" "100%"
973− , Prop "object-fit" "cover"
974− ]
975− ]
976 ]
802 ]
977 , Class (dot classes.any ++ ":focus")
803 , Class (dot classes.any ++ ":focus")
978 [ Prop "outline" "none"
804 [ Prop "outline" "none"
@@ -993,119 +819,11 @@ baseSheet =
993 ]
819 ]
994 ]
820 ]
995 , Child (dot classes.inFront)
821 , Child (dot classes.inFront)
996− [ Descriptor (dot classes.nearby)
822+ [ Descriptor (dot classes.any)
997 [ Prop "position" "fixed"
823 [ Prop "position" "fixed"
998− , Prop "z-index" "20"
999 ]
824 ]
1000 ]
825 ]
1001 ]
826 ]
1002− , Class (dot classes.nearby)
1003− [ Prop "position" "relative"
1004− , Prop "border" "none"
1005− , Prop "display" "flex"
1006− , Prop "flex-direction" "row"
1007− , Prop "flex-basis" "auto"
1008− , Descriptor (dot classes.single)
1009− elDescription
1010− , Batch <|
1011− (\fn -> List.map fn locations) <|
1012− \loc ->
1013− case loc of
1014− Above ->
1015− Descriptor (dot classes.above)
1016− [ Prop "position" "absolute"
1017− , Prop "bottom" "100%"
1018− , Prop "left" "0"
1019− , Prop "width" "100%"
1020− , Prop "z-index" "20"
1021− , Prop "margin" "0 !important"
1022− , Child (dot classes.heightFill)
1023− [ Prop "height" "auto"
1024− ]
1025− , Child (dot classes.widthFill)
1026− [ Prop "width" "100%"
1027− ]
1028− , Prop "pointer-events" "none"
1029− , Child "*"
1030− [ Prop "pointer-events" "auto"
1031− ]
1032− ]
1033−
1034− Below ->
1035− Descriptor (dot classes.below)
1036− [ Prop "position" "absolute"
1037− , Prop "bottom" "0"
1038− , Prop "left" "0"
1039− , Prop "height" "0"
1040− , Prop "width" "100%"
1041− , Prop "z-index" "20"
1042− , Prop "margin" "0 !important"
1043− , Prop "pointer-events" "none"
1044− , Child "*"
1045− [ Prop "pointer-events" "auto"
1046− ]
1047− , Child (dot classes.heightFill)
1048− [ Prop "height" "auto"
1049− ]
1050− ]
1051−
1052− OnRight ->
1053− Descriptor (dot classes.onRight)
1054− [ Prop "position" "absolute"
1055− , Prop "left" "100%"
1056− , Prop "top" "0"
1057− , Prop "height" "100%"
1058− , Prop "margin" "0 !important"
1059− , Prop "z-index" "20"
1060− , Prop "pointer-events" "none"
1061− , Child "*"
1062− [ Prop "pointer-events" "auto"
1063− ]
1064− ]
1065−
1066− OnLeft ->
1067− Descriptor (dot classes.onLeft)
1068− [ Prop "position" "absolute"
1069− , Prop "right" "100%"
1070− , Prop "top" "0"
1071− , Prop "height" "100%"
1072− , Prop "margin" "0 !important"
1073− , Prop "z-index" "20"
1074− , Prop "pointer-events" "none"
1075− , Child "*"
1076− [ Prop "pointer-events" "auto"
1077− ]
1078− ]
1079−
1080− Within ->
1081− Descriptor (dot classes.inFront)
1082− [ Prop "position" "absolute"
1083− , Prop "width" "100%"
1084− , Prop "height" "100%"
1085− , Prop "left" "0"
1086− , Prop "top" "0"
1087− , Prop "margin" "0 !important"
1088− , Prop "pointer-events" "none"
1089− , Child "*"
1090− [ Prop "pointer-events" "auto"
1091− ]
1092− ]
1093−
1094− Behind ->
1095− Descriptor (dot classes.behind)
1096− [ Prop "position" "absolute"
1097− , Prop "width" "100%"
1098− , Prop "height" "100%"
1099− , Prop "left" "0"
1100− , Prop "top" "0"
1101− , Prop "margin" "0 !important"
1102− , Prop "z-index" "0"
1103− , Prop "pointer-events" "none"
1104− , Child "*"
1105− [ Prop "pointer-events" "auto"
1106− ]
1107− ]
1108− ]
1109 , Class (dot classes.any)
827 , Class (dot classes.any)
1110 [ Prop "position" "relative"
828 [ Prop "position" "relative"
1111 , Prop "border" "none"
829 , Prop "border" "none"
@@ -1114,7 +832,6 @@ baseSheet =
1114 , Prop "flex-direction" "row"
832 , Prop "flex-direction" "row"
1115 , Prop "flex-basis" "auto"
833 , Prop "flex-basis" "auto"
1116 , Prop "resize" "none"
834 , Prop "resize" "none"
1117− , Prop "font-feature-settings" "inherit"
1118
835
1119 -- , Prop "flex-basis" "0%"
836 -- , Prop "flex-basis" "0%"
1120 , Prop "box-sizing" "border-box"
837 , Prop "box-sizing" "border-box"
@@ -1127,6 +844,8 @@ baseSheet =
1127 , Prop "font-size" "inherit"
844 , Prop "font-size" "inherit"
1128 , Prop "color" "inherit"
845 , Prop "color" "inherit"
1129 , Prop "font-family" "inherit"
846 , Prop "font-family" "inherit"
847+
848+ -- , Prop "line-height" "inherit"
1130 , Prop "line-height" "1"
849 , Prop "line-height" "1"
1131 , Prop "font-weight" "inherit"
850 , Prop "font-weight" "inherit"
1132
851
@@ -1243,11 +962,95 @@ baseSheet =
1243 -- chrome and safari have a minimum recognized line height for text input of 1.05
962 -- chrome and safari have a minimum recognized line height for text input of 1.05
1244 -- If it's 1, it bumps up to something like 1.2
963 -- If it's 1, it bumps up to something like 1.2
1245 [ Prop "line-height" "1.05"
964 [ Prop "line-height" "1.05"
1246− , Prop "background" "transparent"
1247− , Prop "text-align" "inherit"
1248 ]
965 ]
1249 , Descriptor (dot classes.single)
966 , Descriptor (dot classes.single)
1250− elDescription
967+ [ Prop "display" "flex"
968+ , Prop "flex-direction" "column"
969+ , Prop "white-space" "pre"
970+ , Descriptor (dot classes.hasBehind)
971+ [ Prop "z-index" "0"
972+ , Child (dot classes.behind)
973+ [ Prop "z-index" "-1"
974+ ]
975+ ]
976+ , Descriptor (dot classes.seButton)
977+ -- Special default for text in a button.
978+ -- This is overridden is they put the text inside an `el`
979+ [ Child (dot classes.text)
980+ [ Descriptor (dot classes.heightFill)
981+ [ Prop "flex-grow" "0"
982+ ]
983+ , Descriptor (dot classes.widthFill)
984+ [ Prop "align-self" "auto !important"
985+ ]
986+ ]
987+ ]
988+ , Child (dot classes.heightContent)
989+ [ Prop "height" "auto"
990+ ]
991+ , Child (dot classes.heightFill)
992+ [ Prop "flex-grow" "100000"
993+ ]
994+ , Child (dot classes.widthFill)
995+ [ -- alignLeft, alignRight, centerX are overridden by width.
996+ -- Prop "align-self" "stretch !important"
997+ Prop "width" "100%"
998+ ]
999+ , Child (dot classes.widthContent)
1000+ [ Prop "align-self" "flex-start"
1001+ ]
1002+
1003+ -- , Child (dot classes.widthFill)
1004+ -- [ Prop "align-self" "stretch"
1005+ -- , Descriptor (dot classes.alignedHorizontally)
1006+ -- [ Prop "width" "100%"
1007+ -- ]
1008+ -- ]
1009+ , describeAlignment <|
1010+ \alignment ->
1011+ case alignment of
1012+ Top ->
1013+ ( [ Prop "justify-content" "flex-start" ]
1014+ , [ Prop "margin-bottom" "auto !important"
1015+ , Prop "margin-top" "0 !important"
1016+ ]
1017+ )
1018+
1019+ Bottom ->
1020+ ( [ Prop "justify-content" "flex-end" ]
1021+ , [ Prop "margin-top" "auto !important"
1022+ , Prop "margin-bottom" "0 !important"
1023+ ]
1024+ )
1025+
1026+ Right ->
1027+ ( [ Prop "align-items" "flex-end" ]
1028+ , [ Prop "align-self" "flex-end" ]
1029+ )
1030+
1031+ Left ->
1032+ ( [ Prop "align-items" "flex-start" ]
1033+ , [ Prop "align-self" "flex-start" ]
1034+ )
1035+
1036+ CenterX ->
1037+ ( [ Prop "align-items" "center" ]
1038+ , [ Prop "align-self" "center"
1039+ ]
1040+ )
1041+
1042+ CenterY ->
1043+ ( [ -- Prop "justify-content" "center"
1044+ Child (dot classes.any)
1045+ [ Prop "margin-top" "auto"
1046+ , Prop "margin-bottom" "auto"
1047+ ]
1048+ ]
1049+ , [ Prop "margin-top" "auto !important"
1050+ , Prop "margin-bottom" "auto !important"
1051+ ]
1052+ )
1053+ ]
1251 , Descriptor (dot classes.row)
1054 , Descriptor (dot classes.row)
1252 [ Prop "display" "flex"
1055 [ Prop "display" "flex"
1253 , Prop "flex-direction" "row"
1056 , Prop "flex-direction" "row"
@@ -1256,16 +1059,15 @@ baseSheet =
1256 , Descriptor (dot classes.widthExact)
1059 , Descriptor (dot classes.widthExact)
1257 [ Prop "flex-basis" "auto"
1060 [ Prop "flex-basis" "auto"
1258 ]
1061 ]
1259− , Descriptor (dot classes.link)
1260− [ Prop "flex-basis" "auto"
1261− ]
1262 ]
1062 ]
1263 , Child (dot classes.heightFill)
1063 , Child (dot classes.heightFill)
1064+ [ --Prop "height" "100%"
1264− [ -- alignTop, centerY, and alignBottom need to be disabled
1065+ -- alignTop, centerY, and alignBottom need to be disabled
1265 Prop "align-self" "stretch !important"
1066 Prop "align-self" "stretch !important"
1266 ]
1067 ]
1267 , Child (dot classes.heightFillPortion)
1068 , Child (dot classes.heightFillPortion)
1069+ [ --Prop "height" "100%"
1268− [ -- alignTop, centerY, and alignBottom need to be disabled
1070+ -- alignTop, centerY, and alignBottom need to be disabled
1269 Prop "align-self" "stretch !important"
1071 Prop "align-self" "stretch !important"
1270 ]
1072 ]
1271
1073
@@ -1371,29 +1173,10 @@ baseSheet =
1371 , Descriptor (dot classes.spaceEvenly)
1173 , Descriptor (dot classes.spaceEvenly)
1372 [ Prop "justify-content" "space-between"
1174 [ Prop "justify-content" "space-between"
1373 ]
1175 ]
1374− , Descriptor (dot classes.inputLabel)
1375− [ Prop "align-items" "baseline"
1376− ]
1377 ]
1176 ]
1378 , Descriptor (dot classes.column)
1177 , Descriptor (dot classes.column)
1379 [ Prop "display" "flex"
1178 [ Prop "display" "flex"
1380 , Prop "flex-direction" "column"
1179 , Prop "flex-direction" "column"
1381− , Child (dot classes.any)
1382− -- *Note* - While rows have flex-basis 0%,
1383− -- which allows for the children of a row to default to their content size
1384− -- This apparently is a different story for columns.
1385− -- Safari has an issue if this is flex-basis: 0%, as it goes entirely to 0,
1386− -- instead of the expected content size.
1387− -- So we add `min-height: min-content`, which isn't supported by IE, but works for all other browsers!
1388− -- Separately, 0% is different than 0px, but only for columns
1389− -- In columns, 0% will actually be calculated as `auto` for columns
1390− -- So, 0px is the one we want.
1391− [ Prop "flex-basis" "0px"
1392− , Prop "min-height" "min-content"
1393− , Descriptor (dot classes.heightExact)
1394− [ Prop "flex-basis" "auto"
1395− ]
1396− ]
1397 , Child (dot classes.heightFill)
1180 , Child (dot classes.heightFill)
1398 [ Prop "flex-grow" "100000"
1181 [ Prop "flex-grow" "100000"
1399 ]
1182 ]
@@ -1408,7 +1191,7 @@ baseSheet =
1408 Prop "width" "100%"
1191 Prop "width" "100%"
1409 ]
1192 ]
1410
1193
1411− -- TODO:: This might be necessary, maybe it should move to widthFill?
1194+ -- TODO:: THIs might be necessary, maybe it should move to widthFill?
1412 -- , Child (dot classes.widthFill)
1195 -- , Child (dot classes.widthFill)
1413 -- [ Prop "align-self" "stretch"
1196 -- [ Prop "align-self" "stretch"
1414 -- , Descriptor (dot classes.alignedHorizontally)
1197 -- , Descriptor (dot classes.alignedHorizontally)
@@ -1596,67 +1379,24 @@ baseSheet =
1596 )
1379 )
1597 ]
1380 ]
1598 , Descriptor (dot classes.inputMultiline)
1381 , Descriptor (dot classes.inputMultiline)
1599− [ Prop "white-space" "pre-wrap !important"
1382+ [ Prop "white-space" "pre-wrap"
1600− , Prop "height" "100%"
1601− , Prop "width" "100%"
1602− , Prop "background-color" "transparent"
1603− ]
1604− , Descriptor (dot classes.inputMultilineWrapper)
1605− -- Get this.
1606− -- This allows multiline input to anchor scrolling to the bottom of the node
1607− -- when in a scrolling viewport, and the user is adding content.
1608− -- however, it only works in chrome. In firefox, it prevents scrolling.
1609− --
1610− -- But how crazy is this solution?
1611− -- [ Prop "display" "flex"
1612− -- , Prop "flex-direction" "column-reverse"
1613− -- ]
1614− [ -- to increase specificity to beat another rule
1615− Descriptor (dot classes.single)
1616− [ Prop "flex-basis" "auto" ]
1617− ]
1618− , Descriptor (dot classes.inputMultilineParent)
1619− [ Prop "white-space" "pre-wrap !important"
1620− , Prop "cursor" "text"
1621− , Child (dot classes.inputMultilineFiller)
1622− [ Prop "white-space" "pre-wrap !important"
1623− , Prop "color" "transparent"
1624− ]
1625 ]
1383 ]
1626 , Descriptor (dot classes.paragraph)
1384 , Descriptor (dot classes.paragraph)
1627 [ Prop "display" "block"
1385 [ Prop "display" "block"
1628 , Prop "white-space" "normal"
1386 , Prop "white-space" "normal"
1629− , Prop "overflow-wrap" "break-word"
1630 , Descriptor (dot classes.hasBehind)
1387 , Descriptor (dot classes.hasBehind)
1631 [ Prop "z-index" "0"
1388 [ Prop "z-index" "0"
1632 , Child (dot classes.behind)
1389 , Child (dot classes.behind)
1633 [ Prop "z-index" "-1"
1390 [ Prop "z-index" "-1"
1634 ]
1391 ]
1635 ]
1392 ]
1636− , AllChildren (dot classes.text)
1393+ , Child (dot classes.text)
1637 [ Prop "display" "inline"
1394 [ Prop "display" "inline"
1638 , Prop "white-space" "normal"
1395 , Prop "white-space" "normal"
1639 ]
1396 ]
1640− , AllChildren (dot classes.paragraph)
1641− [ Prop "display" "inline"
1642− , Descriptor "::after"
1643− [ Prop "content" "none"
1644− ]
1645− , Descriptor "::before"
1646− [ Prop "content" "none"
1647− ]
1648− ]
1649− , AllChildren (dot classes.single)
1397+ , Child (dot classes.single)
1650 [ Prop "display" "inline"
1398 [ Prop "display" "inline"
1651 , Prop "white-space" "normal"
1399 , Prop "white-space" "normal"
1652−
1653− -- Inline block allows the width of the item to be set
1654− -- but DOES NOT like wrapping text in a standard, normal, sane way.
1655− -- We're sorta counting that if an exact width has been set,
1656− -- people aren't expecting proper text wrapping for this element
1657− , Descriptor (dot classes.widthExact)
1658− [ Prop "display" "inline-block"
1659− ]
1660 , Descriptor (dot classes.inFront)
1400 , Descriptor (dot classes.inFront)
1661 [ Prop "display" "flex"
1401 [ Prop "display" "flex"
1662 ]
1402 ]
@@ -1681,7 +1421,7 @@ baseSheet =
1681 ]
1421 ]
1682 ]
1422 ]
1683 , Child (dot classes.row)
1423 , Child (dot classes.row)
1684− [ Prop "display" "inline"
1424+ [ Prop "display" "inline-flex"
1685 ]
1425 ]
1686 , Child (dot classes.column)
1426 , Child (dot classes.column)
1687 [ Prop "display" "inline-flex"
1427 [ Prop "display" "inline-flex"
@@ -1725,6 +1465,96 @@ baseSheet =
1725 , Descriptor ".hidden"
1465 , Descriptor ".hidden"
1726 [ Prop "display" "none"
1466 [ Prop "display" "none"
1727 ]
1467 ]
1468+ , Batch <|
1469+ (\fn -> List.map fn locations) <|
1470+ \loc ->
1471+ case loc of
1472+ Above ->
1473+ Descriptor (dot classes.above)
1474+ [ Prop "position" "absolute"
1475+ , Prop "bottom" "100%"
1476+ , Prop "left" "0"
1477+ , Prop "width" "100%"
1478+ , Prop "z-index" "10"
1479+ , Prop "margin" "0 !important"
1480+ , Child (dot classes.heightFill)
1481+ [ Prop "height" "auto"
1482+ ]
1483+ , Child (dot classes.widthFill)
1484+ [ Prop "width" "100%"
1485+ ]
1486+ , Prop "pointer-events" "none"
1487+ , Child (dot classes.any)
1488+ [ Prop "pointer-events" "auto"
1489+ ]
1490+ ]
1491+
1492+ Below ->
1493+ Descriptor (dot classes.below)
1494+ [ Prop "position" "absolute"
1495+ , Prop "bottom" "0"
1496+ , Prop "left" "0"
1497+ , Prop "height" "0"
1498+ , Prop "width" "100%"
1499+ , Prop "z-index" "10"
1500+ , Prop "margin" "0 !important"
1501+ , Prop "pointer-events" "auto"
1502+ , Child (dot classes.heightFill)
1503+ [ Prop "height" "auto"
1504+ ]
1505+ ]
1506+
1507+ OnRight ->
1508+ Descriptor (dot classes.onRight)
1509+ [ Prop "position" "absolute"
1510+ , Prop "left" "100%"
1511+ , Prop "top" "0"
1512+ , Prop "height" "100%"
1513+ , Prop "margin" "0 !important"
1514+ , Prop "z-index" "10"
1515+ , Prop "pointer-events" "auto"
1516+ ]
1517+
1518+ OnLeft ->
1519+ Descriptor (dot classes.onLeft)
1520+ [ Prop "position" "absolute"
1521+ , Prop "right" "100%"
1522+ , Prop "top" "0"
1523+ , Prop "height" "100%"
1524+ , Prop "margin" "0 !important"
1525+ , Prop "z-index" "10"
1526+ , Prop "pointer-events" "auto"
1527+ ]
1528+
1529+ Within ->
1530+ Descriptor (dot classes.inFront)
1531+ [ Prop "position" "absolute"
1532+ , Prop "width" "100%"
1533+ , Prop "height" "100%"
1534+ , Prop "left" "0"
1535+ , Prop "top" "0"
1536+ , Prop "margin" "0 !important"
1537+ , Prop "z-index" "10"
1538+ , Prop "pointer-events" "none"
1539+ , Child (dot classes.any)
1540+ [ Prop "pointer-events" "auto"
1541+ ]
1542+ ]
1543+
1544+ Behind ->
1545+ Descriptor (dot classes.behind)
1546+ [ Prop "position" "absolute"
1547+ , Prop "width" "100%"
1548+ , Prop "height" "100%"
1549+ , Prop "left" "0"
1550+ , Prop "top" "0"
1551+ , Prop "margin" "0 !important"
1552+ , Prop "z-index" "0"
1553+ , Prop "pointer-events" "none"
1554+ , Child (dot classes.any)
1555+ [ Prop "pointer-events" "auto"
1556+ ]
1557+ ]
1728 , Descriptor (dot classes.textThin)
1558 , Descriptor (dot classes.textThin)
1729 [ Prop "font-weight" "100"
1559 [ Prop "font-weight" "100"
1730 ]
1560 ]
tests-rendering/automation/build.jsdeleted−90
@@ -1,90 +0,0 @@
1−const fs = require("fs");
2−const path = require("path");
3−const compileToString = require("node-elm-compiler").compileToString;
4−
5−// {
6−// template: "./tests-rendering/automation/templates/gather-styles.html",
7−// target: "./tmp/test.html",
8−// elm: "src/Tests/Run.elm",
9−// replace:
10−// elmOptions: { cwd: "./tests-rendering" },
11−// }
12−
13−async function compile_and_embed(config) {
14− const elm_entry_module = fs.readFileSync(
15− path.join(config.elmOptions.cwd, config.elm),
16− "utf8"
17− );
18−
19− const module_name = elm_entry_module
20− .split(/[\r\n]+/)[0]
21− .match(/module ([A-Za-z0-9\.]+)/i)[1];
22−
23− // we embed the compiled js to avoid having to start a server to read the app.
24− await compileToString([config.elm], config.elmOptions).then(function (
25− compiled_elm_code
26− ) {
27− // console.log(compiled_elm_code);
28− const compiled = fs
29− .readFileSync(config.template, "utf8")
30− .replace(/~~_compiled_elm_code_~~/, () => compiled_elm_code)
31− .replace(/~~_module_name_~~/, () => module_name);
32−
33− fs.writeFileSync(config.target, compiled);
34− });
35−}
36−
37−async function compile_to_string(config) {
38− const elm_entry_module = fs.readFileSync(
39− path.join(config.elmOptions.cwd, config.elm),
40− "utf8"
41− );
42−
43− const module_name = elm_entry_module
44− .split(/[\r\n]+/)[0]
45− .match(/module ([A-Za-z0-9\.]+)/i)[1];
46−
47− const compiled = await compileToString([config.elm], config.elmOptions).then(
48− function (compiled_elm_code) {
49− return fs
50− .readFileSync(config.template, "utf8")
51− .replace(/~~_module_name_~~/g, () => module_name)
52− .replace(/~~_compiled_elm_code_~~/g, () => compiled_elm_code);
53− }
54− );
55− return compiled;
56−}
57−
58−async function get_module_name(config) {
59− const elm_entry_module = fs.readFileSync(
60− path.join(config.cwd, config.elm),
61− "utf8"
62− );
63−
64− const module_name = elm_entry_module
65− .split(/[\r\n]+/)[0]
66− .match(/module ([A-Za-z0-9\.]+)/i)[1];
67− return module_name;
68−}
69−
70−async function create_runner(config) {
71− const elm_entry_module = fs.readFileSync(config.elm, "utf8");
72−
73− let module_name = elm_entry_module
74− .split(/[\r\n]+/)[0]
75− .match(/module ([A-Za-z0-9\.]+)/i)[1];
76−
77− const module_name_sentence = module_name.replace(/([A-Z])/g, " $1");
78−
79− const runner = fs
80− .readFileSync(config.template, "utf8")
81− .replace(/~~_module_name_~~/g, () => module_name)
82− .replace(/~~_module_name_sentence_~~/g, () => module_name_sentence);
83− fs.writeFileSync(config.target, runner);
84−}
85−
86−exports.compile_and_embed = compile_and_embed;
87−
88−exports.create_runner = create_runner;
89−
90−exports.compile_to_string = compile_to_string;
tests-rendering/automation/doc-preview.shdeleted−1
@@ -1 +0,0 @@
1−elm make --docs docs.json
tests-rendering/automation/publish-file.shdeleted−31
@@ -1,31 +0,0 @@
1−# These env variables need to be set before running this script
2−# FILE="test.html"
3−# BUILD="1.1.0"
4−# NAME="development"
5−DIRECTORY='elm-ui-testing'
6−
7−# Check to see if the repo is already cloned locally
8−cd tmp
9−if [ ! -d "$DIRECTORY" ]; then
10− git clone git@github.com:mdgriffith/elm-ui-testing.git
11−else
12− git pull
13−fi
14−mkdir -p "$DIRECTORY/public/tests/$BUILD/$NAME/"
15−cp "$FILE" "$DIRECTORY/public/tests/$BUILD/$NAME/index.html"
16−if [ -z "$(git status --porcelain)" ]; then
17− # Working directory clean
18− echo "No changes need for $BUILD -> $NAME"
19−else
20− cd "$DIRECTORY"
21− # Uncommitted changes
22− git config --global user.email "$GIT_EMAIL"
23− git config --global user.name "$GIT_NAME"
24− git add .
25− git commit -m "Elm UI test for $NAME on $BUILD"
26− git push origin master
27−
28− echo "Files published for for $BUILD -> $NAME"
29−fi
30−
31−
tests-rendering/automation/run.jsdeleted−304
@@ -1,304 +0,0 @@
1−const { Builder, By, Key, until } = require("selenium-webdriver");
2−const chrome = require("selenium-webdriver/chrome");
3−const firefox = require("selenium-webdriver/firefox");
4−const fs = require("fs");
5−const program = require("commander");
6−const path = require("path");
7−const chalk = require("chalk");
8−const childProcess = require("child_process");
9−const compile_and_embed = require("./build.js").compile_and_embed;
10−
11−program
12− .option("-s, --sauce", "run tests on sauce labs")
13− .option("--chrome", "run chrome tests (default)")
14− .option("--firefox", "run firefox tests")
15− .option("--ie", "run ie tests")
16− .option("--edge", "run edge tests")
17− .option("--build [value]", "Set build number for sauce labs")
18− .option("--name [value]", "Set run name for sauce labs")
19− .option("--verbose", "Print out all test results")
20− .option("--headless", "run tests without showing the browser")
21− .parse(process.argv);
22−
23−// 'Windows 10'
24−
25−const windows = {
26− chrome: {
27− platform: "Windows 10",
28− browser: "chrome",
29− browserVersion: "latest",
30− },
31− firefox: {
32− platform: "Windows 10",
33− browser: "firefox",
34− browserVersion: "latest",
35− },
36− edge: {
37− platform: "Windows 10",
38− browser: "MicrosoftEdge",
39− browserVersion: "latest",
40− },
41− ie: {
42− platform: "Windows 10",
43− browser: "internet explorer",
44− browserVersion: "latest",
45− },
46−};
47−
48−const all_windows = [
49− windows.chrome,
50− windows.firefox,
51− windows.edge,
52− // i.e. takes forever and seems to make selenium timeout :/
53− // not really sure how to extend the timeout.
54− // , windows.ie
55−];
56−
57−// "macOS 10.14"
58−const osx = {
59− chrome: {
60− platform: "macOS 10.14",
61− browser: "chrome",
62− browserVersion: "latest",
63− },
64− firefox: {
65− platform: "macOS 10.14",
66− browser: "firefox",
67− browserVersion: "latest",
68− },
69− safari: {
70− platform: "macOS 10.14",
71− browser: "safari",
72− browserVersion: "latest",
73− },
74−};
75−
76−const all_osx = [osx.safari];
77−
78−const all_browsers = all_windows.concat(all_osx);
79−
80−function prepare_all_envs(config) {
81− var envs = [];
82−
83− for (i = 0; i < all_browsers.length; i++) {
84− envs.push({
85− browser: all_browsers[i].browser,
86− browserVersion: all_browsers[i].browserVersion,
87− platform: all_browsers[i].platform,
88− build: config.build,
89− name: config.name,
90− });
91− }
92−
93− // for (i = 0; i < osx.length; i++) {
94− // envs.push({
95− // browser: osx[i].browser,
96− // browserVersion: osx[i].browserVersion,
97− // platform: "macOS 10.14",
98− // build: config.build,
99− // name: config.name,
100− // });
101− // }
102−
103− return envs;
104−}
105−
106−function prepare_sauce_driver(env) {
107− const username = process.env.SAUCE_USERNAME;
108− const accessKey = process.env.SAUCE_ACCESS_KEY;
109−
110− driver = new Builder()
111− .withCapabilities({
112− browserName: env.browser,
113− platformName: env.platform,
114− browserVersion: env.browserVersion,
115− /* Pass Sauce User Name and Access Key */
116− "sauce:options": {
117− username: username,
118− accessKey: accessKey,
119− build: env.build,
120− name: env.name,
121− },
122− })
123− .usingServer("https://@ondemand.saucelabs.com:443/wd/hub")
124− .build();
125−
126− return driver;
127−}
128−
129−async function prepare_local_driver(env) {
130− const firefoxOptions = new firefox.Options();
131− const chromeOptions = new chrome.Options();
132−
133− if (program.headless) {
134− firefoxOptions.headless();
135− chromeOptions.headless();
136− }
137−
138− let driver = await new Builder()
139− .forBrowser(env.browser)
140− .setChromeOptions(chromeOptions)
141− .setFirefoxOptions(firefoxOptions)
142− .build();
143−
144− return driver;
145−}
146−
147−async function run_test(driver, url) {
148− var results = null;
149− try {
150− await driver
151− .manage()
152− .window()
153− .setRect({ width: 1200, height: 800, x: 0, y: 0 });
154− await driver.get(url);
155− await driver.wait(until.titleIs("tests finished"), 240 * 1000);
156− results = await driver.executeScript("return test_results");
157− } finally {
158− await driver.quit();
159− }
160− return results;
161−}
162−
163−(async () => {
164− var dir = "tmp";
165− if (!fs.existsSync(dir)) {
166− fs.mkdirSync(dir);
167− }
168− console.log("Compiling tests");
169− await compile_and_embed({
170− template: "./tests-rendering/automation/templates/gather-styles.html",
171− target: "./tmp/test.html",
172− elm: "src/Tests/All.elm",
173− elmOptions: { cwd: "./tests-rendering" },
174− });
175− console.log("Done compiling");
176−
177− if (program.sauce) {
178− const build = program.build;
179− const name = program.name;
180−
181− if (build == null || name == null) {
182− throw "A Build and a Name must be specified.";
183− }
184−
185− var results = [];
186−
187− // Publish to netlify
188− childProcess.execSync("sh tests-rendering/automation/publish-file.sh", {
189− env: {
190− FILE: "test.html",
191− BUILD: program.build,
192− NAME: program.name,
193− GIT_EMAIL: "automation@elm-ui.com",
194− GIT_NAME: "Elm UI Automation",
195− HOME: process.env.HOME,
196− SSH_AUTH_SOCK: process.env.SSH_AUTH_SOCK,
197− SSH_AGENT_PID: process.env.SSH_AGENT_PID,
198− },
199− });
200−
201− var url = `http://elm-ui-testing.netlify.com/tests/${program.build}/${program.name}/`;
202− console.log(`Running sauce labs test:`);
203− console.log(` ${url}`);
204−
205− const envs = prepare_all_envs({ build: build, name: name });
206− console.log(envs);
207− var test_runs = [];
208− var test_labels = [];
209− for (i = 0; i < envs.length; i++) {
210− var driver = prepare_sauce_driver(envs[i]);
211− test_runs.push(run_test(driver, url));
212− test_labels.push(envs[i]);
213− }
214− var results = await Promise.all(test_runs);
215− for (i = 0; i < results.length; i++) {
216− print_results(renderEnvName(test_labels[i]), results[i]);
217− }
218− } else {
219− // Run chrome if nothing else is selected
220− if (program.chrome || (!program.chrome && !program.firefox)) {
221− console.log("Running locally on Chrome...");
222− const driver = await prepare_local_driver(osx.chrome);
223− var results = await run_test(
224− driver,
225− "file://" + path.resolve("./tmp/test.html")
226− );
227− print_results("Local Chrome", results);
228− }
229− if (program.firefox) {
230− console.log("Running locally on Firefox...");
231− const driver = await prepare_local_driver(osx.firefox);
232− var results = await run_test(
233− driver,
234− "file://" + path.resolve("./tmp/test.html")
235− );
236− print_results("Local Firefox", results);
237− }
238− if (program.ie) {
239− console.log("Running locally on IE...");
240− const driver = await prepare_local_driver(windows.ie);
241− var results = await run_test(
242− driver,
243− "file://" + path.resolve("./tmp/test.html")
244− );
245− print_results("Local IE", results);
246− }
247− if (program.edge) {
248− console.log("Running locally on Edge...");
249− const driver = await prepare_local_driver(windows.edge);
250− var results = await run_test(
251− driver,
252− "file://" + path.resolve("./tmp/test.html")
253− );
254− print_results("Local Edge", results);
255− }
256− }
257−})();
258−
259−function renderEnvName(env) {
260− return `${env.platform}, ${env.browser} ${env.browserVersion}`;
261−}
262−
263−function print_results(label, tests) {
264− var total_passed = 0;
265− var total_failed = 0;
266− var i;
267− if (program.verbose) {
268− console.log(label);
269− }
270− for (i = 0; i < tests.length; i++) {
271− var passed = 0;
272− var failed = 0;
273− for (j = 0; j < tests[i].results.length; j++) {
274− if (tests[i].results[j].passing) {
275− passed = passed + 1;
276− } else {
277− if (failed == 0) {
278− if (!program.verbose) {
279− console.log(label);
280− }
281− console.log(tests[i].label);
282− }
283− failed = failed + 1;
284− console.log(" " + chalk.red("fail") + " ->");
285− console.log(" " + tests[i].results[j].description);
286− }
287− }
288− total_passed = total_passed + passed;
289− total_failed = total_failed + failed;
290−
291− if (failed != 0) {
292− console.log(chalk.green(` ${passed} tests passed`));
293− console.log(chalk.red(` ${failed} tests failed`));
294− console.log();
295− } else if (program.verbose) {
296− console.log(tests[i].label + chalk.green(` ${passed} tests passed`));
297− }
298− }
299− if (total_failed == 0) {
300− console.log(
301− `${label} -> ` + chalk.green(`All ${total_passed} tests passed`)
302− );
303− }
304−}
tests-rendering/automation/templates/Run.elmdeleted−14
@@ -1,14 +0,0 @@
1−module Tests.Run exposing (main)
2−
3−{-| _NOTE_ this is auto-generated! Notouchy!
4−-}
5−
6−import ~~_module_name_~~
7−import Testable.Runner
8−
9−
10−main : Testable.Runner.TestableProgram
11−main =
12− Testable.Runner.program
13− [ Testable.Runner.rename "~~_module_name_sentence_~~" ~~_module_name_~~.view
14− ]
tests-rendering/automation/templates/gather-styles.htmldeleted−185
@@ -1,185 +0,0 @@
1−<!DOCTYPE html>
2−<html>
3− <head>
4− <meta charset="UTF-8" />
5− <title>Elm UI Rendering Test</title>
6− <script>
7− ~~_compiled_elm_code_~~
8− </script>
9− <script>
10− // Helpers
11− // Calculations for canvas
12− var PIXEL_RATIO = (function () {
13− var ctx = document.createElement("canvas").getContext("2d"),
14− dpr = window.devicePixelRatio || 1,
15− bsr =
16− ctx.webkitBackingStorePixelRatio ||
17− ctx.mozBackingStorePixelRatio ||
18− ctx.msBackingStorePixelRatio ||
19− ctx.oBackingStorePixelRatio ||
20− ctx.backingStorePixelRatio ||
21− 1;
22−
23− return dpr / bsr;
24− })();
25−
26− function createHiDPICanvas(w, h, id, ratio) {
27− if (!ratio) {
28− ratio = PIXEL_RATIO;
29− }
30− let can = document.getElementById(id);
31− can.width = w * ratio;
32− can.height = h * ratio;
33− can.style.width = w + "px";
34− can.style.height = h + "px";
35− can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
36− return can;
37− }
38−
39− function isVisible(id, bbox) {
40− var current = document.getElementById(id);
41− var result = 0;
42− if (current == document.elementFromPoint(bbox["left"], bbox["top"])) {
43− result++;
44− }
45− if (
46− current == document.elementFromPoint(bbox["left"], bbox["bottom"] - 1)
47− ) {
48− result++;
49− }
50− if (
51− current == document.elementFromPoint(bbox["right"] - 1, bbox["top"])
52− ) {
53− result++;
54− }
55− if (
56− current ==
57− document.elementFromPoint(bbox["right"] - 1, bbox["bottom"] - 1)
58− ) {
59− result++;
60− }
61−
62− if (result == 4) {
63− return true;
64− } else {
65− return false;
66− }
67− }
68−
69− function getStyle(element) {
70− var props = [];
71− var style = window.getComputedStyle(element);
72− for (var i = style.length; i--; ) {
73− var name = style.item(i);
74− var value = style.getPropertyValue(name);
75− props.push([name, value]);
76− }
77− return props;
78− }
79−
80− function getBoundingBox(element) {
81− var bbox = element.getBoundingClientRect();
82− var style = window.getComputedStyle(element, null);
83−
84− var padding = {
85− top: parseFloat(style.getPropertyValue("padding-top")),
86− bottom: parseFloat(style.getPropertyValue("padding-bottom")),
87− left: parseFloat(style.getPropertyValue("padding-left")),
88− right: parseFloat(style.getPropertyValue("padding-right")),
89− };
90−
91− return {
92− top: bbox.top,
93− bottom: bbox.bottom,
94− left: bbox.left,
95− right: bbox.right,
96− width: bbox.width,
97− height: bbox.height,
98− padding: padding,
99− };
100− }
101− function getTextMetrics(element) {
102− // Given our element, we want to return the text metrics on the text within.
103− // If it is an element we want to measure:
104− // we want to get the font family
105− // and the font size.
106− // We're going to presume that the font is loaded.
107− let childrenTextMetrics = [];
108− for (i = 0; i < element.children.length; i++) {
109− if (element.children[i].classList.contains("t")) {
110− let style = window.getComputedStyle(element, null);
111− let fontSize = style.getPropertyValue("font-size");
112− let fontFamily = style.getPropertyValue("font-family");
113− let ctx = canvas.getContext("2d");
114−
115− ctx.font = fontSize + " " + fontFamily; //"16px Roboto";
116− let text = ctx.measureText(element.children[i].innerText);
117−
118− childrenTextMetrics.push({
119− actualBoundingBoxAscent: text.actualBoundingBoxAscent,
120− actualBoundingBoxDescent: text.actualBoundingBoxDescent,
121− actualBoundingBoxLeft: text.actualBoundingBoxLeft,
122− actualBoundingBoxRight: text.actualBoundingBoxRight,
123− width: text.width,
124− });
125− }
126− }
127− return childrenTextMetrics;
128− }
129− </script>
130− </head>
131− <style></style>
132− <body id="root">
133− <body id="root">
134− <div id="elm-home"></div>
135− <canvas id="canvas"></canvas>
136− </body>
137− </body>
138−
139− <script type="text/javascript">
140− // Starting Elm App,
141− var app = Elm.~~_module_name_~~.init({
142− node: document.getElementById("elm-home"),
143− });
144−
145− // create a canvas for text measurements
146− let canvas = createHiDPICanvas(200, 100, "canvas");
147−
148− var test_results = "waiting..";
149−
150− app.ports.report.subscribe(function (results) {
151− test_results = results;
152− // NOTE - this is the signal to the automation that it is cool to retrieve results now
153− // So don't remove this like you did before :D
154− document.title = "tests finished";
155− });
156−
157− app.ports.analyze.subscribe(function (ids) {
158− // ids : List String
159− var idsLength = ids.length;
160− var results = [];
161− for (var i = 0; i < idsLength; i++) {
162− var id = ids[i];
163− var element = document.getElementById(id);
164− if (element == null) {
165− console.log("id " + id + " not found");
166− }
167− var style = getStyle(element);
168− var bbox = getBoundingBox(element);
169− var metrics = getTextMetrics(element);
170−
171− var visible = isVisible(id, bbox);
172−
173− var result = {
174− textMetrics: metrics,
175− bbox: bbox,
176− style: style,
177− id: id,
178− isVisible: visible,
179− };
180− results.push(result);
181− }
182− app.ports.styles.send(results);
183− });
184− </script>
185−</html>
tests-rendering/automation/view.jsdeleted−73
@@ -1,73 +0,0 @@
1−const fs = require("fs");
2−const program = require("commander");
3−const path = require("path");
4−const chalk = require("chalk");
5−const childProcess = require("child_process");
6−const build = require("./build.js");
7−const chokidar = require("chokidar");
8−const http = require("http");
9−
10−var filepath = null;
11−var test_filepath = null;
12−program
13− .option("--all", "run all the tests")
14− .option("--debug", "run with debug on")
15− .arguments("<filepath>")
16− .action(function (p) {
17− test_filepath = path.join("./tests-rendering/cases/open", p);
18− })
19− .parse(process.argv);
20−
21−(async () => {
22− if (test_filepath && test_filepath == null && !program.run) {
23− console.log("Open Cases");
24− console.log("");
25− fs.readdirSync("./tests-rendering/cases/open").forEach((file) => {
26− if (file.endsWith("elm")) {
27− console.log(" " + file);
28− }
29− });
30− console.log("");
31− return;
32− }
33−
34− if (program.all) {
35− filepath = "./src/Tests/All.elm";
36− } else {
37− filepath = "src/Tests/Run.elm";
38− build.create_runner({
39− elm: test_filepath,
40− template: "./tests-rendering/automation/templates/Run.elm",
41− target: "./tests-rendering/src/Tests/Run.elm",
42− });
43− }
44−
45− //
46− // Compile and serve
47−
48− let content = await build.compile_to_string({
49− template: "./tests-rendering/automation/templates/gather-styles.html",
50− elm: filepath,
51− elmOptions: { cwd: "./tests-rendering", debug: program.debug },
52− });
53−
54− console.log("Finished compiling");
55− // console.log(content);
56−
57− chokidar.watch("./tests-rendering/*.elm").on("all", (event, path) => {
58− console.log("Changes detected, refresh!");
59− content = build.compile_to_string({
60− template: "./tests-rendering/automation/templates/gather-styles.html",
61− elm: filepath,
62− elmOptions: { cwd: "./tests-rendering", debug: program.debug },
63− });
64− });
65− console.log("Serving on http://localhost:8080");
66− http
67− .createServer(function (req, res) {
68− res.writeHead(200, { "Content-Type": "text/html" });
69− res.write(content);
70− res.end();
71− })
72− .listen(8080);
73−})();
tests-rendering/cases/elm.jsondeleted−23
@@ -1,23 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": ["open", "../src/"],
4− "elm-version": "0.19.1",
5− "dependencies": {
6− "direct": {
7− "elm/browser": "1.0.0",
8− "elm/core": "1.0.0",
9− "elm/html": "1.0.0",
10− "elm/json": "1.0.0",
11− "elm/virtual-dom": "1.0.0",
12− "ohanhi/lorem": "1.0.2"
13− },
14− "indirect": {
15− "elm/time": "1.0.0",
16− "elm/url": "1.0.0"
17− }
18− },
19− "test-dependencies": {
20− "direct": {},
21− "indirect": {}
22− }
23−}
tests-rendering/cases/open/InFrontSize.elmdeleted−43
@@ -1,43 +0,0 @@
1−module InFrontSize exposing (view)
2−
3−{-|
4−
5−
6−# inFront elements with width fill are contained within the parent's border
7−
8−<https://github.com/mdgriffith/elm-ui/issues/201>
9−
10−Though they're expected to be the actual size of the parent.
11−
12−-}
13−
14−import Testable.Element exposing (..)
15−import Testable.Element.Background as Background
16−import Testable.Element.Border as Border
17−
18−
19−view =
20− layout []
21− (el
22− [ width (px 100)
23− , height (px 100)
24− , centerX
25− , centerY
26− , Background.color (rgb 0.1 0.1 0.1)
27− , Border.width 20
28− , Border.color (rgb 0.5 1 1)
29−
30− -- the following element should cover the parent's border
31− , inFront
32− (el
33− [ width fill
34− , height fill
35− , Background.color (rgb 0.1 0.5 0.9)
36−
37− -- , moveUp 40
38− ]
39− none
40− )
41− ]
42− none
43− )
tests-rendering/cases/open/LabelledInputAlignRight.elmdeleted−28
@@ -1,28 +0,0 @@
1−module LabelledInputAlignRight exposing (view)
2−
3−import Testable.Element exposing (..)
4−import Testable.Element.Input as Input
5−
6−
7−view =
8− layout [] <|
9− column [ width fill ]
10− [ Input.text
11− [ width (px 200)
12− , alignRight
13− ]
14− { onChange = always False
15− , text = ""
16− , placeholder = Nothing
17− , label = Input.labelLeft [] (text "label")
18− }
19− , Input.text
20− [ width (px 200)
21− , alignRight
22− ]
23− { onChange = always False
24− , text = ""
25− , placeholder = Nothing
26− , label = Input.labelHidden "label"
27− }
28− ]
tests-rendering/cases/open/NearbyElementBordersOverlap.elmdeleted−46
@@ -1,46 +0,0 @@
1−module NearbyElementBordersOverlap exposing (view)
2−
3−{-| Elements placed with onLeft, onRight, above & below overlap main element's border
4−
5−
6−# inFront elements with width fill are contained within the parent's border
7−
8−<https://github.com/mdgriffith/elm-ui/issues/223>
9−
10−In addition to the overlap, it affects layout in unexpected ways: eg if the elements
11−are the same height, onLeft and onRight elements will be vertically offset
12−from the main element.
13−
14−-}
15−
16−import Testable.Element exposing (..)
17−import Testable.Element.Border as Border
18−
19−
20−blue =
21− rgb 0 0 1
22−
23−
24−green =
25− rgb 0 1 0
26−
27−
28−grey =
29− rgb 0.5 0.5 0.5
30−
31−
32−view =
33− layout [ width fill, height fill ] <|
34− el
35− [ centerX
36− , centerY
37− , Border.width 10
38− , Border.color green
39− , padding 50
40− , above <| el [ Border.color grey, Border.width 10 ] <| text "above"
41− , below <| el [ Border.color grey, Border.width 10 ] <| text "below"
42− , onRight <| el [ Border.color blue, Border.width 10 ] <| text "onRight"
43− , onLeft <| el [ Border.color blue, Border.width 10 ] <| text "onLeft"
44− ]
45− <|
46− text "Centre"
tests-rendering/cases/open/Scrollbar2.elmdeleted−39
@@ -1,39 +0,0 @@
1−module Scrollbar2 exposing (main, myElement, sidebar)
2−
3−import Element exposing (Element, alignRight, centerY, column, el, fill, height, padding, px, rgb255, row, spacing, text, width)
4−import Element.Background as Background
5−import Element.Border as Border
6−import Element.Font as Font
7−
8−
9−main =
10− Element.layout [ height fill ] <|
11− row [ width fill, height fill ]
12− [ sidebar
13− ]
14−
15−
16−sidebar =
17− column [ width fill, height fill, spacing 30 ]
18− [ myElement
19− , column [ width fill, height fill ]
20− [ column [ width (px 350), height fill, Element.scrollbarY, Element.clip, Border.width 1 ]
21− [ column [ width fill ] <|
22− el [] (text "this should scroll indepedendently")
23− :: List.map (always myElement) (List.range 0 100)
24− ]
25− , el [] (text "this should be at the bottom of the screen")
26− ]
27− ]
28−
29−
30−myElement : Element msg
31−myElement =
32− el
33− [ Background.color (rgb255 240 0 245)
34− , Font.color (rgb255 255 255 255)
35− , Border.rounded 3
36− , padding 30
37− , width fill
38− ]
39− (text "stylish!")
tests-rendering/cases/open/Scrollbars.elmdeleted−50
@@ -1,50 +0,0 @@
1−module Scrollbars exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Html.Attributes
6−import Lorem as Lorem
7−
8−
9−main =
10− layout [ height fill ] <|
11− column
12− [ width fill
13− , Background.color (rgba 0.8 0 0 0.5)
14− , height fill
15− ]
16− [ row
17− [ padding 15
18− , width fill
19− , Background.color (rgba 0.8 0.2 0 0.5)
20− ]
21− [ text "this row should always be visible" ]
22− , row
23− [ width fill
24−
25− --, height (px 700)
26− -- Don't know why it doesn't work with `height fill`
27− , height fill
28− , clip
29−
30− --, htmlAttribute (Html.Attributes.style "flex-shrink" "1")
31− , Element.explain Debug.todo
32− ]
33− [ column
34− [ spacing 15
35− , scrollbarY
36− , height fill
37− , width fill
38− , padding 10
39− ]
40− (List.map (\p -> paragraph [] [ text p ]) <| Lorem.paragraphs 10)
41− , column
42− [ spacing 15
43− , scrollbarY
44− , width fill
45− , height fill
46− , padding 10
47− ]
48− (List.map (\p -> paragraph [] [ text p ]) <| Lorem.paragraphs 10)
49− ]
50− ]
tests-rendering/cases/open/StackedScrollingColumnsHeight.elmdeleted−42
@@ -1,42 +0,0 @@
1−module StackedScrollingColumnsHeight exposing (..)
2−
3−{-|
4−
5−
6−# Column height can be set incorrectly for two stacked columns with scrollbarY
7−
8−<https://github.com/mdgriffith/elm-ui/issues/197>
9−
10−Both red and green columns should always have equal height.
11−
12−Currently, the height is set incorrectly if only one column has enough content to scroll.
13−
14−Both columns are correctly set to the same height only if neither has enough content
15−to scroll or if both have enough content to scroll.
16−
17−-}
18−
19−import Testable.Element exposing (..)
20−import Testable.Element.Background as Background
21−
22−
23−view =
24− layout [ height fill ] <|
25− column [ height fill ]
26− [ column
27− [ height fill
28− , scrollbarY
29− , Background.color (rgb 0 255 0)
30− ]
31− <|
32− List.map (\_ -> text "Hello") <|
33− List.range 1 20
34− , column
35− [ height fill
36− , scrollbarY
37− , Background.color (rgb 255 0 0)
38− ]
39− <|
40− List.map (\_ -> text "Hello") <|
41− List.range 1 3
42− ]
tests-rendering/cases/open/WeirdCentering.elmdeleted−35
@@ -1,35 +0,0 @@
1−module WeirdCentering exposing (view)
2−
3−import Testable.Element exposing (..)
4−import Testable.Element.Background as Background
5−
6−
7−view =
8− layout [] <|
9− column []
10− [ text "Example with centerX:"
11− , row
12− [ width fill ]
13− [ row
14− [ centerX
15− , Background.color <| rgb 0 1 0
16− ]
17− [ paragraph
18− [ width shrink
19− ]
20− [ text "Hello world" ]
21− , paragraph
22− [ width shrink
23− ]
24− [ text "Hello world" ]
25− ]
26− ]
27− , text "Example without centerX:"
28− , row
29− [ width fill ]
30− [ row [ Background.color <| rgb 0 1 0 ]
31− [ paragraph [ width shrink ] [ text "Hello world" ]
32− , paragraph [ width shrink ] [ text "Hello world" ]
33− ]
34− ]
35− ]
tests-rendering/cases/resolved/Adjusted.elmdeleted−70
@@ -1,70 +0,0 @@
1−module Main exposing (main)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−import Html.Attributes
9−
10−
11−myFont =
12− Font.with
13− { url = Just "https://fonts.googleapis.com/css?family=Catamaran"
14− , name = "Catamaran"
15− , adjustment =
16− { capital = 1.15
17− , lowercase = 0.96
18− , baseline = 0.465
19− , descender = 0.245
20− }
21− }
22−
23−
24−main =
25− Element.layout
26− [ Background.color (rgba 0 0.8 0.9 1)
27− , Font.color (rgba 1 1 1 1)
28− , Font.size 32
29− , Font.family [ myFont ]
30−
31− -- , Font.family
32− -- [ Font.external
33− -- { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
34− -- , name = "EB Garamond"
35− -- }
36− -- , Font.sansSerif
37− -- ]
38− ]
39− <|
40− column [ centerX, centerY, spacing 20, padding 100, htmlAttribute (Html.Attributes.style "display" "block") ]
41− [ el
42− []
43− (text "Hello stylish friend!")
44− , el
45− [ Font.family
46− [ Font.external
47− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
48− , name = "EB Garamond"
49− }
50− ]
51− ]
52− <|
53− el
54− [ Font.sizeByCapital
55− , Background.color (rgba 1 1 1 1)
56− , Font.color (rgba 0 0 0 1)
57− ]
58− (text "Hello stylish friend!")
59− , el
60− [ Font.sizeByCapital
61− , Background.color (rgba 1 1 1 1)
62− , Font.color (rgba 0 0 0 1)
63− ]
64− (text "Hello stylish friend!")
65− , el
66− [ Background.color (rgba 1 1 1 1)
67− , Font.color (rgba 0 0 0 1)
68− ]
69− (text "Hello stylish friend!")
70− ]
tests-rendering/cases/resolved/BehindContent.elmdeleted−34
@@ -1,34 +0,0 @@
1−module Main exposing (main)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−import Element.Input
9−import Element.Lazy
10−
11−
12−main =
13− Element.layout
14− [ Background.color (rgba 0 0 0 1)
15− , Font.color (rgba 1 1 1 1)
16− , Font.italic
17− , Font.size 32
18− , Font.family
19− [ Font.external
20− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
21− , name = "EB Garamond"
22− }
23− , Font.sansSerif
24− ]
25− ]
26− <|
27− el
28− [ centerX
29− , centerY
30− , Background.color (rgba 0 0.8 0.9 1)
31− , behindContent
32− (el [ height (px 20), width (px 100), Background.color (rgba 0.9 0.8 0 1) ] none)
33− ]
34− (text "Hello stylish friend!")
tests-rendering/cases/resolved/ClippedElInFixedWidthColumn.elmdeleted−31
@@ -1,31 +0,0 @@
1−module ClippedElInFixedWidthColumn exposing (..)
2−
3−{-| el [ clip ] inside a fixed-width column rendered with 0px height in Chrome & Firefox
4−
5−<https://github.com/mdgriffith/elm-ui/issues/191>
6−
7−If an el [ clip ] is placed inside a fixed-width column which is inside a layout
8−with [ width fill, height fill ], then the element is rendered with 0px height in Chrome:
9−
10−layout [ width fill, height fill ] <|
11−column [ width <| px 300 ][ el [ clip ] <| text "The quick brown fox" ]
12−
13−In Firefox, the element is initially rendered correctly, but is resized to 0px height
14−on viewport resize. In Safari, the element is displayed correctly.
15−
16−The above seems to be the minimal reproduction:
17−
18−Removing attributes from layout or from column or from el makes the issue disappear.
19−Replacing column [ width <| px 300 ] with column [ width fill ] makes the issue disappear.
20−Replacing column with el also makes the issue disappear.
21−Adding htmlAttribute <| Attr.style "flex-basis" "auto" to clipped el is a workaround.
22−
23−-}
24−
25−import Testable.Element exposing (..)
26−
27−
28−view =
29− layout [ width fill, height fill ] <|
30− column [ width <| px 300 ]
31− [ el [ clip ] <| text "The quick brown fox" ]
tests-rendering/cases/resolved/ColumnGrowth.elmdeleted−40
@@ -1,40 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (column, fill, fillPortion, height, minimum, paddingXY, px, rgb, row, shrink, spacing, width)
5−import Element.Background as Back
6−import Element.Border as Border
7−import Html exposing (Html)
8−
9−
10−main : Html m
11−main =
12− let
13− box =
14− row
15− [ Border.solid
16− , Border.width 2
17− , Back.color (rgb 1 1 1)
18− , width (px 80)
19− , height (fillPortion 1)
20− ]
21− []
22−
23− grower =
24− column
25− [ width fill
26−
27− -- fillPortion is not being applied here unless we set it to 1.
28− -- It will also resume working if we delete the minimum bound.
29− , height
30− (fillPortion 2
31− |> minimum 20
32− )
33− ]
34− []
35− in
36− Element.layout
37− [ Back.color (rgb 0.9 1 0.8)
38− , paddingXY 20 20
39− ]
40− (column [ height fill ] [ box, grower, box ])
tests-rendering/cases/resolved/ElInFixedHeightColumn.elmdeleted−41
@@ -1,41 +0,0 @@
1−module ElInFixedHeightColumn exposing (view)
2−
3−{-| el inside a fixed height column is rendered with zero height in Safari
4−
5−<https://github.com/mdgriffith/elm-ui/issues/190>
6−
7−If I put an el into a column of fixed height, the el is rendered with zero height
8−in Safari:
9−
10− layout [] <|
11− column
12− [ width fill
13− , height <| px 200
14− ]
15− [ el [ Border.width 3, Border.color <| rgb255 0 0 0 ] <| text "an element" ]
16−
17−Adding htmlAttribute <| Attr.style "flex-basis" "auto" to the el is a workaround
18−that fixes the problem in this instance.
19−
20−Expected behavior
21−
22−Element should be rendered the same as in Firefox & Chrome, with the border going
23−around the text.
24−
25−-}
26−
27−import Testable.Element exposing (..)
28−import Testable.Element.Border as Border
29−
30−
31−view =
32− layout [] <|
33− column
34− [ width fill
35− , height <| px 200
36− ]
37− [ el
38− []
39− <|
40− text "an element"
41− ]
tests-rendering/cases/resolved/FocusStyles.elmdeleted−34
@@ -1,34 +0,0 @@
1−module Main exposing (main)
2−
3−import Element
4−import Element.Background
5−import Element.Input
6−
7−
8−main =
9− Element.layout []
10− (Element.column [ Element.width (Element.px 200), Element.spacing 10 ]
11− [ Element.Input.text [ Element.focused [] ]
12− { label = Element.Input.labelHidden ""
13− , onChange = \_ -> ()
14− , placeholder = Nothing
15− , text = ""
16− }
17− , Element.Input.multiline
18− [ Element.focused [ Element.Background.color (Element.rgb 0 0 0) ] ]
19− { label = Element.Input.labelHidden ""
20− , onChange = \_ -> ()
21− , placeholder = Nothing
22− , spellcheck = False
23− , text = ""
24− }
25− , Element.Input.button [ Element.focused [] ]
26− { label = Element.text "Button"
27− , onPress = Nothing
28− }
29− , Element.Input.button []
30− { label = Element.text "Button"
31− , onPress = Nothing
32− }
33− ]
34− )
tests-rendering/cases/resolved/HugePlaceholder.elmdeleted−25
@@ -1,25 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (Element)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Input as Input
8−import Html exposing (Html, button, div, text)
9−import Html.Events exposing (onClick)
10−
11−
12−main =
13− Element.layout [] sscce
14−
15−
16−sscce =
17− Input.text
18− [ Border.width 1
19− , Element.width <| Element.px 50
20− ]
21− { onChange = always ()
22− , text = ""
23− , placeholder = Just <| Input.placeholder [] <| Element.text "this is a very long place holder ......................"
24− , label = Input.labelHidden ""
25− }
tests-rendering/cases/resolved/Images/ImageRegression.elmdeleted−63
@@ -1,63 +0,0 @@
1−module ImageRegression exposing (main)
2−
3−{-| <https://github.com/mdgriffith/elm-ui/issues/232>
4−-}
5−
6−import Browser
7−import Element exposing (Element, centerX, clipX, el, image, px, rgb255, row, shrink, width)
8−import Element.Background as Background
9−import Html exposing (Html, button, div, text)
10−import Html.Events exposing (onClick)
11−
12−
13−type alias Model =
14− Int
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 -> Html Msg
27−view model =
28− Element.layout [] <|
29− row
30− [ centerX
31− , width shrink
32− , Background.color <| rgb255 255 255 255
33− ]
34− [ viewCard "qs" True
35− , viewCard "ah" False
36− ]
37−
38−
39−main : Program () Model Msg
40−main =
41− Browser.sandbox
42− { init = 0
43− , view = view
44− , update = update
45− }
46−
47−
48−viewCard : String -> Bool -> Element Msg
49−viewCard card bool =
50− let
51− source =
52− "https://hearts-bawolk.herokuapp.com/static/cards/" ++ card ++ ".png"
53−
54− overlapStyles =
55− if bool then
56− [ width (px 50)
57− , clipX
58− ]
59−
60− else
61− []
62− in
63− el overlapStyles (image [] { src = source, description = "" })
tests-rendering/cases/resolved/Images/ImageRegression2.elmdeleted−19
@@ -1,19 +0,0 @@
1−module ImageRegression2 exposing (main)
2−
3−{-| <https://github.com/mdgriffith/elm-ui/issues/228>
4−-}
5−
6−import Element exposing (..)
7−
8−
9−main =
10− Element.layout []
11− (Element.row [ width fill, height fill, explain Debug.todo ]
12− [ text "BEFORE"
13− , image []
14− { src = "https://placekitten.com/300/200"
15− , description = "kitten"
16− }
17− , text "AFTER"
18− ]
19− )
tests-rendering/cases/resolved/Images/ImageSizing.elmdeleted−24
@@ -1,24 +0,0 @@
1−module ImageSizing exposing (main)
2−
3−{-| <https://github.com/mdgriffith/elm-ui/issues/62>
4−-}
5−
6−import Element as E exposing (column, el, px, row, text)
7−import Element.Border as Border
8−import Element.Font as Font
9−import Html exposing (Html)
10−
11−
12−main : Html ()
13−main =
14− E.layout [ E.height E.fill, Border.width 5, E.explain Debug.todo ] <|
15− E.image
16− [ -- E.height (E.px 500)
17− -- ,
18− -- E.width E.fill
19− E.height E.fill
20− ]
21− -- <| px 500 ]
22− { src = "http://bburdette.github.io/music-reader.png"
23− , description = "music-reader screenshot"
24− }
tests-rendering/cases/resolved/Input/FocusLinks.elmdeleted−37
@@ -1,37 +0,0 @@
1−module FocusLinks exposing (main)
2−
3−import Element exposing (Color, Element, el, focused, layout, link, row, spacing, text)
4−import Element.Border as Border
5−import Element.Region as Region
6−import Html exposing (Html)
7−
8−
9−main : Html msg
10−main =
11− layout [] links
12−
13−
14−links : Element msg
15−links =
16− row [ spacing 10 ]
17− [ siteLink "Elm website" "https://elm-lang.org/"
18− , siteLink "Elm-ui" "https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element"
19− ]
20−
21−
22−siteLink : String -> String -> Element msg
23−siteLink label url =
24− link [ focused [ Border.glow blue 2 ] ]
25− { url = url
26− , label = text label
27− }
28−
29−
30−blue : Color
31−blue =
32− Element.fromRgb255
33− { red = 100
34− , green = 180
35− , blue = 250
36− , alpha = 1
37− }
tests-rendering/cases/resolved/Input/FocusStylePrecedingElements.elmdeleted−38
@@ -1,38 +0,0 @@
1−module FocusStylePrecedingElements exposing (main)
2−
3−{-|
4−
5−
6−# `focused` style applied to an element when any element with a lower tab index is focused
7−
8−<https://github.com/mdgriffith/elm-ui/issues/198>
9−
10−When I add a focused attribute, the styles therein are applied not only when
11−the element is focused, but also when any element with a lower tab index is focused.
12−This behaviour is not browser-specific.
13−
14−To reproduce, tab through to the buttons in the Ellie below. As soon as the first
15−button has focus, the third button (which is the only one with a focused attribute)
16−is highlighted as well.
17−
18−I narrowed down the reason for this behaviour to this CSS selector:
19−.s:focus ~ .fc-250-50-50-255-fs:not(.focus)
20−
21−Disabling it produces the correct focus behaviour.
22−
23−-}
24−
25−import Element exposing (..)
26−import Element.Font as Font
27−import Element.Input as Input
28−
29−
30−main =
31− layout [] <|
32− column []
33− [ Input.button [] { onPress = Nothing, label = text "Button" }
34− , Input.button [] { onPress = Nothing, label = text "Button" }
35− , Input.button [ focused [ Font.color <| rgb255 250 50 50 ] ] { onPress = Nothing, label = text "Button" }
36− , Input.button [] { onPress = Nothing, label = text "Button" }
37− , Input.button [] { onPress = Nothing, label = text "Button" }
38− ]
tests-rendering/cases/resolved/Input/InputAlignment.elmdeleted−44
@@ -1,44 +0,0 @@
1−module InputAlignment exposing (main)
2−
3−import Browser
4−import Element exposing (fill, padding, width)
5−import Element.Border as Border
6−import Element.Font as Font
7−import Element.Input as Input
8−import Html exposing (Html)
9−
10−
11−view : () -> Html ()
12−view () =
13− Element.layout [ Font.alignRight ] <|
14− Element.column [ padding 10 ]
15− [ Element.el [ Border.width 1, padding 5, width fill ] <| Element.text "Element.el"
16− , Input.text
17− [ Border.width 1
18− , padding 5
19− , width fill
20− , Border.rounded 0
21− , Font.color (Element.rgb 0 0.5 0.5)
22− ]
23− { onChange = always ()
24− , text = "Input.text"
25− , placeholder = Nothing
26− , label = Input.labelHidden "Input.text"
27− }
28− , Element.paragraph []
29− [ Element.text "Helooooo!" ]
30− , Element.row []
31− [ Element.text "one!"
32− , Element.text "two!"
33− , Element.text "three!"
34− ]
35− ]
36−
37−
38−main : Program () () ()
39−main =
40− Browser.sandbox
41− { init = ()
42− , view = view
43− , update = \_ _ -> ()
44− }
tests-rendering/cases/resolved/Input/LabelAlignBaseline.elmdeleted−34
@@ -1,34 +0,0 @@
1−module LabelAlignBaseline exposing (..)
2−
3−import Element exposing (Element, alignRight, centerY, el, fill, padding, rgb255, row, spacing, text, width)
4−import Element.Background as Background
5−import Element.Border as Border
6−import Element.Font as Font
7−import Element.Input as Input
8−
9−
10−type Msg
11− = Msg
12−
13−
14−main =
15− Element.layout [] <|
16− Element.column []
17− [ Element.row []
18− [ Element.text "dissociated label"
19− , Input.text []
20− { text = "input"
21− , label = Input.labelHidden "hidden"
22− , onChange = \_ -> Msg
23− , placeholder = Nothing
24− }
25− ]
26− , Element.row []
27− [ Input.text []
28− { text = "input"
29− , label = Input.labelLeft [] <| Element.text "associated label"
30− , onChange = \_ -> Msg
31− , placeholder = Nothing
32− }
33− ]
34− ]
tests-rendering/cases/resolved/Input/Placeholder.elmdeleted−59
@@ -1,59 +0,0 @@
1−module Placeholder exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Element.Input as Input
6−import Element.Keyed as Keyed
7−import Html.Attributes exposing (style)
8−
9−
10−grey =
11− rgb 0.8 0.8 0.8
12−
13−
14−darkGrey =
15− rgb 0.7 0.7 0.7
16−
17−
18−type Msg
19− = NoMsg String
20−
21−
22−main =
23− Element.layout [ width fill, height fill ] <|
24− column
25− [ width fill
26− , inFront
27− (el
28− [ width fill
29− , Background.color grey
30− , padding 20
31− , below <|
32− el
33− [ height (px 300)
34− , width (px 300)
35− , Background.color darkGrey
36− , htmlAttribute <| style "z-index" "1"
37− , moveRight 50
38− , padding 50
39− , alpha 0.5
40− ]
41− (el [ alignBottom ] (text "I'm a dropdown menu."))
42− ]
43− (text "I'm a toolbar.")
44− )
45− ]
46− [ Input.text []
47− { onChange = NoMsg
48− , text = ""
49− , placeholder = Just (Input.placeholder [] (text "I'm a text input."))
50− , label = Input.labelAbove [] none
51− }
52− , Input.multiline []
53− { onChange = NoMsg
54− , text = ""
55− , placeholder = Just (Input.placeholder [] (text "I'm a multiline input."))
56− , label = Input.labelAbove [] none
57− , spellcheck = False
58− }
59− ]
tests-rendering/cases/resolved/Input/Slider.elmdeleted−74
@@ -1,74 +0,0 @@
1−module Slider exposing (main)
2−
3−import Browser
4−import Element as Element exposing (Element)
5−import Element.Background as Background
6−import Element.Input as Input
7−import Html exposing (Html, button, div, text)
8−import Html.Events exposing (onClick)
9−
10−
11−type alias Model =
12− { rangeValue : Float }
13−
14−
15−initialModel : Model
16−initialModel =
17− { rangeValue = 160.0 }
18−
19−
20−type Msg
21− = UpdateRange Float
22−
23−
24−update : Msg -> Model -> Model
25−update msg model =
26− case msg of
27− UpdateRange value ->
28− { model | rangeValue = value }
29−
30−
31−viewModal =
32− Element.el
33− [ Element.width Element.fill
34− , Element.height Element.fill
35− , Element.paddingEach { top = 100, left = 0, bottom = 0, right = 0 }
36− , Background.color <| Element.rgba 0 0 0 0.8
37− ]
38− (Element.el [] (Element.text "Hello Modal"))
39−
40−
41−view : Model -> Html Msg
42−view model =
43− Element.layout
44− [--Element.inFront viewModal
45− ]
46− <|
47− Input.slider
48− [ Element.width Element.fill
49− , Element.behindContent <|
50− Element.el
51− [ Element.width Element.fill
52− , Element.height (Element.px 2)
53− , Element.centerY
54− , Background.color (Element.rgb 0.5 0.5 0.5)
55− ]
56− Element.none
57− ]
58− { onChange = UpdateRange
59− , label = Input.labelHidden ""
60− , min = 60.0
61− , max = 280.0
62− , value = model.rangeValue
63− , thumb = Input.defaultThumb
64− , step = Just 1.0
65− }
66−
67−
68−main : Program () Model Msg
69−main =
70− Browser.sandbox
71− { init = initialModel
72− , view = view
73− , update = update
74− }
tests-rendering/cases/resolved/Layout/BreaksWithinParagraph.elmdeleted−17
@@ -1,17 +0,0 @@
1−module BreaksWithinParagraph exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Font as Font
8−
9−
10−main =
11− layout [ width fill, height fill ] <|
12− paragraph [ Border.width 1, width (px 50) ]
13− [ row []
14− [ text "Thequick"
15− ]
16− , text "redfox"
17− ]
tests-rendering/cases/resolved/Layout/ColumnLayouts.elmdeleted−103
@@ -1,103 +0,0 @@
1−module ColumnLayouts exposing (main)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Border as Border
8−import Element.Font as Font
9−
10−
11−main =
12− layout [] <|
13− column [ spacing 48 ]
14− [ column
15− [ width fill
16− , height <| px 200
17− , spacing 24
18− , Border.width 1
19− , Border.color pink
20− ]
21− [ elem
22− , elem
23− , elem
24− ]
25− , column
26− [ width fill
27− , spacing 24
28− , Border.width 1
29− , Border.color pink
30− ]
31− [ elem
32− , elem
33− , elem
34− ]
35− , el [ height <| px 400 ] <|
36− column [ height fill ]
37− [ column
38− [ width fill
39− , height <| px 200
40− , spacing 24
41− , Border.width 1
42− , Border.color pink
43− ]
44− [ elem
45− , elem
46− , el [ alignBottom ] elem
47− ]
48− , el [ alignBottom ] elem
49− ]
50− , column
51− [ width fill
52− , height <| px 200
53− , spacing 24
54− , Border.width 1
55− , Border.color pink
56− ]
57− [ elem
58− , el [] box
59− , el [ alignBottom ] elem
60− ]
61− , column
62− [ width fill
63− , height <| px 200
64− , spacing 24
65− , Border.width 1
66− , Border.color pink
67− ]
68− [ elem
69− , el [] box
70− , filled
71− , el [ alignBottom ] elem
72− ]
73− ]
74−
75−
76−filled =
77− el
78− [ width fill
79− , height fill
80− , Background.color pink
81− ]
82− (text "an element")
83−
84−
85−elem =
86− el
87− [ Background.color pink
88− ]
89− (text "an element")
90−
91−
92−box =
93− el
94− [ width (px 50)
95− , height (px 50)
96− , Background.color (rgb (240 / 255) 0 (245 / 255))
97− , Font.color (rgb 1 1 1)
98− ]
99− none
100−
101−
102−pink =
103− rgb (240 / 255) 0 (245 / 255)
tests-rendering/cases/resolved/Layout/Columns/DistributeHeight.elmdeleted−46
@@ -1,46 +0,0 @@
1−module DistributeHeight exposing (main)
2−
3−import Browser
4−import Element exposing (column, el, fill, fillPortion, height, minimum, none, px, rgb, row, text, width)
5−import Element.Background as Bg
6−import Html as Html exposing (Html)
7−
8−
9−type alias Model =
10− ()
11−
12−
13−update : msg -> Model -> Model
14−update _ model =
15− model
16−
17−
18−view : model -> Html msg
19−view _ =
20− Element.layout [ height fill, width fill ] <|
21− column [ height fill, width fill ]
22− [ row
23− [ height
24− fill
25− , width fill
26− , Bg.color <| rgb 1 0 0
27− ]
28− [ el
29− [ height <| px 200
30− , width fill
31− , Bg.color <| rgb 1 0 1
32− ]
33− (text "Helloooo!")
34− ]
35− , row [ height fill, width fill, Bg.color <| rgb 0 1 0 ]
36− [ none ]
37− ]
38−
39−
40−main : Program () Model msg
41−main =
42− Browser.sandbox
43− { init = ()
44− , view = view
45− , update = update
46− }
tests-rendering/cases/resolved/Layout/Columns/DistributeHeightCorrectly2.elmdeleted−86
@@ -1,86 +0,0 @@
1−module Other exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Border as Border
6−import Element.Events as Events
7−import Html exposing (Html)
8−import Html.Attributes
9−
10−
11−type alias Model =
12− { count : Int }
13−
14−
15−initialModel : Model
16−initialModel =
17− { count = 0 }
18−
19−
20−type Msg
21− = Increment
22− | Decrement
23−
24−
25−update : Msg -> Model -> Model
26−update msg model =
27− case msg of
28− Increment ->
29− { model | count = model.count + 1 }
30−
31− Decrement ->
32− { model | count = model.count - 1 }
33−
34−
35−view : Model -> Html Msg
36−view model =
37− viewElements model
38− |> layout []
39−
40−
41−viewElements : Model -> Element Msg
42−viewElements model =
43− el [ height fill ] <|
44− column [ height fill ]
45− [ el
46− [ height (fillPortion 1)
47− ]
48− <|
49− viewCounter model
50− , el
51− [ height (fillPortion 2)
52− ]
53− <|
54− viewCounters model
55− ]
56−
57−
58−flexBasisZero : Element.Attribute msg
59−flexBasisZero =
60− htmlAttribute (Html.Attributes.style "flex-basis" "0")
61−
62−
63−viewCounters : Model -> Element Msg
64−viewCounters model =
65− column [ height fill ]
66− (List.repeat model.count model
67− |> List.map viewCounter
68− )
69−
70−
71−viewCounter : Model -> Element Msg
72−viewCounter model =
73− column [ width fill, height fill, Border.width 1, Border.dotted ]
74− [ el [ Events.onClick Increment, Border.width 1, Border.rounded 3 ] <| text "+1"
75− , el [] <| text <| String.fromInt model.count
76− , el [ Events.onClick Decrement, Border.width 1, Border.rounded 3 ] <| text "-1"
77− ]
78−
79−
80−main : Program () Model Msg
81−main =
82− Browser.sandbox
83− { init = initialModel
84− , view = view
85− , update = update
86− }
tests-rendering/cases/resolved/Layout/Columns/DoNotCollapseBelow0.elmdeleted−48
@@ -1,48 +0,0 @@
1−module DoNotCollapseBelow0 exposing (main)
2−
3−{-|
4−
5−
6−# Safari bug for `el` heigh calculation in combination with `height fill`
7−
8−The problem appears to be that the height of the first el is 0, and therefore the second
9−text is rendered on the first.
10−
11−Versions
12−
13−OS: macOS Mojave 10.14.5
14−Browser: Safari
15−Browser Version: 12.1.1 (14607.2.6.1.1)
16−Elm Version: 0.19
17−Elm UI Version: 1.1.5
18−
19−<https://github.com/mdgriffith/elm-ui/issues/147>
20−
21−I was able to pinpoint the issue using git bisect to this fd08f1a commit, which lines up.
22−
23−<https://github.com/mdgriffith/elm-ui/commit/fd08f1a953484ba96f2d05037d4f208eab351514>
24−
25−-}
26−
27−import Browser
28−import Element exposing (column, el, fill, height, layout, scrollbarY, text)
29−import Html exposing (Html)
30−
31−
32−view : () -> Html ()
33−view () =
34− layout [ height fill ] <|
35− column
36− [ height fill ]
37− [ el [] <| text "Element that Safari gives height 0, if inside an el and not just text."
38− , text "Text below the el above"
39− ]
40−
41−
42−main : Program () () ()
43−main =
44− Browser.sandbox
45− { init = ()
46− , view = view
47− , update = \() () -> ()
48− }
tests-rendering/cases/resolved/Layout/Columns/SafariTwo.elmdeleted−40
@@ -1,40 +0,0 @@
1−module SafariTwo exposing (main)
2−
3−{-| el inside a fixed height column is rendered with zero height in Safari
4−
5−<https://github.com/mdgriffith/elm-ui/issues/190>
6−
7−If I put an el into a column of fixed height, the el is rendered with zero height
8−in Safari:
9−
10− layout [] <|
11− column
12− [ width fill
13− , height <| px 200
14− ]
15− [ el [ Border.width 3, Border.color <| rgb255 0 0 0 ] <| text "an element" ]
16−
17−Adding htmlAttribute <| Attr.style "flex-basis" "auto" to the el is a workaround
18−that fixes the problem in this instance.
19−
20−Expected behavior
21−
22−Element should be rendered the same as in Firefox & Chrome, with the border going
23−around the text.
24−
25−-}
26−
27−import Element exposing (..)
28−
29−
30−main =
31− layout [] <|
32− column
33− [ width fill
34− , height <| px 200
35− ]
36− [ el
37− []
38− <|
39− text "an element"
40− ]
tests-rendering/cases/resolved/Layout/NestedParagraphs.elmdeleted−165
@@ -1,165 +0,0 @@
1−module Layout.NestedParagraphs exposing (view)
2−
3−{-| Paragraph with children more than one level deep breaks flow
4−
5−<https://github.com/mdgriffith/elm-ui/issues/173>
6−
7−First of all, thanks for such a pleasant library to use! It's been awesome not having to use CSS.
8−
9−The problem I ran into is that paragraph only seems correctly flow text in children a single level deep. As an example, I made an Ellie demonstrating this with an el within a link within a paragraph:
10−
11−<https://ellie-app.com/7JcgLRNprF7a1>
12−
13−This might be a regression, as the resolved #50 and #103 seem to refer to the same problem.
14−
15−Expected behavior
16−Text should flow with no breaks in the paragraph.
17−
18−Versions
19−
20− OS: macOS
21− Browser: Firefox
22− Browser Version: 71.0
23− Elm Version: 0.19.1
24− Elm UI Version: 1.1.5
25−
26−-}
27−
28−import Testable.Element as Element exposing (..)
29−import Testable.Element.Font as Font
30−import Testable.Generator
31−
32−
33−view =
34− layout [] <|
35− column [ spacing 48 ]
36− [ paragraph []
37− [ text "This is a paragraph with a "
38− , el [ Font.bold ] <| text "child"
39− , text " of depth one."
40− ]
41− , paragraph []
42− [ text "This is a paragraph with a "
43− , link []
44− { label =
45− el [ Font.bold ]
46− (text Testable.Generator.lorem)
47− , url = "http://example.com"
48− }
49− , text " of depth two."
50− ]
51− , el [ Font.size 32 ] (text "Many nested els")
52− , paragraph []
53− [ text "This is a paragraph with a "
54− , link []
55− { label =
56− el [ Font.bold ]
57− (text Testable.Generator.lorem)
58− , url = "http://example.com"
59− }
60− , text " of depth two."
61− , el [] (el [] (el [] (text Testable.Generator.lorem)))
62− , el [] (el [] (el [] (el [] (text Testable.Generator.lorem))))
63− ]
64− , el [ Font.size 32 ] (text "NestedParas in els")
65− , paragraph []
66− [ text "This is a paragraph with a "
67− , link []
68− { label =
69− el [ Font.bold ]
70− (text Testable.Generator.lorem)
71− , url = "http://example.com"
72− }
73− , text " of depth two."
74− , el [] (el [] (el [] (text Testable.Generator.lorem)))
75− , el []
76− (paragraph []
77− [ el []
78− (el [] (text Testable.Generator.lorem))
79− ]
80− )
81− ]
82− , el [ Font.size 32 ] (text "Nested with link")
83− , paragraph []
84− [ text "This is a paragraph with a "
85− , link []
86− { label =
87− el [ Font.bold ] <|
88− text "child"
89− , url = "http://example.com"
90− }
91− , text " of depth two."
92− ]
93− , el [ Font.size 32 ] (text "Para with boxes")
94− , paragraph []
95− [ text Testable.Generator.short
96− , Testable.Generator.box
97− , text Testable.Generator.short
98−
99− -- , text Testable.Generator.lorem
100− , Testable.Generator.box
101− ]
102− , el [ Font.size 32 ] (text "Row with boxes")
103− , paragraph []
104− [ text Testable.Generator.short
105− , row [ spacing 25 ]
106− [ Testable.Generator.box
107− , text Testable.Generator.short
108− , Testable.Generator.box
109−
110− -- , text Testable.Generator.lorem
111− ]
112− , text Testable.Generator.short
113−
114− -- , text Testable.Generator.lorem
115− , Testable.Generator.box
116− , paragraph []
117− [ text "This is a paragraph with a "
118− , el [ Font.bold ] <| text "child"
119− , text " of depth one."
120− ]
121− ]
122− , el [ Font.size 32 ] (text "Row with boxes and lots of content")
123− , paragraph []
124− [ column [ alignLeft ]
125− [ Testable.Generator.box, Testable.Generator.box, Testable.Generator.box ]
126− , text Testable.Generator.short
127− , row [ spacing 25 ]
128− [ Testable.Generator.box
129− , text Testable.Generator.lorem
130− , Testable.Generator.box
131−
132− -- , text Testable.Generator.lorem
133− ]
134− , text Testable.Generator.short
135−
136− -- , text Testable.Generator.lorem
137− , Testable.Generator.box
138− , paragraph []
139− [ text "This is a paragraph with a "
140− , el [ Font.bold ] <| text "child"
141− , text " of depth one."
142− ]
143− ]
144− , el [ Font.size 32 ] (text "Row with boxes")
145− , paragraph []
146− [ text Testable.Generator.short
147− , row []
148− [ Testable.Generator.box
149−
150− -- , text Testable.Generator.lorem
151− , Testable.Generator.box
152−
153− -- , text Testable.Generator.lorem
154− ]
155− , text Testable.Generator.short
156−
157− -- , text Testable.Generator.lorem
158− , Testable.Generator.box
159− , paragraph []
160− [ text "This is a paragraph with a "
161− , el [ Font.bold ] <| text "child"
162− , text " of depth one."
163− ]
164− ]
165− ]
tests-rendering/cases/resolved/Layout/Rounded.elmdeleted−54
@@ -1,54 +0,0 @@
1−module Rounded exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Html exposing (Html)
6−
7−
8−sizePadding =
9− 10
10−
11−
12−sizeSpacing =
13− 11
14−
15−
16−nbElement =
17− 10
18−
19−
20−sizeElement =
21− 50
22−
23−
24−totalSizeElement =
25− nbElement * sizeElement
26−
27−
28−totalSpacing =
29− (nbElement - 1) * sizeSpacing
30−
31−
32−totalPadding =
33− 2 * sizePadding
34−
35−
36−sizeRow =
37− totalSizeElement + totalSpacing + totalPadding
38−
39−
40−main : Html msg
41−main =
42− layout [ width fill, height fill ] <|
43− -- The row should have 4.5px of padding to get
44− -- from the 5.5px of margin of the elements on the edge
45− -- up to 10px of padding specified on the wrappedRow.
46− -- Instead the row has 5px of padding.
47− wrappedRow [ width (px sizeRow), padding sizePadding, spacing sizeSpacing, Background.color (rgb 0 0 1) ]
48− <|
49− List.repeat nbElement <|
50− -- Each element has a margin of 5.5px (11px of spacing / 2)
51− el [ width (px sizeElement), height (px sizeElement), Background.color (rgb 1 0 0) ]
52− <|
53− el [ centerX, centerY ] <|
54− text "card"
tests-rendering/cases/resolved/Layout/SafariBugIssue147.elmdeleted−37
@@ -1,37 +0,0 @@
1−module Layout.SafariBugIssue147 exposing (view)
2−
3−{-|
4−
5−
6−# Safari bug for `el` heigh calculation in combination with `height fill`
7−
8−The problem appears to be that the height of the first el is 0, and therefore the second
9−text is rendered on the first.
10−
11−Versions
12−
13−OS: macOS Mojave 10.14.5
14−Browser: Safari
15−Browser Version: 12.1.1 (14607.2.6.1.1)
16−Elm Version: 0.19
17−Elm UI Version: 1.1.5
18−
19−<https://github.com/mdgriffith/elm-ui/issues/147>
20−
21−I was able to pinpoint the issue using git bisect to this fd08f1a commit, which lines up.
22−
23−<https://github.com/mdgriffith/elm-ui/commit/fd08f1a953484ba96f2d05037d4f208eab351514>
24−
25−-}
26−
27−import Testable.Element exposing (..)
28−
29−
30−view =
31− layout [ height fill ] <|
32− el [ height fill ] <|
33− column
34− [ height fill ]
35− [ el [] <| text "Element that Safari gives height 0, if inside an el and not just text."
36− , text "Text below the el above"
37− ]
tests-rendering/cases/resolved/Layout/WrapRow.elmdeleted−13
@@ -1,13 +0,0 @@
1−module WrapRow exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−
6−
7−main =
8− layout [] <|
9− wrappedRow
10− [ padding 10
11− , spacingXY 6 5
12− ]
13− [ text "Higher by 1 px" ]
tests-rendering/cases/resolved/Misc/Scroll.elmdeleted−48
@@ -1,48 +0,0 @@
1−module Scroll exposing (main)
2−
3−import Browser
4−import Element exposing (Element, alignTop, centerX, centerY, column, el, fill, fillPortion, height, inFront, layoutWith, none, padding, px, row, scrollbarY, spacing, text, width, wrappedRow)
5−import Element.Background as Background
6−import Element.Font as Font
7−import Element.Input as Input exposing (button)
8−import Html exposing (Html)
9−import Html.Attributes
10−
11−
12−type alias Model =
13− ()
14−
15−
16−type alias Msg =
17− ()
18−
19−
20−field i =
21− text <| "Scrolling text " ++ String.fromInt i
22−
23−
24−view : Model -> Html Msg
25−view model =
26− layoutWith { options = [] } [ height fill ] <|
27− row
28− [ height fill ]
29− [ column
30− [ height fill
31− , scrollbarY
32−
33− -- The width fill is required, when using scrollbarY above
34− -- else the width is set to 0.
35− --, width fill
36− ]
37− (List.map field (List.range 1 100))
38− , text "Non scrolling text"
39− ]
40−
41−
42−main : Program () Model Msg
43−main =
44− Browser.sandbox
45− { init = ()
46− , view = view
47− , update = \msg model -> model
48− }
tests-rendering/cases/resolved/MismatchTextInputText.elmdeleted−82
@@ -1,82 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (text)
5−import Element.Border as Border
6−import Element.Input as Input
7−import Html exposing (Html, button, div)
8−import Html.Events exposing (onClick)
9−
10−
11−black =
12− Element.rgb 0 0 0
13−
14−
15−styles =
16− [ Border.color black
17− , Border.width 1
18− , Element.padding 5
19− , Border.rounded 0
20− ]
21−
22−
23−view : () -> Html ()
24−view () =
25− -- Element.layout []
26− -- (Input.text [ Border.rounded 0 ]
27− -- { onChange = always ()
28− -- , text = "yes"
29− -- , placeholder = Nothing
30− -- , label = Input.labelAbove [] <| text ""
31− -- }
32− -- )
33− Element.layout [] <|
34− Element.row [ Element.padding 10 ]
35− [ Element.el
36− styles
37− <|
38− Element.text "Hello yes"
39− , Input.text
40− styles
41− { onChange = always ()
42− , text = "Hello yes"
43− , placeholder = Nothing
44− , label = Input.labelHidden "Hello"
45− }
46− , Element.el
47− [ Element.padding 0
48− , Border.color black
49− , Border.width 1
50− ]
51− <|
52− Element.text "Hello yes"
53− , Input.search
54− [ Element.padding 0
55− , Border.color black
56− , Border.width 1
57− ]
58− { onChange = always ()
59− , text = "Hello yes"
60− , placeholder = Nothing
61− , label = Input.labelHidden "Hello"
62− }
63− , Input.text
64− [ Element.padding 0
65− , Border.color black
66− , Border.width 1
67− ]
68− { onChange = always ()
69− , text = "Hello yes"
70− , placeholder = Nothing
71− , label = Input.labelHidden "Hello"
72− }
73− ]
74−
75−
76−main : Program () () ()
77−main =
78− Browser.sandbox
79− { init = ()
80− , view = view
81− , update = \_ _ -> ()
82− }
tests-rendering/cases/resolved/MultilineCollapsed.elmdeleted−61
@@ -1,61 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Input as Input
8−import Html exposing (Html)
9−import Html.Events exposing (onClick)
10−
11−
12−type alias Model =
13− String
14−
15−
16−type Msg
17− = Type String
18−
19−
20−update : Msg -> Model -> Model
21−update msg model =
22− case msg of
23− Type s ->
24− s
25−
26−
27−view : Model -> Html Msg
28−view model =
29− Element.layout [] <|
30− column [ width fill, height fill ]
31− [ Input.multiline
32− [ height (maximum 200 shrink)
33− ]
34− { onChange = Type
35− , text = model
36− , placeholder = Nothing
37− , label = Input.labelAbove [] <| text "only one line!"
38− , spellcheck = False
39− }
40− , Input.multiline []
41− { onChange = Type
42− , text = model
43− , placeholder = Nothing
44− , label = Input.labelAbove [] <| text "expanded to multi lines."
45− , spellcheck = False
46− }
47− ]
48−
49−
50−main : Program () Model Msg
51−main =
52− Browser.sandbox
53− { init = "yes\nno\nmaybe"
54− , view = view
55− , update = update
56− }
57−
58−
59−sscce : Element msg
60−sscce =
61− Element.text "sscce"
tests-rendering/cases/resolved/MultilineInput.elmdeleted−377
@@ -1,377 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Font as Font
8−import Element.Input as Input exposing (labelAbove, multiline)
9−import Html exposing (Html)
10−import Html.Events exposing (onClick)
11−
12−
13−type alias Model =
14− { multiline : String
15− , single : String
16− }
17−
18−
19−initialModel : Model
20−initialModel =
21− { multiline = testtxt
22− , single = ""
23− }
24−
25−
26−type Msg
27− = MultilineChanged String
28− | SingleChanged String
29−
30−
31−update : Msg -> Model -> Model
32−update msg model =
33− case msg of
34− MultilineChanged new ->
35− { model | multiline = new }
36−
37− SingleChanged new ->
38− { model | single = new }
39−
40−
41−examplePlaceholder =
42− Input.placeholder [ Font.color (rgb 0.2 0.2 0.8) ] (text "My placeholder...")
43−
44−
45−examplePlaceholderLong =
46− Input.placeholder [ Font.color (rgb 0.2 0.2 0.8) ] (text "My placeholderMy placeholderMy placeholderMy placeholderMy placeholderMy placeholderMy placeholderMy placeholder...")
47−
48−
49−background =
50− Background.color (rgb 0 1 0)
51−
52−
53−testtxt =
54− """orem Ipsum is simply dummy text of the printing
55−and typesetting industry. Lorem Ipsum has been the industry's
56−standard dummy text ever since the 1500s, when an unknown
57−printer took a galley of type and scrambled it to make a type specimen book.
58−It has survived not only five centuries, but also the leap into electronic
59−typesetting
60−
61−, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Why do we use it?"""
62−
63−
64−rowTest header els =
65− column [ width fill, spacing 24 ]
66− [ el [] (text header)
67− , row
68− [ width fill
69− , height (px 800)
70− , spacing 50
71− , centerX
72− , Border.width 1
73− ]
74− els
75− ]
76−
77−
78−label str =
79− labelAbove
80− [ width (px 100)
81− , Font.italic
82− ]
83− (text str)
84−
85−
86−view : Model -> Html Msg
87−view model =
88− layout [] <|
89− column []
90− [ el [ Font.size 32 ] (text "Single Input")
91− , viewSingle model
92− , el [ Font.size 32 ] (text "Multiline")
93− , viewMultiline model
94− ]
95−
96−
97−viewMultiline model =
98− column
99− [ width (px 1500)
100− , padding 100
101− , spacing 500
102− , centerX
103− ]
104− [ rowTest "Heights"
105− [ multiline [ background ]
106− { onChange = MultilineChanged
107− , text = model.multiline
108− , placeholder = Nothing
109− , spellcheck = False
110− , label =
111− label "Default"
112− }
113− , multiline [ background, height shrink ]
114− { onChange = MultilineChanged
115− , text = model.multiline
116− , placeholder = Nothing
117− , spellcheck = False
118− , label =
119− label "Height shrink"
120− }
121− , multiline [ background, height fill ]
122− { onChange = MultilineChanged
123− , text = model.multiline
124− , placeholder = Nothing
125− , spellcheck = False
126− , label =
127− label "Height Fill"
128− }
129− , multiline [ background, height (px 200) ]
130− { onChange = MultilineChanged
131− , text = model.multiline
132− , placeholder = Nothing
133− , spellcheck = False
134− , label =
135− label "Height 200px"
136− }
137− ]
138− , rowTest "Widths"
139− [ multiline []
140− { onChange = MultilineChanged
141− , text = model.multiline
142− , placeholder = Nothing
143− , spellcheck = False
144− , label =
145− label "Default"
146− }
147− , multiline [ width fill ]
148− { onChange = MultilineChanged
149− , text = model.multiline
150− , placeholder = Nothing
151− , spellcheck = False
152− , label =
153− label "Width fill"
154− }
155− , multiline [ width shrink ]
156− { onChange = MultilineChanged
157− , text = model.multiline
158− , placeholder = Nothing
159− , spellcheck = False
160− , label =
161− label "Width Shrink"
162− }
163− , multiline [ width (px 300) ]
164− { onChange = MultilineChanged
165− , text = model.multiline
166− , placeholder = Nothing
167− , spellcheck = False
168− , label = label "width 300"
169− }
170− ]
171− , rowTest "Spacing"
172− [ multiline []
173− { onChange = MultilineChanged
174− , text = model.multiline
175− , placeholder = Nothing
176− , spellcheck = False
177− , label =
178− label "Default"
179− }
180− , multiline [ spacing 30, padding 60 ]
181− { onChange = MultilineChanged
182− , text = model.multiline
183− , placeholder = Nothing
184− , spellcheck = False
185− , label =
186− label "Spacing 30"
187− }
188− , multiline [ spacing 0 ]
189− { onChange = MultilineChanged
190− , text = model.multiline
191− , placeholder = Nothing
192− , spellcheck = False
193− , label = label "Spacing 0"
194− }
195− ]
196− , rowTest "Scrollable viewport with different paddings "
197− [ multiline [ height (px 200), padding 30 ]
198− { onChange = MultilineChanged
199− , text = model.multiline
200− , placeholder = Nothing
201− , spellcheck = False
202− , label =
203− label "Height 200, Padding 30"
204− }
205− , multiline [ height (px 200), padding 60 ]
206− { onChange = MultilineChanged
207− , text = model.multiline
208− , placeholder = Nothing
209− , spellcheck = False
210− , label =
211− label "Height 200, Padding 60"
212− }
213− , multiline [ height (px 200), padding 0 ]
214− { onChange = MultilineChanged
215− , text = model.multiline
216− , placeholder = Nothing
217− , spellcheck = False
218− , label = label "Height 200, Padding 0"
219− }
220− ]
221− , rowTest "Placeholders"
222− [ multiline []
223− { onChange = MultilineChanged
224− , text = ""
225− , placeholder = Just examplePlaceholder
226− , spellcheck = False
227− , label =
228− label "Default"
229− }
230− , multiline [ height shrink ]
231− { onChange = MultilineChanged
232− , text = ""
233− , placeholder = Just examplePlaceholder
234− , spellcheck = False
235− , label =
236− label "Height shrink"
237− }
238− , multiline [ height fill ]
239− { onChange = MultilineChanged
240− , text = ""
241− , placeholder = Just examplePlaceholder
242− , spellcheck = False
243− , label =
244− label "Height Fill"
245− }
246− , multiline [ height (px 200) ]
247− { onChange = MultilineChanged
248− , text = ""
249− , placeholder = Just examplePlaceholder
250− , spellcheck = False
251− , label =
252− label "Height 200px"
253− }
254− ]
255− , rowTest "Long Placeholders"
256− [ multiline []
257− { onChange = MultilineChanged
258− , text = ""
259− , placeholder = Just examplePlaceholderLong
260− , spellcheck = False
261− , label =
262− label "Default"
263− }
264− , multiline [ height shrink ]
265− { onChange = MultilineChanged
266− , text = ""
267− , placeholder = Just examplePlaceholderLong
268− , spellcheck = False
269− , label =
270− label "Height shrink"
271− }
272− , multiline [ height fill ]
273− { onChange = MultilineChanged
274− , text = ""
275− , placeholder = Just examplePlaceholderLong
276− , spellcheck = False
277− , label =
278− label "Height Fill"
279− }
280− , multiline [ height (px 200) ]
281− { onChange = MultilineChanged
282− , text = ""
283− , placeholder = Just examplePlaceholderLong
284− , spellcheck = False
285− , label =
286− label "Height 200px"
287− }
288− ]
289− ]
290−
291−
292−singleInput attrs labelTxt model =
293− Input.text attrs
294− { onChange = SingleChanged
295− , text = model
296− , label =
297− labelAbove
298− [ width (px 100)
299− , Font.italic
300− ]
301− (text labelTxt)
302− , placeholder =
303− Just
304− (Input.placeholder [ Font.color (rgb 0.8 0.8 0.8) ]
305− (text "Here is my single input")
306− )
307− }
308−
309−
310−singleInputLongPlaceholder attrs labelTxt model =
311− Input.text attrs
312− { onChange = SingleChanged
313− , text = model
314− , label =
315− labelAbove
316− [ width (px 100)
317− , Font.italic
318− ]
319− (text labelTxt)
320− , placeholder =
321− Just
322− (Input.placeholder [ Font.color (rgb 0.8 0.8 0.8) ]
323− (text "Here is my single input with a placeholder that is super long")
324− )
325− }
326−
327−
328−viewSingle model =
329− column
330− [ width (px 1500)
331− , padding 100
332− , spacing 500
333− , centerX
334− ]
335− [ rowTest "Heights"
336− [ singleInput [] "Default" model.single
337− , singleInput [ height shrink ] "Height shrink" model.single
338− , singleInput [ height fill ] "Height Fill" model.single
339− , singleInput [ height (px 200) ] "Height 200px" model.single
340− ]
341− , rowTest "Widths"
342− [ singleInput [] "Default" model.single
343− , singleInput [ width fill ] "Width fill" model.single
344− , singleInput [ width shrink ] "Width Shrink" model.single
345− , singleInput [ width (px 200) ] "width 200" model.single
346− ]
347− , rowTest "Spacing (no effect)"
348− [ singleInput [] "Default" model.single
349− , singleInput [ spacing 60 ] "Spacing 30" model.single
350− , singleInput [ spacing 0 ] "Spacing 0" model.single
351− ]
352− , rowTest "Padding"
353− [ singleInput [] "Default" model.single
354− , singleInput [ padding 60 ] "Padding 30" model.single
355− , singleInput [ padding 0 ] "Padding 0" model.single
356− ]
357− , rowTest "Scrollable viewport with different paddings "
358− [ singleInput [ height (px 200), padding 30 ] "Height 200, Padding 30" model.single
359− , singleInput [ height (px 200), padding 60 ] "Height 200, Padding 60" model.single
360− , singleInput [ height (px 200), padding 0 ] "Height 200, Padding 0" model.single
361− ]
362− , rowTest "Long Placeholders"
363− [ singleInputLongPlaceholder [] "Default" model.single
364− , singleInputLongPlaceholder [ height shrink ] "Height shrink" model.single
365− , singleInputLongPlaceholder [ height fill ] "Height Fill" model.single
366− , singleInputLongPlaceholder [ height (px 200) ] "Height 200px" model.single
367− ]
368− ]
369−
370−
371−main : Program () Model Msg
372−main =
373− Browser.sandbox
374− { init = initialModel
375− , view = view
376− , update = update
377− }
tests-rendering/cases/resolved/MultilineNewline.elmdeleted−61
@@ -1,61 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Font as Font
8−import Element.Input as Input
9−import Html exposing (Html)
10−import Html.Events
11−
12−
13−type alias Model =
14− { content : String }
15−
16−
17−initialModel : Model
18−initialModel =
19− { content = "" }
20−
21−
22−type Msg
23− = ContentChanged String
24−
25−
26−update : Msg -> Model -> Model
27−update msg model =
28− case msg of
29− ContentChanged str ->
30− { model | content = str }
31−
32−
33−view : Model -> Html Msg
34−view model =
35− Element.layout [ Font.color (rgb 1 0 0) ]
36− (viewInput model)
37−
38−
39−main : Program () Model Msg
40−main =
41− Browser.sandbox
42− { init = initialModel
43− , view = view
44− , update = update
45− }
46−
47−
48−viewInput model =
49− Input.multiline
50− [ padding 50
51− , height (shrink |> maximum 300)
52− , width fill
53− , centerX
54− , centerY
55− ]
56− { onChange = ContentChanged
57− , text = model.content
58− , placeholder = Just (Input.placeholder [] (text "Write your novel, dummy!"))
59− , label = Input.labelAbove [] (text "My Input")
60− , spellcheck = False
61− }
tests-rendering/cases/resolved/Nearby/InFrontIssue.elmdeleted−64
@@ -1,64 +0,0 @@
1−module Nearby.InFrontIssue exposing (view)
2−
3−import Browser
4−import Element as Ui exposing (..)
5−import Element.Background as Background
6−import Element.Font as Font
7−import Html exposing (Html)
8−
9−
10−view : Html Msg
11−view =
12− let
13− a =
14− el
15− [ width fill
16− , height <| px 30
17− , Background.color <| rgb 0 1 0
18− ]
19− <|
20− text "A"
21−
22− b =
23− column
24− [ width fill
25− , height <| px 5000
26− , Background.color <| rgb 1 0 1
27− , spacing 60
28− ]
29− [ text "B"
30− , c
31− ]
32−
33− c =
34− el
35− [ width <| px 100
36− , height <| px 100
37− , Background.color <| rgb 0 0 0
38− , Font.color <| rgb 1 1 1
39− , paddingXY 0 30
40− , centerX
41− , above d
42− , below d
43− , onLeft d
44− , onRight d
45− ]
46− <|
47− text "C"
48−
49− d =
50− el
51− [ width <| px 100
52− , height <| px 100
53− , centerX
54− , Background.color <| rgb 1 1 1
55− , Font.color <| rgb 0 0 0
56− ]
57− <|
58− text "D"
59− in
60− layout
61− [ inFront a
62− , paddingXY 0 30
63− ]
64− b
tests-rendering/cases/resolved/Nearby/Issue22ZIndex.elmdeleted−87
@@ -1,87 +0,0 @@
1−module Nearby.Issue22ZIndex exposing (main)
2−
3−import Browser
4−import Element as Ui exposing (..)
5−import Element.Background as Background
6−import Element.Font as Font
7−import Html exposing (Html)
8−
9−
10−type alias Model =
11− {}
12−
13−
14−initialModel : Model
15−initialModel =
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 -> Html Msg
29−view model =
30− let
31− a =
32− el
33− [ width fill
34− , height <| px 30
35− , Background.color <| rgb 0 1 0
36− ]
37− <|
38− text "A"
39−
40− b =
41− column
42− [ width fill
43− , height <| px 5000
44− , Background.color <| rgb 1 0 1
45− , spacing 60
46− ]
47− [ text "B"
48− , c
49− ]
50−
51− c =
52− el
53− [ width fill
54− , height <| px 100
55− , Background.color <| rgb 0 0 0
56− , Font.color <| rgb 1 1 1
57− , paddingXY 0 30
58− , inFront d
59− ]
60− <|
61− text "C"
62−
63− d =
64− el
65− [ width <| px 100
66− , height <| px 100
67− , centerX
68− , Background.color <| rgb 1 1 1
69− , Font.color <| rgb 0 0 0
70− ]
71− <|
72− text "D"
73− in
74− layout
75− [ inFront a
76− , paddingXY 0 30
77− ]
78− b
79−
80−
81−main : Program () Model Msg
82−main =
83− Browser.sandbox
84− { init = initialModel
85− , view = view
86− , update = update
87− }
tests-rendering/cases/resolved/Nearby/OtherInFrontIssue.elmdeleted−55
@@ -1,55 +0,0 @@
1−module Nearby.OtherInFrontIssue exposing (main)
2−
3−import Browser
4−import Element exposing (Element)
5−import Element.Background as Background
6−import Html exposing (Html, button, div, text)
7−import Html.Attributes
8−import Html.Events exposing (onClick)
9−
10−
11−
12−-- helping hack
13−
14−
15−translateLeft : Element.Attribute msg
16−translateLeft =
17− Html.Attributes.style "transform" "translate(-100%)"
18− |> Element.htmlAttribute
19−
20−
21−main =
22− Element.layout
23− [ Element.inFront <|
24− Element.el
25− [ Element.alignLeft
26− , Background.color <| Element.rgb 1 0.5 0.5
27− , Element.height Element.fill
28− ]
29− <|
30− Element.text "Side Menu .........."
31− ]
32− contentPane
33−
34−
35−contentPane =
36− Element.column
37− [ Element.width Element.fill
38− , Element.height Element.fill
39− , Background.color <| Element.rgb 1 0 0
40− ]
41− [ Element.el
42− [ Element.centerX
43− , Element.centerY
44− , Element.onLeft <| Element.text " [ onLeft. onLeft onLeft onLeft onLeft onLeft onLeft ] "
45− ]
46− (Element.text " [ Content: This will remain behind the Side Menu. ]")
47− , Element.el
48− [ Element.centerX
49− , Element.centerY
50− , Element.behindContent <|
51− Element.el [ translateLeft ] <|
52− Element.text " [ behindContent + translateLeft. behindContent + translateLeft ] "
53− ]
54− (Element.text " [ Content: This will remain behind the Side Menu. ]")
55− ]
tests-rendering/cases/resolved/Nearby/ZIndexRegression.elmdeleted−43
@@ -1,43 +0,0 @@
1−module Nearby.ZIndexRegression exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Html exposing (Html)
6−
7−
8−main : Html msg
9−main =
10− layout [] <|
11− column [ width fill, height fill ]
12− [ el
13− [ width fill
14− , height (px 100)
15− , Background.color (rgb 0 0 1)
16− , inFront menu
17− ]
18− none
19− , el
20− [ width fill
21− , height fill
22− , inFront menu
23− ]
24− none
25− ]
26−
27−
28−menu : Element msg
29−menu =
30− el
31− [ transparent True
32− , mouseOver [ transparent False ]
33− , width fill
34− , height fill
35− , below <|
36− el
37− [ width fill
38− , height (px 500)
39− , Background.color (rgb 1 0 0)
40− ]
41− none
42− ]
43− none
tests-rendering/cases/resolved/NestedColumns.elmdeleted−33
@@ -1,33 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element
5−
6−
7−
8−{- Broken in chrome -}
9−
10−
11−main =
12− Element.layout
13− [ Element.inFront
14− (Element.column []
15− [ Element.column []
16− [ Element.text "1"
17− , Element.text "2"
18− , Element.text "3"
19− ]
20− , Element.column []
21− [ Element.text "4"
22− , Element.text "5"
23− , Element.text "6"
24− ]
25− , Element.column []
26− [ Element.text "7"
27− , Element.text "8"
28− , Element.text "9"
29− ]
30− ]
31− )
32− ]
33− Element.none
tests-rendering/cases/resolved/OtherOtherZindex.elmdeleted−31
@@ -1,31 +0,0 @@
1−module Main exposing (main)
2−
3−import Element
4−import Element.Background
5−
6−
7−main =
8− Element.layout []
9− (Element.el
10− [ Element.inFront
11− (Element.el
12− [ Element.width (Element.px 70)
13− , Element.height (Element.px 70)
14− , Element.Background.color (Element.rgb 0 0 0)
15− ]
16− Element.none
17− )
18− ]
19− (Element.el
20− [ Element.inFront
21− (Element.el
22− [ Element.width (Element.px 50)
23− , Element.height (Element.px 50)
24− , Element.Background.color (Element.rgb 1 0 0)
25− ]
26− Element.none
27− )
28− ]
29− Element.none
30− )
31− )
tests-rendering/cases/resolved/OtherZIndex.elmdeleted−85
@@ -1,85 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Html exposing (Html)
5−import Element as Ui exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−
9−
10−type alias Model =
11− {}
12−
13−
14−initialModel : Model
15−initialModel =
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 -> Html Msg
29−view model =
30− let
31− a =
32− el
33− [ width fill
34− , height <| px 30
35− , Background.color <| rgb 0 1 0
36− ]
37− <| text "A"
38−
39− b =
40− column
41− [ width fill
42− , height <| px 5000
43− , Background.color <| rgb 1 0 1
44− , spacing 60
45− ]
46− [ text "B"
47− , c
48− ]
49−
50− c =
51− el
52− [ width fill
53− , height <| px 100
54− , Background.color <| rgb 0 0 0
55− , Font.color <| rgb 1 1 1
56− , paddingXY 0 30
57− , inFront d
58− ]
59− <|
60− text "C"
61−
62− d =
63− el
64− [ width <| px 100
65− , height <| px 100
66− , centerX
67− , Background.color <| rgb 1 1 1
68− , Font.color <| rgb 0 0 0
69− ]
70− <| text "D"
71− in
72− layout
73− [ inFront a
74− , paddingXY 0 30
75− ]
76− b
77−
78−
79−main : Program () Model Msg
80−main =
81− Browser.sandbox
82− { init = initialModel
83− , view = view
84− , update = update
85− }
tests-rendering/cases/resolved/OverflowingInput.elmdeleted−48
@@ -1,48 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Input as Input
6−import Html exposing (Html)
7−
8−
9−type alias Model =
10− {}
11−
12−
13−type Msg
14− = OnInput String
15−
16−
17−update : Msg -> Model -> Model
18−update msg model =
19− model
20−
21−
22−view : Model -> Html Msg
23−view model =
24− layout [] <|
25− row
26− [ width (px 200)
27− , padding 8
28− , spacing 16
29− ]
30− [ Input.text
31− [ padding 4
32− , width fill
33− ]
34− { onChange = OnInput
35− , text = "text"
36− , placeholder = Nothing
37− , label = Input.labelHidden "label"
38− }
39− ]
40−
41−
42−main : Program () Model Msg
43−main =
44− Browser.sandbox
45− { init = {}
46− , view = view
47− , update = update
48− }
tests-rendering/cases/resolved/OverflowingInput2.elmdeleted−54
@@ -1,54 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element
5−import Element.Background as Background
6−import Element.Input as Input
7−import Html exposing (Html)
8−
9−
10−type alias Model =
11− {}
12−
13−
14−type Msg
15− = TextUpdated String
16−
17−
18−update : Msg -> Model -> Model
19−update msg model =
20− case msg of
21− TextUpdated _ ->
22− model
23−
24−
25−view : Model -> Html Msg
26−view model =
27− Element.layout
28− []
29− (Element.row
30− [ Element.width (Element.px 100)
31− , Element.padding 10
32− , Background.color (Element.rgb 1 0 0)
33− ]
34− [ Input.text
35− [ Element.width (Element.fillPortion 2)
36−
37− -- Element.width Element.fill
38− ]
39− { onChange = TextUpdated
40− , text = ""
41− , placeholder = Nothing
42− , label = Input.labelHidden ""
43− }
44− ]
45− )
46−
47−
48−main : Program () Model Msg
49−main =
50− Browser.sandbox
51− { init = {}
52− , view = view
53− , update = update
54− }
tests-rendering/cases/resolved/OverflowingInput3.elmdeleted−95
@@ -1,95 +0,0 @@
1−module Main exposing (main)
2−
3−import Browser
4−import Element exposing (..)
5−import Element.Background as Background
6−import Element.Border as Border
7−import Element.Font as Font
8−import Element.Input as Input
9−import Html exposing (Html)
10−
11−
12−type alias Model =
13− { count : Int }
14−
15−
16−initialModel : Model
17−initialModel =
18− { count = 0 }
19−
20−
21−type Msg
22− = Increment
23− | Decrement
24−
25−
26−update : Msg -> Model -> Model
27−update msg model =
28− case msg of
29− Increment ->
30− { model | count = model.count + 1 }
31−
32− Decrement ->
33− { model | count = model.count - 1 }
34−
35−
36−blue =
37− rgb 0 0 1
38−
39−
40−red =
41− rgb 1 0 0
42−
43−
44−view : Model -> Html Msg
45−view model =
46− layout [ width fill, padding 5 ] <|
47− column [ width fill, spacing 10 ]
48− [ row [ width fill, height <| px 100 ]
49− [ link [ height fill, width <| fillPortion 1, Background.color blue ]
50− { url = "https://github.com/mdgriffith/elm-ui/issues"
51− , label = paragraph [ Font.center ] [ text "Hello!" ]
52− }
53− , el [ height fill, width <| fillPortion 2, Background.color red ] none
54− ]
55− , row [ width fill, height <| px 100 ]
56− [ el [ height fill, width <| fillPortion 1, Background.color blue ] (text "Hello!")
57− , el [ height fill, width <| fillPortion 2, Background.color red ] none
58− ]
59− ]
60−
61−
62−button : String -> Element Msg
63−button label =
64− el
65− [ Border.rounded 2
66− , Border.width 1
67− , Border.color black
68− , Background.color white
69− , Font.color black
70− , padding 5
71− , mouseOver
72− [ Font.color white
73− , Background.color black
74− ]
75− ]
76− (text label)
77−
78−
79−black : Color
80−black =
81− rgb 0 0 0
82−
83−
84−white : Color
85−white =
86− rgb 255 255 255
87−
88−
89−main : Program () Model Msg
90−main =
91− Browser.sandbox
92− { init = initialModel
93− , view = view
94− , update = update
95− }
tests-rendering/cases/resolved/ReversedTableOrder.elmdeleted−56
@@ -1,56 +0,0 @@
1−module Main exposing (Person, main, persons)
2−
3−{-| -}
4−
5−import Element exposing (..)
6−import Element.Background as Background
7−import Element.Font as Font
8−import Element.Input
9−
10−
11−type alias Person =
12− { firstName : String
13− , lastName : String
14− }
15−
16−
17−persons : List Person
18−persons =
19− [ { firstName = "David"
20− , lastName = "Bowie"
21− }
22− , { firstName = "Florence"
23− , lastName = "Welch"
24− }
25− ]
26−
27−
28−main =
29− Element.layout [] <|
30− Element.table []
31− { data = persons
32− , columns =
33− [ { header = Element.text "First Name"
34− , width = fill
35− , view =
36− \person ->
37− Element.Input.text []
38− { text = person.firstName
39− , placeholder = Nothing
40− , onChange = always Nothing
41− , label = Element.Input.labelAbove [] Element.none
42− }
43− }
44− , { header = Element.text "Last Name"
45− , width = fill
46− , view =
47− \person ->
48− Element.Input.text []
49− { text = person.lastName
50− , placeholder = Nothing
51− , onChange = always Nothing
52− , label = Element.Input.labelAbove [] Element.none
53− }
54− }
55− ]
56− }
tests-rendering/cases/resolved/TextAreaMax.elmdeleted−80
@@ -1,80 +0,0 @@
1−module Main exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Bg
5−import Element.Font as Font
6−import Element.Input as Input
7−
8−
9−large =
10− """Hi
11−Hello
12− -->
13−
14− World!"""
15−
16−
17−empty =
18− ""
19−
20−
21−singleLine =
22− "Hello World! ->"
23−
24−
25−placeholder =
26− "placeholder"
27−
28−
29−main =
30− Element.layout [ width fill, height fill, Font.color (rgb 1 0 0) ] <|
31− column [ width fill, height fill ]
32− [ Input.multiline
33− [ centerX
34− , spacing 20
35−
36− -- , height (px 100)
37− , width shrink
38− ]
39− { onChange = always ()
40− , text = empty
41− , placeholder = Just (Input.placeholder [] (text "hello"))
42− , label = Input.labelAbove [] none
43− , spellcheck = False
44− }
45− , el
46− [ width <| px 500
47− , height <| px 20
48− , Bg.color <| rgb255 0 0 0
49− , centerX
50− ]
51− none
52− , Input.text
53− [ centerX
54− , spacing 5
55−
56− -- , height (px 100)
57− -- , width shrink
58− -- , height shrink
59− , width (px 200)
60− ]
61− { onChange = always ()
62− , text = empty
63− , placeholder = Just (Input.placeholder [] (text placeholder))
64− , label = Input.labelAbove [] (text "labeled")
65− }
66− , Input.text
67− [ centerX
68− , spacing 5
69−
70− -- , height (px 100)
71− -- , width shrink
72− -- , height shrink
73− , width (px 200)
74− ]
75− { onChange = always ()
76− , text = "Filled Content"
77− , placeholder = Just (Input.placeholder [] (text placeholder))
78− , label = Input.labelBelow [] (text "labeled")
79− }
80− ]
tests-rendering/cases/resolved/WeirdWrapping.elmdeleted−32
@@ -1,32 +0,0 @@
1−module Main exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Element.Border as Border exposing (widthEach)
6−import Element.Font as Font
7−
8−
9−main =
10− Element.layout
11− [ height fill
12− , width fill
13− , padding 5
14− ]
15− <|
16− row
17− [ width fill ]
18− [ newTabLink
19− [ widthEach
20− { bottom = 0
21− , left = 2
22− , right = 0
23− , top = 0
24− }
25− , paddingXY 3 0
26− ]
27− { url = "url.example.com"
28− , label =
29− [ text "My news site super cool header" ]
30− |> paragraph []
31− }
32− ]
tests-rendering/cases/resolved/ZIndex.elmdeleted−56
@@ -1,56 +0,0 @@
1−module Main exposing (main)
2−
3−import Element exposing (..)
4−import Element.Background as Background
5−import Element.Input as Input
6−import Element.Keyed as Keyed
7−import Html.Attributes exposing (style)
8−
9−
10−grey =
11− rgb 0.8 0.8 0.8
12−
13−
14−darkGrey =
15− rgb 0.7 0.7 0.7
16−
17−
18−type Msg
19− = NoMsg String
20−
21−
22−main =
23− Element.layout [ width fill, height fill ] <|
24− column
25− [ width fill
26− ]
27− [ el
28− [ width fill
29− , Background.color grey
30− , padding 20
31−
32− , below <|
33− el
34− [ height (px 300)
35− , width (px 300)
36− , Background.color darkGrey
37− , moveRight 50
38− , padding 50
39− ]
40− (el [ alignBottom ] (text "I'm a dropdown menu."))
41− ]
42− (text "I'm a toolbar.")
43− , Input.text []
44− { onChange = NoMsg
45− , text = ""
46− , placeholder = Just (Input.placeholder [] (text "I'm a text input."))
47− , label = Input.labelAbove [] none
48− }
49− , Input.multiline []
50− { onChange = NoMsg
51− , text = ""
52− , placeholder = Just (Input.placeholder [] (text "I'm a multiline input."))
53− , label = Input.labelAbove [] none
54− , spellcheck = False
55− }
56− ]
tests-rendering/cases/resolved/elm.jsondeleted−25
@@ -1,25 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": [
4− ".",
5− "../../../src/"
6− ],
7− "elm-version": "0.19.0",
8− "dependencies": {
9− "direct": {
10− "elm/browser": "1.0.0",
11− "elm/core": "1.0.0",
12− "elm/html": "1.0.0",
13− "elm/json": "1.0.0",
14− "elm/virtual-dom": "1.0.0"
15− },
16− "indirect": {
17− "elm/time": "1.0.0",
18− "elm/url": "1.0.0"
19− }
20− },
21− "test-dependencies": {
22− "direct": {},
23− "indirect": {}
24− }
25−}
tests-rendering/elm.jsondeleted−25
@@ -1,25 +0,0 @@
1−{
2− "type": "application",
3− "source-directories": ["src", "../src", "cases/open", "cases/resolved"],
4− "elm-version": "0.19.1",
5− "dependencies": {
6− "direct": {
7− "elm/browser": "1.0.2",
8− "elm/core": "1.0.0",
9− "elm/html": "1.0.0",
10− "elm/json": "1.0.0",
11− "elm/parser": "1.1.0",
12− "elm/random": "1.0.0",
13− "elm/time": "1.0.0",
14− "elm/virtual-dom": "1.0.2",
15− "elm-explorations/test": "1.1.0"
16− },
17− "indirect": {
18− "elm/url": "1.0.0"
19− }
20− },
21− "test-dependencies": {
22− "direct": {},
23− "indirect": {}
24− }
25−}
tests-rendering/src/Testable/Element.elmdeleted−1723
@@ -1,1723 +0,0 @@
1−module Testable.Element exposing
2− ( Length(..)
3− , above
4− , alignBottom
5− , alignLeft
6− , alignRight
7− , alignTop
8− , alpha
9− , behindContent
10− , below
11− , centerX
12− , centerY
13− , clip
14− , column
15− , el
16− , expectRoundedEquality
17− , fill
18− , fillPortion
19− , height
20− , inFront
21− , isVisible
22− , label
23− , layout
24− , link
25− , maximum
26− , minimum
27− , moveDown
28− , moveLeft
29− , moveRight
30− , moveUp
31− , none
32− , onLeft
33− , onRight
34− , padding
35− , paddingXY
36− , paragraph
37− , px
38− , rgb
39− , rgba
40− , row
41− , scrollbarX
42− , scrollbarY
43− , scrollbars
44− , shrink
45− , spacing
46− , text
47− , textColumn
48− , toProgram
49− , transparent
50− , width
51− )
52−
53−{-| This module should mirror the top level `Element` api, with one important distinction.
54−
55−The resulting `Element msg` structure can either be rendered to Html or transformed into a test suite that can be run.
56−
57−In order to run the test:
58−
59− - render html
60− - gather information from the browser
61− - generate tests
62−
63−-}
64−
65−import Dict
66−import Element
67−import Html.Attributes
68−import Testable
69−import Testable.Runner
70−
71−
72−{-| This is used when we want to run all tests in a test suite instead of one at a time.
73−-}
74−toProgram : Testable.Runner.Testable -> Testable.Runner.TestableProgram
75−toProgram testable =
76− Testable.Runner.program [ testable ]
77−
78−
79−layout : List (Testable.Attr msg) -> Testable.Element Testable.Runner.Msg -> Testable.Runner.Testable
80−layout attrs elem =
81− Testable.Runner.testable "Test" elem
82−
83−
84−text : String -> Testable.Element msg
85−text =
86− Testable.Text
87−
88−
89−el : List (Testable.Attr msg) -> Testable.Element msg -> Testable.Element msg
90−el attrs =
91− Testable.El (implicitWidthHeightShrink attrs)
92−
93−
94−row : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
95−row attrs =
96− Testable.Row (implicitWidthHeightShrink attrs)
97−
98−
99−column : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
100−column attrs =
101− Testable.Column (implicitWidthHeightShrink attrs)
102−
103−
104−none : Testable.Element msg
105−none =
106− Testable.Empty
107−
108−
109−paragraph : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
110−paragraph attrs =
111− let
112− withImplicits =
113− implicitTest (widthHelper Nothing Nothing (Fill 1))
114− :: implicitTest (heightHelper Nothing Nothing Shrink)
115− :: attrs
116− in
117− Testable.Paragraph (skipOverridden withImplicits)
118−
119−
120−textColumn : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
121−textColumn attrs =
122− let
123− withImplicits =
124− implicitTest (widthHelper (Just 500) (Just 750) (Fill 1))
125− :: implicitTest (heightHelper Nothing Nothing Shrink)
126− :: attrs
127− in
128− Testable.TextColumn (skipOverridden withImplicits)
129−
130−
131−link :
132− List (Testable.Attr msg)
133− ->
134− { url : String
135− , label : Testable.Element msg
136− }
137− -> Testable.Element msg
138−link attrs details =
139− Testable.Link details.url
140− (implicitWidthHeightShrink attrs)
141− details.label
142−
143−
144−clip =
145− Testable.Attr Element.clip
146−
147−
148−{-| -}
149−scrollbars : Testable.Attr msg
150−scrollbars =
151− Testable.Attr Element.scrollbars
152−
153−
154−{-| -}
155−scrollbarY : Testable.Attr msg
156−scrollbarY =
157− Testable.Attr Element.scrollbarY
158−
159−
160−{-| -}
161−scrollbarX : Testable.Attr msg
162−scrollbarX =
163− Testable.Attr Element.scrollbarX
164−
165−
166−{-| Old labeling mechanism that i removed to hastily
167−-}
168−label str =
169− Testable.Batch []
170−
171−
172−moveUp x =
173− Testable.Attr (Element.moveUp x)
174−
175−
176−moveDown x =
177− Testable.Attr (Element.moveDown x)
178−
179−
180−moveRight x =
181− Testable.Attr (Element.moveRight x)
182−
183−
184−moveLeft x =
185− Testable.Attr (Element.moveLeft x)
186−
187−
188−type Length
189− = Px Int
190− | Fill Int
191− | Shrink
192− | Minimum Int Length
193− | Maximum Int Length
194−
195−
196−minimum =
197− Minimum
198−
199−
200−maximum =
201− Maximum
202−
203−
204−rgb =
205− Element.rgb
206−
207−
208−rgba =
209− Element.rgba
210−
211−
212−px : Int -> Length
213−px =
214− Px
215−
216−
217−fill : Length
218−fill =
219− Fill 1
220−
221−
222−shrink : Length
223−shrink =
224− Shrink
225−
226−
227−fillPortion : Int -> Length
228−fillPortion =
229− Fill
230−
231−
232−transparent : Bool -> Testable.Attr msg
233−transparent on =
234− Testable.LabeledTest
235− { label =
236− if on then
237− "transparent"
238−
239− else
240− "opaque"
241− , attr = Element.transparent on
242− , id = Testable.NoId
243− , test =
244− \context ->
245− let
246− selfTransparency =
247− context.self.style
248− |> Dict.get "opacity"
249− |> Maybe.withDefault "notfound"
250−
251− value =
252− if on then
253− "0"
254−
255− else
256− "1"
257− in
258− [ Testable.equal value selfTransparency ]
259− }
260−
261−
262−{-| -}
263−isVisible : Testable.Attr msg
264−isVisible =
265− Testable.AttrTest
266− { label = "is-visible"
267− , id = Testable.NoId
268− , test =
269− \context ->
270− [ Testable.equal context.self.isVisible True ]
271− }
272−
273−
274−{-| -}
275−alpha : Float -> Testable.Attr msg
276−alpha a =
277− Testable.LabeledTest
278− { label = "alpha-" ++ String.fromFloat a
279− , attr = Element.alpha a
280− , id = Testable.NoId
281− , test =
282− \context ->
283− let
284− selfTransparency =
285− context.self.style
286− |> Dict.get "opacity"
287− |> Maybe.withDefault "notfound"
288− in
289− [ Testable.equal (String.fromFloat a) selfTransparency ]
290− }
291−
292−
293−{-| -}
294−padding : Int -> Testable.Attr msg
295−padding pad =
296− Testable.LabeledTest
297− { label = "padding " ++ String.fromInt pad
298− , attr = Element.padding pad
299− , id = Testable.NoId
300− , test =
301− \found ->
302− [ Testable.true ("Padding " ++ String.fromInt pad ++ " is present")
303− (List.all ((==) pad)
304− [ floor found.self.bbox.padding.left
305− , floor found.self.bbox.padding.right
306− , floor found.self.bbox.padding.top
307− , floor found.self.bbox.padding.bottom
308− ]
309− )
310− ]
311− }
312−
313−
314−{-| -}
315−paddingXY : Int -> Int -> Testable.Attr msg
316−paddingXY x y =
317− Testable.LabeledTest
318− { label = "paddingXY " ++ String.fromInt x ++ ", " ++ String.fromInt y
319− , attr = Element.paddingXY x y
320− , id = Testable.NoId
321− , test =
322− \found ->
323− [ Testable.true ("PaddingXY (" ++ String.fromInt x ++ ", " ++ String.fromInt y ++ ") is present")
324− (List.all ((==) x)
325− [ floor found.self.bbox.padding.left
326− , floor found.self.bbox.padding.right
327− ]
328− && List.all ((==) y)
329− [ floor found.self.bbox.padding.top
330− , floor found.self.bbox.padding.bottom
331− ]
332− )
333− ]
334− }
335−
336−
337−listIf ls =
338− List.filter Tuple.first ls
339− |> List.map Tuple.second
340−
341−
342−widthHelper maybeMin maybeMax len =
343− let
344− addMin l =
345− case maybeMin of
346− Nothing ->
347− l
348−
349− Just minPx ->
350− l |> Element.minimum minPx
351−
352− addMax l =
353− case maybeMax of
354− Nothing ->
355− l
356−
357− Just maxPx ->
358− l |> Element.maximum maxPx
359−
360− minLabel =
361− case maybeMin of
362− Nothing ->
363− ""
364−
365− Just i ->
366− " min:" ++ String.fromInt i
367−
368− maxLabel =
369− case maybeMax of
370− Nothing ->
371− ""
372−
373− Just i ->
374− " max:" ++ String.fromInt i
375−
376− minMaxTest actualWidth =
377− case ( maybeMin, maybeMax ) of
378− ( Nothing, Nothing ) ->
379− True
380−
381− ( Just lower, Nothing ) ->
382− lower <= actualWidth
383−
384− ( Just lower, Just higher ) ->
385− lower <= actualWidth && actualWidth <= higher
386−
387− ( Nothing, Just higher ) ->
388− actualWidth <= higher
389− in
390− case len of
391− Minimum m newLen ->
392− widthHelper (Just m) maybeMax newLen
393−
394− Maximum m newLen ->
395− widthHelper maybeMin (Just m) newLen
396−
397− Px val ->
398− -- Pixel values should ignore min and max?
399− Testable.LabeledTest
400− { label = "width " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
401− , id = Testable.IsWidth
402− , attr =
403− Element.width
404− (Element.px val
405− |> addMin
406− |> addMax
407− )
408− , test =
409− \found ->
410− [ expectRoundedEquality
411− { expected = toFloat val
412− , found = found.self.bbox.width
413− }
414− , Testable.true "min/max is upheld" (minMaxTest (floor found.self.bbox.width))
415− ]
416− }
417−
418− Fill portion ->
419− Testable.LabeledTest
420− { label =
421− if portion == 1 then
422− "width fill" ++ minLabel ++ maxLabel
423−
424− else
425− "width fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
426− , id = Testable.IsWidth
427− , attr =
428− Element.width
429− (Element.fillPortion portion
430− |> addMin
431− |> addMax
432− )
433− , test =
434− \context ->
435− if List.member context.parentLayout [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
436− [ Testable.true "width fill doesn't apply to onright/onleft elements" True ]
437−
438− else
439− let
440− parentAvailableWidth =
441− context.parent.bbox.width - (context.self.bbox.padding.left + context.self.bbox.padding.right)
442− in
443− List.concat
444− [ case context.parentLayout of
445− Testable.IsNearby _ ->
446− [ Testable.true "Nearby Element has fill width"
447− ((floor context.parent.bbox.width == floor context.self.bbox.width)
448− || minMaxTest (floor context.self.bbox.width)
449− )
450− ]
451−
452− Testable.InColumn ->
453− [ Testable.true "Element within column has fill width"
454− ((floor parentAvailableWidth == floor context.self.bbox.width)
455− || minMaxTest (floor context.self.bbox.width)
456− )
457− ]
458−
459− Testable.InEl ->
460− [ Testable.true "Element within element has fill width" <|
461− (floor parentAvailableWidth == floor context.self.bbox.width)
462− || minMaxTest (floor context.self.bbox.width)
463− ]
464−
465− _ ->
466− let
467− spacePerPortion =
468− parentAvailableWidth / toFloat (List.length context.siblings + 1)
469− in
470− [ Testable.true "element has fill width" <|
471− (floor spacePerPortion == floor context.self.bbox.width)
472− || minMaxTest (floor context.self.bbox.width)
473− ]
474− , [ Testable.lessThanOrEqual "not larger than parent"
475− context.self.bbox.width
476− context.parent.bbox.width
477− ]
478− , case context.selfElement of
479− Testable.Paragraph _ _ ->
480− -- A paragraph with width fill
481− -- we want to test for correct text wrapping here.
482− --
483− let
484− childWidth child =
485− child.bbox.width
486−
487− totalChildren =
488− context.children
489− |> List.map childWidth
490− |> List.append (List.map .width context.self.textMetrics)
491− |> List.sum
492−
493− horizontalPadding =
494− context.self.bbox.padding.left + context.self.bbox.padding.right
495−
496− totalCalculatedWidth =
497− totalChildren + horizontalPadding
498−
499− expectedLines =
500− if boxChildrenHeight > 20 then
501− ceiling (boxChildrenHeight / 20)
502−
503− else
504− ceiling (totalCalculatedWidth / context.self.bbox.width)
505−
506− boxChildrenHeight =
507− context.children
508− |> List.map
509− (\c ->
510− c.bbox.height
511− )
512− |> List.sum
513− in
514− [ Testable.true "text wrapping, checking height"
515− -- all we're doing here is testing if wrapping is occurring
516− -- not the exact height, which is a little tricky to calculate perfectly without more information.
517− (if expectedLines > 1 then
518− context.self.bbox.height >= (20 * 2)
519−
520− else
521− -- then it's less than 2 ~ line heights
522− -- there's some weird variance here which makes it hard to be exact.
523− context.self.bbox.height < (20 * 2)
524− )
525− ]
526−
527− _ ->
528− []
529− ]
530− }
531−
532− Shrink ->
533− Testable.LabeledTest
534− { label = "width shrink" ++ minLabel ++ maxLabel
535− , attr =
536− Element.width
537− (Element.shrink
538− |> addMin
539− |> addMax
540− )
541− , id = Testable.IsWidth
542− , test =
543− \context ->
544− case context.selfElement of
545− Testable.El _ _ ->
546− let
547− childWidth child =
548− child.bbox.width
549−
550− totalChildren =
551− context.children
552− |> List.map childWidth
553− |> List.append (List.map .width context.self.textMetrics)
554− |> List.sum
555−
556− horizontalPadding =
557− context.self.bbox.padding.left + context.self.bbox.padding.right
558− in
559− listIf
560− [ ( (context.parentLayout /= Testable.InParagraph)
561− && (context.parentLayout /= Testable.InTextCol)
562− , Testable.rounded "equals children"
563− { expected = totalChildren + horizontalPadding
564− , found = context.self.bbox.width
565− }
566− )
567− , ( context.parentLayout /= Testable.AtRoot
568− , Testable.lessThanOrEqual "not larger than parent"
569− context.self.bbox.width
570− context.parent.bbox.width
571− )
572− ]
573−
574− Testable.Link _ _ _ ->
575− let
576− childWidth child =
577− child.bbox.width
578−
579− totalChildren =
580− context.children
581− |> List.map childWidth
582− |> List.append (List.map .width context.self.textMetrics)
583− |> List.sum
584−
585− horizontalPadding =
586− context.self.bbox.padding.left + context.self.bbox.padding.right
587− in
588− listIf
589− [ ( (context.parentLayout /= Testable.InParagraph)
590− && (context.parentLayout /= Testable.InTextCol)
591− , Testable.rounded "equals children"
592− { expected = totalChildren + horizontalPadding
593− , found = context.self.bbox.width
594− }
595− )
596− , ( context.parentLayout /= Testable.AtRoot
597− , Testable.lessThanOrEqual "not larger than parent"
598− context.self.bbox.width
599− context.parent.bbox.width
600− )
601− ]
602−
603− Testable.Row rowAttrs _ ->
604− -- width of row is the sum of all children widths
605− -- both text elements and others.
606− let
607− childWidth child =
608− child.bbox.width
609−
610− totalChildren =
611− context.children
612− |> List.map childWidth
613− |> List.append (List.map .width context.self.textMetrics)
614− |> List.sum
615−
616− horizontalPadding =
617− context.self.bbox.padding.left + context.self.bbox.padding.right
618−
619− spacingAmount =
620− Testable.getSpacingFromAttributes rowAttrs
621−
622− totalSpacing =
623− toFloat spacingAmount * (toFloat (List.length context.children) - 1)
624− in
625− listIf
626− [ ( True
627− , expectRoundedEquality
628− { expected = totalChildren + horizontalPadding + totalSpacing
629− , found = context.self.bbox.width
630− }
631− )
632− , ( context.parentLayout /= Testable.AtRoot
633− , Testable.lessThanOrEqual "not larger than parent"
634− context.self.bbox.width
635− context.parent.bbox.width
636− )
637− ]
638−
639− Testable.Column _ _ ->
640− -- The width of the column is the width of the widest child.
641− let
642− childWidth child =
643− child.bbox.width
644− + context.self.bbox.padding.left
645− + context.self.bbox.padding.right
646−
647− textChildren =
648− List.map
649− (\txt ->
650− txt.width
651− + context.self.bbox.padding.left
652− + context.self.bbox.padding.right
653− )
654− context.self.textMetrics
655−
656− allChildren =
657− context.children
658− |> List.map childWidth
659− |> List.append textChildren
660− in
661− listIf
662− [ ( True
663− , expectRoundedEquality
664− { expected = Maybe.withDefault 0 (List.maximum allChildren)
665− , found = context.self.bbox.width
666− }
667− )
668− , ( context.parentLayout /= Testable.AtRoot
669− , Testable.lessThanOrEqual "not larger than parent"
670− context.self.bbox.width
671− context.parent.bbox.width
672− )
673− ]
674−
675− Testable.TextColumn _ _ ->
676− -- The width of the column is the width of the widest child.
677− let
678− childWidth child =
679− child.bbox.width
680− + context.self.bbox.padding.left
681− + context.self.bbox.padding.right
682−
683− textChildren =
684− List.map
685− (\txt ->
686− txt.width
687− + context.self.bbox.padding.left
688− + context.self.bbox.padding.right
689− )
690− context.self.textMetrics
691−
692− allChildren =
693− context.children
694− |> List.map childWidth
695− |> List.append textChildren
696− in
697− listIf
698− [ ( True
699− , expectRoundedEquality
700− { expected = Maybe.withDefault 0 (List.maximum allChildren)
701− , found = context.self.bbox.width
702− }
703− )
704− , ( context.parentLayout /= Testable.AtRoot
705− , Testable.lessThanOrEqual "not larger than parent"
706− context.self.bbox.width
707− context.parent.bbox.width
708− )
709− ]
710−
711− Testable.Paragraph _ _ ->
712− -- This should be the size it's text,
713− -- unless it takes up all available space, in which case it should wrap.
714− let
715− childWidth child =
716− child.bbox.width
717−
718− totalChildren =
719− context.children
720− |> List.map childWidth
721− |> List.append (List.map .width context.self.textMetrics)
722− |> List.sum
723−
724− horizontalPadding =
725− context.self.bbox.padding.left + context.self.bbox.padding.right
726− in
727− listIf
728− [ ( True
729− , expectRoundedEquality
730− { expected = totalChildren + horizontalPadding
731− , found = context.self.bbox.width
732− }
733− )
734− , ( context.parentLayout /= Testable.AtRoot
735− , Testable.lessThanOrEqual "not larger than parent"
736− context.self.bbox.width
737− context.parent.bbox.width
738− )
739− ]
740−
741− Testable.Text _ ->
742− []
743−
744− Testable.Empty ->
745− []
746− }
747−
748−
749−heightHelper maybeMin maybeMax len =
750− let
751− addMin l =
752− case maybeMin of
753− Nothing ->
754− l
755−
756− Just minPx ->
757− l |> Element.minimum minPx
758−
759− addMax l =
760− case maybeMax of
761− Nothing ->
762− l
763−
764− Just maxPx ->
765− l |> Element.maximum maxPx
766−
767− minLabel =
768− case maybeMin of
769− Nothing ->
770− ""
771−
772− Just i ->
773− " min:" ++ String.fromInt i
774−
775− maxLabel =
776− case maybeMax of
777− Nothing ->
778− ""
779−
780− Just i ->
781− " max:" ++ String.fromInt i
782−
783− minMaxTest actualheight =
784− case ( maybeMin, maybeMax ) of
785− ( Nothing, Nothing ) ->
786− True
787−
788− ( Just lower, Nothing ) ->
789− lower <= actualheight
790−
791− ( Just lower, Just higher ) ->
792− lower <= actualheight && actualheight <= higher
793−
794− ( Nothing, Just higher ) ->
795− actualheight <= higher
796− in
797− case len of
798− Minimum m newLen ->
799− heightHelper (Just m) maybeMax newLen
800−
801− Maximum m newLen ->
802− heightHelper maybeMin (Just m) newLen
803−
804− Px val ->
805− -- Pixel values should ignore min and max?
806− Testable.LabeledTest
807− { label = "height " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
808− , attr =
809− Element.height
810− (Element.px val
811− |> addMin
812− |> addMax
813− )
814− , id = Testable.IsHeight
815− , test =
816− \found ->
817− [ expectRoundedEquality
818− { expected = toFloat val
819− , found = found.self.bbox.height
820− }
821− , Testable.true "min/max holds true"
822− (minMaxTest (floor found.self.bbox.height))
823− ]
824− }
825−
826− Fill portion ->
827− Testable.LabeledTest
828− { label = "height fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
829− , attr =
830− Element.height
831− (Element.fillPortion portion
832− |> addMin
833− |> addMax
834− )
835− , id = Testable.IsHeight
836− , test =
837− \context ->
838− [ if List.member context.parentLayout [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
839− Testable.true "height fill doesn't apply to above/below elements" True
840−
841− else
842− let
843− parentAvailableHeight =
844− context.parent.bbox.height - (context.self.bbox.padding.top + context.self.bbox.padding.bottom)
845− in
846− case context.parentLayout of
847− Testable.IsNearby _ ->
848− Testable.true "Nearby Element has fill height"
849− ((floor context.parent.bbox.height == floor context.self.bbox.height)
850− || minMaxTest (floor context.self.bbox.height)
851− )
852−
853− Testable.InColumn ->
854− Testable.true "Element within column has fill height"
855− ((floor parentAvailableHeight == floor context.self.bbox.height)
856− || minMaxTest (floor context.self.bbox.height)
857− )
858−
859− Testable.InEl ->
860− Testable.true "Element within el has fill height" <|
861− (floor parentAvailableHeight == floor context.self.bbox.height)
862− || minMaxTest (floor context.self.bbox.height)
863−
864− _ ->
865− let
866− spacePerPortion =
867− parentAvailableHeight / toFloat (List.length context.siblings + 1)
868− in
869− Testable.true "el has fill height" <|
870− (floor spacePerPortion == floor context.self.bbox.height)
871− || minMaxTest (floor context.self.bbox.height)
872− ]
873− }
874−
875− Shrink ->
876− Testable.LabeledTest
877− { label = "height shrink" ++ minLabel ++ maxLabel
878− , attr =
879− Element.height
880− (Element.shrink
881− |> addMin
882− |> addMax
883− )
884− , id = Testable.IsHeight
885− , test =
886− \context ->
887− case context.selfElement of
888− Testable.El _ _ ->
889− let
890− childHeight child =
891− child.bbox.height
892− in
893− if List.isEmpty context.children then
894− -- context.self.textMetrics
895− -- |> List.map Testable.textHeight
896− -- |> List.sum
897− -- TODO: apparently the font metrics we have are for the literal characters rendered
898− -- not for the font itself.
899− [ Testable.todo "calculate height from actual text metrics"
900− ]
901−
902− else
903− [ expectRoundedEquality
904− { expected =
905− context.children
906− |> List.map childHeight
907− |> List.sum
908− |> (\h -> h + context.self.bbox.padding.top + context.self.bbox.padding.bottom)
909− , found = context.self.bbox.height
910− }
911− , Testable.lessThanOrEqual "not larger than parent"
912− context.self.bbox.height
913− context.parent.bbox.height
914− ]
915−
916− Testable.Link _ _ _ ->
917− let
918− childHeight child =
919− child.bbox.height
920− in
921− if List.isEmpty context.children then
922− -- context.self.textMetrics
923− -- |> List.map Testable.textHeight
924− -- |> List.sum
925− -- TODO: apparently the font metrics we have are for the literal characters rendered
926− -- not for the font itself.
927− [ Testable.todo "calculate height from actual text metrics"
928− ]
929−
930− else
931− [ expectRoundedEquality
932− { expected =
933− context.children
934− |> List.map childHeight
935− |> List.sum
936− |> (\h -> h + context.self.bbox.padding.top + context.self.bbox.padding.bottom)
937− , found = context.self.bbox.height
938− }
939− , Testable.lessThanOrEqual "not larger than parent"
940− context.self.bbox.height
941− context.parent.bbox.height
942− ]
943−
944− Testable.Row _ _ ->
945− let
946− childHeight child =
947− child.bbox.height
948− in
949− if List.isEmpty context.children then
950− -- context.self.textMetrics
951− -- |> List.map Testable.textHeight
952− -- |> List.sum
953− -- TODO: apparently the font metrics we have are for the literal characters rendered
954− -- not for the font itself.
955− [ Testable.todo "calculate height from actual text metrics" ]
956−
957− else
958− [ expectRoundedEquality
959− { expected =
960− context.children
961− |> List.map childHeight
962− |> List.maximum
963− |> Maybe.withDefault 0
964− |> (\h -> h + context.self.bbox.padding.top + context.self.bbox.padding.bottom)
965− , found = context.self.bbox.height
966− }
967− , Testable.lessThanOrEqual "not larger than parent"
968− context.self.bbox.height
969− context.parent.bbox.height
970− ]
971−
972− Testable.Column colAttrs _ ->
973− let
974− childHeight child =
975− child.bbox.height
976−
977− totalChildren =
978− context.children
979− |> List.map childHeight
980− |> List.append (List.map Testable.textHeight context.self.textMetrics)
981− |> List.sum
982−
983− verticalPadding =
984− context.self.bbox.padding.top + context.self.bbox.padding.bottom
985−
986− spacingAmount =
987− Testable.getSpacingFromAttributes colAttrs
988−
989− totalSpacing =
990− toFloat spacingAmount * (toFloat (List.length context.children) - 1)
991− in
992− [ expectRoundedEquality
993− { expected = totalChildren + verticalPadding + totalSpacing
994− , found = context.self.bbox.height
995− }
996− , Testable.lessThanOrEqual "not larger than parent"
997− context.self.bbox.height
998− context.parent.bbox.height
999− ]
1000−
1001− Testable.TextColumn _ _ ->
1002− []
1003−
1004− Testable.Paragraph _ _ ->
1005− []
1006−
1007− Testable.Text _ ->
1008− []
1009−
1010− Testable.Empty ->
1011− []
1012− }
1013−
1014−
1015−width : Length -> Testable.Attr msg
1016−width len =
1017− widthHelper Nothing Nothing len
1018−
1019−
1020−height : Length -> Testable.Attr msg
1021−height len =
1022− heightHelper Nothing Nothing len
1023−
1024−
1025−spacing : Int -> Testable.Attr msg
1026−spacing space =
1027− Testable.Batch
1028− [ Testable.Spacing space
1029− , Testable.LabeledTest
1030− { label = "spacing: " ++ String.fromInt space
1031− , attr = Element.spacing space
1032− , id = Testable.NoId
1033− , test =
1034− \found ->
1035− let
1036− findDistance child total =
1037− List.concatMap
1038− (\otherChild ->
1039− let
1040− horizontal =
1041− round <|
1042− child.bbox.left
1043− - otherChild.bbox.right
1044−
1045− vertical =
1046− round <|
1047− child.bbox.top
1048− - otherChild.bbox.bottom
1049− in
1050− [ if horizontal > 0 then
1051− horizontal
1052−
1053− else
1054− space
1055− , if vertical > 0 then
1056− vertical
1057−
1058− else
1059− space
1060− ]
1061− )
1062− found.children
1063− ++ total
1064−
1065− distances =
1066− List.foldl findDistance [] found.children
1067−
1068− allAreSpaced =
1069− List.foldl
1070− (\x wrong ->
1071− if not (x >= space) then
1072− x :: wrong
1073−
1074− else
1075− wrong
1076− )
1077− []
1078− distances
1079− in
1080− [ Testable.true
1081− ("All children are at least "
1082− ++ String.fromInt space
1083− ++ " pixels apart."
1084− ++ Debug.toString allAreSpaced
1085− ++ " are not though"
1086− )
1087− (allAreSpaced == [])
1088− ]
1089− }
1090− ]
1091−
1092−
1093−{-| alignLeft needs to account for
1094−
1095− - parent padding
1096− - elements to the left
1097− - spacing value
1098−
1099−in order to calculate the expected result.
1100−
1101−Also need parent rendering context if this is to work with wrapped rows in the future.
1102−
1103−All sibling elements
1104−
1105−-}
1106−alignLeft : Testable.Attr msg
1107−alignLeft =
1108− Testable.LabeledTest
1109− { label = "alignLeft"
1110− , attr = Element.alignLeft
1111− , id = Testable.NoId
1112− , test =
1113− \found ->
1114− [ if List.member found.parentLayout [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
1115− Testable.true "alignLeft doesn't apply to elements that are onLeft or onRight" True
1116−
1117− else if
1118− List.member found.parentLayout
1119− [ Testable.IsNearby Testable.InFront
1120− , Testable.IsNearby Testable.Behind
1121− , Testable.IsNearby Testable.Above
1122− , Testable.IsNearby Testable.Below
1123− ]
1124− then
1125− expectRoundedEquality
1126− { found = found.self.bbox.left
1127− , expected = found.parent.bbox.left
1128− }
1129−
1130− else if List.length found.siblings == 0 then
1131− expectRoundedEquality
1132− { found = found.self.bbox.left
1133− , expected = found.parent.bbox.left + found.parent.bbox.padding.left
1134− }
1135−
1136− else
1137− case found.parentLayout of
1138− Testable.InRow ->
1139− let
1140− siblingsOnLeft =
1141− List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
1142−
1143− spacings =
1144− toFloat (List.length siblingsOnLeft * found.parentSpacing)
1145−
1146− widthsOnLeft =
1147− siblingsOnLeft
1148− |> List.map (.width << .bbox)
1149− |> List.sum
1150− in
1151− expectRoundedEquality
1152− { found = found.self.bbox.left
1153− , expected = found.parent.bbox.left + (found.parent.bbox.padding.left + widthsOnLeft + spacings)
1154− }
1155−
1156− _ ->
1157− expectRoundedEquality
1158− { found = found.self.bbox.left
1159− , expected = found.parent.bbox.left + found.parent.bbox.padding.left
1160− }
1161− ]
1162− }
1163−
1164−
1165−{-| -}
1166−centerX : Testable.Attr msg
1167−centerX =
1168− Testable.LabeledTest
1169− { label = "centerX"
1170− , attr = Element.centerX
1171− , id = Testable.NoId
1172− , test =
1173− \found ->
1174− let
1175− selfCenter : Float
1176− selfCenter =
1177− found.self.bbox.left + (found.self.bbox.width / 2)
1178−
1179− parentCenter : Float
1180− parentCenter =
1181− found.parent.bbox.left + (found.parent.bbox.width / 2)
1182− in
1183− if List.member found.parentLayout [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
1184− [ Testable.true "centerX doesn't apply to elements that are onLeft or onRight" True ]
1185−
1186− else if List.length found.siblings == 0 then
1187− [ expectRoundedEquality
1188− { found = selfCenter
1189− , expected = parentCenter
1190− }
1191− ]
1192−
1193− else
1194− case found.parentLayout of
1195− Testable.InRow ->
1196− let
1197− siblingsOnLeft =
1198− List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
1199−
1200− siblingsOnRight =
1201− List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
1202−
1203− widthsOnLeft : Float
1204− widthsOnLeft =
1205− siblingsOnLeft
1206− |> List.map (.width << .bbox)
1207− |> List.sum
1208− |> (\x -> x + (toFloat (List.length siblingsOnLeft) * toFloat found.parentSpacing))
1209−
1210− widthsOnRight =
1211− siblingsOnRight
1212− |> List.map (.width << .bbox)
1213− |> List.sum
1214− |> (\x -> x + (toFloat (List.length siblingsOnRight) * toFloat found.parentSpacing))
1215−
1216− expectedCenter : Float
1217− expectedCenter =
1218− found.parent.bbox.left
1219− + widthsOnLeft
1220− + ((found.parent.bbox.width - (widthsOnRight + widthsOnLeft))
1221− / 2
1222− )
1223− in
1224− [ expectRoundedEquality
1225− { found = selfCenter
1226− , expected = expectedCenter
1227− }
1228− ]
1229−
1230− _ ->
1231− [ expectRoundedEquality
1232− { found = selfCenter
1233− , expected = parentCenter
1234− }
1235− ]
1236− }
1237−
1238−
1239−{-| -}
1240−alignRight : Testable.Attr msg
1241−alignRight =
1242− Testable.LabeledTest
1243− { label = "alignRight"
1244− , attr = Element.alignRight
1245− , id = Testable.NoId
1246− , test =
1247− \found ->
1248− if List.member found.parentLayout [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
1249− [ Testable.true "alignRight doesn't apply to elements that are onLeft or onRight" True ]
1250−
1251− else if
1252− List.member found.parentLayout
1253− [ Testable.IsNearby Testable.InFront
1254− , Testable.IsNearby Testable.Behind
1255− , Testable.IsNearby Testable.Above
1256− , Testable.IsNearby Testable.Below
1257− ]
1258− then
1259− [ expectRoundedEquality
1260− { found = found.self.bbox.right
1261− , expected = found.parent.bbox.right
1262− }
1263− ]
1264−
1265− else if List.length found.siblings == 0 then
1266− [ expectRoundedEquality
1267− { found = found.self.bbox.right
1268− , expected = found.parent.bbox.right + found.parent.bbox.padding.right
1269− }
1270− ]
1271−
1272− else
1273− case found.parentLayout of
1274− Testable.InRow ->
1275− let
1276− siblingsOnRight =
1277− List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
1278−
1279− spacings =
1280− toFloat (List.length siblingsOnRight * found.parentSpacing)
1281−
1282− widthsOnRight =
1283− siblingsOnRight
1284− |> List.map (.width << .bbox)
1285− |> List.sum
1286− in
1287− [ expectRoundedEquality
1288− { found = found.self.bbox.right
1289− , expected = found.parent.bbox.right - (found.parent.bbox.padding.right + widthsOnRight + spacings)
1290− }
1291− ]
1292−
1293− _ ->
1294− [ expectRoundedEquality
1295− { found = found.self.bbox.right
1296− , expected = found.parent.bbox.right + found.parent.bbox.padding.right
1297− }
1298− ]
1299− }
1300−
1301−
1302−{-| -}
1303−alignTop : Testable.Attr msg
1304−alignTop =
1305− Testable.LabeledTest
1306− { label = "alignTop"
1307− , attr = Element.alignTop
1308− , id = Testable.NoId
1309− , test =
1310− \found ->
1311− if List.member found.parentLayout [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
1312− [ Testable.true "alignTop doesn't apply to elements that are above or below" True ]
1313−
1314− else if
1315− List.member found.parentLayout
1316− [ Testable.IsNearby Testable.InFront
1317− , Testable.IsNearby Testable.Behind
1318− , Testable.IsNearby Testable.OnRight
1319− , Testable.IsNearby Testable.OnLeft
1320− ]
1321− then
1322− [ expectRoundedEquality
1323− { found = found.self.bbox.top
1324− , expected = found.parent.bbox.top
1325− }
1326− ]
1327−
1328− else if List.length found.siblings == 0 then
1329− [ expectRoundedEquality
1330− { found = found.self.bbox.top
1331− , expected = found.parent.bbox.top + found.parent.bbox.padding.top
1332− }
1333− ]
1334−
1335− else
1336− case found.parentLayout of
1337− Testable.InColumn ->
1338− let
1339− siblingsAbove =
1340− List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
1341−
1342− spacings =
1343− toFloat (List.length siblingsAbove * found.parentSpacing)
1344−
1345− heightsAbove =
1346− siblingsAbove
1347− |> List.map (.height << .bbox)
1348− |> List.sum
1349− in
1350− [ expectRoundedEquality
1351− { found = found.self.bbox.top
1352− , expected = found.parent.bbox.top + (found.parent.bbox.padding.top + heightsAbove + spacings)
1353− }
1354− ]
1355−
1356− _ ->
1357− [ expectRoundedEquality
1358− { found = found.self.bbox.top
1359− , expected = found.parent.bbox.top
1360− }
1361− ]
1362− }
1363−
1364−
1365−{-| -}
1366−alignBottom : Testable.Attr msg
1367−alignBottom =
1368− Testable.LabeledTest
1369− { label = "alignBottom"
1370− , attr = Element.alignBottom
1371− , id = Testable.NoId
1372− , test =
1373− \found ->
1374− if List.member found.parentLayout [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
1375− [ Testable.true "alignBottom doesn't apply to elements that are above or below" True ]
1376−
1377− else if
1378− List.member found.parentLayout
1379− [ Testable.IsNearby Testable.InFront
1380− , Testable.IsNearby Testable.Behind
1381− , Testable.IsNearby Testable.OnRight
1382− , Testable.IsNearby Testable.OnLeft
1383− ]
1384− then
1385− [ expectRoundedEquality
1386− { found = found.self.bbox.bottom
1387− , expected = found.parent.bbox.bottom
1388− }
1389− ]
1390−
1391− else if List.length found.siblings == 0 then
1392− [ expectRoundedEquality
1393− { found = found.self.bbox.bottom
1394− , expected = found.parent.bbox.bottom + found.parent.bbox.padding.bottom
1395− }
1396− ]
1397−
1398− else
1399− case found.parentLayout of
1400− Testable.InColumn ->
1401− let
1402− siblingsBelow =
1403− List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
1404−
1405− spacings =
1406− toFloat (List.length siblingsBelow * found.parentSpacing)
1407−
1408− heightsBelow =
1409− siblingsBelow
1410− |> List.map (.height << .bbox)
1411− |> List.sum
1412− in
1413− [ expectRoundedEquality
1414− { found = found.self.bbox.bottom
1415− , expected = found.parent.bbox.bottom - (found.parent.bbox.padding.bottom + heightsBelow + spacings)
1416− }
1417− ]
1418−
1419− _ ->
1420− [ expectRoundedEquality
1421− { found = found.self.bbox.bottom
1422− , expected = found.parent.bbox.bottom + found.parent.bbox.padding.bottom
1423− }
1424− ]
1425− }
1426−
1427−
1428−expectRoundedEquality : { expected : Float, found : Float } -> Testable.LayoutExpectation
1429−expectRoundedEquality { expected, found } =
1430− Testable.true
1431− ("expected " ++ floatToString expected ++ ", found " ++ floatToString found)
1432− (abs (expected - found) < 1)
1433−
1434−
1435−floatToString : Float -> String
1436−floatToString x =
1437− String.fromFloat (toFloat (round (x * 100)) / 100)
1438−
1439−
1440−{-| -}
1441−centerY : Testable.Attr msg
1442−centerY =
1443− Testable.LabeledTest
1444− { label = "centerY"
1445− , attr = Element.centerY
1446− , id = Testable.NoId
1447− , test =
1448− \found ->
1449− let
1450− selfCenter =
1451− found.self.bbox.top + (found.self.bbox.height / 2)
1452−
1453− parentCenter =
1454− found.parent.bbox.top + (found.parent.bbox.height / 2)
1455− in
1456− if List.member found.parentLayout [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
1457− [ Testable.true "centerY doesn't apply to elements that are above or below" True ]
1458−
1459− else if List.length found.siblings == 0 then
1460− [ expectRoundedEquality
1461− { found = selfCenter
1462− , expected = parentCenter
1463− }
1464− ]
1465−
1466− else
1467− case found.parentLayout of
1468− Testable.InColumn ->
1469− let
1470− siblingsOnTop =
1471− List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
1472−
1473− siblingsBelow =
1474− List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
1475−
1476− heightsAbove : Float
1477− heightsAbove =
1478− siblingsOnTop
1479− |> List.map (.height << .bbox)
1480− |> List.sum
1481− |> (\x -> x + (toFloat (List.length siblingsOnTop) * toFloat found.parentSpacing))
1482−
1483− heightsBelow =
1484− siblingsBelow
1485− |> List.map (.height << .bbox)
1486− |> List.sum
1487− |> (\x -> x + (toFloat (List.length siblingsBelow) * toFloat found.parentSpacing))
1488−
1489− expectedCenter : Float
1490− expectedCenter =
1491− found.parent.bbox.top
1492− + heightsAbove
1493− + ((found.parent.bbox.height - (heightsBelow + heightsAbove))
1494− / 2
1495− )
1496− in
1497− [ expectRoundedEquality
1498− { found = selfCenter
1499− , expected = expectedCenter
1500− }
1501− ]
1502−
1503− _ ->
1504− [ expectRoundedEquality
1505− { found = selfCenter
1506− , expected = parentCenter
1507− }
1508− ]
1509− }
1510−
1511−
1512−{-| -}
1513−above : Testable.Element msg -> Testable.Attr msg
1514−above element =
1515− Testable.Nearby
1516− { location = Testable.Above
1517− , element = element
1518− , label = "above"
1519− , test =
1520− \found ->
1521− [ expectRoundedEquality
1522− { found = found.self.bbox.bottom
1523− , expected = found.parent.bbox.top
1524− }
1525− ]
1526− }
1527−
1528−
1529−{-| -}
1530−below : Testable.Element msg -> Testable.Attr msg
1531−below element =
1532− Testable.Nearby
1533− { location = Testable.Below
1534− , element = element
1535− , label = "below"
1536− , test =
1537− \found ->
1538− [ expectRoundedEquality
1539− { found = found.self.bbox.top
1540− , expected = found.parent.bbox.bottom
1541− }
1542− ]
1543− }
1544−
1545−
1546−{-| -}
1547−onRight : Testable.Element msg -> Testable.Attr msg
1548−onRight element =
1549− Testable.Nearby
1550− { location = Testable.OnRight
1551− , element = element
1552− , label = "onRight"
1553− , test =
1554− \found ->
1555− [ expectRoundedEquality
1556− { found = found.self.bbox.left
1557− , expected = found.parent.bbox.right
1558− }
1559− ]
1560− }
1561−
1562−
1563−{-| -}
1564−onLeft : Testable.Element msg -> Testable.Attr msg
1565−onLeft element =
1566− Testable.Nearby
1567− { location = Testable.OnLeft
1568− , element = element
1569− , label = "onLeft"
1570− , test =
1571− \found ->
1572− [ expectRoundedEquality
1573− { found = found.self.bbox.right
1574− , expected = found.parent.bbox.left
1575− }
1576− ]
1577− }
1578−
1579−
1580−compare x vs y =
1581− vs (round x) (round y) || vs (floor x) (floor y)
1582−
1583−
1584−{-| -}
1585−inFront : Testable.Element msg -> Testable.Attr msg
1586−inFront element =
1587− Testable.Nearby
1588− { location = Testable.InFront
1589− , element = element
1590− , label = "inFront"
1591− , test =
1592− \found ->
1593− [ withinHelper found ]
1594− }
1595−
1596−
1597−withinHelper found =
1598− let
1599− horizontalCheck =
1600− if found.self.bbox.width > found.parent.bbox.width then
1601− [ compare found.self.bbox.right (<=) found.parent.bbox.right
1602− || compare found.self.bbox.left (>=) found.parent.bbox.left
1603− ]
1604−
1605− else
1606− [ compare found.self.bbox.right (<=) found.parent.bbox.right
1607− , compare found.self.bbox.left (>=) found.parent.bbox.left
1608− ]
1609−
1610− verticalCheck =
1611− if found.self.bbox.width > found.parent.bbox.width then
1612− [ compare found.self.bbox.top (>=) found.parent.bbox.top
1613− || compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1614− ]
1615−
1616− else
1617− [ compare found.self.bbox.top (>=) found.parent.bbox.top
1618− , compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1619− ]
1620− in
1621− Testable.true "within the confines of the parent"
1622− (List.all ((==) True)
1623− (List.concat
1624− [ horizontalCheck
1625− , verticalCheck
1626− ]
1627− )
1628− )
1629−
1630−
1631−{-| -}
1632−behindContent : Testable.Element msg -> Testable.Attr msg
1633−behindContent element =
1634− Testable.Nearby
1635− { location = Testable.Behind
1636− , element = element
1637− , label = "behindContent"
1638− , test =
1639− \found ->
1640− [ withinHelper found ]
1641− }
1642−
1643−
1644−
1645−{- Implicit width/height calcualtions -}
1646−
1647−
1648−implicitWidthHeightShrink attrs =
1649− let
1650− withImplicits =
1651− implicitTest (widthHelper Nothing Nothing Shrink)
1652− :: implicitTest (heightHelper Nothing Nothing Shrink)
1653− :: attrs
1654− in
1655− skipOverridden withImplicits
1656−
1657−
1658−attrId attr =
1659− case attr of
1660− Testable.LabeledTest details ->
1661− details.id
1662−
1663− Testable.AttrTest details ->
1664− details.id
1665−
1666− _ ->
1667− Testable.NoId
1668−
1669−
1670−skipOverridden ls =
1671− List.foldr
1672− (\attr ( found, caught ) ->
1673− let
1674− ( skip, has ) =
1675− case attrId attr of
1676− Testable.NoId ->
1677− ( False, found )
1678−
1679− Testable.IsWidth ->
1680− ( found.hasWidth
1681− , { hasWidth = True
1682− , hasHeight = found.hasHeight
1683− }
1684− )
1685−
1686− Testable.IsHeight ->
1687− ( found.hasHeight
1688− , { hasWidth = found.hasWidth
1689− , hasHeight = True
1690− }
1691− )
1692− in
1693− ( has
1694− , if skip then
1695− caught
1696−
1697− else
1698− attr :: caught
1699− )
1700− )
1701− ( { hasWidth = False
1702− , hasHeight = False
1703− }
1704− , []
1705− )
1706− ls
1707− |> Tuple.second
1708− |> List.reverse
1709−
1710−
1711−{-| This is taking a normal test and rmoving its ability to attach a real `Element` attribute.
1712−-}
1713−implicitTest attr =
1714− case attr of
1715− Testable.LabeledTest details ->
1716− Testable.AttrTest
1717− { test = details.test
1718− , label = "Implicit -> " ++ details.label
1719− , id = details.id
1720− }
1721−
1722− otherwise ->
1723− otherwise
tests-rendering/src/Testable/Element/Border.elmdeleted−20
@@ -1,20 +0,0 @@
1−module Testable.Element.Border exposing (..)
2−
3−{-| -}
4−
5−import Dict
6−import Element exposing (Color)
7−import Element.Border as Border
8−import Element.Font as Font
9−import Expect
10−import Testable
11−
12−
13−color : Color -> Testable.Attr msg
14−color clr =
15− Testable.Attr (Border.color clr)
16−
17−
18−width : Int -> Testable.Attr msg
19−width i =
20− Testable.Attr (Border.width i)
tests-rendering/src/Testable/Generator.elmdeleted−398
@@ -1,398 +0,0 @@
1−module Testable.Generator exposing (..)
2−
3−{-| -}
4−
5−import Testable
6−import Testable.Element exposing (..)
7−import Testable.Element.Background as Background
8−import Testable.Element.Font as Font
9−
10−
11−{-| Given a list of attributes, generate every context this list of attributes could be in.
12−
13−So, this means,
14−
15− - every element type
16− - in every element type
17−
18−-}
19−element : String -> List (Testable.Attr msg) -> List ( String, Testable.Element msg )
20−element label attrs =
21− -- [ ( label, paragraph attrs [ short ] )
22− -- ]
23− mapEveryCombo
24− (\( selfLabel, makeSelf ) ( childLabel, child ) ->
25− ( label ++ " - " ++ selfLabel ++ " > " ++ childLabel
26− , makeSelf attrs child
27− )
28− )
29− layouts
30− contents
31−
32−
33−{-| Given a list of attributes, generate every context this list of attributes could be in.
34−
35−So, this means,
36−
37− - every element type
38− - in every element type
39−
40−-}
41−elementInLayout : String -> List (Testable.Attr msg) -> List ( String, Testable.Element msg )
42−elementInLayout label attrs =
43− mapEveryCombo3
44− (\( layoutLabel, makeLayout ) ( selfLabel, makeSelf ) ( childLabel, child ) ->
45− ( label ++ " - " ++ layoutLabel ++ " > " ++ selfLabel ++ " > " ++ childLabel
46− , makeLayout [] (makeSelf attrs child)
47− )
48− )
49− layouts
50− layouts
51− contents
52−
53−
54−{-| Sometimes we want to try a whole bunch of combinations of attributes
55−
56−This makes it a bit easier to construct
57−
58−-}
59−elementWith : String -> List ( String, List (Testable.Attr msg) ) -> List ( String, Testable.Element msg )
60−elementWith label labelAttrs =
61− mapEveryCombo3
62− (\( attrLabel, attrs ) ( selfLabel, makeSelf ) ( childLabel, child ) ->
63− ( label ++ " - " ++ selfLabel ++ " with " ++ attrLabel ++ " > " ++ childLabel
64− , makeSelf attrs child
65− )
66− )
67− labelAttrs
68− layouts
69− contents
70−
71−
72−{-| This varies the layout element that an element is in.
73−-}
74−elementInLayoutWith :
75− String
76− ->
77− List
78− ( String
79− , { self : List (Testable.Attr msg)
80− , parent : List (Testable.Attr msg)
81− }
82− )
83− -> List ( String, Testable.Element msg )
84−elementInLayoutWith label labelAttrs =
85− mapEveryCombo4
86− (\( attrLabel, attrs ) ( layoutLabel, makeLayout ) ( selfLabel, makeSelf ) ( childLabel, child ) ->
87− ( label ++ " - " ++ layoutLabel ++ " > " ++ selfLabel ++ " with " ++ attrLabel ++ " > " ++ childLabel
88− , makeLayout attrs.parent (makeSelf attrs.self child)
89− )
90− )
91− labelAttrs
92− allLayouts
93− layouts
94− contents
95−
96−
97−layouts =
98− [ ( "el"
99− , \attrs child ->
100− el attrs child
101− )
102− , ( "row"
103− , \attrs child ->
104− row attrs [ child ]
105− )
106− , ( "col"
107− , \attrs child ->
108− column attrs [ child ]
109− )
110− , ( "para"
111− , \attrs child ->
112− paragraph attrs [ child ]
113− )
114− , ( "txtCol"
115− , \attrs child ->
116− textColumn attrs [ child ]
117− )
118− ]
119−
120−
121−allElements =
122− [ ( "el"
123− , \attrs child ->
124− el attrs child
125− )
126− , ( "row"
127− , \attrs child ->
128− row attrs [ child ]
129− )
130− , ( "col"
131− , \attrs child ->
132− column attrs [ child ]
133− )
134− , ( "para"
135− , \attrs child ->
136− paragraph attrs [ child ]
137− )
138− , ( "txtCol"
139− , \attrs child ->
140− textColumn attrs [ child ]
141− )
142− ]
143−
144−
145−allLayouts =
146− [ ( "el"
147− , \attrs child ->
148− el attrs child
149− )
150− , ( "row 3, self 1"
151− , \attrs child ->
152− row attrs [ child, box, box ]
153− )
154− , ( "row 3, self 2"
155− , \attrs child ->
156− row attrs [ box, child, box ]
157− )
158− , ( "row 3, self 3"
159− , \attrs child ->
160− row attrs [ box, box, child ]
161− )
162− , ( "col 3, self 1"
163− , \attrs child ->
164− column attrs [ child, box, box ]
165− )
166− , ( "col 3, self 2"
167− , \attrs child ->
168− column attrs [ box, child, box ]
169− )
170− , ( "col 3, self 3"
171− , \attrs child ->
172− column attrs [ box, box, child ]
173− )
174− , ( "para"
175− , \attrs child ->
176− paragraph attrs [ child ]
177− )
178− , ( "txtCol"
179− , \attrs child ->
180− textColumn attrs [ child ]
181− )
182− ]
183−
184−
185−nearbys =
186− [ ( "inFront", inFront )
187− , ( "above", above )
188− , ( "onLeft", onLeft )
189− , ( "onRight", onRight )
190− , ( "below", below )
191− , ( "behindContent", behindContent )
192− ]
193−
194−
195−alignments =
196− horizontal ++ vertical
197−
198−
199−horizontal =
200− [ Tuple.pair "alignLeft" alignLeft
201− , Tuple.pair "alignRight" alignRight
202− , Tuple.pair "centerX" centerX
203− ]
204−
205−
206−vertical =
207− [ Tuple.pair "alignTop" alignTop
208− , Tuple.pair "alignBottom" alignBottom
209− , Tuple.pair "centerY" centerY
210− ]
211−
212−
213−extractLabel maybe =
214− maybe
215−
216−
217−allAlignments =
218− mapEveryCombo
219− (\maybeOne maybeTwo ->
220− let
221− labels =
222− List.filterMap (Maybe.map Tuple.first)
223− [ maybeOne
224− , maybeTwo
225− ]
226−
227− attrs =
228− List.filterMap (Maybe.map Tuple.second)
229− [ maybeOne
230− , maybeTwo
231− ]
232− in
233− Tuple.pair (String.join "++" labels)
234− attrs
235− )
236− (Nothing :: List.map Just horizontal)
237− (Nothing :: List.map Just vertical)
238−
239−
240−contents =
241− [ ( "none", none )
242− , ( "short text", text short )
243−
244− -- , ( "long text", text lorem )
245− , ( "box"
246− , box
247− )
248− ]
249−
250−
251−box =
252− el
253− [ width (px 50)
254− , height (px 50)
255− , Background.color (rgb (240 / 255) 0 (245 / 255))
256− , Font.color (rgb 1 1 1)
257− ]
258− none
259−
260−
261−short =
262− "short and small"
263−
264−
265−lorem =
266− "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc."
267−
268−
269−mapEveryCombo fn listOne listTwo =
270− List.concatMap
271− (\one ->
272− List.map
273− (\two ->
274− fn one two
275− )
276− listTwo
277− )
278− listOne
279−
280−
281−mapEveryCombo3 fn listOne listTwo listThree =
282− List.concatMap
283− (\one ->
284− List.concatMap
285− (\two ->
286− List.map
287− (\three ->
288− fn one two three
289− )
290− listThree
291− )
292− listTwo
293− )
294− listOne
295−
296−
297−mapEveryCombo4 fn listOne listTwo listThree listFour =
298− List.concatMap
299− (\one ->
300− List.concatMap
301− (\two ->
302− List.concatMap
303− (\three ->
304− List.map
305− (\four ->
306− fn one two three four
307− )
308− listFour
309− )
310− listThree
311− )
312− listTwo
313− )
314− listOne
315−
316−
317−sizes render =
318− List.concatMap
319− (\( widthLen, heightLen ) ->
320− [ text (Debug.toString ( widthLen, heightLen ))
321− , render
322− (\attrs children ->
323− el
324− (width widthLen
325− :: height heightLen
326− :: attrs
327− )
328− children
329− )
330− ]
331− )
332− allLengthPairs
333−
334−
335−allLengthPairs : List ( Length, Length )
336−allLengthPairs =
337− let
338− crossProduct len =
339− List.map (Tuple.pair len) lengths
340− in
341− List.concatMap crossProduct lengths
342−
343−
344−lengths =
345− [ px 50
346− , fill
347− , shrink
348− , fill
349− |> maximum 100
350− , fill
351− |> maximum 100
352− |> minimum 50
353− , shrink
354− |> maximum 100
355− , shrink
356− |> maximum 100
357− |> minimum 50
358− ]
359−
360−
361−type Generated thing
362− = Generated (List (Labeled thing))
363−
364−
365−type alias Labeled thing =
366− ( String, thing )
367−
368−
369−with : List (Labeled a) -> List (Labeled (a -> b)) -> List (Labeled b)
370−with first funcs =
371− List.concatMap
372− (\( lbl, fst ) ->
373− List.map
374− (\( fnLbl, fn ) ->
375− Tuple.pair (fnLbl ++ "+" ++ lbl) (fn fst)
376− )
377− funcs
378− )
379− first
380−
381−
382−generate : String -> generated -> List (Labeled generated)
383−generate lbl fn =
384− [ Tuple.pair lbl fn
385− ]
386−
387−
388−test : List (Labeled (Testable.Element msg))
389−test =
390− generate "Alignments"
391− (\align ->
392− el align none
393− )
394− |> with allAlignments
395−
396−
397−
398−-- |>
tests-rendering/src/Testable/Runner.elmdeleted−607
@@ -1,607 +0,0 @@
1−port module Testable.Runner exposing
2− ( Msg
3− , Testable
4− , TestableProgram
5− , program
6− , rename
7− , show
8− , testable
9− )
10−
11−{-| -}
12−
13−import Browser
14−import Dict exposing (Dict)
15−import Element
16−import Element.Background as Background
17−import Element.Border as Border
18−import Element.Events as Events
19−import Element.Font as Font
20−import Html exposing (Html)
21−import Html.Attributes
22−import Process
23−import Task
24−import Testable
25−import Time
26−
27−
28−show : Testable.Element msg -> Html msg
29−show =
30− Testable.toHtml
31−
32−
33−type alias TestableProgram =
34− Program () (Model Msg) Msg
35−
36−
37−{-| This should be a real type, but I'm too busy atm.
38−-}
39−type alias Testable =
40− ( String, Testable.Element Msg )
41−
42−
43−rename : String -> Testable -> Testable
44−rename newName ( _, el ) =
45− ( newName, el )
46−
47−
48−testable : String -> Testable.Element Msg -> Testable
49−testable =
50− Tuple.pair
51−
52−
53−palette =
54− { white = Element.rgb 1 1 1
55− , red = Element.rgb 1 0 0
56− , green = Element.rgb 0 1 0
57− , black = Element.rgb 0 0 0
58− , lightGrey = Element.rgb 0.7 0.7 0.7
59− }
60−
61−
62−program : List Testable -> TestableProgram
63−program tests =
64− let
65− ( current, upcoming ) =
66− case tests of
67− [] ->
68− ( Nothing, [] )
69−
70− cur :: remaining ->
71− ( Just cur, remaining )
72− in
73− Browser.element
74− { init =
75− always
76− ( { current = current
77− , upcoming = upcoming
78− , finished = []
79− , selected = 0
80− , highlightDomId = Nothing
81− }
82− , Task.perform (always Analyze)
83− (Process.sleep 64
84− |> Task.andThen
85− (always Time.now)
86− )
87− )
88− , view = view
89− , update = update
90− , subscriptions = subscriptions
91− }
92−
93−
94−subscriptions : Model Msg -> Sub Msg
95−subscriptions model =
96− Sub.batch
97− [ styles RefreshBoundingBox
98− ]
99−
100−
101−type alias Model msg =
102− { current : Maybe ( String, Testable.Element msg )
103− , upcoming : List ( String, Testable.Element msg )
104− , finished : List (WithResults (Testable.Element msg))
105− , selected : Int
106− , highlightDomId : Maybe String
107− }
108−
109−
110−type alias WithResults thing =
111− { index : Int
112− , element : thing
113− , label : String
114− , results :
115− List Testable.LayoutTest
116− }
117−
118−
119−encodeForReport :
120− List (WithResults (Testable.Element msg))
121− ->
122− List
123− { label : String
124− , results :
125− List
126− { description : String
127− , passing : Bool
128− , todo : Bool
129− }
130− }
131−encodeForReport withResults =
132− let
133− prepareExpectation layoutTest exp =
134− case exp of
135− Testable.Todo description ->
136− { description = description
137− , passing = False
138− , todo = True
139− }
140−
141− Testable.Expect details ->
142− { description = details.description
143− , passing = details.result
144− , todo = False
145− }
146−
147− prepareNode layoutTest =
148− List.map (prepareExpectation layoutTest) layoutTest.expectations
149−
150− prepare { label, results } =
151− { label = label
152− , results = List.concatMap prepareNode results
153− }
154− in
155− List.map prepare withResults
156−
157−
158−type Msg
159− = NoOp
160− | Analyze
161− | Select Int
162− | HighlightDomID (Maybe String)
163− | RefreshBoundingBox
164− (List
165− { id : String
166− , bbox : Testable.BoundingBox
167− , style : List ( String, String )
168− , isVisible : Bool
169− , textMetrics : List Testable.TextMetrics
170− }
171− )
172−
173−
174−runTest : Int -> Dict String Testable.Found -> String -> Testable.Element msg -> WithResults (Testable.Element msg)
175−runTest index boxes label element =
176− let
177− results =
178− Testable.runTests boxes element
179− in
180− { index = index
181− , element = element
182− , label = label
183− , results = results
184− }
185−
186−
187−update : Msg -> Model Msg -> ( Model Msg, Cmd Msg )
188−update msg model =
189− case msg of
190− NoOp ->
191− ( model, Cmd.none )
192−
193− HighlightDomID newId ->
194− ( { model | highlightDomId = newId }
195− , Cmd.none
196− )
197−
198− Select index ->
199− ( { model | selected = index }
200− , Cmd.none
201− )
202−
203− RefreshBoundingBox boxes ->
204− case model.current of
205− Nothing ->
206− ( model
207− , Cmd.none
208− )
209−
210− Just ( label, current ) ->
211− let
212− toTuple box =
213− ( box.id
214− , { style = Dict.fromList box.style
215− , bbox = box.bbox
216− , isVisible = box.isVisible
217− , textMetrics = box.textMetrics
218− }
219− )
220−
221− foundData =
222− boxes
223− |> List.map toTuple
224− |> Dict.fromList
225−
226− currentResults =
227− runTest (List.length model.finished) foundData label current
228− in
229− case model.upcoming of
230− [] ->
231− ( { model
232− | current = Nothing
233− , finished = model.finished ++ [ currentResults ]
234− }
235− , report (encodeForReport (currentResults :: model.finished))
236− )
237−
238− newCurrent :: remaining ->
239− ( { model
240− | finished = model.finished ++ [ currentResults ]
241− , current = Just newCurrent
242− , upcoming = remaining
243− }
244− , Task.perform (always Analyze)
245− (Process.sleep 64
246− |> Task.andThen
247− (always Time.now)
248− )
249− )
250−
251− Analyze ->
252− case model.current of
253− Nothing ->
254− ( model
255− , Cmd.none
256− )
257−
258− Just ( label, current ) ->
259− ( model
260− , analyze (Testable.getIds current)
261− )
262−
263−
264−view : Model Msg -> Html.Html Msg
265−view model =
266− case model.current of
267− Nothing ->
268− if List.isEmpty model.upcoming then
269− let
270− selected =
271− getByIndex model.selected model.finished
272− in
273− Element.layout
274− [ Font.size 16
275− , Element.inFront (Element.html (viewElementHighlight model))
276− , Element.height Element.fill
277− ]
278− <|
279− Element.row [ Element.width Element.fill, Element.height Element.fill ]
280− [ Element.el
281− [ Element.width
282− (Element.fill
283− |> Element.maximum 900
284− )
285− , Element.alignTop
286− , Element.height Element.fill
287− , Element.scrollbars
288− ]
289− (Element.el
290− [ Element.centerX
291− , Element.padding 100
292− , Border.dashed
293− , Border.width 2
294− , Border.color palette.lightGrey
295− , Font.size 20
296− , Element.inFront
297− (Element.el
298− [ Font.size 14
299− , Font.color palette.lightGrey
300− ]
301− (Element.text "test case")
302− )
303− ]
304− (case selected of
305− Nothing ->
306− Element.text "nothing selected"
307−
308− Just sel ->
309− Testable.toElement sel.element
310− )
311− )
312− , Element.column
313− [ Element.spacing 20
314− , Element.padding 20
315− , Element.width Element.fill
316− , Element.height Element.fill
317− , Element.scrollbarY
318− ]
319− (model.finished
320− |> List.sortBy hasFailure
321− |> List.map (viewResult model.selected)
322− )
323− ]
324−
325− else
326− Html.text ""
327−
328− Just ( label, current ) ->
329− Testable.toHtml current
330−
331−
332−getByIndex i ls =
333− List.foldl
334− (\elem ( index, found ) ->
335− if i == index then
336− ( index + 1, Just elem )
337−
338− else
339− ( index + 1, found )
340− )
341− ( 0, Nothing )
342− ls
343− |> Tuple.second
344−
345−
346−viewElementHighlight model =
347− case model.highlightDomId of
348− Nothing ->
349− Html.text ""
350−
351− Just highlightDomId ->
352− let
353− elementHighlight =
354− highlightDomId ++ " { outline: solid black; }"
355−
356− testId =
357− highlightDomId
358− |> String.dropLeft 1
359− |> String.append "#tests-"
360−
361− testHighlight =
362− testId ++ " { outline: dashed black; }"
363−
364− styleSheet =
365− String.join "\n"
366− [ elementHighlight
367− , testHighlight
368− ]
369− in
370− Html.node "style"
371− []
372− [ Html.text styleSheet
373− ]
374−
375−
376−hasFailure : WithResults (Testable.Element Msg) -> Int
377−hasFailure myTest =
378− if
379− List.any
380− (not << isPassing)
381− myTest.results
382− then
383− 0
384−
385− else
386− 1
387−
388−
389−isExpectationPassing result =
390− case result of
391− Testable.Todo label ->
392− True
393−
394− Testable.Expect details ->
395− details.result
396−
397−
398−isPassing layoutTest =
399− List.all isExpectationPassing layoutTest.expectations
400−
401−
402−viewResult : Int -> WithResults (Testable.Element Msg) -> Element.Element Msg
403−viewResult selectedIndex myTest =
404− if myTest.index == selectedIndex then
405− Element.column
406− [ Element.alignLeft
407− , Element.spacing 16
408− ]
409− [ Element.el [ Font.size 24 ] (Element.text myTest.label)
410− , Element.column
411− [ Element.alignLeft, Element.spacing 16 ]
412− (myTest.results
413− |> groupBy .elementDomId
414− |> List.map (expandDetails >> viewLayoutTestGroup)
415− )
416− ]
417−
418− else
419− let
420− ( passing, failing ) =
421− List.partition isPassing myTest.results
422− in
423− Element.column
424− [ Element.alignLeft
425− , Element.spacing 16
426− , Element.pointer
427− , Events.onClick (Select myTest.index)
428− ]
429− [ Element.row [ Element.spacing 16 ]
430− [ Element.el [ Font.size 16 ] (Element.text myTest.label)
431− , Element.text (String.fromInt (List.length passing) ++ " passing")
432− , let
433− failingCount =
434− List.length failing
435− in
436− if failingCount == 0 then
437− Element.none
438−
439− else
440− Element.text (String.fromInt (List.length failing) ++ " failing")
441− ]
442− ]
443−
444−
445−expandDetails group =
446− case group.members of
447− [] ->
448− { id = group.id
449− , elementType = Testable.EmptyType
450− , members = group.members
451− }
452−
453− top :: _ ->
454− { id = group.id
455− , elementType = top.elementType
456− , members = group.members
457− }
458−
459−
460−groupBy fn list =
461− groupWhile (\one two -> fn one == fn two) list
462− |> List.map
463− (\( fst, remaining ) ->
464− { id = fn fst
465− , members = fst :: remaining
466− }
467− )
468−
469−
470−groupWhile : (a -> a -> Bool) -> List a -> List ( a, List a )
471−groupWhile isSameGroup items =
472− List.foldr
473− (\x acc ->
474− case acc of
475− [] ->
476− [ ( x, [] ) ]
477−
478− ( y, restOfGroup ) :: groups ->
479− if isSameGroup x y then
480− ( x, y :: restOfGroup ) :: groups
481−
482− else
483− ( x, [] ) :: acc
484− )
485− []
486− items
487−
488−
489−viewLayoutTestGroup group =
490− let
491− testId =
492− group.id
493− |> String.dropLeft 1
494− |> String.append "tests-"
495− in
496− Element.column
497− [ Element.spacing 8
498− , Element.htmlAttribute (Html.Attributes.id testId)
499− , Events.onMouseEnter (HighlightDomID (Just group.id))
500− , Events.onMouseLeave (HighlightDomID Nothing)
501− , Element.htmlAttribute (Html.Attributes.style "user-select" "none")
502− ]
503− [ Element.row [ Element.spacing 16 ]
504− [ Element.el [] (Element.text (Testable.elementTypeToString group.elementType))
505− , Element.el [ Font.color palette.lightGrey ] (Element.text group.id)
506− ]
507− , Element.column
508− [ Element.spacing 8
509− , Element.paddingXY 32 0
510− ]
511− (List.map viewLayoutTest group.members)
512− ]
513−
514−
515−type alias Grouped thing =
516− { id : String
517− , members : List thing
518− }
519−
520−
521−viewLayoutTest layoutTest =
522− Element.column
523− [ Element.spacing 8
524− ]
525− [ Element.row [ Element.spacing 8 ]
526− [ Element.el [ Font.bold ] (Element.text layoutTest.label)
527−
528− -- , Element.el [ Font.color palette.lightGrey ] (Element.text layoutTest.elementDomId)
529− ]
530− , Element.column [ Element.spacing 8 ]
531− (List.map viewLayoutExpectation layoutTest.expectations)
532− ]
533−
534−
535−viewLayoutExpectation expectation =
536− case expectation of
537− Testable.Todo label ->
538− Element.row [ Element.spacing 4 ]
539− [ todo, Element.text label ]
540−
541− Testable.Expect details ->
542− if details.result then
543− Element.row [ Element.spacing 4 ]
544− [ pass, Element.text details.description ]
545−
546− else
547− Element.row [ Element.spacing 4 ]
548− [ fail, Element.text details.description ]
549−
550−
551−badge color text =
552− Element.el
553− [ Background.color color
554− , Font.color palette.black
555− , Element.paddingXY 4 8
556− , Border.rounded 2
557− ]
558− (Element.text text)
559−
560−
561−todo =
562− badge palette.lightGrey "todo"
563−
564−
565−pass =
566− badge palette.green "pass"
567−
568−
569−fail =
570− badge palette.red "fail"
571−
572−
573−formatKeyValue : String -> String -> String
574−formatKeyValue key val =
575− key ++ ": " ++ val
576−
577−
578−port report :
579− List
580− { label : String
581− , results :
582− List
583− { description : String
584− , passing : Bool
585− , todo : Bool
586− }
587− }
588− -> Cmd msg
589−
590−
591−port test : String -> Cmd msg
592−
593−
594−port analyze : List String -> Cmd msg
595−
596−
597−port styles :
598− (List
599− { id : String
600− , bbox : Testable.BoundingBox
601− , style : List ( String, String )
602− , isVisible : Bool
603− , textMetrics : List Testable.TextMetrics
604− }
605− -> msg
606− )
607− -> Sub msg
tests-rendering/src/Tests/Alignment.elmdeleted−49
@@ -1,49 +0,0 @@
1−module Tests.Alignment exposing (view)
2−
3−{-| Testing nearby elements such as those defined with `above`, `below`, etc.
4−-}
5−
6−import Testable
7−import Testable.Element exposing (..)
8−import Testable.Element.Background as Background
9−import Testable.Element.Font as Font
10−import Testable.Generator
11−import Tests.Palette as Palette exposing (..)
12−
13−
14−box attrs =
15− el
16− ([ width (px 50)
17− , height (px 50)
18− , Background.color blue
19− ]
20− ++ attrs
21− )
22− none
23−
24−
25−{-| -}
26−view : List ( String, Testable.Element msg )
27−view =
28− List.concat
29− [ Testable.Generator.generate "Alignments"
30− (\layout element alignment ->
31− layout
32− [ width (px 800)
33− , height (px 800)
34− , Background.color lightGrey
35− ]
36− (element
37− ([ width (px 200)
38− , height (px 200)
39− , Background.color red
40− ]
41− ++ alignment
42− )
43− none
44− )
45− )
46− |> Testable.Generator.with Testable.Generator.allLayouts
47− |> Testable.Generator.with Testable.Generator.allElements
48− |> Testable.Generator.with Testable.Generator.allAlignments
49− ]
tests-rendering/src/Tests/All.elmdeleted−44
@@ -1,44 +0,0 @@
1−module Tests.All exposing (main)
2−
3−{-| -}
4−
5−import Layout.NestedParagraphs
6−import Layout.SafariBugIssue147
7−import Testable.Generator
8−import Testable.Runner
9−import Tests.Alignment
10−import Tests.Nearby
11−import Tests.Spacing
12−import Tests.TextWrapping
13−import Tests.Transparency
14−
15−
16−main : Testable.Runner.TestableProgram
17−main =
18− (Testable.Runner.program << List.concat)
19− [ Testable.Generator.elementInLayout "Basics" []
20− , Tests.Nearby.view
21− , Tests.Alignment.view
22− , Tests.Spacing.view
23−
24− -- [
25− -- , Tuple.pair "Transparency" Tests.Transparency.view
26− -- ]
27− -- , [ Tuple.pair "Paragraph wrapping" Tests.TextWrapping.view
28− -- ]
29− , issues
30− ]
31−
32−
33−issues =
34− [ -- Testable.Runner.rename "Weird Centering" WeirdCentering.view
35− -- , Testable.Runner.rename "Stacked scrolling columns height" StackedScrollingColumnsHeight.view
36− -- ,
37− Testable.Runner.rename "Safari bug issue147" Layout.SafariBugIssue147.view
38− , Testable.Runner.rename "Nested paragraphs" Layout.NestedParagraphs.view
39−
40− -- , Testable.Runner.rename "Issue 22, zIndex" Nearby.Issue22ZIndex.view
41− -- , Testable.Runner.rename "inFrontIssue" Nearby.InFrontIssue.view
42− -- , Testable.Runner.rename "El in fixed height column" ElInFixedHeightColumn.view
43− -- , Testable.Runner.rename "Clipped el in fixed width column" ClippedElInFixedWidthColumn.view
44− ]
tests-rendering/src/Tests/Nearby.elmdeleted−179
@@ -1,179 +0,0 @@
1−module Tests.Nearby exposing (view)
2−
3−{-| Testing nearby elements such as those defined with `above`, `below`, etc.
4−-}
5−
6−import Html
7−import Testable
8−import Testable.Element exposing (..)
9−import Testable.Element.Background as Background
10−import Testable.Element.Font as Font
11−import Testable.Generator
12−import Testable.Runner
13−import Tests.Palette as Palette exposing (..)
14−
15−
16−box attrs =
17− el
18− ([ width (px 50)
19− , height (px 50)
20− , Background.color blue
21− ]
22− ++ attrs
23− )
24− none
25−
26−
27−justBox size color attrs =
28− el
29− ([ width (px size)
30− , height (px size)
31− , Background.color color
32− ]
33− ++ attrs
34− )
35− none
36−
37−
38−littleBox name attrs =
39− el
40− ([ label name
41− , width (px 5)
42− , height (px 5)
43− ]
44− ++ attrs
45− )
46− none
47−
48−
49−p attrs =
50− paragraph
51− ([ Background.color blue
52− , Font.color white
53− , padding 20
54− ]
55− ++ attrs
56− )
57− [ text "Lorem Ipsum or something or other." ]
58−
59−
60−{-| -}
61−view : List ( String, Testable.Element msg )
62−view =
63− List.concat
64− [ [ Tuple.pair "Parent inFront above child inFront" layeredVisibility
65− , Tuple.pair "Sibling onLeft above sibling inFront" overlappingChildren
66− , Tuple.pair "el with all nearbys and alignments" master
67− , Tuple.pair "paragraph with all nearbys and alignments" masterParagraph
68− ]
69− , Testable.Generator.generate "Nearbys"
70− (\element nearby ->
71− element
72− [ nearby (box [])
73− , width (px 200)
74− , height (px 200)
75− , Background.color red
76− ]
77− none
78− )
79− |> Testable.Generator.with Testable.Generator.allElements
80− |> Testable.Generator.with Testable.Generator.nearbys
81− , Testable.Generator.generate "Nearbys with alignment"
82− (\element nearby align ->
83− element
84− [ nearby (box [ align ])
85− , width (px 200)
86− , height (px 200)
87− , Background.color red
88− ]
89− none
90− )
91− |> Testable.Generator.with Testable.Generator.allElements
92− |> Testable.Generator.with Testable.Generator.nearbys
93− |> Testable.Generator.with Testable.Generator.alignments
94− ]
95−
96−
97−layeredVisibility =
98− el
99− [ centerX
100− , inFront (justBox 40 red [ isVisible ])
101− ]
102− (el [ inFront (justBox 30 green []) ]
103− (justBox 50 blue [])
104− )
105−
106−
107−overlappingChildren =
108− row [ centerX ]
109− [ el [ inFront (justBox 40 green []) ]
110− (justBox 40 darkGrey [])
111− , el [ onLeft (littleBox "overlapping" [ isVisible, Background.color red ]) ]
112− (justBox 40 darkGrey [])
113− ]
114−
115−
116−little name attrs =
117− el
118− ([ label name
119− , width (px 5)
120− , height (px 5)
121− , Background.color darkCharcoal
122− ]
123− ++ attrs
124− )
125− none
126−
127−
128−master =
129− el [ padding 20 ] <|
130− box
131− [ above (little "above-left" [ alignLeft ])
132− , above (little "above-center" [ centerX ])
133− , above (little "above-right" [ alignRight ])
134− , below (little "below-left" [ alignLeft ])
135− , below (little "below-center" [ centerX ])
136− , below (little "below-right" [ alignRight ])
137− , onRight (little "onRight-left" [ alignTop ])
138− , onRight (little "onRight-center" [ centerY ])
139− , onRight (little "onRight-right" [ alignBottom ])
140− , onLeft (little "onLeft-left" [ alignTop ])
141− , onLeft (little "onLeft-center" [ centerY ])
142− , onLeft (little "onLeft-right" [ alignBottom ])
143− , inFront (little "infront-left-top" [ alignTop, alignLeft ])
144− , inFront (little "infront-center-top" [ alignTop, centerX ])
145− , inFront (little "infront-right-top" [ alignTop, alignRight ])
146− , inFront (little "infront-left-center" [ centerY, alignLeft ])
147− , inFront (little "infront-center-center" [ centerY, centerX ])
148− , inFront (little "infront-right-center" [ centerY, alignRight ])
149− , inFront (little "infront-left-bottom" [ alignBottom, alignLeft ])
150− , inFront (little "infront-center-bottom" [ alignBottom, centerX ])
151− , inFront (little "infront-right-bottom" [ alignBottom, alignRight ])
152− ]
153−
154−
155−masterParagraph =
156− el [ padding 20 ] <|
157− p
158− [ above (little "above-left" [ alignLeft ])
159− , above (little "above-center" [ centerX ])
160− , above (little "above-right" [ alignRight ])
161− , below (little "below-left" [ alignLeft ])
162− , below (little "below-center" [ centerX ])
163− , below (little "below-right" [ alignRight ])
164− , onRight (little "onRight-left" [ alignTop ])
165− , onRight (little "onRight-center" [ centerY ])
166− , onRight (little "onRight-right" [ alignBottom ])
167− , onLeft (little "onLeft-left" [ alignTop ])
168− , onLeft (little "onLeft-center" [ centerY ])
169− , onLeft (little "onLeft-right" [ alignBottom ])
170− , inFront (little "infront-left-top" [ alignTop, alignLeft ])
171− , inFront (little "infront-center-top" [ alignTop, centerX ])
172− , inFront (little "infront-right-top" [ alignTop, alignRight ])
173− , inFront (little "infront-left-center" [ centerY, alignLeft ])
174− , inFront (little "infront-center-center" [ centerY, centerX ])
175− , inFront (little "infront-right-center" [ centerY, alignRight ])
176− , inFront (little "infront-left-bottom" [ alignBottom, alignLeft ])
177− , inFront (little "infront-center-bottom" [ alignBottom, centerX ])
178− , inFront (little "infront-right-bottom" [ alignBottom, alignRight ])
179− ]
tests-rendering/src/Tests/Run.elmdeleted−14
@@ -1,14 +0,0 @@
1−module Tests.Run exposing (main)
2−
3−{-| _NOTE_ this is auto-generated! Notouchy!
4−-}
5−
6−import ElInFixedHeightColumn
7−import Testable.Runner
8−
9−
10−main : Testable.Runner.TestableProgram
11−main =
12− Testable.Runner.program
13− [ Testable.Runner.rename " El In Fixed Height Column" ElInFixedHeightColumn.view
14− ]
tests-rendering/src/Tests/Spacing.elmdeleted−36
@@ -1,36 +0,0 @@
1−module Tests.Spacing exposing (view)
2−
3−{-| Test that spacing works
4−-}
5−
6−import Testable
7−import Testable.Element exposing (..)
8−import Testable.Element.Background as Background
9−import Testable.Element.Font as Font
10−import Testable.Generator
11−import Tests.Palette as Palette exposing (..)
12−
13−
14−{-| -}
15−view : List ( String, Testable.Element msg )
16−view =
17− List.concat
18− [ Testable.Generator.generate "Spacing"
19− (\layout element ->
20− layout
21− [ width (px 800)
22− , height (px 800)
23− , Background.color lightGrey
24− , spacing 20
25− ]
26− (element
27− [ width (px 200)
28− , height (px 200)
29− , Background.color red
30− ]
31− none
32− )
33− )
34− |> Testable.Generator.with Testable.Generator.allLayouts
35− |> Testable.Generator.with Testable.Generator.allElements
36− ]
tests-rendering/src/Tests/TextWrapping.elmdeleted−51
@@ -1,51 +0,0 @@
1−module Tests.TextWrapping exposing (main, view)
2−
3−import Html
4−import Testable
5−import Testable.Element exposing (..)
6−import Testable.Element.Background as Background
7−import Testable.Element.Font as Font
8−import Testable.Generator
9−import Testable.Runner
10−import Tests.Palette as Palette exposing (..)
11−
12−
13−box attrs =
14− el
15− ([ width (px 50)
16− , height (px 50)
17− , Background.color blue
18− ]
19− ++ attrs
20− )
21− none
22−
23−
24−{-| -}
25−main : Html.Html msg
26−main =
27− Testable.Runner.show view
28−
29−
30−view =
31− el [] <|
32− paragraph []
33− [ Testable.Generator.box
34− ]
35−
36−
37−
38−-- column [ spacing 16 ]
39−-- [ paragraph []
40−-- [ el [] (text Testable.Generator.short)
41−-- ]
42−-- -- , paragraph []
43−-- -- [ text Testable.Generator.lorem
44−-- -- , text Testable.Generator.lorem
45−-- -- ]
46−-- -- , paragraph []
47−-- -- [ text Testable.Generator.lorem
48−-- -- , paragraph []
49−-- -- [ text Testable.Generator.lorem ]
50−-- -- ]
51−-- ]
tests/Flags.elmdeleted−78
@@ -1,78 +0,0 @@
1−module Flags exposing (suite)
2−
3−{-| -}
4−
5−import Expect
6−import Internal.Flag as Flag
7−import Test
8−
9−
10−suite =
11− Test.describe "Flag Operations"
12− [ Test.test "All Flags Invalidate Themselves" <|
13− \_ ->
14− Expect.equal True (List.all (\flag -> Flag.present flag (Flag.add flag Flag.none)) allFlags)
15− , Test.test "All Flags don't interfere with each other" <|
16− \_ ->
17− Expect.equal True (List.all (doesntInvalidateOthers allFlags) allFlags)
18− ]
19−
20−
21−doesntInvalidateOthers others flag =
22− let
23− withFlag =
24− Flag.none
25− |> Flag.add flag
26− in
27− List.all identity <|
28− List.map
29− (\otherFlag ->
30− Flag.present otherFlag (Flag.add otherFlag withFlag)
31− )
32− others
33−
34−
35−allFlags =
36− [ Flag.transparency
37− , Flag.padding
38− , Flag.spacing
39− , Flag.fontSize
40− , Flag.fontFamily
41− , Flag.width
42− , Flag.height
43− , Flag.bgColor
44− , Flag.bgImage
45− , Flag.bgGradient
46− , Flag.borderStyle
47− , Flag.fontAlignment
48− , Flag.fontWeight
49− , Flag.fontColor
50− , Flag.wordSpacing
51− , Flag.letterSpacing
52− , Flag.borderRound
53− , Flag.shadows
54− , Flag.overflow
55− , Flag.cursor
56− , Flag.scale
57− , Flag.rotate
58− , Flag.moveX
59− , Flag.moveY
60− , Flag.borderWidth
61− , Flag.borderColor
62− , Flag.yAlign
63− , Flag.xAlign
64− , Flag.focus
65− , Flag.active
66− , Flag.hover
67− , Flag.gridTemplate
68− , Flag.gridPosition
69− , Flag.heightContent
70− , Flag.heightFill
71− , Flag.widthContent
72− , Flag.widthFill
73− , Flag.alignRight
74− , Flag.alignBottom
75− , Flag.centerX
76− , Flag.centerY
77− , Flag.fontVariant
78− ]
tests/Tests/Basic.elmnew file+54
@@ -0,0 +1,54 @@
1+module Tests.Basic exposing (view)
2+
3+{-| -}
4+
5+import Element as Actual
6+import Html
7+import Testable
8+import Testable.Element as Element exposing (..)
9+import Testable.Element.Background as Background
10+import Testable.Element.Font as Font
11+import Testable.Runner
12+import Tests.Palette as Palette
13+
14+
15+{-| -}
16+main : Html.Html msg
17+main =
18+ Testable.Runner.show view
19+
20+
21+{-| -}
22+view : Testable.Element msg
23+view =
24+ row [ spacing 50, alignTop ]
25+ [ el
26+ [ width (px 200)
27+ , height (px 200)
28+ , Background.color Palette.blue
29+ , Font.color Palette.white
30+ ]
31+ (text "Hello!")
32+ , el
33+ [ width (px 200)
34+ , height (px 200)
35+ , Background.color Palette.blue
36+ , Font.color Palette.white
37+ ]
38+ (text "Hello!")
39+ , el
40+ [ width (px 200)
41+ , height (px 200)
42+ , Background.color (Actual.rgba 0 0 1 1)
43+ , Font.color Palette.white
44+ , below
45+ (el
46+ [ Background.color Palette.grey
47+ , width (px 50)
48+ , height (px 50)
49+ ]
50+ none
51+ )
52+ ]
53+ (text "Hello!")
54+ ]
tests/Tests/ColumnAlignment.elmnew file+176

This diff is too big to show here.

tests/Tests/ColumnSpacing.elmnew file+68

This diff is too big to show here.

tests/Tests/ElementAlignment.elmnew file+111

This diff is too big to show here.

tests-rendering/cases/Manual/AlignedForm.elm → tests/Tests/Manual/AlignedForm.elmrenamed

The content is the same.

tests-rendering/cases/Manual/All.elm → tests/Tests/Manual/All.elmrenamed

The content is the same.

tests-rendering/cases/Manual/LazyPerformance.elm → tests/Tests/Manual/LazyPerformance.elmrenamed

The content is the same.

tests-rendering/cases/Manual/OtherScrollbars.elm → tests/Tests/Manual/OtherScrollbars.elmrenamed

The content is the same.

tests-rendering/cases/Manual/Overflow.elm → tests/Tests/Manual/Overflow.elmrenamed

The content is the same.

tests-rendering/cases/Manual/Scrollbars.elm → tests/Tests/Manual/Scrollbars.elmrenamed

The content is the same.

tests-rendering/cases/Manual/ScrollbarsPls.elm → tests/Tests/Manual/ScrollbarsPls.elmrenamed

The content is the same.

tests-rendering/cases/Manual/TextLayout.elm → tests/Tests/Manual/TextLayout.elmrenamed

The content is the same.

tests/Tests/Nearby.elmnew file+393

This diff is too big to show here.

tests-rendering/src/Tests/Palette.elm → tests/Tests/Palette.elmrenamed+1−5

This diff is too big to show here.

tests/Tests/RowAlignment.elmnew file+212

This diff is too big to show here.

tests/Tests/RowSpacing.elmnew file+69

This diff is too big to show here.

tests/Tests/Run.elmnew file+28

This diff is too big to show here.

tests-rendering/src/Tests/Table.elm.todo → tests/Tests/Table.elmrenamed+3−3

This diff is too big to show here.

tests-rendering/src/Tests/Transparency.elm → tests/Tests/Transparency.elmrenamed

The content is the same.

tests-rendering/src/Tests/WidthHeight.elm → tests/Tests/WidthHeight.elmrenamed+1−1

This diff is too big to show here.

tests/automation/selenium_test.pynew file+59

This diff is too big to show here.

experiments/virtual-css/elm.json → tests/elm.jsonrenamed+3−2

This diff is too big to show here.

tests/gather-styles.htmlnew file+83

This diff is too big to show here.

tests/live.shnew file+1

This diff is too big to show here.

tests-rendering/src/Generator.elm → tests/src/Generator.elmrenamed

The content is the same.

tests-rendering/src/Testable.elm → tests/src/Testable.elmrenamed+132−342

This diff is too big to show here.

tests/src/Testable/Element.elmnew file+1045

This diff is too big to show here.

tests-rendering/src/Testable/Element/Background.elm → tests/src/Testable/Element/Background.elmrenamed+4−5

This diff is too big to show here.

tests-rendering/src/Testable/Element/Font.elm → tests/src/Testable/Element/Font.elmrenamed+6−14

This diff is too big to show here.

tests/src/Testable/FuzzMain.elmnew file+629

This diff is too big to show here.

tests/src/Testable/Runner.elmnew file+444

This diff is too big to show here.

tests/ClassNames.elm → tests/suite/ClassNames.elmrenamed+3−17

This diff is too big to show here.

tests/suite/Flags.elmnew file+89

This diff is too big to show here.

tests/suite/elm-package.jsonnew file+16

This diff is too big to show here.

yarn.lockdeleted−1271

This diff is too big to show here.