Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/forty-wombats-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/ui-extensions': patch
---

Add support for Function Settings component for Admin
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type {SharedReferenceEntityTemplateSchema} from '../docs-type';

const data: SharedReferenceEntityTemplateSchema = {
name: 'FunctionSettings',
description:
'FunctionSettings should be used when configuring the metafield configuration of a Shopify Function. It provides a structure for various input fields and controls, such as text fields, checkboxes, and selections. It also integrates with the native Contextual Save Bar to handle form submission and reset actions.',
category: 'Polaris web components',
subCategory: 'Forms',
related: [
{
type: 'component',
name: 'TextField',
url: '/docs/api/admin-extensions/components/forms/textfield',
},
{
type: 'component',
name: 'NumberField',
url: '/docs/api/admin-extensions/components/forms/numberfield',
},
{
type: 'component',
name: 'ChoiceList',
url: '/docs/api/admin-extensions/components/forms/choicelist',
},
],
};

export default data;
36 changes: 28 additions & 8 deletions packages/ui-extensions/src/surfaces/admin/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export interface ExtendableEvent extends Event {
interface AggregateError$1<T extends Error> extends Error {
errors: T[];
}
export interface ArgregatedErrorEvent<T extends Error> extends ErrorEvent {
export interface AggregateErrorEvent<T extends Error> extends ErrorEvent {
error: AggregateError$1<T>;
}
export type SizeKeyword =
Expand Down Expand Up @@ -2100,7 +2100,7 @@ interface ColorPickerProps$1 extends GlobalProps, InputProps {
* For RGB and RGBA, both the legacy syntax (comma-separated) and modern syntax (space-separate) are supported.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
*
* If the value is invalid, the component will select rgb(0, 0, 0).
* If the value is invalid, the component will return an empty string ''.
*
* Note that the `onChange` handler will emit the value in hex.
*/
Expand Down Expand Up @@ -2407,12 +2407,19 @@ interface DatePickerProps$1 extends GlobalProps, InputProps, FocusEventProps {
*/
value?: string;
/**
* Callback when any date is selected. Will fire before `onChange`.
* Callback when any date is selected.
*
* - If `type="single"`, fires when a date is selected and happens before `onChange`.
* - If `type="multiple"`, fires when a date is selected before `onChange`.
* - If `type="range"`, fires when a first date is selected (with the partial value formatted as `YYYY-MM-DD--`), and when the last date is selected before `onChange`.
*/
onInput?: (event: Event) => void;
/**
* Callback when the `value` is changed. For `type="single"` and `type="multiple"`, this is the same as `onInput`.
* For `type="range"`, this is only called when the range is completed by selecting the end date of the range.
* Callback when the value is committed.
*
* - If `type="single"`, fires when a date is selected after `onInput`.
* - If `type="multiple"`, fires when a date is selected after `onInput`.
* - If `type="range"`, fires when a range is completed by selecting the end date after `onInput`.
*/
onChange?: (event: Event) => void;
}
Expand All @@ -2432,6 +2439,16 @@ interface DateFieldProps$1
| 'onViewChange'
>,
AutocompleteProps<DateAutocompleteField> {
/**
* Callback when the user makes any changes in the field.
* Also triggered when a date is selected using the date picker popup before `onChange`.
*/
onInput?: (event: Event) => void;
/**
* Callback when the user has **finished editing** a field, e.g. once they have blurred the field.
* Also triggered when a date is selected using the date picker popup after `onInput`.
*/
onChange?: (event: Event) => void;
/**
* Callback when the field has an invalid date.
* This callback will be called, if the date typed is invalid or disabled.
Expand Down Expand Up @@ -2562,7 +2579,7 @@ interface FunctionSettingsProps$1 extends GlobalProps, FormProps$1 {
* highlight the fields that caused the errors, and display the error messages
* to the user.
*/
onError?: (event: ArgregatedErrorEvent<FunctionSettingsError>) => void;
onError?: (event: AggregateErrorEvent<FunctionSettingsError>) => void;
}
export interface FunctionSettingsError extends Error {
/**
Expand Down Expand Up @@ -6205,7 +6222,7 @@ export interface ModalJSXProps
export type RequiredMoneyFieldProps = Required<MoneyFieldProps$1>;
export interface MoneyFieldProps
extends Omit<PreactFieldProps, 'value'>,
Pick<RequiredMoneyFieldProps, 'max' | 'min' | 'step'> {
Pick<RequiredMoneyFieldProps, 'max' | 'min'> {
value: Required<MoneyFieldProps$1>['value'];
}

Expand All @@ -6215,7 +6232,8 @@ declare class MoneyField
{
accessor max: MoneyFieldProps['max'];
accessor min: MoneyFieldProps['min'];
accessor step: MoneyFieldProps['step'];
get value(): string;
set value(value: string);
constructor();
}
declare global {
Expand Down Expand Up @@ -6255,6 +6273,8 @@ declare class NumberField
extends PreactFieldElement<NumberFieldProps['autocomplete']>
implements NumberFieldProps
{
get value(): string;
set value(value: string);
accessor inputMode: NumberFieldProps['inputMode'];
accessor step: NumberFieldProps['step'];
accessor max: NumberFieldProps['max'];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {StandardComponents} from './StandardComponents';

export type FormExtensionComponents = StandardComponents | 'Form';

export default FormExtensionComponents;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs';
import shared from '../../../../docs/shared/components/FunctionSettings';

const data: ReferenceEntityTemplateSchema = {
...shared,
category: 'Polaris web components',
thumbnail: '/assets/templated-apis-screenshots/admin/components/form.png',
isVisualComponent: true,
definitions: [
{
title: 'Events',
description:
'Learn more about [registering events](/docs/api/app-home/using-polaris-components#event-handling).',
type: 'FormEvents',
},
],
defaultExample: {
codeblock: {
title: '',
tabs: [
{
title: 'JSX',
code: './examples/default.tsx',
language: 'jsx',
},
],
},
},
};

export default data;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {render} from 'preact';
import {useState} from 'preact/hooks';

export default async () => {
render(<Extension />, document.body);
};

function Extension() {
const [percentage, setPercentage] = useState(
shopify.data.metafields[0].value,
);

async function applyExtensionMetafieldChange() {
await shopify.applyMetafieldChange({
type: 'updateMetafield',
namespace: '$app:discounts-percentage',
key: 'function-configuration',
value: percentage,
valueType: 'integer',
});
}

return (
<s-function-settings
onSubmit={(e) => e.waitUntil(applyExtensionMetafieldChange())}
onReset={resetForm}
>
<s-number-field
step="1"
suffix="%"
label="Percentage"
name="percentage"
value={shopify.data.metafields[0].value}
onChange={(event) => setPercentage(event.currentTarget.value)}
/>
</s-function-settings>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {FormExtensionComponents} from './FormExtensionComponents';

export type FunctionSettingsComponents =
| FormExtensionComponents
| 'FunctionSettings';

export default FunctionSettingsComponents;
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ declare class PreactFieldElement<Autocomplete extends string = string>
export type RequiredMoneyFieldProps = Required<MoneyFieldProps$1>;
export interface MoneyFieldProps
extends Omit<PreactFieldProps, 'value'>,
Pick<RequiredMoneyFieldProps, 'max' | 'min' | 'step'> {
Pick<RequiredMoneyFieldProps, 'max' | 'min'> {
value: Required<MoneyFieldProps$1>['value'];
}

Expand All @@ -209,7 +209,8 @@ declare class MoneyField
{
accessor max: MoneyFieldProps['max'];
accessor min: MoneyFieldProps['min'];
accessor step: MoneyFieldProps['step'];
get value(): string;
set value(value: string);
constructor();
}
declare global {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ declare class NumberField
extends PreactFieldElement<NumberFieldProps['autocomplete']>
implements NumberFieldProps
{
get value(): string;
set value(value: string);
accessor inputMode: NumberFieldProps['inputMode'];
accessor step: NumberFieldProps['step'];
accessor max: NumberFieldProps['max'];
Expand Down
29 changes: 23 additions & 6 deletions packages/ui-extensions/src/surfaces/admin/components/shared.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export interface ExtendableEvent extends Event {
interface AggregateError$1<T extends Error> extends Error {
errors: T[];
}
export interface ArgregatedErrorEvent<T extends Error> extends ErrorEvent {
export interface AggregateErrorEvent<T extends Error> extends ErrorEvent {
error: AggregateError$1<T>;
}
export type SizeKeyword =
Expand Down Expand Up @@ -2098,7 +2098,7 @@ interface ColorPickerProps$1 extends GlobalProps, InputProps {
* For RGB and RGBA, both the legacy syntax (comma-separated) and modern syntax (space-separate) are supported.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
*
* If the value is invalid, the component will select rgb(0, 0, 0).
* If the value is invalid, the component will return an empty string ''.
*
* Note that the `onChange` handler will emit the value in hex.
*/
Expand Down Expand Up @@ -2405,12 +2405,19 @@ interface DatePickerProps$1 extends GlobalProps, InputProps, FocusEventProps {
*/
value?: string;
/**
* Callback when any date is selected. Will fire before `onChange`.
* Callback when any date is selected.
*
* - If `type="single"`, fires when a date is selected and happens before `onChange`.
* - If `type="multiple"`, fires when a date is selected before `onChange`.
* - If `type="range"`, fires when a first date is selected (with the partial value formatted as `YYYY-MM-DD--`), and when the last date is selected before `onChange`.
*/
onInput?: (event: Event) => void;
/**
* Callback when the `value` is changed. For `type="single"` and `type="multiple"`, this is the same as `onInput`.
* For `type="range"`, this is only called when the range is completed by selecting the end date of the range.
* Callback when the value is committed.
*
* - If `type="single"`, fires when a date is selected after `onInput`.
* - If `type="multiple"`, fires when a date is selected after `onInput`.
* - If `type="range"`, fires when a range is completed by selecting the end date after `onInput`.
*/
onChange?: (event: Event) => void;
}
Expand All @@ -2430,6 +2437,16 @@ interface DateFieldProps$1
| 'onViewChange'
>,
AutocompleteProps<DateAutocompleteField> {
/**
* Callback when the user makes any changes in the field.
* Also triggered when a date is selected using the date picker popup before `onChange`.
*/
onInput?: (event: Event) => void;
/**
* Callback when the user has **finished editing** a field, e.g. once they have blurred the field.
* Also triggered when a date is selected using the date picker popup after `onInput`.
*/
onChange?: (event: Event) => void;
/**
* Callback when the field has an invalid date.
* This callback will be called, if the date typed is invalid or disabled.
Expand Down Expand Up @@ -2560,7 +2577,7 @@ interface FunctionSettingsProps$1 extends GlobalProps, FormProps$1 {
* highlight the fields that caused the errors, and display the error messages
* to the user.
*/
onError?: (event: ArgregatedErrorEvent<FunctionSettingsError>) => void;
onError?: (event: AggregateErrorEvent<FunctionSettingsError>) => void;
}
export interface FunctionSettingsError extends Error {
/**
Expand Down
10 changes: 5 additions & 5 deletions packages/ui-extensions/src/surfaces/admin/extension-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import {
ShouldRenderApi,
ShouldRenderOutput,
} from './api/should-render/should-render';
import type {StandardComponents} from './components/StandardComponents';
import type {BlockExtensionComponents} from './components/BlockExtensionComponents';
import type {ActionExtensionComponents} from './components/ActionExtensionComponents';
import type {PrintActionExtensionComponents} from './components/PrintActionExtensionComponents';
import type {FunctionSettingsComponents} from './components/FunctionSettingsComponents';

export interface ExtensionTargets {
/**
Expand Down Expand Up @@ -59,7 +59,7 @@ export interface ExtensionTargets {
*/
'admin.discount-details.function-settings.render': RenderExtension<
DiscountFunctionSettingsApi<'admin.discount-details.function-settings.render'>,
BlockExtensionComponents
FunctionSettingsComponents
>;

/**
Expand Down Expand Up @@ -487,11 +487,11 @@ export interface ExtensionTargets {
*/
'admin.settings.internal-order-routing-rule.render': RenderExtension<
OrderRoutingRuleApi<'admin.settings.internal-order-routing-rule.render'>,
StandardComponents
FunctionSettingsComponents
>;
'admin.settings.order-routing-rule.render': RenderExtension<
OrderRoutingRuleApi<'admin.settings.order-routing-rule.render'>,
StandardComponents
FunctionSettingsComponents
>;

/**
Expand All @@ -501,7 +501,7 @@ export interface ExtensionTargets {
*/
'admin.settings.validation.render': RenderExtension<
ValidationSettingsApi<'admin.settings.validation.render'>,
StandardComponents
FunctionSettingsComponents
>;

// Admin action shouldRender targets
Expand Down