praxis-kit 6.6.1 → 7.3.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 +1 -0
- package/dist/_shared/diagnostics.js +1 -0
- package/dist/{chunk-6JILZ6GQ.js → chunk-EIKPSL26.js} +126 -40
- package/dist/codemod/index.js +121 -72
- package/dist/contract/index.d.ts +82 -3
- package/dist/contract/index.js +75 -0
- package/dist/eslint/index.js +16 -16
- package/dist/guards/index.d.ts +21 -1
- package/dist/guards/index.js +33 -5
- package/dist/html/index.d.ts +5 -2
- package/dist/html/index.js +17 -14
- package/dist/lit/index.d.ts +34 -3
- package/dist/lit/index.js +143 -43
- package/dist/preact/index.d.ts +34 -3
- package/dist/preact/index.js +167 -65
- package/dist/react/index.d.ts +5 -3
- package/dist/react/index.js +34 -8
- package/dist/react/legacy.d.ts +2 -2
- package/dist/react/legacy.js +17 -3
- package/dist/{react-options-BUBVohU6.d.ts → react-options-DLDsA4Tn.d.ts} +32 -3
- package/dist/solid/index.d.ts +34 -3
- package/dist/solid/index.js +163 -51
- package/dist/svelte/Polymorphic.svelte +15 -1
- package/dist/svelte/index.d.ts +44 -10
- package/dist/svelte/index.js +75 -41
- package/dist/tailwind/index.js +31 -0
- package/dist/ts-plugin/index.cjs +5 -2
- package/dist/vite-plugin/index.d.ts +1 -0
- package/dist/vue/index.d.ts +34 -3
- package/dist/vue/index.js +179 -71
- package/dist/web/index.d.ts +34 -3
- package/dist/web/index.js +154 -47
- package/package.json +8 -8
package/dist/vue/index.js
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
// ../../adapters/vue/src/create-contract-component.ts
|
|
2
2
|
import { computed, defineComponent as defineComponent2 } from "vue";
|
|
3
3
|
|
|
4
|
+
// ../../lib/adapter-utils/src/invariant.ts
|
|
5
|
+
function panic(message) {
|
|
6
|
+
throw new Error(message);
|
|
7
|
+
}
|
|
8
|
+
function invariant(condition, message) {
|
|
9
|
+
if (!condition) panic(message);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ../../lib/adapter-utils/src/runtime/apply-display-name.ts
|
|
13
|
+
function applyDisplayName(component, name) {
|
|
14
|
+
Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ../../lib/adapter-utils/src/runtime/define-component.ts
|
|
18
|
+
function defineContractComponent(options) {
|
|
19
|
+
return (factory) => factory(options);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ../../lib/adapter-utils/src/runtime/assemble-compound-component.ts
|
|
23
|
+
function assembleCompoundComponent(root, subComponents) {
|
|
24
|
+
if (!subComponents) return root;
|
|
25
|
+
return Object.assign(root, subComponents);
|
|
26
|
+
}
|
|
27
|
+
|
|
4
28
|
// ../../lib/primitive/src/tag/resolve-tag.ts
|
|
5
29
|
function makeResolveTag(defaultTag) {
|
|
6
30
|
return function tag(as) {
|
|
@@ -11,6 +35,11 @@ function makeResolveTag(defaultTag) {
|
|
|
11
35
|
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
12
36
|
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
13
37
|
|
|
38
|
+
// ../../lib/primitive/src/rule/dynamic.ts
|
|
39
|
+
function dynamic(resolve) {
|
|
40
|
+
return { [RULE_BRAND]: true, resolve };
|
|
41
|
+
}
|
|
42
|
+
|
|
14
43
|
// ../../lib/primitive/src/guards/foundational/is-defined.ts
|
|
15
44
|
function isUndefined(value) {
|
|
16
45
|
return value === void 0;
|
|
@@ -24,7 +53,7 @@ function isNonNull(value) {
|
|
|
24
53
|
return value != null;
|
|
25
54
|
}
|
|
26
55
|
function isNullish(value) {
|
|
27
|
-
return isNull(value) || value
|
|
56
|
+
return isNull(value) || isUndefined(value);
|
|
28
57
|
}
|
|
29
58
|
|
|
30
59
|
// ../../lib/primitive/src/utils/type-guards.ts
|
|
@@ -38,10 +67,13 @@ function isString(value) {
|
|
|
38
67
|
function isNumber(value) {
|
|
39
68
|
return typeof value === "number";
|
|
40
69
|
}
|
|
70
|
+
function isFunction(value) {
|
|
71
|
+
return typeof value === "function";
|
|
72
|
+
}
|
|
41
73
|
|
|
42
74
|
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
43
75
|
function isDynamicRule(rule) {
|
|
44
|
-
return isObject(rule, true) && rule
|
|
76
|
+
return isObject(rule, true) && Reflect.get(rule, RULE_BRAND) === true;
|
|
45
77
|
}
|
|
46
78
|
|
|
47
79
|
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
@@ -601,6 +633,24 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
|
|
|
601
633
|
]
|
|
602
634
|
]);
|
|
603
635
|
|
|
636
|
+
// ../../lib/primitive/src/constants/html/void-tags.ts
|
|
637
|
+
var VOID_TAGS = [
|
|
638
|
+
"area",
|
|
639
|
+
"base",
|
|
640
|
+
"br",
|
|
641
|
+
"col",
|
|
642
|
+
"embed",
|
|
643
|
+
"hr",
|
|
644
|
+
"img",
|
|
645
|
+
"input",
|
|
646
|
+
"link",
|
|
647
|
+
"meta",
|
|
648
|
+
"param",
|
|
649
|
+
"source",
|
|
650
|
+
"track",
|
|
651
|
+
"wbr"
|
|
652
|
+
];
|
|
653
|
+
|
|
604
654
|
// ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
|
|
605
655
|
function isGlobalAriaAttribute(attr) {
|
|
606
656
|
return GLOBAL_ARIA_ATTRIBUTES.has(attr);
|
|
@@ -653,17 +703,17 @@ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default
|
|
|
653
703
|
// ../../lib/primitive/src/guards/children/is-tag.ts
|
|
654
704
|
function getAsProp(child) {
|
|
655
705
|
if (!isObject(child) || !("props" in child)) return void 0;
|
|
656
|
-
const props = child
|
|
706
|
+
const { props } = child;
|
|
657
707
|
if (!isObject(props)) return void 0;
|
|
658
|
-
const as = props
|
|
708
|
+
const as = Reflect.get(props, "as");
|
|
659
709
|
return isString(as) && as !== "" ? as : void 0;
|
|
660
710
|
}
|
|
661
711
|
function getTag(child) {
|
|
662
712
|
if (!isObject(child) || !("type" in child)) return void 0;
|
|
663
|
-
const t = child
|
|
713
|
+
const { type: t } = child;
|
|
664
714
|
if (isString(t)) return t;
|
|
665
715
|
if (typeof t === "function" || isObject(t)) {
|
|
666
|
-
const defaultTag = t
|
|
716
|
+
const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
|
|
667
717
|
if (!isString(defaultTag)) return void 0;
|
|
668
718
|
return getAsProp(child) ?? defaultTag;
|
|
669
719
|
}
|
|
@@ -683,22 +733,34 @@ function isTag(...args) {
|
|
|
683
733
|
return tag !== void 0 && set2.has(tag);
|
|
684
734
|
}
|
|
685
735
|
|
|
686
|
-
// ../../lib/adapter-utils/src/
|
|
687
|
-
function
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
// ../../lib/adapter-utils/src/runtime/
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
736
|
+
// ../../lib/adapter-utils/src/runtime/finalize-component.ts
|
|
737
|
+
function finalizeComponent(component, defaultTag, subComponents) {
|
|
738
|
+
if (typeof defaultTag === "string") {
|
|
739
|
+
Object.assign(component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
|
|
740
|
+
}
|
|
741
|
+
return assembleCompoundComponent(component, subComponents);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// ../../lib/adapter-utils/src/runtime/is-factory-options-like.ts
|
|
745
|
+
var FACTORY_OPTIONS_FIELD_VALIDATORS = {
|
|
746
|
+
tag: (v) => v === void 0 || isString(v),
|
|
747
|
+
name: (v) => v === void 0 || isString(v),
|
|
748
|
+
defaults: (v) => v === void 0 || isObject(v),
|
|
749
|
+
normalize: (v) => v === void 0 || isFunction(v),
|
|
750
|
+
styling: (v) => v === void 0 || isObject(v),
|
|
751
|
+
enforcement: (v) => v === void 0 || isObject(v),
|
|
752
|
+
diagnostics: (v) => v === void 0 || isObject(v),
|
|
753
|
+
subComponents: (v) => v === void 0 || isObject(v),
|
|
754
|
+
onElement: (v) => v === void 0 || isFunction(v)
|
|
755
|
+
};
|
|
756
|
+
function isFactoryOptionsLike(options, extraFieldValidators) {
|
|
757
|
+
if (!isObject(options)) return false;
|
|
758
|
+
const validators = { ...FACTORY_OPTIONS_FIELD_VALIDATORS, ...extraFieldValidators };
|
|
759
|
+
for (const [key, value] of Object.entries(options)) {
|
|
760
|
+
const validate = validators[key];
|
|
761
|
+
if (!validate || !validate(value)) return false;
|
|
762
|
+
}
|
|
763
|
+
return true;
|
|
702
764
|
}
|
|
703
765
|
|
|
704
766
|
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
@@ -1599,7 +1661,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1599
1661
|
const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
|
|
1600
1662
|
if (cached) return cached;
|
|
1601
1663
|
const fix = {
|
|
1602
|
-
kind:
|
|
1664
|
+
kind: "removeAttribute",
|
|
1665
|
+
attribute: attr,
|
|
1603
1666
|
apply: ({ props }) => {
|
|
1604
1667
|
if (!(attr in props)) return { applied: false, next: props };
|
|
1605
1668
|
return { applied: true, next: omitProp(props, attr), previous: props };
|
|
@@ -1870,7 +1933,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1870
1933
|
if (!impliedLive) return NO_VIOLATIONS2;
|
|
1871
1934
|
if ("aria-live" in props) return NO_VIOLATIONS2;
|
|
1872
1935
|
const injectLive = {
|
|
1873
|
-
kind:
|
|
1936
|
+
kind: "injectLive",
|
|
1937
|
+
attribute: "aria-live",
|
|
1874
1938
|
apply: (ctx) => ({
|
|
1875
1939
|
applied: true,
|
|
1876
1940
|
next: { ...ctx.props, "aria-live": impliedLive },
|
|
@@ -1939,6 +2003,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1939
2003
|
}
|
|
1940
2004
|
};
|
|
1941
2005
|
|
|
2006
|
+
// ../../lib/contract/src/aria/factories.ts
|
|
2007
|
+
function removeProp(props, key) {
|
|
2008
|
+
const next = { ...props };
|
|
2009
|
+
delete next[key];
|
|
2010
|
+
return next;
|
|
2011
|
+
}
|
|
2012
|
+
function removeAttributeFix(attribute) {
|
|
2013
|
+
return Object.freeze({
|
|
2014
|
+
kind: "removeAttribute",
|
|
2015
|
+
attribute,
|
|
2016
|
+
apply: ({ props }) => {
|
|
2017
|
+
if (!(attribute in props)) return { applied: false, next: props };
|
|
2018
|
+
return { applied: true, next: removeProp(props, attribute), previous: props };
|
|
2019
|
+
}
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
|
|
1942
2023
|
// ../../lib/contract/src/children/get-type-name.ts
|
|
1943
2024
|
function getTypeName(value) {
|
|
1944
2025
|
if (value === null) return "null";
|
|
@@ -2257,22 +2338,6 @@ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
|
|
|
2257
2338
|
|
|
2258
2339
|
// ../core/src/html/contracts/categories.ts
|
|
2259
2340
|
var METADATA_TAGS = ["script", "template"];
|
|
2260
|
-
var VOID_TAGS = [
|
|
2261
|
-
"area",
|
|
2262
|
-
"base",
|
|
2263
|
-
"br",
|
|
2264
|
-
"col",
|
|
2265
|
-
"embed",
|
|
2266
|
-
"hr",
|
|
2267
|
-
"img",
|
|
2268
|
-
"input",
|
|
2269
|
-
"link",
|
|
2270
|
-
"meta",
|
|
2271
|
-
"param",
|
|
2272
|
-
"source",
|
|
2273
|
-
"track",
|
|
2274
|
-
"wbr"
|
|
2275
|
-
];
|
|
2276
2341
|
var TEXT_ONLY_TAGS = [
|
|
2277
2342
|
"option",
|
|
2278
2343
|
"script",
|
|
@@ -2396,20 +2461,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
|
|
|
2396
2461
|
|
|
2397
2462
|
// ../core/src/html/spec/validators/attribute-type-validator.ts
|
|
2398
2463
|
var DEFAULT_INPUT_TYPE = "text";
|
|
2399
|
-
function omit(props, key) {
|
|
2400
|
-
const next = { ...props };
|
|
2401
|
-
delete next[key];
|
|
2402
|
-
return next;
|
|
2403
|
-
}
|
|
2404
|
-
function removeAttributeFix(attribute) {
|
|
2405
|
-
return {
|
|
2406
|
-
kind: `removeAttribute:${attribute}`,
|
|
2407
|
-
apply: ({ props }) => {
|
|
2408
|
-
if (!(attribute in props)) return { applied: false, next: props };
|
|
2409
|
-
return { applied: true, next: omit(props, attribute), previous: props };
|
|
2410
|
-
}
|
|
2411
|
-
};
|
|
2412
|
-
}
|
|
2413
2464
|
function createInputAttributeTypeRule({
|
|
2414
2465
|
attribute,
|
|
2415
2466
|
allowedTypes
|
|
@@ -2862,7 +2913,7 @@ function getChildProp(child, key) {
|
|
|
2862
2913
|
if (!isVNodeLike(child)) return void 0;
|
|
2863
2914
|
const { props } = child;
|
|
2864
2915
|
if (!isObject(props)) return void 0;
|
|
2865
|
-
return props
|
|
2916
|
+
return Reflect.get(props, key);
|
|
2866
2917
|
}
|
|
2867
2918
|
|
|
2868
2919
|
// ../core/src/html/contracts/aria/landmarks.ts
|
|
@@ -2915,6 +2966,13 @@ function isLabelableControl(child) {
|
|
|
2915
2966
|
const type = getChildProp(child, "type");
|
|
2916
2967
|
return !isString(type) || type !== "hidden";
|
|
2917
2968
|
}
|
|
2969
|
+
function hasAccessibleNameProp(props) {
|
|
2970
|
+
return "aria-label" in props || "aria-labelledby" in props;
|
|
2971
|
+
}
|
|
2972
|
+
function isNonEmptyTextChild(child) {
|
|
2973
|
+
if (isNumber(child)) return true;
|
|
2974
|
+
return isString(child) && child.trim().length > 0;
|
|
2975
|
+
}
|
|
2918
2976
|
var labelContract = contract([
|
|
2919
2977
|
{ name: "control", match: isLabelableControl, cardinality: { max: 1 } },
|
|
2920
2978
|
{ name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
|
|
@@ -2922,6 +2980,13 @@ var labelContract = contract([
|
|
|
2922
2980
|
name: "other-interactive-content",
|
|
2923
2981
|
match: isTag(...OTHER_INTERACTIVE_TAGS),
|
|
2924
2982
|
cardinality: { max: 0 }
|
|
2983
|
+
},
|
|
2984
|
+
{
|
|
2985
|
+
name: "accessible-name",
|
|
2986
|
+
match: isNonEmptyTextChild,
|
|
2987
|
+
cardinality: dynamic(
|
|
2988
|
+
(ctx) => hasAccessibleNameProp(ctx.props) ? { min: 0 } : { min: 1 }
|
|
2989
|
+
)
|
|
2925
2990
|
}
|
|
2926
2991
|
]);
|
|
2927
2992
|
|
|
@@ -3545,6 +3610,13 @@ function buildRuntime(options) {
|
|
|
3545
3610
|
return built;
|
|
3546
3611
|
}
|
|
3547
3612
|
|
|
3613
|
+
// ../../adapters/vue/src/is-polymorphic-component.ts
|
|
3614
|
+
function isPolymorphicComponent(value) {
|
|
3615
|
+
if (!isObject(value)) return false;
|
|
3616
|
+
if (!("displayName" in value)) return true;
|
|
3617
|
+
return value.displayName === void 0 || isString(value.displayName);
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3548
3620
|
// ../../adapters/vue/src/render.ts
|
|
3549
3621
|
import { cloneVNode, h as h3 } from "vue";
|
|
3550
3622
|
|
|
@@ -3643,7 +3715,7 @@ function prepareRenderState(runtime, attrs, filterProps) {
|
|
|
3643
3715
|
className
|
|
3644
3716
|
};
|
|
3645
3717
|
}
|
|
3646
|
-
function buildElementProps(props, className) {
|
|
3718
|
+
function buildElementProps(props, className, elementRef) {
|
|
3647
3719
|
const { role, ...rest } = props;
|
|
3648
3720
|
return {
|
|
3649
3721
|
...normalizeListenerKeys(rest),
|
|
@@ -3651,11 +3723,17 @@ function buildElementProps(props, className) {
|
|
|
3651
3723
|
// normalizeClass turns it into '' and still emits class="", while the client patcher
|
|
3652
3724
|
// removes the attribute outright. Omitting the key entirely keeps both paths consistent.
|
|
3653
3725
|
...className !== void 0 && { class: className },
|
|
3654
|
-
...isKnownAriaRole(role) && { role }
|
|
3726
|
+
...isKnownAriaRole(role) && { role },
|
|
3727
|
+
// Vue calls a function-ref with the element on mount and with null on unmount, same
|
|
3728
|
+
// contract as React/Preact's callback refs — a natural fit for FactoryOptions.onElement.
|
|
3729
|
+
// Cast: Vue's own VNodeRef type also accepts a resolved *component* instance, since refs
|
|
3730
|
+
// can target components as well as elements — irrelevant here, this is only ever attached
|
|
3731
|
+
// to an intrinsic host tag, which always resolves to a real Element.
|
|
3732
|
+
...elementRef !== void 0 && { ref: elementRef }
|
|
3655
3733
|
};
|
|
3656
3734
|
}
|
|
3657
|
-
function renderIntrinsic(state, runtime, slots) {
|
|
3658
|
-
const elementProps = buildElementProps(state.props, state.className);
|
|
3735
|
+
function renderIntrinsic(state, runtime, slots, elementRef) {
|
|
3736
|
+
const elementProps = buildElementProps(state.props, state.className, elementRef);
|
|
3659
3737
|
const domProps = runtime.resolveAria(state.tag, elementProps).props;
|
|
3660
3738
|
return h3(state.tag, domProps, slots.default ? { default: slots.default } : void 0);
|
|
3661
3739
|
}
|
|
@@ -3668,12 +3746,13 @@ function validateSlotDirectives(directives, validator) {
|
|
|
3668
3746
|
}
|
|
3669
3747
|
return true;
|
|
3670
3748
|
}
|
|
3671
|
-
function tryRenderAsChild(state, children, discarded, validator) {
|
|
3749
|
+
function tryRenderAsChild(state, children, discarded, validator, elementRef) {
|
|
3672
3750
|
if (!validateSlotDirectives(state.directives, validator)) return null;
|
|
3673
3751
|
if (discarded > 0) validator.warnDiscardedChildren(discarded);
|
|
3674
3752
|
const attrs = {
|
|
3675
3753
|
...pickAttributes(state.props),
|
|
3676
|
-
...state.className !== void 0 && { class: state.className }
|
|
3754
|
+
...state.className !== void 0 && { class: state.className },
|
|
3755
|
+
...elementRef !== void 0 && { ref: elementRef }
|
|
3677
3756
|
};
|
|
3678
3757
|
const slottable = extractSlottable(children);
|
|
3679
3758
|
if (slottable) return slottable.rebuild(cloneVNode(slottable.child, attrs));
|
|
@@ -3688,20 +3767,31 @@ function render({
|
|
|
3688
3767
|
state,
|
|
3689
3768
|
slots,
|
|
3690
3769
|
slotValidator,
|
|
3691
|
-
childrenEvaluator
|
|
3770
|
+
childrenEvaluator,
|
|
3771
|
+
elementRef
|
|
3692
3772
|
}) {
|
|
3693
3773
|
const { vnodes: children, discarded } = normalizeChildren(slots);
|
|
3694
3774
|
if (process.env.NODE_ENV !== "production") {
|
|
3695
3775
|
childrenEvaluator?.evaluate(children, { tag: state.tag, props: state.normalizedProps });
|
|
3696
|
-
runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(children);
|
|
3776
|
+
runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(children, { tag: state.tag, props: state.normalizedProps });
|
|
3697
3777
|
}
|
|
3698
|
-
const slotResult = tryRenderAsChild(state, children, discarded, slotValidator);
|
|
3699
|
-
return slotResult ?? renderIntrinsic(state, runtime, slots);
|
|
3778
|
+
const slotResult = tryRenderAsChild(state, children, discarded, slotValidator, elementRef);
|
|
3779
|
+
return slotResult ?? renderIntrinsic(state, runtime, slots, elementRef);
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
// ../../adapters/vue/src/to-vue-factory-options.ts
|
|
3783
|
+
var VUE_FIELD_VALIDATORS = {
|
|
3784
|
+
filterProps: (v) => v === void 0 || isFunction(v)
|
|
3785
|
+
};
|
|
3786
|
+
function isVueFactoryOptions(options) {
|
|
3787
|
+
return isFactoryOptionsLike(options, VUE_FIELD_VALIDATORS);
|
|
3700
3788
|
}
|
|
3701
3789
|
|
|
3702
3790
|
// ../../adapters/vue/src/create-contract-component.ts
|
|
3703
3791
|
function createContractComponent(options) {
|
|
3792
|
+
invariant(isVueFactoryOptions(options), "options is not a valid VueFactoryOptions object");
|
|
3704
3793
|
const bundle = buildRuntime(options);
|
|
3794
|
+
const { onElement } = options;
|
|
3705
3795
|
const Component = defineComponent2({
|
|
3706
3796
|
// normalizeOptions always supplies `name`, so displayName is always defined here —
|
|
3707
3797
|
// the fallback only satisfies the type, which allows it to be absent in general.
|
|
@@ -3711,15 +3801,33 @@ function createContractComponent(options) {
|
|
|
3711
3801
|
const state = computed(
|
|
3712
3802
|
() => prepareRenderState(bundle.runtime, attrs, bundle.filterProps)
|
|
3713
3803
|
);
|
|
3714
|
-
|
|
3804
|
+
let cleanup;
|
|
3805
|
+
let boundElement = null;
|
|
3806
|
+
const onElementRef = onElement ? (element) => {
|
|
3807
|
+
if (element === boundElement) return;
|
|
3808
|
+
if (boundElement) {
|
|
3809
|
+
cleanup?.();
|
|
3810
|
+
cleanup = void 0;
|
|
3811
|
+
}
|
|
3812
|
+
boundElement = element;
|
|
3813
|
+
if (element) {
|
|
3814
|
+
cleanup = onElement(element, () => attrs) ?? void 0;
|
|
3815
|
+
}
|
|
3816
|
+
} : void 0;
|
|
3817
|
+
return () => render({ ...bundle, state: state.value, slots, elementRef: onElementRef });
|
|
3715
3818
|
}
|
|
3716
3819
|
});
|
|
3717
3820
|
applyDisplayName(Component, options.name);
|
|
3718
|
-
const
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3821
|
+
const assembled = finalizeComponent(
|
|
3822
|
+
Component,
|
|
3823
|
+
bundle.runtime.options.defaultTag,
|
|
3824
|
+
options.subComponents
|
|
3825
|
+
);
|
|
3826
|
+
invariant(
|
|
3827
|
+
isPolymorphicComponent(assembled),
|
|
3828
|
+
"Generated component failed to satisfy the PolymorphicComponent shape"
|
|
3829
|
+
);
|
|
3830
|
+
return assembled;
|
|
3723
3831
|
}
|
|
3724
3832
|
export {
|
|
3725
3833
|
Slottable,
|
package/dist/web/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagno
|
|
|
4
4
|
type StringMap<T = unknown> = Record<string, T>;
|
|
5
5
|
type AnyRecord = StringMap<unknown>;
|
|
6
6
|
type EmptyRecord = Record<never, never>;
|
|
7
|
+
/** A compound component's named sub-components, e.g. `{ Header, Content, Footer }`. */
|
|
8
|
+
type SubComponentMap = Readonly<AnyRecord>;
|
|
7
9
|
|
|
8
10
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
9
11
|
|
|
@@ -178,8 +180,8 @@ type AriaContext = {
|
|
|
178
180
|
readonly props: ReadonlyDeep<IntrinsicProps>;
|
|
179
181
|
};
|
|
180
182
|
|
|
181
|
-
type RemoveAttributeFixKind =
|
|
182
|
-
type InjectLiveFixKind =
|
|
183
|
+
type RemoveAttributeFixKind = 'removeAttribute';
|
|
184
|
+
type InjectLiveFixKind = 'injectLive';
|
|
183
185
|
type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
|
|
184
186
|
|
|
185
187
|
type AriaFixResult = {
|
|
@@ -192,6 +194,9 @@ type AriaFixResult = {
|
|
|
192
194
|
};
|
|
193
195
|
type AriaFix = {
|
|
194
196
|
readonly kind: FixKind;
|
|
197
|
+
/** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
|
|
198
|
+
* kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
|
|
199
|
+
readonly attribute?: string;
|
|
195
200
|
readonly priority?: number;
|
|
196
201
|
readonly source?: string;
|
|
197
202
|
readonly apply: (context: AriaContext) => AriaFixResult;
|
|
@@ -285,6 +290,30 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
285
290
|
* be set directly by component authors — use `enforcement.diagnostics` to override per component.
|
|
286
291
|
*/
|
|
287
292
|
readonly diagnostics?: Diagnostics;
|
|
293
|
+
/**
|
|
294
|
+
* Sub-components to attach to the generated root component, producing a
|
|
295
|
+
* compound component API (for example, `Card.Header`, `Card.Content`,
|
|
296
|
+
* and `Card.Footer`). Purely additive — has no effect on
|
|
297
|
+
* `enforcement.children`; author child rules explicitly if the component
|
|
298
|
+
* needs to validate its children.
|
|
299
|
+
*/
|
|
300
|
+
readonly subComponents?: SubComponentMap;
|
|
301
|
+
/**
|
|
302
|
+
* Called once per instance, when the real underlying DOM element first
|
|
303
|
+
* exists, in every adapter — via that adapter's own native mount
|
|
304
|
+
* lifecycle, never through the props/attribute pipeline. Use this for
|
|
305
|
+
* wiring that needs the actual element (native imperative methods like
|
|
306
|
+
* `dialogEl.showModal()`, native events like `close`/`cancel` that have
|
|
307
|
+
* no prop-based equivalent), not for anything expressible as a plain
|
|
308
|
+
* prop.
|
|
309
|
+
*
|
|
310
|
+
* `getProps` returns the instance's *current* resolved props at call
|
|
311
|
+
* time — read it from inside a listener registered once at mount, rather
|
|
312
|
+
* than re-subscribing on every prop change.
|
|
313
|
+
*
|
|
314
|
+
* Return a cleanup function to run when the instance unmounts.
|
|
315
|
+
*/
|
|
316
|
+
readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
|
|
288
317
|
};
|
|
289
318
|
|
|
290
319
|
type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
@@ -349,7 +378,9 @@ type WebContractComponent<TVariants extends Readonly<VariantMap> = Readonly<Empt
|
|
|
349
378
|
* For non-reactive attributes (`aria-*`, `role`, `data-*`) call `element.update()`
|
|
350
379
|
* after setting them to trigger an explicit pipeline re-run.
|
|
351
380
|
*/
|
|
352
|
-
declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<TVariants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory>(options: WebFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin>
|
|
381
|
+
declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<TVariants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: WebFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
|
|
382
|
+
readonly subComponents?: TSubComponents;
|
|
383
|
+
}): WebContractComponent<TVariants, ExtractPluginProps<TPlugin>> & TSubComponents;
|
|
353
384
|
|
|
354
385
|
/**
|
|
355
386
|
* Renders a praxis-kit web component to an HTML string without requiring a DOM.
|