From a9ed4304cc6956eac6c5fc18f9cfc5e949db56ae Mon Sep 17 00:00:00 2001 From: "Chabib N." Date: Sun, 14 Jun 2026 21:43:48 +0700 Subject: [PATCH 1/5] refactor: organize --- src/index.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/index.ts b/src/index.ts index 43aad09..09ad7fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,6 +28,19 @@ export type { StylexProperties as '~StylexProperties' } /* eslint-disable @typescript-eslint/no-empty-object-type */ +/** + * @public + */ +type StyleDeck = + | StyleDeck[] + | StyleCard + | readonly [StyleCard, InlineStyles] + | Theme> + | NonApplicableThemeProperties + | NonApplicableObjectProperties + | NonApplicableSymbolProperties + | undefined + /** * @internal */ @@ -70,19 +83,6 @@ function mergeClassProperty( } } -/** - * @public - */ -type StyleDeck = - | StyleDeck[] - | StyleCard - | readonly [StyleCard, InlineStyles] - | Theme> - | NonApplicableThemeProperties - | NonApplicableObjectProperties - | NonApplicableSymbolProperties - | undefined - /** * Apply styles as props `{ className, style }`, or attrs `{ class, style }`. * From c9563a814d99cb16e9b9003915b0d2a8eb6e763c Mon Sep 17 00:00:00 2001 From: "Chabib N." Date: Sun, 14 Jun 2026 22:35:44 +0700 Subject: [PATCH 2/5] feat: patch for stylex attrs --- eslint.config.js | 9 ++++++--- src/index.spec.ts | 14 ++++++++++++++ src/index.ts | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 4766bd6..6cbd470 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -113,9 +113,12 @@ export default defineConfig([ 'unicorn/prevent-abbreviations': [ 'warn', { - allowList: { - args: true, - }, + ignore: [ + 'args', + /attrs/i, + /props/i, + // + ], }, ], }, diff --git a/src/index.spec.ts b/src/index.spec.ts index ef21f61..0649d25 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -42,6 +42,20 @@ describe('mergeClassProperty', () => { }) }) +describe('attrs', () => { + it('returns attrs', () => { + expect( + attrs({ + '--fooBar': 'initial', + MozAnimation: 'auto', + }), + ).toStrictEqual({ + style: '--fooBar:initial;-moz-animation:auto', + }) + }) +}) + +import { '~attrs' as attrs } from './index.ts' import { describe } from 'vitest' import { expect } from 'vitest' import { it } from 'vitest' diff --git a/src/index.ts b/src/index.ts index 09ad7fc..1298697 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ export { apply } export { sheet } export type { StyleDeck } +export { attrs as '~attrs' } export type { CommonProperties as '~CommonProperties' } export type { CompiledProperties as '~CompiledProperties' } export type { CompiledValue as '~CompiledValue' } @@ -83,6 +84,52 @@ function mergeClassProperty( } } +function attrs( + this: unknown, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ...styles: any[] +): ReturnType<(typeof stylex)['attrs']> extends infer T + ? { [Key in keyof T]: T[Key] | undefined } + : never { + const { + className, + style, + 'data-style-src': styleSource, + } = props.apply(this, styles) + + return { + ...(className == null + ? {} + : { + class: className, + }), + + ...(style == null + ? {} + : { + style: Object.entries(style) + .map(([key, value]) => { + if (key.startsWith('--')) { + return `${key}:${value.toString()}` + } + + return `${toKebabCase(key)}:${value.toString()}` + }) + .join(';'), + }), + + ...(styleSource == null + ? {} + : { + ['data-style-src']: styleSource, + }), + } +} + +function toKebabCase(text: string): string { + return text.replaceAll(/([A-Z])/g, '-$1').toLowerCase() +} + /** * Apply styles as props `{ className, style }`, or attrs `{ class, style }`. * @@ -364,6 +411,7 @@ import type { StyleXClassNameFor as ClassNameFor } from '@stylexjs/stylex' import type { CSSPropertiesWithExtras } from '@stylexjs/stylex/lib/types/StyleXTypes' import type { InlineStyles } from '@stylexjs/stylex' import type { Properties } from 'csstype' +import { props } from '@stylexjs/stylex' import type { Pseudos } from 'csstype' import type * as stylex from '@stylexjs/stylex' import type { StyleXVar } from '@stylexjs/stylex' From 679032322213f0f5bb80d3761f9ed0ffd8ce0d90 Mon Sep 17 00:00:00 2001 From: "Chabib N." Date: Sun, 14 Jun 2026 22:36:22 +0700 Subject: [PATCH 3/5] test: correct test name --- src/index.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.spec.ts b/src/index.spec.ts index 0649d25..4f6d5df 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -19,7 +19,7 @@ describe('mergeClassAttribute', () => { }) describe('mergeClassProperty', () => { - it('merges class attribute', () => { + it('merges class property', () => { expect( mergeClassProperty('foo bar', { className: 'quux', From 26fb727ef682ed89256a24e7e1446ae6823b59d7 Mon Sep 17 00:00:00 2001 From: "Chabib N." Date: Sun, 14 Jun 2026 22:39:13 +0700 Subject: [PATCH 4/5] version(patch): 0.7.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 23cf545..f08c01d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vicinage", - "version": "0.7.21", + "version": "0.7.22", "description": "Type-safe and zero-runtime UI styling, right in the markup.", "license": "MIT", "repository": { From e7b1d30f502677c02a5ce65c42983bb7d66db466 Mon Sep 17 00:00:00 2001 From: "Chabib N." Date: Mon, 15 Jun 2026 18:18:57 +0700 Subject: [PATCH 5/5] build: extract --- etc/vicinage.api.md | 5 +++++ src/index.ts | 3 +++ 2 files changed, 8 insertions(+) diff --git a/etc/vicinage.api.md b/etc/vicinage.api.md index 407c74e..a0bcd62 100644 --- a/etc/vicinage.api.md +++ b/etc/vicinage.api.md @@ -24,6 +24,11 @@ export const sheet: (...styledeck: T) => T; // @public (undocumented) export type StyleDeck = StyleDeck[] | ~StyleCard | readonly [~StyleCard, InlineStyles] | Theme> | ~NonApplicableThemeProperties | ~NonApplicableObjectProperties | ~NonApplicableSymbolProperties | undefined; +// @internal (undocumented) +export function ~attrs(this: unknown, ...styles: any[]): ReturnType<(typeof stylex)['attrs']> extends infer T ? { + [Key in keyof T]: T[Key] | undefined; +} : never; + // @internal (undocumented) export type ~CommonProperties = Properties & Omit; diff --git a/src/index.ts b/src/index.ts index 1298697..164560f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -84,6 +84,9 @@ function mergeClassProperty( } } +/** + * @internal + */ function attrs( this: unknown, // eslint-disable-next-line @typescript-eslint/no-explicit-any