diff --git a/polaris-react/src/components/OptionList/OptionList.tsx b/polaris-react/src/components/OptionList/OptionList.tsx index fb7faa51c28..d3247d8bab7 100644 --- a/polaris-react/src/components/OptionList/OptionList.tsx +++ b/polaris-react/src/components/OptionList/OptionList.tsx @@ -11,8 +11,6 @@ import {useDeepEffect} from '../../utilities/use-deep-effect'; import {Box} from '../Box'; import type {BoxProps} from '../Box'; import {Text} from '../Text'; -import {Bleed} from '../Bleed'; -import {useFeatures} from '../../utilities/features'; import {BlockStack} from '../BlockStack'; import {Option} from './components'; @@ -28,8 +26,6 @@ export interface OptionListProps { options?: OptionDescriptor[]; /** Defines a specific role attribute for the list itself */ role?: 'listbox' | 'combobox' | string; - /** Defines a specific role attribute for each option in the list */ - optionRole?: string; /** Sections containing a header and related options */ sections?: SectionDescriptor[]; /** The selected options */ @@ -53,14 +49,12 @@ export function OptionList({ selected, allowMultiple, role, - optionRole, verticalAlign, onChange, id: idProp, onPointerEnterOption, onFocusOption, }: OptionListProps) { - const {polarisSummerEditions2023} = useFeatures(); const [normalizedOptions, setNormalizedOptions] = useState( createNormalizedOptions(options, sections, title), ); @@ -127,34 +121,16 @@ export function OptionList({ const optionsMarkup = optionsExist ? normalizedOptions.map(({title, options}, sectionIndex) => { const isFirstOption = sectionIndex === 0; - const sectionPaddingBlockStart = polarisSummerEditions2023 ? '3' : '4'; - const firstOptionBlockStartPadding = polarisSummerEditions2023 - ? '05' - : '2'; const titleLevel = isFirstOption ? 'h2' : 'h3'; const titleMarkup = title ? ( - + {title} @@ -177,7 +153,6 @@ export function OptionList({ select={isSelected} allowMultiple={allowMultiple} verticalAlign={verticalAlign} - role={optionRole} onPointerEnter={handlePointerEnter} onFocus={handleFocus} /> @@ -185,35 +160,23 @@ export function OptionList({ }); const option = ( - - - {optionsMarkup} - - + {optionsMarkup} + ); // eslint-disable-next-line no-nested-ternary const blockStartPadding = isFirstOption - ? // eslint-disable-next-line no-nested-ternary - polarisSummerEditions2023 - ? title - ? '1' - : '0' - : undefined - : // eslint-disable-next-line no-nested-ternary - polarisSummerEditions2023 ? title - ? '05' + ? '1' : '0' - : '2'; + : title + ? '05' + : '0'; return ( - {polarisSummerEditions2023 ? ( - - {titleMarkup} - {option} - - ) : ( - <> - {titleMarkup} - {option} - > - )} + + {titleMarkup} + {option} + ); }) : null; return ( - + {optionsMarkup} ); diff --git a/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.scss b/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.scss deleted file mode 100644 index 8571f75320c..00000000000 --- a/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.scss +++ /dev/null @@ -1,84 +0,0 @@ -@import '../../../../styles/common'; - -.Checkbox { - position: relative; - width: 100%; - margin: var(--p-space-025); - // stylelint-disable-next-line selector-max-class -- generated by polaris-migrator DO NOT COPY - &.active .Backdrop { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include focus-ring($style: 'focused'); - } -} - -.Input { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include visually-hidden; - - &:focus-visible + .Backdrop { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include focus-ring($style: 'focused'); - } - - &:active:not(:disabled), - &:checked, - &.Input-indeterminate { - // stylelint-disable-next-line selector-max-class, selector-max-specificity -- generated by polaris-migrator DO NOT COPY - + .Backdrop { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include control-backdrop(active); - } - - // stylelint-disable-next-line selector-max-class, selector-max-specificity -- generated by polaris-migrator DO NOT COPY - ~ .Icon { - transform: translate(-50%, -50%) scale(1); - opacity: 1; - transition: opacity var(--p-motion-duration-150) var(--p-motion-ease), - transform var(--p-motion-duration-150) var(--p-motion-ease); - } - } - - &:disabled + .Backdrop { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include control-backdrop(disabled); - } - - &:disabled:checked { - // stylelint-disable-next-line selector-max-specificity -- generated by polaris-migrator DO NOT COPY - + .Backdrop, - + .Backdrop::before { - background: var(--p-color-border-disabled); - } - } -} - -.Backdrop { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include control-backdrop; - position: relative; - display: block; - width: 100%; - height: 100%; - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include focus-ring($border-width: var(--p-border-width-2)); -} - -.Icon { - position: absolute; - top: 50%; - left: 50%; - transform-origin: 50% 50%; - pointer-events: none; - transform: translate(-50%, -50%) scale(0.25); - opacity: 0; - transition: opacity var(--p-motion-duration-100) var(--p-motion-ease), - transform var(--p-motion-duration-100) var(--p-motion-ease); - - @media (-ms-high-contrast: active) { - fill: windowText; - } - - svg { - fill: var(--p-color-icon-on-color); - } -} diff --git a/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.tsx b/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.tsx deleted file mode 100644 index 4ae49230ffc..00000000000 --- a/polaris-react/src/components/OptionList/components/Checkbox/Checkbox.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, {useId} from 'react'; -import {TickSmallMinor} from '@shopify/polaris-icons'; - -import {classNames} from '../../../../utilities/css'; -import {Icon} from '../../../Icon'; - -import styles from './Checkbox.scss'; - -export interface CheckboxProps { - checked?: boolean; - disabled?: boolean; - active?: boolean; - id?: string; - name?: string; - value?: string; - role?: string; - onChange(): void; -} - -export function Checkbox({ - id: idProp, - checked = false, - disabled, - active, - onChange, - name, - value, - role, -}: CheckboxProps) { - const uniqId = useId(); - const id = idProp ?? uniqId; - - const className = classNames(styles.Checkbox, active && styles.active); - - const inputClassName = classNames(styles.Input); - - return ( - - - - - - - - ); -} diff --git a/polaris-react/src/components/OptionList/components/Checkbox/index.ts b/polaris-react/src/components/OptionList/components/Checkbox/index.ts deleted file mode 100644 index f5c939faf48..00000000000 --- a/polaris-react/src/components/OptionList/components/Checkbox/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Checkbox'; diff --git a/polaris-react/src/components/OptionList/components/Checkbox/tests/Checkbox.test.tsx b/polaris-react/src/components/OptionList/components/Checkbox/tests/Checkbox.test.tsx deleted file mode 100644 index 1db1a97c61e..00000000000 --- a/polaris-react/src/components/OptionList/components/Checkbox/tests/Checkbox.test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import {mountWithApp} from 'tests/utilities'; - -import {Checkbox} from '../Checkbox'; -import type {CheckboxProps} from '../Checkbox'; - -describe('', () => { - const defaultProps: CheckboxProps = { - checked: true, - disabled: false, - id: 'checkboxId', - name: 'Checkbox', - value: 'checkbox', - onChange: noop, - }; - - it('sets pass through props for input', () => { - const input = mountWithApp(); - - expect(input).toContainReactComponent('input', defaultProps); - }); - - it('calls onChange', () => { - const spy = jest.fn(); - - const input = mountWithApp( - , - ).find('input'); - - input!.trigger('onChange'); - - expect(spy).toHaveBeenCalledTimes(1); - }); -}); - -function noop() {} diff --git a/polaris-react/src/components/OptionList/components/Option/Option.scss b/polaris-react/src/components/OptionList/components/Option/Option.scss index d42091ce876..3ab8f31f1f1 100644 --- a/polaris-react/src/components/OptionList/components/Option/Option.scss +++ b/polaris-react/src/components/OptionList/components/Option/Option.scss @@ -20,12 +20,8 @@ $control-vertical-adjustment: 2px; color: inherit; } - #{$se23} & { - min-height: 32px; - - &:first-child { - margin-top: 0; - } + &:first-child { + margin-top: 0; } } @@ -33,60 +29,36 @@ $control-vertical-adjustment: 2px; // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY @include unstyled-button; text-align: left; - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include focus-ring; + + display: flex; + flex-wrap: nowrap; + justify-content: space-between; // stylelint-disable-next-line selector-max-specificity -- required for focus-visible support &.focused:focus-visible:not(:active) { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include focus-ring($style: 'focused'); - - #{$se23} & { - // stylelint-disable-next-line -- se23 - @include no-focus-ring; - outline: var(--p-border-width-2) solid - var(--p-color-border-interactive-focus); - outline-offset: var(--p-space-025); - background-color: var(--p-color-bg-subdued-hover); - } + outline: var(--p-border-width-2) solid + var(--p-color-border-interactive-focus); + outline-offset: var(--p-space-025); + background-color: var(--p-color-bg-subdued-hover); } &.active { - background: var(--p-color-bg-interactive-selected); - - #{$se23} & { - background: var(--p-color-bg-subdued-active); - } - } - - &.active::before, - &.select::before { - // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY - @include list-selected-indicator; - - #{$se23} & { - content: none; - } + background: var(--p-color-bg-subdued-active); } &:not(.disabled) { color: inherit; } - .Media { - padding: 0 var(--p-space-2) 0 0; + // stylelint-disable-next-line selector-max-specificity -- specificity buster + &.select, + &.select:hover:not(.disabled), + &.active { + font-weight: var(--p-font-weight-semibold); } - #{$se23} & { - display: flex; - flex-wrap: nowrap; - justify-content: space-between; - - &.select, - &.select:hover:not(.disabled), - &.active { - font-weight: var(--p-font-weight-semibold); - } + .Media { + padding: 0 var(--p-space-2) 0 0; } } @@ -97,52 +69,41 @@ $control-vertical-adjustment: 2px; align-items: flex-start; width: 100%; cursor: pointer; - border-radius: var(--p-border-radius-1); - padding: var(--p-space-2); + border-radius: var(--p-border-radius-2); + padding: var(--p-space-1_5-experimental); // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY @include text-breakword; &:hover:not(.disabled) { - background: var(--p-color-bg-hover); - outline: var(--p-border-width-1) solid transparent; - - #{$se23} & { - background-color: var(--p-color-bg-subdued-hover); - } + background-color: var(--p-color-bg-subdued-hover); } - #{$se23} & { - border-radius: var(--p-border-radius-2); - padding: var(--p-space-1_5-experimental); - - &:active:not(.disabled) { - background-color: var(--p-color-bg-strong-active); - } - - &.select, - &.select:hover:not(.disabled) { - background-color: var(--p-color-bg-subdued-active); - - // stylelint-disable-next-line -- se23 no way to select parent Checkbox class without :has() - &.CheckboxLabel { - background-color: transparent; - } - } + &:active:not(.disabled) { + background: var(--p-color-bg-interactive-selected); + } - // stylelint-disable-next-line -- se23 apply styles to both multi and single select - .Media { - padding: 0 var(--p-space-2) 0 0; + // stylelint-disable-next-line selector-max-specificity -- specificity buster + &.select, + &.select:hover:not(.disabled) { + background-color: var(--p-color-bg-subdued-active); + // stylelint-disable-next-line -- se23 no way to select parent Checkbox class without :has() + &.CheckboxLabel { + background-color: transparent; } } - // stylelint-disable-next-line selector-max-specificity -- generated by polaris-migrator DO NOT COPY + // stylelint-disable-next-line selector-max-specificity -- style consolidation + &:hover:not(.disabled), + &:active:not(.disabled), &.select, - &.select:hover:not(.disabled), - &:active:not(.disabled) { - background: var(--p-color-bg-interactive-selected); + &.select:hover:not(.disabled) { outline: var(--p-border-width-1) solid transparent; } + .Media { + padding: 0 var(--p-space-2) 0 0; + } + &.disabled { background: transparent; cursor: default; @@ -151,28 +112,12 @@ $control-vertical-adjustment: 2px; } .MultiSelectOption { - #{$se23} & { - &:active:not(.disabled), - &.select, - &.select:hover:not(.disabled), - &:hover:not(.disabled) { - background-color: transparent; - } - } -} - -.Checkbox { - box-sizing: border-box; - display: flex; - flex-shrink: 0; - width: 20px; - height: 20px; - margin-right: var(--p-space-2); - margin-left: calc(-1 * var(--p-space-025)); - - #{$se23} & { - align-items: center; - margin-left: 0; + // stylelint-disable-next-line selector-max-specificity -- specificity buster + &:active:not(.disabled), + &.select, + &.select:hover:not(.disabled), + &:hover:not(.disabled) { + background-color: transparent; } } @@ -198,12 +143,19 @@ $control-vertical-adjustment: 2px; } .Icon { - #{$se23} & { - margin-left: var(--p-space-2); + margin-left: var(--p-space-2); - // stylelint-disable-next-line -- se23 - svg { - fill: var(--p-color-icon-primary); - } + svg { + fill: var(--p-color-icon-primary); } } + +.Checkbox { + box-sizing: border-box; + display: flex; + flex-shrink: 0; + width: 20px; + height: 20px; + margin-right: var(--p-space-2); + align-items: center; +} diff --git a/polaris-react/src/components/OptionList/components/Option/Option.tsx b/polaris-react/src/components/OptionList/components/Option/Option.tsx index ae5aa52dd4c..9879a7f36e2 100644 --- a/polaris-react/src/components/OptionList/components/Option/Option.tsx +++ b/polaris-react/src/components/OptionList/components/Option/Option.tsx @@ -7,9 +7,7 @@ import {Icon} from '../../../Icon'; import type {ThumbnailProps} from '../../../Thumbnail'; import type {AvatarProps} from '../../../Avatar'; import {Scrollable} from '../../../Scrollable'; -import {Checkbox} from '../Checkbox'; import {classNames, variationName} from '../../../../utilities/css'; -import {useFeatures} from '../../../../utilities/features'; import type {InlineStackProps} from '../../../InlineStack'; import {InlineStack} from '../../../InlineStack'; import {Checkbox as PolarisCheckbox} from '../../../Checkbox'; @@ -30,7 +28,6 @@ export interface OptionProps { select?: boolean; allowMultiple?: boolean; verticalAlign?: Alignment; - role?: string; onClick(section: number, option: number): void; /** Callback when pointer enters the option */ onPointerEnter(section: number, option: number): void; @@ -46,7 +43,6 @@ export function Option({ active, allowMultiple, disabled, - role, media, onClick, section, @@ -56,7 +52,6 @@ export function Option({ onFocus, }: OptionProps) { const {value: focused, toggle: toggleFocused} = useToggle(false); - const {polarisSummerEditions2023} = useFeatures(); const handleClick = useCallback(() => { if (disabled) { @@ -99,43 +94,25 @@ export function Option({ active && styles.active, select && styles.select, verticalAlign && styles[variationName('verticalAlign', verticalAlign)], - polarisSummerEditions2023 && allowMultiple && styles.CheckboxLabel, - polarisSummerEditions2023 && allowMultiple && styles.MultiSelectOption, + allowMultiple && styles.CheckboxLabel, + allowMultiple && styles.MultiSelectOption, ); - const checkBoxRole = role === 'option' ? 'presentation' : undefined; - const optionMarkup = allowMultiple ? ( - {polarisSummerEditions2023 ? ( - - ) : ( - - )} + {mediaMarkup} - {polarisSummerEditions2023 ? ( - {label} - ) : ( - label - )} + {label} ) : ( - {polarisSummerEditions2023 ? ( - <> - - {mediaMarkup} - {label} - - {(select || active) && ( - - - - )} - > - ) : ( - <> + <> + {mediaMarkup} {label} - > - )} + + {(select || active) && ( + + + + )} + > ); diff --git a/polaris-react/src/components/OptionList/components/Option/tests/Option.test.tsx b/polaris-react/src/components/OptionList/components/Option/tests/Option.test.tsx index 66b3500502a..3b6f8b30f41 100644 --- a/polaris-react/src/components/OptionList/components/Option/tests/Option.test.tsx +++ b/polaris-react/src/components/OptionList/components/Option/tests/Option.test.tsx @@ -1,8 +1,7 @@ import React from 'react'; import {mountWithApp} from 'tests/utilities'; -import {Checkbox} from '../../Checkbox'; -import {Checkbox as PolarisCheckbox} from '../../../../Checkbox'; +import {Checkbox} from '../../../../Checkbox'; import {Scrollable} from '../../../../Scrollable'; import {Option} from '../Option'; import type {OptionProps} from '../Option'; @@ -20,10 +19,8 @@ describe('', () => { }; it('renders a checkbox if allowMultiple is true', () => { - const checkbox = mountWithApp(, { - features: {polarisSummerEditions2023: true}, - }); - expect(checkbox).toContainReactComponent(PolarisCheckbox); + const checkbox = mountWithApp(); + expect(checkbox).toContainReactComponent(Checkbox); }); it('renders a button if allowMultiple is false or undefined', () => { @@ -123,9 +120,10 @@ describe('', () => { it('sets the pass through props for Checkbox if multiple items are allowed', () => { const {id, value, select, disabled} = defaultProps; - const checkbox = mountWithApp(, { - features: {polarisSummerEditions2023: true}, - }).find(PolarisCheckbox)!; + const checkbox = mountWithApp( + , + {}, + ).find(Checkbox)!; expect(checkbox.prop('id')).toBe(id); expect(checkbox.prop('value')).toBe(value); @@ -202,49 +200,6 @@ describe('', () => { }); }); }); - - // se23 - Custom checbox replaced with PolarisCheckbox - // 'onChange' event replaced with 'onClick' - describe('polarisSummerEditions2023 false', () => { - it('renders a checkbox if allowMultiple is true', () => { - const checkbox = mountWithApp( - , - { - features: {polarisSummerEditions2023: false}, - }, - ); - expect(checkbox).toContainReactComponent(Checkbox); - }); - - it('calls onClick with section and index if option is not disabled and multiple options are allowed', () => { - const spy = jest.fn(); - const {section, index} = defaultProps; - - const input = mountWithApp( - , - {features: {polarisSummerEditions2023: false}}, - ).find('input')!; - input.trigger('onChange'); - - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith(section, index); - }); - - it('sets the pass through props for Checkbox if multiple items are allowed', () => { - const {id, value, select, disabled} = defaultProps; - const checkbox = mountWithApp( - , - { - features: {polarisSummerEditions2023: false}, - }, - ).find(Checkbox)!; - - expect(checkbox.prop('id')).toBe(id); - expect(checkbox.prop('value')).toBe(value); - expect(checkbox.prop('checked')).toBe(select); - expect(checkbox.prop('disabled')).toBe(disabled); - }); - }); }); function noop() {} diff --git a/polaris-react/src/components/OptionList/components/index.ts b/polaris-react/src/components/OptionList/components/index.ts index d06d2c4a99d..e149829a484 100644 --- a/polaris-react/src/components/OptionList/components/index.ts +++ b/polaris-react/src/components/OptionList/components/index.ts @@ -1,3 +1 @@ export * from './Option'; - -export * from './Checkbox'; diff --git a/polaris-react/src/components/OptionList/tests/OptionList.test.tsx b/polaris-react/src/components/OptionList/tests/OptionList.test.tsx index 1ac6b7f2989..091d7556e17 100644 --- a/polaris-react/src/components/OptionList/tests/OptionList.test.tsx +++ b/polaris-react/src/components/OptionList/tests/OptionList.test.tsx @@ -483,7 +483,6 @@ describe('', () => { const inputWrapper = mountWithApp( , - {features: {polarisSummerEditions2023: true}}, ).find('input'); inputWrapper!.trigger('onClick'); @@ -504,7 +503,6 @@ describe('', () => { selected={selected} allowMultiple />, - {features: {polarisSummerEditions2023: true}}, ).find('input'); inputWrapper!.trigger('onClick'); @@ -528,7 +526,6 @@ describe('', () => { selected={selected} allowMultiple />, - {features: {polarisSummerEditions2023: true}}, ).find('input'); inputWrapper!.trigger('onClick'); @@ -584,72 +581,6 @@ describe('', () => { }); }); }); - - // se23 - 'onChange' event replaced with 'onClick' - describe('polarisSummerEditions2023 false', () => { - it('selects an item when nothing was selected', () => { - const spy = jest.fn(); - const {options, sections} = defaultProps; - - const inputWrapper = mountWithApp( - , - {features: {polarisSummerEditions2023: false}}, - ).find('input'); - - inputWrapper!.trigger('onChange'); - - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith([firstOption(options, sections)]); - }); - - it('selects an item when multiple items are selected', () => { - const spy = jest.fn(); - const {options, sections} = defaultProps; - const selected = ['11', '8']; - - const inputWrapper = mountWithApp( - , - {features: {polarisSummerEditions2023: false}}, - ).find('input'); - - inputWrapper!.trigger('onChange'); - - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith([ - firstOption(options, sections), - ...selected, - ]); - }); - - it('deselects an item when it is already selected', () => { - const spy = jest.fn(); - const {options, sections} = defaultProps; - const selected = ['10', '8', '5']; - - const inputWrapper = mountWithApp( - , - {features: {polarisSummerEditions2023: false}}, - ).find('input'); - - inputWrapper!.trigger('onChange'); - - const valueToCheck = firstOption(options, sections); - const newSelected = selected.filter((value) => value !== valueToCheck); - - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith(newSelected); - }); - }); }); function noop() {} diff --git a/polaris.shopify.com/content/components/lists/option-list.md b/polaris.shopify.com/content/components/lists/option-list.md index dcd83ea430f..56cfe7342cd 100644 --- a/polaris.shopify.com/content/components/lists/option-list.md +++ b/polaris.shopify.com/content/components/lists/option-list.md @@ -76,4 +76,3 @@ Controls in simple option lists are [buttons](https://polaris.shopify.com/compon If you customize the option list, you can provide ARIA roles that fit the context. These roles must be valid according to the [W3C ARIA specification](https://www.w3.org/TR/wai-aria-1.1/) to be conveyed correctly to screen reader users. - The `role` prop adds an ARIA role to the option list wrapper -- The `optionRole` prop adds an ARIA role to the option list items