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

View File

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

View File

@ -153,18 +153,20 @@ const EditView = ({
{row.map((grid, gridIndex) => { {row.map((grid, gridIndex) => {
return ( return (
<Grid gap={4} key={gridIndex}> <Grid gap={4} key={gridIndex}>
{grid.map(({ fieldSchema, labelIcon, metadatas, name, size }) => { {grid.map(
({ fieldSchema, labelAction, metadatas, name, size }) => {
return ( return (
<GridItem col={size} key={name}> <GridItem col={size} key={name}>
<Inputs <Inputs
fieldSchema={fieldSchema} fieldSchema={fieldSchema}
keys={name} keys={name}
labelIcon={labelIcon} labelAction={labelAction}
metadatas={metadatas} metadatas={metadatas}
/> />
</GridItem> </GridItem>
); );
})} }
)}
</Grid> </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 React from 'react';
import get from 'lodash/get'; 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'; import { getTrad } from '../utils';
const enhanceRelationLayout = (layout, locale) => const enhanceRelationLayout = (layout, locale) =>
layout.map(current => { layout.map(current => {
const labelIcon = { const labelActionProps = {
title: { title: {
id: getTrad('Field.localized'), id: getTrad('Field.localized'),
defaultMessage: 'This value is unique for the selected locale', defaultMessage: 'This value is unique for the selected locale',
}, },
icon: <Globe />, icon: <I18N aria-hidden />,
}; };
let queryInfos = current.queryInfos; 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 => const enhanceEditLayout = layout =>
@ -35,17 +38,17 @@ const enhanceEditLayout = layout =>
type === 'uid' type === 'uid'
); );
const labelIcon = { const labelActionProps = {
title: { title: {
id: hasI18nEnabled ? getTrad('Field.localized') : getTrad('Field.not-localized'), id: hasI18nEnabled ? getTrad('Field.localized') : getTrad('Field.not-localized'),
defaultMessage: hasI18nEnabled defaultMessage: hasI18nEnabled
? 'This value is unique for the selected locale' ? 'This value is unique for the selected locale'
: 'This value is common to all locales', : '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; return acc;
}, []); }, []);

View File

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