Add demo page

This commit is contained in:
Tom Nunn 2023-04-14 14:15:51 +01:00
parent 7b8c093188
commit 3620d5924c
10 changed files with 2946 additions and 7 deletions

View File

@ -33,11 +33,19 @@ jobs:
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Use Node.js 16
uses: actions/setup-node@v3
with:
node-version: "16.15.0"
- name: 🔨 Build Project
run: |
cd demo
npm install
npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload entire repository
path: 'docs'
path: "demo/dist"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

4
.gitignore vendored
View File

@ -1,4 +1,4 @@
elm-stuff
examples/elm-stuff
examples/index.html
node_modules
node_modules
dist

27
demo/elm.json Normal file
View File

@ -0,0 +1,27 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"mdgriffith/elm-ui": "1.1.8",
"nunntom/elm-ui-select": "3.1.3",
"supermario/elm-countries": "1.1.1"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

View File

@ -4,9 +4,10 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script type="module" src="index.js"></script>
<title>Elm-ui-select Demo</title>
</head>
<body>
Docs
<div id="elm"></div>
</body>
</html>

5
demo/index.js Normal file
View File

@ -0,0 +1,5 @@
import { Elm } from "./src/Main.elm";
const app = Elm.Main.init({
node: document.getElementById("elm"),
});

2572
demo/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
demo/package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "elm-ui-select-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "vite",
"build": "vite build"
},
"author": "",
"license": "ISC",
"devDependencies": {
"elm": "^0.19.1-5",
"elm-format": "^0.8.7",
"vite-plugin-elm": "^2.7.2"
}
}

299
demo/src/Main.elm Normal file
View File

