@material-ui/core#Portal TypeScript Examples
The following examples show how to use
@material-ui/core#Portal.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: context_menu.tsx From jupyter-extensions with Apache License 2.0 | 6 votes |
render() {
const children = React.Children.map(
this.props.children,
(child: React.ReactElement) => {
return React.cloneElement(child, {
onContextMenu: this.openContextMenu,
});
}
);
return (
<>
{children}
<Portal>
<ContextMenuContainer
transitionDuration={0}
open={this.state.isOpen}
anchorReference="anchorPosition"
anchorPosition={{ top: this.state.mouseY, left: this.state.mouseX }}
>
<div ref={this.myRef}>
{this.props.items.map(option => (
<ContextMenuItem key={option.label} onClick={option.onClick}>
{option.label}
</ContextMenuItem>
))}
</div>
</ContextMenuContainer>
</Portal>
</>
);
}
Example #2
Source File: TechDocsReaderPageContentAddons.tsx From backstage with Apache License 2.0 | 5 votes |
TechDocsReaderPageContentAddons = () => {
const addons = useTechDocsAddons();
const { shadowRoot } = useTechDocsReaderPage();
const contentElement = shadowRoot?.querySelector(
'[data-md-component="content"]',
);
const primarySidebarElement = shadowRoot?.querySelector(
'div[data-md-component="sidebar"][data-md-type="navigation"], div[data-md-component="navigation"]',
);
let primarySidebarAddonLocation = primarySidebarElement?.querySelector(
'[data-techdocs-addons-location="primary sidebar"]',
);
if (!primarySidebarAddonLocation) {
primarySidebarAddonLocation = document.createElement('div');
primarySidebarAddonLocation.setAttribute(
'data-techdocs-addons-location',
'primary sidebar',
);
primarySidebarElement?.prepend(primarySidebarAddonLocation);
}
const secondarySidebarElement = shadowRoot?.querySelector(
'div[data-md-component="sidebar"][data-md-type="toc"], div[data-md-component="toc"]',
);
let secondarySidebarAddonLocation = secondarySidebarElement?.querySelector(
'[data-techdocs-addons-location="secondary sidebar"]',
);
if (!secondarySidebarAddonLocation) {
secondarySidebarAddonLocation = document.createElement('div');
secondarySidebarAddonLocation.setAttribute(
'data-techdocs-addons-location',
'secondary sidebar',
);
secondarySidebarElement?.prepend(secondarySidebarAddonLocation);
}
return (
<>
<Portal container={primarySidebarAddonLocation}>
{addons.renderComponentsByLocation(locations.PrimarySidebar)}
</Portal>
<Portal container={contentElement}>
{addons.renderComponentsByLocation(locations.Content)}
</Portal>
<Portal container={secondarySidebarAddonLocation}>
{addons.renderComponentsByLocation(locations.SecondarySidebar)}
</Portal>
</>
);
}
Example #3
Source File: ReportIssue.tsx From backstage with Apache License 2.0 | 5 votes |
ReportIssueAddon = ({ debounceTime = 500, templateBuilder: buildTemplate, }: ReportIssueProps) => { const classes = useStyles(); const [style, setStyle] = useState<Style>(); const repository = useGitRepository(); const defaultTemplate = useGitTemplate(debounceTime); const selection = useShadowRootSelection(debounceTime); const [mainContent, feedbackLink] = useShadowRootElements([ PAGE_MAIN_CONTENT_SELECTOR, PAGE_FEEDBACK_LINK_SELECTOR, ]); let [feedbackContainer] = useShadowRootElements([ ADDON_FEEDBACK_CONTAINER_SELECTOR, ]); if (feedbackLink) { feedbackLink.style.display = 'none'; } // calculates the position of the selected text to be able to set the position of the addon useEffect(() => { if ( // todo(backstage/techdocs-core) handle non-repo rendering !repository || !selection || !selection.containsNode(mainContent!, true) || selection?.containsNode(feedbackContainer!, true) ) { return; } const mainContentPosition = mainContent!.getBoundingClientRect(); const selectionPosition = selection.getRangeAt(0).getBoundingClientRect(); setStyle({ top: `${selectionPosition.top - mainContentPosition.top - 16}px`, left: `${selectionPosition.left + selectionPosition.width / 2}px`, }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [selection, mainContent, feedbackContainer]); if (!selection || !repository) return null; if (!feedbackContainer) { feedbackContainer = document.createElement('div'); feedbackContainer.setAttribute('id', ADDON_FEEDBACK_CONTAINER_ID); mainContent!.prepend(feedbackContainer); } return ( <Portal container={feedbackContainer}> <Paper data-testid="report-issue-addon" className={classes.root} style={style} > <IssueLink repository={repository} template={ buildTemplate ? buildTemplate({ selection }) : defaultTemplate } /> </Paper> </Portal> ); }
Example #4
Source File: Layout.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const stackedSectionsForName: { [name: string]: Section[] } = {};
const breakActionForName: { [name: string]: BreakAction } = {};
this.props.sections.forEach(section => {
const breakAction = (section.breakAlways
? section.breakAction
: (this.props.mediaQueries[section.name] === false && section.breakAction))
|| 'show';
breakActionForName[section.name] = breakAction;
if (breakAction === 'stack' && section.breakAction === 'stack') {
stackedSectionsForName[section.stackWithSectionName] = stackedSectionsForName[section.stackWithSectionName] || [];
stackedSectionsForName[section.stackWithSectionName].push(section);
}
});
const layoutState: LayoutState = {
isShown: name => breakActionForName[name] || 'show',
enableBoxLayout: this.props.mediaQueries.enableBoxLayout,
};
const sectionPreview = this.props.sections.find(s => s.breakAction === 'drawer');
const contentPreview = !sectionPreview || layoutState.isShown(sectionPreview.name) !== 'drawer'
? null : this.renderStackedSections(layoutState, sectionPreview, 'drawer', stackedSectionsForName[sectionPreview.name]);
const sectionMenu = this.props.sections.find(s => s.breakAction === 'menu');
const contentMenu = !sectionMenu || layoutState.isShown(sectionMenu.name) !== 'menu'
? null : this.renderStackedSections(layoutState, sectionMenu, 'menu', stackedSectionsForName[sectionMenu.name]);
const contents: React.ReactNode[] = [];
this.props.sections.forEach(section => {
const breakAction = breakActionForName[section.name];
if (breakAction !== 'show') return;
const content = this.renderStackedSections(layoutState, section, breakAction, stackedSectionsForName[section.name]);
if (!content) return;
contents.push(content);
});
return (
<div>
{!!this.props.toolbarShow && (
<Portal>
<AppBar elevation={0} color='default' className={this.props.classes.appBar}>
<Toolbar>
{!!contentMenu && (
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerToggle.bind(this)}
className={this.props.classes.menuButton}
>
<MenuIcon />
</IconButton>
)}
{this.props.toolbarLeft}
<div className={this.props.classes.grow} />
{this.props.toolbarRight}
</Toolbar>
<Divider />
</AppBar>
</Portal>
)}
{!!contentMenu && (
<Drawer
variant='temporary'
open={this.state.mobileMenuOpen}
onClose={this.handleDrawerToggle.bind(this)}
classes={{
paper: classNames(this.props.classes.menuPaper),
}}
style={{
width: sectionMenu?.size?.maxWidth || sectionMenu?.size?.width || sectionMenu?.size?.breakWidth || '100%',
}}
ModalProps={{
keepMounted: true,
}}
>
{!!this.props.toolbarShow && (<div className={this.props.classes.toolbarSpacer} />)}
{contentMenu}
</Drawer>
)}
{!!contentPreview && (
<Drawer
variant='temporary'
SlideProps={{ mountOnEnter: true }}
anchor='right'
open={!!this.props.previewShow}
onClose={this.handlePreviewClose.bind(this)}
classes={{
modal: this.props.classes.previewMobileModal,
paper: this.props.classes.previewMobilePaper,
}}
style={{
width: sectionPreview?.size?.maxWidth || sectionPreview?.size?.width || sectionPreview?.size?.breakWidth || '100%',
}}
>
{!!this.props.toolbarShow && (<div className={this.props.classes.toolbarSpacer} />)}
{contentPreview}
</Drawer>
)}
<div className={classNames(this.props.classes.page, this.props.classes.flexVertical)}>
{!!this.props.toolbarShow && (<div className={this.props.classes.toolbarSpacer} />)}
<div className={classNames(
this.props.classes.sections,
layoutState.enableBoxLayout ? this.props.classes.sectionsBox : this.props.classes.sectionsNobox,
this.props.classes.grow,
this.props.classes.flexHorizontal,
)}>
{contents}
</div>
</div>
</div>
);
}