@squiz/resource-browser 1.69.2 → 2.1.9-rc.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 +89 -38
- package/LICENSE.md +15 -0
- package/README.md +9 -0
- package/jest.config.ts +22 -21
- package/lib/Hooks/useSelectedState.d.ts +15 -0
- package/lib/Hooks/useSelectedState.js +16 -0
- package/lib/Hooks/useSources.d.ts +6 -6
- package/lib/Hooks/useSources.js +26 -1
- package/lib/MainContainer/MainContainer.d.ts +17 -0
- package/lib/MainContainer/MainContainer.js +61 -0
- package/lib/Plugin/Plugin.d.ts +13 -0
- package/lib/Plugin/Plugin.js +17 -0
- package/lib/ResourceBrowserContext/ResourceBrowserContext.d.ts +2 -3
- package/lib/ResourceBrowserContext/ResourceBrowserContext.js +4 -17
- package/lib/ResourceBrowserInput/ResourceBrowserInput.d.ts +24 -0
- package/lib/ResourceBrowserInput/ResourceBrowserInput.js +16 -0
- package/lib/ResourcePicker/ResourcePicker.d.ts +6 -4
- package/lib/ResourcePicker/ResourcePicker.js +14 -8
- package/lib/ResourcePicker/States/Selected.d.ts +10 -4
- package/lib/ResourcePicker/States/Selected.js +11 -32
- package/lib/SourceDropdown/SourceDropdown.d.ts +5 -11
- package/lib/SourceDropdown/SourceDropdown.js +20 -99
- package/lib/SourceList/SourceList.d.ts +5 -16
- package/lib/SourceList/SourceList.js +14 -75
- package/lib/index.css +42 -202
- package/lib/index.d.ts +7 -7
- package/lib/index.js +69 -13
- package/lib/types.d.ts +41 -59
- package/package.json +82 -80
- package/src/Hooks/useSelectedState.spec.ts +46 -0
- package/src/Hooks/useSelectedState.ts +22 -0
- package/src/Hooks/useSources.spec.ts +60 -13
- package/src/Hooks/useSources.ts +35 -5
- package/src/Icons/CircledLoopIcon.tsx +8 -8
- package/src/MainContainer/MainContainer.spec.tsx +203 -0
- package/src/MainContainer/MainContainer.stories.tsx +62 -0
- package/src/MainContainer/MainContainer.tsx +101 -0
- package/src/Plugin/Plugin.spec.tsx +46 -0
- package/src/Plugin/Plugin.tsx +20 -0
- package/src/ResourceBrowserContext/ResourceBrowserContext.spec.tsx +65 -106
- package/src/ResourceBrowserContext/ResourceBrowserContext.tsx +24 -39
- package/src/ResourceBrowserInput/ResourceBrowserInput.spec.tsx +192 -0
- package/src/ResourceBrowserInput/ResourceBrowserInput.tsx +81 -0
- package/src/ResourcePicker/ResourcePicker.spec.tsx +159 -116
- package/src/ResourcePicker/ResourcePicker.stories.tsx +28 -24
- package/src/ResourcePicker/ResourcePicker.tsx +79 -59
- package/src/ResourcePicker/States/Error.tsx +8 -8
- package/src/ResourcePicker/States/Loading.tsx +3 -3
- package/src/ResourcePicker/States/Selected.tsx +66 -73
- package/src/ResourcePicker/mock-image-resource.json +25 -47
- package/src/ResourcePicker/mock-resource.json +11 -13
- package/src/ResourcePicker/resource-picker.scss +13 -13
- package/src/SourceDropdown/SourceDropdown.spec.tsx +65 -391
- package/src/SourceDropdown/SourceDropdown.stories.tsx +21 -24
- package/src/SourceDropdown/SourceDropdown.tsx +80 -258
- package/src/SourceList/SourceList.spec.tsx +37 -430
- package/src/SourceList/SourceList.stories.tsx +17 -37
- package/src/SourceList/SourceList.tsx +28 -155
- package/src/__mocks__/MockModels.ts +56 -25
- package/src/__mocks__/PluginExample.tsx +98 -0
- package/src/__mocks__/StorybookHelpers.tsx +141 -0
- package/src/__mocks__/renderWithContext.tsx +14 -18
- package/src/__mocks__/sample-sources.json +32 -0
- package/src/index.scss +18 -8
- package/src/index.spec.tsx +277 -99
- package/src/index.stories.tsx +65 -39
- package/src/index.tsx +119 -57
- package/src/types.ts +54 -63
- package/tailwind.config.cjs +92 -92
- package/vite.config.js +12 -12
- package/lib/Hooks/useCategorisedSources.d.ts +0 -14
- package/lib/Hooks/useCategorisedSources.js +0 -38
- package/lib/Hooks/useChildResources.d.ts +0 -16
- package/lib/Hooks/useChildResources.js +0 -13
- package/lib/Hooks/usePreselectedResourcePath.d.ts +0 -20
- package/lib/Hooks/usePreselectedResourcePath.js +0 -31
- package/lib/Hooks/useRecentLocations.d.ts +0 -5
- package/lib/Hooks/useRecentLocations.js +0 -38
- package/lib/Hooks/useRecentResourcesPaths.d.ts +0 -20
- package/lib/Hooks/useRecentResourcesPaths.js +0 -30
- package/lib/Hooks/useResource.d.ts +0 -28
- package/lib/Hooks/useResource.js +0 -25
- package/lib/Hooks/useResourcePath.d.ts +0 -16
- package/lib/Hooks/useResourcePath.js +0 -64
- package/lib/Icons/HistoryIcon.d.ts +0 -4
- package/lib/Icons/HistoryIcon.js +0 -13
- package/lib/PreviewPanel/PreviewPanel.d.ts +0 -5
- package/lib/PreviewPanel/PreviewPanel.js +0 -8
- package/lib/PreviewPanel/details/MatrixResource.d.ts +0 -7
- package/lib/PreviewPanel/details/MatrixResource.js +0 -35
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +0 -9
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +0 -54
- package/lib/ResourceList/ResourceList.d.ts +0 -18
- package/lib/ResourceList/ResourceList.js +0 -49
- package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +0 -17
- package/lib/ResourcePickerContainer/ResourcePickerContainer.js +0 -166
- package/lib/StatusIndicator/StatusIndicator.d.ts +0 -8
- package/lib/StatusIndicator/StatusIndicator.js +0 -27
- package/lib/utils/findBestMatchLineage.d.ts +0 -2
- package/lib/utils/findBestMatchLineage.js +0 -28
- package/lib/utils/uuid.d.ts +0 -1
- package/lib/utils/uuid.js +0 -6
- package/src/Hooks/useCategorisedSources.spec.ts +0 -39
- package/src/Hooks/useCategorisedSources.ts +0 -46
- package/src/Hooks/useChildResources.spec.ts +0 -29
- package/src/Hooks/useChildResources.ts +0 -21
- package/src/Hooks/usePreselectedResourcePath.ts +0 -54
- package/src/Hooks/useRecentLocations.spec.ts +0 -81
- package/src/Hooks/useRecentLocations.ts +0 -44
- package/src/Hooks/useRecentResourcesPaths.ts +0 -54
- package/src/Hooks/useResource.spec.ts +0 -61
- package/src/Hooks/useResource.ts +0 -40
- package/src/Hooks/useResourcePath.spec.ts +0 -120
- package/src/Hooks/useResourcePath.ts +0 -76
- package/src/Icons/HistoryIcon.tsx +0 -17
- package/src/PreviewPanel/PreviewPanel.spec.tsx +0 -198
- package/src/PreviewPanel/PreviewPanel.stories.tsx +0 -76
- package/src/PreviewPanel/PreviewPanel.tsx +0 -6
- package/src/PreviewPanel/details/MatrixResource.tsx +0 -54
- package/src/PreviewPanel/details/matrix-resource.scss +0 -16
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +0 -133
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +0 -24
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +0 -79
- package/src/ResourceBreadcrumb/resource-breadcrumb.scss +0 -28
- package/src/ResourceBreadcrumb/sample-hierarchy.json +0 -27
- package/src/ResourceList/ResourceList.spec.tsx +0 -202
- package/src/ResourceList/ResourceList.stories.tsx +0 -40
- package/src/ResourceList/ResourceList.tsx +0 -83
- package/src/ResourceList/sample-resources.json +0 -851
- package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +0 -780
- package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +0 -45
- package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +0 -290
- package/src/SourceList/sample-sources.json +0 -251
- package/src/StatusIndicator/StatusIndicator.stories.tsx +0 -83
- package/src/StatusIndicator/StatusIndicator.tsx +0 -38
- package/src/__mocks__/JestHelpers.ts +0 -65
- package/src/__mocks__/StorybookHelpers.ts +0 -128
- package/src/__mocks__/jestHelpers.spec.ts +0 -38
- package/src/utils/findBestMatchLineage.spec.ts +0 -81
- package/src/utils/findBestMatchLineage.ts +0 -30
- package/src/utils/uuid.ts +0 -5
@@ -1,271 +1,93 @@
|
|
1
|
-
import React, {
|
2
|
-
import { useFocusWithin, useKeyboard } from '@react-aria/interactions';
|
3
|
-
import { Icon, IconOptions, Spinner } from '@squiz/generic-browser-lib';
|
1
|
+
import React, { useRef, useState } from 'react';
|
4
2
|
|
5
|
-
import
|
6
|
-
|
7
|
-
import
|
8
|
-
import { useCategorisedSources } from '../Hooks/useCategorisedSources';
|
9
|
-
import { HistoryIcon } from '../Icons/HistoryIcon';
|
10
|
-
import { RecentResourcesPaths } from '../Hooks/useRecentResourcesPaths';
|
3
|
+
import { ResourceBrowserSource } from '../types';
|
4
|
+
import { Icon, IconOptions, uuid } from '@squiz/generic-browser-lib';
|
5
|
+
import { useFocusWithin, useKeyboard } from 'react-aria';
|
11
6
|
|
12
7
|
export default function SourceDropdown({
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
onRootSelect,
|
17
|
-
onSourceSelect,
|
18
|
-
setSource,
|
19
|
-
currentResource,
|
20
|
-
recentSources,
|
8
|
+
sources,
|
9
|
+
selectedSource,
|
10
|
+
onSourceSelect,
|
21
11
|
}: {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
onRootSelect: () => void;
|
26
|
-
onSourceSelect: (source: ScopedSource) => void;
|
27
|
-
setSource: (source: ScopedSource | null, path?: Resource[]) => void;
|
28
|
-
currentResource: Resource | null;
|
29
|
-
recentSources: RecentResourcesPaths[];
|
12
|
+
sources: ResourceBrowserSource[];
|
13
|
+
selectedSource: ResourceBrowserSource;
|
14
|
+
onSourceSelect(source: ResourceBrowserSource): void;
|
30
15
|
}) {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
44
|
-
|
16
|
+
const [uniqueId] = useState(uuid());
|
17
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
18
|
+
const [isOpen, setIsOpen] = useState(false);
|
19
|
+
|
20
|
+
// Watch the focus and blur on the menu and close if focus leaves the control
|
21
|
+
const { focusWithinProps } = useFocusWithin({
|
22
|
+
onBlurWithin: () => {
|
23
|
+
setIsOpen(false);
|
24
|
+
},
|
25
|
+
});
|
26
|
+
|
27
|
+
// Listen for Esc key within this element
|
28
|
+
const { keyboardProps } = useKeyboard({
|
29
|
+
onKeyDown: (e) => {
|
30
|
+
if (isOpen && e.key === 'Escape') {
|
31
|
+
setIsOpen(false);
|
32
|
+
buttonRef.current?.focus(); // Restore focus to the element which opened the menu
|
33
|
+
}
|
34
|
+
},
|
35
|
+
});
|
45
36
|
|
46
|
-
|
47
|
-
const { keyboardProps } = useKeyboard({
|
48
|
-
onKeyDown: (e) => {
|
49
|
-
if (isOpen && e.key === 'Escape') {
|
37
|
+
const handleSourceClick = (source: ResourceBrowserSource) => {
|
50
38
|
setIsOpen(false);
|
51
|
-
buttonRef.current?.focus();
|
52
|
-
|
53
|
-
}
|
54
|
-
});
|
39
|
+
buttonRef.current?.focus();
|
40
|
+
onSourceSelect(source);
|
41
|
+
};
|
55
42
|
|
56
|
-
|
57
|
-
|
58
|
-
setRecentLocationSelection(null);
|
59
|
-
buttonRef.current?.focus();
|
60
|
-
onSourceSelect(source);
|
61
|
-
};
|
62
|
-
|
63
|
-
const handleRootSelect = () => {
|
64
|
-
setIsOpen(false);
|
65
|
-
setRecentLocationSelection(null);
|
66
|
-
buttonRef.current?.focus();
|
67
|
-
onRootSelect();
|
68
|
-
};
|
69
|
-
|
70
|
-
const handleRecentLocationClick = (location: RecentResourcesPaths) => {
|
71
|
-
setIsOpen(false);
|
72
|
-
setRecentLocationSelection(location);
|
73
|
-
buttonRef.current?.focus();
|
74
|
-
|
75
|
-
if (location.path) {
|
76
|
-
const [rootNode, ...path] = location.path;
|
77
|
-
setSource(
|
78
|
-
{
|
79
|
-
source: location.source as Source,
|
80
|
-
resource: rootNode,
|
81
|
-
},
|
82
|
-
path,
|
83
|
-
);
|
43
|
+
if (!sources.length) {
|
44
|
+
return <></>;
|
84
45
|
}
|
85
|
-
};
|
86
46
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
>
|
109
|
-
{selectedSource && (
|
110
|
-
<>
|
111
|
-
<span className="sr-only">current source </span>
|
112
|
-
<Icon
|
113
|
-
icon={
|
114
|
-
// Ignoring this specific line in test coverage because its a super niche issue that I could only replicate in Matrix
|
115
|
-
/* istanbul ignore next */
|
116
|
-
recentLocationSelection
|
117
|
-
? currentResource?.type.code || selectedSource.resource?.type.code
|
118
|
-
: selectedSource.resource?.type.code
|
119
|
-
}
|
120
|
-
resourceSource="matrix"
|
121
|
-
aria-hidden
|
122
|
-
className="mr-2.5 h-[20px] w-[20px]"
|
123
|
-
/>
|
124
|
-
<div className="truncate max-w-[200px]">
|
125
|
-
{
|
126
|
-
// Ignoring this specific line in test coverage because its a super niche issue that I could only replicate in Matrix
|
127
|
-
/* istanbul ignore next */
|
128
|
-
recentLocationSelection
|
129
|
-
? currentResource?.name || selectedSource.resource?.name || selectedSource.source.name
|
130
|
-
: selectedSource.resource?.name || selectedSource.source.name
|
131
|
-
}
|
132
|
-
</div>
|
133
|
-
</>
|
134
|
-
)}
|
135
|
-
|
136
|
-
{!selectedSource && (
|
137
|
-
<>
|
138
|
-
<span className="sr-only">view </span>
|
139
|
-
<Icon icon={'root' as IconOptions} aria-hidden className="mr-2.5 h-[20px] w-[20px]" />
|
140
|
-
All available sources
|
141
|
-
</>
|
142
|
-
)}
|
143
|
-
|
144
|
-
<Icon icon={'arrow-down' as IconOptions} aria-hidden className="absolute right-3" />
|
145
|
-
</button>
|
146
|
-
<ul
|
147
|
-
id={`${uniqueId}-button-menu`}
|
148
|
-
aria-hidden={!isOpen}
|
149
|
-
className={`absolute z-50 top-[calc(100%+5px)] -left-0.5 w-[calc(100%+4px)] bg-gray-100 border-2 rounded border-gray-300 p-2 overflow-y-scroll max-h-80 ${
|
150
|
-
!isOpen ? 'hidden' : ''
|
151
|
-
}`}
|
152
|
-
>
|
153
|
-
<li
|
154
|
-
key="return-root"
|
155
|
-
className="flex items-center text-sm font-semibold mb-2 bg-white border-1 rounded border-grey-200"
|
156
|
-
>
|
157
|
-
<button
|
158
|
-
type="button"
|
159
|
-
onClick={handleRootSelect}
|
160
|
-
className={`relative grow flex items-center p-2.5 hover:bg-gray-100 focus:bg-gray-100`}
|
161
|
-
>
|
162
|
-
<Icon icon={'root' as IconOptions} aria-hidden className="mr-2.5" />
|
163
|
-
All available sources
|
164
|
-
</button>
|
165
|
-
</li>
|
166
|
-
{isLoading && (
|
167
|
-
<li className="mt-2">
|
168
|
-
<Spinner size="sm" label="Loading sources" className="m-3" />
|
169
|
-
</li>
|
170
|
-
)}
|
171
|
-
|
172
|
-
{!isLoading && filteredRecentSources.length > 0 && (
|
173
|
-
<li className={`flex flex-col text-sm font-semibold text-grey-800`}>
|
174
|
-
<div className="relative flex justify-center before:w-full before:h-px before:bg-gray-300 before:absolute before:top-2/4 before:z-0">
|
175
|
-
<span className="z-10 bg-gray-100 px-2.5 flex gap-1 items-center">
|
176
|
-
<HistoryIcon />
|
177
|
-
Recent locations
|
178
|
-
</span>
|
179
|
-
</div>
|
180
|
-
<ul aria-label="recent location nodes" className="flex flex-col mt-2">
|
181
|
-
{filteredRecentSources.map((item, index) => {
|
182
|
-
const lastResource = item.path && item.path[item.path.length - 1];
|
183
|
-
const isSelectedSource =
|
184
|
-
item.source?.id === selectedSource?.source.id &&
|
185
|
-
lastResource?.id === recentLocationSelection?.path?.[recentLocationSelection.path?.length - 1]?.id;
|
186
|
-
|
187
|
-
return (
|
188
|
-
<li
|
189
|
-
key={`${index}-${item.source?.id}-${lastResource?.id}`}
|
190
|
-
className="flex items-center bg-white border border-b-0 last:border-b border-grey-200 first:rounded-t last:rounded-b"
|
191
|
-
>
|
192
|
-
<button
|
193
|
-
type="button"
|
194
|
-
onClick={() => handleRecentLocationClick(item)}
|
195
|
-
className={`relative grow flex items-center p-2.5 hover:bg-gray-100 focus:bg-gray-100`}
|
196
|
-
>
|
197
|
-
<Icon
|
198
|
-
icon={(lastResource?.type.code || 'folder') as IconOptions}
|
199
|
-
resourceSource="matrix"
|
200
|
-
aria-label={lastResource?.name || item.source?.name}
|
201
|
-
className="shrink-0 mr-2.5"
|
202
|
-
/>
|
203
|
-
<span className="text-left mr-7">{lastResource?.name || item.source?.name}</span>
|
204
|
-
{isSelectedSource && (
|
205
|
-
<Icon icon={'selected' as IconOptions} aria-label="selected" className="absolute right-4" />
|
206
|
-
)}
|
207
|
-
</button>
|
208
|
-
</li>
|
209
|
-
);
|
210
|
-
})}
|
211
|
-
</ul>
|
212
|
-
</li>
|
213
|
-
)}
|
214
|
-
|
215
|
-
{!isLoading &&
|
216
|
-
categorisedSources.map(({ key, label, sources }, index) => {
|
217
|
-
return (
|
218
|
-
<li
|
219
|
-
key={key}
|
220
|
-
className={`flex flex-col text-sm font-semibold text-grey-800 ${
|
221
|
-
index > 0 || filteredRecentSources.length > 0 ? 'mt-3' : ''
|
47
|
+
return (
|
48
|
+
<div {...focusWithinProps} {...keyboardProps} className="relative w-72 border-2 rounded border-gray-300">
|
49
|
+
<button
|
50
|
+
ref={buttonRef}
|
51
|
+
type="button"
|
52
|
+
aria-label="Source quick select"
|
53
|
+
aria-expanded={isOpen}
|
54
|
+
aria-controls={`${uniqueId}-button-menu`}
|
55
|
+
onClick={() => setIsOpen(!isOpen)}
|
56
|
+
className="relative flex items-center text-sm font-semibold p-1.5 w-full"
|
57
|
+
>
|
58
|
+
<span className="sr-only">current source </span>
|
59
|
+
<Icon icon={selectedSource.type as IconOptions} aria-hidden className="mr-2.5 h-[20px] w-[20px]" />
|
60
|
+
<div className="truncate max-w-[200px]">{selectedSource.name}</div>
|
61
|
+
<Icon icon={'arrow-down' as IconOptions} aria-hidden className="absolute right-3" />
|
62
|
+
</button>
|
63
|
+
<ul
|
64
|
+
id={`${uniqueId}-button-menu`}
|
65
|
+
aria-hidden={!isOpen}
|
66
|
+
className={`absolute z-50 top-[calc(100%+5px)] -left-0.5 w-[calc(100%+4px)] bg-gray-100 border-1 shadow-md rounded border-gray-300 p-2 pb-0 overflow-y-scroll max-h-80 ${
|
67
|
+
!isOpen ? 'hidden' : ''
|
222
68
|
}`}
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
type="button"
|
242
|
-
onClick={() => handleSourceClick({ source, resource })}
|
243
|
-
className={`relative grow flex items-center p-2.5 hover:bg-gray-100 focus:bg-gray-100`}
|
244
|
-
>
|
245
|
-
<Icon
|
246
|
-
icon={resource?.type.code as IconOptions}
|
247
|
-
resourceSource="matrix"
|
248
|
-
aria-label={resource?.type.name}
|
249
|
-
className="shrink-0 mr-2.5"
|
250
|
-
/>
|
251
|
-
<span className="text-left mr-7">{resource?.name || source.name}</span>
|
252
|
-
{isSelectedSource && (
|
253
|
-
<Icon
|
254
|
-
icon={'selected' as IconOptions}
|
255
|
-
aria-label="selected"
|
256
|
-
className="absolute right-4"
|
257
|
-
/>
|
258
|
-
)}
|
259
|
-
</button>
|
69
|
+
>
|
70
|
+
{sources.map((source) => {
|
71
|
+
const { id, name, type } = source;
|
72
|
+
const isSelectedSource = id === selectedSource.id;
|
73
|
+
|
74
|
+
return (
|
75
|
+
<li key={id} className="flex items-center text-sm font-semibold mb-2 bg-white rounded">
|
76
|
+
<button
|
77
|
+
type="button"
|
78
|
+
onClick={() => handleSourceClick(source)}
|
79
|
+
className={`relative grow flex items-center p-2 border-1 border-white rounded hover:bg-gray-50 hover:border-gray-300 focus:bg-gray-100`}
|
80
|
+
>
|
81
|
+
<Icon icon={type as IconOptions} aria-label={type} className="shrink-0 mr-2.5" />
|
82
|
+
<span className="text-left mr-7">{name}</span>
|
83
|
+
{isSelectedSource && (
|
84
|
+
<Icon icon={'selected' as IconOptions} aria-label="selected" className="absolute right-4" />
|
85
|
+
)}
|
86
|
+
</button>
|
260
87
|
</li>
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
);
|
267
|
-
})}
|
268
|
-
</ul>
|
269
|
-
</div>
|
270
|
-
);
|
88
|
+
);
|
89
|
+
})}
|
90
|
+
</ul>
|
91
|
+
</div>
|
92
|
+
);
|
271
93
|
}
|