@ -0,0 +1,299 @@
module Main exposing (main)
import Browser
import Countries exposing (Country)
import Element
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Element.Input as Input
import Element.Region as Region
import Html
import Html.Attributes
import Html.Events
import Select exposing (Select)
-- MODEL
type alias Model =
{ select : Select Country
, clearButton : Bool
, forcePlacement : Maybe Select.MenuPlacement
, moveDown : Maybe Int
, maxWidth : Maybe Int
, maxHeight : Maybe Int
, minInputLength : Maybe Int
, selectOnTab : Bool
, customMenuStyle : Bool
}
init : () -> ( Model, Cmd Msg )
init _ =
( { select =
Select.init "country-select"
|> Select.setItems Countries.all
, clearButton = False
, forcePlacement = Nothing
, moveDown = Nothing
, maxWidth = Nothing
, maxHeight = Nothing
, minInputLength = Nothing
, selectOnTab = True
, customMenuStyle = False
}
, Cmd.none
)
-- UPDATE
type Msg
= SelectMsg (Select.Msg Country)
| ClearButtonChanged Bool
| ForcePlacementChanged (Maybe Select.MenuPlacement)
| MoveDownChanged (Maybe Int)
| MaxWidthChanged (Maybe Int)
| MaxHeightChanged (Maybe Int)
| MinInputLengthChanged (Maybe Int)
| SelectOnTabChanged Bool
| CustomMenuStyleChanged Bool
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
SelectMsg selectMsg ->
Select.update SelectMsg selectMsg model.select
|> Tuple.mapFirst (\s -> { model | select = s })
ClearButtonChanged v ->
( { model | clearButton = v }, Cmd.none )
ForcePlacementChanged v ->
( { model | forcePlacement = v }, Cmd.none )
MoveDownChanged v ->
( { model | moveDown = v }, Cmd.none )
MaxWidthChanged v ->
( { model | maxWidth = v }, Cmd.none )
MaxHeightChanged v ->
( { model | maxHeight = v }, Cmd.none )
MinInputLengthChanged v ->
( { model | minInputLength = v }, Cmd.none )
SelectOnTabChanged v ->
( { model | selectOnTab = v }, Cmd.none )
CustomMenuStyleChanged v ->
( { model | customMenuStyle = v }, Cmd.none )
-- VIEW
view : Model -> Html.Html Msg
view model =
Element.layout
[ Element.padding 50
, Element.height Element.fill
]
<|
Element.column
[ Element.centerX
, Element.spacing 50
, Element.height Element.fill
]
[ Element.paragraph
[ Font.bold
, Font.size 32
, Font.center
]
[ Element.text "elm-ui-select demo" ]
, Element.row
[ Element.spacing 50
, Element.height Element.fill
]
[ Select.view [ Element.htmlAttribute <| Html.Attributes.attribute "autocomplete" "off" ]
{ onChange = SelectMsg
, itemToString = \c -> c.name ++ " " ++ c.flag
, label = Input.labelAbove [] (Element.text "Choose a country")
, placeholder = Nothing
}
|> configureIf model.clearButton (Select.withClearButton (Just clearButton))
|> configureIf (model.forcePlacement == Just Select.MenuAbove) Select.withMenuAlwaysAbove
|> configureIf (model.forcePlacement == Just Select.MenuBelow) Select.withMenuAlwaysBelow
|> Select.withMenuMaxHeight model.maxHeight
|> Select.withMenuMaxWidth model.maxWidth
|> Select.withMinInputLength model.minInputLength
|> Select.withSelectOnTab model.selectOnTab
|> configureIf model.customMenuStyle (Select.withMenuAttributes (menuAttributes <| Select.isMenuOpen model.select))
|> Select.toElement model.select
|> Element.el
[ Element.alignTop
, Element.htmlAttribute <| Html.Attributes.style "z-index" "100"
, Element.width <| Element.fillPortion 1
, Element.htmlAttribute <| Html.Attributes.style "position" "relative"
, Element.htmlAttribute <| Html.Attributes.style "top" (String.fromInt (Maybe.withDefault 0 model.moveDown) ++ "%")
]
, Element.column
[ Element.spacing 20
, Element.alignTop
, Element.width <| Element.fillPortion 1
, Font.size 16
]
[ Input.checkbox []
{ onChange = ClearButtonChanged
, icon = Input.defaultCheckbox
, checked = model.clearButton
, label = Input.labelRight [] (Element.text "With clear button")
}
, Input.radio [ Element.spacing 10 ]
{ onChange = ForcePlacementChanged
, options =
[ Input.option Nothing (Element.text "None")
, Input.option (Just Select.MenuAbove) (Element.text "Above")
, Input.option (Just Select.MenuBelow) (Element.text "Below")
]
, selected = Just model.forcePlacement
, label =
Input.labelAbove [ Element.paddingEach { top = 0, bottom = 20, left = 0, right = 0 } ]
(Element.text "Force placement of menu:")
}
, Element.column [ Element.spacing 20 ]
[ Element.text "Move down"
, Element.html <|
Html.input
[ Html.Attributes.type_ "range"
, Html.Attributes.min "0"
, Html.Attributes.max "90"
, Html.Attributes.style "appearance" "auto"
, Html.Attributes.style "-webkit-appearance" "auto"
, Html.Attributes.style "-moz-appearance" "auto"
, Html.Attributes.style "opacity" "1"
, Html.Attributes.style "position" "static"
, Html.Attributes.style "outline" "none"
, Html.Events.onInput (MoveDownChanged << String.toInt)
, Html.Attributes.value (String.fromInt (Maybe.withDefault 0 model.moveDown))
]
[]
, Element.paragraph
[ Font.size 10
, Font.center
, Font.alignLeft
]
[ Element.text "Move the input down the page to see how it affects the placement and size of the dropdown menu." ]
]
, Element.column [ Element.spacing 10 ]
[ Input.text []
{ onChange = String.toInt >> MaxWidthChanged
, text = model.maxWidth |> Maybe.map String.fromInt |> Maybe.withDefault ""
, label = Input.labelAbove [] (Element.text "Max width of menu (pixels)")
, placeholder = Nothing
}
, Element.paragraph
[ Font.size 10
, Font.center
, Font.alignLeft
]
[ Element.text """Limits the width of the dropdown menu, but only as far as the width of the input!""" ]
]
, Input.text []
{ onChange = String.toInt >> MaxHeightChanged
, text = model.maxHeight |> Maybe.map String.fromInt |> Maybe.withDefault ""
, label = Input.labelAbove [] (Element.text "Max height of menu (pixels)")
, placeholder = Nothing
}
, Input.text []
{ onChange = String.toInt >> MinInputLengthChanged
, text = model.minInputLength |> Maybe.map String.fromInt |> Maybe.withDefault ""
, label = Input.labelAbove [] (Element.text "Min input length to show menu (characters)")
, placeholder = Nothing
}
, Input.checkbox []
{ onChange = SelectOnTabChanged
, icon = Input.defaultCheckbox
, checked = model.selectOnTab
, label = Input.labelRight [] (Element.text "Select highlighted on tab")
}
, Input.checkbox []
{ onChange = CustomMenuStyleChanged
, icon = Input.defaultCheckbox
, checked = model.customMenuStyle
, label = Input.labelRight [] (Element.text "Add some custom styles to the menu")
}
]
]
]
configureIf : Bool -> (a -> a) -> a -> a
configureIf condition f =
if condition then
f
else
identity
clearButton : Select.ClearButton msg
clearButton =
Select.clearButton [ Element.alignRight, Element.centerY, Element.moveLeft 12 ]
(Element.el [ Font.size 10, Region.description "clear selection" ] (Element.text ""))
menuAttributes : Bool -> Select.MenuPlacement -> List (Element.Attribute msg)
menuAttributes isOpen placement =
[ [ Background.color (Element.rgba 1 1 1 1)
, Element.htmlAttribute (Html.Attributes.style "white-space" "auto")
, Element.htmlAttribute (Html.Attributes.class "select-menu")
, Element.htmlAttribute (Html.Attributes.style "transition" "transform 100ms ease-out, opacity 100ms ease-out")
, Font.color (Element.rgba 0 0 0 1)
, Border.rounded 2
, Border.width 0
, Border.shadow
{ offset = ( 0, 4 )
, size = 3
, blur = 10
, color = Element.rgba 0 0 0 0.5
}
]
, if isOpen then
[ Element.htmlAttribute (Html.Attributes.style "opacity" "1")
]
else
[ Element.htmlAttribute (Html.Attributes.style "opacity" "0")
, Element.htmlAttribute (Html.Attributes.style "transform" "scale(0.95)")
]
, case placement of
Select.MenuBelow ->
[ Element.moveDown 10 ]
_ ->
[]
]
|> List.concat
-- MAIN
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}

9
demo/vite.config.js Normal file
View File

@ -0,0 +1,9 @@
import { defineConfig } from "vite";
import elmPlugin from "vite-plugin-elm";
export default defineConfig({
plugins: [elmPlugin()],
build: {
target: "es2015",
},
});

View File

@ -7,7 +7,8 @@
"review": "elm-review",
"review-examples": "elm-review --elmjson examples/elm.json --config=review --ignore-dirs=../src",
"ci": "npm run review && npm run review-examples && npm run test",
"examples": "cd examples/src && elm reactor"
"examples": "cd examples/src && elm reactor",
"build-demo": "cd demo && npm run build"
},
"pre-commit": [
"ci"