From 048b82dfed8cd977fd7e4926387086b54d0a180d Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 4 Jan 2021 16:55:46 +0000 Subject: [PATCH 01/19] feat: added location fields --- src/App.tsx | 2 +- src/components/AssetModal.tsx | 17 ++++++++--- src/components/LabelWithInput.tsx | 51 ++++++++++++++++++++++++++++++- src/types/Asset.ts | 6 ++++ 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fdb9519..e19b473 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -112,7 +112,7 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { setLoading(true); const types = tool ? '"sanity.imageAsset", "sanity.fileAsset"' : '"sanity.imageAsset"'; const newAssets: Array = await client.fetch( - `*[_type in [${types}]] { _createdAt, _id, _type, alt, extension, metadata, originalFilename, size, tags, url }`, + `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, extension, metadata, originalFilename, size, tags, url }`, {} ); setAssets(newAssets); diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 755e7ae..2fdd8dc 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -1,8 +1,8 @@ -import { Asset } from '../types/Asset'; +import { Asset, Geopoint } from '../types/Asset'; import { Button } from './Button'; import { formatDate, formatSize } from '../shared/utils'; import { Icon } from './Icon'; -import { LabelWithInput } from './LabelWithInput'; +import { LabelWithInput, LabelWithLocationInput } from './LabelWithInput'; import { Loader } from './Loader'; import { Modal } from './Modal'; import client from 'part:@sanity/base/client'; @@ -102,12 +102,13 @@ const StyledButtonsContainer = styled.div` `; export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplete, setLoading }: Props) => { - const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, size, tags, url } = asset; + const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, size, tags, url, location } = asset; const { height, width } = metadata?.dimensions || {}; const [localAlt, setLocalAlt] = useState(alt || ''); + const [localLocation, setLocalLocation] = useState(location || {}); const [localTags, setLocalTags] = useState((tags || []).join(',') || ''); - const isChanged = localAlt !== (alt || '') || localTags !== (tags?.join(',') || ''); + const isChanged = localAlt !== (alt || '') || localLocation !== (location || {}) || localTags !== (tags?.join(',') || ''); async function handleSubmit(e: FormEvent) { try { @@ -123,9 +124,10 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet } const alt = localAlt; + const location = localLocation; const tags = localTags.split(',').map((v) => v.trim()); - await client.patch(_id).set({ alt, tags }).commit(); + await client.patch(_id).set({ alt, location, tags }).commit(); onSaveComplete(); } catch (e) { handleError(e); @@ -170,6 +172,11 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet value={localAlt} /> )} + void; @@ -15,6 +15,22 @@ const StyledContainer = styled.label` width: 100%; `; +const StyledWrapper = styled.div` + cursor: pointer; + display: flex; + align-items: center; + width: 100%; + margin-bottom: 8px; + + > ${styled.span} { + font-size: 14px; + margin: 0; + } + > ${styled.input} { + margin-left: 16px; + } +`; + const StyledLabel = styled.span` color: ${({ theme }) => theme.inputLabelColor}; display: block; @@ -45,3 +61,36 @@ export const LabelWithInput = ({ label, onChange, placeholder, value = '', type onChange(e.target.value)} placeholder={placeholder} value={value} type={type} /> ); + +interface LocationProps { + label: string; + onChange: (value: (Geopoint | ((prevState: Geopoint) => Geopoint))) => void + value?: Geopoint | undefined; +} + +export const LabelWithLocationInput = ({ label, onChange, value = { lat: undefined, lng: undefined, alt: undefined } }: LocationProps) => { + const handleChange = (e: React.ChangeEvent) => { + const { name, value } = e.target + onChange(prevState => ({ + ...prevState, + [name]: parseFloat(value) + })) + } + return ( + + {label} + + Latitude + + + + Longitude + + + + Altitude + + + + ) +}; \ No newline at end of file diff --git a/src/types/Asset.ts b/src/types/Asset.ts index 18f0fe3..20e7fc1 100644 --- a/src/types/Asset.ts +++ b/src/types/Asset.ts @@ -1,5 +1,10 @@ export type AssetType = 'sanity.imageAsset' | 'sanity.fileAsset'; +export type Geopoint = { + lat?: number + lng?: number + alt?: number +} export interface Asset { _createdAt: string; _id: string; @@ -14,6 +19,7 @@ export interface Asset { }; originalFilename: string; size: number; + location?: Geopoint; tags?: Array; url: string; } From a022027666429228fc8ef6a5ea8b76ad0a5acc25 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 4 Jan 2021 17:00:04 +0000 Subject: [PATCH 02/19] fix: fixed missing key on MediaList and MediaGrid --- src/components/MediaGrid.tsx | 1 + src/components/MediaList.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/MediaGrid.tsx b/src/components/MediaGrid.tsx index 3cc1fd5..8f78064 100644 --- a/src/components/MediaGrid.tsx +++ b/src/components/MediaGrid.tsx @@ -80,6 +80,7 @@ export const MediaGrid = ({ const Element = asset._type === 'sanity.imageAsset' ? ImageItem : FileItem; return ( setIsDraggingMediaItem(false)} onDragStart={() => { diff --git a/src/components/MediaList.tsx b/src/components/MediaList.tsx index 3890316..a43b919 100644 --- a/src/components/MediaList.tsx +++ b/src/components/MediaList.tsx @@ -108,6 +108,7 @@ export const MediaList = ({ {assets.map((asset) => ( setIsDraggingMediaItem(false)} onDragStart={() => { From de55c520d8a762f5a8acd443dc6ceaef5bd2ddc6 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 4 Jan 2021 17:15:24 +0000 Subject: [PATCH 03/19] fix: added overflow to asset modal --- src/components/AssetModal.tsx | 4 ++++ src/components/LabelWithInput.tsx | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 2fdd8dc..585d1a0 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -87,6 +87,10 @@ const StyledInfoContainer = styled.div` `; const StyledInputsContainer = styled.div` + padding-right: 8px !important; + max-height: 300px; + overflow: hidden scroll; + & > :not(:last-child) { margin: 0 0 20px; } diff --git a/src/components/LabelWithInput.tsx b/src/components/LabelWithInput.tsx index b82a4cf..b7a9188 100644 --- a/src/components/LabelWithInput.tsx +++ b/src/components/LabelWithInput.tsx @@ -22,11 +22,12 @@ const StyledWrapper = styled.div` width: 100%; margin-bottom: 8px; - > ${styled.span} { + & > span { font-size: 14px; margin: 0; + opacity: 0.8; } - > ${styled.input} { + & > input { margin-left: 16px; } `; From 13f7aa6088af65ae58f025379a3eda6c7ea9b06d Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 4 Jan 2021 17:56:53 +0000 Subject: [PATCH 04/19] feat: added title editing, attribution editing and options to show/hide asset fields, updated readme --- README.md | 3 ++ src/App.tsx | 10 +++--- src/components/AssetModal.tsx | 61 ++++++++++++++++++++++++----------- src/components/MediaGrid.tsx | 5 +-- src/components/MediaList.tsx | 7 ++-- src/components/SearchBar.tsx | 2 +- src/config.ts | 12 ++++++- src/types/Asset.ts | 2 ++ 8 files changed, 73 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index a677140..c7ba8e9 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ The missing media library for Sanity. With support for filters per tag and exten - View/Edit your assets in once single place: - View asset details - Add alt tags to your image in a central place + - Add location and attribution information, change title - Grid view and list view (with more details): - Sort by latest or alphabetically - Search by alt, tag, or file name @@ -31,6 +32,8 @@ The missing media library for Sanity. With support for filters per tag and exten - Quick action: Double click an asset to trigger it's primary action - Customizable theme: - Comes with a dark and light theme, both are fully customizable. +- Customizable interface + - Hide unused asset fields ## Installation diff --git a/src/App.tsx b/src/App.tsx index e19b473..d167691 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -58,9 +58,11 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { if (searchQuery && searchQuery !== '') { newFilteredAssets = newFilteredAssets.filter( - ({ alt, originalFilename, tags }) => + ({ alt, originalFilename, title, attribution, tags }) => originalFilename.toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || + (title || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || (alt || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || + (attribution || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || (tags?.join(',') || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 ); } @@ -78,11 +80,11 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { } if (sort === 'az') { - newFilteredAssets.sort((a, b) => (a.originalFilename.localeCompare(b.originalFilename) ? -1 : 1)); + newFilteredAssets.sort((a, b) => ((a.title || a.originalFilename).localeCompare((b.title || b.originalFilename)) ? -1 : 1)); } if (sort === 'za') { - newFilteredAssets.sort((a, b) => (a.originalFilename.localeCompare(b.originalFilename) ? 1 : -1)); + newFilteredAssets.sort((a, b) => ((a.title || a.originalFilename).localeCompare((b.title || b.originalFilename)) ? 1 : -1)); } setFilteredAssets(newFilteredAssets); @@ -112,7 +114,7 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { setLoading(true); const types = tool ? '"sanity.imageAsset", "sanity.fileAsset"' : '"sanity.imageAsset"'; const newAssets: Array = await client.fetch( - `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, extension, metadata, originalFilename, size, tags, url }`, + `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, attribution, extension, metadata, originalFilename, title, size, tags, url }`, {} ); setAssets(newAssets); diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 585d1a0..6616a2c 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -5,6 +5,7 @@ import { Icon } from './Icon'; import { LabelWithInput, LabelWithLocationInput } from './LabelWithInput'; import { Loader } from './Loader'; import { Modal } from './Modal'; +import { assetFields } from '../config'; import client from 'part:@sanity/base/client'; import React, { Fragment, FormEvent, useState } from 'react'; import styled from 'styled-components'; @@ -77,7 +78,7 @@ const StyledInfoContainer = styled.div` font-size: 14px; font-weight: 400; line-height: 1.4; - +˝ & strong { color: ${({ theme }) => theme.assetModalInfoTitleColor}; display: block; @@ -106,13 +107,15 @@ const StyledButtonsContainer = styled.div` `; export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplete, setLoading }: Props) => { - const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, size, tags, url, location } = asset; + const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, title, size, tags, url, location, attribution } = asset; const { height, width } = metadata?.dimensions || {}; + const [localTitle, setLocalTitle] = useState(title || originalFilename); const [localAlt, setLocalAlt] = useState(alt || ''); + const [localAttribution, setLocalAttribution] = useState(attribution || ''); const [localLocation, setLocalLocation] = useState(location || {}); const [localTags, setLocalTags] = useState((tags || []).join(',') || ''); - const isChanged = localAlt !== (alt || '') || localLocation !== (location || {}) || localTags !== (tags?.join(',') || ''); + const isChanged = localTitle !== (title || '') || localAlt !== (alt || '') || localLocation !== (location || {}) || localAttribution !== (attribution || '') || localTags !== (tags?.join(',') || ''); async function handleSubmit(e: FormEvent) { try { @@ -127,11 +130,13 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet return onClose(); } + const title = localTitle const alt = localAlt; const location = localLocation; + const attribution = localAttribution; const tags = localTags.split(',').map((v) => v.trim()); - await client.patch(_id).set({ alt, location, tags }).commit(); + await client.patch(_id).set({ title, alt, location, attribution, tags }).commit(); onSaveComplete(); } catch (e) { handleError(e); @@ -154,8 +159,8 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet )} - {originalFilename} - {formatDate(_createdAt)} + {localTitle || originalFilename} +
{formatDate(_createdAt)}
{width && height && ( @@ -168,7 +173,15 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet - {_type === 'sanity.imageAsset' && ( + {assetFields.title && ( + + )} + {_type === 'sanity.imageAsset' && assetFields.alt && ( )} - - + {assetFields.attribution && ( + + )} + {assetFields.location && ( + + )} + {assetFields.location && ( + + )} diff --git a/src/components/MediaGrid.tsx b/src/components/MediaGrid.tsx index 8f78064..5bf50cc 100644 --- a/src/components/MediaGrid.tsx +++ b/src/components/MediaGrid.tsx @@ -96,6 +96,7 @@ export const MediaGrid = ({ onDoubleClick={() => onDoubleClick(asset)} selected={selectedAssets.findIndex(({ _id }) => _id === asset._id) > -1} {...asset} + title={asset.title || asset.originalFilename} />
); @@ -109,9 +110,9 @@ const ImageItem = ({ alt, onClick, onDoubleClick, selected, url }: MediaItemProp ); -const FileItem = ({ originalFilename, onClick, onDoubleClick, selected }: MediaItemProps) => ( +const FileItem = ({ title, onClick, onDoubleClick, selected }: MediaItemProps) => ( onClick(e)} onDoubleClick={onDoubleClick}> -
{originalFilename}
+
{title}
); diff --git a/src/components/MediaList.tsx b/src/components/MediaList.tsx index a43b919..356a498 100644 --- a/src/components/MediaList.tsx +++ b/src/components/MediaList.tsx @@ -124,6 +124,7 @@ export const MediaList = ({ onDoubleClick={() => onDoubleClick(asset)} selected={selectedAssets.findIndex(({ _id }) => _id === asset._id) > -1} {...asset} + title={asset.title || asset.originalFilename} />
))} @@ -133,7 +134,7 @@ export const MediaList = ({ const MediaListHeader = () => (
-
Filename
+
Title / Filename
Alt
Tags
Dimensions
@@ -151,7 +152,7 @@ const MediaRow = ({ metadata, onClick, onDoubleClick, - originalFilename, + title, selected, size, tags = [], @@ -172,7 +173,7 @@ const MediaRow = ({ )}
-
{originalFilename}
+
{title}
{alt}
{tags.join(', ')}
{width && height && `${width} x ${height}`}
diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 9f04297..544e9fd 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -38,7 +38,7 @@ export const SearchBar = ({ searchQuery, setSearchQuery }: Props) => ( setSearchQuery(e.target.value)} - placeholder="Search by alt, tags or filename" + placeholder="Search by title, alt, attribution, tags or filename" type="search" /> diff --git a/src/config.ts b/src/config.ts index 9cf494e..934588b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,13 @@ import config from 'config:media-library'; -export const { theme = 'dark', themeChanges = {} } = config; +export const { + theme = 'dark', + themeChanges = {}, + assetFields = { + title: true, + alt: true, + location: true, + attribution: true, + tags: true + } +} = config; diff --git a/src/types/Asset.ts b/src/types/Asset.ts index 20e7fc1..6b988cd 100644 --- a/src/types/Asset.ts +++ b/src/types/Asset.ts @@ -18,8 +18,10 @@ export interface Asset { }; }; originalFilename: string; + title?: string; size: number; location?: Geopoint; + attribution?: string; tags?: Array; url: string; } From c9ef86b3a4bce12b177911069a8e690aaaa48c49 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 5 Jan 2021 09:07:40 +0000 Subject: [PATCH 05/19] fix: toggle for showing tags field fixed --- src/components/AssetModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 6616a2c..f8d1e98 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -204,7 +204,7 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet value={localLocation} /> )} - {assetFields.location && ( + {assetFields.tags && ( Date: Tue, 5 Jan 2021 13:23:43 +0000 Subject: [PATCH 06/19] feat: added custom fields --- src/App.tsx | 2 +- src/components/AssetModal.tsx | 40 ++++++++++++++--- src/components/LabelWithInput.tsx | 71 +++++++++++++++++++++++++------ src/config.ts | 3 +- src/types/Asset.ts | 5 +++ 5 files changed, 101 insertions(+), 20 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d167691..fb6f6ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -114,7 +114,7 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { setLoading(true); const types = tool ? '"sanity.imageAsset", "sanity.fileAsset"' : '"sanity.imageAsset"'; const newAssets: Array = await client.fetch( - `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, attribution, extension, metadata, originalFilename, title, size, tags, url }`, + `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, attribution, extension, metadata, originalFilename, title, size, tags, url, attributes }`, {} ); setAssets(newAssets); diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index f8d1e98..1823aa0 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -1,11 +1,11 @@ -import { Asset, Geopoint } from '../types/Asset'; +import { Asset, Geopoint, Attributes } from '../types/Asset'; import { Button } from './Button'; import { formatDate, formatSize } from '../shared/utils'; import { Icon } from './Icon'; -import { LabelWithInput, LabelWithLocationInput } from './LabelWithInput'; +import { LabelWithInput, LabelWithLocationInput, LabelWithCheckbox, LabelWithNumericalInput } from './LabelWithInput'; import { Loader } from './Loader'; import { Modal } from './Modal'; -import { assetFields } from '../config'; +import { assetFields, customAssetFields } from '../config'; import client from 'part:@sanity/base/client'; import React, { Fragment, FormEvent, useState } from 'react'; import styled from 'styled-components'; @@ -19,6 +19,16 @@ interface Props { setLoading: (value: Boolean) => void; } +type CustomAssetField = { + name: string + label: string + placeholder?: string + type: 'text' | 'checkbox' | 'number' | 'textarea'; + min?: number + max?: number + step?: number | 'any' +} + const StyledFormContainer = styled.form` & > :not(:last-child) { border-bottom: solid 1px ${({ theme }) => theme.assetModalBorderColor}; @@ -107,15 +117,16 @@ const StyledButtonsContainer = styled.div` `; export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplete, setLoading }: Props) => { - const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, title, size, tags, url, location, attribution } = asset; + const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, title, size, tags, url, location, attribution, attributes } = asset; const { height, width } = metadata?.dimensions || {}; const [localTitle, setLocalTitle] = useState(title || originalFilename); const [localAlt, setLocalAlt] = useState(alt || ''); const [localAttribution, setLocalAttribution] = useState(attribution || ''); const [localLocation, setLocalLocation] = useState(location || {}); const [localTags, setLocalTags] = useState((tags || []).join(',') || ''); + const [localAttributes, setLocalAttributes] = useState(attributes || {}); - const isChanged = localTitle !== (title || '') || localAlt !== (alt || '') || localLocation !== (location || {}) || localAttribution !== (attribution || '') || localTags !== (tags?.join(',') || ''); + const isChanged = localTitle !== (title || '') || localAlt !== (alt || '') || localLocation !== (location || {}) || localAttribution !== (attribution || '') || localTags !== (tags?.join(',') || '') || localAttributes !== (attributes || {}); async function handleSubmit(e: FormEvent) { try { @@ -134,9 +145,10 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet const alt = localAlt; const location = localLocation; const attribution = localAttribution; + const attributes = localAttributes; const tags = localTags.split(',').map((v) => v.trim()); - await client.patch(_id).set({ title, alt, location, attribution, tags }).commit(); + await client.patch(_id).set({ title, alt, location, attribution, tags, attributes }).commit(); onSaveComplete(); } catch (e) { handleError(e); @@ -145,6 +157,21 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet } } + function renderAttributes(attribute: CustomAssetField) { + const handleChange = (value: any) => setLocalAttributes(prevState => ({ + ...prevState, + [attribute.name]: attribute.type === 'number' && value ? parseFloat(value) : value + })) + switch(attribute.type) { + case 'checkbox': + return ; + case 'number': + return ; + default: + return ; + } + } + return ( @@ -212,6 +239,7 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet value={localTags} /> )} + {customAssetFields.map((field: CustomAssetField) => renderAttributes(field))} diff --git a/src/components/LabelWithInput.tsx b/src/components/LabelWithInput.tsx index b7a9188..85f17ea 100644 --- a/src/components/LabelWithInput.tsx +++ b/src/components/LabelWithInput.tsx @@ -1,13 +1,30 @@ import React from 'react'; import { Geopoint } from 'src/types/Asset'; import styled from 'styled-components'; + interface Props { label: string; - onChange: (value: string) => void; placeholder?: string; - type?: 'text'; - value?: string | number | readonly string[] | undefined; + onChange: (value: any) => void; + value?: string | number | boolean | readonly string[] | undefined; +} +interface PropsText extends Props { + type?: 'text' | 'textarea'; + onChange: (value: string) => void; + value?: string | readonly string[] | undefined; +} +interface PropsNumber extends Props { + onChange: (value: number) => void; + value?: number; + max?: number; + min?: number; + step?: number | 'any'; } +interface PropsCheckbox extends Props { + onChange: (value: boolean) => void; + value?: boolean | undefined; +} + const StyledContainer = styled.label` cursor: pointer; @@ -15,11 +32,16 @@ const StyledContainer = styled.label` width: 100%; `; -const StyledWrapper = styled.div` - cursor: pointer; +const StyledContainerRow = styled(StyledContainer)` display: flex; align-items: center; - width: 100%; + + & > input { + margin-left: 16px; + } +`; + +const StyledWrapper = styled(StyledContainerRow)` margin-bottom: 8px; & > span { @@ -27,9 +49,6 @@ const StyledWrapper = styled.div` margin: 0; opacity: 0.8; } - & > input { - margin-left: 16px; - } `; const StyledLabel = styled.span` @@ -56,12 +75,40 @@ const StyledInput = styled.input` width: 100%; `; -export const LabelWithInput = ({ label, onChange, placeholder, value = '', type = 'text' }: Props) => ( +const StyledTextarea = styled.textarea` + background-color: ${({ theme }) => theme.inputBackgroundColor}; + border-radius: ${({ theme }) => theme.appBorderRadius}; + border: 0; + color: ${({ theme }) => theme.inputTextColor}; + font-family: ${({ theme }) => theme.appFontFamily}; + font-size: 16px; + line-height: 1.1; + outline: 0; + padding: 16px; + width: 100%; +`; + +export const LabelWithInput = ({ label, onChange, placeholder, value = '', type = 'text'}: PropsText) => ( {label} - onChange(e.target.value)} placeholder={placeholder} value={value} type={type} /> + {type === 'textarea' + ? onChange(e.target.value)} value={value} placeholder={placeholder} /> + : onChange(e.target.value)} placeholder={placeholder} value={value} type={type} /> + } ); +export const LabelWithNumericalInput = ({ label, onChange, placeholder, value, min, max, step}: PropsNumber) => ( + + {label} + onChange(parseFloat(e.target.value))} placeholder={placeholder} value={value} type='number' min={min} max={max} step={step}/> + +); +export const LabelWithCheckbox = ({ label, onChange, value = undefined }: PropsCheckbox) => ( + + {label} + onChange(e.target.checked)} checked={value} type='checkbox' /> + +); interface LocationProps { label: string; @@ -78,7 +125,7 @@ export const LabelWithLocationInput = ({ label, onChange, value = { lat: undefin })) } return ( - + {label} Latitude diff --git a/src/config.ts b/src/config.ts index 934588b..36429e3 100644 --- a/src/config.ts +++ b/src/config.ts @@ -9,5 +9,6 @@ export const { location: true, attribution: true, tags: true - } + }, + customAssetFields = [] } = config; diff --git a/src/types/Asset.ts b/src/types/Asset.ts index 6b988cd..e2ae956 100644 --- a/src/types/Asset.ts +++ b/src/types/Asset.ts @@ -5,6 +5,10 @@ export type Geopoint = { lng?: number alt?: number } + +export type Attributes = { + [_id: string]: string | boolean | number | undefined +} export interface Asset { _createdAt: string; _id: string; @@ -24,4 +28,5 @@ export interface Asset { attribution?: string; tags?: Array; url: string; + attributes: Attributes } From d2bebc672b4417ed3ddbb4fa1bd2b33a222a18b0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 5 Jan 2021 13:32:54 +0000 Subject: [PATCH 07/19] chore: updated readme --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index c7ba8e9..f9315e8 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The missing media library for Sanity. With support for filters per tag and exten - Customizable theme: - Comes with a dark and light theme, both are fully customizable. - Customizable interface + - Define custom fields (text, number, checkbox, textarea are currently supported) - Hide unused asset fields ## Installation @@ -115,6 +116,41 @@ Example with themeChanges: } ``` +Example with asset fields listed and custom fields added: +```json +{ + "theme": "dark", + "themeChanges": {}, + "assetFields": { + title: true, + alt: true, + location: true, + attribution: true, + tags: true + }, + "customAssetFields": [ + { + "name": "description", + "label": "Additional description", + "type": "textarea" + }, + { + "name": "decade", + "label": "Decade when photo captured", + "type": "number", + "min": 1800, + "max": 2200, + "step": 10 + }, + { + "name": "premiumPhoto", + "label": "Is a premium photo", + "type": "checkbox" + } + ] +} +``` + ## Roadmap - Improve the tag input in AssetModal From c7285855cd1cd526374b47caf480f90c0635409d Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 5 Jan 2021 13:33:17 +0000 Subject: [PATCH 08/19] feat: changed alt text input to textarea --- src/components/AssetModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 1823aa0..57a9d77 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -214,6 +214,7 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet onChange={setLocalAlt} placeholder={!localAlt ? 'No alt text yet...' : undefined} value={localAlt} + type="textarea" /> )} {assetFields.attribution && ( From 1c10564d79981dbda749baf89b55cd46e6f15674 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 5 Jan 2021 14:09:01 +0000 Subject: [PATCH 09/19] fix: removed duplicate parseFloat --- src/components/AssetModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 57a9d77..26731e8 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -160,7 +160,7 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet function renderAttributes(attribute: CustomAssetField) { const handleChange = (value: any) => setLocalAttributes(prevState => ({ ...prevState, - [attribute.name]: attribute.type === 'number' && value ? parseFloat(value) : value + [attribute.name]: value })) switch(attribute.type) { case 'checkbox': From fbf09d005d8ba1ff1441190257f14bcefbbfa9c0 Mon Sep 17 00:00:00 2001 From: Andrew Grant Date: Wed, 13 Jan 2021 10:27:26 +0000 Subject: [PATCH 10/19] fix: typo --- src/components/AssetModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 26731e8..803d7a6 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -88,7 +88,7 @@ const StyledInfoContainer = styled.div` font-size: 14px; font-weight: 400; line-height: 1.4; -˝ + & strong { color: ${({ theme }) => theme.assetModalInfoTitleColor}; display: block; From 2c43d5f3b06299530ee3948e3e3f1e8c3a1fe446 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Thu, 14 Jan 2021 15:52:33 +0100 Subject: [PATCH 11/19] Move asset title | originalFileName to item --- src/components/MediaGrid.tsx | 5 ++--- src/components/MediaList.tsx | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/MediaGrid.tsx b/src/components/MediaGrid.tsx index 5bf50cc..2c76ec6 100644 --- a/src/components/MediaGrid.tsx +++ b/src/components/MediaGrid.tsx @@ -96,7 +96,6 @@ export const MediaGrid = ({ onDoubleClick={() => onDoubleClick(asset)} selected={selectedAssets.findIndex(({ _id }) => _id === asset._id) > -1} {...asset} - title={asset.title || asset.originalFilename} /> ); @@ -110,9 +109,9 @@ const ImageItem = ({ alt, onClick, onDoubleClick, selected, url }: MediaItemProp ); -const FileItem = ({ title, onClick, onDoubleClick, selected }: MediaItemProps) => ( +const FileItem = ({ title, originalFilename, onClick, onDoubleClick, selected }: MediaItemProps) => ( onClick(e)} onDoubleClick={onDoubleClick}> -
{title}
+
{title || originalFilename}
); diff --git a/src/components/MediaList.tsx b/src/components/MediaList.tsx index 356a498..d0fc7d5 100644 --- a/src/components/MediaList.tsx +++ b/src/components/MediaList.tsx @@ -124,7 +124,6 @@ export const MediaList = ({ onDoubleClick={() => onDoubleClick(asset)} selected={selectedAssets.findIndex(({ _id }) => _id === asset._id) > -1} {...asset} - title={asset.title || asset.originalFilename} /> ))} @@ -152,10 +151,11 @@ const MediaRow = ({ metadata, onClick, onDoubleClick, - title, + originalFilename, selected, size, tags = [], + title, url, }: MediaRowProps) => { const { height, width } = metadata?.dimensions || {}; @@ -173,7 +173,7 @@ const MediaRow = ({ )} -
{title}
+
{title || originalFilename}
{alt}
{tags.join(', ')}
{width && height && `${width} x ${height}`}
From dde0af9b5bce24ef037827319715d4999680864c Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Thu, 14 Jan 2021 15:53:11 +0100 Subject: [PATCH 12/19] Update searchbar message --- src/components/SearchBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 544e9fd..d65b505 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -38,7 +38,7 @@ export const SearchBar = ({ searchQuery, setSearchQuery }: Props) => ( setSearchQuery(e.target.value)} - placeholder="Search by title, alt, attribution, tags or filename" + placeholder="Search by filename, title, alt or tag" type="search" />
From add035b2a254458f6d45696ac1612032f0bef3b6 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Thu, 14 Jan 2021 15:53:43 +0100 Subject: [PATCH 13/19] Refactor to use customFields --- src/App.tsx | 43 ++++++--- src/components/AssetModal.tsx | 127 ++++++++----------------- src/components/LabelWithInput.tsx | 153 +++++++++++++++--------------- src/config.ts | 13 +-- src/types/Asset.ts | 11 +-- 5 files changed, 150 insertions(+), 197 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fb6f6ef..9f61af9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import { acceptedFileTypes } from './shared/acceptedFileTypes'; import { Asset } from './types/Asset'; import { AssetModal } from './components/AssetModal'; +import { customFields } from './config'; import { DeleteModal } from './components/DeleteModal'; import { ErrorNotifications } from './components/ErrorNotifications'; import { MediaLibrary } from './components/MediaLibrary'; @@ -57,13 +58,10 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { let newFilteredAssets = [...assets]; if (searchQuery && searchQuery !== '') { - newFilteredAssets = newFilteredAssets.filter( - ({ alt, originalFilename, title, attribution, tags }) => - originalFilename.toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || - (title || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || - (alt || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || - (attribution || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 || - (tags?.join(',') || '').toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 + newFilteredAssets = newFilteredAssets.filter(({ alt = '', originalFilename = '', title = '', tags = [] }) => + [originalFilename, title, alt, tags.join('')].some( + (value) => value.toUpperCase().indexOf(searchQuery.toUpperCase()) > -1 + ) ); } @@ -80,11 +78,15 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { } if (sort === 'az') { - newFilteredAssets.sort((a, b) => ((a.title || a.originalFilename).localeCompare((b.title || b.originalFilename)) ? -1 : 1)); + newFilteredAssets.sort((a, b) => + (a.title || a.originalFilename).localeCompare(b.title || b.originalFilename) ? -1 : 1 + ); } if (sort === 'za') { - newFilteredAssets.sort((a, b) => ((a.title || a.originalFilename).localeCompare((b.title || b.originalFilename)) ? 1 : -1)); + newFilteredAssets.sort((a, b) => + (a.title || a.originalFilename).localeCompare(b.title || b.originalFilename) ? 1 : -1 + ); } setFilteredAssets(newFilteredAssets); @@ -113,10 +115,25 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { try { setLoading(true); const types = tool ? '"sanity.imageAsset", "sanity.fileAsset"' : '"sanity.imageAsset"'; - const newAssets: Array = await client.fetch( - `*[_type in [${types}]] { _createdAt, _id, _type, alt, location, attribution, extension, metadata, originalFilename, title, size, tags, url, attributes }`, - {} - ); + const includedFields = [ + '_createdAt', + '_id', + '_type', + 'alt', + 'extension', + 'metadata', + 'originalFilename', + 'title', + 'size', + 'tags', + 'url', + ...customFields.map(({ name }: { name: string }) => name), + ]; + + const newAssets: Array = await client.fetch(`*[_type in [${types}]] { ${includedFields.join(',')} }`, {}); + + console.log(newAssets); + setAssets(newAssets); } catch (e) { handleError(e); diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 803d7a6..5b4acb3 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -1,11 +1,11 @@ -import { Asset, Geopoint, Attributes } from '../types/Asset'; +import { Asset } from '../types/Asset'; import { Button } from './Button'; +import { customFields } from '../config'; import { formatDate, formatSize } from '../shared/utils'; import { Icon } from './Icon'; -import { LabelWithInput, LabelWithLocationInput, LabelWithCheckbox, LabelWithNumericalInput } from './LabelWithInput'; +import { LabelWithInput } from './LabelWithInput'; import { Loader } from './Loader'; import { Modal } from './Modal'; -import { assetFields, customAssetFields } from '../config'; import client from 'part:@sanity/base/client'; import React, { Fragment, FormEvent, useState } from 'react'; import styled from 'styled-components'; @@ -19,16 +19,6 @@ interface Props { setLoading: (value: Boolean) => void; } -type CustomAssetField = { - name: string - label: string - placeholder?: string - type: 'text' | 'checkbox' | 'number' | 'textarea'; - min?: number - max?: number - step?: number | 'any' -} - const StyledFormContainer = styled.form` & > :not(:last-child) { border-bottom: solid 1px ${({ theme }) => theme.assetModalBorderColor}; @@ -117,38 +107,50 @@ const StyledButtonsContainer = styled.div` `; export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplete, setLoading }: Props) => { - const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, title, size, tags, url, location, attribution, attributes } = asset; + const { _createdAt, _id, _type, alt, extension, metadata, originalFilename, size, tags, title, url } = asset; const { height, width } = metadata?.dimensions || {}; - const [localTitle, setLocalTitle] = useState(title || originalFilename); - const [localAlt, setLocalAlt] = useState(alt || ''); - const [localAttribution, setLocalAttribution] = useState(attribution || ''); - const [localLocation, setLocalLocation] = useState(location || {}); - const [localTags, setLocalTags] = useState((tags || []).join(',') || ''); - const [localAttributes, setLocalAttributes] = useState(attributes || {}); + const [localValues, setLocalValues] = useState<{ [key: string]: any }>({ + alt, + tags: tags?.join(','), + title, + }); + + const inputFields = [ + { name: 'title', label: 'Title', placeholder: 'No title yet' }, + { name: 'alt', label: 'Alt text', placeholder: 'No alt text yet' }, + { name: 'tags', label: 'Tags', placeholder: 'No tags yet' }, + ...customFields, + ]; + + const isChanged = Object.entries(localValues).some(([key, newValue]) => { + const currentValue = asset[key]; + + if (newValue === '' && typeof currentValue === 'undefined') { + return false; + } - const isChanged = localTitle !== (title || '') || localAlt !== (alt || '') || localLocation !== (location || {}) || localAttribution !== (attribution || '') || localTags !== (tags?.join(',') || '') || localAttributes !== (attributes || {}); + return newValue !== currentValue; + }); async function handleSubmit(e: FormEvent) { try { + e.preventDefault(); + if (loading) { return; } setLoading(true); - e.preventDefault(); if (!isChanged) { return onClose(); } - const title = localTitle - const alt = localAlt; - const location = localLocation; - const attribution = localAttribution; - const attributes = localAttributes; - const tags = localTags.split(',').map((v) => v.trim()); - - await client.patch(_id).set({ title, alt, location, attribution, tags, attributes }).commit(); + const tags = localValues.tags?.split(',').map((v: string) => v.trim()); + await client + .patch(_id) + .set({ ...localValues, tags }) + .commit(); onSaveComplete(); } catch (e) { handleError(e); @@ -157,21 +159,6 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet } } - function renderAttributes(attribute: CustomAssetField) { - const handleChange = (value: any) => setLocalAttributes(prevState => ({ - ...prevState, - [attribute.name]: value - })) - switch(attribute.type) { - case 'checkbox': - return ; - case 'number': - return ; - default: - return ; - } - } - return ( @@ -186,8 +173,9 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet )} - {localTitle || originalFilename} -
{formatDate(_createdAt)} + {localValues.title || originalFilename} +
+ {formatDate(_createdAt)}
{width && height && ( @@ -200,47 +188,14 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet - {assetFields.title && ( - - )} - {_type === 'sanity.imageAsset' && assetFields.alt && ( - - )} - {assetFields.attribution && ( - - )} - {assetFields.location && ( - - )} - {assetFields.tags && ( + {inputFields.map(({ name, ...rest }) => ( setLocalValues({ ...localValues, [name]: value })} + value={localValues[name]} + {...rest} /> - )} - {customAssetFields.map((field: CustomAssetField) => renderAttributes(field))} + ))} diff --git a/src/components/LabelWithInput.tsx b/src/components/LabelWithInput.tsx index 85f17ea..d060f60 100644 --- a/src/components/LabelWithInput.tsx +++ b/src/components/LabelWithInput.tsx @@ -1,30 +1,25 @@ -import React from 'react'; -import { Geopoint } from 'src/types/Asset'; +import { Geopoint } from '../types/Asset'; +import React, { ChangeEvent } from 'react'; import styled from 'styled-components'; interface Props { label: string; - placeholder?: string; onChange: (value: any) => void; + placeholder?: string; + type?: + | 'checkbox' + | 'color' + | 'date' + | 'datetime-local' + | 'email' + | 'location' + | 'number' + | 'tel' + | 'text' + | 'time' + | 'url'; value?: string | number | boolean | readonly string[] | undefined; } -interface PropsText extends Props { - type?: 'text' | 'textarea'; - onChange: (value: string) => void; - value?: string | readonly string[] | undefined; -} -interface PropsNumber extends Props { - onChange: (value: number) => void; - value?: number; - max?: number; - min?: number; - step?: number | 'any'; -} -interface PropsCheckbox extends Props { - onChange: (value: boolean) => void; - value?: boolean | undefined; -} - const StyledContainer = styled.label` cursor: pointer; @@ -32,17 +27,16 @@ const StyledContainer = styled.label` width: 100%; `; -const StyledContainerRow = styled(StyledContainer)` - display: flex; +const StyledWrapper = styled.div` align-items: center; + cursor: pointer; + display: flex; + margin-bottom: 8px; + width: 100%; & > input { margin-left: 16px; } -`; - -const StyledWrapper = styled(StyledContainerRow)` - margin-bottom: 8px; & > span { font-size: 14px; @@ -75,7 +69,7 @@ const StyledInput = styled.input` width: 100%; `; -const StyledTextarea = styled.textarea` +const StyledTextArea = styled.textarea` background-color: ${({ theme }) => theme.inputBackgroundColor}; border-radius: ${({ theme }) => theme.appBorderRadius}; border: 0; @@ -85,60 +79,65 @@ const StyledTextarea = styled.textarea` line-height: 1.1; outline: 0; padding: 16px; + resize: vertical; + rows: 2; width: 100%; `; -export const LabelWithInput = ({ label, onChange, placeholder, value = '', type = 'text'}: PropsText) => ( - - {label} - {type === 'textarea' - ? onChange(e.target.value)} value={value} placeholder={placeholder} /> - : onChange(e.target.value)} placeholder={placeholder} value={value} type={type} /> - } - -); -export const LabelWithNumericalInput = ({ label, onChange, placeholder, value, min, max, step}: PropsNumber) => ( - - {label} - onChange(parseFloat(e.target.value))} placeholder={placeholder} value={value} type='number' min={min} max={max} step={step}/> - -); -export const LabelWithCheckbox = ({ label, onChange, value = undefined }: PropsCheckbox) => ( - - {label} - onChange(e.target.checked)} checked={value} type='checkbox' /> - -); - -interface LocationProps { - label: string; - onChange: (value: (Geopoint | ((prevState: Geopoint) => Geopoint))) => void - value?: Geopoint | undefined; -} +export const LabelWithInput = ({ label, onChange, type = 'text', ...rest }: Props) => { + const elementsMap: { [key: string]: any } = { + checkbox: Checkbox, + location: Location, + textArea: StyledTextArea, + }; + + const onChangeMap: { [key: string]: (e: any) => void } = { + checkbox: (e: ChangeEvent) => onChange(e.target.checked), + location: (value: Geopoint | undefined) => onChange(value), + number: (e: ChangeEvent) => onChange(parseFloat(e.target.value)), + }; + + const defaultOnChange = (e: ChangeEvent) => onChange(e.target.value); + const handleOnChange = onChangeMap[type] || defaultOnChange; + const Element = elementsMap[type] || StyledInput; -export const LabelWithLocationInput = ({ label, onChange, value = { lat: undefined, lng: undefined, alt: undefined } }: LocationProps) => { - const handleChange = (e: React.ChangeEvent) => { - const { name, value } = e.target - onChange(prevState => ({ - ...prevState, - [name]: parseFloat(value) - })) - } return ( - + {label} - - Latitude - - - - Longitude - - - - Altitude - - + + + ); +}; + +const Checkbox = ({ value, ...rest }: { value: boolean | undefined }) => ; + +const Location = ({ + onChange, + value = {}, + ...rest +}: { + onChange: (value: Geopoint | ((prevState: Geopoint) => Geopoint)) => void; + value?: Geopoint | undefined; +}) => { + const fields: Array<{ label: string; name: keyof Geopoint; type: string; step: string }> = [ + { label: 'Latitude', name: 'lat', type: 'number', step: 'any' }, + { label: 'Longitude', name: 'lng', type: 'number', step: 'any' }, + { label: 'Altitude', name: 'alt', type: 'number', step: 'any' }, + ]; + + const handleInputchange = (e: ChangeEvent) => { + console.log(value, e.target.name, e.target.value); + onChange({ ...(value || {}), [e.target.name]: parseFloat(e.target.value) }); + }; + + return ( + + {fields.map(({ label, name, ...rest }: { label: string; name: keyof Geopoint }) => ( + + {label} + + + ))} - ) -}; \ No newline at end of file + ); +}; diff --git a/src/config.ts b/src/config.ts index 36429e3..1bff906 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,14 +1,3 @@ import config from 'config:media-library'; -export const { - theme = 'dark', - themeChanges = {}, - assetFields = { - title: true, - alt: true, - location: true, - attribution: true, - tags: true - }, - customAssetFields = [] -} = config; +export const { theme = 'dark', themeChanges = {}, customFields = [] } = config; diff --git a/src/types/Asset.ts b/src/types/Asset.ts index e2ae956..0f577e7 100644 --- a/src/types/Asset.ts +++ b/src/types/Asset.ts @@ -1,14 +1,7 @@ export type AssetType = 'sanity.imageAsset' | 'sanity.fileAsset'; -export type Geopoint = { - lat?: number - lng?: number - alt?: number -} +export type Geopoint = { alt?: number; lat?: number; lng?: number }; -export type Attributes = { - [_id: string]: string | boolean | number | undefined -} export interface Asset { _createdAt: string; _id: string; @@ -28,5 +21,5 @@ export interface Asset { attribution?: string; tags?: Array; url: string; - attributes: Attributes + [key: string]: any; } From b15eab38e6936fc38c4f876045274d857187de41 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Thu, 14 Jan 2021 15:53:45 +0100 Subject: [PATCH 14/19] Update README --- README.md | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index f9315e8..7daf9d3 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The missing media library for Sanity. With support for filters per tag and exten - View/Edit your assets in once single place: - View asset details - Add alt tags to your image in a central place - - Add location and attribution information, change title + - Easily add custom fields to your assets (like location and attribution) - Grid view and list view (with more details): - Sort by latest or alphabetically - Search by alt, tag, or file name @@ -30,11 +30,10 @@ The missing media library for Sanity. With support for filters per tag and exten - Asset source: - Use it where it's useful: select images with the media library in your documents - Quick action: Double click an asset to trigger it's primary action +- Customizable fields + - Define custom fields for your assets (text, number, checkbox, textarea) - Customizable theme: - Comes with a dark and light theme, both are fully customizable. -- Customizable interface - - Define custom fields (text, number, checkbox, textarea are currently supported) - - Hide unused asset fields ## Installation @@ -121,39 +120,41 @@ Example with asset fields listed and custom fields added: { "theme": "dark", "themeChanges": {}, - "assetFields": { - title: true, - alt: true, - location: true, - attribution: true, - tags: true - }, - "customAssetFields": [ + "customFields": [ { - "name": "description", "label": "Additional description", + "name": "description", + "placeholder": "No description yet...", "type": "textarea" }, { - "name": "decade", "label": "Decade when photo captured", - "type": "number", - "min": 1800, "max": 2200, - "step": 10 + "min": 1800, + "name": "decade", + "placeholder": "Between 1800 and 2200", + "step": 10, + "type": "number" }, { - "name": "premiumPhoto", "label": "Is a premium photo", + "name": "premiumPhoto", "type": "checkbox" + }, + { + "label": "Attribution", + "name": "attribution", + "placeholder": "No attribution yet" + }, + { + "name": "location", + "label": "Location", + "type": "location" } - ] + ], } ``` -## Roadmap -- Improve the tag input in AssetModal - ## Contributing To contribute a theme, add it in `themes/[themename].ts`. -If you run into problems or have feature requests, please create an issue or pull request and I'll look into it as soon as I can. \ No newline at end of file +If you run into problems or have feature requests, please create an issue or pull request and I'll look into it as soon as I can. From ff4b92c8055417f837daa0ceffd5dbe08b26ab34 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Mon, 18 Jan 2021 09:41:04 +0100 Subject: [PATCH 15/19] Remove console.logs --- src/App.tsx | 3 --- src/components/LabelWithInput.tsx | 1 - 2 files changed, 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9f61af9..abb3cb1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -131,9 +131,6 @@ export const App = ({ onClose, onSelect, selectedAssets, tool }: Props) => { ]; const newAssets: Array = await client.fetch(`*[_type in [${types}]] { ${includedFields.join(',')} }`, {}); - - console.log(newAssets); - setAssets(newAssets); } catch (e) { handleError(e); diff --git a/src/components/LabelWithInput.tsx b/src/components/LabelWithInput.tsx index d060f60..2d634dc 100644 --- a/src/components/LabelWithInput.tsx +++ b/src/components/LabelWithInput.tsx @@ -126,7 +126,6 @@ const Location = ({ ]; const handleInputchange = (e: ChangeEvent) => { - console.log(value, e.target.name, e.target.value); onChange({ ...(value || {}), [e.target.name]: parseFloat(e.target.value) }); }; From 4818b95fbb81ff7e53340a05c09ea6d563c274c5 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Mon, 18 Jan 2021 09:41:22 +0100 Subject: [PATCH 16/19] Rename Ttile / Filename to Title --- src/components/MediaList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MediaList.tsx b/src/components/MediaList.tsx index d0fc7d5..9f629db 100644 --- a/src/components/MediaList.tsx +++ b/src/components/MediaList.tsx @@ -133,7 +133,7 @@ export const MediaList = ({ const MediaListHeader = () => (
-
Title / Filename
+
Title
Alt
Tags
Dimensions
From 5d3406f2b315fdafc0790c39ec76de5716d6cb44 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Mon, 18 Jan 2021 09:48:20 +0100 Subject: [PATCH 17/19] Add Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3ab794b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +## 1.0.3 + +- Add support for `customFields` in config object. +- Add multiple input field options \ No newline at end of file From 420c95cc636853640ce98b45931612769feabbf3 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Mon, 18 Jan 2021 09:49:00 +0100 Subject: [PATCH 18/19] Upgrade dependencies --- package.json | 6 +- yarn.lock | 304 +++++++++++++++++++++++---------------------------- 2 files changed, 142 insertions(+), 168 deletions(-) diff --git a/package.json b/package.json index ec12258..8175211 100644 --- a/package.json +++ b/package.json @@ -37,15 +37,15 @@ "@babel/cli": "7.12.10", "@babel/core": "7.12.10", "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/preset-env": "^7.12.10", + "@babel/preset-env": "^7.12.11", "@babel/preset-react": "7.12.10", "@babel/preset-typescript": "7.12.7", "@types/react": "17.0.0", - "@types/styled-components": "^5.1.5", + "@types/styled-components": "^5.1.7", "babel-plugin-styled-components": "^1.12.0", "prettier": "^2.2.1", "rimraf": "^3.0.2", - "typescript": "4.1.2" + "typescript": "4.1.3" }, "peerDependencies": { "@sanity/base": ">= 2.0.2", diff --git a/yarn.lock b/yarn.lock index 5f791da..1518c3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,10 +19,10 @@ "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents" chokidar "^3.4.0" -"@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" @@ -52,12 +52,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.10.tgz#2b188fc329fb8e4f762181703beffc0fe6df3460" - integrity sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww== +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.11" jsesc "^2.5.1" source-map "^0.5.0" @@ -76,23 +76,6 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx-experimental@^7.12.10", "@babel/helper-builder-react-jsx-experimental@^7.12.4": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.12.10.tgz#a58cb96a793dc0fcd5c9ed3bb36d62fdc60534c2" - integrity sha512-3Kcr2LGpL7CTRDTTYm1bzeor9qZbxbvU2AxsLA6mUG9gYarSfIKMK0UlU+azLWI+s0+BH768bwyaziWB2NOJlQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.10" - "@babel/helper-module-imports" "^7.12.5" - "@babel/types" "^7.12.10" - -"@babel/helper-builder-react-jsx@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" - integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/types" "^7.10.4" - "@babel/helper-compilation-targets@^7.12.5": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" @@ -138,16 +121,16 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== +"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" + integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-get-function-arity" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/types" "^7.12.11" -"@babel/helper-get-function-arity@^7.10.4": +"@babel/helper-get-function-arity@^7.12.10": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== @@ -161,7 +144,7 @@ dependencies: "@babel/types" "^7.10.4" -"@babel/helper-member-expression-to-functions@^7.12.1": +"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== @@ -190,7 +173,7 @@ "@babel/types" "^7.12.1" lodash "^4.17.19" -"@babel/helper-optimise-call-expression@^7.10.4": +"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== @@ -212,14 +195,14 @@ "@babel/types" "^7.12.1" "@babel/helper-replace-supers@^7.12.1": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz#f009a17543bbbbce16b06206ae73b63d3fca68d9" - integrity sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA== + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" + integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.12.5" - "@babel/types" "^7.12.5" + "@babel/helper-member-expression-to-functions" "^7.12.7" + "@babel/helper-optimise-call-expression" "^7.12.10" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.11" "@babel/helper-simple-access@^7.12.1": version "7.12.1" @@ -235,22 +218,22 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" + integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.11" -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== -"@babel/helper-validator-option@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" - integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== +"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" + integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== "@babel/helper-wrap-function@^7.10.4": version "7.12.3" @@ -280,15 +263,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.10", "@babel/parser@^7.12.7": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.10.tgz#824600d59e96aea26a5a2af5a9d812af05c3ae81" - integrity sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA== +"@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== "@babel/plugin-proposal-async-generator-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" - integrity sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A== + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566" + integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-remap-async-to-generator" "^7.12.1" @@ -513,10 +496,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" - integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== +"@babel/plugin-transform-block-scoping@^7.12.11": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" + integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" @@ -682,23 +665,22 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-react-jsx-development@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.7.tgz#4c2a647de79c7e2b16bfe4540677ba3121e82a08" - integrity sha512-Rs3ETtMtR3VLXFeYRChle5SsP/P9Jp/6dsewBQfokDSzKJThlsuFcnzLTDRALiUmTC48ej19YD9uN1mupEeEDg== + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz#bccca33108fe99d95d7f9e82046bfe762e71f4e7" + integrity sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg== dependencies: - "@babel/helper-builder-react-jsx-experimental" "^7.12.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.12.1" + "@babel/plugin-transform-react-jsx" "^7.12.12" -"@babel/plugin-transform-react-jsx@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.10.tgz#a7af3097c73479123594c8c8fe39545abebd44e3" - integrity sha512-MM7/BC8QdHXM7Qc1wdnuk73R4gbuOpfrSUgfV/nODGc86sPY1tgmY2M9E9uAnf2e4DOIp8aKGWqgZfQxnTNGuw== +"@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.12.12": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz#b0da51ffe5f34b9a900e9f1f5fb814f9e512d25e" + integrity sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw== dependencies: - "@babel/helper-builder-react-jsx" "^7.10.4" - "@babel/helper-builder-react-jsx-experimental" "^7.12.10" + "@babel/helper-annotate-as-pure" "^7.12.10" + "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx" "^7.12.1" + "@babel/types" "^7.12.12" "@babel/plugin-transform-react-pure-annotations@^7.12.1": version "7.12.1" @@ -782,16 +764,16 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/preset-env@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.10.tgz#ca981b95f641f2610531bd71948656306905e6ab" - integrity sha512-Gz9hnBT/tGeTE2DBNDkD7BiWRELZt+8lSysHuDwmYXUIvtwZl0zI+D6mZgXZX0u8YBlLS4tmai9ONNY9tjRgRA== +"@babel/preset-env@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" + integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== dependencies: "@babel/compat-data" "^7.12.7" "@babel/helper-compilation-targets" "^7.12.5" "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.1" + "@babel/helper-validator-option" "^7.12.11" "@babel/plugin-proposal-async-generator-functions" "^7.12.1" "@babel/plugin-proposal-class-properties" "^7.12.1" "@babel/plugin-proposal-dynamic-import" "^7.12.1" @@ -820,7 +802,7 @@ "@babel/plugin-transform-arrow-functions" "^7.12.1" "@babel/plugin-transform-async-to-generator" "^7.12.1" "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.11" "@babel/plugin-transform-classes" "^7.12.1" "@babel/plugin-transform-computed-properties" "^7.12.1" "@babel/plugin-transform-destructuring" "^7.12.1" @@ -850,7 +832,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.12.1" "@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.11" core-js-compat "^3.8.0" semver "^5.5.0" @@ -902,26 +884,26 @@ "@babel/types" "^7.12.7" "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.4.5": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a" - integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.10" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.10" - "@babel/types" "^7.12.10" + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== + dependencies: + "@babel/code-frame" "^7.12.11" + "@babel/generator" "^7.12.11" + "@babel/helper-function-name" "^7.12.11" + "@babel/helper-split-export-declaration" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/types" "^7.12.12" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.10.tgz#7965e4a7260b26f09c56bcfcb0498af1f6d9b260" - integrity sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" to-fast-properties "^2.0.0" @@ -977,13 +959,6 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== -"@types/react-native@*": - version "0.63.37" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.37.tgz#c43df90c9d3cc082a97a49a53e989de26cb8ab45" - integrity sha512-xr9SZG7tQQBKT6840tAGaWEC65D2gjyxZtuZxz631UgeW1ofItuu9HMVhoyYqot2hRSa6Q4YC8FYkRVUpM53/w== - dependencies: - "@types/react" "*" - "@types/react@*", "@types/react@17.0.0": version "17.0.0" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8" @@ -992,14 +967,13 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/styled-components@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.5.tgz#a98e2ead1a1c7660b966f3aade4df9c0ec8ed75a" - integrity sha512-VWwoKm39W783a75oILtdCjnNn+FSV8Yh3O9naIudtZCAkk+rRfwLWzuPjf5k/OilENgZqAkxJ9sukSOZTAD86g== +"@types/styled-components@^5.1.7": + version "5.1.7" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.7.tgz#3cd10b088c1cb1acde2e4b166b3e8275a3083710" + integrity sha512-BJzPhFygYspyefAGFZTZ/8lCEY4Tk+Iqktvnko3xmJf9LrLqs3+grxPeU3O0zLl6yjbYBopD0/VikbHgXDbJtA== dependencies: "@types/hoist-non-react-statics" "*" "@types/react" "*" - "@types/react-native" "*" csstype "^3.0.2" ansi-styles@^3.2.1: @@ -1106,9 +1080,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== brace-expansion@^1.1.7: version "1.1.11" @@ -1141,16 +1115,16 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.15.0: - version "4.16.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.0.tgz#410277627500be3cb28a1bfe037586fbedf9488b" - integrity sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ== +browserslist@^4.14.5, browserslist@^4.16.0: + version "4.16.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" + integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== dependencies: - caniuse-lite "^1.0.30001165" + caniuse-lite "^1.0.30001173" colorette "^1.2.1" - electron-to-chromium "^1.3.621" + electron-to-chromium "^1.3.634" escalade "^3.1.1" - node-releases "^1.1.67" + node-releases "^1.1.69" cache-base@^1.0.1: version "1.0.1" @@ -1168,22 +1142,22 @@ cache-base@^1.0.1: unset-value "^1.0.0" call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" - get-intrinsic "^1.0.0" + get-intrinsic "^1.0.2" camelize@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001165: - version "1.0.30001165" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz#32955490d2f60290bb186bb754f2981917fa744f" - integrity sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA== +caniuse-lite@^1.0.30001173: + version "1.0.30001178" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz#3ad813b2b2c7d585b0be0a2440e1e233c6eabdbc" + integrity sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ== chalk@^2.0.0: version "2.4.2" @@ -1195,9 +1169,9 @@ chalk@^2.0.0: supports-color "^5.3.0" chokidar@^3.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -1207,7 +1181,7 @@ chokidar@^3.4.0: normalize-path "~3.0.0" readdirp "~3.5.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.1" class-utils@^0.3.5: version "0.3.6" @@ -1272,11 +1246,11 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.8.0: - version "3.8.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.1.tgz#8d1ddd341d660ba6194cbe0ce60f4c794c87a36e" - integrity sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ== + version "3.8.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.2.tgz#3717f51f6c3d2ebba8cbf27619b57160029d1d4c" + integrity sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ== dependencies: - browserslist "^4.15.0" + browserslist "^4.16.0" semver "7.0.0" core-util-is@~1.0.0: @@ -1299,9 +1273,9 @@ css-to-react-native@^3.0.0: postcss-value-parser "^4.0.2" csstype@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8" - integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ== + version "3.0.6" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" + integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -1351,10 +1325,10 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -electron-to-chromium@^1.3.621: - version "1.3.621" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.621.tgz#0bbe2100ef0b28f88d0b1101fbdf433312f69be0" - integrity sha512-FeIuBzArONbAmKmZIsZIFGu/Gc9AVGlVeVbhCq+G2YIl6QkT0TDn2HKN/FMf1btXEB9kEmIuQf3/lBTVAbmFOg== +electron-to-chromium@^1.3.634: + version "1.3.641" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.641.tgz#03f14efd70a7971eff2efc947b3c1d0f717c82b9" + integrity sha512-b0DLhsHSHESC1I+Nx6n4w4Lr61chMd3m/av1rZQhS2IXTzaS5BMM5N+ldWdMIlni9CITMRM09m8He4+YV/92TA== escalade@^3.1.1: version "3.1.1" @@ -1452,10 +1426,10 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== function-bind@^1.1.1: version "1.1.1" @@ -1467,10 +1441,10 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-intrinsic@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" - integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== +get-intrinsic@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -1860,10 +1834,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -node-releases@^1.1.67: - version "1.1.67" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" - integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== +node-releases@^1.1.69: + version "1.1.69" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6" + integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA== normalize-path@^2.1.1: version "2.1.1" @@ -2051,9 +2025,9 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + version "0.6.6" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.6.tgz#6d8c939d1a654f78859b08ddcc4aa777f3fa800a" + integrity sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ== dependencies: jsesc "~0.5.0" @@ -2264,10 +2238,10 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -typescript@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9" - integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ== +typescript@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" From d66940e20dd4675239d45f4e3545d424dc22ba59 Mon Sep 17 00:00:00 2001 From: Dennis Passway Date: Mon, 18 Jan 2021 09:49:11 +0100 Subject: [PATCH 19/19] Bump to 1.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8175211..f02f248 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sanity-plugin-media-library", "description": "The missing media library for Sanity. With filters per tag and filtetype. And it's fully themeable.", - "version": "1.0.2", + "version": "1.0.3", "license": "MIT", "author": "Dennis Passway", "main": "lib/index.js",