mirror of
https://github.com/strapi/strapi.git
synced 2025-12-12 15:32:42 +00:00
Design relations for D&P
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
d3082807d1
commit
76c662d4e7
@ -1,21 +1,28 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const RelationDPState = styled.div`
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin: auto;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: flex;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-bottom: 1px;
|
||||
margin-left: 10px;
|
||||
margin-top: ${({ marginTop }) => marginTop};
|
||||
margin-left: ${({ marginLeft }) => marginLeft};
|
||||
margin-bottom: ${({ marginBottom }) => marginBottom};
|
||||
margin-right: ${({ marginRight }) => marginRight};
|
||||
border-radius: 50%;
|
||||
background-color: ${({ theme, isDraft }) =>
|
||||
isDraft ? theme.main.colors.mediumBlue : theme.main.colors.green};
|
||||
}
|
||||
`;
|
||||
|
||||
RelationDPState.defaultProps = {
|
||||
marginLeft: '10px',
|
||||
marginRight: '0',
|
||||
marginTop: '0',
|
||||
marginBottom: '1px',
|
||||
};
|
||||
|
||||
export default RelationDPState;
|
||||
|
||||
@ -92,6 +92,7 @@ const Li = styled.li`
|
||||
> div {
|
||||
width: 90%;
|
||||
> a {
|
||||
flex-grow: 2;
|
||||
max-width: 100%;
|
||||
color: rgb(35, 56, 77);
|
||||
}
|
||||
@ -143,7 +144,7 @@ const Li = styled.li`
|
||||
|
||||
const Span = styled.span`
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-width: calc(100% - 10px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@ -9,6 +9,7 @@ import ListItem from './ListItem';
|
||||
|
||||
function SelectMany({
|
||||
addRelation,
|
||||
components,
|
||||
mainField,
|
||||
name,
|
||||
hasDraftAndPublish,
|
||||
@ -57,6 +58,8 @@ function SelectMany({
|
||||
return (
|
||||
<>
|
||||
<Select
|
||||
components={components}
|
||||
hasDraftAndPublish={hasDraftAndPublish}
|
||||
isDisabled={isDisabled}
|
||||
id={name}
|
||||
filterOption={(candidate, input) => {
|
||||
@ -116,12 +119,14 @@ function SelectMany({
|
||||
}
|
||||
|
||||
SelectMany.defaultProps = {
|
||||
components: {},
|
||||
move: () => {},
|
||||
value: null,
|
||||
};
|
||||
|
||||
SelectMany.propTypes = {
|
||||
addRelation: PropTypes.func.isRequired,
|
||||
components: PropTypes.object,
|
||||
hasDraftAndPublish: PropTypes.bool.isRequired,
|
||||
isDisabled: PropTypes.bool.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isEmpty } from 'lodash';
|
||||
import { Flex, Padded, Text } from '@buffetjs/core';
|
||||
import RelationDPState from '../RelationDPState';
|
||||
|
||||
const SingleValue = props => {
|
||||
const Component = components.SingleValue;
|
||||
const hasDraftAndPublish = props.selectProps.hasDraftAndPublish;
|
||||
const isDraft = isEmpty(get(props, 'data.value.published_at'));
|
||||
const value = props.selectProps.value.label;
|
||||
|
||||
if (hasDraftAndPublish) {
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Padded left size="sm" right>
|
||||
<Flex>
|
||||
<RelationDPState
|
||||
marginLeft="0"
|
||||
marginTop="1px"
|
||||
marginRight="10px"
|
||||
isDraft={isDraft}
|
||||
marginBottom="0"
|
||||
/>
|
||||
<div>
|
||||
<Text ellipsis>{value}</Text>
|
||||
</div>
|
||||
</Flex>
|
||||
</Padded>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Padded left right size="sm">
|
||||
{value}
|
||||
</Padded>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
SingleValue.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
selectProps: PropTypes.shape({
|
||||
hasDraftAndPublish: PropTypes.bool,
|
||||
value: PropTypes.object,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default SingleValue;
|
||||
@ -1,12 +1,14 @@
|
||||
import React, { memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isNull } from 'lodash';
|
||||
|
||||
import Select from 'react-select';
|
||||
import SingleValue from './SingleValue';
|
||||
|
||||
function SelectOne({
|
||||
components,
|
||||
mainField,
|
||||
name,
|
||||
hasDraftAndPublish,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
onChange,
|
||||
@ -20,6 +22,8 @@ function SelectOne({
|
||||
}) {
|
||||
return (
|
||||
<Select
|
||||
hasDraftAndPublish={hasDraftAndPublish}
|
||||
components={{ ...components, SingleValue }}
|
||||
id={name}
|
||||
isClearable
|
||||
isDisabled={isDisabled}
|
||||
@ -37,10 +41,13 @@ function SelectOne({
|
||||
}
|
||||
|
||||
SelectOne.defaultProps = {
|
||||
components: {},
|
||||
value: null,
|
||||
};
|
||||
|
||||
SelectOne.propTypes = {
|
||||
components: PropTypes.object,
|
||||
hasDraftAndPublish: PropTypes.bool.isRequired,
|
||||
isDisabled: PropTypes.bool.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
mainField: PropTypes.string.isRequired,
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Remove } from '@buffetjs/icons';
|
||||
import { components } from 'react-select';
|
||||
|
||||
const ClearIndicator = props => {
|
||||
const Component = components.ClearIndicator;
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Remove width="11px" height="11px" fill="#9EA7B8" />
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClearIndicator;
|
||||
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { Flex } from '@buffetjs/core';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Wrapper = styled(Flex)`
|
||||
height: 100%;
|
||||
width: 32px;
|
||||
background: #fafafb;
|
||||
> svg {
|
||||
align-self: center;
|
||||
font-size: 11px;
|
||||
color: #b3b5b9;
|
||||
}
|
||||
`;
|
||||
|
||||
const DropdownIndicator = ({ selectProps: { menuIsOpen } }) => {
|
||||
const icon = menuIsOpen ? 'caret-up' : 'caret-down';
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<FontAwesomeIcon icon={icon} />
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
DropdownIndicator.propTypes = {
|
||||
selectProps: PropTypes.shape({
|
||||
menuIsOpen: PropTypes.bool.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
Wrapper.defaultProps = {
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
};
|
||||
|
||||
export default DropdownIndicator;
|
||||
@ -0,0 +1,3 @@
|
||||
const IndicatorSeparator = () => null;
|
||||
|
||||
export default IndicatorSeparator;
|
||||
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { components } from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isEmpty } from 'lodash';
|
||||
import { Flex, Text } from '@buffetjs/core';
|
||||
import RelationDPState from '../RelationDPState';
|
||||
|
||||
const TextGrow = styled(Text)`
|
||||
flex-grow: 2;
|
||||
`;
|
||||
|
||||
const Option = props => {
|
||||
const Component = components.Option;
|
||||
const hasDraftAndPublish = props.selectProps.hasDraftAndPublish;
|
||||
const isDraft = isEmpty(get(props, 'data.value.published_at'));
|
||||
|
||||
if (hasDraftAndPublish) {
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Flex>
|
||||
<RelationDPState
|
||||
marginLeft="0"
|
||||
marginTop="1px"
|
||||
marginRight="10px"
|
||||
isDraft={isDraft}
|
||||
marginBottom="0"
|
||||
/>
|
||||
|
||||
<TextGrow ellipsis as="div">
|
||||
{props.label}
|
||||
</TextGrow>
|
||||
</Flex>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Text ellipsis>{props.label}</Text>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
Option.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
selectProps: PropTypes.shape({
|
||||
hasDraftAndPublish: PropTypes.bool,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default Option;
|
||||
@ -1,132 +1,14 @@
|
||||
import styled from 'styled-components';
|
||||
import { Text } from '@buffetjs/core';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
margin-bottom: 27px;
|
||||
label {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
const BaselineAlignment = styled.div`
|
||||
padding-top: 1px;
|
||||
`;
|
||||
|
||||
nav + div {
|
||||
height: 34px;
|
||||
background-color: white;
|
||||
margin-top: 5px;
|
||||
> div {
|
||||
min-height: 34px;
|
||||
height: 100%;
|
||||
border: 1px solid #e3e9f3;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 1px 0 rgba(104, 118, 142, 0.05);
|
||||
flex-wrap: initial;
|
||||
padding: 0 10px;
|
||||
|
||||
/* Arrow */
|
||||
&:before {
|
||||
content: '\f0d7';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
font-family: 'FontAwesome';
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
color: #aaa;
|
||||
}
|
||||
> div {
|
||||
padding: 0;
|
||||
&:first-of-type {
|
||||
/* Placeholder */
|
||||
> div span {
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
div:last-of-type {
|
||||
span {
|
||||
display: none;
|
||||
& + div {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
svg {
|
||||
width: 15px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
span {
|
||||
font-size: 13px;
|
||||
line-height: 34px;
|
||||
color: #333740;
|
||||
}
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
border-color: #e3e9f3;
|
||||
&:before {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
span[aria-live='polite'] + div {
|
||||
&:before {
|
||||
transform: rotate(180deg);
|
||||
top: 4px;
|
||||
}
|
||||
& + div {
|
||||
z-index: 2;
|
||||
height: fit-content;
|
||||
padding: 0;
|
||||
margin-top: -2px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
&:before {
|
||||
content: '';
|
||||
}
|
||||
div {
|
||||
width: 100%;
|
||||
}
|
||||
> div {
|
||||
max-height: 200px;
|
||||
height: fit-content;
|
||||
div {
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const A = styled(Text)`
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`;
|
||||
|
||||
const Nav = styled.nav`
|
||||
> div {
|
||||
display: flex;
|
||||
|
||||
justify-content: space-between;
|
||||
|
||||
a {
|
||||
color: #007eff !important;
|
||||
font-size: 1.3rem;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.description {
|
||||
color: #9ea7b8;
|
||||
font-family: 'Lato';
|
||||
font-size: 1.2rem;
|
||||
margin-top: -5px;
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
|
||||
export { Nav, Wrapper };
|
||||
export { A, BaselineAlignment };
|
||||
|
||||
@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { cloneDeep, findIndex, get, isArray, isEmpty, set, has } from 'lodash';
|
||||
import { request } from 'strapi-helper-plugin';
|
||||
import { Flex, Text, Padded } from '@buffetjs/core';
|
||||
import pluginId from '../../pluginId';
|
||||
import useDataManager from '../../hooks/useDataManager';
|
||||
import useEditView from '../../hooks/useEditView';
|
||||
@ -12,8 +13,12 @@ import { getFieldName } from '../../utils';
|
||||
import NotAllowedInput from '../NotAllowedInput';
|
||||
import SelectOne from '../SelectOne';
|
||||
import SelectMany from '../SelectMany';
|
||||
import { Nav, Wrapper } from './components';
|
||||
import { connect, select } from './utils';
|
||||
import ClearIndicator from './ClearIndicator';
|
||||
import DropdownIndicator from './DropdownIndicator';
|
||||
import IndicatorSeparator from './IndicatorSeparator';
|
||||
import Option from './Option';
|
||||
import { A, BaselineAlignment } from './components';
|
||||
import { connect, select, styles } from './utils';
|
||||
|
||||
function SelectWrapper({
|
||||
componentUid,
|
||||
@ -189,24 +194,14 @@ function SelectWrapper({
|
||||
targetModel
|
||||
) ? null : (
|
||||
<Link to={{ pathname: to, state: { from: pathname } }}>
|
||||
<FormattedMessage id="content-manager.containers.Edit.seeDetails" />
|
||||
<FormattedMessage id="content-manager.containers.Edit.seeDetails">
|
||||
{msg => <A color="mediumBlue">{msg}</A>}
|
||||
</FormattedMessage>
|
||||
</Link>
|
||||
);
|
||||
const Component = isSingle ? SelectOne : SelectMany;
|
||||
const associationsLength = isArray(value) ? value.length : 0;
|
||||
|
||||
const customStyles = {
|
||||
option: provided => {
|
||||
return {
|
||||
...provided,
|
||||
maxWidth: '100% !important',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const isDisabled = useMemo(() => {
|
||||
if (isMorph) {
|
||||
return true;
|
||||
@ -228,54 +223,63 @@ function SelectWrapper({
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper className="form-group">
|
||||
<Nav>
|
||||
<div>
|
||||
<label htmlFor={name}>
|
||||
{label}
|
||||
{!isSingle && (
|
||||
<span style={{ fontWeight: 400, fontSize: 12 }}> ({associationsLength})</span>
|
||||
)}
|
||||
</label>
|
||||
{isSingle && link}
|
||||
</div>
|
||||
{!isEmpty(description) && <p className="description">{description}</p>}
|
||||
</Nav>
|
||||
<Component
|
||||
addRelation={value => {
|
||||
addRelation({ target: { name, value } });
|
||||
}}
|
||||
hasDraftAndPublish={hasDraftAndPublish}
|
||||
id={name}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={isLoading}
|
||||
isClearable
|
||||
mainField={mainField}
|
||||
move={moveRelation}
|
||||
name={name}
|
||||
options={filteredOptions}
|
||||
onChange={value => {
|
||||
onChange({ target: { name, value: value ? value.value : value } });
|
||||
}}
|
||||
onInputChange={onInputChange}
|
||||
onMenuClose={() => {
|
||||
setState(prevState => ({ ...prevState, _contains: '' }));
|
||||
}}
|
||||
onMenuScrollToBottom={onMenuScrollToBottom}
|
||||
onRemove={onRemoveRelation}
|
||||
placeholder={
|
||||
isEmpty(placeholder) ? (
|
||||
<FormattedMessage id={`${pluginId}.containers.Edit.addAnItem`} />
|
||||
) : (
|
||||
placeholder
|
||||
)
|
||||
}
|
||||
styles={customStyles}
|
||||
targetModel={targetModel}
|
||||
value={value}
|
||||
/>
|
||||
<div style={{ marginBottom: 18 }} />
|
||||
</Wrapper>
|
||||
<Padded>
|
||||
<BaselineAlignment />
|
||||
<Flex justifyContent="space-between">
|
||||
<Text fontWeight="semiBold">
|
||||
{label}
|
||||
{!isSingle && ` (${associationsLength})`}
|
||||
</Text>
|
||||
{isSingle && link}
|
||||
</Flex>
|
||||
{!isEmpty(description) && (
|
||||
<Padded top size="xs">
|
||||
<BaselineAlignment />
|
||||
<Text fontSize="sm" color="grey" lineHeight="12px" ellipsis>
|
||||
{description}
|
||||
</Text>
|
||||
</Padded>
|
||||
)}
|
||||
<Padded top size="sm">
|
||||
<BaselineAlignment />
|
||||
|
||||
<Component
|
||||
addRelation={value => {
|
||||
addRelation({ target: { name, value } });
|
||||
}}
|
||||
components={{ ClearIndicator, DropdownIndicator, IndicatorSeparator, Option }}
|
||||
hasDraftAndPublish={hasDraftAndPublish}
|
||||
id={name}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={isLoading}
|
||||
isClearable
|
||||
mainField={mainField}
|
||||
move={moveRelation}
|
||||
name={name}
|
||||
options={filteredOptions}
|
||||
onChange={value => {
|
||||
onChange({ target: { name, value: value ? value.value : value } });
|
||||
}}
|
||||
onInputChange={onInputChange}
|
||||
onMenuClose={() => {
|
||||
setState(prevState => ({ ...prevState, _contains: '' }));
|
||||
}}
|
||||
onMenuScrollToBottom={onMenuScrollToBottom}
|
||||
onRemove={onRemoveRelation}
|
||||
placeholder={
|
||||
isEmpty(placeholder) ? (
|
||||
<FormattedMessage id={`${pluginId}.containers.Edit.addAnItem`} />
|
||||
) : (
|
||||
placeholder
|
||||
)
|
||||
}
|
||||
styles={styles}
|
||||
targetModel={targetModel}
|
||||
value={value}
|
||||
/>
|
||||
</Padded>
|
||||
<div style={{ marginBottom: 28 }} />
|
||||
</Padded>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
export { default as connect } from './connect';
|
||||
export { default as select } from './select';
|
||||
export { default as styles } from './styles';
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
/* eslint-disable indent */
|
||||
/* eslint-disable no-nested-ternary */
|
||||
|
||||
const styles = {
|
||||
container: base => ({ ...base, background: '#ffffff' }),
|
||||
control: (base, state) => {
|
||||
const borderRadiusStyle = state.selectProps.menuIsOpen
|
||||
? {
|
||||
borderBottomLeftRadius: '0 !important',
|
||||
borderBottomRightRadius: '0 !important',
|
||||
}
|
||||
: {};
|
||||
|
||||
const {
|
||||
selectProps: { error, value },
|
||||
} = state;
|
||||
|
||||
let border;
|
||||
let borderBottom;
|
||||
let backgroundColor;
|
||||
|
||||
if (state.isFocused) {
|
||||
border = '1px solid #78caff !important';
|
||||
} else if (error && !value.length) {
|
||||
border = '1px solid #f64d0a !important';
|
||||
} else {
|
||||
border = '1px solid #e3e9f3 !important';
|
||||
}
|
||||
|
||||
if (state.menuIsOpen === true) {
|
||||
borderBottom = '1px solid #e3e9f3 !important';
|
||||
}
|
||||
|
||||
if (state.isDisabled) {
|
||||
backgroundColor = '#fafafb !important';
|
||||
}
|
||||
|
||||
return {
|
||||
...base,
|
||||
fontSize: 13,
|
||||
height: 34,
|
||||
minHeight: 34,
|
||||
border,
|
||||
outline: 0,
|
||||
boxShadow: 0,
|
||||
borderRadius: '2px !important',
|
||||
...borderRadiusStyle,
|
||||
borderBottom,
|
||||
backgroundColor,
|
||||
};
|
||||
},
|
||||
input: base => ({ ...base, marginLeft: 10 }),
|
||||
menu: base => {
|
||||
return {
|
||||
...base,
|
||||
width: '100%',
|
||||
margin: '0',
|
||||
paddingTop: 0,
|
||||
borderRadius: '2px !important',
|
||||
borderTopLeftRadius: '0 !important',
|
||||
borderTopRightRadius: '0 !important',
|
||||
border: '1px solid #78caff !important',
|
||||
boxShadow: 0,
|
||||
borderTop: '0 !important',
|
||||
fontSize: '13px',
|
||||
};
|
||||
},
|
||||
menuList: base => ({
|
||||
...base,
|
||||
maxHeight: '112px',
|
||||
paddingTop: 2,
|
||||
}),
|
||||
option: (base, state) => {
|
||||
return {
|
||||
...base,
|
||||
height: 36,
|
||||
backgroundColor: state.isSelected ? '#fff' : base.backgroundColor,
|
||||
color: state.isSelected ? '#007eff' : '#333740',
|
||||
fontWeight: state.isSelected ? '600' : '400',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
},
|
||||
placeholder: base => ({
|
||||
...base,
|
||||
marginTop: 0,
|
||||
marginLeft: 10,
|
||||
color: '#aaa',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
maxWidth: 'calc(100% - 32px)',
|
||||
}),
|
||||
valueContainer: base => ({
|
||||
...base,
|
||||
padding: '2px 0px 4px 0px',
|
||||
lineHeight: '18px',
|
||||
}),
|
||||
};
|
||||
|
||||
export default styles;
|
||||
Loading…
x
Reference in New Issue
Block a user