mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-17 17:40:31 +08:00
add ref to chakra-ui components
This commit is contained in:
parent
cb3d7e9dd2
commit
f40c42fa8a
@ -295,7 +295,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ customStyle, slotsElements, ...restProps }) => {
|
||||
})(({ customStyle, slotsElements, $ref, ...restProps }) => {
|
||||
const styleProps = pick(restProps, StyleProps);
|
||||
return (
|
||||
<BaseBox
|
||||
@ -309,6 +309,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
{slotsElements.content}
|
||||
</BaseBox>
|
||||
|
@ -80,6 +80,7 @@ export default implementRuntimeComponent({
|
||||
colorScheme,
|
||||
mergeState,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
const groupContext = useCheckboxGroupContext();
|
||||
let _defaultIsChecked = false;
|
||||
@ -133,6 +134,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<Text value={text} />
|
||||
</BaseCheckbox>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Type } from '@sinclair/typebox';
|
||||
import { CheckboxGroup as BaseCheckboxGroup } from '@chakra-ui/react';
|
||||
import { Box, CheckboxGroup as BaseCheckboxGroup } from '@chakra-ui/react';
|
||||
import { implementRuntimeComponent } from '@sunmao-ui/runtime';
|
||||
import { SizePropertySchema, IsDisabledSchema } from './Checkbox';
|
||||
|
||||
@ -40,20 +40,22 @@ export default implementRuntimeComponent({
|
||||
styleSlots: [],
|
||||
events: [],
|
||||
},
|
||||
})(({ size, defaultValue, isDisabled, slotsElements, mergeState }) => {
|
||||
})(({ size, defaultValue, isDisabled, slotsElements, mergeState, $ref }) => {
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
useEffect(() => {
|
||||
mergeState({ value });
|
||||
}, [mergeState, value]);
|
||||
|
||||
return (
|
||||
<BaseCheckboxGroup
|
||||
size={size}
|
||||
defaultValue={defaultValue}
|
||||
isDisabled={isDisabled}
|
||||
onChange={val => setValue(val)}
|
||||
>
|
||||
{slotsElements.content}
|
||||
</BaseCheckboxGroup>
|
||||
<Box ref={$ref}>
|
||||
<BaseCheckboxGroup
|
||||
size={size}
|
||||
defaultValue={defaultValue}
|
||||
isDisabled={isDisabled}
|
||||
onChange={val => setValue(val)}
|
||||
>
|
||||
{slotsElements.content}
|
||||
</BaseCheckboxGroup>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
|
@ -75,6 +75,7 @@ export default implementRuntimeComponent({
|
||||
colorScheme: 'blue',
|
||||
},
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [title, setTitle] = useState(customerTitle || '');
|
||||
@ -129,6 +130,7 @@ export default implementRuntimeComponent({
|
||||
<AlertDialogContent
|
||||
className={`${customStyle?.content}`}
|
||||
{...(containerRef.current ? dialogContentProps : {})}
|
||||
ref={$ref}
|
||||
>
|
||||
<AlertDialogHeader>{title}</AlertDialogHeader>
|
||||
<AlertDialogBody>{slotsElements.content}</AlertDialogBody>
|
||||
|
@ -25,12 +25,13 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ customStyle }) => {
|
||||
})(({ customStyle, $ref }) => {
|
||||
return (
|
||||
<Divider
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -48,6 +48,7 @@ export default implementRuntimeComponent({
|
||||
slotsElements,
|
||||
childrenMap,
|
||||
component,
|
||||
$ref,
|
||||
}) => {
|
||||
const [invalidArray, setInvalidArray] = useState<boolean[]>([]);
|
||||
const [isFormInvalid, setIsFormInvalid] = useState<boolean>(false);
|
||||
@ -151,6 +152,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
{slotsElements.content}
|
||||
{hideSubmit ? undefined : (
|
||||
|
@ -69,6 +69,7 @@ export default implementRuntimeComponent({
|
||||
slotsElements,
|
||||
childrenMap,
|
||||
component,
|
||||
$ref,
|
||||
}) => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
// don't show Invalid state on component mount
|
||||
@ -147,6 +148,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<HStack width="full">
|
||||
<FormLabel flex="0 0 auto" width="33%" margin="auto 0">
|
||||
|
@ -129,6 +129,7 @@ export default implementRuntimeComponent({
|
||||
crossOrigin,
|
||||
callbackMap,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
const style = boxSize
|
||||
? css`
|
||||
@ -154,6 +155,7 @@ export default implementRuntimeComponent({
|
||||
ignoreFallback={ignoreFallback}
|
||||
borderRadius={borderRadius}
|
||||
fallbackSrc={fallbackSrc}
|
||||
ref={$ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ text, mergeState, customStyle }) => {
|
||||
})(({ text, mergeState, customStyle, $ref }) => {
|
||||
useEffect(() => {
|
||||
mergeState({ value: text.raw });
|
||||
}, [mergeState, text.raw]);
|
||||
@ -49,6 +49,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<Text value={text} />
|
||||
</BaseKbd>
|
||||
|
@ -37,7 +37,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ text, href, isExternal, customStyle }) => {
|
||||
})(({ text, href, isExternal, customStyle, $ref }) => {
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
@ -46,6 +46,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<Text value={text} />
|
||||
</Link>
|
||||
|
@ -56,7 +56,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ listData, template, app, services, customStyle }) => {
|
||||
})(({ listData, template, app, services, customStyle, $ref }) => {
|
||||
if (!listData) {
|
||||
return null;
|
||||
}
|
||||
@ -88,6 +88,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
{listItems}
|
||||
</BaseList>
|
||||
|
@ -96,6 +96,7 @@ export default implementRuntimeComponent({
|
||||
variant,
|
||||
mergeState,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
const newValue = (defaultValue || []).map(o => o.value);
|
||||
@ -113,6 +114,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<BaseMultiSelect
|
||||
isMulti
|
||||
|
@ -86,6 +86,7 @@ export default implementRuntimeComponent({
|
||||
mergeState,
|
||||
subscribeMethods,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
const onChange = (_: string, valueAsNumber: number) => setValue(valueAsNumber || 0);
|
||||
@ -125,6 +126,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<NumberInputField />
|
||||
<NumberInputStepper>
|
||||
|
@ -74,6 +74,7 @@ export default implementRuntimeComponent({
|
||||
colorScheme,
|
||||
mergeState,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
mergeState({ value: text.raw });
|
||||
@ -99,6 +100,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
<Text value={text} />
|
||||
</BaseRadio>
|
||||
|
@ -38,7 +38,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ defaultValue, isNumerical, slotsElements, mergeState, customStyle }) => {
|
||||
})(({ defaultValue, isNumerical, slotsElements, mergeState, customStyle, $ref }) => {
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
|
||||
useEffect(() => {
|
||||
@ -56,6 +56,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
{slotsElements.content}
|
||||
</BaseRadioGroup>
|
||||
|
@ -24,7 +24,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: [],
|
||||
events: [],
|
||||
},
|
||||
})(({ slotsElements }) => {
|
||||
})(({ slotsElements, $ref }) => {
|
||||
return (
|
||||
<ChakraProvider
|
||||
theme={extendTheme({
|
||||
@ -32,7 +32,7 @@ export default implementRuntimeComponent({
|
||||
useSystemColorMode: false,
|
||||
})}
|
||||
>
|
||||
<>{slotsElements.root}</>
|
||||
<div ref={$ref}>{slotsElements.root}</div>
|
||||
</ChakraProvider>
|
||||
);
|
||||
});
|
||||
|
@ -95,6 +95,7 @@ export default implementRuntimeComponent({
|
||||
variant,
|
||||
mergeState,
|
||||
customStyle,
|
||||
$ref,
|
||||
}) => {
|
||||
const [value, setValue] = useState<string | undefined>(defaultValue);
|
||||
|
||||
@ -123,6 +124,7 @@ export default implementRuntimeComponent({
|
||||
className={css`
|
||||
${customStyle?.content}
|
||||
`}
|
||||
ref={$ref}
|
||||
>
|
||||
{options.map(opt => (
|
||||
<option key={opt.value} value={opt.value}>
|
||||
|
@ -70,9 +70,9 @@ export default implementRuntimeComponent({
|
||||
styleSlots: [],
|
||||
events: [],
|
||||
},
|
||||
})(({ direction, wrap, align, justify, spacing, slotsElements }) => {
|
||||
})(({ direction, wrap, align, justify, spacing, slotsElements, $ref }) => {
|
||||
return (
|
||||
<BaseStack {...{ direction, wrap, align, justify, spacing }}>
|
||||
<BaseStack {...{ direction, wrap, align, justify, spacing }} ref={$ref}>
|
||||
{slotsElements.content}
|
||||
</BaseStack>
|
||||
);
|
||||
|
@ -32,6 +32,7 @@ export const TableImpl = implementTable(
|
||||
mergeState,
|
||||
services,
|
||||
app,
|
||||
$ref,
|
||||
}) => {
|
||||
const [selectedItem, setSelectedItem] = useState<Record<string, any> | undefined>();
|
||||
const [selectedItems, setSelectedItems] = useState<Array<Record<string, any>>>([]);
|
||||
@ -86,7 +87,7 @@ export const TableImpl = implementTable(
|
||||
let newSelectedItems;
|
||||
if (isItemSelected(item)) {
|
||||
newSelectedItems = selectedItems.filter(
|
||||
selectedItem => selectedItem[majorKey] != item[majorKey]
|
||||
selectedItem => selectedItem[majorKey] !== item[majorKey]
|
||||
);
|
||||
} else {
|
||||
newSelectedItems = selectedItems.concat(item);
|
||||
@ -115,7 +116,7 @@ export const TableImpl = implementTable(
|
||||
isIndeterminate={isIndeterminate}
|
||||
checked={isAllChecked}
|
||||
onChange={onChange}
|
||||
></Checkbox>
|
||||
/>
|
||||
</Th>
|
||||
);
|
||||
}, [data, isMultiSelect, selectedItems.length, updateSelectedItems]);
|
||||
@ -169,7 +170,7 @@ export const TableImpl = implementTable(
|
||||
key="$checkbox"
|
||||
onClick={onClickCheckbox}
|
||||
>
|
||||
<Checkbox size="lg" isChecked={isSelected}></Checkbox>
|
||||
<Checkbox size="lg" isChecked={isSelected} />
|
||||
</Td>
|
||||
);
|
||||
|
||||
@ -222,6 +223,7 @@ export const TableImpl = implementTable(
|
||||
borderColor="gray.200"
|
||||
borderRadius="base"
|
||||
overflow="auto"
|
||||
ref={$ref}
|
||||
>
|
||||
{!data ? loadingSpinner : tableContent}
|
||||
</Box>
|
||||
|
@ -47,7 +47,7 @@ export default implementRuntimeComponent({
|
||||
events: [],
|
||||
},
|
||||
})(props => {
|
||||
const { tabNames, mergeState, initialSelectedTabIndex, customStyle, slotsElements } =
|
||||
const { tabNames, mergeState, initialSelectedTabIndex, customStyle, slotsElements, $ref } =
|
||||
props;
|
||||
const [selectedTabIndex, setSelectedTabIndex] = useState(initialSelectedTabIndex ?? 0);
|
||||
|
||||
@ -62,6 +62,7 @@ export default implementRuntimeComponent({
|
||||
<BaseTabs
|
||||
defaultIndex={initialSelectedTabIndex}
|
||||
onChange={idx => setSelectedTabIndex(idx)}
|
||||
ref={$ref}
|
||||
>
|
||||
<TabList>
|
||||
{tabNames.map((name, idx) => (
|
||||
|
@ -68,6 +68,7 @@ export default implementRuntimeComponent({
|
||||
isDisabled,
|
||||
defaultIsOpen,
|
||||
slotsElements,
|
||||
$ref,
|
||||
}) => {
|
||||
return (
|
||||
/*
|
||||
@ -82,6 +83,7 @@ export default implementRuntimeComponent({
|
||||
isDisabled={isDisabled}
|
||||
defaultIsOpen={defaultIsOpen}
|
||||
shouldWrapChildren={shouldWrapChildren}
|
||||
ref={$ref}
|
||||
>
|
||||
{slotsElements.content}
|
||||
</Tooltip>
|
||||
|
@ -124,8 +124,8 @@ export const EditorMask: React.FC<Props> = observer((props: Props) => {
|
||||
|
||||
const getMaskPosition = useCallback(
|
||||
(componentId: string) => {
|
||||
if (!wrapperRect.current) return;
|
||||
const rect = rects[componentId];
|
||||
if (!wrapperRect.current || !rect) return;
|
||||
return {
|
||||
id: componentId,
|
||||
style: {
|
||||
|
@ -8,10 +8,14 @@ import {
|
||||
RuntimeApplication,
|
||||
RuntimeComponentSchema,
|
||||
} from '@sunmao-ui/core';
|
||||
import { UIServices, ModuleSchema } from '../../types';
|
||||
import { ImplWrapper } from './ImplWrapper';
|
||||
import { watch } from '../../utils/watchReactivity';
|
||||
import { ImplementedRuntimeModule, EventHandlerSchema } from '../../types';
|
||||
import {
|
||||
ImplementedRuntimeModule,
|
||||
EventHandlerSchema,
|
||||
UIServices,
|
||||
ModuleSchema,
|
||||
} from '../../types';
|
||||
import { resolveChildrenMap } from '../../utils/resolveChildrenMap';
|
||||
|
||||
type Props = Static<typeof ModuleSchema> & {
|
||||
@ -20,19 +24,20 @@ type Props = Static<typeof ModuleSchema> & {
|
||||
app?: RuntimeApplication;
|
||||
};
|
||||
|
||||
export const ModuleRenderer: React.FC<Props> = props => {
|
||||
export const ModuleRenderer = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
|
||||
const { type, services } = props;
|
||||
try {
|
||||
const moduleSpec = services.registry.getModuleByType(type);
|
||||
return <ModuleRendererContent {...props} moduleSpec={moduleSpec} />;
|
||||
} catch {
|
||||
return <span>Cannot find Module {type}.</span>;
|
||||
return <div ref={ref}>Cannot find Module {type}.</div>;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const ModuleRendererContent: React.FC<
|
||||
const ModuleRendererContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
Props & { moduleSpec: ImplementedRuntimeModule }
|
||||
> = props => {
|
||||
>((props, ref) => {
|
||||
const { moduleSpec, properties, handlers, evalScope, services, app } = props;
|
||||
const moduleId = services.stateManager.maskedEval(props.id, true, evalScope) as string;
|
||||
|
||||
@ -159,8 +164,8 @@ const ModuleRendererContent: React.FC<
|
||||
});
|
||||
}, [evaledModuleTemplate, services, app]);
|
||||
|
||||
return <>{result}</>;
|
||||
};
|
||||
return <div ref={ref}>{result}</div>;
|
||||
});
|
||||
|
||||
function parseTypeComponents(
|
||||
c: Application['spec']['components'][0]
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
@ -17,14 +18,14 @@ export type TextProps = {
|
||||
cssStyle?: string;
|
||||
};
|
||||
|
||||
const Text: React.FC<TextProps> = ({ value, cssStyle }) => {
|
||||
const Text = React.forwardRef<HTMLDivElement, TextProps>(({ value, cssStyle }, ref) => {
|
||||
const text = typeof value.raw === 'string' ? value.raw : `${value.raw}`;
|
||||
if (value.format === 'md') {
|
||||
const Div = styled.div`
|
||||
${cssStyle}
|
||||
`;
|
||||
return (
|
||||
<Div>
|
||||
<Div ref={ref}>
|
||||
<ReactMarkdown>{text}</ReactMarkdown>
|
||||
</Div>
|
||||
);
|
||||
@ -34,7 +35,7 @@ const Text: React.FC<TextProps> = ({ value, cssStyle }) => {
|
||||
const Span = styled.span`
|
||||
${cssStyle}
|
||||
`;
|
||||
return <Span>{text}</Span>;
|
||||
};
|
||||
return <Span ref={ref}>{text}</Span>;
|
||||
});
|
||||
|
||||
export default Text;
|
||||
|
@ -27,7 +27,7 @@ export default implementRuntimeComponent({
|
||||
styleSlots: [],
|
||||
events: [],
|
||||
},
|
||||
})(({ id, type, properties, handlers, services, app }) => {
|
||||
})(({ id, type, properties, handlers, services, app, $ref }) => {
|
||||
if (!type) {
|
||||
return <span>Please choose a module to render.</span>;
|
||||
}
|
||||
@ -43,6 +43,7 @@ export default implementRuntimeComponent({
|
||||
handlers={handlers}
|
||||
services={services}
|
||||
app={app}
|
||||
ref={$ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -37,6 +37,6 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ value, customStyle }) => {
|
||||
return <_Text value={value} cssStyle={customStyle?.content} />;
|
||||
})(({ value, customStyle, $ref }) => {
|
||||
return <_Text value={value} cssStyle={customStyle?.content} ref={$ref} />;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user