praxis-kit 7.0.0 → 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.
@@ -5,6 +5,8 @@ import { ComponentChildren, VNode, ComponentType, JSX, Ref } from 'preact';
5
5
  type StringMap<T = unknown> = Record<string, T>;
6
6
  type AnyRecord = StringMap<unknown>;
7
7
  type EmptyRecord = Record<never, never>;
8
+ /** A compound component's named sub-components, e.g. `{ Header, Content, Footer }`. */
9
+ type SubComponentMap = Readonly<AnyRecord>;
8
10
 
9
11
  type IntrinsicTag = keyof HTMLElementTagNameMap;
10
12
 
@@ -306,6 +308,30 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
306
308
  * be set directly by component authors — use `enforcement.diagnostics` to override per component.
307
309
  */
308
310
  readonly diagnostics?: Diagnostics;
311
+ /**
312
+ * Sub-components to attach to the generated root component, producing a
313
+ * compound component API (for example, `Card.Header`, `Card.Content`,
314
+ * and `Card.Footer`). Purely additive — has no effect on
315
+ * `enforcement.children`; author child rules explicitly if the component
316
+ * needs to validate its children.
317
+ */
318
+ readonly subComponents?: SubComponentMap;
319
+ /**
320
+ * Called once per instance, when the real underlying DOM element first
321
+ * exists, in every adapter — via that adapter's own native mount
322
+ * lifecycle, never through the props/attribute pipeline. Use this for
323
+ * wiring that needs the actual element (native imperative methods like
324
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
325
+ * no prop-based equivalent), not for anything expressible as a plain
326
+ * prop.
327
+ *
328
+ * `getProps` returns the instance's *current* resolved props at call
329
+ * time — read it from inside a listener registered once at mount, rather
330
+ * than re-subscribing on every prop change.
331
+ *
332
+ * Return a cleanup function to run when the instance unmounts.
333
+ */
334
+ readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
309
335
  };
310
336
 
311
337
  declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
@@ -362,6 +388,8 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
362
388
  displayName?: string;
363
389
  };
364
390
 
365
- declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory>(options: PreactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin>): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>>;
391
+ declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: PreactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
392
+ readonly subComponents?: TSubComponents;
393
+ }): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>> & TSubComponents;
366
394
 
367
395
  export { type AnyFactoryOptions, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type PolymorphicWithAsChild, type PreactFactoryOptions, Slottable, createContractComponent, defineContractComponent };
@@ -1,3 +1,27 @@
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
+
9
+ // ../../lib/adapter-utils/src/runtime/apply-display-name.ts
10
+ function applyDisplayName(component, name) {
11
+ Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
12
+ }
13
+
14
+ // ../../lib/adapter-utils/src/runtime/define-component.ts
15
+ function defineContractComponent(options) {
16
+ return (factory) => factory(options);
17
+ }
18
+
19
+ // ../../lib/adapter-utils/src/runtime/assemble-compound-component.ts
20
+ function assembleCompoundComponent(root, subComponents) {
21
+ if (!subComponents) return root;
22
+ return Object.assign(root, subComponents);
23
+ }
24
+
1
25
  // ../../lib/primitive/src/tag/resolve-tag.ts
