diff --git a/.changeset/friendly-walls-pull.md b/.changeset/friendly-walls-pull.md new file mode 100644 index 0000000000..c057cf8584 --- /dev/null +++ b/.changeset/friendly-walls-pull.md @@ -0,0 +1,5 @@ +--- +'@shopify/ui-extensions': minor +--- + +Add ButtonGroup component to customer account diff --git a/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-preview.png b/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-preview.png new file mode 100644 index 0000000000..99b2bbdf1f Binary files /dev/null and b/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-preview.png differ diff --git a/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-thumbnail.png b/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-thumbnail.png new file mode 100644 index 0000000000..2674f2a448 Binary files /dev/null and b/packages/ui-extensions/docs/surfaces/customer-account/screenshots/buttongroup-thumbnail.png differ diff --git a/packages/ui-extensions/src/surfaces/customer-account/components.d.ts b/packages/ui-extensions/src/surfaces/customer-account/components.d.ts index cfc32a657a..b6e0713436 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components.d.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components.d.ts @@ -5,6 +5,11 @@ import { AvatarElement, AvatarEvents, } from './components/Avatar'; +import { + ButtonGroupProps, + ButtonGroupElement, + ButtonGroupElementSlots, +} from './components/ButtonGroup'; import { CustomerAccountActionProps, CustomerAccountActionElement, @@ -123,3 +128,26 @@ declare module 'preact' { } } } + +export type ButtonGroupPropsDocs = ButtonGroupProps; +export type ButtonGroupElementDocs = ButtonGroupElement; +export type ButtonGroupElementSlotsDocs = ButtonGroupElementSlots; + +declare global { + interface HTMLElementTagNameMap { + ['s-button-group']: ButtonGroupElement; + } +} + +declare module 'preact' { + interface BaseProps { + children?: preact.ComponentChildren; + slot?: Lowercase; + } + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace createElement.JSX { + interface IntrinsicElements { + ['s-button-group']: BaseProps & ButtonGroupProps; + } + } +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup.d.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup.d.ts new file mode 100644 index 0000000000..3fe356a3da --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup.d.ts @@ -0,0 +1,39 @@ +import {BaseElementPropsWithChildren, IdProps} from './shared'; + +export interface ButtonGroupProps extends IdProps { + /** + * Label for the button group that describes the content of the group for screen reader users to understand what's included. + */ + accessibilityLabel?: string; +} + +export interface ButtonGroupElementSlots { + /** + * The primary action to perform, provided as a button type element. + */ + 'primary-action'?: HTMLElement; + /** + * The secondary actions to perform, provided as button type elements. + */ + 'secondary-actions'?: HTMLElement; +} + +export interface ButtonGroupElement + extends ButtonGroupProps, + Omit {} + +declare global { + interface HTMLElementTagNameMap { + ['s-button-group']: ButtonGroupElement; + } +} + +declare module 'preact' { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace createElement.JSX { + interface IntrinsicElements { + ['s-button-group']: BaseElementPropsWithChildren & + ButtonGroupProps; + } + } +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/ButtonGroup.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/ButtonGroup.doc.ts new file mode 100644 index 0000000000..0a1007aed4 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/ButtonGroup.doc.ts @@ -0,0 +1,42 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ButtonGroup', + description: + 'ButtonGroup is used to display multiple buttons in a layout that is contextual based on the screen width or parent component. When there is more than one secondary action, they get collapsed.', + thumbnail: 'buttongroup-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'Properties', + description: '', + type: 'ButtonGroupPropsDocs', + }, + { + title: 'Slots', + description: '', + type: 'ButtonGroupElementSlotsDocs', + }, + ], + category: 'Polaris web components', + defaultExample: { + image: 'buttongroup-preview.png', + altText: + 'An example of the ButtonGroup component shows a primary action and multiple collapsed secondary actions.', + codeblock: { + title: 'Basic ButtonGroup', + tabs: [ + { + title: 'Preact', + code: './examples/basic-ButtonGroup-preact.example.tsx', + language: 'tsx', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/examples/basic-ButtonGroup-preact.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/examples/basic-ButtonGroup-preact.example.tsx new file mode 100644 index 0000000000..84eeb4645b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ButtonGroup/examples/basic-ButtonGroup-preact.example.tsx @@ -0,0 +1,21 @@ +import {render} from 'preact'; + +export default function extension() { + render(, document.body); +} + +function App() { + return ( + + + Pay now + + + Edit order + + + Cancel order + + + ); +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/StandardComponents.ts b/packages/ui-extensions/src/surfaces/customer-account/components/StandardComponents.ts index 9f223a381f..87e4741aae 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/StandardComponents.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/StandardComponents.ts @@ -3,6 +3,7 @@ import {AnyComponent} from '../../checkout'; export type StandardComponents = | AnyComponent | 'Avatar' + | 'ButtonGroup' | 'CustomerAccountAction' | 'ImageGroup' | 'Menu'