foldkit 0.44.0 → 0.46.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.
Files changed (45) hide show
  1. package/dist/propsModule.d.ts +3 -0
  2. package/dist/propsModule.d.ts.map +1 -0
  3. package/dist/propsModule.js +50 -0
  4. package/dist/test/apps/interactions.d.ts +26 -0
  5. package/dist/test/apps/interactions.d.ts.map +1 -0
  6. package/dist/test/apps/interactions.js +59 -0
  7. package/dist/test/apps/multiRole.d.ts +13 -0
  8. package/dist/test/apps/multiRole.d.ts.map +1 -0
  9. package/dist/test/apps/multiRole.js +19 -0
  10. package/dist/test/matchers.d.ts +26 -2
  11. package/dist/test/matchers.d.ts.map +1 -1
  12. package/dist/test/matchers.js +89 -9
  13. package/dist/test/query.d.ts +113 -12
  14. package/dist/test/query.d.ts.map +1 -1
  15. package/dist/test/query.js +265 -35
  16. package/dist/test/scene.d.ts +77 -8
  17. package/dist/test/scene.d.ts.map +1 -1
  18. package/dist/test/scene.js +281 -28
  19. package/dist/test/vitest-setup.d.ts +0 -17
  20. package/dist/test/vitest-setup.d.ts.map +1 -1
  21. package/dist/test/vitest-setup.js +2 -3
  22. package/dist/test/vitest.d.ts +33 -0
  23. package/dist/test/vitest.d.ts.map +1 -0
  24. package/dist/test/vitest.js +16 -0
  25. package/dist/ui/input/index.d.ts +0 -2
  26. package/dist/ui/input/index.d.ts.map +1 -1
  27. package/dist/ui/input/index.js +2 -5
  28. package/dist/ui/input/public.d.ts +1 -1
  29. package/dist/ui/input/public.d.ts.map +1 -1
  30. package/dist/ui/input/public.js +1 -1
  31. package/dist/ui/select/index.d.ts +0 -2
  32. package/dist/ui/select/index.d.ts.map +1 -1
  33. package/dist/ui/select/index.js +2 -5
  34. package/dist/ui/select/public.d.ts +1 -1
  35. package/dist/ui/select/public.d.ts.map +1 -1
  36. package/dist/ui/select/public.js +1 -1
  37. package/dist/ui/textarea/index.d.ts +0 -2
  38. package/dist/ui/textarea/index.d.ts.map +1 -1
  39. package/dist/ui/textarea/index.js +2 -5
  40. package/dist/ui/textarea/public.d.ts +1 -1
  41. package/dist/ui/textarea/public.d.ts.map +1 -1
  42. package/dist/ui/textarea/public.js +1 -1
  43. package/dist/vdom.d.ts.map +1 -1
  44. package/dist/vdom.js +2 -1
  45. package/package.json +5 -1
