Skip to content

Commit

Permalink
feat(Tabs): Enhance parent width handling and remove auto edge detection
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Feb 21, 2022
1 parent e4d0a79 commit d002f2c
Show file tree
Hide file tree
Showing 7 changed files with 472 additions and 346 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const TabsExampleUsingData = () => (
)

export const TabsExampleScrollable = () => (
<MaxWidth>
<Wrapper>
<ComponentBox
data-visual-test="tabs-tablist-scrollable"
scope={{ manyTabs, manyTabsContent }}
Expand All @@ -109,7 +109,7 @@ export const TabsExampleScrollable = () => (
</Tabs>
`}
</ComponentBox>
</MaxWidth>
</Wrapper>
)

export const TabsExampleLeftAligned = () => (
Expand All @@ -129,56 +129,97 @@ export const TabsExampleLeftAligned = () => (
</Wrapper>
)

export class TabsExampleRightAligned extends React.PureComponent {
state = { activeTabKey: 'second' }
openTab = ({ key }) => {
this.setState({
activeTabKey: key,
})
}
isActive(tabKey) {
return this.state.activeTabKey === tabKey
}
export const TabsExampleHorizontalAligned = () => (
<ComponentBox
data-visual-test="tabs-horizontal-aligned"
scope={{ manyTabs }}
useRender
>
{() => /* jsx */ `
render() {
const { activeTabKey } = this.state
const openTab = this.openTab
return (
<Wrapper>
<ComponentBox
data-visual-test="tabs-tablist-right-aligned"
scope={{ exampleContent, activeTabKey, openTab, data }}
>
{() => /* jsx */ `
<Tabs
selected_key={activeTabKey}
align="right"
label="Some Tabs label"
data={data}
on_change={openTab}
render={({ Wrapper, Content, TabsList, Tabs }) => {
const FlexWrapper = styled.div\`
display: flex;
flex-direction: row;
\`
const MaxWidthWrapper = styled.div\`
max-width: 30rem;
background: var(--color-mint-green-12);
\`
const LeftArea = styled.div\`
/* Ensure no-wrap */
flex-shrink: 0;
\`
const RightArea = styled.div\`
/* Ensure the tabbar is hidden outside this area */
overflow: hidden;
/* Ensure the focus ring is visible! (because of overflow: hidden) */
margin: -2px;
padding: 2px;
\`
function TabsHorizontalAligned() {
return (
<Wrapper>
<TabsList className="dnb-section">
<small>
<b>Active:</b> {activeTabKey}
</small>
<Tabs />
</TabsList>
<Content />
</Wrapper>
<FlexWrapper>
<LeftArea>
<ToggleButton.Group value="first">
<ToggleButton text="first" value="first" />
<ToggleButton text="second" value="second" />
</ToggleButton.Group>
</LeftArea>
<RightArea>
<Tabs
left
no_border
selected_key="first"
id="unique-tabs-row"
data={manyTabs}
/>
</RightArea>
</FlexWrapper>
)
}}
>
{ exampleContent /* See Example Content below */ }
</Tabs>
}
render(<TabsHorizontalAligned />)
`}
</ComponentBox>
</Wrapper>
)
}
</ComponentBox>
)

export const TabsExampleMaxWidth = () => (
<ComponentBox
data-visual-test="tabs-max-width"
scope={{ manyTabs }}
useRender
>
{() => /* jsx */ `
const MaxWidthWrapper = styled.div\`
max-width: 30rem;
background: var(--color-mint-green-12);
\`
function TabsMaxWidth() {
return (
<MaxWidthWrapper>
<Tabs
top
no_border
selected_key="fifth"
id="unique-tabs-max-width"
data={manyTabs}
/>
</MaxWidthWrapper>
)
}
render(<TabsMaxWidth />)
`}
</ComponentBox>
)

export const TabsExampleReactRouterNavigation = () =>
typeof window === 'undefined' ? null : (
<Wrapper>
Expand Down Expand Up @@ -275,12 +316,6 @@ const exampleContent = {
fourth: 'Fourth as a string only',
}

const data = [
{ title: 'First', key: 'first' },
{ title: 'Second', key: 'second' },
{ title: 'Third', key: 'third', disabled: true },
{ title: 'Fourth', key: 'fourth' },
]
const manyTabs = [
{ title: 'First', key: 'first' },
{ title: 'Second', key: 'second' },
Expand All @@ -304,18 +339,6 @@ const Wrapper = styled.div`
}
`

// The example has a `max-width` of 60rem.
const MaxWidth = styled(Wrapper)`
/* @media screen and (max-width: 40em) {
NB: Now this gets handled automatically
.dnb-tabs .dnb-tabs__tabs {
margin: 0 -4rem;
}
.dnb-tabs .dnb-tabs__tabs__tablist {
padding: 0 4rem;
}
} */
`
export const TabsNoBorder = () => (
<Wrapper>
<ComponentBox data-visual-test="tabs-no-border">
Expand All @@ -331,4 +354,4 @@ export const TabsNoBorder = () => (
`}
</ComponentBox>
</Wrapper>
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ TabsExampleContentObject,
TabsExampleScrollable,
TabsExampleLeftAligned,
TabsExampleUsingData,
TabsExampleRightAligned,
TabsExampleHorizontalAligned,
TabsExampleMaxWidth,
TabsExampleReachRouterNavigation,
TabsExampleReactRouterNavigation,
TabsNoBorder,
Expand Down Expand Up @@ -40,31 +41,23 @@ Also, this is an example of how to define a different content background color,

<TabsExampleLeftAligned />

### Right aligned tabs
### Tabs without bottom border

<TabsNoBorder />

<TabsExampleRightAligned />
### Tabs optimized for narrow screens

### Tabs optimized for mobile
Navigation buttons will be shown and the tabs-list will be scrollable.

<TabsExampleScrollable />

**Notes about the mobile view:** The Tabs component does automatically calculate the remaining spacing once the screen gets under `40em` in width.
But depending on your setup, you may have to align your Tabs all the way to the edge of the browser window. E.g. with a negative margin:

```css
@media screen and (min-width: 40em) {
.dnb-tabs .dnb-tabs__tabs {
margin: 0 -2rem;
}
.dnb-tabs .dnb-tabs__tabs__tablist {
padding: 0 2rem;
}
}
```
### Horizontal aligned tabs

### Tabs without bottom border
<TabsExampleHorizontalAligned />

<TabsNoBorder />
### max-width usage

<TabsExampleMaxWidth />

### Router navigation with Reach Router

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,24 @@ showTabs: true

## Properties

| Properties | Description |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `selected_key` | _(optional)_ in case one of the tabs should be opened by a `key`. |
| `align` | _(optional)_ to align the tab list on the right side `align="right"`. Default to `left`. |
| `content_style` | _(optional)_ to enable the visual helper `.dnb-section` on to the content wrapper. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `null`. |
| Properties | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `selected_key` | _(optional)_ in case one of the tabs should be opened by a `key`. |
| `align` | _(optional)_ to align the tab list on the right side `align="right"`. Default to `left`. |
| `content_style` | _(optional)_ to enable the visual helper `.dnb-section` on to the content wrapper. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `null`. |
| `content_spacing` | _(optional)_ to modify the `spacing` onto the content wrapper. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `true`. |
| `tabs_style` | _(optional)_ to enable the visual helper `.dnb-section` inside the tabs list. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `null`. |
| `tabs_style` | _(optional)_ to enable the visual helper `.dnb-section` inside the tabs list. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `null`. |
| `tabs_spacing` | _(optional)_ to modify the `spacing` inside the tab list. Use a supported modifier from the [Section component](/uilib/components/section/properties). Defaults to `false`. |
| `tab_element` | _(optional)_ define what HTML element should be used. You can provide e.g. `tab_element={GatsbyLink}` – you may then provide the `to` property inside every entry (`data={[{ to: 'url', ... }]}`). Defaults to `<button>`. |
| `data` | _(required)_ defines the data structure to load as a JSON. e.g. `[{title: '...', content: 'Current tab', key | hash: '...'}]` |
| `tab_element` | _(optional)_ define what HTML element should be used. You can provide e.g. `tab_element={GatsbyLink}` – you may then provide the `to` property inside every entry (`data={[{ to: 'url', ... }]}`). Defaults to `<button>`. |
| `data` | _(required)_ defines the data structure to load as a JSON. e.g. `[{title: '...', content: 'Current tab', key | hash: '...'}]` |
| `children` or `content` | _(required)_ the content to render. Can be a function, returning the current tab content `(key) => ('Current tab')`, a React Component or an object with the keys and content `{key1: 'Current tab'}`. |
| `prerender` | _(optional)_ if set to `true`, the Tabs content will pre-render all contents. The visibility will be handled by using the `hidden` and `aria-hidden` HTML attributes. Defaults to `false`. |
| `prerender` | _(optional)_ if set to `true`, the Tabs content will pre-render all contents. The visibility will be handled by using the `hidden` and `aria-hidden` HTML attributes. Defaults to `false`. |
| `prevent_rerender` | _(optional)_ if set to `true`, the Tabs content will stay in the DOM. The visibility will be handled by using the `hidden` and `aria-hidden` HTML attributes. Similar to `prerender`, but in contrast, the content will render once the user is activating a tab. Defaults to `false`. |
| `scroll` | _(optional)_ if set to `true`, the content will scroll on tab change, until all tabs will be visible on the upper side of the browser window view. Defaults to `false`. |
| `no_border` | _(optional)_ if set to `true`, the default horizontal border line under the tablist will be removed. Defaults to `false`. |
| `skeleton` | _(optional)_ if set to `true`, an overlaying skeleton with animation will be shown. |
| [Space](/uilib/components/space/properties) | _(optional)_ spacing properties like `top` or `bottom` are supported. |
| `scroll` | _(optional)_ if set to `true`, the content will scroll on tab change, until all tabs will be visible on the upper side of the browser window view. Defaults to `false`. |
| `no_border` | _(optional)_ if set to `true`, the default horizontal border line under the tablist will be removed. Defaults to `false`. |
| `nav_button_edge` | _(optional)_ if set to `true`, the navigation icons will have a straight border at their outside. This feature is meant to be used when the Tabs component goes all the way to the browser window. Defaults to `false`. |
| `skeleton` | _(optional)_ if set to `true`, an overlaying skeleton with animation will be shown. |
| [Space](/uilib/components/space/properties) | _(optional)_ spacing properties like `top` or `bottom` are supported. |

## Key

Expand Down
Loading

0 comments on commit d002f2c

Please sign in to comment.