美しいオーバーレイ、ツールチップ、ポップオーバー、その他必要なものを配置するためのコンポーネントのセットです。
React-Bootstrapのオーバーレイコンポーネントについて知っておくべきこと。
- オーバーレイは、サードパーティライブラリのPopper.jsに依存しています。これはReact-Bootstrapに自動的に含まれていますが、より高度なユースケースについてはAPIを参照する必要があります。
<Tooltip>
および<Popover>
コンポーネントは、それ自体を配置しません。代わりに、<Overlay>
(または<OverlayTrigger>
)コンポーネントがref
およびstyle
プロパティを注入します。
- Tooltipは、
<Overlay>
コンポーネントによって注入された特定のプロパティを予期します。
disabled
要素のツールチップは、ラッパー要素でトリガーする必要があります。
オーバーレイ
Overlay
は、ツールチップの配置と可視性を制御するための基本コンポーネントです。これはPopper.jsのラッパーであり、トランジションと可視性の切り替えのサポートを追加します。
オーバーレイの作成
オーバーレイは、少なくとも2つの要素で構成されます。配置される要素である「オーバーレイ」と、オーバーレイが配置される基準となる要素である「ターゲット」です。また、ツールチップやポップオーバーのように、「矢印」要素を持つこともできますが、これはオプションです。注入されたプロパティの詳細については、Popperのドキュメントを確認してください。
import { useState, useRef } from 'react';
import Button from 'react-bootstrap/Button';
import Overlay from 'react-bootstrap/Overlay';
function Example() {
const [show, setShow] = useState(false);
const target = useRef(null);
return (
<>
<Button variant="danger" ref={target} onClick={() => setShow(!show)}>
Click me to see
</Button>
<Overlay target={target.current} show={show} placement="right">
{({
placement: _placement,
arrowProps: _arrowProps,
show: _show,
popper: _popper,
hasDoneInitialMeasure: _hasDoneInitialMeasure,
...props
}) => (
<div
{...props}
style={{
position: 'absolute',
backgroundColor: 'rgba(255, 100, 100, 0.85)',
padding: '2px 10px',
color: 'white',
borderRadius: 3,
...props.style,
}}
>
Simple tooltip
</div>
)}
</Overlay>
</>
);
}
export default Example;
オーバーレイレンダリングのカスタマイズ
Overlay
は、レンダリング動作をカスタマイズするために使用できる多くのプロパティを注入します。Popper
が適切に測定および配置できる前に、オーバーレイを表示する必要がある場合があります。React-Bootstrapでは、ツールチップとポップオーバーは、オーバーレイの初期位置が正しくないという問題を回避するために、不透明度と位置を設定します。これがどのように行われるかの例については、Tooltipの実装を参照してください。
OverlayTrigger
上記のようなパターンは非常に一般的ですが、冗長であるため、一般的なユースケースを支援するために<OverlayTrigger>
コンポーネントが含まれています。遅延表示または非表示の機能や、組み合わせることができるいくつかの異なる「トリガー」イベントも備えています。
トリガーコンポーネントは、<OverlayTrigger>
が追加を試みるため、refを受け入れることができる必要があります。関数コンポーネントには、forwardRef()を使用できます。
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
function TriggerExample() {
const renderTooltip = (props) => (
<Tooltip id="button-tooltip" {...props}>
Simple tooltip
</Tooltip>
);
return (
<OverlayTrigger
placement="right"
delay={{ show: 250, hide: 400 }}
overlay={renderTooltip}
>
<Button variant="success">Hover me to see</Button>
</OverlayTrigger>
);
}
export default TriggerExample;
トリガー動作のカスタマイズ
より高度な動作のために、<OverlayTrigger>
は、設定されたtrigger
プロパティに対応する注入されたref
とイベントハンドラーを渡す関数子を受け入れます。
プロパティを手動で任意の要素に適用したり、分割したりできます。以下の例は、オーバーレイの可視性をトリガーする要素とは異なる要素にオーバーレイを配置する方法を示しています。
OverlayTriggerの関数形式を使用すると、厳密モードに準拠しようとするユーザーにとって、React.findDOMNode
の呼び出しを回避できます。
import Button from 'react-bootstrap/Button';
import Image from 'react-bootstrap/Image';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
function TriggerRendererProp() {
return (
<OverlayTrigger
placement="bottom"
overlay={<Tooltip id="button-tooltip-2">Check out this avatar</Tooltip>}
>
{({ ref, ...triggerHandler }) => (
<Button
variant="light"
{...triggerHandler}
className="d-inline-flex align-items-center"
>
<Image
ref={ref}
roundedCircle
src="holder.js/20x20?text=J&bg=28a745&fg=FFF"
/>
<span className="ms-1">Hover to see</span>
</Button>
)}
</OverlayTrigger>
);
}
export default TriggerRendererProp;
アンカータグのよりスタイリッシュな代替としてのツールチップコンポーネント
title
属性。
ツールチップを表示するには、以下のリンクにカーソルを合わせてください。
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
function TooltipInCopyExample() {
const Link = ({ id, children, title }) => (
<OverlayTrigger overlay={<Tooltip id={id}>{title}</Tooltip>}>
<a href="#">{children}</a>
</OverlayTrigger>
);
return (
<p>
Tight pants next level keffiyeh{' '}
<Link title="Default title" id="t-1">
you probably
</Link>{' '}
haven't heard of them. Farm-to-table seitan, mcsweeney's fixie sustainable
quinoa 8-bit american apparel{' '}
<Link id="t-2" title="Another one">
have a
</Link>{' '}
terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo
thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's
cleanse vegan chambray. A really ironic artisan{' '}
<Link title="Another one here too" id="t-3">
whatever keytar
</Link>
, scenester farm-to-table banksy Austin{' '}
<Link title="The last tip!" id="t-4">
twitter handle
</Link>{' '}
freegan cred raw denim single-origin coffee viral.
</p>
);
}
export default TooltipInCopyExample;
Overlay
が注入したプロパティをTooltipコンポーネントに直接渡すことができます。
import { useState, useRef } from 'react';
import Button from 'react-bootstrap/Button';
import Overlay from 'react-bootstrap/Overlay';
import Tooltip from 'react-bootstrap/Tooltip';
function Example() {
const [show, setShow] = useState(false);
const target = useRef(null);
return (
<>
<Button ref={target} onClick={() => setShow(!show)}>
Click me!
</Button>
<Overlay target={target.current} show={show} placement="right">
{(props) => (
<Tooltip id="overlay-example" {...props}>
My Tooltip
</Tooltip>
)}
</Overlay>
</>
);
}
export default Example;
または、代わりにTooltip要素をOverlayTrigger
に渡します。
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
function TooltipPositionedExample() {
return (
<>
{['top', 'right', 'bottom', 'left'].map((placement) => (
<OverlayTrigger
key={placement}
placement={placement}
overlay={
<Tooltip id={`tooltip-${placement}`}>
Tooltip on <strong>{placement}</strong>.
</Tooltip>
}
>
<Button variant="secondary">Tooltip on {placement}</Button>
</OverlayTrigger>
))}
</>
);
}
export default TooltipPositionedExample;
ポップオーバー
iOSにあるようなポップオーバーコンポーネント。
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Popover from 'react-bootstrap/Popover';
const popover = (
<Popover id="popover-basic">
<Popover.Header as="h3">Popover right</Popover.Header>
<Popover.Body>
And here's some <strong>amazing</strong> content. It's very engaging.
right?
</Popover.Body>
</Popover>
);
const Example = () => (
<OverlayTrigger trigger="click" placement="right" overlay={popover}>
<Button variant="success">Click me to see</Button>
</OverlayTrigger>
);
render(<Example />);
<Tooltip>
と同様に、Popoverの配置を制御できます。
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Popover from 'react-bootstrap/Popover';
function PopoverPositionedExample() {
return (
<>
{['top', 'right', 'bottom', 'left'].map((placement) => (
<OverlayTrigger
trigger="click"
key={placement}
placement={placement}
overlay={
<Popover id={`popover-positioned-${placement}`}>
<Popover.Header as="h3">{`Popover ${placement}`}</Popover.Header>
<Popover.Body>
<strong>Holy guacamole!</strong> Check this info.
</Popover.Body>
</Popover>
}
>
<Button variant="secondary">Popover on {placement}</Button>
</OverlayTrigger>
))}
</>
);
}
export default PopoverPositionedExample;
無効な要素
disabled
属性を持つ要素はインタラクティブではなく、ユーザーがそれらにカーソルを合わせたりクリックしたりしてポップオーバー(またはツールチップ)をトリガーすることはできません。回避策として、ラッパー<div>
または<span>
からオーバーレイをトリガーし、無効な要素のpointer-events
をオーバーライドする必要があります。
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
function DisabledExample() {
return (
<OverlayTrigger overlay={<Tooltip id="tooltip-disabled">Tooltip!</Tooltip>}>
<span className="d-inline-block">
<Button disabled style={{ pointerEvents: 'none' }}>
Disabled button
</Button>
</span>
</OverlayTrigger>
);
}
export default DisabledExample;
コンテナーの変更
オーバーレイが追加されるDOM要素を制御するためにcontainer
を指定できます。これは、スタイルがオーバーレイと競合する場合に特に役立ちます。
import { useState, useRef } from 'react';
import Button from 'react-bootstrap/Button';
import Overlay from 'react-bootstrap/Overlay';
import Popover from 'react-bootstrap/Popover';
function Example() {
const [show, setShow] = useState(false);
const [target, setTarget] = useState(null);
const ref = useRef(null);
const handleClick = (event) => {
setShow(!show);
setTarget(event.target);
};
return (
<div ref={ref}>
<Button onClick={handleClick}>Holy guacamole!</Button>
<Overlay
show={show}
target={target}
placement="bottom"
container={ref}
containerPadding={20}
>
<Popover id="popover-contained">
<Popover.Header as="h3">Popover bottom</Popover.Header>
<Popover.Body>
<strong>Holy guacamole!</strong> Check this info.
</Popover.Body>
</Popover>
</Overlay>
</div>
);
}
export default Example;
位置を動的に更新する
オーバーレイのサイズが変更されるたびに把握することはできないため、位置を変更する場合は、変更に応じてオーバーレイの位置を更新するために手動で操作する必要があります。
このため、Overlayコンポーネントは、オーバーレイコンポーネントが自身の位置を変更するために使用できるscheduleUpdate()
メソッドを持つpopper
プロパティも注入します。
import React, { useEffect, useState } from 'react';
import Button from 'react-bootstrap/Button';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Popover from 'react-bootstrap/Popover';
const UpdatingPopover = React.forwardRef(
({ popper, children, show: _, ...props }, ref) => {
useEffect(() => {
console.log('updating!');
popper.scheduleUpdate();
}, [children, popper]);
return (
<Popover ref={ref} body {...props}>
{children}
</Popover>
);
},
);
const longContent = `
Very long
Multiline content
that is engaging and what-not
`;
const shortContent = 'Short and sweet!';
function Example() {
const [content, setContent] = useState(shortContent);
useEffect(() => {
const timerId = setInterval(() => {
setContent(content === shortContent ? longContent : shortContent);
}, 3000);
return () => clearInterval(timerId);
});
return (
<OverlayTrigger
trigger="click"
overlay={
<UpdatingPopover id="popover-contained">{content}</UpdatingPopover>
}
>
<Button>Holy guacamole!</Button>
</OverlayTrigger>
);
}
render(<Example />);
API
Overlay
OverlayTrigger
Popover
PopoverBody