mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-23 17:49:49 +08:00
Merge pull request #100 from webzard-io/user-center
Some small features
This commit is contained in:
commit
2d7d22a9f8
@ -45,7 +45,7 @@
|
|||||||
"babel-jest": "^27.2.1",
|
"babel-jest": "^27.2.1",
|
||||||
"jest": "^27.2.1",
|
"jest": "^27.2.1",
|
||||||
"typescript": "^4.4.3",
|
"typescript": "^4.4.3",
|
||||||
"vite": "^2.5.10"
|
"vite": "^2.6.13"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { flatten } from 'lodash-es';
|
import { flatten } from 'lodash-es';
|
||||||
import { FormControl, FormLabel, Input, VStack } from '@chakra-ui/react';
|
import { FormControl, FormLabel, Input, Textarea, VStack } from '@chakra-ui/react';
|
||||||
import { EmotionJSX } from '@emotion/react/types/jsx-namespace';
|
import { EmotionJSX } from '@emotion/react/types/jsx-namespace';
|
||||||
import { TSchema } from '@sinclair/typebox';
|
import { TSchema } from '@sinclair/typebox';
|
||||||
import { Application } from '@meta-ui/core';
|
import { Application } from '@meta-ui/core';
|
||||||
@ -27,7 +27,7 @@ export const renderField = (properties: {
|
|||||||
}) => {
|
}) => {
|
||||||
const { value, type, fullKey, selectedId } = properties;
|
const { value, type, fullKey, selectedId } = properties;
|
||||||
if (typeof value !== 'object') {
|
if (typeof value !== 'object') {
|
||||||
const ref = React.createRef<HTMLInputElement>();
|
const ref = React.createRef<HTMLTextAreaElement>();
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
const operation = type
|
const operation = type
|
||||||
? new ModifyTraitPropertyOperation(selectedId, type, fullKey, ref.current?.value)
|
? new ModifyTraitPropertyOperation(selectedId, type, fullKey, ref.current?.value)
|
||||||
@ -37,7 +37,7 @@ export const renderField = (properties: {
|
|||||||
return (
|
return (
|
||||||
<FormControl key={`${selectedId}-${fullKey}`}>
|
<FormControl key={`${selectedId}-${fullKey}`}>
|
||||||
<FormLabel>{fullKey}</FormLabel>
|
<FormLabel>{fullKey}</FormLabel>
|
||||||
<Input ref={ref} onBlur={onBlur} defaultValue={value as string} />
|
<Textarea ref={ref} onBlur={onBlur} defaultValue={value as string} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,7 +96,7 @@ export const Editor = () => {
|
|||||||
<Tab>UI Tree</Tab>
|
<Tab>UI Tree</Tab>
|
||||||
<Tab>State</Tab>
|
<Tab>State</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanels flex="1">
|
<TabPanels flex="1" overflow="auto">
|
||||||
<TabPanel p={0}>
|
<TabPanel p={0}>
|
||||||
<StructureTree
|
<StructureTree
|
||||||
app={app}
|
app={app}
|
||||||
|
@ -12,121 +12,424 @@ export const DefaultAppSchema: Application = {
|
|||||||
spec: {
|
spec: {
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
id: 'root',
|
id: 'grid_layout1',
|
||||||
type: 'chakra_ui/v1/root',
|
type: 'core/v1/grid_layout',
|
||||||
properties: {},
|
properties: {
|
||||||
|
layout: [
|
||||||
|
{
|
||||||
|
w: 10,
|
||||||
|
h: 15,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
i: 'tabs1',
|
||||||
|
moved: false,
|
||||||
|
static: false,
|
||||||
|
isDraggable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
traits: [],
|
traits: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'btn',
|
id: 'fetchUsers',
|
||||||
type: 'plain/v1/button',
|
type: 'core/v1/dummy',
|
||||||
properties: {
|
properties: {},
|
||||||
text: {
|
|
||||||
raw: '**Open Dialog**',
|
|
||||||
format: 'md',
|
|
||||||
},
|
|
||||||
colorScheme: 'red',
|
|
||||||
},
|
|
||||||
traits: [
|
traits: [
|
||||||
{
|
{
|
||||||
type: 'core/v1/slot',
|
type: 'core/v1/fetch',
|
||||||
properties: {
|
properties: {
|
||||||
container: {
|
url: 'https://6177d4919c328300175f5b99.mockapi.io/users',
|
||||||
id: 'root',
|
method: 'get',
|
||||||
slot: 'root',
|
lazy: false,
|
||||||
},
|
headers: {},
|
||||||
},
|
body: {},
|
||||||
},
|
onComplete: [],
|
||||||
{
|
|
||||||
type: 'core/v1/event',
|
|
||||||
properties: {
|
|
||||||
handlers: [
|
|
||||||
{
|
|
||||||
type: 'onClick',
|
|
||||||
componentId: 'dialog',
|
|
||||||
method: {
|
|
||||||
name: 'openDialog',
|
|
||||||
parameters: {
|
|
||||||
title: 'hi',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wait: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'dialog',
|
id: 'usersTable',
|
||||||
type: 'chakra_ui/v1/dialog',
|
type: 'chakra_ui/v1/table',
|
||||||
properties: {
|
properties: {
|
||||||
title: 'This is a dialog',
|
data: '{{fetchUsers.fetch.data}}',
|
||||||
confirmButton: {
|
columns: [
|
||||||
text: 'hello',
|
{ key: 'username', title: '用户名', type: 'link' },
|
||||||
colorScheme: 'pink',
|
{ key: 'job', title: '职位', type: 'text' },
|
||||||
},
|
{ key: 'area', title: '地区', type: 'text' },
|
||||||
cancelButton: {
|
{
|
||||||
text: 'thanks',
|
key: 'createdTime',
|
||||||
},
|
title: '创建时间',
|
||||||
|
displayValue: "{{dayjs($listItem.createdTime).format('LL')}}",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
majorKey: 'id',
|
||||||
|
rowsPerPage: '3',
|
||||||
|
isMultiSelect: 'false',
|
||||||
},
|
},
|
||||||
traits: [
|
traits: [
|
||||||
{
|
{
|
||||||
type: 'core/v1/slot',
|
type: 'core/v1/slot',
|
||||||
properties: {
|
properties: {
|
||||||
container: {
|
container: { id: 'tabContentVStack', slot: 'content' },
|
||||||
id: 'root',
|
|
||||||
slot: 'root',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// dialog events
|
|
||||||
{
|
|
||||||
type: 'core/v1/event',
|
|
||||||
properties: {
|
|
||||||
handlers: [
|
|
||||||
// when click confirm
|
|
||||||
{
|
|
||||||
type: 'confirmDialog',
|
|
||||||
componentId: 'dialog',
|
|
||||||
method: {
|
|
||||||
name: 'confirmDialog',
|
|
||||||
},
|
|
||||||
wait: {},
|
|
||||||
disabled: 'false',
|
|
||||||
},
|
|
||||||
// when cancel confirm
|
|
||||||
{
|
|
||||||
type: 'cancelDialog',
|
|
||||||
componentId: 'dialog',
|
|
||||||
method: {
|
|
||||||
name: 'cancelDialog',
|
|
||||||
},
|
|
||||||
wait: {},
|
|
||||||
disabled: 'false',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'dialogContent',
|
id: 'userInfoContainer',
|
||||||
|
type: 'chakra_ui/v1/vstack',
|
||||||
|
properties: { spacing: '2', align: 'stretch' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'tabContentVStack', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: "{{!usersTable.selectedItem ? 'display: none' : ''}}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'userInfoTitle',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**基本信息**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hstack1',
|
||||||
|
type: 'chakra_ui/v1/hstack',
|
||||||
|
properties: { spacing: '24px', hideBorder: '' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: 'padding: 0; border: none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'usernameLabel',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**用户名**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack1', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'usernameValue',
|
||||||
type: 'core/v1/text',
|
type: 'core/v1/text',
|
||||||
properties: {
|
properties: {
|
||||||
value: {
|
value: {
|
||||||
raw: '**This is a dialog**',
|
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.username : ''}}",
|
||||||
format: 'md',
|
format: 'plain',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
traits: [
|
traits: [
|
||||||
{
|
{
|
||||||
type: 'core/v1/slot',
|
type: 'core/v1/slot',
|
||||||
properties: {
|
properties: {
|
||||||
container: {
|
container: { id: 'hstack1', slot: 'content' },
|
||||||
id: 'dialog',
|
},
|
||||||
slot: 'content',
|
},
|
||||||
},
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'divider1',
|
||||||
|
type: 'chakra_ui/v1/divider',
|
||||||
|
properties: {},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'jobLabel',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**职位**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack2', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hstack2',
|
||||||
|
type: 'chakra_ui/v1/hstack',
|
||||||
|
properties: { spacing: '24px', hideBorder: '' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: 'padding: 0; border: none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'areaLabel',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**地区**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack3', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'areaValue',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: {
|
||||||
|
value: {
|
||||||
|
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.area : ''}}",
|
||||||
|
format: 'plain',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack3', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'divider2',
|
||||||
|
type: 'chakra_ui/v1/divider',
|
||||||
|
properties: {},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'createdTimeLabel',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**创建时间**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack4', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'createdTimeValue',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: {
|
||||||
|
value: {
|
||||||
|
raw: "{{usersTable.selectedItem ? dayjs(usersTable.selectedItem.createdTime).format('LL') : ''}}",
|
||||||
|
format: 'plain',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack4', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: { string: { kind: {}, type: {} } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hstack3',
|
||||||
|
type: 'chakra_ui/v1/hstack',
|
||||||
|
properties: { spacing: '24px', hideBorder: '' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: 'padding: 0; border: none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'divider3',
|
||||||
|
type: 'chakra_ui/v1/divider',
|
||||||
|
properties: {},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hstack4',
|
||||||
|
type: 'chakra_ui/v1/hstack',
|
||||||
|
properties: { spacing: '24px', hideBorder: '' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'userInfoContainer', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: 'padding: 0; border: none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tabs1',
|
||||||
|
type: 'chakra_ui/v1/tabs',
|
||||||
|
properties: {
|
||||||
|
tabNames: ['用户信息', '角色'],
|
||||||
|
initialSelectedTabIndex: 0,
|
||||||
|
},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'grid_layout1', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tabContentVStack',
|
||||||
|
type: 'chakra_ui/v1/vstack',
|
||||||
|
properties: { spacing: '24px' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: { container: { id: 'tabs1', slot: 'content' } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'testtext',
|
||||||
|
type: 'core/v1/text',
|
||||||
|
properties: { value: { raw: '**测试角色**', format: 'md' } },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: { container: { id: 'tabs1', slot: 'content' } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'jobValue',
|
||||||
|
type: 'chakra_ui/v1/vstack',
|
||||||
|
properties: { spacing: '1', align: 'stretch' },
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'hstack2', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'core/v1/style',
|
||||||
|
properties: {
|
||||||
|
styleSlot: 'content',
|
||||||
|
style: 'padding: 0; border: none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'link1',
|
||||||
|
type: 'chakra_ui/v1/link',
|
||||||
|
properties: {
|
||||||
|
text: {
|
||||||
|
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.job : ''}}",
|
||||||
|
format: 'plain',
|
||||||
|
},
|
||||||
|
href: 'https://www.google.com',
|
||||||
|
},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'jobValue', slot: 'content' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'link2',
|
||||||
|
type: 'chakra_ui/v1/link',
|
||||||
|
properties: {
|
||||||
|
text: {
|
||||||
|
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.job : ''}}",
|
||||||
|
format: 'plain',
|
||||||
|
},
|
||||||
|
href: 'https://www.google.com',
|
||||||
|
},
|
||||||
|
traits: [
|
||||||
|
{
|
||||||
|
type: 'core/v1/slot',
|
||||||
|
properties: {
|
||||||
|
container: { id: 'jobValue', slot: 'content' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -43,18 +43,15 @@
|
|||||||
{
|
{
|
||||||
type: 'core/v1/style',
|
type: 'core/v1/style',
|
||||||
properties: {
|
properties: {
|
||||||
style: {
|
styleSlot: 'tabItem',
|
||||||
tabItem: {
|
style: `color: red`,
|
||||||
'&:hover': {
|
},
|
||||||
color: 'red',
|
},
|
||||||
},
|
{
|
||||||
},
|
type: 'core/v1/style',
|
||||||
tabContent: {
|
properties: {
|
||||||
'&:hover': {
|
styleSlot: 'tabContent',
|
||||||
color: 'green',
|
style: `color: green`,
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -74,7 +71,7 @@
|
|||||||
properties: {
|
properties: {
|
||||||
container: {
|
container: {
|
||||||
id: 'tabs',
|
id: 'tabs',
|
||||||
slot: 'tab_content_0',
|
slot: 'content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -85,7 +82,7 @@
|
|||||||
type: 'core/v1/text',
|
type: 'core/v1/text',
|
||||||
properties: {
|
properties: {
|
||||||
value: {
|
value: {
|
||||||
raw: 'hover me',
|
raw: 'hover me2',
|
||||||
format: 'plain',
|
format: 'plain',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -95,7 +92,7 @@
|
|||||||
properties: {
|
properties: {
|
||||||
container: {
|
container: {
|
||||||
id: 'tabs',
|
id: 'tabs',
|
||||||
slot: 'tab_content_1',
|
slot: 'content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -68,6 +68,6 @@
|
|||||||
"jest": "^27.1.0",
|
"jest": "^27.1.0",
|
||||||
"tsup": "^5.5.0",
|
"tsup": "^5.5.0",
|
||||||
"typescript": "^4.3.2",
|
"typescript": "^4.3.2",
|
||||||
"vite": "^2.3.8"
|
"vite": "^2.6.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,6 @@ import 'react-resizable/css/styles.css';
|
|||||||
import { DROP_EXAMPLE_SIZE_PREFIX, GRID_HEIGHT } from '../../constants';
|
import { DROP_EXAMPLE_SIZE_PREFIX, GRID_HEIGHT } from '../../constants';
|
||||||
import { decodeDragDataTransfer } from '../../utils/encodeDragDataTransfer';
|
import { decodeDragDataTransfer } from '../../utils/encodeDragDataTransfer';
|
||||||
|
|
||||||
// hack: add onDropDragOver to ReactGridLayoutProps definition
|
|
||||||
const ReactGridLayout: React.FC<RGL.ReactGridLayoutProps & { onDropDragOver: any }> =
|
|
||||||
RGL as any;
|
|
||||||
|
|
||||||
const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const spacing = 10;
|
const spacing = 10;
|
||||||
@ -25,12 +21,12 @@ const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
|||||||
background-position: 0px ${spacing / 2}px;
|
background-position: 0px ${spacing / 2}px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const onDropDragOver = (e: React.DragEvent) => {
|
const onDropDragOver = (e: any) => {
|
||||||
// Here we need to get data in dataTransfer
|
// Here we need to get data in dataTransfer
|
||||||
// but normally we cannot access dataTransfer in onDragOver, so I use a hack
|
// but normally we cannot access dataTransfer in onDragOver, so I use a hack
|
||||||
// I use the key of dataTransfer to store data, the key will look like 'exampleSize: [1,4]'
|
// I use the key of dataTransfer to store data, the key will look like 'exampleSize: [1,4]'
|
||||||
// https://stackoverflow.com/questions/28487352/dragndrop-datatransfer-getdata-empty
|
// https://stackoverflow.com/questions/28487352/dragndrop-datatransfer-getdata-empty
|
||||||
const key = e.dataTransfer.types
|
const key = (e as React.DragEvent).dataTransfer.types
|
||||||
.map(decodeDragDataTransfer)
|
.map(decodeDragDataTransfer)
|
||||||
.find(t => t.startsWith(DROP_EXAMPLE_SIZE_PREFIX));
|
.find(t => t.startsWith(DROP_EXAMPLE_SIZE_PREFIX));
|
||||||
const componentSize = JSON.parse(key?.replace(DROP_EXAMPLE_SIZE_PREFIX, '') || '');
|
const componentSize = JSON.parse(key?.replace(DROP_EXAMPLE_SIZE_PREFIX, '') || '');
|
||||||
@ -39,7 +35,7 @@ const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} css={bgCss}>
|
<div ref={ref} css={bgCss}>
|
||||||
<ReactGridLayout
|
<RGL
|
||||||
cols={12}
|
cols={12}
|
||||||
compactType={null}
|
compactType={null}
|
||||||
preventCollision={true}
|
preventCollision={true}
|
||||||
@ -51,7 +47,7 @@ const GridLayout: React.FC<RGL.ReactGridLayoutProps> = props => {
|
|||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</ReactGridLayout>
|
</RGL>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
31
packages/runtime/src/components/chakra-ui/Divider.tsx
Normal file
31
packages/runtime/src/components/chakra-ui/Divider.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Divider } from '@chakra-ui/react';
|
||||||
|
import { createComponent } from '@meta-ui/core';
|
||||||
|
import { ComponentImplementation } from '../../services/registry';
|
||||||
|
|
||||||
|
const DividerImpl: ComponentImplementation = () => {
|
||||||
|
return <Divider />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
...createComponent({
|
||||||
|
version: 'chakra_ui/v1',
|
||||||
|
metadata: {
|
||||||
|
name: 'divider',
|
||||||
|
displayName: 'Divider',
|
||||||
|
description: 'chakra-ui divider',
|
||||||
|
isDraggable: true,
|
||||||
|
isResizable: true,
|
||||||
|
exampleProperties: {},
|
||||||
|
exampleSize: [4, 1],
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
properties: {},
|
||||||
|
state: {},
|
||||||
|
methods: [],
|
||||||
|
slots: [],
|
||||||
|
styleSlots: [],
|
||||||
|
events: [],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
impl: DividerImpl,
|
||||||
|
};
|
@ -1,4 +1,5 @@
|
|||||||
import { createComponent } from '@meta-ui/core';
|
import { createComponent } from '@meta-ui/core';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
import { HStack as BaseHStack } from '@chakra-ui/react';
|
import { HStack as BaseHStack } from '@chakra-ui/react';
|
||||||
import { ComponentImplementation } from '../../services/registry';
|
import { ComponentImplementation } from '../../services/registry';
|
||||||
@ -18,6 +19,7 @@ const HStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
justify,
|
justify,
|
||||||
spacing,
|
spacing,
|
||||||
slotsMap,
|
slotsMap,
|
||||||
|
customStyle,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<BaseHStack
|
<BaseHStack
|
||||||
@ -28,6 +30,9 @@ const HStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
border="1px solid"
|
border="1px solid"
|
||||||
borderColor="gray.200"
|
borderColor="gray.200"
|
||||||
borderRadius="4"
|
borderRadius="4"
|
||||||
|
css={css`
|
||||||
|
${customStyle?.content}
|
||||||
|
`}
|
||||||
{...{ direction, wrap, align, justify, spacing }}
|
{...{ direction, wrap, align, justify, spacing }}
|
||||||
>
|
>
|
||||||
<Slot slotsMap={slotsMap} slot="content" />
|
<Slot slotsMap={slotsMap} slot="content" />
|
||||||
|
53
packages/runtime/src/components/chakra-ui/Link.tsx
Normal file
53
packages/runtime/src/components/chakra-ui/Link.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Link } from '@chakra-ui/react';
|
||||||
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
|
import { createComponent } from '@meta-ui/core';
|
||||||
|
import { ComponentImplementation } from '../../services/registry';
|
||||||
|
import Text, { TextPropertySchema } from '../_internal/Text';
|
||||||
|
|
||||||
|
const LinkImpl: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||||
|
text,
|
||||||
|
href,
|
||||||
|
isExternal,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Link href={href} isExternal={isExternal} color="blue.500">
|
||||||
|
<Text value={text} />
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PropsSchema = Type.Object({
|
||||||
|
text: TextPropertySchema,
|
||||||
|
href: Type.String(),
|
||||||
|
isExternal: Type.Optional(Type.Boolean()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
...createComponent({
|
||||||
|
version: 'chakra_ui/v1',
|
||||||
|
metadata: {
|
||||||
|
name: 'link',
|
||||||
|
displayName: 'Link',
|
||||||
|
description: 'chakra-ui link',
|
||||||
|
isDraggable: true,
|
||||||
|
isResizable: true,
|
||||||
|
exampleProperties: {
|
||||||
|
text: {
|
||||||
|
raw: 'link',
|
||||||
|
format: 'plain',
|
||||||
|
},
|
||||||
|
href: 'https://www.google.com',
|
||||||
|
},
|
||||||
|
exampleSize: [2, 1],
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
properties: PropsSchema,
|
||||||
|
state: {},
|
||||||
|
methods: [],
|
||||||
|
slots: [],
|
||||||
|
styleSlots: [],
|
||||||
|
events: [],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
impl: LinkImpl,
|
||||||
|
};
|
@ -95,8 +95,8 @@ const List: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PropsSchema = Type.Object({
|
const PropsSchema = Type.Object({
|
||||||
listData: Type.Array(Type.Object(Type.String(), Type.String())),
|
listData: Type.Array(Type.Record(Type.String(), Type.String())),
|
||||||
template: Type.Object(Type.String(), Type.Array(Type.Object(Type.String()))),
|
template: Type.Array(Type.Any()),
|
||||||
});
|
});
|
||||||
|
|
||||||
const exampleProperties = {
|
const exampleProperties = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Static } from '@sinclair/typebox';
|
import { Static } from '@sinclair/typebox';
|
||||||
import { ColumnSchema } from './TableTypes';
|
import { ColumnSchema } from './TableTypes';
|
||||||
import { Button, Td } from '@chakra-ui/react';
|
import { Button, Link, Td } from '@chakra-ui/react';
|
||||||
import { LIST_ITEM_EXP } from '../../../constants';
|
import { LIST_ITEM_EXP } from '../../../constants';
|
||||||
import { MetaUIServices } from 'src/types/RuntimeSchema';
|
import { MetaUIServices } from 'src/types/RuntimeSchema';
|
||||||
|
|
||||||
@ -20,11 +20,17 @@ export const TableTd: React.FC<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let content = value;
|
let content = value;
|
||||||
|
|
||||||
switch (column.type) {
|
switch (column.type) {
|
||||||
case 'image':
|
case 'image':
|
||||||
content = <img src={value} />;
|
content = <img src={value} />;
|
||||||
break;
|
break;
|
||||||
|
case 'link':
|
||||||
|
content = (
|
||||||
|
<Link href={value} color="blue.600">
|
||||||
|
{value}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
break;
|
||||||
case 'button':
|
case 'button':
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
onClickItem();
|
onClickItem();
|
||||||
|
@ -16,6 +16,7 @@ export const TdTypeSchema = Type.KeyOf(
|
|||||||
Type.Object({
|
Type.Object({
|
||||||
text: Type.String(),
|
text: Type.String(),
|
||||||
image: Type.String(),
|
image: Type.String(),
|
||||||
|
link: Type.String(),
|
||||||
button: Type.String(),
|
button: Type.String(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import { createComponent } from '@meta-ui/core';
|
import { createComponent } from '@meta-ui/core';
|
||||||
import { Tabs as BaseTabs, TabList, Tab, TabPanels, TabPanel } from '@chakra-ui/react';
|
import { Tabs as BaseTabs, TabList, Tab, TabPanels, TabPanel } from '@chakra-ui/react';
|
||||||
import { Type, Static } from '@sinclair/typebox';
|
import { Type, Static } from '@sinclair/typebox';
|
||||||
import { ComponentImplementation } from '../../services/registry';
|
import { ComponentImplementation } from '../../services/registry';
|
||||||
import Slot from '../_internal/Slot';
|
import { getSlots } from '../_internal/Slot';
|
||||||
|
|
||||||
const Tabs: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
const Tabs: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||||
tabNames,
|
tabNames,
|
||||||
mergeState,
|
mergeState,
|
||||||
initialSelectedTabIndex,
|
initialSelectedTabIndex,
|
||||||
slotsMap,
|
slotsMap,
|
||||||
style,
|
customStyle,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedTabIndex, setSelectedTabIndex] = useState(initialSelectedTabIndex ?? 0);
|
const [selectedTabIndex, setSelectedTabIndex] = useState(initialSelectedTabIndex ?? 0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mergeState({ selectedTabIndex });
|
mergeState({ selectedTabIndex });
|
||||||
}, [selectedTabIndex]);
|
}, [selectedTabIndex]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseTabs
|
<BaseTabs
|
||||||
defaultIndex={initialSelectedTabIndex}
|
defaultIndex={initialSelectedTabIndex}
|
||||||
@ -25,17 +25,24 @@ const Tabs: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
>
|
>
|
||||||
<TabList>
|
<TabList>
|
||||||
{tabNames.map((name, idx) => (
|
{tabNames.map((name, idx) => (
|
||||||
<Tab key={idx} css={style?.tabItem}>
|
<Tab key={idx} css={css`${customStyle?.tabItem}}`}>
|
||||||
{name}
|
{name}
|
||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanels>
|
<TabPanels>
|
||||||
{tabNames.map((_, idx) => (
|
{getSlots(slotsMap, 'content').map((content, idx) => {
|
||||||
<TabPanel key={idx} css={style?.tabContent}>
|
return (
|
||||||
<Slot slotsMap={slotsMap} slot={`tab_content_${idx}`} />
|
<TabPanel
|
||||||
</TabPanel>
|
key={idx}
|
||||||
))}
|
css={css`
|
||||||
|
${customStyle?.tabContent}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</TabPanel>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</TabPanels>
|
</TabPanels>
|
||||||
</BaseTabs>
|
</BaseTabs>
|
||||||
);
|
);
|
||||||
@ -70,8 +77,8 @@ export default {
|
|||||||
state: StateSchema,
|
state: StateSchema,
|
||||||
methods: [],
|
methods: [],
|
||||||
// tab slot is dynamic
|
// tab slot is dynamic
|
||||||
slots: [],
|
slots: ['content'],
|
||||||
styleSlots: [],
|
styleSlots: ['tabItem', 'tabContent'],
|
||||||
events: [],
|
events: [],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { createComponent } from '@meta-ui/core';
|
import { createComponent } from '@meta-ui/core';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
import { VStack as BaseVStack } from '@chakra-ui/react';
|
import { VStack as BaseVStack } from '@chakra-ui/react';
|
||||||
import { ComponentImplementation } from '../../services/registry';
|
import { ComponentImplementation } from '../../services/registry';
|
||||||
@ -18,6 +19,7 @@ const VStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
justify,
|
justify,
|
||||||
spacing,
|
spacing,
|
||||||
slotsMap,
|
slotsMap,
|
||||||
|
customStyle,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<BaseVStack
|
<BaseVStack
|
||||||
@ -28,6 +30,9 @@ const VStack: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
|||||||
border="1px solid"
|
border="1px solid"
|
||||||
borderColor="gray.200"
|
borderColor="gray.200"
|
||||||
borderRadius="4"
|
borderRadius="4"
|
||||||
|
css={css`
|
||||||
|
${customStyle?.content}
|
||||||
|
`}
|
||||||
{...{ direction, wrap, align, justify, spacing }}
|
{...{ direction, wrap, align, justify, spacing }}
|
||||||
>
|
>
|
||||||
<Slot slotsMap={slotsMap} slot="content" />
|
<Slot slotsMap={slotsMap} slot="content" />
|
||||||
|
@ -123,11 +123,8 @@ export const ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
|
|||||||
if (result.props?.effects) {
|
if (result.props?.effects) {
|
||||||
effects = effects?.concat(result.props?.effects);
|
effects = effects?.concat(result.props?.effects);
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
...prevProps,
|
return merge(prevProps, result.props, { effects });
|
||||||
...result.props,
|
|
||||||
effects,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
{} as TraitResult['props']
|
{} as TraitResult['props']
|
||||||
);
|
);
|
||||||
|
@ -13,10 +13,12 @@ import ChakraUITabs from '../components/chakra-ui/Tabs';
|
|||||||
import ChakraUITable from '../components/chakra-ui/Table';
|
import ChakraUITable from '../components/chakra-ui/Table';
|
||||||
import ChakraUIInput from '../components/chakra-ui/Input';
|
import ChakraUIInput from '../components/chakra-ui/Input';
|
||||||
import ChakraUIBox from '../components/chakra-ui/Box';
|
import ChakraUIBox from '../components/chakra-ui/Box';
|
||||||
|
import ChakraUIDivider from '../components/chakra-ui/Divider';
|
||||||
import ChakraUIFormControl from '../components/chakra-ui/Form/FormControl';
|
import ChakraUIFormControl from '../components/chakra-ui/Form/FormControl';
|
||||||
import ChakraUIForm from '../components/chakra-ui/Form/Form';
|
import ChakraUIForm from '../components/chakra-ui/Form/Form';
|
||||||
import ChakraUIKbd from '../components/chakra-ui/Kbd';
|
import ChakraUIKbd from '../components/chakra-ui/Kbd';
|
||||||
import ChakraUIList from '../components/chakra-ui/List';
|
import ChakraUIList from '../components/chakra-ui/List';
|
||||||
|
import ChakraUILink from '../components/chakra-ui/Link';
|
||||||
import ChakraUINumberInput from '../components/chakra-ui/NumberInput';
|
import ChakraUINumberInput from '../components/chakra-ui/NumberInput';
|
||||||
import ChakraUICheckboxGroup from '../components/chakra-ui/CheckboxGroup';
|
import ChakraUICheckboxGroup from '../components/chakra-ui/CheckboxGroup';
|
||||||
import ChakraUICheckbox from '../components/chakra-ui/Checkbox';
|
import ChakraUICheckbox from '../components/chakra-ui/Checkbox';
|
||||||
@ -130,10 +132,12 @@ export function initRegistry(): Registry {
|
|||||||
registry.registerComponent(ChakraUITable);
|
registry.registerComponent(ChakraUITable);
|
||||||
registry.registerComponent(ChakraUIInput);
|
registry.registerComponent(ChakraUIInput);
|
||||||
registry.registerComponent(ChakraUIBox);
|
registry.registerComponent(ChakraUIBox);
|
||||||
|
registry.registerComponent(ChakraUIDivider);
|
||||||
registry.registerComponent(ChakraUIFormControl);
|
registry.registerComponent(ChakraUIFormControl);
|
||||||
registry.registerComponent(ChakraUIForm);
|
registry.registerComponent(ChakraUIForm);
|
||||||
registry.registerComponent(ChakraUIKbd);
|
registry.registerComponent(ChakraUIKbd);
|
||||||
registry.registerComponent(ChakraUIList);
|
registry.registerComponent(ChakraUIList);
|
||||||
|
registry.registerComponent(ChakraUILink);
|
||||||
registry.registerComponent(ChakraUINumberInput);
|
registry.registerComponent(ChakraUINumberInput);
|
||||||
registry.registerComponent(ChakraUICheckbox);
|
registry.registerComponent(ChakraUICheckbox);
|
||||||
registry.registerComponent(ChakraUICheckboxGroup);
|
registry.registerComponent(ChakraUICheckboxGroup);
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import { toNumber, mapValues, isArray, isPlainObject, set } from 'lodash-es';
|
import { toNumber, mapValues, isArray, isPlainObject, set } from 'lodash-es';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
import isLeapYear from 'dayjs/plugin/isLeapYear';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
|
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
|
||||||
import { reactive } from '@vue/reactivity';
|
import { reactive } from '@vue/reactivity';
|
||||||
import { watch } from '../utils/watchReactivity';
|
import { watch } from '../utils/watchReactivity';
|
||||||
import { LIST_ITEM_EXP, LIST_ITEM_INDEX_EXP } from '../constants';
|
import { LIST_ITEM_EXP, LIST_ITEM_INDEX_EXP } from '../constants';
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
dayjs.extend(isLeapYear);
|
||||||
|
dayjs.extend(LocalizedFormat);
|
||||||
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
type ExpChunk = {
|
type ExpChunk = {
|
||||||
expression: string;
|
expression: string;
|
||||||
|
@ -32,6 +32,14 @@ const useFetchTrait: TraitImplementation<Static<typeof FetchTraitPropertiesSchem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mergeState({
|
||||||
|
fetch: {
|
||||||
|
loading: true,
|
||||||
|
data: undefined,
|
||||||
|
error: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// fetch data
|
// fetch data
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method,
|
method,
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { CSSProperties } from 'react';
|
|
||||||
import { createTrait } from '@meta-ui/core';
|
import { createTrait } from '@meta-ui/core';
|
||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
import { TraitImplementation } from 'src/types/RuntimeSchema';
|
import { TraitImplementation } from 'src/types/RuntimeSchema';
|
||||||
|
|
||||||
const useHiddenTrait: TraitImplementation<Static<typeof PropsSchema>> = ({ hidden }) => {
|
const useHiddenTrait: TraitImplementation<Static<typeof PropsSchema>> = ({ hidden }) => {
|
||||||
const style: CSSProperties = {};
|
|
||||||
if (hidden) {
|
|
||||||
style.display = 'none';
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
style,
|
customStyle: {
|
||||||
|
content: hidden ? 'display: none' : '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -2,19 +2,24 @@ import { createTrait } from '@meta-ui/core';
|
|||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
import { TraitImplementation } from 'src/types/RuntimeSchema';
|
import { TraitImplementation } from 'src/types/RuntimeSchema';
|
||||||
|
|
||||||
const StyleTrait: TraitImplementation<{
|
const StyleTrait: TraitImplementation<Static<typeof PropsSchema>> = ({
|
||||||
style: Static<typeof PropsSchema>;
|
styleSlot,
|
||||||
}> = ({ style }) => {
|
style,
|
||||||
|
}) => {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
style: style,
|
customStyle: {
|
||||||
|
[styleSlot]: style,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const PropsSchema = Type.Object({
|
const PropsSchema = Type.Object({
|
||||||
string: Type.Object(Type.String()),
|
styleSlot: Type.String(),
|
||||||
|
style: Type.String(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...createTrait({
|
...createTrait({
|
||||||
version: 'core/v1',
|
version: 'core/v1',
|
||||||
|
@ -74,7 +74,7 @@ export type ComponentImplementationProps = ImplWrapperProps &
|
|||||||
export type TraitResult = {
|
export type TraitResult = {
|
||||||
props: {
|
props: {
|
||||||
data?: unknown;
|
data?: unknown;
|
||||||
style?: Record<string, any>;
|
customStyle?: Record<string, string>;
|
||||||
callbackMap?: CallbackMap;
|
callbackMap?: CallbackMap;
|
||||||
effects?: Array<() => void>;
|
effects?: Array<() => void>;
|
||||||
} | null;
|
} | null;
|
||||||
|
Loading…
Reference in New Issue
Block a user