diff --git a/.changeset/pos-list-component.md b/.changeset/pos-list-component.md new file mode 100644 index 0000000000..bfdb88388b --- /dev/null +++ b/.changeset/pos-list-component.md @@ -0,0 +1,5 @@ +--- +'@shopify/ui-extensions': minor +--- + +Add the `s-pos-list` web component for structured, incrementally loaded POS lists. diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/generated_docs_data_v2.json b/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/generated_docs_data_v2.json index a8efafa3a2..ddc60b2eb2 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/generated_docs_data_v2.json +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/generated_docs_data_v2.json @@ -4572,86 +4572,760 @@ "value": "interface TabListJSXProps extends Pick {\n children?: ComponentChildren;\n}" } }, - "LinkEvents": { + "POSListJSXProps": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "POSListJSXProps", + "description": "Displays structured rows with text, badges, images, and optional trailing content.", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "header", + "value": "ComponentChild", + "description": "Content displayed before the rows as part of the list's scrollable content.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the element.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "imageDisplayStrategy", + "value": "POSListImageDisplayStrategy", + "description": "Controls whether rows reserve space for images.\n\n- `auto`: Displays images or placeholders when a row includes an image source.\n- `always`: Displays images or placeholders for every row.\n- `never`: Displays rows without images or image placeholders.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "loadingMore", + "value": "boolean", + "description": "Whether additional rows are being loaded.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "onLoadMore", + "value": "((event: CallbackEvent) => void) | null", + "description": "Callback when more rows should be loaded.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "rows", + "value": "POSListRow[]", + "description": "The rows displayed in the list.", + "isOptional": true, + "defaultValue": "[]" + } + ], + "value": "interface POSListJSXProps {\n /** A unique identifier for the element. */\n id?: string;\n /**\n * The rows displayed in the list.\n *\n * @default []\n */\n rows?: POSListRow[];\n /**\n * Controls whether rows reserve space for images.\n *\n * - `auto`: Displays images or placeholders when a row includes an image source.\n * - `always`: Displays images or placeholders for every row.\n * - `never`: Displays rows without images or image placeholders.\n *\n * @default 'auto'\n */\n imageDisplayStrategy?: POSListImageDisplayStrategy;\n /**\n * Whether additional rows are being loaded.\n *\n * @default false\n */\n loadingMore?: boolean;\n /** Callback when more rows should be loaded. */\n onLoadMore?: ((event: CallbackEvent) => void) | null;\n /** Content displayed before the rows as part of the list's scrollable content. */\n header?: ComponentChild;\n}" + } + }, + "ComponentChild": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ComponentChild", + "value": "VNode | object | string | number | bigint | boolean | null | undefined", + "description": "" + } + }, + "VNode": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "VNode", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "endTime", + "value": "number", + "description": "The time that the rendering of this `vnode` was completed. Will only be set when the devtools are attached. Default value: `-1`", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "key", + "value": "Key", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "props", + "value": "P & { children: ComponentChildren$1; }", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "ref", + "value": "Ref | null", + "description": "ref is not guaranteed by React.ReactElement, for compatibility reasons with popular react libs we define it as optional too", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "startTime", + "value": "number", + "description": "The time this `vnode` started rendering. Will only be set when the devtools are attached. Default value: `0`", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "ComponentType

| string", + "description": "" + } + ], + "value": "export interface VNode

{\n type: ComponentType

| string;\n props: P & {\n children: ComponentChildren$1;\n };\n key: Key;\n /**\n * ref is not guaranteed by React.ReactElement, for compatibility reasons\n * with popular react libs we define it as optional too\n */\n ref?: Ref | null;\n /**\n * The time this `vnode` started rendering. Will only be set when\n * the devtools are attached.\n * Default value: `0`\n */\n startTime?: number;\n /**\n * The time that the rendering of this `vnode` was completed. Will only be\n * set when the devtools are attached.\n * Default value: `-1`\n */\n endTime?: number;\n}" + } + }, + "Key": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Key", + "value": "string | number | any", + "description": "" + } + }, + "Ref": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Ref", + "value": "RefObject | RefCallback | null", + "description": "" + } + }, + "RefObject": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "RefObject", + "value": "{\n current: T | null;\n}", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "current", + "value": "T | null", + "description": "" + } + ] + } + }, + "RefCallback": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "RefCallback", + "description": "", + "params": [ + { + "name": "instance", + "description": "", + "value": "T", + "filePath": "src/surfaces/point-of-sale/components.ts" + } + ], + "returns": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "description": "", + "name": "void | (() => void)", + "value": "void | (() => void)" + }, + "value": "(instance: T | null) => void | (() => void)" + } + }, + "ComponentType": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ComponentType", + "value": "ComponentClass

| FunctionComponent

", + "description": "" + } + }, + "ComponentClass": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "ComponentClass", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "contextType", + "value": "Context", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "defaultProps", + "value": "Partial

", + "description": "Make all properties in T optional", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "displayName", + "value": "string", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "MethodSignature", + "name": "getDerivedStateFromError", + "value": "(error: any) => Partial", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "MethodSignature", + "name": "getDerivedStateFromProps", + "value": "(props: Readonly

, state: Readonly) => Partial", + "description": "", + "isOptional": true + } + ], + "value": "export interface ComponentClass

