Skip to content

Commit 5f0a667

Browse files
author
Cem Yılmaz
committed
Fixing things for library publishing..
1 parent 8c667dc commit 5f0a667

File tree

7 files changed

+170
-27
lines changed

7 files changed

+170
-27
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
</head>
88
<body style="background: black">
99
<div id="app"></div>
10-
<script type="module" src="/src/parse.ts"></script>
10+
<script type="module" src="/src/index.ts"></script>
1111
</body>
1212
</html>

src/classname.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import type {AST} from "./parse.ts";
2+
import {functionalPlugins, getPluginsByNs, type Modifier, namedPlugins, type Variant} from "./plugins.ts";
3+
import {inferDataType} from "./utils/infer-data-type.ts";
4+
import {getTailwindTheme} from "./theme.ts";
5+
import {isColor} from "./utils/is-color.ts";
6+
import {decodeArbitraryValue} from "./utils/decodeArbitraryValue.ts";
7+
8+
export type AstDeclaration = {
9+
property: string
10+
value: string
11+
variants?: Variant[]
12+
modifiers?: Modifier[],
13+
important?: boolean
14+
negative?: boolean,
15+
}
16+
17+
export const classname = (ast: AstDeclaration): string => {
18+
const theme = getTailwindTheme()
19+
const important = ast.important ? "!" : ""
20+
let variants = ast.variants?.length ? buildVariants(ast.variants) : []
21+
22+
/**
23+
* output "sm:hover:lg:!" or "!" or ""
24+
*/
25+
const prefix = `${variants}${important}`
26+
const [namedPluginClassName, namedPluginClassPlugin] = [...namedPlugins.entries()].find(([,plugin]) => plugin.value === ast.value) || []
27+
if(namedPluginClassName){
28+
return `${prefix}${namedPluginClassName}`
29+
}
30+
31+
//color is special, we need to find if value is a color
32+
if(isColor(ast.value, theme)){
33+
console.log(decodeArbitraryValue(ast.value))
34+
return `${prefix}text-[${ast.value}]`
35+
}
36+
37+
/*
38+
const [functionalPluginClassName, matchedFunctionalPlugins] = [...functionalPlugins.entries()].find(([,plugin]) => plugin.value === ast.value) || []
39+
if(key){
40+
return `${prefix}${key}`
41+
}*/
42+
43+
return "dummy"
44+
}
45+
46+
const buildVariants = (variants: Variant[]): string => {
47+
const variantOrder: Variant["type"][] = ["media", 'system', "interaction", "pseudo", "content", "form", "state", "misc"]
48+
const _sortedVariants = variants.sort((a, b) => variantOrder.indexOf(a.type) - variantOrder.indexOf(b.type))
49+
return _sortedVariants.length > 0 ? _sortedVariants.map(x => x.value).join(':') + ':' : ''
50+
}

src/index.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
1-
export * from "./parse"
1+
import {parse} from "./parse.ts";
2+
import {classname} from "./classname.ts";
3+
4+
console.log(parse("sm:!flex"))
5+
console.log(parse("lg:hover:bg-red-500/50"))
6+
7+
8+
console.log(classname({
9+
property: "display",
10+
value: "flex",
11+
variants: [
12+
{
13+
"kind": "named",
14+
"type": "interaction",
15+
"value": "hover"
16+
},
17+
{
18+
"kind": "named",
19+
"type": "media",
20+
"value": "sm"
21+
}
22+
],
23+
}))
24+
console.log(classname({
25+
property: "flexGrow",
26+
value: "0",
27+
variants: [
28+
{
29+
"kind": "named",
30+
"type": "interaction",
31+
"value": "hover"
32+
},
33+
{
34+
"kind": "named",
35+
"type": "media",
36+
"value": "sm"
37+
}
38+
],
39+
}))
40+
41+
console.log(classname({
42+
property: "backgroundColor",
43+
value: "#ff0000",
44+
}))
45+
46+
export {parse, classname}

