@squiz/resource-browser 1.32.1-alpha.33 → 1.32.1-alpha.35
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/lib/Hooks/useAsync.d.ts +21 -0
- package/lib/Hooks/useAsync.js +53 -0
- package/lib/Hooks/useChildResources.d.ts +3 -7
- package/lib/Hooks/useChildResources.js +5 -29
- package/lib/Hooks/useResource.d.ts +15 -0
- package/lib/Hooks/useResource.js +12 -0
- package/lib/Hooks/useResourcePath.d.ts +1 -1
- package/lib/PreviewPanel/details/MatrixResource.js +2 -1
- package/lib/ResourceBrowserContext/ResourceBrowserContext.d.ts +8 -0
- package/lib/ResourceBrowserContext/ResourceBrowserContext.js +18 -0
- package/lib/ResourceItem/ResourceItem.js +1 -1
- package/lib/ResourcePicker/ResetButton.d.ts +5 -0
- package/lib/ResourcePicker/ResetButton.js +11 -0
- package/lib/ResourcePicker/ResourcePicker.d.ts +14 -0
- package/lib/ResourcePicker/ResourcePicker.js +26 -0
- package/lib/ResourcePicker/States/Error.d.ts +6 -0
- package/lib/ResourcePicker/States/Error.js +14 -0
- package/lib/ResourcePicker/States/Loading.d.ts +1 -0
- package/lib/ResourcePicker/States/Loading.js +11 -0
- package/lib/ResourcePicker/States/Selected.d.ts +7 -0
- package/lib/ResourcePicker/States/Selected.js +43 -0
- package/lib/ResourcePickerContainer/ResourcePickerContainer.js +3 -3
- package/lib/Skeleton/ListItem/SkeletonListItem.js +1 -1
- package/lib/SourceDropdown/SourceDropdown.js +3 -3
- package/lib/StatusIndicator/StatusIndicator.d.ts +2 -1
- package/lib/StatusIndicator/StatusIndicator.js +3 -2
- package/lib/index.css +6 -0
- package/lib/index.d.ts +8 -7
- package/lib/index.js +35 -13
- package/lib/types.d.ts +67 -0
- package/lib/types.js +2 -0
- package/package.json +3 -3
- package/src/Hooks/useAsync.spec.ts +106 -0
- package/src/Hooks/useAsync.ts +62 -0
- package/src/Hooks/useChildResources.spec.ts +2 -23
- package/src/Hooks/useChildResources.ts +9 -34
- package/src/Hooks/useResource.spec.ts +32 -0
- package/src/Hooks/useResource.ts +19 -0
- package/src/Hooks/useSources.spec.ts +2 -14
- package/src/Hooks/useSources.ts +3 -26
- package/src/PreviewPanel/details/MatrixResource.tsx +1 -2
- package/src/ResourceBrowserContext/ResourceBrowserContext.spec.tsx +32 -0
- package/src/ResourceBrowserContext/ResourceBrowserContext.ts +20 -0
- package/src/ResourceItem/ResourceItem.tsx +1 -1
- package/src/ResourcePicker/ResetButton.tsx +7 -1
- package/src/ResourcePicker/ResourcePicker.spec.tsx +8 -4
- package/src/ResourcePicker/ResourcePicker.stories.tsx +2 -2
- package/src/ResourcePicker/ResourcePicker.tsx +21 -12
- package/src/ResourcePicker/States/Error.tsx +9 -3
- package/src/ResourcePicker/States/Selected.tsx +9 -4
- package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +5 -5
- package/src/Skeleton/ListItem/SkeletonListItem.tsx +1 -1
- package/src/SourceDropdown/SourceDropdown.tsx +3 -3
- package/src/StatusIndicator/StatusIndicator.tsx +5 -2
- package/src/__mocks__/StorybookHelpers.ts +18 -13
- package/src/index.spec.tsx +4 -4
- package/src/index.stories.tsx +15 -15
- package/src/index.tsx +39 -54
- package/src/{types.d.ts → types.ts} +1 -1
- package/tailwind.config.cjs +5 -0
- package/lib/Hooks/useSources.d.ts +0 -16
- package/lib/Hooks/useSources.js +0 -31
@@ -1,10 +1,9 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
|
3
|
-
import { Resource } from '../types';
|
4
2
|
import AdsClickRoundedIcon from '@mui/icons-material/AdsClickRounded';
|
5
3
|
import AddCircleOutlineRoundedIcon from '@mui/icons-material/AddCircleOutlineRounded';
|
6
4
|
import PhotoLibraryRoundedIcon from '@mui/icons-material/PhotoLibraryRounded';
|
7
|
-
|
5
|
+
import { DOMAttributes } from '@react-types/shared';
|
6
|
+
import { Resource } from '../types';
|
8
7
|
import ModalTrigger from '../Modal/ModalTrigger';
|
9
8
|
import { ErrorState } from './States/Error';
|
10
9
|
import { LoadingState } from './States/Loading';
|
@@ -12,16 +11,26 @@ import { SelectedState } from './States/Selected';
|
|
12
11
|
import clsx from 'clsx';
|
13
12
|
|
14
13
|
export type ResourcePickerProps = {
|
15
|
-
resource: Resource;
|
14
|
+
resource: Resource | null;
|
16
15
|
allowedTypes: string[] | undefined;
|
17
|
-
|
16
|
+
error: Error | null;
|
18
17
|
isLoading: boolean;
|
19
|
-
isDisabled
|
18
|
+
isDisabled?: boolean;
|
19
|
+
children: (onClose: () => void, titleProps: DOMAttributes) => React.ReactElement;
|
20
|
+
onClear: () => void;
|
20
21
|
};
|
21
22
|
|
22
|
-
const ResourcePicker = ({
|
23
|
-
|
24
|
-
|
23
|
+
const ResourcePicker = ({
|
24
|
+
resource,
|
25
|
+
allowedTypes,
|
26
|
+
error,
|
27
|
+
isLoading,
|
28
|
+
isDisabled,
|
29
|
+
children,
|
30
|
+
onClear,
|
31
|
+
}: ResourcePickerProps) => {
|
32
|
+
const isImagePicker = allowedTypes && allowedTypes.length === 1 && allowedTypes.includes('image');
|
33
|
+
const isEmpty = resource === null && !isLoading && !error;
|
25
34
|
|
26
35
|
return (
|
27
36
|
<div className={clsx('resource-picker', isDisabled && 'bg-gray-300')}>
|
@@ -37,14 +46,14 @@ const ResourcePicker = ({ resource, allowedTypes, isError, isLoading, isDisabled
|
|
37
46
|
icon={<AddCircleOutlineRoundedIcon aria-hidden className="!w-4 !h-4" />}
|
38
47
|
isDisabled={isDisabled}
|
39
48
|
>
|
40
|
-
{
|
49
|
+
{children}
|
41
50
|
</ModalTrigger>
|
42
51
|
) : (
|
43
52
|
<div className="resource-picker-info">
|
44
53
|
<div className="resource-picker-info__layout">
|
45
54
|
{isLoading && <LoadingState />}
|
46
|
-
{
|
47
|
-
{resource
|
55
|
+
{error && <ErrorState error={error} onClear={onClear} />}
|
56
|
+
{resource && <SelectedState resource={resource} isDisabled={isDisabled} onClear={onClear} />}
|
48
57
|
</div>
|
49
58
|
</div>
|
50
59
|
)}
|
@@ -3,10 +3,16 @@ import React from 'react';
|
|
3
3
|
import Icon, { IconOptions } from '../../Icons/Icon';
|
4
4
|
import { ResetButton } from '../ResetButton';
|
5
5
|
|
6
|
-
export
|
6
|
+
export type ErrorStateProps = {
|
7
|
+
error: Error;
|
8
|
+
isDisabled?: boolean;
|
9
|
+
onClear: () => void;
|
10
|
+
};
|
11
|
+
|
12
|
+
export const ErrorState = ({ error, isDisabled, onClear }: ErrorStateProps) => (
|
7
13
|
<>
|
8
14
|
<Icon icon={'error' as IconOptions} aria-hidden className="w-6 h-6 text-red-300" />
|
9
|
-
<div className="text-red-300">
|
10
|
-
<ResetButton isDisabled={isDisabled} />
|
15
|
+
<div className="text-red-300">{error.message}</div>
|
16
|
+
<ResetButton isDisabled={isDisabled} onClick={onClear} />
|
11
17
|
</>
|
12
18
|
);
|
@@ -8,10 +8,15 @@ import { ResetButton } from '../ResetButton';
|
|
8
8
|
|
9
9
|
export type SelectedStateProps = {
|
10
10
|
resource: Resource;
|
11
|
-
isDisabled
|
11
|
+
isDisabled?: boolean;
|
12
|
+
onClear: () => void;
|
12
13
|
};
|
13
14
|
|
14
|
-
export const SelectedState = ({
|
15
|
+
export const SelectedState = ({
|
16
|
+
resource: { id, type, name, status, squizImage },
|
17
|
+
isDisabled,
|
18
|
+
onClear,
|
19
|
+
}: SelectedStateProps) => {
|
15
20
|
const fileSize = squizImage?.imageVariations?.original?.byteSize;
|
16
21
|
const fileWidth = squizImage?.imageVariations?.original?.width;
|
17
22
|
const fileHeight = squizImage?.imageVariations?.original?.height;
|
@@ -23,9 +28,9 @@ export const SelectedState = ({ resource: { id, type, name, status, squizImage }
|
|
23
28
|
{/* Center column */}
|
24
29
|
<div className="justify-self-start self-center">{name}</div>
|
25
30
|
{/* End column */}
|
26
|
-
<ResetButton isDisabled={isDisabled} />
|
31
|
+
<ResetButton isDisabled={isDisabled} onClick={onClear} />
|
27
32
|
</>
|
28
|
-
<dl className="col-start-2 col-end-2 flex flex-
|
33
|
+
<dl className="col-start-2 col-end-2 flex flex-row gap-1 justify-self-start items-center font-normal text-sm">
|
29
34
|
<div>
|
30
35
|
<dt className="hidden">Status: {status.name}</dt>
|
31
36
|
<dd className="flex items-center">
|
@@ -10,8 +10,8 @@ import SourceDropdown from '../SourceDropdown/SourceDropdown';
|
|
10
10
|
|
11
11
|
import { Source, Resource, HydratedResourceReference, ScopedSource } from '../types';
|
12
12
|
import { useResourcePath } from '../Hooks/useResourcePath';
|
13
|
+
import { useAsync } from '../Hooks/useAsync';
|
13
14
|
import { useChildResources } from '../Hooks/useChildResources';
|
14
|
-
import { useSources } from '../Hooks/useSources';
|
15
15
|
|
16
16
|
interface ResourcePickerContainerProps {
|
17
17
|
title: string;
|
@@ -38,16 +38,16 @@ function ResourcePickerContainer({
|
|
38
38
|
const { source, currentResource, hierarchy, setSource, push, popUntil } = useResourcePath();
|
39
39
|
|
40
40
|
const {
|
41
|
-
sources,
|
41
|
+
data: sources,
|
42
42
|
isLoading: isSourceLoading,
|
43
43
|
reload: handleSourceReload,
|
44
44
|
error: sourceError,
|
45
|
-
} =
|
45
|
+
} = useAsync({ callback: onRequestSources, defaultValue: [] }, []);
|
46
46
|
|
47
47
|
const {
|
48
|
-
resources,
|
48
|
+
data: resources,
|
49
49
|
isLoading: isResourcesLoading,
|
50
|
-
|
50
|
+
reload: handleResourceReload,
|
51
51
|
error: resourceError,
|
52
52
|
} = useChildResources({ source, currentResource, onRequestChildren });
|
53
53
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
|
3
3
|
export const SkeletonListItem = () => (
|
4
|
-
<li className="flex items-center p-1 first:mt-0 bg-white border border-b-0 border-grey-200 first:rounded-t-lg last:rounded-b-lg last:border-b">
|
4
|
+
<li className="flex items-center p-1 first:mt-0 bg-white border-1 border-b-0 border-grey-200 first:rounded-t-lg last:rounded-b-lg last:border-b">
|
5
5
|
<div className="animate-skeleton-pulse grid grid-cols-[24px_1fr_45px] w-full flex items-center p-4 rounded">
|
6
6
|
<span className="w-6 h-6 bg-gray-200 rounded-full" />
|
7
7
|
<div className="w-full d-flex flex-col mx-4">
|
@@ -56,7 +56,7 @@ export default function SourceDropdown({
|
|
56
56
|
};
|
57
57
|
|
58
58
|
return (
|
59
|
-
<div {...focusWithinProps} {...keyboardProps} className="relative w-72 border
|
59
|
+
<div {...focusWithinProps} {...keyboardProps} className="relative w-72 border-2 rounded border-gray-300">
|
60
60
|
<button
|
61
61
|
ref={buttonRef}
|
62
62
|
type="button"
|
@@ -92,13 +92,13 @@ export default function SourceDropdown({
|
|
92
92
|
<ul
|
93
93
|
id={`${uniqueId}-button-menu`}
|
94
94
|
aria-hidden={!isOpen}
|
95
|
-
className={`absolute z-50 top-[calc(100%+5px)] -left-0.5 w-[calc(100%+4px)] bg-gray-100 border
|
95
|
+
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 ${
|
96
96
|
!isOpen ? 'hidden' : ''
|
97
97
|
}`}
|
98
98
|
>
|
99
99
|
<li
|
100
100
|
key="return-root"
|
101
|
-
className="flex items-center text-sm font-semibold mb-2 bg-white border rounded border-grey-200"
|
101
|
+
className="flex items-center text-sm font-semibold mb-2 bg-white border-1 rounded border-grey-200"
|
102
102
|
>
|
103
103
|
<button
|
104
104
|
type="button"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import clsx from 'clsx';
|
2
3
|
import { Status } from '../types';
|
3
4
|
|
4
5
|
const statusColour = {
|
@@ -18,16 +19,18 @@ const statusColour = {
|
|
18
19
|
};
|
19
20
|
|
20
21
|
export type StatusIndicatorProps = {
|
22
|
+
className?: string;
|
21
23
|
status: Status;
|
22
24
|
};
|
23
25
|
|
24
|
-
const StatusIndicator = ({ status }: StatusIndicatorProps) => {
|
26
|
+
const StatusIndicator = ({ className, status }: StatusIndicatorProps) => {
|
25
27
|
const color = statusColour[status.code as keyof typeof statusColour] || statusColour.unknown;
|
26
28
|
|
27
29
|
return (
|
28
30
|
<span
|
29
31
|
style={{ backgroundColor: color }}
|
30
|
-
className=
|
32
|
+
className={clsx('block rounded-full w-3 h-3 border-1 border-solid border-black border-opacity-20', className)}
|
33
|
+
title={status.name}
|
31
34
|
></span>
|
32
35
|
);
|
33
36
|
};
|
@@ -18,15 +18,15 @@ export const createResourceBrowserCallbacks = ({
|
|
18
18
|
return {
|
19
19
|
onRequestSources: () => {
|
20
20
|
return new Promise((resolve, reject) => {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
if (!sourceIsLoading) {
|
22
|
+
setTimeout(() => {
|
23
|
+
if (error && Math.random() > 0.5) {
|
24
|
+
reject(new Error(error));
|
25
|
+
} else {
|
26
26
|
resolve(sampleSources);
|
27
27
|
}
|
28
|
-
}
|
29
|
-
}
|
28
|
+
}, delay);
|
29
|
+
}
|
30
30
|
});
|
31
31
|
},
|
32
32
|
onRequestChildren: (source: Source, resource: Resource | null) => {
|
@@ -36,8 +36,7 @@ export const createResourceBrowserCallbacks = ({
|
|
36
36
|
if (error && Math.random() > 0.5) {
|
37
37
|
reject(new Error(error));
|
38
38
|
} else {
|
39
|
-
|
40
|
-
resolve(children);
|
39
|
+
resolve(((resource as any)?._children || sampleResources) as Resource[] | undefined);
|
41
40
|
}
|
42
41
|
}, delay);
|
43
42
|
}
|
@@ -56,10 +55,16 @@ export const createResourceBrowserCallbacks = ({
|
|
56
55
|
}
|
57
56
|
});
|
58
57
|
},
|
59
|
-
onChange: (
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
onChange: (reference: HydratedResourceReference | null) => {
|
59
|
+
if (reference) {
|
60
|
+
const { resource, source } = reference;
|
61
|
+
|
62
|
+
alert(
|
63
|
+
`Resource Browser has selected resource #${resource.id} (${resource.name}) from source #${source.id} (${source.name}).`,
|
64
|
+
);
|
65
|
+
} else {
|
66
|
+
alert(`Resource Browser has cleared selected resource.`);
|
67
|
+
}
|
63
68
|
},
|
64
69
|
};
|
65
70
|
};
|
package/src/index.spec.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { render, screen } from '@testing-library/react';
|
3
|
-
import
|
3
|
+
import { ResourceBrowserInput } from './index';
|
4
4
|
|
5
5
|
const mockRequestSources = jest.fn();
|
6
6
|
const mockRequestChildren = jest.fn();
|
@@ -18,14 +18,14 @@ const defaultProps: any = {
|
|
18
18
|
|
19
19
|
describe('Related Asset Picker', () => {
|
20
20
|
it('should render the related asset picker with the default label', () => {
|
21
|
-
render(<
|
21
|
+
render(<ResourceBrowserInput {...defaultProps} />);
|
22
22
|
const pickerLabel = screen.getByText('Choose asset');
|
23
23
|
|
24
24
|
expect(pickerLabel).toBeInTheDocument();
|
25
25
|
});
|
26
26
|
|
27
27
|
it('should display the generic asset picking icon', () => {
|
28
|
-
render(<
|
28
|
+
render(<ResourceBrowserInput {...defaultProps} />);
|
29
29
|
const pickerLabel = screen.getByText('Choose asset');
|
30
30
|
const pickerIcon = screen.getByTestId('AdsClickRoundedIcon');
|
31
31
|
|
@@ -34,7 +34,7 @@ describe('Related Asset Picker', () => {
|
|
34
34
|
});
|
35
35
|
|
36
36
|
it('should display the image icon when only images are allowed', () => {
|
37
|
-
render(<
|
37
|
+
render(<ResourceBrowserInput {...defaultProps} allowedTypes={['image']} />);
|
38
38
|
const pickerLabel = screen.getByText('Choose image');
|
39
39
|
const pickerIcon = screen.getByTestId('PhotoLibraryRoundedIcon');
|
40
40
|
|
package/src/index.stories.tsx
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
import { StoryFn, Meta } from '@storybook/react';
|
2
|
-
import
|
2
|
+
import { ResourceBrowserInput, ResourceBrowserContext } from './index';
|
3
3
|
import { createResourceBrowserCallbacks } from './__mocks__/StorybookHelpers';
|
4
4
|
|
5
5
|
export default {
|
6
|
-
title: '
|
7
|
-
component:
|
8
|
-
} as Meta<typeof
|
6
|
+
title: 'Resource browser input',
|
7
|
+
component: ResourceBrowserInput,
|
8
|
+
} as Meta<typeof ResourceBrowserInput>;
|
9
9
|
|
10
|
-
const Template: StoryFn<typeof
|
11
|
-
const { sourceIsLoading, resourceIsLoading, error } = props;
|
10
|
+
const Template: StoryFn<typeof ResourceBrowserInput> = (props) => {
|
11
|
+
const { sourceIsLoading, resourceIsLoading, error, ...other } = props;
|
12
12
|
const { onRequestSources, onRequestChildren, onRequestResource, onChange } = createResourceBrowserCallbacks({
|
13
13
|
sourceIsLoading: !!sourceIsLoading,
|
14
14
|
resourceIsLoading: !!resourceIsLoading,
|
@@ -17,13 +17,9 @@ const Template: StoryFn<typeof RelatedAssetPicker> = (props) => {
|
|
17
17
|
|
18
18
|
return (
|
19
19
|
<div className="w-[400px] m-3">
|
20
|
-
<
|
21
|
-
{...
|
22
|
-
|
23
|
-
onRequestChildren={onRequestChildren}
|
24
|
-
onRequestResource={onRequestResource}
|
25
|
-
onChange={onChange}
|
26
|
-
/>
|
20
|
+
<ResourceBrowserContext.Provider value={{ onRequestSources, onRequestChildren, onRequestResource }}>
|
21
|
+
<ResourceBrowserInput {...other} onChange={onChange} />
|
22
|
+
</ResourceBrowserContext.Provider>
|
27
23
|
</div>
|
28
24
|
);
|
29
25
|
};
|
@@ -31,11 +27,15 @@ const Template: StoryFn<typeof RelatedAssetPicker> = (props) => {
|
|
31
27
|
export const Primary = Template.bind({});
|
32
28
|
|
33
29
|
Primary.args = {
|
34
|
-
modalTitle: '
|
30
|
+
modalTitle: 'Choose asset',
|
35
31
|
sourceIsLoading: false,
|
36
32
|
resourceIsLoading: false,
|
37
33
|
error: '',
|
38
|
-
|
34
|
+
};
|
35
|
+
|
36
|
+
export const Selected = Template.bind({});
|
37
|
+
Selected.args = {
|
38
|
+
value: { resource: '1', source: '2' },
|
39
39
|
};
|
40
40
|
|
41
41
|
export const ImagesOnly = Template.bind({});
|
package/src/index.tsx
CHANGED
@@ -1,68 +1,53 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import ModalTrigger from './Modal/ModalTrigger';
|
1
|
+
import React, { useContext } from 'react';
|
3
2
|
import ResourcePickerContainer from './ResourcePickerContainer/ResourcePickerContainer';
|
4
3
|
import { HydratedResourceReference, Resource, ResourceReference, Source } from './types';
|
5
|
-
import
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import clsx from 'clsx';
|
9
|
-
// import { LoadingState, ErrorState, SelectedState } from './ResourcePicker/ResourcePicker';
|
4
|
+
import { ResourceBrowserContext } from './ResourceBrowserContext/ResourceBrowserContext';
|
5
|
+
import ResourcePicker from './ResourcePicker/ResourcePicker';
|
6
|
+
import { useResource } from './Hooks/useResource';
|
10
7
|
|
11
8
|
export type { HydratedResourceReference, Resource, ResourceReference, Source };
|
9
|
+
export { ResourceBrowserContext };
|
12
10
|
|
13
|
-
|
11
|
+
type ResourceBrowserInputProps = {
|
12
|
+
modalTitle: string;
|
13
|
+
allowedTypes?: string[];
|
14
|
+
isDisabled?: boolean;
|
15
|
+
value: ResourceReference | null;
|
16
|
+
onChange(resource: HydratedResourceReference | null): void;
|
17
|
+
};
|
18
|
+
|
19
|
+
export const ResourceBrowserInput = ({
|
14
20
|
modalTitle,
|
15
21
|
allowedTypes,
|
16
|
-
onRequestSources,
|
17
|
-
onRequestChildren,
|
18
22
|
onChange,
|
23
|
+
value,
|
19
24
|
isDisabled,
|
20
|
-
}: {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
onRequestChildren(source: Source, resource: Resource | null): Promise<Resource[]>;
|
25
|
-
onRequestResource(reference: ResourceReference): Promise<Resource | null>;
|
26
|
-
onChange(resource: HydratedResourceReference | null): void;
|
27
|
-
isDisabled?: boolean;
|
28
|
-
}) {
|
29
|
-
const isImagePicker = allowedTypes && allowedTypes.length === 1 && allowedTypes.includes('image');
|
25
|
+
}: ResourceBrowserInputProps) => {
|
26
|
+
const { onRequestSources, onRequestChildren, onRequestResource } = useContext(ResourceBrowserContext);
|
27
|
+
const { data: resource, error, isLoading } = useResource({ onRequestResource, reference: value });
|
28
|
+
|
30
29
|
return (
|
31
30
|
<div className="squiz-rb-scope">
|
32
|
-
<
|
33
|
-
{
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
<ResourcePicker
|
32
|
+
resource={resource}
|
33
|
+
allowedTypes={allowedTypes}
|
34
|
+
error={error}
|
35
|
+
isLoading={isLoading}
|
36
|
+
isDisabled={isDisabled}
|
37
|
+
onClear={() => onChange(null)}
|
38
|
+
>
|
39
|
+
{(onClose, titleProps) => (
|
40
|
+
<ResourcePickerContainer
|
41
|
+
title={modalTitle}
|
42
|
+
titleAriaProps={titleProps}
|
43
|
+
allowedTypes={allowedTypes}
|
44
|
+
onClose={onClose}
|
45
|
+
onRequestSources={onRequestSources}
|
46
|
+
onRequestChildren={onRequestChildren}
|
47
|
+
onChange={onChange}
|
48
|
+
/>
|
37
49
|
)}
|
38
|
-
|
39
|
-
<ModalTrigger
|
40
|
-
showLabel={true}
|
41
|
-
label={isImagePicker ? `Choose image` : `Choose asset`}
|
42
|
-
icon={<AddCircleOutlineRoundedIcon aria-hidden className="!w-4 !h-4" />}
|
43
|
-
isDisabled={isDisabled}
|
44
|
-
>
|
45
|
-
{(onClose, titleProps) => (
|
46
|
-
<ResourcePickerContainer
|
47
|
-
title={modalTitle}
|
48
|
-
titleAriaProps={titleProps}
|
49
|
-
allowedTypes={allowedTypes}
|
50
|
-
onClose={onClose}
|
51
|
-
onRequestSources={onRequestSources}
|
52
|
-
onRequestChildren={onRequestChildren}
|
53
|
-
onChange={onChange}
|
54
|
-
/>
|
55
|
-
)}
|
56
|
-
</ModalTrigger>
|
57
|
-
{/* TODO: Add all these states in - examples of them can be found in the Resource Picker story and corresponding file /ResourcePicker/ResourcePicker.tsx */}
|
58
|
-
{/* <div className="resource-picker-info">
|
59
|
-
<div className="resource-picker-info__layout">
|
60
|
-
{isLoading && <LoadingState />}
|
61
|
-
{isError && <ErrorState />}
|
62
|
-
{resource !== null && <SelectedState resource={resource} />}
|
63
|
-
</div>
|
64
|
-
</div> */}
|
65
|
-
</div>
|
50
|
+
</ResourcePicker>
|
66
51
|
</div>
|
67
52
|
);
|
68
|
-
}
|
53
|
+
};
|
@@ -63,7 +63,7 @@ export type Hierarchy<T> = Array<{
|
|
63
63
|
/**
|
64
64
|
* Augments a type so that all properties are optional.
|
65
65
|
*/
|
66
|
-
type DeepPartial<T> = {
|
66
|
+
export type DeepPartial<T> = {
|
67
67
|
[P in keyof T]?: T[P] extends Array<infer U>
|
68
68
|
? Array<DeepPartial<U>>
|
69
69
|
: T[P] extends ReadonlyArray<infer U>
|
package/tailwind.config.cjs
CHANGED
@@ -3,6 +3,11 @@ module.exports = {
|
|
3
3
|
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}', './node_modules/flowbite/**/*.js'],
|
4
4
|
theme: {
|
5
5
|
extend: {
|
6
|
+
borderWidth: {
|
7
|
+
// We shouldn't use ".border" class and instead use ".border-1".
|
8
|
+
// ".border" has !important styling defined in Matrix so overrides anything various border styling if used.
|
9
|
+
1: '1px',
|
10
|
+
},
|
6
11
|
borderRadius: {
|
7
12
|
DEFAULT: '4px',
|
8
13
|
md: '6px',
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { Source } from '../types';
|
2
|
-
type UseSourcesProps = {
|
3
|
-
onRequestSources: () => Promise<Source[]>;
|
4
|
-
};
|
5
|
-
/**
|
6
|
-
* Loads and caches the source list when a component using the hook is mounted.
|
7
|
-
*
|
8
|
-
* @param {Function} onRequestSources
|
9
|
-
*/
|
10
|
-
export declare const useSources: ({ onRequestSources }: UseSourcesProps) => {
|
11
|
-
isLoading: boolean;
|
12
|
-
sources: Source[];
|
13
|
-
reload: () => void;
|
14
|
-
error: Error | null;
|
15
|
-
};
|
16
|
-
export {};
|
package/lib/Hooks/useSources.js
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.useSources = void 0;
|
4
|
-
const react_1 = require("react");
|
5
|
-
/**
|
6
|
-
* Loads and caches the source list when a component using the hook is mounted.
|
7
|
-
*
|
8
|
-
* @param {Function} onRequestSources
|
9
|
-
*/
|
10
|
-
const useSources = ({ onRequestSources }) => {
|
11
|
-
const [error, setError] = (0, react_1.useState)(null);
|
12
|
-
const [isLoading, setIsLoading] = (0, react_1.useState)(true);
|
13
|
-
const [sources, setSources] = (0, react_1.useState)([]);
|
14
|
-
const loadSources = (0, react_1.useCallback)(() => {
|
15
|
-
setIsLoading(true);
|
16
|
-
onRequestSources()
|
17
|
-
.then((sources) => {
|
18
|
-
setIsLoading(false);
|
19
|
-
setSources(sources);
|
20
|
-
setError(null);
|
21
|
-
})
|
22
|
-
.catch((error) => {
|
23
|
-
setIsLoading(false);
|
24
|
-
setError(error);
|
25
|
-
});
|
26
|
-
}, []);
|
27
|
-
// trigger a load of the sources when the component using the hook is initially rendered.
|
28
|
-
(0, react_1.useEffect)(loadSources, []);
|
29
|
-
return { isLoading, sources, reload: loadSources, error };
|
30
|
-
};
|
31
|
-
exports.useSources = useSources;
|