@chakra-ui/react#ButtonGroup TypeScript Examples
The following examples show how to use
@chakra-ui/react#ButtonGroup.
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: MultiPicker.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
// TODO (Zane): change "any" type to something else?
export default function MultiPicker({
options,
onChange,
}: {
options: any;
onChange: (state: string) => any;
}) {
// start with first option as default
const [selectedKey, setSelectedKey] = useState<string>(
Object.keys(options)[0]
);
useEffect(() => {
onChange(selectedKey);
}, [onChange, selectedKey]);
return (
<ButtonGroup spacing="0" borderRadius="full" bgColor="#2D3748">
{Object.keys(options).map((key) => (
<MultiPickerButton
selected={key === selectedKey}
onClick={() => setSelectedKey(key)}
key={key}
>
{options[key]}
</MultiPickerButton>
))}
</ButtonGroup>
);
}
Example #2
Source File: UserListItem.tsx From next-crud with MIT License | 6 votes |
UserListItem = ({ id, username, onEdit, onDelete }: IProps) => {
return (
<Flex
direction="row"
align="center"
justify="space-between"
py={2}
width="100%"
>
<HStack spacing={8} align="center">
<Text>#{id}</Text>
<Text>{username}</Text>
</HStack>
<ButtonGroup spacing={2}>
<IconButton
aria-label="Edit"
icon={<EditIcon color="white" />}
colorScheme="blue"
onClick={() => onEdit(id)}
size="sm"
/>
<IconButton
aria-label="Delete"
icon={<DeleteIcon color="white" />}
colorScheme="red"
onClick={() => onDelete(id)}
size="sm"
/>
</ButtonGroup>
</Flex>
)
}
Example #3
Source File: Footer.tsx From phonepare with MIT License | 6 votes |
Footer: FC = () => {
return <Box as='footer' role='contentinfo' mx='auto' maxW='7xl' py='12' px={{ base: '4', md: '8' }}>
<Stack>
<Stack direction='row' spacing='4' align='center' justify='space-between'>
<Box>
<Link to='/'>
<Heading>Phonepare</Heading>
</Link>
<Text>휴대폰을 비교하세요.</Text>
</Box>
<Box>
<ButtonGroup variant='ghost' color='gray.600'>
<IconButton as={Link} to='/' aria-label='Home' icon={<FaHome fontSize='20px' />} />
<IconButton as='a' href='https://github.com/wonderlandpark/phonepare' aria-label='Github' icon={<FaGithub fontSize='20px' />} />
</ButtonGroup>
</Box>
</Stack>
<Text fontSize='sm' alignSelf={{ base: 'center', sm: 'start' }}>
© {new Date().getFullYear()} Junseo Park. All rights reserved.
</Text>
</Stack>
</Box>
}
Example #4
Source File: AddAppDomain.tsx From ledokku with MIT License | 5 votes |
AddAppDomain = ({ appId, appDomainsRefetch }: AddDomainProps) => {
const toast = useToast();
const [addDomainMutation] = useAddDomainMutation();
const [showAddForm, setShowAddForm] = useState(false);
const formik = useFormik<{ domainName: string }>({
initialValues: {
domainName: '',
},
validateOnChange: true,
validationSchema: addAppDomainYupSchema,
onSubmit: async (values) => {
try {
await addDomainMutation({
variables: {
input: {
appId,
domainName: values.domainName,
},
},
});
await appDomainsRefetch();
toast.success('Domain added successfully');
formik.resetForm();
} catch (error) {
toast.error(error.message);
}
},
});
return (
<>
{!showAddForm ? (
<Button variant="outline" onClick={() => setShowAddForm(true)}>
Add custom domain
</Button>
) : (
<form onSubmit={formik.handleSubmit}>
<FormControl
id="domainName"
isInvalid={Boolean(
formik.errors.domainName && formik.touched.domainName
)}
>
<Input
placeholder="www.mydomain.com"
name="domainName"
value={formik.values.domainName}
onChange={formik.handleChange}
/>
<FormErrorMessage>{formik.errors.domainName}</FormErrorMessage>
</FormControl>
<ButtonGroup mt="4" spacing="2">
<Button isLoading={formik.isSubmitting} type="submit">
Save
</Button>
<Button
variant="outline"
disabled={formik.isSubmitting}
onClick={() => setShowAddForm(false)}
>
Cancel
</Button>
</ButtonGroup>
</form>
)}
</>
);
}
Example #5
Source File: index.tsx From calories-in with MIT License | 5 votes |
function UndoRedoButtons() {
return (
<ButtonGroup spacing={2} variant="outline">
<UndoButton />
<RedoButton />
</ButtonGroup>
)
}
Example #6
Source File: FuseTabBar.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
FuseTabBar = () => {
const isMobile = useIsSmallScreen();
const { t } = useTranslation();
let { poolId } = useParams();
let navigate = useNavigate();
const filter = useFilter();
const location = useLocation();
const hasCreatedPools = useHasCreatedPools();
return (
<DashboardBox width="100%" mt={4} height={isMobile ? "auto" : "65px"}>
<RowOrColumn
isRow={!isMobile}
expand
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
p={4}
>
{!poolId ? (
<ButtonGroup
mr={4}
size="sm"
isAttached
variant="outline"
height="35px"
>
<DashboardBox height="35px">
<Row
pl={2}
expand
crossAxisAlignment="center"
mainAxisAlignment="flex-start"
fontWeight="bold"
>
<Text flexShrink={0}>{t("Search:")}</Text>
<Input
value={filter ?? ""}
onChange={(event) => {
const value = encodeURIComponent(event.target.value);
if (value) {
navigate("?filter=" + value);
} else {
navigate("");
}
}}
width="100px"
height="100%"
ml={2}
placeholder={t("USDC, DAI")}
variant="filled"
size="sm"
_placeholder={{ color: "#e0e0e0" }}
_focus={{ bg: "#282727" }}
_hover={{ bg: "#282727" }}
bg="#282727"
borderRadius={filter ? "0px" : "0px 9px 9px 0px"}
/>
</Row>
</DashboardBox>
{filter ? (
<DashboardBox bg="#282727" ml={-1}>
<Link
/* @ts-ignore */
as={RouterLink}
to=""
>
<Center expand pr={2} fontWeight="bold">
<DeleteIcon mb="2px" />
</Center>
</Link>
</DashboardBox>
) : null}
</ButtonGroup>
) : null}
<TabLink ml={0} route="/fuse?filter=my-pools" text={t("My Pools")} />
<TabLink route="/fuse" text={t("Verified Pools")} />
<TabLink
route="/fuse?filter=unverified-pools"
text={t("Unverified Pools")}
/>
{hasCreatedPools && (
<TabLink
route="/fuse?filter=created-pools"
text={t("Created Pools")}
/>
)}
<TabExternalLink
route="https://metrics.rari.capital"
text={t("Metrics")}
/>
<TabLink route="/fuse/liquidations" text={t("Liquidations")} />
{poolId ? (
<>
<DashboardBox
{...(!location.pathname.includes("info") ? activeStyle : {})}
ml={isMobile ? 0 : 4}
mt={isMobile ? 4 : 0}
height="35px"
>
<Link
/* @ts-ignore */
as={RouterLink}
to={`/fuse/pool/${poolId}`}
className="no-underline"
>
<Center expand px={2} fontWeight="bold">
{t("Pool #{{poolId}}", { poolId })}
</Center>
</Link>
</DashboardBox>
<DashboardBox
{...(location.pathname.includes("info") ? activeStyle : {})}
ml={isMobile ? 0 : 4}
mt={isMobile ? 4 : 0}
height="35px"
>
<Link
/* @ts-ignore */
as={RouterLink}
to={`/fuse/pool/${poolId}/info`}
className="no-underline"
>
<Center expand px={2} fontWeight="bold">
{t("Pool #{{poolId}} Info", { poolId })}
</Center>
</Link>
</DashboardBox>
</>
) : null}
<NewPoolButton />
</RowOrColumn>
</DashboardBox>
);
}
Example #7
Source File: index.tsx From engine with MIT License | 4 votes |
Header = () => (
<AccordionItem>
<Heading>
<AccordionButton _expanded={{ bg: "gray.300", color: "white" }}>
<Box flex="1" textAlign="left">
Header
</Box>
<AccordionIcon />
</AccordionButton>
</Heading>
<AccordionPanel pb={4}>
<HStack mb="3">
<Box w="70%">
Fill values from a past runtime call, a unit test or auto determine
values based on observe and update dependencies
</Box>
<Box w="30%">
<Button size="sm" mr="3" mb="2" color="teal">
Auto
</Button>
<Popover>
<PopoverTrigger>
<Button size="sm" mr="3" mb="2" color="purple">
From call
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverHeader>Runtime call history (5)</PopoverHeader>
<PopoverCloseButton />
<PopoverBody>
<OrderedList>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
23/02/2022 14:15:10.123
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
23/02/2022 14:13:2.130
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
23/02/2022 14:12:41.500
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
23/02/2022 13:21:20.341
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
23/02/2022 12:40:19.983
</ListItem>
</OrderedList>
</PopoverBody>
</PopoverContent>
</Popover>
<Popover>
<PopoverTrigger>
<Button size="sm" color="blue">
From test
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverHeader>Tests (100% coverage)</PopoverHeader>
<PopoverCloseButton />
<PopoverBody>
<OrderedList>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
should ensure guards work (30% coverage)
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
should do computation when y is less (70% coverage)
</ListItem>
<ListItem
cursor="pointer"
_hover={{
color: "teal.500",
}}
>
should reject if y is greater than (64% coverage)
</ListItem>
</OrderedList>
</PopoverBody>
</PopoverContent>
</Popover>
</Box>
</HStack>
<Divider mb="4" />
<Box mb="4">
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="pie" w="32" />
<Input defaultValue="3.14" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="http" w="32" />
<Input defaultValue={`axios from "axios"`} />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input defaultValue="[mock]" bg="black.100" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="operation" w="32" />
<Input defaultValue="prop.operation" />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input defaultValue="sum" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="foo" w="32" />
<Input defaultValue="observe.foo.value" />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input defaultValue="123" bg="teal.800" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="bam" w="32" />
<Input defaultValue="observe.bar.internal.something" />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input defaultValue="321" bg="teal.800" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="updateSome" w="32" />
<Input defaultValue="update.a.value.somewhere" />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input defaultValue="444" bg="yellow.700" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
<HStack>
<InputGroup size="sm" w="70%">
<InputLeftAddon children="" w="32" />
<Input placeholder="enter something..." />
</InputGroup>
<InputGroup size="sm" w="30%">
<Input placeholder="sample value" />
<InputRightAddon children={<SettingsIcon />} cursor="pointer" />
</InputGroup>
</HStack>
</Box>
<HStack>
<Text w="70%" size="sm">
Last run took 14ms
</Text>
<ButtonGroup variant="outline" spacing="4">
<Button size="sm" colorScheme="black">
Save as test
</Button>
<Button size="sm" colorScheme="green" variant="solid">
Run
</Button>
</ButtonGroup>
</HStack>
</AccordionPanel>
</AccordionItem>
)
Example #8
Source File: index.tsx From formik-chakra-ui with MIT License | 4 votes |
App = () => {
return (
<ChakraProvider>
<Heading as="h1" size="xl" textAlign="center">
Formik Chakra UI
</Heading>
<Box as="p" textAlign="center">
Example using{' '}
<Link href="https://github.com/kgnugur/formik-chakra-ui" isExternal>
Formik Chakra UI{' '}
</Link>
</Box>
<Formik
initialValues={initialValues}
onSubmit={onSubmit}
validationSchema={validationSchema}
>
{({ handleSubmit, values, errors }) => (
<Stack
spacing={5}
borderWidth="1px"
rounded="lg"
shadow="1px 1px 3px rgba(0,0,0,0.3)"
maxWidth={800}
p={6}
m="10px auto"
as="form"
onSubmit={handleSubmit as any}
>
<InputControl name="firstName" label="First Name" />
<InputControl name="lastName" label="Last Name" />
<NumberInputControl
name="age"
label="Age"
helperText="Helper text"
/>
<CheckboxSingleControl name="employed">
Employed
</CheckboxSingleControl>
<RadioGroupControl name="favoriteColor" label="Favorite Color">
<Radio value="#ff0000">Red</Radio>
<Radio value="#00ff00">Green</Radio>
<Radio value="#0000ff">Blue</Radio>
</RadioGroupControl>
<CheckboxContainer name="toppings" label="Toppings">
<CheckboxControl name="toppings1" value="chicken">
Chicken
</CheckboxControl>
<CheckboxControl name="toppings" value="ham">
Ham
</CheckboxControl>
<CheckboxControl name="toppings" value="mushrooms">
Mushrooms
</CheckboxControl>
<CheckboxControl name="toppings" value="cheese">
Cheese
</CheckboxControl>
<CheckboxControl name="toppings" value="tuna">
Tuna
</CheckboxControl>
<CheckboxControl name="toppings" value="pineapple">
Pineapple
</CheckboxControl>
</CheckboxContainer>
<TextareaControl name="notes" label="Notes" />
<SwitchControl name="employedd" label="Employed" />
<SelectControl
label="Select label"
name="select"
selectProps={{ placeholder: 'Select option' }}
>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</SelectControl>
<SliderControl name="foo" sliderProps={{ max: 40 }} />
<PinInputControl
name="bar"
pinAmount={4}
pinInputProps={{ size: 'sm' }}
/>
<PercentComplete />
<FormControl
name="customField"
label="Custom FormControl"
helperText="Helper text"
>
<Field
as={Input}
name="customField"
placeholder="A custom field"
/>
</FormControl>
<InputControl
name="customElements"
label="Custom elements"
labelProps={{ color: 'blue' }}
errorMessageProps={{ fontWeight: 'bold' }}
helperText="Helper text"
helperTextProps={{ fontStyle: 'italic' }}
/>
<ButtonGroup>
<SubmitButton>Submit</SubmitButton>
<ResetButton>Reset</ResetButton>
</ButtonGroup>
<Box as="pre" marginY={10}>
{JSON.stringify(values, null, 2)}
<br />
{JSON.stringify(errors, null, 2)}
</Box>
</Stack>
)}
</Formik>
</ChakraProvider>
);
}
Example #9
Source File: IconDetailOverlay.tsx From lucide with ISC License | 4 votes |
IconDetailOverlay = ({ open = true, close, icon }) => {
const toast = useToast();
const { colorMode } = useColorMode();
const { tags = [], name } = icon;
const {color, strokeWidth, size} = useContext(IconStyleContext);
const iconRef = useRef<SVGSVGElement>(null);
const [isMobile] = useMediaQuery("(max-width: 560px)")
const { isOpen, onOpen, onClose } = useDisclosure()
const handleClose = () => {
onClose();
close();
};
useEffect(() => {
if(open) {
onOpen()
}
}, [open])
const iconStyling = (isLight) => ({
height: "25vw",
width: "25vw",
minHeight: "160px",
minWidth: "160px",
maxHeight: "240px",
maxWidth: "240px",
color: color,
});
const downloadIcon = ({src, name} : IconDownload) => download(src, `${name}.svg`, 'image/svg+xml');
const copyIcon = ({src, name} : IconDownload) => {
copy(src);
toast({
title: "Copied!",
description: `Icon "${name}" copied to clipboard.`,
status: "success",
duration: 1500,
isClosable: true
});
}
const downloadPNG = ({src, name}: IconDownload) => {
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext("2d");
const image = new Image();
image.src = `data:image/svg+xml;base64,${btoa(src)}`;
image.onload = function() {
ctx.drawImage(image, 0, 0);
const link = document.createElement('a');
link.download = `${name}.png`;
link.href = canvas.toDataURL('image/png')
link.click();
}
}
return (
<Box
position="fixed"
bottom={0}
zIndex={2}
width="100%"
left={0}
height={0}
key={name}
>
<Slide direction="bottom" in={isOpen} style={{ zIndex: 10 }}>
<Flex
alignItems="center"
justifyContent="space-between"
pt={4}
pb={4}
maxW="850px"
margin="0 auto"
w="full"
px={8}
>
<Box
borderWidth="1px"
rounded="lg"
width="full"
boxShadow={theme.shadows.xl}
position="relative"
bg={
colorMode == "light"
? theme.colors.white
: theme.colors.gray[700]
}
padding={8}
>
<IconButton
size="sm"
aria-label="Close overlay"
variant="ghost"
color="current"
ml="3"
position="absolute"
top={4}
right={4}
onClick={handleClose}
icon={<Close />}
/>
<Flex direction={['column', 'row']} alignItems={['center', 'flex-start']}>
<Flex>
<Box
borderWidth="1px"
rounded="md"
position="relative"
bg={
colorMode == "light"
? theme.colors.whiteAlpha[800]
: theme.colors.blackAlpha[500]
}
padding={0}
>
<div
style={iconStyling(colorMode == "light")}
className="icon-large"
>
<IconWrapper
content={icon.content}
stroke={color}
strokeWidth={strokeWidth}
height={size}
width={size}
ref={iconRef}
/>
</div>
<svg className="icon-grid" width="24" height="24" viewBox={`0 0 ${size} ${size}`} fill="none" stroke={colorMode == "light" ? '#E2E8F0' : theme.colors.gray[600]} strokeWidth="0.1" xmlns="http://www.w3.org/2000/svg">
{ Array.from({ length:(size - 1) }, (_, i) => (
<g key={`grid-${i}`}>
<line key={`horizontal-${i}`} x1={0} y1={i + 1} x2={size} y2={i + 1} />
<line key={`vertical-${i}`} x1={i + 1} y1={0} x2={i + 1} y2={size} />
</g>
)) }
</svg>
</Box>
</Flex>
<Flex marginLeft={[0, 8]} w="100%">
<Box w="100%">
<Flex
justify={isMobile ? 'center' : 'flex-start'}
marginTop={isMobile ? 10 : 0}
>
<Box
position="relative"
mb={1}
display="inline-block"
style={{ cursor: "pointer" }}
pr={6}
>
<Text fontSize="3xl">
{icon.name}
</Text>
{ icon?.contributors?.length ? ( <ModifiedTooltip/> ) : null}
</Box>
</Flex>
<Box mb={4}>
{ tags?.length ? (
<Text
fontSize="xl"
fontWeight="bold"
color={
colorMode === "light"
? 'gray.600'
: 'gray.500'
}
>
{ tags.join(' • ') }
</Text>
) : ''}
{/* <Button size="sm" fontSize="md" variant="ghost" onClick={() => downloadIcon(icon)}>
Edit Tags
</Button> */}
</Box>
<Box overflowY="auto" w="100%" pt={1} pb={1}>
<ButtonGroup spacing={4}>
<Button variant="solid" onClick={() => downloadIcon({src: iconRef.current.outerHTML, name: icon.name})} mb={1}>
Download SVG
</Button>
<Button variant="solid" onClick={() => copyIcon({src: iconRef.current.outerHTML, name: icon.name})} mb={1}>
Copy SVG
</Button>
<Button variant="solid" onClick={() => downloadPNG({src: iconRef.current.outerHTML, name: icon.name})} mb={1}>
Download PNG
</Button>
</ButtonGroup>
</Box>
{ icon?.contributors?.length ? (
<>
<Heading as="h5" size="sm" marginTop={4} marginBottom={2}>
Contributors:
</Heading>
<AvatarGroup size="md">
{ icon.contributors.map((commit, index) => (
<Link href={`https://github.com/${commit.author}`} isExternal key={`${index}_${commit.sha}`}>
<Tooltip label={commit.author} key={commit.sha}>
<Avatar name={commit.author} src={`https://github.com/${commit.author}.png?size=88`} />
</Tooltip>
</Link>
)) }
</AvatarGroup>
</>
) : null }
</Box>
</Flex>
</Flex>
</Box>
</Flex>
</Slide>
</Box>
);
}
Example #10
Source File: Package.tsx From lucide with ISC License | 4 votes |
Package = ({ name, description, image, shields, source, documentation }) => {
const { colorMode } = useColorMode();
return (
<Box
borderWidth="1px"
rounded="lg"
position="relative"
width="100%"
maxWidth="1152px"
boxShadow="lg"
bg={colorMode == 'light' ? 'gray-200' : 'gray.700'}
padding={8}
>
<Flex
justifyContent={{
base: 'center',
md: 'flex-start',
}}
flexDirection={{
base: 'column',
md: 'row',
}}
>
<Flex
marginRight={{
base: 0,
md: 8,
}}
marginBottom={{
base: 4,
md: 0,
}}
flex={3}
align="center"
>
<Box marginX="auto">
<Image width={278} height={120} src={image} />
</Box>
</Flex>
<Box
flex={5}
marginRight={4}
textAlign={{
base: 'center',
md: 'left',
}}
>
<Heading as="h2" fontSize="3xl" mb={2}>
{name}
</Heading>
<Text mb={3}>{description}</Text>
<ButtonGroup spacing={2}>
{shields.map(({ alt, src, href }, index) => (
<Link href={href} passHref>
<a target="_blank">
<img {...{ alt, src }} key={index} />
</a>
</Link>
))}
</ButtonGroup>
</Box>
<Flex
placeItems="center"
align="center"
marginTop={{
base: 4,
md: 0,
}}
>
<ButtonGroup
// as={Stack}
// spacing={8}
// align='center'
flexDirection={{
base: 'column',
lg: 'initial',
}}
margin="auto"
justifyContent={{
base: 'center',
sm: 'flex-start',
}}
>
<Link passHref href={documentation}>
<Button as="a" variant="solid" textDecoration="none" leftIcon={<FileText />} my={2}>
Documentation
</Button>
</Link>
<Link passHref href={source}>
<Button as="a" variant="solid" textDecoration="none" leftIcon={<Code />} my={2}>
Source
</Button>
</Link>
</ButtonGroup>
</Flex>
</Flex>
</Box>
);
}
Example #11
Source File: Items.tsx From ksana.in with Apache License 2.0 | 4 votes |
export function Items({ user, isFormVisible, onShowForm }: IUrlListProps) {
const { data, isLoading = true } = useUrls(user?.id || '')
const [searchText, setSearchText] = useState<string>('')
const [view, setView] = useState<string>(VIEW.LIST)
const [filteredData, setFilteredData] = useState<IUrl[]>(data)
useEffect(() => {
if (!isLoading) {
if (searchText === '') {
setFilteredData(data)
} else if (searchText && searchText.length > 1) {
const foundData = data.filter((d: IUrl) => {
const containUrl = d.real_url.toLowerCase().includes(searchText.toLowerCase())
const containSlug = d.slug.toLowerCase().includes(searchText.toLowerCase())
return containSlug || containUrl
})
setFilteredData(foundData)
}
}
}, [isLoading, searchText, data])
if (isLoading) {
return <LoadingSkeleton />
}
const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
setSearchText(e.target.value)
}
const isGrid = view === VIEW.GRID
const isList = view === VIEW.LIST
const handleViewGrid = () => {
setView(VIEW.GRID)
}
const handleViewList = () => {
setView(VIEW.LIST)
}
return (
<>
{!isLoading && data && data.length > 0 ? (
<>
<TotalStats data={data} />
<SearchInput onChangeSearch={handleSearch} searchText={searchText} />
<Flex justifyContent="flex-end" alignItems="center">
<ButtonGroup spacing="2" variant="outline">
<IconButton
variant="outline"
borderColor={'orange.400'}
color="orange.400"
_hover={{
bg: 'orange.200'
}}
_focus={{
bg: 'orange.200'
}}
_active={{
bg: 'orange.400',
color: 'white'
}}
aria-label="View Grid"
isActive={isGrid}
onClick={handleViewGrid}
icon={<HiViewGrid />}
/>
<IconButton
variant="outline"
borderColor={'orange.400'}
color="orange.400"
_hover={{
bg: 'orange.200'
}}
_focus={{
bg: 'orange.200'
}}
_active={{
bg: 'orange.400',
color: 'white'
}}
aria-label="View List"
isActive={isList}
onClick={handleViewList}
icon={<HiViewList />}
/>
</ButtonGroup>
</Flex>
{filteredData.length > 0 ? (
<SimpleGrid columns={isGrid ? 2 : 1} spacing={2}>
{filteredData.map((urlItem: IUrl) => (
<Item data={urlItem} user={user} key={urlItem.id} />
))}
</SimpleGrid>
) : (
<ErrorDataNotFound
useCta={false}
title="Tidak menemukan apapun nih, coba kata kunci lain!"
/>
)}
</>
) : (
<>{!isFormVisible ? <ErrorDataNotFound useCta ctaAction={onShowForm} /> : null}</>
)}
</>
)
}
Example #12
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 #13
Source File: TextPanel.tsx From openchakra with MIT License | 4 votes |
TextPanel = () => {
const { setValue, setValueFromEvent } = useForm()
const theme = useTheme()
const fontWeight = usePropsSelector('fontWeight')
const fontStyle = usePropsSelector('fontStyle')
const textAlign = usePropsSelector('textAlign')
const fontSize = usePropsSelector('fontSize')
const letterSpacing = usePropsSelector('letterSpacing')
const lineHeight = usePropsSelector('lineHeight')
return (
<>
<FormControl label="Style">
<IconButton
mr={1}
aria-label="bold"
icon={<GoBold />}
onClick={() => {
setValue('fontWeight', fontWeight ? null : 'bold')
}}
size="xs"
colorScheme={fontWeight ? 'whatsapp' : 'gray'}
variant={fontWeight ? 'solid' : 'outline'}
>
Bold
</IconButton>
<IconButton
aria-label="italic"
icon={<GoItalic />}
onClick={() => {
setValue('fontStyle', fontStyle === 'italic' ? null : 'italic')
}}
size="xs"
colorScheme={fontStyle === 'italic' ? 'whatsapp' : 'gray'}
variant={fontStyle === 'italic' ? 'solid' : 'outline'}
>
Italic
</IconButton>
</FormControl>
<FormControl label="Text align">
<ButtonGroup size="xs" isAttached>
<IconButton
aria-label="bold"
icon={<MdFormatAlignLeft />}
onClick={() => {
setValue('textAlign', 'left')
}}
colorScheme={textAlign === 'left' ? 'whatsapp' : 'gray'}
variant={textAlign === 'left' ? 'solid' : 'outline'}
/>
<IconButton
aria-label="italic"
icon={<MdFormatAlignCenter />}
onClick={() => {
setValue('textAlign', 'center')
}}
colorScheme={textAlign === 'center' ? 'whatsapp' : 'gray'}
variant={textAlign === 'center' ? 'solid' : 'outline'}
/>
<IconButton
aria-label="italic"
icon={<MdFormatAlignRight />}
onClick={() => {
setValue('textAlign', 'right')
}}
colorScheme={textAlign === 'right' ? 'whatsapp' : 'gray'}
variant={textAlign === 'right' ? 'solid' : 'outline'}
/>
<IconButton
aria-label="italic"
icon={<MdFormatAlignJustify />}
onClick={() => {
setValue('textAlign', 'justify')
}}
colorScheme={textAlign === 'justify' ? 'whatsapp' : 'gray'}
variant={textAlign === 'justify' ? 'solid' : 'outline'}
/>
</ButtonGroup>
</FormControl>
<FormControl label="Font size" htmlFor="fontSize">
<InputSuggestion
value={fontSize}
handleChange={setValueFromEvent}
name="fontSize"
>
{Object.keys(theme.fontSizes).map(option => (
<ComboboxOption key={option} value={option} />
))}
</InputSuggestion>
</FormControl>
<ColorsControl withFullColor enableHues name="color" label="Color" />
<FormControl label="Line height" htmlFor="lineHeight">
<InputSuggestion
value={lineHeight}
handleChange={setValueFromEvent}
name="lineHeight"
>
{Object.keys(theme.lineHeights).map(option => (
<ComboboxOption key={option} value={option} />
))}
</InputSuggestion>
</FormControl>
<FormControl label="Letter spacing" htmlFor="letterSpacing">
<InputSuggestion
value={letterSpacing}
handleChange={setValueFromEvent}
name="letterSpacing"
>
{Object.keys(theme.letterSpacings).map(option => (
<ComboboxOption key={option} value={option} />
))}
</InputSuggestion>
</FormControl>
</>
)
}