mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-09-21 12:19:03 +03:00
Extract the premium chekcbox functionality
This commit is contained in:
parent
d34e29f84f
commit
2c4169a334
@ -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
|
||||
|
84
src/Nri/Ui/PremiumCheckbox/V1.elm
Normal file
84
src/Nri/Ui/PremiumCheckbox/V1.elm
Normal 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
|
||||
}
|
@ -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 =
|
||||
|
180
tests/Spec/Nri/Ui/PremiumCheckbox/V1.elm
Normal file
180
tests/Spec/Nri/Ui/PremiumCheckbox/V1.elm
Normal 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"
|
||||
}
|
Loading…
Reference in New Issue
Block a user