react-icons/ai#AiOutlinePlus TypeScript Examples
The following examples show how to use
react-icons/ai#AiOutlinePlus.
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: index.tsx From dxvote with GNU Affero General Public License v3.0 | 6 votes |
AddButton: React.FC<ActionButtonProps> = ({
label,
onClick,
...rest
}) => {
return (
<StyledIconButton iconLeft onClick={onClick} {...rest}>
<AiOutlinePlus /> {label}
</StyledIconButton>
);
}
Example #2
Source File: proposalTypes.tsx From dxvote with GNU Affero General Public License v3.0 | 6 votes |
ProposalTypesConfig: ProposalTypesConfigProps[] = [
{
title: 'Signal Proposal',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo quam, blandit eu sapien eu, commodo dapibus nisl.',
icon: Signal,
onChainAction: false,
},
{
title: 'Tranfer Funds',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo quam, blandit eu sapien eu, commodo dapibus nisl.',
icon: Vector,
onChainAction: true,
},
{
title: 'Contributer Payment',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo quam, blandit eu sapien eu, commodo dapibus nisl.',
icon: MdCreditCard,
onChainAction: true,
},
{
title: 'Mint Reputation',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo quam, blandit eu sapien eu, commodo dapibus nisl.',
icon: AiOutlinePlus,
onChainAction: true,
},
{
title: 'Custom Proposal',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo quam, blandit eu sapien eu, commodo dapibus nisl.',
icon: ImPencil,
onChainAction: true,
},
]
Example #3
Source File: BoardSelector.tsx From HoldemSolver with MIT License | 6 votes |
function BoardSelector(props: BoardSelectorProps): React.ReactElement {
const { className = '' } = props;
const [modalShown, setModalShown] = useState(false);
return (
<BoardSelectorStyle className={className}>
<Modal
title="Set Board"
shown={modalShown}
closeModal={() => setModalShown(false)}
>
<Cards/>
</Modal>
<div className="board-selector">
<div className="board-title">BOARD</div>
<div className="board-cards">
<div onClick={() => setModalShown(true)} className="board-card">
<AiOutlinePlus />
</div>
<div onClick={() => setModalShown(true)} className="board-card">
<AiOutlinePlus />
</div>
<div onClick={() => setModalShown(true)} className="board-card">
<AiOutlinePlus />
</div>
<div onClick={() => setModalShown(true)} className="board-card">
<AiOutlinePlus />
</div>
<div onClick={() => setModalShown(true)} className="board-card">
<AiOutlinePlus />
</div>
</div>
</div>
</BoardSelectorStyle>
);
}
Example #4
Source File: ContactDialog.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
ContactDialog = ({
onCancel,
onDelete,
onCreate,
onUpdate,
onClose,
onAddressAdd,
onAddressDelete,
isOpen,
modalRef,
existingContact,
}: ContactDialogProps): JSX.Element => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [displayName, setDisplayName] = useState('');
const [currentAddress, setCurrentAddress] = useState('');
const [hasEdited, setHasEdited] = useBoolean(false);
const [phones, setPhones] = useState([] as ContactAddress[]);
const [emails, setEmails] = useState([] as ContactAddress[]);
const [firstNameError, setFirstNameError] = useState('');
const isNameValid = (firstNameError ?? '').length > 0;
useEffect(() => {
if (!existingContact) return;
if (existingContact.firstName) setFirstName(existingContact.firstName);
if (existingContact.lastName) setLastName(existingContact.lastName);
if (existingContact.displayName) setDisplayName(existingContact.displayName);
if (existingContact.phoneNumbers) setPhones(existingContact.phoneNumbers);
if (existingContact.emails) setEmails(existingContact.emails);
}, [existingContact]);
const addAddress = (address: string) => {
const existsPhone = phones.map((e: ContactAddress) => e.address).includes(address);
const existsEmail = emails.map((e: ContactAddress) => e.address).includes(address);
if (existsPhone || existsEmail) {
return showErrorToast({
id: 'contacts',
description: 'Address already exists!'
});
}
if (address.includes('@')) {
setEmails([{ address }, ...emails]);
} else {
setPhones([{ address }, ...phones]);
}
if (onAddressAdd && existingContact) {
onAddressAdd(existingContact.id, address);
}
};
const removeAddress = (address: string, addressId: number | null) => {
if (address.includes('@')) {
setEmails(emails.filter((e: NodeJS.Dict<any>) => e.address !== address));
} else {
setPhones(phones.filter((e: NodeJS.Dict<any>) => e.address !== address));
}
if (onAddressDelete && addressId) {
onAddressDelete(addressId);
}
};
const _onClose = () => {
setPhones([]);
setEmails([]);
setFirstName('');
setLastName('');
setDisplayName('');
setCurrentAddress('');
setHasEdited.off();
if (onClose) onClose();
};
return (
<AlertDialog
isOpen={isOpen}
leastDestructiveRef={modalRef}
onClose={() => onClose()}
>
<AlertDialogOverlay>
<AlertDialogContent>
<AlertDialogHeader fontSize='lg' fontWeight='bold'>
{(existingContact) ? 'Edit Contact' : 'Add a new Contact'}
</AlertDialogHeader>
<AlertDialogBody>
<Text>Add a custom contact to the server's database</Text>
<FormControl isInvalid={isNameValid} mt={5}>
<FormLabel htmlFor='firstName'>First Name</FormLabel>
<Input
id='firstName'
type='text'
value={firstName}
placeholder='Tim'
onChange={(e) => {
setFirstNameError('');
setFirstName(e.target.value);
if (!hasEdited) {
setDisplayName(`${e.target.value} ${lastName}`.trim());
}
}}
/>
{isNameValid ? (
<FormErrorMessage>{firstNameError}</FormErrorMessage>
) : null}
</FormControl>
<FormControl mt={5}>
<FormLabel htmlFor='lastName'>Last Name</FormLabel>
<Input
id='lastName'
type='text'
value={lastName}
placeholder='Apple'
onChange={(e) => {
setLastName(e.target.value);
if (!hasEdited) {
setDisplayName(`${firstName} ${e.target.value}`.trim());
}
}}
/>
</FormControl>
<FormControl mt={5}>
<FormLabel htmlFor='lastName'>Display Name</FormLabel>
<Input
id='displayName'
type='text'
value={displayName}
placeholder='Tim Apple'
onChange={(e) => {
setHasEdited.on();
setDisplayName(e.target.value);
}}
/>
</FormControl>
<FormControl mt={5}>
<FormLabel htmlFor='address'>Addresses</FormLabel>
<HStack>
<Input
id='address'
type='text'
value={currentAddress}
placeholder='Add Address'
onChange={(e) => {
setCurrentAddress(e.target.value);
}}
/>
<IconButton
onClick={() => {
if (!currentAddress || currentAddress.length === 0) return;
addAddress(currentAddress);
setCurrentAddress('');
}}
aria-label='Add'
icon={<AiOutlinePlus />}
/>
</HStack>
<Flex flexDirection="row" alignItems="center" justifyContent="flex-start" flexWrap="wrap" mt={2}>
{[...phones, ...emails].map(((e: ContactAddress) => {
return (
<Tag
mt={1}
mx={1}
size={'md'}
key={e.address}
borderRadius='full'
variant='solid'
>
<TagLabel>{e.address}</TagLabel>
<TagCloseButton
onClick={() => {
removeAddress(e.address, (e.id) ? e.id : null);
}}
/>
</Tag>
);
}))}
</Flex>
</FormControl>
</AlertDialogBody>
<AlertDialogFooter>
<Button
ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
onClick={() => {
if (!existingContact && onCancel) onCancel();
if (existingContact && onUpdate) {
existingContact.firstName = firstName;
existingContact.lastName = lastName;
existingContact.displayName = displayName;
onUpdate(existingContact);
}
_onClose();
}}
>
{(existingContact) ? 'Save & Close' : 'Cancel'}
</Button>
{(existingContact) ? (
<Button
ml={3}
bg='red'
ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
onClick={() => {
if (onDelete) {
onDelete(Number.parseInt(existingContact.id));
}
_onClose();
}}
>
Delete
</Button>
) : null}
{(!existingContact) ? (
<Button
ml={3}
bg='brand.primary'
ref={modalRef as React.LegacyRef<HTMLButtonElement> | undefined}
onClick={() => {
if (firstName.length === 0) {
setFirstNameError('Please enter a first name for the contact!');
return;
}
if (onCreate) {
onCreate({
firstName,
lastName,
phoneNumbers: phones,
emails: emails,
displayName,
birthday: '',
avatar: '',
id: '',
sourceType: 'db'
});
}
_onClose();
}}
>
Create
</Button>
) : null}
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialogOverlay>
</AlertDialog>
);
}
Example #5
Source File: ApiLayout.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
ApiLayout = (): JSX.Element => {
const dialogRef = useRef(null);
const [dialogOpen, setDialogOpen] = useBoolean();
const webhooks = useAppSelector(state => state.webhookStore.webhooks);
return (
<Box p={3} borderRadius={10}>
<Flex flexDirection="column">
<Stack direction='column' p={5}>
<Flex flexDirection='row' justifyContent='flex-start' alignItems='center'>
<Text fontSize='2xl'>API</Text>
<Popover trigger='hover'>
<PopoverTrigger>
<Box ml={2} _hover={{ color: 'brand.primary', cursor: 'pointer' }}>
<AiOutlineInfoCircle />
</Box>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>Information</PopoverHeader>
<PopoverBody>
<Text>
Learn how you can interact with the API to automate and orchestrate iMessage-related
actions. Our REST API gives you access to the underlying iMessage API in a
more succinct and easy to digest way. We also offer webhooks so you can receive
callbacks from the server.
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
</Flex>
<Divider orientation='horizontal' />
<Text>
BlueBubbles offers a high-level REST API to interact with the server, as well as iMessage itself.
With the API, you'll be able to send messages, fetch messages, filter chats, and more! To see what
else you can do in the API, please see the documentation below:
</Text>
<Spacer />
<LinkBox as='article' maxW='sm' px='5' pb={5} pt={2} borderWidth='1px' rounded='xl'>
<Text color='gray'>
https://documenter.getpostman.com
</Text>
<Heading size='sm' mt={2}>
<LinkOverlay href='https://documenter.getpostman.com/view/765844/UV5RnfwM' target='_blank'>
Click to view API documentation
</LinkOverlay>
</Heading>
</LinkBox>
</Stack>
<Stack direction='column' p={5}>
<Flex flexDirection='row' justifyContent='flex-start' alignItems='center'>
<Text fontSize='2xl'>Webhooks</Text>
<Popover trigger='hover'>
<PopoverTrigger>
<Box ml={2} _hover={{ color: 'brand.primary', cursor: 'pointer' }}>
<AiOutlineInfoCircle />
</Box>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>Information</PopoverHeader>
<PopoverBody>
<Text>
Any webhooks registered here will receive a POST request whenever an iMessage event
occurs. The body of the POST request will be a JSON payload containing the type of
event and the event data.
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
</Flex>
<Divider orientation='horizontal' />
<Spacer />
<Box>
<Menu>
<MenuButton
as={Button}
rightIcon={<BsChevronDown />}
width="12em"
>
Manage
</MenuButton>
<MenuList>
<MenuItem icon={<AiOutlinePlus />} onClick={setDialogOpen.on}>
Add Webhook
</MenuItem>
</MenuList>
</Menu>
</Box>
<Spacer />
<WebhooksTable webhooks={webhooks} />
</Stack>
</Flex>
<AddWebhookDialog
modalRef={dialogRef}
isOpen={dialogOpen}
onClose={() => setDialogOpen.off()}
/>
</Box>
);
}
Example #6
Source File: Tabs.tsx From slice-machine with Apache License 2.0 | 4 votes |
CustomTypeTabs: React.FC<CustomTypeTabsProps> = ({ sx, renderTab }) => {
const { currentCustomType } = useSelector((store: SliceMachineStoreType) => ({
currentCustomType: selectCurrentCustomType(store),
}));
const { theme } = useThemeUI();
const { createCustomTypeTab, updateCustomTypeTab, deleteCustomTypeTab } =
useSliceMachineActions();
const [tabIndex, setTabIndex] = useState<number>(0);
const [state, setState] = useState<ModalState | undefined>();
if (!currentCustomType) return null;
return (
<Box sx={{ bg: "backgroundClear" }}>
<FlexWrapper
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
sx={sx}
>
<Tabs
selectedIndex={tabIndex}
onSelect={(index) => setTabIndex(index)}
style={{ width: "100%" }}
>
<TabList>
{currentCustomType.tabs.map((tab, i) => (
<Tab
key={tab.key}
style={{
display: "flex",
height: "48px",
}}
>
<Flex sx={{ alignItems: "center" }}>
{tab.key}
{i === tabIndex ? (
<Icon
theme={theme}
onClick={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
setState({
title: "Edit Tab",
type: ModalType.UPDATE,
key: tab.key,
allowDelete: currentCustomType.tabs.length > 1,
});
}}
/>
) : null}
</Flex>
</Tab>
))}
<Tab
key={"new-tab"}
style={{ height: "48px" }}
disabled
onClick={() =>
setState({ title: "Add Tab", type: ModalType.CREATE })
}
>
<Button variant="transparent" sx={{ m: 0, color: "text" }}>
<AiOutlinePlus style={{ position: "relative", top: "2px" }} />{" "}
Add Tab
</Button>
</Tab>
</TabList>
{currentCustomType.tabs.map((tab) => (
<TabPanel key={tab.key}>{renderTab(tab)}</TabPanel>
))}
<TabPanel key={"new-tab"} />
</Tabs>
</FlexWrapper>
{state?.type === ModalType.CREATE ? (
<CreateModal
{...state}
isOpen
tabIds={currentCustomType.tabs.map((e) => e.key.toLowerCase())}
close={() => setState(undefined)}
onSubmit={({ id }: { id: string }) => {
createCustomTypeTab(id);
// current.tabs is not updated yet
setTabIndex(currentCustomType.tabs.length);
}}
/>
) : null}
{state?.type === ModalType.UPDATE ? (
<UpdateModal
{...state}
isOpen
tabIds={currentCustomType.tabs
.filter((e) => e.key !== state.key)
.map((e) => e.key.toLowerCase())}
close={() => setState(undefined)}
onSubmit={({
id,
actionType,
}: {
id: string;
actionType: UpdateModalActionType;
}) => {
if (actionType === UpdateModalActionType.UPDATE) {
updateCustomTypeTab(state.key, id);
}
if (actionType === UpdateModalActionType.DELETE) {
deleteCustomTypeTab(state.key);
setTabIndex(0);
}
}}
/>
) : null}
</Box>
);
}