2
26
  function makeResolveTag(defaultTag) {
3
27
  return function tag(as) {
@@ -54,7 +78,7 @@ function isPlainObject(value) {
54
78
 
55
79
  // ../../lib/primitive/src/rule/is-dynamic-rule.ts
56
80
  function isDynamicRule(rule) {
57
- return isObject(rule, true) && rule[RULE_BRAND] === true;
81
+ return isObject(rule, true) && Reflect.get(rule, RULE_BRAND) === true;
58
82
  }
59
83
 
60
84
  // ../../lib/primitive/src/rule/resolve-rule.ts
@@ -703,17 +727,17 @@ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default
703
727
  // ../../lib/primitive/src/guards/children/is-tag.ts
704
728
  function getAsProp(child) {
705
729
  if (!isObject(child) || !("props" in child)) return void 0;
706
- const props = child.props;
730
+ const { props } = child;
707
731
  if (!isObject(props)) return void 0;
708
- const as = props.as;
732
+ const as = Reflect.get(props, "as");
709
733
  return isString(as) && as !== "" ? as : void 0;
710
734
  }
711
735
  function getTag(child) {
712
736
  if (!isObject(child) || !("type" in child)) return void 0;
713
- const t = child.type;
737
+ const { type: t } = child;
714
738
  if (isString(t)) return t;
715
739
  if (typeof t === "function" || isObject(t)) {
716
- const defaultTag = t[COMPONENT_DEFAULT_TAG];
740
+ const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
717
741
  if (!isString(defaultTag)) return void 0;
718
742
  return getAsProp(child) ?? defaultTag;
719
743
  }
@@ -733,25 +757,34 @@ function isTag(...args) {
733
757
  return tag !== void 0 && set2.has(tag);
734
758
  }
735
759
 
736
- // ../../adapters/preact/src/create-contract-component.ts
737
- import { forwardRef as forwardRef2 } from "preact/compat";
738
-
739
- // ../../lib/adapter-utils/src/invariant.ts
740
- function panic(message) {
741
- throw new Error(message);
742
- }
743
- function invariant(condition, message) {
744
- if (!condition) panic(message);
745
- }
746
-
747
- // ../../lib/adapter-utils/src/runtime/apply-display-name.ts
748
- function applyDisplayName(component, name) {
749
- Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
750
- }
751
-
752
- // ../../lib/adapter-utils/src/runtime/define-component.ts
753
- function defineContractComponent(options) {
754
- return (factory) => factory(options);
760
+ // ../../lib/adapter-utils/src/runtime/finalize-component.ts
761
+ function finalizeComponent(component, defaultTag, subComponents) {
762
+ if (typeof defaultTag === "string") {
763
+ Object.assign(component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
764
+ }
765
+ return assembleCompoundComponent(component, subComponents);
766
+ }
767
+
768
+ // ../../lib/adapter-utils/src/runtime/is-factory-options-like.ts
769
+ var FACTORY_OPTIONS_FIELD_VALIDATORS = {
770
+ tag: (v) => v === void 0 || isString(v),
771
+ name: (v) => v === void 0 || isString(v),
772
+ defaults: (v) => v === void 0 || isObject(v),
773
+ normalize: (v) => v === void 0 || isFunction(v),
774
+ styling: (v) => v === void 0 || isObject(v),
775
+ enforcement: (v) => v === void 0 || isObject(v),
776
+ diagnostics: (v) => v === void 0 || isObject(v),
777
+ subComponents: (v) => v === void 0 || isObject(v),
778
+ onElement: (v) => v === void 0 || isFunction(v)
779
+ };
780
+ function isFactoryOptionsLike(options, extraFieldValidators) {
781
+ if (!isObject(options)) return false;
782
+ const validators = { ...FACTORY_OPTIONS_FIELD_VALIDATORS, ...extraFieldValidators };
783
+ for (const [key, value] of Object.entries(options)) {
784
+ const validate = validators[key];
785
+ if (!validate || !validate(value)) return false;
786
+ }
787
+ return true;
755
788
  }
756
789
 
757
790
  // ../../lib/contract/src/aria/aria-role-policy.ts
@@ -2904,7 +2937,7 @@ function getChildProp(child, key) {
2904
2937
  if (!isVNodeLike(child)) return void 0;
2905
2938
  const { props } = child;
2906
2939
  if (!isObject(props)) return void 0;
2907
- return props[key];
2940
+ return Reflect.get(props, key);
2908
2941
  }
2909
2942
 
2910
2943
  // ../core/src/html/contracts/aria/landmarks.ts
@@ -3619,6 +3652,10 @@ function applyMergePolicy(key, slotVal, childVal) {
3619
3652
  return policyHandlers[classifyProp(key, slotVal, childVal)](slotVal, childVal);
3620
3653
  }
3621
3654
 
3655
+ // ../../adapters/preact/src/create-contract-component.ts
3656
+ import { forwardRef as forwardRef2 } from "preact/compat";
3657
+ import { useCallback, useRef } from "preact/hooks";
3658
+
3622
3659
  // ../../adapters/preact/src/render.tsx
3623
3660
  import { h as h2 } from "preact";
3624
3661
 
@@ -3881,18 +3918,54 @@ function buildRuntime(options) {
3881
3918
  return built;
3882
3919
  }
3883
3920
 
3921
+ // ../../adapters/preact/src/is-polymorphic-component.ts
3922
+ function isPolymorphicComponent(value) {
3923
+ if (!isFunction(value)) return false;
3924
+ if (!("displayName" in value)) return true;
3925
+ return value.displayName === void 0 || isString(value.displayName);
3926
+ }
3927
+
3928
+ // ../../adapters/preact/src/to-preact-factory-options.ts
3929
+ var PREACT_FIELD_VALIDATORS = {
3930
+ slotComponent: (v) => v === void 0 || isFunction(v) || isObject(v),
3931
+ filterProps: (v) => v === void 0 || isFunction(v)
3932
+ };
3933
+ function isPreactFactoryOptions(options) {
3934
+ return isFactoryOptionsLike(options, PREACT_FIELD_VALIDATORS);
3935
+ }
3936
+
3884
3937
  // ../../adapters/preact/src/create-contract-component.ts
3885
3938
  function createContractComponent(options) {
3939
+ invariant(isPreactFactoryOptions(options), "options is not a valid PreactFactoryOptions object");
3886
3940
  const bundle = buildRuntime(options);
3941
+ const { onElement } = options;
3887
3942
  const Component = forwardRef2(function Component2(props, ref) {
3888
- return render({ ...bundle, props, ref: ref ?? null });
3943
+ const propsRef = useRef(props);
3944
+ propsRef.current = props;
3945
+ const cleanupRef = useRef(void 0);
3946
+ const onElementRef = useCallback((el) => {
3947
+ if (!onElement) return;
3948
+ if (el) {
3949
+ cleanupRef.current = onElement(el, () => propsRef.current) ?? void 0;
3950
+ } else {
3951
+ cleanupRef.current?.();
3952
+ cleanupRef.current = void 0;
3953
+ }
3954
+ }, []);
3955
+ const mergedRef = onElement ? mergeRefs(ref, onElementRef) : ref;
3956
+ return render({ ...bundle, props, ref: mergedRef });
3889
3957
  });
3890
3958
  applyDisplayName(Component, options.name);
3891
- const defaultTag = bundle.runtime.options.defaultTag;
3892
- if (typeof defaultTag === "string") {
3893
- Object.assign(Component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
3894
- }
3895
- return Component;
3959
+ const assembled = finalizeComponent(
3960
+ Component,
3961
+ bundle.runtime.options.defaultTag,
3962
+ options.subComponents
3963
+ );
3964
+ invariant(
3965
+ isPolymorphicComponent(assembled),
3966
+ "Generated component failed to satisfy the PolymorphicComponent shape"
3967
+ );
3968
+ return assembled;
3896
3969
  }
3897
3970
  export {
3898
3971
  Slottable,
@@ -1,5 +1,5 @@
1
- import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-Cm99IE5J.js';
2
- export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, m as composeRefs, l as defineContractComponent, m as mergeRefs } from '../react-options-Cm99IE5J.js';
1
+ import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as AnyRecord, c as ReactFactoryOptions, P as PolymorphicComponent, d as PolymorphicGenerics, e as ExtractPluginProps } from '../react-options-DLDsA4Tn.js';
2
+ export { f as AnyFactoryOptions, g as ElementRef, F as FactoryOptions, h as PolymorphicProps, i as PolymorphicWithAsChild, j as PolymorphicWithRender, k as RenderCallbackProps, S as Slottable, l as SlottableProps, m as composeRefs, n as defineContractComponent, m as mergeRefs } from '../react-options-DLDsA4Tn.js';
3
3
  import * as react from 'react';
4
4
  import { ReactElement, Ref } from 'react';
5
5
  import 'type-fest';
@@ -22,7 +22,9 @@ type CloneInput = {
22
22
  ref: NormalizedRef;
23
23
  };
24
24
 
25
- declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType>(options: ReactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin, TAllowed>): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset, TAllowed>>;
25
+ declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: ReactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin, TAllowed> & {
26
+ readonly subComponents?: TSubComponents;
27
+ }): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset, TAllowed>> & TSubComponents;
26
28
 
27
29
  type SlotProps = {
28
30
  ref?: Ref<unknown> | null;
@@ -1,18 +1,24 @@
1
1
  import {
2
- COMPONENT_DEFAULT_TAG,
3
2
  SLOT_NAME,
4
3
  Slottable,
5
4
  applyDisplayName,
6
5
  applySlot,
7
6
  buildRuntime,
8
7
  defineContractComponent,
8
+ finalizeComponent,
9
9
  getElementRef,
10
10
  getPropsRef,
11
11
  hasWarningGetter,
12
+ invariant,
13
+ isPolymorphicComponent,
14
+ isReactFactoryOptions,
12
15
  makeCloneSlotChild,
13
16
  mergeRefs,
14
17
  render
15
- } from "../chunk-35CJAOJW.js";
18
+ } from "../chunk-EIKPSL26.js";
19
+
20
+ // ../../adapters/react/src/current/create-contract-component.ts
21
+ import { useCallback, useRef } from "react";
16
22
 
17
23
  // ../../adapters/react/src/current/slot/composeRefs.ts
18
24
  function getChildRef(element) {
@@ -43,16 +49,36 @@ function buildRuntime2(options) {
43
49
 
44
50
  // ../../adapters/react/src/current/create-contract-component.ts
45
51
  function createContractComponent(options) {
52
+ invariant(isReactFactoryOptions(options), "options is not a valid ReactFactoryOptions object");
46
53
  const bundle = buildRuntime2(options);
54
+ const { onElement } = options;
47
55
  function Component({ ref, ...props }) {
48
- return render({ ...bundle, props, ref: ref ?? null });
56
+ const propsRef = useRef(props);
57
+ propsRef.current = props;
58
+ const cleanupRef = useRef(void 0);
59
+ const onElementRef = useCallback((el) => {
60
+ if (!onElement) return;
61
+ if (el) {
62
+ cleanupRef.current = onElement(el, () => propsRef.current) ?? void 0;
63
+ } else {
64
+ cleanupRef.current?.();
65
+ cleanupRef.current = void 0;
66
+ }
67
+ }, []);
68
+ const mergedRef = onElement ? mergeRefs(ref, onElementRef) : ref;
69
+ return render({ ...bundle, props, ref: mergedRef ?? null });
49
70
  }
50
71
  applyDisplayName(Component, options.name);
51
- const defaultTag = bundle.runtime.options.defaultTag;
52
- if (typeof defaultTag === "string") {
53
- Object.assign(Component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
54
- }
55
- return Component;
72
+ const assembled = finalizeComponent(
73
+ Component,
74
+ bundle.runtime.options.defaultTag,
75
+ options.subComponents
76
+ );
77
+ invariant(
78
+ isPolymorphicComponent(assembled),
79
+ "Generated component failed to satisfy the PolymorphicComponent shape"
80
+ );
81
+ return assembled;
56
82
  }
57
83
  export {
58
84
  Slot,
@@ -1,5 +1,5 @@
1
- import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-Cm99IE5J.js';
2
- export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, l as defineContractComponent, m as mergeRefs } from '../react-options-Cm99IE5J.js';
1
+ import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, c as ReactFactoryOptions, P as PolymorphicComponent, d as PolymorphicGenerics, e as ExtractPluginProps } from '../react-options-DLDsA4Tn.js';
2
+ export { f as AnyFactoryOptions, g as ElementRef, F as FactoryOptions, h as PolymorphicProps, i as PolymorphicWithAsChild, j as PolymorphicWithRender, k as RenderCallbackProps, S as Slottable, l as SlottableProps, n as defineContractComponent, m as mergeRefs } from '../react-options-DLDsA4Tn.js';
3
3
  import * as react from 'react';
4
4
  import 'type-fest';
5
5
  import '../_shared/diagnostics.js';
@@ -13,10 +13,10 @@ import {
13
13
  makeCloneSlotChild,
14
14
  mergeRefs,
15
15
  render
16
- } from "../chunk-35CJAOJW.js";
16
+ } from "../chunk-EIKPSL26.js";
17
17
 
18
18
  // ../../adapters/react/src/legacy/create-contract-component.ts
19
- import { forwardRef as forwardRef2 } from "react";
19
+ import { forwardRef as forwardRef2, useCallback, useRef } from "react";
20
20
 
21
21
  // ../../adapters/react/src/legacy/slot/Slot.tsx
22
22
  import { forwardRef } from "react";
@@ -49,8 +49,22 @@ function buildRuntime2(options) {
49
49
  // ../../adapters/react/src/legacy/create-contract-component.ts
50
50
  function createContractComponent(options) {
51
51
  const bundle = buildRuntime2(options);
52
+ const { onElement } = options;
52
53
  const Component = forwardRef2(function Component2(props, ref) {
53
- return render({ ...bundle, props, ref });
54
+ const propsRef = useRef(props);
55
+ propsRef.current = props;
56
+ const cleanupRef = useRef(void 0);
57
+ const onElementRef = useCallback((el) => {
58
+ if (!onElement) return;
59
+ if (el) {
60
+ cleanupRef.current = onElement(el, () => propsRef.current) ?? void 0;
61
+ } else {
62
+ cleanupRef.current?.();
63
+ cleanupRef.current = void 0;
64
+ }
65
+ }, []);
66
+ const mergedRef = onElement ? mergeRefs(ref, onElementRef) : ref;
67
+ return render({ ...bundle, props, ref: mergedRef });
54
68
  });
55
69
  applyDisplayName(Component, options.name);
56
70
  const defaultTag = bundle.runtime.options.defaultTag;
@@ -5,6 +5,8 @@ import { Diagnostics, DiagnosticInput, DiagnosticsMode } from './_shared/diagnos
5
5
  type StringMap<T = unknown> = Record<string, T>;
6
6
  type AnyRecord = StringMap<unknown>;
7
7
  type EmptyRecord = Record<never, never>;
8
+ /** A compound component's named sub-components, e.g. `{ Header, Content, Footer }`. */
9
+ type SubComponentMap = Readonly<AnyRecord>;
8
10
 
9
11
  type IntrinsicTag = keyof HTMLElementTagNameMap;
10
12
 
@@ -307,6 +309,30 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
307
309
  * be set directly by component authors — use `enforcement.diagnostics` to override per component.
308
310
  */
309
311
  readonly diagnostics?: Diagnostics;
312
+ /**
313
+ * Sub-components to attach to the generated root component, producing a
314
+ * compound component API (for example, `Card.Header`, `Card.Content`,
315
+ * and `Card.Footer`). Purely additive — has no effect on
316
+ * `enforcement.children`; author child rules explicitly if the component
317
+ * needs to validate its children.
318
+ */
319
+ readonly subComponents?: SubComponentMap;
320
+ /**
321
+ * Called once per instance, when the real underlying DOM element first
322
+ * exists, in every adapter — via that adapter's own native mount
323
+ * lifecycle, never through the props/attribute pipeline. Use this for
324
+ * wiring that needs the actual element (native imperative methods like
325
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
326
+ * no prop-based equivalent), not for anything expressible as a plain
327
+ * prop.
328
+ *
329
+ * `getProps` returns the instance's *current* resolved props at call
330
+ * time — read it from inside a listener registered once at mount, rather
331
+ * than re-subscribing on every prop change.
332
+ *
333
+ * Return a cleanup function to run when the instance unmounts.
334
+ */
335
+ readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
310
336
  };
311
337
 
312
338
  type MetadataMap = AnyRecord;
@@ -521,4 +547,4 @@ type ReactFactoryOptions<TDefault extends ElementType, Props extends UnknownProp
521
547
  artifact?: CompiledArtifact;
522
548
  };
523
549
 
524
- export { type AnyClassPluginFactory as A, type ElementType as E, type FactoryOptions as F, type PolymorphicComponent as P, type RecipeMap as R, Slottable as S, type UnknownProps as U, type VariantMap as V, type EmptyRecord as a, type ReactFactoryOptions as b, type PolymorphicGenerics as c, type ExtractPluginProps as d, type AnyFactoryOptions as e, type ElementRef as f, type PolymorphicProps as g, type PolymorphicWithAsChild as h, type PolymorphicWithRender as i, type RenderCallbackProps as j, type SlottableProps as k, defineContractComponent as l, mergeRefs as m };
550
+ export { type AnyClassPluginFactory as A, type ElementType as E, type FactoryOptions as F, type PolymorphicComponent as P, type RecipeMap as R, Slottable as S, type UnknownProps as U, type VariantMap as V, type EmptyRecord as a, type AnyRecord as b, type ReactFactoryOptions as c, type PolymorphicGenerics as d, type ExtractPluginProps as e, type AnyFactoryOptions as f, type ElementRef as g, type PolymorphicProps as h, type PolymorphicWithAsChild as i, type PolymorphicWithRender as j, type RenderCallbackProps as k, type SlottableProps as l, mergeRefs as m, defineContractComponent as n };
@@ -5,6 +5,8 @@ import { JSX } from 'solid-js';
5
5
  type StringMap<T = unknown> = Record<string, T>;
6
6
  type AnyRecord = StringMap<unknown>;
7
7
  type EmptyRecord = Record<never, never>;
8
+ /** A compound component's named sub-components, e.g. `{ Header, Content, Footer }`. */
9
+ type SubComponentMap = Readonly<AnyRecord>;
8
10
 
9
11
  type IntrinsicTag = keyof HTMLElementTagNameMap;
10
12
 
@@ -306,6 +308,30 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
306
308
  * be set directly by component authors — use `enforcement.diagnostics` to override per component.
307
309
  */
308
310
  readonly diagnostics?: Diagnostics;
311
+ /**
312
+ * Sub-components to attach to the generated root component, producing a
313
+ * compound component API (for example, `Card.Header`, `Card.Content`,
314
+ * and `Card.Footer`). Purely additive — has no effect on
315
+ * `enforcement.children`; author child rules explicitly if the component
316
+ * needs to validate its children.
317
+ */
318
+ readonly subComponents?: SubComponentMap;
319
+ /**
320
+ * Called once per instance, when the real underlying DOM element first
321
+ * exists, in every adapter — via that adapter's own native mount
322
+ * lifecycle, never through the props/attribute pipeline. Use this for
323
+ * wiring that needs the actual element (native imperative methods like
324
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
325
+ * no prop-based equivalent), not for anything expressible as a plain
326
+ * prop.
327
+ *
328
+ * `getProps` returns the instance's *current* resolved props at call
329
+ * time — read it from inside a listener registered once at mount, rather
330
+ * than re-subscribing on every prop change.
331
+ *
332
+ * Return a cleanup function to run when the instance unmounts.
333
+ */
334
+ readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
309
335
  };
310
336
 
311
337
  declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
@@ -357,6 +383,8 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
357
383
  displayName?: string;
358
384
  };
359
385
 
360
- declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory>(options: SolidFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin>): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>>;
386
+ declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: SolidFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
387
+ readonly subComponents?: TSubComponents;
388
+ }): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>> & TSubComponents;
361
389
 
362
390
  export { type AnyFactoryOptions, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type SolidFactoryOptions, createContractComponent, defineContractComponent };