Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable themes (#852) #862

Merged
merged 19 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli-ux/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as uxPrompt from './prompt'
import * as styled from './styled'
import uxWait from './wait'
import write from './write'

const hyperlinker = require('hyperlinker')

export class ux {
Expand Down Expand Up @@ -195,4 +194,5 @@ export {ExitError} from './exit'
export {IPromptOptions} from './prompt'
export {Table} from './styled'

export {colorize} from './theme'
export {default as write} from './write'
31 changes: 31 additions & 0 deletions src/cli-ux/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import chalk from 'chalk'
import * as Color from 'color'

import {STANDARD_CHALK, StandardChalk, Theme} from '../interfaces/theme'

function isStandardChalk(color: any): color is StandardChalk {
return STANDARD_CHALK.includes(color)
}

export function colorize(color: Color | StandardChalk | undefined, text: string): string {
if (isStandardChalk(color)) return chalk[color](text)

return color ? chalk.hex(color.hex())(text) : text
}

export function parseTheme(untypedTheme: Record<string, string>): Theme {
return Object.fromEntries(
Object.entries(untypedTheme)
.map(([key, value]) => [key, getColor(value)])
.filter(([_, value]) => value),
)
}

export function getColor(color: string): Color
export function getColor(color: StandardChalk): StandardChalk
export function getColor(color: string | StandardChalk): Color | StandardChalk | undefined {
try {
// eslint-disable-next-line new-cap
return isStandardChalk(color) ? color : new Color.default(color)
} catch {}
}
2 changes: 1 addition & 1 deletion src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {join, resolve, sep} from 'node:path'
import {URL, fileURLToPath} from 'node:url'

import {ux} from '../cli-ux'
import {parseTheme} from '../cli-ux/theme'
import {Command} from '../command'
import {CLIError, error, exit, warn} from '../errors'
import {getHelpFlagAdditions} from '../help/util'
Expand All @@ -17,7 +18,6 @@ import {OCLIF_MARKER_OWNER, Performance} from '../performance'
import {settings} from '../settings'
import {requireJson, safeReadJson} from '../util/fs'
import {getHomeDir, getPlatform} from '../util/os'
import {parseTheme} from '../util/theme'
import {compact, isProd} from '../util/util'
import Cache from './cache'
import PluginLoader from './plugin-loader'
Expand Down
2 changes: 1 addition & 1 deletion src/help/command.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import chalk from 'chalk'
import stripAnsi from 'strip-ansi'

import {colorize} from '../cli-ux/theme'
import {Command} from '../command'
import * as Interfaces from '../interfaces'
import {ensureArgObject} from '../util/ensure-arg-object'
import {toStandardizedId} from '../util/ids'
import {colorize} from '../util/theme'
import {castArray, compact, sortBy} from '../util/util'
import {DocOpts} from './docopts'
import {HelpFormatter, HelpSection, HelpSectionRenderer} from './formatter'
Expand Down
2 changes: 1 addition & 1 deletion src/help/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import stripAnsi from 'strip-ansi'
import widestLine from 'widest-line'
import wrap from 'wrap-ansi'

import {colorize} from '../cli-ux/theme'
import {Command} from '../command'
import * as Interfaces from '../interfaces'
import {stdtermwidth} from '../screen'
import {colorize} from '../util/theme'
import {template} from './util'

export type HelpSectionKeyValueTable = {description: string; name: string}[]
Expand Down
2 changes: 1 addition & 1 deletion src/help/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {format} from 'node:util'
import stripAnsi from 'strip-ansi'

import {colorize} from '../cli-ux/theme'
import write from '../cli-ux/write'
import {Command} from '../command'
import {error} from '../errors'
import * as Interfaces from '../interfaces'
import {load} from '../module-loader'
import {cacheDefaultValue} from '../util/cache-default-value'
import {toConfiguredId} from '../util/ids'
import {colorize} from '../util/theme'
import {compact, sortBy, uniqBy} from '../util/util'
import {CommandHelp} from './command'
import {HelpFormatter} from './formatter'
Expand Down
2 changes: 1 addition & 1 deletion src/help/root.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import stripAnsi from 'strip-ansi'

import {colorize} from '../cli-ux/theme'
import * as Interfaces from '../interfaces'
import {colorize} from '../util/theme'
import {compact} from '../util/util'
import {HelpFormatter} from './formatter'

Expand Down
39 changes: 38 additions & 1 deletion src/interfaces/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,41 @@ export const STANDARD_CHALK = [

export type StandardChalk = (typeof STANDARD_CHALK)[number]

export type Theme = Record<string, Color | StandardChalk>
export const THEME_KEYS = [
'alias',
'bin',
'command',
'commandSummary',
'dollarSign',
'flag',
'flagDefaultValue',
'flagOptions',
'flagRequired',
'flagSeparator',
'flagType',
'sectionDescription',
'sectionHeader',
'topic',
'version',
] as const

export type ThemeKey = (typeof THEME_KEYS)[number]

export type Theme = {
[key: string | ThemeKey]: Color | StandardChalk | undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I see a use case for this. CLI developers can extend the oclif's Theme Spec with their own theme specific keys so that plugins built with their own CLI API can take advantage of their own Theme Spec, which is just a combination of Oclif + CLI Theme Specs. Makes sense now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't Theme be a interface to allow it to be extensible in typescript world?

alias?: Color | StandardChalk
bin?: Color | StandardChalk
command?: Color | StandardChalk
commandSummary?: Color | StandardChalk
dollarSign?: Color | StandardChalk
flag?: Color | StandardChalk
flagDefaultValue?: Color | StandardChalk
flagOptions?: Color | StandardChalk
flagRequired?: Color | StandardChalk
flagSeparator?: Color | StandardChalk
flagType?: Color | StandardChalk
sectionDescription?: Color | StandardChalk
sectionHeader?: Color | StandardChalk
topic?: Color | StandardChalk
version?: Color | StandardChalk
}
170 changes: 0 additions & 170 deletions src/util/theme.ts

This file was deleted.

Loading
Loading