Add i18n icons

Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
soupette 2021-09-21 08:59:51 +02:00
parent f0a6a3ff68
commit 509e38561c
6 changed files with 122 additions and 70 deletions

View File

@ -15,6 +15,7 @@ const Input = ({
description,
disabled,
intlLabel,
labelAction,
error,
name,
onChange,
@ -34,6 +35,7 @@ const Input = ({
description={description}
disabled={disabled}
intlLabel={intlLabel}
labelAction={labelAction}
error={error}
name={name}
onChange={onChange}
@ -63,6 +65,7 @@ const Input = ({
disabled={disabled}
hint={hint}
label={label}
labelAction={labelAction}
name={name}
offLabel={formatMessage({
id: 'app.components.ToggleCheckbox.off-label',
@ -93,6 +96,7 @@ const Input = ({
disabled={disabled}
error={errorMessage}
label={label}
labelAction={labelAction}
id={name}
hint={hint}
name={name}
@ -109,6 +113,7 @@ Input.defaultProps = {
description: null,
disabled: false,
error: '',
labelAction: undefined,
placeholder: null,
value: '',
};
@ -127,6 +132,7 @@ Input.propTypes = {
defaultMessage: PropTypes.string.isRequired,
values: PropTypes.object,
}).isRequired,
labelAction: PropTypes.element,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.shape({

View File

@ -4,7 +4,6 @@ import get from 'lodash/get';
import omit from 'lodash/omit';
import take from 'lodash/take';
import isEqual from 'react-fast-compare';
import { useIntl } from 'react-intl';
// import { Inputs as InputsIndex } from '@buffetjs/custom';
// import { NotAllowedInput, useLibrary } from '@strapi/helper-plugin';
import { useContentTypeLayout } from '../../hooks';
@ -29,7 +28,7 @@ function Inputs({
formErrors,
isCreatingEntry,
keys,
labelIcon,
labelAction,
metadatas,
onBlur,
onChange,
@ -41,11 +40,6 @@ function Inputs({
// const { fields } = useLibrary();
const { contentType: currentContentTypeLayout } = useContentTypeLayout();
const { formatMessage } = useIntl();
const labelIconformatted = labelIcon
? { icon: labelIcon.icon, title: formatMessage(labelIcon.title) }
: labelIcon;
const disabled = useMemo(() => !get(metadatas, 'editable', true), [metadatas]);
const type = fieldSchema.type;
@ -183,7 +177,7 @@ function Inputs({
// return (
// <NotAllowedInput
// label={metadatas.label}
// labelIcon={labelIconformatted}
// labelAction={labelAction}
// error={errorMessage}
// />
// );
@ -196,7 +190,7 @@ function Inputs({
// <SelectWrapper
// {...metadatas}
// {...fieldSchema}
// labelIcon={labelIcon}
// labelAction={labelAction}
// isUserAllowedToEditField={isUserAllowedToEditField}
// isUserAllowedToReadField={isUserAllowedToReadField}
// name={keys}
@ -217,7 +211,7 @@ function Inputs({
disabled={shouldDisableField}
error={errorId}
// inputDescription={description}
labelIcon={labelIconformatted}
labelAction={labelAction}
contentTypeUID={currentContentTypeLayout.uid}
customInputs={{
// json: InputJSONWithErrors,
@ -244,7 +238,7 @@ function Inputs({
Inputs.defaultProps = {
formErrors: {},
labelIcon: null,
labelAction: undefined,
onBlur: null,
queryInfos: {},
value: null,
@ -256,13 +250,7 @@ Inputs.propTypes = {
formErrors: PropTypes.object,
keys: PropTypes.string.isRequired,
isCreatingEntry: PropTypes.bool.isRequired,
labelIcon: PropTypes.shape({
icon: PropTypes.node.isRequired,
title: PropTypes.shape({
id: PropTypes.string.isRequired,
defaultMessage: PropTypes.string.isRequired,
}).isRequired,
}),
labelAction: PropTypes.element,
metadatas: PropTypes.object.isRequired,
onBlur: PropTypes.func,
onChange: PropTypes.func.isRequired,

View File

@ -153,18 +153,20 @@ const EditView = ({
{row.map((grid, gridIndex) => {
return (
<Grid gap={4} key={gridIndex}>
{grid.map(({ fieldSchema, labelIcon, metadatas, name, size }) => {
return (
<GridItem col={size} key={name}>
<Inputs
fieldSchema={fieldSchema}
keys={name}
labelIcon={labelIcon}
metadatas={metadatas}
/>
</GridItem>
);
})}
{grid.map(
({ fieldSchema, labelAction, metadatas, name, size }) => {
return (
<GridItem col={size} key={name}>
<Inputs
fieldSchema={fieldSchema}
keys={name}
labelAction={labelAction}
metadatas={metadatas}
/>
</GridItem>
);
}
)}
</Grid>
);
})}

View File

@ -0,0 +1,34 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { Tooltip } from '@strapi/parts/Tooltip';
const LabelAction = ({ title, icon }) => {
const { formatMessage } = useIntl();
return (
<Tooltip description={formatMessage(title)}>
<button
aria-label={formatMessage(title)}
style={{
border: 'none',
padding: 0,
background: 'transparent',
}}
type="button"
>
{icon}
</button>
</Tooltip>
);
};
LabelAction.propTypes = {
icon: PropTypes.element.isRequired,
title: PropTypes.shape({
id: PropTypes.string.isRequired,
defaultMessage: PropTypes.string.isRequired,
}).isRequired,
};
export default LabelAction;

View File

@ -1,16 +1,19 @@
import React from 'react';
import get from 'lodash/get';
import { Globe, GlobeCrossed } from '@buffetjs/icons';
import I18N from '@strapi/icons/I18N';
// FIXME
import HelpIcon from '@strapi/icons/HelpIcon';
import LabelAction from '../components/LabelAction';
import { getTrad } from '../utils';
const enhanceRelationLayout = (layout, locale) =>
layout.map(current => {
const labelIcon = {
const labelActionProps = {
title: {
id: getTrad('Field.localized'),
defaultMessage: 'This value is unique for the selected locale',
},
icon: <Globe />,
icon: <I18N aria-hidden />,
};
let queryInfos = current.queryInfos;
@ -22,7 +25,7 @@ const enhanceRelationLayout = (layout, locale) =>
};
}
return { ...current, labelIcon, queryInfos };
return { ...current, labelAction: <LabelAction {...labelActionProps} />, queryInfos };
});
const enhanceEditLayout = layout =>
@ -35,17 +38,17 @@ const enhanceEditLayout = layout =>
type === 'uid'
);
const labelIcon = {
const labelActionProps = {
title: {
id: hasI18nEnabled ? getTrad('Field.localized') : getTrad('Field.not-localized'),
defaultMessage: hasI18nEnabled
? 'This value is unique for the selected locale'
: 'This value is common to all locales',
},
icon: hasI18nEnabled ? <Globe /> : <GlobeCrossed />,
icon: hasI18nEnabled ? <I18N aria-hidden /> : <HelpIcon aria-hidden />,
};
acc.push({ ...field, labelIcon });
acc.push({ ...field, labelAction: <LabelAction {...labelActionProps} /> });
return acc;
}, []);

View File

@ -1,5 +1,8 @@
import React from 'react';
import { Globe, GlobeCrossed } from '@buffetjs/icons';
import I18N from '@strapi/icons/I18N';
// FIXME
import HelpIcon from '@strapi/icons/HelpIcon';
import LabelAction from '../../components/LabelAction';
import { getTrad } from '../../utils';
import mutateEditViewLayout, {
enhanceComponentsLayout,
@ -115,10 +118,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
},
size: 6,
targetModelPluginOptions: {},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
],
},
@ -352,10 +357,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
pluginOptions: { i18n: { localized: true } },
type: 'string',
},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
],
[
@ -366,10 +373,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
pluginOptions: { i18n: { localized: true } },
type: 'string',
},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
{
name: 'slug',
@ -377,10 +386,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
fieldSchema: {
type: 'uid',
},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
],
];
@ -420,10 +431,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
pluginOptions: { i18n: { localized: true } },
type: 'string',
},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
],
[
@ -434,10 +447,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
pluginOptions: { i18n: { localized: false } },
type: 'string',
},
labelIcon: {
title: { id: notLocalizedTrad, defaultMessage: notLocalizedTradDefaultMessage },
icon: <GlobeCrossed />,
},
labelAction: (
<LabelAction
title={{ id: notLocalizedTrad, defaultMessage: notLocalizedTradDefaultMessage }}
icon={<HelpIcon aria-hidden />}
/>
),
},
],
];
@ -466,10 +481,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
queryInfos: {},
size: 6,
targetModelPluginOptions: {},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
];
@ -509,10 +526,12 @@ describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
targetModelPluginOptions: {
i18n: { localized: true },
},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
labelAction: (
<LabelAction
title={{ id: localizedTrad, defaultMessage: localizedTradDefaultMessage }}
icon={<I18N aria-hidden />}
/>
),
},
];