Compare commits
2 Commits
chore/add-
...
v0.0.25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fff3c4c0ba | ||
|
|
2692cdad20 |
48
demo/collections/LotsOfFields.js
Normal file
48
demo/collections/LotsOfFields.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const fields = [];
|
||||
|
||||
let i = 0;
|
||||
|
||||
for (i; i < 30; i += 1) {
|
||||
fields.push({
|
||||
name: `array${i}`,
|
||||
type: 'array',
|
||||
label: `array${i}`,
|
||||
fields: [
|
||||
{
|
||||
name: `number${i}`,
|
||||
type: 'number',
|
||||
label: 'Number Field',
|
||||
},
|
||||
{
|
||||
name: `text${i}`,
|
||||
type: 'text',
|
||||
label: 'Text Field',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
fields.push({
|
||||
name: `text${i}`,
|
||||
type: 'text',
|
||||
label: `Text ${i}`,
|
||||
});
|
||||
}
|
||||
|
||||
// for (i; i < 1000; i += 1) {
|
||||
// fields.push({
|
||||
// name: `number${i}`,
|
||||
// type: 'number',
|
||||
// label: 'Number Field',
|
||||
// });
|
||||
// }
|
||||
|
||||
const LotsOfFields = {
|
||||
slug: 'lots-of-fields',
|
||||
labels: {
|
||||
singular: 'Lots of Fields Test',
|
||||
plural: 'Lots of Fields Tests',
|
||||
},
|
||||
fields,
|
||||
};
|
||||
|
||||
module.exports = LotsOfFields;
|
||||
@@ -9,6 +9,7 @@ const Blocks = require('./collections/Blocks');
|
||||
const HiddenFields = require('./collections/HiddenFields');
|
||||
const Hooks = require('./collections/Hooks');
|
||||
const Localized = require('./collections/Localized');
|
||||
const LotsOfFields = require('./collections/LotsOfFields');
|
||||
const LocalizedArray = require('./collections/LocalizedArray');
|
||||
const Media = require('./collections/Media');
|
||||
const NestedArrays = require('./collections/NestedArrays');
|
||||
@@ -46,6 +47,7 @@ module.exports = {
|
||||
Hooks,
|
||||
Localized,
|
||||
LocalizedArray,
|
||||
LotsOfFields,
|
||||
Media,
|
||||
NestedArrays,
|
||||
Preview,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/payload",
|
||||
"version": "0.0.24",
|
||||
"version": "0.0.25",
|
||||
"description": "CMS and Application Framework",
|
||||
"license": "ISC",
|
||||
"author": "Payload CMS LLC",
|
||||
@@ -96,6 +96,7 @@
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-router-navigation-prompt": "^1.8.11",
|
||||
"react-select": "^3.0.8",
|
||||
"react-window": "^1.6.0-alpha.1",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"sass-loader": "7.1.0",
|
||||
"sharp": "^0.25.2",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
RenderFieldsNotes
|
||||
|
||||
slides.0.meta.title
|
||||
slides.1.heroInfo.title
|
||||
|
||||
fields: [
|
||||
{
|
||||
name: slides,
|
||||
type: array,
|
||||
fields: [
|
||||
{
|
||||
type: group,
|
||||
name: meta,
|
||||
fields: [
|
||||
{
|
||||
name: title,
|
||||
type: text,
|
||||
component: require.resolve('/aslifjawelifjaew)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: group,
|
||||
name: heroInfo,
|
||||
fields: [
|
||||
{
|
||||
name: title,
|
||||
type: text,
|
||||
component: require.resolve('/aslifjawelifjaew)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DynamicSizeList as List } from 'react-window';
|
||||
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
|
||||
|
||||
import './index.scss';
|
||||
@@ -25,74 +26,88 @@ const RenderFields = (props) => {
|
||||
const customComponentsPath = customComponentsPathFromProps || customComponentsPathFromContext;
|
||||
const operation = operationFromProps || operationFromContext;
|
||||
|
||||
const renderRow = ({ index, style }) => {
|
||||
const field = fieldSchema[index];
|
||||
|
||||
if (!field?.hidden && field?.admin?.disabled !== true) {
|
||||
if ((filter && typeof filter === 'function' && filter(field)) || !filter) {
|
||||
const FieldComponent = field?.admin?.hidden ? fieldTypes.hidden : fieldTypes[field.type];
|
||||
|
||||
let initialFieldData;
|
||||
let fieldPermissions = permissions[field.name];
|
||||
|
||||
if (!field.name) {
|
||||
initialFieldData = initialData;
|
||||
fieldPermissions = permissions;
|
||||
} else if (initialData?.[field.name] !== undefined) {
|
||||
initialFieldData = initialData[field.name];
|
||||
}
|
||||
|
||||
let { admin: { readOnly } = {} } = field;
|
||||
|
||||
if (readOnlyOverride) readOnly = true;
|
||||
|
||||
if (permissions?.[field?.name]?.read?.permission !== false) {
|
||||
if (permissions?.[field?.name]?.[operation]?.permission === false) {
|
||||
readOnly = true;
|
||||
}
|
||||
|
||||
if (FieldComponent) {
|
||||
return (
|
||||
<div style={{ ...style, top: 200 * index }}>
|
||||
<RenderCustomComponent
|
||||
key={field.name || `field-${index}`}
|
||||
path={`${customComponentsPath}${field.name ? `${field.name}.field` : ''}`}
|
||||
DefaultComponent={FieldComponent}
|
||||
componentProps={{
|
||||
...field,
|
||||
path: field.path || field.name,
|
||||
fieldTypes,
|
||||
initialData: initialFieldData,
|
||||
admin: {
|
||||
...(field.admin || {}),
|
||||
readOnly,
|
||||
},
|
||||
permissions: fieldPermissions,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
className="missing-field"
|
||||
key={index}
|
||||
>
|
||||
No matched field found for
|
||||
{' '}
|
||||
"
|
||||
{field.label}
|
||||
"
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
if (fieldSchema) {
|
||||
return (
|
||||
<RenderedFieldContext.Provider value={{ customComponentsPath, operation }}>
|
||||
{fieldSchema.map((field, i) => {
|
||||
if (!field?.hidden && field?.admin?.disabled !== true) {
|
||||
if ((filter && typeof filter === 'function' && filter(field)) || !filter) {
|
||||
const FieldComponent = field?.admin?.hidden ? fieldTypes.hidden : fieldTypes[field.type];
|
||||
|
||||
let initialFieldData;
|
||||
let fieldPermissions = permissions[field.name];
|
||||
|
||||
if (!field.name) {
|
||||
initialFieldData = initialData;
|
||||
fieldPermissions = permissions;
|
||||
} else if (initialData?.[field.name] !== undefined) {
|
||||
initialFieldData = initialData[field.name];
|
||||
}
|
||||
|
||||
let { admin: { readOnly } = {} } = field;
|
||||
|
||||
if (readOnlyOverride) readOnly = true;
|
||||
|
||||
if (permissions?.[field?.name]?.read?.permission !== false) {
|
||||
if (permissions?.[field?.name]?.[operation]?.permission === false) {
|
||||
readOnly = true;
|
||||
}
|
||||
|
||||
if (FieldComponent) {
|
||||
return (
|
||||
<RenderCustomComponent
|
||||
key={field.name || `field-${i}`}
|
||||
path={`${customComponentsPath}${field.name ? `${field.name}.field` : ''}`}
|
||||
DefaultComponent={FieldComponent}
|
||||
componentProps={{
|
||||
...field,
|
||||
path: field.path || field.name,
|
||||
fieldTypes,
|
||||
initialData: initialFieldData,
|
||||
admin: {
|
||||
...(field.admin || {}),
|
||||
readOnly,
|
||||
},
|
||||
permissions: fieldPermissions,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="missing-field"
|
||||
key={i}
|
||||
>
|
||||
No matched field found for
|
||||
{' '}
|
||||
"
|
||||
{field.label}
|
||||
"
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
})}
|
||||
<List
|
||||
data={fieldSchema}
|
||||
itemCount={fieldSchema.length}
|
||||
height={600}
|
||||
width={750}
|
||||
>
|
||||
{renderRow}
|
||||
</List>
|
||||
</RenderedFieldContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { ScrollInfoProvider } from '@faceless-ui/scroll-info';
|
||||
|
||||
@@ -18,6 +18,9 @@ import LeaveWithoutSaving from '../../../modals/LeaveWithoutSaving';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const mainFieldFilter = (field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'));
|
||||
const sidebarFieldFilter = (field) => field?.admin?.position === 'sidebar';
|
||||
|
||||
const { serverURL, routes: { api, admin } } = config;
|
||||
|
||||
const baseClass = 'collection-edit';
|
||||
@@ -26,7 +29,7 @@ const DefaultEditView = (props) => {
|
||||
const { params: { id } = {} } = useRouteMatch();
|
||||
|
||||
const {
|
||||
collection, isEditing, data, onSave, permissions, isLoading,
|
||||
collection, isEditing, data, onSave, permissions,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
@@ -66,28 +69,23 @@ const DefaultEditView = (props) => {
|
||||
<Eyebrow />
|
||||
<LeaveWithoutSaving />
|
||||
<div className={`${baseClass}__edit`}>
|
||||
{isLoading && (
|
||||
<Loading />
|
||||
)}
|
||||
{!isLoading && (
|
||||
<React.Fragment>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h1>
|
||||
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
|
||||
</h1>
|
||||
</header>
|
||||
<RenderFields
|
||||
operation={isEditing ? 'update' : 'create'}
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={(field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'))}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
initialData={data}
|
||||
customComponentsPath={`${slug}.fields.`}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<React.Fragment>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h1>
|
||||
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
|
||||
</h1>
|
||||
</header>
|
||||
<RenderFields
|
||||
operation={isEditing ? 'update' : 'create'}
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={mainFieldFilter}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
initialData={data}
|
||||
customComponentsPath={`${slug}.fields.`}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${baseClass}__sidebar`}>
|
||||
@@ -134,48 +132,46 @@ const DefaultEditView = (props) => {
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
{!isLoading && (
|
||||
<React.Fragment>
|
||||
<div className={`${baseClass}__sidebar-fields`}>
|
||||
<RenderFields
|
||||
operation={isEditing ? 'update' : 'create'}
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={(field) => field?.admin?.position === 'sidebar'}
|
||||
position="sidebar"
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
initialData={data}
|
||||
customComponentsPath={`${slug}.fields.`}
|
||||
/>
|
||||
</div>
|
||||
{isEditing && (
|
||||
<ul className={`${baseClass}__meta`}>
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>ID</div>
|
||||
<div>{id}</div>
|
||||
</li>
|
||||
{timestamps && (
|
||||
<React.Fragment>
|
||||
{data.updatedAt && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Last Modified</div>
|
||||
<div>{format(new Date(data.updatedAt), 'MMMM do yyyy, h:mma')}</div>
|
||||
</li>
|
||||
)}
|
||||
{data.createdAt && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Created</div>
|
||||
<div>{format(new Date(data.createdAt), 'MMMM do yyyy, h:mma')}</div>
|
||||
</li>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
<React.Fragment>
|
||||
<div className={`${baseClass}__sidebar-fields`}>
|
||||
<RenderFields
|
||||
operation={isEditing ? 'update' : 'create'}
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={sidebarFieldFilter}
|
||||
position="sidebar"
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
initialData={data}
|
||||
customComponentsPath={`${slug}.fields.`}
|
||||
/>
|
||||
</div>
|
||||
{isEditing && (
|
||||
<ul className={`${baseClass}__meta`}>
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>ID</div>
|
||||
<div>{id}</div>
|
||||
</li>
|
||||
{timestamps && (
|
||||
<React.Fragment>
|
||||
{data.updatedAt && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Last Modified</div>
|
||||
<div>{format(new Date(data.updatedAt), 'MMMM do yyyy, h:mma')}</div>
|
||||
</li>
|
||||
)}
|
||||
{data.createdAt && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Created</div>
|
||||
<div>{format(new Date(data.createdAt), 'MMMM do yyyy, h:mma')}</div>
|
||||
</li>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
</ul>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</React.Fragment>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
@@ -185,12 +181,10 @@ const DefaultEditView = (props) => {
|
||||
|
||||
DefaultEditView.defaultProps = {
|
||||
isEditing: false,
|
||||
isLoading: true,
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
DefaultEditView.propTypes = {
|
||||
isLoading: PropTypes.bool,
|
||||
collection: PropTypes.shape({
|
||||
labels: PropTypes.shape({
|
||||
plural: PropTypes.string,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useRouteMatch, useHistory, useLocation } from 'react-router-dom';
|
||||
import config from 'payload/config';
|
||||
@@ -6,7 +6,7 @@ import { useStepNav } from '../../../elements/StepNav';
|
||||
import usePayloadAPI from '../../../../hooks/usePayloadAPI';
|
||||
import { useUser } from '../../../data/User';
|
||||
import formatFields from './formatFields';
|
||||
|
||||
import Loading from '../../../elements/Loading';
|
||||
import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
|
||||
import DefaultEdit from './Default';
|
||||
|
||||
@@ -18,6 +18,7 @@ const EditView = (props) => {
|
||||
const history = useHistory();
|
||||
const { setStepNav } = useStepNav();
|
||||
const [fields, setFields] = useState([]);
|
||||
const [componentProps, setComponentProps] = useState(null);
|
||||
const { permissions } = useUser();
|
||||
|
||||
const { collection, isEditing } = props;
|
||||
@@ -32,7 +33,7 @@ const EditView = (props) => {
|
||||
},
|
||||
} = collection;
|
||||
|
||||
const onSave = (json) => {
|
||||
const onSave = useCallback((json) => {
|
||||
history.push(`${admin}/collections/${collection.slug}/${json?.doc?.id}`, {
|
||||
status: {
|
||||
message: json.message,
|
||||
@@ -40,7 +41,7 @@ const EditView = (props) => {
|
||||
},
|
||||
data: json.doc,
|
||||
});
|
||||
};
|
||||
}, [collection, history]);
|
||||
|
||||
const [{ data, isLoading }] = usePayloadAPI(
|
||||
(isEditing ? `${serverURL}${api}/${slug}/${id}` : null),
|
||||
@@ -74,20 +75,31 @@ const EditView = (props) => {
|
||||
|
||||
const collectionPermissions = permissions?.[slug];
|
||||
|
||||
return (
|
||||
<RenderCustomComponent
|
||||
DefaultComponent={DefaultEdit}
|
||||
path={`${slug}.views.Edit`}
|
||||
componentProps={{
|
||||
isLoading,
|
||||
data: dataToRender,
|
||||
collection: { ...collection, fields },
|
||||
permissions: collectionPermissions,
|
||||
isEditing,
|
||||
onSave,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
useEffect(() => {
|
||||
setComponentProps({
|
||||
data: dataToRender,
|
||||
collection: { ...collection, fields },
|
||||
permissions: collectionPermissions,
|
||||
isEditing,
|
||||
onSave,
|
||||
});
|
||||
}, [dataToRender, collection, fields, collectionPermissions, isEditing, onSave]);
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (componentProps) {
|
||||
return (
|
||||
<RenderCustomComponent
|
||||
DefaultComponent={DefaultEdit}
|
||||
path={`${slug}.views.Edit`}
|
||||
componentProps={componentProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
EditView.defaultProps = {
|
||||
|
||||
@@ -16,6 +16,8 @@ import Cell from './Cell';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const apiOptions = { initialParams: { depth: 0 } };
|
||||
|
||||
const { serverURL, routes: { api, admin } } = config;
|
||||
|
||||
const baseClass = 'collection-list';
|
||||
@@ -44,7 +46,7 @@ const DefaultList = (props) => {
|
||||
|
||||
const apiURL = `${serverURL}${api}/${slug}`;
|
||||
|
||||
const [{ data }, { setParams }] = usePayloadAPI(apiURL, { initialParams: { depth: 0 } });
|
||||
const [{ data }, { setParams }] = usePayloadAPI(apiURL, apiOptions);
|
||||
|
||||
useEffect(() => {
|
||||
const params = {};
|
||||
|
||||
25
yarn.lock
25
yarn.lock
@@ -875,6 +875,13 @@
|
||||
core-js-pure "^3.0.0"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.0.0":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.5.tgz#303d8bd440ecd5a491eae6117fd3367698674c5c"
|
||||
integrity sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99"
|
||||
@@ -6965,6 +6972,11 @@ media-typer@0.3.0:
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
memoize-one@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-3.1.1.tgz#ef609811e3bc28970eac2884eece64d167830d17"
|
||||
integrity sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA==
|
||||
|
||||
memoize-one@^5.0.0, memoize-one@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
|
||||
@@ -7252,11 +7264,6 @@ mongodb@3.5.9, mongodb@^3.5.4:
|
||||
optionalDependencies:
|
||||
saslprep "^1.0.0"
|
||||
|
||||
mongoose-autopopulate@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/mongoose-autopopulate/-/mongoose-autopopulate-0.11.0.tgz#9b5e9c9a36f63a39f8b205d12693e1d8a9260225"
|
||||
integrity sha512-pbL6w8Yt3KF0yxHZqP498CHelygOSCvYo6SvO0Pz7UW3Mzu4/xIDdoazwnmodDeI81dlKNvpWTS8fVKSTM8sDg==
|
||||
|
||||
mongoose-hidden@^1.8.1:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/mongoose-hidden/-/mongoose-hidden-1.9.0.tgz#6cc7c0ce6e8134885f73ea7874061e88880f8d50"
|
||||
@@ -9301,6 +9308,14 @@ react-use@^15.1.0:
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
react-window@^1.6.0-alpha.1:
|
||||
version "1.6.0-alpha.1"
|
||||
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.6.0-alpha.1.tgz#6ffbf8168a1325512fe0127582ee2672ecadb67a"
|
||||
integrity sha512-Q4Yg/rnVHTSjHdqVuTnZFTD3cwEzXFxFMyEZ5ihK3qu/NLiiFA67M1WM/Q558VmGUQumtJAW5oxKoo5JcdqoOQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
memoize-one "^3.1.1"
|
||||
|
||||
react@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||
|
||||
Reference in New Issue
Block a user