@ankhorage/zora 25.0.1 → 25.2.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.
- package/CHANGELOG.md +13 -0
- package/README.md +2 -2
- package/dist/features/explorer/adapters/inbound/Explorer.d.ts.map +1 -1
- package/dist/features/explorer/adapters/inbound/Explorer.js +72 -14
- package/dist/features/explorer/adapters/inbound/Explorer.js.map +1 -1
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.d.ts +9 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.d.ts.map +1 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.js +5 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.js.map +1 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.native.d.ts +9 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.native.d.ts.map +1 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.native.js +5 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.native.js.map +1 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.web.d.ts +9 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.web.d.ts.map +1 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.web.js +10 -0
- package/dist/features/explorer/adapters/inbound/ExplorerKeyboardProxy.web.js.map +1 -0
- package/dist/features/explorer/adapters/inbound/useExplorerKeyboardFocus.d.ts +14 -0
- package/dist/features/explorer/adapters/inbound/useExplorerKeyboardFocus.d.ts.map +1 -0
- package/dist/features/explorer/adapters/inbound/useExplorerKeyboardFocus.js +54 -0
- package/dist/features/explorer/adapters/inbound/useExplorerKeyboardFocus.js.map +1 -0
- package/dist/features/explorer/application/getExplorerNextFocusId.d.ts +6 -0
- package/dist/features/explorer/application/getExplorerNextFocusId.d.ts.map +1 -0
- package/dist/features/explorer/application/getExplorerNextFocusId.js +53 -0
- package/dist/features/explorer/application/getExplorerNextFocusId.js.map +1 -0
- package/dist/features/explorer/application/shouldDispatchExplorerPageRequest.d.ts +8 -0
- package/dist/features/explorer/application/shouldDispatchExplorerPageRequest.d.ts.map +1 -0
- package/dist/features/explorer/application/shouldDispatchExplorerPageRequest.js +9 -0
- package/dist/features/explorer/application/shouldDispatchExplorerPageRequest.js.map +1 -0
- package/dist/features/explorer/application/shouldRequestExplorerPage.d.ts +4 -0
- package/dist/features/explorer/application/shouldRequestExplorerPage.d.ts.map +1 -0
- package/dist/features/explorer/application/shouldRequestExplorerPage.js +14 -0
- package/dist/features/explorer/application/shouldRequestExplorerPage.js.map +1 -0
- package/dist/features/explorer/meta.d.ts +110 -0
- package/dist/features/explorer/meta.d.ts.map +1 -1
- package/dist/features/explorer/meta.js +25 -0
- package/dist/features/explorer/meta.js.map +1 -1
- package/dist/features/explorer/public.d.ts +2 -1
- package/dist/features/explorer/public.d.ts.map +1 -1
- package/dist/features/explorer/public.js +1 -0
- package/dist/features/explorer/public.js.map +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.d.ts +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.d.ts.map +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.js +36 -4
- package/dist/features/grid-view/adapters/inbound/GridView.js.map +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.d.ts +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.d.ts.map +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.js +7 -3
- package/dist/features/grid-view/adapters/inbound/TileGrid.js.map +1 -1
- package/dist/types/explorer.d.ts +28 -0
- package/dist/types/explorer.d.ts.map +1 -1
- package/dist/types/explorer.js.map +1 -1
- package/dist/types/grid-view.d.ts +10 -0
- package/dist/types/grid-view.d.ts.map +1 -1
- package/dist/types/grid-view.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/index.test.ts +10 -6
- package/src/features/explorer/adapters/inbound/Explorer.tsx +158 -53
- package/src/features/explorer/adapters/inbound/ExplorerKeyboardProxy.native.tsx +11 -0
- package/src/features/explorer/adapters/inbound/ExplorerKeyboardProxy.tsx +11 -0
- package/src/features/explorer/adapters/inbound/ExplorerKeyboardProxy.web.tsx +20 -0
- package/src/features/explorer/adapters/inbound/useExplorerKeyboardFocus.test.tsx +232 -0
- package/src/features/explorer/adapters/inbound/useExplorerKeyboardFocus.ts +77 -0
- package/src/features/explorer/application/getExplorerNextFocusId.test.ts +37 -0
- package/src/features/explorer/application/getExplorerNextFocusId.ts +61 -0
- package/src/features/explorer/application/shouldDispatchExplorerPageRequest.test.ts +43 -0
- package/src/features/explorer/application/shouldDispatchExplorerPageRequest.ts +18 -0
- package/src/features/explorer/application/shouldRequestExplorerPage.test.ts +93 -0
- package/src/features/explorer/application/shouldRequestExplorerPage.ts +26 -0
- package/src/features/explorer/meta.test.ts +55 -0
- package/src/features/explorer/meta.ts +25 -0
- package/src/features/explorer/public.ts +3 -0
- package/src/features/grid-view/adapters/inbound/GridView.tsx +49 -1
- package/src/features/grid-view/adapters/inbound/TileGrid.tsx +11 -0
- package/src/types/explorer.ts +30 -0
- package/src/types/grid-view.ts +10 -0
- package/web-dist/chunks/{Accordion-b20zfsfz.js → Accordion-54k0ncs3.js} +83 -0
- package/web-dist/chunks/Accordion-kkr7xfh2.js +397 -0
- package/web-dist/components/explorer/Explorer.js +2 -2
- package/web-dist/components/file-explorer/FileExplorer.js +2 -2
- package/web-dist/components/grid-view/GridView.js +1 -1
- package/web-dist/components/media-explorer/MediaExplorer.js +2 -2
- package/web-dist/components/tile-grid/TileGrid.js +1 -1
- package/web-dist/components/uploader/Uploader.js +2 -2
- package/web-dist/manifest.json +10 -10
- package/web-dist/chunks/Accordion-0md8wbtx.js +0 -197
|
@@ -38,6 +38,19 @@ export declare const mediaExplorerMeta: {
|
|
|
38
38
|
readonly type: "string";
|
|
39
39
|
}];
|
|
40
40
|
};
|
|
41
|
+
readonly loadMore: {
|
|
42
|
+
readonly label: "Load more";
|
|
43
|
+
readonly eventType: "explorer.loadMore";
|
|
44
|
+
readonly payloadFields: readonly [{
|
|
45
|
+
readonly path: "loadedItemCount";
|
|
46
|
+
readonly type: "number";
|
|
47
|
+
}];
|
|
48
|
+
};
|
|
49
|
+
readonly requestPermission: {
|
|
50
|
+
readonly label: "Request permission";
|
|
51
|
+
readonly eventType: "explorer.requestPermission";
|
|
52
|
+
readonly payloadFields: readonly [];
|
|
53
|
+
};
|
|
41
54
|
};
|
|
42
55
|
readonly props: {
|
|
43
56
|
readonly items: {
|
|
@@ -110,6 +123,14 @@ export declare const mediaExplorerMeta: {
|
|
|
110
123
|
readonly type: "array";
|
|
111
124
|
readonly category: "Selection";
|
|
112
125
|
};
|
|
126
|
+
readonly defaultSelectedIds: {
|
|
127
|
+
readonly type: "array";
|
|
128
|
+
readonly category: "Selection";
|
|
129
|
+
};
|
|
130
|
+
readonly width: {
|
|
131
|
+
readonly type: "number";
|
|
132
|
+
readonly category: "Layout";
|
|
133
|
+
};
|
|
113
134
|
readonly tileSize: {
|
|
114
135
|
readonly type: "number";
|
|
115
136
|
readonly category: "Layout";
|
|
@@ -129,6 +150,32 @@ export declare const mediaExplorerMeta: {
|
|
|
129
150
|
readonly type: "boolean";
|
|
130
151
|
readonly category: "State";
|
|
131
152
|
};
|
|
153
|
+
readonly hasMore: {
|
|
154
|
+
readonly type: "boolean";
|
|
155
|
+
readonly category: "Paging";
|
|
156
|
+
};
|
|
157
|
+
readonly loadingMore: {
|
|
158
|
+
readonly type: "boolean";
|
|
159
|
+
readonly category: "Paging";
|
|
160
|
+
};
|
|
161
|
+
readonly pagingCollectionId: {
|
|
162
|
+
readonly type: "string";
|
|
163
|
+
readonly category: "Paging";
|
|
164
|
+
};
|
|
165
|
+
readonly pagingRetryToken: {
|
|
166
|
+
readonly type: "string";
|
|
167
|
+
readonly category: "Paging";
|
|
168
|
+
};
|
|
169
|
+
readonly permissionStatus: {
|
|
170
|
+
readonly type: "enum";
|
|
171
|
+
readonly category: "Permission";
|
|
172
|
+
readonly enum: readonly ["granted", "limited", "denied", "unavailable"];
|
|
173
|
+
readonly default: "granted";
|
|
174
|
+
};
|
|
175
|
+
readonly permissionText: {
|
|
176
|
+
readonly type: "string";
|
|
177
|
+
readonly category: "Permission";
|
|
178
|
+
};
|
|
132
179
|
readonly errorText: {
|
|
133
180
|
readonly type: "string";
|
|
134
181
|
readonly category: "State";
|
|
@@ -153,6 +200,14 @@ export declare const mediaExplorerMeta: {
|
|
|
153
200
|
readonly type: "action";
|
|
154
201
|
readonly category: "Events";
|
|
155
202
|
};
|
|
203
|
+
readonly onLoadMore: {
|
|
204
|
+
readonly type: "action";
|
|
205
|
+
readonly category: "Events";
|
|
206
|
+
};
|
|
207
|
+
readonly onRequestPermission: {
|
|
208
|
+
readonly type: "action";
|
|
209
|
+
readonly category: "Events";
|
|
210
|
+
};
|
|
156
211
|
};
|
|
157
212
|
};
|
|
158
213
|
export declare const fileExplorerMeta: {
|
|
@@ -186,6 +241,19 @@ export declare const fileExplorerMeta: {
|
|
|
186
241
|
readonly type: "string";
|
|
187
242
|
}];
|
|
188
243
|
};
|
|
244
|
+
readonly loadMore: {
|
|
245
|
+
readonly label: "Load more";
|
|
246
|
+
readonly eventType: "explorer.loadMore";
|
|
247
|
+
readonly payloadFields: readonly [{
|
|
248
|
+
readonly path: "loadedItemCount";
|
|
249
|
+
readonly type: "number";
|
|
250
|
+
}];
|
|
251
|
+
};
|
|
252
|
+
readonly requestPermission: {
|
|
253
|
+
readonly label: "Request permission";
|
|
254
|
+
readonly eventType: "explorer.requestPermission";
|
|
255
|
+
readonly payloadFields: readonly [];
|
|
256
|
+
};
|
|
189
257
|
};
|
|
190
258
|
readonly props: {
|
|
191
259
|
readonly items: {
|
|
@@ -258,6 +326,14 @@ export declare const fileExplorerMeta: {
|
|
|
258
326
|
readonly type: "array";
|
|
259
327
|
readonly category: "Selection";
|
|
260
328
|
};
|
|
329
|
+
readonly defaultSelectedIds: {
|
|
330
|
+
readonly type: "array";
|
|
331
|
+
readonly category: "Selection";
|
|
332
|
+
};
|
|
333
|
+
readonly width: {
|
|
334
|
+
readonly type: "number";
|
|
335
|
+
readonly category: "Layout";
|
|
336
|
+
};
|
|
261
337
|
readonly tileSize: {
|
|
262
338
|
readonly type: "number";
|
|
263
339
|
readonly category: "Layout";
|
|
@@ -277,6 +353,32 @@ export declare const fileExplorerMeta: {
|
|
|
277
353
|
readonly type: "boolean";
|
|
278
354
|
readonly category: "State";
|
|
279
355
|
};
|
|
356
|
+
readonly hasMore: {
|
|
357
|
+
readonly type: "boolean";
|
|
358
|
+
readonly category: "Paging";
|
|
359
|
+
};
|
|
360
|
+
readonly loadingMore: {
|
|
361
|
+
readonly type: "boolean";
|
|
362
|
+
readonly category: "Paging";
|
|
363
|
+
};
|
|
364
|
+
readonly pagingCollectionId: {
|
|
365
|
+
readonly type: "string";
|
|
366
|
+
readonly category: "Paging";
|
|
367
|
+
};
|
|
368
|
+
readonly pagingRetryToken: {
|
|
369
|
+
readonly type: "string";
|
|
370
|
+
readonly category: "Paging";
|
|
371
|
+
};
|
|
372
|
+
readonly permissionStatus: {
|
|
373
|
+
readonly type: "enum";
|
|
374
|
+
readonly category: "Permission";
|
|
375
|
+
readonly enum: readonly ["granted", "limited", "denied", "unavailable"];
|
|
376
|
+
readonly default: "granted";
|
|
377
|
+
};
|
|
378
|
+
readonly permissionText: {
|
|
379
|
+
readonly type: "string";
|
|
380
|
+
readonly category: "Permission";
|
|
381
|
+
};
|
|
280
382
|
readonly errorText: {
|
|
281
383
|
readonly type: "string";
|
|
282
384
|
readonly category: "State";
|
|
@@ -301,6 +403,14 @@ export declare const fileExplorerMeta: {
|
|
|
301
403
|
readonly type: "action";
|
|
302
404
|
readonly category: "Events";
|
|
303
405
|
};
|
|
406
|
+
readonly onLoadMore: {
|
|
407
|
+
readonly type: "action";
|
|
408
|
+
readonly category: "Events";
|
|
409
|
+
};
|
|
410
|
+
readonly onRequestPermission: {
|
|
411
|
+
readonly type: "action";
|
|
412
|
+
readonly category: "Events";
|
|
413
|
+
};
|
|
304
414
|
};
|
|
305
415
|
};
|
|
306
416
|
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/features/explorer/meta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/features/explorer/meta.ts"],"names":[],"mappings":"AAkFA,0FAA0F;AAC1F,eAAO,MAAM,YAAY;;;;;;;CAOa,CAAC;AAEvC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYQ,CAAC;AAEvC,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYS,CAAC"}
|
|
@@ -28,16 +28,31 @@ const explorerProps = {
|
|
|
28
28
|
default: 'single',
|
|
29
29
|
},
|
|
30
30
|
selectedIds: { type: 'array', category: 'Selection' },
|
|
31
|
+
defaultSelectedIds: { type: 'array', category: 'Selection' },
|
|
32
|
+
width: { type: 'number', category: 'Layout' },
|
|
31
33
|
tileSize: { type: 'number', category: 'Layout', default: 120 },
|
|
32
34
|
height: { type: 'number', category: 'Layout', default: 440 },
|
|
33
35
|
zoom: { type: 'number', category: 'Layout', default: 1 },
|
|
34
36
|
loading: { type: 'boolean', category: 'State' },
|
|
37
|
+
hasMore: { type: 'boolean', category: 'Paging' },
|
|
38
|
+
loadingMore: { type: 'boolean', category: 'Paging' },
|
|
39
|
+
pagingCollectionId: { type: 'string', category: 'Paging' },
|
|
40
|
+
pagingRetryToken: { type: 'string', category: 'Paging' },
|
|
41
|
+
permissionStatus: {
|
|
42
|
+
type: 'enum',
|
|
43
|
+
category: 'Permission',
|
|
44
|
+
enum: ['granted', 'limited', 'denied', 'unavailable'],
|
|
45
|
+
default: 'granted',
|
|
46
|
+
},
|
|
47
|
+
permissionText: { type: 'string', category: 'Permission' },
|
|
35
48
|
errorText: { type: 'string', category: 'State' },
|
|
36
49
|
emptyText: { type: 'string', category: 'Content' },
|
|
37
50
|
disabled: { type: 'boolean', category: 'State' },
|
|
38
51
|
readOnly: { type: 'boolean', category: 'State' },
|
|
39
52
|
onSelectionChange: { type: 'action', category: 'Events' },
|
|
40
53
|
onActivate: { type: 'action', category: 'Events' },
|
|
54
|
+
onLoadMore: { type: 'action', category: 'Events' },
|
|
55
|
+
onRequestPermission: { type: 'action', category: 'Events' },
|
|
41
56
|
};
|
|
42
57
|
const explorerEvents = {
|
|
43
58
|
selectionChange: {
|
|
@@ -50,6 +65,16 @@ const explorerEvents = {
|
|
|
50
65
|
eventType: 'explorer.activate',
|
|
51
66
|
payloadFields: [{ path: 'id', type: 'string' }],
|
|
52
67
|
},
|
|
68
|
+
loadMore: {
|
|
69
|
+
label: 'Load more',
|
|
70
|
+
eventType: 'explorer.loadMore',
|
|
71
|
+
payloadFields: [{ path: 'loadedItemCount', type: 'number' }],
|
|
72
|
+
},
|
|
73
|
+
requestPermission: {
|
|
74
|
+
label: 'Request permission',
|
|
75
|
+
eventType: 'explorer.requestPermission',
|
|
76
|
+
payloadFields: [],
|
|
77
|
+
},
|
|
53
78
|
};
|
|
54
79
|
/** Framework-bound Explorer is a composition primitive, not a separate manifest shape. */
|
|
55
80
|
export const explorerMeta = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/features/explorer/meta.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE;YACV,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;YAC/D;gBACE,GAAG,EAAE,MAAM;gBACX,MAAM,EAAE;oBACN,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC;iBAChE;aACF;YACD,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;YAChE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;YAC5D,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;YACtE,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;YACpE,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;YAClE,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;YACvE,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;SACpE;KACF;IACD,aAAa,EAAE;QACb,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,WAAW;QACrB,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QACzB,OAAO,EAAE,QAAQ;KAClB;IACD,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE;IACrD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE;IAC9D,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE;IAC5D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;IACxD,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;IAC/C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE;IAChD,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE;IAClD,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;IAChD,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;IAChD,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACzD,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/features/explorer/meta.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ZoraComponentMeta } from '../../types/authoring';\n\nconst explorerProps = {\n items: {\n type: 'array',\n category: 'Data',\n itemSchema: [\n { key: 'id', schema: { type: 'string', category: 'Identity' } },\n {\n key: 'kind',\n schema: {\n type: 'enum',\n category: 'Data',\n enum: ['image', 'video', 'audio', 'document', 'file', 'folder'],\n },\n },\n { key: 'name', schema: { type: 'string', category: 'Content' } },\n { key: 'uri', schema: { type: 'string', category: 'Data' } },\n { key: 'thumbnailUri', schema: { type: 'string', category: 'Media' } },\n { key: 'contentType', schema: { type: 'string', category: 'Data' } },\n { key: 'sizeBytes', schema: { type: 'number', category: 'Data' } },\n { key: 'providerId', schema: { type: 'string', category: 'Identity' } },\n { key: 'disabled', schema: { type: 'boolean', category: 'State' } },\n ],\n },\n selectionMode: {\n type: 'enum',\n category: 'Selection',\n enum: ['single', 'multi'],\n default: 'single',\n },\n selectedIds: { type: 'array', category: 'Selection' },\n defaultSelectedIds: { type: 'array', category: 'Selection' },\n width: { type: 'number', category: 'Layout' },\n tileSize: { type: 'number', category: 'Layout', default: 120 },\n height: { type: 'number', category: 'Layout', default: 440 },\n zoom: { type: 'number', category: 'Layout', default: 1 },\n loading: { type: 'boolean', category: 'State' },\n hasMore: { type: 'boolean', category: 'Paging' },\n loadingMore: { type: 'boolean', category: 'Paging' },\n pagingCollectionId: { type: 'string', category: 'Paging' },\n pagingRetryToken: { type: 'string', category: 'Paging' },\n permissionStatus: {\n type: 'enum',\n category: 'Permission',\n enum: ['granted', 'limited', 'denied', 'unavailable'],\n default: 'granted',\n },\n permissionText: { type: 'string', category: 'Permission' },\n errorText: { type: 'string', category: 'State' },\n emptyText: { type: 'string', category: 'Content' },\n disabled: { type: 'boolean', category: 'State' },\n readOnly: { type: 'boolean', category: 'State' },\n onSelectionChange: { type: 'action', category: 'Events' },\n onActivate: { type: 'action', category: 'Events' },\n onLoadMore: { type: 'action', category: 'Events' },\n onRequestPermission: { type: 'action', category: 'Events' },\n} as const;\n\nconst explorerEvents = {\n selectionChange: {\n label: 'Selection change',\n eventType: 'explorer.selectionChange',\n payloadFields: [{ path: 'selectedIds', type: 'unknown' }],\n },\n activate: {\n label: 'Activate item',\n eventType: 'explorer.activate',\n payloadFields: [{ path: 'id', type: 'string' }],\n },\n loadMore: {\n label: 'Load more',\n eventType: 'explorer.loadMore',\n payloadFields: [{ path: 'loadedItemCount', type: 'number' }],\n },\n requestPermission: {\n label: 'Request permission',\n eventType: 'explorer.requestPermission',\n payloadFields: [],\n },\n} as const;\n\n/** Framework-bound Explorer is a composition primitive, not a separate manifest shape. */\nexport const explorerMeta = {\n name: 'Explorer',\n category: 'pattern',\n directManifestNode: false,\n note: 'Shared code-only Explorer composition; MediaExplorer and FileExplorer own manifest representation.',\n allowedChildren: [],\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const mediaExplorerMeta = {\n name: 'MediaExplorer',\n category: 'pattern',\n description: 'Virtualized media library with normalized selection and activation events.',\n directManifestNode: true,\n allowedChildren: [],\n blueprint: {\n label: 'Media explorer',\n defaultProps: { items: [], selectionMode: 'single', tileSize: 120 },\n },\n events: explorerEvents,\n props: explorerProps,\n} as const satisfies ZoraComponentMeta;\n\nexport const fileExplorerMeta = {\n name: 'FileExplorer',\n category: 'pattern',\n description: 'Virtualized file and folder collection with normalized selection and activation.',\n directManifestNode: true,\n allowedChildren: [],\n blueprint: {\n label: 'File explorer',\n defaultProps: { items: [], selectionMode: 'single', tileSize: 120 },\n },\n events: explorerEvents,\n props: explorerProps,\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export type { ExplorerActivateEvent, ExplorerItem, ExplorerItemKind, ExplorerProps, ExplorerSelectionChangeEvent, ExplorerSelectionMode, } from '../../types/explorer';
|
|
1
|
+
export type { ExplorerActivateEvent, ExplorerItem, ExplorerItemKind, ExplorerPageRequestEvent, ExplorerPermissionStatus, ExplorerProps, ExplorerSelectionChangeEvent, ExplorerSelectionMode, } from '../../types/explorer';
|
|
2
2
|
export { Explorer } from './adapters/inbound/Explorer';
|
|
3
3
|
export { FileExplorer } from './adapters/inbound/FileExplorer';
|
|
4
4
|
export { MediaExplorer } from './adapters/inbound/MediaExplorer';
|
|
5
|
+
export { getExplorerNextFocusId } from './application/getExplorerNextFocusId';
|
|
5
6
|
export { resolveExplorerSelection } from './application/resolveExplorerSelection';
|
|
6
7
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/explorer/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/explorer/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Explorer } from './adapters/inbound/Explorer';
|
|
2
2
|
export { FileExplorer } from './adapters/inbound/FileExplorer';
|
|
3
3
|
export { MediaExplorer } from './adapters/inbound/MediaExplorer';
|
|
4
|
+
export { getExplorerNextFocusId } from './application/getExplorerNextFocusId';
|
|
4
5
|
export { resolveExplorerSelection } from './application/resolveExplorerSelection';
|
|
5
6
|
//# sourceMappingURL=public.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/explorer/public.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/explorer/public.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC","sourcesContent":["export type {\n ExplorerActivateEvent,\n ExplorerItem,\n ExplorerItemKind,\n ExplorerPageRequestEvent,\n ExplorerPermissionStatus,\n ExplorerProps,\n ExplorerSelectionChangeEvent,\n ExplorerSelectionMode,\n} from '../../types/explorer';\nexport { Explorer } from './adapters/inbound/Explorer';\nexport { FileExplorer } from './adapters/inbound/FileExplorer';\nexport { MediaExplorer } from './adapters/inbound/MediaExplorer';\nexport { getExplorerNextFocusId } from './application/getExplorerNextFocusId';\nexport { resolveExplorerSelection } from './application/resolveExplorerSelection';\n"]}
|
|
@@ -6,5 +6,5 @@ import type { GridViewProps } from '../../../../types/grid-view';
|
|
|
6
6
|
* This first renderer uses nested native scroll regions. Only visible items are mounted;
|
|
7
7
|
* logical cells and invisible elements are never rendered.
|
|
8
8
|
*/
|
|
9
|
-
export declare function GridView({ items, contentWidth, contentHeight, width, height, zoom, overscanPixels, interactionPolicy, onViewportChange, renderItem, testID, }: GridViewProps): React.JSX.Element;
|
|
9
|
+
export declare function GridView({ items, contentWidth, contentHeight, width, height, zoom, overscanPixels, focusedItemId, revealPaddingPixels, interactionPolicy, onViewportChange, onVisibleItemIdsChange, renderItem, testID, }: GridViewProps): React.JSX.Element;
|
|
10
10
|
//# sourceMappingURL=GridView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridView.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GridView.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,YAAY,EACZ,aAAa,EACb,KAAK,EACL,MAAM,EACN,IAAQ,EACR,cAAoB,EACpB,aAAa,EACb,mBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,MAAM,GACP,EAAE,aAAa,qBA8Gf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getVisibleGridItems, worldToViewport } from '@ankhorage/grid-view';
|
|
1
|
+
import { getVisibleGridItems, revealWorldRect, worldToViewport, } from '@ankhorage/grid-view';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { ScrollView as NativeScrollView, View as NativeView } from 'react-native';
|
|
4
4
|
/***
|
|
@@ -7,9 +7,11 @@ import { ScrollView as NativeScrollView, View as NativeView } from 'react-native
|
|
|
7
7
|
* This first renderer uses nested native scroll regions. Only visible items are mounted;
|
|
8
8
|
* logical cells and invisible elements are never rendered.
|
|
9
9
|
*/
|
|
10
|
-
export function GridView({ items, contentWidth, contentHeight, width, height, zoom = 1, overscanPixels = 160, interactionPolicy, onViewportChange, renderItem, testID, }) {
|
|
10
|
+
export function GridView({ items, contentWidth, contentHeight, width, height, zoom = 1, overscanPixels = 160, focusedItemId, revealPaddingPixels = 8, interactionPolicy, onViewportChange, onVisibleItemIdsChange, renderItem, testID, }) {
|
|
11
11
|
const [scrollX, setScrollX] = React.useState(0);
|
|
12
12
|
const [scrollY, setScrollY] = React.useState(0);
|
|
13
|
+
const horizontalScrollRef = React.useRef(null);
|
|
14
|
+
const verticalScrollRef = React.useRef(null);
|
|
13
15
|
const scale = Math.max(0.01, zoom);
|
|
14
16
|
const viewport = React.useMemo(() => ({
|
|
15
17
|
width,
|
|
@@ -20,11 +22,41 @@ export function GridView({ items, contentWidth, contentHeight, width, height, zo
|
|
|
20
22
|
pixelsPerUnitY: scale,
|
|
21
23
|
}), [height, scale, scrollX, scrollY, width]);
|
|
22
24
|
const visibleItems = React.useMemo(() => getVisibleGridItems(items, viewport, overscanPixels), [items, overscanPixels, viewport]);
|
|
25
|
+
const viewportVisibleIds = React.useMemo(() => getVisibleGridItems(visibleItems, viewport).map((item) => item.id), [viewport, visibleItems]);
|
|
26
|
+
const previousVisibleIdsRef = React.useRef([]);
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
if (!onVisibleItemIdsChange)
|
|
29
|
+
return;
|
|
30
|
+
const previous = previousVisibleIdsRef.current;
|
|
31
|
+
if (previous.length === viewportVisibleIds.length &&
|
|
32
|
+
previous.every((id, index) => id === viewportVisibleIds.at(index))) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
previousVisibleIdsRef.current = viewportVisibleIds;
|
|
36
|
+
onVisibleItemIdsChange(viewportVisibleIds);
|
|
37
|
+
}, [onVisibleItemIdsChange, viewportVisibleIds]);
|
|
23
38
|
React.useEffect(() => {
|
|
24
39
|
onViewportChange?.(viewport);
|
|
25
40
|
}, [onViewportChange, viewport]);
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
const viewportRef = React.useRef(viewport);
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
viewportRef.current = viewport;
|
|
44
|
+
}, [viewport]);
|
|
45
|
+
React.useEffect(() => {
|
|
46
|
+
const currentViewport = viewportRef.current;
|
|
47
|
+
const focusedItem = items.find((item) => item.id === focusedItemId);
|
|
48
|
+
if (!focusedItem)
|
|
49
|
+
return;
|
|
50
|
+
const revealed = revealWorldRect(currentViewport, focusedItem, revealPaddingPixels);
|
|
51
|
+
if (revealed.offsetX !== currentViewport.offsetX) {
|
|
52
|
+
horizontalScrollRef.current?.scrollTo({ x: revealed.offsetX * scale, animated: true });
|
|
53
|
+
}
|
|
54
|
+
if (revealed.offsetY !== currentViewport.offsetY) {
|
|
55
|
+
verticalScrollRef.current?.scrollTo({ y: revealed.offsetY * scale, animated: true });
|
|
56
|
+
}
|
|
57
|
+
}, [focusedItemId, height, items, revealPaddingPixels, scale, width]);
|
|
58
|
+
return (<NativeScrollView ref={horizontalScrollRef} horizontal scrollEnabled={interactionPolicy !== 'passive'} scrollEventThrottle={32} showsHorizontalScrollIndicator style={{ width, height }} testID={testID} onScroll={(event) => setScrollX(event.nativeEvent.contentOffset.x)}>
|
|
59
|
+
<NativeScrollView ref={verticalScrollRef} scrollEnabled={interactionPolicy !== 'passive'} scrollEventThrottle={32} showsVerticalScrollIndicator style={{ width: contentWidth * scale, height }} onScroll={(event) => setScrollY(event.nativeEvent.contentOffset.y)}>
|
|
28
60
|
<NativeView style={{ width: contentWidth * scale, height: contentHeight * scale }}>
|
|
29
61
|
{visibleItems.map((item) => {
|
|
30
62
|
const position = worldToViewport({ x: item.x, y: item.y }, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridView.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"GridView.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getVisibleGridItems,\n type GridViewport,\n revealWorldRect,\n worldToViewport,\n} from '@ankhorage/grid-view';\nimport React from 'react';\nimport { ScrollView as NativeScrollView, View as NativeView } from 'react-native';\n\nimport type { GridViewProps } from '../../../../types/grid-view';\n\n/***\n * Renders world-positioned items on native and web using the canonical viewport/culling engine.\n *\n * This first renderer uses nested native scroll regions. Only visible items are mounted;\n * logical cells and invisible elements are never rendered.\n */\nexport function GridView({\n items,\n contentWidth,\n contentHeight,\n width,\n height,\n zoom = 1,\n overscanPixels = 160,\n focusedItemId,\n revealPaddingPixels = 8,\n interactionPolicy,\n onViewportChange,\n onVisibleItemIdsChange,\n renderItem,\n testID,\n}: GridViewProps) {\n const [scrollX, setScrollX] = React.useState(0);\n const [scrollY, setScrollY] = React.useState(0);\n const horizontalScrollRef = React.useRef<NativeScrollView>(null);\n const verticalScrollRef = React.useRef<NativeScrollView>(null);\n const scale = Math.max(0.01, zoom);\n const viewport = React.useMemo<GridViewport>(\n () => ({\n width,\n height,\n offsetX: scrollX / scale,\n offsetY: scrollY / scale,\n pixelsPerUnitX: scale,\n pixelsPerUnitY: scale,\n }),\n [height, scale, scrollX, scrollY, width],\n );\n const visibleItems = React.useMemo(\n () => getVisibleGridItems(items, viewport, overscanPixels),\n [items, overscanPixels, viewport],\n );\n const viewportVisibleIds = React.useMemo(\n () => getVisibleGridItems(visibleItems, viewport).map((item) => item.id),\n [viewport, visibleItems],\n );\n const previousVisibleIdsRef = React.useRef<readonly string[]>([]);\n\n React.useEffect(() => {\n if (!onVisibleItemIdsChange) return;\n const previous = previousVisibleIdsRef.current;\n if (\n previous.length === viewportVisibleIds.length &&\n previous.every((id, index) => id === viewportVisibleIds.at(index))\n ) {\n return;\n }\n previousVisibleIdsRef.current = viewportVisibleIds;\n onVisibleItemIdsChange(viewportVisibleIds);\n }, [onVisibleItemIdsChange, viewportVisibleIds]);\n\n React.useEffect(() => {\n onViewportChange?.(viewport);\n }, [onViewportChange, viewport]);\n\n const viewportRef = React.useRef(viewport);\n React.useEffect(() => {\n viewportRef.current = viewport;\n }, [viewport]);\n\n React.useEffect(() => {\n const currentViewport = viewportRef.current;\n const focusedItem = items.find((item) => item.id === focusedItemId);\n if (!focusedItem) return;\n const revealed = revealWorldRect(currentViewport, focusedItem, revealPaddingPixels);\n if (revealed.offsetX !== currentViewport.offsetX) {\n horizontalScrollRef.current?.scrollTo({ x: revealed.offsetX * scale, animated: true });\n }\n if (revealed.offsetY !== currentViewport.offsetY) {\n verticalScrollRef.current?.scrollTo({ y: revealed.offsetY * scale, animated: true });\n }\n }, [focusedItemId, height, items, revealPaddingPixels, scale, width]);\n\n return (\n <NativeScrollView\n ref={horizontalScrollRef}\n horizontal\n scrollEnabled={interactionPolicy !== 'passive'}\n scrollEventThrottle={32}\n showsHorizontalScrollIndicator\n style={{ width, height }}\n testID={testID}\n onScroll={(event) => setScrollX(event.nativeEvent.contentOffset.x)}\n >\n <NativeScrollView\n ref={verticalScrollRef}\n scrollEnabled={interactionPolicy !== 'passive'}\n scrollEventThrottle={32}\n showsVerticalScrollIndicator\n style={{ width: contentWidth * scale, height }}\n onScroll={(event) => setScrollY(event.nativeEvent.contentOffset.y)}\n >\n <NativeView style={{ width: contentWidth * scale, height: contentHeight * scale }}>\n {visibleItems.map((item) => {\n const position = worldToViewport(\n { x: item.x, y: item.y },\n {\n ...viewport,\n offsetX: 0,\n offsetY: 0,\n },\n );\n return (\n <NativeView\n key={item.id}\n style={{\n position: 'absolute',\n left: position.x,\n top: position.y,\n width: item.width * scale,\n height: item.height * scale,\n }}\n >\n {renderItem(item)}\n </NativeView>\n );\n })}\n </NativeView>\n </NativeScrollView>\n </NativeScrollView>\n );\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { TileGridProps } from '../../../../types/grid-view';
|
|
3
3
|
/*** Composes a responsive, virtualized tile presentation over the generic GridView renderer. */
|
|
4
|
-
export declare function TileGrid({ items, width, height, tileSize, gap, zoom, overscanPixels, renderItem, interactionPolicy, testID, }: TileGridProps): React.JSX.Element;
|
|
4
|
+
export declare function TileGrid({ items, width, height, tileSize, gap, zoom, overscanPixels, focusedItemId, revealPaddingPixels, onColumnsChange, onVisibleItemIdsChange, renderItem, interactionPolicy, testID, }: TileGridProps): React.JSX.Element;
|
|
5
5
|
//# sourceMappingURL=TileGrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileGrid.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/TileGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,MAAY,EACZ,QAAc,EACd,GAAQ,EACR,IAAQ,EACR,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,MAAM,GACP,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"TileGrid.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/TileGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,MAAY,EACZ,QAAc,EACd,GAAQ,EACR,IAAQ,EACR,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,UAAU,EACV,iBAAiB,EACjB,MAAM,GACP,EAAE,aAAa,qBAwCf"}
|
|
@@ -3,16 +3,20 @@ import { View as NativeView } from 'react-native';
|
|
|
3
3
|
import { layoutTileGrid } from '../../application/layoutTileGrid';
|
|
4
4
|
import { GridView } from './GridView';
|
|
5
5
|
/*** Composes a responsive, virtualized tile presentation over the generic GridView renderer. */
|
|
6
|
-
export function TileGrid({ items, width, height = 440, tileSize = 120, gap = 12, zoom = 1, overscanPixels, renderItem, interactionPolicy, testID, }) {
|
|
6
|
+
export function TileGrid({ items, width, height = 440, tileSize = 120, gap = 12, zoom = 1, overscanPixels, focusedItemId, revealPaddingPixels, onColumnsChange, onVisibleItemIdsChange, renderItem, interactionPolicy, testID, }) {
|
|
7
7
|
const [measuredWidth, setMeasuredWidth] = React.useState(0);
|
|
8
8
|
const resolvedWidth = width ?? measuredWidth;
|
|
9
9
|
const layout = React.useMemo(() => layoutTileGrid(items, resolvedWidth, tileSize, gap, zoom), [items, resolvedWidth, tileSize, gap, zoom]);
|
|
10
10
|
const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
if (resolvedWidth > 0)
|
|
13
|
+
onColumnsChange?.(layout.columns);
|
|
14
|
+
}, [layout.columns, onColumnsChange, resolvedWidth]);
|
|
11
15
|
return (<NativeView onLayout={(event) => setMeasuredWidth(event.nativeEvent.layout.width)} style={{ width, height, overflow: 'hidden' }} testID={testID}>
|
|
12
|
-
{resolvedWidth > 0 ? (<GridView contentHeight={layout.height} contentWidth={Math.max(resolvedWidth / zoom, layout.width)} height={height} interactionPolicy={interactionPolicy} items={layout.items} overscanPixels={overscanPixels} renderItem={(item) => {
|
|
16
|
+
{resolvedWidth > 0 ? (<GridView contentHeight={layout.height} contentWidth={Math.max(resolvedWidth / zoom, layout.width)} height={height} focusedItemId={focusedItemId} interactionPolicy={interactionPolicy} items={layout.items} onVisibleItemIdsChange={onVisibleItemIdsChange} overscanPixels={overscanPixels} renderItem={(item) => {
|
|
13
17
|
const source = itemLookup.get(item.id);
|
|
14
18
|
return source ? renderItem(source) : null;
|
|
15
|
-
}} width={resolvedWidth} zoom={zoom}/>) : null}
|
|
19
|
+
}} revealPaddingPixels={revealPaddingPixels} width={resolvedWidth} zoom={zoom}/>) : null}
|
|
16
20
|
</NativeView>);
|
|
17
21
|
}
|
|
18
22
|
//# sourceMappingURL=TileGrid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileGrid.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/TileGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,gGAAgG;AAChG,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,MAAM,GAAG,GAAG,EACZ,QAAQ,GAAG,GAAG,EACd,GAAG,GAAG,EAAE,EACR,IAAI,GAAG,CAAC,EACR,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,MAAM,GACQ;IACd,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,KAAK,IAAI,aAAa,CAAC;IAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,EAC/D,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAC5C,CAAC;IACF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAE/F,OAAO,CACL,CAAC,UAAU,CACT,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CACtE,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAC7C,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,CACnB,CAAC,QAAQ,CACP,aAAa,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAC7B,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAC3D,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,CACrC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACpB,cAAc,CAAC,CAAC,cAAc,CAAC,CAC/B,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE;gBACnB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvC,OAAO,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5C,CAAC,CAAC,CACF,KAAK,CAAC,CAAC,aAAa,CAAC,CACrB,IAAI,CAAC,CAAC,IAAI,CAAC,EACX,CACH,CAAC,CAAC,CAAC,IAAI,CACV;IAAA,EAAE,UAAU,CAAC,CACd,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\nimport { View as NativeView } from 'react-native';\n\nimport type { TileGridProps } from '../../../../types/grid-view';\nimport { layoutTileGrid } from '../../application/layoutTileGrid';\nimport { GridView } from './GridView';\n\n/*** Composes a responsive, virtualized tile presentation over the generic GridView renderer. */\nexport function TileGrid({\n items,\n width,\n height = 440,\n tileSize = 120,\n gap = 12,\n zoom = 1,\n overscanPixels,\n renderItem,\n interactionPolicy,\n testID,\n}: TileGridProps) {\n const [measuredWidth, setMeasuredWidth] = React.useState(0);\n const resolvedWidth = width ?? measuredWidth;\n const layout = React.useMemo(\n () => layoutTileGrid(items, resolvedWidth, tileSize, gap, zoom),\n [items, resolvedWidth, tileSize, gap, zoom],\n );\n const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);\n\n return (\n <NativeView\n onLayout={(event) => setMeasuredWidth(event.nativeEvent.layout.width)}\n style={{ width, height, overflow: 'hidden' }}\n testID={testID}\n >\n {resolvedWidth > 0 ? (\n <GridView\n contentHeight={layout.height}\n contentWidth={Math.max(resolvedWidth / zoom, layout.width)}\n height={height}\n interactionPolicy={interactionPolicy}\n items={layout.items}\n overscanPixels={overscanPixels}\n renderItem={(item) => {\n const source = itemLookup.get(item.id);\n return source ? renderItem(source) : null;\n }}\n width={resolvedWidth}\n zoom={zoom}\n />\n ) : null}\n </NativeView>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TileGrid.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/TileGrid.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { View as NativeView } from 'react-native';\n\nimport type { TileGridProps } from '../../../../types/grid-view';\nimport { layoutTileGrid } from '../../application/layoutTileGrid';\nimport { GridView } from './GridView';\n\n/*** Composes a responsive, virtualized tile presentation over the generic GridView renderer. */\nexport function TileGrid({\n items,\n width,\n height = 440,\n tileSize = 120,\n gap = 12,\n zoom = 1,\n overscanPixels,\n focusedItemId,\n revealPaddingPixels,\n onColumnsChange,\n onVisibleItemIdsChange,\n renderItem,\n interactionPolicy,\n testID,\n}: TileGridProps) {\n const [measuredWidth, setMeasuredWidth] = React.useState(0);\n const resolvedWidth = width ?? measuredWidth;\n const layout = React.useMemo(\n () => layoutTileGrid(items, resolvedWidth, tileSize, gap, zoom),\n [items, resolvedWidth, tileSize, gap, zoom],\n );\n const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);\n\n React.useEffect(() => {\n if (resolvedWidth > 0) onColumnsChange?.(layout.columns);\n }, [layout.columns, onColumnsChange, resolvedWidth]);\n\n return (\n <NativeView\n onLayout={(event) => setMeasuredWidth(event.nativeEvent.layout.width)}\n style={{ width, height, overflow: 'hidden' }}\n testID={testID}\n >\n {resolvedWidth > 0 ? (\n <GridView\n contentHeight={layout.height}\n contentWidth={Math.max(resolvedWidth / zoom, layout.width)}\n height={height}\n focusedItemId={focusedItemId}\n interactionPolicy={interactionPolicy}\n items={layout.items}\n onVisibleItemIdsChange={onVisibleItemIdsChange}\n overscanPixels={overscanPixels}\n renderItem={(item) => {\n const source = itemLookup.get(item.id);\n return source ? renderItem(source) : null;\n }}\n revealPaddingPixels={revealPaddingPixels}\n width={resolvedWidth}\n zoom={zoom}\n />\n ) : null}\n </NativeView>\n );\n}\n"]}
|
package/dist/types/explorer.d.ts
CHANGED
|
@@ -14,12 +14,18 @@ export interface ExplorerItem {
|
|
|
14
14
|
readonly disabled?: boolean;
|
|
15
15
|
}
|
|
16
16
|
export type ExplorerSelectionMode = 'single' | 'multi';
|
|
17
|
+
/** Provider-owned access state projected into the portable explorer presentation. */
|
|
18
|
+
export type ExplorerPermissionStatus = 'granted' | 'limited' | 'denied' | 'unavailable';
|
|
17
19
|
export interface ExplorerActivateEvent {
|
|
18
20
|
readonly id: string;
|
|
19
21
|
}
|
|
20
22
|
export interface ExplorerSelectionChangeEvent {
|
|
21
23
|
readonly selectedIds: readonly string[];
|
|
22
24
|
}
|
|
25
|
+
/** Requests the next provider page without exposing a provider cursor or native object. */
|
|
26
|
+
export interface ExplorerPageRequestEvent {
|
|
27
|
+
readonly loadedItemCount: number;
|
|
28
|
+
}
|
|
23
29
|
export interface ExplorerProps extends ZoraBaseProps {
|
|
24
30
|
items: readonly ExplorerItem[];
|
|
25
31
|
selectionMode?: ExplorerSelectionMode;
|
|
@@ -32,6 +38,28 @@ export interface ExplorerProps extends ZoraBaseProps {
|
|
|
32
38
|
tileSize?: number;
|
|
33
39
|
zoom?: number;
|
|
34
40
|
loading?: boolean;
|
|
41
|
+
/** Provider paging remains application-owned; Explorer only requests the next page near its end. */
|
|
42
|
+
hasMore?: boolean;
|
|
43
|
+
loadingMore?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Stable serializable identity for a provider collection.
|
|
46
|
+
*
|
|
47
|
+
* Supply this whenever paging is enabled so a replacement collection with the same number of
|
|
48
|
+
* loaded rows receives its own initial page request.
|
|
49
|
+
*/
|
|
50
|
+
pagingCollectionId?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Provider-controlled retry token for the current page boundary.
|
|
53
|
+
*
|
|
54
|
+
* Change this after a failed request to permit one deliberate retry without causing automatic
|
|
55
|
+
* retry loops.
|
|
56
|
+
*/
|
|
57
|
+
pagingRetryToken?: string;
|
|
58
|
+
onLoadMore?: (event: ExplorerPageRequestEvent) => void;
|
|
59
|
+
/** Never pass a native permission object through this presentation boundary. */
|
|
60
|
+
permissionStatus?: ExplorerPermissionStatus;
|
|
61
|
+
permissionText?: string;
|
|
62
|
+
onRequestPermission?: () => void;
|
|
35
63
|
errorText?: string;
|
|
36
64
|
emptyText?: string;
|
|
37
65
|
disabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../../src/types/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,4FAA4F;AAC5F,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
1
|
+
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../../src/types/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,4FAA4F;AAC5F,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,qFAAqF;AACrF,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;AAExF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,2FAA2F;AAC3F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oGAAoG;IACpG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACvD,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../../src/types/explorer.ts"],"names":[],"mappings":"","sourcesContent":["import type { ZoraBaseProps } from './base';\n\n/** Portable catalogue row. Providers retain permissions, pagination and storage objects. */\nexport type ExplorerItemKind = 'image' | 'video' | 'audio' | 'document' | 'file' | 'folder';\n\nexport interface ExplorerItem {\n readonly id: string;\n readonly kind: ExplorerItemKind;\n readonly name: string;\n readonly thumbnailUri?: string;\n readonly uri?: string;\n readonly contentType?: string;\n readonly sizeBytes?: number;\n readonly durationSeconds?: number;\n readonly providerId?: string;\n readonly disabled?: boolean;\n}\n\nexport type ExplorerSelectionMode = 'single' | 'multi';\n\nexport interface ExplorerActivateEvent {\n readonly id: string;\n}\n\nexport interface ExplorerSelectionChangeEvent {\n readonly selectedIds: readonly string[];\n}\n\nexport interface ExplorerProps extends ZoraBaseProps {\n items: readonly ExplorerItem[];\n selectionMode?: ExplorerSelectionMode;\n selectedIds?: readonly string[];\n defaultSelectedIds?: readonly string[];\n onSelectionChange?: (event: ExplorerSelectionChangeEvent) => void;\n onActivate?: (event: ExplorerActivateEvent) => void;\n width?: number;\n height?: number;\n tileSize?: number;\n zoom?: number;\n loading?: boolean;\n errorText?: string;\n emptyText?: string;\n disabled?: boolean;\n readOnly?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../../src/types/explorer.ts"],"names":[],"mappings":"","sourcesContent":["import type { ZoraBaseProps } from './base';\n\n/** Portable catalogue row. Providers retain permissions, pagination and storage objects. */\nexport type ExplorerItemKind = 'image' | 'video' | 'audio' | 'document' | 'file' | 'folder';\n\nexport interface ExplorerItem {\n readonly id: string;\n readonly kind: ExplorerItemKind;\n readonly name: string;\n readonly thumbnailUri?: string;\n readonly uri?: string;\n readonly contentType?: string;\n readonly sizeBytes?: number;\n readonly durationSeconds?: number;\n readonly providerId?: string;\n readonly disabled?: boolean;\n}\n\nexport type ExplorerSelectionMode = 'single' | 'multi';\n\n/** Provider-owned access state projected into the portable explorer presentation. */\nexport type ExplorerPermissionStatus = 'granted' | 'limited' | 'denied' | 'unavailable';\n\nexport interface ExplorerActivateEvent {\n readonly id: string;\n}\n\nexport interface ExplorerSelectionChangeEvent {\n readonly selectedIds: readonly string[];\n}\n\n/** Requests the next provider page without exposing a provider cursor or native object. */\nexport interface ExplorerPageRequestEvent {\n readonly loadedItemCount: number;\n}\n\nexport interface ExplorerProps extends ZoraBaseProps {\n items: readonly ExplorerItem[];\n selectionMode?: ExplorerSelectionMode;\n selectedIds?: readonly string[];\n defaultSelectedIds?: readonly string[];\n onSelectionChange?: (event: ExplorerSelectionChangeEvent) => void;\n onActivate?: (event: ExplorerActivateEvent) => void;\n width?: number;\n height?: number;\n tileSize?: number;\n zoom?: number;\n loading?: boolean;\n /** Provider paging remains application-owned; Explorer only requests the next page near its end. */\n hasMore?: boolean;\n loadingMore?: boolean;\n /**\n * Stable serializable identity for a provider collection.\n *\n * Supply this whenever paging is enabled so a replacement collection with the same number of\n * loaded rows receives its own initial page request.\n */\n pagingCollectionId?: string;\n /**\n * Provider-controlled retry token for the current page boundary.\n *\n * Change this after a failed request to permit one deliberate retry without causing automatic\n * retry loops.\n */\n pagingRetryToken?: string;\n onLoadMore?: (event: ExplorerPageRequestEvent) => void;\n /** Never pass a native permission object through this presentation boundary. */\n permissionStatus?: ExplorerPermissionStatus;\n permissionText?: string;\n onRequestPermission?: () => void;\n errorText?: string;\n emptyText?: string;\n disabled?: boolean;\n readOnly?: boolean;\n}\n"]}
|
|
@@ -10,7 +10,12 @@ export interface GridViewProps extends ZoraBaseProps {
|
|
|
10
10
|
height: number;
|
|
11
11
|
zoom?: number;
|
|
12
12
|
overscanPixels?: number;
|
|
13
|
+
/** Stable item identity that must be scrolled into view without duplicating viewport geometry. */
|
|
14
|
+
focusedItemId?: string;
|
|
15
|
+
/** Pixel inset retained around a revealed focused item. */
|
|
16
|
+
revealPaddingPixels?: number;
|
|
13
17
|
onViewportChange?: (viewport: GridViewport) => void;
|
|
18
|
+
onVisibleItemIdsChange?: (ids: readonly string[]) => void;
|
|
14
19
|
renderItem: (item: GridRectItem) => React.ReactNode;
|
|
15
20
|
}
|
|
16
21
|
/** An item needs a stable ID; visual positioning belongs to the TileGrid composition. */
|
|
@@ -26,6 +31,11 @@ export interface TileGridProps extends ZoraBaseProps {
|
|
|
26
31
|
gap?: number;
|
|
27
32
|
zoom?: number;
|
|
28
33
|
overscanPixels?: number;
|
|
34
|
+
focusedItemId?: string;
|
|
35
|
+
revealPaddingPixels?: number;
|
|
36
|
+
/** Reports the same measured column count used to position tiles. */
|
|
37
|
+
onColumnsChange?: (columns: number) => void;
|
|
38
|
+
onVisibleItemIdsChange?: (ids: readonly string[]) => void;
|
|
29
39
|
renderItem: (item: TileGridItem) => React.ReactNode;
|
|
30
40
|
}
|
|
31
41
|
//# sourceMappingURL=grid-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-view.d.ts","sourceRoot":"","sources":["../../src/types/grid-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,gFAAgF;AAChF,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAC;CACrD;AAED,yFAAyF;AACzF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,6EAA6E;AAC7E,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAC;CACrD"}
|
|
1
|
+
{"version":3,"file":"grid-view.d.ts","sourceRoot":"","sources":["../../src/types/grid-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,gFAAgF;AAChF,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kGAAkG;IAClG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1D,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAC;CACrD;AAED,yFAAyF;AACzF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,6EAA6E;AAC7E,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1D,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,KAAK,CAAC,SAAS,CAAC;CACrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-view.js","sourceRoot":"","sources":["../../src/types/grid-view.ts"],"names":[],"mappings":"","sourcesContent":["import type { GridRectItem, GridViewport } from '@ankhorage/grid-view';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from './base';\n\n/** The renderer owns presentation only; world geometry comes from grid-view. */\nexport interface GridViewProps extends ZoraBaseProps {\n items: readonly GridRectItem[];\n contentWidth: number;\n contentHeight: number;\n width: number;\n height: number;\n zoom?: number;\n overscanPixels?: number;\n onViewportChange?: (viewport: GridViewport) => void;\n renderItem: (item: GridRectItem) => React.ReactNode;\n}\n\n/** An item needs a stable ID; visual positioning belongs to the TileGrid composition. */\nexport interface TileGridItem {\n readonly id: string;\n}\n\n/** Reusable tile presentation based on the generic world/viewport engine. */\nexport interface TileGridProps extends ZoraBaseProps {\n items: readonly TileGridItem[];\n width?: number;\n height?: number;\n tileSize?: number;\n gap?: number;\n zoom?: number;\n overscanPixels?: number;\n renderItem: (item: TileGridItem) => React.ReactNode;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"grid-view.js","sourceRoot":"","sources":["../../src/types/grid-view.ts"],"names":[],"mappings":"","sourcesContent":["import type { GridRectItem, GridViewport } from '@ankhorage/grid-view';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from './base';\n\n/** The renderer owns presentation only; world geometry comes from grid-view. */\nexport interface GridViewProps extends ZoraBaseProps {\n items: readonly GridRectItem[];\n contentWidth: number;\n contentHeight: number;\n width: number;\n height: number;\n zoom?: number;\n overscanPixels?: number;\n /** Stable item identity that must be scrolled into view without duplicating viewport geometry. */\n focusedItemId?: string;\n /** Pixel inset retained around a revealed focused item. */\n revealPaddingPixels?: number;\n onViewportChange?: (viewport: GridViewport) => void;\n onVisibleItemIdsChange?: (ids: readonly string[]) => void;\n renderItem: (item: GridRectItem) => React.ReactNode;\n}\n\n/** An item needs a stable ID; visual positioning belongs to the TileGrid composition. */\nexport interface TileGridItem {\n readonly id: string;\n}\n\n/** Reusable tile presentation based on the generic world/viewport engine. */\nexport interface TileGridProps extends ZoraBaseProps {\n items: readonly TileGridItem[];\n width?: number;\n height?: number;\n tileSize?: number;\n gap?: number;\n zoom?: number;\n overscanPixels?: number;\n focusedItemId?: string;\n revealPaddingPixels?: number;\n /** Reports the same measured column count used to position tiles. */\n onColumnsChange?: (columns: number) => void;\n onVisibleItemIdsChange?: (ids: readonly string[]) => void;\n renderItem: (item: TileGridItem) => React.ReactNode;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "25.0
|
|
4
|
+
"version": "25.2.0",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|