Skip to content

Conversation

@hyperz111
Copy link
Contributor

@hyperz111 hyperz111 commented Nov 16, 2025

In this PR, i add theme option to some prompts:

  • autocomplete
  • autocomplete-multiselect
  • confirm
  • group-multi-select
  • multiselect
  • password
  • select-key (NOT perfect)
  • select
  • text

See ThemeOptions in common.ts.

fixes #345

@changeset-bot
Copy link

changeset-bot bot commented Nov 16, 2025

⚠️ No Changeset found

Latest commit: c3ee6bd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 16, 2025

@example/basic@example/changesets

npm i https://pkg.pr.new/bombshell-dev/clack/@clack/core@415
npm i https://pkg.pr.new/bombshell-dev/clack/@clack/prompts@415

commit: 3c4c1d5

@43081j
Copy link
Collaborator

43081j commented Nov 17, 2025

the approach isn't far off, but i don't think it makes sense to have a single set of options

each prompt has its own style. they only cross over on some things, such as the left guide/border.

i'd expect CommonOptions to have a type parameter for the style, or multiple inheritance of interfaces:

interface CommonOptions<TStyle> {
  // ...
  style: TStyle;
}

// or

interface Whatever extends CommonOptions, StyleOptions<WhateverStyle> {
  // ..
}

}

interface AutocompleteSharedOptions<Value> extends CommonOptions {
type AutocompleteSharedOptions<Value, TStyle> = CommonOptions<TStyle> & {
Copy link
Collaborator

@43081j 43081j Nov 19, 2025

Choose a reason for hiding this comment

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

Suggested change
type AutocompleteSharedOptions<Value, TStyle> = CommonOptions<TStyle> & {
interface AutocompleteSharedOptions<Value> extends CommonOptions<AutocompleteStyle> {

nobody should be changing the style type of any prompt

each prompt should expose its own style interface, or the base style interface

@43081j
Copy link
Collaborator

43081j commented Nov 19, 2025

you're not far off but its not quite what i meant

here:

interface TextPromptStyle {
  someTextPromptSpecificStyle: string;
  anotherOne: string;
}

interface TextPromptOptions extends CommonOptions<TextPromptStyle> {
  // ..
}

every prompt would have its own style interface. if it doesn't have any of its own, it would use a BaseStyle or some such thing

the style will always be a flat object. the only reason you had to introduce deep merge logic is because you chose to make the shape nested. just don't bother - keep it flat and you can throw the deep merge stuff away.

CommonOptions should basically be CommonOptions<TStyle extends Record<string, string>>

@hyperz111
Copy link
Contributor Author

Like this?

// Before 
interface CheckboxTheme {
	selected?: {
		active?: string;
		inactive?: string;
	};
	unselected?: {
		active?: string;
		inactive?: string;
	};
	disabled?: string;
}

// After
interface CheckboxThemeFlat {
	selectedActive?: string;
	selectedInactive?: string;
	unselectedActive?: string;
	unselectedInactive?: string;
	disabled?: string;
}

@43081j
Copy link
Collaborator

43081j commented Nov 20, 2025

yes exactly, but there'd be no such thing as a "checkbox theme"

there would be a text prompt theme, a select prompt theme, etc.

if any of those share some properties, just have an internal interface they both extend

Copy link
Member

@dreyfus92 dreyfus92 left a comment

Choose a reason for hiding this comment

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

hey @hyperz111, amazing work on this! however, I would suggest a different approach given the scope of changes needed.

what @43081j is suggesting is a significant architectural refactor, the nested structure needs to be completely flattened. trying to tackle all 8 prompts at once makes this PR very difficult to review.

break this into separate PRs, starting with just the autocomplete prompt. once we get that pattern right and merged, the others will follow the same approach and be much easier to review.

for this PR, I'd suggest:

  • focus only on autocomplete.ts and autocompleteMultiselect.ts
  • implement the flat theme structure James outlined (no nesting, prompt-specific styles)
  • remove @fastify/deepmerge and use simple shallow merging like object spreading
  • get this pattern approved and merged first

then follow up with separate PRs for:

  • select.ts and multiselect.ts
  • confirm.ts
  • password.ts and text.ts
  • group-multiselect.ts
  • select-key.ts

@43081j
Copy link
Collaborator

43081j commented Nov 21, 2025

having another think about this. i wonder if we should have something like this:

interface GlobalTheme {
  formatGuide?: (str: string) => string;
}

interface ThemeOptions<T> {
  theme?: T & GlobalTheme;
}

interface CommonOptions {
  // existing common options interface
}

// ...

export interface TextTheme {
 formatCancel?: (str: string) => string;
}
  
export interface TextOptions extends CommonOptions, ThemeOptions<TextTheme> {
  message: string;
  placeholder?: string;
  defaultValue?: string;
  initialValue?: string;
  validate?: (value: string | undefined) => string | Error | undefined;
}

so you'd use it like this:

text({
  theme: {
    formatGuide: (str) => colors.red(str), // make the left guide line/border red
  }
});

the names need some bikeshedding but this pattern is what i had in mind. and fully agree we need to really strip this down to granular changes

@hyperz111
Copy link
Contributor Author

break this into separate PRs, starting with just the autocomplete prompt. once we get that pattern right and merged, the others will follow the same approach and be much easier to review.

I don't want to do that, but if it's for making the review easy. Maybe i can

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request] add a style representation to all prompts

3 participants