【Polaris和訳】Components/Forms①
この記事について
この記事は、Polaris/Components/Formsの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
Forms①
Autocomplete
autocomplete コンポーネントは、マーチャントが入力すると、選択可能な候補が表示される入力フィールドです。マーチャントは、大量の選択肢の中からすばやく検索して選択することができます。オートコンプリートは、Combobox および Listbox コンポーネントの便利なラッパーですが、UI には若干の違いがあります。
例
Basic autocomplete
React
function AutocompleteExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (value === '') {
setOptions(deselectedOptions);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = deselectedOptions.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
},
[deselectedOptions],
);
const updateSelection = useCallback(
(selected) => {
const selectedValue = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedValue[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="base" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
options={options}
selected={selectedOptions}
onSelect={updateSelection}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField6Label" for="PolarisComboboxTextField6" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField6Prefix"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField6" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField6Label PolarisComboboxTextField6Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover6" aria-owns="Polarispopover6">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal3"></div>
</div>
</div>
Multiple tags autocomplete
React
function MultiAutocompleteExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (value === '') {
setOptions(deselectedOptions);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = deselectedOptions.filter((option) =>
option.label.match(filterRegex),
);
let endIndex = resultOptions.length - 1;
if (resultOptions.length === 0) {
endIndex = 0;
}
setOptions(resultOptions);
},
[deselectedOptions],
);
const removeTag = useCallback(
(tag) => () => {
const options = [...selectedOptions];
options.splice(options.indexOf(tag), 1);
setSelectedOptions(options);
},
[selectedOptions],
);
const tagsMarkup = selectedOptions.map((option) => {
let tagLabel = '';
tagLabel = option.replace('_', ' ');
tagLabel = titleCase(tagLabel);
return (
<Tag key={`option${option}`} onRemove={removeTag(option)}>
{tagLabel}
</Tag>
);
});
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
placeholder="Vintage, cotton, summer"
/>
);
return (
<div style={{height: '325px'}}>
<TextContainer>
<Stack>{tagsMarkup}</Stack>
</TextContainer>
<br />
<Autocomplete
allowMultiple
options={options}
selected={selectedOptions}
textField={textField}
onSelect={setSelectedOptions}
listTitle="Suggested Tags"
/>
</div>
);
function titleCase(string) {
return string
.toLowerCase()
.split(' ')
.map((word) => word.replace(word[0], word[0].toUpperCase()))
.join('');
}
}
HTML
<div>
<div style="height: 325px;">
<div class="Polaris-TextContainer">
<div class="Polaris-Stack"></div>
</div><br>
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField8Label" for="PolarisComboboxTextField8" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField"><input id="PolarisComboboxTextField8" role="combobox" placeholder="Vintage, cotton, summer" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField8Label" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover8" aria-owns="Polarispopover8">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal4"></div>
</div>
</div>
Multiple sections autocomplete
React
function AutocompleteExample() {
const deselectedOptions = useMemo(
() => [
{
title: 'Frequently used',
options: [
{value: 'ups', label: 'UPS'},
{value: 'usps', label: 'USPS'},
],
},
{
title: 'All carriers',
options: [
{value: 'dhl', label: 'DHL Express'},
{value: 'canada_post', label: 'Canada Post'},
],
},
],
[],
);
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (value === '') {
setOptions(deselectedOptions);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = [];
deselectedOptions.forEach((opt) => {
const lol = opt.options.filter((option) =>
option.label.match(filterRegex),
);
resultOptions.push({
title: opt.title,
options: lol,
});
});
setOptions(resultOptions);
},
[deselectedOptions],
);
const updateSelection = useCallback(
([selected]) => {
let selectedValue;
options.forEach(({options: opt}) => {
if (selectedValue) {
return;
}
const matchedOption = opt.find((option) =>
option.value.match(selected),
);
if (matchedOption) {
selectedValue = matchedOption.label;
}
});
setSelectedOptions([selected]);
setInputValue(String(selectedValue) ? String(selectedValue) : '');
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="base" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
textField={textField}
selected={selectedOptions}
options={options}
onSelect={updateSelection}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField10Label" for="PolarisComboboxTextField10" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField10Prefix"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField10" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField10Label PolarisComboboxTextField10Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover10" aria-owns="Polarispopover10">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal5"></div>
</div>
</div>
Autocomplete with loading
React
function AutocompleteExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [loading, setLoading] = useState(false);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (!loading) {
setLoading(true);
}
setTimeout(() => {
if (value === '') {
setOptions(deselectedOptions);
setLoading(false);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = deselectedOptions.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
setLoading(false);
}, 300);
},
[deselectedOptions, options, loading],
);
const updateSelection = useCallback(
(selected) => {
const selectedText = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedText[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="base" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
options={options}
selected={selectedOptions}
onSelect={updateSelection}
loading={loading}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField12Label" for="PolarisComboboxTextField12" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField12Prefix"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField12" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField12Label PolarisComboboxTextField12Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover12" aria-owns="Polarispopover12">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal6"></div>
</div>
</div>
Autocomplete with lazy loading
React
function AutoCompleteLazyLoadExample() {
const paginationInterval = 25;
const deselectedOptions = Array.from(Array(100)).map((_, index) => ({
value: `rustic ${index + 1}`,
label: `Rustic ${index + 1}`,
}));
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [isLoading, setIsLoading] = useState(false);
const [willLoadMoreResults, setWillLoadMoreResults] = useState(true);
const [visibleOptionIndex, setVisibleOptionIndex] =
useState(paginationInterval);
const handleLoadMoreResults = useCallback(() => {
if (willLoadMoreResults) {
setIsLoading(true);
setTimeout(() => {
const remainingOptionCount = options.length - visibleOptionIndex;
const nextVisibleOptionIndex =
remainingOptionCount >= paginationInterval
? visibleOptionIndex + paginationInterval
: visibleOptionIndex + remainingOptionCount;
setIsLoading(false);
setVisibleOptionIndex(nextVisibleOptionIndex);
if (remainingOptionCount <= paginationInterval) {
setWillLoadMoreResults(false);
}
}, 1000);
}
}, [willLoadMoreResults, visibleOptionIndex, options.length]);
const removeTag = useCallback(
(tag) => () => {
const options = [...selectedOptions];
options.splice(options.indexOf(tag), 1);
setSelectedOptions(options);
},
[selectedOptions],
);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (value === '') {
setOptions(deselectedOptions);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = deselectedOptions.filter((option) =>
option.label.match(filterRegex),
);
let endIndex = resultOptions.length - 1;
if (resultOptions.length === 0) {
endIndex = 0;
}
setOptions(resultOptions);
setInputValue;
},
[deselectedOptions, options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
placeholder="Vintage, cotton, summer"
/>
);
const hasSelectedOptions = selectedOptions.length > 0;
const tagsMarkup = hasSelectedOptions
? selectedOptions.map((option) => {
let tagLabel = '';
tagLabel = option.replace('_', ' ');
tagLabel = titleCase(tagLabel);
return (
<Tag key={`option${option}`} onRemove={removeTag(option)}>
{tagLabel}
</Tag>
);
})
: null;
const optionList = options.slice(0, visibleOptionIndex);
const selectedTagMarkup = hasSelectedOptions ? (
<Stack spacing="extraTight">{tagsMarkup}</Stack>
) : null;
return (
<Stack vertical>
{selectedTagMarkup}
<Autocomplete
allowMultiple
options={optionList}
selected={selectedOptions}
textField={textField}
onSelect={setSelectedOptions}
listTitle="Suggested Tags"
loading={isLoading}
onLoadMoreResults={handleLoadMoreResults}
willLoadMoreResults={willLoadMoreResults}
/>
</Stack>
);
function titleCase(string) {
return string
.toLowerCase()
.split(' ')
.map((word) => {
return word.replace(word[0], word[0].toUpperCase());
})
.join(' ');
}
}
HTML
<div>
<div class="Polaris-Stack Polaris-Stack--vertical">
<div class="Polaris-Stack__Item">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField14Label" for="PolarisComboboxTextField14" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField"><input id="PolarisComboboxTextField14" role="combobox" placeholder="Vintage, cotton, summer" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField14Label" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover14" aria-owns="Polarispopover14">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal7"></div>
</div>
</div>
Autocomplete with empty state
React
function AutocompleteExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [loading, setLoading] = useState(false);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (!loading) {
setLoading(true);
}
setTimeout(() => {
if (value === '') {
setOptions(deselectedOptions);
setLoading(false);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = deselectedOptions.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
setLoading(false);
}, 300);
},
[deselectedOptions, loading, options],
);
const updateSelection = useCallback(
(selected) => {
const selectedText = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedText[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="base" />}
placeholder="Search"
/>
);
const emptyState = (
<React.Fragment>
<Icon source={SearchMinor} />
<div style={{textAlign: 'center'}}>
<TextContainer>Could not find any results</TextContainer>
</div>
</React.Fragment>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
options={options}
selected={selectedOptions}
onSelect={updateSelection}
emptyState={emptyState}
loading={loading}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField16Label" for="PolarisComboboxTextField16" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField16Prefix"><span class="Polaris-Icon Polaris-Icon--colorBase Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField16" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField16Label PolarisComboboxTextField16Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover16" aria-owns="Polarispopover16">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal8"></div>
</div>
</div>
Autocomplete with action
React
function AutocompleteActionBeforeExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [loading, setLoading] = useState(false);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (!loading) {
setLoading(true);
}
setTimeout(() => {
if (value === '') {
setOptions(deselectedOptions);
setLoading(false);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = options.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
setLoading(false);
}, 300);
},
[deselectedOptions, loading, options],
);
const updateSelection = useCallback(
(selected) => {
const selectedText = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedText[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="inkLighter" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
actionBefore={{
accessibilityLabel: 'Action label',
badge: {
status: 'new',
content: 'New!',
},
content: 'Action with long name',
ellipsis: true,
helpText: 'Help text',
icon: CirclePlusMinor,
}}
options={options}
selected={selectedOptions}
onSelect={updateSelection}
listTitle="Suggested tags"
loading={loading}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField18Label" for="PolarisComboboxTextField18" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField18Prefix"><span class="Polaris-Icon Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField18" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField18Label PolarisComboboxTextField18Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover18" aria-owns="Polarispopover18">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal9"></div>
</div>
</div>
Autocomplete with wrapping action
React
function AutocompleteActionBeforeExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [loading, setLoading] = useState(false);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (!loading) {
setLoading(true);
}
setTimeout(() => {
if (value === '') {
setOptions(deselectedOptions);
setLoading(false);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = options.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
setLoading(false);
}, 300);
},
[deselectedOptions, loading, options],
);
const updateSelection = useCallback(
(selected) => {
const selectedText = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedText[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="inkLighter" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
actionBefore={{
accessibilityLabel: 'Action label',
badge: {
status: 'new',
content: 'New!',
},
content:
'Action with long name that will need to wrap on small display in order to have a nice display',
ellipsis: true,
helpText: 'Help text',
icon: CirclePlusMinor,
wrapOverflow: true,
}}
options={options}
selected={selectedOptions}
onSelect={updateSelection}
listTitle="Suggested tags"
loading={loading}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField20Label" for="PolarisComboboxTextField20" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField20Prefix"><span class="Polaris-Icon Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField20" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField20Label PolarisComboboxTextField20Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover20" aria-owns="Polarispopover20">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal10"></div>
</div>
</div>
Autocomplete with destructive action
React
function AutocompleteActionBeforeExample() {
const deselectedOptions = [
{value: 'rustic', label: 'Rustic'},
{value: 'antique', label: 'Antique'},
{value: 'vinyl', label: 'Vinyl'},
{value: 'vintage', label: 'Vintage'},
{value: 'refurbished', label: 'Refurbished'},
];
const [selectedOptions, setSelectedOptions] = useState([]);
const [inputValue, setInputValue] = useState('');
const [options, setOptions] = useState(deselectedOptions);
const [loading, setLoading] = useState(false);
const updateText = useCallback(
(value) => {
setInputValue(value);
if (!loading) {
setLoading(true);
}
setTimeout(() => {
if (value === '') {
setOptions(deselectedOptions);
setLoading(false);
return;
}
const filterRegex = new RegExp(value, 'i');
const resultOptions = options.filter((option) =>
option.label.match(filterRegex),
);
setOptions(resultOptions);
setLoading(false);
}, 300);
},
[deselectedOptions, loading, options],
);
const updateSelection = useCallback(
(selected) => {
const selectedText = selected.map((selectedItem) => {
const matchedOption = options.find((option) => {
return option.value.match(selectedItem);
});
return matchedOption && matchedOption.label;
});
setSelectedOptions(selected);
setInputValue(selectedText[0]);
},
[options],
);
const textField = (
<Autocomplete.TextField
onChange={updateText}
label="Tags"
value={inputValue}
prefix={<Icon source={SearchMinor} color="inkLighter" />}
placeholder="Search"
/>
);
return (
<div style={{height: '225px'}}>
<Autocomplete
actionBefore={{
accessibilityLabel: 'Destructive action label',
content: 'Destructive action',
destructive: true,
icon: DeleteMinor,
}}
options={options}
selected={selectedOptions}
onSelect={updateSelection}
listTitle="Suggested tags"
loading={loading}
textField={textField}
/>
</div>
);
}
HTML
<div>
<div style="height: 225px;">
<div>
<div class="">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisComboboxTextField22Label" for="PolarisComboboxTextField22" class="Polaris-Label__Text">Tags</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField">
<div class="Polaris-TextField__Prefix" id="PolarisComboboxTextField22Prefix"><span class="Polaris-Icon Polaris-Icon--applyColor"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm9.707 4.293-4.82-4.82A5.968 5.968 0 0 0 14 8 6 6 0 0 0 2 8a6 6 0 0 0 6 6 5.968 5.968 0 0 0 3.473-1.113l4.82 4.82a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414z"></path>
</svg></span></div><input id="PolarisComboboxTextField22" role="combobox" placeholder="Search" class="Polaris-TextField__Input" aria-labelledby="PolarisComboboxTextField22Label PolarisComboboxTextField22Prefix" aria-invalid="false" aria-autocomplete="list" aria-expanded="false" value="" tabindex="0" aria-controls="Polarispopover22" aria-owns="Polarispopover22">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer">
<div data-portal-id="popover-Polarisportal11"></div>
</div>
</div>
Props
allowMultiple
boolean
複数のオプションを選択可能
emptyState
React.ReactNode
選択肢がない場合にレンダリングされます
id
string
オートコンプリートの一意の識別子
listTitle
string
選択肢のリストのタイトル
loading
boolean
ディスプレイローディングの state
options
(Required
)
Array
リストアップされるオプションのコレクション
preferredPosition
"above"
| "below"
| "mostSpace"
ポップオーバーを開くのに適した方向
selected
(Required
)
string[]
選択されたオプション
textField
(Required
)
ReactElement
選択肢のリストに添付されるテキストフィールドコンポーネント
willLoadMoreResults
boolean
より多くの結果を動的に読み込むかどうかを示す
onLoadMoreResults
() => void
リストの最後に到達したときのコールバック
onSelect
(Required
)
(selected: string[]) => void
選択肢が変更されたときのコールバック
アクセシビリティ
構造
オートコンプリートコンポーネントは、ARIA 1.2 combobox patternとAria 1.2 Listbox patternに基づいています。
autocomplete リストは、デフォルトでは、テキストフィールドなどのコントロールの下に表示されるので、マーチャントが見つけやすく、使いやすいです。ただし、preferredPosition
プロップで位置を変更できます。
autocomplete 機能は、視覚障害、運動障害、認知障害を持つマーチャントにとって難しい場合があります。ベストプラクティスに基づいて構築されていても、一部の支援技術ではこれらの機能を使用することが困難な場合があります。マーチャントは、autocomplete に頼らずに、常に検索、データ入力、またはその他のアクティビティを実行できる必要があります。
キーボード対応
- tabキーで autocomplete のテキスト入力にキーボードフォーカスを与える(逆方向にタブするときは shift+tab キー)。
- 上下の矢印キーでオプションのリストにアクセス
- フォーカスされているオプションを enter/return キーで選択
ベストプラクティス
autocomplete コンポーネントは、以下の点に注意してください。
- マーチャントがどのような種類のオプションを利用できるかがわかるように、明確なラベルを付ける。
- 一度に表示するオプションの数を制限する。
- ポップオーバーの中では使用しない。
- オプションのデータが入力されている間は、マーチャントに読み込み中であることを示す。
コンテンツガイドライン
autocomplete 用の入力フィールドは、テキストフィールドのコンテンツガイドラインに従うべきです。
関連コンポーネント
- 推奨されるオプションのない入力フィールドには、テキストフィールドコンポーネントを使用します。
- 入力フィールドにリンクされていない、選択可能なオプションのリストには、オプションリストコンポーネントを使用します。
- ポップオーバーを誘発するテキストフィールドには、コンボボックスコンポーネントを使用します。
Checkbox
チェックボックスは、マーチャントがさまざまな選択(0、1、または複数)をするための手段として最も一般的に使用されます。また、マーチャントが特定の条件やサービスに同意することを示す手段としても使用されます。
Web
例
Default checkboxes
フォームで、何かの状態をオンまたはオフに切り替えるために使用します。デフォルトのチェックボックスは、「選択されているが無効」「選択されていない」の 2 つの状態で表示されます。
React
function CheckboxExample() {
const [checked, setChecked] = useState(false);
const handleChange = useCallback((newChecked) => setChecked(newChecked), []);
return (
<Checkbox
label="Basic checkbox"
checked={checked}
onChange={handleChange}
/>
);
}
HTML
<div><label class="Polaris-Choice" for="PolarisCheckbox2"><span class="Polaris-Choice__Control"><span class="Polaris-Checkbox"><input id="PolarisCheckbox2" type="checkbox" class="Polaris-Checkbox__Input" aria-invalid="false" role="checkbox" aria-checked="false" value=""><span class="Polaris-Checkbox__Backdrop"></span><span class="Polaris-Checkbox__Icon"><span class="Polaris-Icon"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m8.315 13.859-3.182-3.417a.506.506 0 0 1 0-.684l.643-.683a.437.437 0 0 1 .642 0l2.22 2.393 4.942-5.327a.436.436 0 0 1 .643 0l.643.684a.504.504 0 0 1 0 .683l-5.91 6.35a.437.437 0 0 1-.642 0"></path>
</svg></span></span></span></span><span class="Polaris-Choice__Label">Basic checkbox</span></label>
<div id="PolarisPortalsContainer"></div>
</div>
Props
ariaControls
string
チェックボックスで制御される要素の ID を示す
ariaDescribedBy
string
チェックボックスを記述した要素の ID を示す
checked
boolean
| "indeterminate"
チェックボックスが選択されています。indeterminate
では、チェックボックスに横線が表示されます。
disabled
boolean
入力を無効にする
error
string
| ReactElement
| (string | ReactElement)[]
| boolean
エラーメッセージを表示する
helpText
React.ReactNode
使用時の補助テキストの追加
id
string
フォーム入力用の ID
label
(Required
)
React.ReactNode
チェックボックスのラベル
labelHidden
boolean
ラベルを視覚的に隠す
name
string
フォーム入力用の名前
value
string
フォーム入力用の値
onBlur
() => void
フォーカスが外れた時のコールバック
onChange
(newChecked: boolean, id: string) => void
チェックボックスが切り替えられた時のコールバック
onFocus
() => void
チェックボックスがフォーカスされた時のコールバック
アクセシビリティ
スクリーン・リーダーはチェックボックスの状態を自動的に伝えます。
-
disabled
prop を使って、チェックボックスの<input>
に HTML のdisabled
属性を適用します。これにより、マーチャントはチェックボックスを操作することができなくなり、アシスティブテクノロジーにはその非アクティブな状態が伝えられます。 -
id
prop を使って、チェックボックスに一意のid
属性値を与えます。id
が指定されていない場合は、コンポーネントがid
を生成します。アシスティブテクノロジーで正しく動作させるためには、すべてのチェックボックスに一意のid
値が必要です。 -
checked="indeterminate"
を設定すると、aria-checked="mixed"
を使用して、チェックボックスの状態を伝えます。 -
ariaControls
prop を設定すると、チェックボックスの内容や存在が制御される要素の ID が、aria-controls
属性を使ってスクリーン・リーダーのユーザーに伝えられます。
ラベリング
- 必須の
label
prop は、すべてのマーチャントにチェックボックスの目的を伝えます。 -
labelHidden
prop を使ってラベルを視覚的に隠しますが、支援技術で利用できるようにします。 -
helpText
prop でヘルプテキストを与えたり、error
prop でインラインエラーメッセージを与える場合、ヘルプやエラーの内容はaria-describedby
属性でスクリーンリーダーのユーザーに伝えられます。
キーボードサポート
- 各チェックボックスにフォーカスを移すには、tabキー(逆方向のタブ操作の場合は、shift+tabキー)を使います。
- キーボードフォーカスがある状態でチェックボックスを操作するには、sapceキー
Android
デフォルトのチェックボックス
フォームで、何かの状態をオンまたはオフに切り替えるために使用します。デフォルトのチェックボックスは、「選択されているが無効」「選択されていない」の 2 つの状態で表示されます。
アクセシビリティ
Android のアクセシビリティについては、Material Design と開発ドキュメントをご覧ください。
iOS
デフォルトのチェックボックス
フォームで、何かの状態をオンまたはオフに切り替えるために使用します。デフォルトのチェックボックスは、「選択されているが無効」「選択されていない」の 2 つの状態で表示されます。
アクセシビリティ
iOS のアクセシビリティについては、Apple の Human Interface Guidelines や API のドキュメントをご覧ください。
ベストプラクティス
チェックボックスは以下のことに注意してください。
- あるチェックボックスを選択しても、リスト内の別のチェックボックスの選択状態が変わることはありません。ただし、複数の項目を一括して選択するためにチェックボックスを使用する場合は例外です。
- ポジティブなフレームであること:例えば、
Turn off notifications
ではなくTurn on notifications
のように。 - 設定のオン/オフを切り替えるために使用される場合は、必ずラベルを付ける。
- アルファベット順、数字順、時間順、その他の明確なシステムなど、論理的な順序に沿って表示されていること。
- 必要に応じて、詳細情報へのリンクやサブタイトルをつけて、より詳しい説明をすること。チェックボックスの説明をツールチップに頼るのはやめましょう。
コンテンツガイドライン
チェックボックスのリスト
チェックボックスを使うリストは以下のことに注意してください。
- 最初の文字を大文字にする。
- カンマやセミコロンを各行の最後に使わない。
- チェックボックスでマーチャントに規約やサービスへの同意を求めている稀なケースでは、一人称である。
関連コンポーネント
- マーチャントが単一の選択しかできない選択肢のリストを表示するには、ラジオボタンコンポーネントを使用します。
- 関連するコンテンツのリストを表示するには、選択リストコンポーネントを使用します。
- グループ化されていないリストを作成するには、コンテンツリストコンポーネントを使用します。
Choice list
チョイスリストでは、グループ化されたラジオボタンやチェックボックスのリストを作成できます。このコンポーネントは、インタラクティブな選択肢の関連リストをグループ化する必要がある場合に使用します。
Web
例
Single choice list
マーチャントがリストから 1 つのオプションを選択できるようにします。
- すべてのオプションが、どちらか一方のみの選択であることを確認してください。
React
function SingleChoiceListExample() {
const [selected, setSelected] = useState(['hidden']);
const handleChange = useCallback((value) => setSelected(value), []);
return (
<ChoiceList
title="Company name"
choices={[
{label: 'Hidden', value: 'hidden'},
{label: 'Optional', value: 'optional'},
{label: 'Required', value: 'required'},
]}
selected={selected}
onChange={handleChange}
/>
);
}
HTML
<div>
<fieldset class="Polaris-ChoiceList" id="PolarisChoiceList2" aria-invalid="false">
<legend class="Polaris-ChoiceList__Title">Company name</legend>
<ul class="Polaris-ChoiceList__Choices">
<li><label class="Polaris-Choice" for="PolarisRadioButton4"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton4" name="PolarisChoiceList2" type="radio" class="Polaris-RadioButton__Input" value="hidden" checked=""><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Hidden</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton5"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton5" name="PolarisChoiceList2" type="radio" class="Polaris-RadioButton__Input" value="optional"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Optional</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton6"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton6" name="PolarisChoiceList2" type="radio" class="Polaris-RadioButton__Input" value="required"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Required</span></label></li>
</ul>
</fieldset>
<div id="PolarisPortalsContainer"></div>
</div>
Single choice list with error
エラーメッセージとエラーのあるフィールドを結びつけることで、アクセス可能なエラー処理を可能にします。
React
function ChoiceListWithErrorExample() {
const [selected, setSelected] = useState('hidden');
const handleChange = useCallback((value) => setSelected(value), []);
return (
<ChoiceList
title="Company name"
choices={[
{label: 'Hidden', value: 'hidden', describedByError: true},
{label: 'Optional', value: 'optional'},
{label: 'Required', value: 'required'},
]}
selected={selected}
onChange={handleChange}
error="Company name cannot be hidden at this time"
/>
);
}
HTML
<div>
<fieldset class="Polaris-ChoiceList" id="PolarisChoiceList4" aria-invalid="true">
<legend class="Polaris-ChoiceList__Title">Company name</legend>
<ul class="Polaris-ChoiceList__Choices">
<li><label class="Polaris-Choice" for="PolarisRadioButton10"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton10" name="PolarisChoiceList4" type="radio" class="Polaris-RadioButton__Input" aria-describedby="PolarisChoiceList4Error" value="hidden" checked=""><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Hidden</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton11"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton11" name="PolarisChoiceList4" type="radio" class="Polaris-RadioButton__Input" value="optional"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Optional</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton12"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton12" name="PolarisChoiceList4" type="radio" class="Polaris-RadioButton__Input" value="required"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Required</span></label></li>
</ul>
<div class="Polaris-ChoiceList__ChoiceError">
<div id="PolarisChoiceList4Error" class="Polaris-InlineError">
<div class="Polaris-InlineError__Icon"><span class="Polaris-Icon"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16zM9 9a1 1 0 0 0 2 0V7a1 1 0 1 0-2 0v2zm0 4a1 1 0 1 0 2 0 1 1 0 0 0-2 0z"></path>
</svg></span></div>Company name cannot be hidden at this time
</div>
</div>
</fieldset>
<div id="PolarisPortalsContainer"></div>
</div>
Multi-choice list
マーチャントがリストから複数のオプションを選択できるようにします。
- どちらか一方しか選べないオプションは避けてください。
React
function MultiChoiceListExample() {
const [selected, setSelected] = useState(['hidden']);
const handleChange = useCallback((value) => setSelected(value), []);
return (
<ChoiceList
allowMultiple
title="While the customer is checking out"
choices={[
{
label: 'Use the shipping address as the billing address by default',
value: 'shipping',
helpText:
'Reduces the number of fields required to check out. The billing address can still be edited.',
},
{
label: 'Require a confirmation step',
value: 'confirmation',
helpText:
'Customers must review their order details before purchasing.',
},
]}
selected={selected}
onChange={handleChange}
/>
);
}
HTML
<div>
<fieldset class="Polaris-ChoiceList" id="PolarisChoiceList6[]" aria-invalid="false">
<legend class="Polaris-ChoiceList__Title">While the customer is checking out</legend>
<ul class="Polaris-ChoiceList__Choices">
<li>
<div><label class="Polaris-Choice" for="PolarisCheckbox3"><span class="Polaris-Choice__Control"><span class="Polaris-Checkbox"><input id="PolarisCheckbox3" name="PolarisChoiceList6[]" type="checkbox" class="Polaris-Checkbox__Input" aria-invalid="false" aria-describedby="PolarisCheckbox3HelpText" role="checkbox" aria-checked="false" value="shipping"><span class="Polaris-Checkbox__Backdrop"></span><span class="Polaris-Checkbox__Icon"><span class="Polaris-Icon"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m8.315 13.859-3.182-3.417a.506.506 0 0 1 0-.684l.643-.683a.437.437 0 0 1 .642 0l2.22 2.393 4.942-5.327a.436.436 0 0 1 .643 0l.643.684a.504.504 0 0 1 0 .683l-5.91 6.35a.437.437 0 0 1-.642 0"></path>
</svg></span></span></span></span><span class="Polaris-Choice__Label">Use the shipping address as the billing address by default</span></label>
<div class="Polaris-Choice__Descriptions">
<div class="Polaris-Choice__HelpText" id="PolarisCheckbox3HelpText">Reduces the number of fields required to check out. The billing address can still be edited.</div>
</div>
</div>
</li>
<li>
<div><label class="Polaris-Choice" for="PolarisCheckbox4"><span class="Polaris-Choice__Control"><span class="Polaris-Checkbox"><input id="PolarisCheckbox4" name="PolarisChoiceList6[]" type="checkbox" class="Polaris-Checkbox__Input" aria-invalid="false" aria-describedby="PolarisCheckbox4HelpText" role="checkbox" aria-checked="false" value="confirmation"><span class="Polaris-Checkbox__Backdrop"></span><span class="Polaris-Checkbox__Icon"><span class="Polaris-Icon"><span class="Polaris-VisuallyHidden"></span><svg viewBox="0 0 20 20" class="Polaris-Icon__Svg" focusable="false" aria-hidden="true">
<path d="m8.315 13.859-3.182-3.417a.506.506 0 0 1 0-.684l.643-.683a.437.437 0 0 1 .642 0l2.22 2.393 4.942-5.327a.436.436 0 0 1 .643 0l.643.684a.504.504 0 0 1 0 .683l-5.91 6.35a.437.437 0 0 1-.642 0"></path>
</svg></span></span></span></span><span class="Polaris-Choice__Label">Require a confirmation step</span></label>
<div class="Polaris-Choice__Descriptions">
<div class="Polaris-Choice__HelpText" id="PolarisCheckbox4HelpText">Customers must review their order details before purchasing.</div>
</div>
</div>
</li>
</ul>
</fieldset>
<div id="PolarisPortalsContainer"></div>
</div>
Single-choice or multi-choice list with children content (always rendered)
マーチャントが選択肢の下にある追加コンテンツを見たり、操作したりする必要がある場合に使用します。コンテンツは常にレンダリングされます。選択肢が一つしかないときと複数あるときの両方に対応しています。
React
function SingleOrMultiChoiceListWithChildrenContextExample() {
const [selected, setSelected] = useState(['none']);
const [textFieldValue, setTextFieldValue] = useState('');
const handleChoiceListChange = useCallback((value) => setSelected(value), []);
const handleTextFieldChange = useCallback(
(value) => setTextFieldValue(value),
[],
);
const renderChildren = useCallback(
() => (
<TextField
label="Minimum Quantity"
labelHidden
onChange={handleTextFieldChange}
value={textFieldValue}
autoComplete="off"
/>
),
[handleTextFieldChange, textFieldValue],
);
return (
<ChoiceList
title="Discount minimum requirements"
choices={[
{label: 'None', value: 'none'},
{label: 'Minimum purchase', value: 'minimum_purchase'},
{
label: 'Minimum quantity',
value: 'minimum_quantity',
renderChildren,
},
]}
selected={selected}
onChange={handleChoiceListChange}
/>
);
}
HTML
<div>
<fieldset class="Polaris-ChoiceList" id="PolarisChoiceList8" aria-invalid="false">
<legend class="Polaris-ChoiceList__Title">Discount minimum requirements</legend>
<ul class="Polaris-ChoiceList__Choices">
<li><label class="Polaris-Choice" for="PolarisRadioButton16"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton16" name="PolarisChoiceList8" type="radio" class="Polaris-RadioButton__Input" value="none" checked=""><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">None</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton17"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton17" name="PolarisChoiceList8" type="radio" class="Polaris-RadioButton__Input" value="minimum_purchase"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Minimum purchase</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton18"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton18" name="PolarisChoiceList8" type="radio" class="Polaris-RadioButton__Input" value="minimum_quantity"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Minimum quantity</span></label>
<div class="Polaris-ChoiceList__ChoiceChildren">
<div class="Polaris-Labelled--hidden">
<div class="Polaris-Labelled__LabelWrapper">
<div class="Polaris-Label"><label id="PolarisTextField2Label" for="PolarisTextField2" class="Polaris-Label__Text">Minimum Quantity</label></div>
</div>
<div class="Polaris-Connected">
<div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
<div class="Polaris-TextField"><input id="PolarisTextField2" autocomplete="off" class="Polaris-TextField__Input" aria-labelledby="PolarisTextField2Label" aria-invalid="false" value="">
<div class="Polaris-TextField__Backdrop"></div>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</fieldset>
<div id="PolarisPortalsContainer"></div>
</div>
Single-choice or multi-choice list with children content (only rendered when choice is selected)
マーチャントが選択肢の下にある追加コンテンツを見たり、操作したりする必要がある場合に使用します。このコンテンツは、選択肢が選択されたときにのみレンダリングされます。選択肢が一つしかないときと複数あるときの両方に対応しています。
React
function SingleOrMultuChoiceListWithChildrenContextWhenSelectedExample() {
const [selected, setSelected] = useState(['none']);
const [textFieldValue, setTextFieldValue] = useState('');
const handleChoiceListChange = useCallback((value) => setSelected(value), []);
const handleTextFieldChange = useCallback(
(value) => setTextFieldValue(value),
[],
);
const renderChildren = useCallback(
(isSelected) =>
isSelected && (
<TextField
label="Minimum Quantity"
labelHidden
onChange={handleTextFieldChange}
value={textFieldValue}
autoComplete="off"
/>
),
[handleTextFieldChange, textFieldValue],
);
return (
<div style={{height: '150px'}}>
<ChoiceList
title="Discount minimum requirements"
choices={[
{label: 'None', value: 'none'},
{label: 'Minimum purchase', value: 'minimum_purchase'},
{
label: 'Minimum quantity',
value: 'minimum_quantity',
renderChildren,
},
]}
selected={selected}
onChange={handleChoiceListChange}
/>
</div>
);
}
HTML
<div>
<div style="height: 150px;">
<fieldset class="Polaris-ChoiceList" id="PolarisChoiceList14" aria-invalid="false">
<legend class="Polaris-ChoiceList__Title">Discount minimum requirements</legend>
<ul class="Polaris-ChoiceList__Choices">
<li><label class="Polaris-Choice" for="PolarisRadioButton34"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton34" name="PolarisChoiceList14" type="radio" class="Polaris-RadioButton__Input" value="none" checked=""><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">None</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton35"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton35" name="PolarisChoiceList14" type="radio" class="Polaris-RadioButton__Input" value="minimum_purchase"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Minimum purchase</span></label></li>
<li><label class="Polaris-Choice" for="PolarisRadioButton36"><span class="Polaris-Choice__Control"><span class="Polaris-RadioButton"><input id="PolarisRadioButton36" name="PolarisChoiceList14" type="radio" class="Polaris-RadioButton__Input" value="minimum_quantity"><span class="Polaris-RadioButton__Backdrop"></span></span></span><span class="Polaris-Choice__Label">Minimum quantity</span></label></li>
</ul>
</fieldset>
</div>
<div id="PolarisPortalsContainer"></div>
</div>
Props
allowMultiple
boolean
マーチャントが一度に複数のオプションを選択できるようにする
choices
(Required
)
Choice[]
選択肢のコレクション
disabled
boolean
すべての選択肢を無効にする
error
string
| ReactElement
| (string | ReactElement)[]
エラーメッセージを表示する
name
string
フォーム入力用の名前
selected
(Required
)
string[]
厳選された選択肢のコレクション
title
(Required
)
React.ReactNode
選択肢のリストのラベル
titleHidden
boolean
タイトルの表示を切り替える
onChange
(selected: string[], name: string) => void
選択された選択肢が変更されたときのコールバック
アクセシビリティ
選択肢リストコンポーネントは、チェックボックスコンポーネントとラジオボタンコンポーネントのアクセシビリティ機能を使用しています。
Android
シングルチョイスリスト
マーチャントがリストから 1 つのオプションを選択できるようにします。
- 全てのオプションが、どちらか一方のみの選択であることを確認してください
エラー付きのシングルチョイスリスト
エラーメッセージとエラーのあるフィールドを結びつけることで、アクセス可能なエラー処理を可能にします。
マルチチョイスリスト
マーチャントがリストから複数のオプションを選択できるようにします。
- どちらか一方しか選べない選択肢は避けてください。
アクセシビリティ
Android のアクセシビリティについては、Material Design と開発ドキュメントをご覧ください。
iOS
シングルチョイスリスト
マーチャントがリストから 1 つのオプションを選択できるようにします。
- すべてのオプションが、どちらか一方のみの選択であることを確認してください。
エラー付きのシングルチョイスリスト
エラーメッセージとエラーのあるフィールドを結びつけることで、アクセス可能なエラー処理を可能にします。
マルチチョイスリスト
- どちらか一方しか選べないオプションは避けてください。
アクセシビリティ
iOS のアクセシビリティについては、Apple の Human Interface Guidelines や API のドキュメントをご覧ください。
ベストプラクティス
選択肢のリストは以下のことに注意してください。
- マーチャントが何をすべきか、または利用可能なオプションを説明するタイトルを含む
- オプションが何をするものなのかを明確に表示する。
- 複数選択が可能な場合、互いに排他的なオプションは避ける
コンテンツガイドライン
リストタイトル
リストタイトルは以下のことに注意してください
- マーチャントがリスト内のアイテムがどのようにグループ化されているかを理解できるようにする、またはマーチャントがどのような選択をしているかを説明する。
- 簡潔でスキャンしやすいこと
- 一目見てわかるように、シンプルで明確な表現を使用する
- リストタイトルは一文にとどめる
- タイトルが直下のリストを示している場合は、コロンで終わること
- 大文字小文字をくべるすること
- コロンを使わない
選択肢リスト
選択肢リストのすべての項目は、以下の通りです。
- 大文字で始まる
- 各行の最後にカンマやセミコロンを使わない
- 文語体(最初の単語は大文字、残りの単語は小文字)で書かれていること
ヘルパーテキストと説明文
リストにヘルパーテキストが含まれている場合、リストアイテムの下にある説明文にのみ句読点を入れる必要があります。
関連コンポーネント
- ラジオボタンの長いリストを表示する場合や、スペースが限られている場合は、セレクトコンポーネントを使用します。
- ラジオボタンやチェックボックスのグループを独自のレイアウトで作成するには、ラジオボタンコンポーネントまたはチェックボックスコンポーネントを使用します。
- シンプルで非インタラクティブな関連コンテンツのリストを表示するには、リストコンポーネントを使用します。
Color picker
カラーピッカーは、マーチャントが視覚的に色を選択するためのものです。例えば、マーチャントはカラーピッカーを使って、ショップのメールテンプレートのアクセントカラーをカスタマイズします。
例
Default color picker
マーチャントが色を選択する必要があるときに使用して、視覚的に選択できるようにします。
React
function ColorPickerExample() {
const [color, setColor] = useState({
hue: 120,
brightness: 1,
saturation: 1,
});
return <ColorPicker onChange={setColor} color={color} />;
}
HTML
<div>
<div class="Polaris-ColorPicker">
<div class="Polaris-ColorPicker__MainColor">
<div class="Polaris-ColorPicker__ColorLayer" style="background-color: rgb(0, 255, 0);"></div>
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(160px, 0px, 0px);"></div>
</div>
</div>
<div class="Polaris-ColorPicker__HuePicker">
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(0px, 58.6667px, 0px);"></div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer"></div>
</div>
Colorpicker with transparent value
ビジュアルビルダーに接続されている場合に使用し、指定されたオブジェクトが透明な背景を持ち、下にあるオブジェクトが透けて見えるようにします。
React
function ColorPickerWithTransparentValueExample() {
const [color, setColor] = useState({
hue: 300,
brightness: 1,
saturation: 0.7,
alpha: 0.7,
});
return <ColorPicker onChange={setColor} color={color} allowAlpha />;
}
HTML
<div>
<div class="Polaris-ColorPicker">
<div class="Polaris-ColorPicker__MainColor">
<div class="Polaris-ColorPicker__ColorLayer" style="background-color: rgba(255, 0, 255, 0.7);"></div>
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(112px, 0px, 0px);"></div>
</div>
</div>
<div class="Polaris-ColorPicker__HuePicker">
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(0px, 127.167px, 0px);"></div>
</div>
</div>
<div class="Polaris-ColorPicker__AlphaPicker">
<div class="Polaris-ColorPicker__ColorLayer" style="background: linear-gradient(to top, rgba(255, 77, 255, 0) 18px, rgb(255, 77, 255) calc(100% - 18px));"></div>
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(0px, 54.1px, 0px);"></div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer"></div>
</div>
Colorpicker with transparent value full width
ビジュアルビルダーに接続されている場合に使用し、指定されたオブジェクトが透明な背景を持ち、下にあるオブジェクトが透けて見えるようにします。
React
function ColorPickerWithTransparentValueExample() {
const [color, setColor] = useState({
hue: 300,
brightness: 1,
saturation: 0.7,
alpha: 0.7,
});
return <ColorPicker fullWidth onChange={setColor} color={color} allowAlpha />;
}
HTML
<div>
<div class="Polaris-ColorPicker Polaris-ColorPicker--fullWidth">
<div class="Polaris-ColorPicker__MainColor">
<div class="Polaris-ColorPicker__ColorLayer" style="background-color: rgba(255, 0, 255, 0.7);"></div>
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(473.2px, 0px, 0px);"></div>
</div>
</div>
<div class="Polaris-ColorPicker__HuePicker">
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(0px, 127.167px, 0px);"></div>
</div>
</div>
<div class="Polaris-ColorPicker__AlphaPicker">
<div class="Polaris-ColorPicker__ColorLayer" style="background: linear-gradient(to top, rgba(255, 77, 255, 0) 18px, rgb(255, 77, 255) calc(100% - 18px));"></div>
<div class="Polaris-ColorPicker__Slidable">
<div class="Polaris-ColorPicker__Dragger" style="transform: translate3d(0px, 54.1px, 0px);"></div>
</div>
</div>
</div>
<div id="PolarisPortalsContainer"></div>
</div>
Props
allowAlpha
boolean
ユーザーがアルファ値を選択できるようにする
color(Required)
Object
alpha
type: number
透明度
brightness
(Required
)
type: number
色の明るさ
hue
(Required
)
type: number
色
saturation
(Required
)
type: number
色の彩度
Color
現在選択されている色
fullWidth
boolean
HuePicker が幅いっぱいに表示されるようにする
id
string
要素の ID
onChange
(Required
)
(color: HSBAColor) => void
色が選択された時のコールバック
ベストプラクティス
- マーチャントが透明な色を選択できるようにするには、アルファスライダを使用します。
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
Discussion