Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions packages/clay-form/src/LocalizedInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
* SPDX-License-Identifier: BSD-3-Clause
*/

import ClayForm, {ClayInput} from '.';
import {ClayButtonWithIcon} from '@clayui/button';
const spritemap = require('@clayui/css/lib/images/icons/icons.svg');
import ClayDropDown, {Align} from '@clayui/drop-down';
import ClayIcon from '@clayui/icon';
import ClayLabel from '@clayui/label';
import React from 'react';

const DropDownWithState: React.FunctionComponent<any> = ({
children,
language,
...others
}) => {
const [active, setActive] = React.useState(false);

return (
<ClayDropDown
{...others}
active={active}
alignmentPosition={Align.BottomLeft}
onActiveChange={newVal => setActive(newVal)}
trigger={
<ClayButtonWithIcon
aria-expanded="false"
aria-haspopup="true"
displayType="unstyled"
onClick={() => setActive(!active)}
spritemap={spritemap}
symbol={language.symbol}
title="Open Language Dropdown"
/>
}
>
{children}
</ClayDropDown>
);
};
interface IProps extends React.InputHTMLAttributes<HTMLInputElement> {
defaultLanguage: {label: string; symbol: string; value: string};
languages: any;
label?: string;
onInputValueChange?: any;
onLanguageChange?: any;
placeholder?: string;
selectedLanguage: {label: string; symbol: string; value: string};
textarea?: boolean;
url?: boolean;
value?: string;
}

const ClayLocalizedInput = React.forwardRef<HTMLInputElement, IProps>(
({
defaultLanguage,
label = 'Check for translations',
languages,
onInputValueChange,
onLanguageChange,
placeholder = 'Text to translate...',
selectedLanguage,
url,
value,
}) => (
<ClayForm.Group>
<label htmlFor="localizedInput">{label}</label>

<ClayInput.Group>
{url && (
<ClayInput.GroupItem prepend shrink>
<ClayInput.GroupText>{'/'}</ClayInput.GroupText>
</ClayInput.GroupItem>
)}

<ClayInput.GroupItem>
<ClayInput
id="localizedInput"
onChange={event =>
onInputValueChange(event.target.value)
}
placeholder={placeholder}
value={value}
/>
</ClayInput.GroupItem>

<ClayInput.GroupItem shrink>
<DropDownWithState
hasRightSymbols
language={selectedLanguage}
>
<ClayDropDown.ItemList>
{languages.map(
(language: {
label: string;
symbol: string;
value: string;
}) => (
<ClayDropDown.Item
key={language.label}
onClick={() =>
onLanguageChange(language)
}
>
<ClayIcon
className="inline-item inline-item-before"
spritemap={spritemap}
symbol={language.symbol}
/>

{language.label}

<ClayLabel
className="dropdown-item-indicator-end"
displayType={
language.label ===
defaultLanguage.label
? 'info'
: language.value
? 'success'
: 'warning'
}
>
{language.label ===
defaultLanguage.label
? 'Default Value'
: language.value
? 'Translated'
: 'Untranslated'}
</ClayLabel>
</ClayDropDown.Item>
)
)}
</ClayDropDown.ItemList>
</DropDownWithState>
</ClayInput.GroupItem>
</ClayInput.Group>

{defaultLanguage.value && <span>{defaultLanguage.value}</span>}
</ClayForm.Group>
)
);

export default ClayLocalizedInput;
2 changes: 2 additions & 0 deletions packages/clay-form/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ClayCheckbox from './Checkbox';
import ClayForm from './Form';
import ClayInput from './Input';
import ClayLocalizedInput from './LocalizedInput';
import ClayRadio from './Radio';
import ClayRadioGroup from './RadioGroup';
import ClaySelect from './Select';
Expand All @@ -15,6 +16,7 @@ import ClayToggle from './Toggle';
export {
ClayCheckbox,
ClayInput,
ClayLocalizedInput,
ClayRadio,
ClayRadioGroup,
ClaySelect,
Expand Down
97 changes: 97 additions & 0 deletions packages/clay-form/stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import '@clayui/css/lib/css/atlas.css';
const spritemap = require('@clayui/css/lib/images/icons/icons.svg');
import {boolean, select, text} from '@storybook/addon-knobs';

import ClayLocalizedInput from '../src/LocalizedInput';

const ClayCheckboxWithState = () => {
const [value, setValue] = React.useState<boolean>(false);

Expand Down Expand Up @@ -78,6 +80,101 @@ storiesOf('Components|ClayCheckbox', module)
</ClayCheckbox>
));

storiesOf('Components|ClayLocalizedInput', module).add('default', () => {
const locales = [
{
label: 'en-US',
symbol: 'en-us',
value: '',
},
{
label: 'es-ES',
symbol: 'es-es',
value: '',
},
{
label: 'hr-HR',
symbol: 'hr-hr',
value: '',
},
];

function updateLanguages(
inputValue: string,
languages: Array<{
label: string;
symbol: string;
value: string;
}>,
language: {
label: string;
symbol: string;
value: string;
}
) {
const updatedLanguages = [...languages];
const languageIndex = updatedLanguages.indexOf(language);

language.value = inputValue;
updatedLanguages.splice(languageIndex, 1, language);

return updatedLanguages;
}

const [languages, setLanguages] = React.useState(locales);
const [selectedLanguage, setSelectedLanguage] = React.useState<{
label: string;
symbol: string;
value: string;
}>(languages[0]);
const [inputValue, setInputValue] = React.useState<string>(
selectedLanguage.value
);

const inputName = 'localizedInput';

return (
<div>
<ClayLocalizedInput
defaultLanguage={languages[0]}
languages={languages}
onInputValueChange={(inputValue: string) =>
setInputValue(inputValue)
}
onLanguageChange={(language: {
label: string;
symbol: string;
value: string;
}) => {
if (inputValue) {
const updatedLanguages = updateLanguages(
inputValue,
languages,
selectedLanguage
);

setLanguages(updatedLanguages);
setInputValue(language.value);
}

setSelectedLanguage(language);
}}
selectedLanguage={selectedLanguage}
value={inputValue}
/>

{languages.map(language => (
<input
key={language.label}
name={`${inputName}_${language}`}
type="hidden"
value={language.value}
/>
))}
</div>
);
});

storiesOf('Components|ClayInput', module)
.add('default', () => (
<div className="sheet">
Expand Down