styled-components#useTheme JavaScript Examples
The following examples show how to use
styled-components#useTheme.
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.native.js From polaris with Apache License 2.0 | 6 votes |
Header = () => {
const { t } = useTranslation()
const navigation = useNavigation()
const theme = useTheme()
const { currentRoute, params } = usePlatformLocation()
const { defaultPath } = useContext(RoutesContext)
const isHome = currentRoute.path === defaultPath
const translatedName = t(currentRoute.name)
const title = replaceParams(translatedName, params)
return (
<NativeHeader
leftComponent={<Left isHome={isHome} goBack={navigation.goBack} />}
centerComponent={{
text: title,
style: {
color: theme.colors.white,
fontSize: 21
}
}}
rightComponent={<Right toggleDrawer={navigation.toggleDrawer} />}
/>
)
}
Example #2
Source File: nav.test.web.js From polaris with Apache License 2.0 | 6 votes |
ThemeSwitchFixture = () => {
const theme = useTheme()
return (
<View>
<Navigation />
<Text>Theme: {theme.name}</Text>
</View>
)
}
Example #3
Source File: index.web.jsx From polaris with Apache License 2.0 | 6 votes |
export default function Header() {
const { t } = useTranslation()
const { toggleTheme } = useContext(ThemeActionsContext)
const theme = useTheme()
return (
<Wrapper>
<Left>
<Link title={t('home:title')} path={'/'} />
</Left>
<Center>
<ThemeText>{t('nav:topCenter')}</ThemeText>
</Center>
<Right>
<Link title={t('home:settingsButton')} path={'/settings'} />
<Switch
onValueChange={toggleTheme}
value={theme.name !== 'light'}
testID="theme-switch"
/>
</Right>
</Wrapper>
)
}
Example #4
Source File: index.jsx From polaris with Apache License 2.0 | 6 votes |
HomeScreen = () => {
const { t } = useTranslation()
const theme = useTheme()
return (
<Container>
<NearformLogo
width={200}
height={50}
fill={theme.colors.primary}
title="Nearform logo"
/>
<StyledLinkButton title={t('home:simpleButton')} path="/simple" />
<StyledLinkButton title={t('home:listViewButton')} path="/listView" />
{Platform.OS !== 'web' && (
<StyledLinkButton title={t('home:cameraButton')} path="/camera" />
)}
<StyledLinkButton
title={t('home:pushNotificationsButton')}
path="/pushNotifications"
/>
<StyledLinkButton title={t('home:responsiveButton')} path="/responsive" />
<StyledLinkButton title={t('home:authButton')} path="/auth" />
{Platform.OS !== 'web' && (
<>
<StyledLinkButton title={t('home:qrCodeButton')} path="/qrCode" />
<StyledLinkButton title={t('home:mapButton')} path="/map" />
</>
)}
<Text testID="welcome">Text for tests</Text>
</Container>
)
}
Example #5
Source File: fixtures.js From polaris with Apache License 2.0 | 6 votes |
ContextualView = () => {
const theme = useTheme()
const translation = useTranslation()
if (!translation) throw new Error('Nothing returned from useTranslation')
if (!theme || !theme.name)
throw new Error(`${!theme ? 'No' : 'Empty'} theme returned from useTheme`)
const { t, i18n } = translation
return (
<View>
<Text>{t('headingText')}</Text>
<Text testID="lang-name">Current language is {i18n.language}</Text>
<Text testID="theme-name">Current theme is {theme.name}</Text>
</View>
)
}
Example #6
Source File: theme-switcher.js From polaris with Apache License 2.0 | 6 votes |
ThemeSwitcher = () => {
const { toggleTheme } = React.useContext(ThemeActionsContext);
const theme = useTheme();
return (
<Container>
<Text>Switch theme</Text>
<Switch onValueChange={toggleTheme} value={theme.name !== 'light'} testID="theme-switch" />
</Container>
);
}
Example #7
Source File: Icon.web.js From blade with MIT License | 6 votes |
Icon = ({ size, fill, children, ...rest }) => {
const theme = useTheme();
return (
<svg
focusable={false}
aria-hidden={true}
fill={getColor(theme, fill)}
height={iconSize[size]}
width={iconSize[size]}
{...automation('ds-icon')}
{...rest}
>
{children}
</svg>
);
}
Example #8
Source File: UserHeader.js From plataforma-sabia with MIT License | 6 votes |
UserHeader = () => {
const { colors } = useTheme();
const { user } = useAuth();
const { t } = useTranslation(['common']);
const [ref, isDropDownVisible, setIsDropDownVisible] = useVisibleComponent();
const userFirstName = user.full_name && user.full_name.split(' ')[0];
const router = useRouter();
const toggleVisible = () => setIsDropDownVisible((prev) => !prev);
const handleToggleDropDown = (e) => {
e.preventDefault();
if (!user?.email) {
router.push(internalPages.signIn);
} else {
toggleVisible();
}
};
return (
<LoginBox ref={ref}>
<UserButton type="button" onClick={handleToggleDropDown} data-cy="user-dropdown-button">
<MdAccountCircle color={colors.secondary} />
<span>{userFirstName || t('common:login')}</span>
</UserButton>
<UserProfileDropDown visible={isDropDownVisible} toggleVisible={toggleVisible} />
</LoginBox>
);
}
Example #9
Source File: new.js From plataforma-sabia with MIT License | 5 votes |
NewSolutionPage = () => {
const { colors } = useTheme();
const { t } = useTranslation(['pages']);
return (
<>
<Head
title={t('pages:solution.new.title')}
description={t('pages:solution.new.description')}
keywords={t('pages:solution.new.keywords')}
/>
<Wrapper>
<Container>
<Title color={colors.black}>Que tipo de solução você irá cadastrar?</Title>
<RegisterType>
<Link href={internalPages.newTechnology} passHref>
<RectangularButton
as="a"
variant="backgroundImage"
backgroundUrl="/buttons/agro-machine.png"
colorVariant="orange"
fullWidth
>
Tecnologias
</RectangularButton>
</Link>
<Link href={internalPages.newService} passHref>
<RectangularButton
as="a"
variant="backgroundImage"
backgroundUrl="/buttons/hand-holding-earth.png"
colorVariant="green"
fullWidth
>
Serviços
</RectangularButton>
</Link>
</RegisterType>
</Container>
</Wrapper>
</>
);
}
Example #10
Source File: index.native.jsx From polaris with Apache License 2.0 | 5 votes |
ButtonAtom = props => {
const theme = useTheme()
return <Button color={theme.colors.primary} {...props} />
}
Example #11
Source File: index.js From plataforma-sabia with MIT License | 5 votes |
Button = ({
children,
disabled,
onClick,
variant,
type,
fullWidth,
isLink,
linkType,
...rest
}) => {
const { colors } = useTheme();
const Link = isLink && linkType === 'default' ? StyledNextLink : StyledScrollLink;
let bgColor;
switch (variant) {
case 'primary':
bgColor = colors.primary;
break;
case 'secondary':
bgColor = colors.secondary;
break;
default:
bgColor = colors.primary;
}
return isLink ? (
<Link $bgColor={bgColor} $color={colors.white} {...rest}>
{children}
</Link>
) : (
<StyledButton
onClick={onClick}
disabled={disabled}
type={type}
$bgColor={bgColor}
$color={colors.white}
fullWidth={fullWidth}
>
{children}
</StyledButton>
);
}
Example #12
Source File: CircularButton.js From plataforma-sabia with MIT License | 5 votes |
Button = ({
children,
disabled,
onClick,
variant,
type,
title,
size,
float,
name,
height,
width,
}) => {
const { colors } = useTheme();
let bgColor;
switch (variant) {
case 'primary':
bgColor = colors.primary;
break;
case 'secondary':
bgColor = colors.lightGray;
break;
case 'success':
bgColor = colors.green;
break;
case 'info':
bgColor = colors.lightBlue;
break;
case 'remove':
bgColor = colors.lightGray3;
break;
default:
bgColor = colors.primary;
}
return (
<CircularButton
onClick={onClick}
disabled={disabled}
type={type}
bgColor={bgColor}
color={colors.white}
size={size}
title={title}
float={float}
name={name}
height={height}
width={width}
>
{children}
</CircularButton>
);
}
Example #13
Source File: Button.js From plataforma-sabia with MIT License | 5 votes |
Button = ({
children,
disabled,
onClick,
variant,
type,
title,
uppercase,
name,
as,
href,
}) => {
const { colors } = useTheme();
let bgColor;
switch (variant) {
case 'primary':
bgColor = colors.primary;
break;
case 'secondary':
bgColor = colors.lightGray;
break;
case 'success':
bgColor = colors.secondary;
break;
case 'info':
bgColor = colors.blue;
break;
default:
bgColor = colors.primary;
}
return (
<StyledButton
onClick={onClick}
disabled={disabled}
type={type}
bgColor={bgColor}
color={colors.white}
title={title}
uppercase={uppercase}
name={name}
as={as}
href={href}
>
{children}
</StyledButton>
);
}
Example #14
Source File: Label.web.js From blade with MIT License | 5 votes |
AnimatedLabel = ({
children,
position,
disabled,
isFocused,
hasError,
variant,
value,
hasText,
layoutDimensions,
width,
id,
}) => {
const theme = useTheme();
const floatViewAnimationStyle = getFloatViewAnimationStyle({
isFocused,
hasText,
layoutDimensions,
});
return (
<Space
margin={styles.label.margin({
position,
variant,
})}
>
<FloatView layoutDimensions={layoutDimensions} style={floatViewAnimationStyle}>
<StyledText
as="label"
htmlFor={id}
isFocused={isFocused}
hasError={hasError}
hasText={hasText}
disabled={disabled}
variant={variant}
value={value}
theme={theme}
position={position}
width={width}
>
{children}
</StyledText>
</FloatView>
</Space>
);
}
Example #15
Source File: Label.web.js From blade with MIT License | 5 votes |
RegularLabel = ({
children,
position,
hasError,
hasText,
disabled,
variant,
value,
isFocused,
width,
id,
}) => {
const theme = useTheme();
return (
<Space
margin={styles.label.margin({
position,
variant,
})}
>
<StyledText
as="label"
htmlFor={id}
hasError={hasError}
disabled={disabled}
variant={variant}
value={value}
hasText={hasText}
theme={theme}
isFocused={isFocused}
position={position}
width={width}
id={id}
>
{children}
</StyledText>
</Space>
);
}
Example #16
Source File: TextInput.web.js From blade with MIT License | 4 votes |
TextInput = ({
placeholder,
onChange,
onBlur,
helpText,
errorText,
variant,
prefix,
suffix,
disabled,
value,
iconLeft,
iconRight,
onRightIconClick,
maxLength,
label,
testID,
labelPosition,
width,
type,
id,
name,
_isMultiline,
autoCapitalize,
}) => {
const theme = useTheme();
const inputRef = useRef();
const containerRef = useRef();
const [isFocused, setIsFocused] = useState(false);
const [input, setInput] = useState(value || '');
// Used for storing layout value of TextInput
const [layoutDimensions, setLayoutDimensions] = useState(null);
// Used to hide placeholder while label is inside the TextInput
const [isPlaceholderVisible, setIsPlaceholderVisible] = useState(isFocused);
const hasText = !isEmpty(input);
const hasAnimatedLabel = variant === 'outlined';
const placeholderTextColor = getPlaceholderTextColor({
theme,
disabled,
isPlaceholderVisible,
hasAnimatedLabel,
});
// Derive accessory conditions based on props
const { hasError, hasPrefix, hasSuffix, hasLeftIcon, hasRightIcon } = getAccessoryConfig({
errorText,
prefix,
suffix,
iconLeft,
iconRight,
});
if (labelPosition === 'left' && variant === 'outlined') {
// Outlined Text Input has only a top label
throw Error('Cannot have a left label on an outlined Text Input');
}
if (!isEmpty(prefix) && !isEmpty(iconLeft)) {
throw Error('Cannot have prefix and left icon together');
}
if (!isEmpty(suffix) && !isEmpty(iconRight)) {
throw Error('Cannot have suffix and right icon together');
}
const onFocus = useCallback(() => {
setIsFocused(true);
/* Wait for 90ms to show the placeholder since it takes 100ms for Label to animate from inside to top of the TextInput.
Otherwise they both overlap */
/* Don't have any delay if label is on left of TextInput */
setTimeout(() => {
setIsPlaceholderVisible(true);
}, 90);
}, [setIsFocused, setIsPlaceholderVisible]);
const onBlurText = useCallback(
(event) => {
setIsFocused(false);
setIsPlaceholderVisible(false);
const inputValue = event.target.value;
setInput(inputValue);
onBlur(inputValue);
},
[onBlur],
);
const onChangeText = useCallback(
(event) => {
let inputValue = event.target.value;
if (inputValue.length > maxLength) {
return;
}
if (autoCapitalize !== 'none') {
inputValue = transformString(inputValue, autoCapitalize);
}
setInput(inputValue);
onChange(inputValue);
},
[maxLength, onChange, autoCapitalize],
);
// allowed values = 0-9 "." "," "whitespace" "-"
const isInputNumberAllowed = (inputValue) => /^[0-9., -]+$/g.test(inputValue);
const onKeyPress = useCallback(
(event) => {
if (type === 'number') {
const charCode = typeof event.which === 'number' ? event.which : event.keyCode;
const char = String.fromCharCode(charCode);
const isAllowed = isInputNumberAllowed(char);
if (!isAllowed) {
event.preventDefault();
}
}
},
[type],
);
const onPaste = useCallback(
(event) => {
if (type === 'number') {
const inputValue = event.clipboardData.getData('Text');
const isAllowed = isInputNumberAllowed(inputValue);
if (!isAllowed) {
event.preventDefault();
}
}
},
[type],
);
useEffect(() => {
if (value === '' || value) {
setInput(value);
}
}, [value]);
useEffect(() => {
if (inputRef.current && containerRef.current) {
const containerRect = containerRef.current.getBoundingClientRect();
const inputRect = inputRef.current.getBoundingClientRect();
const initialLeftPosition = inputRect.x - containerRect.x;
const finalTopPosition = inputRef.current.offsetHeight;
setLayoutDimensions({
initialLeftPosition,
finalTopPosition,
});
}
}, [inputRef, containerRef]);
useEffect(() => {
// Adjust height of textarea as user types for outlined variant
if (inputRef.current && _isMultiline && variant === 'outlined') {
inputRef.current.style.height = 'inherit';
const height = inputRef.current.scrollHeight;
// if scroll-height is greater than 60 then keep height at 60 for some space between Input & Line
if (height > 60) {
inputRef.current.style.height = `60px`;
} else {
inputRef.current.style.height = `${height}px`;
}
}
}, [_isMultiline, variant, inputRef, input]);
// Due to browser issues, if type=number we use type=text and show numpad on mobile devices using inputMode=numeric
const inputType = type === 'number' ? 'text' : type;
/* Specifies the initial value for rows in textarea(_isMultiline)
* Has no effect on text-input as rows is not passed if _isMultiline = false */
const noOfRows = variant === 'outlined' ? 1 : 3;
return (
<Flex flexDirection="column" justifyContent="flex-end">
<View ref={containerRef}>
{labelPosition === 'top' && !hasAnimatedLabel ? (
<Label.Regular
position={labelPosition}
disabled={disabled}
//@ts-expect-error
isFocused={isFocused}
variant={variant}
hasError={hasError}
hasText={hasText}
value={input}
width={width}
id={id}
>
{label}
</Label.Regular>
) : null}
{/* Text Input Container */}
<Flex flexDirection="row" alignItems="flex-start">
<View>
{!hasAnimatedLabel && labelPosition === 'left' ? (
<Label.Regular
position={labelPosition}
disabled={disabled}
//@ts-expect-error
isFocused={isFocused}
variant={variant}
hasError={hasError}
hasText={hasText}
value={input}
width={width}
id={id}
>
{label}
</Label.Regular>
) : null}
{/* Text Input */}
<Flex flexDirection="column" flex={width === 'auto' ? 1 : 0}>
<View>
<InteractionContainer disabled={disabled} hasError={hasError}>
<Size
height={styles.fillContainer.height({
variant,
_isMultiline,
})}
maxHeight={8}
>
<Space
padding={styles.fillContainer.padding({
variant,
})}
>
<FillContainer variant={variant} isFocused={isFocused} disabled={disabled}>
{hasAnimatedLabel && !isEmpty(layoutDimensions) ? (
<Label.Animated
//@ts-expect-error
position={labelPosition}
disabled={disabled}
isFocused={isFocused}
variant={variant}
hasError={hasError}
value={input}
hasText={hasText}
layoutDimensions={layoutDimensions}
width={width}
id={id}
>
{label}
</Label.Animated>
) : null}
<Flex flexDirection="row" alignItems="center">
<Size
width={styles.inputContainer.width({
width,
})}
maxHeight="100%"
>
<InputContainer>
{hasPrefix ? (
<AccessoryText
//@ts-expect-error
position="left"
variant={variant}
disabled={disabled}
isFocused={isFocused}
>
{prefix}
</AccessoryText>
) : null}
{hasLeftIcon ? (
<AccessoryIcon
variant={variant}
icon={iconLeft}
disabled={disabled}
hasError={hasError}
//@ts-expect-error
isFocused={isFocused}
position="left"
/>
) : null}
<Flex flex={1}>
<Space
padding={styles.textInput.padding({
variant,
})}
>
<Size maxHeight={8}>
<StyledInput
id={id}
name={name}
type={inputType}
placeholder={placeholder}
placeholderTextColor={placeholderTextColor}
onFocus={onFocus}
onBlur={onBlurText}
onChange={onChangeText}
onKeyPress={onKeyPress}
onPaste={onPaste}
hasText={hasText}
readonly={disabled}
disabled={disabled}
variant={variant}
hasPrefix={hasPrefix}
hasLeftIcon={hasLeftIcon}
maxLength={maxLength}
value={input}
ref={inputRef}
as={_isMultiline ? 'textarea' : 'input'}
rows={_isMultiline ? noOfRows : ''}
inputMode={type === 'number' ? 'numeric' : null} // pass only for type=number, otherwise let browser infer via type
{...automation(testID)}
/>
</Size>
</Space>
</Flex>
{hasSuffix ? (
<AccessoryText
//@ts-expect-error
position="right"
variant={variant}
disabled={disabled}
isFocused={isFocused}
>
{suffix}
</AccessoryText>
) : null}
{hasRightIcon ? (
<View
onClick={onRightIconClick}
{...automation(`${testID}-right-icon`)}
>
<AccessoryIcon
variant={variant}
icon={iconRight}
disabled={disabled}
hasError={hasError}
//@ts-expect-error
isFocused={isFocused}
position="right"
/>
</View>
) : null}
</InputContainer>
</Size>
</Flex>
</FillContainer>
</Space>
</Size>
<Line isFocused={isFocused} hasError={hasError} disabled={disabled} />
</InteractionContainer>
{/* Bottom texts */}
{hasError || helpText ? (
<Flex flexDirection="row" justifyContent="space-between">
<View>
<Text errorText={errorText} helpText={helpText} disabled={disabled} />
{maxLength ? (
<CharacterCount
disabled={disabled}
maxLength={maxLength}
currentLength={input.length || 0}
/>
) : null}
</View>
</Flex>
) : null}
</View>
</Flex>
</View>
</Flex>
</View>
</Flex>
);
}
Example #17
Source File: Controls.js From plataforma-sabia with MIT License | 4 votes |
Controls = ({
data,
sortOptions,
handleSortBy,
currentOrder,
handlePagination,
currentPage,
totalPages,
totalItems,
itemsPerPage,
}) => {
const [sortOption, setSortOption] = useState('');
const isSelectFocusedRef = useRef(false);
const { t } = useTranslation(['datagrid']);
const {
colors: { lightGray },
} = useTheme();
/**
* Formats page items count based on current page
*
* @returns {string} Formatted pagination data, e.g. `1-10 of 20`
*/
const getFirstAndLastItem = () => {
if (currentPage === 1) {
return {
firstItem: 1,
lastItem: data.length,
};
}
if (currentPage === totalPages) {
return {
firstItem: totalItems - data.length + 1,
lastItem: totalItems,
};
}
return {
firstItem: (currentPage - 1) * itemsPerPage + 1,
lastItem: data.length + (currentPage - 1) * itemsPerPage,
};
};
const getItemsCountByPage = () => {
const { firstItem, lastItem } = getFirstAndLastItem();
return `${firstItem} - ${lastItem} ${t('datagrid:paginationLabel')} ${totalItems}`;
};
const sortByI18 = t('datagrid:sortByOption');
const customSelectStyles = useMemo(
() => ({
container: (base, state) => {
isSelectFocusedRef.current = state.isFocused;
return {
...base,
display: 'inline-block',
};
},
placeholder: (base, state) => {
return {
...base,
...(isSelectFocusedRef.current && state.value
? {}
: {
position: 'static',
top: 'auto',
transform: 'none',
}),
};
},
input: (base, state) => {
return {
...base,
...(isSelectFocusedRef.current && state.value
? {}
: {
position: 'absolute',
}),
};
},
singleValue: (base, state) => {
return {
...base,
maxWidth: 'none',
...(isSelectFocusedRef.current && state.value
? {}
: {
position: 'static',
top: 'auto',
transform: 'none',
}),
};
},
valueContainer: (base) => ({
...base,
alignItems: 'center',
display: 'flex',
':before': {
content: `"${sortByI18}"`,
color: lightGray,
},
}),
}),
[sortByI18, lightGray],
);
return (
<GridControls>
{handleSortBy && (
<div className="sort-by">
<Select
instanceId="bookmarks-ordering-select"
options={sortOptions}
styles={customSelectStyles}
value={sortOption}
placeholder={t('datagrid:sortByPlaceholder')}
onChange={(option) => {
setSortOption(option);
handleSortBy(option.value);
}}
isSearchable={false}
/>
{sortOption && (
<div className="sort-order">
<button
type="button"
aria-label="Ascending Order"
onClick={() => handleSortBy(sortOption.value, orderEnum.ASC)}
>
<AscOrderIcon
className={
currentOrder === orderEnum.ASC ? 'active' : undefined
}
/>
</button>
<button
type="button"
aria-label="Descending Order"
onClick={() => handleSortBy(sortOption.value, orderEnum.DESC)}
>
<DescOrderIcon
className={
currentOrder === orderEnum.DESC ? 'active' : undefined
}
/>
</button>
</div>
)}
</div>
)}
{handlePagination && (
<div className="pagination">
<button
type="button"
onClick={() => handlePagination(1)}
disabled={currentPage === 1}
aria-label="First Page"
>
<DoubleArrowLeftIcon />
</button>
<button
type="button"
onClick={() => handlePagination(currentPage - 1)}
disabled={currentPage === 1}
aria-label="Previous Page"
>
<ArrowLeftIcon />
</button>
<span>{getItemsCountByPage()}</span>
<button
type="button"
onClick={() => handlePagination(currentPage + 1)}
disabled={currentPage === totalPages}
aria-label="Next Page"
>
<ArrowRightIcon />
</button>
<button
type="button"
onClick={() => handlePagination(totalPages)}
disabled={currentPage === totalPages}
aria-label="Last Page"
>
<DoubleArrowRightIcon />
</button>
</div>
)}
</GridControls>
);
}
Example #18
Source File: RadioOption.web.js From blade with MIT License | 4 votes |
RadioOption = ({ value, disabled, title, helpText, errorText, testID, name, id }) => {
const context = useRadioButtonContext();
const theme = useTheme();
const checked = isChecked({
context,
value,
});
const variantColor = context.variantColor;
const size = context.size;
const radioColor = styles.radio.color({
theme,
disabled,
checked,
variantColor,
});
const onClick = (event) => {
/* prevent default behaviour of label firing click event on the associated input */
event.preventDefault();
if (isDefined(context.onChange) && !disabled) {
context.onChange(value);
}
};
const descriptionText = errorText || helpText;
const shouldShowDescriptionText = (!isEmpty(helpText) || !isEmpty(errorText)) && size !== 'small';
return (
<Flex flexDirection="column" alignSelf="flex-start">
<View>
<Flex alignItems="center">
<Label as="label" onClick={onClick} htmlFor={id} disabled={disabled}>
<Input
id={id}
name={name}
value={value}
disabled={disabled}
checked={checked}
size={size}
backdropStyles={styles.backdrop}
variantColor={variantColor}
{...automation(testID)}
/>
<Flex flexDirection="column" justifyContent="center" alignItems="center">
<Size
width={
styles.backdrop.dimensions({
size,
}).width
}
height={
styles.backdrop.dimensions({
size,
}).height
}
>
<Backdrop>
<Size
width={
styles.circle.dimensions({
size,
}).width
}
height={
styles.circle.dimensions({
size,
}).height
}
>
<Circle
borderWidth={
styles.circle.dimensions({
size,
}).borderWidth
}
color={radioColor}
>
{checked ? (
<Size
width={
styles.dot.dimensions({
size,
}).width
}
height={
styles.dot.dimensions({
size,
}).height
}
>
<Dot backgroundColor={radioColor} />
</Size>
) : null}
</Circle>
</Size>
</Backdrop>
</Size>
</Flex>
<Space margin={styles.title.margin()}>
<Text
color={styles.title.color({
disabled,
})}
size={size}
>
{title}
</Text>
</Space>
</Label>
</Flex>
{shouldShowDescriptionText ? (
<Space
margin={styles.descriptionText.margin({
size,
})}
>
<Text
size={styles.descriptionText.textSize({
size,
})}
color={styles.descriptionText.color({
disabled,
errorText,
})}
>
{descriptionText}
</Text>
</Space>
) : null}
</View>
</Flex>
);
}
Example #19
Source File: new.js From plataforma-sabia with MIT License | 4 votes |
NewServicePage = ({ keywordTerms }) => {
const form = useForm({
defaultValues: {
name: '',
keywords: null,
description: '',
measure_unit: null,
price: '',
type: null,
payment_message: '',
thumbnail_id: null,
},
});
const { colors } = useTheme();
const [addedServices, setAddedServices] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [uploadError, setUploadError] = useState('');
const [thumbnailPreview, setThumbnailPreview] = useState('');
const router = useRouter();
const { user } = useAuth();
const { openModal } = useModal();
const handleSubmit = async (values, _, isFinalize) => {
setIsSubmitting(true);
const preparedData = prepareFormData(values);
const result = await createService(preparedData);
if (result) {
toast.success('Serviço criado com sucesso!');
form.reset();
setThumbnailPreview(null);
setAddedServices((prevValue) => [...prevValue, result]);
} else {
return toast.error('Erro ao criar serviço, tente novamente em instantes');
}
if (isFinalize) {
return router.push('/');
}
return setIsSubmitting(false);
};
const handleDeleteService = async (serviceId) => {
setIsSubmitting(true);
const result = await deleteService(serviceId);
if (!result)
toast.error(
'Ocorreu um erro ao tentar deletar o serviço. Tente novamente em instantes',
);
else {
toast.success('Serviço deletado com sucesso');
setAddedServices((prevValue) => prevValue.filter((item) => item.id !== serviceId));
}
setIsSubmitting(false);
};
/*
* If user's adding the first service he can click in finalize button so it'll
* add the service and then redirect to home
* If user already added some services he can click in finalize button and then
* he'll be just redirected to home
* The advantage is that user can register only one service and get redirected to home
* in just one click
*/
const handleFinalizeRegistration = async () => {
if (addedServices.length) {
return router.push('/');
}
const isValidForm = await form.trigger();
if (isValidForm) {
await handleSubmit(form.getValues(), null, true);
}
return true;
};
const onCreateTerm = async (inputValue, taxonomy) => {
const term = await createTerm(inputValue, taxonomy);
return { label: term.term, value: `${term.id}` };
};
const onDropAttachment = async (acceptedFiles) => {
if (!acceptedFiles) return null;
const formData = new FormData();
if (acceptedFiles.length !== 0) {
formData.append(`files[0]`, acceptedFiles[0], acceptedFiles[0].name);
}
const response = await upload(formData);
if (response.status === 200) {
const { id, url } = response.data[0];
setThumbnailPreview(url);
form.setValue('thumbnail_id', id);
} else {
setUploadError(response.data.error.message[0].message);
}
return true;
};
return (
<Wrapper>
<Protected>
<Container onSubmit={form.handleSubmit(handleSubmit)}>
<Details>
<Title align="left" color={colors.black}>
Novo serviço
</Title>
<Fields>
<Dropzone
accept="image/*"
onDrop={(acceptedFiles) => onDropAttachment(acceptedFiles)}
multiple={false}
>
{({ getRootProps, getInputProps }) => (
<UploadWrapper>
{thumbnailPreview && (
<ThumbnailWrapper>
<Image
src={thumbnailPreview}
width={80}
height={80}
alt="Service thumbnail"
/>
</ThumbnailWrapper>
)}
<UploadThumbnail {...getRootProps()}>
<UploadBody>
<FiImage fontSize={24} />
<div>
<p>Selecione uma imagem de capa</p>
<p>Limite de 5mb</p>
</div>
</UploadBody>
<input name="logo" {...getInputProps()} />
</UploadThumbnail>
{uploadError && <UploadError>{uploadError}</UploadError>}
</UploadWrapper>
)}
</Dropzone>
<InputHiddenField form={form} name="thumbnail_id" />
<Inputs>
<InputField
form={form}
name="name"
label="Nome do serviço"
validation={{ required: true }}
placeholder="Digite o nome"
variant="gray"
/>
<SelectField
form={form}
name="keywords"
instanceId="keywords-select"
placeholder="Busque por palavras chaves (pode adicionar mais de um item)"
label="Palavras-chave"
validation={{ required: true }}
options={mapArrayOfObjectToSelect(keywordTerms, 'term', 'id')}
onCreate={(inputValue) => onCreateTerm(inputValue, 'KEYWORDS')}
variant="gray"
isMulti
creatable
/>
<TextField
form={form}
name="description"
validation={{ required: true }}
label="Descrição"
placeholder="Digite a descrição"
variant="gray"
resize="none"
/>
<SelectField
form={form}
name="measure_unit"
instanceId="measure_unit-select"
label="Unidade de Medida"
placeholder="Escolha uma unidade"
validation={{ required: true }}
options={measureUnitOptions}
variant="rounded"
/>
<CurrencyInputField
form={form}
name="price"
validation={{ required: true }}
label="Preço"
placeholder="Digite o preço"
variant="gray"
/>
<SelectField
form={form}
name="type"
instanceId="type-select"
label="Tipo"
placeholder="Escolha um tipo"
validation={{ required: true }}
options={typeOptions}
variant="rounded"
/>
</Inputs>
<RectangularButton
disabled={isSubmitting}
variant="outlined"
colorVariant="blue"
type="submit"
fullWidth
>
Adicionar novo serviço
</RectangularButton>
<RectangularButton
variant="filled"
colorVariant="orange"
disabled={isSubmitting}
onClick={handleFinalizeRegistration}
fullWidth
>
Finalizar cadastro
</RectangularButton>
</Fields>
<PaymentMessage>
<div>
<p>Responsável:</p>
<p>{user.full_name}</p>
<p>Instituição:</p>
<p>{user.institution?.name}</p>
</div>
<Watcher
form={form}
property="payment_message"
render={(paymentMessageHtml) => (
<HtmlViewField
label="Mensagem de pagamento"
placeholder="Insira a mensagem de pagamento"
html={paymentMessageHtml}
/>
)}
/>
<RectangularButton
fullWidth
variant="text"
colorVariant="blue"
onClick={() =>
openModal(
'ckEditor',
{
form,
name: 'payment_message',
config: {
placeholder: 'Insira a mensagem de pagamento',
removePlugins: [
'ImageUpload',
'Table',
'MediaEmbed',
],
},
onChange: (editorData) =>
form.setValue('payment_message', editorData),
renderWithController: false,
defaultValue: form.getValues()?.payment_message,
},
{
customModal: true,
overlayClick: false,
},
)
}
>
<FiEdit3 fontSize={14} />
Editar mensagem
</RectangularButton>
<InputHiddenField form={form} name="payment_message" />
</PaymentMessage>
</Details>
<Review>
<Title align="left" color={colors.black}>
Serviços
</Title>
{addedServices.map((service) => (
<ServiceCard key={service.id}>
<div>
<ServiceThumbnailWrapper>
<Image
src={service.thumbnail?.url || '/card-image.jpg'}
width={80}
height={80}
/>
</ServiceThumbnailWrapper>
<ServiceInfos>
<p>{service.name}</p>
<span>{service.description}</span>
<p>{formatMoney(service.price)}</p>
</ServiceInfos>
</div>
<RectangularButton
variant="text"
colorVariant="red"
onClick={() => handleDeleteService(service.id)}
>
Remover
</RectangularButton>
</ServiceCard>
))}
</Review>
</Container>
</Protected>
</Wrapper>
);
}
Example #20
Source File: Button.web.js From blade with MIT License | 4 votes |
Button = ({
onClick,
children,
variant,
size,
disabled,
variantColor,
icon: Icon,
iconAlign,
align,
block,
type,
testID,
id,
name,
}) => {
const theme = useTheme();
/* children can only be string or undefined (icon only button) */
if (typeof children !== 'string' && typeof children !== 'undefined') {
throw new Error(
`Error in Button: expected \`children\` of type \`string\` but found ${typeof children}.`,
);
}
/* Button remains focused on Chrome after click until focused on any other element.
* This causes the focus styles to be present on the button.
* Manually call blur on the button when user click and releases the mouse button. */
const onMouseUp = ({ currentTarget }) => {
currentTarget.blur();
};
return (
<Flex
flex={block ? 1 : 0}
flexDirection="row"
alignItems="center"
alignSelf={styles.align({
align,
})}
justifyContent="center"
>
<Size
height={styles.height({
size,
theme,
})}
>
<Space
padding={styles.padding({
size,
children,
theme,
})}
>
<StyledButton
variantColor={variantColor}
onClick={onClick}
onMouseUp={onMouseUp}
disabled={disabled}
size={size}
block={block}
variant={variant}
type={type}
id={id}
name={name}
{...automation(testID)}
>
<React.Fragment>
{isValidElement(Icon) && iconAlign === 'left' ? (
<Space
margin={styles.spaceBetween({
size,
iconAlign,
children,
})}
>
<Icon
size={styles.iconSize({
size,
children,
})}
fill={styles.fontColor({
variant,
variantColor,
disabled,
})}
testID="button-left-icon"
/>
</Space>
) : null}
{children ? (
<Text
color={styles.fontColor({
variant,
variantColor,
disabled,
})}
size={styles.fontSize({
size,
})}
align="center"
weight="bold"
_letterSpacing={styles.letterSpacing({
size,
})}
_lineHeight={styles.lineHeight({
size,
})}
>
{size === 'xsmall' ? children.toUpperCase() : children}
</Text>
) : null}
{isValidElement(Icon) && iconAlign === 'right' ? (
<Space
margin={styles.spaceBetween({
size,
iconAlign,
children,
})}
>
<Icon
size={styles.iconSize({
size,
children,
})}
fill={styles.fontColor({
variant,
variantColor,
disabled,
})}
testID="button-right-icon"
/>
</Space>
) : null}
</React.Fragment>
</StyledButton>
</Space>
</Size>
</Flex>
);
}