Bento

Bento 手風琴

<head>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <script src="https://cdn.ampproject.org/bento.js"></script>
    <script
      async
      src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js"
    ></script>
    <link
      rel="stylesheet"
      type="text/css"
      href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css"
    />
    <style>
      body {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
          Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
          'Segoe UI Symbol';
        background: #ecf1f3;
      }
      .my-accordion > section {
        border-radius: 0.5rem;
        margin: 1rem;
        background: white;
        background-repeat: no-repeat;
        background-position: right 1rem top 1rem;
      }
      .my-accordion h2 {
        background: white;
        padding: 2rem;
        border: none;
        background: none;
      }
      .my-accordion div {
        padding: 2rem;
        padding-top: 0;
      }
      .my-accordion section[expanded] {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48px' viewBox='0 0 24 24' width='48px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath d='M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14l-6-6z'/%3E%3C/svg%3E%0A");
      }
      .my-accordion section:not([expanded]) {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48px' viewBox='0 0 24 24' width='48px' fill='%23000000'%3E%3Cpath d='M24 24H0V0h24v24z' fill='none' opacity='.87'/%3E%3Cpath d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'/%3E%3C/svg%3E%0A");
      }
    </style>
</head>

<body>

    <bento-accordion id="my-accordion" class="my-accordion">
      <section>
        <h2>Section 1</h2>
        <div>Content in section 1.</div>
      </section>
      <section>
        <h2>Section 2</h2>
        <div>Content in section 2.</div>
      </section>
      <section expanded>
        <h2>Section 3</h2>
        <div>Content in section 3.</div>
      </section>
    </bento-accordion>
</body>

顯示可以收合和展開的內容區塊。這個元件讓瀏覽者能夠瀏覽內容大綱,並跳到任意區塊。有效地使用可減少行動裝置的捲動需求。

  • Bento 手風琴接受一個或多個 <section> 元素作為其子元素。
  • 每個 <section> 必須包含兩個子元素。
  • <section> 的第一個子元素是 Bento 手風琴該區塊的標題。它必須是標題元素,例如 <h1>-<h6><header>
  • <section> 的第二個子元素是可展開/收合的內容。
    • 它可以是 AMP HTML 中允許的任意標籤。
  • 點選或輕觸 <section> 標題會展開或收合該區塊。
  • 具有已定義 id 的 Bento 手風琴會在使用者留在您的網域時,保存每個區塊的收合或展開狀態。

使用 bento-accordion 作為網路元件或 React 函數式元件

↓ 網路元件 ↓ React / Preact

網路元件

您必須納入每個 Bento 元件所需的 CSS 函式庫,以確保適當地載入,並在新增自訂樣式之前執行。或使用可內嵌的精簡預升級樣式。請參閱 版面配置與樣式

透過 npm 匯入

npm install @bentoproject/accordion
import {defineElement as defineBentoAccordion} from '@bentoproject/accordion';
defineBentoAccordion();

透過 <script> 納入

<script type="module" src="https://cdn.ampproject.org/bento.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/bento.js" crossorigin="anonymous"></script>
<script type="module" src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css" crossorigin="anonymous">

範例

<head>

<script
      type="module"
      async
      src="https://cdn.ampproject.org/bento.mjs"
    ></script>
    <script nomodule src="https://cdn.ampproject.org/bento.js"></script>
    <script
      type="module"
      async
      src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs"
    ></script>
    <script
      nomodule
      async
      src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js"
    ></script>
    <link
      rel="stylesheet"
      type="text/css"
      href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css"
    />
</head>

<body>

<bento-accordion id="my-accordion">
      <section>
        <h2>Section 1</h2>
        <div>Content in section 1.</div>
      </section>
      <section>
        <h2>Section 2</h2>
        <div>Content in section 2.</div>
      </section>
       <!-- Expanded on page load due to attribute: -->
      <section expanded>
        <h2>Section 3</h2>
        <div>Content in section 3.</div>
      </section>
    </bento-accordion>
</body>

互動性和 API 使用

Bento 元件透過其 API 具備高度互動性。bento-accordion 元件 API 可透過在您的文件納入下列 script 標籤存取

await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();

API 範例

<head>

