コンテンツにスキップ

Tabs

タブ要素を作成できるコンポーネントです。
スタイリングは最低限にしているので、適宜カスタマイズしてご利用ください。

Props

プロパティ説明
<Tabs.Root>
variant
d--tabs--{variant}クラスが出力されます。デフォルトは"default"です。
<Tabs.Root>
keepHeight
[data-tabs-height="keep"]が出力され、タブの高さを一番コンテンツ量の多いパネルに合わせて固定することができます。
<Tabs.Root>
defaultIndex
最初に開いておくタブ番号を指定できます。
<Tabs.Root>
tabProps,listProps,panelProps
それぞれタブボタン部分、リスト部分、パネル部分に対するpropsを指定できます。
<Tabs.Item>
label
タブテキストを指定します。

ボタンカラーについて

平常時のカラーと、アクティブ時のカラーをそれぞれ専用の変数で管理しています。

:where(.d--tabs) {
--tab-c: var(--c--text);
--tab-c--active: var(--c--base);
--tab-bgc: var(--c--base-2);
--tab-bgc--active: var(--c--text);
}

Import

import { Tabs } from '@lism-ui/core';

Usage

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

<Tabs.Root g='20'>
<Tabs.Item label='Tab 1'>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

各タブテキストは<Tabs.Item>labelで指定できますが、jsx式を使いたい場合、Astroではslot='label'を使ってください。

タブテキストにJSX式を渡す例

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

<Tabs.Root g='20'>
<Tabs.Item label={<><Icon isInline icon='good'/> Tab <small>small text</small></>}>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

<Tabs.Root>ji='center' を指定すると、タブボタンを中央寄せにすることができます。

タブリストの中央寄せ

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

<Tabs.Root g='20' ji='center'>
<Tabs.Item label='Tab 1'>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

高さが変わらないようにする

タブを切り替えた時、デフォルトでは、表示されるコンテンツ量が変わることでタブ全体の高さも変わります。
<Tabs.Root>keepHeight([data-tabs-height="keep"]) を指定すると、タブの高さを一番コンテンツ量の多いパネルに合わせて固定することができます。

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

<Tabs.Root keepHeight g='20'>
<Tabs.Item label='Tab 1'>
<p>...</p>
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<p>...</p>
</Tabs.Item>
</Tabs.Root>

最初に開いておくタブ番号を指定する

<Tabs.Root>defaultIndex で、最初に開いておくタブ番号を指定できます。
(インデックス番号は0から始まります。)

index:1

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi provident libero, eum nulla sunt, porro sed dicta. Impedit ullam eveniet obcaecati minima.

<Tabs.Root defaultIndex={1} g='20'>
<Tabs.Item label='Tab 1'>
<p>index:0</p>
<p>...</p>
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<p>index:1</p>
<p>...</p>
</Tabs.Item>
</Tabs.Root>

Tabs 子要素に対するpropsの指定

<Tabs.Root>tabProps,listProps, panelProps を指定でき、それぞれタブボタン部分、リスト部分、パネル部分に対するpropsを指定できます。

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

リサイズ可能
<Tabs.Root bgc='base-2' bxsh='2' isFlow='s'
style={{'--tab-bgc':'transparent'}}
tabProps={{px:'30', py:'20', fx:'1', whs:'nw', mb:'-1px'}}
listProps={{fz:'m',bd:'b'}}
panelProps={{p:'40'}}
>
<Tabs.Item label='Tab 1'>
<Dummy />
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<Dummy />
<Dummy length='l' />
</Tabs.Item>
<Tabs.Item label='Tab 3'>
<Dummy length='s'/>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 4'>
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

タブコンテンツを横並び配置にする

<Tabs.Root>(.d--tabs)にgrid:var(--gd--hz); を指定すると、タブリストとコンテンツが横並びになります。

それと同時に、タブリスト(.d--tabs__list)のボタンを縦並び(flex-direction:column;)に変更すると、以下のようなレイアウトが実現できます。

@smサイズより大きい場合、コンテンツを横並びにする例

index:0

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

リサイズ可能
<Tabs.Root keepHeight colg='30' rowg='20' gd={[null, 'var(--gd--hz)']} listProps={{fxd: [null, 'column']}} isFlow='s' >
<Tabs.Item label='Tab 1'>
<p>index:0</p>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<p>index:1</p>
<Dummy />
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

<Tabs.Root>isHorizontalを指定すると、上記のgd,listPropsが自動的に適用されるようにもなっています。

スタイルバリエーションの作成例

コアではスタイルを特に持ちませんので、サイトごとにスタイルを用意してご利用ください。
ここでは、いくつかその例を紹介します。

variant='line'

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

リサイズ可能
:where(.d--tabs--line) {
--tab-c: var(--c--text);
--tab-c--active: var(--c--text);
--tab-bgc: transparent;
--tab-bgc--active: transparent;
--sh-size: inset 0 -2px;
.d--tabs__list {
box-shadow: var(--sh-size) 0 var(--c--divider);
}
.d--tabs__tab[aria-selected='true'] {
box-shadow: var(--sh-size) 0 0 currentColor;
}
}
variant='emboss'

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

リサイズ可能
:where(.d--tabs--emboss) {
--tab-c: var(--c--text);
--tab-c--active: var(--c--text);
--tab-bgc: transparent;
--tab-bgc--active: var(--c--base);
> .d--tabs__list {
background-color: var(--c--base-2);
padding: 4px;
gap: 0.5em;
border-radius: var(--bdrs--2);
}
.d--tabs__tab {
border-radius: calc(var(--bdrs--2) - 2px);
}
.d--tabs__tab:where([aria-selected='true']) {
box-shadow: var(--bxsh--1);
}
}
variant='emboss'でisHorizontalがオン

index:0

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

リサイズ可能
<Tabs.Root variant='emboss' isHorizontal keepHeight g='30' ai='s' ji='c' isFlow='s'>
<Tabs.Item label='Tab 1'>
<p>index:0</p>
<Dummy />
</Tabs.Item>
<Tabs.Item label='Tab 2'>
<p>index:1</p>
<Dummy />
<Dummy length='l' />
</Tabs.Item>
</Tabs.Root>

Tabs.Itemを使わない書き方

より柔軟にタブコンテンツをカスタマイズしたい場合、<Tabs.Item>を使わずに、<Tabs.List>,<Tabs.Tab>,<Tabs.Panel>を使って書くこともできます。

ただし、ReactとAstroでは少し書き方が異なるので注意してください

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor.

Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.

<Tabs.Root uid='tab-uid' defaultIndex={0} g='20'>
<Tabs.List>
<Tabs.Tab index={0}>
<Icon isInline icon='good' /> Tab 1
</Tabs.Tab>
<Tabs.Tab index={1}>
<Icon isInline icon='bad' /> Tab 2
</Tabs.Tab>
</Tabs.List>
<Tabs.Panel index={0}>
<Dummy length='s' />
<Dummy />
</Tabs.Panel>
<Tabs.Panel index={1}>
<Dummy length='l' />
</Tabs.Panel>
</Tabs.Root>