mirror of
https://github.com/nunntom/elm-ui-select.git
synced 2024-11-22 03:33:11 +03:00
Add demo page
This commit is contained in:
parent
7b8c093188
commit
3620d5924c
12
.github/workflows/static.yml
vendored
12
.github/workflows/static.yml
vendored
@ -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
4
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
elm-stuff
|
||||
examples/elm-stuff
|
||||
examples/index.html
|
||||
node_modules
|
||||
node_modules
|
||||
dist
|
27
demo/elm.json
Normal file
27
demo/elm.json
Normal 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": {}
|
||||
}
|
||||
}
|
@ -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
5
demo/index.js
Normal 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
2572
demo/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
demo/package.json
Normal file
17
demo/package.json
Normal 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
299
demo/src/Main.elm
Normal 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
9
demo/vite.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
import { defineConfig } from "vite";
|
||||
import elmPlugin from "vite-plugin-elm";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [elmPlugin()],
|
||||
build: {
|
||||
target: "es2015",
|
||||
},
|
||||
});
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user