@ankhorage/zora 25.1.0 → 25.2.1
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 +1 -1
- package/dist/features/explorer/adapters/inbound/Explorer.d.ts.map +1 -1
- package/dist/features/explorer/adapters/inbound/Explorer.js +43 -2
- package/dist/features/explorer/adapters/inbound/Explorer.js.map +1 -1
- 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 +1 -1
- package/dist/features/explorer/public.d.ts.map +1 -1
- package/dist/features/explorer/public.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/package.json +5 -5
- package/src/capabilities/index.test.ts +10 -6
- package/src/features/explorer/adapters/inbound/Explorer.tsx +82 -13
- 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 +2 -0
- package/src/types/explorer.ts +30 -0
- package/web-dist/chunks/{Accordion-fmn31fgf.js → Accordion-kkr7xfh2.js} +88 -12
- package/web-dist/components/explorer/Explorer.js +1 -1
- package/web-dist/components/file-explorer/FileExplorer.js +1 -1
- package/web-dist/components/media-explorer/MediaExplorer.js +1 -1
- package/web-dist/components/uploader/Uploader.js +1 -1
- package/web-dist/manifest.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 25.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 67a39fe: Update dependencies: `@ankhorage/ankh`.
|
|
8
|
+
|
|
9
|
+
## 25.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 92ed809: Finish the Explorer migration with provider-neutral paging and permission presentation, and extend
|
|
14
|
+
the runnable GridView workspace example with paged, limited-access, and Uploader interactions.
|
|
15
|
+
|
|
3
16
|
## 25.1.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/zora
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.
|
|
9
9
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Explorer.d.ts","sourceRoot":"","sources":["../../../../../src/features/explorer/adapters/inbound/Explorer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"Explorer.d.ts","sourceRoot":"","sources":["../../../../../src/features/explorer/adapters/inbound/Explorer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAgB9E,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,qDAAoC,CAAC"}
|
|
@@ -7,22 +7,51 @@ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThem
|
|
|
7
7
|
import { useZoraTheme } from '../../../theme/composition/useZoraTheme';
|
|
8
8
|
import { Text } from '../../../typography/public';
|
|
9
9
|
import { resolveExplorerSelection } from '../../application/resolveExplorerSelection';
|
|
10
|
+
import { shouldDispatchExplorerPageRequest, } from '../../application/shouldDispatchExplorerPageRequest';
|
|
11
|
+
import { shouldRequestExplorerPage } from '../../application/shouldRequestExplorerPage';
|
|
10
12
|
import { ExplorerKeyboardProxy } from './ExplorerKeyboardProxy';
|
|
11
13
|
import { useExplorerKeyboardFocus } from './useExplorerKeyboardFocus';
|
|
12
14
|
/*** Single canonical Explorer implementation for media and file catalogue presentation. */
|
|
13
15
|
export const Explorer = withZoraThemeScope(ExplorerInner);
|
|
14
16
|
/*** Presents provider-neutral asset tiles with controlled or uncontrolled selection. */
|
|
15
|
-
function ExplorerInner({ items, selectedIds, defaultSelectedIds = [], selectionMode = 'single', onSelectionChange, onActivate, width, height, tileSize = 120, zoom = 1, loading = false, errorText, emptyText = 'No items', disabled = false, readOnly = false, interactionPolicy, testID, }) {
|
|
17
|
+
function ExplorerInner({ items, selectedIds, defaultSelectedIds = [], selectionMode = 'single', onSelectionChange, onActivate, width, height, tileSize = 120, zoom = 1, loading = false, hasMore = false, loadingMore = false, pagingCollectionId, pagingRetryToken, onLoadMore, permissionStatus = 'granted', permissionText, onRequestPermission, errorText, emptyText = 'No items', disabled = false, readOnly = false, interactionPolicy, testID, }) {
|
|
16
18
|
const { theme } = useZoraTheme();
|
|
17
19
|
const [internalSelectedIds, setInternalSelectedIds] = React.useState(defaultSelectedIds);
|
|
18
20
|
const anchorId = React.useRef(null);
|
|
19
21
|
const [columns, setColumns] = React.useState(1);
|
|
20
22
|
const [visibleIds, setVisibleIds] = React.useState([]);
|
|
23
|
+
const lastPageRequestRef = React.useRef(null);
|
|
21
24
|
const effectiveSelectedIds = selectedIds ?? internalSelectedIds;
|
|
22
25
|
const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);
|
|
23
26
|
const ids = React.useMemo(() => items.filter((item) => !item.disabled).map((item) => item.id), [items]);
|
|
24
27
|
const selected = new Set(effectiveSelectedIds);
|
|
25
28
|
const passive = interactionPolicy === 'passive' || disabled || readOnly;
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
const request = {
|
|
31
|
+
collectionId: pagingCollectionId,
|
|
32
|
+
loadedItemCount: items.length,
|
|
33
|
+
retryToken: pagingRetryToken,
|
|
34
|
+
};
|
|
35
|
+
if (!onLoadMore ||
|
|
36
|
+
!shouldDispatchExplorerPageRequest(lastPageRequestRef.current, request) ||
|
|
37
|
+
!shouldRequestExplorerPage(ids, visibleIds, hasMore, loadingMore, loading, errorText, permissionStatus)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
lastPageRequestRef.current = request;
|
|
41
|
+
onLoadMore({ loadedItemCount: items.length });
|
|
42
|
+
}, [
|
|
43
|
+
errorText,
|
|
44
|
+
hasMore,
|
|
45
|
+
ids,
|
|
46
|
+
items.length,
|
|
47
|
+
loading,
|
|
48
|
+
loadingMore,
|
|
49
|
+
onLoadMore,
|
|
50
|
+
pagingCollectionId,
|
|
51
|
+
pagingRetryToken,
|
|
52
|
+
permissionStatus,
|
|
53
|
+
visibleIds,
|
|
54
|
+
]);
|
|
26
55
|
const select = (item, intent) => {
|
|
27
56
|
if (passive || item.disabled)
|
|
28
57
|
return;
|
|
@@ -73,13 +102,25 @@ function ExplorerInner({ items, selectedIds, defaultSelectedIds = [], selectionM
|
|
|
73
102
|
</NativePressable>
|
|
74
103
|
</ExplorerKeyboardProxy>);
|
|
75
104
|
};
|
|
105
|
+
if (permissionStatus === 'denied' || permissionStatus === 'unavailable') {
|
|
106
|
+
return (<NativeView testID={testID}>
|
|
107
|
+
<Text>{permissionText ?? 'This collection is unavailable without permission.'}</Text>
|
|
108
|
+
{permissionStatus === 'denied' && onRequestPermission ? (<NativePressable accessibilityRole="button" onPress={onRequestPermission}>
|
|
109
|
+
<Text>Grant access</Text>
|
|
110
|
+
</NativePressable>) : null}
|
|
111
|
+
</NativeView>);
|
|
112
|
+
}
|
|
76
113
|
if (errorText)
|
|
77
114
|
return <Text testID={testID}>{errorText}</Text>;
|
|
78
115
|
if (loading)
|
|
79
116
|
return <Text testID={testID}>Loading…</Text>;
|
|
80
117
|
if (items.length === 0)
|
|
81
118
|
return <Text testID={testID}>{emptyText}</Text>;
|
|
82
|
-
return (<
|
|
119
|
+
return (<NativeView>
|
|
120
|
+
{permissionStatus === 'limited' ? (<Text>{permissionText ?? 'Showing the media you have allowed.'}</Text>) : null}
|
|
121
|
+
<TileGrid focusedItemId={keyboard.focusedId ?? undefined} height={height} interactionPolicy={interactionPolicy} onColumnsChange={setColumns} onVisibleItemIdsChange={setVisibleIds} items={items} renderItem={renderTile} testID={testID} tileSize={tileSize} width={width} zoom={zoom}/>
|
|
122
|
+
{loadingMore ? <Text>Loading more…</Text> : null}
|
|
123
|
+
</NativeView>);
|
|
83
124
|
}
|
|
84
125
|
/***
|
|
85
126
|
* Normalize platform press modifiers into selection intents
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Explorer.js","sourceRoot":"","sources":["../../../../../src/features/explorer/adapters/inbound/Explorer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Platform, Pressable as NativePressable, View as NativeView } from 'react-native';\n\nimport type { ExplorerItem, ExplorerProps } from '../../../../types/explorer';\nimport { TileGrid } from '../../../grid-view/public';\nimport { Icon } from '../../../icon/public';\nimport { Image } from '../../../image/public';\nimport { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';\nimport { useZoraTheme } from '../../../theme/composition/useZoraTheme';\nimport { Text } from '../../../typography/public';\nimport { resolveExplorerSelection } from '../../application/resolveExplorerSelection';\nimport { ExplorerKeyboardProxy } from './ExplorerKeyboardProxy';\nimport { useExplorerKeyboardFocus } from './useExplorerKeyboardFocus';\n\n/*** Single canonical Explorer implementation for media and file catalogue presentation. */\nexport const Explorer = withZoraThemeScope(ExplorerInner);\n\n/*** Presents provider-neutral asset tiles with controlled or uncontrolled selection. */\nfunction ExplorerInner({\n items,\n selectedIds,\n defaultSelectedIds = [],\n selectionMode = 'single',\n onSelectionChange,\n onActivate,\n width,\n height,\n tileSize = 120,\n zoom = 1,\n loading = false,\n errorText,\n emptyText = 'No items',\n disabled = false,\n readOnly = false,\n interactionPolicy,\n testID,\n}: ExplorerProps) {\n const { theme } = useZoraTheme();\n const [internalSelectedIds, setInternalSelectedIds] =\n React.useState<readonly string[]>(defaultSelectedIds);\n const anchorId = React.useRef<string | null>(null);\n const [columns, setColumns] = React.useState(1);\n const [visibleIds, setVisibleIds] = React.useState<readonly string[]>([]);\n const effectiveSelectedIds = selectedIds ?? internalSelectedIds;\n const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);\n const ids = React.useMemo(\n () => items.filter((item) => !item.disabled).map((item) => item.id),\n [items],\n );\n const selected = new Set(effectiveSelectedIds);\n const passive = interactionPolicy === 'passive' || disabled || readOnly;\n\n const select = (item: ExplorerItem, intent: 'replace' | 'toggle' | 'range') => {\n if (passive || item.disabled) return;\n const next = resolveExplorerSelection(\n ids,\n effectiveSelectedIds,\n item.id,\n anchorId.current,\n intent,\n selectionMode,\n );\n if (intent !== 'range') anchorId.current = item.id;\n if (selectedIds === undefined) setInternalSelectedIds(next);\n onSelectionChange?.({ selectedIds: next });\n };\n\n const keyboard = useExplorerKeyboardFocus(\n items,\n columns,\n passive,\n visibleIds,\n (targetId, originId, shiftKey) => {\n if (!shiftKey) return;\n anchorId.current ??= originId;\n const nextItem = itemLookup.get(targetId);\n if (nextItem) select(nextItem, 'range');\n },\n );\n\n const renderTile = (tile: { readonly id: string }) => {\n const item = itemLookup.get(tile.id);\n if (!item) return null;\n const isSelected = selected.has(item.id);\n const canInteract = !passive && !item.disabled;\n return (\n <ExplorerKeyboardProxy\n onKeyDown={(key, shiftKey) => keyboard.onKeyDown(item.id, key, shiftKey)}\n >\n <NativePressable\n accessibilityLabel={item.name}\n accessibilityRole=\"button\"\n accessibilityState={{ selected: isSelected, disabled: !canInteract }}\n disabled={!canInteract}\n focusable={canInteract && (Platform.OS !== 'web' || item.id === keyboard.tabStopId)}\n onFocus={() => keyboard.onFocus(item.id)}\n onLongPress={() => select(item, 'toggle')}\n onPress={(event) => {\n const intent = resolveExplorerPressIntent(event.nativeEvent);\n select(item, intent);\n if (selectionMode === 'single' && intent === 'replace') {\n onActivate?.({ id: item.id });\n }\n }}\n style={{\n flex: 1,\n overflow: 'hidden',\n borderRadius: 8,\n borderWidth: isSelected ? 2 : 1,\n borderColor: isSelected ? theme.colors.primary : theme.semantics.neutral.divider,\n backgroundColor: theme.semantics.neutral.surface,\n padding: 8,\n gap: 4,\n }}\n ref={(node) => keyboard.registerTile(item.id, node)}\n testID={`explorer-item-${item.id}`}\n >\n <NativeView style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>\n {item.thumbnailUri ? (\n <Image\n accessibilityLabel={item.name}\n aspectRatio={1}\n source={item.thumbnailUri}\n width=\"100%\"\n />\n ) : (\n <Icon\n name={item.kind === 'folder' ? 'folder-outline' : 'document-outline'}\n size={32}\n />\n )}\n </NativeView>\n <Text numberOfLines={1} variant=\"caption\">\n {item.name}\n </Text>\n </NativePressable>\n </ExplorerKeyboardProxy>\n );\n };\n\n if (errorText) return <Text testID={testID}>{errorText}</Text>;\n if (loading) return <Text testID={testID}>Loading…</Text>;\n if (items.length === 0) return <Text testID={testID}>{emptyText}</Text>;\n\n return (\n <TileGrid\n focusedItemId={keyboard.focusedId ?? undefined}\n height={height}\n interactionPolicy={interactionPolicy}\n onColumnsChange={setColumns}\n onVisibleItemIdsChange={setVisibleIds}\n items={items}\n renderItem={renderTile}\n testID={testID}\n tileSize={tileSize}\n width={width}\n zoom={zoom}\n />\n );\n}\n\n/***\n * Normalize platform press modifiers into selection intents\n * without passing event objects into the public contracts.\n */\nfunction resolveExplorerPressIntent(event: unknown): 'replace' | 'toggle' | 'range' {\n if (typeof event !== 'object' || event === null) return 'replace';\n if ('shiftKey' in event && event.shiftKey === true) return 'range';\n if ('ctrlKey' in event && event.ctrlKey === true) return 'toggle';\n if ('metaKey' in event && event.metaKey === true) return 'toggle';\n return 'replace';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Explorer.js","sourceRoot":"","sources":["../../../../../src/features/explorer/adapters/inbound/Explorer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Platform, Pressable as NativePressable, View as NativeView } from 'react-native';\n\nimport type { ExplorerItem, ExplorerProps } from '../../../../types/explorer';\nimport { TileGrid } from '../../../grid-view/public';\nimport { Icon } from '../../../icon/public';\nimport { Image } from '../../../image/public';\nimport { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';\nimport { useZoraTheme } from '../../../theme/composition/useZoraTheme';\nimport { Text } from '../../../typography/public';\nimport { resolveExplorerSelection } from '../../application/resolveExplorerSelection';\nimport {\n type ExplorerPageRequestSignature,\n shouldDispatchExplorerPageRequest,\n} from '../../application/shouldDispatchExplorerPageRequest';\nimport { shouldRequestExplorerPage } from '../../application/shouldRequestExplorerPage';\nimport { ExplorerKeyboardProxy } from './ExplorerKeyboardProxy';\nimport { useExplorerKeyboardFocus } from './useExplorerKeyboardFocus';\n\n/*** Single canonical Explorer implementation for media and file catalogue presentation. */\nexport const Explorer = withZoraThemeScope(ExplorerInner);\n\n/*** Presents provider-neutral asset tiles with controlled or uncontrolled selection. */\nfunction ExplorerInner({\n items,\n selectedIds,\n defaultSelectedIds = [],\n selectionMode = 'single',\n onSelectionChange,\n onActivate,\n width,\n height,\n tileSize = 120,\n zoom = 1,\n loading = false,\n hasMore = false,\n loadingMore = false,\n pagingCollectionId,\n pagingRetryToken,\n onLoadMore,\n permissionStatus = 'granted',\n permissionText,\n onRequestPermission,\n errorText,\n emptyText = 'No items',\n disabled = false,\n readOnly = false,\n interactionPolicy,\n testID,\n}: ExplorerProps) {\n const { theme } = useZoraTheme();\n const [internalSelectedIds, setInternalSelectedIds] =\n React.useState<readonly string[]>(defaultSelectedIds);\n const anchorId = React.useRef<string | null>(null);\n const [columns, setColumns] = React.useState(1);\n const [visibleIds, setVisibleIds] = React.useState<readonly string[]>([]);\n const lastPageRequestRef = React.useRef<ExplorerPageRequestSignature | null>(null);\n const effectiveSelectedIds = selectedIds ?? internalSelectedIds;\n const itemLookup = React.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);\n const ids = React.useMemo(\n () => items.filter((item) => !item.disabled).map((item) => item.id),\n [items],\n );\n const selected = new Set(effectiveSelectedIds);\n const passive = interactionPolicy === 'passive' || disabled || readOnly;\n\n React.useEffect(() => {\n const request = {\n collectionId: pagingCollectionId,\n loadedItemCount: items.length,\n retryToken: pagingRetryToken,\n };\n if (\n !onLoadMore ||\n !shouldDispatchExplorerPageRequest(lastPageRequestRef.current, request) ||\n !shouldRequestExplorerPage(\n ids,\n visibleIds,\n hasMore,\n loadingMore,\n loading,\n errorText,\n permissionStatus,\n )\n ) {\n return;\n }\n lastPageRequestRef.current = request;\n onLoadMore({ loadedItemCount: items.length });\n }, [\n errorText,\n hasMore,\n ids,\n items.length,\n loading,\n loadingMore,\n onLoadMore,\n pagingCollectionId,\n pagingRetryToken,\n permissionStatus,\n visibleIds,\n ]);\n\n const select = (item: ExplorerItem, intent: 'replace' | 'toggle' | 'range') => {\n if (passive || item.disabled) return;\n const next = resolveExplorerSelection(\n ids,\n effectiveSelectedIds,\n item.id,\n anchorId.current,\n intent,\n selectionMode,\n );\n if (intent !== 'range') anchorId.current = item.id;\n if (selectedIds === undefined) setInternalSelectedIds(next);\n onSelectionChange?.({ selectedIds: next });\n };\n\n const keyboard = useExplorerKeyboardFocus(\n items,\n columns,\n passive,\n visibleIds,\n (targetId, originId, shiftKey) => {\n if (!shiftKey) return;\n anchorId.current ??= originId;\n const nextItem = itemLookup.get(targetId);\n if (nextItem) select(nextItem, 'range');\n },\n );\n\n const renderTile = (tile: { readonly id: string }) => {\n const item = itemLookup.get(tile.id);\n if (!item) return null;\n const isSelected = selected.has(item.id);\n const canInteract = !passive && !item.disabled;\n return (\n <ExplorerKeyboardProxy\n onKeyDown={(key, shiftKey) => keyboard.onKeyDown(item.id, key, shiftKey)}\n >\n <NativePressable\n accessibilityLabel={item.name}\n accessibilityRole=\"button\"\n accessibilityState={{ selected: isSelected, disabled: !canInteract }}\n disabled={!canInteract}\n focusable={canInteract && (Platform.OS !== 'web' || item.id === keyboard.tabStopId)}\n onFocus={() => keyboard.onFocus(item.id)}\n onLongPress={() => select(item, 'toggle')}\n onPress={(event) => {\n const intent = resolveExplorerPressIntent(event.nativeEvent);\n select(item, intent);\n if (selectionMode === 'single' && intent === 'replace') {\n onActivate?.({ id: item.id });\n }\n }}\n style={{\n flex: 1,\n overflow: 'hidden',\n borderRadius: 8,\n borderWidth: isSelected ? 2 : 1,\n borderColor: isSelected ? theme.colors.primary : theme.semantics.neutral.divider,\n backgroundColor: theme.semantics.neutral.surface,\n padding: 8,\n gap: 4,\n }}\n ref={(node) => keyboard.registerTile(item.id, node)}\n testID={`explorer-item-${item.id}`}\n >\n <NativeView style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>\n {item.thumbnailUri ? (\n <Image\n accessibilityLabel={item.name}\n aspectRatio={1}\n source={item.thumbnailUri}\n width=\"100%\"\n />\n ) : (\n <Icon\n name={item.kind === 'folder' ? 'folder-outline' : 'document-outline'}\n size={32}\n />\n )}\n </NativeView>\n <Text numberOfLines={1} variant=\"caption\">\n {item.name}\n </Text>\n </NativePressable>\n </ExplorerKeyboardProxy>\n );\n };\n\n if (permissionStatus === 'denied' || permissionStatus === 'unavailable') {\n return (\n <NativeView testID={testID}>\n <Text>{permissionText ?? 'This collection is unavailable without permission.'}</Text>\n {permissionStatus === 'denied' && onRequestPermission ? (\n <NativePressable accessibilityRole=\"button\" onPress={onRequestPermission}>\n <Text>Grant access</Text>\n </NativePressable>\n ) : null}\n </NativeView>\n );\n }\n if (errorText) return <Text testID={testID}>{errorText}</Text>;\n if (loading) return <Text testID={testID}>Loading…</Text>;\n if (items.length === 0) return <Text testID={testID}>{emptyText}</Text>;\n\n return (\n <NativeView>\n {permissionStatus === 'limited' ? (\n <Text>{permissionText ?? 'Showing the media you have allowed.'}</Text>\n ) : null}\n <TileGrid\n focusedItemId={keyboard.focusedId ?? undefined}\n height={height}\n interactionPolicy={interactionPolicy}\n onColumnsChange={setColumns}\n onVisibleItemIdsChange={setVisibleIds}\n items={items}\n renderItem={renderTile}\n testID={testID}\n tileSize={tileSize}\n width={width}\n zoom={zoom}\n />\n {loadingMore ? <Text>Loading more…</Text> : null}\n </NativeView>\n );\n}\n\n/***\n * Normalize platform press modifiers into selection intents\n * without passing event objects into the public contracts.\n */\nfunction resolveExplorerPressIntent(event: unknown): 'replace' | 'toggle' | 'range' {\n if (typeof event !== 'object' || event === null) return 'replace';\n if ('shiftKey' in event && event.shiftKey === true) return 'range';\n if ('ctrlKey' in event && event.ctrlKey === true) return 'toggle';\n if ('metaKey' in event && event.metaKey === true) return 'toggle';\n return 'replace';\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ExplorerPageRequestSignature {
|
|
2
|
+
readonly collectionId: string | undefined;
|
|
3
|
+
readonly loadedItemCount: number;
|
|
4
|
+
readonly retryToken: string | undefined;
|
|
5
|
+
}
|
|
6
|
+
/*** Preserves one request per provider page boundary until its collection, row count, or retry token changes. */
|
|
7
|
+
export declare function shouldDispatchExplorerPageRequest(previous: ExplorerPageRequestSignature | null, next: ExplorerPageRequestSignature): boolean;
|
|
8
|
+
//# sourceMappingURL=shouldDispatchExplorerPageRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shouldDispatchExplorerPageRequest.d.ts","sourceRoot":"","sources":["../../../../src/features/explorer/application/shouldDispatchExplorerPageRequest.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,iHAAiH;AACjH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,4BAA4B,GAAG,IAAI,EAC7C,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAOT"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*** Preserves one request per provider page boundary until its collection, row count, or retry token changes. */
|
|
2
|
+
export function shouldDispatchExplorerPageRequest(previous, next) {
|
|
3
|
+
if (previous === null)
|
|
4
|
+
return true;
|
|
5
|
+
return (previous.collectionId !== next.collectionId ||
|
|
6
|
+
previous.loadedItemCount !== next.loadedItemCount ||
|
|
7
|
+
previous.retryToken !== next.retryToken);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=shouldDispatchExplorerPageRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shouldDispatchExplorerPageRequest.js","sourceRoot":"","sources":["../../../../src/features/explorer/application/shouldDispatchExplorerPageRequest.ts"],"names":[],"mappings":"AAMA,iHAAiH;AACjH,MAAM,UAAU,iCAAiC,CAC/C,QAA6C,EAC7C,IAAkC;IAElC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,CACL,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;QAC3C,QAAQ,CAAC,eAAe,KAAK,IAAI,CAAC,eAAe;QACjD,QAAQ,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CACxC,CAAC;AACJ,CAAC","sourcesContent":["export interface ExplorerPageRequestSignature {\n readonly collectionId: string | undefined;\n readonly loadedItemCount: number;\n readonly retryToken: string | undefined;\n}\n\n/*** Preserves one request per provider page boundary until its collection, row count, or retry token changes. */\nexport function shouldDispatchExplorerPageRequest(\n previous: ExplorerPageRequestSignature | null,\n next: ExplorerPageRequestSignature,\n): boolean {\n if (previous === null) return true;\n return (\n previous.collectionId !== next.collectionId ||\n previous.loadedItemCount !== next.loadedItemCount ||\n previous.retryToken !== next.retryToken\n );\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExplorerPermissionStatus } from '../../../types/explorer';
|
|
2
|
+
/*** Determines whether the mounted, accessible viewport has reached the provider-owned page boundary. */
|
|
3
|
+
export declare function shouldRequestExplorerPage(itemIds: readonly string[], visibleIds: readonly string[], hasMore: boolean, loadingMore: boolean, loading: boolean, errorText: string | undefined, permissionStatus: ExplorerPermissionStatus, threshold?: number): boolean;
|
|
4
|
+
//# sourceMappingURL=shouldRequestExplorerPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shouldRequestExplorerPage.d.ts","sourceRoot":"","sources":["../../../../src/features/explorer/application/shouldRequestExplorerPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAExE,yGAAyG;AACzG,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,gBAAgB,EAAE,wBAAwB,EAC1C,SAAS,SAAK,GACb,OAAO,CAaT"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*** Determines whether the mounted, accessible viewport has reached the provider-owned page boundary. */
|
|
2
|
+
export function shouldRequestExplorerPage(itemIds, visibleIds, hasMore, loadingMore, loading, errorText, permissionStatus, threshold = 12) {
|
|
3
|
+
if (!hasMore ||
|
|
4
|
+
loadingMore ||
|
|
5
|
+
loading ||
|
|
6
|
+
errorText !== undefined ||
|
|
7
|
+
(permissionStatus !== 'granted' && permissionStatus !== 'limited') ||
|
|
8
|
+
visibleIds.length === 0) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const firstPagingIndex = Math.max(0, itemIds.length - threshold);
|
|
12
|
+
return visibleIds.some((id) => itemIds.indexOf(id) >= firstPagingIndex);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=shouldRequestExplorerPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shouldRequestExplorerPage.js","sourceRoot":"","sources":["../../../../src/features/explorer/application/shouldRequestExplorerPage.ts"],"names":[],"mappings":"AAEA,yGAAyG;AACzG,MAAM,UAAU,yBAAyB,CACvC,OAA0B,EAC1B,UAA6B,EAC7B,OAAgB,EAChB,WAAoB,EACpB,OAAgB,EAChB,SAA6B,EAC7B,gBAA0C,EAC1C,SAAS,GAAG,EAAE;IAEd,IACE,CAAC,OAAO;QACR,WAAW;QACX,OAAO;QACP,SAAS,KAAK,SAAS;QACvB,CAAC,gBAAgB,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS,CAAC;QAClE,UAAU,CAAC,MAAM,KAAK,CAAC,EACvB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,gBAAgB,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["import type { ExplorerPermissionStatus } from '../../../types/explorer';\n\n/*** Determines whether the mounted, accessible viewport has reached the provider-owned page boundary. */\nexport function shouldRequestExplorerPage(\n itemIds: readonly string[],\n visibleIds: readonly string[],\n hasMore: boolean,\n loadingMore: boolean,\n loading: boolean,\n errorText: string | undefined,\n permissionStatus: ExplorerPermissionStatus,\n threshold = 12,\n): boolean {\n if (\n !hasMore ||\n loadingMore ||\n loading ||\n errorText !== undefined ||\n (permissionStatus !== 'granted' && permissionStatus !== 'limited') ||\n visibleIds.length === 0\n ) {\n return false;\n }\n const firstPagingIndex = Math.max(0, itemIds.length - threshold);\n return visibleIds.some((id) => itemIds.indexOf(id) >= firstPagingIndex);\n}\n"]}
|
|
@@ -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,4 +1,4 @@
|
|
|
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';
|
|
@@ -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,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,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 +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"]}
|
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"]}
|