【Polaris和訳】Components/Overlays②
この記事について
この記事は、Polaris/Components/Overlaysの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
Overlays(続き)
Modal with scroll listener
モーダルコンテンツの無限スクロールを実現するために使用します。
React
function ModalWithScrollListenerExample() {
const [active, setActive] = useState(true);
const handleChange = useCallback(() => setActive(!active), [active]);
const handleScrollBottom = useCallback(() => alert('Scrolled to bottom'), []);
const activator = <Button onClick={handleChange}>Open</Button>;
return (
<div style={{height: '500px'}}>
<Modal
activator={activator}
open={active}
title="Scrollable content"
onClose={handleChange}
onScrolledToBottom={handleScrollBottom}
>
{Array.from({length: 50}, (_, index) => (
<Modal.Section key={index}>
<TextContainer>
<p>
Item <a href="#">#{index}</a>
</p>
</TextContainer>
</Modal.Section>
))}
</Modal>
</div>
);
}
HTML
<div>
<div style="height: 500px;">
<div><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Open</span></span></button></div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="modal-Polarisportal54">
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header54" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header54" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Scrollable content</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical Polaris-Scrollable--hasBottomShadow Polaris-Scrollable--verticalHasScrolling" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#0</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#1</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#2</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#3</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#4</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#5</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#6</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#7</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#8</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#9</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#10</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#11</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#12</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#13</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#14</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#15</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#16</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#17</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#18</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#19</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#20</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#21</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#22</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#23</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#24</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#25</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#26</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#27</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#28</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#29</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#30</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#31</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#32</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#33</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#34</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#35</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#36</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#37</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#38</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#39</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#40</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#41</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#42</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#43</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#44</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#45</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#46</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#47</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#48</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#49</a></p>
</div>
</section>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
</div>
</div>
</div>
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header54" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header54" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Scrollable content</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical Polaris-Scrollable--hasBottomShadow Polaris-Scrollable--verticalHasScrolling" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#0</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#1</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#2</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#3</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#4</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#5</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#6</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#7</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#8</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#9</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#10</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#11</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#12</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#13</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#14</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#15</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#16</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#17</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#18</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#19</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#20</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#21</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#22</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#23</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#24</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#25</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#26</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#27</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#28</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#29</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#30</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#31</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#32</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#33</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#34</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#35</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#36</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#37</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#38</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#39</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#40</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#41</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#42</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#43</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#44</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#45</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#46</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#47</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#48</a></p>
</div>
</section>
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Item <a href="#">#49</a></p>
</div>
</section>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
Modal with activator ref
要素を用意するよりも便利な場合は、activator ref を用意してください。これにより、モーダルを閉じる際のフォーカス管理が適切に行われます。フォーカスに関する詳しい情報は、モーダルのアクセシビリティ機能を参照してください。
React
function ModalExample() {
const [active, setActive] = useState(true);
const buttonRef = useRef(null);
const handleOpen = useCallback(() => setActive(true), []);
const handleClose = useCallback(() => {
setActive(false);
}, []);
const activator = (
<div ref={buttonRef}>
<Button onClick={handleOpen}>Open</Button>
</div>
);
return (
<div style={{height: '500px'}}>
{activator}
<Modal
activator={buttonRef}
open={active}
onClose={handleClose}
title="Reach more shoppers with Instagram product tags"
primaryAction={{
content: 'Add Instagram',
onAction: handleClose,
}}
secondaryActions={[
{
content: 'Learn more',
onAction: handleClose,
},
]}
>
<Modal.Section>
<TextContainer>
<p>
Use Instagram posts to share your products with millions of
people. Let shoppers buy from your store without leaving
Instagram.
</p>
</TextContainer>
</Modal.Section>
</Modal>
</div>
);
}
HTML
<div>
<div style="height: 500px;">
<div><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Open</span></span></button></div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="modal-Polarisportal56">
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header56" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header56" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Reach more shoppers with Instagram product tags</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Use Instagram posts to share your products with millions of people. Let shoppers buy from your store without leaving Instagram.</p>
</div>
</section>
</div>
</div>
<div class="Polaris-Modal-Footer">
<div class="Polaris-Modal-Footer__FooterContent">
<div class="Polaris-Stack Polaris-Stack--alignmentCenter">
<div class="Polaris-Stack__Item Polaris-Stack__Item--fill"></div>
<div class="Polaris-Stack__Item">
<div class="Polaris-ButtonGroup">
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Learn more</span></span></button></div>
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button Polaris-Button--primary" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Add Instagram</span></span></button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
</div>
</div>
</div>
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header56" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header56" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Reach more shoppers with Instagram product tags</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Use Instagram posts to share your products with millions of people. Let shoppers buy from your store without leaving Instagram.</p>
</div>
</section>
</div>
</div>
<div class="Polaris-Modal-Footer">
<div class="Polaris-Modal-Footer__FooterContent">
<div class="Polaris-Stack Polaris-Stack--alignmentCenter">
<div class="Polaris-Stack__Item Polaris-Stack__Item--fill"></div>
<div class="Polaris-Stack__Item">
<div class="Polaris-ButtonGroup">
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Learn more</span></span></button></div>
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button Polaris-Button--primary" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Add Instagram</span></span></button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
Modal without an activator prop
技術的な制約により、アクチベーターをエレメントやレフとして通過させることができない場合は、外部アクチベーターを使用する。この方法を選択する場合は、アクチベーターを close にフォーカスするようにしてください。フォーカスに関する詳細は、モーダルのアクセシビリティ機能を参照してください。
React
function ModalExample() {
const [active, setActive] = useState(true);
const button = useRef();
const handleOpen = useCallback(() => setActive(true), []);
const handleClose = useCallback(() => {
setActive(false);
requestAnimationFrame(() => button.current.querySelector('button').focus());
}, []);
return (
<div style={{height: '500px'}}>
<div ref={button}>
<Button onClick={handleOpen}>Open</Button>
</div>
<Modal
instant
open={active}
onClose={handleClose}
title="Reach more shoppers with Instagram product tags"
primaryAction={{
content: 'Add Instagram',
onAction: handleClose,
}}
secondaryActions={[
{
content: 'Learn more',
onAction: handleClose,
},
]}
>
<Modal.Section>
<TextContainer>
<p>
Use Instagram posts to share your products with millions of
people. Let shoppers buy from your store without leaving
Instagram.
</p>
</TextContainer>
</Modal.Section>
</Modal>
</div>
);
}
HTML
<div>
<div style="height: 500px;">
<div><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Open</span></span></button></div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="modal-Polarisportal58">
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header58" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header58" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Reach more shoppers with Instagram product tags</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Use Instagram posts to share your products with millions of people. Let shoppers buy from your store without leaving Instagram.</p>
</div>
</section>
</div>
</div>
<div class="Polaris-Modal-Footer">
<div class="Polaris-Modal-Footer__FooterContent">
<div class="Polaris-Stack Polaris-Stack--alignmentCenter">
<div class="Polaris-Stack__Item Polaris-Stack__Item--fill"></div>
<div class="Polaris-Stack__Item">
<div class="Polaris-ButtonGroup">
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Learn more</span></span></button></div>
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button Polaris-Button--primary" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Add Instagram</span></span></button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
</div>
</div>
</div>
<div>
<div class="Polaris-Modal-Dialog__Container" data-polaris-layer="true" data-polaris-overlay="true">
<div>
<div role="dialog" aria-modal="true" aria-labelledby="Polarismodal-header58" tabindex="-1" class="Polaris-Modal-Dialog">
<div class="Polaris-Modal-Dialog__Modal">
<div class="Polaris-Modal-Header">
<div id="Polarismodal-header58" class="Polaris-Modal-Header__Title">
<h2 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall">Reach more shoppers with Instagram product tags</h2>
</div><button class="Polaris-Modal-CloseButton" aria-label="Close"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m11.414 10 6.293-6.293a1 1 0 1 0-1.414-1.414L10 8.586 3.707 2.293a1 1 0 0 0-1.414 1.414L8.586 10l-6.293 6.293a1 1 0 1 0 1.414 1.414L10 11.414l6.293 6.293A.998.998 0 0 0 18 17a.999.999 0 0 0-.293-.707L11.414 10z"></path>
</svg></span></button>
</div>
<div class="Polaris-Modal__BodyWrapper">
<div class="Polaris-Modal__Body Polaris-Scrollable Polaris-Scrollable--vertical" data-polaris-scrollable="true">
<section class="Polaris-Modal-Section">
<div class="Polaris-TextContainer">
<p>Use Instagram posts to share your products with millions of people. Let shoppers buy from your store without leaving Instagram.</p>
</div>
</section>
</div>
</div>
<div class="Polaris-Modal-Footer">
<div class="Polaris-Modal-Footer__FooterContent">
<div class="Polaris-Stack Polaris-Stack--alignmentCenter">
<div class="Polaris-Stack__Item Polaris-Stack__Item--fill"></div>
<div class="Polaris-Stack__Item">
<div class="Polaris-ButtonGroup">
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Learn more</span></span></button></div>
<div class="Polaris-ButtonGroup__Item"><button class="Polaris-Button Polaris-Button--primary" type="button"><span class="Polaris-Button__Content"><span class="Polaris-Button__Text">Add Instagram</span></span></button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="Polaris-Backdrop"></div>
Props
activator
Type
RefObject
type: RefObject
Or
ReactElement
type: ReactElement
RefObject
| ReactElement
モーダルをアクティブにする要素または RefObject
children
React.ReactNode
モーダル内に表示するコンテンツ
footer
React.ReactNode
フッターの内部コンテンツ
iFrameName
string
モーダルコンテンツの iframe の名前
instant
boolean
アニメーションを無効にして、瞬時にモーダルを開く
large
boolean
モーダルの幅を大きくする
limitHeight
boolean
スクロールする大きな画面でモーダルの高さを制限する
loading
boolean
バックグラウンドアクションが実行されている間、モーダルコンテンツをスピナーに置き換える
noScroll
boolean
モーダルコンテンツから Scrollable コンテナを削除する
open
(Required
)
boolean
モーダルが開いているかどうか
primaryAction
Object
accessibilityLabel
type: string
スクリーンリーダーのための視覚的に隠されたテキスト
content
type: string
アクションが表示するコンテンツ
destructive
type: boolean
破壊的なアクション
disabled
type: boolean
アクションが無効であるかどうか
external
type: boolean
URL を新しいタブで開くようにする
icon
type: React.SFC
| "placeholder"
| string
アイコンのソース
id
type: string
アクションの一意の識別子
loading
type: boolean
スピナーを表示させるか
outline
type: boolean
アクションは輪郭のあるボタンで表示すべき
url
type: string
アクションで表示されるリンク先
onAction
type: () => void
アクションが起こったときのコールバック
onMouseEnter
type: () => void
マウス入力時のコールバック
onTouchStart
type: () => void
要素がタッチされたときのコールバック
ComplexAction
プライマリーアクション
secondaryActions
Array of type: ComplexAction[]
accessibilityLabel
type: string
スクリーンリーダーのための視覚的に隠されたテキスト
content
type: string
アクションが表示するコンテンツ
destructive
type: boolean
破壊的なアクション
disabled
type: boolean
アクションが無効であるかどうか
external
type: boolean
URL を新しいタブで開くようにする
icon
type: React.SFC
| "placeholder"
| string
アイコンのソース
id
type: string
アクションの一意の識別子
loading
type: boolean
スピナーを表示させるか
outline
type: boolean
アクションは輪郭のあるボタンで表示すべき
url
type: string
アクションで表示されるリンク先
onAction
type: () => void
アクションが起こったときのコールバック
onMouseEnter
type: () => void
マウス入力時のコールバック
onTouchStart
type: () => void
要素がタッチされたときのコールバック
ComplexAction[]
セカンダリーアクションのコレクション
sectioned
boolean
モーダルに自動でセクションを追加
small
boolean
モーダルの幅を小さくする
src
string
モーダルのコンテンツとして読み込まれる URL
title (Required)
Type
string
type: string
Or
React.ReactNode
type: React.ReactNode
string
| React.ReactNode
モーダルのタイトルを表すコンテンツ
titleHidden
boolean
モーダルのタイトルを隠す
onClose
(Required
)
() => void
モーダルが閉じられたときのコールバック
onIFrameLoad
(evt: SyntheticEvent) => void
iframe がロードされたときのコールバック
onScrolledToBottom
() => void
モーダルコンテンツの最下部に到達したときのコールバック
onTransitionEnd
() => void
モーダルトランジションのアニメーションが終了したときのコールバック
アクセシビリティ
- モーダルは ARIA
role="dialog"
を使用して、スクリーンリーダーのユーザーにネイティブのダイアログウィンドウのように動作することを伝えます。 - モーダルコンポーネントに見出しを与えるために
title
プロップを設定すると、ダイアログ要素にaria-labelledby
でラベルを付けるためにtitle
が使用されます。これにより、モーダルが表示されたときに、スクリーンリーダーのユーザーにモーダルの目的を伝えることができます。 - モーダルが閉じられた後、モーダルを起動したボタンにフォーカスを戻すためには、そのボタンを
activator
としてモーダルに渡します。
キーボード対応
- モーダルが開くと、キーボードユーザーがアクセスできるように、自動的にモーダルコンテナにフォーカスが移動します。
- モーダルが開いている間、キーボードのフォーカスはモーダルから離れてはいけません。
- マーチャントはキーボードでXボタン、キャンセルボタン(提供されている場合)、またはEscキーを押すことでモーダルを閉じることができます。
- モーダルを閉じた後、フォーカスはモーダルを起動したボタンに戻ります。
Android
プライマリーアクションのあるモーダル
マーチャントに主要なアクションを起こさせるために使用します。
プライマリーアクションとセカンダリーアクションのあるモーダル
マーチャントがモーダルの下部で重要なアクションを取るために使用します。
警告モーダル
マーチャントにそのアクションが潜在的に危険であることを明確にするために使用します。このオプションは、マーチャントが元に戻せない、または元に戻すのが困難なアクションを実行しようとしている場合にのみ使用してください。
アクセシビリティ
Android のアクセシビリティについては、Material Design と開発ドキュメントをご覧ください。
iOS
プライマリーアクションのあるモーダル
マーチャントに重要なアクションを起こさせるために使用します。
プライマリーアクションとセカンダリーアクションのあるモーダル
マーチャントがモーダルの下部で重要なアクションを取るために使用します。
警告モーダル
マーチャントにそのアクションが潜在的に危険であることを明確にするために使用します。このオプションは、マーチャントが元に戻せない、または元に戻すのが困難なアクションを実行しようとしている場合にのみ使用してください。
アクセシビリティ
iOS のアクセシビリティについては、Apple の Human Interface Guidelines や API のドキュメントをご覧ください。
組み込みアプリケーションでの使用(非推奨)
アプリプロバイダコンポーネントに API キーを渡すと、モーダルコンポーネントがスタンドアロンアプリケーションのようにレンダリングするのではなく、Shopify App Bridgeにデリゲートするようになります。
組み込みアプリケーションのコンテキストでは、ドキュメントにあるすべてのプロパティが利用できるわけではありません。いくつかのプロパティは、スタンドアロン・アプリケーションでのみ利用可能です。
スタンドアローン・コンテキストでのみ利用可能なプロパティは、(stand-alone app use only)として文書化されています。例えば、children
プロパティは、(stand-alone app use only)として文書化されています。
次の例では、モーダルコンポーネントを埋め込みアプリケーションのコンテキストで使用しています。
function EmbeddedAppModalExample() {
const [modalOpen, setModalOpen] = useState(false)
const handleModalClose = useCallback(() => setModalOpen(false), [])
return (
<AppProvider apiKey="YOUR_API_KEY" i18n={{}} shopOrigin="YOUR_SHOP_ORIGIN">
<Modal
src="https://my-app.com/upgrade-to-retail-package"
open={modalOpen}
title="Upgrade your Shopify POS with the Retail Package"
primaryAction={{
content: "Add Retail Package",
onAction: handleModalClose,
}}
secondaryActions={[
{
content: "Cancel",
onAction: handleModalClose,
},
]}
onClose={handleModalClose}
/>
</AppProvider>
)
}
非推奨の根拠
v3.17.0 の時点で、埋め込みアプリでModalを使用することは非推奨となっています。v5.0 では、基盤となる Shopify App Bridge ライブラリが Polaris React から削除されるため、このサポートは削除されます。非推奨の理由についてはこちらをご覧ください。代わりに@shopify/app-bridge-react
のModalを使用してください。
ベストプラクティス
マーチャントがアクションを完了しないとメインのワークフローに進めない場合にモーダルを使用します。複雑なフォームや大量の情報を表示するためにモーダルを使用することは避けてください。
モーダルは、次のようなものでなければなりません。
- マーチャントがアクションを起こすことが必要です。
- マーチャントがXボタン、キャンセルボタン、またはEscキーを押したときに閉じるのであって、マーチャントがモーダルの外の領域をクリックまたはタップしたときに閉じるのではありません。
- 下部に 2 つ以上のボタン(プライマリおよびセカンダリ)を配置しない。これにより、アクションの階層が不明確になり、モバイル画面での混雑を防ぐことができます。モーダルは集中したタスクのためのものなので、アクションも集中したものでなければなりません。しかし、場合によっては、第三のアクションが適切なこともあります。
コンテンツガイドライン
タイトル
モーダルタイトルは、次のようなものでなければなりません。
- 明確な{動詞}+{名詞}の質問や文を使う
- 見出し、小見出しのコンテンツガイドラインに従う
本文の内容
本文の内容は、次のようなものでなければなりません。
- 実行可能: マーチャントにどのようなアクションが可能か(特に新しいこと)を伝えるときは、命令形の動詞で文を始めます。「You can」のような寛容な言葉は使わないでください。
- マーチャントの成功のための構造化:常に最も重要な情報を最初に置く。
- 明確に:マーチャントが何かをしなければならない時には、「必要」という動詞を使って理解できるようにします。
プライマリーアクションとセカンダリーアクション
アクションは、次のようなものでなければなりません。
- 明確で予測可能であること:マーチャントはボタンをクリックしたときに何が起こるのかを予測できなければなりません。アクションのラベルを間違えてマーチャントを騙してはいけません。
スキャナブル:the、an、a などの不要な単語や冠詞を避ける。
第三次アクション
第三次アクションは、次のようなものでなければなりません。
- アクションがモーダルのコンテンツのコンテキストを必要とする場合にのみ使用する。
- モーダルの解除には使用しない
フッター
本文の内容は、次のようなものでなければなりません。
実行可能: マーチャントにどのようなアクションが可能か(特に新しいこと)を伝えるときは、命令形の動詞で文を始めます。「You can」のような寛容な言葉は使わないでください。
- マーチャントの成功のための構造化:常に最も重要な情報を最初に置く。
- 明確に:マーチャントが何かをしなければならない時には、「必要」という動詞を使って理解できるようにします。
関連コンポーネント
- 確認を必要としない大量の追加情報やアクションを表示するには、collapsible コンポーネントを使用して、ページ内の所定の位置にコンテンツを展開します。
- 少量のコンテンツやアクションのメニューをノンブロッキングオーバーレイで表示するには、popover コンポーネントを使用します。
- マーチャントの注意が必要な変化や状態をページ内で伝えるには、banner コンポーネントを使用します。
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
Discussion