@@ -0,0 +1,3 @@
1
+ import type { Module } from 'snabbdom';
2
+ export declare const propsModule: Module;
3
+ //# sourceMappingURL=propsModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"propsModule.d.ts","sourceRoot":"","sources":["../src/propsModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAyDtC,eAAO,MAAM,WAAW,EAAE,MAAqD,CAAA"}
@@ -0,0 +1,50 @@
1
+ /** A custom props module that extends snabbdom's built-in propsModule with
2
+ * proper cleanup of removed properties.
3
+ *
4
+ * Snabbdom's propsModule only iterates over _new_ props — it never resets
5
+ * old props that disappeared between renders. This means `elm.disabled = true`
6
+ * persists even after `Disabled(true)` is removed from the attribute array.
7
+ * Since a disabled button swallows click events at the browser level, an
8
+ * `OnClick` handler that replaces `Disabled` at the same index silently fails.
9
+ *
10
+ * This module adds a second loop (mirroring what snabbdom's attributesModule
11
+ * already does) that resets removed props to type-appropriate defaults:
12
+ * booleans → false, strings → '', numbers → 0. */
13
+ function updateProps(oldVnode, vnode) {
14
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
15
+ const elm = vnode.elm;
16
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
17
+ let oldProps = oldVnode.data?.props;
18
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
19
+ let props = vnode.data?.props;
20
+ if (!oldProps && !props) {
21
+ return;
22
+ }
23
+ if (oldProps === props) {
24
+ return;
25
+ }
26
+ oldProps = oldProps ?? {};
27
+ props = props ?? {};
28
+ for (const key in props) {
29
+ const cur = props[key];
30
+ const old = oldProps[key];
31
+ if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
32
+ elm[key] = cur;
33
+ }
34
+ }
35
+ for (const key in oldProps) {
36
+ if (!(key in props)) {
37
+ const old = oldProps[key];
38
+ if (typeof old === 'boolean') {
39
+ elm[key] = false;
40
+ }
41
+ else if (typeof old === 'string') {
42
+ elm[key] = '';
43
+ }
44
+ else if (typeof old === 'number') {
45
+ elm[key] = 0;
46
+ }
47
+ }
48
+ }
49
+ }
50
+ export const propsModule = { create: updateProps, update: updateProps };
@@ -0,0 +1,26 @@
1
+ import { Schema as S } from 'effect';
2
+ import { type Html } from '../../html';
3
+ export declare const Model: S.Struct<{
4
+ clicks: typeof S.Number;
5
+ doubleClicks: typeof S.Number;
6
+ hovered: typeof S.Boolean;
7
+ focused: typeof S.Boolean;
8
+ changed: typeof S.String;
9
+ }>;
10
+ export type Model = typeof Model.Type;
11
+ export declare const ClickedButton: import("../../schema").CallableTaggedStruct<"ClickedButton", {}>;
12
+ export declare const DoubleClickedButton: import("../../schema").CallableTaggedStruct<"DoubleClickedButton", {}>;
13
+ export declare const HoveredTarget: import("../../schema").CallableTaggedStruct<"HoveredTarget", {}>;
14
+ export declare const FocusedInput: import("../../schema").CallableTaggedStruct<"FocusedInput", {}>;
15
+ export declare const BlurredInput: import("../../schema").CallableTaggedStruct<"BlurredInput", {}>;
16
+ export declare const ChangedSelect: import("../../schema").CallableTaggedStruct<"ChangedSelect", {
17
+ value: typeof S.String;
18
+ }>;
19
+ export declare const Message: S.Union<[import("../../schema").CallableTaggedStruct<"ClickedButton", {}>, import("../../schema").CallableTaggedStruct<"DoubleClickedButton", {}>, import("../../schema").CallableTaggedStruct<"HoveredTarget", {}>, import("../../schema").CallableTaggedStruct<"FocusedInput", {}>, import("../../schema").CallableTaggedStruct<"BlurredInput", {}>, import("../../schema").CallableTaggedStruct<"ChangedSelect", {
20
+ value: typeof S.String;
21
+ }>]>;
22
+ export type Message = typeof Message.Type;
23
+ export declare const initialModel: Model;
24
+ export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<never>];
25
+ export declare const view: (model: Model) => Html;
26
+ //# sourceMappingURL=interactions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../../../src/test/apps/interactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEhD,OAAO,EAAE,KAAK,IAAI,EAAQ,MAAM,YAAY,CAAA;AAK5C,eAAO,MAAM,KAAK;;;;;;EAMhB,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,eAAO,MAAM,aAAa,kEAAqB,CAAA;AAC/C,eAAO,MAAM,mBAAmB,wEAA2B,CAAA;AAC3D,eAAO,MAAM,aAAa,kEAAqB,CAAA;AAC/C,eAAO,MAAM,YAAY,iEAAoB,CAAA;AAC7C,eAAO,MAAM,YAAY,iEAAoB,CAAA;AAC7C,eAAO,MAAM,aAAa;;EAA0C,CAAA;AAEpE,eAAO,MAAM,OAAO;;IAOnB,CAAA;AACD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAA;AAID,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAcrC,CAAA;AAqBH,eAAO,MAAM,IAAI,GAAI,OAAO,KAAK,KAAG,IA2BjC,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { Match as M, Schema as S } from 'effect';
2
+ import { html } from '../../html';
3
+ import { m } from '../../message';
4
+ // MODEL
5
+ export const Model = S.Struct({
6
+ clicks: S.Number,
7
+ doubleClicks: S.Number,
8
+ hovered: S.Boolean,
9
+ focused: S.Boolean,
10
+ changed: S.String,
11
+ });
12
+ // MESSAGE
13
+ export const ClickedButton = m('ClickedButton');
14
+ export const DoubleClickedButton = m('DoubleClickedButton');
15
+ export const HoveredTarget = m('HoveredTarget');
16
+ export const FocusedInput = m('FocusedInput');
17
+ export const BlurredInput = m('BlurredInput');
18
+ export const ChangedSelect = m('ChangedSelect', { value: S.String });
19
+ export const Message = S.Union(ClickedButton, DoubleClickedButton, HoveredTarget, FocusedInput, BlurredInput, ChangedSelect);
20
+ // INIT
21
+ export const initialModel = {
22
+ clicks: 0,
23
+ doubleClicks: 0,
24
+ hovered: false,
25
+ focused: false,
26
+ changed: '',
27
+ };
28
+ // UPDATE
29
+ export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
30
+ ClickedButton: () => [{ ...model, clicks: model.clicks + 1 }, []],
31
+ DoubleClickedButton: () => [
32
+ { ...model, doubleClicks: model.doubleClicks + 1 },
33
+ [],
34
+ ],
35
+ HoveredTarget: () => [{ ...model, hovered: true }, []],
36
+ FocusedInput: () => [{ ...model, focused: true }, []],
37
+ BlurredInput: () => [{ ...model, focused: false }, []],
38
+ ChangedSelect: ({ value }) => [{ ...model, changed: value }, []],
39
+ }));
40
+ // VIEW
41
+ const { div, button, input, select, option, OnClick, OnDblClick, OnMouseEnter, OnFocus, OnBlur, OnChange, Role, AriaLabel, Value, } = html();
42
+ export const view = (model) => div([], [
43
+ button([
44
+ OnClick(ClickedButton()),
45
+ OnDblClick(DoubleClickedButton()),
46
+ OnMouseEnter(HoveredTarget()),
47
+ AriaLabel('action'),
48
+ ], [`clicks=${model.clicks} dbl=${model.doubleClicks}`]),
49
+ input([
50
+ Role('textbox'),
51
+ AriaLabel('name'),
52
+ OnFocus(FocusedInput()),
53
+ OnBlur(BlurredInput()),
54
+ ]),
55
+ select([AriaLabel('fruit'), OnChange(value => ChangedSelect({ value }))], [
56
+ option([Value('apple')], ['Apple']),
57
+ option([Value('banana')], ['Banana']),
58
+ ]),
59
+ ]);
@@ -0,0 +1,13 @@
1
+ import { Schema as S } from 'effect';
2
+ import { type Html } from '../../html';
3
+ export declare const Model: S.Struct<{
4
+ clicks: typeof S.Number;
5
+ }>;
6
+ export type Model = typeof Model.Type;
7
+ export declare const ClickedFallback: import("../../schema").CallableTaggedStruct<"ClickedFallback", {}>;
8
+ export declare const Message: import("../../schema").CallableTaggedStruct<"ClickedFallback", {}>;
9
+ export type Message = typeof Message.Type;
10
+ export declare const initialModel: Model;
11
+ export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<never>];
12
+ export declare const view: (model: Model) => Html;
13
+ //# sourceMappingURL=multiRole.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multiRole.d.ts","sourceRoot":"","sources":["../../../src/test/apps/multiRole.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEhD,OAAO,EAAE,KAAK,IAAI,EAAQ,MAAM,YAAY,CAAA;AAK5C,eAAO,MAAM,KAAK;;EAAiC,CAAA;AACnD,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,eAAO,MAAM,eAAe,oEAAuB,CAAA;AAEnD,eAAO,MAAM,OAAO,oEAA2B,CAAA;AAC/C,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,eAAO,MAAM,YAAY,EAAE,KAAqB,CAAA;AAIhD,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAMrC,CAAA;AAMH,eAAO,MAAM,IAAI,GAAI,OAAO,KAAK,KAAG,IASjC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { Match as M, Schema as S } from 'effect';
2
+ import { html } from '../../html';
3
+ import { m } from '../../message';
4
+ // MODEL
5
+ export const Model = S.Struct({ clicks: S.Number });
6
+ // MESSAGE
7
+ export const ClickedFallback = m('ClickedFallback');
8
+ export const Message = S.Union(ClickedFallback);
9
+ // INIT
10
+ export const initialModel = { clicks: 0 };
11
+ // UPDATE
12
+ export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
13
+ ClickedFallback: () => [{ ...model, clicks: model.clicks + 1 }, []],
14
+ }));
15
+ // VIEW
16
+ const { div, OnClick, Role } = html();
17
+ export const view = (model) => div([], [
18
+ div([Role('doc-subtitle heading'), OnClick(ClickedFallback())], [`Fallback element clicks=${model.clicks}`]),
19
+ ]);
@@ -2,14 +2,14 @@ import { Option } from 'effect';
2
2
  import type { VNode } from '../vdom';
