diff --git a/README.md b/README.md index 59f9a3d..1e340c3 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,18 @@ Example with asset fields listed and custom fields added: "name": "location", "label": "Location", "type": "location" - } + }, + { + "label": "Copyright", + "name": "copyright", + "placeholder": "pick oneā€¦", + "type": "select", + "options": [ + { "title": "Copyright", "value": "copyright" }, + { "title": "Public Domain", "value": "public-domain" }, + { "title": "Creative Commons", "value": "creative-commons" } + ] + }, ], } ``` diff --git a/src/components/AssetModal.tsx b/src/components/AssetModal.tsx index 5b4acb3..e308640 100644 --- a/src/components/AssetModal.tsx +++ b/src/components/AssetModal.tsx @@ -7,7 +7,7 @@ import { LabelWithInput } from './LabelWithInput'; import { Loader } from './Loader'; import { Modal } from './Modal'; import client from 'part:@sanity/base/client'; -import React, { Fragment, FormEvent, useState } from 'react'; +import React, { Fragment, FormEvent, useState, useEffect } from 'react'; import styled from 'styled-components'; interface Props { @@ -115,6 +115,10 @@ export const AssetModal = ({ asset, loading, handleError, onClose, onSaveComplet title, }); + useEffect(() => { + customFields.map((field: any) => setLocalValues((values) => ({ ...values, [field.name]: asset[field.name] }))); + }, []); + const inputFields = [ { name: 'title', label: 'Title', placeholder: 'No title yet' }, { name: 'alt', label: 'Alt text', placeholder: 'No alt text yet' }, diff --git a/src/components/LabelWithInput.tsx b/src/components/LabelWithInput.tsx index 2d634dc..ad6468e 100644 --- a/src/components/LabelWithInput.tsx +++ b/src/components/LabelWithInput.tsx @@ -14,6 +14,7 @@ interface Props { | 'email' | 'location' | 'number' + | 'select' | 'tel' | 'text' | 'time' @@ -84,17 +85,51 @@ const StyledTextArea = styled.textarea` width: 100%; `; +const StyledSelectWrapper = styled.div` + position: relative; +`; + +const StyledSelectArrow = styled.span` + background-color: ${({ theme }) => theme.inputTextColor}; + bottom: 0; + clip-path: polygon(100% 0%, 0 0%, 50% 100%); + content: ''; + height: 0.5em; + pointer-events: none; + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + width: 0.8em; +`; + +const StyledSelect = styled.select` + appearance: none; + background-color: ${({ theme }) => theme.inputBackgroundColor}; + border-radius: ${({ theme }) => theme.appBorderRadius}; + border: 0; + color: ${({ theme }) => theme.inputTextColor}; + font-family: ${({ theme }) => theme.appFontFamily}; + font-size: 16px 16px 34px 16px; + line-height: 1.1; + outline: 0; + padding: 16px; + width: 100%; +`; + export const LabelWithInput = ({ label, onChange, type = 'text', ...rest }: Props) => { const elementsMap: { [key: string]: any } = { checkbox: Checkbox, location: Location, textArea: StyledTextArea, + select: Select, }; 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)), + select: (e: ChangeEvent) => onChange(e.target.value), }; const defaultOnChange = (e: ChangeEvent) => onChange(e.target.value); @@ -140,3 +175,33 @@ const Location = ({ ); }; + +type SelectOption = { + title: string; + value: string; +}; + +const Select = ({ + options, + placeholder, + value, + ...rest +}: { + options: Array; + placeholder: string | undefined; + value: string | undefined; +}) => { + return ( + + + + {options?.map((option: SelectOption) => ( + + ))} + + + + ); +};