{\n new (props: P, context?: any): Component;\n displayName?: string;\n defaultProps?: Partial

;\n contextType?: Context;\n getDerivedStateFromProps?(\n props: Readonly

,\n state: Readonly,\n ): Partial | null;\n getDerivedStateFromError?(error: any): Partial | null;\n}" + } + }, + "Context": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "Context", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "Consumer", + "value": "Consumer", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "defaultProps", + "value": "Partial

| undefined", + "description": "Make all properties in T optional", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "displayName", + "value": "string", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "Provider", + "value": "Provider", + "description": "" + } + ], + "value": "export interface Context extends Provider {\n Consumer: Consumer;\n Provider: Provider;\n displayName?: string;\n}" + } + }, + "Consumer": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "Consumer", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "defaultProps", + "value": "Partial

| undefined", + "description": "Make all properties in T optional", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "displayName", + "value": "string", + "description": "", + "isOptional": true + } + ], + "value": "export interface Consumer\n extends FunctionComponent<{\n children: (value: T) => ComponentChildren$1;\n }> {}" + } + }, + "Provider": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "Provider", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "defaultProps", + "value": "Partial

| undefined", + "description": "Make all properties in T optional", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "displayName", + "value": "string", + "description": "", + "isOptional": true + } + ], + "value": "export interface Provider\n extends FunctionComponent<{\n value: T;\n children?: ComponentChildren$1;\n }> {}" + } + }, + "FunctionComponent": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "FunctionComponent", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "defaultProps", + "value": "Partial

| undefined", + "description": "Make all properties in T optional", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "displayName", + "value": "string", + "description": "", + "isOptional": true + } + ], + "value": "export interface FunctionComponent

