@unbound-app/api 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,20 @@
1
1
  // Auto-generated by generate-plugin-sdk.ts - DO NOT EDIT
2
2
 
3
+ import type { LiteralUnion } from './utils';
4
+ import * as ReactModule from 'react';
5
+ import { ComponentType, ReactNode } from 'react';
6
+ import * as ReactNativeModule from 'react-native';
3
7
  import {
8
+ AccessibilityState,
4
9
  ImageSourcePropType,
5
10
  ImageStyle,
11
+ PressableProps,
6
12
  StyleProp,
7
13
  TextInputProps as RNTextInputProps,
8
14
  TextStyle,
9
15
  ViewProps,
10
16
  ViewStyle,
11
17
  } from 'react-native';
12
- import { ComponentType, ReactNode } from 'react';
13
-
14
- import type { Fn, LiteralUnion } from './utils';
15
18
 
16
19
  declare const THEME_FLAG_KEYS: readonly [
17
20
  'MOBILE_DARK_GRADIENT_THEME_ENABLED',
@@ -21,22 +24,49 @@ declare const THEME_FLAG_KEYS: readonly [
21
24
  'REDUCE_SATURATION_ENABLED',
22
25
  ];
23
26
  declare const TRANSITION_STATE_KEYS: readonly ['MOUNTED', 'ENTERED', 'YEETED'];
24
-
27
+ declare const nativeHandle: unique symbol;
28
+ /** The kinds of addon a manifest can declare. */
29
+ export declare const ADDON_TYPES: readonly ['plugin', 'theme', 'icon-pack', 'font'];
30
+ export declare const NATIVE_PLUGIN_CAPABILITIES: readonly [
31
+ 'native.objc.classes',
32
+ 'native.objc.invoke',
33
+ 'native.objc.ivars',
34
+ 'native.objc.associations',
35
+ 'native.objc.hooks',
36
+ 'native.ffi.symbols',
37
+ 'native.ffi.call',
38
+ 'native.fabric.mount',
39
+ ];
40
+ export type ActionSheetProps = {
41
+ children?: ReactModule.ReactNode;
42
+ };
43
+ export type ActionSheetRowProps = {
44
+ label: ReactModule.ReactNode;
45
+ subLabel?: ReactModule.ReactNode;
46
+ icon?: ReactModule.ReactNode;
47
+ onPress?: DiscordFunction<void>;
48
+ };
25
49
  /** A loaded addon entity: its runtime state, instance, source bundle, and {@link AddonManifest}. */
26
- export interface Addon {
50
+ export type Addon = {
27
51
  started: boolean;
28
- instance: any;
52
+ /** What the bundle evaluated to. Every addon kind may implement the {@link Plugin} lifecycle hooks. */
53
+ instance: Plugin$1 | null;
29
54
  context?: PluginContext;
30
55
  id: string;
31
56
  failed: boolean;
32
57
  data: AddonManifest;
33
58
  bundle: string;
34
- }
59
+ };
60
+ /** The author of an addon: a display name and a numeric user id. */
61
+ export type AddonAuthor = {
62
+ name: string;
63
+ id: `${number}`;
64
+ };
35
65
  /** The manifest describing an addon's metadata, entry point, and source. */
36
- export interface AddonManifest {
66
+ export type AddonManifest = {
37
67
  id: string;
38
68
  /** The addon kind this manifest describes; used to validate installs. */
39
- type?: 'plugin' | 'theme' | 'icon-pack' | 'font';
69
+ type?: AddonType;
40
70
  name: string;
41
71
  description: string;
42
72
  authors: AddonAuthor[];
@@ -53,21 +83,45 @@ export interface AddonManifest {
53
83
  url: string;
54
84
  capabilities?: NativePluginCapability[];
55
85
  minNativePluginApi?: string;
56
- }
86
+ /** Requirements on the Unbound client running the addon. */
87
+ unbound?: {
88
+ /** The minimum Unbound client version (semver) the addon supports. */
89
+ min?: string;
90
+ };
91
+ };
92
+ /** An addon referenced either by its id string or the {@link Addon} entity itself. */
93
+ export type AddonResolveable = string | Addon;
94
+ export type AddonType = (typeof ADDON_TYPES)[number];
95
+ export type AlertActionButtonProps = {
96
+ text: string;
97
+ variant?: ButtonVariant;
98
+ loading?: boolean;
99
+ disabled?: boolean;
100
+ onPress?: DiscordFunction<void>;
101
+ };
102
+ export type AlertModalProps = {
103
+ title?: ReactModule.ReactNode;
104
+ content?: ReactModule.ReactNode;
105
+ extraContent?: ReactModule.ReactNode;
106
+ actions?: ReactModule.ReactNode;
107
+ };
57
108
  /** The native module used to register and resolve {@link DiscordAsset}s by id. */
58
- export interface AssetsModule {
109
+ export type AssetsModule = {
59
110
  registerAsset: (asset: DiscordAsset) => number;
60
111
  getAssetByID: (id: number) => DiscordAsset | null;
61
- [key: PropertyKey]: any;
62
- }
63
- export interface ButtonProps {
112
+ };
113
+ /** `Button` with its attached `Icon` static. */
114
+ export type ButtonComponent = ReactModule.ComponentType<ButtonProps> & {
115
+ Icon: ReactModule.ComponentType<TableRowIconProps>;
116
+ };
117
+ export type ButtonProps = {
64
118
  text?: string;
65
- textElement?: ReactNode;
119
+ textElement?: ReactModule.ReactNode;
66
120
  variant?: ButtonVariant;
67
121
  size?: ButtonSize;
68
122
  loading?: boolean;
69
123
  disabled?: boolean;
70
- icon?: ReactNode | number;
124
+ icon?: ReactModule.ReactNode | number;
71
125
  iconPosition?: 'start' | 'end';
72
126
  grow?: boolean;
73
127
  shrink?: boolean;
@@ -75,72 +129,100 @@ export interface ButtonProps {
75
129
  textVariant?: TextVariant;
76
130
  style?: StyleProp<ViewStyle>;
77
131
  accessibilityLabel?: string;
78
- onPress?: Fn<void>;
79
- onPressIn?: Fn<void>;
80
- onPressOut?: Fn<void>;
81
- }
82
- export interface CardProps extends ViewProps {
132
+ onPress?: DiscordFunction<void>;
133
+ onPressIn?: DiscordFunction<void>;
134
+ onPressOut?: DiscordFunction<void>;
135
+ };
136
+ export type ButtonSize = LiteralUnion<'sm' | 'md' | 'lg'>;
137
+ export type ButtonVariant = LiteralUnion<
138
+ 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'active' | 'expressive'
139
+ >;
140
+ export type CardProps = {
83
141
  variant?: LiteralUnion<'primary' | 'secondary' | 'muted' | 'transparent'>;
84
142
  border?: LiteralUnion<'none' | 'subtle' | 'strong'>;
85
143
  shadow?: LiteralUnion<'none' | 'low' | 'medium' | 'high' | 'border'>;
86
144
  radius?: number;
87
145
  start?: boolean;
88
146
  end?: boolean;
89
- children?: ReactNode;
90
- }
91
- export interface CheckboxProps {
92
- label?: ReactNode;
93
- description?: ReactNode;
147
+ children?: ReactModule.ReactNode;
148
+ } & ViewProps;
149
+ export type CheckboxProps = {
150
+ label?: ReactModule.ReactNode;
151
+ description?: ReactModule.ReactNode;
94
152
  checked: boolean;
95
153
  required?: boolean;
96
154
  accessibilityRole?: string;
97
- accessibilityState?: Record<string, any>;
98
- onToggle: Fn<void>;
99
- }
155
+ accessibilityState?: AccessibilityState;
156
+ onToggle: DiscordFunction<void>;
157
+ };
158
+ /** An entry of a `ContextMenu`. */
159
+ export type ContextMenuItem = {
160
+ label: string;
161
+ action: DiscordFunction<void>;
162
+ variant?: LiteralUnion<'default' | 'destructive'>;
163
+ iconSource?: number;
164
+ };
165
+ /** `ContextMenu`: an anchored popover whose `children` render the trigger from the props it passes. */
166
+ export type ContextMenuProps = {
167
+ title?: string;
168
+ items: ContextMenuItem[];
169
+ triggerOnTap?: boolean;
170
+ children: (props: PressableProps) => ReactModule.ReactNode;
171
+ };
100
172
  /**
101
- * The Discord mobile design system. This is the single metro module keyed by
102
- * `createStyles` / `dismissAlerts` / `ContextMenu` (aliased `Design` on the v3 branch). It is
103
- * intentionally left open: every listed member is precisely typed, and the index signature keeps
104
- * the rest (and anything Discord adds in a future build) accessible as `any` without a change here.
105
- *
106
- * See `DESIGN.md` at the repo root for the full catalogue.
173
+ * The style factory: turns a spec (or a function returning one) into a theme-aware hook, so call it
174
+ * inside a component body: `const styles = useStyles();`.
175
+ */
176
+ export type CreateStyles = <T extends StyleSheetSpec>(
177
+ styles: StyleSheetSpecOrFactory<T>,
178
+ ) => () => ResolvedStyles<T>;
179
+ /**
180
+ * The Discord mobile design system module (keyed by `createStyles` / `dismissAlerts` / `ContextMenu`).
181
+ * See `DESIGN.md` for the full catalogue.
107
182
  */
108
- export interface DesignModule {
183
+ export type DesignModule = {
109
184
  createStyles: CreateStyles;
110
185
  TextStyleSheet: Record<TextVariant, TextStyle>;
111
- Text: ComponentType<TextProps>;
112
- Heading: ComponentType<TextProps>;
186
+ Text: ReactModule.ComponentType<TextProps>;
187
+ Heading: ReactModule.ComponentType<TextProps>;
113
188
  TableRow: TableRowComponent;
114
- TableSwitchRow: ComponentType<TableSwitchRowProps>;
115
- TableCheckboxRow: ComponentType<TableCheckboxRowProps>;
116
- TableRadioRow: ComponentType<TableRadioRowProps>;
117
- TableRowGroup: ComponentType<TableRowGroupProps>;
118
- TableRowGroupTitle: ComponentType<TableRowGroupTitleProps>;
119
- TableRowIcon: ComponentType<TableRowIconProps>;
120
- RowButton: ComponentType<RowButtonProps>;
121
- RowGroup: ComponentType<ViewProps>;
189
+ TableSwitchRow: ReactModule.ComponentType<TableSwitchRowProps>;
190
+ TableCheckboxRow: ReactModule.ComponentType<TableCheckboxRowProps>;
191
+ TableRadioRow: ReactModule.ComponentType<TableRadioRowProps>;
192
+ TableRowGroup: ReactModule.ComponentType<TableRowGroupProps>;
193
+ TableRowGroupTitle: ReactModule.ComponentType<TableRowGroupTitleProps>;
194
+ TableRowIcon: ReactModule.ComponentType<TableRowIconProps>;
195
+ RowButton: ReactModule.ComponentType<RowButtonProps>;
196
+ RowGroup: ReactModule.ComponentType<ViewProps>;
122
197
  Button: ButtonComponent;
123
- IconButton: ComponentType<IconButtonProps>;
124
- ImageButton: ComponentType<ViewProps>;
125
- FloatingActionButton: ComponentType<FloatingActionButtonProps>;
126
- TextInput: ComponentType<TextInputProps>;
127
- TextField: ComponentType<TextFieldProps>;
128
- TextArea: ComponentType<TextAreaProps>;
129
- TextAreaField: ComponentType<TextAreaProps>;
130
- SearchField: ComponentType<Omit<TextFieldProps, 'leadingIcon'>>;
131
- GhostInput: ComponentType<GhostInputProps>;
132
- SplitTextInput: ComponentType<SplitTextInputProps>;
133
- Slider: ComponentType<SliderProps>;
134
- Checkbox: ComponentType<CheckboxProps>;
135
- SegmentedControl: ComponentType<SegmentedControlProps>;
136
- Stack: ComponentType<StackProps>;
137
- Card: ComponentType<CardProps>;
138
- openAlert: Fn<void>;
198
+ IconButton: ReactModule.ComponentType<IconButtonProps>;
199
+ ImageButton: ReactModule.ComponentType<ViewProps>;
200
+ FloatingActionButton: ReactModule.ComponentType<FloatingActionButtonProps>;
201
+ TextInput: ReactModule.ComponentType<TextInputProps>;
202
+ TextField: ReactModule.ComponentType<TextFieldProps>;
203
+ TextArea: ReactModule.ComponentType<TextAreaProps>;
204
+ TextAreaField: ReactModule.ComponentType<TextAreaProps>;
205
+ SearchField: ReactModule.ComponentType<Omit<TextFieldProps, 'leadingIcon'>>;
206
+ GhostInput: ReactModule.ComponentType<GhostInputProps>;
207
+ SplitTextInput: ReactModule.ComponentType<SplitTextInputProps>;
208
+ Slider: ReactModule.ComponentType<SliderProps>;
209
+ Checkbox: ReactModule.ComponentType<CheckboxProps>;
210
+ SegmentedControl: ReactModule.ComponentType<SegmentedControlProps>;
211
+ SegmentedControlPages: ReactModule.ComponentType<SegmentedControlPagesProps>;
212
+ useSegmentedControlState: (options: SegmentedControlStateOptions) => SegmentedControlState;
213
+ Stack: ReactModule.ComponentType<StackProps>;
214
+ Card: ReactModule.ComponentType<CardProps>;
215
+ AlertModal: ReactModule.ComponentType<AlertModalProps>;
216
+ AlertActionButton: ReactModule.ComponentType<AlertActionButtonProps>;
217
+ ActionSheet: ReactModule.ComponentType<ActionSheetProps>;
218
+ ActionSheetRow: ReactModule.ComponentType<ActionSheetRowProps>;
219
+ ContextMenu: ReactModule.ComponentType<ContextMenuProps>;
220
+ openAlert: DiscordFunction<void>;
139
221
  dismissAlert: (key: string) => void;
140
- dismissAlerts: Fn<void>;
141
- showConfirmModal: Fn;
142
- showSimpleActionSheet: Fn;
143
- hideContextMenu: Fn<void>;
222
+ dismissAlerts: DiscordFunction<void>;
223
+ showConfirmModal: DiscordFunction;
224
+ showSimpleActionSheet: DiscordFunction;
225
+ hideContextMenu: DiscordFunction<void>;
144
226
  useNavigation: <T = any>() => Navigation<T>;
145
227
  setColorOpacity: (color: string, opacity: number) => string;
146
228
  darkenColor: (color: string, amount: number) => string;
@@ -149,33 +231,47 @@ export interface DesignModule {
149
231
  TransitionStates: EnumLike<typeof TRANSITION_STATE_KEYS>;
150
232
  ThemeContextFlags: EnumLike<typeof THEME_FLAG_KEYS>;
151
233
  WCAGContrastRatios: Record<'NonText' | 'Text' | 'HighContrastText', number>;
152
- [key: PropertyKey]: any;
153
- }
234
+ };
154
235
  /** An asset registered with Discord's packager (its metadata and dimensions). */
155
- export interface DiscordAsset {
236
+ export type DiscordAsset = {
156
237
  __packager_asset?: boolean;
157
238
  name: string;
158
- httpServerLocation?: string;
239
+ httpServerLocation: string;
159
240
  width: number;
160
241
  height: number;
161
242
  scales: number[];
162
243
  hash: string;
163
244
  type: string;
164
- [key: PropertyKey]: any;
165
- }
245
+ };
246
+ /** A function exported by a Discord module, whose signature Discord does not document. */
247
+ export type DiscordFunction<T = any> = (...args: any[]) => T;
248
+ /** Discord ships numeric enums as bidirectional maps; this models both directions. */
249
+ export type EnumLike<K extends readonly string[]> = {
250
+ [P in K[number]]: number;
251
+ } & {
252
+ [n: number]: K[number];
253
+ };
166
254
  /** `FloatingActionButton`: a single-icon FAB, typically pinned to a screen corner. */
167
- export interface FloatingActionButtonProps {
168
- icon?: ReactNode | number;
255
+ export type FloatingActionButtonProps = {
256
+ icon?: ReactModule.ReactNode | number;
169
257
  style?: StyleProp<ViewStyle>;
170
- onPress?: Fn<void>;
171
- }
258
+ onPress?: DiscordFunction<void>;
259
+ };
260
+ /** A custom font the native loader has registered, as injected on `window.UNBOUND_FONTS`. */
261
+ export type FontDescriptor = {
262
+ name: string;
263
+ file: string;
264
+ path: string;
265
+ };
266
+ /** A font managed by the Fonts manager: currently identical to its {@link FontDescriptor}. */
267
+ export type FontEntity = FontDescriptor;
172
268
  /** `GhostInput`: a borderless field bridging to the `useTextField` hook. */
173
- export interface GhostInputProps extends TextFieldProps {
269
+ export type GhostInputProps = {
174
270
  isCentered?: boolean;
175
271
  containerStyle?: StyleProp<ViewStyle>;
176
- }
177
- export interface IconButtonProps {
178
- icon?: ReactNode | number;
272
+ } & TextFieldProps;
273
+ export type IconButtonProps = {
274
+ icon?: ReactModule.ReactNode | number;
179
275
  variant?: ButtonVariant;
180
276
  size?: ButtonSize;
181
277
  loading?: boolean;
@@ -183,32 +279,76 @@ export interface IconButtonProps {
183
279
  label?: string;
184
280
  accessibilityLabel?: string;
185
281
  style?: StyleProp<ViewStyle>;
186
- onPress?: Fn<void>;
187
- }
282
+ onPress?: DiscordFunction<void>;
283
+ };
284
+ /** A loaded icon pack: its bundle marker and {@link IconPackManifest}. */
285
+ export type IconPack = {
286
+ bundle: string;
287
+ manifest: IconPackManifest;
288
+ };
289
+ /** An icon pack's manifest: an {@link AddonManifest} tagged with its source kind. */
290
+ export type IconPackManifest = AddonManifest & {
291
+ type: 'icon-pack';
292
+ source: 'github' | 'other';
293
+ };
294
+ /** Icon slot: a rendered node, a component, or a render function. */
295
+ export type IconSlot =
296
+ | ReactModule.ReactNode
297
+ | ReactModule.ComponentType<any>
298
+ | DiscordFunction<ReactModule.ReactNode>;
299
+ /** Input sizing, shared by the whole `TextField`/`Input` family. */
300
+ export type InputSize = LiteralUnion<'sm' | 'md' | 'lg'>;
301
+ /** Input status. `focused` is an internal state and is not user-settable. */
302
+ export type InputStatus = LiteralUnion<'default' | 'error'>;
188
303
  /** {@link ToastOptions} enriched with the fields the store tracks internally. */
189
- export interface InternalToastOptions extends ToastOptions {
304
+ export type InternalToastOptions = {
190
305
  id: string;
191
306
  closing?: boolean;
192
307
  date?: number;
193
- }
194
- export interface NativeCallOptions {
308
+ } & ToastOptions;
309
+ export type NativeAssociationKey = NativeHandle;
310
+ export type NativeCallOptions = {
195
311
  thread?: NativeThreadPolicy;
196
- }
197
- export interface NativeFFIBridge {
312
+ };
313
+ export type NativeClassHandle = NativeHandle;
314
+ export type NativeFFIBridge = {
198
315
  symbol(name: string, image?: string): NativePointer | null;
199
316
  call(pointer: NativePointer, signature: NativeFFISignature, ...args: unknown[]): unknown;
200
- }
201
- export interface NativeFFISignature {
317
+ };
318
+ export type NativeFFISignature = {
202
319
  returnType: NativeFFIType;
203
320
  args: NativeFFIType[];
204
- }
205
- export interface NativeFabricBridge {
321
+ };
322
+ export type NativeFFIType =
323
+ | NativeFFITypeName
324
+ | {
325
+ struct: string;
326
+ };
327
+ export type NativeFFITypeName =
328
+ | 'void'
329
+ | 'bool'
330
+ | 'i8'
331
+ | 'u8'
332
+ | 'i16'
333
+ | 'u16'
334
+ | 'i32'
335
+ | 'u32'
336
+ | 'i64'
337
+ | 'u64'
338
+ | 'float'
339
+ | 'double'
340
+ | 'cstring'
341
+ | 'pointer'
342
+ | 'object'
343
+ | 'class'
344
+ | 'selector';
345
+ export type NativeFabricBridge = {
206
346
  mount(
207
347
  container: NativeObjectHandle,
208
348
  moduleName: string,
209
- properties?: Record<string, unknown>,
349
+ properties?: NativeSerializableObject,
210
350
  ): NativeFabricSurface;
211
- update(surface: NativeFabricSurface, properties: Record<string, unknown>): void;
351
+ update(surface: NativeFabricSurface, properties: NativeSerializableObject): void;
212
352
  setSize(
213
353
  surface: NativeFabricSurface,
214
354
  minimumSize: NativeFabricSize,
@@ -217,42 +357,47 @@ export interface NativeFabricBridge {
217
357
  setFrame(surface: NativeFabricSurface, frame: NativeFabricFrame): void;
218
358
  measure(view: NativeObjectHandle): NativeFabricFrame;
219
359
  unmount(surface: NativeFabricSurface): void;
220
- }
221
- export interface NativeFabricFrame {
360
+ };
361
+ export type NativeFabricFrame = {
222
362
  x: number;
223
363
  y: number;
224
364
  width: number;
225
365
  height: number;
226
- }
227
- export interface NativeFabricSize {
366
+ };
367
+ export type NativeFabricSize = {
228
368
  width: number;
229
369
  height: number;
230
- }
231
- export interface NativeHookContext {
370
+ };
371
+ export type NativeFabricSurface = NativeHandle;
372
+ /** An opaque reference to a native object. Only the bridge creates handles; plugins pass them back. */
373
+ export type NativeHandle = {
374
+ readonly [nativeHandle]: true;
375
+ };
376
+ export type NativeHookContext = {
232
377
  self: NativeObjectHandle;
233
378
  selector: string;
234
379
  args: unknown[];
235
380
  original: (...args: unknown[]) => unknown;
236
381
  replaceObjectArgument(index: number, value: NativeObjectHandle | null): void;
237
- }
238
- export interface NativeHookHandlers {
382
+ };
383
+ export type NativeHookHandlers = {
239
384
  before?: (context: NativeHookContext) => void | Promise<void>;
240
385
  after?: (context: NativeHookContext) => void | Promise<void>;
241
386
  replace?: (context: NativeHookContext) => unknown;
242
- }
243
- export interface NativeHookOptions extends NativeCallOptions {
387
+ };
388
+ export type NativeHookOptions = {
244
389
  cacheOnly?: boolean;
245
390
  instance?: NativeObjectHandle;
246
391
  once?: boolean;
247
- }
248
- export interface NativeHookToken {
392
+ } & NativeCallOptions;
393
+ export type NativeHookToken = {
249
394
  readonly active: boolean;
250
395
  setReturnValue(self: NativeObjectHandle, args: unknown[], value: unknown): void;
251
396
  removeReturnValue(self: NativeObjectHandle, args: unknown[]): void;
252
397
  clearReturnValues(): void;
253
398
  remove(): void;
254
- }
255
- export interface NativeObjCBridge {
399
+ };
400
+ export type NativeObjCBridge = {
256
401
  getClass(name: string): NativeClassHandle | null;
257
402
  alloc(classOrName: string | NativeClassHandle): NativeObjectHandle;
258
403
  className(handle: NativeHandle): string | null;
@@ -287,7 +432,10 @@ export interface NativeObjCBridge {
287
432
  value: unknown,
288
433
  policy?: string,
289
434
  ): void;
290
- struct<T extends object = Record<string, unknown>>(name: string, fields: T): NativeStruct<T>;
435
+ struct<T extends NativeStructFields = NativeStructFields>(
436
+ name: string,
437
+ fields: T,
438
+ ): NativeStruct<T>;
291
439
  array(handle: NativeObjectHandle): unknown[];
292
440
  data(value: ArrayBuffer | Uint8Array): NativeObjectHandle;
293
441
  hook(
@@ -296,80 +444,139 @@ export interface NativeObjCBridge {
296
444
  handlers: NativeHookHandlers,
297
445
  options?: NativeHookOptions,
298
446
  ): NativeHookToken;
299
- }
300
- export interface NativePlatformApp {
447
+ };
448
+ export type NativeObjectHandle = NativeHandle;
449
+ export type NativePlatformApp = {
301
450
  getAppSource(): string;
302
- }
303
- export interface NativePlatformBridge {
451
+ };
452
+ export type NativePlatformBridge = {
304
453
  evaluateBytecode(bytecode: ArrayBuffer, tag?: string): unknown;
305
454
  readonly device: NativePlatformDevice;
306
455
  readonly app: NativePlatformApp;
307
- }
308
- export interface NativePlatformDevice {
456
+ };
457
+ export type NativePlatformDevice = {
309
458
  getDeviceModel(): string;
310
459
  getiOSVersionString(): string;
311
460
  isJailbroken(): boolean;
312
461
  isSystemApp(): boolean;
313
462
  isVerifiedBuild(): boolean;
314
- getEntitlements(): Record<string, any>;
463
+ getEntitlements(): NativeSerializableObject;
315
464
  getEntitlementsAsPlist(): string;
316
- }
317
- export interface NativePluginBridge {
465
+ };
466
+ export type NativePluginBridge = {
318
467
  readonly apiVersion: string;
319
468
  readonly abiVersion: string;
320
469
  readonly capabilities: readonly NativePluginCapability[];
321
470
  readonly objc: NativeObjCBridge;
322
471
  readonly ffi: NativeFFIBridge;
323
472
  readonly fabric: NativeFabricBridge;
324
- }
325
- export interface NativePluginError {
473
+ };
474
+ export type NativePluginCapability = (typeof NATIVE_PLUGIN_CAPABILITIES)[number];
475
+ export type NativePluginError = {
326
476
  code: NativePluginErrorCode;
327
477
  message: string;
328
478
  capability?: NativePluginCapability;
329
- }
330
- export interface NativeStruct<T extends object = Record<string, unknown>> extends NativeHandle {
479
+ };
480
+ export type NativePluginErrorCode =
481
+ | 'NATIVE_BRIDGE_ERROR'
482
+ | 'NATIVE_PLUGIN_API_VERSION_UNSUPPORTED'
483
+ | 'NATIVE_PLUGIN_CAPABILITY_DENIED'
484
+ | 'NATIVE_PLUGIN_SCOPE_DISPOSED'
485
+ | 'NATIVE_PLUGIN_UNAVAILABLE';
486
+ export type NativePointer = NativeHandle;
487
+ /** A value the bridge serializes by structure, such as Fabric surface props or a plist. */
488
+ export type NativeSerializable =
489
+ | string
490
+ | number
491
+ | boolean
492
+ | null
493
+ | NativeSerializable[]
494
+ | NativeSerializableObject;
495
+ export type NativeSerializableObject = {
496
+ [key: string]: NativeSerializable;
497
+ };
498
+ export type NativeStruct<T extends NativeStructFields = NativeStructFields> = {
331
499
  readonly name: string;
332
500
  readonly value?: T;
333
- }
334
- export interface Navigation<T = any> {
501
+ } & NativeHandle;
502
+ /** A C struct field: a scalar, a pointer or object, or a nested struct. */
503
+ export type NativeStructField = number | boolean | NativeHandle | NativeStructFields;
504
+ export type NativeStructFields = {
505
+ [field: string]: NativeStructField;
506
+ };
507
+ export type NativeThreadPolicy = 'current' | 'main';
508
+ export type Navigation<T = any> = {
335
509
  push: (route: string, params?: T) => void;
336
510
  pop: () => void;
337
511
  navigate: (route: string, params?: T) => void;
338
512
  goBack: () => void;
339
- setOptions: (options: Record<string, any>) => void;
340
- addListener: (event: string, callback: Fn) => Fn<void>;
341
- [key: string]: any;
342
- }
343
- export interface PluginContext {
513
+ setOptions: (options: NavigationOptions) => void;
514
+ addListener: (event: string, callback: DiscordFunction) => DiscordFunction<void>;
515
+ };
516
+ /** The screen options accepted by {@link Navigation.setOptions}. */
517
+ export type NavigationOptions = {
518
+ title?: string;
519
+ headerRight?: DiscordFunction<ReactModule.ReactNode>;
520
+ };
521
+ export type PluginContext = {
344
522
  readonly manifest: AddonManifest;
345
523
  readonly id: string;
346
524
  readonly capabilities: readonly NativePluginCapability[];
347
525
  readonly native: NativePluginBridge;
348
526
  dispose(): void;
349
- }
350
- export interface RowButtonProps {
351
- label?: ReactNode;
352
- icon?: ReactNode;
527
+ };
528
+ /** An {@link Addon} whose instance is a {@link Plugin}. */
529
+ export type PluginEntity = Addon & {
530
+ instance: Plugin$1 | null;
531
+ };
532
+ /** Resolves each key of a {@link StyleSheetSpec} to the concrete RN style type it produced. */
533
+ export type ResolvedStyles<T extends StyleSheetSpec> = {
534
+ [K in keyof T]: T[K] extends ImageStyle
535
+ ? ImageStyle
536
+ : T[K] extends TextStyle
537
+ ? TextStyle
538
+ : ViewStyle;
539
+ };
540
+ export type RowButtonProps = {
541
+ label?: ReactModule.ReactNode;
542
+ icon?: ReactModule.ReactNode;
353
543
  arrow?: boolean;
354
544
  disabled?: boolean;
355
545
  variant?: LiteralUnion<'primary' | 'secondary'>;
356
- onPress?: Fn<void>;
357
- }
358
- export interface SegmentedControlProps {
546
+ onPress?: DiscordFunction<void>;
547
+ };
548
+ /** A tab of a segmented control, with the page it shows. */
549
+ export type SegmentedControlItem = {
550
+ id: string;
551
+ label: string;
552
+ page?: ReactModule.ReactNode;
553
+ };
554
+ /** `SegmentedControlPages`: the swipeable pages driven by a segmented control's state. */
555
+ export type SegmentedControlPagesProps = {
556
+ state: SegmentedControlState;
557
+ };
558
+ export type SegmentedControlProps = {
359
559
  /** The controller returned by `useSegmentedControlState`. */
360
560
  state: SegmentedControlState;
361
561
  /** @default 'default' */
362
562
  variant?: LiteralUnion<'default'>;
363
563
  keyboardShouldPersistTaps?: boolean | 'always' | 'never' | 'handled';
364
- }
564
+ };
365
565
  /** The state controller a `SegmentedControl` is driven by. */
366
- export interface SegmentedControlState {
566
+ export type SegmentedControlState = {
367
567
  activeIndex: number;
368
- items: any[];
568
+ items: SegmentedControlItem[];
369
569
  setActiveIndex: (index: number) => void;
370
- }
570
+ };
571
+ /** The options `useSegmentedControlState` builds a {@link SegmentedControlState} from. */
572
+ export type SegmentedControlStateOptions = {
573
+ items: SegmentedControlItem[];
574
+ pageWidth: number;
575
+ defaultIndex?: number;
576
+ onPageChange?: (index: number) => void;
577
+ };
371
578
  /** A registered Unbound settings entry, mirroring Discord's `SETTING_RENDERER_CONFIG` route shape. */
372
- export interface SettingsEntry {
579
+ export type SettingsEntry = {
373
580
  type: 'route';
374
581
  key: string;
375
582
  useTitle: () => string;
@@ -377,19 +584,26 @@ export interface SettingsEntry {
377
584
  parent: string | null;
378
585
  section?: string;
379
586
  excludeFromDisplay?: boolean;
380
- IconComponent?: ComponentType<any>;
587
+ IconComponent?: ReactModule.ComponentType;
381
588
  screen: SettingsScreen;
382
- }
589
+ };
590
+ /** A settings store, or a nested group of settings within one. */
591
+ export type SettingsObject = {
592
+ [key: string]: SettingsValue;
593
+ };
383
594
  /** The screen descriptor a settings route entry renders. */
384
- export interface SettingsScreen {
595
+ export type SettingsScreen = {
385
596
  route: string;
386
- getComponent: () => ComponentType<any>;
387
- }
597
+ /** Discord's navigator renders the screen with its own route props, so any component fits. */
598
+ getComponent: () => ReactModule.ComponentType<never>;
599
+ };
600
+ /** A JSON value held in a settings store. */
601
+ export type SettingsValue = string | number | boolean | null | SettingsValue[] | SettingsObject;
388
602
  /**
389
603
  * The DS `Slider`. It reads only `startIcon` / `endIcon` / `style` / `onValueChange` / `step`; the
390
604
  * remaining slider props (`value`, bounds, tint colours) are spread onto the underlying RN slider.
391
605
  */
392
- export interface SliderProps {
606
+ export type SliderProps = {
393
607
  value?: number;
394
608
  defaultValue?: number;
395
609
  minimumValue?: number;
@@ -400,52 +614,62 @@ export interface SliderProps {
400
614
  tapToSeek?: boolean;
401
615
  lowerLimit?: number;
402
616
  upperLimit?: number;
403
- startIcon?: ReactNode;
404
- endIcon?: ReactNode;
405
- valueLabel?: ReactNode;
617
+ startIcon?: ReactModule.ReactNode;
618
+ endIcon?: ReactModule.ReactNode;
619
+ valueLabel?: ReactModule.ReactNode;
406
620
  minimumTrackTintColor?: string;
407
621
  maximumTrackTintColor?: string;
408
622
  style?: StyleProp<ViewStyle>;
409
623
  onValueChange?: (value: number) => void;
410
624
  onSlidingStart?: (value: number) => void;
411
625
  onSlidingComplete?: (value: number) => void;
412
- }
626
+ };
413
627
  /** `SplitTextInput` / `SplitTextField`: a segmented input (e.g. verification codes). */
414
- export interface SplitTextInputProps extends TextFieldProps {
628
+ export type SplitTextInputProps = {
415
629
  isRound?: boolean;
416
630
  leadingText?: string;
417
- leadingPressableProps?: Record<string, any>;
418
- }
419
- export interface StackProps extends ViewProps {
631
+ leadingPressableProps?: PressableProps;
632
+ } & TextFieldProps;
633
+ export type StackProps = {
420
634
  spacing?: number;
421
635
  direction?: 'horizontal' | 'vertical';
422
636
  align?: 'start' | 'center' | 'end' | 'stretch';
423
637
  justify?: 'start' | 'center' | 'end' | 'between' | 'around';
424
- children?: ReactNode;
425
- }
426
- export interface SwitchProps {
638
+ children?: ReactModule.ReactNode;
639
+ } & ViewProps;
640
+ /** A stylesheet spec: each key maps to a view, text, or image style. */
641
+ export type StyleSheetSpec = Record<string, ViewStyle | TextStyle | ImageStyle>;
642
+ /** A stylesheet spec, or a function producing one (Discord accepts both forms). */
643
+ export type StyleSheetSpecOrFactory<T extends StyleSheetSpec> = T | ((...args: any[]) => T);
644
+ export type SwitchProps = {
427
645
  value: boolean;
428
646
  disabled?: boolean;
429
647
  accessibilityLabel?: string;
430
648
  onValueChange: (value: boolean) => void;
431
- }
432
- export interface TableCheckboxRowProps {
433
- label?: ReactNode;
434
- subLabel?: ReactNode;
649
+ };
650
+ export type TableCheckboxRowProps = {
651
+ label?: ReactModule.ReactNode;
652
+ subLabel?: ReactModule.ReactNode;
435
653
  checked: boolean;
436
654
  disabled?: boolean;
437
655
  accessibilityHint?: string;
438
- onPress: Fn<void>;
439
- }
440
- export interface TableRadioRowProps {
441
- label?: ReactNode;
442
- subLabel?: ReactNode;
656
+ onPress: DiscordFunction<void>;
657
+ };
658
+ export type TableRadioRowProps = {
659
+ label?: ReactModule.ReactNode;
660
+ subLabel?: ReactModule.ReactNode;
443
661
  value: any;
444
662
  disabled?: boolean;
445
663
  accessibilityHint?: string;
446
664
  legacyCompat?: boolean;
447
- }
448
- export interface TableRowGroupProps {
665
+ };
666
+ /** `TableRow` with its attached statics (`Icon`, `Arrow`, `TrailingText`). */
667
+ export type TableRowComponent = ReactModule.ComponentType<TableRowProps> & {
668
+ Icon: ReactModule.ComponentType<TableRowIconProps>;
669
+ Arrow: ReactModule.ComponentType<ViewProps>;
670
+ TrailingText: ReactModule.ComponentType<TrailingTextProps>;
671
+ };
672
+ export type TableRowGroupProps = {
449
673
  title?: string;
450
674
  description?: string;
451
675
  helperText?: string;
@@ -453,21 +677,21 @@ export interface TableRowGroupProps {
453
677
  hasTrailingText?: boolean;
454
678
  accessibilityRole?: string;
455
679
  accessibilityLabel?: string;
456
- children?: ReactNode;
457
- }
458
- export interface TableRowGroupTitleProps {
680
+ children?: ReactModule.ReactNode;
681
+ };
682
+ export type TableRowGroupTitleProps = {
459
683
  title: string;
460
- }
461
- export interface TableRowIconProps {
684
+ };
685
+ export type TableRowIconProps = {
462
686
  source?: number;
463
- IconComponent?: ComponentType<any>;
687
+ IconComponent?: ReactModule.ComponentType<any>;
464
688
  variant?: LiteralUnion<'default' | 'danger' | 'blurple'>;
465
- }
466
- export interface TableRowProps {
467
- label?: ReactNode;
468
- subLabel?: ReactNode;
469
- icon?: ReactNode;
470
- trailing?: ReactNode;
689
+ };
690
+ export type TableRowProps = {
691
+ label?: ReactModule.ReactNode;
692
+ subLabel?: ReactModule.ReactNode;
693
+ icon?: ReactModule.ReactNode;
694
+ trailing?: ReactModule.ReactNode;
471
695
  arrow?: boolean;
472
696
  disabled?: boolean;
473
697
  /** Rounds the top corners; set on the first row of a manually laid-out group. */
@@ -478,30 +702,29 @@ export interface TableRowProps {
478
702
  subLabelLineClamp?: number;
479
703
  variant?: LiteralUnion<'default' | 'danger'>;
480
704
  draggable?: boolean;
481
- onPress?: Fn<void>;
482
- children?: ReactNode;
483
- }
484
- export interface TableSwitchRowProps {
485
- label?: ReactNode;
486
- subLabel?: ReactNode;
487
- icon?: ReactNode;
488
- trailing?: ReactNode;
705
+ onPress?: DiscordFunction<void>;
706
+ children?: ReactModule.ReactNode;
707
+ };
708
+ export type TableSwitchRowProps = {
709
+ label?: ReactModule.ReactNode;
710
+ subLabel?: ReactModule.ReactNode;
711
+ icon?: ReactModule.ReactNode;
712
+ trailing?: ReactModule.ReactNode;
489
713
  value: boolean;
490
714
  disabled?: boolean;
491
715
  accessibilityHint?: string;
492
716
  variant?: LiteralUnion<'default'>;
493
717
  onValueChange: (value: boolean) => void;
494
- }
718
+ };
495
719
  /** `TextArea` extends the field family with a character limit. */
496
- export interface TextAreaProps extends TextFieldProps {
720
+ export type TextAreaProps = {
497
721
  maxLength?: number;
498
- }
722
+ } & TextFieldProps;
499
723
  /**
500
- * The redesign `TextField` and its siblings (`TextArea`, `SearchField`, `GhostInput`,
501
- * `SplitTextInput`). This is where the `size` / `status` / `isClearable` / `leadingIcon` chrome
502
- * actually lives, unlike {@link TextInputProps}. `onChange` receives the string value.
724
+ * The redesign `TextField` family (`TextArea`, `SearchField`, `GhostInput`, `SplitTextInput`), which
725
+ * owns the `size` / `status` / `leadingIcon` chrome. `onChange` receives the string value.
503
726
  */
504
- export interface TextFieldProps {
727
+ export type TextFieldProps = {
505
728
  value?: string;
506
729
  defaultValue?: string;
507
730
  placeholder?: string;
@@ -517,8 +740,8 @@ export interface TextFieldProps {
517
740
  trailingIcon?: IconSlot;
518
741
  leadingText?: string;
519
742
  trailingText?: string;
520
- leadingPressableProps?: Record<string, any>;
521
- trailingPressableProps?: Record<string, any>;
743
+ leadingPressableProps?: PressableProps;
744
+ trailingPressableProps?: PressableProps;
522
745
  secureTextEntry?: boolean;
523
746
  keyboardType?: RNTextInputProps['keyboardType'];
524
747
  autoComplete?: RNTextInputProps['autoComplete'];
@@ -527,19 +750,36 @@ export interface TextFieldProps {
527
750
  enableAndroidSanitizedInputWorkaround?: boolean;
528
751
  style?: StyleProp<ViewStyle>;
529
752
  inputStyle?: StyleProp<TextStyle>;
530
- children?: ReactNode;
753
+ children?: ReactModule.ReactNode;
531
754
  onChange?: (value: string) => void;
532
- onClear?: Fn<void>;
755
+ onClear?: DiscordFunction<void>;
533
756
  onFocus?: RNTextInputProps['onFocus'];
534
757
  onBlur?: RNTextInputProps['onBlur'];
535
- }
758
+ };
759
+ /**
760
+ * Native `TextInput` props forwarded through `TextInput` (`maxLength`, `selectionColor`, `onFocus`, …),
761
+ * minus the members `TextInput` overrides with its own semantics.
762
+ */
763
+ export type TextInputPassthrough = Omit<
764
+ RNTextInputProps,
765
+ | 'value'
766
+ | 'placeholder'
767
+ | 'multiline'
768
+ | 'numberOfLines'
769
+ | 'autoFocus'
770
+ | 'secureTextEntry'
771
+ | 'keyboardType'
772
+ | 'keyboardAppearance'
773
+ | 'autoCapitalize'
774
+ | 'autoCorrect'
775
+ | 'style'
776
+ | 'onChange'
777
+ >;
536
778
  /**
537
- * Discord's own form-style `TextInput` (`TextInput.native`), not React Native's. Its `onChange`
538
- * receives the raw string value, not an event. These are the props it reads verbatim off its props
539
- * object; every other prop is collected and spread onto the underlying native input via
540
- * {@link TextInputPassthrough}.
779
+ * Discord's form-style `TextInput` (`TextInput.native`), whose `onChange` receives the string value.
780
+ * Props it does not read are spread onto the native input via {@link TextInputPassthrough}.
541
781
  */
542
- export interface TextInputProps extends TextInputPassthrough {
782
+ export type TextInputProps = {
543
783
  value?: string;
544
784
  /** @default '' */
545
785
  placeholder?: string;
@@ -575,9 +815,9 @@ export interface TextInputProps extends TextInputPassthrough {
575
815
  /** Switches between the legacy and redesign render paths. @default true */
576
816
  allowRedesignTextInput?: boolean;
577
817
  onChange?: (value: string) => void;
578
- }
579
- export interface TextProps extends ViewProps {
580
- children?: ReactNode;
818
+ } & TextInputPassthrough;
819
+ export type TextProps = {
820
+ children?: ReactModule.ReactNode;
581
821
  variant?: TextVariant;
582
822
  color?: LiteralUnion<'text-normal' | 'text-muted' | 'header-primary' | 'header-secondary'>;
583
823
  style?: StyleProp<TextStyle>;
@@ -587,9 +827,28 @@ export interface TextProps extends ViewProps {
587
827
  animated?: boolean;
588
828
  numberOfLines?: number;
589
829
  allowFontScaling?: boolean;
590
- }
830
+ } & ViewProps;
831
+ /** Every typography variant Discord ships in `TextStyleSheet`, kept open for new ones. */
832
+ export type TextVariant = LiteralUnion<
833
+ | `heading-${'sm' | 'md' | 'lg' | 'xl' | 'xxl'}/${TextWeight | 'extrabold'}`
834
+ | `experimental/heading-${'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'}/${'semibold' | 'bold'}`
835
+ | `heading-deprecated-12/${TextWeight | 'extrabold'}`
836
+ | `redesign/heading-18/${'medium' | 'semibold' | 'bold'}`
837
+ | `text-${'xxs' | 'xs' | 'sm' | 'md' | 'lg'}/${TextWeight}`
838
+ | `redesign/message-preview/${TextWeight}`
839
+ | `redesign/channel-title/${TextWeight}`
840
+ | `experimental/body-${'xs' | 'sm' | 'md' | 'lg'}/${'normal' | 'medium'}`
841
+ | `experimental/meta/${'normal' | 'medium'}`
842
+ | `experimental/label-${'xs' | 'sm' | 'md' | 'lg'}/${'medium' | 'semibold'}`
843
+ | `experimental/mono-${'sm' | 'md'}/${'normal' | 'bold'}`
844
+ | `display-${'sm' | 'md' | 'lg'}`
845
+ | `experimental/display-${'xs' | 'sm' | 'md' | 'lg'}`
846
+ | 'eyebrow'
847
+ >;
848
+ /** The four common font weights used across typography variants. */
849
+ export type TextWeight = 'normal' | 'medium' | 'semibold' | 'bold';
591
850
  /** A theme's semantic and raw colour definitions plus optional background. */
592
- export interface Theme {
851
+ export type Theme = {
593
852
  semantic: Record<PropertyKey, ThemeSemanticColor>;
594
853
  raw: Record<PropertyKey, string>;
595
854
  type: 'midnight' | 'darker' | 'light';
@@ -598,213 +857,51 @@ export interface Theme {
598
857
  opacity?: number;
599
858
  url: string;
600
859
  };
601
- }
860
+ };
861
+ /** An {@link Addon} whose instance is a {@link Theme}, tracking its registration state. */
862
+ export type ThemeEntity = Addon & {
863
+ registered: boolean;
864
+ instance: Theme | null;
865
+ };
866
+ /** A single semantic colour definition in a {@link Theme}. */
867
+ export type ThemeSemanticColor = {
868
+ type: 'color' | 'raw';
869
+ value: string;
870
+ opacity?: number;
871
+ };
602
872
  /** A button rendered inside a toast. */
603
- export interface ToastButton {
873
+ export type ToastButton = {
604
874
  variant?: 'primary' | 'secondary' | 'tertiary';
605
875
  size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
606
876
  iconPosition?: 'start' | 'end';
607
877
  content: string;
608
878
  icon?: number;
609
- onPress: Fn;
610
- }
879
+ onPress: () => void;
880
+ };
611
881
  /** A handle returned when showing a toast, used to update or close it. */
612
- export interface ToastHandle {
882
+ export type ToastHandle = {
613
883
  update: (options: Partial<ToastOptions>) => void;
614
884
  close: () => void;
615
- }
885
+ };
616
886
  /** Options accepted when showing a toast. */
617
- export interface ToastOptions {
618
- title?: string | ComponentType;
887
+ export type ToastOptions = {
888
+ title?: string | ReactModule.ComponentType;
619
889
  content?: string;
620
890
  duration?: number;
621
- onTimeout?: Fn;
891
+ onTimeout?: () => void;
622
892
  icon?: string | number | ImageSourcePropType;
623
893
  id?: string;
624
894
  buttons?: ToastButton[];
625
895
  tintedIcon?: boolean;
626
- }
896
+ };
627
897
  /** State and actions of the toast store. */
628
- export interface ToastStoreState {
898
+ export type ToastStoreState = {
629
899
  toasts: Record<string, InternalToastOptions>;
630
900
  addToast: (options: InternalToastOptions) => ToastHandle;
631
901
  updateToastWithOptions: (id: string, options: Partial<InternalToastOptions>) => void;
632
- }
633
- export interface TrailingTextProps {
634
- text: string;
635
- }
636
- /** The author of an addon: a display name and a numeric user id. */
637
- export type AddonAuthor = {
638
- name: string;
639
- id: `${number}`;
640
902
  };
641
- /** An addon referenced either by its id string or the {@link Addon} entity itself. */
642
- export type AddonResolveable = string | Addon;
643
- /** `Button` with its attached `Icon` static. */
644
- export type ButtonComponent = ComponentType<ButtonProps> & {
645
- Icon: ComponentType<TableRowIconProps>;
646
- };
647
- export type ButtonSize = LiteralUnion<'sm' | 'md' | 'lg'>;
648
- export type ButtonVariant = LiteralUnion<
649
- 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'active' | 'expressive'
650
- >;
651
- /**
652
- * The style factory. Accepts a spec object (or a function returning one) and returns a hook. The
653
- * hook subscribes to the theme context and lazily resolves each key on access, so it must be called
654
- * inside a component body: `const styles = useStyles();`.
655
- */
656
- export type CreateStyles = <T extends StyleSheetSpec>(
657
- styles: StyleSheetSpecOrFactory<T>,
658
- ) => Fn<ResolvedStyles<T>>;
659
- /** Discord ships numeric enums as bidirectional maps; this models both directions. */
660
- export type EnumLike<K extends readonly string[]> = {
661
- [P in K[number]]: number;
662
- } & {
663
- [n: number]: K[number];
664
- };
665
- /** A custom font the native loader has registered, as injected on `window.UNBOUND_FONTS`. */
666
- export type FontDescriptor = {
667
- name: string;
668
- file: string;
669
- path: string;
670
- };
671
- /** A font managed by the Fonts manager: currently identical to its {@link FontDescriptor}. */
672
- export type FontEntity = FontDescriptor;
673
- /** A loaded icon pack: its bundle marker and {@link IconPackManifest}. */
674
- export type IconPack = {
675
- bundle: string;
676
- manifest: IconPackManifest;
677
- };
678
- /** An icon pack's manifest: an {@link AddonManifest} tagged with its source kind. */
679
- export type IconPackManifest = AddonManifest & {
680
- type: 'icon-pack';
681
- source: 'github' | 'other';
682
- };
683
- /** Icon slot: a rendered node, a component, or a render function. */
684
- export type IconSlot = ReactNode | ComponentType<any> | Fn<ReactNode>;
685
- /** Input sizing, shared by the whole `TextField`/`Input` family. */
686
- export type InputSize = LiteralUnion<'sm' | 'md' | 'lg'>;
687
- /** Input status. `focused` is an internal state and is not user-settable. */
688
- export type InputStatus = LiteralUnion<'default' | 'error'>;
689
- export type NativeAssociationKey = NativeHandle;
690
- export type NativeClassHandle = NativeHandle;
691
- export type NativeFFIType =
692
- | NativeFFITypeName
693
- | {
694
- struct: string;
695
- };
696
- export type NativeFFITypeName =
697
- | 'void'
698
- | 'bool'
699
- | 'i8'
700
- | 'u8'
701
- | 'i16'
702
- | 'u16'
703
- | 'i32'
704
- | 'u32'
705
- | 'i64'
706
- | 'u64'
707
- | 'float'
708
- | 'double'
709
- | 'cstring'
710
- | 'pointer'
711
- | 'object'
712
- | 'class'
713
- | 'selector';
714
- export type NativeFabricSurface = NativeHandle;
715
- export type NativeHandle = object;
716
- export type NativeObjectHandle = NativeHandle;
717
- export type NativePluginCapability =
718
- | 'native.objc.classes'
719
- | 'native.objc.invoke'
720
- | 'native.objc.ivars'
721
- | 'native.objc.associations'
722
- | 'native.objc.hooks'
723
- | 'native.ffi.symbols'
724
- | 'native.ffi.call'
725
- | 'native.fabric.mount';
726
- export type NativePluginErrorCode =
727
- | 'NATIVE_BRIDGE_ERROR'
728
- | 'NATIVE_PLUGIN_API_VERSION_UNSUPPORTED'
729
- | 'NATIVE_PLUGIN_CAPABILITY_DENIED'
730
- | 'NATIVE_PLUGIN_SCOPE_DISPOSED'
731
- | 'NATIVE_PLUGIN_UNAVAILABLE';
732
- export type NativePointer = NativeHandle;
733
- export type NativeThreadPolicy = 'current' | 'main';
734
- /** An {@link Addon} whose instance is a {@link Plugin}. */
735
- export type PluginEntity = Addon & {
736
- instance: Plugin$1 | null;
737
- };
738
- /** Resolves each key of a {@link StyleSheetSpec} to the concrete RN style type it produced. */
739
- export type ResolvedStyles<T extends StyleSheetSpec> = {
740
- [K in keyof T]: T[K] extends ImageStyle
741
- ? ImageStyle
742
- : T[K] extends TextStyle
743
- ? TextStyle
744
- : ViewStyle;
745
- };
746
- /** A stylesheet spec: each key maps to a view, text, or image style. */
747
- export type StyleSheetSpec = Record<
748
- string,
749
- ViewStyle | TextStyle | ImageStyle | Record<PropertyKey, any>
750
- >;
751
- /** A stylesheet spec, or a function producing one (Discord accepts both forms). */
752
- export type StyleSheetSpecOrFactory<T extends StyleSheetSpec> = T | ((...args: any[]) => T);
753
- /** `TableRow` with its attached statics (`Icon`, `Arrow`, `TrailingText`). */
754
- export type TableRowComponent = ComponentType<TableRowProps> & {
755
- Icon: ComponentType<TableRowIconProps>;
756
- Arrow: ComponentType<ViewProps>;
757
- TrailingText: ComponentType<TrailingTextProps>;
758
- };
759
- /**
760
- * Native `TextInput` props forwarded through `TextInput`. Everything the DS component does not read
761
- * itself (`maxLength`, `selectionColor`, `onFocus`, …) is spread onto the underlying native input,
762
- * so it accepts the RN surface too, minus the members `TextInput` overrides with its own semantics.
763
- */
764
- export type TextInputPassthrough = Omit<
765
- RNTextInputProps,
766
- | 'value'
767
- | 'placeholder'
768
- | 'multiline'
769
- | 'numberOfLines'
770
- | 'autoFocus'
771
- | 'secureTextEntry'
772
- | 'keyboardType'
773
- | 'keyboardAppearance'
774
- | 'autoCapitalize'
775
- | 'autoCorrect'
776
- | 'style'
777
- | 'onChange'
778
- >;
779
- /** Every typography variant Discord ships in `TextStyleSheet`, kept open for new ones. */
780
- export type TextVariant = LiteralUnion<
781
- | `heading-${'sm' | 'md' | 'lg' | 'xl' | 'xxl'}/${TextWeight | 'extrabold'}`
782
- | `experimental/heading-${'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'}/${'semibold' | 'bold'}`
783
- | `heading-deprecated-12/${TextWeight | 'extrabold'}`
784
- | `redesign/heading-18/${'medium' | 'semibold' | 'bold'}`
785
- | `text-${'xxs' | 'xs' | 'sm' | 'md' | 'lg'}/${TextWeight}`
786
- | `redesign/message-preview/${TextWeight}`
787
- | `redesign/channel-title/${TextWeight}`
788
- | `experimental/body-${'xs' | 'sm' | 'md' | 'lg'}/${'normal' | 'medium'}`
789
- | `experimental/meta/${'normal' | 'medium'}`
790
- | `experimental/label-${'xs' | 'sm' | 'md' | 'lg'}/${'medium' | 'semibold'}`
791
- | `experimental/mono-${'sm' | 'md'}/${'normal' | 'bold'}`
792
- | `display-${'sm' | 'md' | 'lg'}`
793
- | `experimental/display-${'xs' | 'sm' | 'md' | 'lg'}`
794
- | 'eyebrow'
795
- >;
796
- /** The four common font weights used across typography variants. */
797
- export type TextWeight = 'normal' | 'medium' | 'semibold' | 'bold';
798
- /** An {@link Addon} whose instance is a {@link Theme}, tracking its registration state. */
799
- export type ThemeEntity = Addon & {
800
- registered: boolean;
801
- instance: Theme | null;
802
- };
803
- /** A single semantic colour definition in a {@link Theme}. */
804
- export type ThemeSemanticColor = {
805
- type: 'color' | 'raw';
806
- value: string;
807
- opacity?: number;
903
+ export type TrailingTextProps = {
904
+ text: string;
808
905
  };
809
906
  /** `TransitionStates`: MOUNTED = 0, ENTERED = 1, YEETED = 2. */
810
907
  export type TransitionState = 'MOUNTED' | 'ENTERED' | 'YEETED';
@@ -813,12 +910,13 @@ export type UnboundAsset = DiscordAsset & {
813
910
  iconPackPath?: string;
814
911
  iconPackScale?: number;
815
912
  };
816
-
817
913
  /** The lifecycle and settings contract implemented by a plugin. */
818
- interface Plugin$1 {
914
+ type Plugin$1 = {
819
915
  start?(context?: PluginContext): void;
820
916
  stop?(): void;
821
- getSettingsPanel?(): ReactNode;
822
- }
917
+ getSettingsPanel?(): ReactModule.ReactNode;
918
+ };
823
919
 
824
920
  export { Plugin$1 as Plugin };
921
+
922
+ export {};