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.
@@ -1,3 +1,8 @@
1
+ // ../../lib/primitive/src/guards/foundational/is-defined.ts
2
+ function isDefined(value) {
3
+ return value !== void 0;
4
+ }
5
+
1
6
  // ../../lib/primitive/src/utils/iterate.ts
2
7
  function find(iterable, callback) {
3
8
  for (const value of iterable) {
@@ -168,6 +173,72 @@ var iterate = Object.freeze({
168
173
  values
169
174
  });
170
175
 
176
+ // ../../lib/contract/src/aria/factories.ts
177
+ function invalidWithoutFix(input) {
178
+ return {
179
+ valid: false,
180
+ fixable: false,
181
+ severity: input.severity,
182
+ ...isDefined(input.attribute) && { attribute: input.attribute },
183
+ ...isDefined(input.message) && { message: input.message },
184
+ ...isDefined(input.diagnostic) && { diagnostic: input.diagnostic }
185
+ };
186
+ }
187
+ function invalidWithFix(input) {
188
+ return {
189
+ valid: false,
190
+ fixable: true,
191
+ severity: input.severity,
192
+ ...isDefined(input.attribute) && { attribute: input.attribute },
193
+ ...isDefined(input.message) && { message: input.message },
194
+ ...isDefined(input.diagnostic) && { diagnostic: input.diagnostic },
195
+ fix: input.fix
196
+ };
197
+ }
198
+ function removeProp(props, key) {
199
+ const next = { ...props };
200
+ delete next[key];
201
+ return next;
202
+ }
203
+ function removeAttributeFix(attribute) {
204
+ return Object.freeze({
205
+ kind: "removeAttribute",
206
+ attribute,
207
+ apply: ({ props }) => {
208
+ if (!(attribute in props)) return { applied: false, next: props };
209
+ return { applied: true, next: removeProp(props, attribute), previous: props };
210
+ }
211
+ });
212
+ }
213
+ function defineRuleMetadata(rule, metadata) {
214
+ const descriptors = {};
215
+ for (const key of Object.keys(metadata)) {
216
+ descriptors[key] = { value: metadata[key], enumerable: false };
217
+ }
218
+ Object.defineProperties(rule, descriptors);
219
+ return rule;
220
+ }
221
+ function createRemoveAttributeRule(attribute, options) {
222
+ const { when, severity = "warning", message, diagnostic, readsProps, tags } = options;
223
+ const fix = removeAttributeFix(attribute);
224
+ const rule = (context) => {
225
+ if (!when(context)) return [];
226
+ return [
227
+ invalidWithFix({
228
+ severity,
229
+ attribute,
230
+ ...isDefined(message) && { message },
231
+ ...isDefined(diagnostic) && { diagnostic: diagnostic(context) },
232
+ fix
233
+ })
234
+ ];
235
+ };
236
+ return defineRuleMetadata(rule, {
237
+ ...isDefined(readsProps) && { readsProps },
238
+ ...isDefined(tags) && { tags }
239
+ });
240
+ }
241
+
171
242
  // ../../lib/contract/src/props/get-active-props.ts
172
243
  var activeProps = ({
173
244
  active,
@@ -333,12 +404,15 @@ function mergeContracts(...contracts) {
333
404
  export {
334
405
  activeContract,
335
406
  activeProps,
407
+ createRemoveAttributeRule,
336
408
  disabledContract,
337
409
  disabledProps,
338
410
  expandedContract,
339
411
  expandedProps,
340
412
  invalidContract,
341
413
  invalidProps,
414
+ invalidWithFix,
415
+ invalidWithoutFix,
342
416
  loadingContract,
343
417
  loadingProps,
344
418
  mergeContracts,
@@ -346,6 +420,7 @@ export {
346
420
  pressedProps,
347
421
  readonlyContract,
348
422
  readonlyProps,
423
+ removeAttributeFix,
349
424
  selectedContract,
350
425
  selectedProps
351
426
  };
@@ -28,9 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  mod
29
29
  ));
30
30
 
31
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js
31
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js
32
32
  var require_deepMerge = __commonJS({
33
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js"(exports) {
33
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js"(exports) {
34
34
  "use strict";
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.isObjectNotArray = isObjectNotArray;
@@ -63,9 +63,9 @@ var require_deepMerge = __commonJS({
63
63
  }
64
64
  });
65
65
 
66
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js
66
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js
67
67
  var require_applyDefault = __commonJS({
68
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js"(exports) {
68
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js"(exports) {
69
69
  "use strict";
70
70
  Object.defineProperty(exports, "__esModule", { value: true });
71
71
  exports.applyDefault = applyDefault;
@@ -90,9 +90,9 @@ var require_applyDefault = __commonJS({
90
90
  }
91
91
  });
92
92
 
93
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js
93
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js
94
94
  var require_parserSeemsToBeTSESLint = __commonJS({
95
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js"(exports) {
95
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js"(exports) {
96
96
  "use strict";
97
97
  Object.defineProperty(exports, "__esModule", { value: true });
98
98
  exports.parserSeemsToBeTSESLint = parserSeemsToBeTSESLint;
@@ -102,9 +102,9 @@ var require_parserSeemsToBeTSESLint = __commonJS({
102
102
  }
103
103
  });
104
104
 
105
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js
105
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js
106
106
  var require_getParserServices = __commonJS({
107
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js"(exports) {
107
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js"(exports) {
108
108
  "use strict";
109
109
  Object.defineProperty(exports, "__esModule", { value: true });
110
110
  exports.getParserServices = getParserServices;
@@ -135,17 +135,17 @@ var require_getParserServices = __commonJS({
135
135
  }
136
136
  });
137
137
 
138
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js
138
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js
139
139
  var require_InferTypesFromRule = __commonJS({
140
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js"(exports) {
140
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js"(exports) {
141
141
  "use strict";
142
142
  Object.defineProperty(exports, "__esModule", { value: true });
143
143
  }
144
144
  });
145
145
 
146
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js
146
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js
147
147
  var require_nullThrows = __commonJS({
148
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js"(exports) {
148
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js"(exports) {
149
149
  "use strict";
150
150
  Object.defineProperty(exports, "__esModule", { value: true });
151
151
  exports.NullThrowsReasons = void 0;
@@ -163,9 +163,9 @@ var require_nullThrows = __commonJS({
163
163
  }
164
164
  });
165
165
 
166
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js
166
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js
167
167
  var require_RuleCreator = __commonJS({
168
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js"(exports) {
168
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js"(exports) {
169
169
  "use strict";
170
170
  Object.defineProperty(exports, "__esModule", { value: true });
171
171
  exports.RuleCreator = RuleCreator8;
@@ -211,9 +211,9 @@ var require_RuleCreator = __commonJS({
211
211
  }
212
212
  });
213
213
 
214
- // ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js
214
+ // ../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js
215
215
  var require_eslint_utils = __commonJS({
216
- "../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js"(exports) {
216
+ "../../node_modules/.pnpm/@typescript-eslint+utils@8.65.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js"(exports) {
217
217
  "use strict";
218
218
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
219
219
  if (k2 === void 0) k2 = k;
@@ -1,6 +1,26 @@
1
1
  type StringMap<T = unknown> = Record<string, T>;
2
2
  type AnyRecord = StringMap<unknown>;
3
3
 
4
+ /**
5
+ * Well-known Symbol stamped onto every component created by praxis-kit factories.
6
+ * Stores the factory's defaultTag — the tag that renders when no `as` prop is given.
7
+ * HOC wrappers must propagate it: `Wrapped[COMPONENT_DEFAULT_TAG] = Original[COMPONENT_DEFAULT_TAG]`.
8
+ */
9
+ declare const COMPONENT_DEFAULT_TAG: unique symbol;
10
+ /**
11
+ * Stamps `COMPONENT_DEFAULT_TAG` onto a component function/object, so `isTag()`
12
+ * (and every built-in/custom `enforcement.children` rule built on it) resolves it
13
+ * to `tag` — the same recognition a component created via `createContractComponent`
14
+ * gets automatically. A transparent wrapper around a praxis-kit component (added
15
+ * purely to narrow prop types, for example) is a *different* function object with
16
+ * no `COMPONENT_DEFAULT_TAG` of its own, so without this it silently stops being
17
+ * recognized as a valid child by every parent contract. Returns `component` for
18
+ * call-site chaining, e.g. `export const Wrapped = markComponentTag(WrapperFn, 'source')`.
19
+ */
20
+ declare function markComponentTag<T extends object>(component: T, tag: string): T;
21
+ /** Reads `COMPONENT_DEFAULT_TAG` off a component function/object, if present. */
22
+ declare function getComponentDefaultTag(component: unknown): string | undefined;
23
+
4
24
  /**
5
25
  * Resolves the effective HTML tag for a vnode:
6
26
  * - native element: returns its type string directly
@@ -42,4 +62,4 @@ declare function isObject(value: unknown, excludeArrays: true): value is AnyReco
42
62
  declare function isObject(value: unknown, excludeArrays?: false): value is object;
43
63
  declare function isString(value: unknown): value is string;
44
64
 
45
- export { type FlowContentChild, type TagChild, getTag, isFlowContent, isObject, isString, isTag };
65
+ export { COMPONENT_DEFAULT_TAG, type FlowContentChild, type TagChild, getComponentDefaultTag, getTag, isFlowContent, isObject, isString, isTag, markComponentTag };
@@ -9,24 +9,49 @@ function isString(value) {
9
9
  function isNumber(value) {
10
10
  return typeof value === "number";
11
11
  }
12
+ function isFunction(value) {
13
+ return typeof value === "function";
14
+ }
12
15
 
13
16
  // ../../lib/primitive/src/guards/children/component-id.ts
14
17
  var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
18
+ function isMarkable(value) {
19
+ return isFunction(value) || isObject(value);
20
+ }
21
+ function defineComponentMetadata(component, metadata) {
22
+ for (const key of Object.getOwnPropertySymbols(metadata)) {
23
+ Object.defineProperty(component, key, {
24
+ value: metadata[key],
25
+ writable: false,
26
+ configurable: true,
27
+ enumerable: false
28
+ });
29
+ }
30
+ return component;
31
+ }
32
+ function markComponentTag(component, tag) {
33
+ return defineComponentMetadata(component, { [COMPONENT_DEFAULT_TAG]: tag });
34
+ }
35
+ function getComponentDefaultTag(component) {
36
+ if (!isMarkable(component)) return void 0;
37
+ const tag = component[COMPONENT_DEFAULT_TAG];
38
+ return typeof tag === "string" ? tag : void 0;
39
+ }
15
40
 
16
41
  // ../../lib/primitive/src/guards/children/is-tag.ts
17
42
  function getAsProp(child) {
18
43
  if (!isObject(child) || !("props" in child)) return void 0;
19
- const props = child.props;
44
+ const { props } = child;
20
45
  if (!isObject(props)) return void 0;
21
- const as = props.as;
46
+ const as = Reflect.get(props, "as");
22
47
  return isString(as) && as !== "" ? as : void 0;
23
48
  }
24
49
  function getTag(child) {
25
50
  if (!isObject(child) || !("type" in child)) return void 0;
26
- const t = child.type;
51
+ const { type: t } = child;
27
52
  if (isString(t)) return t;
28
53
  if (typeof t === "function" || isObject(t)) {
29
- const defaultTag = t[COMPONENT_DEFAULT_TAG];
54
+ const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
30
55
  if (!isString(defaultTag)) return void 0;
31
56
  return getAsProp(child) ?? defaultTag;
32
57
  }
@@ -54,9 +79,12 @@ function isFlowContent(...blockedTags) {
54
79
  };
55
80
  }
56
81
  export {
82
+ COMPONENT_DEFAULT_TAG,
83
+ getComponentDefaultTag,
57
84
  getTag,
58
85
  isFlowContent,
59
86
  isObject,
60
87
  isString,
61
- isTag
88
+ isTag,
89
+ markComponentTag
62
90
  };
@@ -25,8 +25,8 @@ type AriaContext = {
25
25
  readonly props: ReadonlyDeep<IntrinsicProps>;
26
26
  };
27
27
 
28
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
29
- type InjectLiveFixKind = `injectLive:${string}`;
28
+ type RemoveAttributeFixKind = 'removeAttribute';
29
+ type InjectLiveFixKind = 'injectLive';
30
30
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
31
31
 
32
32
  type AriaFixResult = {
@@ -39,6 +39,9 @@ type AriaFixResult = {
39
39
  };
40
40
  type AriaFix = {
41
41
  readonly kind: FixKind;
42
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
43
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
44
+ readonly attribute?: string;
42
45
  readonly priority?: number;
43
46
  readonly source?: string;
44
47
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -360,6 +360,23 @@ var InputAccessibilityDiagnostics = {
360
360
  }
361
361
  };
362
362
 
363
+ // ../../lib/contract/src/aria/factories.ts
364
+ function removeProp(props, key) {
365
+ const next = { ...props };
366
+ delete next[key];
367
+ return next;
368
+ }
369
+ function removeAttributeFix(attribute) {
370
+ return Object.freeze({
371
+ kind: "removeAttribute",
372
+ attribute,
373
+ apply: ({ props }) => {
374
+ if (!(attribute in props)) return { applied: false, next: props };
375
+ return { applied: true, next: removeProp(props, attribute), previous: props };
376
+ }
377
+ });
378
+ }
379
+
363
380
  // ../core/src/html/contracts/categories.ts
364
381
  var LANDMARK_TAGS = [
365
382
  "article",
@@ -424,20 +441,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
424
441
 
425
442
  // ../core/src/html/spec/validators/attribute-type-validator.ts
426
443
  var DEFAULT_INPUT_TYPE = "text";
427
- function omit(props, key) {
428
- const next = { ...props };
429
- delete next[key];
430
- return next;
431
- }
432
- function removeAttributeFix(attribute) {
433
- return {
434
- kind: `removeAttribute:${attribute}`,
435
- apply: ({ props }) => {
436
- if (!(attribute in props)) return { applied: false, next: props };
437
- return { applied: true, next: omit(props, attribute), previous: props };
438
- }
439
- };
440
- }
441
444
  function createInputAttributeTypeRule({
442
445
  attribute,
443
446
  allowedTypes
@@ -5,6 +5,8 @@ import { LitElement } from 'lit';
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
 
@@ -179,8 +181,8 @@ type AriaContext = {
179
181
  readonly props: ReadonlyDeep<IntrinsicProps>;
180
182
  };
181
183
 
182
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
183
- type InjectLiveFixKind = `injectLive:${string}`;
184
+ type RemoveAttributeFixKind = 'removeAttribute';
185
+ type InjectLiveFixKind = 'injectLive';
184
186
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
185
187
 
186
188
  type AriaFixResult = {
@@ -193,6 +195,9 @@ type AriaFixResult = {
193
195
  };
194
196
  type AriaFix = {
195
197
  readonly kind: FixKind;
198
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
199
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
200
+ readonly attribute?: string;
196
201
  readonly priority?: number;
197
202
  readonly source?: string;
198
203
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -286,6 +291,30 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
286
291
  * be set directly by component authors — use `enforcement.diagnostics` to override per component.
287
292
  */
288
293
  readonly diagnostics?: Diagnostics;
294
+ /**
295
+ * Sub-components to attach to the generated root component, producing a
296
+ * compound component API (for example, `Card.Header`, `Card.Content`,
297
+ * and `Card.Footer`). Purely additive — has no effect on
298
+ * `enforcement.children`; author child rules explicitly if the component
299
+ * needs to validate its children.
300
+ */
301
+ readonly subComponents?: SubComponentMap;
302
+ /**
303
+ * Called once per instance, when the real underlying DOM element first
304
+ * exists, in every adapter — via that adapter's own native mount
305
+ * lifecycle, never through the props/attribute pipeline. Use this for
306
+ * wiring that needs the actual element (native imperative methods like
307
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
308
+ * no prop-based equivalent), not for anything expressible as a plain
309
+ * prop.
310
+ *
311
+ * `getProps` returns the instance's *current* resolved props at call
312
+ * time — read it from inside a listener registered once at mount, rather
313
+ * than re-subscribing on every prop change.
314
+ *
315
+ * Return a cleanup function to run when the instance unmounts.
316
+ */
317
+ readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
289
318
  };
290
319
 
291
320
  type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
@@ -345,7 +374,9 @@ type LitContractComponent<TVariants extends Readonly<VariantMap> = Readonly<Empt
345
374
  * customElements.define('praxis-button', Button)
346
375
  * ```
347
376
  */
348
- 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: LitFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin>): LitContractComponent<TVariants, ExtractPluginProps<TPlugin>>;
377
+ 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: LitFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
378
+ readonly subComponents?: TSubComponents;
379
+ }): LitContractComponent<TVariants, ExtractPluginProps<TPlugin>> & TSubComponents;
349
380
 
350
381
  /**
351
382
  * Renders a praxis-kit Lit component to an HTML string without requiring a DOM.