{\n (props: RenderableProps

, context?: any): ComponentChildren$1;\n displayName?: string;\n defaultProps?: Partial

| undefined;\n}" + } + }, + "POSListImageDisplayStrategy": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListImageDisplayStrategy", + "value": "'auto' | 'always' | 'never'", + "description": "" + } + }, + "CallbackEvent": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "CallbackEvent", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "bubbles", + "value": "boolean", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "cancelable", + "value": "boolean", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "composed", + "value": "boolean", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "currentTarget", + "value": "HTMLElementTagNameMap[T]", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "detail", + "value": "any", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "eventPhase", + "value": "number", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "target", + "value": "HTMLElementTagNameMap[T] | null", + "description": "" + } + ], + "value": "interface CallbackEvent {\n currentTarget: HTMLElementTagNameMap[T];\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n detail?: any;\n eventPhase: number;\n target: HTMLElementTagNameMap[T] | null;\n}" + } + }, + "POSListRow": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRow", + "value": "{\n /** A unique identifier for the row. */\n id: string;\n /** The primary content displayed at the start of the row. */\n start: POSListRowStart;\n /**\n * Callback invoked when the row is activated.\n *\n * When provided, the row is interactive.\n */\n onClick?: (event: CallbackEvent) => void;\n /** Optional content displayed at the end of the row. */\n end?: POSListRowEnd;\n}", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "end", + "value": "POSListRowEnd", + "description": "Optional content displayed at the end of the row.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the row." + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "onClick", + "value": "(event: CallbackEvent<\"s-pos-list\">) => void", + "description": "Callback invoked when the row is activated.\n\nWhen provided, the row is interactive.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "start", + "value": "POSListRowStart", + "description": "The primary content displayed at the start of the row." + } + ] + } + }, + "POSListRowEnd": { "src/surfaces/point-of-sale/components.ts": { "filePath": "src/surfaces/point-of-sale/components.ts", - "name": "LinkEvents", - "description": "The link component provides event callbacks for handling user interactions. Learn more about [handling events](/docs/api/polaris/using-polaris-web-components#handling-events).", - "isPublicDocs": true, + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRowEnd", + "value": "{\n /** Supporting text displayed at the end of the row. */\n label?: string;\n /**\n * Whether to display a chevron at the end of the row.\n *\n * @default false\n */\n showChevron?: boolean;\n /** A toggle switch displayed at the end of the row. */\n toggleSwitch?: POSListToggleSwitch;\n}", + "description": "", "members": [ { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "click", - "value": "(event: CallbackEvent<\"s-link\">) => void", - "description": "Called when the link is activated.", + "name": "label", + "value": "string", + "description": "Supporting text displayed at the end of the row.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "showChevron", + "value": "boolean", + "description": "Whether to display a chevron at the end of the row.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "toggleSwitch", + "value": "POSListToggleSwitch", + "description": "A toggle switch displayed at the end of the row.", "isOptional": true } - ], - "value": "interface LinkEvents {\n /** Called when the link is activated. */\n click?: (event: CallbackEvent) => void;\n}" + ] } }, - "CallbackEvent": { + "POSListToggleSwitch": { "src/surfaces/point-of-sale/components.ts": { "filePath": "src/surfaces/point-of-sale/components.ts", - "name": "CallbackEvent", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListToggleSwitch", + "value": "{\n /**\n * The current state of the toggle switch.\n *\n * @default false\n */\n checked?: boolean;\n /**\n * Whether the toggle switch prevents interaction.\n *\n * @default false\n */\n disabled?: boolean;\n}", "description": "", "members": [ { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "bubbles", + "name": "checked", "value": "boolean", - "description": "", - "isOptional": true + "description": "The current state of the toggle switch.", + "isOptional": true, + "defaultValue": "false" }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "cancelable", + "name": "disabled", "value": "boolean", - "description": "", + "description": "Whether the toggle switch prevents interaction.", + "isOptional": true, + "defaultValue": "false" + } + ] + } + }, + "POSListRowStart": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRowStart", + "value": "{\n /** The primary text for the row. */\n label: string;\n /** Up to three lines of supporting text displayed below the label. */\n subtitles?: [POSListRowSubtitle, POSListRowSubtitle?, POSListRowSubtitle?];\n /** Status or category badges displayed with the row content. */\n badges?: POSListBadge[];\n /** The image displayed at the start of the row. */\n image?: POSListRowImage;\n}", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "badges", + "value": "POSListBadge[]", + "description": "Status or category badges displayed with the row content.", "isOptional": true }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "composed", - "value": "boolean", - "description": "", + "name": "image", + "value": "POSListRowImage", + "description": "The image displayed at the start of the row.", "isOptional": true }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "currentTarget", - "value": "HTMLElementTagNameMap[T]", - "description": "" + "name": "label", + "value": "string", + "description": "The primary text for the row." }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "detail", - "value": "any", - "description": "", + "name": "subtitles", + "value": "[POSListRowSubtitle, POSListRowSubtitle?, POSListRowSubtitle?]", + "description": "Up to three lines of supporting text displayed below the label.", "isOptional": true + } + ] + } + }, + "POSListBadge": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListBadge", + "value": "{\n /** The badge text. */\n text: string;\n /**\n * The semantic appearance of the badge.\n *\n * @default 'neutral'\n */\n tone?: 'neutral' | 'critical' | 'warning' | 'success' | 'highlight';\n}", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "text", + "value": "string", + "description": "The badge text." }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "eventPhase", + "name": "tone", + "value": "'neutral' | 'critical' | 'warning' | 'success' | 'highlight'", + "description": "The semantic appearance of the badge.", + "isOptional": true, + "defaultValue": "'neutral'" + } + ] + } + }, + "POSListRowImage": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRowImage", + "value": "{\n /** The URL of the image displayed at the start of the row. */\n src?: string;\n /** A numeric badge displayed over the image. */\n badge?: number;\n}", + "description": "", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "badge", "value": "number", - "description": "" + "description": "A numeric badge displayed over the image.", + "isOptional": true }, { "filePath": "src/surfaces/point-of-sale/components.ts", "syntaxKind": "PropertySignature", - "name": "target", - "value": "HTMLElementTagNameMap[T] | null", - "description": "" + "name": "src", + "value": "string", + "description": "The URL of the image displayed at the start of the row.", + "isOptional": true + } + ] + } + }, + "POSListRowSubtitle": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRowSubtitle", + "value": "string | {\n /** The subtitle text. */\n content: string;\n /**\n * The semantic color applied to the subtitle.\n *\n * @default 'neutral'\n */\n color?: POSListRowSubtitleColor;\n }", + "description": "" + } + }, + "POSListRowSubtitleColor": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "POSListRowSubtitleColor", + "value": "'neutral' | 'subdued' | 'disabled' | 'warning' | 'critical' | 'success' | 'interactive' | 'highlight'", + "description": "" + } + }, + "POSListEvents": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "POSListEvents", + "description": "Events emitted by the POS list.", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "loadmore", + "value": "(event: CallbackEvent<\"s-pos-list\">) => void", + "description": "Fired when more rows should be loaded.", + "isOptional": true } ], - "value": "interface CallbackEvent {\n currentTarget: HTMLElementTagNameMap[T];\n bubbles?: boolean;\n cancelable?: boolean;\n composed?: boolean;\n detail?: any;\n eventPhase: number;\n target: HTMLElementTagNameMap[T] | null;\n}" + "value": "interface POSListEvents {\n /** Fired when more rows should be loaded. */\n loadmore?: (event: CallbackEvent) => void;\n}" + } + }, + "POSListSlots": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "POSListSlots", + "description": "Content slots for the POS list.", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "header", + "value": "HTMLElement", + "description": "Content displayed before the rows as part of the list's scrollable content.", + "isOptional": true + } + ], + "value": "interface POSListSlots {\n /** Content displayed before the rows as part of the list's scrollable content. */\n header?: HTMLElement;\n}" + } + }, + "POSList": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "POSList", + "description": "Displays structured rows with text, badges, images, and optional trailing content.", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the element.", + "isOptional": true + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "imageDisplayStrategy", + "value": "POSListImageDisplayStrategy", + "description": "Controls whether rows reserve space for images.\n\n- `auto`: Displays images or placeholders when a row includes an image source.\n- `always`: Displays images or placeholders for every row.\n- `never`: Displays rows without images or image placeholders.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "loadingMore", + "value": "boolean", + "description": "Whether additional rows are being loaded.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "rows", + "value": "POSListRow[]", + "description": "The rows displayed in the list.", + "isOptional": true, + "defaultValue": "[]" + } + ], + "value": "interface POSList {\n /** A unique identifier for the element. */\n id?: string;\n /**\n * The rows displayed in the list.\n * @default []\n */\n rows?: POSListRow[];\n /**\n * Controls whether rows reserve space for images.\n *\n * - `auto`: Displays images or placeholders when a row includes an image source.\n * - `always`: Displays images or placeholders for every row.\n * - `never`: Displays rows without images or image placeholders.\n * @default 'auto'\n */\n imageDisplayStrategy?: POSListImageDisplayStrategy;\n /**\n * Whether additional rows are being loaded.\n * @default false\n */\n loadingMore?: boolean;\n}" + } + }, + "LinkEvents": { + "src/surfaces/point-of-sale/components.ts": { + "filePath": "src/surfaces/point-of-sale/components.ts", + "name": "LinkEvents", + "description": "The link component provides event callbacks for handling user interactions. Learn more about [handling events](/docs/api/polaris/using-polaris-web-components#handling-events).", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/point-of-sale/components.ts", + "syntaxKind": "PropertySignature", + "name": "click", + "value": "(event: CallbackEvent<\"s-link\">) => void", + "description": "Called when the link is activated.", + "isOptional": true + } + ], + "value": "interface LinkEvents {\n /** Called when the link is activated. */\n click?: (event: CallbackEvent) => void;\n}" } }, "Link": { @@ -7738,7 +8412,7 @@ "filePath": "src/surfaces/point-of-sale/components/targets/StandardComponents.ts", "syntaxKind": "TypeAliasDeclaration", "name": "StandardComponents", - "value": "'Badge' | 'Banner' | 'Box' | 'Button' | 'Choice' | 'ChoiceList' | 'Clickable' | 'DateField' | 'DatePicker' | 'DateSpinner' | 'Divider' | 'EmailField' | 'Embed' | 'EmptyState' | 'Heading' | 'Icon' | 'Image' | 'Link' | 'Modal' | 'NumberField' | 'Page' | 'POSBlock' | 'PosBlock' | 'Route' | 'Router' | 'ScrollBox' | 'SearchField' | 'Section' | 'Spinner' | 'Stack' | 'Switch' | 'Tab' | 'TabList' | 'TabPanel' | 'Tabs' | 'Text' | 'TextArea' | 'TextField' | 'Tile' | 'TimeField' | 'TimePicker'", + "value": "'Badge' | 'Banner' | 'Box' | 'Button' | 'Choice' | 'ChoiceList' | 'Clickable' | 'DateField' | 'DatePicker' | 'DateSpinner' | 'Divider' | 'EmailField' | 'Embed' | 'EmptyState' | 'Heading' | 'Icon' | 'Image' | 'Link' | 'Modal' | 'NumberField' | 'Page' | 'POSBlock' | 'PosBlock' | 'POSList' | 'Route' | 'Router' | 'ScrollBox' | 'SearchField' | 'Section' | 'Spinner' | 'Stack' | 'Switch' | 'Tab' | 'TabList' | 'TabPanel' | 'Tabs' | 'Text' | 'TextArea' | 'TextField' | 'Tile' | 'TimeField' | 'TimePicker'", "description": "", "isPublicDocs": true } @@ -7748,7 +8422,7 @@ "filePath": "src/surfaces/point-of-sale/components/targets/BasicComponents.ts", "syntaxKind": "TypeAliasDeclaration", "name": "BasicComponents", - "value": "'Badge' | 'Banner' | 'Box' | 'Button' | 'Choice' | 'ChoiceList' | 'Clickable' | 'DateField' | 'DatePicker' | 'DateSpinner' | 'Divider' | 'EmailField' | 'Embed' | 'EmptyState' | 'Heading' | 'Icon' | 'Image' | 'Link' | 'Modal' | 'NumberField' | 'Page' | 'POSBlock' | 'PosBlock' | 'Route' | 'Router' | 'ScrollBox' | 'SearchField' | 'Section' | 'Spinner' | 'Stack' | 'Switch' | 'Tab' | 'TabList' | 'TabPanel' | 'Tabs' | 'Text' | 'TextArea' | 'TextField' | 'TimeField' | 'TimePicker'", + "value": "'Badge' | 'Banner' | 'Box' | 'Button' | 'Choice' | 'ChoiceList' | 'Clickable' | 'DateField' | 'DatePicker' | 'DateSpinner' | 'Divider' | 'EmailField' | 'Embed' | 'EmptyState' | 'Heading' | 'Icon' | 'Image' | 'Link' | 'Modal' | 'NumberField' | 'Page' | 'POSBlock' | 'PosBlock' | 'POSList' | 'Route' | 'Router' | 'ScrollBox' | 'SearchField' | 'Section' | 'Spinner' | 'Stack' | 'Switch' | 'Tab' | 'TabList' | 'TabPanel' | 'Tabs' | 'Text' | 'TextArea' | 'TextField' | 'TimeField' | 'TimePicker'", "description": "", "isPublicDocs": true } @@ -9317,7 +9991,7 @@ "syntaxKind": "PropertySignature", "name": "paymentvalidations", "value": "PaymentValidationsEvent", - "description": "Dispatched when staff selects a payment method on the payments screen." + "description": "Dispatched when a tender is confirmed but not yet committed — after the amount is entered, before the payment is recorded. One event per tender attempt; split payments dispatch one event per tender, each carrying its own amount." } ], "value": "export interface ShopifyInterceptMap {\n [POS_INTERCEPT_NAMES.CART_VALIDATIONS]: CartValidationsEvent;\n [POS_INTERCEPT_NAMES.PAYMENT_VALIDATIONS]: PaymentValidationsEvent;\n}" @@ -9502,7 +10176,7 @@ "src/surfaces/point-of-sale/events.ts": { "filePath": "src/surfaces/point-of-sale/events.ts", "name": "PaymentValidationsEvent", - "description": "Dispatched when staff selects a payment method on the payments screen.", + "description": "Dispatched when a tender is confirmed but not yet committed — after the amount is entered, before the payment is recorded. One event per tender attempt; split payments dispatch one event per tender, each carrying its own amount.", "members": [ { "filePath": "src/surfaces/point-of-sale/events.ts", @@ -9730,10 +10404,10 @@ "returns": { "filePath": "src/surfaces/point-of-sale/events.ts", "description": "", - "name": "InterceptResult", - "value": "InterceptResult" + "name": "InterceptResult>", + "value": "InterceptResult>" }, - "value": "(\n event: TEvent,\n) => InterceptResult" + "value": "(\n event: TEvent,\n) => InterceptResult>" } }, "InterceptResult": { @@ -9746,11 +10420,11 @@ "filePath": "src/surfaces/point-of-sale/events.ts", "syntaxKind": "PropertySignature", "name": "operations", - "value": "Operation[]", + "value": "Operation[]", "description": "" } ], - "value": "export interface InterceptResult {\n operations: Operation[];\n}" + "value": "export interface InterceptResult<\n TTarget extends ValidationTarget = ValidationTarget,\n> {\n operations: Operation[];\n}" } }, "Operation": { @@ -9763,12 +10437,12 @@ "filePath": "src/surfaces/point-of-sale/events.ts", "syntaxKind": "PropertySignature", "name": "validationAdd", - "value": "ValidationAdd", - "description": "Adds a validation to the workflow being intercepted.", + "value": "ValidationAdd", + "description": "", "isOptional": true } ], - "value": "export interface Operation {\n validationAdd?: ValidationAdd;\n}" + "value": "export interface Operation<\n TTarget extends ValidationTarget = ValidationTarget,\n> {\n validationAdd?: ValidationAdd;\n}" } }, "ValidationAdd": { @@ -9782,7 +10456,7 @@ "syntaxKind": "PropertySignature", "name": "handle", "value": "string", - "description": "Stable identifier for this validation." + "description": "Stable identifier for this validation. Handles are namespaced per extension and may repeat across targets: the same handle on two line items is two validations." }, { "filePath": "src/surfaces/point-of-sale/events.ts", @@ -9795,12 +10469,12 @@ "filePath": "src/surfaces/point-of-sale/events.ts", "syntaxKind": "PropertySignature", "name": "target", - "value": "string", - "description": "JSON-path locator for where the validation applies.", + "value": "TTarget", + "description": "Locates the data the validation applies to; the host decides where it renders. Omitted or unrecognized targets fall back to the event's root scope (`$.cart` / `$.payment`) — the validation still applies, rendered less specifically.\n\nLine item uuids are only valid within the event that delivered them: use `lineItems[n].uuid` from this event's cart snapshot, don't cache uuids across events. Bundle components are not addressable; target their parent line.", "isOptional": true } ], - "value": "export interface ValidationAdd {\n /** `ERROR` blocks the workflow. `WARNING` does not. */\n level: ValidationLevel;\n\n /** Stable identifier for this validation. */\n handle: string;\n\n /** JSON-path locator for where the validation applies. */\n target?: string;\n}" + "value": "export interface ValidationAdd<\n TTarget extends ValidationTarget = ValidationTarget,\n> {\n /** `ERROR` blocks the workflow. `WARNING` does not. */\n level: ValidationLevel;\n\n /**\n * Stable identifier for this validation. Handles are namespaced per\n * extension and may repeat across targets: the same handle on two line\n * items is two validations.\n */\n handle: string;\n\n /**\n * Locates the data the validation applies to; the host decides where it\n * renders. Omitted or unrecognized targets fall back to the event's root\n * scope (`$.cart` / `$.payment`) — the validation still applies, rendered\n * less specifically.\n *\n * Line item uuids are only valid within the event that delivered them:\n * use `lineItems[n].uuid` from this event's cart snapshot, don't cache\n * uuids across events. Bundle components are not addressable; target\n * their parent line.\n */\n target?: TTarget;\n}" } }, "ValidationLevel": { @@ -9812,6 +10486,84 @@ "description": "" } }, + "ValidationTargetFor": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ValidationTargetFor", + "value": "TEvent['type'] extends keyof ValidationTargetMap\n ? ValidationTargetMap[TEvent['type']]\n : ValidationTarget", + "description": "The validation targets valid for a given intercepted event." + } + }, + "ValidationTargetMap": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "name": "ValidationTargetMap", + "description": "Maps POS interceptable workflow names to their valid validation targets.", + "members": [ + { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "PropertySignature", + "name": "cartvalidations", + "value": "CartValidationTarget", + "description": "" + }, + { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "PropertySignature", + "name": "paymentvalidations", + "value": "PaymentValidationTarget", + "description": "" + } + ], + "value": "interface ValidationTargetMap {\n [POS_INTERCEPT_NAMES.CART_VALIDATIONS]: CartValidationTarget;\n [POS_INTERCEPT_NAMES.PAYMENT_VALIDATIONS]: PaymentValidationTarget;\n}" + } + }, + "CartValidationTarget": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CartValidationTarget", + "value": "CartTarget | CartLineItemTarget", + "description": "" + } + }, + "CartTarget": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CartTarget", + "value": "'$.cart'", + "description": "Targets the whole cart rather than a specific line item." + } + }, + "CartLineItemTarget": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CartLineItemTarget", + "value": "`$.cart.lineItems['${string}']`", + "description": "Targets one cart line item by its `uuid` from this event's `cart` snapshot, for example `$.cart.lineItems['adfd6b06-4a24-4f5f-9f4b-ea21f4432dd4']`." + } + }, + "PaymentValidationTarget": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "PaymentValidationTarget", + "value": "\"$.payment\"", + "description": "" + } + }, + "ValidationTarget": { + "src/surfaces/point-of-sale/events.ts": { + "filePath": "src/surfaces/point-of-sale/events.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ValidationTarget", + "value": "CartValidationTarget | PaymentValidationTarget", + "description": "Where a validation applies, as an enumerated token. Targets are matched as exact strings, never evaluated as JSON paths." + } + }, "Docs_AppBackgroundEventMethods": { "src/surfaces/point-of-sale/api/docs.ts": { "filePath": "src/surfaces/point-of-sale/api/docs.ts", diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/targets.json b/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/targets.json index ff41d794c2..e0c6f399cb 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/targets.json +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/generated/pos_ui_extensions/2026-10/targets.json @@ -56,6 +56,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -137,6 +138,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -257,6 +259,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -379,6 +382,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -501,6 +505,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -623,6 +628,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -745,6 +751,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -827,6 +834,7 @@ "Modal", "NumberField", "POSBlock", + "POSList", "Page", "PosBlock", "Route", @@ -1644,6 +1652,18 @@ "pos.register-details.block.render" ] }, + "POSList": { + "targets": [ + "pos.cart.line-item-details.action.render", + "pos.customer-details.action.render", + "pos.draft-order-details.action.render", + "pos.home.modal.render", + "pos.order-details.action.render", + "pos.product-details.action.render", + "pos.purchase.post.action.render", + "pos.register-details.action.render" + ] + }, "Page": { "targets": [ "pos.cart.line-item-details.action.render", diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/components.d.ts b/packages/ui-extensions/src/surfaces/point-of-sale/components.d.ts index 3b0afd29bc..02e31dc65e 100644 --- a/packages/ui-extensions/src/surfaces/point-of-sale/components.d.ts +++ b/packages/ui-extensions/src/surfaces/point-of-sale/components.d.ts @@ -5416,6 +5416,144 @@ declare module 'preact' { } } +declare const posListTagName = 's-pos-list'; +type POSListImageDisplayStrategy = 'auto' | 'always' | 'never'; +type POSListRowSubtitleColor = + | 'neutral' + | 'subdued' + | 'disabled' + | 'warning' + | 'critical' + | 'success' + | 'interactive' + | 'highlight'; +type POSListRowSubtitle = + | string + | { + /** The subtitle text. */ + content: string; + /** + * The semantic color applied to the subtitle. + * + * @default 'neutral' + */ + color?: POSListRowSubtitleColor; + }; +type POSListBadge = { + /** The badge text. */ + text: string; + /** + * The semantic appearance of the badge. + * + * @default 'neutral' + */ + tone?: 'neutral' | 'critical' | 'warning' | 'success' | 'highlight'; +}; +type POSListRowImage = { + /** The URL of the image displayed at the start of the row. */ + src?: string; + /** A numeric badge displayed over the image. */ + badge?: number; +}; +type POSListToggleSwitch = { + /** + * The current state of the toggle switch. + * + * @default false + */ + checked?: boolean; + /** + * Whether the toggle switch prevents interaction. + * + * @default false + */ + disabled?: boolean; +}; +type POSListRowStart = { + /** The primary text for the row. */ + label: string; + /** Up to three lines of supporting text displayed below the label. */ + subtitles?: [POSListRowSubtitle, POSListRowSubtitle?, POSListRowSubtitle?]; + /** Status or category badges displayed with the row content. */ + badges?: POSListBadge[]; + /** The image displayed at the start of the row. */ + image?: POSListRowImage; +}; +type POSListRowEnd = { + /** Supporting text displayed at the end of the row. */ + label?: string; + /** + * Whether to display a chevron at the end of the row. + * + * @default false + */ + showChevron?: boolean; + /** A toggle switch displayed at the end of the row. */ + toggleSwitch?: POSListToggleSwitch; +}; +type POSListRow = { + /** A unique identifier for the row. */ + id: string; + /** The primary content displayed at the start of the row. */ + start: POSListRowStart; + /** + * Callback invoked when the row is activated. + * + * When provided, the row is interactive. + */ + onClick?: (event: CallbackEvent) => void; + /** Optional content displayed at the end of the row. */ + end?: POSListRowEnd; +}; +/** + * Displays structured rows with text, badges, images, and optional trailing content. + * + * @publicDocs + */ +interface POSListJSXProps { + /** A unique identifier for the element. */ + id?: string; + /** + * The rows displayed in the list. + * + * @default [] + */ + rows?: POSListRow[]; + /** + * Controls whether rows reserve space for images. + * + * - `auto`: Displays images or placeholders when a row includes an image source. + * - `always`: Displays images or placeholders for every row. + * - `never`: Displays rows without images or image placeholders. + * + * @default 'auto' + */ + imageDisplayStrategy?: POSListImageDisplayStrategy; + /** + * Whether additional rows are being loaded. + * + * @default false + */ + loadingMore?: boolean; + /** Callback when more rows should be loaded. */ + onLoadMore?: ((event: CallbackEvent) => void) | null; + /** Content displayed before the rows as part of the list's scrollable content. */ + header?: ComponentChild; +} +type POSListElementProps = Omit; +declare global { + interface HTMLElementTagNameMap { + [posListTagName]: HtmlElementTagNameProps; + } +} +declare module 'preact' { + namespace createElement.JSX { + interface IntrinsicElements { + [posListTagName]: IntrinsicElementProps; + } + } +} + export type { BadgeJSXProps, BannerJSXProps, @@ -5438,6 +5576,7 @@ export type { ModalJSXProps, NumberFieldJSXProps, PageJSXProps, + POSListJSXProps, PosBlockJSXProps, QrCodeJSXProps, ScrollBoxJSXProps, @@ -5458,6 +5597,52 @@ export type { TimePickerJSXProps, }; +/** + * Events emitted by the POS list. + * @publicDocs + */ +interface POSListEvents { + /** Fired when more rows should be loaded. */ + loadmore?: (event: CallbackEvent) => void; +} + +/** + * Content slots for the POS list. + * @publicDocs + */ +interface POSListSlots { + /** Content displayed before the rows as part of the list's scrollable content. */ + header?: HTMLElement; +} + +/** + * Displays structured rows with text, badges, images, and optional trailing content. + * @publicDocs + */ +interface POSList { + /** A unique identifier for the element. */ + id?: string; + /** + * The rows displayed in the list. + * @default [] + */ + rows?: POSListRow[]; + /** + * Controls whether rows reserve space for images. + * + * - `auto`: Displays images or placeholders when a row includes an image source. + * - `always`: Displays images or placeholders for every row. + * - `never`: Displays rows without images or image placeholders. + * @default 'auto' + */ + imageDisplayStrategy?: POSListImageDisplayStrategy; + /** + * Whether additional rows are being loaded. + * @default false + */ + loadingMore?: boolean; +} + /** * The link component provides event callbacks for handling user interactions. Learn more about [handling events](/docs/api/polaris/using-polaris-web-components#handling-events). * @publicDocs @@ -7771,3 +7956,18 @@ declare global { } } } + +declare module 'react' { + namespace JSX { + interface IntrinsicElements { + [posListTagName]: IntrinsicElementProps; + } + } +} +declare global { + namespace JSX { + interface IntrinsicElements { + [posListTagName]: IntrinsicElementProps; + } + } +} diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList.d.ts b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList.d.ts new file mode 100644 index 0000000000..1831b49b74 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList.d.ts @@ -0,0 +1,197 @@ +/** VERSION: undefined **/ +/* eslint-disable import-x/extensions */ +/* eslint-disable @typescript-eslint/no-namespace */ +/* eslint-disable @typescript-eslint/member-ordering */ +/* eslint-disable line-comment-position */ +/* eslint-disable @typescript-eslint/unified-signatures */ +/* eslint-disable no-var */ +/* eslint-disable import-x/namespace */ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment +/// +import type {Key, Ref, ComponentChild} from './components-shared.d.ts'; + +export type ComponentChildren = any; +/** + * Used when an element does not have children. + */ +export interface BaseElementProps { + key?: Key; + ref?: Ref; + slot?: Lowercase; +} +/** + * Used when an element has children. + */ +export interface BaseElementPropsWithChildren + extends BaseElementProps { + children?: ComponentChildren; +} +export type IntrinsicElementProps = T & + BaseElementPropsWithChildren; +export type HtmlElementTagNameProps = T & HTMLElement; +export type ElementForTag = + T extends keyof HTMLElementTagNameMap + ? HTMLElementTagNameMap[T] + : HTMLElement; +export interface CallbackEvent { + currentTarget: ElementForTag; + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; + detail?: any; + eventPhase: number; + target: ElementForTag | null; +} + +declare const tagName = 's-pos-list'; +export type POSListImageDisplayStrategy = 'auto' | 'always' | 'never'; +export type POSListRowSubtitleColor = + | 'neutral' + | 'subdued' + | 'disabled' + | 'warning' + | 'critical' + | 'success' + | 'interactive' + | 'highlight'; +export type POSListRowSubtitle = + | string + | { + /** The subtitle text. */ + content: string; + /** + * The semantic color applied to the subtitle. + * + * @default 'neutral' + */ + color?: POSListRowSubtitleColor; + }; +export type POSListBadge = { + /** The badge text. */ + text: string; + /** + * The semantic appearance of the badge. + * + * @default 'neutral' + */ + tone?: 'neutral' | 'critical' | 'warning' | 'success' | 'highlight'; +}; +export type POSListRowImage = { + /** The URL of the image displayed at the start of the row. */ + src?: string; + /** A numeric badge displayed over the image. */ + badge?: number; +}; +export type POSListToggleSwitch = { + /** + * The current state of the toggle switch. + * + * @default false + */ + checked?: boolean; + /** + * Whether the toggle switch prevents interaction. + * + * @default false + */ + disabled?: boolean; +}; +export type POSListRowStart = { + /** The primary text for the row. */ + label: string; + /** Up to three lines of supporting text displayed below the label. */ + subtitles?: [POSListRowSubtitle, POSListRowSubtitle?, POSListRowSubtitle?]; + /** Status or category badges displayed with the row content. */ + badges?: POSListBadge[]; + /** The image displayed at the start of the row. */ + image?: POSListRowImage; +}; +export type POSListRowEnd = { + /** Supporting text displayed at the end of the row. */ + label?: string; + /** + * Whether to display a chevron at the end of the row. + * + * @default false + */ + showChevron?: boolean; + /** A toggle switch displayed at the end of the row. */ + toggleSwitch?: POSListToggleSwitch; +}; +export type POSListRow = { + /** A unique identifier for the row. */ + id: string; + /** The primary content displayed at the start of the row. */ + start: POSListRowStart; + /** + * Callback invoked when the row is activated. + * + * When provided, the row is interactive. + */ + onClick?: (event: CallbackEvent) => void; + /** Optional content displayed at the end of the row. */ + end?: POSListRowEnd; +}; +/** + * Displays structured rows with text, badges, images, and optional trailing content. + * + * @publicDocs + */ +export interface POSListJSXProps { + /** A unique identifier for the element. */ + id?: string; + /** + * The rows displayed in the list. + * + * @default [] + */ + rows?: POSListRow[]; + /** + * Controls whether rows reserve space for images. + * + * - `auto`: Displays images or placeholders when a row includes an image source. + * - `always`: Displays images or placeholders for every row. + * - `never`: Displays rows without images or image placeholders. + * + * @default 'auto' + */ + imageDisplayStrategy?: POSListImageDisplayStrategy; + /** + * Whether additional rows are being loaded. + * + * @default false + */ + loadingMore?: boolean; + /** Callback when more rows should be loaded. */ + onLoadMore?: ((event: CallbackEvent) => void) | null; + /** Content displayed before the rows as part of the list's scrollable content. */ + header?: ComponentChild; +} +export type ElementProps = Omit; +declare global { + interface HTMLElementTagNameMap { + [tagName]: HtmlElementTagNameProps; + } +} +declare module 'preact' { + namespace createElement.JSX { + interface IntrinsicElements { + [tagName]: IntrinsicElementProps; + } + } +} + +export {tagName}; +export type { + ElementProps, + POSListBadge, + POSListImageDisplayStrategy, + POSListJSXProps, + POSListRow, + POSListRowEnd, + POSListRowImage, + POSListRowStart, + POSListRowSubtitle, + POSListRowSubtitleColor, + POSListToggleSwitch, +}; diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/default.jsx b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/default.jsx new file mode 100644 index 0000000000..c710c3bbf8 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/default.jsx @@ -0,0 +1,33 @@ + { + console.log('Selected row: graphic-tee', event); + }, + }, + { + id: 'canvas-tote', + start: { + label: 'Canvas tote', + subtitles: ['Natural'], + }, + end: {label: '$18.00', showChevron: true}, + onClick: (event) => { + console.log('Selected row: canvas-tote', event); + }, + }, + ]} +> + Products +; diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/incremental-loading.jsx b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/incremental-loading.jsx new file mode 100644 index 0000000000..fa6bde4032 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/point-of-sale/components/POSList/examples/incremental-loading.jsx @@ -0,0 +1,8 @@ + { + console.log('Load more requested', event); + void loadMoreProducts(); + }} +/>; diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/components/targets/StandardComponents.ts b/packages/ui-extensions/src/surfaces/point-of-sale/components/targets/StandardComponents.ts index 71a74c8f59..722f51f88a 100644 --- a/packages/ui-extensions/src/surfaces/point-of-sale/components/targets/StandardComponents.ts +++ b/packages/ui-extensions/src/surfaces/point-of-sale/components/targets/StandardComponents.ts @@ -25,6 +25,7 @@ export type StandardComponents = | 'Page' | 'POSBlock' | 'PosBlock' // Case is important in 2025-10 + | 'POSList' | 'Route' | 'Router' | 'ScrollBox'