AppNavi

処理中
ドラッグして幅を変更
ドラッグして高さを変更
import { action } from '@storybook/addon-actions'
import { Story } from '@storybook/react'
import React, { FC, ReactNode } from 'react'
import styled, { css } from 'styled-components'
import { FaBirthdayCakeIcon, FaChartPieIcon, FaCogIcon, FaFileIcon, FaUserAltIcon } from '../Icon'
import { AppNavi } from './AppNavi'
export default {
title: 'Navigation(ナビゲーション)/AppNavi',
component: AppNavi,
parameters: {
withTheming: true,
},
}
const Link: FC<{ to: string; children: ReactNode; disabled?: boolean; className?: string }> = ({
to,
children,
disabled = false,
className = '',
...props
}) => (
// eslint-disable-next-line smarthr/a11y-anchor-has-href-attribute
<a {...props} {...(disabled ? {} : { href: to })} className={className}>
{children}
</a>
)
const List: FC = () => {
return (
<ListWrapper>
<li>
<button onClick={action('clicked item 1')}>ドロップダウンアイテム1</button>
</li>
<li>
<button onClick={action('clicked item 2')}>ドロップダウンアイテム2</button>
</li>
<li>
<button onClick={action('clicked item 3')}>ドロップダウンアイテム3</button>
</li>
<li>
<button onClick={action('clicked item 4')}>ドロップダウンアイテム4</button>
</li>
</ListWrapper>
)
}
const buttons = [
{
children: 'カレントボタン',
icon: FaFileIcon,
current: true,
onClick: action('click!!'),
},
{
children: 'ボタン',
icon: FaUserAltIcon,
onClick: action('click!!'),
},
{
children: 'アンカー',
icon: FaCogIcon,
href: '/',
},
{
children: 'ドロップダウン',
icon: FaChartPieIcon,
dropdownContent: <List />,
},
{
children: 'カスタムタグ',
icon: FaBirthdayCakeIcon,
tag: Link,
href: '/',
},
]
const withoutIconButtons = buttons.map(({ icon, ...button }) => button)
export const WithChildren: Story = () => {
return (
<Wrapper>
<AppNavi label="機能名" buttons={withoutIconButtons} displayDropdownCaret>
<Child>Some child components</Child>
</AppNavi>
</Wrapper>
)
}
WithChildren.storyName = 'with children'
export const WithoutChildren: Story = () => {
return (
<Wrapper>
<AppNavi label="機能名" buttons={withoutIconButtons} displayDropdownCaret />
</Wrapper>
)
}
WithoutChildren.storyName = 'without children'
export const UnclickableCurrent: Story = () => {
const items = buttons.map(({ current, ...button }) => button)
return (
<Wrapper>
{items.map((_, currentIndex) => (
<InnerWrapper key={currentIndex}>
<AppNavi
label="機能名"
buttons={items.map((item, index) => {
if (index === currentIndex) {
return { ...item, current: true }
}
return item
})}
isCurrentUnclickable
displayDropdownCaret
/>
</InnerWrapper>
))}
</Wrapper>
)
}
UnclickableCurrent.storyName = 'unclickable current'
export const NoIconAndCaret: Story = () => {
return (
<Wrapper>
<AppNavi label="機能名" buttons={buttons} />
</Wrapper>
)
}
NoIconAndCaret.storyName = 'アイコンありドロップダウン示唆なし'
export const ContainerScrollX: Story = () => {
return (
<OverflowWrapper>
<AppNavi label="機能名" buttons={withoutIconButtons} displayDropdownCaret>
<Child>Some child components</Child>
</AppNavi>
</OverflowWrapper>
)
}
ContainerScrollX.storyName = '横スクロールさせる場合'
const Wrapper = styled.div`
${({ theme }) => {
const { color } = theme
return css`
padding: 32px 0;
background-color: ${color.BACKGROUND};
`
}}
`
const OverflowWrapper = styled(Wrapper)`
overflow-x: auto;
`
const Child = styled.p`
margin: 0 0 0 auto;
`
const InnerWrapper = styled.div`
margin-bottom: 40px;
`
const ListWrapper = styled.ul(
({ theme: { color } }) => css`
margin: 0;
padding: 8px 0;
list-style: none;
& > li > button {
line-height: 40px;
width: 100%;
padding: 0 20px;
border: none;
background-color: ${color.WHITE};
color: ${color.TEXT_BLACK};
&:hover {
background-color: ${color.hoverColor(color.WHITE)};
}
}
`,
)
処理中

Props

AppNavi props

label
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

ラベルのテキスト

buttons
(AppNaviDropdownProps | AppNaviCustomTagProps | AppNaviButtonProps | AppNaviAnchorProps)[]

表示するボタンの Props の配列

isCurrentUnclickable
falsetrue

アクティブ状態のボタンがクリック可能かどうか

children
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

追加で表示する内容

className
string

コンポーネントに適用するクラス名

displayDropdownCaret
falsetrue

ドロップダウンにキャレットを表示するかどうか

AppNaviButton props

children必須
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

ボタンのテキスト

icon
FunctionComponent<ComponentProps>ComponentClass<ComponentProps, any>

表示するアイコンタイプ

current
falsetrue

アクティブ状態であるかどうか

onClick
(e: MouseEvent<HTMLButtonElement, MouseEvent>) => void

クリックイベントのハンドラ

isUnclickable
falsetrue

AppNaviAnchor props

children必須
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

アンカーのテキスト

href必須
string

アンカーの href

icon
FunctionComponent<ComponentProps>ComponentClass<ComponentProps, any>

表示するアイコンタイプ

current
falsetrue

アクティブ状態であるかどうか

isUnclickable
falsetrue

AppNaviDropdown props

children必須
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

ボタンのテキスト

dropdownContent必須
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

ドロップダウンのコンテンツ

icon
FunctionComponent<ComponentProps>ComponentClass<ComponentProps, any>

表示するアイコンタイプ

current
falsetrue

アクティブ状態であるかどうか

isUnclickable
falsetrue
displayCaret
falsetrue

AppNaviCustomTag props

children必須
stringnumberfalsetrueReactElement<any, string | JSXElementConstructor<any>>ReactFragmentReactPortal

ボタンのテキスト

tag必須
ComponentClass<any, any>FunctionComponent<any>

このボタンのカスタムタグ

icon
FunctionComponent<ComponentProps>ComponentClass<ComponentProps, any>

表示するアイコンタイプ

current
falsetrue

アクティブ状態であるかどうか

isUnclickable
falsetrue