@chakra-ui/react#InputRightElement TypeScript Examples
The following examples show how to use
@chakra-ui/react#InputRightElement.
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: SearchInput.tsx From ksana.in with Apache License 2.0 | 6 votes |
export function SearchInput({ searchText, onChangeSearch }: ISearchInputProps) {
return (
<Box width={{ base: '100%' }}>
<Stack spacing={4}>
<InputGroup>
<Input
size="lg"
borderWidth="2px"
borderColor="orange.400"
name="searchText"
placeholder="Cari tautan kamu"
variant="filled"
value={searchText}
onChange={onChangeSearch}
/>
<InputRightElement
fontSize="2em"
color="orange.400"
mr="2"
mt="1"
children={<FiSearch />}
/>
</InputGroup>
</Stack>
</Box>
)
}
Example #2
Source File: InputRightElement.tsx From openchakra with MIT License | 6 votes |
InputRightElementPreview: React.FC<{ component: IComponent }> = ({
component,
}) => {
const { drop, isOver } = useDropComponent(component.id)
const { props, ref } = useInteractive(component, true)
if (isOver) {
props.bg = 'teal.50'
}
return (
<InputRightElement top="10px" right="10px" {...props} ref={drop(ref)}>
{component.children.map((key: string) => (
<ComponentPreview key={key} componentName={key} />
))}
</InputRightElement>
)
}
Example #3
Source File: Profile.tsx From dope-monorepo with GNU General Public License v3.0 | 5 votes |
Profile = () => {
const [section, setSection] = useQueryParam('section', SECTIONS[0]);
const [searchValue, setSearchValue] = useQueryParam('q', '');
const debouncedSearchValue = useDebounce<string>(searchValue, 250);
const handleSearchChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setSearchValue(value);
};
return (
<>
<Stack
margin="0"
spacing="8px"
width="100%"
padding="16px"
background="white"
borderBottom="2px solid black"
direction={['column', 'column', 'row']}
>
<InputGroup>
<Input
className="search"
placeholder="Search…"
size="sm"
border="2px solid black"
borderRadius="4px"
onChange={handleSearchChange}
value={searchValue}
_focus={{ boxShadow: '0' }}
/>
{searchValue !== '' && (
<InputRightElement height="100%">
<Image
width="16px"
src="/images/icon/circle-clear-input.svg"
alt="Search"
onClick={() => setSearchValue('')}
cursor="pointer"
/>
</InputRightElement>
)}
</InputGroup>
</Stack>
<Accordion
allowToggle
defaultIndex={SECTIONS.findIndex(val => val === section)}
onChange={idx => {
if (idx == -1) return;
const sectionIdx = Array.isArray(idx) ? idx[0] : idx;
setSection(SECTIONS[sectionIdx]);
}}
>
<Section>
<Hustlers searchValue={debouncedSearchValue} />
</Section>
<Section>
<Gear searchValue={debouncedSearchValue} />
</Section>
<Section>
<Dopes searchValue={debouncedSearchValue} />
</Section>
</Accordion>
</>
);
}
Example #4
Source File: index.tsx From dope-monorepo with GNU General Public License v3.0 | 4 votes |
MarketFilterBar = ({
setViewCompactCards,
setOrderBy,
orderBy,
setFilterBy,
filterBy,
compactSwitchOn,
setSearchValue,
}: MarketFilterBarProps) => {
const [sortBy, setSortBy] = useQueryParam('sort_by', sortKeys[1].value);
const [status, setStatus] = useQueryParam('status', statusKeys[2]);
const [searchValueParam, setSearchValueParam] = useQueryParam('q', '');
const debouncedSearchValue = useDebounce<string>(searchValueParam, 250);
useEffect(() => {
setSearchValue(debouncedSearchValue);
}, [debouncedSearchValue, setSearchValue]);
useEffect(() => {
setFilterBy(status as FILTERS);
setOrderBy(sortBy as SearchOrderField);
}, [sortBy, setOrderBy, status, setFilterBy]);
const handleSearchChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setSearchValueParam(value);
setSearchValue(value);
};
const handleStatusChange = (event: ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
setStatus(value);
setFilterBy(status as FILTERS);
};
const handleSortChange = (event: ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
setSortBy(value);
setFilterBy(value as FILTERS);
};
const iconPath = '/images/icon';
const icon = compactSwitchOn ? 'expand' : 'collapse';
return (
<Stack
margin="0"
spacing="8px"
width="100%"
padding="16px"
background="white"
borderBottom="2px solid black"
direction={['column', 'column', 'row']}
>
<a
href="https://dope-wars.notion.site/dope-wars/Dope-Wiki-e237166bd7e6457babc964d1724befb2#d97ecd4b61ef4189964cd67f230c91c5"
target="wiki"
>
<Button fontSize="xs">DOPE NFT FAQ</Button>
</a>
<Container>
<InputGroup>
<Input
className="search"
placeholder="Search…"
size="sm"
onChange={handleSearchChange}
value={searchValueParam}
_focus={{ boxShadow: '0' }}
/>
{searchValueParam !== '' && (
<InputRightElement height="100%">
<Image
width="16px"
src="/images/icon/circle-clear-input.svg"
alt="Search"
onClick={() => setSearchValueParam('')}
cursor="pointer"
/>
</InputRightElement>
)}
</InputGroup>
<div>
<Select
className="status"
size="sm"
onChange={handleStatusChange}
value={filterBy}
fontSize="xs"
>
<option disabled>Status…</option>
{statusKeys.map((value, index) => (
<option key={`${value}-${index}`}>{value}</option>
))}
</Select>
</div>
<div>
<Select size="sm" fontSize="xs" onChange={handleSortChange} value={orderBy}>
<option disabled>Sort By…</option>
{sortKeys.map(({ label, value }, index) => (
<option key={`${value}-${index}`} value={value}>
{label}
</option>
))}
</Select>
</div>
<Button
className="toggleButton"
onClick={() => setViewCompactCards(prevState => !prevState)}
>
<Image alt="toggle" src={`${iconPath}/${icon}.svg`} />
</Button>
</Container>
</Stack>
);
}
Example #5
Source File: ChatType.tsx From dope-monorepo with GNU General Public License v3.0 | 4 votes |
export default function ChatType(props: Props) {
const [ unreadMessages, setUnreadMessages ] = React.useState(0);
const [ inputText, setInputText ] = React.useState('');
const [ messages, setMessages ] = React.useState(props.messagesStore);
const [ canSendMessage, setCanSendMessage ] = React.useState((props.chatMessageBoxes?.length ?? 0) < 3);
const messagesListRef = React.useRef<HTMLUListElement>(null);
let state = React.useRef({
i: -1,
});
useEffect(() => {
props.manager.events.on('chat_message', (message: DataTypes[NetworkEvents.SERVER_PLAYER_CHAT_MESSAGE]) => {
setMessages(m => [...m, message]);
const lastMessageEl = messagesListRef.current?.lastElementChild as HTMLLIElement;
if (lastMessageEl &&
lastMessageEl?.parentElement?.parentElement && !isVisible(lastMessageEl, lastMessageEl?.parentElement?.parentElement))
setUnreadMessages(u => u + 1);
});
// constantly check chatMessageBoxes size and if it's less than 3, set canSendMessage to true
const interval = setInterval(() => setCanSendMessage((props.chatMessageBoxes?.length ?? 0) < 3));
return () => clearInterval(interval);
}, []);
const handleInputKey = (e: KeyboardEvent) => {
if (e.key === 'Enter' && canSendMessage) handleSubmit(inputText);
else if (e.key === 'Escape')
// send "nothing", chat will get closed & message will not get sent
handleSubmit('');
else if (e.key === 'ArrowUp') {
state.current.i = ++state.current.i % props.precedentMessages.length;
const precedentMessage = props.precedentMessages[state.current.i];
if (precedentMessage) setInputText(precedentMessage);
} else if (e.key === 'ArrowDown') {
// rolling window, wrap around
state.current.i = --state.current.i % props.precedentMessages.length;
if (state.current.i < 0) state.current.i = props.precedentMessages.length - 1;
const precedentMessage = props.precedentMessages[state.current.i];
if (precedentMessage) setInputText(precedentMessage);
}
};
const handleSubmit = (content: string) => {
if (content.length > 150)
return;
props.manager.events.emit('chat_submit', content);
};
return (
<ChakraProvider theme={theme}>
<Container
style={{
position: 'absolute',
backgroundColor: 'rgba(0,0,0,0.7)',
borderRadius: '0.5rem',
boxShadow: '0 0.5rem 1rem rgba(0, 0, 0, 0.7)',
height: '30%',
width: '30%',
left: "1%",
bottom: "1%",
}}>
<Stack style={{
paddingTop: '1rem',
height: '95%',
}}>
<div style={{
display: 'flex',
overflow: 'auto',
flexDirection: 'column-reverse',
marginBottom: '-3%',
}}>
<List ref={messagesListRef} spacing={-2} style={{
}}>
<Text style={{
color: 'blueviolet',
}}>
Welcome to the Dopeverse!
</Text>
{messages.map((message, i) => <ListItem key={i}>
<HStack style={{
opacity: '0.8'
}}>
<Text style={{
color: 'white',
}}>
{message.author}: {message.message}
</Text>
<Spacer />
<Text style={{
color: 'grey',
fontSize: '0.6rem',
}}>
{new Date(message.timestamp).toLocaleString()}
</Text>
</HStack>
</ListItem>)}
</List>
</div>
<Spacer />
<Center>
<Button
style={{
marginRight: '1%',
marginTop: '-10%'
}}
variant="primary"
backgroundColor="red.600"
hidden={inputText.length <= 150}
onClick={() => setInputText(inputText.substring(0, 150))}
>
❌ Message too long
</Button>
<Button
style={{
marginTop: '-10%',
}}
variant="primary"
hidden={unreadMessages === 0}
onClick={(e) => {
setUnreadMessages(0);
e.currentTarget.hidden = true;
if (messagesListRef.current)
(messagesListRef.current as HTMLOListElement).lastElementChild?.scrollIntoView({
behavior: 'smooth',
});
}}
>
⬇️ New message ({unreadMessages})
</Button>
</Center>
<Center>
<InputGroup width="90%" size="md">
<Input
autoFocus={true}
focusBorderColor="white"
onBlur={({ target }) => target.focus()}
pr="4.5rem"
placeholder="Message"
_placeholder={{ color: '#b8b8b8' }}
textColor="#f5f5f5"
value={inputText}
onChange={({ target }) => setInputText(target.value)}
onKeyDown={handleInputKey}
style={{
backgroundColor: 'rgba(0, 0, 0, 0.3)',
}}
/>
<InputRightElement width="4.5rem" style={{ paddingRight: '2%' }}>
<Button h="1.75rem" size="sm" disabled={!canSendMessage} onClick={() => handleSubmit(inputText)}>
Send
</Button>
</InputRightElement>
</InputGroup>
</Center>
</Stack>
</Container>
</ChakraProvider>
);
}
Example #6
Source File: CustomPropsPanel.tsx From openchakra with MIT License | 4 votes |
CustomPropsPanel = () => {
const dispatch = useDispatch()
const inputRef = useRef<HTMLInputElement>(null)
const activePropsRef = useInspectorState()
const { props, id } = useSelector(getSelectedComponent)
const { setValue } = useForm()
const [quickProps, setQuickProps] = useState('')
const [hasError, setError] = useState(false)
const onDelete = (propsName: string) => {
dispatch.components.deleteProps({
id,
name: propsName,
})
}
const activeProps = activePropsRef || []
const customProps = Object.keys(props).filter(
propsName => !activeProps.includes(propsName),
)
return (
<>
<form
onSubmit={(event: FormEvent) => {
event.preventDefault()
const [name, value] = quickProps.split(SEPARATOR)
if (name && value) {
setValue(name, value)
setQuickProps('')
setError(false)
} else {
setError(true)
}
}}
>
<InputGroup mb={3} size="sm">
<InputRightElement
children={<Box as={IoIosFlash} color="gray.300" />}
/>
<Input
ref={inputRef}
isInvalid={hasError}
value={quickProps}
placeholder={`props${SEPARATOR}value`}
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setQuickProps(event.target.value)
}
/>
</InputGroup>
</form>
{customProps.map((propsName, i) => (
<Flex
key={propsName}
alignItems="center"
px={2}
bg={i % 2 === 0 ? 'white' : 'gray.50'}
fontSize="xs"
justifyContent="space-between"
>
<SimpleGrid width="100%" columns={2} spacing={1}>
<Box fontWeight="bold">{propsName}</Box>
<Box>{props[propsName]}</Box>
</SimpleGrid>
<ButtonGroup display="flex" size="xs" isAttached>
<IconButton
onClick={() => {
setQuickProps(`${propsName}=`)
if (inputRef.current) {
inputRef.current.focus()
}
}}
variant="ghost"
size="xs"
aria-label="edit"
icon={<EditIcon path="" />}
/>
<IconButton
onClick={() => onDelete(propsName)}
variant="ghost"
size="xs"
aria-label="delete"
icon={<SmallCloseIcon path="" />}
/>
</ButtonGroup>
</Flex>
))}
</>
)
}
Example #7
Source File: Sidebar.tsx From openchakra with MIT License | 4 votes |
Menu = () => {
const [searchTerm, setSearchTerm] = useState('')
return (
<DarkMode>
<Box
maxH="calc(100vh - 3rem)"
overflowY="auto"
overflowX="visible"
boxShadow="xl"
flex="0 0 14rem"
p={5}
m={0}
as="menu"
backgroundColor="#2e3748"
width="15rem"
>
<InputGroup size="sm" mb={4}>
<Input
value={searchTerm}
color="gray.300"
placeholder="Search component…"
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setSearchTerm(event.target.value)
}
borderColor="rgba(255, 255, 255, 0.04)"
bg="rgba(255, 255, 255, 0.06)"
_hover={{
borderColor: 'rgba(255, 255, 255, 0.08)',
}}
zIndex={0}
/>
<InputRightElement zIndex={1}>
{searchTerm ? (
<IconButton
color="gray.300"
aria-label="clear"
icon={<CloseIcon path="" />}
size="xs"
onClick={() => setSearchTerm('')}
/>
) : (
<SearchIcon path="" color="gray.300" />
)}
</InputRightElement>
</InputGroup>
{(Object.keys(menuItems) as ComponentType[])
.filter(c => c.toLowerCase().includes(searchTerm.toLowerCase()))
.map(name => {
const { children, soon } = menuItems[name] as MenuItem
if (children) {
const elements = Object.keys(children).map(childName => (
<DragItem
isChild
key={childName}
label={childName}
type={childName as any}
id={childName as any}
rootParentType={menuItems[name]?.rootParentType || name}
>
{childName}
</DragItem>
))
return [
<DragItem
isMeta
soon={soon}
key={`${name}Meta`}
label={name}
type={`${name}Meta` as any}
id={`${name}Meta` as any}
rootParentType={menuItems[name]?.rootParentType || name}
>
{name}
</DragItem>,
...elements,
]
}
return (
<DragItem
soon={soon}
key={name}
label={name}
type={name as any}
id={name as any}
rootParentType={menuItems[name]?.rootParentType || name}
>
{name}
</DragItem>
)
})}
</Box>
</DarkMode>
)
}
Example #8
Source File: EditUrlInput.tsx From coindrop with GNU General Public License v3.0 | 4 votes |
EditUrlInput: FunctionComponent<Props> = ({ register, value }) => {
const { query: { piggybankName }} = useRouter();
const currentPiggybankId = Array.isArray(piggybankName) ? piggybankName[0] : piggybankName;
const [isValidating, setIsValidating] = useState(false);
const [isValid, setIsValid] = useState(false);
const [error, setError] = useState<'Invalid input' | 'Id taken' | 'Network error'>();
const debouncedValue = useDebounce(value, 1500);
const { setIsPiggybankIdAvailable } = useContext(AdditionalValidation);
const isUrlUnchanged = value === currentPiggybankId;
const isInvalid = !debouncedValue.match(piggybankPathRegex);
const validateIsAvailable = async () => {
if (isUrlUnchanged) {
setIsValid(true);
setIsPiggybankIdAvailable(true);
setError(null);
setIsValidating(false);
return;
}
if (isInvalid) {
setIsValid(false);
setIsPiggybankIdAvailable(false);
setError('Invalid input');
setIsValidating(false);
return;
}
try {
const isAvailable = await isCoindropUrlAvailable(debouncedValue);
setIsValid(isAvailable && !isInvalid);
setIsPiggybankIdAvailable(isAvailable && !isInvalid);
if (!isAvailable) {
setError('Id taken');
}
} catch (err) {
setIsValid(false);
setIsPiggybankIdAvailable(false);
setError('Network error');
} finally {
setIsValidating(false);
}
};
useEffect(() => {
validateIsAvailable();
}, [debouncedValue]);
useEffect(() => {
setIsValidating(true);
setError(null);
}, [value]);
useEffect(() => {
setIsValidating(false);
}, []);
return (
<>
<InputGroup>
<InputLeftAddon>
coindrop.to/
</InputLeftAddon>
<Input
id="input-piggybankId"
maxLength={32}
roundedLeft="0"
isInvalid={!isValid && !isValidating && value === debouncedValue && !isUrlUnchanged}
ref={register}
name="piggybankId"
/>
<InputRightElement>
<StatusIcon
value={value}
debouncedValue={debouncedValue}
currentPiggybankId={currentPiggybankId}
isValid={isValid}
isValidating={isValidating}
/>
</InputRightElement>
</InputGroup>
{error === 'Invalid input' && (
<CoindropRequirements />
)}
{error === 'Id taken' && (
<CreateCoindropError
error="URL is taken, try another!"
/>
)}
{error === 'Network error' && (
<CreateCoindropError
error="Error checking availability, please try again"
/>
)}
</>
);
}