src/parse.ts

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {segment} from "./utils/segment";
22
import {findRoot} from "./find-root";
3-
import {functionalPlugins, namedPlugins, type Variant} from "./plugins";
3+
import {functionalPlugins, type Modifier, namedPlugins, type Variant} from "./plugins";
44
import {parseVariant} from "./parse-variant";
55
import {inferDataType} from "./utils/infer-data-type.ts";
6-
import {getValue} from "./utils/value.ts";
6+
import {getValue, type Value} from "./utils/value.ts";
77
import {PluginNotFoundException} from "./exceptions/plugin-not-found-exception.ts";
88
import {decodeArbitraryValue} from "./utils/decodeArbitraryValue.ts";
99
import type {CustomThemeConfig, ScreensConfig} from "tailwindcss/types/config";
@@ -15,7 +15,19 @@ export type State = {
1515
negative: boolean
1616
}
1717

18-
export const parse = (input: string, config?: CustomThemeConfig) => {
18+
export type AST = {
19+
root: string
20+
kind: "named" | "functional"
21+
property: string
22+
value: Value
23+
variants: Variant[]
24+
modifiers: Modifier[],
25+
important: boolean
26+
negative: boolean,
27+
arbitrary: boolean
28+
}
29+
30+
export const parse = (input: string, config?: CustomThemeConfig): AST => {
1931
const theme = getTailwindTheme(config)
2032
let state: State = {
2133
important: false,
@@ -28,8 +40,8 @@ export const parse = (input: string, config?: CustomThemeConfig) => {
2840

2941
for (let i = variants.length - 1; i >= 0; --i) {
3042
let parsedVariant = parseVariant(variants[i], theme.screens as ScreensConfig)
31-
if (parsedVariant === null) return null
32-
parsedCandidateVariants.push(parsedVariant)
43+
if (parsedVariant !== null)
44+
parsedCandidateVariants.push(parsedVariant)
3345
}
3446

3547
if (base[0] === '!') {
@@ -46,16 +58,19 @@ export const parse = (input: string, config?: CustomThemeConfig) => {
4658
if (namedPlugin) {
4759
return {
4860
root: base,
49-
kind: "static",
61+
kind: "named",
5062
property: namedPlugin!.ns,
5163
value: {
5264
class: namedPlugin.class,
5365
raw: base,
66+
kind: "named",
5467
value: namedPlugin.value,
5568
},
56-
modifier: parsedCandidateVariants,
69+
variants: parsedCandidateVariants,
70+
modifiers: [],
5771
important: state.important,
58-
negative: state.negative
72+
negative: state.negative,
73+
arbitrary: false
5974
}
6075
}
6176

@@ -77,14 +92,16 @@ export const parse = (input: string, config?: CustomThemeConfig) => {
7792

7893
return {
7994
root: root,
95+
kind: "functional",
8096
property: associatedPluginByType!.ns,
8197
value: {
8298
value: arbitraryValue,
8399
class: associatedPluginByType!.class,
84100
raw: value,
85-
type: unitType
101+
kind: unitType || "named"
86102
},
87-
modifier: parsedCandidateVariants,
103+
variants: parsedCandidateVariants,
104+
modifiers: [],
88105
arbitrary: true,
89106
important: state.important,
90107
negative: state.negative
@@ -95,27 +112,26 @@ export const parse = (input: string, config?: CustomThemeConfig) => {
95112
let isValueColor = isColor(value, theme)
96113

97114
//we need to remove modifier from value
115+
const modifiers: Modifier[] = []
98116
if (value && isValueColor) {
99117
let [valueWithoutModifier, modifierSegment = null] = segment(value, '/')
100118
value = valueWithoutModifier
101119
if (modifierSegment) {
102120
if (modifierSegment[0] === '[' && modifierSegment[modifierSegment.length - 1] === ']') {
103-
parsedCandidateVariants.push({
121+
modifiers.push({
104122
kind: 'arbitrary',
105-
type: "opacity",
106123
value: decodeArbitraryValue(modifierSegment.slice(1, -1)),
107124
})
108125
} else {
109-
parsedCandidateVariants.push({
126+
modifiers.push({
110127
kind: 'named',
111-
type: "opacity",
112128
value: modifierSegment,
113129
})
114130
}
115131
}
116132
}
117133

118-
if(!value){
134+
if (!value) {
119135
value = 'DEFAULT'
120136
}
121137
//check value against each scale of available plugins
@@ -126,10 +142,13 @@ export const parse = (input: string, config?: CustomThemeConfig) => {
126142

127143
return {
128144
root: root,
145+
kind: "functional",
129146
property: matchedPlugin.ns,
130147
value: getValue(value, matchedPlugin, theme[matchedPlugin.scaleKey]),
131-
modifier: parsedCandidateVariants,
148+
variants: parsedCandidateVariants,
149+
modifiers: modifiers,
132150
important: state.important,
133-
negative: state.negative
151+
negative: state.negative,
152+
arbitrary: false,
134153
}
135154
}

src/plugins.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import type {DataType} from "./utils/infer-data-type";
22

33
export type Variant = {
44
kind: 'arbitrary' | 'named',
5-
type: 'opacity' | 'media' | 'pseudo' | 'content' | 'form' | 'state' | 'interaction' | 'misc'
5+
type: 'opacity' | 'media' | 'pseudo' | 'content' | 'form' | 'state' | 'interaction' | 'misc' | 'system'
6+
value: string
7+
}
8+
9+
export type Modifier = {
10+
kind: 'arbitrary' | 'named',
611
value: string
712
}
813

@@ -14,7 +19,7 @@ export type FunctionalPlugin = {
1419
supportNegative?: boolean
1520
}
1621

17-
export type NamedPlugin ={
22+
export type NamedPlugin = {
1823
value: string
1924
class: string[],
2025
ns: string,
@@ -366,4 +371,25 @@ export const variants = new Map<string, Variant["type"]>([
366371
['active', 'interaction'],
367372
['enabled', 'interaction'],
368373
['disabled', 'interaction'],
369-
])
374+
375+
['dark', 'system']
376+
])
377+
378+
export const getPluginsByNs = (ns: string, pluginMap: Map<string, NamedPlugin | FunctionalPlugin>) => {
379+
const filteredMap = new Map()
380+
for(const [key, value] of Object.entries(pluginMap)) {
381+
console.log(value)
382+
383+
if(Array.isArray(value)){
384+
for(const plugin of value){
385+
if(plugin.ns === ns) {
386+
filteredMap.set(key, plugin)
387+
}
388+
}
389+
}else if(value.ns === ns) {
390+
filteredMap.set(key, value)
391+
}
392+
}
393+
394+
return filteredMap
395+
}

src/utils/infer-data-type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type DataType =
1818
| 'relative-size'
1919
| 'angle'
2020
| 'vector'
21+
| 'named'
2122

2223
const checks: Record<DataType, (value: string) => boolean> = {
2324
color: isColor,
@@ -35,6 +36,7 @@ const checks: Record<DataType, (value: string) => boolean> = {
3536
'relative-size': isRelativeSize,
3637
angle: isAngle,
3738
vector: isVector,
39+
named: () => true
3840
}
3941

4042
/**

src/utils/is-color.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,12 @@ const IS_COLOR_FN = /^(rgba?|hsla?|hwb|color|(ok)?(lab|lch)|light-dark|color-mix
203203
export function isColor(value: string, theme?: CustomThemeConfig): boolean {
204204
if (!value) return false
205205

206-
const isThemeColor =
207-
theme &&
208-
!!segment(value, "/")?.[0]
209-
.split("-")
210-
.reduce((acc, val) => acc[val], theme.colors as any);
206+
let isThemeColor = false
207+
208+
if (theme) {
209+
const [trueValue,] = segment(value, '/')
210+
isThemeColor = !!trueValue.split('-').reduce((acc, val) => acc[val], theme.colors as any);
211+
}
211212

212213
return (
213214
value.charCodeAt(0) === HASH || IS_COLOR_FN.test(value) || NAMED_COLORS.has(value.toLowerCase()) || isThemeColor

0 commit comments

Comments
 (0)