zyzz 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/Config.d.ts +1 -0
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Vars.d.ts +22 -15
- package/dist/Vars.d.ts.map +1 -1
- package/dist/Vars.js +26 -0
- package/dist/Vars.js.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +3 -0
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/internal/Configurations.d.ts.map +1 -1
- package/dist/compiler/internal/Configurations.js +3 -0
- package/dist/compiler/internal/Configurations.js.map +1 -1
- package/dist/compiler/internal/Contract.d.ts.map +1 -1
- package/dist/compiler/internal/Contract.js +30 -4
- package/dist/compiler/internal/Contract.js.map +1 -1
- package/dist/compiler/internal/Themes.d.ts.map +1 -1
- package/dist/compiler/internal/Themes.js +83 -23
- package/dist/compiler/internal/Themes.js.map +1 -1
- package/dist/default.d.ts +7 -11
- package/dist/default.d.ts.map +1 -1
- package/dist/default.js +4 -5
- package/dist/default.js.map +2 -2
- package/dist/default.js.zyzz.json +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/Token.d.ts +11 -2
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +2 -0
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/VariableSets.d.ts.map +1 -1
- package/dist/internal/VariableSets.js +18 -1
- package/dist/internal/VariableSets.js.map +1 -1
- package/dist/node/Host.d.ts +2 -0
- package/dist/node/Host.d.ts.map +1 -1
- package/dist/node/Host.js +7 -0
- package/dist/node/Host.js.map +1 -1
- package/dist/oxlint/index.d.ts +6 -0
- package/dist/oxlint/index.d.ts.map +1 -0
- package/dist/oxlint/index.js +18 -0
- package/dist/oxlint/index.js.map +1 -0
- package/dist/oxlint/internal/Bindings.d.ts +20 -0
- package/dist/oxlint/internal/Bindings.d.ts.map +1 -0
- package/dist/oxlint/internal/Bindings.js +203 -0
- package/dist/oxlint/internal/Bindings.js.map +1 -0
- package/dist/oxlint/internal/Declarations.d.ts +19 -0
- package/dist/oxlint/internal/Declarations.d.ts.map +1 -0
- package/dist/oxlint/internal/Declarations.js +114 -0
- package/dist/oxlint/internal/Declarations.js.map +1 -0
- package/dist/oxlint/rules/noConflictingProps.d.ts +5 -0
- package/dist/oxlint/rules/noConflictingProps.d.ts.map +1 -0
- package/dist/oxlint/rules/noConflictingProps.js +45 -0
- package/dist/oxlint/rules/noConflictingProps.js.map +1 -0
- package/dist/oxlint/rules/noUnused.d.ts +5 -0
- package/dist/oxlint/rules/noUnused.d.ts.map +1 -0
- package/dist/oxlint/rules/noUnused.js +62 -0
- package/dist/oxlint/rules/noUnused.js.map +1 -0
- package/dist/oxlint/rules/restrictedProperties.d.ts +5 -0
- package/dist/oxlint/rules/restrictedProperties.d.ts.map +1 -0
- package/dist/oxlint/rules/restrictedProperties.js +82 -0
- package/dist/oxlint/rules/restrictedProperties.js.map +1 -0
- package/dist/oxlint/rules/useLogicalProperties.d.ts +5 -0
- package/dist/oxlint/rules/useLogicalProperties.d.ts.map +1 -0
- package/dist/oxlint/rules/useLogicalProperties.js +76 -0
- package/dist/oxlint/rules/useLogicalProperties.js.map +1 -0
- package/dist/oxlint/rules/validStyles.d.ts +5 -0
- package/dist/oxlint/rules/validStyles.d.ts.map +1 -0
- package/dist/oxlint/rules/validStyles.js +75 -0
- package/dist/oxlint/rules/validStyles.js.map +1 -0
- package/dist/react-native/StyleSheet.js +2 -0
- package/dist/react-native/StyleSheet.js.map +1 -1
- package/dist/runtime/Composition.d.ts +1 -1
- package/dist/runtime/ConditionalRecipe.d.ts +1 -1
- package/dist/runtime/PayloadRecipe.d.ts +1 -1
- package/dist/runtime/Recipe.d.ts +1 -1
- package/dist/styleFunction.d.ts +1 -1
- package/dist/styleFunction.d.ts.map +1 -1
- package/dist/styleFunction.js.map +1 -1
- package/dist/variants.d.ts +14 -6
- package/dist/variants.d.ts.map +1 -1
- package/dist/variants.js.map +1 -1
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +75 -30
- package/dist/vite/index.js.map +1 -1
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +4 -0
- package/dist/web/internal/Themes.js.map +1 -1
- package/package.json +7 -1
- package/src/Config.ts +5 -0
- package/src/Vars.ts +88 -29
- package/src/cli/index.ts +5 -0
- package/src/compiler/Source.ts +3 -0
- package/src/compiler/internal/Configurations.ts +3 -0
- package/src/compiler/internal/Contract.ts +47 -4
- package/src/compiler/internal/Themes.ts +109 -34
- package/src/default.ts +8 -10
- package/src/index.ts +15 -0
- package/src/internal/Authoring.ts +1 -1
- package/src/internal/Token.ts +39 -11
- package/src/internal/VariableSets.ts +25 -1
- package/src/node/Host.ts +19 -0
- package/src/oxlint/index.ts +21 -0
- package/src/oxlint/internal/Bindings.ts +270 -0
- package/src/oxlint/internal/Declarations.ts +137 -0
- package/src/oxlint/rules/noConflictingProps.ts +52 -0
- package/src/oxlint/rules/noUnused.ts +67 -0
- package/src/oxlint/rules/restrictedProperties.ts +92 -0
- package/src/oxlint/rules/useLogicalProperties.ts +81 -0
- package/src/oxlint/rules/validStyles.ts +88 -0
- package/src/react-native/StyleSheet.ts +6 -0
- package/src/styleFunction.ts +1 -3
- package/src/variants.ts +38 -16
- package/src/vite/index.ts +94 -33
- package/src/web/internal/Themes.ts +4 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Finds unused style members in local TypeScript namespaces. @module */
|
|
2
|
+
import type { ESTree, Rule } from '@oxlint/plugins'
|
|
3
|
+
import * as Bindings from '../internal/Bindings.js'
|
|
4
|
+
|
|
5
|
+
/** Leaves module exports and escaped namespaces available to unknown consumers. */
|
|
6
|
+
export const noUnused: Rule = {
|
|
7
|
+
meta: {
|
|
8
|
+
messages: { unused: "Style '{{name}}' is never used." },
|
|
9
|
+
schema: [],
|
|
10
|
+
type: 'suggestion',
|
|
11
|
+
},
|
|
12
|
+
create(context) {
|
|
13
|
+
const bindings = Bindings.create(context)
|
|
14
|
+
const declarations: ESTree.VariableDeclarator[] = []
|
|
15
|
+
return {
|
|
16
|
+
VariableDeclarator(node) {
|
|
17
|
+
if (
|
|
18
|
+
node.id.type === 'Identifier' &&
|
|
19
|
+
node.init &&
|
|
20
|
+
bindings.resolve(node.init)?.kind === 'definition'
|
|
21
|
+
)
|
|
22
|
+
declarations.push(node)
|
|
23
|
+
},
|
|
24
|
+
'Program:exit'() {
|
|
25
|
+
for (const declaration of declarations) {
|
|
26
|
+
if (declaration.id.type !== 'Identifier') continue
|
|
27
|
+
let parent: ESTree.Node = declaration.parent
|
|
28
|
+
while (
|
|
29
|
+
parent.type === 'VariableDeclaration' ||
|
|
30
|
+
parent.type === 'ExportNamedDeclaration'
|
|
31
|
+
)
|
|
32
|
+
parent = parent.parent
|
|
33
|
+
if (
|
|
34
|
+
parent.type !== 'TSModuleBlock' ||
|
|
35
|
+
parent.parent.type !== 'TSModuleDeclaration'
|
|
36
|
+
)
|
|
37
|
+
continue
|
|
38
|
+
const namespace = parent.parent
|
|
39
|
+
if (namespace.id.type !== 'Identifier') continue
|
|
40
|
+
// Nested and exported namespaces may have consumers outside this local scope.
|
|
41
|
+
if (namespace.parent.type !== 'Program') continue
|
|
42
|
+
const variable = bindings.variable(declaration.id)
|
|
43
|
+
const owner = bindings.variable(namespace.id)
|
|
44
|
+
if (!variable || !owner || owner.defs.length !== 1) continue
|
|
45
|
+
if (variable.references.some((reference) => reference.isRead()))
|
|
46
|
+
continue
|
|
47
|
+
const used = owner.references.some((reference) => {
|
|
48
|
+
if (!reference.isRead()) return false
|
|
49
|
+
const member = reference.identifier.parent
|
|
50
|
+
return (
|
|
51
|
+
member.type !== 'MemberExpression' ||
|
|
52
|
+
member.object !== reference.identifier ||
|
|
53
|
+
Bindings.key(member) === undefined ||
|
|
54
|
+
Bindings.key(member) === variable.name
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
if (!used)
|
|
58
|
+
context.report({
|
|
59
|
+
data: { name: `${namespace.id.name}.${variable.name}` },
|
|
60
|
+
messageId: 'unused',
|
|
61
|
+
node: declaration.id,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** Applies explicit project restrictions to known web declarations. @module */
|
|
2
|
+
import type { Rule } from '@oxlint/plugins'
|
|
3
|
+
import * as Bindings from '../internal/Bindings.js'
|
|
4
|
+
import * as Declarations from '../internal/Declarations.js'
|
|
5
|
+
|
|
6
|
+
/** Reports forbidden properties or literal values outside an explicit allowlist. */
|
|
7
|
+
export const restrictedProperties: Rule = {
|
|
8
|
+
meta: {
|
|
9
|
+
messages: {
|
|
10
|
+
restricted: "Property '{{property}}' is restricted. {{reason}}",
|
|
11
|
+
},
|
|
12
|
+
schema: [
|
|
13
|
+
{
|
|
14
|
+
additionalProperties: {
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
reason: { type: 'string' },
|
|
18
|
+
values: { items: { type: ['string', 'number'] }, type: 'array' },
|
|
19
|
+
},
|
|
20
|
+
type: 'object',
|
|
21
|
+
},
|
|
22
|
+
type: 'object',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
type: 'suggestion',
|
|
26
|
+
},
|
|
27
|
+
create(context) {
|
|
28
|
+
const bindings = Bindings.create(context)
|
|
29
|
+
const restrictions = context.options[0]
|
|
30
|
+
const reported = new Set<number>()
|
|
31
|
+
return {
|
|
32
|
+
CallExpression(node) {
|
|
33
|
+
if (
|
|
34
|
+
!restrictions ||
|
|
35
|
+
typeof restrictions !== 'object' ||
|
|
36
|
+
Array.isArray(restrictions)
|
|
37
|
+
)
|
|
38
|
+
return
|
|
39
|
+
const binding = bindings.resolve(node.callee)
|
|
40
|
+
if (binding?.kind !== 'style' && binding?.kind !== 'variants') return
|
|
41
|
+
const input = node.arguments[0]
|
|
42
|
+
if (!input || input.type === 'SpreadElement') return
|
|
43
|
+
Declarations.visit(input, {
|
|
44
|
+
bindings,
|
|
45
|
+
recipe: binding.kind === 'variants',
|
|
46
|
+
visitors: {
|
|
47
|
+
declaration(property, name) {
|
|
48
|
+
if (
|
|
49
|
+
!Object.hasOwn(restrictions, name) ||
|
|
50
|
+
reported.has(property.start)
|
|
51
|
+
)
|
|
52
|
+
return
|
|
53
|
+
const restriction = restrictions[name]
|
|
54
|
+
if (
|
|
55
|
+
!restriction ||
|
|
56
|
+
typeof restriction !== 'object' ||
|
|
57
|
+
Array.isArray(restriction)
|
|
58
|
+
)
|
|
59
|
+
return
|
|
60
|
+
const allowed = restriction.values
|
|
61
|
+
if (Array.isArray(allowed)) {
|
|
62
|
+
const literal = Declarations.literal(property.value, bindings)
|
|
63
|
+
if (!literal) return
|
|
64
|
+
const values: unknown[] = Array.isArray(literal.value)
|
|
65
|
+
? literal.value
|
|
66
|
+
: [literal.value]
|
|
67
|
+
if (
|
|
68
|
+
values.every((value) =>
|
|
69
|
+
allowed.some((allowed) => allowed === value),
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
reported.add(property.start)
|
|
75
|
+
context.report({
|
|
76
|
+
data: {
|
|
77
|
+
property: name,
|
|
78
|
+
reason:
|
|
79
|
+
typeof restriction.reason === 'string'
|
|
80
|
+
? restriction.reason
|
|
81
|
+
: 'Use an approved property or value.',
|
|
82
|
+
},
|
|
83
|
+
messageId: 'restricted',
|
|
84
|
+
node: property.key,
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Encourages logical CSS properties in web style declarations. @module */
|
|
2
|
+
import type { Rule } from '@oxlint/plugins'
|
|
3
|
+
import * as Bindings from '../internal/Bindings.js'
|
|
4
|
+
import * as Declarations from '../internal/Declarations.js'
|
|
5
|
+
|
|
6
|
+
const replacements: Readonly<Record<string, string>> = {
|
|
7
|
+
borderBottomLeftRadius: 'borderEndStartRadius',
|
|
8
|
+
borderBottomRightRadius: 'borderEndEndRadius',
|
|
9
|
+
borderLeft: 'borderInlineStart',
|
|
10
|
+
borderLeftColor: 'borderInlineStartColor',
|
|
11
|
+
borderLeftStyle: 'borderInlineStartStyle',
|
|
12
|
+
borderLeftWidth: 'borderInlineStartWidth',
|
|
13
|
+
borderRight: 'borderInlineEnd',
|
|
14
|
+
borderRightColor: 'borderInlineEndColor',
|
|
15
|
+
borderRightStyle: 'borderInlineEndStyle',
|
|
16
|
+
borderRightWidth: 'borderInlineEndWidth',
|
|
17
|
+
borderTopLeftRadius: 'borderStartStartRadius',
|
|
18
|
+
borderTopRightRadius: 'borderStartEndRadius',
|
|
19
|
+
insetLeft: 'insetInlineStart',
|
|
20
|
+
insetRight: 'insetInlineEnd',
|
|
21
|
+
left: 'insetInlineStart',
|
|
22
|
+
marginLeft: 'marginInlineStart',
|
|
23
|
+
marginRight: 'marginInlineEnd',
|
|
24
|
+
paddingLeft: 'paddingInlineStart',
|
|
25
|
+
paddingRight: 'paddingInlineEnd',
|
|
26
|
+
right: 'insetInlineEnd',
|
|
27
|
+
scrollMarginLeft: 'scrollMarginInlineStart',
|
|
28
|
+
scrollMarginRight: 'scrollMarginInlineEnd',
|
|
29
|
+
scrollPaddingLeft: 'scrollPaddingInlineStart',
|
|
30
|
+
scrollPaddingRight: 'scrollPaddingInlineEnd',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Reports physical properties without changing direction-dependent behavior. */
|
|
34
|
+
export const useLogicalProperties: Rule = {
|
|
35
|
+
meta: {
|
|
36
|
+
messages: {
|
|
37
|
+
logical:
|
|
38
|
+
"Use a CSS logical property instead of '{{property}}', such as '{{replacement}}' for horizontal LTR layouts.",
|
|
39
|
+
},
|
|
40
|
+
schema: [],
|
|
41
|
+
type: 'suggestion',
|
|
42
|
+
},
|
|
43
|
+
create(context) {
|
|
44
|
+
const bindings = Bindings.create(context)
|
|
45
|
+
const reported = new Set<number>()
|
|
46
|
+
return {
|
|
47
|
+
CallExpression(node) {
|
|
48
|
+
const binding = bindings.resolve(node.callee)
|
|
49
|
+
if (binding?.kind !== 'style' && binding?.kind !== 'variants') return
|
|
50
|
+
const input = node.arguments[0]
|
|
51
|
+
if (!input || input.type === 'SpreadElement') return
|
|
52
|
+
Declarations.visit(input, {
|
|
53
|
+
bindings,
|
|
54
|
+
recipe: binding.kind === 'variants',
|
|
55
|
+
visitors: {
|
|
56
|
+
declaration(property, name) {
|
|
57
|
+
const replacement = Object.hasOwn(replacements, name)
|
|
58
|
+
? replacements[name]
|
|
59
|
+
: undefined
|
|
60
|
+
if (!replacement || reported.has(property.start)) return
|
|
61
|
+
if (
|
|
62
|
+
context.sourceCode
|
|
63
|
+
.getCommentsBefore(property)
|
|
64
|
+
.some((comment) =>
|
|
65
|
+
comment.value.includes('allow-physical-property'),
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
return
|
|
69
|
+
reported.add(property.start)
|
|
70
|
+
context.report({
|
|
71
|
+
data: { property: name, replacement },
|
|
72
|
+
messageId: 'logical',
|
|
73
|
+
node: property.key,
|
|
74
|
+
})
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Reports statically known declaration errors using Zyzz's authoring validation. @module */
|
|
2
|
+
import type { ESTree, Rule } from '@oxlint/plugins'
|
|
3
|
+
import * as Bindings from '../internal/Bindings.js'
|
|
4
|
+
import * as Declarations from '../internal/Declarations.js'
|
|
5
|
+
import * as Literal from '../../internal/Literal.js'
|
|
6
|
+
import * as Style from '../../Style.js'
|
|
7
|
+
|
|
8
|
+
/** Validates known structure and values while leaving unresolved bindings to the compiler. */
|
|
9
|
+
export const validStyles: Rule = {
|
|
10
|
+
meta: { messages: { invalid: '{{message}}' }, schema: [], type: 'problem' },
|
|
11
|
+
create(context) {
|
|
12
|
+
const bindings = Bindings.create(context)
|
|
13
|
+
const reported = new Set<number>()
|
|
14
|
+
function report(node: ESTree.Node, message: string) {
|
|
15
|
+
if (reported.has(node.start)) return
|
|
16
|
+
reported.add(node.start)
|
|
17
|
+
context.report({ data: { message }, messageId: 'invalid', node })
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
CallExpression(node) {
|
|
21
|
+
const binding = bindings.resolve(node.callee)
|
|
22
|
+
if (binding?.kind !== 'style' && binding?.kind !== 'variants') return
|
|
23
|
+
const input = node.arguments[0]
|
|
24
|
+
if (!input || input.type === 'SpreadElement') return
|
|
25
|
+
Declarations.visit(input, {
|
|
26
|
+
bindings,
|
|
27
|
+
recipe: binding.kind === 'variants',
|
|
28
|
+
visitors: {
|
|
29
|
+
declaration(property, name) {
|
|
30
|
+
if (binding.themed && name === 'typography') return
|
|
31
|
+
if (
|
|
32
|
+
!binding.themed &&
|
|
33
|
+
!name.startsWith('--') &&
|
|
34
|
+
!Object.hasOwn(Literal.rules, name)
|
|
35
|
+
) {
|
|
36
|
+
report(property.key, `Unknown CSS property '${name}'.`)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
const value = bindings.expression(property.value)
|
|
40
|
+
if (value.type === 'ObjectExpression') {
|
|
41
|
+
report(
|
|
42
|
+
value,
|
|
43
|
+
'CSS declarations require scalar values or fallback arrays.',
|
|
44
|
+
)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if (
|
|
48
|
+
value.type === 'ArrayExpression' &&
|
|
49
|
+
value.elements.some((element) => !element)
|
|
50
|
+
) {
|
|
51
|
+
report(
|
|
52
|
+
value,
|
|
53
|
+
'Fallback arrays require dense data entries without holes.',
|
|
54
|
+
)
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
const literal = Declarations.literal(value, bindings)
|
|
58
|
+
if (!literal) return
|
|
59
|
+
const values = Array.isArray(literal.value)
|
|
60
|
+
? literal.value
|
|
61
|
+
: [literal.value]
|
|
62
|
+
if (
|
|
63
|
+
values.some(
|
|
64
|
+
(value) =>
|
|
65
|
+
typeof value !== 'string' && typeof value !== 'number',
|
|
66
|
+
)
|
|
67
|
+
) {
|
|
68
|
+
report(
|
|
69
|
+
value,
|
|
70
|
+
'CSS declarations require string or number values.',
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
Style.define({ lint: { [name]: literal.value } } as never)
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (!(error instanceof Style.InvalidError)) throw error
|
|
78
|
+
for (const diagnostic of error.diagnostics)
|
|
79
|
+
report(value, diagnostic.message)
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
invalid: report,
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
}
|
|
@@ -785,6 +785,12 @@ function resolve(
|
|
|
785
785
|
resolved = resolved.value
|
|
786
786
|
continue
|
|
787
787
|
}
|
|
788
|
+
if (Token.isExpression(resolved))
|
|
789
|
+
fail(
|
|
790
|
+
'unsupported_feature',
|
|
791
|
+
'Composed variables require a web target.',
|
|
792
|
+
path,
|
|
793
|
+
)
|
|
788
794
|
if ('default' in resolved)
|
|
789
795
|
fail(
|
|
790
796
|
'unsupported_feature',
|
package/src/styleFunction.ts
CHANGED
|
@@ -114,9 +114,7 @@ export declare namespace style {
|
|
|
114
114
|
/** Compiled and supplied class names. */
|
|
115
115
|
readonly className: string
|
|
116
116
|
/** Supplied inline styling overrides when present. */
|
|
117
|
-
readonly style?:
|
|
118
|
-
| Readonly<Record<string, string | number | undefined>>
|
|
119
|
-
| undefined
|
|
117
|
+
readonly style?: Readonly<Record<string, string | number | undefined>>
|
|
120
118
|
}
|
|
121
119
|
|
|
122
120
|
/** Callable definition; source rewriting supplies its implementation. */
|
package/src/variants.ts
CHANGED
|
@@ -61,32 +61,54 @@ type CheckedChoice<
|
|
|
61
61
|
: never)
|
|
62
62
|
: CheckedStyles<style, tokens, layers, mappings>
|
|
63
63
|
|
|
64
|
-
type SuggestedStyles<
|
|
65
|
-
|
|
64
|
+
type SuggestedStyles<
|
|
65
|
+
tokens extends Theme.Tokens,
|
|
66
|
+
styles = Record<string, unknown>,
|
|
67
|
+
> = Completion.Properties<tokens, styles> & Readonly<Record<string, unknown>>
|
|
66
68
|
|
|
67
69
|
/** Editor hints remain independent of declaration and selection validation. */
|
|
68
|
-
type Suggestions<
|
|
69
|
-
|
|
70
|
+
type Suggestions<
|
|
71
|
+
tokens extends Theme.Tokens,
|
|
72
|
+
definition = Record<string, unknown>,
|
|
73
|
+
> = {
|
|
74
|
+
readonly base?:
|
|
75
|
+
| SuggestedStyles<
|
|
76
|
+
tokens,
|
|
77
|
+
definition extends { base: infer styles }
|
|
78
|
+
? styles
|
|
79
|
+
: Record<string, unknown>
|
|
80
|
+
>
|
|
81
|
+
| undefined
|
|
70
82
|
readonly compoundVariants?:
|
|
71
83
|
| readonly {
|
|
72
84
|
readonly style: SuggestedStyles<tokens>
|
|
73
85
|
readonly when: unknown
|
|
74
86
|
}[]
|
|
75
87
|
| undefined
|
|
76
|
-
readonly variants?:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
readonly variants?: definition extends { variants: infer axes }
|
|
89
|
+
? {
|
|
90
|
+
readonly [axis in keyof axes]: {
|
|
91
|
+
readonly [choice in keyof axes[axis]]: axes[axis][choice] extends (
|
|
92
|
+
...args: never[]
|
|
93
|
+
) => unknown
|
|
94
|
+
? (...args: never[]) => SuggestedStyles<tokens>
|
|
95
|
+
: SuggestedStyles<tokens, axes[axis][choice]>
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
:
|
|
99
|
+
| Readonly<
|
|
81
100
|
Record<
|
|
82
101
|
string,
|
|
83
|
-
|
|
84
|
-
|
|
102
|
+
Readonly<
|
|
103
|
+
Record<
|
|
104
|
+
string,
|
|
105
|
+
| SuggestedStyles<tokens>
|
|
106
|
+
| ((...args: never[]) => SuggestedStyles<tokens>)
|
|
107
|
+
>
|
|
108
|
+
>
|
|
85
109
|
>
|
|
86
110
|
>
|
|
87
|
-
|
|
88
|
-
>
|
|
89
|
-
| undefined
|
|
111
|
+
| undefined
|
|
90
112
|
}
|
|
91
113
|
|
|
92
114
|
type Keys<value> = value extends unknown ? keyof value : never
|
|
@@ -201,7 +223,7 @@ type Checked<
|
|
|
201
223
|
export function variants<const definition extends Record<string, unknown>>(
|
|
202
224
|
definition: definition &
|
|
203
225
|
NoInfer<Checked<definition, {}, never, {}>> &
|
|
204
|
-
Suggestions<{}
|
|
226
|
+
Suggestions<{}, NoInfer<definition>>,
|
|
205
227
|
options: style.DefinitionOptions = {},
|
|
206
228
|
): variants.ReturnType<definition> {
|
|
207
229
|
return Authoring.variants(
|
|
@@ -221,7 +243,7 @@ export declare namespace variants {
|
|
|
221
243
|
> = <const definition extends Record<string, unknown>>(
|
|
222
244
|
definition: definition &
|
|
223
245
|
NoInfer<Checked<definition, tokens, layers, mappings>> &
|
|
224
|
-
Suggestions<tokens
|
|
246
|
+
Suggestions<tokens, NoInfer<definition>>,
|
|
225
247
|
options?: style.DefinitionOptions,
|
|
226
248
|
) => ReturnType<definition, output>
|
|
227
249
|
|