Skip to content

Commit

Permalink
feat: Support alpha values for theme() function
Browse files Browse the repository at this point in the history
  • Loading branch information
sastan committed Oct 3, 2022
1 parent 5895824 commit bdc0a7a
Show file tree
Hide file tree
Showing 9 changed files with 993 additions and 191 deletions.
6 changes: 6 additions & 0 deletions .changeset/sour-rules-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@twind/preset-tailwind': patch
'twind': patch
---

support alpha values for `theme()` function
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
"name": "twind",
"path": "packages/twind/dist/twind.esnext.js",
"brotli": true,
"limit": "7.6kb"
"limit": "7.65kb"
},
{
"name": "twind (setup)",
"path": "packages/twind/dist/twind.esnext.js",
"import": "{ setup }",
"brotli": true,
"limit": "5.2kb"
"limit": "5.25kb"
},
{
"name": "twind (twind + cssom)",
Expand Down Expand Up @@ -100,12 +100,12 @@
"devDependencies": {
"@changesets/cli": "^2.20.0",
"@changesets/get-github-info": "^0.5.0",
"@size-limit/esbuild": "^7.0.8",
"@size-limit/file": "^7.0.8",
"@typescript-eslint/eslint-plugin": "^5.11.0",
"@typescript-eslint/parser": "^5.11.0",
"@vitest/ui": "^0.3.4",
"c8": "^7.11.0",
"@size-limit/esbuild": "^8.1.0",
"@size-limit/file": "^8.1.0",
"@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1",
"@vitest/ui": "^0.23.4",
"c8": "^7.12.0",
"distilt": "^0.16.8",
"dotenv": "^10.0.0",
"eslint": "^8.9.0",
Expand All @@ -120,12 +120,12 @@
"local-pkg": "^0.4.1",
"prettier": "^2.5.1",
"prettier-plugin-svelte": "^2.6.0",
"size-limit": "^7.0.8",
"size-limit": "^8.1.0",
"style-vendorizer": "^2.1.1",
"svelte": "^3.46.4",
"tslib": "^2.3.1",
"tslib": "^2.4.0",
"typescript": "^4.8.4",
"vitest": "^0.3.4"
"vitest": "^0.23.4"
},
"prettier": {
"printWidth": 100,
Expand Down
6 changes: 5 additions & 1 deletion packages/preset-tailwind/src/rules.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -2013,5 +2013,9 @@
"peer-focus-within:text-base": ".peer:focus-within~.peer-focus-within\\:text-base{font-size:1rem;line-height:1.5rem}",
"focus-visible:text-base": ".focus-visible\\:text-base:focus-visible{font-size:1rem;line-height:1.5rem}",
"group-focus-visible:text-base": ".group:focus-visible .group-focus-visible\\:text-base{font-size:1rem;line-height:1.5rem}",
"peer-focus-visible:text-base": ".peer:focus-visible~.peer-focus-visible\\:text-base{font-size:1rem;line-height:1.5rem}"
"peer-focus-visible:text-base": ".peer:focus-visible~.peer-focus-visible\\:text-base{font-size:1rem;line-height:1.5rem}",
"text-translucent-rose": ".text-translucent-rose{color:rgba(244,63,94,50%)}",
"text-translucent-blue": ".text-translucent-blue{color:rgba(59,130,246,var(--my-alpha))}",
"text-translucent-emerald": ".text-translucent-emerald{color:rgba(16,185,129,0.5)}",
"text-[theme(colors.amber.500/theme(opacity.75))]": ".text-\\[theme\\(colors\\.amber\\.500\\/theme\\(opacity\\.75\\)\\)\\]{color:rgba(245,158,11,0.75)}"
}
9 changes: 7 additions & 2 deletions packages/preset-tailwind/src/rules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ const tw = twind(
{ min: '868px' },
],
},
colors: {
colors: ({ theme }) => ({
gainsboro: 'gainsboro',
'gray-light': '#d3dce6',
primary: 'rgb(var(--color-primary) / <alpha-value>)',
},
translucent: {
rose: 'theme(colors.rose.500 / 50%)',
blue: 'theme(colors.blue.500 / var(--my-alpha))',
emerald: theme('colors.emerald.500 / theme(opacity.50)'),
},
}),
backgroundImage: {
'hero-pattern': "url('/img/hero-pattern.svg')",
},
Expand Down
8 changes: 4 additions & 4 deletions packages/twind/src/internal/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ function serialize$<Theme extends BaseTheme = BaseTheme>(
key,
// support theme(...) function in values
// calc(100vh - theme('spacing.12'))
resolveThemeFunction('' + value, context) + (important ? ' !important' : ''),
resolveThemeFunction('' + value, context.theme) + (important ? ' !important' : ''),
),
)
.join(';')
Expand Down Expand Up @@ -225,7 +225,7 @@ function serialize$<Theme extends BaseTheme = BaseTheme>(

export function resolveThemeFunction<Theme extends BaseTheme = BaseTheme>(
value: string,
context: Context<Theme>,
theme: Context<Theme>['theme'],
): string {
// support theme(...) function in values
// calc(100vh - theme('spacing.12'))
Expand All @@ -235,8 +235,8 @@ export function resolveThemeFunction<Theme extends BaseTheme = BaseTheme>(
// if (value.includes('theme')) {
return value.replace(
/theme\((["'`])?(.+?)\1(?:\s*,\s*(["'`])?(.+?)\3)?\)/g,
(_, __, key, ___, defaultValue) => {
const value = context.theme(key, defaultValue)
(_, __, key: string, ___, defaultValue: string | undefined) => {
const value = theme(key, defaultValue)

if (typeof value == 'function' && /color|fill|stroke/i.test(key)) {
return toColorValue(value as ColorValue)
Expand Down
10 changes: 10 additions & 0 deletions packages/twind/src/internal/theme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,13 @@ test('reference the default theme', () => {
...(defaultTheme.fontFamily as Theme['fontFamily']).sans,
])
})

test('can apply alpha values to colors', () => {
const theme = makeThemeFunction<Theme>(defaultTheme)

assert.strictEqual(theme('colors.gray.500 / 0.5'), 'rgba(107,114,128,0.5)')
assert.strictEqual(
theme('colors.gray.500 / var(--my-alpha)'),
'rgba(107,114,128,var(--my-alpha))',
)
})
23 changes: 20 additions & 3 deletions packages/twind/src/internal/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type {
ThemeFunction,
ThemeSectionResolverContext,
} from '../types'
import { toColorValue } from '../colors'
import { resolveThemeFunction } from './serialize'

export function makeThemeFunction<Theme extends BaseTheme = BaseTheme>({
extend = {},
Expand All @@ -14,7 +16,9 @@ export function makeThemeFunction<Theme extends BaseTheme = BaseTheme>({
const resolved: Record<string, any> = {}

const resolveContext: ThemeSectionResolverContext<Theme> = {
colors: theme('colors'),
get colors() {
return theme('colors')
},

theme,

Expand All @@ -38,8 +42,17 @@ export function makeThemeFunction<Theme extends BaseTheme = BaseTheme>({

return theme as ThemeFunction<Theme>

function theme(sectionKey?: string, key?: string, defaultValue?: any): any {
function theme(
sectionKey?: string,
key?: string,
defaultValue?: any,
opacityValue?: string | undefined,
): any {
if (sectionKey) {
;({ 1: sectionKey, 2: opacityValue } =
// eslint-disable-next-line no-sparse-arrays
/^(\S+?)(?:\s*\/\s*([^/]+))?$/.exec(sectionKey) || ([, sectionKey] as RegExpExecArray))

if (/[.[]/.test(sectionKey)) {
const path: string[] = []

Expand Down Expand Up @@ -68,7 +81,11 @@ export function makeThemeFunction<Theme extends BaseTheme = BaseTheme>({

if (key == null) return section

return section[key || 'DEFAULT'] ?? defaultValue
const value = section[key || 'DEFAULT'] ?? defaultValue

return opacityValue
? toColorValue(value, { opacityValue: resolveThemeFunction(opacityValue, theme) })
: value
}

// Collect the whole theme
Expand Down
2 changes: 1 addition & 1 deletion packages/twind/src/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export function arbitrary<Theme extends BaseTheme = BaseTheme>(
context: Context<Theme>,
): string | undefined {
if (value[0] == '[' && value.slice(-1) == ']') {
value = normalize(resolveThemeFunction(value.slice(1, -1), context))
value = normalize(resolveThemeFunction(value.slice(1, -1), context.theme))

// TODO remove arbitrary type prefix — we do not need it but user may use it
// https://github.com/tailwindlabs/tailwindcss/blob/master/src/util/dataTypes.js
Expand Down
Loading

0 comments on commit bdc0a7a

Please sign in to comment.