1
0
mirror of synced 2026-03-23 02:58:34 +08:00

feat(vue-components,react-components): 增加点击事件,使用组件状态hook

This commit is contained in:
roymondchen
2025-03-06 20:29:38 +08:00
parent 8d0040da53
commit 0736646c63
60 changed files with 594 additions and 378 deletions

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-button",
"type": "module",
"main": "src/index.ts",
@@ -14,16 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -18,8 +18,9 @@
import React from 'react';
import type { Id, MComponent } from '@tmagic/core';
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent } from '@tmagic/schema';
interface ButtonSchema extends Omit<MComponent, 'id'> {
id?: Id;
@@ -35,6 +36,7 @@ interface ButtonProps {
containerIndex: number;
iteratorIndex?: number[];
iteratorContainerId?: Id[];
onClick: any;
}
const Page: React.FC<ButtonProps> = ({
@@ -46,10 +48,16 @@ const Page: React.FC<ButtonProps> = ({
iteratorIndex,
iteratorContainerId,
}) => {
const { app } = useApp({ config, iteratorIndex, iteratorContainerId });
const { app, node } = useApp({ config, iteratorIndex, iteratorContainerId });
if (!app) return null;
const clickHandler = () => {
if (node && app) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
};
return (
<button
className={className}
@@ -58,6 +66,7 @@ const Page: React.FC<ButtonProps> = ({
data-tmagic-container-index={containerIndex}
data-tmagic-iterator-index={iteratorIndex}
data-tmagic-iterator-container-id={iteratorContainerId}
onClick={clickHandler}
>
{config.text || ''}
</button>

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-container",
"type": "module",
"main": "src/index.ts",
@@ -14,17 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/utils": "workspace:^",
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -0,0 +1,66 @@
/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useContext } from 'react';
import type TMagicApp from '@tmagic/core';
import type { Id, MComponent } from '@tmagic/core';
import { IS_DSL_NODE_KEY } from '@tmagic/core';
import { AppContent, useComponentStatus, useNode } from '@tmagic/react-runtime-help';
interface ComponentProps {
config: Omit<MComponent, 'id'>;
index: number;
iteratorIndex: number[];
iteratorContainerId: Id[];
}
const Container: React.FC<ComponentProps> = (props) => {
const app: TMagicApp | undefined = useContext(AppContent);
const node = useNode(props);
const MagicUiComp = app?.resolveComponent(props.config.type || 'container');
if (!MagicUiComp) return null;
if (typeof props.config.display === 'function' && props.config.display({ app, node }) === false) {
return null;
}
const { style, className } = useComponentStatus(props);
return (
<MagicUiComp
data-tmagic-id={`${props.config.id || ''}`}
data-container-index={props.index}
data-tmagic-iterator-index={props.iteratorIndex}
data-tmagic-iterator-container-id={props.iteratorContainerId}
containerIndex={props.index}
iteratorIndex={props.iteratorIndex}
iteratorContainerId={props.iteratorContainerId}
key={props.config.id ?? props.index}
config={{ ...props.config, [IS_DSL_NODE_KEY]: true }}
className={className}
style={style}
></MagicUiComp>
);
};
Container.displayName = 'magic-ui-container-item';
export default Container;

View File

@@ -18,9 +18,11 @@
import React from 'react';
import type { Id, MContainer, MNode } from '@tmagic/core';
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MContainer, MNode } from '@tmagic/schema';
import { IS_DSL_NODE_KEY } from '@tmagic/utils';
import Component from './Component';
interface ContainerSchema extends Omit<MContainer, 'id'> {
id?: Id;
@@ -28,71 +30,53 @@ interface ContainerSchema extends Omit<MContainer, 'id'> {
}
interface ContainerProps {
id?: Id;
config: ContainerSchema;
className: string;
style: Record<string, any>;
id: string;
containerIndex: number;
iteratorIndex: number[];
iteratorContainerId: Id[];
}
const Container: React.FC<ContainerProps> = ({
config,
id,
style,
config,
className,
containerIndex,
style,
iteratorIndex,
iteratorContainerId,
}) => {
const { app, display } = useApp({ config });
const { app, node } = useApp({ config });
if (!app) return null;
const classNames = config[IS_DSL_NODE_KEY] ? [] : ['magic-ui-container'];
if (config.layout) {
classNames.push(`magic-layout-${config.layout}`);
}
if (className) {
classNames.push(className);
}
const clickHandler = () => {
if (node && app) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
};
return (
<div
data-tmagic-id={`${id || ''}`}
data-tmagic-id={`${id || config.id || ''}`}
data-container-index={containerIndex}
data-tmagic-iterator-index={iteratorIndex}
data-tmagic-iterator-container-id={iteratorContainerId}
className={classNames.join(' ')}
style={config[IS_DSL_NODE_KEY] ? style : app.transformStyle(config.style || {})}
className={className}
style={style}
onClick={clickHandler}
>
{config.items?.map((item: MNode, index: number) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const MagicUiComp = app.resolveComponent(item.type || 'container');
if (!MagicUiComp) return null;
if (!display(item)) return null;
const itemClassName = [`magic-ui-${item.type}`];
if (item.className) {
itemClassName.push(item.className);
}
return (
<MagicUiComp
id={`${item.id || ''}`}
containerIndex={index}
iteratorIndex={iteratorIndex}
iteratorContainerId={iteratorContainerId}
key={item.id ?? index}
config={{ ...item, [IS_DSL_NODE_KEY]: true }}
className={itemClassName.join(' ')}
style={app.transformStyle(item.style || {})}
></MagicUiComp>
);
})}
{config.items?.map((item: MNode, index: number) => (
<Component
key={item.id ?? index}
config={item}
index={index}
iteratorIndex={iteratorIndex}
iteratorContainerId={iteratorContainerId}
/>
))}
</div>
);
};

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};

View File

@@ -16,7 +16,7 @@
* limitations under the License.
*/
import { getElById } from '@tmagic/utils';
import { getElById } from '@tmagic/core';
export default [
{

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.3",
"version": "0.1.0",
"name": "@tmagic/react-img",
"type": "module",
"main": "src/index.ts",
@@ -14,16 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -18,8 +18,8 @@
import React from 'react';
import type { Id, MComponent } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent } from '@tmagic/schema';
interface ImgSchema extends Omit<MComponent, 'id'> {
id?: Id;

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-iterator-container",
"type": "module",
"main": "src/index.ts",
@@ -14,17 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/utils": "workspace:^",
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -1,8 +1,13 @@
import React from 'react';
import type { IteratorContainer as TMagicIteratorContainer } from '@tmagic/core';
import {
COMMON_EVENT_PREFIX,
type Id,
type IteratorContainer as TMagicIteratorContainer,
type MIteratorContainer,
type MNode,
} from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MIteratorContainer, MNode } from '@tmagic/schema';
interface IteratorContainerSchema extends Omit<MIteratorContainer, 'id'> {
id?: Id;
@@ -36,7 +41,7 @@ const IteratorContainer: React.FC<IteratorContainerProps> = ({
iteratorIndex,
iteratorContainerId,
}) => {
const { app } = useApp({ config, iteratorIndex, iteratorContainerId });
const { app, node } = useApp({ config, iteratorIndex, iteratorContainerId });
let { iteratorData = [] } = config;
const { itemConfig, dsField, items } = config;
@@ -81,6 +86,12 @@ const IteratorContainer: React.FC<IteratorContainerProps> = ({
};
});
const clickHandler = () => {
if (node && app) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
};
return (
<div
className={className}
@@ -89,6 +100,7 @@ const IteratorContainer: React.FC<IteratorContainerProps> = ({
data-container-index={containerIndex}
data-iterator-index={iteratorIndex}
data-iterator-container-id={iteratorContainerId}
onClick={clickHandler}
>
{configs.map((config: any, index: number) => (
<MagicUiComp

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};

View File

@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NODE_CONDS_KEY } from '@tmagic/schema';
import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX } from '@tmagic/utils';
import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, NODE_CONDS_KEY } from '@tmagic/core';
export default [
{

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-overlay",
"type": "module",
"main": "src/index.ts",
@@ -14,16 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -18,8 +18,8 @@
import React, { useEffect, useState } from 'react';
import { type Id, IS_DSL_NODE_KEY, type MComponent, type MContainer, type MNode, type MPage } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
interface OverlayProps {
config: MComponent;
@@ -93,11 +93,11 @@ const Overlay: React.FC<OverlayProps> = ({
return (
<MagicUiComp
id={id}
data-tmagic-id={`${id || config.id || ''}`}
containerIndex={containerIndex}
iteratorIndex={iteratorIndex}
iteratorContainerId={iteratorContainerId}
config={config}
config={{ ...config, [IS_DSL_NODE_KEY]: false }}
className={className}
style={style}
></MagicUiComp>

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-page-fragment-container",
"type": "module",
"main": "src/index.ts",
@@ -14,16 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { type Id, IS_DSL_NODE_KEY, type MComponent, type MNode } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent, MNode } from '@tmagic/schema';
interface PageFragmentContainerProps {
config: MComponent;
@@ -59,14 +59,14 @@ const PageFragmentContainer: React.FC<PageFragmentContainerProps> = ({
return (
<div
data-tmagic-id={`${id || ''}`}
data-tmagic-id={`${id || config.id || ''}`}
data-container-index={containerIndex}
data-tmagic-iterator-index={iteratorIndex}
data-tmagic-iterator-container-id={iteratorContainerId}
className={classNames.join(' ')}
style={style}
>
<MagicUiContainer config={containerConfig}></MagicUiContainer>
<MagicUiContainer config={{ ...containerConfig, [IS_DSL_NODE_KEY]: false }}></MagicUiContainer>
</div>
);
};

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-page-fragment",
"type": "module",
"main": "src/index.ts",
@@ -14,17 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/utils": "workspace:^",
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { IS_DSL_NODE_KEY, type MPageFragment } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { MPageFragment } from '@tmagic/schema';
interface PageFragmentProps {
config: MPageFragment;
@@ -21,7 +21,13 @@ const PageFragment: React.FC<PageFragmentProps> = ({ config }) => {
classNames.push(config.className);
}
return <MagicUiComp config={config} id={config.id} className={classNames.join(' ')}></MagicUiComp>;
return (
<MagicUiComp
config={{ ...config, [IS_DSL_NODE_KEY]: false }}
id={config.id}
className={classNames.join(' ')}
></MagicUiComp>
);
};
PageFragment.displayName = 'magic-ui-page-fragment';

View File

@@ -16,7 +16,7 @@
* limitations under the License.
*/
import { getElById } from '@tmagic/utils';
import { getElById } from '@tmagic/core';
export default [
{

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-page",
"type": "module",
"main": "src/index.ts",
@@ -14,17 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/utils": "workspace:^",
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -18,8 +18,9 @@
import React from 'react';
import { useApp } from '@tmagic/react-runtime-help';
import type { MPage } from '@tmagic/schema';
import type { MPage } from '@tmagic/core';
import { IS_DSL_NODE_KEY } from '@tmagic/core';
import { useApp, useComponentStatus } from '@tmagic/react-runtime-help';
interface PageProps {
config: MPage;
@@ -27,7 +28,7 @@ interface PageProps {
const Page: React.FC<PageProps> = ({ config }) => {
const { app } = useApp({
config,
config: { ...config, [IS_DSL_NODE_KEY]: true },
methods: {
refresh: () => window.location.reload(),
},
@@ -37,12 +38,16 @@ const Page: React.FC<PageProps> = ({ config }) => {
const MagicUiComp = app.resolveComponent('container');
const classNames = ['magic-ui-page'];
if (config.className) {
classNames.push(config.className);
}
const { style, className } = useComponentStatus({ config });
return <MagicUiComp config={config} id={config.id} className={classNames.join(' ')}></MagicUiComp>;
return (
<MagicUiComp
config={{ ...config, [IS_DSL_NODE_KEY]: false }}
id={config.id}
className={className}
style={style}
></MagicUiComp>
);
};
Page.displayName = 'magic-ui-page';

View File

@@ -16,7 +16,7 @@
* limitations under the License.
*/
import { getElById } from '@tmagic/utils';
import { getElById } from '@tmagic/core';
export default [
{

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-qrcode",
"type": "module",
"main": "src/index.ts",
@@ -17,16 +17,13 @@
"qrcode": "^1.5.0"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -19,6 +19,7 @@
import React, { useEffect, useState } from 'react';
import QRCode from 'qrcode';
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent } from '@tmagic/schema';
@@ -47,7 +48,7 @@ const QrCode: React.FC<QrCodeProps> = ({
iteratorIndex,
iteratorContainerId,
}) => {
const { app } = useApp({ config });
const { app, node } = useApp({ config });
if (!app) return null;
@@ -60,6 +61,12 @@ const QrCode: React.FC<QrCodeProps> = ({
});
}, [config.url]);
const clickHandler = () => {
if (node && app) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
};
return (
<img
className={className}
@@ -69,6 +76,7 @@ const QrCode: React.FC<QrCodeProps> = ({
data-tmagic-iterator-index={iteratorIndex}
data-tmagic-iterator-container-id={iteratorContainerId}
src={imgSrc}
onClick={clickHandler}
/>
);
};

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.2",
"version": "0.1.0",
"name": "@tmagic/react-text",
"type": "module",
"main": "src/index.ts",
@@ -14,16 +14,13 @@
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"peerDependencies": {
"@tmagic/schema": "workspace:^",
"@tmagic/core": "workspace:^",
"@tmagic/react-runtime-help": "workspace:^",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"typescript": {
"optional": true
}

View File

@@ -18,8 +18,9 @@
import React from 'react';
import type { Id, MComponent } from '@tmagic/core';
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
import { useApp } from '@tmagic/react-runtime-help';
import type { Id, MComponent } from '@tmagic/schema';
interface TextSchema extends Omit<MComponent, 'id'> {
id?: Id;
@@ -46,18 +47,25 @@ const Text: React.FC<TextProps> = ({
iteratorIndex,
iteratorContainerId,
}) => {
const { app } = useApp({ config, iteratorIndex, iteratorContainerId });
const { app, node } = useApp({ config, iteratorIndex, iteratorContainerId });
if (!app) return null;
const clickHandler = () => {
if (node && app) {
app.emit(`${COMMON_EVENT_PREFIX}click`, node);
}
};
return (
<p
className={className}
style={style}
data-tmagic-id={id}
data-tmagic-id={`${id || config.id || ''}`}
data-tmagic-container-index={containerIndex}
data-tmagic-iterator-index={iteratorIndex}
data-tmagic-iterator-container-id={iteratorContainerId}
onClick={clickHandler}
>
{config.text}
</p>

View File

@@ -1,4 +1,6 @@
import { COMMON_EVENT_PREFIX } from '@tmagic/core';
export default {
methods: [],
events: [],
events: [{ label: '点击', value: `${COMMON_EVENT_PREFIX}click` }],
};