@mui/material#useTheme TypeScript Examples
The following examples show how to use
@mui/material#useTheme.
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: WidgetsSidebar.tsx From fluttertemplates.dev with MIT License | 6 votes |
function SubGroupRenderer(props: SubGroupRendererProps) {
const theme = useTheme();
return (
<List>
{props.group.widget_subgroups.map((subgroup, index) => (
<SingleSubGroupRenderer
subgroup={subgroup}
selectedSubGroup={props.selectedSubGroup}
/>
))}
</List>
);
}
Example #2
Source File: GithubLogo.tsx From ui-schema with MIT License | 6 votes |
GithubIcon: React.ComponentType<{
width?: number
fill?: string
style?: React.CSSProperties
// eslint-disable-next-line react/display-name
}> = React.forwardRef(({width = 20, fill, style = {}}, ref) => {
const theme = useTheme()
return <svg
// @ts-ignore
ref={ref}
role="img"
style={{
width: width,
verticalAlign: 'middle',
padding: 1,
...style,
}}
viewBox="0 0 24 24" fill={fill || theme.palette.text.primary} xmlns="http://www.w3.org/2000/svg">
<title>GitHub</title>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
</svg>
})
Example #3
Source File: SolidColoredTextfield.tsx From genshin-optimizer with MIT License | 6 votes |
export default function SolidColoredTextField({ hasValue, startAdornment, flattenCorners = false, InputProps, sx, ...props }: SolidColoredTextFieldProps) {
const theme = useTheme()
return <TextField
{...props}
variant="filled"
color={hasValue ? "success" : "primary"}
hiddenLabel={props.label ? false : true}
type="search"
InputProps={{
...InputProps,
startAdornment,
}}
InputLabelProps={{ style: { color: theme.palette.text.primary } }}
sx={{
...sx,
"& .MuiFilledInput-root": { backgroundColor: hasValue ? theme.palette.success.main : theme.palette.primary.main, borderRadius: flattenCorners ? 0 : 1, paddingTop: props.label ? undefined : 0, paddingBottom: 0 },
"& .MuiFilledInput-root:before": { border: "none" },
"& .MuiFilledInput-root:after": { border: "none" },
"& .MuiFilledInput-root.Mui-focused": { backgroundColor: hasValue ? theme.palette.success.light : theme.palette.primary.light },
"& .MuiFilledInput-root:hover": { backgroundColor: hasValue ? theme.palette.success.dark : theme.palette.primary.dark },
"& .MuiFilledInput-root:hover:not(.Mui-disabled):before": { border: "none" },
// Remove the x at the end of search input for IE
"& input[type=search]::-ms-clear": { display: "none", width: 0, height: 0 },
"& input[type=search]::-ms-reveal": { display: "none", width: 0, height: 0 },
// Remove the x at the end of search input for Chrome
"& input[type=search]::-webkit-search-decoration": { display: "none" },
"& input[type=search]::-webkit-search-cancel-button": { display: "none" },
"& input[type=search]::-webkit-search-results-button": { display: "none" },
"& input[type=search]::-webkit-search-results-decoration": { display: "none" },
}}
/>
}
Example #4
Source File: Hex.tsx From sapio-studio with Mozilla Public License 2.0 | 6 votes |
function BaseHex(props: { value: string; styling: string; label?: string }) {
const [tip_message, set_tip] = React.useState(null as null | string);
const code = React.useRef<HTMLDivElement>(null);
const theme = useTheme();
const copy = () => {
navigator.clipboard.writeText(props.value);
set_tip('Copied!');
setTimeout(() => {
set_tip(null);
}, 1000);
};
React.useEffect(() => {
code.current?.addEventListener('dblclick', copy);
});
return (
<Tooltip
title={tip_message ?? 'double click to copy.'}
arrow
placement="top"
>
<div>
<TextField
ref={code}
fullWidth
label={props.label}
value={props.value}
variant="outlined"
InputProps={{
readOnly: true,
}}
/>
</div>
</Tooltip>
);
}
Example #5
Source File: SyntaxHighlighter.tsx From GTAV-NativeDB with MIT License | 6 votes |
function SyntaxHighlighter({ language, children, customStyle }: SyntaxHighlighterProps) {
const theme = useTheme()
const highlighterStyle = theme.palette.mode === 'dark'
? darkStyle
: lightStyle
return (
<Highlighter
language={language}
style={highlighterStyle}
customStyle={{
background: 'none',
padding: theme.spacing(2),
margin: 0,
...customStyle
}}
>
{children}
</Highlighter>
)
}
Example #6
Source File: useMediaQueryUp.tsx From genshin-optimizer with MIT License | 6 votes |
export default function useMediaQueryUp() {
const theme = useTheme();
const sm = useMediaQuery(theme.breakpoints.up('sm'));
const md = useMediaQuery(theme.breakpoints.up('md'));
const lg = useMediaQuery(theme.breakpoints.up('lg'));
const xl = useMediaQuery(theme.breakpoints.up('xl'));
if (xl) return "xl"
if (lg) return "lg"
if (md) return "md"
if (sm) return "sm"
return "xs"
}
Example #7
Source File: layout.tsx From usehooks-ts with MIT License | 6 votes |
Layout: FC = ({ children }) => {
const { title } = useSiteMetadata()
const [isSidebarOpen, { openSidebar, closeSidebar }] = useSidebar()
const [isModalOpen, { openModal, closeModal }] = useSearchModal()
const theme = useTheme()
const isLarge = useMediaQuery(theme.breakpoints.up('md'))
return (
<Root>
<CustomScrollbar theme={theme} />
<Header
siteTitle={title}
openSidebar={openSidebar}
openSearch={openModal}
/>
<Sidebar open={isSidebarOpen} onClose={closeSidebar} />
<Main
sx={{ paddingLeft: isLarge && isSidebarOpen ? `${drawerWidth}px` : 0 }}
>
{children}
<Footer />
</Main>
<SearchModal open={isModalOpen} onClose={closeModal} />
<BackToTop />
</Root>
)
}
Example #8
Source File: ColorModeContext.tsx From metaplex with Apache License 2.0 | 6 votes |
ColorModeContextProvider = ({
children = undefined,
}: {
children: React.ReactNode;
}) => {
const [mode, setMode] = React.useState<'light' | 'dark'>('dark');
const theme = useTheme();
const toggleColorMode = () => {
setMode(prevMode => (prevMode === 'light' ? 'dark' : 'light'));
};
return (
<ColorModeContext.Provider
value={{
toggleColorMode,
mode,
theme,
}}
>
{children}
</ColorModeContext.Provider>
);
}
Example #9
Source File: Footer.tsx From frontend with MIT License | 6 votes |
SocialIcons = () => {
const theme = useTheme()
const sm = useMediaQuery(theme.breakpoints.up('sm'))
return (
<Grid direction="row" container spacing={2} justifyContent={sm ? 'flex-start' : 'center'}>
<Grid item>
<ExternalLink href={socialUrls.facebook}>
<Facebook />
</ExternalLink>
</Grid>
<Grid item>
<ExternalLink href={socialUrls.linkedin}>
<LinkedIn />
</ExternalLink>
</Grid>
<Grid item>
<ExternalLink href={socialUrls.youtube}>
<YouTube />
</ExternalLink>
</Grid>
<Grid item>
<ExternalLink href={socialUrls.instagram}>
<Instagram />
</ExternalLink>
</Grid>
</Grid>
)
}
Example #10
Source File: ContainedButton.tsx From fluttertemplates.dev with MIT License | 6 votes |
function CustomContainedButton(props: CustomContainedButtonProps) {
const theme = useTheme();
// const styles = useStyles();
return (
<Button
variant="contained"
href={props.href}
disableElevation
endIcon={props.endIcon}
style={{
padding: "12px 32px",
backgroundColor: `${theme.palette.secondary.main}`,
color: "#ffffff",
textTransform: "capitalize",
fontWeight: "bold",
borderRadius: "10rem",
}}
>
{props.label}
</Button>
);
}
Example #11
Source File: SearchBarComponent.tsx From professor-prebid with Apache License 2.0 | 5 votes |
ListboxComponent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLElement>>(function ListboxComponent(props, ref) {
const theme = useTheme();
const { children, ...other } = props;
const itemData: React.ReactChild[] = [];
(children as React.ReactChild[]).forEach((item: React.ReactChild & { children?: React.ReactChild[] }) => {
itemData.push(item);
itemData.push(...(item.children || []));
});
const smUp = useMediaQuery(theme.breakpoints.up('sm'), {
noSsr: true,
});
const itemCount = itemData.length;
const itemSize = smUp ? 36 : 48;
const getChildSize = (child: React.ReactChild) => {
if (child.hasOwnProperty('group')) {
return 48;
}
return itemSize;
};
const getHeight = () => {
if (itemCount > 8) {
return 8 * itemSize;
}
return itemData.map(getChildSize).reduce((a, b) => a + b, 0);
};
const gridRef = useResetCache(itemCount);
return (
<div ref={ref}>
<OuterElementContext.Provider value={other}>
<VariableSizeList
itemData={itemData}
height={getHeight() + 2 * LISTBOX_PADDING}
width="100%"
ref={gridRef}
outerElementType={OuterElementType}
innerElementType="ul"
itemSize={(index) => getChildSize(itemData[index])}
overscanCount={5}
itemCount={itemCount}
>
{renderRow}
</VariableSizeList>
</OuterElementContext.Provider>
</div>
);
})
Example #12
Source File: ArtifactAutocomplete.tsx From genshin-optimizer with MIT License | 5 votes |
function ArtifactSingleAutocomplete<T extends ArtifactSingleAutocompleteKey>({ allArtifactKeys, selectedArtifactKey, setArtifactKey, getName, getImage, label, disable= () => false, showDefault = false, defaultText = "", defaultIcon = "", flattenCorners = false, ...props }:
ArtifactSingleAutocompleteProps<T>) {
const theme = useTheme();
const options = useMemo(() =>
(showDefault
? [{ key: "" as T, label: defaultText }]
: []
).concat(allArtifactKeys.map(key => (
{ key: key, label: getName(key) }
))), [allArtifactKeys, getName, defaultText, showDefault])
return <Autocomplete
autoHighlight
options={options}
value={{ key: selectedArtifactKey, label: getName(selectedArtifactKey) }}
onChange={(_, newValue) => setArtifactKey(newValue ? newValue.key : "")}
getOptionLabel={(option) => option.label ? option.label : defaultText}
isOptionEqualToValue={(option, value) => option.key === value.key}
getOptionDisabled={option => option.key ? disable(option.key) : false}
renderInput={(props) => <SolidColoredTextField
{...props}
label={label}
startAdornment={getImage(selectedArtifactKey)}
hasValue={selectedArtifactKey ? true : false}
flattenCorners={flattenCorners}
/>}
renderOption={(props, option) => (
<MenuItemWithImage
key={option.key}
value={option.key}
image={getImage(option.key)}
text={option.label}
theme={theme}
isSelected={selectedArtifactKey === option.key}
props={props}
/>
)}
{...props}
/>
}
Example #13
Source File: SlotsComponent.tsx From professor-prebid with Apache License 2.0 | 5 votes |
Row = ({ adUnit, events }: { adUnit: IPrebidAdUnit; events: IPrebidDetails['events'] }): JSX.Element => {
const [winningBids, setWinningBids] = React.useState<IPrebidBidWonEventData[]>([]);
const [bidsReceived, setBidsReceived] = React.useState<IPrebidBidWonEventData[]>([]);
const [adsRendered, setAdsRendered] = React.useState<IPrebidAdRenderSucceededEventData[]>([]);
const theme = useTheme();
useEffect(() => {
setWinningBids(((events || []) as IPrebidBidWonEventData[]).filter((event) => event.eventType === 'bidWon'));
setBidsReceived(((events || []) as IPrebidBidWonEventData[]).filter((event) => event.eventType === 'bidResponse'));
setAdsRendered(((events || []) as IPrebidAdRenderSucceededEventData[]).filter((event) => event.eventType === 'adRenderSucceeded'));
}, [events]);
return (
<React.Fragment>
<Grid item xs={4} sx={{ [theme.breakpoints.down('sm')]: { display: 'none' } }}>
<Paper sx={{ height: '100%' }}>
<AdUnitChipComponent adUnit={adUnit} />
</Paper>
</Grid>
<Grid item xs={4} sx={{ [theme.breakpoints.down('sm')]: { display: 'none' } }}>
<Paper sx={{ height: '100%' }}>
<MediaTypesComponent mediaTypes={adUnit.mediaTypes} />
</Paper>
</Grid>
<Grid item xs={4} sx={{ [theme.breakpoints.down('sm')]: { display: 'none' } }}>
<Paper sx={{ height: '100%' }}>
<Stack direction="row" flexWrap={'wrap'} gap={0.5} sx={{ p: 0.5 }}>
{adUnit.bids.map((bid, index) => {
const bidReceived = bidsReceived.find(
(bidReceived) =>
bidReceived.args?.adUnitCode === adUnit.code &&
bidReceived.args.bidder === bid.bidder &&
adUnit.sizes?.map((size) => `${size[0]}x${size[1]}`).includes(bidReceived?.args?.size)
);
const isWinner = winningBids.some(
(winningBid) =>
winningBid.args.adUnitCode === adUnit.code &&
winningBid.args.bidder === bid.bidder &&
adUnit.sizes?.map((size) => `${size[0]}x${size[1]}`).includes(bidReceived?.args.size)
);
const isRendered = adsRendered.some(
(renderedAd) => renderedAd.args.bid.adUnitCode === adUnit.code && renderedAd.args.bid.bidder === bid.bidder
);
const label = bidReceived?.args.cpm
? `${bid.bidder} (${bidReceived?.args.cpm.toFixed(2)} ${bidReceived?.args.currency})`
: `${bid.bidder}`;
return <BidChipComponent input={bid} label={label} key={index} isWinner={isWinner} bidReceived={bidReceived} isRendered={isRendered} />;
})}
</Stack>
</Paper>
</Grid>
</React.Fragment>
);
}
Example #14
Source File: ArtifactCardNano.tsx From genshin-optimizer with MIT License | 5 votes |
export default function ArtifactCardNano({ artifactId, slotKey: pSlotKey, mainStatAssumptionLevel = 0, showLocation = false, onClick, BGComponent = CardDark }: Data) { const art = useArtifact(artifactId) const sheet = usePromise(ArtifactSheet.get(art?.setKey), [art]) const actionWrapperFunc = useCallback(children => <CardActionArea onClick={onClick} sx={{ height: "100%" }}>{children}</CardActionArea>, [onClick],) const theme = useTheme() if (!art) return <BGComponent sx={{ display: "flex", height: "100%", alignItems: "center", justifyContent: "center" }}> <Box component="img" src={Assets.slot[pSlotKey]} sx={{ width: "25%", height: "auto", opacity: 0.7 }} /> </BGComponent> const { slotKey, rarity, level, mainStatKey, substats, location } = art const mainStatLevel = Math.max(Math.min(mainStatAssumptionLevel, rarity * 4), level) const mainStatUnit = KeyMap.unit(mainStatKey) const levelVariant = "roll" + (Math.floor(Math.max(level, 0) / 4) + 1) const element = allElementsWithPhy.find(ele => art.mainStatKey.includes(ele)) const color = element ? alpha(theme.palette[element].main, 0.6) : alpha(theme.palette.secondary.main, 0.6) return <BGComponent sx={{ height: "100%" }}><ConditionalWrapper condition={!!onClick} wrapper={actionWrapperFunc} > <Box display="flex" height="100%"> <Box className={`grad-${rarity}star`} sx={{ position: "relative", flexGrow: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }} > <ArtifactSetSlotTooltip slotKey={slotKey} sheet={sheet}> <Box component="img" src={sheet?.slotIcons[slotKey] ?? ""} sx={{ m: -1, maxHeight: "110%", maxWidth: "110%" }} /> </ArtifactSetSlotTooltip> <Box sx={{ position: "absolute", width: "100%", height: "100%", p: 0.5, opacity: 0.85, display: "flex", justifyContent: "space-between", pointerEvents: "none" }} > <Chip size="small" label={<strong>{` +${level}`}</strong>} color={levelVariant as any} /> {showLocation && <Chip size="small" label={<LocationIcon location={location} />} color={"secondary"} sx={{ overflow: "visible", ".MuiChip-label": { overflow: "visible" } }} />} </Box> {/* mainstats */} <Chip size="small" sx={{ position: "absolute", bottom: 0, mb: 1, backgroundColor: color }} label={<Typography variant="h6" sx={{ display: "flex", gap: 1, px: 1, zIndex: 1 }}> <BootstrapTooltip placement="top" title={<Typography>{KeyMap.getArtStr(mainStatKey)}</Typography>} disableInteractive> <span>{element ? uncoloredEleIcons[element] : StatIcon[mainStatKey]}</span> </BootstrapTooltip> <ColorText color={mainStatLevel !== level ? "warning" : undefined}>{cacheValueString(Artifact.mainStatValue(mainStatKey, rarity, mainStatLevel) ?? 0, KeyMap.unit(mainStatKey))}{mainStatUnit}</ColorText> </Typography>} /> </Box> {/* substats */} <Box display="flex" flexDirection="column" justifyContent="space-between" sx={{ p: 1, }}> {substats.map((stat: ICachedSubstat, i: number) => <SubstatDisplay key={i + stat.key} stat={stat} />)} </Box> </Box> </ConditionalWrapper></BGComponent > }
Example #15
Source File: ToolsComponent.tsx From professor-prebid with Apache License 2.0 | 5 votes |
ToolsComponent = ({ prebid }: ToolsComponentProps): JSX.Element => {
const theme = useTheme();
const [consoleState, setConsoleState] = useState<boolean>(null);
useEffect(() => {
chrome.storage.local.get(constants.CONSOLE_TOGGLE, (result) => {
const checked = result ? result[constants.CONSOLE_TOGGLE] : false;
setConsoleState(checked);
});
}, [consoleState]);
const handleConsoleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setConsoleState(event.target.checked);
const { checked } = event.target;
try {
chrome.storage.local.set({ [constants.CONSOLE_TOGGLE]: checked }, () => {
chrome.tabs.query({ currentWindow: true, active: true }, (tabs) => {
const tab = tabs[0];
logger.log('[PopupHandler] Send onConsoleToggle', { tab }, { type: constants.CONSOLE_TOGGLE, consoleState: checked });
chrome.tabs.sendMessage(tab.id as number, { type: constants.CONSOLE_TOGGLE, consoleState: checked });
});
});
} catch (e) {
logger.error('onConsoleToggle', e);
}
};
logger.log(`[PopUp][ToolsComponent]: render `, consoleState);
return (
<Box sx={{ m: 1 }}>
<Grid container direction="row" rowSpacing={0} columnSpacing={0.5} justifyContent="stretch" alignItems="center">
<Grid item sx={{ height: 36 }}>
<Paper elevation={1} sx={{ alignItems: 'center' }}>
<Button size="small" variant="outlined" onClick={dfp_open_console} startIcon={<GoogleIcon />}>
<Typography variant="h3">open google AdManager console</Typography>
</Button>
</Paper>
</Grid>
<Grid item sx={{ height: 36 }}>
<Paper elevation={1}>
<Button size="small" variant="outlined" onClick={openDebugTab} startIcon={<BugReportIcon />}>
<Typography variant="h3">open debug tab</Typography>
</Button>
</Paper>
</Grid>
<Grid item sx={{ height: 36 }}>
<Paper elevation={1}>
<Button size="small" variant="outlined" onClick={() => chrome.storage?.local.set({ tabInfos: null })} startIcon={<DeleteOutlineIcon />}>
<Typography variant="h3"> delete tabInfos</Typography>
</Button>
</Paper>
</Grid>
<Grid item xs={12}>
<Box sx={{ backgroundColor: 'background.paper', borderRadius: 1, p: 1 }}>
<Grid container rowSpacing={1} columnSpacing={0.5}>
<Grid item xs={12}>
<Grid container rowSpacing={1} columnSpacing={0.5}>
{prebid && <ModifyBidResponsesComponent prebid={prebid} />}
</Grid>
</Grid>
<Grid item sm={1} xs={1}>
<Box sx={{ alignContent: 'center', [theme.breakpoints.down('sm')]: { transform: 'rotate(90deg)' } }}>
<FormControl>
<FormControlLabel control={<Switch checked={consoleState || false} onChange={handleConsoleChange} />} label="" />
</FormControl>
</Box>
</Grid>
<Grid item xs={11} sm={11}>
<Box sx={{ border: 1, borderColor: consoleState ? 'primary.main' : 'text.disabled', borderRadius: 1 }}>
<Typography variant="h4" sx={{ width: 1, p: 1.5, color: consoleState ? 'primary.main' : 'text.disabled' }}>
Show AdUnit Info Overlay
</Typography>
</Box>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
</Box>
);
}
Example #16
Source File: BitcoinStatusBar.tsx From sapio-studio with Mozilla Public License 2.0 | 5 votes |
export function BitcoinStatusBar(props: BitcoinStatusBarProps) {
const theme = useTheme();
const freq = useSelector(selectNodePollFreq);
const [balance, setBalance] = React.useState<number>(0);
const [blockchaininfo, setBlockchaininfo] = React.useState<any>(null);
React.useEffect(() => {
let next: ReturnType<typeof setTimeout> | null = null;
let mounted = true;
const periodic_update_stats = async () => {
next = null;
try {
const balance = await props.api.check_balance();
setBalance(balance);
} catch (err) {
console.error(err);
setBalance(0);
}
try {
const info = await props.api.blockchaininfo();
console.log(balance);
setBlockchaininfo(info);
} catch (err) {
console.error(err);
setBlockchaininfo(null);
}
if (mounted) {
let prefs = freq;
prefs = clamp(prefs ?? 0, 5, 5 * 60);
console.log('StatusBar', 'NEXT PERIODIC CHECK IN ', prefs);
next = setTimeout(periodic_update_stats, prefs * 1000);
}
};
let prefs = freq;
prefs = clamp(prefs ?? 0, 5, 5 * 60);
next = setTimeout(periodic_update_stats, prefs * 1000);
return () => {
mounted = false;
if (next !== null) clearTimeout(next);
};
}, []);
const network = blockchaininfo?.chain ?? 'disconnected';
const headers = blockchaininfo?.headers ?? '?';
const blocks = blockchaininfo?.headers ?? '?';
return (
<Paper
square={true}
sx={{
top: 'auto',
bottom: 0,
}}
className="BitcoinStatusBar Draggable"
style={{
background: theme.palette.background.default,
color: theme.palette.info.main,
}}
>
<Toolbar variant="dense">
<Typography variant="h6" color="inherit" component="div">
<div>chain: {network}</div>
</Typography>
<Typography variant="h6" color="inherit" component="div">
<div style={{ marginLeft: '0.5em' }}>
balance: {balance} BTC
</div>
</Typography>
<Typography variant="h6" color="inherit" component="div">
<div style={{ marginLeft: '0.5em' }}>
processed: {blocks}/{headers}
</div>
</Typography>
</Toolbar>
</Paper>
);
}
Example #17
Source File: SearchResultModule.tsx From ui-schema with MIT License | 5 votes |
SearchResultModule: React.FC<{
match: any
term: string | undefined
}> = (
{
match, term,
},
) => {
const {setOpen} = useSearch()
const {setOpen: setDrawerOpen} = useDrawer()
const {breakpoints} = useTheme()
const isMd = useMediaQuery(breakpoints.up('md'))
return <Box mb={1}>
<SearchLink
to={match.pagePath + '#doc-module--' + match.module}
onClick={() => {
setOpen(false)
if (!isMd) {
setDrawerOpen(false)
}
}}
// style={{textDecoration: 'none'}}
>
<Paper variant={'outlined'} style={{borderRadius: 5}}>
<Box p={1}>
<Typography>
<Highlighter
searchWords={term?.split(' ') || []}
textToHighlight={match.module}
autoEscape
highlightTag={SearchHighlight}
/>
</Typography>
<Box style={{display: 'flex'}}>
<Typography variant={'body2'}>{match.package}</Typography>
<Typography variant={'caption'} style={{marginLeft: 'auto', opacity: 0.6}}>Score: {match.score.toFixed(2)}</Typography>
</Box>
</Box>
</Paper>
</SearchLink>
</Box>
}
Example #18
Source File: index.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 5 votes |
headCells: HeadCell<GenericListItem>[] = [
{
numeric: false,
disablePadding: false,
align: 'center',
label: 'Strategy Name',
format: (item: GenericListItem) => {
const theme = useTheme();
return (
<Link
style={{
color:
theme.palette.mode === 'light' ? 'blue' : '#ce93d8',
}}
to={`/network/${item.network}/vault/${item.vault}/strategy/${item.address}`}
target="_blank"
>
{`${item.name} (${extractAddress(item.address as string)})`}
</Link>
);
},
},
{
numeric: true,
disablePadding: false,
align: 'center',
label: 'Activation',
format: (item: GenericListItem) => {
return <div>{new Date(item.activation).toUTCString()}</div>;
},
},
{
id: 'estimatedTotalAssetsUsdcNumber',
numeric: true,
disablePadding: false,
align: 'center',
label: 'TVL (MM)',
},
{
id: 'tvlImpact',
numeric: true,
disablePadding: false,
align: 'center',
label: 'TVL Impact (5-1 Extreme-Low)',
},
]
Example #19
Source File: add-button.tsx From tams-club-cal with MIT License | 5 votes |
AddButton = (props: AddButtonProps) => {
const router = useRouter();
const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down('md'));
const redirectTo = () => {
router.push(props.path || '#');
};
// Change position of button to the left side if it's the edit history button
const leftOrRight = props.editHistory ? { left: { lg: 32, xs: 12 } } : { right: { lg: 32, xs: 12 } };
return (
<Tooltip
title={
props.editHistory ? 'Show Edit History' : `${props.edit ? 'Edit' : 'Add'} ${props.label || 'resource'}`
}
>
<Fab
variant={props.editHistory ? 'extended' : 'circular'}
size={matches ? 'small' : 'large'}
color={props.editHistory ? 'primary' : props.color || 'default'}
aria-label={props.editHistory ? 'edit history' : props.edit ? 'edit' : 'add'}
onClick={redirectTo}
sx={{
display: 'flex',
margin: props.editHistory ? '12px auto' : 'auto',
position: 'fixed',
bottom: { lg: 32, xs: 12 },
zIndex: (theme) => theme.zIndex.appBar + 1,
color: (theme) => theme.palette.common.white,
...leftOrRight,
}}
>
{props.editHistory ? (
<AccessTimeRoundedIcon sx={{ marginRight: 1 }} width="16" />
) : props.edit ? (
<EditIcon width="16" />
) : (
<AddIcon htmlColor="white" width="16" />
)}
{props.editHistory ? 'Show Edit History' : null}
</Fab>
</Tooltip>
);
}
Example #20
Source File: NativesPage.tsx From GTAV-NativeDB with MIT License | 5 votes |
function NativeInfoDrawer() {
const { native: nativeHash } = useParams<{ native?: string }>()
const history = useHistory()
const theme = useTheme()
const handleClose = useCallback(() => {
history.replace(`/natives${history.location.search}`)
}, [history])
return (
<SwipeableDrawer
anchor="bottom"
open={!!nativeHash}
onOpen={() => { }}
onClose={handleClose}
PaperProps={{
sx: {
height: `calc(100vh - 5px)`,
borderRadius: `${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0px 0px`
}
}}
components={{
Root: 'section'
}}
>
<Paper
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '0px',
position: 'sticky',
top: 0,
p: 1,
backdropFilter: 'blur(20px)',
backgroundColor: alpha(theme.palette.background.default, 0.6),
...(theme.palette.mode === 'dark' && {
backgroundImage: `linear-gradient(${alpha(
'#fff',
getOverlayAlpha(4),
)}, ${alpha('#fff', getOverlayAlpha(4))})`,
}),
zIndex: 1
}}
>
<Box sx={{ flexGrow: 1 }} />
<Typography component="h1" variant="h6" align="center">
Native Details
</Typography>
<Box sx={{ flexGrow: 1 }} />
<IconButton onClick={handleClose}>
<CloseIcon />
</IconButton>
</Paper>
<NativeInfo />
</SwipeableDrawer>
)
}
Example #21
Source File: MultiSelect.tsx From multi-downloader-nx with MIT License | 5 votes |
MultiSelect: React.FC<MultiSelectProps> = (props) => {
const theme = useTheme();
return <div>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="multi-select-label">{props.title}</InputLabel>
<Select
labelId="multi-select-label"
id="multi-select"
multiple
value={(props.selected ?? [])}
onChange={e => {
const val = typeof e.target.value === "string" ? e.target.value.split(",") : e.target.value;
if (props.allOption && val.includes('all')) {
if (props.values.length === val.length - 1)
props.onChange([]);
else
props.onChange(props.values);
} else {
props.onChange(val);
}
}}
input={<OutlinedInput id="select-multiple-chip" label={props.title} />}
renderValue={(selected) => (
selected.join(', ')
)}
MenuProps={MenuProps}
>
{props.values.concat(props.allOption ? 'all' : []).map((name) => (
<MenuItem
key={`${props.title}_${name}`}
value={name}
style={getStyles(name, props.selected, theme)}
>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
}
Example #22
Source File: SubmitProposalSection.tsx From fluttertemplates.dev with MIT License | 5 votes |
export default function SubmitProposalSection() {
const theme = useTheme();
return (
<section
style={{
height: "50vh",
marginTop: "5rem",
marginBottom: "5rem",
backgroundColor: `${theme.palette.secondary.main}10`,
}}
>
<Grid
container
direction="column"
justifyContent="center"
alignItems="center"
style={{
height: "100%",
}}
>
<Grid item>
<Typography
variant="h6"
align="center"
style={{
fontWeight: "bold",
}}
>
Didn't find the template you were looking for?
</Typography>
</Grid>
<Grid
item
style={{
marginTop: "1rem",
}}
>
<a
href={`${GITHUB_LINK}/issues/new?assignees=&labels=widget_template&template=request-a-new-widget.md`}
target="_blank"
rel="noopener noreferrer"
>
<CustomContainedButton
label="Submit a proposal"
endIcon={<FavoriteRounded fontSize="small" />}
/>
</a>
</Grid>
</Grid>
</section>
);
}
Example #23
Source File: NativeSelect.tsx From GTAV-NativeDB with MIT License | 5 votes |
ListboxComponent = React.forwardRef<HTMLDivElement>(function ListboxComponent(
props,
ref,
) {
const { children, ...other } = props
const itemData = React.Children.toArray(children)
const theme = useTheme()
const smUp = useMediaQuery(theme.breakpoints.up('sm'), {
noSsr: true
})
const itemCount = itemData.length
const itemSize = smUp ? 36 : 48
const getHeight = () => {
if (itemCount > 8) {
return 8 * itemSize
}
return itemData.map(() => smUp ? 36 : 48).reduce((a, b) => a + b, 0)
}
const gridRef = useResetCache(itemCount);
return (
<div ref={ref}>
<OuterElementContext.Provider value={other}>
<FixedSizeList
itemData={itemData}
height={getHeight() + 2 * LISTBOX_PADDING}
width="100%"
ref={gridRef}
outerElementType={OuterElementType}
innerElementType="ul"
itemSize={smUp ? 36 : 48}
overscanCount={5}
itemCount={itemCount}
>
{renderRow}
</FixedSizeList>
</OuterElementContext.Provider>
</div>
);
})
Example #24
Source File: FeaturesSection.tsx From fluttertemplates.dev with MIT License | 5 votes |
function SingleFeature(props: SingleFeatureProps) {
const theme = useTheme();
return (
<Grid item xs={12} md={4} lg={3}>
<Grid
container
direction="column"
justifyContent="center"
alignItems="center"
spacing={1}
>
<Grid item>
<Card
elevation={0}
style={{
padding: "2rem",
marginBottom: "0.5rem",
background: `${theme.palette.secondary.main}20`,
borderRadius: "1.5rem",
}}
>
{props.icon}
</Card>
</Grid>
<Grid item>
<Typography
variant="h4"
style={{
fontSize: "1.2rem",
fontWeight: "bold",
}}
>
{props.title}
</Typography>
</Grid>
<Grid item>
<Typography
variant="caption"
style={{
fontSize: "1rem",
display: "flex",
flexGrow: 1,
textAlign: "center",
}}
>
{props.description}
</Typography>
</Grid>
</Grid>
</Grid>
);
}
Example #25
Source File: UTXONodeWidget.tsx From sapio-studio with Mozilla Public License 2.0 | 4 votes |
/**
* Default node that models the UTXONodeModel. It creates two columns
* for both all the input ports on the left, and the output ports on the right.
*/
//node: HTMLDivElement | null;
//callback: () => any;
export function UTXONodeWidget(props: DefaultNodeProps) {
const selected_entity_id: EntityType = useSelector(selectEntityToView);
const has_continuations =
Object.keys(
useSelector(selectContinuation)(
`${props.node.getOptions().txid}:${
props.node.getOptions().index
}`
) ?? {}
).length > 0;
const [id, setID] = React.useState(Math.random());
const is_reachable = useSelector(selectIsReachable)(
props.node.getOptions().txid
);
const [amount, setAmount] = React.useState(props.node.getAmount());
React.useEffect(() => {
const l = props.node.registerListener({
sync: (e: BaseEvent) =>
setAmount((props.node as UTXOModel).getAmount()),
});
return () => {
props.node.deregisterListener(l);
};
});
const generatePort = (port: DefaultPortModel) => {
return (
<DefaultPortLabel
engine={props.engine}
port={port}
key={port.getID()}
/>
);
};
const ports_in = _.map(props.node.getInPorts(), generatePort);
const ports_out = _.map(props.node.getOutPorts(), generatePort);
const theme = useTheme();
const textColor = theme.palette.text.primary;
const ports_top =
ports_in.length === 0 ? null : (
<PortsTop key="ports" color={'transparent'} textColor={textColor}>
<PortsContainerUTXOTop key="inputs">
{ports_in}
</PortsContainerUTXOTop>
</PortsTop>
);
const ports_bottom =
ports_out.length === 0 ? null : (
<PortsBottom
color={theme.palette.secondary.light}
textColor={theme.palette.secondary.contrastText}
>
<PortsContainerUTXOBottom key="outputs">
{ports_out}
</PortsContainerUTXOBottom>
</PortsBottom>
);
const is_continuable = !has_continuations ? null : (
<div
style={{
background: theme.palette.info.light,
color: theme.palette.info.contrastText,
textAlign: 'center',
}}
>
UPDATABLE
</div>
);
const reachable_cl = is_reachable ? 'reachable' : 'unreachable';
const colorObj = Color(props.node.getOptions().color);
const color = colorObj.alpha(0.2).toString();
const opts = props.node.getOptions();
const is_selected =
selected_entity_id[0] === 'UTXO' &&
selected_entity_id[1].hash === opts.txid &&
selected_entity_id[1].nIn === opts.index;
return (
<div>
{ports_top}
<div style={{ position: 'relative' }}>
<UTXONode
data-default-utxonode-name={props.node.getOptions().name}
key={id}
selected={is_selected}
className={reachable_cl}
>
<Title color={color} textColor={textColor}>
<TitleName>{props.node.getOptions().name}</TitleName>
</Title>
{is_continuable}
<ConfirmationWidget t={props.node.getOptions().txid} />
<Title color={color} textColor={textColor}>
<TitleName>{PrettyAmount(amount)}</TitleName>
</Title>
{ports_bottom}
</UTXONode>
</div>
</div>
);
}
Example #26
Source File: Extensions.tsx From Tachidesk-WebUI with Mozilla Public License 2.0 | 4 votes |
export default function MangaExtensions() {
const { setTitle, setAction } = useContext(NavbarContext);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownExtensionLangs', extensionDefaultLangs());
const [showNsfw] = useLocalStorage<boolean>('showNsfw', true);
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const [query] = useQueryParam('query', StringParam);
useEffect(() => {
setTitle('Extensions');
setAction(
<>
<AppbarSearch />
<IconButton
onClick={
() => document.getElementById('external-extension-file')?.click()
}
size="large"
>
<AddIcon />
</IconButton>
<LangSelect
shownLangs={shownLangs}
setShownLangs={setShownLangs}
allLangs={allLangs}
/>
</>,
);
}, [shownLangs]);
const [extensionsRaw, setExtensionsRaw] = useState<IExtension[]>([]);
const [updateTriggerHolder, setUpdateTriggerHolder] = useState(0); // just a hack
const triggerUpdate = () => setUpdateTriggerHolder(updateTriggerHolder + 1); // just a hack
useEffect(() => {
client.get('/api/v1/extension/list')
.then((response) => response.data)
.then((data) => setExtensionsRaw(data));
}, [updateTriggerHolder]);
const [toasts, makeToast] = makeToaster(useState<React.ReactElement[]>([]));
const submitExternalExtension = (file: File) => {
if (file.name.toLowerCase().endsWith('apk')) {
const formData = new FormData();
formData.append('file', file);
// empty the input
// @ts-ignore
document.getElementById('external-extension-file').value = null;
makeToast('Installing Extension File....', 'info');
client.post('/api/v1/extension/install',
formData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(() => {
makeToast('Installed extension successfully!', 'success');
triggerUpdate();
})
.catch(() => makeToast('Extension installion failed!', 'error'));
} else {
makeToast('invalid file type!', 'error');
}
};
const dropHandler = async (e: Event) => {
e.preventDefault();
const files = await fromEvent(e);
submitExternalExtension(files[0] as File);
};
const dragOverHandler = (e: Event) => {
e.preventDefault();
};
useEffect(() => {
document.addEventListener('drop', dropHandler);
document.addEventListener('dragover', dragOverHandler);
const changeHandler = async (evt: Event) => {
const files = await fromEvent(evt);
submitExternalExtension(files[0] as File);
};
const input = document.getElementById('external-extension-file');
input?.addEventListener('change', changeHandler);
return () => {
document.removeEventListener('drop', dropHandler);
document.removeEventListener('dragover', dragOverHandler);
input?.removeEventListener('change', changeHandler);
};
}, [extensionsRaw]); // useEffect only after <input> renders
if (extensionsRaw.length === 0) {
return <LoadingPlaceholder />;
}
const filtered = extensionsRaw.filter((ext) => {
const nsfwFilter = showNsfw || !ext.isNsfw;
if (!query) return nsfwFilter;
return nsfwFilter && ext.name.toLowerCase().includes(query.toLowerCase());
});
const combinedShownLangs = ['installed', 'updates pending', 'all', ...shownLangs];
const groupedExtensions: [string, IExtension[]][] = groupExtensions(filtered)
.filter((group) => group[EXTENSIONS].length > 0)
.filter((group) => combinedShownLangs.includes(group[LANGUAGE]));
const flatRenderItems: (IExtension | string)[] = groupedExtensions.flat(2);
return (
<>
{toasts}
<input
type="file"
id="external-extension-file"
style={{ display: 'none' }}
/>
<Virtuoso
style={{
height: isMobile ? 'calc(100vh - 64px - 64px)' : 'calc(100vh - 64px)',
}}
totalCount={flatRenderItems.length}
itemContent={(index) => {
if (typeof (flatRenderItems[index]) === 'string') {
const item = flatRenderItems[index] as string;
return (
<Typography
key={item}
variant="h2"
style={{
paddingLeft: 25,
paddingBottom: '0.83em',
paddingTop: '0.83em',
backgroundColor: 'rgb(18, 18, 18)',
fontSize: '2em',
fontWeight: 'bold',
}}
>
{langCodeToName(item)}
</Typography>
);
}
const item = flatRenderItems[index] as IExtension;
return (
<ExtensionCard
key={item.apkName}
extension={item}
notifyInstall={() => {
triggerUpdate();
}}
/>
);
}}
/>
</>
);
}
Example #27
Source File: UTXODetail.tsx From sapio-studio with Mozilla Public License 2.0 | 4 votes |
export function UTXODetailInner(props: UTXODetailProps) {
const theme = useTheme();
const dispatch = useDispatch();
const select_continuations = useSelector(selectContinuation);
const opts = props.entity.getOptions();
const txid = opts.txn.get_txid();
const idx = opts.utxo.index;
const object_metadata = props.contract.object_metadata[`${txid}:${idx}`];
const outpoint = { hash: txid, nIn: idx };
const external_utxo = useSelector(selectUTXO)(outpoint);
const flash = useSelector(selectUTXOFlash);
const this_is_mock = is_mock_outpoint(outpoint);
const is_confirmed = external_utxo && external_utxo.confirmations > 0;
const decomp =
external_utxo?.scriptPubKey.address ??
Bitcoin.script.toASM(
Bitcoin.script.decompile(opts.utxo.script) ?? Buffer.from('')
);
// first attempt to get the address from the extenral utxo if it's present,
// otherwise attempt to read if from the utxo model
let address = external_utxo?.scriptPubKey.address;
let asm = external_utxo?.scriptPubKey.asm ?? null;
if (!address) {
address = 'UNKNOWN';
try {
asm = Bitcoin.script.toASM(opts.utxo.script);
address = Bitcoin.address.fromOutputScript(
opts.utxo.script,
/// TODO: Read from preferences?
Bitcoin.networks.regtest
);
} catch {
// TODO: Recovery?
}
}
const spends = opts.utxo.spends.map((elt, i) => (
<div key={get_wtxid_backwards(elt.tx)} className="Spend">
<Hex value={elt.get_txid()} label="TXID" />
<Tooltip title="Go To The Spending Transaction">
<IconButton
aria-label="goto-spending-txn"
onClick={() => dispatch(select_txn(elt.get_txid()))}
>
<DoubleArrowIcon style={{ color: green[500] }} />
</IconButton>
</Tooltip>
</div>
));
const creator =
!this_is_mock || is_confirmed ? null : (
<Tooltip title="Create Contract">
<IconButton
aria-label="create-contract"
onClick={() =>
dispatch(
create(opts.txn.tx, props.entity, props.contract)
)
}
>
<AddCircleOutlineIcon style={{ color: green[500] }} />
</IconButton>
</Tooltip>
);
const check_exists =
this_is_mock || is_confirmed ? null : (
<Tooltip title="Check if Coin Exists">
<IconButton
aria-label="check-coin-exists"
onClick={() => dispatch(fetch_utxo(outpoint))}
>
<CloudDownloadIcon style={{ color: purple[500] }} />
</IconButton>
</Tooltip>
);
const title =
opts.txn instanceof PhantomTransactionModel ? (
<p>External UTXO</p>
) : (
<PrettyAmountField amount={opts.utxo.amount} />
);
const obj = select_continuations(`${txid}:${idx}`);
const continuations = obj
? Object.entries(obj).map(([k, v]) => {
return <ContinuationOption key={k} v={v} />;
})
: null;
const cont = continuations ? (
<div>
<Typography variant="h5" color={theme.palette.text.primary}>
Continuations
</Typography>
{continuations}
</div>
) : null;
return (
<div className="UTXODetail">
<div>{flash}</div>
<div>
{creator}
{check_exists}
</div>
{title}
{cont}
{object_metadata && (
<OutputMetadataTable metadata={object_metadata} />
)}
<OutpointDetail txid={txid} n={idx} />
<ASM className="txhex" value={address} label="Address" />
<ASM className="txhex" value={asm ?? 'UNKNOWN'} label="ASM" />
{asm}
<Typography variant="h5" color={theme.palette.text.primary}>
Spent By
</Typography>
{spends}
</div>
);
}
Example #28
Source File: SlideFadeTransition.tsx From firecms with MIT License | 4 votes |
SlideFade = React.forwardRef(function SlideFade(props: SlideProps, ref) {
const {
children,
in: inProp,
timeout,
onExitAnimation,
...other
} = props;
const theme: any = useTheme();
const childrenRef = React.useRef<any>(null);
const handleRefIntermediary = useForkRef(children.ref, childrenRef);
const handleRef = useForkRef(handleRefIntermediary, ref);
const normalizedTransitionCallback = (callback: any) => (isAppearing: boolean) => {
if (callback) {
// onEnterXxx and onExitXxx callbacks have a different arguments.length value.
if (isAppearing === undefined) {
callback(childrenRef.current);
} else {
callback(childrenRef.current, isAppearing);
}
}
};
const handleEnter = normalizedTransitionCallback((node: any) => {
setTranslateValue(node);
reflow(node);
});
const handleEntering = normalizedTransitionCallback((node: any) => {
const transitionProps = getTransitionProps(
{ timeout },
{
mode: "enter"
}
);
node.style.webkitTransition = theme.transitions.create("-webkit-transform", {
...transitionProps,
easing: theme.transitions.easing.easeOut
});
node.style.transition = theme.transitions.create("transform", {
...transitionProps,
easing: theme.transitions.easing.easeOut
});
node.style.webkitTransform = "none";
node.style.transform = "none";
node.style.opacity = 1;
});
const handleExit: any = normalizedTransitionCallback((node: any) => {
const transitionProps = getTransitionProps(
{ timeout },
{
mode: "exit"
}
);
node.style.opacity = 0.5;
node.style.webkitTransition = theme.transitions.create(["-webkit-transform", "opacity"], {
...transitionProps,
easing: theme.transitions.easing.sharp
});
node.style.transition = theme.transitions.create(["transform", "opacity"], {
...transitionProps,
easing: theme.transitions.easing.sharp
});
setTranslateValue(node);
});
const handleExited: any = normalizedTransitionCallback((node: any) => {
// No need for transitions when the component is hidden
node.style.webkitTransition = "";
node.style.transition = "";
});
const updatePosition = React.useCallback(() => {
if (childrenRef.current) {
setTranslateValue(childrenRef.current);
}
}, []);
React.useEffect(() => {
// Skip configuration where the position is screen size invariant.
if (inProp) {
return undefined;
}
const handleResize = debounce(() => {
if (childrenRef.current) {
setTranslateValue(childrenRef.current);
}
});
const containerWindow = ownerWindow(childrenRef.current);
containerWindow.addEventListener("resize", handleResize);
return () => {
handleResize.clear();
containerWindow.removeEventListener("resize", handleResize);
};
}, [inProp]);
React.useEffect(() => {
if (!inProp) {
// We need to update the position of the drawer when the direction change and
// when it's hidden.d
updatePosition();
}
}, [inProp, updatePosition]);
return (
<Transition
nodeRef={childrenRef}
onEnter={handleEnter}
onEntering={handleEntering}
onExit={handleExit}
onExited={handleExited}
appear={true}
in={inProp}
timeout={timeout}
{...other}
>
{((state: any, childProps: any) => {
return React.cloneElement(children, {
ref: handleRef,
style: {
visibility: state === "exited" && !inProp ? "hidden" : undefined,
...children.props.style
},
...childProps
});
}) as any}
</Transition>
);
})
Example #29
Source File: DocsDetails.tsx From ui-schema with MIT License | 4 votes |
DocContent: React.FC<{
content: string | undefined
id: string
progress: string
doc?: DocRouteModule
}> = ({content, id, progress, doc}) => {
const {palette} = useTheme()
const [loadingModuleDocs, setLoadingModuleDocs] = React.useState<boolean>(false)
const [fullWidth, setFullWidth] = React.useState(window.localStorage.getItem('docs-details--fullWidth') === 'yes')
const [modules, setModules] = React.useState<any>(undefined)
const {breakpoints} = useTheme()
const isLg = useMediaQuery(breakpoints.up('lg'))
const module = doc?.docModule
React.useEffect(() => {
if (!module || (module && moduleDocsCache.current[module.modulePath])) {
setModules(module ? moduleDocsCache.current[module.modulePath] : undefined)
setLoadingModuleDocs(false)
return
}
setLoadingModuleDocs(true)
fetch('/docs/' + module.package + '/' + module.fromPath + '.json')
.then((res) => res.status !== 200 ? Promise.reject(res) : res.json())
.then((data) => {
moduleDocsCache.current[module.modulePath] = data
setModules(data)
setLoadingModuleDocs(false)
})
.catch(e => {
console.error('error loading module-api docs', module, e)
setLoadingModuleDocs(false)
})
return () => setModules(undefined)
}, [module])
const mdData = React.useMemo(() => {
if (!content) return undefined
const lines: string[] = content.split('\n')
// todo: add correct front-matter extraction, but e.g. `front-matter` is no longer maintained/browser-optimized
if (lines[0] === '---') {
const i = lines.slice(1).findIndex((l: string) => l === '---')
if (i !== -1) {
lines.splice(0, i + 2)
}
}
return lines.join('\n')
}, [content])
return <>
<PageContent maxWidth={isLg && fullWidth ? 'xl' : 'md'} style={{flexGrow: 1}}>
<div style={{display: 'flex', alignItems: 'center', margin: '4px 12px'}}>
{isLg ?
<Button
onClick={() => {
setFullWidth(f => {
const n = !f
window.localStorage.setItem('docs-details--fullWidth', n ? 'yes' : 'no')
return n
})
}}
color={'secondary'} size={'small'}
>
{fullWidth ? <IcShowCompact style={{transform: 'rotate(90deg)'}}/> : <IcShowFull style={{transform: 'rotate(90deg)'}}/>}
</Button> : null}
<Typography variant={'body2'} style={{marginLeft: 'auto'}}>
<Link
target={'_blank'} rel="noreferrer noopener nofollow"
href={'https://github.com/ui-schema/ui-schema/tree/develop/packages/docs/src/content/' + id + '.md'}
>Edit Page</Link>
</Typography>
</div>
<Paper style={{margin: '0 0 12px 0', padding: 24, display: 'flex', flexDirection: 'column', borderRadius: 5}} variant={'outlined'}>
{progress === 'start' || progress === 'progress' || loadingModuleDocs ?
<LoadingCircular title={'Loading Docs'}/> :
progress === 'error' ?
'error' :
progress === 'not-found' ?
<PageNotFound
title={'Not Available'}
error={'This document seems to be vanished - or not yet created.'}
/> :
<Markdown source={mdData}/>}
</Paper>
{progress === 'success' && !loadingModuleDocs ?
<>
{doc?.demos?.schema ?
<div style={{display: 'block', textAlign: 'right', margin: '0 12px 4px 12px'}}>
<Typography variant={'body2'} style={{marginLeft: 'auto'}}>
<Link
target={'_blank'} rel="noreferrer noopener nofollow"
href={'https://github.com/ui-schema/ui-schema/tree/develop/packages/docs/src/content/' + id + 'Demo.js'}
>Edit Demos</Link>
</Typography>
</div> : null}
{doc?.demos?.schema ?
<Paper style={{marginBottom: 12, padding: 24, display: 'flex', flexDirection: 'column', borderRadius: 5}} variant={'outlined'}>
<Markdown
source={`
## Demo UI Generator
Examples of this widget, using \`ds-material\`. Type in/change the input and check the data or change the schema (e.g. add specific keywords from above), the demo generators are showing invalid directly.
`}/>
{doc?.demos?.schema.map(([demoText, demoSchema], i) =>
<React.Fragment key={i}>
<Markdown source={demoText}/>
<DemoUIGenerator activeSchema={demoSchema} id={'i-' + i}/>
</React.Fragment>)}
</Paper>
: null}
{doc?.docModule ?
<Paper style={{margin: '12px 0', padding: 24, display: 'flex', flexDirection: 'column', borderRadius: 5}} variant={'outlined'}>
<DocsDetailsModules modules={modules}/>
</Paper> : null}
</> : null}
</PageContent>
<Paper
style={{
margin: '0 12px',
// padding: '0 12px',
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
opacity: progress === 'success' ? 1 : 0,
transition: '0.32s opacity ease-out',
flexShrink: 0,
position: 'sticky',
bottom: 12,
left: 0,
right: 0,
zIndex: 10,
maxHeight: '85vh',
maxWidth: 375,
borderRadius: 5,
//borderTop: '1px solid ' + palette.primary.main,
//background: palette.primary.main,
boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)',
}}
// elevation={4}
variant={'outlined'}
>
<LinkableHeadlineMenu
disableNavLink
//style={{margin: 0, padding: 0}}
startIcon={<IcToc/>}
titleStyle={{color: palette.background.paper, fontWeight: 'bold', background: palette.primary.main}}
btnVariant={'contained'}
disablePadding
bindKey={'m'}
linkListStyle={{display: 'flex', flexDirection: 'column', overflow: 'auto'}}
// collapseStyle={{overflow: 'auto'}}
//linkItemStyle={{color: palette.background.paper}}
/>
</Paper>
</>
}