Extract the premium chekcbox functionality

This commit is contained in:
Tessa Kelly 2018-06-19 17:52:58 -07:00
parent d34e29f84f
commit 2c4169a334
4 changed files with 265 additions and 229 deletions

View File

@ -3,9 +3,7 @@ module Nri.Ui.Checkbox.V3
( ColorTheme(..)
, IsSelected(..)
, Model
, PremiumConfig
, Theme(..)
, premium
, view
, viewWithLabel
)
@ -16,11 +14,6 @@ module Nri.Ui.Checkbox.V3
@docs view, viewWithLabel
## Premium
@docs PremiumConfig, premium
-}
import Accessibility.Styled as Html
@ -40,7 +33,6 @@ import Json.Encode
import Nri.Ui.AssetPath exposing (Asset(..))
import Nri.Ui.AssetPath.Css
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumLevel as PremiumLevel exposing (PremiumLevel(..))
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.Html.V2 as HtmlExtra
@ -101,75 +93,6 @@ viewWithLabel assets model =
Html.span [] [ Html.text model.label ]
{-|
- `onChange`: A message for when the user toggles the checkbox
- `onLockedClick`: A message for when the user clicks a checkbox they don't have PremiumLevel for.
If you get this message, you should show an `Nri.Ui.Premium.Model.view`
-}
type alias PremiumConfig msg =
{ label : String
, id : String
, selected : IsSelected
, disabled : Bool
, teacherPremiumLevel : PremiumLevel
, contentPremiumLevel : PremiumLevel
, showFlagWhenLocked : Bool
, onChange : Bool -> msg
, onLockedClick : msg
, noOpMsg : msg
}
{-| A checkbox that should be used for premium content
This checkbox is locked when the premium level of the content is greater than the premium level of the teacher
-}
premium : Assets a -> PremiumConfig msg -> Html.Html msg
premium assets config =
let
isLocked =
not <|
PremiumLevel.allowedFor
config.contentPremiumLevel
config.teacherPremiumLevel
modifierClasses =
List.concat
[ if config.showFlagWhenLocked && config.contentPremiumLevel /= Free then
[ "PremiumClass" ]
else
[]
]
theme =
if isLocked then
LockOnInside
else if config.contentPremiumLevel /= Free then
Premium
else
Square Default
in
buildCheckbox assets
modifierClasses
{ identifier = config.id
, label = config.label
, setterMsg =
if isLocked then
\_ -> config.onLockedClick
else
config.onChange
, selected = config.selected
, disabled = config.disabled
, theme = theme
, noOpMsg = config.noOpMsg
}
<|
Html.span [] [ Html.text config.label ]
buildCheckbox : Assets a -> List String -> Model msg -> Html.Html msg -> Html.Html msg
buildCheckbox assets modifierClasses model labelContent =
let

View File

@ -0,0 +1,84 @@
module Nri.Ui.PremiumCheckbox.V1 exposing (PremiumConfig, premium)
{-|
@docs PremiumConfig, premium
-}
import Accessibility.Styled as Html
import Nri.Ui.AssetPath exposing (Asset(..))
import Nri.Ui.Checkbox.V3 as Checkbox
import Nri.Ui.Data.PremiumLevel as PremiumLevel exposing (PremiumLevel(..))
{-|
- `onChange`: A message for when the user toggles the checkbox
- `onLockedClick`: A message for when the user clicks a checkbox they don't have PremiumLevel for.
If you get this message, you should show an `Nri.Ui.Premium.Model.view`
-}
type alias PremiumConfig msg =
{ label : String
, id : String
, selected : Checkbox.IsSelected
, disabled : Bool
, teacherPremiumLevel : PremiumLevel
, contentPremiumLevel : PremiumLevel
, showFlagWhenLocked : Bool
, onChange : Bool -> msg
, onLockedClick : msg
, noOpMsg : msg
}
{-| A checkbox that should be used for premium content
This checkbox is locked when the premium level of the content is greater than the premium level of the teacher
-}
premium : Assets a -> PremiumConfig msg -> Html.Html msg
premium assets config =
let
isLocked =
not <|
PremiumLevel.allowedFor
config.contentPremiumLevel
config.teacherPremiumLevel
theme =
if isLocked then
Checkbox.LockOnInside
else if config.contentPremiumLevel /= Free then
Checkbox.Premium
else
Checkbox.Square Checkbox.Default
in
Checkbox.viewWithLabel assets
{ identifier = config.id
, label = config.label
, setterMsg =
if isLocked then
\_ -> config.onLockedClick
else
config.onChange
, selected = config.selected
, disabled = config.disabled
, theme = theme
, noOpMsg = config.noOpMsg
}
{-| The assets used in this module.
-}
type alias Assets r =
{ r
| checkboxUnchecked_svg : Asset
, checkboxChecked_svg : Asset
, checkboxCheckedPartially_svg : Asset
, iconPremiumUnlocked_png : Asset
, iconPremiumLocked_png : Asset
, checkboxLockOnInside_svg : Asset
, iconPremiumFlag_svg : Asset
}

View File