<script
      type="module"
      async
      src="https://cdn.ampproject.org/bento.mjs"
    ></script>
    <script nomodule src="https://cdn.ampproject.org/bento.js"></script>
    <script
      type="module"
      async
      src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs"
    ></script>
    <script
      nomodule
      async
      src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js"
    ></script>
    <link
      rel="stylesheet"
      type="text/css"
      href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css"
    />
</head>

<body>

<bento-accordion id="my-accordion">
      <section>
        <h2>Section 1</h2>
        <div>Content in section 1.</div>
      </section>
      <section>
        <h2>Section 2</h2>
        <div>Content in section 2.</div>
      </section>
       <!-- Expanded on page load due to attribute: -->
      <section expanded>
        <h2>Section 3</h2>
        <div>Content in section 3.</div>
      </section>
    </bento-accordion>
    <script>
      (async () => {
        const accordion = document.querySelector('#my-accordion');
        await customElements.whenDefined('bento-accordion');
        const api = await accordion.getApi();

        // programatically expand all sections
        api.expand();
        // programatically collapse all sections
        api.collapse();
      })();
    </script>
</body>

動作

toggle()

toggle 動作切換 bento-accordion 區塊的 expandedcollapsed 狀態。在沒有參數的情況下呼叫時,它會切換手風琴的所有區塊。如要指定特定區塊,請新增 section 參數,並使用對應的 id 作為值。

<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Toggle All Sections</button>
<button id="button2">Toggle Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();

// set up button actions
document.querySelector('#button1').onclick = () => {
api.toggle();
};
document.querySelector('#button2').onclick = () => {
api.toggle('section1');
};
})();
</script>
expand()

expand 動作會展開 bento-accordion 的區段。如果區段已經展開,則保持展開。如果沒有參數呼叫時,它會展開 accordion 的所有區段。若要指定區段,請新增 section 參數,並使用其對應的 id 作為值。

<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Expand All Sections</button>
<button id="button2">Expand Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();

// set up button actions
document.querySelector('#button1').onclick = () => {
api.expand();
};
document.querySelector('#button2').onclick = () => {
api.expand('section1');
};
})();
</script>
collapse()

collapse 動作會收合 bento-accordion 的區段。如果區段已經收合,則保持收合。如果沒有參數呼叫時,它會收合 accordion 的所有區段。若要指定區段,請新增 section 參數,並使用其對應的 id 作為值。

<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Collapse All Sections</button>
<button id="button2">Collapse Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();

// set up button actions
document.querySelector('#button1').onclick = () => {
api.collapse();
};
document.querySelector('#button2').onclick = () => {
api.collapse('section1');
};
})();
</script>

事件

bento-accordion API 允許您註冊並回應以下事件:

展開

當 accordion 區段展開且從展開的區段分派時,會觸發這個事件。

詳見以下範例。

收合

當 accordion 區段收合且從收合的區段分派時,會觸發這個事件。

在以下範例中,section 1 會聆聽 展開 事件,並在其展開時展開 section 2section 2 會聆聽 收合 事件,並在其收合時收合 section 1

詳見以下範例。

事件範例
<bento-accordion id="eventsAccordion" animate>
<section id="section1">
<h2>Section 1</h2>
<div>Puppies are cute.</div>
</section>
<section id="section2">
<h2>Section 2</h2>
<div>Kittens are furry.</div>
</section>
</bento-accordion>

