zyzz 0.0.27 → 0.0.28
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/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +165 -11
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/Transform.d.ts.map +1 -1
- package/dist/compiler/Transform.js +3 -0
- package/dist/compiler/Transform.js.map +1 -1
- package/dist/compiler/internal/Applications.d.ts.map +1 -1
- package/dist/compiler/internal/Applications.js +42 -1
- package/dist/compiler/internal/Applications.js.map +1 -1
- package/dist/compiler/internal/Selectors.d.ts +3 -2
- package/dist/compiler/internal/Selectors.d.ts.map +1 -1
- package/dist/compiler/internal/Selectors.js +23 -11
- package/dist/compiler/internal/Selectors.js.map +1 -1
- package/dist/internal/Authoring.d.ts.map +1 -1
- package/dist/internal/Authoring.js +37 -7
- package/dist/internal/Authoring.js.map +1 -1
- package/dist/internal/Configuration.d.ts +6 -1
- package/dist/internal/Configuration.d.ts.map +1 -1
- package/dist/internal/Configuration.js.map +1 -1
- package/dist/internal/Literal.d.ts +1 -1
- package/dist/internal/Literal.d.ts.map +1 -1
- package/dist/internal/Literal.js +3 -0
- package/dist/internal/Literal.js.map +1 -1
- package/dist/internal/Theme.d.ts +4 -0
- package/dist/internal/Theme.d.ts.map +1 -1
- package/dist/internal/Theme.js.map +1 -1
- package/dist/styleFunction.d.ts +11 -2
- package/dist/styleFunction.d.ts.map +1 -1
- package/dist/styleFunction.js +3 -1
- package/dist/styleFunction.js.map +1 -1
- package/dist/vite/index.d.ts +7 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +173 -22
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/src/compiler/Source.ts +237 -13
- package/src/compiler/Transform.ts +4 -1
- package/src/compiler/internal/Applications.ts +57 -1
- package/src/compiler/internal/Selectors.ts +25 -11
- package/src/internal/Authoring.ts +53 -18
- package/src/internal/Configuration.ts +38 -1
- package/src/internal/Literal.ts +3 -0
- package/src/internal/Theme.ts +15 -0
- package/src/styleFunction.ts +31 -2
- package/src/vite/index.ts +242 -27
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Finds nonescaping local static callables whose applications can become props. @module */
|
|
2
2
|
import type * as Ast from '@oxc-project/types'
|
|
3
3
|
import * as Walker from 'oxc-walker'
|
|
4
|
+
import * as Expression from './Expression.js'
|
|
4
5
|
import * as Scope from './Scope.js'
|
|
5
6
|
import type * as Source from '../Source.js'
|
|
6
7
|
|
|
@@ -158,6 +159,8 @@ export function create(
|
|
|
158
159
|
if (!candidates.length) return undefined
|
|
159
160
|
|
|
160
161
|
const lexical = new Set<Ast.Node>()
|
|
162
|
+
// Extraction resolves these reads and rewrites their definitions, so none run.
|
|
163
|
+
const resolved = new Set<Ast.Node>()
|
|
161
164
|
// Reads inside functions, classes, or namespaces may run before initialization.
|
|
162
165
|
const deferred = new Set<Ast.Node>()
|
|
163
166
|
const terminals = new Set<Ast.Node>()
|
|
@@ -200,6 +203,7 @@ export function create(
|
|
|
200
203
|
) {
|
|
201
204
|
lexical.add(node)
|
|
202
205
|
if (terminal(ancestors)) terminals.add(node)
|
|
206
|
+
if (extracted(ancestors, definitions)) resolved.add(node)
|
|
203
207
|
if (
|
|
204
208
|
ancestors.some((node) =>
|
|
205
209
|
[
|
|
@@ -240,7 +244,7 @@ export function create(
|
|
|
240
244
|
const called = new Set<string>()
|
|
241
245
|
|
|
242
246
|
for (const reference of references.get(declaration.id.name) ?? []) {
|
|
243
|
-
if (reference === declaration.id) continue
|
|
247
|
+
if (reference === declaration.id || resolved.has(reference)) continue
|
|
244
248
|
|
|
245
249
|
let callee: Ast.Node = reference
|
|
246
250
|
let call = direct
|
|
@@ -492,6 +496,58 @@ export declare namespace create {
|
|
|
492
496
|
}
|
|
493
497
|
}
|
|
494
498
|
|
|
499
|
+
// Matches a selector interpolation or composition entry inside a definition, which
|
|
500
|
+
// extraction resolves statically. Computed keys elsewhere in a definition fail extraction.
|
|
501
|
+
function extracted(
|
|
502
|
+
path: readonly Ast.Node[],
|
|
503
|
+
definitions: ReadonlyMap<number, Source.Call>,
|
|
504
|
+
): boolean {
|
|
505
|
+
let index = path.length - 1
|
|
506
|
+
const member = path[index - 1]
|
|
507
|
+
if (
|
|
508
|
+
member?.type === 'MemberExpression' &&
|
|
509
|
+
member.object === path[index] &&
|
|
510
|
+
!member.computed
|
|
511
|
+
)
|
|
512
|
+
index--
|
|
513
|
+
|
|
514
|
+
// Type assertions around a node keep the same read.
|
|
515
|
+
function parent() {
|
|
516
|
+
const node = path[index]!
|
|
517
|
+
while (index > 0 && Expression.unwrap(path[index - 1]!) === node) index--
|
|
518
|
+
return path[--index]
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function definition(node: Ast.Node | undefined) {
|
|
522
|
+
return (
|
|
523
|
+
node?.type === 'CallExpression' &&
|
|
524
|
+
definitions.get(node.start)?.end === node.end
|
|
525
|
+
)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const container = parent()
|
|
529
|
+
|
|
530
|
+
if (container?.type === 'ArrayExpression') {
|
|
531
|
+
const call = parent()
|
|
532
|
+
return (
|
|
533
|
+
call?.type === 'CallExpression' &&
|
|
534
|
+
definition(call) &&
|
|
535
|
+
!!call.arguments[0] &&
|
|
536
|
+
Expression.unwrap(call.arguments[0]) === container
|
|
537
|
+
)
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (container?.type !== 'TemplateLiteral') return false
|
|
541
|
+
|
|
542
|
+
const property = parent()
|
|
543
|
+
return (
|
|
544
|
+
property?.type === 'Property' &&
|
|
545
|
+
property.computed &&
|
|
546
|
+
Expression.unwrap(property.key) === container &&
|
|
547
|
+
path.slice(0, index).some(definition)
|
|
548
|
+
)
|
|
549
|
+
}
|
|
550
|
+
|
|
495
551
|
// Matches a no-argument application spread onto, or read as the class of, a DOM element.
|
|
496
552
|
function terminal(path: readonly Ast.Node[]): boolean {
|
|
497
553
|
let index = path.length - 1
|
|
@@ -11,7 +11,7 @@ import * as Expression from './Expression.js'
|
|
|
11
11
|
import type * as Scope from './Scope.js'
|
|
12
12
|
import * as Themes from './Themes.js'
|
|
13
13
|
|
|
14
|
-
/** Collects scoped selectors, local identities,
|
|
14
|
+
/** Collects scoped selectors, local identities, exported style references, and composed definitions. */
|
|
15
15
|
export function scan(
|
|
16
16
|
program: Ast.Program,
|
|
17
17
|
scope: Scope.Tracker,
|
|
@@ -21,6 +21,7 @@ export function scan(
|
|
|
21
21
|
selectorKeys: ReadonlySet<number> = new Set(),
|
|
22
22
|
cssNamespaces: ReadonlyMap<number, string> = new Map(),
|
|
23
23
|
moduleId = namespace,
|
|
24
|
+
composed: readonly Ast.Node[] = [],
|
|
24
25
|
) {
|
|
25
26
|
const authoredNames = Names.collect(program)
|
|
26
27
|
const conditions = new Map<number, string>()
|
|
@@ -33,6 +34,7 @@ export function scan(
|
|
|
33
34
|
const namespaces = new Map<number, Map<string, Ast.Expression>>()
|
|
34
35
|
const importedNames = new Map<string, Themes.Link>()
|
|
35
36
|
const imported = new Map<number, Themes.Link>()
|
|
37
|
+
const compositions = new Map<number, Ast.CallExpression | Themes.Link>()
|
|
36
38
|
|
|
37
39
|
const names = new Map<string, Ast.Expression>()
|
|
38
40
|
const publicNames = new Map<string, string>()
|
|
@@ -122,7 +124,7 @@ export function scan(
|
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
if (!calls.length && !imported.size)
|
|
125
|
-
return { conditions, exports, identities, localConditions }
|
|
127
|
+
return { compositions, conditions, exports, identities, localConditions }
|
|
126
128
|
|
|
127
129
|
const exposed = new Map<Ast.Expression, readonly (readonly string[])[]>()
|
|
128
130
|
for (const [name, local] of publicNames) {
|
|
@@ -138,8 +140,8 @@ export function scan(
|
|
|
138
140
|
for (const [member, value] of values)
|
|
139
141
|
exposed.set(value, [...(exposed.get(value) ?? []), [name, member]])
|
|
140
142
|
|
|
141
|
-
if (!selectorKeys.size && !exposed.size)
|
|
142
|
-
return { conditions, exports, identities, localConditions }
|
|
143
|
+
if (!selectorKeys.size && !exposed.size && !composed.length)
|
|
144
|
+
return { compositions, conditions, exports, identities, localConditions }
|
|
143
145
|
|
|
144
146
|
type Entry = { node: Ast.Node; parent: Ast.Node | null | undefined }
|
|
145
147
|
const nodes: Entry[] = []
|
|
@@ -179,10 +181,11 @@ export function scan(
|
|
|
179
181
|
}
|
|
180
182
|
}
|
|
181
183
|
|
|
182
|
-
|
|
184
|
+
// Composition reads the definition itself, so only selector references claim an identity.
|
|
185
|
+
function target(
|
|
183
186
|
node: Ast.Node,
|
|
184
187
|
seen = new Set<Ast.Node>(),
|
|
185
|
-
): Themes.Link | undefined {
|
|
188
|
+
): Ast.CallExpression | Themes.Link | undefined {
|
|
186
189
|
node = Expression.unwrap(node)
|
|
187
190
|
if (seen.has(node)) return undefined
|
|
188
191
|
seen.add(node)
|
|
@@ -191,7 +194,7 @@ export function scan(
|
|
|
191
194
|
node.type === 'CallExpression' &&
|
|
192
195
|
definitions.get(node.start)?.end === node.end
|
|
193
196
|
)
|
|
194
|
-
return
|
|
197
|
+
return node
|
|
195
198
|
|
|
196
199
|
if (node.type === 'Identifier') {
|
|
197
200
|
const declaration = declarations.get(node.start)
|
|
@@ -199,7 +202,7 @@ export function scan(
|
|
|
199
202
|
const external = imported.get(declaration)
|
|
200
203
|
if (external) return external
|
|
201
204
|
const value = bindings.get(declaration)
|
|
202
|
-
return value ?
|
|
205
|
+
return value ? target(value, seen) : undefined
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
if (node.type === 'MemberExpression' && !node.optional) {
|
|
@@ -221,14 +224,25 @@ export function scan(
|
|
|
221
224
|
declaration === undefined
|
|
222
225
|
? undefined
|
|
223
226
|
: namespaces.get(declaration)?.get(name)
|
|
224
|
-
if (value) return
|
|
227
|
+
if (value) return target(value, seen)
|
|
225
228
|
}
|
|
226
|
-
|
|
229
|
+
const object = target(node.object, seen)
|
|
230
|
+
return object && !('type' in object) ? object.members?.[name] : undefined
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
return undefined
|
|
230
234
|
}
|
|
231
235
|
|
|
236
|
+
function resolve(node: Ast.Node): Themes.Link | undefined {
|
|
237
|
+
const value = target(node)
|
|
238
|
+
return value && 'type' in value ? link(value) : value
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for (const node of composed) {
|
|
242
|
+
const value = target(node)
|
|
243
|
+
if (value) compositions.set(node.start, value)
|
|
244
|
+
}
|
|
245
|
+
|
|
232
246
|
for (const { node } of nodes) {
|
|
233
247
|
if (node.type === 'VariableDeclarator' && node.init)
|
|
234
248
|
for (const [key, member] of exposed.get(node.init) ?? []) {
|
|
@@ -335,5 +349,5 @@ export function scan(
|
|
|
335
349
|
return [...imported.values()].some(contains)
|
|
336
350
|
}
|
|
337
351
|
|
|
338
|
-
return { conditions, exports, identities, localConditions }
|
|
352
|
+
return { compositions, conditions, exports, identities, localConditions }
|
|
339
353
|
}
|
|
@@ -10,6 +10,10 @@ import type * as Theme from './Theme.js'
|
|
|
10
10
|
/** Private ownership used by uncompiled composition; never spread onto DOM props. */
|
|
11
11
|
export const metadata = Symbol.for('zyzz.authoring')
|
|
12
12
|
|
|
13
|
+
// Static definitions retain their style data so later compositions can read it,
|
|
14
|
+
// including definitions created by another bundled copy of the runtime.
|
|
15
|
+
const data = Symbol.for('zyzz.style')
|
|
16
|
+
|
|
13
17
|
/** Identity and replaceable attribute/slot ownership for an applied definition. */
|
|
14
18
|
export type Owner = {
|
|
15
19
|
readonly name: string
|
|
@@ -77,24 +81,54 @@ export function create(
|
|
|
77
81
|
if (!dynamic && !id && Object.keys(input as object).length === 0)
|
|
78
82
|
Identity.requireId(undefined, 'Empty style')
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
84
|
+
const define = (input: unknown) =>
|
|
85
|
+
(
|
|
86
|
+
Style.define as (
|
|
87
|
+
input: Record<string, unknown>,
|
|
88
|
+
options: Style.define.Options,
|
|
89
|
+
) => Style.Definition
|
|
90
|
+
)(
|
|
91
|
+
{ style: body(input as Record<string, unknown>) },
|
|
92
|
+
{ vars: options.theme },
|
|
93
|
+
).styles[0]!
|
|
94
|
+
|
|
95
|
+
const style = (() => {
|
|
96
|
+
if (dynamic) return undefined
|
|
97
|
+
if (!Array.isArray(input)) return define(input)
|
|
98
|
+
|
|
99
|
+
// Mirrors compiled composition: each entry is one ordered declaration segment.
|
|
100
|
+
const rules: Style.Rule[] = []
|
|
101
|
+
for (const [index, entry] of (input as readonly unknown[]).entries()) {
|
|
102
|
+
if (typeof entry !== 'function') {
|
|
103
|
+
rules.push({ style: define(entry) })
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const style = Object.getOwnPropertyDescriptor(entry, data)?.value as
|
|
108
|
+
| Style.NamedStyle
|
|
109
|
+
| undefined
|
|
110
|
+
if (style) {
|
|
111
|
+
rules.push({ style })
|
|
112
|
+
continue
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Compiled callables carry only class names, so an explicit id names the composite.
|
|
116
|
+
if (id) return undefined
|
|
117
|
+
|
|
118
|
+
throw new Style.InvalidError([
|
|
119
|
+
{
|
|
120
|
+
code: 'invalid_structure',
|
|
121
|
+
message:
|
|
122
|
+
'Composition entries require literal objects or static style definitions. Compositions of compiled definitions require an explicit id, and variants and dynamic styles are applied with cx.',
|
|
123
|
+
path: [String(index)],
|
|
124
|
+
},
|
|
125
|
+
])
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return { name: 'style', declarations: [], rules } satisfies Style.NamedStyle
|
|
129
|
+
})()
|
|
130
|
+
|
|
131
|
+
const className = id ? `z-style-${id}` : Identity.style(style!, namespace)
|
|
98
132
|
const props = Props.create({ className })
|
|
99
133
|
const apply = (values?: style.Options & Record<string, unknown>) => {
|
|
100
134
|
let result = props(values as style.Options)
|
|
@@ -124,6 +158,7 @@ export function create(
|
|
|
124
158
|
Object.defineProperty(apply, Symbol.toPrimitive, {
|
|
125
159
|
value: () => `.${className}`,
|
|
126
160
|
})
|
|
161
|
+
if (style) Object.defineProperty(apply, data, { value: style })
|
|
127
162
|
return apply as style.ReturnType
|
|
128
163
|
}
|
|
129
164
|
|
|
@@ -625,15 +625,52 @@ export type StyleFactory<
|
|
|
625
625
|
? [options?: style.DefinitionOptions]
|
|
626
626
|
: [invalid: never, unavailable: never]
|
|
627
627
|
: [invalid: never, unavailable: never]
|
|
628
|
-
|
|
628
|
+
// TypeScript types a call that matches no overload with this signature. Other
|
|
629
|
+
// inputs leave `callback` at its constraint, so their definitions stay static.
|
|
630
|
+
): ((...args: never[]) => unknown) extends callback
|
|
631
|
+
? style.ReturnType<output>
|
|
632
|
+
: style.Dynamic<values, output>
|
|
629
633
|
<const styles extends Record<string, unknown>>(
|
|
630
634
|
styles: styles &
|
|
631
635
|
NoInfer<Body<styles, tokens, layers, mappings>> &
|
|
632
636
|
Completion.Properties<tokens>,
|
|
633
637
|
options?: style.DefinitionOptions,
|
|
634
638
|
): style.ReturnType<output>
|
|
639
|
+
<const entries>(
|
|
640
|
+
styles: entries & Entries<entries, tokens, layers, mappings>,
|
|
641
|
+
...options: entries extends readonly unknown[]
|
|
642
|
+
? [options?: style.DefinitionOptions]
|
|
643
|
+
: [invalid: never, unavailable: never]
|
|
644
|
+
): style.ReturnType<output>
|
|
635
645
|
}
|
|
636
646
|
|
|
647
|
+
// Composition entries are static definitions or checked literal objects.
|
|
648
|
+
type Entries<
|
|
649
|
+
entries,
|
|
650
|
+
tokens extends Theme.Tokens,
|
|
651
|
+
layers extends string,
|
|
652
|
+
mappings extends Shorthands.Map,
|
|
653
|
+
> = {
|
|
654
|
+
readonly [index in keyof entries]: Entry<
|
|
655
|
+
entries[index],
|
|
656
|
+
tokens,
|
|
657
|
+
layers,
|
|
658
|
+
mappings
|
|
659
|
+
>
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Distributes over mixed element unions so each member keeps its own contract.
|
|
663
|
+
type Entry<
|
|
664
|
+
entry,
|
|
665
|
+
tokens extends Theme.Tokens,
|
|
666
|
+
layers extends string,
|
|
667
|
+
mappings extends Shorthands.Map,
|
|
668
|
+
> = entry extends (...args: never) => unknown
|
|
669
|
+
? style.Composable<entry>
|
|
670
|
+
: entry &
|
|
671
|
+
NoInfer<Body<entry, tokens, layers, mappings>> &
|
|
672
|
+
Completion.Properties<tokens>
|
|
673
|
+
|
|
637
674
|
type Keys<styles> = styles extends unknown ? keyof styles : never
|
|
638
675
|
|
|
639
676
|
/** Checked declaration body shared by configured styles and recipe choices. */
|
package/src/internal/Literal.ts
CHANGED
|
@@ -1588,7 +1588,10 @@ const properties = {
|
|
|
1588
1588
|
direction: { kind: 'enum', values: ['ltr', 'rtl'] },
|
|
1589
1589
|
display: {
|
|
1590
1590
|
kind: 'enum',
|
|
1591
|
+
// The Compat Standard keeps the legacy box keywords that -webkit-line-clamp requires.
|
|
1591
1592
|
values: [
|
|
1593
|
+
'-webkit-box',
|
|
1594
|
+
'-webkit-inline-box',
|
|
1592
1595
|
'block',
|
|
1593
1596
|
'block flex',
|
|
1594
1597
|
'block flow',
|
package/src/internal/Theme.ts
CHANGED
|
@@ -38,6 +38,14 @@ export type StyleFactory<tokens extends Tokens> = {
|
|
|
38
38
|
(values extends Binding.Inputs<values> ? unknown : never),
|
|
39
39
|
options?: style.DefinitionOptions,
|
|
40
40
|
): style.Dynamic<values>
|
|
41
|
+
<const entries>(
|
|
42
|
+
styles: entries & {
|
|
43
|
+
readonly [index in keyof entries]: Entry<entries[index], tokens>
|
|
44
|
+
},
|
|
45
|
+
...options: entries extends readonly unknown[]
|
|
46
|
+
? [options?: style.DefinitionOptions]
|
|
47
|
+
: [invalid: never, unavailable: never]
|
|
48
|
+
): style.ReturnType
|
|
41
49
|
<const styles extends Record<string, unknown>>(
|
|
42
50
|
styles: styles & NoInfer<Style.Accepted<styles, tokens>>,
|
|
43
51
|
options?: style.DefinitionOptions,
|
|
@@ -56,6 +64,13 @@ export type StyleFactory<tokens extends Tokens> = {
|
|
|
56
64
|
): style.ReturnType
|
|
57
65
|
}
|
|
58
66
|
|
|
67
|
+
// Distributes over mixed element unions so each member keeps its own contract.
|
|
68
|
+
type Entry<entry, tokens extends Tokens> = entry extends (
|
|
69
|
+
...args: never
|
|
70
|
+
) => unknown
|
|
71
|
+
? style.Composable<entry>
|
|
72
|
+
: entry & NoInfer<Style.Accepted<entry, tokens>>
|
|
73
|
+
|
|
59
74
|
/**
|
|
60
75
|
* Defines scalar tokens and typography sets without defaults or environment access.
|
|
61
76
|
* Colors currently use the supported literal color grammar; spacing and radius
|
package/src/styleFunction.ts
CHANGED
|
@@ -29,9 +29,21 @@ type VariableOptions<input> = input extends {
|
|
|
29
29
|
}
|
|
30
30
|
: unknown
|
|
31
31
|
|
|
32
|
+
// Composition entries are static definitions or exact literal objects.
|
|
33
|
+
type Entries<entries> = {
|
|
34
|
+
readonly [index in keyof entries]: Entry<entries[index]>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Distributes over mixed element unions so each member keeps its own contract.
|
|
38
|
+
type Entry<entry> = entry extends (...args: never) => unknown
|
|
39
|
+
? style.Composable<entry>
|
|
40
|
+
: entry & NoInfer<Style.Accepted<entry, {}, true>> & Completion.Properties
|
|
41
|
+
|
|
32
42
|
/**
|
|
33
43
|
* Declares literal styles for source extraction. Requires a compile-time transform.
|
|
34
|
-
*
|
|
44
|
+
* An array composes static definitions and literal objects in order, so later entries
|
|
45
|
+
* win as later declarations do.
|
|
46
|
+
* @param styles - Token-free literal CSS properties, or an array of static definitions and literal objects. Omit for an empty definition.
|
|
35
47
|
* @returns A callable style definition after source rewriting.
|
|
36
48
|
* @throws {Error} When a definition needs an explicit identity and none is supplied.
|
|
37
49
|
*/
|
|
@@ -53,16 +65,29 @@ export function style<
|
|
|
53
65
|
? [options?: style.DefinitionOptions]
|
|
54
66
|
: [invalid: never, unavailable: never]
|
|
55
67
|
: [invalid: never, unavailable: never]
|
|
56
|
-
|
|
68
|
+
// TypeScript types a call that matches no overload with this signature. Other
|
|
69
|
+
// inputs leave `callback` at its constraint, so their definitions stay static.
|
|
70
|
+
): ((...args: never[]) => unknown) extends callback
|
|
71
|
+
? style.ReturnType
|
|
72
|
+
: style.Dynamic<values>
|
|
57
73
|
export function style<const styles extends Record<string, unknown>>(
|
|
58
74
|
styles: styles &
|
|
59
75
|
NoInfer<Style.Accepted<styles, {}, true>> &
|
|
60
76
|
Completion.Properties,
|
|
61
77
|
options?: style.DefinitionOptions,
|
|
62
78
|
): style.ReturnType
|
|
79
|
+
export function style<const entries>(
|
|
80
|
+
styles: entries & Entries<entries>,
|
|
81
|
+
// Exclude non-array inputs by arity so they cannot mask object-property diagnostics.
|
|
82
|
+
...options: entries extends readonly unknown[]
|
|
83
|
+
? [options?: style.DefinitionOptions]
|
|
84
|
+
: [invalid: never, unavailable: never]
|
|
85
|
+
): style.ReturnType
|
|
63
86
|
export function style(
|
|
64
87
|
styles?: unknown,
|
|
65
88
|
options: style.DefinitionOptions = {},
|
|
89
|
+
// Matches the arity-gated overloads, whose invalid branches add parameters.
|
|
90
|
+
..._: readonly never[]
|
|
66
91
|
): style.ReturnType {
|
|
67
92
|
return Authoring.create(styles, options)
|
|
68
93
|
}
|
|
@@ -73,6 +98,10 @@ type Reference = { readonly [identity]: true }
|
|
|
73
98
|
|
|
74
99
|
/** Contracts for the literal authoring boundary. */
|
|
75
100
|
export declare namespace style {
|
|
101
|
+
/** Accepts a static definition as a composition entry. Dynamic definitions and variants require cx. */
|
|
102
|
+
type Composable<entry> = entry extends Reference & (() => unknown)
|
|
103
|
+
? entry
|
|
104
|
+
: ReturnType<Output>
|
|
76
105
|
/** Stable identity for selectors and definitions that cannot be content-addressed. */
|
|
77
106
|
type DefinitionOptions = { readonly id?: string | undefined }
|
|
78
107
|
/** Callable compiled bindings with required scalar inputs and styling overrides. */
|