clay 0.12.3 → 0.16.1
raw patch · 33 files changed
Files
- CHANGELOG +163/−0
- CONTRIBUTING.md +53/−0
- README.md +13/−0
- clay.cabal +30/−16
- src/Clay.hs +4/−1
- src/Clay/Animation.hs +1/−1
- src/Clay/Background.hs +2/−3
- src/Clay/Border.hs +1/−1
- src/Clay/Box.hs +4/−1
- src/Clay/Color.hs +8/−6
- src/Clay/Comments.hs +0/−1
- src/Clay/Common.hs +54/−30
- src/Clay/Display.hs +99/−23
- src/Clay/Filter.hs +1/−1
- src/Clay/Flexbox.hs +4/−2
- src/Clay/Font.hs +2/−1
- src/Clay/FontFace.hs +0/−2
- src/Clay/Geometry.hs +103/−1
- src/Clay/Gradient.hs +0/−2
- src/Clay/Grid.hs +775/−0
- src/Clay/List.hs +1/−2
- src/Clay/Mask.hs +0/−2
- src/Clay/Media.hs +40/−4
- src/Clay/Property.hs +21/−15
- src/Clay/Pseudo.hs +19/−3
- src/Clay/Render.hs +10/−5
- src/Clay/Selector.hs +10/−15
- src/Clay/Size.hs +100/−32
- src/Clay/Stylesheet.hs +7/−5
- src/Clay/Text.hs +107/−4
- src/Clay/Time.hs +0/−1
- src/Clay/Transform.hs +55/−12
- src/Clay/Transition.hs +9/−7
+ CHANGELOG view
@@ -0,0 +1,163 @@+CHANGELOG++ 0.16.1:+ - Add support for overscroll-behaviour+ Thanks to Sylvain Henry++ 0.16.0:+ - Add grid size and location support.+ - Derive `Stretch` for justified content+ - Add `AspectRatio`+ - Promote `not` to a type class+ - Render CSS refinements+ - Bugfixes & improved test suite+ Thanks to Leonard Monnier, Yoo Chung, Skyfold, qwbarch, David Fox++ 0.15.0:+ - Add `all` media type.+ - Support `prefers-color-scheme` media feature.+ - Use `matrix` rather than `matrix3d`+ - Add media type `all`+ - Add some relative units+ - Add CSS properties related to hyphenation+ - Use `Number` type instead of `Double` as an argument type in many places+ - Fix rendering of `Number` type+ Thanks to Yoo Chung, Charles Bayley and David Fox++ 0.14.0:+ - Drop support for GHC 8.2+ - Added `text-align-last`+ - Fix typo in `stepsStart`+ - Added clay-examples+ - Fix `cubicBezier` and other issues+ Thanks to Vasiliy Yorkin, Florian Grignon, Nick Saunders, David Fox, Ben Sima, Murakami Kennzo, Owen Shepherd, Anton Gushcha, Temur Saidkhodjaev, Rob Bassi, Alex Sayers, and further contributors.++ 0.13.3:+ - Improve README+ - Relax types for `sym2` and `sym3` combinators+ - Add new cursors+ Thanks to Sridhar Ratnakumar, Brad Ediger and Alexandre Esteves.++ 0.13.2:+ - Bump hspec versions+ Thanks to Julien Dehos and Sean Parsons.++ 0.13.1:+ - 'Clay.Size': Add 'sticky: Position'.+ - Adhere to Semigroup-Monoid-Hierarchy+ - 'Clay.Transition': Add 'stepEnd: TimingFunction'+ Thanks to Sean Parsons, Elliot Cameron, Simon Jakobi and Olivier Sohn.++ 0.13.0:+ - Added commenting to append comment to a property.+ - Comments are displayed by default in pretty but not compact mode.+ - Rewrite boxShadow functionality with BoxShadow newtype for arguments.+ - Added 'important' to append !important to values.+ - Update eachLine and hanging to work as spec (for textIndent).+ - Rename (internal) intersperse function to intercalate.+ - Not pseudo takes selector.+ Thanks to dbaynard and sebastiaanvisser.++ 0.10 -> 0.10.1+ - Expose a render function for single selectors.+ - Added super for vertical-align.+ - Added support for border-collapse.+ - Allow initial for the content property.+ - Added support for CSS import.+ Thanks to Heather, Collin J. Doering, Fraser Murray and Jonathan Fischoff.++ 0.9 -> 0.10+ - Bumped up text requirement.+ - Added cursor property.+ - Added vertical-align property.+ - Removed Abs constraint from Geometry functions.+ - Added support for rem dimensions.+ - Added support for ListStyle.+ Thanks to Lorenzo Bolla, Fraser Murray, Heather and Sergey!++ 0.9 -> 0.9.0.1+ - Fixed bug in easing properties.++ 0.8 -> 0.9+ - Added list-style-type property.+ - Added some CSS3 selectors and pseudo-classes.+ - Added some missing HTML5 elements.+ - Added keyframes support.+ - Fixed bug in linear in transition.+ - Added Initial and Unset type classes.+ - Added animation related styling rules.+ - Restored old renderer.+ - Fixed bunch of warnings.+ - Added :last-child pseudo selector.+ - Stub test suite+ Thanks to Sergei Trofimovich, Levi Ad, Ian D. Bollinger, Ben Gamari and Oly Mi!++ 0.8 -> 0.8.0.1+ - Widened dependency on text.+ Thanks to bgamari.++ 0.7 -> 0.8+ - Print prettier doubles.+ - Loosen type of sym functions.+ - Added some missing multi-side properties.+ - Added content URL support.+ - Added inset box shadows.+ Thanks Deck and James Fisher.++ 0.6 -> 0.7+ - Stop printing banner in compact mode.+ - Generic font family as datatype.+ - Only drop final semicolon if doing compact printing.++ 0.5.1 -> 0.6+ - Simplified implementation of size rendering.+ - Implemented @font-face construct. By James Fisher.+ - Make hsl(a) colors actually print percentage values.+ - Changed the renderer to haul @font-face to the top level.++ 0.5 -> 0.5.1+ - Fixed bug in fontFamily renderer.++ 0.4 -> 0.5+ - Generalized the borderRadius function.+ - Fixed some small issues in Dynamic.++ 0.3 -> 0.4+ - Added dynamic presentation. (thanks to chrisdone)+ - Float now has its own value, don't incorrectly share side. (thanks to chrisdone)+ - Added nil size constructor.+ - Slightly improved the gradient syntax.+ - Expose the Propery module by default.+ - Introduced shared 'all' value.++ 0.2 -> 0.3+ - Fixed value grammar of radial gradients.+ - Added mask related properties.+ - Allow multiple box-shadows.+ - Added filter property.+ - Also render value prefix when both key and value are prefixed.++ 0.1.1 -> 0.2+ - Rotate takes only one argument.+ - Added opacity property.+ - Print Clay banner in CSS comments by default.+ - Fixed bug in font-family rendering (Firefox only).+ - Added outline related properties.+ - Fixed bug in monospace font family.++ 0.1 -> 0.1.1+ - Fixed bug in visibility property.+ Thanks to Conrad Indiono for the pull request.++ 0.0.1 -> 0.1++ - Fixed bug in combined selector rendering.+ - Fixed bug in font familty fallback category rendering.+ - Added maxWidth and maxHeight.+ - Fixed example code.+ - Fixed overflowX/overflowY bug.+ - Added some show instance for debugging purposes.+ - Don't print the star (*) selector in the case of refinements.+ - Refinements applied to the top level magically introduce star selector.+ Thanks to listx, bergmark, Cynede, chrisdone, Primigenus, Sigrlami for the+ pull requests and bug reports.
+ CONTRIBUTING.md view
@@ -0,0 +1,53 @@+# Build setup++Ideally, you build this project with [`nix`](https://nixos.org/nix/):++```+git clone git@github.com:sebastiaanvisser/clay.git+cd clay+nix-build+```++This will build `clay` for the current default version of GHC.+To build for a particular version,+set the `GHC_VERSION` environment variable:++```+GHC_VERSION=ghc881 nix-build+```++To find out which GHC versions our nix setup provides:++```+$ nix eval '(builtins.attrNames (import (builtins.fetchTarball (import ./nix/nixpkgs.nix)) {}).haskell.compiler)'+[ "ghc8102Binary" "ghc8102BinaryMinimal" "ghc8104" "ghc865Binary" "ghc884" "ghc901" "ghcHEAD" "integer-simple" "native-bignum" ]+```++# Building your pull request++You are heartily encouraged to close an issue by contributing a pull request that fixes it :)+To test whether your fix will build,+ideally you should build it for all GHC versions:++```+nix-build all-ghcs.nix+```++You can see all supported versions in `.travis.yml`.+If your fix breaks an older version, do not despair.+As long as the last three versions work,+you can delete older GHC versions from `.travis.yml` in your pull request,+and deprecation of that version will be considered.++If you fix an important bug or contribute a new feature,+consider adding a line to `CHANGELOG` describing what you have changed.++# Running tests locally++Tests will be run with the above `nix-build` calls, but if you want to run them+without doing a full nix build, you can do so with cabal:++```+nix-shell+cabal test+```
+ README.md view
@@ -0,0 +1,13 @@+# Clay++[](https://github.com/sebastiaanvisser/clay/actions/workflows/ci.yml)+[](https://hackage.haskell.org/package/clay)++Clay is a CSS preprocessor like LESS and Sass, but implemented as an embedded+domain specific language (EDSL) in Haskell. This means that all CSS selectors+and style rules are first class Haskell functions, which makes reuse and+composability easy.++The project is described on [the project homepage](http://fvisser.nl/clay).++The API documentation can be found in the top level module `Clay`.
clay.cabal view
@@ -1,5 +1,5 @@ Name: clay-Version: 0.12.3+Version: 0.16.1 Synopsis: CSS preprocessor as embedded Haskell. Description: Clay is a CSS preprocessor like LESS and Sass, but implemented as an embedded@@ -20,13 +20,24 @@ License: BSD3 License-File: LICENSE Category: Web, Graphics-Cabal-Version: >= 1.8+Cabal-Version: >= 1.10 Build-Type: Simple +Extra-Source-Files:+ README.md CHANGELOG CONTRIBUTING.md+ Tested-With:- GHC==7.8.4,- GHC==7.10.3,- GHC==8.0.1+ GHC==8.4.4,+ GHC==8.6.5,+ GHC==8.8.4,+ GHC==8.10.7,+ GHC==9.0.2,+ GHC==9.2.2,+ GHC==9.4.2,+ GHC==9.6.6,+ GHC==9.8.1,+ GHC==9.10.1,+ GHC==9.12.1 Source-Repository head Type: git@@ -54,6 +65,7 @@ Clay.FontFace Clay.Geometry Clay.Gradient+ Clay.Grid Clay.List Clay.Media Clay.Mask@@ -68,21 +80,23 @@ Clay.Transform Clay.Transition - GHC-Options: -Wall Build-Depends:- base >= 4.5 && < 5,- mtl >= 1 && < 2.3,- text >= 0.11 && < 1.3+ base >= 4.11 && < 4.22,+ mtl >= 1,+ text >= 0.11+ GHC-Options: -Wall -Wcompat+ Default-Language: Haskell2010 Test-Suite Test-Clay Type: exitcode-stdio-1.0 HS-Source-Dirs: spec, src+ Build-Tools: hspec-discover main-is: Spec.hs Build-Depends:- base >= 4.5 && < 5,- base >= 4 && < 5,- mtl >= 1 && < 2.3,- text >= 0.11 && < 1.3,- hspec-expectations >= 0.7.2 && < 0.9,- hspec >= 2.2.0 && < 2.5- Ghc-Options: -Wall+ base >= 4.11 && < 4.22,+ mtl >= 1,+ text >= 0.11,+ hspec >= 2.2.0,+ hspec-discover >= 2.2.0+ GHC-Options: -Wall -Wcompat+ Default-Language: Haskell2010
src/Clay.hs view
@@ -39,6 +39,7 @@ , (|>) , (#) , (|+)+, (|~) -- ** Refining selectors. @@ -112,6 +113,7 @@ , module Clay.FontFace , module Clay.Geometry , module Clay.Gradient+, module Clay.Grid , module Clay.List , module Clay.Text , module Clay.Transform@@ -155,6 +157,7 @@ import Clay.FontFace import Clay.Geometry import Clay.Gradient+import Clay.Grid import Clay.List import Clay.Size import Clay.Text hiding (pre)@@ -182,6 +185,6 @@ -- grouped with the preceding value when rendered compactly. -- -- Note that /every/ generated line in the generated content will feature the--- comment. +-- comment. -- -- An empty comment generates '@/* */@'.
src/Clay/Animation.hs view
@@ -142,7 +142,7 @@ infinite :: IterationCount infinite = IterationCount "infinite" -iterationCount :: Double -> IterationCount+iterationCount :: Number -> IterationCount iterationCount = IterationCount . value -------------------------------------------------------------------------------
src/Clay/Background.hs view
@@ -145,13 +145,12 @@ ------------------------------------------------------------------------------- newtype BackgroundSize = BackgroundSize Value- deriving (Val, Other, Inherit)+ deriving (Val, Other, Inherit, Contain) instance Auto BackgroundSize where auto = auto `by` auto -contain, cover :: BackgroundSize+cover :: BackgroundSize -contain = BackgroundSize "contain" cover = BackgroundSize "cover" by :: Size a -> Size b -> BackgroundSize
src/Clay/Border.hs view
@@ -56,7 +56,7 @@ ------------------------------------------------------------------------------- -border, borderTop, borderLeft, borderBottom, borderRight :: Stroke -> Size LengthUnit -> Color -> Css+border, borderTop, borderLeft, borderBottom, borderRight :: Size LengthUnit -> Stroke -> Color -> Css border a b c = key "border" (a ! b ! c) borderTop a b c = key "border-top" (a ! b ! c)
src/Clay/Box.hs view
@@ -20,7 +20,6 @@ ) where -import Data.Monoid import Data.List.NonEmpty (NonEmpty) import Clay.Color@@ -82,6 +81,10 @@ -- > boxShadow . pure $ shadow (px 1) (px 1) -- -- Use with @{-# LANGUAGE OverloadedLists #-}@ for the simplest list syntax.+-- Note that sometimes when @{-# LANGUAGE OverloadedLists #-}@ is active, GHC+-- has troubles identifying what type the list should be converted to. Examples:+-- 1) "forM_ [0..10] $ \x -> ..."+-- 2) "[left, top, right, bottom] `forM_` ($ pct 4)" -- -- > boxShadow [none] -- > boxShadow [shadow (px 1) (px 1)]
src/Clay/Color.hs view
@@ -2,11 +2,10 @@ module Clay.Color where import Data.Char (isHexDigit)-import Data.Monoid import Data.String-import Data.Text (Text) import Text.Printf +import Data.Text (Text) import qualified Data.Text as Text import Data.Text.Read as Text @@ -119,14 +118,17 @@ (*.) :: Color -> Integer -> Color (*.) (Rgba r g b a) i = Rgba (clamp (r * i)) (clamp (g * i)) (clamp (b * i)) a (*.) o _ = o+infixl 7 *. (+.) :: Color -> Integer -> Color (+.) (Rgba r g b a) i = Rgba (clamp (r + i)) (clamp (g + i)) (clamp (b + i)) a (+.) o _ = o+infixl 6 +. (-.) :: Color -> Integer -> Color (-.) (Rgba r g b a) i = Rgba (clamp (r - i)) (clamp (g - i)) (clamp (b - i)) a (-.) o _ = o+infixl 6 -. clamp :: Ord a => Num a => a -> a clamp i = max (min i (fromIntegral (255 :: Integer))) (fromIntegral (0 :: Integer))@@ -176,10 +178,10 @@ instance Val Color where value clr = case clr of- Rgba r g b 1.0 -> Value $mconcat ["#", p' r, p' g, p' b]- Rgba r g b a -> Value $mconcat ["rgba(", p r, ",", p g, ",", p b, ",", ah a, ")"]- Hsla h s l 1.0 -> Value $mconcat ["hsl(", p h, ",", f s, ",", f l, ")"]- Hsla h s l a -> Value $mconcat ["hsla(", p h, ",", f s, ",", f l, ",", ah a, ")"]+ Rgba r g b 1.0 -> Value $ mconcat ["#", p' r, p' g, p' b]+ Rgba r g b a -> Value $ mconcat ["rgba(", p r, ",", p g, ",", p b, ",", ah a, ")"]+ Hsla h s l 1.0 -> Value $ mconcat ["hsl(", p h, ",", f s, ",", f l, ")"]+ Hsla h s l a -> Value $ mconcat ["hsla(", p h, ",", f s, ",", f l, ",", ah a, ")"] Other o -> o where p = fromString . show p' = fromString . printf "%02x"
src/Clay/Comments.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE OverloadedStrings #-} module Clay.Comments where -import Data.Monoid ((<>)) import Data.Maybe (isNothing) import Data.List (partition)
src/Clay/Common.hs view
@@ -9,23 +9,26 @@ module Clay.Common where +import Data.Text (Text) import Clay.Property import Data.String (IsString)-import Data.Monoid (Monoid, (<>)) ------------------------------------------------------------------------------- -class All a where all :: a-class Auto a where auto :: a-class Baseline a where baseline :: a-class Center a where center :: a-class Inherit a where inherit :: a-class None a where none :: a-class Normal a where normal :: a-class Visible a where visible :: a-class Hidden a where hidden :: a-class Initial a where initial :: a-class Unset a where unset :: a+class All a where all :: a+class Auto a where auto :: a+class Baseline a where baseline :: a+class Center a where center :: a+class Inherit a where inherit :: a+class None a where none :: a+class Normal a where normal :: a+class Visible a where visible :: a+class Hidden a where hidden :: a+class Initial a where initial :: a+class Unset a where unset :: a+class Contain a where contain :: a+class Revert a where revert :: a+class RevertLayer a where revertLayer :: a -- | The other type class is used to escape from the type safety introduced by -- embedding CSS properties into the typed world of Clay. `Other` allows you to@@ -55,32 +58,53 @@ initialValue = "initial" unsetValue :: Value unsetValue = "unset"+containValue :: Value+containValue = "contain"+revertValue :: Value+revertValue = "revert"+revertLayerValue :: Value+revertLayerValue = "revert-layer" -instance All Value where all = allValue-instance Auto Value where auto = autoValue-instance Baseline Value where baseline = baselineValue-instance Center Value where center = centerValue-instance Inherit Value where inherit = inheritValue-instance Normal Value where normal = normalValue-instance None Value where none = noneValue-instance Visible Value where visible = visibleValue-instance Hidden Value where hidden = hiddenValue-instance Other Value where other = id-instance Initial Value where initial = initialValue-instance Unset Value where unset = unsetValue+instance All Value where all = allValue+instance Auto Value where auto = autoValue+instance Baseline Value where baseline = baselineValue+instance Center Value where center = centerValue+instance Inherit Value where inherit = inheritValue+instance Normal Value where normal = normalValue+instance None Value where none = noneValue+instance Visible Value where visible = visibleValue+instance Hidden Value where hidden = hiddenValue+instance Other Value where other = id+instance Initial Value where initial = initialValue+instance Unset Value where unset = unsetValue+instance Contain Value where contain = containValue+instance Revert Value where revert = revertValue+instance RevertLayer Value where revertLayer = revertLayerValue ------------------------------------------------------------------------------- -- | Common list browser prefixes to make experimental properties work in -- different browsers. +webkitPrefix :: (Text, Text)+webkitPrefix = ( "-webkit-", "" )++emptyPrefix :: (Text, Text)+emptyPrefix = ( "", "" )++webkit :: Prefixed+webkit = Prefixed $+ [ webkitPrefix+ , emptyPrefix+ ]+ browsers :: Prefixed-browsers = Prefixed- [ ( "-webkit-", "" )- , ( "-moz-", "" )- , ( "-ms-", "" )- , ( "-o-", "" )- , ( "", "" )+browsers = Prefixed $+ [ webkitPrefix+ , ( "-moz-", "" )+ , ( "-ms-", "" )+ , ( "-o-", "" )+ , emptyPrefix ] -------------------------------------------------------------------------------
src/Clay/Display.hs view
@@ -17,7 +17,7 @@ , Position , position-, static, absolute, fixed, relative+, static, absolute, fixed, relative, sticky -- * Display @@ -34,6 +34,15 @@ , scroll , overflow, overflowX, overflowY +-- * Overscroll+, Overscroll+, overscrollBehavior+, overscrollBehavior2+, overscrollBehaviorX+, overscrollBehaviorY+, overscrollBehaviorBlock+, overscrollBehaviorInline+ -- * Visibility. , Visibility@@ -70,19 +79,24 @@ -- * Cursor , Cursor(..)-, crosshair, cursorDefault, pointer, move, eResize, neResize, nwResize, nResize, seResize, swResize, sResize, wResize, cursorText, wait, cursorProgress, help, cursorUrl-+, cursorUrl+, cursorDefault+, contextMenu, help, pointer, cursorProgress, wait+, cell, crosshair, cursorText, vText+, alias, cursorCopy, move, noDrop, notAllowed, grab, grabbing+, allScroll, colResize, rowResize, nResize, eResize, sResize, wResize+, neResize, nwResize, seResize, swResize, ewResize, nsResize, neswResize, nwseResize+, zoomIn, zoomOut ) where -import Data.Monoid import Data.String import Clay.Size import Clay.Property import Clay.Stylesheet import Clay.Common-import Data.Text (Text) +import Data.Text (Text) ------------------------------------------------------------------------------- @@ -116,12 +130,13 @@ newtype Position = Position Value deriving (Val, Other, Inherit) -static, absolute, fixed, relative :: Position+static, absolute, fixed, relative, sticky :: Position static = Position "static" absolute = Position "absolute" fixed = Position "fixed" relative = Position "relative"+sticky = Position $ Value (webkit <> Plain "sticky") position :: Position -> Css position = key "position"@@ -179,8 +194,32 @@ ------------------------------------------------------------------------------- +newtype Overscroll = Overscroll Value+ deriving (Val, Other, None, Auto, Contain, Inherit, Initial, Unset, Revert, RevertLayer)++-- | Specify both X and Y overscroll at once+overscrollBehavior :: Overscroll -> Css+overscrollBehavior = key "overscroll-behavior"++overscrollBehavior2 :: Overscroll -> Overscroll -> Css+overscrollBehavior2 x y = key "overscroll-behavior" (x ! y)++overscrollBehaviorX :: Overscroll -> Css+overscrollBehaviorX = key "overscroll-behavior-x"++overscrollBehaviorY :: Overscroll -> Css+overscrollBehaviorY = key "overscroll-behavior-y"++overscrollBehaviorBlock :: Overscroll -> Css+overscrollBehaviorBlock = key "overscroll-behavior-block"++overscrollBehaviorInline :: Overscroll -> Css+overscrollBehaviorInline = key "overscroll-behavior-inline"++-------------------------------------------------------------------------------+ newtype Visibility = Visibility Value- deriving (Val, Other, Auto, Inherit, Hidden, Visible)+ deriving (Val, Other, Inherit, Hidden, Unset, Visible) separate, collapse :: Visibility @@ -203,7 +242,7 @@ ------------------------------------------------------------------------------- -opacity :: Double -> Css+opacity :: Number -> Css opacity = key "opacity" zIndex :: Integer -> Css@@ -239,7 +278,7 @@ instance VerticalAlign VerticalAlignValue instance VerticalAlign (Size a) -middle,vAlignSub,vAlignSuper,textTop,textBottom,vAlignTop,vAlignBottom,vAlignBaseline :: VerticalAlignValue +middle,vAlignSub,vAlignSuper,textTop,textBottom,vAlignTop,vAlignBottom,vAlignBaseline :: VerticalAlignValue middle = VerticalAlignValue "middle" vAlignSub = VerticalAlignValue "sub"@@ -250,34 +289,71 @@ vAlignTop = VerticalAlignValue "top" vAlignBottom = VerticalAlignValue "bottom" -------------------------------------------------------------------------------- +------------------------------------------------------------------------------- class (Val a) => Cursor a where cursor :: a -> Css cursor = key "cursor" -newtype CursorValue a = CursorValue Value deriving (Val,Inherit,Auto)+newtype CursorValue a = CursorValue Value deriving (Val,Inherit,Auto,None) instance Cursor (CursorValue a) -crosshair,cursorDefault,pointer,move,eResize,neResize,nwResize,nResize,seResize,swResize,sResize,wResize,cursorText,wait,cursorProgress,help :: CursorValue Value- -crosshair = CursorValue "crosshair"+cursorUrl :: Text -> CursorValue Value+cursorUrl u = CursorValue $ value ("url(\"" <> u <> "\")")++-- Using the classification from https://developer.mozilla.org/en-US/docs/Web/CSS/cursor+cursorDefault+ , contextMenu, help, pointer, cursorProgress, wait+ , cell, crosshair, cursorText, vText+ , alias, cursorCopy, move, noDrop, notAllowed, grab, grabbing+ , allScroll, colResize, rowResize, nResize, eResize, sResize, wResize+ , neResize, nwResize, seResize, swResize, ewResize, nsResize, neswResize, nwseResize+ , zoomIn, zoomOut :: CursorValue Value++-- General cursorDefault = CursorValue "default"++-- Links & status+contextMenu = CursorValue "context-menu"+help = CursorValue "help" pointer = CursorValue "pointer"+cursorProgress = CursorValue "progress"+wait = CursorValue "wait"++-- Selection+cell = CursorValue "cell"+crosshair = CursorValue "crosshair"+cursorText = CursorValue "text"+vText = CursorValue "vertical-text"++-- Drag & drop+alias = CursorValue "alias"+cursorCopy = CursorValue "copy" move = CursorValue "move"+noDrop = CursorValue "no-drop"+notAllowed = CursorValue "not-allowed"+grab = CursorValue "grab"+grabbing = CursorValue "grabbing"++-- Resizing & scrolling+allScroll = CursorValue "all-scroll"+colResize = CursorValue "col-resize"+rowResize = CursorValue "row-resize"+nResize = CursorValue "n-resize" eResize = CursorValue "e-resize"+sResize = CursorValue "s-resize"+wResize = CursorValue "w-resize"+ neResize = CursorValue "ne-resize" nwResize = CursorValue "nw-resize"-nResize = CursorValue "n-resize" seResize = CursorValue "se-resize" swResize = CursorValue "sw-resize"-sResize = CursorValue "s-resize"-wResize = CursorValue "w-resize"-cursorText = CursorValue "text"-wait = CursorValue "wait"-cursorProgress = CursorValue "progress"-help = CursorValue "help"+ewResize = CursorValue "ew-resize"+nsResize = CursorValue "ns-resize"+neswResize = CursorValue "nesw-resize"+nwseResize = CursorValue "nwse-resize" -cursorUrl :: Text -> CursorValue Value-cursorUrl u = CursorValue $ value ("url(\"" <> u <> "\")")+-- Zooming+zoomIn = CursorValue "zoom-in"+zoomOut = CursorValue "zoom-out"
src/Clay/Filter.hs view
@@ -52,7 +52,7 @@ blur :: Size LengthUnit -> Filter blur i = Filter ("blur(" <> value i <> ")") -brightness :: Double -> Filter+brightness :: Number -> Filter brightness i = Filter ("brightness(" <> value i <> ")") contrast :: Size Percentage -> Filter
src/Clay/Flexbox.hs view
@@ -14,19 +14,21 @@ class FlexStart a where flexStart :: a class SpaceAround a where spaceAround :: a class SpaceBetween a where spaceBetween :: a+class SpaceEvenly a where spaceEvenly :: a class Stretch a where stretch :: a instance FlexEnd Value where flexEnd = "flex-end" instance FlexStart Value where flexStart = "flex-start" instance SpaceAround Value where spaceAround = "space-around" instance SpaceBetween Value where spaceBetween = "space-between"+instance SpaceEvenly Value where spaceEvenly = "space-evenly" instance Stretch Value where stretch = "stretch" ------------------------------------------------------------------------------- newtype AlignContentValue = AlignContentValue Value deriving (Val, Other, Inherit, FlexStart, FlexEnd- , Center, SpaceBetween, SpaceAround, Stretch)+ , Center, SpaceBetween, SpaceAround, SpaceEvenly, Stretch) alignContent :: AlignContentValue -> Css alignContent = key "align-content"@@ -107,7 +109,7 @@ newtype JustifyContentValue = JustifyContentValue Value deriving (Val, Other, Inherit, Center, FlexEnd- , FlexStart, SpaceAround, SpaceBetween)+ , FlexStart, SpaceAround, SpaceBetween, SpaceEvenly, Stretch) justifyContent :: JustifyContentValue -> Css justifyContent = key "justify-content"
src/Clay/Font.hs view
@@ -102,7 +102,8 @@ [GenericFontFamily] instance Val (Required a) where- value (Required a Nothing c d) = value (a ! (Literal <$> c) ! d)+ value (Required a Nothing c d) = value a <> " " <> (value $ Literal <$> c) <> sep <> value d+ where sep = if null c || null d then "" else "," value (Required a (Just b) c d) = value ((value a <> "/" <> value b) ! (Literal <$> c) ! d) instance Font ( Required a)
src/Clay/FontFace.hs view
@@ -9,8 +9,6 @@ import Clay.Property (Prefixed (Plain), Value(Value), Val (value), quote) import Clay.Stylesheet (Css, key) -import Data.Monoid ((<>))-import Data.Functor ((<$>)) import Data.Maybe (fromMaybe) import Data.Text (Text)
src/Clay/Geometry.hs view
@@ -7,6 +7,12 @@ -- * Sizing. , width, height, minWidth, minHeight, maxWidth, maxHeight +-- ** Aspect ratio.+, AspectRatio+, aspectRatio+, (%)+, withFallback+ -- * Padding. , padding , paddingTop, paddingLeft, paddingRight, paddingBottom@@ -17,6 +23,9 @@ ) where +import qualified Data.Ratio as R+import Data.String (fromString)+import Clay.Common import Clay.Property import Clay.Stylesheet import Clay.Size@@ -42,6 +51,100 @@ ------------------------------------------------------------------------------- +-- | Represents an aspect ratio for use with 'aspectRatio'.+--+-- A fixed ratio can be formed from two integers:+--+-- >>> let _ = 4%3 :: AspectRatio+--+-- An aspect ratio can also be converted from a 'Rational':+--+-- >>> let _ = fromRational 0.5 :: AspectRatio+--+data AspectRatio = AspectRatio Rational+ | AspectRatioValue Value+ | AspectRatioWithFallback (AspectRatio, AspectRatio)++instance Auto AspectRatio where auto = AspectRatioValue auto+instance Inherit AspectRatio where inherit = AspectRatioValue inherit+instance Initial AspectRatio where initial = AspectRatioValue initial+instance Unset AspectRatio where unset = AspectRatioValue unset+instance Other AspectRatio where other = AspectRatioValue++-- | An 'AspectRatio' can be converted from an 'Integer',+-- but other operations are not supported.+instance Num AspectRatio where+ fromInteger = AspectRatio . toRational+ (+) = error "plus not implemented for AspectRatio"+ (*) = error "times not implemented for AspectRatio"+ abs = error "abs not implemented for AspectRatio"+ signum = error "signum not implemented for AspectRatio"+ negate = error "negate not implemented for AspectRatio"++-- | An 'AspectRatio' can be converted from a 'Rational',+-- but other operations are not supported.+instance Fractional AspectRatio where+ fromRational = AspectRatio+ recip = error "recip not implemented for AspectRatio"++instance Val AspectRatio where+ value (AspectRatioValue v) = v+ value (AspectRatio r) = v+ where v = fromString $ numerator <> "/" <> denominator :: Value+ numerator = show (R.numerator r)+ denominator = show (R.denominator r)+ value (AspectRatioWithFallback (a, b)) = value a <> " " <> value b++-- | Defines the width to height ratio of an element.+-- At least one of the width or height must be of automatic size,+-- otherwise the aspect ratio will be ignored.+--+-- It can be given a fixed ratio of the width to the height:+--+-- >>> renderWith compact [] $ aspectRatio (4%3)+-- "{aspect-ratio:4/3}"+--+-- It can also be the intrinsic aspect ratio for the element:+--+-- >>> renderWith compact [] $ aspectRatio auto+-- "{aspect-ratio:auto}"+--+-- It can be told to use the intrinsic aspect ratio for the element,+-- but to use a fixed ratio while it is unknown or if the element does not have one:+--+-- >>> renderWith compact [] $ aspectRatio $ auto `withFallback` (4%3)+-- "{aspect-ratio:auto 4/3}"+--+-- Corresponds to the+-- [@aspect-ratio@](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio)+-- property in CSS.+aspectRatio :: AspectRatio -> Css+aspectRatio = key "aspect-ratio"++-- | The aspect ratio of the width to the height for use with 'aspectRatio'.+--+-- Note that this is /not/ the same @%@ operator from the "Data.Ratio" module,+-- although they do both semantically represent ratios. The same symbol is used+-- to signify that the return value is a ratio.+(%) :: Integer -> Integer -> AspectRatio+(%) m n = fromRational $ (R.%) m n++-- The same as the normal % operator.+infixl 7 %++-- | Returns an aspect ratio specifying that the intrinsic aspect+-- ratio should be used, but when it is unknown or there is none,+-- a fixed ratio can be used as a fallback.+withFallback :: AspectRatio -> AspectRatio -> AspectRatio+withFallback x@(AspectRatioValue "auto") y@(AspectRatio _) =+ AspectRatioWithFallback (x, y)+withFallback x@(AspectRatio _) y@(AspectRatioValue "auto") =+ AspectRatioWithFallback (x, y)+withFallback _ _ =+ error "Arguments for aspectRatio . withFallback must be auto and a ratio in either order"++-------------------------------------------------------------------------------+ padding :: Size a -> Size a -> Size a -> Size a -> Css padding a b c d = key "padding" (a ! b ! c ! d) @@ -63,4 +166,3 @@ marginLeft = key "margin-left" marginRight = key "margin-right" marginBottom = key "margin-bottom"-
src/Clay/Gradient.hs view
@@ -36,8 +36,6 @@ ) where -import Data.Monoid- import Clay.Color import Clay.Common import Clay.Property
+ src/Clay/Grid.hs view
@@ -0,0 +1,775 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ExtendedDefaultRules #-}+{-# OPTIONS_GHC -Wno-type-defaults #-}++-- | Partial implementation of+-- | <https://alligator.io/css/css-grid-layout-grid-areas grid area CSS API>.+module Clay.Grid+(+ -- * Grid+ --+ -- $gridIntro+ gridGap+ , gridTemplateColumns++ -- * Size and location+ --+ -- $sizeAndLocationIntro++ -- ** Data types and type classes+ , GridLine+ , ToGridLine+ , GridLines2+ , ToGridLines2+ , GridLines4+ , ToGridLines4+ , OneGridLine+ , TwoGridLines+ , ThreeGridLines+ , FourGridLines+ , CustomIdentGrid+ , customIdentToText+ , partialMkCustomIdentGrid+ , ToSpan++ -- ** Style properties+ --+ -- $invalidValues+ , gridArea+ , gridColumn+ , gridColumnStart+ , gridColumnEnd+ , gridRow+ , gridRowStart+ , gridRowEnd++ -- ** Keywords+ , (//)+ , span_+)+where++import qualified Clay.Common as Com+import Clay.Property (Val, Value, noCommas, value)+import Clay.Size (Size)+import Clay.Stylesheet (Css, key)+import Data.Char (isNumber)+import Data.Text (Text)+import qualified Data.Text as T+import Prelude++-- $gridIntro+-- @grid-gap@ and @grid-template@ CSS properties.+--+-- === Example+-- For the below CSS code:+--+-- @+-- .grid1 {+-- display: grid;+-- width: max-content;+-- }+--+-- .grid3 {+-- display: grid;+-- width: max-content;+-- }+--+-- \@media (min-width: 40.0rem) {+-- .grid3 {+-- display: grid;+-- grid-template-columns: 1fr 1fr 1fr;+-- grid-gap: 1rem;+-- width: max-content;+-- }+-- }+-- @+--+-- The corresponding clay code is:+--+-- @+-- ".grid1" ? do+-- display grid+-- width maxContent+-- ".grid3" ? do+-- display grid+-- width maxContent+-- query M.screen [M.minWidth (rem 40)] $ ".grid3" ? do+-- display grid+-- gridTemplateColumns [fr 1, fr 1, fr 1]+-- gridGap $ rem 1+-- width maxContent+-- @++-- | Property sets the gaps (gutters) between rows and columns.+gridGap :: Size a -> Css+gridGap = key "grid-gap"++-- | Property defines the line names and track sizing functions of the grid columns.+gridTemplateColumns :: [Size a] -> Css+gridTemplateColumns = key "grid-template-columns" . noCommas++-- $sizeAndLocationIntro+--+-- == CSS documentation+-- The below functions are based on+-- [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS)+-- CSS documentation.+--+-- === __Naming note__+-- In this documentation, as the functions are polymorphic we sometimes+-- refer to the CSS types as used in the+-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS)+-- rather than the Haskell types.+-- For example, @grid-line@ is used instead of 'GridLine' as a the argument+-- might be provided as a 'GridLine' but also as an 'Integer', 'String', etc.+--+-- == Pragma+-- #pragma#+-- If you want to avoid specifying the types of the arguments, enable+-- the @ExtendedDefaultRules@ GHC language pragma as well as the+-- @-Wno-type-defaults@ GHC option to avoid compilation warnings.+--+-- @+-- {-# LANGUAGE ExtendedDefaultRules #-}+-- {-# OPTIONS_GHC -Wno-type-defaults #-}+-- @+--+-- === __Examples__+-- With the above enabled, you can write:+--+-- >> gridRowStart 2+--+-- >> gridRowStart "somegridarea"+--+-- If you do not enable those, then you must write:+--+-- >> gridRowStart (2 :: Integer)+--+-- >> gridRowStart ("somegridarea" :: String)+--+-- === __Note__+-- If you decide to enable the above, it is advisable to have your Clay+-- CSS code in its own module, so the behaviour of the rest of your code+-- is not affected.+--+-- == Examples+-- Examples are provided through the documentation for the various functions.+-- Further examples can be found in the source code of the test suite+-- in the GridSpec.hs module.++-- | A @grid-line@ value.+--+-- A @grid-line@ value specifies a size and location in a grid.+--+-- === __Note__+-- To know more about @grid-line@ value, see for example the documentation of+-- the [grid-row-start](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row-start)+-- CSS property.+data GridLine++ -- | 'Integer' value.+ --+ -- __NOTE:__ 'Integer' value of 0 is invalid.+ = Coordinate Integer++ -- | @custom-ident@ with an optional 'Integer' value.+ --+ -- __NOTE:__ 'Integer' value of 0 is invalid.+ | GridLineCustomIdent CustomIdentGrid (Maybe Integer)++ -- | @span@ CSS keyword with an optional @custom-ident@+ -- | and/or 'Integer' value.+ --+ -- __NOTE:__ negative 'Integer' or 0 are invalid.+ | Span (Maybe CustomIdentGrid) (Maybe Integer)++ -- | Other grid line values: @auto@, @inherit@, @initial@, @unset@.+ | OtherGridLine Value+ deriving (Eq, Show)++class ToGridLine a where+ -- | Convert the provided type to a 'GridLine'.+ toGridLine :: a -> GridLine++instance ToGridLine GridLine where+ toGridLine = id++instance ToGridLine Integer where+ -- | __NOTE:__ 'Integer' value of 0 is invalid.+ toGridLine = Coordinate++-- | @custom-ident@ value.+instance ToGridLine CustomIdentGrid where+ toGridLine x = GridLineCustomIdent x Nothing++-- | @custom-ident@ value.+instance ToGridLine String where+ toGridLine = toGridLine . partialMkCustomIdentGrid . T.pack++-- | Both @custom-ident@ and `Integer` values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLine (CustomIdentGrid, Integer) where+ toGridLine (x, y) = GridLineCustomIdent x (Just y)++-- | Both @custom-ident@ and `Integer` values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLine (String, Integer) where+ toGridLine (x, y) = toGridLine (partialMkCustomIdentGrid $ T.pack x, y)++-- | One or two @grid-line@ values.+data GridLines2+ -- | One @grid-line@ value.+ = One2 OneGridLine+ -- | Two @grid-line@ values.+ | Two2 TwoGridLines++class ToGridLines2 a where++ -- | Convert the provided type to 'GridLines2' (one or two @grid-line@ values).+ toGridLines2 :: a -> GridLines2++-- | One @grid-line@ value.+instance ToGridLines2 GridLine where+ toGridLines2 = One2 . OneGridLine++-- | One @grid-line@ value.+instance ToGridLines2 OneGridLine where+ toGridLines2 = One2++-- | Two @grid-line@ values.+instance ToGridLines2 TwoGridLines where+ toGridLines2 = Two2++-- | One or two @grid-line@ values.+instance ToGridLines2 GridLines2 where+ toGridLines2 = id++-- | One 'Integer' value.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines2 Integer where+ toGridLines2 = toGridLines2 . toGridLine++-- | One @custom-ident@ value.+instance ToGridLines2 CustomIdentGrid where+ toGridLines2 = toGridLines2 . toGridLine++-- | One @custom-ident@ value.+instance ToGridLines2 String where+ toGridLines2 = toGridLines2 . toGridLine++-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines2 (CustomIdentGrid, Integer) where+ toGridLines2 = toGridLines2 . toGridLine++-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines2 (String, Integer) where+ toGridLines2 = toGridLines2 . toGridLine++-- | One, two, three or four @grid-line@ values.+data GridLines4++ -- | One @grid-line@ value.+ = One4 OneGridLine++ -- | Two @grid-line@ values.+ | Two4 TwoGridLines++ -- | Three @grid-line@ values.+ | Three4 ThreeGridLines++ -- | Four @grid-line@ values.+ | Four4 FourGridLines++class ToGridLines4 a where+ -- | Convert the provided type to 'GridLines4'+ -- (one, two, three or four @grid-line@ values).+ toGridLines4 :: a -> GridLines4++-- | One @grid-line@ value.+instance ToGridLines4 GridLine where+ toGridLines4 = One4 . OneGridLine++-- | One @grid-line@ value.+instance ToGridLines4 OneGridLine where+ toGridLines4 = One4++-- | Two @grid-line@ values.+instance ToGridLines4 TwoGridLines where+ toGridLines4 = Two4++-- | Three @grid-line@ values.+instance ToGridLines4 ThreeGridLines where+ toGridLines4 = Three4++-- | Four @grid-line@ values.+instance ToGridLines4 FourGridLines where+ toGridLines4 = Four4++-- | One, two, three or four @grid-line@ values.+instance ToGridLines4 GridLines4 where+ toGridLines4 = id++-- | One 'Integer' value.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines4 Integer where+ toGridLines4 = toGridLines4 . toGridLine++-- | One @custom-ident@ value.+instance ToGridLines4 CustomIdentGrid where+ toGridLines4 = toGridLines4 . toGridLine++-- | One @custom-ident@ value.+instance ToGridLines4 String where+ toGridLines4 = toGridLines4 . toGridLine++-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines4 (CustomIdentGrid, Integer) where+ toGridLines4 = toGridLines4 . toGridLine++-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.+--+-- __NOTE:__ 'Integer' value of 0 is invalid.+instance ToGridLines4 (String, Integer) where+ toGridLines4 = toGridLines4 . toGridLine++-- | One 'GridLine' value.+newtype OneGridLine = OneGridLine GridLine++-- | Two 'GridLine' values.+data TwoGridLines = TwoGridLines GridLine GridLine++-- | Three 'GridLine' values.+data ThreeGridLines = ThreeGridLines GridLine GridLine GridLine++-- | Four 'GridLine' values.+data FourGridLines = FourGridLines GridLine GridLine GridLine GridLine++-- | CSS @custom-ident@.+--+-- The data constructor is not exported. Use the 'partialMkCustomIdentGrid'+-- smart constructor to create a 'CustomIdentGrid'.+--+-- === __Note__+-- In CSS, some values for @custom-ident@ are invalid depending on the CSS+-- property the @custom-ident@ is used with.+-- Consequently, the @custom-ident@ is only for CSS grid.+newtype CustomIdentGrid = CustomIdentGrid Text deriving (Eq, Ord, Read, Show)++-- | Convert a 'CustomIdentGrid' to 'Text'.+--+-- === __Note__+-- The function is defined on its own as the newtype constructor+-- of 'CustomIdentGrid'is not exported.+customIdentToText :: CustomIdentGrid -> Text+customIdentToText (CustomIdentGrid x) = x++-- | Create a 'CustomIdentGrid'.+--+-- __WARNING__: this function is partial. An error will be raised if:+--+-- * "span" is provided as a value (this is a reserved keyword in this context)+-- * a number is provided as first character+-- * __If__ a hyphen (-) is provided as first character:+--+-- ** a number is provided as second character+-- ** a hyphen (-) is provided as second character.+--+-- === __Note__+-- The above is a partial implementation of the CSS custom-ident naming rules.+-- If you stick to the following charset @[a-zA-z0-9-_]@ the checks will be effective+-- and your CSS custom-ident will be a valid one.+-- On the other hand, the following will not be checked:+--+-- * character escaping (for example @\?@) or unicode+-- * characters provided as hexadecimal number (for example @\0x03BB@)+-- * characters outside of the above charset.+--+-- More information regarding this topic can be found on+-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)+partialMkCustomIdentGrid :: Text -> CustomIdentGrid+partialMkCustomIdentGrid "span" = error "Custom-ident for a grid property cannot be named span"+partialMkCustomIdentGrid txt = checkText+ where+ checkText = checkHead (fst unconsTxt)++ checkHead :: Char -> CustomIdentGrid+ checkHead c+ | isNumber c = error "Custom-ident cannot start with a number"+ | c == '-' = checkSecond second+ | otherwise = CustomIdentGrid txt++ checkSecond (Just s)+ | s == '-' =+ error "Custom-ident cannot start with two hyphens"+ | isNumber s =+ error "Custom-ident cannot start with a hyphen followed by a number"+ | otherwise = CustomIdentGrid txt+ checkSecond Nothing = CustomIdentGrid txt++ unconsTxt = case T.uncons txt of+ Nothing -> error "Custom-ident cannot be empty"+ Just (f, r) -> (f, r)++ second :: Maybe Char+ second = fst <$> T.uncons (snd unconsTxt)++-- $invalidValues+--+-- #partial#+-- The below functions are partial. They will raise an error if+-- provided with a @grid-line@ value which is:+--+-- * an 'Integer' value of 0+-- * a pair with an 'Integer' component of value 0+-- * a 'span_' function provided with an 'Integer' value of 0 or negative+-- * a 'span_' function provided with a pair value with+-- an 'Integer' component of 0 or negative.+-- * an invalid @custom-ident@ value, see 'partialMkCustomIdentGrid'.++-- | Property shorthand specifies a grid item's size and location+-- within a grid.+--+-- One to four @grid-line@ values can be specified.+-- Grid-line values must be separated by a '(//)' operator.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridArea (auto :: GridLine)+--+-- > gridArea "somegridarea"+--+-- > gridArea $ ("somegridarea", 4) // ("someothergridarea", 2)+--+-- > gridArea $ 1 // 3 // 4+gridArea :: ToGridLines4 a => a -> Css+gridArea x = key "grid-area" (partialToGridLines4 x)++-- | Property shorthand specifies a grid item's size and location+-- within a grid column.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridColumn (auto :: GridLine)+--+-- > gridColumn $ span_ 3+--+-- > gridColumn $ span_ ("somegridarea", 5)+--+-- > gridColumn $ span_ 3 // 6+gridColumn :: ToGridLines2 a => a -> Css+gridColumn x = key "grid-column" (partialToGridLines2 x)++-- | Property specifies a grid item's start position within the grid column.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridColumnStart (inherit :: GridLine)+--+-- > gridColumnStart 2+--+-- > gridColumnStart ("somegridarea", 4)+--+-- > gridColumnStart $ span_ ("somegridarea", 5)+gridColumnStart :: ToGridLine a => a -> Css+gridColumnStart x = key "grid-column-start" (partialToGridLine x)++-- | Property specifies a grid item's end position within the grid column.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridColumnEnd (initial :: GridLine)+--+-- > gridColumnEnd 2+--+-- > gridColumnEnd "somegridarea"+--+-- > gridColumnEnd $ span_ "somegridarea"+gridColumnEnd :: ToGridLine a => a -> Css+gridColumnEnd x = key "grid-column-end" (partialToGridLine x)++-- | Property shorthand specifies a grid item's size and location+-- within a grid row.+--+-- One or two @grid-line@ values can be specified.+-- @grid-line@ values must be separated by a '(//)' operator.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridRow (unset :: GridLine)+--+-- > gridRow $ span_ 3+--+-- > gridRow $ span_ 3 // 6+--+-- > gridRow $ span_ ("somegridarea", 5) // span_ 2+gridRow :: ToGridLines2 a => a -> Css+gridRow x = key "grid-row" (partialToGridLines2 x)++-- | Property specifies a grid item's start position within the grid row.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridRowStart (initial :: GridLine)+--+-- > gridRowStart (-2)+--+-- > gridRowStart $ span_ "somegridarea"+--+-- > gridRowStart "somegridarea"+gridRowStart :: ToGridLine a => a -> Css+gridRowStart x = key "grid-row-start" (partialToGridLine x)++-- | Property specifies a grid item's end position within the grid row.+--+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".+--+-- ==== __Examples__+--+-- The below examples assume that the @ExtendedDefaultRules@ GHC language+-- pragma is enabled. See above "Clay.Grid#pragma".+--+-- > gridRowEnd (auto :: GridLine)+--+-- > gridRowEnd (-2)+--+-- > gridRowEnd ("somegridarea", 4)+--+-- > gridRowEnd $ span_ 3+gridRowEnd :: ToGridLine a => a -> Css+gridRowEnd x = key "grid-row-end" (partialToGridLine x)++class Slash a r | a -> r where+ -- | `/` CSS operator.+ -- Separates @grid-line@ values.+ (//) :: ToGridLine b => a -> b -> r++instance Slash GridLine TwoGridLines where+ x // y = TwoGridLines x (toGridLine y)++instance Slash Integer TwoGridLines where+ x // y = TwoGridLines (toGridLine x) (toGridLine y)++instance Slash CustomIdentGrid TwoGridLines where+ x // y = TwoGridLines (toGridLine x) (toGridLine y)++instance Slash String TwoGridLines where+ x // y = TwoGridLines (toGridLine x) (toGridLine y)++instance Slash (CustomIdentGrid, Integer) TwoGridLines where+ x // y = TwoGridLines (toGridLine x) (toGridLine y)++instance Slash (String, Integer) TwoGridLines where+ x // y = TwoGridLines (toGridLine x) (toGridLine y)++instance Slash TwoGridLines ThreeGridLines where+ (TwoGridLines xx xy) // y = ThreeGridLines xx xy (toGridLine y)++instance Slash ThreeGridLines FourGridLines where+ (ThreeGridLines xx xy xz) // y = FourGridLines xx xy xz (toGridLine y)++class ToSpan a where++ -- | @span@ CSS keyword, contributes to the grid item's placement.+ span_ :: a -> GridLine++-- | Contributes the nth grid line to the grid item's placement.+--+-- __NOTE:__ negative 'Integer' or 0 values are invalid.+instance ToSpan Integer where+ span_ x = Span Nothing (Just x)++-- | One line from the provided name is counted.+instance ToSpan String where+ span_ x = Span (Just . partialMkCustomIdentGrid $ T.pack x) Nothing++-- | Nth lines from the provided name are counted.+--+-- __NOTE:__ negative 'Integer' or 0 values are invalid.+instance ToSpan (String, Integer) where+ span_ (x, y) = Span (Just . partialMkCustomIdentGrid $ T.pack x) (Just y)++-- | Keyword indicating that the property contributes nothing+-- to the grid item's placement.+instance Com.Auto GridLine where+ auto = OtherGridLine $ value ("auto" :: Text)++-- | Keyword `inherit` applied to a 'GridLine'.+instance Com.Inherit GridLine where+ inherit = OtherGridLine $ value ("inherit" :: Text)++-- | Keyword `initial` applied to a 'GridLine'.+instance Com.Initial GridLine where+ initial = OtherGridLine $ value ("initial" :: Text)++-- | Keyword `unset` applied to a 'GridLine'.+instance Com.Unset GridLine where+ unset = OtherGridLine $ value ("unset" :: Text)++-- | Convertion of 'GridLine' to 'Clay.Property.Value'.+instance Val GridLine where+ value (OtherGridLine val) = val+ value (Coordinate x) = value x+ value (GridLineCustomIdent x y) =+ value $ customIdentToText x <> foldMap ((" " <>) . tshow) y+ value (Span x y) =+ value $ "span" <> foldMap ((" " <>)+ . customIdentToText) x <> foldMap ((" " <>) . tshow) y++instance Val OneGridLine where+ value (OneGridLine x) = value x++instance Val TwoGridLines where+ value (TwoGridLines x y) =+ value x <> value (" / " :: Text) <> value y++instance Val ThreeGridLines where+ value (ThreeGridLines x y z) =+ value x+ <> value (" / " :: Text) <> value y+ <> value (" / " :: Text) <> value z++instance Val FourGridLines where+ value (FourGridLines xx xy xz yx) =+ value xx+ <> value (" / " :: Text) <> value xy+ <> value (" / " :: Text) <> value xz+ <> value (" / " :: Text) <> value yx++instance Val GridLines2 where+ value (One2 x) = value x+ value (Two2 x) = value x++instance Val GridLines4 where+ value (One4 x) = value x+ value (Two4 x) = value x+ value (Three4 x) = value x+ value (Four4 x) = value x++-- | Private partial function checking a 'GridLine'.+--+-- An error is raised when:+-- - An 'Integer' value of 0 is provided.+-- - A negative 'Integer' value is provided for a 'Span' constructor.+--+-- Otherwise, the initially provided 'GridLine' value is returned.+partialCheckGridLine :: GridLine -> GridLine+partialCheckGridLine gridLine = case gridLine of+ Coordinate 0 -> errorValue 0+ GridLineCustomIdent _ (Just 0) -> errorValue 0+ s@(Span _ (Just n)) -> if n < 1+ then errorValue n+ else s+ _ -> gridLine+ where+ errorValue n = error ("Value " ++ show n ++ " is invalid")++-- | Private partial function checking 'OneGridLine'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialCheckOneGridLine :: OneGridLine -> OneGridLine+partialCheckOneGridLine (OneGridLine gridLine) =+ OneGridLine (partialCheckGridLine gridLine)++-- | Private partial function checking 'TwoGridLines'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialCheckTwoGridLines :: TwoGridLines -> TwoGridLines+partialCheckTwoGridLines (TwoGridLines gridLine1 gridLine2) =+ TwoGridLines (partialCheckGridLine gridLine1) (partialCheckGridLine gridLine2)++-- | Private partial function checking 'ThreeGridLines'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialCheckThreeGridLines :: ThreeGridLines -> ThreeGridLines+partialCheckThreeGridLines (ThreeGridLines gridLine1 gridLine2 gridLine3) =+ ThreeGridLines+ (partialCheckGridLine gridLine1)+ (partialCheckGridLine gridLine2)+ (partialCheckGridLine gridLine3)++-- | Private partial function checking 'FourGridLines'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialCheckFourGridLines :: FourGridLines -> FourGridLines+partialCheckFourGridLines+ (FourGridLines gridLine1 gridLine2 gridLine3 gridLine4) =+ FourGridLines+ (partialCheckGridLine gridLine1)+ (partialCheckGridLine gridLine2)+ (partialCheckGridLine gridLine3)+ (partialCheckGridLine gridLine4)++-- | Private partial function converting its argument to 'GridLine'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialToGridLine :: ToGridLine a => a -> GridLine+partialToGridLine = partialCheckGridLine . toGridLine++-- | Private partial function converting its argument to 'GridLines2'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialToGridLines2 :: ToGridLines2 a => a -> GridLines2+partialToGridLines2 x = partialGridLine' gridLines+ where+ gridLines = toGridLines2 x+ partialGridLine' (One2 gl) = One2 (partialCheckOneGridLine gl)+ partialGridLine' (Two2 gl) = Two2 (partialCheckTwoGridLines gl)++-- | Private partial function converting its argument to 'GridLines4'.+--+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.+partialToGridLines4 :: ToGridLines4 a => a -> GridLines4+partialToGridLines4 x = partialGridLine' gridLines+ where+ gridLines = toGridLines4 x+ partialGridLine' (One4 gl) = One4 (partialCheckOneGridLine gl)+ partialGridLine' (Two4 gl) = Two4 (partialCheckTwoGridLines gl)+ partialGridLine' (Three4 gl) = Three4 (partialCheckThreeGridLines gl)+ partialGridLine' (Four4 gl) = Four4 (partialCheckFourGridLines gl)++-- | Private utility function to show 'Text' instead of 'String'.+tshow :: Show a => a -> Text+tshow = T.pack . show
src/Clay/List.hs view
@@ -36,7 +36,6 @@ ) where -import Data.Monoid import Data.Text (Text) import Clay.Common@@ -75,7 +74,7 @@ listStyleType = key "list-style-type" newtype ListStylePosition = ListStylePosition Value- deriving (Val, Initial, Inherit, None, Other)+ deriving (Val, Initial, Inherit, Other) inside, outside :: ListStylePosition
src/Clay/Mask.hs view
@@ -57,8 +57,6 @@ ) where -import Data.Monoid- import Clay.Background import Clay.Common import Clay.Property
src/Clay/Media.hs view
@@ -4,9 +4,13 @@ -- * Media types. - aural, braille, handheld, print, projection-, screen, tty, tv, embossed+ all, screen, print +-- ** Deprecated.++-- | These media types were deprecated by Media Queries 4.+, aural, braille, handheld, projection, tty, tv, embossed+ -- * Geometrical features. , width, minWidth, maxWidth, height, minHeight, maxHeight, deviceWidth@@ -33,6 +37,16 @@ , Resolution , dpi , dppx++-- * Preference related features.++, prefersColorScheme++-- ** Preference related values.++, ColorScheme+, light+, dark ) where@@ -40,7 +54,7 @@ import Data.Text (Text, pack) import Data.Monoid -import Clay.Common+import Clay.Common hiding (all) import Clay.Size import Clay.Property import Clay.Stylesheet@@ -49,14 +63,18 @@ ------------------------------------------------------------------------------- -aural, braille, handheld, print, projection+all, aural, braille, handheld, print, projection , screen, tty, tv, embossed :: MediaType +-- | Suitable for all devices.+all = MediaType "all" aural = MediaType "aural" braille = MediaType "braille" handheld = MediaType "handheld"+-- | Intended primarily for printed material or in a print layout. print = MediaType "print" projection = MediaType "projection"+-- | Intended primarily for screen-based devices. screen = MediaType "screen" tty = MediaType "tty" tv = MediaType "tv"@@ -132,3 +150,21 @@ dppx :: Integer -> Resolution dppx i = Resolution (value (pack (show i) <> "dppx")) +-------------------------------------------------------------------------------++-- | Feature detecting whether user prefers light or dark color scheme.+prefersColorScheme :: ColorScheme -> Feature+prefersColorScheme = with "prefers-color-scheme"++-- | A color scheme preferred by a user.+newtype ColorScheme = ColorScheme Value+ deriving (Val, Other)++-- | User indicates that they prefer a light theme with their interface,+-- or that they have not indicated a preference.+light :: ColorScheme+light = ColorScheme (value (pack "light"))++-- | User indicates that they prefer a dark theme with their interface.+dark :: ColorScheme+dark = ColorScheme (value (pack "dark"))
src/Clay/Property.hs view
@@ -2,7 +2,6 @@ module Clay.Property where import Control.Arrow (second)-import Control.Monad.Writer import Data.Fixed (Fixed, HasResolution (resolution), showFixed) import Data.List (partition, sort) import Data.List.NonEmpty (NonEmpty, toList)@@ -16,9 +15,12 @@ instance IsString Prefixed where fromString s = Plain (fromString s) +instance Semigroup Prefixed where+ (<>) = merge+ instance Monoid Prefixed where mempty = ""- mappend = merge+ mappend = (<>) merge :: Prefixed -> Prefixed -> Prefixed merge (Plain x ) (Plain y ) = Plain (x <> y)@@ -41,7 +43,7 @@ ------------------------------------------------------------------------------- newtype Key a = Key { unKeys :: Prefixed }- deriving (Show, Monoid, IsString)+ deriving (Show, Semigroup, Monoid, IsString) cast :: Key a -> Key () cast (Key k) = Key k@@ -49,7 +51,7 @@ ------------------------------------------------------------------------------- newtype Value = Value { unValue :: Prefixed }- deriving (Show, Monoid, IsString, Eq)+ deriving (Show, Semigroup, Monoid, IsString, Eq) class Val a where value :: a -> Value@@ -58,7 +60,7 @@ value t = Value (Plain t) newtype Literal = Literal Text- deriving (Show, Monoid, IsString)+ deriving (Show, Semigroup, Monoid, IsString) instance Val Literal where value (Literal t) = Value (Plain (quote t))@@ -69,15 +71,6 @@ data E5 = E5 instance HasResolution E5 where resolution _ = 100000 -instance Val Double where- value = Value . Plain . cssDoubleText--cssDoubleText :: Double -> Text-cssDoubleText = fromString . showFixed' . realToFrac- where- showFixed' :: Fixed E5 -> String- showFixed' = showFixed True- instance Val Value where value = id @@ -100,7 +93,20 @@ intercalate :: Monoid a => a -> [a] -> a intercalate _ [] = mempty-intercalate s (x:xs) = foldl (\a b -> a <> s <> b) x xs+intercalate s (x:xs) = foldl (\a b -> a `mappend` s `mappend` b) x xs++-------------------------------------------------------------------------------++-- | A number type to represent the CSS @number@ type.+-- It has fixed precision, supporting up to 5 decimal places.+newtype Number = Number { unNumber :: Fixed E5 }+ deriving (Enum, Eq, Fractional, Num, Ord, Read, Real, RealFrac, Show)++instance Val Number where+ value = Value . Plain . cssNumberText++cssNumberText :: Number -> Text+cssNumberText = fromString . showFixed True . unNumber -------------------------------------------------------------------------------
src/Clay/Pseudo.hs view
@@ -1,9 +1,11 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-} module Clay.Pseudo where import Data.Text (Text) -import Clay.Render (renderSelector)+import Clay.Render (renderSelector, renderRefinement) import Clay.Selector import qualified Data.Text.Lazy as Lazy@@ -64,5 +66,19 @@ nthLastOfType n = func "nth-last-of-type" [n] nthOfType n = func "nth-of-type" [n] -not :: Selector -> Refinement-not r = func "not" [Lazy.toStrict (renderSelector r)]+-- | The 'not' pseudo selector can be applied to both a 'Refinement'+--+-- > input # not checked+-- +-- or a 'Selector'+--+-- > not p++class Not a where+ not :: a -> Refinement++instance Not Selector where+ not r = func "not" [Lazy.toStrict (renderSelector r)]++instance Not Refinement where+ not r = func "not" (Lazy.toStrict <$> renderRefinement r)
src/Clay/Render.hs view
@@ -8,16 +8,16 @@ , putCss , renderWith , renderSelector+, renderRefinement , withBanner ) where import Control.Applicative import Control.Monad.Writer-import Data.Foldable (foldMap) import Data.List (sort) import Data.Maybe-import Data.Text (Text, pack)+import Data.Text (Text) import Data.Text.Lazy.Builder import Prelude hiding ((**)) @@ -121,6 +121,10 @@ renderSelector :: Selector -> Lazy.Text renderSelector = toLazyText . selector compact +-- | Render a CSS `Refinement`.+renderRefinement :: Refinement -> [Lazy.Text]+renderRefinement r = toLazyText . predicate <$> unFilter r+ ------------------------------------------------------------------------------- renderBanner :: Config -> Lazy.Text -> Lazy.Text@@ -148,10 +152,10 @@ ) (unPrefixed browsers) -frame :: Config -> (Double, [Rule]) -> Builder+frame :: Config -> (Number, [Rule]) -> Builder frame cfg (p, rs) = mconcat- [ fromText (pack (show p))+ [ fromText (cssNumberText p) , "% " , rules cfg [] rs ]@@ -185,7 +189,7 @@ feature :: Feature -> Builder feature (Feature k mv) = case mv of- Nothing -> fromText k+ Nothing -> mconcat [ "(", fromText k, ")" ] Just (Value v) -> mconcat [ "(" , fromText k , ": " , fromText (plain v) , ")" ] @@ -304,6 +308,7 @@ Child a b -> ins " > " <$> rec a <*> rec b Deep a b -> ins " " <$> rec a <*> rec b Adjacent a b -> ins " + " <$> rec a <*> rec b+ Sibling a b -> ins " ~ " <$> rec a <*> rec b Combined a b -> rec a ++ rec b where ins s a b = a <> s <> b
src/Clay/Selector.hs view
@@ -6,20 +6,12 @@ , UndecidableInstances , ViewPatterns , PatternGuards- , CPP #-} module Clay.Selector where -import Control.Applicative-import Data.Monoid import Data.String import Data.Text (Text)-import Prelude hiding (foldl) -#if MIN_VERSION_base(4,9,0)-import Data.Semigroup-#endif- import qualified Data.Text as Text -- | The star selector applies to all elements. Maps to @*@ in CSS.@@ -59,6 +51,11 @@ (|+) :: Selector -> Selector -> Selector (|+) a b = In (SelectorF (Refinement []) (Adjacent a b)) +-- | The general sibling selector composer. Maps to @sel1 ~ sel2@ in CSS.++(|~) :: Selector -> Selector -> Selector+(|~) a b = In (SelectorF (Refinement []) (Sibling a b))+ -- | Named alias for `#`. with :: Selector -> Refinement -> Selector@@ -157,7 +154,7 @@ deriving (Eq, Ord, Show) newtype Refinement = Refinement { unFilter :: [Predicate] }- deriving (Show, Monoid)+ deriving (Show, Semigroup, Monoid) instance IsString Refinement where fromString = refinementFromText . fromString@@ -182,6 +179,7 @@ | Child f f | Deep f f | Adjacent f f+ | Sibling f f | Combined f f deriving Show @@ -204,12 +202,9 @@ -> with star (refinementFromText t) _ -> In $ SelectorF (Refinement []) (Elem t) -#if MIN_VERSION_base(4,9,0) instance Semigroup (Fix SelectorF) where- (<>) = mappend-#endif+ a <> b = In (SelectorF (Refinement []) (Combined a b)) instance Monoid (Fix SelectorF) where- mempty = error "Selector is a semigroup"- mappend a b = In (SelectorF (Refinement []) (Combined a b))-+ mempty = error "Selector is a semigroup"+ mappend = (<>)
src/Clay/Size.hs view
@@ -27,12 +27,28 @@ , pc , em , ex+, ch , pct , rem+, lh+, rlh , vw , vh , vmin , vmax+, vb+, vi+, svw+, svh+, lvw+, lvh+, dvw+, dvh+, fr+, maxContent+, minContent+, available+, fitContent -- * Calculation operators for calc @@ -89,8 +105,8 @@ SimpleSize Text | forall b c. SumSize (Size b) (Size c) | forall b c. DiffSize (Size b) (Size c) |- MultSize Double (Size a) |- DivSize Double (Size a) |+ MultSize Number (Size a) |+ DivSize Number (Size a) | OtherSize Value deriving instance Show (Size a)@@ -99,8 +115,8 @@ sizeToText (SimpleSize txt) = txt sizeToText (SumSize a b) = mconcat ["(", sizeToText a, " + ", sizeToText b, ")"] sizeToText (DiffSize a b) = mconcat ["(", sizeToText a, " - ", sizeToText b, ")"]-sizeToText (MultSize a b) = mconcat ["(", cssDoubleText a, " * ", sizeToText b, ")"]-sizeToText (DivSize a b) = mconcat ["(", sizeToText b, " / ", cssDoubleText a, ")"]+sizeToText (MultSize a b) = mconcat ["(", cssNumberText a, " * ", sizeToText b, ")"]+sizeToText (DivSize a b) = mconcat ["(", sizeToText b, " / ", cssNumberText a, ")"] sizeToText (OtherSize a) = plain $ unValue a instance Val (Size a) where@@ -119,55 +135,107 @@ nil = SimpleSize "0" -- | Unitless size (as recommended for line-height).-unitless :: Double -> Size a+unitless :: Number -> Size a unitless i = SimpleSize ((plain . unValue . value) i) -cm, mm, inches, px, pt, pc :: Double -> Size LengthUnit+cm, mm, inches, px, pt, pc :: Number -> Size LengthUnit -- | Size in centimeters.-cm i = SimpleSize (cssDoubleText i <> "cm")+cm i = SimpleSize (cssNumberText i <> "cm") -- | Size in millimeters.-mm i = SimpleSize (cssDoubleText i <> "mm")+mm i = SimpleSize (cssNumberText i <> "mm") -- | Size in inches (1in = 2.54 cm).-inches i = SimpleSize (cssDoubleText i <> "in")+inches i = SimpleSize (cssNumberText i <> "in") -- | Size in pixels.-px i = SimpleSize (cssDoubleText i <> "px")+px i = SimpleSize (cssNumberText i <> "px") -- | Size in points (1pt = 1/72 of 1in).-pt i = SimpleSize (cssDoubleText i <> "pt")+pt i = SimpleSize (cssNumberText i <> "pt") -- | Size in picas (1pc = 12pt).-pc i = SimpleSize (cssDoubleText i <> "pc")+pc i = SimpleSize (cssNumberText i <> "pc") -em, ex, rem, vw, vh, vmin, vmax :: Double -> Size LengthUnit+em, ex, ch, rem, lh, rlh, vw, vh, vmin, vmax, vb, vi, svw, svh, lvw, lvh, dvw, dvh, fr :: Number -> Size LengthUnit --- | Size in em's (computed cssDoubleText of the font-size).-em i = SimpleSize (cssDoubleText i <> "em")+-- | Size in em's (computed cssNumberText of the font-size).+em i = SimpleSize (cssNumberText i <> "em") -- | SimpleSize in ex'es (x-height of the first avaliable font).-ex i = SimpleSize (cssDoubleText i <> "ex")+ex i = SimpleSize (cssNumberText i <> "ex") +-- | SimpleSize in ch's (The width of the glyph "0" of the element's font).+ch i = SimpleSize (cssNumberText i <> "ch")+ -- | SimpleSize in rem's (em's, but always relative to the root element).-rem i = SimpleSize (cssDoubleText i <> "rem")+rem i = SimpleSize (cssNumberText i <> "rem") +-- | SimpleSize in lh's (Line height of the element).+lh i = SimpleSize (cssNumberText i <> "lh")++-- | SimpleSize in rlh's (lh's, but always relative to the root element).+rlh i = SimpleSize (cssNumberText i <> "rlh")+ -- | SimpleSize in vw's (1vw = 1% of viewport width).-vw i = SimpleSize (cssDoubleText i <> "vw")+vw i = SimpleSize (cssNumberText i <> "vw") -- | SimpleSize in vh's (1vh = 1% of viewport height).-vh i = SimpleSize (cssDoubleText i <> "vh")+vh i = SimpleSize (cssNumberText i <> "vh") -- | SimpleSize in vmin's (the smaller of vw or vh).-vmin i = SimpleSize (cssDoubleText i <> "vmin")+vmin i = SimpleSize (cssNumberText i <> "vmin") -- | SimpleSize in vmax's (the larger of vw or vh).-vmax i = SimpleSize (cssDoubleText i <> "vmax")+vmax i = SimpleSize (cssNumberText i <> "vmax") +-- | SimpleSize in vb's (1vb = 1% of the parent's size in the direction of the root element's block axis).+vb i = SimpleSize (cssNumberText i <> "vb")++-- | SimpleSize in vi's (1vi = 1% of the parent's size in the direction of the root element's inline axis).+vi i = SimpleSize (cssNumberText i <> "vi")++-- | SimpleSize in svw's (1svw = 1% of the small viewport's width).+svw i = SimpleSize (cssNumberText i <> "svw")++-- | SimpleSize in svh's (1svh = 1% of the small viewport's height).+svh i = SimpleSize (cssNumberText i <> "svh")++-- | SimpleSize in lvw's (1lvw = 1% of the large viewport's width).+lvw i = SimpleSize (cssNumberText i <> "lvw")++-- | SimpleSize in lvh's (1lvh = 1% of the large viewport's height).+lvh i = SimpleSize (cssNumberText i <> "lvh")++-- | SimpleSize in dvw's (1dvw = 1% of the dynamic viewport's width).+dvw i = SimpleSize (cssNumberText i <> "dvw")++-- | SimpleSize in dvh's (1dvh = 1% of the dynamic viewport's height).+dvh i = SimpleSize (cssNumberText i <> "dvh")++-- | 'SimpleSize' in fr's (a fractional unit and 1fr is for 1 part of the available space in grid areas).+fr i = SimpleSize (cssNumberText i <> "fr")++-- | SimpleSize for the intrinsic preferred width.+maxContent :: Size LengthUnit+maxContent = SimpleSize "max-content"++-- | SimpleSize for the intrinsic minimum width.+minContent :: Size LengthUnit+minContent = SimpleSize "min-content"++-- | SimpleSize for the containing block width minus horizontal margin, border, and padding.+available :: Size LengthUnit+available = SimpleSize "available"++-- | The larger of the intrinsic minimum width or the smaller of the intrinsic preferred width and the available width.+fitContent :: Size LengthUnit+fitContent = SimpleSize "fit-content"+ -- | SimpleSize in percents.-pct :: Double -> Size Percentage-pct i = SimpleSize (cssDoubleText i <> "%")+pct :: Number -> Size Percentage+pct i = SimpleSize (cssNumberText i <> "%") instance Num (Size LengthUnit) where fromInteger = px . fromInteger@@ -212,17 +280,17 @@ -- | Times operator to combine sizes into calc function infixl 7 *@-(*@) :: Double -> Size a -> Size a+(*@) :: Number -> Size a -> Size a a *@ b = MultSize a b -- | Reversed times operator to combine sizes into calc function infixl 7 @*-(@*) :: Size a -> Double -> Size a+(@*) :: Size a -> Number -> Size a a @* b = MultSize b a -- | Division operator to combine sizes into calc function infixl 7 @/-(@/) :: Size a -> Double -> Size a+(@/) :: Size a -> Number -> Size a a @/ b = DivSize b a -------------------------------------------------------------------------------@@ -230,10 +298,10 @@ sym :: (a -> a -> a -> a -> Css) -> a -> Css sym k a = k a a a a -sym3 :: (a -> a -> a -> a -> Css) -> a -> a -> a -> Css+sym3 :: (tb -> l -> tb -> r -> Css) -> tb -> l -> r -> Css sym3 k tb l r = k tb l tb r -sym2 :: (a -> a -> a -> a -> Css) -> a -> a -> Css+sym2 :: (tb -> lr -> tb -> lr -> Css) -> tb -> lr -> Css sym2 k tb lr = k tb lr tb lr -------------------------------------------------------------------------------@@ -247,19 +315,19 @@ deriving (Val, Auto, Inherit, Other) -- | Angle in degrees.-deg :: Double -> Angle Deg+deg :: Number -> Angle Deg deg i = Angle (value i <> "deg") -- | Angle in radians.-rad :: Double -> Angle Rad+rad :: Number -> Angle Rad rad i = Angle (value i <> "rad") -- | Angle in gradians (also knows as gons or grades).-grad :: Double -> Angle Grad+grad :: Number -> Angle Grad grad i = Angle (value i <> "grad") -- | Angle in turns.-turn :: Double -> Angle Turn+turn :: Number -> Angle Turn turn i = Angle (value i <> "turn") instance Num (Angle Deg) where
src/Clay/Stylesheet.hs view
@@ -6,9 +6,8 @@ import Control.Applicative import Control.Arrow (second)-import Control.Monad.Writer hiding (All)+import Control.Monad.Writer (Writer, execWriter, tell) import Data.Maybe (isJust)-import Data.Semigroup (Semigroup) import Data.String (IsString) import Data.Text (Text) @@ -56,7 +55,7 @@ | Sub Selector deriving Show -data Keyframes = Keyframes Text [(Double, [Rule])]+data Keyframes = Keyframes Text [(Number, [Rule])] deriving Show data Rule@@ -83,9 +82,12 @@ type Css = StyleM () +instance Semigroup Css where+ (<>) = liftA2 (<>)+ instance Monoid Css where mempty = pure ()- mappend = liftA2 mappend+ mappend = (<>) -- | Add a new style property to the stylesheet with the specified `Key` and -- value. The value can be any type that is in the `Val' typeclass, with other@@ -163,7 +165,7 @@ ------------------------------------------------------------------------------- -keyframes :: Text -> [(Double, Css)] -> Css+keyframes :: Text -> [(Number, Css)] -> Css keyframes n xs = rule $ Keyframe (Keyframes n (map (second runS) xs)) keyframesFromTo :: Text -> Css -> Css -> Css
src/Clay/Text.hs view
@@ -35,6 +35,7 @@ , TextAlign , textAlign+, textAlignLast , justify, matchParent, start, end , alignSide , alignString@@ -72,14 +73,24 @@ , wordBreak , breakAll , keepAll- + -- * Overflow-wrap (and Word-wrap). , OverflowWrap , overflowWrap , wordWrap , breakWord- ++-- * Hyphenation.++, hyphens+, hyphenateCharacter+, hyphenateLimitChars+, manual+, Hyphens+, HyphenateCharacter+, HyphenateLimit+ -- * Content. , Content@@ -94,9 +105,8 @@ ) where -import Data.Monoid import Data.String-import Data.Text (Text)+import Data.Text (Text, pack) import Clay.Background import Clay.Border@@ -208,6 +218,9 @@ textAlign :: TextAlign -> Css textAlign = key "text-align" +textAlignLast :: TextAlign -> Css+textAlignLast = key "text-align-last"+ ------------------------------------------------------------------------------- newtype WhiteSpace = WhiteSpace Value@@ -302,6 +315,96 @@ textOverflow :: TextOverflow -> Css textOverflow = key "text-overflow"++-------------------------------------------------------------------------------++-- | Type for values which can be provided to 'hyphens'.+newtype Hyphens = Hyphens Value+ deriving (Val, None, Auto, Initial, Inherit, Unset, Other)++-- | Specifies how words should be hyphenated.+--+-- Possible values are:+--+-- ['none']: No hyphenation.+-- Words will not be hyphenated even if it is explicitly suggested for a word.+--+-- ['manual']: Manual hyphenation.+-- Specific characters such as @­@ in a word will suggest break points.+-- This is the default.+--+-- ['auto']: Automatic hyphenation.+-- The browser is free to hyphenate words as it sees fit.+-- However, explicitly suggested break points will take precedence.+--+-- For example,+--+-- >>> hyphens auto+--+-- The hyphenation rules depend on the language,+-- which must be specified by the @lang@ attribute.+--+-- For reference, see+-- [@hyphens@](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens).+hyphens :: Hyphens -> Css+hyphens = key "hyphens"++-- | Value for 'hyphens' specifying that hyphenation be manual.+manual :: Hyphens+manual = Hyphens "manual"+-- 'manual' feels like it should be a function and type class in Clay.Common,+-- but @hyphens@ is the only CSS property which uses it as a specified value.++-- | Type for values which can be provided to 'hyphenateCharacter'.+newtype HyphenateCharacter = HyphenateCharacter Value+ deriving (Val, Auto, Initial, Inherit, Unset, Other)++-- Allow a 'HyphenateCharacter' value to be specified directly with a string.+instance IsString HyphenateCharacter where+ fromString = HyphenateCharacter . Value . Plain . quote . pack++-- | Customizes the character used for hyphenation.+--+-- For example,+--+-- >>> hyphenateCharacter "~"+--+-- For reference, see+-- [@hyphenate-character@](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphenate-character).+hyphenateCharacter :: HyphenateCharacter -> Css+hyphenateCharacter = key "hyphenate-character"++-- | Type for values which can be provded to 'hyphenateLimitChars'.+newtype HyphenateLimit = HyphenateLimit Value+ deriving (Val, Auto, Initial, Inherit, Unset, Other)++-- Allow a 'HyphenateLimit' value to be specified directly with a number.+instance Num HyphenateLimit where+ fromInteger = HyphenateLimit . value+ (+) = error "plus not implemented for HyphenateLimit"+ (*) = error "times not implemented for HyphenateLimit"+ abs = error "abs not implemented for HyphenateLimit"+ signum = error "signum not implemented for HyphenateLimit"+ negate = error "negate not implemented for HyphenateLimit"++-- | Adjusts the minumum number of characters involved in hyphenation.+--+-- I.e., specifies the minumum number of characters allowed in a breakable word,+-- before a break point, and after a break point when hyphenating a word.+--+-- For example,+--+-- >>> hyphenateLimitChars 14 auto auto+--+-- For reference, see+-- [@hyphenate-limit-chars@](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphenate-limit-chars).+hyphenateLimitChars+ :: HyphenateLimit -- ^ Minimum length of a word which can be hyphenated.+ -> HyphenateLimit -- ^ Minimum number of characters allowed before a break point.+ -> HyphenateLimit -- ^ Minimum number of characters allowed after a break point.+ -> Css+hyphenateLimitChars word before after =+ key "hyphenate-limit-chars" (word ! before ! after) -------------------------------------------------------------------------------
src/Clay/Time.hs view
@@ -12,7 +12,6 @@ ) where -import Data.Monoid import Data.Text (pack) import Clay.Common
src/Clay/Transform.hs view
@@ -7,6 +7,18 @@ Transformation , transform , transforms+, TransformStyle+, transformStyle+, flat+, preserve3d+, TransformBox+, transformBox+, transformContentBox+, transformBorderBox+, fillBox+, strokeBox+, viewBox+, transformOrigin -- * Translating. @@ -39,7 +51,6 @@ ) where -import Data.Monoid import Prelude hiding (Left, Right) import Clay.Property@@ -58,16 +69,48 @@ ------------------------------------------------------------------------------- -scale :: Double -> Double -> Transformation+newtype TransformStyle = TransformStyle Value+ deriving (Val, Inherit, Initial, Unset)++transformStyle :: TransformStyle -> Css+transformStyle = prefixed (browsers <> "transform-style")++flat, preserve3d :: TransformStyle+flat = TransformStyle "flat"+preserve3d = TransformStyle "preserve-3d"++-------------------------------------------------------------------------------++newtype TransformBox = TransformBox Value+ deriving (Val, Inherit, Initial, Unset)++transformBox :: TransformBox -> Css+transformBox = prefixed (browsers <> "transform-box")++transformContentBox, transformBorderBox, fillBox, strokeBox, viewBox :: TransformBox+transformContentBox = TransformBox "contentBox"+transformBorderBox = TransformBox "borderBox"+fillBox = TransformBox "fillBox"+strokeBox = TransformBox "strokeBox"+viewBox = TransformBox "viewBox"++-------------------------------------------------------------------------------++transformOrigin :: [Size a] -> Css+transformOrigin = prefixed (browsers <> "transform-origin") . noCommas++-------------------------------------------------------------------------------++scale :: Number -> Number -> Transformation scale x y = Transformation ("scale(" <> value [x, y] <> ")") -scaleX, scaleY, scaleZ :: Double -> Transformation+scaleX, scaleY, scaleZ :: Number -> Transformation scaleX x = Transformation ("scaleX(" <> value x <> ")") scaleY y = Transformation ("scaleY(" <> value y <> ")") scaleZ z = Transformation ("scaleZ(" <> value z <> ")") -scale3d :: Double -> Double -> Double -> Transformation+scale3d :: Number -> Number -> Number -> Transformation scale3d x y z = Transformation ("scale3d(" <> value [x, y, z] <> ")") -------------------------------------------------------------------------------@@ -81,7 +124,7 @@ rotateY y = Transformation ("rotateY(" <> value y <> ")") rotateZ z = Transformation ("rotateZ(" <> value z <> ")") -rotate3d :: Double -> Double -> Double -> Angle a -> Transformation+rotate3d :: Number -> Number -> Number -> Angle a -> Transformation rotate3d x y z a = Transformation ("rotate3d(" <> value [value x, value y, value z, value a] <> ")") -------------------------------------------------------------------------------@@ -111,16 +154,16 @@ ------------------------------------------------------------------------------- -perspective :: Double -> Transformation+perspective :: Number -> Transformation perspective p = Transformation ("perspective(" <> value p <> ")") -matrix :: Double -> Double -> Double -> Double -> Double -> Double -> Transformation-matrix u v w x y z = Transformation ("matrix3d(" <> value [ u, v, w, x, y, z ] <> ")")+matrix :: Number -> Number -> Number -> Number -> Number -> Number -> Transformation+matrix u v w x y z = Transformation ("matrix(" <> value [ u, v, w, x, y, z ] <> ")") -matrix3d :: Double -> Double -> Double -> Double- -> Double -> Double -> Double -> Double- -> Double -> Double -> Double -> Double- -> Double -> Double -> Double -> Double+matrix3d :: Number -> Number -> Number -> Number + -> Number -> Number -> Number -> Number+ -> Number -> Number -> Number -> Number+ -> Number -> Number -> Number -> Number -> Transformation matrix3d w0 x0 y0 z0 w1 x1 y1 z1
src/Clay/Transition.hs view
@@ -25,7 +25,7 @@ , TimingFunction , transitionTimingFunction , transitionTimingFunctions-, ease, easeIn, easeOut, easeInOut, linear, stepStart, stepStop+, ease, easeIn, easeOut, easeInOut, linear, stepStart, stepEnd, stepStop , stepsStart, stepsStop , cubicBezier @@ -36,7 +36,6 @@ ) where -import Data.Monoid import Data.Text (Text) import Clay.Common@@ -75,7 +74,7 @@ newtype TimingFunction = TimingFunction Value deriving (Val, Other, Auto) -ease, easeIn, easeOut, easeInOut, linear, stepStart, stepStop :: TimingFunction+ease, easeIn, easeOut, easeInOut, linear, stepStart, stepEnd, stepStop :: TimingFunction ease = other "ease" easeIn = other "ease-in"@@ -83,15 +82,18 @@ easeInOut = other "ease-in-out" linear = other "linear" stepStart = other "step-start"-stepStop = other "step-stop"+stepEnd = other "step-end" +stepStop = stepEnd+{-# DEPRECATED stepStop "Use `stepEnd` instead." #-}+ stepsStart, stepsStop :: Integer -> TimingFunction -stepsStart s = other ("steps(" <> value s <> ", end)")+stepsStart s = other ("steps(" <> value s <> ", start)") stepsStop s = other ("steps(" <> value s <> ", end)") -cubicBezier :: Double -> Double -> Double -> Double -> TimingFunction-cubicBezier a b c d = other ("cubic-bezier(" <> value (a ! b ! c ! d) <> ")")+cubicBezier :: Number -> Number -> Number -> Number -> TimingFunction+cubicBezier a b c d = other ("cubic-bezier(" <> value [a, b, c, d] <> ")") transitionTimingFunction :: TimingFunction -> Css transitionTimingFunction = key "transition-timing-function"