Skip to content

Commit

Permalink
feat: Expander component (vertical tabs). Closes #33
Browse files Browse the repository at this point in the history
  • Loading branch information
lo5 committed Jul 16, 2022
1 parent ce9061b commit aebcd07
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 11 deletions.
50 changes: 50 additions & 0 deletions docs/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,58 @@ view(
![Screenshot](assets/screenshots/layout_tabs.png)


## Lay out in tabs vertically

Set `layout='column'` to lay out tabs one below the other.


```py
view(
box(
mode='tabs',
layout='column',
items=[
box(
'Profile',
icon='Contact',
items=[
box('First name', value='Boaty'),
box('Last name', value='McBoatface'),
box('Age', value=42)
],
),
box(
'Billing Address',
icon='PaymentCard',
items=[
box('Billing address line 1', value=''),
box('Billing address line 2', value=''),
row(box('City', value=''), box('State', value=''), box('Zip', value='')),
],
),
box(
'Shipping Address',
icon='DeliveryTruck',
items=[
box('Shipping address line 1', value=''),
box('Shipping address line 2', value=''),
row(box('City', value=''), box('State', value=''), box('Zip', value='')),
],
),
]
)
)
```


![Screenshot](assets/screenshots/layout_tabs_vertical.png)


## Show icons on tabs

Set `icon=` on each tab to show an icon on the tab.


```py
view(
box(
Expand Down
41 changes: 41 additions & 0 deletions py/pkg/docs/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,48 @@ def layout_tabs(view: View): # height 5
)


# ## Lay out in tabs vertically
# Set `layout='column'` to lay out tabs one below the other.
def layout_tabs_vertical(view: View): # height 5
view(
box(
mode='tabs',
layout='column',
items=[
box(
'Profile',
icon='Contact',
items=[
box('First name', value='Boaty'),
box('Last name', value='McBoatface'),
box('Age', value=42)
],
),
box(
'Billing Address',
icon='PaymentCard',
items=[
box('Billing address line 1', value=''),
box('Billing address line 2', value=''),
row(box('City', value=''), box('State', value=''), box('Zip', value='')),
],
),
box(
'Shipping Address',
icon='DeliveryTruck',
items=[
box('Shipping address line 1', value=''),
box('Shipping address line 2', value=''),
row(box('City', value=''), box('State', value=''), box('Zip', value='')),
],
),
]
)
)


# ## Show icons on tabs
# Set `icon=` on each tab to show an icon on the tab.
def layout_tabs_icons(view: View): # height 5
view(
box(
Expand Down
53 changes: 53 additions & 0 deletions web/src/expander.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 H2O.ai, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { ActionButton, IButtonStyles, IIconProps } from '@fluentui/react';
import React from 'react';
import styled from 'styled-components';
import { S, signal } from './core';
import { make } from './ui';

const
iconOpen: IIconProps = { iconName: 'ChevronDownMed' },
iconClose: IIconProps = { iconName: 'ChevronRightMed' },
bodyOpenStyle: React.CSSProperties = { display: 'block' },
bodyCloseStyle: React.CSSProperties = { display: 'none' },
buttonStyles: IButtonStyles = { root: { padding: 0 } }

const
Body = styled.div`
padding: 0 0 10px 30px;
`

export const Expander = make(({ headerText, children }: { headerText: S, children: JSX.Element }) => {
const
expandedB = signal(false),
toggle = () => expandedB(!expandedB()),
render = () => {
const expanded = expandedB()
return (
<div>
<div>
<ActionButton
iconProps={expanded ? iconOpen : iconClose}
onClick={toggle}
styles={buttonStyles}
>{headerText}</ActionButton>
</div>
<Body style={expanded ? bodyOpenStyle : bodyCloseStyle}>{children}</Body>
</div>
)
}
return { render, expandedB }
})
33 changes: 22 additions & 11 deletions web/src/zone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import styled from 'styled-components';
import { XBox } from './box';
import { ClientContext } from './client';
import { B, Dict, isS, S } from './core';
import { Expander } from './expander';
import { Help } from './help';
import { ImageBlock } from './image';
import { Box } from './protocol';
Expand Down Expand Up @@ -202,25 +203,35 @@ const Container = styled.div`
`
export const Zone = ({ context, box, inRow }: { context: ClientContext, box: Box, inRow: B }) => {
const
{ mode, items } = box,
{ mode, items, layout } = box,
isRow = mode === 'row',
style = computeStyle(box, inRow)

if (items) {
switch (mode) {
case 'tabs':
{
const tabs = items.map((box, i) => (
<PivotItem key={box.xid} headerText={box.text ?? `Tab ${i + 1}`} itemIcon={box.icon ?? undefined}>
<Zone key={box.xid} context={context} box={box} inRow={isRow} />
</PivotItem>
))
return (
<Container data-name={box.name ?? undefined} style={style}>
<Pivot>{tabs}</Pivot>
</Container>
)
if (layout === 'column') {
const tabs = items.map((box, i) => (
<Expander key={box.xid} headerText={box.text ?? `Tab ${i + 1}`}>
<Zone key={box.xid} context={context} box={box} inRow={isRow} />
</Expander>
))
return <Container data-name={box.name ?? undefined} style={style}>{tabs}</Container>
} else {
const tabs = items.map((box, i) => (
<PivotItem key={box.xid} headerText={box.text ?? `Tab ${i + 1}`} itemIcon={box.icon ?? undefined}>
<Zone key={box.xid} context={context} box={box} inRow={isRow} />
</PivotItem>
))
return (
<Container data-name={box.name ?? undefined} style={style}>
<Pivot>{tabs}</Pivot>
</Container>
)
}
}
break
default:
{
const children = items.map(box => (
Expand Down

0 comments on commit aebcd07

Please sign in to comment.