@ -9,161 +9,10 @@ import Test.Html.Query as Query
import Test.Html.Selector as Selector
premiumView config =
Checkbox.premium assets
{ label = config.label
, id = "id"
, selected = config.selected
, disabled = config.disabled
, teacherPremiumLevel = config.teacherPremiumLevel
, contentPremiumLevel = config.contentPremiumLevel
, showFlagWhenLocked = config.showFlagWhenLocked
, onChange = \_ -> ()
, onLockedClick = ()
, noOpMsg = ()
}
|> Html.Styled.toUnstyled
|> Query.fromHtml
spec : Test
spec =
describe "Nri.Ui.Checkbox.V1"
[ describe "premium"
[ test "displays the label" <|
\() ->
premiumView
{ label = "i am label"
, selected = Selected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.text "i am label" ]
, test "appears selected when Selected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = Selected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Checked" ]
, test "appears unselected when NotSelected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = NotSelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Unchecked" ]
, test "appears partially selected when PartiallySelected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Indeterminate" ]
, test "appears locked when teacherPremiumLevel < contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-LockOnInsideClass" ]
, test "appears unlocked when teacherPremiumLevel >= contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Premium
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.hasNot [ Selector.class "checkbox-LockOnInsideClass" ]
, test "appears with P flag when teacherPremiumLevel >= contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Premium
, contentPremiumLevel = Premium
, showFlagWhenLocked = False
}
|> Query.has [ Selector.class "checkbox-PremiumClass" ]
, test "does not appear with P flag when teacherPremiumLevel < contentPremiumLevel and showFlagWhenLocked = False" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = False
}
|> Query.hasNot [ Selector.class "checkbox-PremiumClass" ]
, test "appears with P flag for Premium content when teacherPremiumLevel < contentPremiumLevel and showFlagWhenLocked = True" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-PremiumClass" ]
, test "never shows P flag for nonPremium content" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.hasNot [ Selector.class "checkbox-PremiumClass" ]
, test "is not disabled when disabled = False and the checkbox is unlocked" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.disabled False ]
, test "is disabled when disabled = True and the checkbox is unlocked" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = True
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.disabled True ]
]
]
[]
assets =

View File

@ -0,0 +1,180 @@
module Spec.Nri.Ui.PremiumCheckbox.V1 exposing (spec)
import Html.Styled
import Nri.Ui.AssetPath exposing (Asset(Asset))
import Nri.Ui.Checkbox.V3 exposing (IsSelected(..))
import Nri.Ui.Data.PremiumLevel exposing (PremiumLevel(..))
import Nri.Ui.PremiumCheckbox.V1 as PremiumCheckbox
import Test exposing (..)
import Test.Html.Query as Query
import Test.Html.Selector as Selector
premiumView config =
PremiumCheckbox.premium assets
{ label = config.label
, id = "id"
, selected = config.selected
, disabled = config.disabled
, teacherPremiumLevel = config.teacherPremiumLevel
, contentPremiumLevel = config.contentPremiumLevel
, showFlagWhenLocked = config.showFlagWhenLocked
, onChange = \_ -> ()
, onLockedClick = ()
, noOpMsg = ()
}
|> Html.Styled.toUnstyled
|> Query.fromHtml
spec : Test
spec =
describe "Nri.Ui.PremiumCheckbox.V1"
[ describe "premium"
[ test "displays the label" <|
\() ->
premiumView
{ label = "i am label"
, selected = Selected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.text "i am label" ]
, test "appears selected when Selected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = Selected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Checked" ]
, test "appears unselected when NotSelected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = NotSelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Unchecked" ]
, test "appears partially selected when PartiallySelected is passed in" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-Indeterminate" ]
, test "appears locked when teacherPremiumLevel < contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-LockOnInsideClass" ]
, test "appears unlocked when teacherPremiumLevel >= contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Premium
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.hasNot [ Selector.class "checkbox-LockOnInsideClass" ]
, test "appears with P flag when teacherPremiumLevel >= contentPremiumLevel" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Premium
, contentPremiumLevel = Premium
, showFlagWhenLocked = False
}
|> Query.has [ Selector.class "checkbox-PremiumClass" ]
, test "does not appear with P flag when teacherPremiumLevel < contentPremiumLevel and showFlagWhenLocked = False" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = False
}
|> Query.hasNot [ Selector.class "checkbox-PremiumClass" ]
, test "appears with P flag for Premium content when teacherPremiumLevel < contentPremiumLevel and showFlagWhenLocked = True" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Premium
, showFlagWhenLocked = True
}
|> Query.has [ Selector.class "checkbox-PremiumClass" ]
, test "never shows P flag for nonPremium content" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.hasNot [ Selector.class "checkbox-PremiumClass" ]
, test "is not disabled when disabled = False and the checkbox is unlocked" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = False
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.disabled False ]
, test "is disabled when disabled = True and the checkbox is unlocked" <|
\() ->
premiumView
{ label = "i am label"
, selected = PartiallySelected
, disabled = True
, teacherPremiumLevel = Free
, contentPremiumLevel = Free
, showFlagWhenLocked = True
}
|> Query.has [ Selector.disabled True ]
]
]
assets =
{ checkboxUnchecked_svg = Asset "checkboxUnchecked reference"
, checkboxChecked_svg = Asset "checkboxChecked reference"
, checkboxCheckedPartially_svg = Asset "checkboxCheckedPartially reference"
, iconPremiumUnlocked_png = Asset "iconPremiumUnlocked reference"
, iconCheck_png = Asset "iconCheck reference"
, iconPremiumLocked_png = Asset "iconPremiumLocked reference"
, checkboxLockOnInside_svg = Asset "checkboxLockOnInside reference"
, iconPremiumKey_png = Asset "iconPremiumKey reference"
, iconPremiumFlag_svg = Asset "iconPremiumFlag reference"
}