3
3
  /** Custom Vitest matchers for scene testing. Register with `expect.extend(Scene.sceneMatchers)`. */
4
4
  export declare const sceneMatchers: {
5
- toHaveText(received: Option.Option<VNode>, expected: string): {
5
+ toHaveText(received: Option.Option<VNode>, expected: string | RegExp): {
6
6
  pass: boolean;
7
7
  message: () => string;
8
8
  } | {
9
9
  pass: boolean;
10
10
  message: () => string;
11
11
  };
12
- toContainText(received: Option.Option<VNode>, expected: string): {
12
+ toContainText(received: Option.Option<VNode>, expected: string | RegExp): {
13
13
  pass: boolean;
14
14
  message: () => string;
15
15
  } | {
@@ -83,6 +83,30 @@ export declare const sceneMatchers: {
83
83
  pass: boolean;
84
84
  message: () => "Expected element not to be enabled but it is." | "Expected element to be enabled but it is disabled.";
85
85
  };
86
+ toBeEmpty(received: Option.Option<VNode>): {
87
+ pass: boolean;
88
+ message: () => "Expected element to be empty but the element does not exist.";
89
+ } | {
90
+ pass: boolean;
91
+ message: () => string;
92
+ };
93
+ toBeVisible(received: Option.Option<VNode>): {
94
+ pass: boolean;
95
+ message: () => "Expected element to be visible but the element does not exist.";
96
+ } | {
97
+ pass: boolean;
98
+ message: () => "Expected element not to be visible but it is." | "Expected element to be visible but it is hidden.";
99
+ };
100
+ toHaveId(received: Option.Option<VNode>, expected: string): {
101
+ pass: boolean;
102
+ message: () => string;
103
+ } | {
104
+ pass: false;
105
+ message: () => string;
106
+ } | {
107
+ pass: boolean;
108
+ message: () => string;
109
+ };
86
110
  toBeChecked(received: Option.Option<VNode>): {
87
111
  pass: boolean;
88
112
  message: () => "Expected element to be checked but the element does not exist.";
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/test/matchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAKpC,oGAAoG;AACpG,eAAO,MAAM,aAAa;yBACH,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;4BAqBnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;0BAqBxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;yBAmBhD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QACxB,MAAM,kBACI,MAAM;;;;;;;sBA2CN,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;yBAWjB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;0BAY7B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QACxB,MAAM,kBACI,MAAM;;;;;;;yBA8CH,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,MAAM;;;;;;;4BAsB/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,MAAM;;;;;;;0BAkBpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;;;;2BA4BrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;0BAyBrB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;0BAyBpB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;CAwB3C,CAAA"}
1
+ {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/test/matchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAA;AAElD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAcpC,oGAAoG;AACpG,eAAO,MAAM,aAAa;yBACH,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,GAAG,MAAM;;;;;;;4BAqB5C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,GAAG,MAAM;;;;;;;0BAqBjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;yBAmBhD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QACxB,MAAM,kBACI,MAAM;;;;;;;sBA2CN,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;yBAWjB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;0BAY7B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QACxB,MAAM,kBACI,MAAM;;;;;;;yBA8CH,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,MAAM;;;;;;;4BAsB/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,MAAM;;;;;;;0BAkBpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;;;;2BA4BrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;0BAyBrB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;wBAyBtB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;uBAgBnB,MAAM;;0BAUL,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;uBAiCvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM;;;;;;;;;;0BA4BnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;CAwB3C,CAAA"}
@@ -1,22 +1,25 @@
1
- import { Option } from 'effect';
1
+ import { Option, String as String_ } from 'effect';
2
2
  import { attr, textContent } from './query';
3
+ const describeExpected = (expected) => expected instanceof RegExp ? `${expected}` : `"${expected}"`;
4
+ const textMatches = (value, expected) => expected instanceof RegExp ? expected.test(value) : value === expected;
5
+ const textIncludes = (value, expected) => expected instanceof RegExp ? expected.test(value) : value.includes(expected);
3
6
  /** Custom Vitest matchers for scene testing. Register with `expect.extend(Scene.sceneMatchers)`. */
4
7
  export const sceneMatchers = {
5
8
  toHaveText(received, expected) {
6
9
  return Option.match(received, {
7
10
  onNone: () => ({
8
11
  pass: false,
9
- message: () => `Expected element to have text "${expected}" but the element does not exist.`,
12
+ message: () => `Expected element to have text ${describeExpected(expected)} but the element does not exist.`,
10
13
  }),
11
14
  onSome: vnode => {
12
15
  const actualText = textContent(vnode);
13
16
  return {
14
- pass: actualText === expected,
17
+ pass: textMatches(actualText, expected),
15
18
  message: () =>
16
19
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
17
20
  this.isNot
18
- ? `Expected element not to have text "${expected}" but it does.`
19
- : `Expected element to have text "${expected}" but received "${actualText}".`,
21
+ ? `Expected element not to have text ${describeExpected(expected)} but it does.`
22
+ : `Expected element to have text ${describeExpected(expected)} but received "${actualText}".`,
20
23
  };
21
24
  },
22
25
  });
@@ -25,17 +28,17 @@ export const sceneMatchers = {
25
28
  return Option.match(received, {
26
29
  onNone: () => ({
27
30
  pass: false,
28
- message: () => `Expected element to contain text "${expected}" but the element does not exist.`,
31
+ message: () => `Expected element to contain text ${describeExpected(expected)} but the element does not exist.`,
29
32
  }),
30
33
  onSome: vnode => {
31
34
  const actualText = textContent(vnode);
32
35
  return {
33
- pass: actualText.includes(expected),
36
+ pass: textIncludes(actualText, expected),
34
37
  message: () =>
35
38
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
36
39
  this.isNot
37
- ? `Expected element not to contain text "${expected}" but it does.`
38
- : `Expected element to contain text "${expected}" but received "${actualText}".`,
40
+ ? `Expected element not to contain text ${describeExpected(expected)} but it does.`
41
+ : `Expected element to contain text ${describeExpected(expected)} but received "${actualText}".`,
39
42
  };
40
43
  },
41
44
  });
@@ -258,6 +261,83 @@ export const sceneMatchers = {
258
261
  },
259
262
  });
260
263
  },
264
+ toBeEmpty(received) {
265
+ return Option.match(received, {
266
+ onNone: () => ({
267
+ pass: false,
268
+ message: () => 'Expected element to be empty but the element does not exist.',
269
+ }),
270
+ onSome: vnode => {
271
+ const childCount = (vnode.children ?? []).length;
272
+ const text = textContent(vnode);
273
+ const pass = String_.isEmpty(text) && childCount === 0;
274
+ const actual = String_.isNonEmpty(text)
275
+ ? `received text "${text}"`
276
+ : `received ${childCount} child(ren)`;
277
+ return {
278
+ pass,
279
+ message: () =>
280
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
281
+ this.isNot
282
+ ? 'Expected element not to be empty but it is.'
283
+ : `Expected element to be empty but ${actual}.`,
284
+ };
285
+ },
286
+ });
287
+ },
288
+ toBeVisible(received) {
289
+ return Option.match(received, {
290
+ onNone: () => ({
291
+ pass: false,
292
+ message: () => 'Expected element to be visible but the element does not exist.',
293
+ }),
294
+ onSome: vnode => {
295
+ const hiddenAttr = attr(vnode, 'hidden');
296
+ const hiddenByAttr = Option.isSome(hiddenAttr) && hiddenAttr.value !== 'false';
297
+ const ariaHidden = attr(vnode, 'aria-hidden');
298
+ const hiddenByAria = Option.isSome(ariaHidden) && ariaHidden.value === 'true';
299
+ const display = vnode.data?.style?.['display'];
300
+ const visibility = vnode.data?.style?.['visibility'];
301
+ const isHidden = hiddenByAttr ||
302
+ hiddenByAria ||
303
+ display === 'none' ||
304
+ visibility === 'hidden';
305
+ return {
306
+ pass: !isHidden,
307
+ message: () =>
308
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
309
+ this.isNot
310
+ ? 'Expected element not to be visible but it is.'
311
+ : 'Expected element to be visible but it is hidden.',
312
+ };
313
+ },
314
+ });
315
+ },
316
+ toHaveId(received, expected) {
317
+ return Option.match(received, {
318
+ onNone: () => ({
319
+ pass: false,
320
+ message: () => `Expected element to have id "${expected}" but the element does not exist.`,
321
+ }),
322
+ onSome: vnode => {
323
+ const actualId = attr(vnode, 'id');
324
+ return Option.match(actualId, {
325
+ onNone: () => ({
326
+ pass: false,
327
+ message: () => `Expected element to have id "${expected}" but the element has no id.`,
328
+ }),
329
+ onSome: actual => ({
330
+ pass: actual === expected,
331
+ message: () =>
332
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
333
+ this.isNot
334
+ ? `Expected element not to have id "${expected}" but it does.`
335
+ : `Expected element to have id "${expected}" but received "${actual}".`,
336
+ }),
337
+ });
338
+ },
339
+ });
340
+ },
261
341
  toBeChecked(received) {
262
342
  return Option.match(received, {
263
343
  onNone: () => ({
@@ -14,6 +14,16 @@ type SimpleSelector = Readonly<{
14
14
  }>;
15
15
  type Selector = ReadonlyArray<SimpleSelector>;
16
16
  export declare const parseSelector: (input: string) => Selector;
17
+ /** Returns the ancestor chain of `target` within `root`, ordered from root to
18
+ * the immediate parent of `target` (exclusive). Returns an empty array when
19
+ * `target` is `root` itself or is not present in the subtree. */
20
+ export declare const ancestorsOf: (root: VNode, target: VNode) => ReadonlyArray<VNode>;
21
+ /** Computes the accessible name of an element. Resolves via
22
+ * `aria-labelledby`, `aria-label`, `<label for>`, text content, then `title`. */
23
+ export declare const accessibleName: (root: VNode) => (vnode: VNode) => string;
24
+ /** Computes the accessible description of an element. Resolves via
25
+ * `aria-describedby` (joining referenced elements' text content). */
26
+ export declare const accessibleDescription: (root: VNode) => (vnode: VNode) => string;
17
27
  /** Finds the first VNode matching the CSS selector. */
18
28
  export declare const find: {
19
29
  (html: VNode, selectorString: string): Option.Option<VNode>;
@@ -31,14 +41,21 @@ export declare const attr: {
31
41
  (vnode: VNode, name: string): Option.Option<string>;
32
42
  (name: string): (vnode: VNode) => Option.Option<string>;
33
43
  };
34
- /** Finds the first element with the given ARIA role and optional accessible name. */
35
- export declare const getByRole: (role: string, options?: Readonly<{
44
+ type RoleOptions = Readonly<{
36
45
  name?: string;
37
- }>) => (html: VNode) => Option.Option<VNode>;
38
- /** Finds all elements with the given ARIA role and optional accessible name. */
39
- export declare const getAllByRole: (html: VNode, role: string, options?: Readonly<{
40
- name?: string;
41
- }>) => ReadonlyArray<VNode>;
46
+ level?: number;
47
+ checked?: boolean | 'mixed';
48
+ selected?: boolean;
49
+ pressed?: boolean | 'mixed';
50
+ expanded?: boolean;
51
+ disabled?: boolean;
52
+ }>;
53
+ /** Finds the first element with the given ARIA role and optional matching options.
54
+ * Supports `name` (accessible name), `level` (heading level), `checked`,
55
+ * `selected`, `pressed`, `expanded`, and `disabled` state filters. */
56
+ export declare const getByRole: (role: string, options?: RoleOptions) => (html: VNode) => Option.Option<VNode>;
57
+ /** Finds all elements with the given ARIA role and optional matching options. */
58
+ export declare const getAllByRole: (role: string, options?: RoleOptions) => (html: VNode) => ReadonlyArray<VNode>;
42
59
  /** Finds the most specific element matching the given text content.
43
60
  * Skips text VNodes (sel undefined) — only returns actual DOM elements. */
44
61
  export declare const getByText: (target: string, options?: Readonly<{
@@ -47,8 +64,37 @@ export declare const getByText: (target: string, options?: Readonly<{
47
64
  /** Finds the first element with the given placeholder attribute. */
48
65
  export declare const getByPlaceholder: (placeholderValue: string) => (html: VNode) => Option.Option<VNode>;
49
66
  /** Finds the first element with the given label text. Checks `aria-label`
50
- * first, then `<label for="id">` association, then `<label>` nesting. */
67
+ * first, then `<label for="id">` association, then `<label>` nesting,
68
+ * then `aria-labelledby` reverse lookup. */
51
69
  export declare const getByLabel: (labelValue: string) => (html: VNode) => Option.Option<VNode>;
70
+ /** Finds every element with the given label text. Applies the same four
71
+ * resolution strategies as `getByLabel` (`aria-label`, `<label for="id">`,
72
+ * `<label>` nesting, `aria-labelledby`) and returns deduplicated matches. */
73
+ export declare const getAllByLabel: (labelValue: string) => (html: VNode) => ReadonlyArray<VNode>;
74
+ /** Finds the first element with the given `alt` attribute. */
75
+ export declare const getByAltText: (altValue: string) => (html: VNode) => Option.Option<VNode>;
76
+ /** Finds the first element with the given `title` attribute. */
77
+ export declare const getByTitle: (titleValue: string) => (html: VNode) => Option.Option<VNode>;
78
+ /** Finds the first element with the given `data-testid` attribute. */
79
+ export declare const getByTestId: (testIdValue: string) => (html: VNode) => Option.Option<VNode>;
80
+ /** Finds all elements matching the given text content.
81
+ * Includes nested ancestors — a `<div><p>hi</p></div>` with text "hi" yields both. */
82
+ export declare const getAllByText: (target: string, options?: Readonly<{
83
+ exact?: boolean;
84
+ }>) => (html: VNode) => ReadonlyArray<VNode>;
85
+ /** Finds all elements with the given placeholder attribute. */
86
+ export declare const getAllByPlaceholder: (placeholderValue: string) => (html: VNode) => ReadonlyArray<VNode>;
87
+ /** Finds all elements with the given `alt` attribute. */
88
+ export declare const getAllByAltText: (altValue: string) => (html: VNode) => ReadonlyArray<VNode>;
89
+ /** Finds all elements with the given `title` attribute. */
90
+ export declare const getAllByTitle: (titleValue: string) => (html: VNode) => ReadonlyArray<VNode>;
91
+ /** Finds all elements with the given `data-testid` attribute. */
92
+ export declare const getAllByTestId: (testIdValue: string) => (html: VNode) => ReadonlyArray<VNode>;
93
+ /** Finds all form controls whose current value matches. */
94
+ export declare const getAllByDisplayValue: (displayValueString: string) => (html: VNode) => ReadonlyArray<VNode>;
95
+ /** Finds the first form control whose current value matches. Checks the `value`
96
+ * attribute on inputs, textareas, and selects. */
97
+ export declare const getByDisplayValue: (displayValue: string) => (html: VNode) => Option.Option<VNode>;
52
98
  /** A deferred element query that resolves against a VNode tree. Callable as a
53
99
  * function (`locator(html)`) so it composes directly in `flow` and `pipe` chains.
54
100
  * Used by interaction steps (`click`, `type`, `submit`, `keydown`) to
@@ -56,14 +102,27 @@ export declare const getByLabel: (labelValue: string) => (html: VNode) => Option
56
102
  export type Locator = ((html: VNode) => Option.Option<VNode>) & Readonly<{
57
103
  description: string;
58
104
  }>;
59
- /** Creates a Locator that finds an element by ARIA role and optional accessible name. */
60
- export declare const role: (roleValue: string, options?: Readonly<{
61
- name?: string;
62
- }>) => Locator;
105
+ /** A deferred multi-element query that resolves to all matching VNodes.
106
+ * Produced by `all*` locator factories and by `filter(...)`. Convert to a
107
+ * single-match `Locator` via `first`, `last`, or `nth(n)`. */
108
+ export type LocatorAll = ((html: VNode) => ReadonlyArray<VNode>) & Readonly<{
109
+ description: string;
110
+ }>;
111
+ /** Creates a Locator that finds an element by ARIA role. Supports matching on
112
+ * `name`, `level`, `checked`, `selected`, `pressed`, `expanded`, and `disabled`. */
113
+ export declare const role: (roleValue: string, options?: RoleOptions) => Locator;
63
114
  /** Creates a Locator that finds an element by placeholder attribute. */
64
115
  export declare const placeholder: (placeholderValue: string) => Locator;
65
116
  /** Creates a Locator that finds an element by aria-label. */
66
117
  export declare const label: (labelValue: string) => Locator;
118
+ /** Creates a Locator that finds an element by its `alt` attribute. */
119
+ export declare const altText: (altValue: string) => Locator;
120
+ /** Creates a Locator that finds an element by its `title` attribute. */
121
+ export declare const title: (titleValue: string) => Locator;
122
+ /** Creates a Locator that finds an element by its `data-testid` attribute. */
123
+ export declare const testId: (testIdValue: string) => Locator;
124
+ /** Creates a Locator that finds a form control by its current `value`. */
125
+ export declare const displayValue: (valueString: string) => Locator;
67
126
  /** Creates a Locator that finds the most specific element matching the given text content. */
68
127
  export declare const text: (target: string, options?: Readonly<{
69
128
  exact?: boolean;
@@ -78,6 +137,48 @@ export declare const within: {
78
137
  (parent: Locator, child: Locator): Locator;
79
138
  (child: Locator): (parent: Locator) => Locator;
80
139
  };
140
+ /** Creates a LocatorAll that finds every element matching the role. */
141
+ export declare const allRole: (roleValue: string, options?: RoleOptions) => LocatorAll;
142
+ /** Creates a LocatorAll that finds every element matching the text. */
143
+ export declare const allText: (target: string, options?: Readonly<{
144
+ exact?: boolean;
145
+ }>) => LocatorAll;
146
+ /** Creates a LocatorAll that finds every element with the given label. */
147
+ export declare const allLabel: (labelValue: string) => LocatorAll;
148
+ /** Creates a LocatorAll that finds every element with the given placeholder. */
149
+ export declare const allPlaceholder: (placeholderValue: string) => LocatorAll;
150
+ /** Creates a LocatorAll that finds every element with the given alt text. */
151
+ export declare const allAltText: (altValue: string) => LocatorAll;
152
+ /** Creates a LocatorAll that finds every element with the given title. */
153
+ export declare const allTitle: (titleValue: string) => LocatorAll;
154
+ /** Creates a LocatorAll that finds every element with the given data-testid. */
155
+ export declare const allTestId: (testIdValue: string) => LocatorAll;
156
+ /** Creates a LocatorAll that finds every form control with the given value. */
157
+ export declare const allDisplayValue: (valueString: string) => LocatorAll;
158
+ /** Creates a LocatorAll from a CSS selector — returns every match. */
159
+ export declare const allSelector: (css: string) => LocatorAll;
160
+ /** Picks the first match from a LocatorAll, producing a single-match Locator. */
161
+ export declare const first: (locatorAll: LocatorAll) => Locator;
162
+ /** Picks the last match from a LocatorAll, producing a single-match Locator. */
163
+ export declare const last: (locatorAll: LocatorAll) => Locator;
164
+ /** Picks the nth match (0-indexed) from a LocatorAll, producing a Locator. */
165
+ export declare const nth: {
166
+ (locatorAll: LocatorAll, index: number): Locator;
167
+ (index: number): (locatorAll: LocatorAll) => Locator;
168
+ };
169
+ type FilterOptions = Readonly<{
170
+ has?: Locator;
171
+ hasNot?: Locator;
172
+ hasText?: string;
173
+ hasNotText?: string;
174
+ }>;
175
+ /** Filters a LocatorAll's matches. Supports `has`/`hasNot` to keep entries
176
+ * that do/don't contain a matching descendant, and `hasText`/`hasNotText`
177
+ * to keep entries whose text content does/doesn't include a substring. */
178
+ export declare const filter: {
179
+ (locatorAll: LocatorAll, options: FilterOptions): LocatorAll;
180
+ (options: FilterOptions): (locatorAll: LocatorAll) => LocatorAll;
181
+ };
81
182
  /** Resolves a target (CSS selector string or Locator) against a VNode tree. */
82
183
  export declare const resolveTarget: (html: VNode, target: string | Locator) => Readonly<{
83
184
  maybeElement: Option.Option<VNode>;
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/test/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/test/query.ts"],"names":[],"mappings":"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"}