mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-20 20:21:33 +03:00
259 lines
7.6 KiB
Elm
259 lines
7.6 KiB
Elm
module Examples.Tabs exposing
|
|
( example
|
|
, State, Msg
|
|
)
|
|
|
|
{-|
|
|
|
|
@docs example
|
|
@docs State, Msg
|
|
|
|
-}
|
|
|
|
import Browser.Dom as Dom
|
|
import Category exposing (Category(..))
|
|
import Css
|
|
import Debug.Control as Control exposing (Control)
|
|
import Example exposing (Example)
|
|
import Html.Styled as Html exposing (fromUnstyled)
|
|
import Html.Styled.Attributes exposing (css)
|
|
import KeyboardSupport exposing (Key(..))
|
|
import Nri.Ui.Colors.V1 as Colors
|
|
import Nri.Ui.Svg.V1 as Svg
|
|
import Nri.Ui.Tabs.V7 as Tabs exposing (Alignment(..), Tab)
|
|
import Nri.Ui.Text.V6 as Text
|
|
import Nri.Ui.Tooltip.V3 as Tooltip
|
|
import Nri.Ui.UiIcon.V1 as UiIcon
|
|
import Routes
|
|
import Task
|
|
|
|
|
|
type alias State =
|
|
{ selected : Id
|
|
, settings : Control Settings
|
|
, openTooltip : Maybe Id
|
|
}
|
|
|
|
|
|
init : State
|
|
init =
|
|
{ selected = First
|
|
, settings = initSettings
|
|
, openTooltip = Nothing
|
|
}
|
|
|
|
|
|
type alias Settings =
|
|
{ title : Maybe String
|
|
, alignment : Alignment
|
|
, customSpacing : Maybe Float
|
|
, labelledBy : Maybe String
|
|
}
|
|
|
|
|
|
initSettings : Control Settings
|
|
initSettings =
|
|
Control.record Settings
|
|
|> Control.field "title" (Control.maybe False (Control.string "Title"))
|
|
|> Control.field "alignment"
|
|
(Control.choice
|
|
[ ( "Left", Control.value Left )
|
|
, ( "Center", Control.value Center )
|
|
, ( "Right", Control.value Right )
|
|
]
|
|
)
|
|
|> Control.field "customSpacing"
|
|
(Control.maybe False
|
|
(Control.choice
|
|
[ ( "2", Control.value 2 )
|
|
, ( "3", Control.value 3 )
|
|
, ( "4", Control.value 4 )
|
|
, ( "8", Control.value 8 )
|
|
, ( "16", Control.value 16 )
|
|
]
|
|
)
|
|
)
|
|
|> Control.field "labelledBy" (Control.maybe False (Control.string "someId"))
|
|
|
|
|
|
type Id
|
|
= First
|
|
| Second
|
|
| Third
|
|
| Fourth
|
|
|
|
|
|
type Msg
|
|
= FocusAndSelectTab { select : Id, focus : Maybe String }
|
|
| Focused (Result Dom.Error ())
|
|
| SetSettings (Control Settings)
|
|
| ToggleTooltip Id Bool
|
|
|
|
|
|
update : Msg -> State -> ( State, Cmd Msg )
|
|
update msg model =
|
|
case msg of
|
|
FocusAndSelectTab { select, focus } ->
|
|
( { model | selected = select }
|
|
, focus
|
|
|> Maybe.map (Dom.focus >> Task.attempt Focused)
|
|
|> Maybe.withDefault Cmd.none
|
|
)
|
|
|
|
Focused error ->
|
|
( model, Cmd.none )
|
|
|
|
SetSettings settings ->
|
|
( { model | settings = settings }, Cmd.none )
|
|
|
|
ToggleTooltip id openTooltip ->
|
|
( { model
|
|
| openTooltip =
|
|
if openTooltip then
|
|
Just id
|
|
|
|
else
|
|
Nothing
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
|
|
exampleName : String
|
|
exampleName =
|
|
"Tabs"
|
|
|
|
|
|
example : Example State Msg
|
|
example =
|
|
{ name = exampleName
|
|
, version = 7
|
|
, categories = [ Layout ]
|
|
, keyboardSupport =
|
|
[ { keys = [ KeyboardSupport.Tab ]
|
|
, result = "Move focus to the currently-selected Tab's tab panel"
|
|
}
|
|
, { keys = [ Arrow KeyboardSupport.Left ]
|
|
, result = "Select the tab to the left of the currently-selected Tab"
|
|
}
|
|
, { keys = [ Arrow KeyboardSupport.Right ]
|
|
, result = "Select the tab to the right of the currently-selected Tab"
|
|
}
|
|
]
|
|
, state = init
|
|
, update = update
|
|
, subscriptions = \_ -> Sub.none
|
|
, preview =
|
|
[ -- faking a mini version of the Tabs component to give styleguide users a sense of what the
|
|
-- component might look like
|
|
Html.div [ css [ Css.displayFlex, Css.flexWrap Css.wrap ] ]
|
|
[ Html.div
|
|
[ css
|
|
[ Css.backgroundColor Colors.white
|
|
, Css.padding (Css.px 4)
|
|
, Css.borderRadius4 (Css.px 4) (Css.px 4) Css.zero Css.zero
|
|
, Css.border3 (Css.px 1) Css.solid Colors.navy
|
|
, Css.borderBottomWidth Css.zero
|
|
]
|
|
]
|
|
[ Text.smallBody [ Text.plaintext "Tab 1" ] ]
|
|
, Html.div
|
|
[ css [ Css.width (Css.px 4), Css.borderBottom3 (Css.px 1) Css.solid Colors.navy ]
|
|
]
|
|
[]
|
|
, Html.div
|
|
[ css
|
|
[ Css.backgroundColor Colors.frost
|
|
, Css.padding (Css.px 4)
|
|
, Css.borderRadius4 (Css.px 4) (Css.px 4) Css.zero Css.zero
|
|
, Css.border3 (Css.px 1) Css.solid Colors.navy
|
|
]
|
|
]
|
|
[ Text.smallBody [ Text.plaintext "Tab 1" ] ]
|
|
, Html.div
|
|
[ css
|
|
[ Css.width (Css.px 30)
|
|
, Css.borderBottom3 (Css.px 1) Css.solid Colors.navy
|
|
]
|
|
]
|
|
[]
|
|
, Html.div
|
|
[ css
|
|
[ Css.paddingTop (Css.px 4)
|
|
, Css.minWidth (Css.px 100)
|
|
]
|
|
]
|
|
[ Text.caption [ Text.plaintext "Tab 1 content" ] ]
|
|
]
|
|
]
|
|
, view =
|
|
\ellieLinkConfig model ->
|
|
let
|
|
settings =
|
|
Control.currentValue model.settings
|
|
in
|
|
[ Control.view SetSettings model.settings |> fromUnstyled
|
|
, Tabs.view
|
|
{ title = settings.title
|
|
, alignment = settings.alignment
|
|
, customSpacing = settings.customSpacing
|
|
, focusAndSelect = FocusAndSelectTab
|
|
, selected = model.selected
|
|
, tabs = allTabs model.openTooltip settings.labelledBy
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
allTabs : Maybe Id -> Maybe String -> List (Tab Id Msg)
|
|
allTabs openTooltipId labelledBy =
|
|
let
|
|
bulbIcon =
|
|
UiIcon.bulb
|
|
|> Svg.withWidth (Css.px 40)
|
|
|> Svg.withHeight (Css.px 45)
|
|
|> Svg.withLabel "Bulb"
|
|
|> Svg.withCss [ Css.padding2 Css.zero (Css.px 6) ]
|
|
|> Svg.toHtml
|
|
in
|
|
[ Tabs.build { id = First, idString = "tab-0" }
|
|
([ Tabs.spaHref <| Routes.toString (Routes.Doodad exampleName)
|
|
, Tabs.tabString "1"
|
|
, Tabs.withTooltip
|
|
[ Tooltip.plaintext "Link Example"
|
|
, Tooltip.onHover (ToggleTooltip First)
|
|
, Tooltip.alignStart (Css.px 75)
|
|
, Tooltip.primaryLabel
|
|
, Tooltip.open (openTooltipId == Just First)
|
|
]
|
|
, Tabs.panelHtml (Html.text "First Panel")
|
|
]
|
|
++ (case labelledBy of
|
|
Nothing ->
|
|
[]
|
|
|
|
Just labelledById ->
|
|
[ Tabs.labelledBy labelledById ]
|
|
)
|
|
)
|
|
, Tabs.build { id = Second, idString = "tab-1" }
|
|
[ Tabs.tabString "Second Tab (disabled)"
|
|
, Tabs.disabled True
|
|
, Tabs.panelHtml (Html.text "Second Panel")
|
|
]
|
|
, Tabs.build { id = Third, idString = "tab-2" }
|
|
[ Tabs.tabHtml bulbIcon
|
|
, Tabs.withTooltip
|
|
[ Tooltip.plaintext "The Electrifying Third Tab"
|
|
, Tooltip.onHover (ToggleTooltip Third)
|
|
, Tooltip.primaryLabel
|
|
, Tooltip.open (openTooltipId == Just Third)
|
|
]
|
|
, Tabs.panelHtml (Html.text "Third Panel")
|
|
]
|
|
, Tabs.build { id = Fourth, idString = "tab-3" }
|
|
[ Tabs.tabString "Fourth Tab"
|
|
, Tabs.panelHtml (Html.text "Fourth Panel")
|
|
]
|
|
]
|