@material-ui/core#InputBase TypeScript Examples
The following examples show how to use
@material-ui/core#InputBase.
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: SearchBar.tsx From log4brains with Apache License 2.0 | 6 votes |
export function SearchBar(props: SearchBarProps) {
const { InputProps, InputLabelProps, open, onClear, ...params } = props;
const classes = useStyles(props);
return (
<InputBase
placeholder="Search..."
classes={{
root: classes.inputRoot,
input: classes.inputInput
}}
startAdornment={
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
}
endAdornment={
// eslint-disable-next-line react/destructuring-assignment
<Fade in={open && props.inputProps.value !== ""}>
<InputAdornment position="end">
<IconButton
onClick={(event) => onClear(event)}
size="small"
title="Clear"
className={classes.clearIcon}
>
<ClearIcon />
</IconButton>
</InputAdornment>
</Fade>
}
ref={InputProps.ref}
{...params}
/>
);
}
Example #2
Source File: actionbar-search-field.tsx From mtcute with GNU Lesser General Public License v3.0 | 6 votes |
export function ActionBarSearchField(
params: Partial<InputBaseProps> & { inputRef?: React.Ref<any> }
): React.ReactElement {
const classes = useStyles()
return (
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
ref={params.inputRef}
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'search' }}
{...params}
/>
</div>
)
}
Example #3
Source File: HubSortDropdown.tsx From dashboard with Apache License 2.0 | 6 votes |
HubSortDropdown = ({
selectedSortOption,
sortOptions,
handleSortOption,
}: Props) => {
return (
<FormControl>
<SortLabel shrink>Sort</SortLabel>
<SortSelect
value={selectedSortOption}
onChange={handleSortOption}
input={<InputBase />}
data-name={`selectedHubSortDropdown-${selectedSortOption.replaceAll(
" ",
"_"
)}`}
>
{sortOptions.map((sortOption) => (
<MenuItem
data-name={`sortOptionHubSortDropdown-${sortOption.replaceAll(
" ",
"_"
)}`}
value={sortOption}
>
{sortOption}
</MenuItem>
))}
</SortSelect>
</FormControl>
)
}
Example #4
Source File: index.tsx From GroupChat with MIT License | 6 votes |
Search: React.FC<Props> = props => {
const [searchValue, setSearchValue] = useState('');
const searchHandler = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setSearchValue(e.target.value);
const allGroups = props.groups;
const filteredGroups: Group[] = allGroups.filter(grp =>
grp.title.toLowerCase().includes(e.target.value.toLowerCase())
);
props.update(filteredGroups);
};
return (
<div className={styles.container}>
<IconButton className={styles.iconButton}>
<SearchIcon className={styles.search} />
</IconButton>
<InputBase
className={styles.input}
placeholder="Search..."
onChange={e => searchHandler(e)}
value={searchValue}
/>
</div>
);
}
Example #5
Source File: SenderFilterInput.tsx From parity-bridges-ui with GNU General Public License v3.0 | 6 votes |
export default function SenderFilterInput({ handleChange }: Props) {
const classes = useStyles();
return (
<div className={classes.box}>
<SelectLabel>Sender</SelectLabel>
<Box display="flex" alignItems="center">
<AccountIdenticon />
<InputBase
placeholder="select address or start typing"
onChange={handleChange}
fullWidth
className={classes.input}
/>
<ArrowDropUp color="primary" />
</Box>
</div>
);
}
Example #6
Source File: DatePicker.tsx From backstage with Apache License 2.0 | 6 votes |
BootstrapInput = withStyles((theme: Theme) =>
createStyles({
root: {
margin: `${theme.spacing(1)} 0px`,
maxWidth: 300,
'label + &': {
marginTop: theme.spacing(3),
},
},
input: {
borderRadius: 4,
position: 'relative',
backgroundColor: theme.palette.background.paper,
border: '1px solid #ced4da',
fontSize: 16,
padding: '10px 26px 10px 12px',
transition: theme.transitions.create(['border-color', 'box-shadow']),
fontFamily: 'Helvetica Neue',
height: 25,
'&:focus': {
background: theme.palette.background.paper,
borderRadius: 4,
},
},
}),
)(InputBase)
Example #7
Source File: ExpandingSearchbar.tsx From dashboard with Apache License 2.0 | 6 votes |
function ExpandingSearchbar({ onSearch, value, onChange }: Props) {
const handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter") {
onSearch && onSearch(value)
}
}
const clearSearch = () => {
onSearch && onSearch("")
}
const SearchBar = styled.div`
display: flex;
background-color: ${(props) => props.theme.palette.grey[100]};
border-radius: 2px;
`
return (
<SearchBar>
<IconButton type="submit" onClick={() => onSearch && onSearch(value)}>
<SearchIcon />
</IconButton>
<InputBase
autoFocus={true}
onChange={(e) => onChange(e.target.value)}
defaultValue={value}
placeholder="Search"
onKeyPress={handleKeyPress}
/>
{value && (
<IconButton onClick={clearSearch}>
<CancelIcon />
</IconButton>
)}
</SearchBar>
)
}
Example #8
Source File: ReceiverInput.tsx From parity-bridges-ui with GNU General Public License v3.0 | 6 votes |
// TODO: To refactor state management for this component #160
function ReceiverInput() {
const classes = useStyles();
const { onReceiverChange } = useReceiver();
const { unformattedReceiverAddress, formatFound, showBalance, transactionToBeExecuted } = useTransactionContext();
const { api, address } = useApiBalance(unformattedReceiverAddress, formatFound, false);
const state = useBalance(api, address, true);
const addressInput = unformattedReceiverAddress || '';
return (
<div className={classes.accountMain}>
<SelectLabel>Receiver</SelectLabel>
<Box display="flex" alignItems="center">
<AccountIdenticon address={addressInput} formatFound={formatFound} />
<InputBase
id="test-receiver-input"
className={classes.address}
fullWidth
onChange={onReceiverChange}
autoComplete="off"
value={addressInput}
placeholder="Recipient address"
disabled={transactionToBeExecuted}
/>
{showBalance && state && <Balance balance={state.formattedBalance} id="test-receiver-balance" />}
</Box>
</div>
);
}
Example #9
Source File: DashboardHeaderPageButton.tsx From neodash with Apache License 2.0 | 5 votes |
NeoPageButton = ({ title, disabled = false, selected = false, onSelect, onRemove, onTitleUpdate }) => {
// TODO - debounce page title update
const [modalOpen, setModalOpen] = React.useState(false);
const handleClose = () => {
setModalOpen(false);
};
const [titleText, setTitleText] = React.useState(title);
useEffect(() => {
// Reset text to the dashboard state when the page gets reorganized.
if (titleText !== title) {
setTitleText(title);
}
}, [title])
const content = (
<>
<Grid style={{ height: "100%" }}
onClick={onSelect}
container spacing={1} alignItems="flex-end">
<Grid item key={1} style={{ width: "100%" }}>
<InputBase
value={titleText}
onChange={(event) => {
if (disabled) {
return;
}
onTitleUpdate(event);
setTitleText(event.target.value);
}}
onFocus={(e) => {
if (disabled) {
e.preventDefault();
e.stopPropagation();
}
}}
readOnly={disabled}
inputProps={{ style: { textTransform: 'none', cursor: 'pointer', fontWeight: 'normal' } }}
style={{ height: "36px", width: "100%", paddingLeft: "10px", color: selected ? 'black' : '#888', textAlign: "center", textTransform: "uppercase" }}
placeholder="Page name..."
/>
</Grid>
</Grid>
<div style={{position: "absolute", top: 5, right: 0, paddingRight: 3, background: selected ? "white" : "transparent"}}>
{(selected && !disabled) ? <IconButton size="medium" style={{ padding: "5px", color: "white" }} aria-label="move left" onClick={() => setModalOpen(true)}>
<CloseIcon color="disabled" />
</IconButton> : <IconButton size="medium" style={{ opacity: 0, padding: "5px", color: "white" }} aria-label="move left"
onClick={(event) => null}>
<CloseIcon color="disabled" />
</IconButton>}
</div>
<NeoDeletePageModal modalOpen={modalOpen} onRemove={onRemove} handleClose={handleClose}></NeoDeletePageModal>
</>
);
return content;
}
Example #10
Source File: HubNavigationBar.tsx From dashboard with Apache License 2.0 | 5 votes |
export default function HubNavigationBar({
handleChange,
handleSearch,
tabNumber,
}: Props) {
let [searchString, setSearchString] = useState("")
const NavItems = ["Hub Explore", "Hub List", "My Images", "My Favourites"]
const SearchBar = styled.div`
background-color: ${(props) => props.theme.palette.grey[100]};
border-radius: 2px;
cursor: pointer;
min-width: 350px;
display: flex;
`
const HubTabs = styled(Tabs)`
flex-grow: 1;
`
const HubSearchIcon = styled(SearchIcon)`
margin: 11px;
margin-left: 20px;
`
const handleKeyPress = (event: KeyboardEvent<HTMLDivElement>) => {
if (event.key === "Enter") handleSearch(searchString)
}
return (
<AppBar elevation={0} position={"static"}>
<Toolbar>
<HubTabs
value={tabNumber}
onChange={handleChange}
aria-label="simple tabs example"
textColor="secondary"
indicatorColor="secondary"
>
{NavItems.map((NavItem, idx) => (
<Tab label={NavItem} {...a11yProps(idx)} />
))}
</HubTabs>
<SearchBar>
<HubSearchIcon onClick={(e) => handleSearch(searchString)} />
<InputBase
onKeyPress={handleKeyPress}
autoFocus={true} //todo this is a hack. It looses focus after setSearchString gets triggered
value={searchString}
onChange={(e) => setSearchString(e.target.value)}
placeholder="Search"
fullWidth={true}
/>
</SearchBar>
</Toolbar>
</AppBar>
)
}
Example #11
Source File: DashboardHeaderTitleBar.tsx From neodash with Apache License 2.0 | 5 votes |
NeoDashboardHeaderTitleBar = ({ dashboardTitle, downloadImageEnabled, onDownloadImage, open, setDashboardTitle, connection, editable, standalone, handleDrawerOpen, onConnectionModalOpen }) => {
const [dashboardTitleText, setDashboardTitleText] = React.useState(dashboardTitle);
const debouncedDashboardTitleUpdate = useCallback(
debounce(setDashboardTitle, 250),
[],
);
useEffect(() => {
// Reset text to the dashboard state when the page gets reorganized.
if (dashboardTitle !== dashboardTitleText) {
setDashboardTitleText(dashboardTitle);
}
}, [dashboardTitle])
const content = <Toolbar key={1} style={{ paddingRight: 24, minHeight: "64px", background: '#0B297D', zIndex: 1201 }}>
{!standalone ? <IconButton
edge="start"
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
style={
(open) ? {
display: 'none',
} : {
marginRight: 36,
marginLeft: -19,
}
}
>
<MenuIcon />
</IconButton> : <></>}
<InputBase
id="center-aligned"
style={{ textAlign: 'center', fontSize: "22px", flexGrow: 1, color: "white" }}
placeholder="Dashboard Name..."
fullWidth
maxRows={4}
value={dashboardTitleText}
onChange={(event) => {
if (editable) {
setDashboardTitleText(event.target.value);
debouncedDashboardTitleUpdate(event.target.value);
}
}}
/>
{downloadImageEnabled ? <Tooltip title={"Download Dashboard as Image"}>
<IconButton style={{background: "#ffffff22", padding: "3px", marginRight: "3px"}} onClick={(e) => onDownloadImage()}>
<ImageIcon style={{ padding: 6, color: "#ffffffdd", width: "36px", height: "36px", fontSize: "1.3rem", zIndex: 5 }} fontSize="small">
</ImageIcon>
</IconButton>
</Tooltip> : <></>}
<Tooltip title={connection.protocol + "://" + connection.url + ":" + connection.port} placement="left" aria-label="host">
<IconButton style={{ background: "#ffffff22", padding: "3px" }} onClick={(e) => {
if (!standalone) {
onConnectionModalOpen();
}
}}>
<Badge badgeContent={""} >
<img style={{ width: "36px", height: "36px" }} src="neo4j-icon.png" />
</Badge>
</IconButton>
</Tooltip>
</Toolbar>;
return content;
}
Example #12
Source File: DashboardPlaceholder.tsx From neodash with Apache License 2.0 | 5 votes |
NeoDashboardPlaceholder = ({connected}) => {
const content = (
<div style={{zIndex: -99}}>
<AppBar position="absolute" style={{
zIndex: "auto",
boxShadow: "none",
transition: "width 125ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
}
}>
<Toolbar style={{ paddingRight: 24, minHeight: "64px", background: '#0B297D', zIndex: 1201 }}>
<IconButton
edge="start"
color="inherit"
aria-label="open drawer"
style={
(open) ? {
display: 'none',
} : {
marginRight: 36,
marginLeft: -19,
}
}
>
<MenuIcon />
</IconButton>
<InputBase
disabled
id="center-aligned"
label="placeholder"
style={{ textAlign: 'center', fontSize: "22px", flexGrow: 1, color: "white" }}
placeholder="Dashboard Name..."
fullWidth
maxRows={4}
value={"NeoDash ⚡"}
/>
</Toolbar>
<Toolbar style={{ zIndex: 10, minHeight: "50px", paddingLeft: "0px", paddingRight: "0px", background: "white" }}>
<div style={{
width: '100%', zIndex: -112, height: "48px", overflowX: "hidden", overflowY: "auto", background: "rgba(240,240,240)",
boxShadow: "2px 1px 10px 0px rgb(0 0 0 / 12%)",
borderBottom: "1px solid lightgrey"
}}>
</div>
</Toolbar>
</AppBar>
<div style={{
position: "absolute",
width: "100%",
height: "100%"
}}>
<Typography variant="h2" color="textSecondary" style={{
position: "absolute", top: "50%", left: "50%",
transform: "translate(-50%, -50%)"
}}>
{!connected ? <CircularProgress color="inherit" /> :<></>}
</Typography>
</div>
</div>
);
return content;
}
Example #13
Source File: SearchInput.tsx From baleen3 with Apache License 2.0 | 5 votes |
Input = styled(InputBase)({ flexGrow: 1, })
Example #14
Source File: DashboardSearchControls.tsx From clearflask with Apache License 2.0 | 5 votes |
render() {
return (
<div className={this.props.classes.search}>
<SearchIcon
className={this.props.classes.searchIcon}
color='inherit'
/>
<InputBase
className={this.props.classes.searchText}
placeholder={this.props.placeholder || 'Search'}
fullWidth
value={this.state.searchText || ''}
onChange={e => {
const newSearchText = e.target.value === '' ? undefined : e.target.value;
this.setState({ searchText: newSearchText });
this.onSearchChanged(newSearchText);
}}
/>
{this.props.filters && (
<>
<IconButton
className={this.props.classes.filterIcon}
onClick={() => this.setState({ filtersOpen: !this.state.filtersOpen })}
ref={this.filtersAnchorRef}
>
<FilterIcon />
</IconButton>
<ClosablePopper
anchorType='ref'
anchor={this.filtersAnchorRef}
closeButtonPosition='disable'
open={!!this.state.filtersOpen}
onClose={() => this.setState({ filtersOpen: false })}
placement='top'
arrow
clickAway
// Allow DatePicker modal to overlap this one
zIndex={this.props.theme.zIndex.modal}
>
{this.props.filters}
</ClosablePopper>
</>
)}
</div>
);
}
Example #15
Source File: CatalogKindHeader.tsx From backstage with Apache License 2.0 | 5 votes |
/** @public */
export function CatalogKindHeader(props: CatalogKindHeaderProps) {
const { initialFilter = 'component', allowedKinds } = props;
const classes = useStyles();
const catalogApi = useApi(catalogApiRef);
const { value: allKinds } = useAsync(async () => {
return await catalogApi
.getEntityFacets({ facets: ['kind'] })
.then(response => response.facets.kind?.map(f => f.value).sort() || []);
});
const {
updateFilters,
queryParameters: { kind: kindParameter },
} = useEntityList();
const queryParamKind = useMemo(
() => [kindParameter].flat()[0]?.toLocaleLowerCase('en-US'),
[kindParameter],
);
const [selectedKind, setSelectedKind] = useState(
queryParamKind ?? initialFilter,
);
useEffect(() => {
updateFilters({
kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,
});
}, [selectedKind, updateFilters]);
// Set selected Kind on query parameter updates; this happens at initial page load and from
// external updates to the page location.
useEffect(() => {
if (queryParamKind) {
setSelectedKind(queryParamKind);
}
}, [queryParamKind]);
// Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not
// be present in allKinds. It should still be shown in the dropdown, but may not have the nice
// enforced casing from the catalog-backend. This makes a key/value record for the Select options,
// including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the
// more proper catalog kind if it exists.
const availableKinds = [capitalize(selectedKind)].concat(
allKinds?.filter(k =>
allowedKinds
? allowedKinds.some(
a => a.toLocaleLowerCase('en-US') === k.toLocaleLowerCase('en-US'),
)
: true,
) ?? [],
);
const options = availableKinds.sort().reduce((acc, kind) => {
acc[kind.toLocaleLowerCase('en-US')] = kind;
return acc;
}, {} as Record<string, string>);
return (
<Select
input={<InputBase value={selectedKind} />}
value={selectedKind}
onChange={e => setSelectedKind(e.target.value as string)}
classes={classes}
>
{Object.keys(options).map(kind => (
<MenuItem value={kind} key={kind}>
{`${options[kind]}s`}
</MenuItem>
))}
</Select>
);
}
Example #16
Source File: index.tsx From GroupChat with MIT License | 5 votes |
MsgInput: React.FC<Props> = props => {
const [msg, setMsg] = useState('');
const getDateString = () => {
const monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
let dateObj = new Date();
let month = monthNames[dateObj.getMonth()];
let day = String(dateObj.getDate()).padStart(2, '0');
let output = month + ' ' + day + ',';
return `${output} - ${new Date().getHours()}:${new Date().getMinutes()}`;
};
const sendHandler = () => {
props.sendClick(msg, getDateString());
setMsg('');
};
return (
<div className={styles.container} onClick={props.onClick}>
<InputBase
className={styles.input}
placeholder="Write here..."
value={msg}
onChange={e => setMsg(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') sendHandler();
}}
/>
<IconButton className={styles.iconButton} onClick={sendHandler}>
<SendIcon className={styles.send} />
</IconButton>
</div>
);
}
Example #17
Source File: ClassicCipher.tsx From DamnVulnerableCryptoApp with MIT License | 5 votes |
ClassicCipher = (props: IChallengeProps) => {
const classes = useStyles();
const [answer, setAnswer] = useState("");
const [enigma, setEnigma] = useState("");
const [errorMessage, setErrorMessage] = useState("");
const layoutContext = useContext(LayoutContext);
const checkAnswer = (event: React.SyntheticEvent) => {
event.preventDefault();
layoutContext.setLoading(true);
setErrorMessage("");
ClassicService.checkAnswer(answer).then(res => {
const flag = res.flag;
props.setFlag(flag);
if (!res.success) setErrorMessage("Sorry, not quite there yet...");
layoutContext.setLoading(false);
}).catch(() => layoutContext.setLoading(false));
};
useEffect(() => {
layoutContext.setLoading(true);
ClassicService.init().then(data => {
setEnigma(data);
layoutContext.setLoading(false);
}).catch(() => layoutContext.setLoading(false));
}, []);
const onAnswerChange = (e: React.ChangeEvent<HTMLInputElement>) => setAnswer(e.target.value);
return (
<Box>
<Box className={classes.paper} boxShadow={3}>
<strong>{enigma}</strong>
</Box>
<Box className={classes.formContainer}>
<Typography>Decrypt the message and solve the riddle</Typography>
<Paper component="form" onSubmit={checkAnswer} >
<Box className={classes.inputContainer}>
<InputBase className={classes.input} fullWidth placeholder="[1,4,13,27,35,46,49,62,71]" onChange={onAnswerChange} />
<IconButton color="primary" type="submit">
<SendIcon />
</IconButton>
</Box>
{errorMessage ? <Alert severity="error">{errorMessage}</Alert> : <div />}
</Paper>
</Box>
</Box>
);
}
Example #18
Source File: ExpandableListItemInput.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 4 votes |
export default function ExpandableListItemKey({
label,
value,
onConfirm,
onChange,
confirmLabel,
confirmLabelDisabled,
expandedOnly,
helperText,
placeholder,
loading,
mapperFn,
locked,
}: Props): ReactElement | null {
const classes = useStyles()
const [open, setOpen] = useState(Boolean(expandedOnly))
const [inputValue, setInputValue] = useState<string>(value || '')
const toggleOpen = () => setOpen(!open)
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
if (mapperFn) {
e.target.value = mapperFn(e.target.value)
}
setInputValue(e.target.value)
if (onChange) onChange(e.target.value)
}
return (
<>
<ListItem className={`${classes.header} ${open ? classes.headerOpen : ''}`}>
<Grid container direction="column" justifyContent="space-between" alignItems="stretch">
<Grid container direction="row" justifyContent="space-between" alignItems="center">
{label && (
<Typography variant="body1" className={classes.unselectableLabel}>
{label}
</Typography>
)}
<Typography variant="body2">
<div>
{!open && value}
{!expandedOnly && !locked && (
<IconButton size="small" className={classes.copyValue}>
{open ? (
<Minus onClick={toggleOpen} strokeWidth={1} />
) : (
<Edit onClick={toggleOpen} strokeWidth={1} />
)}
</IconButton>
)}
</div>
</Typography>
</Grid>
<Collapse in={open} timeout="auto" unmountOnExit>
<InputBase
value={inputValue}
placeholder={placeholder}
onChange={handleChange}
fullWidth
className={classes.content}
autoFocus
hidden={locked}
/>
</Collapse>
</Grid>
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
{helperText && <ExpandableListItemNote>{helperText}</ExpandableListItemNote>}
<ExpandableListItemActions>
<SwarmButton
disabled={
loading ||
inputValue === value ||
Boolean(confirmLabelDisabled) || // Disable if external validation is provided
(inputValue === '' && value === undefined) // Disable if no initial value was not provided and the field is empty. The undefined check is improtant so that it is possible to submit with empty input in other cases
}
loading={loading}
iconType={Search}
onClick={() => {
if (onConfirm) onConfirm(inputValue)
}}
>
{confirmLabel || 'Save'}
</SwarmButton>
<SwarmButton
disabled={loading || inputValue === value || inputValue === ''}
iconType={X}
onClick={() => setInputValue(value || '')}
cancel
>
Cancel
</SwarmButton>
</ExpandableListItemActions>
</Collapse>
</>
)
}
Example #19
Source File: SearchBar.tsx From glific-frontend with GNU Affero General Public License v3.0 | 4 votes |
SearchBar: React.SFC<SearchBarProps> = (props) => {
const {
searchMode,
searchVal,
onReset,
endAdornment,
handleClick,
handleSubmit,
handleChange,
className,
} = props;
const [localSearchValue, setLocalSearchValue] = useState(searchVal);
const { t } = useTranslation();
// use local state value so that we can set the defaults correctly
// local value is needed for list component
let inputValue: any = '';
if (searchMode) {
inputValue = localSearchValue;
} else if (searchVal) {
inputValue = searchVal;
}
// display reset button only if value is entered
let resetButton = null;
if (inputValue) {
resetButton = (
<IconButton
data-testid="resetButton"
className={styles.ResetSearch}
onClick={() => {
setLocalSearchValue('');
onReset();
}}
>
<CloseIcon className={styles.CloseIcon} />
</IconButton>
);
}
let endAdornmentInput;
if (endAdornment) {
endAdornmentInput = (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={(e: any) => {
handleClick(e, 'search', 'update');
}}
>
<AdvancedSearch />
</IconButton>
</InputAdornment>
);
}
return (
<form onSubmit={handleSubmit} autoComplete="off" data-testid="searchForm">
<div className={`${styles.SearchBar} ${className}`}>
<div className={styles.IconAndText}>
<img src={searchIcon} className={styles.SearchIcon} alt="Search" />
<InputBase
data-testid="searchInput"
className={styles.SearchField}
name="searchInput" // This is important for extracting the search value in parent component.
placeholder={t('Search')}
onChange={(e: any) => {
setLocalSearchValue(e.target.value);
if (handleChange) {
handleChange(e);
}
}}
value={inputValue}
endAdornment={endAdornmentInput}
/>
</div>
{resetButton}
</div>
</form>
);
}
Example #20
Source File: NotesPanel.tsx From vscode-crossnote with GNU Affero General Public License v3.0 | 4 votes |
export function NotesPanel(props: Props) {
const classes = useStyles(props);
const { t } = useTranslation();
const [selectedSection, setSelectedSection] = useState<SelectedSection>(null);
const [selectedNote, setSelectedNote] = useState<Note>(null);
const [notes, setNotes] = useState<Note[]>([]);
const [searchValue, setSearchValue] = useState<string>("");
const [searchValueInputTimeout, setSearchValueInputTimeout] = useState<
NodeJS.Timeout
>(null);
const [finalSearchValue, setFinalSearchValue] = useState<string>("");
const [sortMenuAnchorEl, setSortMenuAnchorEl] = useState<HTMLElement>(null);
const [orderBy, setOrderBy] = useState<OrderBy>(OrderBy.ModifiedAt);
const [orderDirection, setOrderDirection] = useState<OrderDirection>(
OrderDirection.DESC
);
const createNewNote = useCallback(() => {
if (!selectedSection) {
return;
}
const message: Message = {
action: MessageAction.CreateNewNote,
data: selectedSection,
};
vscode.postMessage(message);
}, [selectedSection]);
const onChangeSearchValue = useCallback(
(event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
const value = event.target.value;
setSearchValue(value);
if (searchValueInputTimeout) {
clearTimeout(searchValueInputTimeout);
}
const timeout = setTimeout(() => {
setFinalSearchValue(value);
}, 400);
setSearchValueInputTimeout(timeout);
},
[searchValueInputTimeout]
);
useEffect(() => {
const message: Message = {
action: MessageAction.InitializedNotesPanelWebview,
data: {},
};
vscode.postMessage(message);
}, []);
useEffect(() => {
const onMessage = (event) => {
const message: Message = event.data;
let note: Note;
switch (message.action) {
case MessageAction.SelectedSection:
setSelectedSection(message.data);
if (
selectedSection &&
message.data.notebook.dir !== selectedSection.notebook.dir
) {
setSearchValue("");
}
break;
case MessageAction.SendNotes:
const notes: Note[] = message.data;
notes.forEach((note) => {
note.config.createdAt = new Date(note.config.createdAt || 0);
note.config.modifiedAt = new Date(note.config.modifiedAt || 0);
});
setNotes(message.data || []);
break;
case MessageAction.CreatedNewNote:
note = message.data;
note.config.createdAt = new Date(note.config.createdAt || 0);
note.config.modifiedAt = new Date(note.config.modifiedAt || 0);
setNotes((notes) => [note, ...notes]);
setSelectedNote(note);
break;
case MessageAction.SelectedNote:
note = message.data;
note.config.createdAt = new Date(note.config.createdAt || 0);
note.config.modifiedAt = new Date(note.config.modifiedAt || 0);
setSelectedNote(note);
break;
default:
break;
}
};
window.addEventListener("message", onMessage);
return () => {
window.removeEventListener("message", onMessage);
};
}, [selectedSection]);
return (
<Box className={clsx(classes.notesPanel)}>
<Card className={clsx(classes.topPanel)}>
<Box className={clsx(classes.row)}>
<div className={clsx(classes.search)}>
<div className={clsx(classes.searchIcon)}>
<Magnify />
</div>
<InputBase
placeholder={t("search/placeholder")}
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
value={searchValue}
inputProps={{ "aria-label": "search" }}
onChange={onChangeSearchValue}
autoComplete={"off"}
autoCorrect={"off"}
/>
</div>
<IconButton onClick={createNewNote}>
<FileEditOutline></FileEditOutline>
</IconButton>
</Box>
<Box
className={clsx(classes.row)}
style={{ justifyContent: "space-between" }}
>
{selectedSection?.type === CrossnoteSectionType.Notes ||
selectedSection?.type === CrossnoteSectionType.Notebook ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="notes">
?
</span>
<Typography className={clsx(classes.sectionName)}>
{selectedSection.notebook.name}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Today ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="today-notes">
?
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/today")}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Todo ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="todo-notes">
☑️
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/todo")}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Tagged ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="tagged-notes">
?️
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/tagged")}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Untagged ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="untagged-notes">
?
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/untagged")}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Tag ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="tag">
?️
</span>
<Typography className={clsx(classes.sectionName)}>
{selectedSection.path}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Encrypted ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="encrypted-notes">
?
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/encrypted")}
</Typography>
</Box>
) : selectedSection?.type === CrossnoteSectionType.Conflicted ? (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="conflicted-notes">
⚠️
</span>
<Typography className={clsx(classes.sectionName)}>
{t("general/conflicted")}
</Typography>
</Box>
) : (
selectedSection?.type === CrossnoteSectionType.Directory && (
<Box className={clsx(classes.row)}>
<span role="img" aria-label="folder">
{"?"}
</span>
<Typography className={clsx(classes.sectionName)}>
{selectedSection.path}
</Typography>
</Box>
)
)}
<Box>
<IconButton
onClick={(event) => setSortMenuAnchorEl(event.currentTarget)}
>
<SortVariant></SortVariant>
</IconButton>
<Popover
anchorEl={sortMenuAnchorEl}
keepMounted
open={Boolean(sortMenuAnchorEl)}
onClose={() => setSortMenuAnchorEl(null)}
>
<List>
<ListItem
button
onClick={() => setOrderBy(OrderBy.ModifiedAt)}
className={clsx(
orderBy === OrderBy.ModifiedAt && classes.sortSelected
)}
>
<ListItemText
primary={t("general/date-modified")}
></ListItemText>
</ListItem>
<ListItem
button
onClick={() => setOrderBy(OrderBy.CreatedAt)}
className={clsx(
orderBy === OrderBy.CreatedAt && classes.sortSelected
)}
>
<ListItemText
primary={t("general/date-created")}
></ListItemText>
</ListItem>
<ListItem
button
onClick={() => setOrderBy(OrderBy.Title)}
className={clsx(
orderBy === OrderBy.Title && classes.sortSelected
)}
>
<ListItemText primary={t("general/title")}></ListItemText>
</ListItem>
<Divider></Divider>
<ListItem
button
onClick={() => setOrderDirection(OrderDirection.DESC)}
className={clsx(
orderDirection === OrderDirection.DESC &&
classes.sortSelected
)}
>
<ListItemText primary={"Desc"}></ListItemText>
<ListItemIcon style={{ marginLeft: "8px" }}>
<SortDescending></SortDescending>
</ListItemIcon>
</ListItem>
<ListItem
button
onClick={() => setOrderDirection(OrderDirection.ASC)}
className={clsx(
orderDirection === OrderDirection.ASC &&
classes.sortSelected
)}
>
<ListItemText primary={"Asc"}></ListItemText>
<ListItemIcon style={{ marginLeft: "8px" }}>
<SortAscending></SortAscending>
</ListItemIcon>
</ListItem>
</List>
</Popover>
</Box>
</Box>
</Card>
<Notes
searchValue={finalSearchValue}
notes={notes}
orderBy={orderBy}
orderDirection={orderDirection}
selectedNote={selectedNote}
setSelectedNote={setSelectedNote}
></Notes>
</Box>
);
}
Example #21
Source File: Search.tsx From gatsby-theme-pristine with Apache License 2.0 | 4 votes |
Search: React.FC = () => {
const data = useStaticQuery(graphql`
query SearchIndexQuery {
localSearchPages {
index
store
}
}
`);
const [query, setQuery] = useState("");
const [selectedItem, setSelectedItem] = useState();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleFocus = (event: any) => {
setAnchorEl(event.currentTarget);
};
const results = useFlexSearch(
query,
data.localSearchPages.index,
JSON.parse(data.localSearchPages.store),
);
const open = Boolean(anchorEl);
const selected = selectedItem || results[0];
return (
<div style={{ marginRight: "5px" }}>
<InputBase
onKeyDown={(ev: any) => {
// Enter
if (ev.keyCode === 13) {
if (selected) {
setQuery("");
if (anchorEl !== null) {
(anchorEl as any).blur();
setAnchorEl(null);
}
navigate(selected.slug);
}
} else if (ev.keyCode === 40) {
// Down
const currIndex = _.findIndex(results, (result: any) => result.id === selected.id);
const newSelected = results[currIndex + 1];
if (newSelected) {
setSelectedItem(newSelected);
}
} else if (ev.keyCode === 38) {
// Up
const currIndex = _.findIndex(results, (result: any) => result.id === selected.id);
const newSelected = results[currIndex - 1];
if (newSelected) {
setSelectedItem(newSelected);
}
}
}}
onChange={(ev: any) => {
setQuery(ev.target.value);
}}
onFocus={handleFocus}
placeholder={"? Search"}
value={query}
style={{
fontSize: "16px",
background: "rgba(0,0,0,0.1)",
borderRadius: "4px",
paddingRight: "10px",
paddingLeft: "10px",
paddingTop: "4px",
marginBottom: "4px",
}}
/>
{results.length !== 0 &&
<Popper
open={open}
style={{ marginTop: "5px" }}
anchorEl={anchorEl as any}
popperOptions={{
placement: "bottom",
}}
>
<Paper style={{ maxWidth: "450px", marginTop: "12px" }}>
<List>
{results.map((result: any) => (
<ListItem key={result.id} selected={selected.id === result.id}>
<GatsbyLink to={result.slug} style={{ textDecoration: "none" }} onClick={() => {
setQuery("");
setAnchorEl(null);
}}>
<ListItemText primary={result.slug} secondary={result.title} />
</GatsbyLink>
</ListItem>
))}
</List>
</Paper>
</Popper>
}
</div>
);
}
Example #22
Source File: SearchBar.tsx From backstage with Apache License 2.0 | 4 votes |
SearchBarBase = ({
onChange,
onKeyDown,
onSubmit,
debounceTime = 200,
clearButton = true,
fullWidth = true,
value: defaultValue,
inputProps: defaultInputProps = {},
endAdornment: defaultEndAdornment,
...props
}: SearchBarBaseProps) => {
const configApi = useApi(configApiRef);
const [value, setValue] = useState<string>(defaultValue as string);
const hasSearchContext = useSearchContextCheck();
useEffect(() => {
setValue(prevValue =>
prevValue !== defaultValue ? (defaultValue as string) : prevValue,
);
}, [defaultValue]);
useDebounce(() => onChange(value), debounceTime, [value]);
const handleChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
},
[setValue],
);
const handleKeyDown = useCallback(
(e: KeyboardEvent<HTMLInputElement>) => {
if (onKeyDown) onKeyDown(e);
if (onSubmit && e.key === 'Enter') {
onSubmit();
}
},
[onKeyDown, onSubmit],
);
const handleClear = useCallback(() => {
onChange('');
}, [onChange]);
const placeholder = `Search in ${
configApi.getOptionalString('app.title') || 'Backstage'
}`;
const startAdornment = (
<InputAdornment position="start">
<IconButton aria-label="Query" disabled>
<SearchIcon />
</IconButton>
</InputAdornment>
);
const endAdornment = (
<InputAdornment position="end">
<IconButton aria-label="Clear" onClick={handleClear}>
<ClearButton />
</IconButton>
</InputAdornment>
);
const searchBar = (
<TrackSearch>
<InputBase
data-testid="search-bar-next"
value={value}
placeholder={placeholder}
startAdornment={startAdornment}
endAdornment={clearButton ? endAdornment : defaultEndAdornment}
inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}
fullWidth={fullWidth}
onChange={handleChange}
onKeyDown={handleKeyDown}
{...props}
/>
</TrackSearch>
);
return hasSearchContext ? (
searchBar
) : (
<SearchContextProvider>{searchBar}</SearchContextProvider>
);
}
Example #23
Source File: ExperimentsTableAgGrid.tsx From abacus with GNU General Public License v2.0 | 4 votes |
ExperimentsTable = ({ experiments }: { experiments: ExperimentSummary[] }): JSX.Element => {
const theme = useTheme()
const classes = useStyles()
const gridApiRef = useRef<GridApi | null>(null)
const gridColumnApiRef = useRef<ColumnApi | null>(null)
const onGridReady = (event: GridReadyEvent) => {
gridApiRef.current = event.api
gridColumnApiRef.current = gridColumnApiRef.current = event.columnApi
event.api.sizeColumnsToFit()
searchQuery && setSearchState(searchQuery)
}
const onGridResize = () => {
if (!gridApiRef.current) {
return
}
gridApiRef.current.sizeColumnsToFit()
}
const history = useHistory()
const { pathname, search } = useLocation()
const searchQuery = Object.fromEntries(new URLSearchParams(search).entries())?.search
const [searchState, setSearchState] = useState<string>('')
const onSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchState(event.target.value)
event.target.value ? history.replace(`${pathname}?search=${event.target.value}`) : history.replace(pathname)
}
useEffect(() => {
// istanbul ignore next; trivial and shouldn't occur
if (!gridApiRef.current) {
return
}
gridApiRef.current?.setQuickFilter(searchState)
}, [searchState])
const onNewDataRender = () => {
// istanbul ignore next; trivial and shouldn't occur
if (!gridApiRef.current || !gridColumnApiRef.current) {
return
}
gridColumnApiRef.current.autoSizeAllColumns()
gridColumnApiRef.current.resetColumnState()
gridApiRef.current.setFilterModel(null)
gridColumnApiRef.current.applyColumnState({
state: [
{
colId: 'status',
sort: 'asc',
sortIndex: 0,
},
{
colId: 'startDatetime',
sort: 'desc',
sortIndex: 1,
},
],
defaultState: { sort: null },
})
}
const onReset = () => {
setSearchState('')
history.push(pathname)
onNewDataRender()
}
return (
<div className={clsx('ag-theme-alpine', classes.root)}>
<div className={classes.toolbar}>
<Typography variant='h2'>Experiments</Typography>
<div className={classes.controls}>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder='Search…'
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'Search' }}
value={searchState}
onChange={onSearchChange}
/>
</div>
<Button onClick={onReset}> Reset </Button>
</div>
</div>
<div className={clsx('ag-theme-alpine', classes.gridContainer)}>
<AgGridReact
columnDefs={[
{
headerName: 'Name',
field: 'name',
cellStyle: {
fontFamily: theme.custom.fonts.monospace,
fontWeight: 600,
},
cellRendererFramework: ({ value: name, data }: { value: Status; data: ExperimentSummary }) => (
<Link component={RouterLink} to={`/experiments/${createIdSlug(data.experimentId, data.name)}`}>
{name}
</Link>
),
sortable: true,
filter: true,
resizable: true,
width: 520,
},
{
headerName: 'Status',
field: 'status',
cellRendererFramework: ({ value: status }: { value: Status }) => <ExperimentStatus status={status} />,
comparator: statusComparator,
sortable: true,
filter: true,
resizable: true,
},
{
headerName: 'Platform',
field: 'platform',
cellStyle: {
fontFamily: theme.custom.fonts.monospace,
},
sortable: true,
filter: true,
resizable: true,
},
{
headerName: 'Owner',
field: 'ownerLogin',
cellStyle: {
fontFamily: theme.custom.fonts.monospace,
},
sortable: true,
filter: true,
resizable: true,
},
{
headerName: 'Start',
field: 'startDatetime',
cellRendererFramework: ({ value: startDatetime }: { value: Date }) => {
return <DatetimeText datetime={startDatetime} excludeTime />
},
sortable: true,
filter: 'agDateColumnFilter',
resizable: true,
},
{
headerName: 'End',
field: 'endDatetime',
cellRendererFramework: ({ value: endDatetime }: { value: Date }) => {
return <DatetimeText datetime={endDatetime} excludeTime />
},
sortable: true,
filter: 'agDateColumnFilter',
resizable: true,
},
{
field: 'description',
hide: true,
},
{
headerName: 'Participants',
valueGetter: (params: { data: { analyses: Analysis[] } }) =>
params.data.analyses[0]?.participantStats.total || 0,
cellRendererFramework: ({ value: participants }: { value: number }) => {
return <MetricValue value={participants} metricParameterType={MetricParameterType.Count} />
},
sortable: true,
filter: 'agNumberColumnFilter',
resizable: true,
type: 'rightAligned',
},
]}
rowData={experiments}
containerStyle={{ flex: 1, height: 'auto' }}
onFirstDataRendered={onNewDataRender}
onGridReady={onGridReady}
onGridSizeChanged={onGridResize}
/>
</div>
</div>
)
}