diff --git a/.circleci/config.yml b/.circleci/config.yml
index f369fb7..32d062b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -9,7 +9,7 @@ jobs:
- restore_cache:
keys:
- - deps-{{ checksum "bower.json" }}-{{ checksum "examples/spago.dhall" }}
+ - deps-{{ checksum "examples/package.json" }}-{{ checksum "examples/packages.dhall" }}
- run:
command: |
@@ -28,7 +28,7 @@ jobs:
- examples/node_modules
- examples/.spago
- output
- key: deps-{{ checksum "bower.json" }}-{{ checksum "examples/spago.dhall" }}
+ key: deps-{{ checksum "examples/package.json" }}-{{ checksum "examples/packages.dhall" }}
- run:
command: |
diff --git a/LICENSE b/LICENSE
index e743565..7bebcaa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
BSD 3-Clause License
-Copyright (c) 2019, Nonbili Inc.
+Copyright (c) 2019-present, Nonbili Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index db6310c..57d9ef3 100644
--- a/README.md
+++ b/README.md
@@ -8,4 +8,9 @@ aNother Select library in purescript halogen.
## Development
-Follow [examples/README.md](examples/README.md).
+```
+cd examples
+yarn
+spago build -w
+yarn start
+```
diff --git a/examples/LICENSE b/examples/LICENSE
deleted file mode 100644
index e743565..0000000
--- a/examples/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-BSD 3-Clause License
-
-Copyright (c) 2019, Nonbili Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/examples/README.md b/examples/README.md
index 8fdaa11..9cbc6de 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,5 +1,152 @@
+# NSelect
+
+NSelect is a select library for PureScript Halogen. It manages some common logic to make building components like typeahead or dropdown easier. How your component looks is completely controlled by you.
+
+This document assumes you are already familiar with PureScript and Halogen. The type signatures in this document are for demonstration purpose only, they are inaccurate because many type variables are ommited.
+
+## Introduction
+
+Every Halogen component has a type signature like this:
+
+```hs
+component :: H.Component HH.HTML Query Props Message m
```
-yarn
-spago build -w
-yarn start
+
+- `Query` defines what actions can be sent to this component from the outside (parent component).
+- `Props` defines what data this component is accepting, also called `input` in other documentations. It's similar to the props in React, but not exactly the same.
+- `Message` defines what events this component emits to the outside (parent component), also called `output` in other documentations.
+
+In the case of `NSelect.component`, `Props` is more interesting than the other two.
+
+```hs
+-- Excerpt from module NSelect
+
+type State =
+ { isOpen :: Boolean
+ , highlightedIndex :: Int
+ }
+
+type Props =
+ { render :: State -> HTML
+ , itemCount :: Int
+ }
```
+
+`Props` is a record of two fields, let's ignore the `itemCount` field and focus on the `render` field. You can see from the type signature, `render` field is a function that takes `State` and returns `HTML`. This means when using `NSelect`, you need to pass a `render` function to `NSelect`.
+
+And if you take a look at the definition of `NSelect.render`:
+
+```hs
+render :: InnerState -> HTML
+render state =
+ state.props.render $ innerStateToState state
+```
+
+`NSelect` doesn't render anything more than you passed in. That's why at the beginning of this document, we said
+
+> How the component looks is completely controlled by you.
+
+## A dropdown example
+
+Let's use `NSelect` to build a simple dropdown. The `purescript-halogen-nselect` package has only one module called `NSelect`, first `import NSelect as NSelect`.
+
+```hs
+module Example.Dropdown where
+
+import NSelect as Select
+```
+
+Then, let's write the `render` function and fill in the missing parts piece by piece.
+
+```hs
+render :: State -> HTML
+render state =
+ HH.slot _dropdown unit Select.component
+ { render: renderSelect state
+ , itemCount: 0
+ } $ Just <<< HandleDropdown
+
+```
+
+The standard way in Halogen to render a child component is by using `HH.slot`. As said above, we need to pass a `render` function to `NSelect`. Here, we pass `renderSelect` to `Select.component`.
+
+```hs
+renderSelect :: State -> Select.State -> Select.HTML
+renderSelect state st =
+ HH.div (Select.setRootProps []) $ join
+ [ -- A button to open/close dropdown
+ pure $ HH.button
+ ( Select.setToggleProps [])
+ [ HH.text $ if st.isOpen then "Close" else "Open" ]
+ -- The dropdown itself
+ , guard st.isOpen $> HH.div_
+ [ HH.input
+ [ HP.value state.value
+ , HE.onValueInput $ Just <<< Select.raise <<< OnInput
+ ]
+ , HH.div_
+ [ HH.text $ "You typed: " <> state.value
+ ]
+ ]
+ ]
+```
+
+Some observations:
+
+- `Select.setRootProps` is used on the dropdown root element, so that click outside will close the dropdown.
+- `Select.setToggleProps` is used on the toggle button, so that `NSelect` will update the `st.isOpen` value.
+- Since `renderSelect` is passed to and rendered inside `NSelect`, it has different return type from `Example.Dropdown.render`. But you can still trigger `Example.Dropdown.Action` by using `Select.raise`.
+
+Demo:
+
+
+
+
+
+Click the button above should open a dropdown. So, with only a few lines of code, you get:
+
+- A toggle button to open a dropdown, you don't need to manage the `open` state of dropdown
+- Click outside to close the dropdown, you don't need to implement it repeatedly
+
+## More examples
+
+The source code can be found in the [examples](https://github.com/nonbili/purescript-halogen-nselect/tree/master/examples) folder.
+
+### Render another component in dropdown
+
+This example is similar to the above one, but this time, the input inside the dropdown is actually another component. This means you can embed any components furthur inside `NSelect`, as long as `Slot` types are correct.
+
+
+
+
+
+### Autocomplete
+
+Besides `Select.setRootProps`, this example uses three more helpers:
+
+- `Select.setInputProps` allows `NSelect` to manage focus/blur event of ``, to change `isOpen` state accordingly
+- `Select.setMenuProps` allows `NSelect` to track the scroll position
+- `Select.setItemProps` allows `NSelect` to emit `Selected` Message when user select an item
+
+This example demonstrates:
+
+- Press `ArrowUp`/`ArrowDown` to change selection, `NSelect` will make sure current highlighted item is visible
+- Press `Enter` to select
+
+
+
+
+
+### Two inputs
+
+When using `Select.setInputProps`, `NSelect` manages `KeyDownEvent` of `` for you, so that pressing `Enter` will select current highlighted item. Use `Select.setInputProps'` to bind more shortcuts to your ``.
+
+This example demonstrates using `Tab` key to select an item in the first input dropdown and focus the second input.
+
+
+
+
+
+## Acknowledgement
+
+This library was inspired by [downshift](https://github.com/downshift-js/downshift) and [purescript-halogen-select](https://github.com/citizennet/purescript-halogen-select).
diff --git a/examples/index.html b/examples/index.html
index 9dd5691..4ad4cdf 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -4,7 +4,7 @@
-
+
diff --git a/examples/index.md b/examples/index.md
deleted file mode 100644
index 9cbc6de..0000000
--- a/examples/index.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# NSelect
-
-NSelect is a select library for PureScript Halogen. It manages some common logic to make building components like typeahead or dropdown easier. How your component looks is completely controlled by you.
-
-This document assumes you are already familiar with PureScript and Halogen. The type signatures in this document are for demonstration purpose only, they are inaccurate because many type variables are ommited.
-
-## Introduction
-
-Every Halogen component has a type signature like this:
-
-```hs
-component :: H.Component HH.HTML Query Props Message m
-```
-
-- `Query` defines what actions can be sent to this component from the outside (parent component).
-- `Props` defines what data this component is accepting, also called `input` in other documentations. It's similar to the props in React, but not exactly the same.
-- `Message` defines what events this component emits to the outside (parent component), also called `output` in other documentations.
-
-In the case of `NSelect.component`, `Props` is more interesting than the other two.
-
-```hs
--- Excerpt from module NSelect
-
-type State =
- { isOpen :: Boolean
- , highlightedIndex :: Int
- }
-
-type Props =
- { render :: State -> HTML
- , itemCount :: Int
- }
-```
-
-`Props` is a record of two fields, let's ignore the `itemCount` field and focus on the `render` field. You can see from the type signature, `render` field is a function that takes `State` and returns `HTML`. This means when using `NSelect`, you need to pass a `render` function to `NSelect`.
-
-And if you take a look at the definition of `NSelect.render`:
-
-```hs
-render :: InnerState -> HTML
-render state =
- state.props.render $ innerStateToState state
-```
-
-`NSelect` doesn't render anything more than you passed in. That's why at the beginning of this document, we said
-
-> How the component looks is completely controlled by you.
-
-## A dropdown example
-
-Let's use `NSelect` to build a simple dropdown. The `purescript-halogen-nselect` package has only one module called `NSelect`, first `import NSelect as NSelect`.
-
-```hs
-module Example.Dropdown where
-
-import NSelect as Select
-```
-
-Then, let's write the `render` function and fill in the missing parts piece by piece.
-
-```hs
-render :: State -> HTML
-render state =
- HH.slot _dropdown unit Select.component
- { render: renderSelect state
- , itemCount: 0
- } $ Just <<< HandleDropdown
-
-```
-
-The standard way in Halogen to render a child component is by using `HH.slot`. As said above, we need to pass a `render` function to `NSelect`. Here, we pass `renderSelect` to `Select.component`.
-
-```hs
-renderSelect :: State -> Select.State -> Select.HTML
-renderSelect state st =
- HH.div (Select.setRootProps []) $ join
- [ -- A button to open/close dropdown
- pure $ HH.button
- ( Select.setToggleProps [])
- [ HH.text $ if st.isOpen then "Close" else "Open" ]
- -- The dropdown itself
- , guard st.isOpen $> HH.div_
- [ HH.input
- [ HP.value state.value
- , HE.onValueInput $ Just <<< Select.raise <<< OnInput
- ]
- , HH.div_
- [ HH.text $ "You typed: " <> state.value
- ]
- ]
- ]
-```
-
-Some observations:
-
-- `Select.setRootProps` is used on the dropdown root element, so that click outside will close the dropdown.
-- `Select.setToggleProps` is used on the toggle button, so that `NSelect` will update the `st.isOpen` value.
-- Since `renderSelect` is passed to and rendered inside `NSelect`, it has different return type from `Example.Dropdown.render`. But you can still trigger `Example.Dropdown.Action` by using `Select.raise`.
-
-Demo:
-
-
-
-
-
-Click the button above should open a dropdown. So, with only a few lines of code, you get:
-
-- A toggle button to open a dropdown, you don't need to manage the `open` state of dropdown
-- Click outside to close the dropdown, you don't need to implement it repeatedly
-
-## More examples
-
-The source code can be found in the [examples](https://github.com/nonbili/purescript-halogen-nselect/tree/master/examples) folder.
-
-### Render another component in dropdown
-
-This example is similar to the above one, but this time, the input inside the dropdown is actually another component. This means you can embed any components furthur inside `NSelect`, as long as `Slot` types are correct.
-
-
-
-
-
-### Autocomplete
-
-Besides `Select.setRootProps`, this example uses three more helpers:
-
-- `Select.setInputProps` allows `NSelect` to manage focus/blur event of ``, to change `isOpen` state accordingly
-- `Select.setMenuProps` allows `NSelect` to track the scroll position
-- `Select.setItemProps` allows `NSelect` to emit `Selected` Message when user select an item
-
-This example demonstrates:
-
-- Press `ArrowUp`/`ArrowDown` to change selection, `NSelect` will make sure current highlighted item is visible
-- Press `Enter` to select
-
-
-
-
-
-### Two inputs
-
-When using `Select.setInputProps`, `NSelect` manages `KeyDownEvent` of `` for you, so that pressing `Enter` will select current highlighted item. Use `Select.setInputProps'` to bind more shortcuts to your ``.
-
-This example demonstrates using `Tab` key to select an item in the first input dropdown and focus the second input.
-
-