mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-06 21:40:23 +08:00
Merge pull request #434 from webzard-io/feat/iframe
feat: add the iframe component
This commit is contained in:
commit
00c5f345da
@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react';
|
||||
import { EditorServices } from '../../types';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
@ -66,6 +66,26 @@ export const EditorMaskWrapper: React.FC<Props> = observer(props => {
|
||||
);
|
||||
};
|
||||
|
||||
const onClickIframe = useCallback(() => {
|
||||
if (document.activeElement?.tagName === 'IFRAME') {
|
||||
setSelectedComponentId(document.activeElement?.getAttribute('title') || '');
|
||||
setTimeout(() => {
|
||||
window.focus();
|
||||
});
|
||||
}
|
||||
}, [setSelectedComponentId]);
|
||||
|
||||
// can't capture the iframe click event
|
||||
// use window's blur event to detect whether clicking the iframes
|
||||
useEffect(() => {
|
||||
window.focus();
|
||||
window.addEventListener('blur', onClickIframe);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('blur', onClickIframe);
|
||||
};
|
||||
}, [onClickIframe]);
|
||||
|
||||
const mousePositionWithOffset: [number, number] = [
|
||||
mousePosition[0] + scrollOffset[0],
|
||||
mousePosition[1] + scrollOffset[1],
|
||||
|
118
packages/runtime/src/components/core/Iframe.tsx
Normal file
118
packages/runtime/src/components/core/Iframe.tsx
Normal file
@ -0,0 +1,118 @@
|
||||
import { implementRuntimeComponent } from '../../utils/buildKit';
|
||||
import { Type } from '@sinclair/typebox';
|
||||
import { CORE_VERSION, CoreComponentName, StringUnion } from '@sunmao-ui/shared';
|
||||
import { css } from '@emotion/css';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export default implementRuntimeComponent({
|
||||
version: CORE_VERSION,
|
||||
metadata: {
|
||||
name: CoreComponentName.Iframe,
|
||||
displayName: 'Iframe',
|
||||
description: '',
|
||||
isDraggable: false,
|
||||
isResizable: false,
|
||||
exampleProperties: {
|
||||
src: 'https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik',
|
||||
referrerpolicy: 'unset',
|
||||
sandbox: 'unset',
|
||||
fetchpriority: 'auto',
|
||||
},
|
||||
exampleSize: [1, 1],
|
||||
annotations: {
|
||||
category: 'Advance',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
properties: Type.Object({
|
||||
src: Type.String({ title: 'Src' }),
|
||||
referrerpolicy: StringUnion(
|
||||
[
|
||||
'unset',
|
||||
'no-referrer',
|
||||
'no-referrer-when-downgrade',
|
||||
'origin',
|
||||
'origin-when-cross-origin',
|
||||
'same-origin',
|
||||
'strict-origin',
|
||||
'strict-origin-when-cross-origin',
|
||||
'unsafe-url',
|
||||
],
|
||||
{
|
||||
title: 'Referrer Policy',
|
||||
description:
|
||||
"Indicates which referrer to send when fetching the frame's resource.",
|
||||
}
|
||||
),
|
||||
sandbox: StringUnion(
|
||||
[
|
||||
'unset',
|
||||
'allow-forms',
|
||||
'allow-modals',
|
||||
'allow-orientation-lock',
|
||||
'allow-pointer-lock',
|
||||
'allow-popups',
|
||||
'allow-popups-to-escape-sandbox',
|
||||
'allow-presentation',
|
||||
'allow-same-origin',
|
||||
'allow-scripts',
|
||||
'allow-top-navigation',
|
||||
'allow-top-navigation-by-user-activation',
|
||||
],
|
||||
{
|
||||
title: 'Sandbox',
|
||||
description: 'Applies extra restrictions to the content in the frame.',
|
||||
}
|
||||
),
|
||||
fetchpriority: StringUnion(['auto', 'low', 'high'], {
|
||||
title: 'Fetch Priority',
|
||||
description:
|
||||
'Provides a hint of the relative priority to use when fetching the iframe document',
|
||||
}),
|
||||
}),
|
||||
state: Type.Object({}),
|
||||
methods: {
|
||||
requestFullscreen: Type.Object({}),
|
||||
},
|
||||
slots: {},
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(
|
||||
({
|
||||
component,
|
||||
src,
|
||||
referrerpolicy,
|
||||
sandbox,
|
||||
fetchpriority,
|
||||
elementRef,
|
||||
customStyle,
|
||||
subscribeMethods,
|
||||
}) => {
|
||||
const iframeProps: Record<string, unknown> = {
|
||||
title: component.id,
|
||||
src,
|
||||
fetchpriority,
|
||||
};
|
||||
|
||||
if (referrerpolicy !== 'unset') {
|
||||
iframeProps.referrerpolicy = referrerpolicy;
|
||||
}
|
||||
|
||||
if (sandbox !== 'unset') {
|
||||
iframeProps.sandbox = sandbox;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
subscribeMethods({
|
||||
requestFullscreen() {
|
||||
elementRef?.current.requestFullscreen();
|
||||
},
|
||||
});
|
||||
}, [elementRef, subscribeMethods]);
|
||||
|
||||
return (
|
||||
<iframe ref={elementRef} {...iframeProps} className={css(customStyle?.content)} />
|
||||
);
|
||||
}
|
||||
);
|
@ -8,6 +8,7 @@ import CoreDummy from '../components/core/Dummy';
|
||||
import CoreModuleContainer from '../components/core/ModuleContainer';
|
||||
import CoreStack from '../components/core/Stack';
|
||||
import CoreFileInput from '../components/core/FileInput';
|
||||
import CoreIframe from '../components/core/Iframe';
|
||||
|
||||
// traits
|
||||
import CoreArrayState from '../traits/core/ArrayState';
|
||||
@ -242,6 +243,7 @@ export function initRegistry(
|
||||
registry.registerComponent(CoreModuleContainer);
|
||||
registry.registerComponent(CoreStack);
|
||||
registry.registerComponent(CoreFileInput);
|
||||
registry.registerComponent(CoreIframe);
|
||||
|
||||
registry.registerTrait(CoreState);
|
||||
registry.registerTrait(CoreArrayState);
|
||||
|
@ -28,7 +28,7 @@ export type ComponentImplProps<
|
||||
> = ImplWrapperProps &
|
||||
TraitResult<KStyleSlot, KEvent>['props'] &
|
||||
RuntimeFunctions<TState, TMethods, TSlots> & {
|
||||
elementRef?: React.Ref<any>;
|
||||
elementRef?: React.MutableRefObject<any>;
|
||||
getElement?: (ele: HTMLElement) => void;
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@ export enum CoreComponentName {
|
||||
ModuleContainer = 'moduleContainer',
|
||||
GridLayout = 'grid_layout',
|
||||
Text = 'text',
|
||||
Iframe = 'iframe',
|
||||
}
|
||||
// core traits
|
||||
export enum CoreTraitName {
|
||||
|
Loading…
x
Reference in New Issue
Block a user