add chakra-ui toast.

This commit is contained in:
Sczlog 2021-09-16 18:48:07 +08:00
parent 14ffa30acf
commit a5fafc4798
4 changed files with 270 additions and 1 deletions

View File

@ -0,0 +1,184 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>meta-ui runtime example: tooltip</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from '../../src/main.tsx';
renderApp({
version: 'example/v1',
metadata: {
name: 'tooltip',
description: 'tooltip',
},
spec: {
components: [
{
id: 'root',
type: 'chakra_ui/v1/root',
properties: {},
traits: [],
},
{
id: 'open_button',
type: 'chakra_ui/v1/button',
properties: {
text: {
raw: 'open toast',
format: 'plain',
},
},
traits: [
{
type: 'core/v1/state',
properties: {
key: 'lastToast',
initialValue: undefined,
},
},
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'root',
},
},
},
{
type: 'core/v1/event',
properties: {
events: [
{
event: 'click',
componentId: 'open_button',
method: {
name: 'setValue',
parameters: {
key: 'lastToast',
value: '{{Math.random().toString()}}',
},
},
wait: {},
},
{
event: 'click',
componentId: '$utils',
method: {
name: 'toast.open',
parameters: {
id: '{{open_button.lastToast}}',
title: 'i am a title',
description: 'i am a description',
position: 'bottom-right',
duration: null,
isClosable: true,
},
},
wait: {},
},
],
},
},
],
},
{
id: 'close_last_button',
type: 'chakra_ui/v1/button',
properties: {
text: {
raw: 'close last toast',
format: 'plain',
},
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'root',
},
},
},
{
type: 'core/v1/event',
properties: {
events: [
{
event: 'click',
componentId: '$utils',
method: {
name: 'toast.close',
parameters: {
id: '{{open_button.lastToast}}',
},
},
wait: {},
disabled: '{{!open_button.lastToast}}',
},
{
event: 'click',
componentId: 'open_button',
method: {
name: 'setValue',
parameters: {
key: 'lastToast',
value: '',
},
},
wait: {},
disabled: '{{!open_button.lastToast}}',
},
],
},
},
],
},
{
id: 'close_all_button',
type: 'chakra_ui/v1/button',
properties: {
text: {
raw: 'close all toast',
format: 'plain',
},
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'root',
},
},
},
{
type: 'core/v1/event',
properties: {
events: [
{
event: 'click',
componentId: '$utils',
method: {
name: 'toast.close',
},
wait: {},
},
],
},
},
],
},
],
},
});
</script>
</body>
</html>

View File

@ -0,0 +1,41 @@
import { Type, Static } from '@sinclair/typebox';
const ToastPosition = Type.Union([
Type.Literal('top'),
Type.Literal('top-right'),
Type.Literal('top-left'),
Type.Literal('bottom'),
Type.Literal('bottom-right'),
Type.Literal('bottom-left'),
]);
export const ToastOpenParamterSchema = Type.Object({
position: Type.Optional(ToastPosition),
duration: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
title: Type.Optional(Type.String()),
description: Type.Optional(Type.String()),
isClosable: Type.Optional(Type.Boolean()),
variant: Type.Optional(
Type.Union([
Type.Literal('subtle'),
Type.Literal('solid'),
Type.Literal('left-accent'),
Type.Literal('top-accent'),
])
),
status: Type.Optional(
Type.Union([
Type.Literal('error'),
Type.Literal('success'),
Type.Literal('warning'),
Type.Literal('info'),
])
),
id: Type.Optional(Type.String()),
});
export const ToastCloseParameterSchema = Type.Object({
id: Type.Optional(Type.Union([Type.Number(), Type.String()])),
positions: Type.Optional(Type.Array(ToastPosition)),
});
export type ToastOpenParameter = Static<typeof ToastOpenParamterSchema>;
export type ToastCloseParameter = Static<typeof ToastCloseParameterSchema>;

View File

@ -1,15 +1,47 @@
import { apiService } from './api-service';
import { createStandaloneToast } from '@chakra-ui/react';
import {
ToastCloseParameterSchema,
ToastOpenParamterSchema,
} from './components/chakra-ui/Types/Toast';
import { pickProperty } from './utils/pickProperty';
export function mountUtilMethods() {
let toast: ReturnType<typeof createStandaloneToast> | undefined = undefined;
apiService.on('uiMethod', ({ componentId, name, parameters }) => {
if (componentId !== '$utils') {
return;
}
switch (name) {
case 'alert':
window.alert(parameters);
break;
case 'toast.open':
if (!toast) {
toast = createStandaloneToast();
}
if (parameters) {
toast(pickProperty(ToastOpenParamterSchema, parameters));
}
break;
case 'toast.close':
if (!toast) {
break;
}
if (!parameters) {
toast.closeAll();
} else {
const closeParameters = pickProperty(
ToastCloseParameterSchema,
parameters
);
if (closeParameters.id !== undefined) {
toast.close(closeParameters.id);
} else {
toast.closeAll(closeParameters);
}
}
break;
default:
break;
}

View File

@ -0,0 +1,12 @@
import { Static, TObject, TProperties } from '@sinclair/typebox';
export const pickProperty = <T extends TProperties, U extends TProperties>(
schema: TObject<T>,
object: U
): Partial<Static<TObject<T>>> => {
const result: Partial<TProperties> = {};
for (const key in schema.properties) {
result[key] = object[key];
}
return result as Partial<Static<TObject<T>>>;
};