mtrl-addons 0.1.2 → 0.2.2

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 (117) hide show
  1. package/AI.md +28 -230
  2. package/CLAUDE.md +882 -0
  3. package/build.js +253 -24
  4. package/package.json +14 -4
  5. package/scripts/debug/vlist-selection.ts +121 -0
  6. package/src/components/index.ts +5 -41
  7. package/src/components/{list → vlist}/config.ts +66 -95
  8. package/src/components/vlist/constants.ts +23 -0
  9. package/src/components/vlist/features/api.ts +626 -0
  10. package/src/components/vlist/features/index.ts +10 -0
  11. package/src/components/vlist/features/selection.ts +436 -0
  12. package/src/components/vlist/features/viewport.ts +59 -0
  13. package/src/components/vlist/index.ts +17 -0
  14. package/src/components/{list → vlist}/types.ts +242 -32
  15. package/src/components/vlist/vlist.ts +92 -0
  16. package/src/core/compose/features/gestures/index.ts +227 -0
  17. package/src/core/compose/features/gestures/longpress.ts +383 -0
  18. package/src/core/compose/features/gestures/pan.ts +424 -0
  19. package/src/core/compose/features/gestures/pinch.ts +475 -0
  20. package/src/core/compose/features/gestures/rotate.ts +485 -0
  21. package/src/core/compose/features/gestures/swipe.ts +492 -0
  22. package/src/core/compose/features/gestures/tap.ts +334 -0
  23. package/src/core/compose/features/index.ts +2 -38
  24. package/src/core/compose/index.ts +13 -29
  25. package/src/core/gestures/index.ts +31 -0
  26. package/src/core/gestures/longpress.ts +68 -0
  27. package/src/core/gestures/manager.ts +418 -0
  28. package/src/core/gestures/pan.ts +48 -0
  29. package/src/core/gestures/pinch.ts +58 -0
  30. package/src/core/gestures/rotate.ts +58 -0
  31. package/src/core/gestures/swipe.ts +66 -0
  32. package/src/core/gestures/tap.ts +45 -0
  33. package/src/core/gestures/types.ts +387 -0
  34. package/src/core/gestures/utils.ts +128 -0
  35. package/src/core/index.ts +27 -151
  36. package/src/core/layout/schema.ts +153 -72
  37. package/src/core/layout/types.ts +5 -2
  38. package/src/core/viewport/constants.ts +145 -0
  39. package/src/core/viewport/features/base.ts +73 -0
  40. package/src/core/viewport/features/collection.ts +1182 -0
  41. package/src/core/viewport/features/events.ts +130 -0
  42. package/src/core/viewport/features/index.ts +20 -0
  43. package/src/core/{list-manager/features/viewport → viewport/features}/item-size.ts +31 -34
  44. package/src/core/{list-manager/features/viewport → viewport/features}/loading.ts +4 -4
  45. package/src/core/viewport/features/momentum.ts +269 -0
  46. package/src/core/viewport/features/placeholders.ts +335 -0
  47. package/src/core/viewport/features/rendering.ts +962 -0
  48. package/src/core/viewport/features/scrollbar.ts +434 -0
  49. package/src/core/viewport/features/scrolling.ts +634 -0
  50. package/src/core/viewport/features/utils.ts +94 -0
  51. package/src/core/viewport/features/virtual.ts +525 -0
  52. package/src/core/viewport/index.ts +31 -0
  53. package/src/core/viewport/types.ts +133 -0
  54. package/src/core/viewport/utils/speed-tracker.ts +79 -0
  55. package/src/core/viewport/viewport.ts +265 -0
  56. package/src/index.ts +0 -7
  57. package/src/styles/components/_vlist.scss +352 -0
  58. package/src/styles/index.scss +1 -1
  59. package/test/components/vlist-selection.test.ts +240 -0
  60. package/test/components/vlist.test.ts +63 -0
  61. package/test/core/collection/adapter.test.ts +161 -0
  62. package/bun.lock +0 -792
  63. package/src/components/list/api.ts +0 -314
  64. package/src/components/list/constants.ts +0 -56
  65. package/src/components/list/features/api.ts +0 -428
  66. package/src/components/list/features/index.ts +0 -31
  67. package/src/components/list/features/list-manager.ts +0 -502
  68. package/src/components/list/index.ts +0 -39
  69. package/src/components/list/list.ts +0 -234
  70. package/src/core/collection/base-collection.ts +0 -100
  71. package/src/core/collection/collection-composer.ts +0 -178
  72. package/src/core/collection/collection.ts +0 -745
  73. package/src/core/collection/constants.ts +0 -172
  74. package/src/core/collection/events.ts +0 -428
  75. package/src/core/collection/features/api/loading.ts +0 -279
  76. package/src/core/collection/features/operations/data-operations.ts +0 -147
  77. package/src/core/collection/index.ts +0 -104
  78. package/src/core/collection/state.ts +0 -497
  79. package/src/core/collection/types.ts +0 -404
  80. package/src/core/compose/features/collection.ts +0 -119
  81. package/src/core/compose/features/selection.ts +0 -213
  82. package/src/core/compose/features/styling.ts +0 -108
  83. package/src/core/list-manager/api.ts +0 -599
  84. package/src/core/list-manager/config.ts +0 -593
  85. package/src/core/list-manager/constants.ts +0 -268
  86. package/src/core/list-manager/features/api.ts +0 -58
  87. package/src/core/list-manager/features/collection/collection.ts +0 -705
  88. package/src/core/list-manager/features/collection/index.ts +0 -17
  89. package/src/core/list-manager/features/viewport/constants.ts +0 -42
  90. package/src/core/list-manager/features/viewport/index.ts +0 -16
  91. package/src/core/list-manager/features/viewport/placeholders.ts +0 -281
  92. package/src/core/list-manager/features/viewport/rendering.ts +0 -575
  93. package/src/core/list-manager/features/viewport/scrollbar.ts +0 -495
  94. package/src/core/list-manager/features/viewport/scrolling.ts +0 -795
  95. package/src/core/list-manager/features/viewport/template.ts +0 -220
  96. package/src/core/list-manager/features/viewport/viewport.ts +0 -654
  97. package/src/core/list-manager/features/viewport/virtual.ts +0 -309
  98. package/src/core/list-manager/index.ts +0 -279
  99. package/src/core/list-manager/list-manager.ts +0 -206
  100. package/src/core/list-manager/types.ts +0 -439
  101. package/src/core/list-manager/utils/calculations.ts +0 -290
  102. package/src/core/list-manager/utils/range-calculator.ts +0 -349
  103. package/src/core/list-manager/utils/speed-tracker.ts +0 -273
  104. package/src/styles/components/_list.scss +0 -244
  105. package/src/types/mtrl.d.ts +0 -6
  106. package/test/components/list.test.ts +0 -256
  107. package/test/core/collection/failed-ranges.test.ts +0 -270
  108. package/test/core/compose/features.test.ts +0 -183
  109. package/test/core/list-manager/features/collection.test.ts +0 -704
  110. package/test/core/list-manager/features/viewport.test.ts +0 -698
  111. package/test/core/list-manager/list-manager.test.ts +0 -593
  112. package/test/core/list-manager/utils/calculations.test.ts +0 -433
  113. package/test/core/list-manager/utils/range-calculator.test.ts +0 -569
  114. package/test/core/list-manager/utils/speed-tracker.test.ts +0 -530
  115. package/tsconfig.build.json +0 -23
  116. /package/src/components/{list → vlist}/features.ts +0 -0
  117. /package/src/core/{compose → viewport}/features/performance.ts +0 -0
