Skip to content

chore(widgets): port credits to react#5822

Open
wesrupert wants to merge 1 commit intomasterfrom
feat/wr/credits/dev
Open

chore(widgets): port credits to react#5822
wesrupert wants to merge 1 commit intomasterfrom
feat/wr/credits/dev

Conversation

@wesrupert
Copy link
Copy Markdown
Contributor

  • Migrate Credits widget to React
  • Clean up widget form types
Screenshot 2026-04-01 at 12 42 47

@wesrupert wesrupert added enhancement react tech debt infra changes, refactors, etc labels Apr 1, 2026
@wesrupert wesrupert force-pushed the feat/wr/credits/dev branch from 1510eca to 8b1b29f Compare April 1, 2026 19:56
Comment on lines -50 to +49
export type TInputMetadata<T = string> =
| ITextMetadata
| INumberMetadata
| ISliderMetadata
| ITextBoolMetadata
| ICheckboxGroupMetadata
| IRadioGroupMetadata
| IListMetadata<T>;

interface IBaseMetadata {
export interface IBaseMetadata {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This union type was hiding some potential bugs, so I moved to using the underlying base interface as our main export:

  • There was no way for other widgets to reference the base class for input types that don't have a hand-written type yet
  • The inference from TInputMetadata<unknown> was casting custom types to incorrect subtypes, like SponsorBanner's imagepicker input was casting as a IListMetadata since it was the only type with .options

Comment on lines +42 to +45
type TCreditsMeta = PartialRec<
keyof ICreditsState['data']['settings'] | 'themes' | `_${string}`,
IBaseMetadata
>;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After struggling a bit to figure out how widget settings are synced via this system, I wanted to make it explicit in the types. This record type forces each section to either (a) use a synced value defined above, or (b) be explicit in its unsynced behavior via an underscore. See creditsMeta for more details.

'{new_follower_count}',
].join(', '),
}),
_includes: {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the TCreditsMeta magic helps make the config explicit. If this were named includes, TypeScript will now emit the following:

Diagnostics:
Object literal may only specify known properties,
and 'includes' does not exist in type 'Partial<Record<
  "theme" | "credit_title" | "credit_subtitle" | "background_color"
    | "font_color" | "font_size" | "font" | "muted_chatters" | "bits"
    | "subscribers" | "moderators" | "donations" | ... 11 more ...
    | `_${string}`,
  IBaseMetadata>
>'. [2353]

Same thing for typos like font_size vs fontsize, and even widget API mismatches like Credits' font_size vs Event List's text_size.

value: theme,
})),
}),
background_color: metadata.color({
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review question: how does the new system handle previews? I didn't see anywhere in the reference code where event list was handling preview.

height: 200,
x: 1,
y: 1,
anchor: AnchorPoint.North,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guessed at this value. Was it defined in the old code somewhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement react tech debt infra changes, refactors, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant