Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@
- Tooling
- [SolidTV Devtools](/tools/solid_devtools.md)
- [JSX Locator Plugin](/tools/jsx_locator.md)
- [Hex Color Transform](/tools/hex_color_transform.md)
96 changes: 96 additions & 0 deletions docs/tools/hex_color_transform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Hex Color Transform

A Vite plugin that transforms hex color strings (`"#RRGGBB"`, `"#RGB"`, `"#RRGGBBAA"`, `"#RGBA"`) into the `0xRRGGBBAA` numeric format required by the SolidTV renderer at build time.

This means you can write natural hex color strings in your code and have them automatically converted to the correct format.

## Installation

The plugin is included in `@solidtv/solid` — no additional packages needed.

## Usage

Import and add the plugin to your `vite.config.ts`:

```typescript
import { defineConfig } from 'vite';
import { hexColorTransform } from '@solidtv/solid/devtools';

export default defineConfig({
plugins: [hexColorTransform()],
});
```

### With Include/Exclude Filters

You can control which files the plugin processes:

```typescript
import { defineConfig } from 'vite';
import { hexColorTransform } from '@solidtv/solid/devtools';

export default defineConfig({
plugins: [
hexColorTransform({
include: ['src/**/*.ts', 'src/**/*.tsx'],
exclude: 'src/ignore-this-directory/**',
}),
],
});
```

### Options

| Option | Type | Default | Description |
| --------- | -------------------- | ------------- | ------------------------------------------------- |
| `include` | `string \| string[]` | all files | Glob pattern(s) specifying which files to process |
| `exclude` | `string \| string[]` | no exclusions | Glob pattern(s) specifying which files to skip |

## How It Works

The plugin runs during Vite's `transform` step and converts all hex color string literals to `0xRRGGBBAA` numeric literals.

### Before

```typescript
const color = '#f6f6f6';
const shortColor = '#fff';
const alphaColor = '#f6f6f680';
const shortAlpha = '#fff8';
```

### After

```typescript
const color = 0xf6f6f6ff;
const shortColor = 0xffffffff;
const alphaColor = 0xf6f6f680;
const shortAlpha = 0xffffff88;
```

- 3-character hex (`#RGB`) is expanded to `#RRGGBBFF` (full opacity)
- 4-character hex (`#RGBA`) is expanded to `#RRGGBBAA`
- 6-character hex (`#RRGGBB`) gets `FF` appended for full opacity
- 8-character hex (`#RRGGBBAA`) is used as-is

## Migrating from `hexColor()`

If you were previously using the `hexColor()` helper function, you can remove all calls with a find-and-replace:

**VSCode regex find:**

```
hexColor\("(#[A-Fa-f0-9]{4,8})"\)
```

**Replace with:**

```
"$1"
```

> Be mindful of single vs double quotes — the regex matches double quotes.

After removing `hexColor()` calls, the Vite plugin handles the conversion automatically at build time.

**Tip:** Enable `editor.defaultColorDecorators` in VSCode settings (Command + , to search) to get built-in color highlighting for hex strings.
56 changes: 56 additions & 0 deletions src/devtools/hexColorTransform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createFilter, type Plugin } from 'vite';

Check failure on line 1 in src/devtools/hexColorTransform.ts

View workflow job for this annotation

GitHub Actions / build-test

Cannot find module 'vite' or its corresponding type declarations.

export interface HexColorTransformOptions {
include?: string | string[];
exclude?: string | string[];
}

export default function hexColorTransform(
options: HexColorTransformOptions = {},
): Plugin {
const filter = createFilter(options.include, options.exclude);

return {
name: 'vite-plugin-hex-color-transform',

transform(code, id) {

Check failure on line 16 in src/devtools/hexColorTransform.ts

View workflow job for this annotation

GitHub Actions / build-test

Parameter 'id' implicitly has an 'any' type.

Check failure on line 16 in src/devtools/hexColorTransform.ts

View workflow job for this annotation

GitHub Actions / build-test

Parameter 'code' implicitly has an 'any' type.
if (!filter(id)) {
return null;
}

const hexColorRegex =
/["']#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})["']/g;

const convertHexTo0x = (_match: string, p1: string) => {
let hex = p1;

if (hex.length === 3) {
hex =
hex
.split('')
.map((char) => char + char)
.join('') + 'FF';
} else if (hex.length === 4) {
const alpha = hex[3]! + hex[3]!;
hex =
hex
.slice(0, 3)
.split('')
.map((char) => char + char)
.join('') + alpha;
} else if (hex.length === 6) {
hex += 'FF';
}

return `0x${hex.toUpperCase()}`;
};

const transformedCode = code.replace(hexColorRegex, convertHexTo0x);

return {
code: transformedCode,
map: null,
};
},
};
}
3 changes: 3 additions & 0 deletions src/devtools/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as debug from '@solid-devtools/debugger/types';
import * as lng from '../core/index.js';

export { default as hexColorTransform } from './hexColorTransform.js';
export type { HexColorTransformOptions } from './hexColorTransform.js';

const EMPTY_CHILDREN: (lng.ElementNode | lng.ElementText)[] = [];

/**
Expand Down
Loading