This repository has been archived by the owner on Jun 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from safareli/init
Initial version
- Loading branch information
Showing
10 changed files
with
1,344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,6 @@ node_modules | |
# Generated files | ||
.psci | ||
output | ||
example/example.js | ||
|
||
.psc-ide-port |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
# purescript-colorpicker-halogen | ||
|
||
Halogen component for color picking | ||
|
||
## Examples | ||
|
||
To run examples | ||
|
||
```bash | ||
npm run build | ||
http-server example | ||
``` | ||
|
||
you can install [http-server using npm](https://www.npmjs.com/package/http-server) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "purescript-colorpicker-halogen", | ||
"license": "Apache-2.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/slamdata/purescript-colorpicker-halogen.git" | ||
}, | ||
"authors": [ | ||
"Irakli Safareli <[email protected]>" | ||
], | ||
"ignore": [ | ||
"**/.*", | ||
"bower_components", | ||
"node_modules", | ||
"output", | ||
"tests", | ||
"tmp", | ||
"bower.json", | ||
"package.json", | ||
"example" | ||
], | ||
"dependencies": { | ||
"purescript-colors": "^4.0.0", | ||
"purescript-halogen": "^2.1.0", | ||
"purescript-halogen-css": "^6.0.0", | ||
"purescript-dom-classy": "^2.1.0", | ||
"purescript-dom": "^4.7.0", | ||
"purescript-number-input-halogen": "git://github.com/safareli/purescript-number-input-halogen.git#initial-props" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<title>Halogen Datepicker Example</title> | ||
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/7.0.0/normalize.css"> | ||
<link rel="stylesheet" href="styles.css"> | ||
<style> | ||
.root { max-width: 700px } | ||
</style> | ||
</head> | ||
<body> | ||
<script src="example.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
module Main where | ||
|
||
import Prelude | ||
|
||
import Color (Color, rgb) | ||
import Color.Scheme.X11 (blue, orange, red) | ||
import ColorPicker.Halogen.Component as CPicker | ||
import ColorPicker.Halogen.Layout as L | ||
import Control.Monad.Aff.Class (class MonadAff) | ||
import Control.Monad.Eff (Eff) | ||
import Control.MonadZero (guard) | ||
import Data.Array (reverse) | ||
import Data.Either.Nested as Either | ||
import Data.Functor.Coproduct.Nested as Coproduct | ||
import Data.Map (Map, insert, lookup) | ||
import Data.Maybe (Maybe(..), maybe) | ||
import Data.Monoid (mempty) | ||
import Halogen as H | ||
import Halogen.Aff as HA | ||
import Halogen.Component.ChildPath as CP | ||
import Halogen.HTML as HH | ||
import Halogen.HTML.Events as HE | ||
import Halogen.HTML.Properties as HP | ||
import Halogen.VDom.Driver (runUI) | ||
|
||
main ∷ Eff (HA.HalogenEffects ()) Unit | ||
main = HA.runHalogenAff do | ||
body ← HA.awaitBody | ||
runUI example unit body | ||
|
||
data Query a = HandleMsg ColorIdx CPicker.Message a | ||
|
||
type State = Map Int {current ∷ Color, next ∷ Color } | ||
type ColorIdx = Int | ||
type ChildQuery = Coproduct.Coproduct1 CPicker.Query | ||
type Slot = Either.Either1 ColorIdx | ||
|
||
cpColor ∷ CP.ChildPath CPicker.Query ChildQuery ColorIdx Slot | ||
cpColor = CP.cp1 | ||
|
||
type HTML m = H.ParentHTML Query ChildQuery Slot m | ||
type DSL m = H.ParentDSL State Query ChildQuery Slot Void m | ||
|
||
|
||
example ∷ ∀ m r. MonadAff (CPicker.PickerEffects r) m => H.Component HH.HTML Query Unit Void m | ||
example = H.parentComponent | ||
{ initialState: const mempty | ||
, render | ||
, eval | ||
, receiver: const Nothing | ||
} | ||
|
||
render ∷ ∀ m r. MonadAff (CPicker.PickerEffects r) m => State → HTML m | ||
render state = HH.div [HP.class_ $ H.ClassName "root"] | ||
$ renderPicker orange 0 config0 | ||
<> renderPicker blue 1 config1 | ||
<> renderPicker red 2 config2 | ||
<> renderPicker red 3 config3 | ||
|
||
where | ||
renderPicker color idx conf = | ||
[ HH.h1_ [ HH.text $ "Picker " <> show idx ] | ||
, HH.slot' cpColor idx (CPicker.picker color) conf (HE.input $ HandleMsg idx) | ||
, HH.p_ [ HH.text case lookup idx state of | ||
Just ({current, next}) → | ||
"uncommited (current: " <> show current <>", next:" <> show next <> ")" | ||
Nothing → "no color" | ||
] | ||
] | ||
|
||
eval ∷ ∀ m. Query ~> DSL m | ||
eval (HandleMsg idx msg next) = do | ||
H.modify update | ||
pure next | ||
where | ||
update state = insert idx val state | ||
where | ||
val = case lookup idx state, msg of | ||
Just s, CPicker.NextChange nextVal → s{next = nextVal} | ||
_, CPicker.NextChange x → { next: x, current: x } | ||
_, CPicker.NotifyChange x → {next: x, current: x} | ||
|
||
config0 ∷ CPicker.Props | ||
config0 = mkConf $ L.Root c $ reverse l | ||
where | ||
L.Root c l = mkLayout | ||
[H.ClassName "ColorPicker--small", H.ClassName "ColorPicker--inline"] | ||
[ [ L.componentHue | ||
, L.componentSaturationHSL | ||
, L.componentLightness | ||
] | ||
] | ||
|
||
config1 ∷ CPicker.Props | ||
config1 = mkConf $ mkLayout | ||
[H.ClassName "ColorPicker--large", H.ClassName "ColorPicker--inline"] | ||
[ [ L.componentHue | ||
, L.componentSaturationHSV | ||
, L.componentValue | ||
, L.componentSaturationHSL | ||
, L.componentLightness | ||
] | ||
, [ L.componentRed | ||
, L.componentGreen | ||
, L.componentBlue | ||
, L.componentHEX | ||
] | ||
] | ||
|
||
config2 ∷ CPicker.Props | ||
config2 = mkConf $ mkLayout | ||
[H.ClassName "ColorPicker--small", H.ClassName "ColorPicker--inline"] | ||
[ [ const componentRedORNoRed ]] | ||
|
||
config3 ∷ CPicker.Props | ||
config3 = mkConf $ mkLayout | ||
[H.ClassName "ColorPicker--small", H.ClassName "ColorPicker--block"] | ||
[ [ const componentRedORNoRed ]] | ||
|
||
componentRedORNoRed ∷ L.PickerComponent | ||
componentRedORNoRed = L.TextComponentSpec | ||
{ fromString: \str → guard (str == "red") $> red | ||
, view: \{color, value, onBlur, onValueInput } → pure $ | ||
HH.label | ||
[ HP.classes inputClasses.root] | ||
[ HH.span [HP.classes inputClasses.label] [HH.text "🛑"] | ||
, HH.input | ||
[ HP.type_ HP.InputText | ||
, HP.classes | ||
$ inputClasses.elem | ||
<> (guard (L.isInvalid value) *> (inputClasses.elemInvalid)) | ||
, HP.title "red or nored?" | ||
, HP.value $ maybe (toString color) _.value value | ||
, HP.placeholder "red" | ||
, HE.onValueInput $ onValueInput >>> Just | ||
, HE.onBlur $ onBlur >>> Just | ||
] | ||
] | ||
} | ||
where | ||
red = rgb 255 0 0 | ||
toString = \color → if color == red then "red" else "noRed" | ||
|
||
|
||
mkConf ∷ L.Layout → CPicker.Props | ||
mkConf = { layout: _ } | ||
|
||
mkLayout | ||
∷ Array H.ClassName | ||
→ Array (Array (L.InputProps → L.PickerComponent)) | ||
→ L.Layout | ||
mkLayout root editGroups = | ||
([ H.ClassName "ColorPicker"] <> root) `L.Root` | ||
[ [ H.ClassName "ColorPicker-dragger" ] `L.Group` | ||
[ L.Component $ L.componentDragSV | ||
{ root: [ H.ClassName "ColorPicker-field" ] | ||
, isLight: [ H.ClassName "IsLight" ] | ||
, isDark: [ H.ClassName "IsDark" ] | ||
, selector: [ H.ClassName "ColorPicker-fieldSelector"] | ||
} | ||
, L.Component $ L.componentDragHue | ||
{ root: [ H.ClassName "ColorPicker-slider" ] | ||
, selector: [ H.ClassName "ColorPicker-sliderSelector"] | ||
} | ||
] | ||
, [ H.ClassName "ColorPicker-aside" ] `L.Group` | ||
[ [ H.ClassName "ColorPicker-stage" ] `L.Group` | ||
[ L.Component $ L.componentPreview [ H.ClassName "ColorPicker-colorBlockCurrent" ] | ||
, L.Component $ L.componentHistory 4 [ H.ClassName "ColorPicker-colorBlockOld" ] | ||
] | ||
, L.Group [ H.ClassName "ColorPicker-editing" ] $ | ||
editGroups <#> \editGroup → | ||
L.Group [ H.ClassName "ColorPicker-editingItem" ] $ | ||
editGroup <#> \mkItem → L.Component $ mkItem inputClasses | ||
, [ H.ClassName "ColorPicker-actions" ] `L.Group` | ||
[ L.Component $ L.componentSet [ H.ClassName "ColorPicker-actionSet" ] ] | ||
] | ||
] | ||
|
||
inputClasses ∷ L.InputProps | ||
inputClasses = | ||
{ root: [H.ClassName "ColorPicker-input"] | ||
, label: [H.ClassName "ColorPicker-inputLabel"] | ||
, elem: [H.ClassName "ColorPicker-inputElem"] | ||
, elemInvalid: [H.ClassName "ColorPicker-inputElem--invalid"] | ||
} |
Oops, something went wrong.