praxis-kit 7.0.0 → 7.4.0
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/_shared/diagnostics.d.ts +6 -0
- package/dist/{chunk-35CJAOJW.js → chunk-EIKPSL26.js} +63 -6
- package/dist/codemod/index.js +121 -72
- package/dist/contract/index.d.ts +92 -0
- package/dist/guards/index.d.ts +6 -0
- package/dist/guards/index.js +4 -4
- package/dist/html/index.d.ts +6 -0
- package/dist/lit/index.d.ts +158 -6
- package/dist/lit/index.js +83 -9
- package/dist/preact/index.d.ts +164 -3
- package/dist/preact/index.js +104 -31
- package/dist/react/index.d.ts +26 -3
- package/dist/react/index.js +34 -8
- package/dist/react/legacy.d.ts +25 -3
- package/dist/react/legacy.js +17 -3
- package/dist/{react-options-Cm99IE5J.d.ts → react-options-BnjZpdVh.d.ts} +141 -3
- package/dist/solid/index.d.ts +163 -3
- package/dist/solid/index.js +100 -17
- package/dist/svelte/Polymorphic.svelte +25 -0
- package/dist/svelte/index.d.ts +231 -13
- package/dist/svelte/index.js +16 -8
- package/dist/tailwind/index.d.ts +12 -0
- package/dist/ts-plugin/index.cjs +5 -2
- package/dist/vite-plugin/index.d.ts +6 -0
- package/dist/vue/index.d.ts +166 -3
- package/dist/vue/index.js +119 -37
- package/dist/web/index.d.ts +132 -4
- package/dist/web/index.js +94 -13
- package/package.json +4 -4
package/dist/lit/index.d.ts
CHANGED
|
@@ -2,9 +2,72 @@ import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
|
|
|
2
2
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
3
3
|
import { LitElement } from 'lit';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A string-keyed object whose values are of type `T`.
|
|
7
|
+
*/
|
|
5
8
|
type StringMap<T = unknown> = Record<string, T>;
|
|
9
|
+
/**
|
|
10
|
+
* A string-keyed object with values of unknown type.
|
|
11
|
+
*/
|
|
6
12
|
type AnyRecord = StringMap<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* An object type with no named properties.
|
|
15
|
+
*
|
|
16
|
+
* Unlike `{}`, this excludes arbitrary properties during type operations while
|
|
17
|
+
* still satisfying `extends object`.
|
|
18
|
+
*/
|
|
7
19
|
type EmptyRecord = Record<never, never>;
|
|
20
|
+
/**
|
|
21
|
+
* A compound component's named sub-components, for example
|
|
22
|
+
* `{ Header, Content, Footer }`.
|
|
23
|
+
*/
|
|
24
|
+
type SubComponentMap = Readonly<AnyRecord>;
|
|
25
|
+
/**
|
|
26
|
+
* Default `Variants` type for components that declare no variants.
|
|
27
|
+
*
|
|
28
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
29
|
+
* editor hovers remain self-descriptive.
|
|
30
|
+
*/
|
|
31
|
+
type NoVariants = Readonly<EmptyRecord>;
|
|
32
|
+
/**
|
|
33
|
+
* Default `TPreset` type for components that declare no named presets.
|
|
34
|
+
*
|
|
35
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
36
|
+
* editor hovers remain self-descriptive.
|
|
37
|
+
*/
|
|
38
|
+
type NoPreset = Readonly<EmptyRecord>;
|
|
39
|
+
/**
|
|
40
|
+
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
41
|
+
* props, including the no-plugin case.
|
|
42
|
+
*
|
|
43
|
+
* Structurally identical to `EmptyRecord`, but named separately so editor
|
|
44
|
+
* hovers remain self-descriptive.
|
|
45
|
+
*/
|
|
46
|
+
type NoPluginProps = EmptyRecord;
|
|
47
|
+
/**
|
|
48
|
+
* Determines whether an object type should be treated as empty.
|
|
49
|
+
*
|
|
50
|
+
* `keyof T` ignores call and construct signatures...
|
|
51
|
+
*/
|
|
52
|
+
type IsEmptyRecord<T extends object> = T extends (...args: never[]) => unknown ? false : T extends new (...args: never[]) => unknown ? false : keyof T extends never ? true : false;
|
|
53
|
+
/**
|
|
54
|
+
* Merges two object types while eliding empty operands.
|
|
55
|
+
*
|
|
56
|
+
* If either operand is {@link EmptyRecord}, the other operand is returned
|
|
57
|
+
* directly instead of producing intersections such as
|
|
58
|
+
* `Component & EmptyRecord` in editor hovers.
|
|
59
|
+
*
|
|
60
|
+
* Unlike a homomorphic mapped type (for example `Simplify<T>`), this preserves
|
|
61
|
+
* call and construct signatures. Many component types are callable objects,
|
|
62
|
+
* and mapped types silently discard those signatures.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Instantiate `MergeRecords` directly. Introducing an intermediate alias for
|
|
66
|
+
* one operand (for example `type C = PolymorphicComponent<G>`) can prevent
|
|
67
|
+
* `IsEmptyRecord` from evaluating eagerly, which breaks assignability under
|
|
68
|
+
* `exactOptionalPropertyTypes`.
|
|
69
|
+
*/
|
|
70
|
+
type MergeRecords<A extends object, B extends object> = IsEmptyRecord<A> extends true ? B : IsEmptyRecord<B> extends true ? A : A & B;
|
|
8
71
|
|
|
9
72
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
10
73
|
|
|
@@ -170,7 +233,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
170
233
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
171
234
|
* capability wiring). */
|
|
172
235
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
173
|
-
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ?
|
|
236
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
174
237
|
|
|
175
238
|
type AriaContext = {
|
|
176
239
|
readonly tag: IntrinsicTag;
|
|
@@ -234,6 +297,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
234
297
|
* `@praxis-kit/diagnostics`.
|
|
235
298
|
*/
|
|
236
299
|
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
300
|
+
/**
|
|
301
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
302
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
303
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
304
|
+
* and friends in `praxis-kit/contract`).
|
|
305
|
+
*/
|
|
237
306
|
readonly aria?: readonly AriaRule[];
|
|
238
307
|
/**
|
|
239
308
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -245,6 +314,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
245
314
|
* misleading `aria` name to get the machinery it needs.
|
|
246
315
|
*/
|
|
247
316
|
readonly rules?: readonly AriaRule[];
|
|
317
|
+
/**
|
|
318
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
319
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
320
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
321
|
+
*/
|
|
248
322
|
readonly children?: readonly ChildRuleInput[];
|
|
249
323
|
/**
|
|
250
324
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -257,19 +331,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
257
331
|
* or any listed rule. Default: true.
|
|
258
332
|
*/
|
|
259
333
|
readonly allowText?: boolean;
|
|
334
|
+
/**
|
|
335
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
336
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
337
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
338
|
+
*/
|
|
260
339
|
readonly props?: readonly PropNormalizer[];
|
|
261
340
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
262
341
|
readonly allowedAs?: readonly TAllowed[];
|
|
263
342
|
};
|
|
264
343
|
|
|
265
344
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
345
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
266
346
|
readonly base?: ClassName;
|
|
347
|
+
/**
|
|
348
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
349
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
350
|
+
*/
|
|
267
351
|
readonly variants?: V;
|
|
352
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
268
353
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
354
|
+
/**
|
|
355
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
356
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
357
|
+
* need a class neither variant would add on its own).
|
|
358
|
+
*/
|
|
269
359
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
360
|
+
/**
|
|
361
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
362
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
363
|
+
*/
|
|
270
364
|
readonly presets?: TPreset;
|
|
365
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
271
366
|
readonly tags?: Readonly<TagMap>;
|
|
367
|
+
/**
|
|
368
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
369
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
370
|
+
*/
|
|
272
371
|
readonly plugin?: TPlugin;
|
|
372
|
+
/**
|
|
373
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
374
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
375
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
376
|
+
*/
|
|
273
377
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
274
378
|
};
|
|
275
379
|
|
|
@@ -278,19 +382,65 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
278
382
|
}['normalize'];
|
|
279
383
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
280
384
|
type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType> = {
|
|
385
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
281
386
|
readonly tag?: TDefault;
|
|
387
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
282
388
|
readonly name?: string;
|
|
389
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
283
390
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
391
|
+
/**
|
|
392
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
393
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
394
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
395
|
+
*/
|
|
284
396
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
397
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
285
398
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
399
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
286
400
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
287
401
|
/**
|
|
288
402
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
|
289
403
|
* be set directly by component authors — use `enforcement.diagnostics` to override per component.
|
|
290
404
|
*/
|
|
291
405
|
readonly diagnostics?: Diagnostics;
|
|
406
|
+
/**
|
|
407
|
+
* Sub-components to attach to the generated root component, producing a
|
|
408
|
+
* compound component API (for example, `Card.Header`, `Card.Content`,
|
|
409
|
+
* and `Card.Footer`). Purely additive — has no effect on
|
|
410
|
+
* `enforcement.children`; author child rules explicitly if the component
|
|
411
|
+
* needs to validate its children.
|
|
412
|
+
*/
|
|
413
|
+
readonly subComponents?: SubComponentMap;
|
|
414
|
+
/**
|
|
415
|
+
* Called once per instance, when the real underlying DOM element first
|
|
416
|
+
* exists, in every adapter — via that adapter's own native mount
|
|
417
|
+
* lifecycle, never through the props/attribute pipeline. Use this for
|
|
418
|
+
* wiring that needs the actual element (native imperative methods like
|
|
419
|
+
* `dialogEl.showModal()`, native events like `close`/`cancel` that have
|
|
420
|
+
* no prop-based equivalent), not for anything expressible as a plain
|
|
421
|
+
* prop.
|
|
422
|
+
*
|
|
423
|
+
* `getProps` returns the instance's *current* resolved props at call
|
|
424
|
+
* time — read it from inside a listener registered once at mount, rather
|
|
425
|
+
* than re-subscribing on every prop change.
|
|
426
|
+
*
|
|
427
|
+
* Return a cleanup function to run when the instance unmounts.
|
|
428
|
+
*/
|
|
429
|
+
readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
|
|
292
430
|
};
|
|
293
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Determines whether a prop should be stripped before forwarding to the
|
|
434
|
+
* rendered element.
|
|
435
|
+
*
|
|
436
|
+
* Returning `true` excludes the prop from the output; returning `false`
|
|
437
|
+
* keeps it. This is the inverse polarity of `shouldForwardProp`-style
|
|
438
|
+
* predicates (Emotion/styled-components), where `true` means include.
|
|
439
|
+
*
|
|
440
|
+
* @param key - The prop name being evaluated.
|
|
441
|
+
* @param variantKeys - The set of configured variant prop names.
|
|
442
|
+
* @returns `true` to strip the prop; `false` to forward it.
|
|
443
|
+
*/
|
|
294
444
|
type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
295
445
|
|
|
296
446
|
declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
|
|
@@ -306,7 +456,7 @@ declare function defineContractComponent<O extends FactoryOptions>(options: O):
|
|
|
306
456
|
* Note: this adapter targets Light DOM composition only. Shadow DOM slot
|
|
307
457
|
* protocol is intentionally out of scope.
|
|
308
458
|
*/
|
|
309
|
-
type LitFactoryOptions<TDefault extends ElementType = ElementType, TProps extends AnyRecord = EmptyRecord, TVariants extends Readonly<VariantMap> =
|
|
459
|
+
type LitFactoryOptions<TDefault extends ElementType = ElementType, TProps extends AnyRecord = EmptyRecord, TVariants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<TVariants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = FactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
|
|
310
460
|
readonly filterProps?: FilterPredicate;
|
|
311
461
|
};
|
|
312
462
|
|
|
@@ -318,14 +468,14 @@ type UnknownProps = AnyRecord;
|
|
|
318
468
|
* (which would trigger TS4094 in declaration emit). Variant key instance
|
|
319
469
|
* properties are typed via the TVariants parameter.
|
|
320
470
|
*/
|
|
321
|
-
type LitContractComponent<TVariants extends Readonly<VariantMap> =
|
|
322
|
-
new (): LitElement & {
|
|
471
|
+
type LitContractComponent<TVariants extends Readonly<VariantMap> = NoVariants, TPluginProps extends AnyRecord = EmptyRecord> = {
|
|
472
|
+
new (): MergeRecords<LitElement & {
|
|
323
473
|
as: string | undefined;
|
|
324
474
|
recipe: string | undefined;
|
|
325
475
|
praxisClass: string | undefined;
|
|
326
476
|
} & {
|
|
327
477
|
[K in Extract<keyof TVariants, string>]?: string | null;
|
|
328
|
-
}
|
|
478
|
+
}, TPluginProps>;
|
|
329
479
|
};
|
|
330
480
|
|
|
331
481
|
/**
|
|
@@ -348,7 +498,9 @@ type LitContractComponent<TVariants extends Readonly<VariantMap> = Readonly<Empt
|
|
|
348
498
|
* customElements.define('praxis-button', Button)
|
|
349
499
|
* ```
|
|
350
500
|
*/
|
|
351
|
-
declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> =
|
|
501
|
+
declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<TVariants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: LitFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
|
|
502
|
+
readonly subComponents?: TSubComponents;
|
|
503
|
+
}): MergeRecords<LitContractComponent<TVariants, ExtractPluginProps<TPlugin>>, TSubComponents>;
|
|
352
504
|
|
|
353
505
|
/**
|
|
354
506
|
* Renders a praxis-kit Lit component to an HTML string without requiring a DOM.
|
package/dist/lit/index.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
+
// ../../lib/adapter-utils/src/invariant.ts
|
|
2
|
+
function panic(message) {
|
|
3
|
+
throw new Error(message);
|
|
4
|
+
}
|
|
5
|
+
function invariant(condition, message) {
|
|
6
|
+
if (!condition) panic(message);
|
|
7
|
+
}
|
|
8
|
+
|
|
1
9
|
// ../../lib/adapter-utils/src/runtime/define-component.ts
|
|
2
10
|
function defineContractComponent(options) {
|
|
3
11
|
return (factory) => factory(options);
|
|
4
12
|
}
|
|
5
13
|
|
|
14
|
+
// ../../lib/adapter-utils/src/runtime/assemble-compound-component.ts
|
|
15
|
+
function assembleCompoundComponent(root, subComponents) {
|
|
16
|
+
if (!subComponents) return root;
|
|
17
|
+
return Object.assign(root, subComponents);
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
// ../../lib/primitive/src/tag/resolve-tag.ts
|
|
7
21
|
function makeResolveTag(defaultTag) {
|
|
8
22
|
return function tag(as) {
|
|
@@ -45,10 +59,13 @@ function isString(value) {
|
|
|
45
59
|
function isNumber(value) {
|
|
46
60
|
return typeof value === "number";
|
|
47
61
|
}
|
|
62
|
+
function isFunction(value) {
|
|
63
|
+
return typeof value === "function";
|
|
64
|
+
}
|
|
48
65
|
|
|
49
66
|
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
50
67
|
function isDynamicRule(rule) {
|
|
51
|
-
return isObject(rule, true) && rule
|
|
68
|
+
return isObject(rule, true) && Reflect.get(rule, RULE_BRAND) === true;
|
|
52
69
|
}
|
|
53
70
|
|
|
54
71
|
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
@@ -587,17 +604,17 @@ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default
|
|
|
587
604
|
// ../../lib/primitive/src/guards/children/is-tag.ts
|
|
588
605
|
function getAsProp(child) {
|
|
589
606
|
if (!isObject(child) || !("props" in child)) return void 0;
|
|
590
|
-
const props = child
|
|
607
|
+
const { props } = child;
|
|
591
608
|
if (!isObject(props)) return void 0;
|
|
592
|
-
const as = props
|
|
609
|
+
const as = Reflect.get(props, "as");
|
|
593
610
|
return isString(as) && as !== "" ? as : void 0;
|
|
594
611
|
}
|
|
595
612
|
function getTag(child) {
|
|
596
613
|
if (!isObject(child) || !("type" in child)) return void 0;
|
|
597
|
-
const t = child
|
|
614
|
+
const { type: t } = child;
|
|
598
615
|
if (isString(t)) return t;
|
|
599
616
|
if (typeof t === "function" || isObject(t)) {
|
|
600
|
-
const defaultTag = t
|
|
617
|
+
const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
|
|
601
618
|
if (!isString(defaultTag)) return void 0;
|
|
602
619
|
return getAsProp(child) ?? defaultTag;
|
|
603
620
|
}
|
|
@@ -617,6 +634,28 @@ function isTag(...args) {
|
|
|
617
634
|
return tag !== void 0 && set2.has(tag);
|
|
618
635
|
}
|
|
619
636
|
|
|
637
|
+
// ../../lib/adapter-utils/src/runtime/is-factory-options-like.ts
|
|
638
|
+
var FACTORY_OPTIONS_FIELD_VALIDATORS = {
|
|
639
|
+
tag: (v) => v === void 0 || isString(v),
|
|
640
|
+
name: (v) => v === void 0 || isString(v),
|
|
641
|
+
defaults: (v) => v === void 0 || isObject(v),
|
|
642
|
+
normalize: (v) => v === void 0 || isFunction(v),
|
|
643
|
+
styling: (v) => v === void 0 || isObject(v),
|
|
644
|
+
enforcement: (v) => v === void 0 || isObject(v),
|
|
645
|
+
diagnostics: (v) => v === void 0 || isObject(v),
|
|
646
|
+
subComponents: (v) => v === void 0 || isObject(v),
|
|
647
|
+
onElement: (v) => v === void 0 || isFunction(v)
|
|
648
|
+
};
|
|
649
|
+
function isFactoryOptionsLike(options, extraFieldValidators) {
|
|
650
|
+
if (!isObject(options)) return false;
|
|
651
|
+
const validators = { ...FACTORY_OPTIONS_FIELD_VALIDATORS, ...extraFieldValidators };
|
|
652
|
+
for (const [key, value] of Object.entries(options)) {
|
|
653
|
+
const validate = validators[key];
|
|
654
|
+
if (!validate || !validate(value)) return false;
|
|
655
|
+
}
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
|
|
620
659
|
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
621
660
|
function getImplicitRole(tag, props) {
|
|
622
661
|
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
@@ -2721,7 +2760,7 @@ function getChildProp(child, key) {
|
|
|
2721
2760
|
if (!isVNodeLike(child)) return void 0;
|
|
2722
2761
|
const { props } = child;
|
|
2723
2762
|
if (!isObject(props)) return void 0;
|
|
2724
|
-
return props
|
|
2763
|
+
return Reflect.get(props, key);
|
|
2725
2764
|
}
|
|
2726
2765
|
|
|
2727
2766
|
// ../core/src/html/contracts/aria/landmarks.ts
|
|
@@ -3503,7 +3542,7 @@ function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
|
|
|
3503
3542
|
}
|
|
3504
3543
|
|
|
3505
3544
|
// ../../adapters/lit/src/create-contract-component.ts
|
|
3506
|
-
import { LitElement, html } from "lit";
|
|
3545
|
+
import { LitElement as LitElement2, html } from "lit";
|
|
3507
3546
|
|
|
3508
3547
|
// ../../adapters/lit/src/build-runtime.ts
|
|
3509
3548
|
import { silentDiagnostics as silentDiagnostics4 } from "../_shared/diagnostics.js";
|
|
@@ -3531,6 +3570,12 @@ function buildRuntime(options) {
|
|
|
3531
3570
|
};
|
|
3532
3571
|
}
|
|
3533
3572
|
|
|
3573
|
+
// ../../adapters/lit/src/is-lit-contract-component.ts
|
|
3574
|
+
import { LitElement } from "lit";
|
|
3575
|
+
function isLitContractComponent(value) {
|
|
3576
|
+
return isFunction(value) && value.prototype instanceof LitElement;
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3534
3579
|
// ../../adapters/lit/src/render-to-string.ts
|
|
3535
3580
|
var ssrRegistry = /* @__PURE__ */ new WeakMap();
|
|
3536
3581
|
function registerForSsr(cls, bundle) {
|
|
@@ -3547,8 +3592,17 @@ function renderToString(component, props = {}, innerHTML = "") {
|
|
|
3547
3592
|
return renderBundleToString(entry.bundle, props, innerHTML);
|
|
3548
3593
|
}
|
|
3549
3594
|
|
|
3595
|
+
// ../../adapters/lit/src/to-lit-factory-options.ts
|
|
3596
|
+
var LIT_FIELD_VALIDATORS = {
|
|
3597
|
+
filterProps: (v) => v === void 0 || isFunction(v)
|
|
3598
|
+
};
|
|
3599
|
+
function isLitFactoryOptions(options) {
|
|
3600
|
+
return isFactoryOptionsLike(options, LIT_FIELD_VALIDATORS);
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3550
3603
|
// ../../adapters/lit/src/create-contract-component.ts
|
|
3551
3604
|
function createContractComponent(options) {
|
|
3605
|
+
invariant(isLitFactoryOptions(options), "options is not a valid LitFactoryOptions object");
|
|
3552
3606
|
const bundle = buildRuntime(options);
|
|
3553
3607
|
const looseBundle = toLooseBundle(bundle);
|
|
3554
3608
|
const variantKeys = options.styling?.variants ? Object.keys(options.styling.variants) : [];
|
|
@@ -3573,7 +3627,7 @@ function createContractComponent(options) {
|
|
|
3573
3627
|
iterate.forEach(pluginKeys, (key) => {
|
|
3574
3628
|
staticProps[key] = { type: String, attribute: key };
|
|
3575
3629
|
});
|
|
3576
|
-
class PolymorphicLitElement extends
|
|
3630
|
+
class PolymorphicLitElement extends LitElement2 {
|
|
3577
3631
|
// Tracks keys set by the pipeline last render so stale attrs are removed.
|
|
3578
3632
|
_pipelineAttrs = /* @__PURE__ */ new Set();
|
|
3579
3633
|
// Starts true so the first update always runs the pipeline regardless of
|
|
@@ -3635,6 +3689,21 @@ function createContractComponent(options) {
|
|
|
3635
3689
|
const props = this._buildProps();
|
|
3636
3690
|
diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
|
|
3637
3691
|
}
|
|
3692
|
+
// Light DOM means `this` already is the real host element — no ref/indirection needed.
|
|
3693
|
+
// connectedCallback/disconnectedCallback are the native mount/unmount lifecycle, called
|
|
3694
|
+
// once per instance regardless of how many pipeline re-runs `_applyPraxis` does.
|
|
3695
|
+
_onElementCleanup;
|
|
3696
|
+
connectedCallback() {
|
|
3697
|
+
super.connectedCallback();
|
|
3698
|
+
if (options.onElement) {
|
|
3699
|
+
this._onElementCleanup = options.onElement(this, () => this._buildProps()) ?? void 0;
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
disconnectedCallback() {
|
|
3703
|
+
super.disconnectedCallback();
|
|
3704
|
+
this._onElementCleanup?.();
|
|
3705
|
+
this._onElementCleanup = void 0;
|
|
3706
|
+
}
|
|
3638
3707
|
render() {
|
|
3639
3708
|
const children = Array.from(this.childNodes);
|
|
3640
3709
|
const { tag, normalizedProps } = resolveTagAndNormalizedProps(looseBundle, this._buildProps());
|
|
@@ -3648,8 +3717,13 @@ function createContractComponent(options) {
|
|
|
3648
3717
|
if (options.name) {
|
|
3649
3718
|
Object.defineProperty(PolymorphicLitElement, "name", { value: options.name });
|
|
3650
3719
|
}
|
|
3720
|
+
invariant(
|
|
3721
|
+
isLitContractComponent(PolymorphicLitElement),
|
|
3722
|
+
"Generated class failed to satisfy the LitContractComponent shape"
|
|
3723
|
+
);
|
|
3651
3724
|
registerForSsr(PolymorphicLitElement, looseBundle);
|
|
3652
|
-
|
|
3725
|
+
const assembled = assembleCompoundComponent(PolymorphicLitElement, options.subComponents);
|
|
3726
|
+
return assembled;
|
|
3653
3727
|
}
|
|
3654
3728
|
export {
|
|
3655
3729
|
createContractComponent,
|