diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Dialog/index.tsx | 4 | ||||
-rw-r--r-- | src/components/Dialog/types.ts | 1 | ||||
-rw-r--r-- | src/components/Link.tsx | 15 | ||||
-rw-r--r-- | src/components/Lists.tsx | 5 | ||||
-rw-r--r-- | src/components/Menu/index.tsx | 35 | ||||
-rw-r--r-- | src/components/Menu/index.web.tsx | 96 | ||||
-rw-r--r-- | src/components/Menu/types.ts | 33 | ||||
-rw-r--r-- | src/components/Prompt.tsx | 93 | ||||
-rw-r--r-- | src/components/dialogs/MutedWords.tsx | 37 | ||||
-rw-r--r-- | src/components/icons/Camera.tsx | 9 | ||||
-rw-r--r-- | src/components/icons/DotGrid.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/Flag.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/Heart2.tsx | 9 | ||||
-rw-r--r-- | src/components/icons/PeopleRemove2.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/PersonCheck.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/PersonX.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/StreamingLive.tsx | 5 |
17 files changed, 285 insertions, 82 deletions
diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index f0e7b7e82..5f6edeac7 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -75,6 +75,7 @@ export function Outer({ control, onClose, nativeOptions, + testID, }: React.PropsWithChildren<DialogOuterProps>) { const t = useTheme() const sheet = React.useRef<BottomSheet>(null) @@ -145,7 +146,8 @@ export function Outer({ accessibilityViewIsModal // Android importantForAccessibility="yes" - style={[a.absolute, a.inset_0]}> + style={[a.absolute, a.inset_0]} + testID={testID}> <BottomSheet enableDynamicSizing={!hasSnapPoints} enablePanDownToClose diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 4fc60ec39..9e7ad3c04 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -46,6 +46,7 @@ export type DialogOuterProps = { sheet?: Omit<BottomSheetProps, 'children'> } webOptions?: {} + testID?: string } type DialogInnerPropsBase<T> = React.PropsWithChildren<ViewStyleProp> & T diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 8c963909b..00e6a56f4 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -1,17 +1,13 @@ import React from 'react' import {GestureResponderEvent} from 'react-native' -import { - useLinkProps, - useNavigation, - StackActions, -} from '@react-navigation/native' +import {useLinkProps, StackActions} from '@react-navigation/native' import {sanitizeUrl} from '@braintree/sanitize-url' import {useInteractionState} from '#/components/hooks/useInteractionState' import {isWeb} from '#/platform/detection' import {useTheme, web, flatten, TextStyleProp, atoms as a} from '#/alf' import {Button, ButtonProps} from '#/components/Button' -import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types' +import {AllNavigatorParams} from '#/lib/routes/types' import { convertBskyAppUrlIfNeeded, isExternalUrl, @@ -21,6 +17,7 @@ import {useModalControls} from '#/state/modals' import {router} from '#/routes' import {Text, TextProps} from '#/components/Typography' import {useOpenLink} from 'state/preferences/in-app-browser' +import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped' /** * Only available within a `Link`, since that inherits from `Button`. @@ -74,7 +71,7 @@ export function useLink({ }: BaseLinkProps & { displayText: string }) { - const navigation = useNavigation<NavigationProp>() + const navigation = useNavigationDeduped() const {href} = useLinkProps<AllNavigatorParams>({ to: typeof to === 'string' ? convertBskyAppUrlIfNeeded(sanitizeUrl(to)) : to, @@ -231,6 +228,7 @@ export function InlineLink({ onPress: outerOnPress, download, selectable, + label, ...rest }: InlineLinkProps) { const t = useTheme() @@ -258,7 +256,8 @@ export function InlineLink({ return ( <Text selectable={selectable} - label={href} + accessibilityHint="" + accessibilityLabel={label || href} {...rest} style={[ {color: t.palette.primary_500}, diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index c879f9411..8a6dfdc7c 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -9,9 +9,8 @@ import {cleanError} from 'lib/strings/errors' import {Button} from '#/components/Button' import {Text} from '#/components/Typography' import {StackActions} from '@react-navigation/native' -import {useNavigation} from '@react-navigation/core' -import {NavigationProp} from 'lib/routes/types' import {router} from '#/routes' +import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped' export function ListFooter({ isFetching, @@ -144,7 +143,7 @@ export function ListMaybePlaceholder({ notFoundType?: 'page' | 'results' onRetry?: () => Promise<unknown> }) { - const navigation = useNavigation<NavigationProp>() + const navigation = useNavigationDeduped() const t = useTheme() const {gtMobile, gtTablet} = useBreakpoints() const {_} = useLingui() diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index ee96a5667..9be9dd86b 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {View, Pressable} from 'react-native' +import {View, Pressable, ViewStyle, StyleProp} from 'react-native' import flattenReactChildren from 'react-keyed-flatten-children' import {atoms as a, useTheme} from '#/alf' @@ -16,6 +16,10 @@ import { ItemTextProps, ItemIconProps, } from '#/components/Menu/types' +import {Button, ButtonText} from '#/components/Button' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {isNative} from 'platform/detection' export {useDialogControl as useMenuControl} from '#/components/Dialog' @@ -68,7 +72,13 @@ export function Trigger({children, label}: TriggerProps) { }) } -export function Outer({children}: React.PropsWithChildren<{}>) { +export function Outer({ + children, + showCancel, +}: React.PropsWithChildren<{ + showCancel?: boolean + style?: StyleProp<ViewStyle> +}>) { const context = React.useContext(Context) return ( @@ -78,7 +88,10 @@ export function Outer({children}: React.PropsWithChildren<{}>) { {/* Re-wrap with context since Dialogs are portal-ed to root */} <Context.Provider value={context}> <Dialog.ScrollableInner label="Menu TODO"> - <View style={[a.gap_lg]}>{children}</View> + <View style={[a.gap_lg]}> + {children} + {isNative && showCancel && <Cancel />} + </View> <View style={{height: a.gap_lg.gap}} /> </Dialog.ScrollableInner> </Context.Provider> @@ -185,6 +198,22 @@ export function Group({children, style}: GroupProps) { ) } +function Cancel() { + const {_} = useLingui() + const {control} = React.useContext(Context) + + return ( + <Button + label={_(msg`Close this dialog`)} + size="small" + variant="ghost" + color="secondary" + onPress={() => control.close()}> + <ButtonText>Cancel</ButtonText> + </Button> + ) +} + export function Divider() { return null } diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx index 054e51b01..f4b03f680 100644 --- a/src/components/Menu/index.web.tsx +++ b/src/components/Menu/index.web.tsx @@ -1,6 +1,10 @@ +/* eslint-disable react/prop-types */ + import React from 'react' -import {View, Pressable} from 'react-native' +import {View, Pressable, ViewStyle, StyleProp} from 'react-native' import * as DropdownMenu from '@radix-ui/react-dropdown-menu' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' import * as Dialog from '#/components/Dialog' import {useInteractionState} from '#/components/hooks/useInteractionState' @@ -14,8 +18,10 @@ import { GroupProps, ItemTextProps, ItemIconProps, + RadixPassThroughTriggerProps, } from '#/components/Menu/types' import {Context} from '#/components/Menu/context' +import {Portal} from '#/components/Portal' export function useMenuControl(): Dialog.DialogControlProps { const id = React.useId() @@ -47,6 +53,7 @@ export function Root({ }: React.PropsWithChildren<{ control?: Dialog.DialogOuterProps['control'] }>) { + const {_} = useLingui() const defaultControl = useMenuControl() const context = React.useMemo<ContextType>( () => ({ @@ -67,6 +74,18 @@ export function Root({ return ( <Context.Provider value={context}> + {context.control.isOpen && ( + <Portal> + <Pressable + style={[a.fixed, a.inset_0, a.z_50]} + onPress={() => context.control.close()} + accessibilityHint="" + accessibilityLabel={_( + msg`Context menu backdrop, click to close the menu.`, + )} + /> + </Portal> + )} <DropdownMenu.Root open={context.control.isOpen} onOpenChange={onOpenChange}> @@ -76,7 +95,24 @@ export function Root({ ) } -export function Trigger({children, label, style}: TriggerProps) { +const RadixTriggerPassThrough = React.forwardRef( + ( + props: { + children: ( + props: RadixPassThroughTriggerProps & { + ref: React.Ref<any> + }, + ) => React.ReactNode + }, + ref, + ) => { + // @ts-expect-error Radix provides no types of this stuff + return props.children({...props, ref}) + }, +) +RadixTriggerPassThrough.displayName = 'RadixTriggerPassThrough' + +export function Trigger({children, label}: TriggerProps) { const {control} = React.useContext(Context) const { state: hovered, @@ -87,33 +123,42 @@ export function Trigger({children, label, style}: TriggerProps) { return ( <DropdownMenu.Trigger asChild> - <Pressable - accessibilityHint="" - accessibilityLabel={label} - onFocus={onFocus} - onBlur={onBlur} - style={flatten([style, focused && web({outline: 0})])} - onPointerDown={() => control.open()} - {...web({ - onMouseEnter, - onMouseLeave, - })}> - {children({ - isNative: false, - control, - state: { - hovered, - focused, - pressed: false, - }, - props: {}, - })} - </Pressable> + <RadixTriggerPassThrough> + {props => + children({ + isNative: false, + control, + state: { + hovered, + focused, + pressed: false, + }, + props: { + ...props, + // disable on web, use `onPress` + onPointerDown: () => false, + onPress: () => + control.isOpen ? control.close() : control.open(), + onFocus: onFocus, + onBlur: onBlur, + onMouseEnter, + onMouseLeave, + accessibilityLabel: label, + }, + }) + } + </RadixTriggerPassThrough> </DropdownMenu.Trigger> ) } -export function Outer({children}: React.PropsWithChildren<{}>) { +export function Outer({ + children, + style, +}: React.PropsWithChildren<{ + showCancel?: boolean + style?: StyleProp<ViewStyle> +}>) { const t = useTheme() return ( @@ -125,6 +170,7 @@ export function Outer({children}: React.PropsWithChildren<{}>) { a.p_xs, t.name === 'light' ? t.atoms.bg : t.atoms.bg_contrast_25, t.atoms.shadow_md, + style, ]}> {children} </View> diff --git a/src/components/Menu/types.ts b/src/components/Menu/types.ts index 2f52e6390..e710971ee 100644 --- a/src/components/Menu/types.ts +++ b/src/components/Menu/types.ts @@ -1,5 +1,9 @@ import React from 'react' -import {GestureResponderEvent, PressableProps} from 'react-native' +import { + GestureResponderEvent, + PressableProps, + AccessibilityProps, +} from 'react-native' import {Props as SVGIconProps} from '#/components/icons/common' import * as Dialog from '#/components/Dialog' @@ -9,7 +13,23 @@ export type ContextType = { control: Dialog.DialogOuterProps['control'] } -export type TriggerProps = ViewStyleProp & { +export type RadixPassThroughTriggerProps = { + id: string + type: 'button' + disabled: boolean + ['data-disabled']: boolean + ['data-state']: string + ['aria-controls']?: string + ['aria-haspopup']?: boolean + ['aria-expanded']?: AccessibilityProps['aria-expanded'] + onKeyDown: (e: React.KeyboardEvent) => void + /** + * Radix provides this, but we override on web to use `onPress` instead, + * which is less sensitive while scrolling. + */ + onPointerDown: PressableProps['onPointerDown'] +} +export type TriggerProps = { children(props: TriggerChildProps): React.ReactNode label: string } @@ -52,7 +72,14 @@ export type TriggerChildProps = */ pressed: false } - props: {} + props: RadixPassThroughTriggerProps & { + onPress: () => void + onFocus: () => void + onBlur: () => void + onMouseEnter: () => void + onMouseLeave: () => void + accessibilityLabel: string + } } export type ItemProps = React.PropsWithChildren< diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 3b245c440..1b9348d9c 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -1,11 +1,12 @@ import React from 'react' -import {View, PressableProps} from 'react-native' +import {View} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {isNative} from '#/platform/detection' import {useTheme, atoms as a, useBreakpoints} from '#/alf' import {Text} from '#/components/Typography' -import {Button} from '#/components/Button' +import {Button, ButtonColor, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' @@ -22,8 +23,10 @@ const Context = React.createContext<{ export function Outer({ children, control, + testID, }: React.PropsWithChildren<{ control: Dialog.DialogOuterProps['control'] + testID?: string }>) { const {gtMobile} = useBreakpoints() const titleId = React.useId() @@ -35,7 +38,7 @@ export function Outer({ ) return ( - <Dialog.Outer control={control}> + <Dialog.Outer control={control} testID={testID}> <Context.Provider value={context}> <Dialog.Handle /> @@ -80,7 +83,10 @@ export function Actions({children}: React.PropsWithChildren<{}>) { a.w_full, a.gap_sm, a.justify_end, - gtMobile ? [a.flex_row] : [a.flex_col, a.pt_md, a.pb_4xl], + gtMobile + ? [a.flex_row, a.flex_row_reverse, a.justify_start] + : [a.flex_col], + isNative && [a.pb_4xl], ]}> {children} </View> @@ -89,18 +95,29 @@ export function Actions({children}: React.PropsWithChildren<{}>) { export function Cancel({ children, -}: React.PropsWithChildren<{onPress?: PressableProps['onPress']}>) { + cta, +}: React.PropsWithChildren<{ + /** + * Optional i18n string, used in lieu of `children` for simple buttons. If + * undefined (and `children` is undefined), it will default to "Cancel". + */ + cta?: string +}>) { const {_} = useLingui() const {gtMobile} = useBreakpoints() const {close} = Dialog.useDialogContext() + const onPress = React.useCallback(() => { + close() + }, [close]) + return ( <Button variant="solid" color="secondary" size={gtMobile ? 'small' : 'medium'} - label={_(msg`Cancel`)} - onPress={() => close()}> - {children} + label={cta || _(msg`Cancel`)} + onPress={onPress}> + {children ? children : <ButtonText>{cta || _(msg`Cancel`)}</ButtonText>} </Button> ) } @@ -108,22 +125,70 @@ export function Cancel({ export function Action({ children, onPress, -}: React.PropsWithChildren<{onPress?: () => void}>) { + color = 'primary', + cta, + testID, +}: React.PropsWithChildren<{ + onPress: () => void + color?: ButtonColor + /** + * Optional i18n string, used in lieu of `children` for simple buttons. If + * undefined (and `children` is undefined), it will default to "Confirm". + */ + cta?: string + testID?: string +}>) { const {_} = useLingui() const {gtMobile} = useBreakpoints() const {close} = Dialog.useDialogContext() const handleOnPress = React.useCallback(() => { close() - onPress?.() + onPress() }, [close, onPress]) + return ( <Button variant="solid" - color="primary" + color={color} size={gtMobile ? 'small' : 'medium'} - label={_(msg`Confirm`)} - onPress={handleOnPress}> - {children} + label={cta || _(msg`Confirm`)} + onPress={handleOnPress} + testID={testID}> + {children ? children : <ButtonText>{cta || _(msg`Confirm`)}</ButtonText>} </Button> ) } + +export function Basic({ + control, + title, + description, + cancelButtonCta, + confirmButtonCta, + onConfirm, + confirmButtonColor, +}: React.PropsWithChildren<{ + control: Dialog.DialogOuterProps['control'] + title: string + description: string + cancelButtonCta?: string + confirmButtonCta?: string + onConfirm: () => void + confirmButtonColor?: ButtonColor +}>) { + return ( + <Outer control={control} testID="confirmModal"> + <Title>{title}</Title> + <Description>{description}</Description> + <Actions> + <Action + cta={confirmButtonCta} + onPress={onConfirm} + color={confirmButtonColor} + testID="confirmBtn" + /> + <Cancel cta={cancelButtonCta} /> + </Actions> + </Outer> + ) +} diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 658ba2aae..dcdaccea3 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -254,9 +254,9 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { </View> {isNative && <View style={{height: 20}} />} - - <Dialog.Close /> </View> + + <Dialog.Close /> </Dialog.ScrollableInner> ) } @@ -277,29 +277,16 @@ function MutedWordRow({ return ( <> - <Prompt.Outer control={control}> - <Prompt.Title> - <Trans>Are you sure?</Trans> - </Prompt.Title> - <Prompt.Description> - <Trans> - This will delete {word.value} from your muted words. You can always - add it back later. - </Trans> - </Prompt.Description> - <Prompt.Actions> - <Prompt.Cancel> - <ButtonText> - <Trans>Nevermind</Trans> - </ButtonText> - </Prompt.Cancel> - <Prompt.Action onPress={remove}> - <ButtonText> - <Trans>Remove</Trans> - </ButtonText> - </Prompt.Action> - </Prompt.Actions> - </Prompt.Outer> + <Prompt.Basic + control={control} + title={_(msg`Are you sure?`)} + description={_( + msg`This will delete ${word.value} from your muted words. You can always add it back later.`, + )} + onConfirm={remove} + confirmButtonCta={_(msg`Remove`)} + confirmButtonColor="negative" + /> <View style={[ diff --git a/src/components/icons/Camera.tsx b/src/components/icons/Camera.tsx new file mode 100644 index 000000000..ced8e7442 --- /dev/null +++ b/src/components/icons/Camera.tsx @@ -0,0 +1,9 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Camera_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8.371 3.89A2 2 0 0 1 10.035 3h3.93a2 2 0 0 1 1.664.89L17.035 6H20a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.965L8.37 3.89ZM13.965 5h-3.93L8.63 7.11A2 2 0 0 1 6.965 8H4v11h16V8h-2.965a2 2 0 0 1-1.664-.89L13.965 5ZM12 11a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z', +}) + +export const Camera_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8.371 3.89A2 2 0 0 1 10.035 3h3.93a2 2 0 0 1 1.664.89L17.035 6H20a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.965L8.37 3.89ZM12 9a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7Z', +}) diff --git a/src/components/icons/DotGrid.tsx b/src/components/icons/DotGrid.tsx new file mode 100644 index 000000000..c50d7a440 --- /dev/null +++ b/src/components/icons/DotGrid.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const DotGrid_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M2 12a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm16 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm-6-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z', +}) diff --git a/src/components/icons/Flag.tsx b/src/components/icons/Flag.tsx new file mode 100644 index 000000000..d986db75a --- /dev/null +++ b/src/components/icons/Flag.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Flag_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 4a2 2 0 0 1 2-2h13.131c1.598 0 2.55 1.78 1.665 3.11L18.202 9l2.594 3.89c.886 1.33-.067 3.11-1.665 3.11H6v5a1 1 0 1 1-2 0V4Zm2 10h13.131l-2.593-3.89a2 2 0 0 1 0-2.22L19.13 4H6v10Z', +}) diff --git a/src/components/icons/Heart2.tsx b/src/components/icons/Heart2.tsx new file mode 100644 index 000000000..07f5a1d2c --- /dev/null +++ b/src/components/icons/Heart2.tsx @@ -0,0 +1,9 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Heart2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M16.734 5.091c-1.238-.276-2.708.047-4.022 1.38a1 1 0 0 1-1.424 0C9.974 5.137 8.504 4.814 7.266 5.09c-1.263.282-2.379 1.206-2.92 2.556C3.33 10.18 4.252 14.84 12 19.348c7.747-4.508 8.67-9.168 7.654-11.7-.541-1.351-1.657-2.275-2.92-2.557Zm4.777 1.812c1.604 4-.494 9.69-9.022 14.47a1 1 0 0 1-.978 0C2.983 16.592.885 10.902 2.49 6.902c.779-1.942 2.414-3.334 4.342-3.764 1.697-.378 3.552.003 5.169 1.286 1.617-1.283 3.472-1.664 5.17-1.286 1.927.43 3.562 1.822 4.34 3.764Z', +}) + +export const Heart2_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12.489 21.372c8.528-4.78 10.626-10.47 9.022-14.47-.779-1.941-2.414-3.333-4.342-3.763-1.697-.378-3.552.003-5.169 1.287-1.617-1.284-3.472-1.665-5.17-1.287-1.927.43-3.562 1.822-4.34 3.764-1.605 4 .493 9.69 9.021 14.47a1 1 0 0 0 .978 0Z', +}) diff --git a/src/components/icons/PeopleRemove2.tsx b/src/components/icons/PeopleRemove2.tsx new file mode 100644 index 000000000..3d16ed968 --- /dev/null +++ b/src/components/icons/PeopleRemove2.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PeopleRemove2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M10 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM5.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM16 11a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2h-5a1 1 0 0 1-1-1ZM3.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C1.917 15.521 5.242 12 10 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 17.5 21h-15a1 1 0 0 1-.996-1.094Z', +}) diff --git a/src/components/icons/PersonCheck.tsx b/src/components/icons/PersonCheck.tsx new file mode 100644 index 000000000..097271d89 --- /dev/null +++ b/src/components/icons/PersonCheck.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PersonCheck_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5a6.69 6.69 0 0 1 2.612.51 1 1 0 0 0 .776-1.844A8.687 8.687 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H11a1 1 0 1 0 0-2H5.679Zm14.835-4.857a1 1 0 0 1 .344 1.371l-3 5a1 1 0 0 1-1.458.286l-2-1.5a1 1 0 0 1 1.2-1.6l1.113.835 2.43-4.05a1 1 0 0 1 1.372-.342Z', +}) diff --git a/src/components/icons/PersonX.tsx b/src/components/icons/PersonX.tsx new file mode 100644 index 000000000..a015e1376 --- /dev/null +++ b/src/components/icons/PersonX.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PersonX_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5 .302 0 .595.018.878.053a1 1 0 0 0 .243-1.985A9.235 9.235 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H12a1 1 0 1 0 0-2H5.679Zm9.614-3.707a1 1 0 0 1 1.414 0L18 16.586l1.293-1.293a1 1 0 0 1 1.414 1.414L19.414 18l1.293 1.293a1 1 0 0 1-1.414 1.414L18 19.414l-1.293 1.293a1 1 0 0 1-1.414-1.414L16.586 18l-1.293-1.293a1 1 0 0 1 0-1.414Z', +}) diff --git a/src/components/icons/StreamingLive.tsx b/src/components/icons/StreamingLive.tsx new file mode 100644 index 000000000..8ab5099da --- /dev/null +++ b/src/components/icons/StreamingLive.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const StreamingLive_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H4Zm8 12.5c1.253 0 2.197.609 2.674 1.5H9.326c.477-.891 1.42-1.5 2.674-1.5Zm0-2c2.404 0 4.235 1.475 4.822 3.5H20V6H4v12h3.178c.587-2.025 2.418-3.5 4.822-3.5Zm-1.25-3.75a1.25 1.25 0 1 1 2.5 0 1.25 1.25 0 0 1-2.5 0ZM12 7.5a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5Zm5.75 2a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z', +}) |