@jini-ai/ui-kit 0.1.4 → 0.1.5
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/CHANGELOG.md +4 -0
- package/dist/confirm.js +4 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{kit.spec.d.ts → kit-contract.d.ts} +1 -1
- package/dist/{kit.spec.js → kit-contract.js} +1 -1
- package/dist/needs.d.ts +1 -1
- package/dist/needs.js +1 -1
- package/dist/react/Kit.hooks.d.ts +1 -1
- package/dist/react/Kit.hooks.js +1 -1
- package/dist/react/confirm/ConfirmDialog.hooks.js +7 -4
- package/dist/react/confirm/guard.js +57 -33
- package/dist/react/kit.d.ts +1 -1
- package/dist/react/kit.js +1 -1
- package/dist/react/native/Dialog.hooks.js +6 -4
- package/dist/react/native/Navigation.hooks.js +11 -4
- package/dist/react/testing/driver.d.ts +1 -1
- package/dist/react/testing/driver.js +16 -11
- package/dist/react/types.d.ts +1 -1
- package/dist/testing/scenarios.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @jini-ai/ui-kit
|
|
2
2
|
|
|
3
|
+
## 0.1.5 — 2026-10-22
|
|
4
|
+
|
|
5
|
+
- 2026-10-22: Complexity refactors, coverage.
|
|
6
|
+
|
|
3
7
|
## 0.1.4 — 2026-10-13
|
|
4
8
|
|
|
5
9
|
- Break facade/native import cycles: native dialogs pick the provider's Button through a context-only lookup (`NativeButton` fallback; `nativeActions` still forces native), and `ToastRegion` creates its Toast elements. No API change.
|
package/dist/confirm.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
const defaultConsequences = new Map([
|
|
2
|
+
['warning', 'changes access, but is reversible'], ['danger', 'cannot be undone'],
|
|
3
|
+
]);
|
|
1
4
|
export function planConfirm(required, _optional = {}) {
|
|
2
5
|
const pending = required.pending === true, tone = required.tone ?? 'default';
|
|
3
|
-
const consequence = required.consequence?.trim() || (tone
|
|
6
|
+
const consequence = required.consequence?.trim() || defaultConsequences.get(tone);
|
|
4
7
|
const confirmLabel = `${required.confirmLabel} — ${required.title}${consequence ? `; ${consequence}` : ''}`;
|
|
5
8
|
const cancelLabel = required.cancelLabel ?? 'Cancel';
|
|
6
9
|
const agent = (action, label) => required.agentHandle === undefined ? undefined :
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { KIT_CONTRACT, kitSpec, kitParts, implementedComponents } from './kit.
|
|
2
|
-
export type { KitComponentName, ImplementedComponentName, KitPart } from './kit.
|
|
1
|
+
export { KIT_CONTRACT, kitSpec, kitParts, implementedComponents } from './kit-contract.js';
|
|
2
|
+
export type { KitComponentName, ImplementedComponentName, KitPart } from './kit-contract.js';
|
|
3
3
|
export type { KitAttrs, AgentSpec, AgentAttrsPort } from './attrs.js';
|
|
4
4
|
export { needs, assertKitContract, KitConfigError } from './needs.js';
|
|
5
5
|
export type { KitNeeds } from './needs.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { KIT_CONTRACT, kitSpec, kitParts, implementedComponents } from './kit.
|
|
1
|
+
export { KIT_CONTRACT, kitSpec, kitParts, implementedComponents } from './kit-contract.js';
|
|
2
2
|
export { needs, assertKitContract, KitConfigError } from './needs.js';
|
|
3
3
|
export { planConfirm, createConfirmController } from './confirm.js';
|
|
4
4
|
export { createToastService } from './toast.js';
|
|
@@ -488,4 +488,4 @@ export type ImplementedComponentName = {
|
|
|
488
488
|
export type KitPart = typeof kitSpec[ImplementedComponentName]['parts'][number];
|
|
489
489
|
export declare const implementedComponents: readonly ImplementedComponentName[];
|
|
490
490
|
export declare const kitParts: readonly KitPart[];
|
|
491
|
-
//# sourceMappingURL=kit.
|
|
491
|
+
//# sourceMappingURL=kit-contract.d.ts.map
|
|
@@ -37,4 +37,4 @@ export const kitSpec = {
|
|
|
37
37
|
};
|
|
38
38
|
export const implementedComponents = Object.freeze(Object.keys(kitSpec).filter((name) => kitSpec[name].status === 'implemented'));
|
|
39
39
|
export const kitParts = Object.freeze([...new Set(implementedComponents.flatMap(name => [...kitSpec[name].parts]))]);
|
|
40
|
-
//# sourceMappingURL=kit.
|
|
40
|
+
//# sourceMappingURL=kit-contract.js.map
|
package/dist/needs.d.ts
CHANGED
package/dist/needs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import { type ImplementedComponentName } from '../kit.
|
|
2
|
+
import { type ImplementedComponentName } from '../kit-contract.js';
|
|
3
3
|
import type { KitContextValue, KitProviderProps, ReactKitProps, ToastProps } from './types.js';
|
|
4
4
|
import { createToastService } from '../toast.js';
|
|
5
5
|
export declare function useKit(_required?: Record<string, never>, _optional?: Record<string, never>): KitContextValue;
|
package/dist/react/Kit.hooks.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createPortal } from 'react-dom';
|
|
|
3
3
|
import { useKitContext } from './context.js';
|
|
4
4
|
import { createKit } from './kit.js';
|
|
5
5
|
import { assertKitContract, KitConfigError } from '../needs.js';
|
|
6
|
-
import { kitSpec } from '../kit.
|
|
6
|
+
import { kitSpec } from '../kit-contract.js';
|
|
7
7
|
import { createToastService } from '../toast.js';
|
|
8
8
|
let defaultValue;
|
|
9
9
|
function getDefault() {
|
|
@@ -17,12 +17,15 @@ export function useConfirmController(required, optional = {}) {
|
|
|
17
17
|
onCancel: () => latest.current.onCancel({}), onConfirm: () => latest.current.onConfirm({}) }), []);
|
|
18
18
|
const pending = !!required.pending || executing;
|
|
19
19
|
const plan = planConfirm({ ...required, cancelLabel: required.cancelLabel ?? context.cancelLabel, pending });
|
|
20
|
-
|
|
20
|
+
const actionState = pending ? 'pending' : 'ready';
|
|
21
|
+
function actionAttrs(input, _optional = {}) {
|
|
22
|
+
const { part, spec } = input;
|
|
23
|
+
const label = input.label ?? spec?.label ?? input.fallbackLabel;
|
|
21
24
|
const agent = optional.agent ?? context.agent;
|
|
22
25
|
const attrs = spec && agent ? agent({ handle: spec.handle }, { role: spec.role, label: spec.label }) : {};
|
|
23
26
|
return Object.freeze({ ...attrs, 'data-jini-part': part, 'aria-label': label,
|
|
24
27
|
...(required.actionAccessibleNames && plan.consequence ? { 'aria-describedby': consequenceId } : {}),
|
|
25
|
-
'aria-busy': pending, 'data-jini-state':
|
|
28
|
+
'aria-busy': pending, 'data-jini-state': actionState });
|
|
26
29
|
}
|
|
27
30
|
async function onPress() {
|
|
28
31
|
if (model.isExecuting({}) || !latest.current.open || latest.current.pending)
|
|
@@ -47,10 +50,10 @@ export function useConfirmController(required, optional = {}) {
|
|
|
47
50
|
'aria-labelledby': titleId, 'aria-modal': true, 'aria-busy': pending }),
|
|
48
51
|
titleAttrs: { id: titleId, 'data-jini-part': 'confirm.title' },
|
|
49
52
|
consequenceAttrs: { id: consequenceId, 'data-jini-part': 'confirm.consequence' },
|
|
50
|
-
cancel: Object.freeze({ attrs: actionAttrs('confirm.cancel', plan.cancel, required.actionAccessibleNames?.cancel
|
|
53
|
+
cancel: Object.freeze({ attrs: actionAttrs({ part: 'confirm.cancel', spec: plan.cancel, label: required.actionAccessibleNames?.cancel, fallbackLabel: `${plan.cancelLabel} — no action taken` }),
|
|
51
54
|
ref: cancelRef, disabled: pending, variant: 'secondary', children: plan.cancelLabel,
|
|
52
55
|
onPress: () => { model.requestDismiss({ reason: 'cancel-button' }); } }),
|
|
53
|
-
confirm: Object.freeze({ attrs: actionAttrs('confirm.confirm', plan.confirm, required.actionAccessibleNames?.confirm
|
|
56
|
+
confirm: Object.freeze({ attrs: actionAttrs({ part: 'confirm.confirm', spec: plan.confirm, label: required.actionAccessibleNames?.confirm, fallbackLabel: plan.confirmLabel }), disabled: pending, pending,
|
|
54
57
|
variant: plan.confirmVariant, children: required.confirmLabel, onPress }),
|
|
55
58
|
boundaryRef, overlayContainer: useOverlayContainer({}), agentMayConfirm: required.agentMayConfirm !== false,
|
|
56
59
|
requestDismiss: model.requestDismiss,
|
|
@@ -6,49 +6,73 @@ function visible(element) {
|
|
|
6
6
|
}
|
|
7
7
|
return true;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const c = required.controller, issues = [];
|
|
12
|
-
const frame = c.frameAttrs.id ? document.getElementById(c.frameAttrs.id) : null;
|
|
13
|
-
if (!frame)
|
|
14
|
-
return ['missing confirm frame'];
|
|
9
|
+
function inspectFrame({ controller: c, frame }, _optional = {}) {
|
|
10
|
+
const issues = [];
|
|
15
11
|
if (frame.dataset.jiniPart !== 'confirm.dialog' || frame.getAttribute('role') !== 'alertdialog')
|
|
16
12
|
issues.push('missing alertdialog semantics');
|
|
17
13
|
if (!c.overlayContainer?.contains(frame))
|
|
18
14
|
issues.push('frame outside overlay container');
|
|
19
15
|
if (frame.getAttribute('aria-labelledby') !== c.frameAttrs['aria-labelledby'])
|
|
20
16
|
issues.push('missing title association');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (!element.matches('button,input,[role="button"][tabindex]'))
|
|
29
|
-
issues.push(`${name} part is not on a focusable action`);
|
|
30
|
-
if (!visible(element))
|
|
31
|
-
issues.push(`${name} action hidden`);
|
|
32
|
-
for (const [key, value] of Object.entries(bag.attrs ?? {})) {
|
|
33
|
-
if (value !== undefined && element.getAttribute(key) !== String(value))
|
|
34
|
-
issues.push(`${name} did not forward ${key}`);
|
|
35
|
-
}
|
|
36
|
-
if (c.pending && !element.matches(':disabled') && element.getAttribute('aria-disabled') !== 'true')
|
|
37
|
-
issues.push(`${name} enabled while pending`);
|
|
17
|
+
return issues;
|
|
18
|
+
}
|
|
19
|
+
function inspectForwardedAttrs({ name, element, attrs }, _optional = {}) {
|
|
20
|
+
const issues = [];
|
|
21
|
+
for (const [key, value] of Object.entries(attrs ?? {})) {
|
|
22
|
+
if (value !== undefined && element.getAttribute(key) !== String(value))
|
|
23
|
+
issues.push(`${name} did not forward ${key}`);
|
|
38
24
|
}
|
|
39
|
-
|
|
25
|
+
return issues;
|
|
26
|
+
}
|
|
27
|
+
function inspectAction({ name, element, bag, pending }, _optional = {}) {
|
|
28
|
+
if (!element)
|
|
29
|
+
return [`missing ${name} action`];
|
|
30
|
+
const issues = [];
|
|
31
|
+
if (!element.matches('button,input,[role="button"][tabindex]'))
|
|
32
|
+
issues.push(`${name} part is not on a focusable action`);
|
|
33
|
+
if (!visible(element))
|
|
34
|
+
issues.push(`${name} action hidden`);
|
|
35
|
+
issues.push(...inspectForwardedAttrs({ name, element, attrs: bag.attrs }));
|
|
36
|
+
if (pending && !element.matches(':disabled') && element.getAttribute('aria-disabled') !== 'true')
|
|
37
|
+
issues.push(`${name} enabled while pending`);
|
|
38
|
+
return issues;
|
|
39
|
+
}
|
|
40
|
+
function inspectInteraction({ controller: c, checkFocus, cancel, confirm, activeElement }, _optional = {}) {
|
|
41
|
+
const issues = [];
|
|
42
|
+
if (!c.pending && checkFocus && cancel && activeElement !== cancel)
|
|
40
43
|
issues.push('initial focus is not cancel');
|
|
41
44
|
if (!c.agentMayConfirm && confirm && [confirm, ...confirm.querySelectorAll('*')].some(element => element.getAttributeNames().some(name => name.startsWith('data-agent-'))))
|
|
42
45
|
issues.push('human-only confirm published agent metadata');
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
return issues;
|
|
47
|
+
}
|
|
48
|
+
function inspectDescription({ description, frame, confirm, consequence }, _optional = {}) {
|
|
49
|
+
const describedIds = confirm.getAttribute('aria-describedby')?.split(/\s+/) ?? [];
|
|
50
|
+
if (!description || !frame.contains(description) || !visible(description) ||
|
|
51
|
+
!describedIds.includes(description.id) || !description.textContent?.includes(consequence))
|
|
52
|
+
return ['missing consequence label'];
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
function inspectConsequence({ controller: c, frame, confirm, document: dom }, _optional = {}) {
|
|
56
|
+
if (!c.consequence || !confirm || confirm.getAttribute('aria-label')?.includes(c.consequence))
|
|
57
|
+
return [];
|
|
58
|
+
// A concise action name still has to expose the real, visible consequence as its
|
|
59
|
+
// description. An override dropping the associated paragraph must fail the guard.
|
|
60
|
+
const description = c.consequenceAttrs?.id ? dom.getElementById(c.consequenceAttrs.id) : null;
|
|
61
|
+
return inspectDescription({ description, frame, confirm, consequence: c.consequence });
|
|
62
|
+
}
|
|
63
|
+
/** Checks real mounted DOM. jsdom cannot prove layout or browser top-layer behavior; those are browser scenarios. */
|
|
64
|
+
export function inspectConfirm(required, _optional = {}) {
|
|
65
|
+
const c = required.controller;
|
|
66
|
+
const frame = c.frameAttrs.id ? document.getElementById(c.frameAttrs.id) : null;
|
|
67
|
+
if (!frame)
|
|
68
|
+
return ['missing confirm frame'];
|
|
69
|
+
const issues = inspectFrame({ controller: c, frame });
|
|
70
|
+
const cancel = frame.querySelector('[data-jini-part="confirm.cancel"]');
|
|
71
|
+
const confirm = frame.querySelector('[data-jini-part="confirm.confirm"]');
|
|
72
|
+
issues.push(...inspectAction({ name: 'cancel', element: cancel, bag: c.cancel, pending: c.pending }));
|
|
73
|
+
issues.push(...inspectAction({ name: 'confirm', element: confirm, bag: c.confirm, pending: c.pending }));
|
|
74
|
+
issues.push(...inspectInteraction({ controller: c, checkFocus: required.checkFocus, cancel, confirm, activeElement: document.activeElement }));
|
|
75
|
+
issues.push(...inspectConsequence({ controller: c, frame, confirm, document }));
|
|
52
76
|
return issues;
|
|
53
77
|
}
|
|
54
78
|
//# sourceMappingURL=guard.js.map
|
package/dist/react/kit.d.ts
CHANGED
package/dist/react/kit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KIT_CONTRACT, implementedComponents, kitSpec } from '../kit.
|
|
1
|
+
import { KIT_CONTRACT, implementedComponents, kitSpec } from '../kit-contract.js';
|
|
2
2
|
import { assertKitContract, KitConfigError } from '../needs.js';
|
|
3
3
|
import { nativeKit } from './native/index.js';
|
|
4
4
|
export function createKit(required, optional = {}) {
|
|
@@ -12,8 +12,7 @@ export function useNativeDialog(required, optional = {}) {
|
|
|
12
12
|
if (!dialog)
|
|
13
13
|
return;
|
|
14
14
|
if (!required.open) {
|
|
15
|
-
|
|
16
|
-
opener.current.focus({ preventScroll: true });
|
|
15
|
+
restoreDialogFocus({ opener: opener.current });
|
|
17
16
|
return;
|
|
18
17
|
}
|
|
19
18
|
opener.current = (optional.document ?? document).activeElement;
|
|
@@ -35,8 +34,7 @@ export function useNativeDialog(required, optional = {}) {
|
|
|
35
34
|
}
|
|
36
35
|
else
|
|
37
36
|
dialog.removeAttribute('open');
|
|
38
|
-
|
|
39
|
-
opener.current.focus({ preventScroll: true });
|
|
37
|
+
restoreDialogFocus({ opener: opener.current });
|
|
40
38
|
};
|
|
41
39
|
// Open is the transition boundary: editing content must not recapture the original trigger.
|
|
42
40
|
}, [required.open]);
|
|
@@ -54,6 +52,10 @@ export function useNativeDialog(required, optional = {}) {
|
|
|
54
52
|
onClick: (event) => { if (event.target === event.currentTarget && !required.pending && isOutsideBox(event))
|
|
55
53
|
required.onClose({}); } } };
|
|
56
54
|
}
|
|
55
|
+
function restoreDialogFocus({ opener }, _optional = {}) {
|
|
56
|
+
if (opener instanceof HTMLElement && opener.isConnected)
|
|
57
|
+
opener.focus({ preventScroll: true });
|
|
58
|
+
}
|
|
57
59
|
/** True when the pointer is outside the dialog's own rectangle, i.e. on the ::backdrop. A click with no
|
|
58
60
|
* coordinates (keyboard activation, synthetic test clicks) keeps the old target-only behaviour. */
|
|
59
61
|
function isOutsideBox(event) {
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { createElement, useId, useRef, useState, useEffect, useLayoutEffect } from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
|
+
function navigationIndex(required, _optional = {}) {
|
|
4
|
+
switch (required.key) {
|
|
5
|
+
case 'Home': return 0;
|
|
6
|
+
case 'End': return required.count - 1;
|
|
7
|
+
case required.forward: return (required.current + 1) % required.count;
|
|
8
|
+
case required.backward: return (required.current - 1 + required.count) % required.count;
|
|
9
|
+
default: return undefined;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
3
12
|
export function useNativeTabs(required, _optional = {}) {
|
|
4
13
|
const prefix = useId(), root = useRef(null);
|
|
5
14
|
const enabled = required.items.filter(item => !item.disabled);
|
|
6
15
|
const active = enabled.find(item => item.id === required.value) ?? enabled[0];
|
|
7
16
|
function onKeyDown(event) {
|
|
8
17
|
const index = enabled.findIndex(item => item.id === event.currentTarget.dataset.tabId);
|
|
9
|
-
const next =
|
|
10
|
-
event.key === 'ArrowRight' ? (index + 1) % enabled.length : event.key === 'ArrowLeft' ? (index - 1 + enabled.length) % enabled.length : undefined;
|
|
18
|
+
const next = navigationIndex({ key: event.key, current: index, count: enabled.length, forward: 'ArrowRight', backward: 'ArrowLeft' });
|
|
11
19
|
if (next === undefined || !enabled[next])
|
|
12
20
|
return;
|
|
13
21
|
event.preventDefault();
|
|
@@ -69,8 +77,7 @@ export function useNativeMenu(required, _optional = {}) {
|
|
|
69
77
|
setOpen(false);
|
|
70
78
|
return;
|
|
71
79
|
}
|
|
72
|
-
const next =
|
|
73
|
-
event.key === 'ArrowDown' ? (current + 1) % enabled.length : event.key === 'ArrowUp' ? (current - 1 + enabled.length) % enabled.length : undefined;
|
|
80
|
+
const next = navigationIndex({ key: event.key, current, count: enabled.length, forward: 'ArrowDown', backward: 'ArrowUp' });
|
|
74
81
|
if (next !== undefined) {
|
|
75
82
|
event.preventDefault();
|
|
76
83
|
focus(next);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentAttrsPort } from '../../attrs.js';
|
|
2
2
|
import type { KitScenario } from '../../testing/scenarios.js';
|
|
3
|
-
import type { ImplementedComponentName } from '../../kit.
|
|
3
|
+
import type { ImplementedComponentName } from '../../kit-contract.js';
|
|
4
4
|
import type { ResolvedKit } from '../types.js';
|
|
5
5
|
export interface KitConformanceResult {
|
|
6
6
|
readonly id: string;
|
|
@@ -28,14 +28,15 @@ function check(expectation, root, calls) {
|
|
|
28
28
|
return `missing ${expectation.selector}`;
|
|
29
29
|
if (expectation.type === 'attribute')
|
|
30
30
|
return element.getAttribute(expectation.name) === expectation.value ? undefined : `${expectation.selector} did not forward ${expectation.name}=${expectation.value}`;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return element
|
|
37
|
-
|
|
38
|
-
return element.matches('button,input,select,textarea,[tabindex]') ? undefined : `${expectation.selector} is not focusable`;
|
|
31
|
+
return checkElementState({ expectation, element });
|
|
32
|
+
}
|
|
33
|
+
function checkElementState({ expectation, element }, _optional) {
|
|
34
|
+
switch (expectation.type) {
|
|
35
|
+
case 'focused': return element === document.activeElement ? undefined : `${expectation.selector} not focused`;
|
|
36
|
+
case 'disabled': return element.matches(':disabled') || element.getAttribute('aria-disabled') === 'true' ? undefined : `${expectation.selector} not disabled`;
|
|
37
|
+
case 'native-select': return element instanceof HTMLSelectElement ? undefined : 'Select must render HTMLSelectElement';
|
|
38
|
+
case 'focusable': return element.matches('button,input,select,textarea,[tabindex]') ? undefined : `${expectation.selector} is not focusable`;
|
|
39
|
+
}
|
|
39
40
|
}
|
|
40
41
|
export const reactConformanceDriver = {
|
|
41
42
|
async run({ kit, scenario, agent }) {
|
|
@@ -82,10 +83,14 @@ export const reactConformanceDriver = {
|
|
|
82
83
|
return errors;
|
|
83
84
|
},
|
|
84
85
|
};
|
|
85
|
-
|
|
86
|
-
const driver =
|
|
87
|
-
if (
|
|
86
|
+
function resolveConformanceDriver(required, _optional) {
|
|
87
|
+
const driver = required.driver ?? reactConformanceDriver;
|
|
88
|
+
if (required.includeBrowser && driver === reactConformanceDriver)
|
|
88
89
|
throw new Error('Browser cases require a real browser driver');
|
|
90
|
+
return driver;
|
|
91
|
+
}
|
|
92
|
+
export async function runKitConformance(required, optional = {}) {
|
|
93
|
+
const driver = resolveConformanceDriver(optional);
|
|
89
94
|
const results = [];
|
|
90
95
|
for (const scenario of optional.scenarios ?? kitConformanceScenarios) {
|
|
91
96
|
if (optional.only && !optional.only.includes(scenario.component))
|
package/dist/react/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentType, ReactNode, Ref, RefObject, HTMLAttributes } from 'react';
|
|
2
2
|
import type { KitAttrs, AgentAttrsPort } from '../attrs.js';
|
|
3
3
|
import type { ConfirmInput, DismissReason } from '../confirm.js';
|
|
4
|
-
import type { ImplementedComponentName } from '../kit.
|
|
4
|
+
import type { ImplementedComponentName } from '../kit-contract.js';
|
|
5
5
|
import type { KitNeeds } from '../needs.js';
|
|
6
6
|
import type { ToastService } from '../toast.js';
|
|
7
7
|
export interface BaseProps {
|