<script>
(async () => {
const accordion = document.querySelector('#eventsAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();

// when section 1 expands, section 2 also expands
// when section 2 collapses, section 1 also collapses
const section1 = document.querySelector('#section1');
const section2 = document.querySelector('#section2');
section1.addEventListener('expand', () => {
api.expand('section2');
});
section2.addEventListener('collapse', () => {
api.collapse('section1');
});
})();
</script>

配置和樣式

每個 Bento 元件都有個小型的 CSS 程式庫,您必須將它包含在內,才能確保正確載入而不會有任何 內容轉移。由於基於順序的特定性,您必須手動確保在任何自訂樣式之前已包含樣式表。

<link
rel="stylesheet"
type="text/css"
href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css"
/>

或者,您也可以將輕量化預先升級的樣式以內嵌方式提供。

<style>
bento-accordion {
display: block;
contain: layout;
}

bento-accordion,
bento-accordion > section,
bento-accordion > section > :first-child
{
margin: 0;
}

bento-accordion > section > * {
display: block;
float: none;
overflow: hidden; /* clearfix */
position: relative;
}

@media (min-width: 1px) {
:where(bento-accordion > section) > :first-child {
cursor: pointer;
background-color: #efefef;
padding-right: 20px;
border: 1px solid #dfdfdf;
}
}

.i-amphtml-accordion-header {
cursor: pointer;
background-color: #efefef;
padding-right: 20px;
border: 1px solid #dfdfdf;
}

bento-accordion
> section:not([expanded])
> :last-child:not(.i-amphtml-animating),
bento-accordion
> section:not([expanded])
> :last-child:not(.i-amphtml-animating)
*
{
display: none !important;
}
</style>

屬性

動畫

<bento-accordion> 中包含 animate 屬性,以便展開內容時新增「向下展開」動畫,並在收合時新增「向上收合」動畫。

此屬性可根據 媒體查詢 進行設定。

<bento-accordion animate>
<section>
<h2>Section 1</h2>
<div>Content in section 1.</div>
</section>
<section>
<h2>Section 2</h2>
<div>Content in section 2.</div>
</section>
<section>
<h2>Section 3</h2>
<div>Content in section 2.</div>
</section>
</bento-accordion>

已展開

expanded 屬性套用到巢狀的 <section>,以便在頁面載入時展開該區段。

<bento-accordion>
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section id="section2">
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section id="section3" expanded>
<h2>Section 3</h2>
<div>Bunch of awesome expanded content</div>
</section>
</bento-accordion>

展開單一區段

透過將 expand-single-section 屬性套用到 <bento-accordion> 元件,一次只允許展開一個區段。這表示,如果使用者點選已收合的 <section>,它將展開並收合其他已展開的 <section>

<bento-accordion expand-single-section>
<section>
<h2>Section 1</h2>
<div>Content in section 1.</div>
</section>
<section>
<h2>Section 2</h2>
<div>Content in section 2.</div>
</section>
<section>
<h2>Section 3</h2>
<img
src="https://source.unsplash.com/random/320x256"
width="320"
height="256"
/>

</section>
</bento-accordion>

樣式設定

您可以使用 bento-accordion 元件選擇器來自由設定 accordion 的樣式。

設定 amp-accordion 的樣式時,請注意以下各點

  • bento-accordion 元件永遠是 display: block
  • float 無法設定 <section>、標題或內容元件的樣式。
  • 展開的區段會將 expanded 屬性套用到 <section> 元件。
  • 內容元素具有 clear-fixed 和 overflow: hidden,因此不會有捲軸。
  • <bento-accordion><section>、標題和內容元素的邊界設為 0,但可在自訂樣式中覆寫。
  • 標題和內容元素都是 position: relative

Preact/React 元件

透過 npm 匯入

npm install @bentoproject/accordion

範例

import React from 'react';
import {
  BentoAccordion,
  BentoAccordionSection,
  BentoAccordionHeader,
  BentoAccordionContent
} from '@bentoproject/accordion/react';
import '@bentoproject/accordion/styles.css';

function App() {
  return (
    <BentoAccordion>
      <BentoAccordionSection key={1}>
        <BentoAccordionHeader>
          <h1>Section 1</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 1</BentoAccordionContent>
      </BentoAccordionSection>

      <BentoAccordionSection key={2}>
        <BentoAccordionHeader>
          <h1>Section 2</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 2</BentoAccordionContent>
      </BentoAccordionSection>

      <BentoAccordionSection key={3}>
        <BentoAccordionHeader>
          <h1>Section 3</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 3</BentoAccordionContent>
      </BentoAccordionSection>
    </BentoAccordion>
  );
}

互動性和 API 使用

Bento 元件會透過其 API 進行高度互動。BentoAccordion 元件 API 可透過傳遞 ref 存取

import React, {createRef} from 'react';
const ref = createRef();

function App() {
return (
<BentoAccordion ref={ref}>
<BentoAccordionSection id="section1" key={1}>
<BentoAccordionHeader>
<h1>Section 1</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 1</BentoAccordionContent>
</BentoAccordionSection>

<BentoAccordionSection id="section2" key={2}>
<BentoAccordionHeader>
<h1>Section 2</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 2</BentoAccordionContent>
</BentoAccordionSection>

<BentoAccordionSection id="section3" key={3}>
<BentoAccordionHeader>
<h1>Section 3</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 3</BentoAccordionContent>
</BentoAccordionSection>
</BentoAccordion>
);
}

動作

BentoAccordion API 可執行下列動作

toggle()

toggle 動作切換 bento-accordion 區塊的 expandedcollapsed 狀態。在沒有參數的情況下呼叫時,它會切換手風琴的所有區塊。如要指定特定區塊,請新增 section 參數,並使用對應的 id 作為值。

ref.current.toggle();
ref.current.toggle('section1');
expand()

expand 動作會展開 bento-accordion 的區段。如果區段已經展開,則保持展開。如果沒有參數呼叫時,它會展開 accordion 的所有區段。若要指定區段,請新增 section 參數,並使用其對應的 id 作為值。

ref.current.expand();
ref.current.expand('section1');
collapse()

collapse 動作會收合 bento-accordion 的區段。如果區段已經收合,則保持收合。如果沒有參數呼叫時,它會收合 accordion 的所有區段。若要指定區段,請新增 section 參數,並使用其對應的 id 作為值。

ref.current.collapse();
ref.current.collapse('section1');

事件

Bento Accordion API 可讓您回應下列事件

onExpandStateChange

此事件會在手風琴區段展開或收合時在區段上觸發,並從展開的區段派發。

請見下方 範例

onCollapse

此事件會在手風琴區段收合時在區段上觸發,並從收合的區段派發。

在以下範例中,section 1 會聆聽 展開 事件,並在其展開時展開 section 2section 2 會聆聽 收合 事件,並在其收合時收合 section 1

請見下方 範例

事件範例
import React, {createRef} from 'react';
import {
  BentoAccordion,
  BentoAccordionSection,
  BentoAccordionHeader,
  BentoAccordionContent
} from '@bentoproject/accordion/react';
import '@bentoproject/accordion/styles.css';


function App() {
  const ref = createRef();
  return (
    <BentoAccordion ref={ref}>
      <BentoAccordionSection
        id="section1"
        key={1}
        onExpandStateChange={(expanded) => {
          alert(expanded ?  'section1 expanded' : 'section1 collapsed');
        }}
      >
        <BentoAccordionHeader>
          <h1>Section 1</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 1</BentoAccordionContent>
      </BentoAccordionSection>

      <BentoAccordionSection
        id="section2"
        key={2}
        onExpandStateChange={(expanded) => {
          alert(expanded ?  'section2 expanded' : 'section2 collapsed');
        }}
      >
        <BentoAccordionHeader>
          <h1>Section 2</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 2</BentoAccordionContent>
      </BentoAccordionSection>

      <BentoAccordionSection
        id="section3"
        key={3}
        onExpandStateChange={(expanded) => {
          alert(expanded ?  'section3 expanded' : 'section3 collapsed');
        }}
      >
        <BentoAccordionHeader>
          <h1>Section 3</h1>
        </BentoAccordionHeader>
        <BentoAccordionContent>Content 3</BentoAccordionContent>
      </BentoAccordionSection>
    </BentoAccordion>
  )
}

配置和樣式

容器類型

BentoAccordion 元件有定義的版面大小類型。為確保元件正確呈現,务必透過想要的 CSS 版面 (例如以 heightwidthaspect-ratio 或其他此類屬性定義的版面) 為元件及其直接子項套用大小。這些可內嵌套用

<BentoAccordion style={{width: 300, height: 100}}>...</BentoAccordion>

或透過 className 套用

<BentoAccordion className="custom-styles">...</BentoAccordion>
.custom-styles {
background-color: red;
}

屬性

BentoAccordion

動畫

如果為 true,會在各個區段展開和收合時使用「向下捲動」/「向上捲動」動畫。

預設值:false

expandSingleSection

如果為 true,展開一個區段會自動收合所有其他區段。

預設值:false

BentoAccordionSection

動畫

如果為 true,會在展開或收合區段時使用「向下捲動」/「向上捲動」動畫。

預設值:false

已展開

如果為 true,會展開區段。

預設值:false

onExpandStateChange
(expanded: boolean): void

用於監聽展開狀態變更的回呼。接收布林旗標作為參數,指出區段是否剛展開 (false 表示已收合)

BentoAccordionHeader

共用屬性

此元件支援 React 和 Preact 元件的 共用屬性

BentoAccordionHeader 目前不支援任何自訂屬性

BentoAccordionContent

共用屬性

此元件支援 React 和 Preact 元件的 共用屬性

BentoAccordionContent 目前不支援任何自訂屬性

更多詳情