@@ -0,0 +1,161 @@
1
+ // test/core/collection/adapter.test.ts
2
+
3
+ import { describe, test, expect, beforeEach } from "bun:test";
4
+ import {
5
+ createRouteAdapter,
6
+ withRouteAdapter,
7
+ } from "../../../src/core/collection/features/adapter";
8
+ import { createCollection } from "../../../src/core/collection";
9
+
10
+ describe("Route Adapter", () => {
11
+ let fetchMock: any;
12
+
13
+ beforeEach(() => {
14
+ // Mock fetch
15
+ fetchMock = {
16
+ calls: [] as any[],
17
+ response: {
18
+ items: [
19
+ { id: "1", name: "Item 1" },
20
+ { id: "2", name: "Item 2" },
21
+ ],
22
+ meta: {
23
+ total: 100,
24
+ hasNext: true,
25
+ cursor: "next-cursor",
26
+ },
27
+ },
28
+ };
29
+
30
+ global.fetch = async (url: any, options: any) => {
31
+ fetchMock.calls.push({ url, options });
32
+ return {
33
+ ok: true,
34
+ headers: {
35
+ get: () => "application/json",
36
+ },
37
+ json: async () => fetchMock.response,
38
+ } as any;
39
+ };
40
+ });
41
+
42
+ describe("createRouteAdapter", () => {
43
+ test("creates adapter with default config", () => {
44
+ const adapter = createRouteAdapter();
45
+ expect(adapter).toBeDefined();
46
+ expect(adapter.read).toBeDefined();
47
+ expect(adapter.disconnect).toBeDefined();
48
+ });
49
+
50
+ test("makes API request with correct parameters", async () => {
51
+ const adapter = createRouteAdapter({
52
+ base: "/api",
53
+ endpoints: { list: "/users" },
54
+ headers: { Authorization: "Bearer token" },
55
+ pagination: { strategy: "offset" }, // Use offset strategy for this test
56
+ });
57
+
58
+ const result = await adapter.read({
59
+ offset: 0,
60
+ limit: 20,
61
+ search: "john",
62
+ sort: "name",
63
+ });
64
+
65
+ expect(fetchMock.calls).toHaveLength(1);
66
+ const [call] = fetchMock.calls;
67
+ expect(call.url).toContain("/api/users");
68
+ expect(call.url).toContain("offset=0");
69
+ expect(call.url).toContain("limit=20");
70
+ expect(call.url).toContain("search=john");
71
+ expect(call.url).toContain("sort=name");
72
+ expect(call.options.headers["Authorization"]).toBe("Bearer token");
73
+ });
74
+
75
+ test("handles different pagination strategies", async () => {
76
+ // Cursor pagination
77
+ const cursorAdapter = createRouteAdapter({
78
+ base: "/api",
79
+ endpoints: { list: "/items" },
80
+ pagination: { strategy: "cursor" },
81
+ });
82
+
83
+ await cursorAdapter.read({ cursor: "abc123", limit: 10 });
84
+ expect(fetchMock.calls[0].url).toContain("cursor=abc123");
85
+
86
+ // Page pagination
87
+ const pageAdapter = createRouteAdapter({
88
+ base: "/api",
89
+ endpoints: { list: "/items" },
90
+ pagination: { strategy: "page" },
91
+ });
92
+
93
+ await pageAdapter.read({ page: 3, limit: 10 });
94
+ expect(fetchMock.calls[1].url).toContain("page=3");
95
+ });
96
+
97
+ test("transforms query operators", async () => {
98
+ const adapter = createRouteAdapter({
99
+ base: "/api",
100
+ endpoints: { list: "/items" },
101
+ });
102
+
103
+ await adapter.read({
104
+ filters: {
105
+ age: { GT: 18, LTE: 65 },
106
+ status: { EQ: "active" },
107
+ tags: { IN: ["premium", "verified"] },
108
+ },
109
+ });
110
+
111
+ const url = fetchMock.calls[0].url;
112
+ expect(url).toContain("age_gt=18");
113
+ expect(url).toContain("age_lte=65");
114
+ expect(url).toContain("status_eq=active");
115
+ expect(url).toContain("tags_in=premium");
116
+ expect(url).toContain("tags_in=verified");
117
+ });
118
+
119
+ test("handles caching", async () => {
120
+ const adapter = createRouteAdapter({
121
+ base: "/api",
122
+ endpoints: { list: "/items" },
123
+ cache: true,
124
+ pagination: { strategy: "offset" }, // Use offset strategy to test offset params
125
+ });
126
+
127
+ // First call
128
+ await adapter.read({ offset: 0, limit: 10 });
129
+ expect(fetchMock.calls).toHaveLength(1);
130
+
131
+ // Second call with same params - should use cache
132
+ await adapter.read({ offset: 0, limit: 10 });
133
+ expect(fetchMock.calls).toHaveLength(1);
134
+
135
+ // Different params - should make new request
136
+ await adapter.read({ offset: 10, limit: 10 });
137
+ expect(fetchMock.calls).toHaveLength(2);
138
+ });
139
+ });
140
+
141
+ describe("withRouteAdapter", () => {
142
+ test("adds route adapter to collection", async () => {
143
+ const collection = createCollection({
144
+ pageSize: 20,
145
+ });
146
+
147
+ const enhancedCollection = withRouteAdapter({
148
+ base: "/api",
149
+ endpoints: { list: "/users" },
150
+ })(collection);
151
+
152
+ expect(enhancedCollection.disconnect).toBeDefined();
153
+
154
+ // Load data
155
+ await enhancedCollection.loadPage(1);
156
+
157
+ expect(fetchMock.calls).toHaveLength(1);
158
+ expect(fetchMock.calls[0].url).toContain("/api/users");
159
+ });
160
+ });
161
+ });