@mui/icons-material#Send TypeScript Examples
The following examples show how to use
@mui/icons-material#Send.
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: Terminal.tsx From NekoMaid with MIT License | 4 votes |
Terminal: React.FC = () => {
const logs = useMemo<JSX.Element[]>(() => [], [])
const ref = useRef<HTMLDivElement | null>(null)
const plugin = usePlugin()
const [, update] = useState(0)
const [open, setOpen] = useState(false)
const [command, setCommand] = useState('')
const [suggestions, setSuggestions] = useState<Array<[string, boolean] | [string]>>([])
const getSuggestions = useMemo(() => throttle(
(it: string) => {
let cmd = it.substr(0, it.lastIndexOf(' '))
if (cmd) cmd += ' '
return plugin.emit('console:complete', (data: string[] = []) => {
setSuggestions(JSON.parse(localStorage.getItem(`NekoMaid:${address}:commandHistory`) || '[]').concat(data.map(c => [cmd + c] as [string])))
}, it)
},
500
), [])
const scrollToEnd = useMemo(() => throttle(
(elm: HTMLDivElement) => {
const select = (window.getSelection || document.getSelection)()
if (select && !select.isCollapsed) {
let node = select?.anchorNode
while (node && node !== document) {
if (node === elm) return
node = node.parentNode
}
}
if (elm) elm.lastElementChild?.scrollIntoView()
},
300
), [])
const execCommand = () => {
if (!command) return
plugin.emit('console:run', action, command)
const arr = JSON.parse(localStorage.getItem(`NekoMaid:${address}:commandHistory`) || '[]').filter((it: [string]) => it[0] !== command)
if (arr.length === 5) arr.pop()
arr.unshift([command, true])
localStorage.setItem(`NekoMaid:${address}:commandHistory`, JSON.stringify(arr))
setCommand('')
}
useEffect(() => {
const runCommand = (it: string) => plugin.emit('console:run', action, it)
let lastLog: Log = {} as any
const onLog = (data: Log) => {
if (lastLog.logger === data.logger && (lastLog.time / 100 | 0) === (data.time / 100 | 0) &&
lastLog.level === data.level && (!lastLog.components === !data.components)) {
logs.pop()
if (data.components) {
lastLog.components!.push(null as any)
lastLog.components = lastLog.components!.concat(data.components)
} else lastLog.msg += '\n' + data.msg
data = lastLog
} else lastLog = data
logs.push(parseLog(data, runCommand, setCommand))
update(++i)
}
const offLogs = plugin.on('console:logs', (it: Log[]) => {
logs.length = 0
it.forEach(onLog)
})
const offLog = plugin.on('console:log', onLog)
plugin.switchPage('console')
return () => {
offLogs()
offLog()
}
}, [])
useEffect(() => { ref.current && scrollToEnd(ref.current) }, [logs[logs.length - 1]])
return <Box sx={{
width: '100%',
height: '100vh',
overflow: 'hidden',
display: 'flex',
fontSize: '0.91rem',
flexDirection: 'column',
fontFamily: '"Roboto Mono","Helvetica","Arial",sans-serif',
'& p': {
margin: 0,
whiteSpace: 'pre-wrap',
wordBreak: 'break-word',
display: 'flex',
'& .msg': {
flex: '1'
},
'& .logger': {
color: theme => theme.palette.secondary.main,
fontStyle: 'italic'
},
'& .level': {
userSelect: 'none',
height: 'fit-content',
fontWeight: 'bolder',
cursor: 'pointer',
color: theme => theme.palette.primary.main
},
'& .white': {
textShadow: theme => theme.palette.mode === 'light' ? '#000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0' : undefined
},
'& .black': {
textShadow: theme => theme.palette.mode === 'dark' ? '#fff 1px 0 0, #fff 0 1px 0, #fff -1px 0 0, #fff 0 -1px 0' : undefined
},
'& .more': {
color: theme => theme.palette.secondary.main,
marginRight: '4px',
cursor: 'pointer',
textDecoration: 'underline'
}
},
'& .warn, & .warn .level': {
color: theme => theme.palette.warning.main
},
'& .error, & .error .level': {
color: theme => theme.palette.error.main
}
}}>
<Toolbar />
<Box
ref={ref}
sx={{
height: '100%',
overflow: 'hidden scroll',
backgroundColor: theme => theme.palette.background.default,
padding: theme => theme.spacing(1)
}}>
{logs}
</Box>
<Paper sx={{
display: 'flex',
borderRadius: '4px 4px 0 0',
padding: theme => theme.spacing(1),
zIndex: 2
}}>
<Autocomplete
freeSolo
open={open}
inputValue={command}
options={suggestions}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
onFocus={() => getSuggestions(command)}
onKeyUp={(e: any) => e.key === 'Enter' && (!open || !suggestions.length) && execCommand()}
sx={{ flex: '1' }}
classes={{ popper: 'command-popper' }}
renderInput={params => <TextField {...params as any} label={lang.terminal.command} />}
getOptionLabel={it => typeof it === 'string' ? it : it[0]}
groupBy={it => it[1] ? lang.history : lang.terminal.command}
onInputChange={(_, it) => {
getSuggestions(it)
setCommand(it)
}}
/>
<IconButton
color='primary'
disabled={!command}
onClick={execCommand}
sx={{ margin: theme => theme.spacing('auto', 0, 'auto', 1) }}
><Send /></IconButton>
</Paper>
</Box>
}