@chakra-ui/react#CircularProgress TypeScript Examples
The following examples show how to use
@chakra-ui/react#CircularProgress.
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 nextjs-hasura-boilerplate with MIT License | 5 votes |
Loader: FC<Props> = ({ size = "50px", thickness = 0.15 }) => {
return (
<Box w="full" textAlign="center" maxH="200px">
<CircularProgress isIndeterminate size={size} thickness={thickness} />
</Box>
);
}
Example #2
Source File: ChatStatusView.tsx From takeout-app with MIT License | 5 votes |
ChatStatusView: React.FC<Props> = ({ status, loading, error }) => {
const shouldClose = status === "CONNECTED" && !loading && !error;
const [shouldCloseState, setShouldCloseState] = React.useState(shouldClose);
React.useEffect(() => {
const timer = setTimeout(() => setShouldCloseState(shouldClose), 1500);
return () => clearTimeout(timer);
}, [shouldClose]);
let statusHuman = "Doing something (unknown state!?)";
let progress = -1;
if (status === "INIT" || status === undefined) {
statusHuman = "Obtaining chat session";
progress = 25;
} else if (status === "READY" || status === "CONNECTING" || status == "CONNECT_ERROR") {
statusHuman = "Connecting to chat";
progress = 50;
} else if (loading) {
statusHuman = "Loading chat history";
progress = 75;
} else if (status === "CONNECTED") {
statusHuman = "Connected to chat";
progress = 100;
} else if (status === "SHUTTING_DOWN") {
statusHuman = "Disconnecting";
progress = -1;
}
// TODO: (refactor) move minH/w/flexBasis to TrackChat
return (
<Box w="100%" flexBasis={0}>
<Collapse in={!shouldCloseState} animateOpacity>
<VStack py={1} w="100%" bgColor="#ffffff" borderBottom="1px solid" borderColor={Colors.chatBorder}>
<HStack>
<CircularProgress
aria-label={`${statusHuman}`}
value={progress}
isIndeterminate={progress === -1}
size="15px"
/>
<Text aria-hidden="true" fontSize="14px">
{statusHuman}
</Text>
</HStack>
</VStack>
</Collapse>
{error ? <ErrorAlert error={error} /> : null}
</Box>
);
}
Example #3
Source File: ContactsLayout.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
ContactsLayout = (): JSX.Element => {
const [search, setSearch] = useState('' as string);
const [isLoading, setIsLoading] = useBoolean(true);
const [contacts, setContacts] = useState([] as any[]);
const [permission, setPermission] = useState((): string | null => {
return null;
});
const dialogRef = useRef(null);
const inputFile = useRef(null);
const [dialogOpen, setDialogOpen] = useBoolean();
const alertRef = useRef(null);
const [requiresConfirmation, confirm] = useState((): string | null => {
return null;
});
let filteredContacts = contacts;
if (search && search.length > 0) {
filteredContacts = filteredContacts.filter((c) => buildIdentifier(c).includes(search.toLowerCase()));
}
const {
currentPage,
setCurrentPage,
pagesCount,
pages
} = usePagination({
pagesCount: Math.ceil(filteredContacts.length / perPage),
initialState: { currentPage: 1 },
});
const refreshPermissionStatus = async (): Promise<void> => {
setPermission(null);
await waitMs(500);
ipcRenderer.invoke('contact-permission-status').then((status: string) => {
setPermission(status);
}).catch(() => {
setPermission('Unknown');
});
};
const requestContactPermission = async (): Promise<void> => {
setPermission(null);
ipcRenderer.invoke('request-contact-permission').then((status: string) => {
setPermission(status);
}).catch(() => {
setPermission('Unknown');
});
};
const loadContacts = (showToast = false) => {
ipcRenderer.invoke('get-contacts').then((contactList: any[]) => {
setContacts(contactList.map((e: any) => {
// Patch the ID as a string
e.id = String(e.id);
return e;
}));
setIsLoading.off();
}).catch(() => {
setIsLoading.off();
});
if (showToast) {
showSuccessToast({
id: 'contacts',
description: 'Successfully refreshed Contacts!'
});
}
};
useEffect(() => {
loadContacts();
refreshPermissionStatus();
}, []);
const getEmptyContent = () => {
const wrap = (child: JSX.Element) => {
return (
<section style={{marginTop: 20}}>
{child}
</section>
);
};
if (isLoading) {
return wrap(<CircularProgress isIndeterminate />);
}
if (contacts.length === 0) {
return wrap(<Text fontSize="md">BlueBubbles found no contacts in your Mac's Address Book!</Text>);
}
return null;
};
const filterContacts = () => {
return filteredContacts.slice((currentPage - 1) * perPage, currentPage * perPage);
};
const onCreate = async (contact: ContactItem) => {
const newContact = await createContact(
contact.firstName,
contact.lastName,
{
emails: contact.emails.map((e: NodeJS.Dict<any>) => e.address),
phoneNumbers: contact.phoneNumbers.map((e: NodeJS.Dict<any>) => e.address)
}
);
if (newContact) {
// Patch the contact using a string ID & source type
newContact.id = String(newContact.id);
newContact.sourceType = 'db';
// Patch the addresses
(newContact as any).phoneNumbers = (newContact as any).addresses.filter((e: any) => e.type === 'phone');
(newContact as any).emails = (newContact as any).addresses.filter((e: any) => e.type === 'email');
setContacts([newContact, ...contacts]);
}
};
const onUpdate = async (contact: NodeJS.Dict<any>) => {
const cId = typeof(contact.id) === 'string' ? Number.parseInt(contact.id) : contact.id as number;
const newContact = await updateContact(
cId,
{
firstName: contact.firstName,
lastName: contact.lastName,
displayName: contact.displayName
}
);
const copiedContacts = [...contacts];
let updated = false;
for (let i = 0; i < copiedContacts.length; i++) {
if (copiedContacts[i].id === String(cId)) {
copiedContacts[i].firstName = newContact.firstName;
copiedContacts[i].lastName = newContact.lastName;
copiedContacts[i].displayName = newContact.displayName;
updated = true;
}
}
if (updated) {
setContacts(copiedContacts);
}
};
const onDelete = async (contactId: number | string) => {
await deleteContact(typeof(contactId) === 'string' ? Number.parseInt(contactId as string) : contactId);
setContacts(contacts.filter((e: ContactItem) => {
return e.id !== String(contactId);
}));
};
const onAddAddress = async (contactId: number | string, address: string) => {
const cId = typeof(contactId) === 'string' ? Number.parseInt(contactId as string) : contactId;
const addr = await addAddressToContact(cId, address, address.includes('@') ? 'email' : 'phone');
if (addr) {
setContacts(contacts.map((e: ContactItem) => {
if (e.id !== String(contactId)) return e;
if (address.includes('@')) {
e.emails = [...e.emails, addr];
} else {
e.phoneNumbers = [...e.phoneNumbers, addr];
}
return e;
}));
}
};
const onDeleteAddress = async (contactAddressId: number) => {
await deleteContactAddress(contactAddressId);
setContacts(contacts.map((e: ContactItem) => {
e.emails = e.emails.filter((e: ContactAddress) => e.id !== contactAddressId);
e.phoneNumbers = e.phoneNumbers.filter((e: ContactAddress) => e.id !== contactAddressId);
return e;
}));
};
const clearLocalContacts = async () => {
// Delete the contacts, then filter out the DB items
await deleteLocalContacts();
setContacts(contacts.filter(e => e.sourceType !== 'db'));
};
const confirmationActions: ConfirmationItems = {
clearLocalContacts: {
message: (
'Are you sure you want to clear/delete all local Contacts?<br /><br />' +
'This will remove any Contacts added manually, via the API, or via the import process'
),
func: clearLocalContacts
}
};
return (
<Box p={3} borderRadius={10}>
<Stack direction='column' p={5}>
<Text fontSize='2xl'>Controls</Text>
<Divider orientation='horizontal' />
<Box>
<Menu>
<MenuButton
as={Button}
rightIcon={<BsChevronDown />}
width="12em"mr={5}
>
Manage
</MenuButton>
<MenuList>
<MenuItem icon={<BsPersonPlus />} onClick={() => setDialogOpen.on()}>
Add Contact
</MenuItem>
<MenuItem icon={<BiRefresh />} onClick={() => loadContacts(true)}>
Refresh Contacts
</MenuItem>
<MenuItem
icon={<BiImport />}
onClick={() => {
if (inputFile && inputFile.current) {
(inputFile.current as HTMLElement).click();
}
}}
>
Import VCF
<input
type='file'
id='file'
ref={inputFile}
accept=".vcf"
style={{display: 'none'}}
onChange={(e) => {
const files = e?.target?.files ?? [];
for (const i of files) {
ipcRenderer.invoke('import-vcf', i.webkitRelativePath);
}
}}
/>
</MenuItem>
<MenuDivider />
<MenuItem icon={<FiTrash />} onClick={() => confirm('clearLocalContacts')}>
Clear Local Contacts
</MenuItem>
</MenuList>
</Menu>
<Menu>
<MenuButton
as={Button}
rightIcon={<BsChevronDown />}
width="12em"
mr={5}
>
Permissions
</MenuButton>
<MenuList>
<MenuItem icon={<BiRefresh />} onClick={() => refreshPermissionStatus()}>
Refresh Permission Status
</MenuItem>
{(permission !== null && permission !== 'Authorized') ? (
<MenuItem icon={<BsUnlockFill />} onClick={() => requestContactPermission()}>
Request Permission
</MenuItem>
) : null}
</MenuList>
</Menu>
<Text as="span" verticalAlign="middle">
Status: <Text as="span" color={getPermissionColor(permission)}>
{permission ? permission : 'Checking...'}
</Text>
</Text>
</Box>
</Stack>
<Stack direction='column' p={5}>
<Flex flexDirection='row' justifyContent='flex-start' alignItems='center'>
<Text fontSize='2xl'>Contacts ({filteredContacts.length})</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>
Here are the contacts on your macOS device that BlueBubbles knows about,
and will serve to any clients that want to know about them. These include
contacts from this Mac's Address Book, as well as contacts from uploads/imports
or manual entry.
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
</Flex>
<Divider orientation='horizontal' />
<Flex flexDirection='row' justifyContent='flex-end' alignItems='center' pt={3}>
<InputGroup width="xxs">
<InputLeftElement pointerEvents='none'>
<AiOutlineSearch color='gray.300' />
</InputLeftElement>
<Input
placeholder='Search Contacts'
onChange={(e) => {
if (currentPage > 1) {
setCurrentPage(1);
}
setSearch(e.target.value);
}}
value={search}
/>
</InputGroup>
</Flex>
<Flex justifyContent="center" alignItems="center">
{getEmptyContent()}
</Flex>
{(contacts.length > 0) ? (
<ContactsTable
contacts={filterContacts()}
onCreate={onCreate}
onDelete={onDelete}
onUpdate={onUpdate}
onAddressAdd={onAddAddress}
onAddressDelete={onDeleteAddress}
/>
) : null}
<Pagination
pagesCount={pagesCount}
currentPage={currentPage}
onPageChange={setCurrentPage}
>
<PaginationContainer
align="center"
justify="space-between"
w="full"
pt={2}
>
<PaginationPrevious minWidth={'75px'}>Previous</PaginationPrevious>
<Box ml={1}></Box>
<PaginationPageGroup flexWrap="wrap" justifyContent="center">
{pages.map((page: number) => (
<PaginationPage
key={`pagination_page_${page}`}
page={page}
my={1}
px={3}
fontSize={14}
/>
))}
</PaginationPageGroup>
<Box ml={1}></Box>
<PaginationNext minWidth={'50px'}>Next</PaginationNext>
</PaginationContainer>
</Pagination>
</Stack>
<ContactDialog
modalRef={dialogRef}
isOpen={dialogOpen}
onCreate={onCreate}
onDelete={onDelete}
onAddressAdd={onAddAddress}
onAddressDelete={onDeleteAddress}
onClose={() => setDialogOpen.off()}
/>
<ConfirmationDialog
modalRef={alertRef}
onClose={() => confirm(null)}
body={confirmationActions[requiresConfirmation as string]?.message}
onAccept={() => {
confirmationActions[requiresConfirmation as string].func();
}}
isOpen={requiresConfirmation !== null}
/>
</Box>
);
}