feat(lib/discord/ui): export Components and add DiscordModules.Components namespace
This commit is contained in:
parent
5d9ee978a6
commit
c8dc4699a5
4 changed files with 383 additions and 4 deletions
57
lib/discord/src/ui/common.ts
Normal file
57
lib/discord/src/ui/common.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { lookupModule } from '@revenge-mod/modules/finders'
|
||||
import { byDependencies, byProps, looseDeps, moduleStateAware, relativeDep } from '@revenge-mod/modules/finders/filters'
|
||||
|
||||
import { proxify } from '@revenge-mod/utils/proxy'
|
||||
|
||||
import type { DiscordModules } from '../../types'
|
||||
|
||||
export let Components: Components = proxify(
|
||||
() => {
|
||||
// ID: 3236
|
||||
// [3237, 1366, 3238, 3239, 2, ...];
|
||||
const module = lookupModule(
|
||||
moduleStateAware(
|
||||
byProps('TableRow', 'Button'),
|
||||
byDependencies(looseDeps([relativeDep(1), undefined, relativeDep(2), relativeDep(3), 2])),
|
||||
),
|
||||
{
|
||||
includeUninitialized: true,
|
||||
},
|
||||
) as Components | undefined
|
||||
|
||||
if (module) {
|
||||
// This allows the Proxy instance to be garbage collected
|
||||
// after the module is initialized.
|
||||
Components = module
|
||||
gc()
|
||||
return module
|
||||
}
|
||||
},
|
||||
{
|
||||
cache: true,
|
||||
hint: 'object',
|
||||
},
|
||||
)!
|
||||
|
||||
export interface Components {
|
||||
ActionSheet: DiscordModules.Components.ActionSheet
|
||||
ActionSheetRow: DiscordModules.Components.ActionSheetRow
|
||||
ActionSheetSwitchRow: DiscordModules.Components.ActionSheetSwitchRow
|
||||
AlertActionButton: DiscordModules.Components.AlertActionButton
|
||||
AlertModal: DiscordModules.Components.AlertModal
|
||||
Button: DiscordModules.Components.Button
|
||||
Card: DiscordModules.Components.Card
|
||||
ContextMenu: DiscordModules.Components.ContextMenu
|
||||
ContextMenuItem: DiscordModules.Components.ContextMenuItem
|
||||
FormSwitch: DiscordModules.Components.FormSwitch
|
||||
IconButton: DiscordModules.Components.IconButton
|
||||
ImageButton: DiscordModules.Components.ImageButton
|
||||
Stack: DiscordModules.Components.Stack
|
||||
TableRow: DiscordModules.Components.TableRow
|
||||
TableRowTrailingText: DiscordModules.Components.TableRowTrailingText
|
||||
TableSwitchRow: DiscordModules.Components.TableSwitchRow
|
||||
Text: DiscordModules.Components.Text
|
||||
TextArea: DiscordModules.Components.TextArea
|
||||
TextField: DiscordModules.Components.TextField
|
||||
TextInput: DiscordModules.Components.TextInput
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
export * from './common'
|
||||
export * as settings from './settings'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { lookupModule } from '@revenge-mod/modules/finders'
|
||||
import { byDependencies, byProps, looseDeps, moduleStateAware, relativeDep } from '@revenge-mod/modules/finders/filters'
|
||||
|
||||
import { ReactJsxRuntimeModuleId, ReactModuleId, ReactNativeModuleId } from '@revenge-mod/react'
|
||||
|
||||
import { proxify } from '@revenge-mod/utils/proxy'
|
||||
|
||||
import type { ComponentType, ReactNode } from 'react'
|
||||
|
|
@ -11,13 +13,12 @@ export let SettingListRenderer: SettingListRenderer = proxify(
|
|||
moduleStateAware(
|
||||
byProps('SettingsList'),
|
||||
byDependencies(
|
||||
// biome-ignore lint/suspicious/noSparseArray: don't care
|
||||
looseDeps([
|
||||
ReactModuleId,
|
||||
ReactNativeModuleId,
|
||||
relativeDep(1),
|
||||
relativeDep(2),
|
||||
,
|
||||
undefined,
|
||||
ReactJsxRuntimeModuleId,
|
||||
]),
|
||||
),
|
||||
|
|
@ -43,7 +44,7 @@ export let SettingListRenderer: SettingListRenderer = proxify(
|
|||
|
||||
export interface SettingListRenderer {
|
||||
SettingsList: ComponentType<{
|
||||
ListHeaderComponent: ComponentType
|
||||
sections: Array<{ label: string | ReactNode; settings: string[] }>
|
||||
ListHeaderComponent?: ComponentType
|
||||
sections: Array<{ label?: string | ReactNode; settings: string[]; subLabel?: string | ReactNode }>
|
||||
}>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,15 @@
|
|||
import type { ComponentProps, FC, ReactNode } from 'react'
|
||||
import type {
|
||||
ImageSourcePropType,
|
||||
ImageStyle,
|
||||
PressableProps,
|
||||
TextInputProps as RNTextInputProps,
|
||||
TextProps as RNTextProps,
|
||||
TextStyle,
|
||||
ViewProps,
|
||||
ViewStyle,
|
||||
} from 'react-native'
|
||||
|
||||
export * from './native'
|
||||
|
||||
export namespace DiscordModules {
|
||||
|
|
@ -98,4 +110,312 @@ export namespace DiscordModules {
|
|||
verbose(...args: unknown[]): void
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Styles {
|
||||
export type TextType = 'heading' | 'text'
|
||||
export type BasicTextSize = 'sm' | 'md' | 'lg'
|
||||
export type BasicTextSizeWithExtraLarges = BasicTextSize | 'xl' | 'xxl'
|
||||
export type TextSize = BasicTextSizeWithExtraLarges | 'xs' | 'xxs'
|
||||
export type TextWeight = 'normal' | 'medium' | 'semibold' | 'bold'
|
||||
export type TextWeightWithExtraBold = TextWeight | 'extrabold'
|
||||
export type RedesignTextCategory = 'message-preview' | 'channel-title'
|
||||
|
||||
export type TextVariant =
|
||||
| `heading-${BasicTextSizeWithExtraLarges}/${TextWeightWithExtraBold}`
|
||||
| `text-${TextSize}/${TextWeight}`
|
||||
| `display-${BasicTextSize}`
|
||||
| `redesign/${RedesignTextCategory}/${TextWeight}`
|
||||
| 'redesign/heading-18/bold'
|
||||
| 'eyebrow'
|
||||
|
||||
export type TextStyleSheet = Record<TextVariant, RNTextProps>
|
||||
export type CreateStylesFn = <const S extends Record<string, TextStyle | ViewStyle | ImageStyle>>(
|
||||
styles: S,
|
||||
) => () => S
|
||||
}
|
||||
|
||||
export namespace Components {
|
||||
export interface BaseButtonProps extends PressableProps {
|
||||
disabled?: boolean
|
||||
size?: ButtonSize
|
||||
variant?:
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'tertiary'
|
||||
| 'destructive'
|
||||
| 'active'
|
||||
| 'primary-overlay'
|
||||
| 'secondary-overlay'
|
||||
loading?: boolean
|
||||
grow?: boolean
|
||||
scaleAmountInPx?: number
|
||||
}
|
||||
|
||||
export interface ButtonProps extends BaseButtonProps {
|
||||
icon?: number
|
||||
loading?: boolean
|
||||
iconPosition?: 'start' | 'end'
|
||||
renderIcon?(): ReactNode
|
||||
renderRightIcon?(): ReactNode
|
||||
renderShine?(): ReactNode
|
||||
renderLinearGradient?(): ReactNode
|
||||
cornerRadius?: number
|
||||
textStyle?: TextStyle
|
||||
loadingColorLight?: string
|
||||
loadingColorDark?: string
|
||||
text: string
|
||||
}
|
||||
|
||||
// Buttons
|
||||
export type ButtonSize = 'sm' | 'md' | 'lg'
|
||||
export type Button = FC<ButtonProps>
|
||||
|
||||
export interface IconButtonProps extends BaseButtonProps {
|
||||
icon: number
|
||||
label?: string
|
||||
}
|
||||
|
||||
export type IconButton = FC<IconButtonProps>
|
||||
|
||||
export interface ImageButtonProps extends BaseButtonProps {
|
||||
image: ImageSourcePropType
|
||||
}
|
||||
|
||||
export type ImageButton = FC<ImageButtonProps>
|
||||
|
||||
export interface StackProps extends ViewProps {
|
||||
spacing?: number
|
||||
direction?: 'vertical' | 'horizontal'
|
||||
}
|
||||
|
||||
export type Stack = FC<StackProps>
|
||||
|
||||
export interface CardProps extends ViewProps {
|
||||
start?: boolean
|
||||
end?: boolean
|
||||
variant?: 'primary' | 'secondary'
|
||||
border?: 'faint' | 'normal' | 'strong' | 'subtle'
|
||||
// TODO
|
||||
shadow?: 'none'
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export type Card = FC<CardProps>
|
||||
|
||||
// Inputs
|
||||
export interface TextFieldProps {
|
||||
onChange?: (value: string) => void
|
||||
onBlur?: () => void
|
||||
onFocus?: () => void
|
||||
|
||||
leadingIcon?: () => JSX.Element
|
||||
trailingIcon?: () => JSX.Element
|
||||
leadingText?: string
|
||||
trailingText?: string
|
||||
description?: string
|
||||
errorMessage?: string
|
||||
|
||||
isDisabled?: boolean
|
||||
focusable?: boolean
|
||||
editable?: boolean
|
||||
status?: TextFieldStatus
|
||||
|
||||
defaultValue?: string
|
||||
value?: string
|
||||
|
||||
placeholder?: string
|
||||
placeholderTextColor?: string
|
||||
|
||||
maxLength?: number
|
||||
multiline?: boolean
|
||||
|
||||
autoFocus?: boolean
|
||||
secureTextEntry?: boolean
|
||||
returnKeyType?: RNTextInputProps['returnKeyType']
|
||||
isClearable?: boolean
|
||||
|
||||
size?: TextFieldSize
|
||||
style?: ViewStyle | ViewStyle[]
|
||||
}
|
||||
|
||||
export type TextFieldSize = 'sm' | 'md' | 'lg'
|
||||
|
||||
export type TextFieldStatus = 'default' | 'error'
|
||||
|
||||
export interface TextInputProps extends TextFieldProps {
|
||||
isRound?: boolean
|
||||
label?: string
|
||||
}
|
||||
|
||||
export interface TextAreaProps extends Omit<TextInputProps, 'multiline'> {}
|
||||
|
||||
export type TextInput = FC<TextInputProps>
|
||||
export type TextField = FC<TextFieldProps>
|
||||
export type TextArea = FC<TextAreaProps>
|
||||
|
||||
export interface FormSwitchProps extends ViewProps {
|
||||
value: boolean
|
||||
onValueChange(value: boolean): void
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export type FormSwitch = FC<FormSwitchProps>
|
||||
// TODO
|
||||
// export type FormRadio = FC
|
||||
// export type FormCheckbox = FC
|
||||
|
||||
export interface ActionSheetProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export type ActionSheet = FC<ActionSheetProps>
|
||||
|
||||
export interface ActionSheetCloseButtonProps extends Pick<ComponentProps<IconButton>, 'variant' | 'onPress'> {}
|
||||
|
||||
export type ActionSheetCloseButton = FC<ActionSheetCloseButtonProps>
|
||||
|
||||
export type ActionSheetRow = TableRow
|
||||
export type ActionSheetRowIcon = TableRowIcon
|
||||
export type ActionSheetRowGroup = TableRowGroup
|
||||
export type ActionSheetSwitchRow = TableSwitchRow
|
||||
// TODO
|
||||
// export type ActionSheetIconHeader = FC
|
||||
// export type ActionSheetHeaderBar = FC
|
||||
// export type BottomSheetTitleHeader = FC
|
||||
|
||||
export type IconSize =
|
||||
| 'extraSmall10'
|
||||
| 'extraSmall'
|
||||
| 'small'
|
||||
| 'small20'
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'custom'
|
||||
| 'refreshSmall16'
|
||||
| 'small14'
|
||||
|
||||
export type TableRowVariant = 'default' | 'danger'
|
||||
|
||||
export interface TableRowProps {
|
||||
label: string
|
||||
subLabel?: string
|
||||
icon?: ReactNode
|
||||
trailing?: ReactNode
|
||||
arrow?: boolean
|
||||
onPress?: PressableProps['onPress']
|
||||
disabled?: boolean
|
||||
draggable?: boolean
|
||||
dragHandlePressableProps?: PressableProps
|
||||
labelLineClamp?: number
|
||||
subLabelLineClamp?: number
|
||||
// TODO
|
||||
start?: unknown
|
||||
end?: unknown
|
||||
variant?: TableRowVariant
|
||||
}
|
||||
|
||||
export type TableRow = FC<TableRowProps> & {
|
||||
Arrow: FC
|
||||
Icon: TableRowIcon
|
||||
}
|
||||
|
||||
export interface TableSwitchRowProps extends Omit<TableRowProps, 'trailing'> {
|
||||
accessibilityHint?: string
|
||||
value: boolean
|
||||
onValueChange(value: boolean): void
|
||||
}
|
||||
|
||||
export type TableSwitchRow = FC<TableSwitchRowProps>
|
||||
|
||||
export interface TableRowGroupProps {
|
||||
title?: string
|
||||
description?: string
|
||||
hasIcons?: boolean
|
||||
accessibilityLabel?: string
|
||||
accessibilityRole?: string
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export type TableRowGroup = FC<TableRowGroupProps>
|
||||
|
||||
export interface TableRowGroupTitleProps {
|
||||
title: string
|
||||
}
|
||||
|
||||
export type TableRowGroupTitle = FC<TableRowGroupTitleProps>
|
||||
|
||||
export type TableRowIconVariant =
|
||||
| 'default'
|
||||
| 'blurple'
|
||||
| 'boosting-pink'
|
||||
| 'status-online'
|
||||
| 'status-idle'
|
||||
| 'status-dnd'
|
||||
| 'status-offline'
|
||||
| 'xbox'
|
||||
| 'playstation'
|
||||
| 'danger'
|
||||
| 'secondary'
|
||||
| 'translucent'
|
||||
|
||||
export interface TableRowIconProps {
|
||||
source: ImageSourcePropType
|
||||
variant?: TableRowIconVariant
|
||||
}
|
||||
|
||||
export type TableRowIcon = FC<TableRowIconProps>
|
||||
|
||||
export interface TableRowTrailingTextProps {
|
||||
text: string
|
||||
}
|
||||
|
||||
export type TableRowTrailingText = FC<TableRowTrailingTextProps>
|
||||
|
||||
export interface AlertModalProps {
|
||||
title: string
|
||||
content?: ReactNode
|
||||
extraContent?: ReactNode
|
||||
actions?: ReactNode
|
||||
}
|
||||
|
||||
export type AlertModal = FC<AlertModalProps>
|
||||
|
||||
export type AlertActionButton = Button
|
||||
|
||||
export interface ContextMenuProps {
|
||||
title: ReactNode
|
||||
triggerOnLongPress?: boolean
|
||||
items: Array<ContextMenuItem | ContextMenuItem[]>
|
||||
align?: 'left' | 'right' | 'above' | 'below'
|
||||
children: (props: Partial<BaseButtonProps>) => ReactNode
|
||||
}
|
||||
|
||||
export type ContextMenu = FC<ContextMenuProps>
|
||||
|
||||
export interface ContextMenuItem {
|
||||
label: string
|
||||
IconComponent?: FC
|
||||
variant?: 'default' | 'destructive'
|
||||
action(): void
|
||||
}
|
||||
|
||||
export interface TextProps extends RNTextProps {
|
||||
variant?: DiscordModules.Styles.TextVariant
|
||||
color?: string
|
||||
style?: TextStyle
|
||||
lineClamp?: number
|
||||
ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip'
|
||||
tabularNumbers?: boolean
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
export type Text = FC<TextProps>
|
||||
|
||||
export interface IntlLinkProps {
|
||||
target: string
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
export type IntlLink = FC<IntlLinkProps>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue