# ChoiceList Use choice lists to present a list of choices where buyers can make a single selection or multiple selections. ### Basic ChoiceList ```tsx import { reactExtension, BlockStack, Choice, ChoiceList, Icon, InlineStack, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <InlineStack> <ChoiceList name="group-single" variant="group" value="ship" onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <Choice secondaryContent={ <Icon source="truck" /> } id="ship" > Ship </Choice> <Choice secondaryContent={ <Icon source="marker" /> } id="ship-to-pickup-point" > Ship to pickup point </Choice> <Choice secondaryContent={ <Icon source="store" /> } id="pick-up" > Pick up in store </Choice> </ChoiceList> <ChoiceList name="base-multiple" value={['remember-me']} onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <BlockStack> <Choice id="remember-me"> Save this information for next time </Choice> <Choice id="email-me"> Email me with news and offers </Choice> <Choice id="text-me"> Text me with news and offers </Choice> </BlockStack> </ChoiceList> </InlineStack> ); } ``` ```js import { extension, InlineStack, ChoiceList, Choice, BlockStack, Icon, } from '@shopify/ui-extensions/checkout'; export default extension('purchase.checkout.block.render', (root) => { const inlineStack = root.createComponent(InlineStack, undefined, [ root.createComponent( ChoiceList, { name: 'group-single', variant: 'group', value: 'ship', onChange: (value) => { console.log(`onChange event with value: ${value}`); }, }, [ root.createComponent( Choice, { secondaryContent: root.createComponent(Icon, {source: 'truck'}), id: 'ship', }, 'Ship', ), root.createComponent( Choice, { secondaryContent: root.createComponent(Icon, {source: 'marker'}), id: 'ship-to-pickup-point', }, 'Ship to pickup point', ), root.createComponent( Choice, { secondaryContent: root.createComponent(Icon, {source: 'store'}), id: 'pick-up', }, 'Pick up in store', ), ], ), root.createComponent( ChoiceList, { name: 'base-multiple', value: ['remember-me'], onChange: (value) => { console.log(`onChange event with value: ${value}`); }, }, [ root.createComponent(BlockStack, undefined, [ root.createComponent( Choice, {id: 'remember-me'}, 'Save this information for next time', ), root.createComponent( Choice, {id: 'email-me'}, 'Email me with news and offers', ), root.createComponent( Choice, {id: 'text-me'}, 'Text me with news and offers', ), ]), ], ), ]); root.appendChild(inlineStack); }); ``` ## ChoiceListProps ### ChoiceListProps ### name A unique identifier for the field in the closest `Form` component. ### onChange A callback that is run whenever the choice list is changed. This callback is called with a string or array of strings indicating the ids of choices that should now be selected. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), so you must store this value in state and reflect it back in the `value` prop. ### value A `string` or `string[]` indicating the ids of selected choices. **When a string is set, choices render as radios. When a string array is set, choices render as checkboxes**. ### variant Toggle between `base` and `group` look. Check the [best practices](#best-practices) to learn more about the variants. ## Related - [Choice](choice) - [Checkbox](checkbox) ## Examples Use choice lists to present a list of choices where buyers can make a single selection or multiple selections. ### The base variant’s flexibility allows for the creation of Likert scales using the ChoiceList component. By utilizing layout components, you can easily structure rows and columns for this purpose. ### Custom survey using the base variant ```jsx import { reactExtension, Choice, ChoiceList, Grid, TextBlock, View, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <Grid columns={[ 'fill', '13%', '13%', '13%', '13%', '13%', ]} rows="auto" spacing="none" border="base" cornerRadius="base" overflow="hidden" > <View /> <View padding={['tight', 'extraTight']} blockAlignment="center" accessibilityVisibility="hidden" > <TextBlock inlineAlignment="center"> Strongly disagree </TextBlock> </View> <View padding={['tight', 'extraTight']} blockAlignment="center" accessibilityVisibility="hidden" > <TextBlock inlineAlignment="center"> Disagree </TextBlock> </View> <View padding={['tight', 'extraTight']} blockAlignment="center" accessibilityVisibility="hidden" > <TextBlock inlineAlignment="center"> Neutral </TextBlock> </View> <View padding={['tight', 'extraTight']} blockAlignment="center" accessibilityVisibility="hidden" > <TextBlock inlineAlignment="center"> Agree </TextBlock> </View> <View padding={['tight', 'extraTight']} blockAlignment="center" accessibilityVisibility="hidden" > <TextBlock inlineAlignment="center"> Strongly agree </TextBlock> </View> <ChoiceList name="question1" value="" onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <View background="subdued" padding="base" blockAlignment="center" > <TextBlock> I recommend Plant to others. </TextBlock> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question1-1" accessibilityLabel="Strongly disagree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question1-2" accessibilityLabel="Disagree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question1-3" accessibilityLabel="Neutral" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question1-4" accessibilityLabel="Agree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question1-5" accessibilityLabel="Strongly agree" /> </View> </ChoiceList> <ChoiceList name="question2" value="" onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <View padding="base" blockAlignment="center" > <TextBlock> I have had a positive experience purchasing from Plant. </TextBlock> </View> <View blockAlignment="center" inlineAlignment="center" > <Choice id="question2-1" accessibilityLabel="Strongly disagree" /> </View> <View blockAlignment="center" inlineAlignment="center" > <Choice id="question2-2" accessibilityLabel="Disagree" /> </View> <View blockAlignment="center" inlineAlignment="center" > <Choice id="question2-3" accessibilityLabel="Neutral" /> </View> <View blockAlignment="center" inlineAlignment="center" > <Choice id="question2-4" accessibilityLabel="Agree" /> </View> <View blockAlignment="center" inlineAlignment="center" > <Choice id="question2-5" accessibilityLabel="Strongly agree" /> </View> </ChoiceList> <ChoiceList name="question3" value="" onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <View background="subdued" padding="base" blockAlignment="center" > <TextBlock> I would purchase from Plant again. </TextBlock> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question3-1" accessibilityLabel="Strongly disagree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question3-2" accessibilityLabel="Disagree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question3-3" accessibilityLabel="Neutral" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question3-4" accessibilityLabel="Agree" /> </View> <View background="subdued" blockAlignment="center" inlineAlignment="center" > <Choice id="question3-5" accessibilityLabel="Strongly agree" /> </View> </ChoiceList> </Grid> ); } ``` ```js import { extension, Choice, ChoiceList, Grid, TextBlock, View, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const grid = root.createComponent( Grid, { columns: [ 'fill', '13%', '13%', '13%', '13%', '13%', ], rows: 'auto', spacing: 'none', border: 'base', cornerRadius: 'base', overflow: 'hidden', }, [ root.createComponent(View, {}, []), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Strongly disagree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Disagree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Neutral', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Agree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Strongly agree', ), ), // Then create the ChoiceList for 'question1' root.createComponent( ChoiceList, { name: 'question1', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { background: 'subdued', padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I recommend Plant to others.', ), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-5', accessibilityLabel: 'Strongly agree', }), ), ], ), // Then create the ChoiceList for 'question2' root.createComponent( ChoiceList, { name: 'question2', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I have had a positive experience purchasing from Plant.', ), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-5', accessibilityLabel: 'Strongly agree', }), ), ], ), // Then create the ChoiceList for 'question3' root.createComponent( ChoiceList, { name: 'question3', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { background: 'subdued', padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I would purchase from Plant again.', ), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-5', accessibilityLabel: 'Strongly agree', }), ), ], ), ], ); root.appendChild(grid); }, ); ``` ### The ChoiceList’s group variant, combined with the details property, allows for the conditional display of information when needed. ### Collecting additional information ```jsx import { reactExtension, BlockStack, Choice, ChoiceList, DatePicker, TextBlock, TextField, View, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <ChoiceList variant="group" name="white-glove" value={['white-glove-1']} onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <Choice id="white-glove-1" details={ <> <BlockStack spacing="base"> <BlockStack spacing="extraTight"> <TextBlock> Choose a delivery date </TextBlock> <View background="base" border="base" cornerRadius="base" padding="base" > <DatePicker selected="" /> </View> </BlockStack> <BlockStack spacing="extraTight"> <TextField label="Additional instructions" value="" /> <TextBlock appearance="subdued" size="small" > The more detailed the delivery instructions are, the best we can make the delivery experience for you. </TextBlock> </BlockStack> </BlockStack> </> } > Use white glove delivery service </Choice> </ChoiceList> ); } ``` ```js import { extension, BlockStack, Choice, ChoiceList, DatePicker, TextBlock, TextField, View, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const choiceList = root.createComponent( ChoiceList, { name: 'white-glove', value: ['white-glove-1'], onChange: (nextValue) => { console.log( `onChange event with value: ${nextValue}`, ); }, }, [ root.createComponent( Choice, {id: 'white-glove-1'}, [ root.createComponent( BlockStack, {spacing: 'base'}, [ root.createComponent( BlockStack, {spacing: 'extraTight'}, [ root.createComponent( TextBlock, {}, 'Choose a delivery date', ), root.createComponent( View, { background: 'base', border: 'base', cornerRadius: 'base', padding: 'base', }, root.createComponent( DatePicker, {selected: ''}, ), ), ], ), root.createComponent( BlockStack, {spacing: 'extraTight'}, [ root.createComponent( TextField, { label: 'Additional instructions', value: '', }, ), root.createComponent( TextBlock, { appearance: 'subdued', size: 'small', }, 'The more detailed the delivery instructions are, the best we can make the delivery experience for you.', ), ], ), ], ), ], ), ], ); root.appendChild(choiceList); }, ); ``` ### The ChoiceList component is great for presenting a concise list of options, particularly when showcasing time ranges due to its ample horizontal space. However, if there’s more than 5 choices, use the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component instead. ### Displaying a short list of time choices ```jsx import { reactExtension, BlockStack, ChoiceList, Choice, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <ChoiceList name="time" value="" onChange={(value) => { console.log( `onChange event with value: ${value}`, ); }} > <BlockStack> <Choice id="morning"> 9:00 AM - 12:00 PM </Choice> <Choice id="afternoon"> 12:00 PM - 3:00 PM </Choice> <Choice id="evening"> 3:00 PM - 5:00 PM </Choice> </BlockStack> </ChoiceList> ); } ``` ```js import { extension, BlockStack, ChoiceList, Choice, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const choiceList = root.createComponent( ChoiceList, { name: 'time', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent(BlockStack, {}, [ root.createComponent( Choice, {id: 'morning'}, '9:00 AM - 12:00 PM', ), root.createComponent( Choice, {id: 'afternoon'}, '12:00 PM - 3:00 PM', ), root.createComponent( Choice, {id: 'evening'}, '3:00 PM - 5:00 PM', ), ]), ], ); root.appendChild(choiceList); }, ); ```