mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-11 17:37:40 +08:00
commit
24e7b87c89
@ -5,21 +5,22 @@ import { Type, Static } from '@sinclair/typebox';
|
||||
import { FALLBACK_METADATA, getComponentProps } from '../sunmao-helper';
|
||||
import { TabsPropsSpec as BaseTabsPropsSpec } from '../generated/types/Tabs';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
const TabsPropsSpec = Type.Object(BaseTabsPropsSpec);
|
||||
const TabsStateSpec = Type.Object({
|
||||
activeTab: Type.String(),
|
||||
activeTab: Type.Number(),
|
||||
});
|
||||
const TabPane = BaseTabs.TabPane;
|
||||
|
||||
const exampleProperties: Static<typeof TabsPropsSpec> = {
|
||||
type: 'line',
|
||||
defaultActiveTab: '0',
|
||||
defaultActiveTab: 0,
|
||||
tabPosition: 'top',
|
||||
size: 'default',
|
||||
tabNames: ['Tab1', 'Tab2', 'Tab3'],
|
||||
};
|
||||
|
||||
const options = {
|
||||
export const Tabs = implementRuntimeComponent({
|
||||
version: 'arco/v1',
|
||||
metadata: {
|
||||
...FALLBACK_METADATA,
|
||||
@ -33,18 +34,24 @@ const options = {
|
||||
spec: {
|
||||
properties: TabsPropsSpec,
|
||||
state: TabsStateSpec,
|
||||
methods: {},
|
||||
methods: {
|
||||
setActiveTab: Type.Object({
|
||||
activeTab: Type.Number(),
|
||||
}),
|
||||
},
|
||||
slots: ['content'],
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
};
|
||||
|
||||
export const Tabs = implementRuntimeComponent(options)(props => {
|
||||
})(props => {
|
||||
const { defaultActiveTab, tabNames, ...cProps } = getComponentProps(props);
|
||||
const { getElement, customStyle, mergeState, slotsElements } = props;
|
||||
const { getElement, customStyle, mergeState, subscribeMethods, slotsElements } = props;
|
||||
const ref = useRef<{ current: HTMLDivElement }>(null);
|
||||
const [activeTab, setActiveTab] = useState<string>(String(defaultActiveTab));
|
||||
const [activeTab, setActiveTab] = useState<number>(defaultActiveTab ?? 0);
|
||||
|
||||
useEffect(() => {
|
||||
mergeState({ activeTab: defaultActiveTab });
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const ele = ref.current?.current;
|
||||
@ -57,19 +64,28 @@ export const Tabs = implementRuntimeComponent(options)(props => {
|
||||
? slotsElements.content
|
||||
: [slotsElements.content];
|
||||
|
||||
useEffect(() => {
|
||||
subscribeMethods({
|
||||
setActiveTab: ({ activeTab }) => {
|
||||
setActiveTab(activeTab);
|
||||
mergeState({ activeTab });
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<BaseTabs
|
||||
className={css(customStyle?.content)}
|
||||
onChange={key => {
|
||||
setActiveTab(key);
|
||||
mergeState({ activeTab: key });
|
||||
setActiveTab(Number(key));
|
||||
mergeState({ activeTab: Number(key) });
|
||||
}}
|
||||
{...cProps}
|
||||
activeTab={activeTab}
|
||||
activeTab={String(activeTab)}
|
||||
ref={ref}
|
||||
>
|
||||
{tabNames.map((tabName, idx) => (
|
||||
<TabPane key={String(idx)} title={tabName}>
|
||||
<TabPane key={idx} title={tabName}>
|
||||
{slots[idx]}
|
||||
</TabPane>
|
||||
))}
|
||||
|
@ -3,8 +3,8 @@ import { StringUnion } from '../../sunmao-helper';
|
||||
import { Category } from '../../constants/category';
|
||||
|
||||
export const TabsPropsSpec = {
|
||||
defaultActiveTab: Type.String({
|
||||
title: 'Default Active Tab Index',
|
||||
defaultActiveTab: Type.Number({
|
||||
title: 'Default Active Tab',
|
||||
category: Category.Basic,
|
||||
description: 'The index of default active Tab. Start with 0.',
|
||||
}),
|
||||
|
@ -114,10 +114,7 @@ export const Editor: React.FC<Props> = observer(
|
||||
const appComponent = useMemo(() => {
|
||||
return isDisplayApp ? (
|
||||
<ErrorBoundary>
|
||||
<App
|
||||
options={app}
|
||||
gridCallbacks={gridCallbacks}
|
||||
/>
|
||||
<App options={app} gridCallbacks={gridCallbacks} />
|
||||
</ErrorBoundary>
|
||||
) : null;
|
||||
}, [App, app, gridCallbacks, isDisplayApp]);
|
||||
@ -198,7 +195,7 @@ export const Editor: React.FC<Props> = observer(
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
textAlign="left"
|
||||
lazyBehavior='keepMounted'
|
||||
lazyBehavior="keepMounted"
|
||||
isLazy
|
||||
index={explorerMenuTab}
|
||||
onChange={activatedTab => {
|
||||
@ -211,11 +208,11 @@ export const Editor: React.FC<Props> = observer(
|
||||
<Tab>Data</Tab>
|
||||
<Tab>State</Tab>
|
||||
</TabList>
|
||||
<TabPanels flex="1" overflow="auto">
|
||||
<TabPanel p={0}>
|
||||
<TabPanels overflow='hidden' height="full" flex="1">
|
||||
<TabPanel height="full" overflow="auto" p={0}>
|
||||
<Explorer services={services} />
|
||||
</TabPanel>
|
||||
<TabPanel p={0}>
|
||||
<TabPanel height="full" overflow="auto" p={0}>
|
||||
<StructureTree
|
||||
components={components}
|
||||
selectedComponentId={selectedComponentId}
|
||||
@ -225,10 +222,10 @@ export const Editor: React.FC<Props> = observer(
|
||||
services={services}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel p={0}>
|
||||
<TabPanel height="full" overflow="auto" p={0}>
|
||||
<DataSource active={activeDataSource?.id ?? ''} services={services} />
|
||||
</TabPanel>
|
||||
<TabPanel p={0} height="100%">
|
||||
<TabPanel overflow="auto" p={0} height="100%">
|
||||
<StateViewer store={stateStore} />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
|
@ -51,11 +51,14 @@ export const StructureTree: React.FC<Props> = props => {
|
||||
useEffect(() => {
|
||||
wrapperRef.current
|
||||
?.querySelector(`#tree-item-${selectedComponentId}`)
|
||||
?.scrollIntoView();
|
||||
?.scrollIntoView({
|
||||
behavior:'smooth',
|
||||
block:'center'
|
||||
});
|
||||
}, [selectedComponentId]);
|
||||
|
||||
return (
|
||||
<VStack ref={wrapperRef} spacing="2" padding="4" alignItems="start" overflow="auto">
|
||||
<VStack ref={wrapperRef} height='full' spacing="2" padding="4" alignItems="start" overflowX='hidden' overflowY="auto">
|
||||
<Text fontSize="lg" fontWeight="bold" mb="0.5rem">
|
||||
Components
|
||||
</Text>
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
CORE_VERSION,
|
||||
CoreComponentName,
|
||||
} from '@sunmao-ui/shared';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
type EditingTarget = {
|
||||
kind: 'app' | 'module';
|
||||
@ -77,7 +78,12 @@ export class EditorStore {
|
||||
// when switch app or module, components should refresh
|
||||
reaction(
|
||||
() => this.currentEditingTarget,
|
||||
target => {
|
||||
(target, prevTarget) => {
|
||||
|
||||
if (isEqual(prevTarget, target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.name) {
|
||||
this.setCurrentComponentsVersion(0);
|
||||
this.setLastSavedComponentsVersion(0);
|
||||
@ -175,7 +181,7 @@ export class EditorStore {
|
||||
}
|
||||
|
||||
get activeDataSource(): ComponentSchema | null {
|
||||
return this.components.find((component)=> component.id === this.activeDataSourceId) || null;
|
||||
return this.components.find((component) => component.id === this.activeDataSourceId) || null;
|
||||
}
|
||||
|
||||
get activeDataSourceType(): DataSourceType | null {
|
||||
|
Loading…
Reference in New Issue
Block a user