mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-18 11:11:38 +03:00
Merge pull request #111 from NoRedInk/ink-james--premium-checkbox
Don't require PremiumLevel; allow general premium levels
This commit is contained in:
commit
b29f6f783d
@ -35,6 +35,7 @@
|
||||
"Nri.Ui.Page.V1",
|
||||
"Nri.Ui.Palette.V1",
|
||||
"Nri.Ui.PremiumCheckbox.V1",
|
||||
"Nri.Ui.PremiumCheckbox.V2",
|
||||
"Nri.Ui.SegmentedControl.V1",
|
||||
"Nri.Ui.SegmentedControl.V2",
|
||||
"Nri.Ui.SegmentedControl.V3",
|
||||
|
117
src/Nri/Ui/PremiumCheckbox/V2.elm
Normal file
117
src/Nri/Ui/PremiumCheckbox/V2.elm
Normal file
@ -0,0 +1,117 @@
|
||||
module Nri.Ui.PremiumCheckbox.V2 exposing (Pennant(..), PremiumConfig, premium)
|
||||
|
||||
{-|
|
||||
|
||||
@docs PremiumConfig, premium, Pennant
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled as Html
|
||||
import Css exposing (..)
|
||||
import Html.Styled.Attributes as Attributes exposing (css)
|
||||
import Nri.Ui.AssetPath exposing (Asset(..))
|
||||
import Nri.Ui.AssetPath.Css
|
||||
import Nri.Ui.Checkbox.V3 as Checkbox
|
||||
|
||||
|
||||
{-|
|
||||
|
||||
- `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
|
||||
, isLocked : Bool
|
||||
, pennant : Maybe Pennant
|
||||
, onChange : Bool -> msg
|
||||
, onLockedClick : msg
|
||||
, noOpMsg : msg
|
||||
}
|
||||
|
||||
|
||||
{-| Premium is the yellow "P" pennant
|
||||
PremiumWithWriting is the yellow "P+" pennant
|
||||
-}
|
||||
type Pennant
|
||||
= Premium
|
||||
| PremiumWithWriting
|
||||
|
||||
|
||||
{-| A checkbox that should be used for premium content
|
||||
-}
|
||||
premium : Assets a -> PremiumConfig msg -> Html.Html msg
|
||||
premium assets config =
|
||||
Html.div
|
||||
[ css
|
||||
[ displayFlex
|
||||
, alignItems center
|
||||
]
|
||||
]
|
||||
[ Checkbox.viewWithLabel assets
|
||||
{ identifier = config.id
|
||||
, label = config.label
|
||||
, setterMsg =
|
||||
if config.isLocked then
|
||||
\_ -> config.onLockedClick
|
||||
else
|
||||
config.onChange
|
||||
, selected = config.selected
|
||||
, disabled = config.disabled
|
||||
, theme =
|
||||
if config.isLocked then
|
||||
Checkbox.Locked
|
||||
else
|
||||
Checkbox.Square
|
||||
, noOpMsg = config.noOpMsg
|
||||
}
|
||||
, case config.pennant of
|
||||
Just pennant ->
|
||||
Html.div
|
||||
[ Attributes.class "premium-checkbox-V1__PremiumClass"
|
||||
, css
|
||||
[ property "content" "''"
|
||||
, display inlineBlock
|
||||
, width (px 26)
|
||||
, height (px 24)
|
||||
, marginLeft (px 8)
|
||||
, backgroundImage
|
||||
(case pennant of
|
||||
Premium ->
|
||||
assets.iconPremiumFlag_svg
|
||||
|
||||
PremiumWithWriting ->
|
||||
assets.iconPremiumWithWritingFlag_svg
|
||||
)
|
||||
, backgroundRepeat noRepeat
|
||||
, backgroundPosition center
|
||||
]
|
||||
]
|
||||
[]
|
||||
|
||||
Nothing ->
|
||||
Html.text ""
|
||||
]
|
||||
|
||||
|
||||
{-| The assets used in this module.
|
||||
-}
|
||||
type alias Assets r =
|
||||
{ r
|
||||
| checkboxUnchecked_svg : Asset
|
||||
, checkboxChecked_svg : Asset
|
||||
, checkboxCheckedPartially_svg : Asset
|
||||
, checkboxLockOnInside_svg : Asset
|
||||
, iconPremiumFlag_svg : Asset
|
||||
, iconPremiumWithWritingFlag_svg : Asset
|
||||
}
|
||||
|
||||
|
||||
backgroundImage : Asset -> Style
|
||||
backgroundImage =
|
||||
Nri.Ui.AssetPath.Css.url
|
||||
>> property "background-image"
|
@ -39,6 +39,7 @@ type alias Assets =
|
||||
, iconCheck_png : Asset
|
||||
, iconFlag_png : Asset
|
||||
, iconPremiumFlag_svg : Asset
|
||||
, iconPremiumWithWritingFlag_svg : Asset
|
||||
, icons_arrowDownBlue_svg : Asset
|
||||
, icons_arrowRightBlue_svg : Asset
|
||||
, icons_clockRed_svg : Asset
|
||||
@ -127,6 +128,7 @@ assets =
|
||||
, iconCheck_png = Asset "assets/images/icon-check.png"
|
||||
, iconFlag_png = Asset "assets/images/icon-flag.png"
|
||||
, iconPremiumFlag_svg = Asset "assets/images/icon_premium_flag.svg"
|
||||
, iconPremiumWithWritingFlag_svg = Asset "assets/images/icon_premium_writing_flag.svg"
|
||||
, icons_arrowDownBlue_svg = Asset "assets/images/arrow-down-blue.svg"
|
||||
, icons_arrowRightBlue_svg = Asset "assets/images/arrow-right-blue.svg"
|
||||
, icons_clockRed_svg = Asset "assets/images/clock-red.svg"
|
||||
|
@ -12,21 +12,19 @@ import Html.Styled as Html exposing (..)
|
||||
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Checkbox.V3 as Checkbox
|
||||
import Nri.Ui.Data.PremiumLevel as PremiumLevel exposing (PremiumLevel(..))
|
||||
import Nri.Ui.PremiumCheckbox.V1 as PremiumCheckbox
|
||||
import Nri.Ui.PremiumCheckbox.V2 as PremiumCheckbox
|
||||
import Set exposing (Set)
|
||||
|
||||
|
||||
{-| -}
|
||||
type Msg
|
||||
= ToggleCheck Id Bool
|
||||
| SetPremiumControl (Control PremiumExampleConfig)
|
||||
| NoOp
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias State =
|
||||
{ isChecked : Set String
|
||||
, premiumControl : Control PremiumExampleConfig
|
||||
}
|
||||
|
||||
|
||||
@ -41,8 +39,6 @@ example parentMessage state =
|
||||
, viewLockedOnInsideCheckbox "styleguide-locked-on-inside-checkbox" state
|
||||
, viewDisabledCheckbox "styleguide-checkbox-disabled" state
|
||||
, h3 [] [ text "Premium Checkboxes" ]
|
||||
, Control.view SetPremiumControl state.premiumControl
|
||||
|> Html.fromUnstyled
|
||||
, viewPremiumCheckboxes state
|
||||
]
|
||||
|> List.map (Html.toUnstyled << Html.map parentMessage)
|
||||
@ -53,17 +49,6 @@ example parentMessage state =
|
||||
init : State
|
||||
init =
|
||||
{ isChecked = Set.empty
|
||||
, premiumControl =
|
||||
Control.record PremiumExampleConfig
|
||||
|> Control.field "disabled" (Control.bool False)
|
||||
|> Control.field "teacherPremiumLevel"
|
||||
(Control.choice
|
||||
[ ( "Free", Control.value PremiumLevel.Free )
|
||||
, ( "Premium", Control.value PremiumLevel.Premium )
|
||||
, ( "Premium (with writing)", Control.value PremiumLevel.PremiumWithWriting )
|
||||
]
|
||||
)
|
||||
|> Control.field "showFlagWhenLocked" (Control.bool True)
|
||||
}
|
||||
|
||||
|
||||
@ -81,9 +66,6 @@ update msg state =
|
||||
in
|
||||
( { state | isChecked = isChecked }, Cmd.none )
|
||||
|
||||
SetPremiumControl premiumControl ->
|
||||
( { state | premiumControl = premiumControl }, Cmd.none )
|
||||
|
||||
NoOp ->
|
||||
( state, Cmd.none )
|
||||
|
||||
@ -95,7 +77,7 @@ update msg state =
|
||||
type alias PremiumExampleConfig =
|
||||
{ disabled : Bool
|
||||
, teacherPremiumLevel : PremiumLevel
|
||||
, showFlagWhenLocked : Bool
|
||||
, pennant : Maybe PremiumCheckbox.Pennant
|
||||
}
|
||||
|
||||
|
||||
@ -158,32 +140,29 @@ viewDisabledCheckbox id state =
|
||||
viewPremiumCheckboxes : State -> Html Msg
|
||||
viewPremiumCheckboxes state =
|
||||
let
|
||||
config =
|
||||
Control.currentValue state.premiumControl
|
||||
|
||||
checkbox label premiumLevel =
|
||||
checkbox config =
|
||||
PremiumCheckbox.premium
|
||||
assets
|
||||
{ label = label
|
||||
, id = "premium-checkbox-" ++ label
|
||||
{ label = config.label
|
||||
, id = "premium-checkbox-" ++ config.label
|
||||
, selected =
|
||||
if Set.member label state.isChecked then
|
||||
if Set.member config.label state.isChecked then
|
||||
Checkbox.Selected
|
||||
else
|
||||
Checkbox.NotSelected
|
||||
, disabled = config.disabled
|
||||
, teacherPremiumLevel = config.teacherPremiumLevel
|
||||
, contentPremiumLevel = premiumLevel
|
||||
, showFlagWhenLocked = config.showFlagWhenLocked
|
||||
, onChange = ToggleCheck label
|
||||
, isLocked = config.isLocked
|
||||
, pennant = config.pennant
|
||||
, onChange = ToggleCheck config.label
|
||||
, onLockedClick = NoOp
|
||||
, noOpMsg = NoOp
|
||||
}
|
||||
in
|
||||
Html.div []
|
||||
[ checkbox "Identify Adjectives 1 (Free)" PremiumLevel.Free
|
||||
, checkbox "Identify Adjectives 2 (Premium)" PremiumLevel.Premium
|
||||
, checkbox "Revising Wordy Phrases 1 (Writing)" PremiumLevel.PremiumWithWriting
|
||||
[ checkbox { label = "Identify Adjectives 1 (Free)", disabled = False, isLocked = False, pennant = Nothing }
|
||||
, checkbox { label = "Identify Adjectives 2 (Premium)", disabled = False, isLocked = False, pennant = Just PremiumCheckbox.Premium }
|
||||
, checkbox { label = "Revising Wordy Phrases 1 (Writing)", disabled = False, isLocked = True, pennant = Just PremiumCheckbox.PremiumWithWriting }
|
||||
, checkbox { label = "Revising Wordy Phrases 2 (Writing) (Disabled)", disabled = True, isLocked = True, pennant = Just PremiumCheckbox.PremiumWithWriting }
|
||||
]
|
||||
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:16221aee450224605f8a4aae798ed2ebbba3698fac2dc101d0132729e8f5cdce
|
||||
size 817
|
141
tests/Spec/Nri/Ui/PremiumCheckbox/V2.elm
Normal file
141
tests/Spec/Nri/Ui/PremiumCheckbox/V2.elm
Normal file
@ -0,0 +1,141 @@
|
||||
module Spec.Nri.Ui.PremiumCheckbox.V2 exposing (spec)
|
||||
|
||||
import Html.Attributes
|
||||
import Html.Styled
|
||||
import Nri.Ui.AssetPath exposing (Asset(Asset))
|
||||
import Nri.Ui.Checkbox.V3 exposing (IsSelected(..))
|
||||
import Nri.Ui.Data.PremiumLevel as PremiumLevel exposing (PremiumLevel(..))
|
||||
import Nri.Ui.PremiumCheckbox.V2 as PremiumCheckbox
|
||||
import Test exposing (..)
|
||||
import Test.Html.Query as Query
|
||||
import Test.Html.Selector as Selector
|
||||
|
||||
|
||||
premiumView config =
|
||||
PremiumCheckbox.premium assets
|
||||
{ label = "i am label"
|
||||
, id = "id"
|
||||
, selected = config.selected
|
||||
, disabled = config.disabled
|
||||
, isLocked = config.isLocked
|
||||
, pennant = config.pennant
|
||||
, onChange = \_ -> ()
|
||||
, onLockedClick = ()
|
||||
, noOpMsg = ()
|
||||
}
|
||||
|> Html.Styled.toUnstyled
|
||||
|> Query.fromHtml
|
||||
|
||||
|
||||
spec : Test
|
||||
spec =
|
||||
describe "Nri.Ui.PremiumCheckbox.V2"
|
||||
[ describe "premium"
|
||||
[ test "displays the label" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.text "i am label" ]
|
||||
, test "appears selected when Selected is passed in" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.class "checkbox-V3__Checked" ]
|
||||
, test "appears unselected when NotSelected is passed in" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = NotSelected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.class "checkbox-V3__Unchecked" ]
|
||||
, test "appears partially selected when PartiallySelected is passed in" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = PartiallySelected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.class "checkbox-V3__Indeterminate" ]
|
||||
, test "appears locked when isLocked = True" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = True
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.class "checkbox-V3__Locked" ]
|
||||
, test "appears unlocked when isLocked = False" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.hasNot [ Selector.class "checkbox-V3__Locked" ]
|
||||
, test "appears with P flag when Premium pennant is passed in" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Just PremiumCheckbox.Premium
|
||||
}
|
||||
|> Query.find [ Selector.tag "style" ]
|
||||
|> Query.has [ Selector.text "iconPremiumFlag reference" ]
|
||||
, test "appears with P+ flag when Premium pennant is passed in" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Just PremiumCheckbox.PremiumWithWriting
|
||||
}
|
||||
|> Query.find [ Selector.tag "style" ]
|
||||
|> Query.has [ Selector.text "iconPremiumWritingFlag reference" ]
|
||||
, test "is not disabled when disabled = False" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = False
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> Query.has [ Selector.disabled False ]
|
||||
, test "is disabled when disabled = True" <|
|
||||
\() ->
|
||||
premiumView
|
||||
{ selected = Selected
|
||||
, disabled = True
|
||||
, isLocked = False
|
||||
, pennant = Nothing
|
||||
}
|
||||
|> 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"
|
||||
, iconPremiumWithWritingFlag_svg = Asset "iconPremiumWritingFlag reference"
|
||||
}
|
Loading…
Reference in New Issue
Block a user