Tabs
Panels of one place, one shown at a time, moved between by the arrow keys.
Six people, three open milestones, one launch.
forSlots(TabsSlots)(Recipes.Tabs({}))
Usage
The function that drew the preview, over the theme module Create a theme writes. The preview passes it the style picked above instead of its default.
export const TabsStyle = forSlots(TabsSlots)(Recipes.Tabs({}))
export const Section = Schema.Literals(['overview', 'activity', 'settings'])
export type Section = typeof Section.Type
// Annotated: the inferred type names a foldkit internal module.
export const SectionTabs: ReturnType<typeof UiTabs.create<Section>> = UiTabs.create<Section>()
const sections: Record<Section, { readonly label: string; readonly text: string }> = {
overview: { label: 'Overview', text: 'Six people, three open milestones, one launch.' },
activity: { label: 'Activity', text: 'Ada published the pricing page an hour ago.' },
settings: { label: 'Settings', text: 'Who can see the project, and who can edit it.' },
}
/** The tabs' focus is the component's; which tab shows is the Model's. */
export interface TabsState {
readonly tabs: UiTabs.Model
readonly section: Section
}
export const tabs = <Message>(
style: NamedStyle<typeof TabsSlots>,
state: TabsState,
toMessage: (message: UiTabs.Message) => Message,
h: HtmlBuilder<Message>,
): Html =>
h.submodel({
slotId: state.tabs.id,
model: state.tabs,
view: SectionTabs.view,
viewInputs: {
tabs: Section.literals,
selectedValue: state.section,
ariaLabel: 'Project',
toView: Tabs.toView<Section, Message>(
[style.mixin, ...Tabs.fluid],
{ h },
({ tablist, indicator, highlight, tabs, activeIndex }) =>
h.div(
[],
[
h.div(tablist, [
h.div(indicator),
h.div(highlight),
...tabs.map(tab => h.button(tab.tab, [sections[tab.value].label])),
]),
...tabs
.filter(tab => tab.index === activeIndex)
.map(tab => h.div(tab.panel, [h.p([], [sections[tab.value].text])])),
],
),
),
},
toParentMessage: toMessage,
})