React Accordion (アコーディオン) の概要
Ignite UI for React アコーディオンは、単一のコンテナーに表示されるクリック可能なヘッダーと関連するコンテンツ セクションを含む垂直方向に展開可能なパネルを構築するための GUI コンポーネントです。Accordion は、単一のページのコンテンツの複数のセクションでスクロールする必要性を軽減するためによく使用されます。キーボード ナビゲーションと基になるパネルの展開状態を制御する API を提供します。
ユーザーは、サムネイルやラベルなどの項目のリスト間で操作および移動できます。含まれる情報を表示するために、各項目を切り替えることができます (展開または縮小)。構成に応じて、一度に 1 つまたは複数の展開されている項目があります。
React アコーディオンの例
以下は FAQ セクションの基本的な Ignite UI for React アコーディオンの例です。アコーディオンとして動作し、個別に動作します。複数のパネルを同時に展開しながら、各テキスト ブロックをシングル クリックで切り替えることができます。これにより、自動的に展開および縮小パネル間を前後に移動することなく、情報をより簡単に読み取ることができます。このパネルは、以前に開いたセクションを毎回非表示にします。
その中で、アコーディオンとその展開パネルを定義する方法を見ることができます。このサンプルは、2 種類の展開動作も示します。切り替えボタンは singleExpand
プロパティを設定し、一度に展開する単一ブランチと複数ブランチを切り替えます。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import './AccordionOverview.css';
import {
IgrAccordion, IgrAccordionModule, IgrExpansionPanel, IgrExpansionPanelModule, IgrSwitch, IgrSwitchModule,
IgrCheckboxChangeEventArgs } from "@infragistics/igniteui-react";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
IgrAccordionModule.register();
IgrExpansionPanelModule.register();
IgrSwitchModule.register();
export default class AccordionOverview extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = { singleExpand: false };
this.switchChange = this.switchChange.bind(this);
}
public render(): JSX.Element {
return (
<div id="root">
<IgrSwitch key="switch" change={this.switchChange}><span key="swText">Single Expand</span></IgrSwitch>
<div className="sample-wrapper">
<IgrAccordion singleExpand={this.state.singleExpand}>
<IgrExpansionPanel key="ep1">
<h1 slot="title" key="ep1Title">What has changed about subscription and pricing model?</h1>
<span key="ep1Span">We have moved to a subscription-based pricing model for all our developer tools. This makes it easier
for you to manage your license subscriptions and allows us to provide a better level of service for you. We
updated our pricing and packages to provide you with flexible options and the best value. This includes Ignite UI
(formerly Ignite UI for JavaScript) which includes all of our JavaScript framework components for web development,
including: Angular, ASP.NET (Core and MVC), Blazor, JQuery, React and Web Components, as well as Infragistics Professional,
Infragistics Ultimate, our Ultimate UI products. We also offer multi-year subscriptions options with a built-in discount,
so you can see the value up front. With these updates we are confident that we are providing the best platforms and the best
price.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep2">
<h1 slot="title" key="ep2Title">Who will the updated changes impact?</h1>
<span key="ep2Span">The license updates will impact all new and current customers using Ignite UI, Infragistics Professional and
Infragistics Ultimate. Specifically, we have also made updates to our product and packaging for Ignite UI for JavaScript,
Ignite UI for Angular, Ignite UI for React and Ignite UI for Web components. For more information, please refer to this
blog: Announcement: Changes to Ignite UI Product & Packaging The pricing has been updated for all products and packages.
So, all new or additional licenses will be sold based on our new pricing and packages. All existing license agreements will
be honored and renewed based upon the current agreement.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep3">
<h1 slot="title" key="ep3Title">What is the difference between your old model and your current subscription model for Ignite UI?</h1>
<span key="ep3Span">For Ignite UI customers, we are moving away from NPM for licensed packages. The current NPM packages will be replaced with
packages that include a “Trial Version” watermark. Licensed packages for Ignite UI will be available from our cloud hosted ProGet
server. For more information, please refer to this article: Moving from Trial to Licensed Ignite UI NPM Packages</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep4">
<h1 slot="title" key="ep4Title">What happens if I don't renew my subscription?</h1>
<span key="ep4Span">Any unlicensed or trial versions of Ignite UI for Angular, React and Web Components will now include this watermark.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep5">
<h1 slot="title" key="ep5Title">If I don't renew my subscription will I still have access to previous versions of Infragistics products?</h1>
<span key="ep5Span">Any version of Infragistics software which you have downloaded can continue to be used perpetually. Access to download any new or
previous versions through our customer portal and package feeds will require maintaining an active subscription by continuing
to renew it.</span>
</IgrExpansionPanel>
</IgrAccordion>
</div>
</div>
);
}
public switchChange(s: IgrSwitch, e: IgrCheckboxChangeEventArgs) {
this.setState({ singleExpand: e.detail.checked })
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<AccordionOverview />);
tsxigc-accordion {
width: 100%;
}
.sample-wrapper {
overflow-y: auto;
max-height: 380px;
margin: 8px;
}
igc-switch {
padding: 16px;
}
igc-expansion-panel {
border: 1px solid rgba(174, 174, 174, 0.25);
}
css
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
React アコーディオンで作業を開始
まず、次のコマンドを実行して、対応する Ignite UI for React npm パッケージをインストールする必要があります:
npm install igniteui-react
cmd
次に、以下のように、IgrAccordion
および IgrExpansionPanel
とそれに必要な CSS をインポートし、そのモジュールを登録する必要があります:
import {
IgrAccordion,
IgrAccordionModule,
IgrExpansionPanel,
IgrExpansionPanelModule,
} from "igniteui-react";
import "igniteui-webcomponents/themes/light/bootstrap.css";
IgrAccordionModule.register();
IgrExpansionPanelModule.register();
tsx
これで、IgrAccordion
とそのパネルの基本構成から始めることができます。
使用方法
React アコーディオン コンポーネントの各セクションは、React 展開パネルを使用して定義されます。
パネルには、Disabled
および Open
プロパティが用意されており、要件に応じてパネルの状態を構成できます。
Accordion の宣言
アコーディオンは、その中で宣言されたすべての展開パネルをラップします。
<IgrAccordion singleExpand={true}>
<IgrExpansionPanel>
<div slot="title">Title Panel 1</div>
<div>Content Panel 1</div>
</IgrExpansionPanel>
<IgrExpansionPanel>
<div slot="title">Title Panel 2</div>
<div>Content Panel 2</div>
</IgrExpansionPanel>
</IgrAccordion>
tsx
上記で示したように、singleExpand
プロパティを使用すると、一度に 1 つまたは複数のパネルを展開できるかどうかを設定できます。
hideAll
メソッドと showAll
メソッドを使用すると、IgrAccordion
のすべての IgrExpansionPanel
をプログラムでそれぞれ省略したり展開したりできます。
singleExpand プロパティが true に設定されている場合、showAll メソッドを呼び出すと、フォーカスされたパネルのみが展開されます。
React アコーディオンのカスタマイズの例
React アコーディオンを使用すると、ヘッダーとコンテンツ パネルの外観をカスタマイズできます。
以下のサンプルは、IgrExpansionPanel
の組み込みスロットを使用して、複雑なフィルタリング オプションを実装する方法を示しています。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import './AccordionCustomization.css';
import {
IgrAccordion, IgrAccordionModule, IgrCheckbox, IgrCheckboxChangeEventArgs, IgrCheckboxModule,
IgrDateTimeInput, IgrDateTimeInputModule, IgrExpansionPanel, IgrExpansionPanelModule, IgrIcon,
IgrIconModule, IgrRadio, IgrRadioModule, IgrRadioGroup, IgrRadioGroupModule, IgrRating,
IgrRatingModule, IgrRangeSlider, IgrRangeSliderModule, IgrRadioChangeEventArgs,
IgrRangeSliderValueEventArgs, IIgrRadioProps, IgrComponentDateValueChangedEventArgs
} from "@infragistics/igniteui-react";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
IgrAccordionModule.register();
IgrCheckboxModule.register();
IgrDateTimeInputModule.register();
IgrExpansionPanelModule.register();
IgrIconModule.register();
IgrRadioModule.register();
IgrRadioGroupModule.register();
IgrRangeSliderModule.register();
IgrRatingModule.register();
type Category = { checked: boolean; type: string };
export default class AccordionCustomization extends React.Component<any, any> {
private categories = [
{ checked: false, type: "Bike" },
{ checked: false, type: "Motorcycle" },
{ checked: false, type: "Car" },
{ checked: false, type: "Taxi" },
{ checked: false, type: "Public Transport" }
];
private clearIcon: IgrIcon;
private clockIcon: IgrIcon;
private dateTimeInput: IgrDateTimeInput;
constructor(props: any) {
super(props);
this.state = {
categories: this.categories,
cost: { lower: 200, upper: 800 },
rating: '',
time: 'Time'
};
this.categoriesChange = this.categoriesChange.bind(this);
this.costRangeChange = this.costRangeChange.bind(this);
this.ratingChange = this.ratingChange.bind(this);
this.timeChange = this.timeChange.bind(this);
this.clearTime = this.clearTime.bind(this);
this.clockIconRef = this.clockIconRef.bind(this);
this.clearIconRef = this.clearIconRef.bind(this);
this.dateTimeInputRef = this.dateTimeInputRef.bind(this);
}
public render(): JSX.Element {
return (
<div id="root">
<div className="sample-wrapper">
<IgrAccordion>
<IgrExpansionPanel key="ep1">
<h1 slot="title" key="ep1Title">
Categories
{this.state.categories.some((c: Category) => c.checked) && ': '}
{this.state.categories.filter((c: Category) => c.checked).map((c: Category) => c.type).join(', ')}
</h1>
<span key="ep1Span">
<div className="categories-container">
{this.state.categories.map((c: Category) => {
return (
<IgrCheckbox key={'checkbox-' + c.type}
change={(s: IgrCheckbox, e: IgrCheckboxChangeEventArgs) => this.categoriesChange(s, e, c.type)}>
<span key={'cbSpan-' + c.type}>{c.type}</span>
</IgrCheckbox>
);
})}
</div>
</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep2">
<h1 slot="title" key="ep2Title">
Cost: $<span id="lowerCost">{this.state.cost.lower}</span> to $<span id="upperCost">{this.state.cost.upper}</span>
</h1>
<span key="ep2Span">
<IgrRangeSlider key="rangeSlider" min={0} max={1000} lower={this.state.cost.lower} upper={this.state.cost.upper}
change={this.costRangeChange}>
</IgrRangeSlider>
</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep3">
<h1 slot="title" key="ep3Title">Rating{this.state.rating && ': '}{this.state.rating}</h1>
<span key="ep3Span">
<IgrRadioGroup key="radio" alignment="horizontal">
{[1, 2, 3, 4].map(rating => {
return (
<IgrRadio key={`${rating}star`} name="rating" value={rating.toString()} change={this.ratingChange}>
<IgrRating label={`${rating} star${rating > 1 ? 's' : ''} or more`} max={5} value={rating + 0.5}
className="size-small" readonly key={`{r-${rating}}`}>
</IgrRating>
</IgrRadio>
);
})}
</IgrRadioGroup>
</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep4">
<h1 slot="title" key="ep4Title">{this.state.time}</h1>
<span key="ep4Span">
<IgrDateTimeInput className="size-small" key="dtInput" inputFormat="hh:mm tt" label="Arrive before"
ref={this.dateTimeInputRef} change={this.timeChange}>
<span key="sPrefix" slot="prefix">
<IgrIcon name="clock" collection="material" ref={this.clockIconRef} />
</span>
<span key="sSuffix" slot="suffix" onClick={this.clearTime}>
<IgrIcon name="clear" collection="material" ref={this.clearIconRef} />
</span>
</IgrDateTimeInput>
</span>
</IgrExpansionPanel>
</IgrAccordion>
</div>
</div>
);
}
public categoriesChange(s: IgrCheckbox, e: IgrCheckboxChangeEventArgs, type: string) {
const categoryIndex = this.categories.findIndex(c => c.type === type);
if (categoryIndex === -1) { return; }
let categoriesCopy = this.state.categories;
categoriesCopy[categoryIndex].checked = e.detail.checked;
this.setState({
categories: categoriesCopy
});
}
public costRangeChange(s: IgrRangeSlider, e: IgrRangeSliderValueEventArgs) {
this.setState({
cost: { lower: e.detail.lower, upper: e.detail.upper }
});
}
public ratingChange(s: IgrRadio<IIgrRadioProps>, e: IgrRadioChangeEventArgs) {
if (!e.detail) { return; }
this.setState({
rating: `${+s.value} star${+s.value > 1 ? 's' : ''} or more`
});
}
public timeChange(s: IgrDateTimeInput, e: IgrComponentDateValueChangedEventArgs) {
const result = s.value !== null ? `Arrive before ${e.detail.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}` : 'Time';
this.setState({
time: result
});
}
public clearTime() {
this.dateTimeInput.clear(); this.setState({
time: 'Time'
});
}
public dateTimeInputRef(input: IgrDateTimeInput) {
if (!input) { return; }
this.dateTimeInput = input;
}
public clearIconRef(icon: IgrIcon) {
if (!icon) { return; }
this.clearIcon = icon;
const clearIcon =
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' width='24' height='24' viewBox='0 0 24 24'><path d='M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z' /></svg>";
this.clearIcon.registerIconFromText("clear", clearIcon, "material");
}
public clockIconRef(icon: IgrIcon) {
if (!icon) { return; }
this.clockIcon = icon;
const clockIcon =
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' width='24' height='24' viewBox='0 0 24 24'><path d='M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z' /></svg>";
this.clockIcon.registerIconFromText("clock", clockIcon, "material");
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<AccordionCustomization />);
tsxigc-accordion {
width: 100%;
}
.sample-wrapper {
overflow-y: auto;
max-height: 530px;
margin: 8px;
}
igc-range-slider {
margin: 24px;
}
.categories-container {
display: flex;
flex-flow: column nowrap;
}
igc-checkbox,
igc-radio {
margin: 4px 0;
}
igc-expansion-panel {
border: 1px solid rgba(174, 174, 174, 0.25);
}
igc-rating {
flex-direction: row;
}
.size-small {
--ig-size: var(--ig-size-small);
}
css
ネストされた React アコーディオンのシナリオ
次の React アコーディオンの例では、この一般的なアプリケーション シナリオにどのように取り組むことができるかを説明するために、複雑な FAQ セクションが作成されています。サンプルでは、ネストされたアコーディオンは、展開パネル内に IgrAccordion
を追加することによって実現されます。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import './AccordionNestedScenario.css';
import {
IgrAccordion, IgrExpansionPanel, IgrSwitch, IgrAccordionModule, IgrExpansionPanelModule, IgrSwitchModule,
IgrCheckboxChangeEventArgs
} from "@infragistics/igniteui-react";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
IgrAccordionModule.register();
IgrExpansionPanelModule.register();
IgrSwitchModule.register();
export default class AccordionNestedScenario extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = { singleExpand: false };
this.switchChange = this.switchChange.bind(this);
}
public render(): JSX.Element {
return (
<div id="root">
<IgrSwitch key="switch" change={this.switchChange}><span key="swText">Single Expand</span></IgrSwitch>
<div className="sample-wrapper">
<IgrAccordion singleExpand={this.state.singleExpand}>
<IgrExpansionPanel key="ep1">
<h1 slot="title" key="ep1Title">What has changed about subscription and pricing model?</h1>
<span key="ep1Span">We have moved to a subscription-based pricing model for all our developer tools. This makes it easier
for you to manage your license subscriptions and allows us to provide a better level of service for you. We
updated our pricing and packages to provide you with flexible options and the best value. This includes Ignite UI
(formerly Ignite UI for JavaScript) which includes all of our JavaScript framework components for web development,
including: Angular, ASP.NET (Core and MVC), Blazor, JQuery, React and Web Components, as well as Infragistics Professional,
Infragistics Ultimate, our Ultimate UI products. We also offer multi-year subscriptions options with a built-in discount,
so you can see the value up front. With these updates we are confident that we are providing the best platforms and the best
price.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep2">
<h1 slot="title" key="ep2Title">Who will the updated changes impact?</h1>
<span key="ep2Span">The license updates will impact all new and current customers using Ignite UI, Infragistics Professional and
Infragistics Ultimate. Specifically, we have also made updates to our product and packaging for Ignite UI for JavaScript,
Ignite UI for Angular, Ignite UI for React and Ignite UI for Web components. For more information, please refer to this
blog: Announcement: Changes to Ignite UI Product & Packaging The pricing has been updated for all products and packages.
So, all new or additional licenses will be sold based on our new pricing and packages. All existing license agreements will
be honored and renewed based upon the current agreement.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep3">
<h1 slot="title" key="ep3Title">What is the difference between your old model and your current subscription model for Ignite UI?</h1>
<span key="ep3Span">For Ignite UI customers, we are moving away from NPM for licensed packages. The current NPM packages will be replaced with
packages that include a “Trial Version” watermark. Licensed packages for Ignite UI will be available from our cloud hosted ProGet
server. For more information, please refer to this article: Moving from Trial to Licensed Ignite UI NPM Packages</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep4">
<h1 slot="title" key="ep4Title">Common questions about renewal.</h1>
<span key="ep4Span">
<IgrAccordion>
<IgrExpansionPanel key="ep4.1">
<h1 slot="title" key="ep4.1Title">What happens if I don't renew my subscription?</h1>
<span key="ep4.1Span">Any unlicensed or trial versions of Ignite UI for Angular, React and Web Components will now include this watermark.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep4.2">
<h1 slot="title" key="ep4.2Title">If I don't renew my subscription will I still have access to previous versions of Infragistics products?</h1>
<span key="ep4.2Span">Any version of Infragistics software which you have downloaded can continue to be used perpetually. Access to download any new or
previous versions through our customer portal and package feeds will require maintaining an active subscription by continuing
to renew it.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep4.3">
<h1 slot="title" key="ep4.3Title">Will I be automatically charged for my renewal/ Can I be automatically charged for renewal?</h1>
<span key="ep4.3Span">Any new subscriptions purchased online, via our eCommerce system, will renew automatically. Subscription renewal can be canceled,
at any time, before the next automatic renewal date. Subscriptions purchased directly from Infragistics or Infragistics' partners are
subject to the renewal terms that were agreed upon as part of that purchase.</span>
</IgrExpansionPanel>
</IgrAccordion>
</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep5">
<h1 slot="title" key="ep5Title">I split my work across two computers. Can I install on both using my single-user license?</h1>
<span key="ep5Span">The Infragistics Ultimate license is tied to the user, and not the computer. That means you're welcome to install and use Ignite UI,
Infragistics Professional, and Infragistics Ultimate on any computer you use. However, if we notice a large number of activations using the
same license, we may contact you to verify this behavior.</span>
</IgrExpansionPanel>
<IgrExpansionPanel key="ep6">
<h1 slot="title" key="ep6Title">I used up my trial for an earlier version of Infragistics Ultimate. Can I start a new trial when a major version is released?</h1>
<span key="ep6Span">Yes! If you have tried a previous version in the past, and used up your 30-day trial, you can try the next major version for another 30 days!
You can do this in the following two ways:
<ul>
<li>If you have days remaining in your 30-day trial period for the current version (e.g., the
Version 15.1 Volume Release), use the Check for Update option inside the Platform Installer or
your account. You will be able to start a fresh trial for the next major version (e.g., 20.1
Volume Release)</li>
<li>If you have used up the 30-day trial for the previous major version (e.g., the 19.2 Volume
Release), simply download and install Infragistics Ultimate from our <a
href="https://www.infragistics.com/products/ultimate">website</a> (This will also allow you
to start a new trial.)</li>
</ul></span>
</IgrExpansionPanel>
</IgrAccordion>
</div>
</div>
);
}
public switchChange(s: IgrSwitch, e: IgrCheckboxChangeEventArgs) {
this.setState({ singleExpand: e.detail.checked })
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<AccordionNestedScenario />);
tsxigc-accordion {
width: 100%;
}
.sample-wrapper {
overflow-y: auto;
max-height: 470px;
margin: 8px;
}
igc-switch {
padding: 16px;
}
igc-expansion-panel {
border: 1px solid rgba(174, 174, 174, 0.25);
}
css
キーボード ナビゲーション
React アコーディオンのキーボード ナビゲーションは、エンド ユーザーにさまざまなキーボード操作を提供します。この機能はデフォルトで有効になっており、エンドユーザーは簡単にパネル間を移動できます。
アコーディオン ナビゲーションは、W3C アクセシビリティ標準に準拠しており、使いやすいです。
キーの組み合わせ
- ↓ - フォーカスを下のパネルに移動します。
- ↑ - フォーカスを上のパネルに移動します。
- Alt + ↓ - アコーディオンでフォーカスされたパネルを開きます。
- Alt + ↑ - Accordion でフォーカスされたパネルを閉じます。
- Shift + Alt + ↓ - 有効なすべてのパネルを開きます。(singleExpand が true に設定されている場合、フォーカスされたパネルが開きます)。
- Shift + Alt + ↑ - 有効なすべてのパネルを閉じます。
- Home - Accordion の最初の有効なパネルに移動します。
- End - Accordion の最後の有効なパネルに移動します。