Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs for Flask 12.4 #1540

Merged
merged 19 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
3 changes: 3 additions & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ of the [MetaMask developer page](https://metamask.io/developer/).

## September 2024

- Documented new [Snaps custom UI with JSX components](/snaps/features/custom-ui/with-jsx) for Flask
version 12.4.
([#1540](https://github.com/MetaMask/metamask-docs/pull/1540))
- Documented [Snaps user-defined components](/snaps/features/custom-ui/user-defined-components).
([#1557](https://github.com/MetaMask/metamask-docs/pull/1557))
- Updated [Android SDK documentation](/wallet/how-to/use-sdk/mobile/android) with convenience
Expand Down
Binary file added snaps/assets/custom-ui-checkbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added snaps/assets/custom-ui-file-input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified snaps/assets/custom-ui-heading.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added snaps/assets/custom-ui-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added snaps/assets/custom-ui-radio-group.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added snaps/assets/custom-ui-selector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added snaps/assets/custom-ui-tooltip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified snaps/assets/home-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions snaps/features/custom-ui/interactive-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ If you need to [update the interface](#update-an-interactive-interface) or
[get its state](#get-an-interactive-interfaces-state) at a future time, you should store its ID in
the Snap's storage.

### Add context to an interface

You can optionally add context to an interface by passing a `context` object to the
[`snap_createInterface`](../../reference/snaps-api.md#snap_createinterface) method.
This object can contain any data you want to pass to the interface.
This context will be passed to [`onUserInput`](../../reference/entry-points.md#onuserinput) when the user interacts with the interface.

## Update an interactive interface

To update an interactive interface that is still active, use the
Expand Down
271 changes: 259 additions & 12 deletions snaps/features/custom-ui/with-jsx.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ Outputs a box, which can be used as a container for other components.
#### Props

- `direction` - (Optional) The direction in which elements flow inside the box.
Possible values are `"horizontal"` or `"vertical"`.
Possible values are `"horizontal"` and `"vertical"`.
The default is `"vertical"`.
- `alignment` - (Optional) The alignment of the elements inside the box.
Possible values are `"start"`, `"center"`, `"end"`, `"space-between"`, or `"space-around"`.
Possible values are `"start"`, `"center"`, `"end"`, `"space-between"`, and `"space-around"`.
The default is `"start"`.

#### Example
Expand Down Expand Up @@ -209,14 +209,15 @@ For use in [interactive UI](interactive-ui.md).

#### Props

- `children`: `string` - The text of the button.
- `children` - The contents of the button.
This can be text, an [`Image`](#image) component, or an [`Icon`](#icon) component.
- `type` - (Optional) The type of button.
Possible values are `"button"` or `"submit"`.
Possible values are `"button"` and `"submit"`.
The default is `"button"`.
- `name`: `string` - (Optional) The name that will be sent to [`onUserInput`](../../reference/entry-points.md#onuserinput)
when a user selects the button.
- `variant` - (Optional) Determines the appearance of the button.
Possible values are `"primary"` or `"destructive"`.
Possible values are `"primary"` and `"destructive"`.
The default is `"primary"`.

#### Example
Expand Down Expand Up @@ -250,6 +251,40 @@ await snap.request({
<img src={require("../../assets/custom-ui-button.png").default} alt="Button UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Checkbox`

Outputs a checkbox for use in [interactive UI](interactive-ui.md).

#### Props

- `name`: `string` - The name sent to [`onUserInput`](../../reference/entry-points.md#onuserinput).
- `checked`: `boolean` - (Optional) Whether the checkbox is checked.
- `label`: `string` - (Optional) The label for the checkbox.
- `variant` - (Optional) The variant of the checkbox.
Possible values are `"default"` and `"toggle"`.

#### Example

```js
import { Checkbox } from "@metamask/snaps-sdk/jsx";

const interfaceId = await snap.request({
method: "snap_createInterface",
params: {
ui: (
<Box>
<Checkbox name="accept-terms" label="I understand the terms" />
<Checkbox name="dark-mode" label="Dark mode" variant="toggle" />
</Box>
),
},
});
```

<p align="center">
<img src={require("../../assets/custom-ui-checkbox.png").default} alt="Checkbox UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Copyable`

Outputs a read-only text field with a copy-to-clipboard shortcut.
Expand Down Expand Up @@ -359,13 +394,14 @@ await snap.request({

### `Field`

Outputs a form field, wrapping a [`Dropdown`](#dropdown) or [`Input`](#input) to give it a label and optional error.
Outputs a form field, wrapping an element to give it a label and optional error.

#### Props

- `label`: `string` - The label for the wrapped element.
- `error`: `string` - Any error for the wrapped element. Setting this changes the styling of the wrapped element to show that there is an error.
- `children` - The [`Dropdown`](#dropdown) or [`Input`](#input) element to be wrapped.
- `error`: `string` - (Optional) Any error for the wrapped element. Setting this changes the style of the wrapped element to show that there is an error.
- `children` - The element to be wrapped.
This can be a [`Dropdown`](#dropdown), [`Input`](#input), [`Selector`](#selector), or [`RadioGroup`](#radiogroup) component.

#### Example

Expand Down Expand Up @@ -399,6 +435,60 @@ await snap.request({
<img src={require("../../assets/custom-ui-field.png").default} alt="Field example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `FileInput`

Outputs a file input component for use in [interactive UI](interactive-ui.md).

#### Props

- `name`: `string` - The name that will be sent to [`onUserInput`](../../reference/entry-points.md#onuserinput)
when a user interacts with the form.
- `accept`: `string[]` - (Optional) The file types that the file input field accepts. If not
specified, the file input field accepts all file types. For examples of
valid values, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
- `compact`: `boolean` - (Optional) Whether the file input field is compact.

#### Example

```js
import { FileInput } from "@metamask/snaps-sdk/jsx";

export const onHomePage = async () => {
const interfaceId = await snap.request({
method: "snap_createInterface",
params: {
ui: (
<Box>
<Heading>File Upload</Heading>
<Form name="file-upload-form">
<Field>
<FileInput name="file-input" />
</Field>
<Button name="submit-file-upload-form" type="submit">
Submit
</Button>
</Form>
</Box>
),
},
});

return {
id: interfaceId,
}
};

export const onUserInput = async ({ id, event }) => {
if (event.type === UserInputEventType.FileUploadEvent && event.file !== null) {
console.log(event.file);
}
};
```

<p align="center">
<img src={require("../../assets/custom-ui-file-input.png").default} alt="File input UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Form`

Outputs a form for use in [interactive UI](interactive-ui.md).
Expand Down Expand Up @@ -467,6 +557,43 @@ module.exports.onHomePage = async () => {
<img src={require("../../assets/custom-ui-heading.png").default} alt="Divider UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Icon`

Outputs an icon.

#### Props

- `name` - The name of the icon.
Possible values include `"confirmation"`, `"search"`, "`warning`", and `"menu"`.
See the [full list of possible `name` values](https://github.com/MetaMask/snaps/blob/0014ff6d7566dbc2945600db740d0a90f818b2d8/packages/snaps-sdk/src/jsx/components/Icon.ts#L5-L163).
alexandratran marked this conversation as resolved.
Show resolved Hide resolved
- `color` - (Optional) The color of the icon.
Possible values are `"default"`, `"primary"`, and `"muted"`.
- `size` - (Optional) The size of the icon.
Possible values are `"md"` and `"inherit"`.
alexandratran marked this conversation as resolved.
Show resolved Hide resolved

#### Example

```javascript title="index.jsx"
import { Icon } from "@metamask/snaps-sdk/jsx";

await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: (
<Box direction="horizontal">
<Icon name="warning" size="md" />
<Text>Double-check the "to" address before proceeding.</Text>
</Box>
),
},
});
```

<p align="center">
<img src={require("../../assets/custom-ui-icon.png").default} alt="Icon UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Image`

Outputs an image.
Expand Down Expand Up @@ -527,7 +654,7 @@ Outputs an input component for use in [interactive UI](interactive-ui.md).
- `name`: `string` - The name that will be used as a key to the event sent to
[`onUserInput`](../../reference/entry-points.md#onuserinput) when the containing form is submitted.
- `type` - (Optional) The type of input.
Possible values are `"text"`, `"number"`, or `"password"`.
Possible values are `"text"`, `"number"`, and `"password"`.
The default is `"text"`.
- `placeholder`: `string` - (Optional) The text displayed when the input is empty.
- `label`: `string` - (Optional) The text displayed alongside the input to label it.
Expand Down Expand Up @@ -625,6 +752,42 @@ module.exports.onHomePage = async () => {
<img src={require("../../assets/custom-ui-links.png").default} alt="Links UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `RadioGroup`

Outputs a radio group component for use in [interactive UI](interactive-ui.md).

#### Props

- `name`: `string` - The name that will be used as a key to the event sent to
[`onUserInput`](../../reference/entry-points.md#onuserinput) when the containing form is submitted.
- `children`: `Radio[]` - One or more `Radio` components, each with a `value` and text child.

#### Example

```js
import { RadioGroup, Radio } from "@metamask/snaps-sdk/jsx";

const interfaceId = await snap.request({
method: "snap_createInterface",
params: {
ui: (
<Form name="form-example">
<Field label="Select an option">
<RadioGroup name="radio-group-example">
<Radio value="option-1">Option 1</Radio>
<Radio value="option-2">Option 2</Radio>
</RadioGroup>
</Field>
</Form>
),
},
});
```

<p align="center">
<img src={require("../../assets/custom-ui-radio-group.png").default} alt="RadioGroup UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Row`

Outputs a row with a label and value, which can be used for key-value data.
Expand All @@ -633,7 +796,7 @@ Outputs a row with a label and value, which can be used for key-value data.

- `label`: `string` - The label of the row.
- `variant` - (Optional) The variant of the label.
Possible values are `"default"`, `"error"`, or `"warning"`.
Possible values are `"default"`, `"error"`, and `"warning"`.
- `children` - The value of the row, which can be a [`Text`](#text), [`Image`](#image), or
[`Address`](#address) component.

Expand Down Expand Up @@ -664,6 +827,43 @@ await snap.request({
<img src={require("../../assets/custom-ui-row.png").default} alt="Row UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### `Selector`

Outputs a selector component for use in [interactive UI](interactive-ui.md).

#### Props

- `name`: `string` - The name that will be used as a key to the event sent to
[`onUserInput`](../../reference/entry-points.md#onuserinput) when the containing form is submitted.
- `title`: `string` - The title of the selector, displayed when the selector is opened.
- `children`: `SelectorOption[]` - One or more `SelectorOption` components, each with a `Card` child.

#### Example

```js
import { Selector, SelectorOption, Card } from "@metamask/snaps-sdk/jsx";

const interfaceId = await snap.request({
method: "snap_createInterface",
params: {
ui: (
<Selector name="selector-example" title="Select an option">
<SelectorOption value="option-1">
<Card title="Option 1" value="First option" />
</SelectorOption>
<SelectorOption value="option-2">
<Card title="Option 2" value="Second option" />
</SelectorOption>
</Selector>
),
},
});
```

<p align="center">
<img src={require("../../assets/custom-ui-selector.png").default} alt="Selector UI example" width="450px" />
</p>

### `Spinner`

Outputs a loading indicator.
Expand Down Expand Up @@ -693,7 +893,15 @@ await snap.request({

### `Text`

Outputs text.
Outputs text.

#### Props

- `color` - (Optional) The color of the text.
Possible values are `"default"`, "`alternative`", `"muted"`, `"error"`, `"success"`, and `"warning"`.
- `alignment` - (Optional) The alignment of the text.
Possible values are `"start"`, `"center"`, and `"end"`.
alexandratran marked this conversation as resolved.
Show resolved Hide resolved


#### Example

Expand All @@ -716,7 +924,46 @@ module.exports.onHomePage = async () => {
<img src={require("../../assets/custom-ui-heading.png").default} alt="Text UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

### Emojis
### `Tooltip`

Outputs a tooltip when the wrapped element is hovered over.

#### Props

- `content`: - The content of the tooltip.
- `children`: - The element to wrap.

#### Example

```javascript title="index.jsx"
import { Tooltip, Text } from "@metamask/snaps-sdk/jsx";

await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: (
<Box>
<Tooltip
content={
<Text>
Tooltip <Bold>text</Bold>
</Text>
}
>
<Text>Hello world!</Text>
</Tooltip>
</Box>
),
},
});
```

<p align="center">
<img src={require("../../assets/custom-ui-tooltip.png").default} alt="Tooltip UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
</p>

## Emojis

Text-based components (such as [`Heading`](#heading) and [`Text`](#text)) accept emojis.

Expand Down
Loading
Loading