diff --git a/packages/runtime/example/toast/index.html b/packages/runtime/example/toast/index.html new file mode 100644 index 00000000..de073b13 --- /dev/null +++ b/packages/runtime/example/toast/index.html @@ -0,0 +1,184 @@ + + + + + + meta-ui runtime example: tooltip + + + +
+ + + diff --git a/packages/runtime/src/components/chakra-ui/Types/Toast.ts b/packages/runtime/src/components/chakra-ui/Types/Toast.ts new file mode 100644 index 00000000..236ad5e2 --- /dev/null +++ b/packages/runtime/src/components/chakra-ui/Types/Toast.ts @@ -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; +export type ToastCloseParameter = Static; \ No newline at end of file diff --git a/packages/runtime/src/util-methods.ts b/packages/runtime/src/util-methods.ts index 0c93254a..07e9c644 100644 --- a/packages/runtime/src/util-methods.ts +++ b/packages/runtime/src/util-methods.ts @@ -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 | 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; } diff --git a/packages/runtime/src/utils/pickProperty.ts b/packages/runtime/src/utils/pickProperty.ts new file mode 100644 index 00000000..98e5c4ae --- /dev/null +++ b/packages/runtime/src/utils/pickProperty.ts @@ -0,0 +1,12 @@ +import { Static, TObject, TProperties } from '@sinclair/typebox'; + +export const pickProperty = ( + schema: TObject, + object: U +): Partial>> => { + const result: Partial = {}; + for (const key in schema.properties) { + result[key] = object[key]; + } + return result as Partial>>; +};