[CORL-406] Tenant Locale Selection (#2450)

* feat: added preload config

* feat: support changing locale

* fix: name case

* fix: removed unused code

* feat: added translations for default reactions

* fix: do not translate icon

* fix: shorter i18n keys
This commit is contained in:
Wyatt Johnson
2019-09-05 17:02:06 +00:00
committed by GitHub
parent 5bf4f22931
commit 04c56b3fb5
54 changed files with 673 additions and 207 deletions
-1
View File
@@ -13,7 +13,6 @@ async function main() {
const ManagedCoralContextProvider = await createManaged({
initLocalState,
localesData,
userLocales: navigator.languages,
});
const Index: FunctionComponent = () => (
-1
View File
@@ -13,7 +13,6 @@ async function main() {
const ManagedCoralContextProvider = await createManaged({
initLocalState,
localesData,
userLocales: navigator.languages,
});
const Index: FunctionComponent = () => (
@@ -1,6 +1,7 @@
import { FormApi, FormState } from "final-form";
import React from "react";
import { CoralContext, withContext } from "coral-framework/lib/bootstrap";
import { SubmitHookHandler } from "coral-framework/lib/form";
import { MutationProp, withMutation } from "coral-framework/lib/relay";
@@ -9,6 +10,7 @@ import NavigationWarningContainer from "./NavigationWarningContainer";
import UpdateSettingsMutation from "./UpdateSettingsMutation";
interface Props {
changeLocale: CoralContext["changeLocale"];
updateSettings: MutationProp<typeof UpdateSettingsMutation>;
children: React.ReactElement;
}
@@ -27,6 +29,10 @@ class ConfigureRoute extends React.Component<Props, State> {
form: FormApi
) => {
await this.props.updateSettings({ settings: data });
const localeFieldState = form.getFieldState("locale");
if (localeFieldState && localeFieldState.dirty) {
await this.props.changeLocale(data.locale);
}
form.initialize(data);
};
@@ -52,6 +58,8 @@ class ConfigureRoute extends React.Component<Props, State> {
}
}
const enhanced = withMutation(UpdateSettingsMutation)(ConfigureRoute);
const enhanced = withContext(({ changeLocale }) => ({ changeLocale }))(
withMutation(UpdateSettingsMutation)(ConfigureRoute)
);
export default enhanced;
@@ -8,6 +8,7 @@ import ClosingCommentStreamsConfigContainer from "./ClosingCommentStreamsConfigC
import CommentEditingConfigContainer from "./CommentEditingConfigContainer";
import CommentLengthConfigContainer from "./CommentLengthConfigContainer";
import GuidelinesConfigContainer from "./GuidelinesConfigContainer";
import LocaleConfigContainer from "./LocaleConfigContainer";
import ReactionConfigContainer from "./ReactionConfigContainer";
import SitewideCommentingConfigContainer from "./SitewideCommentingConfigContainer";
@@ -19,7 +20,8 @@ interface Props {
PropTypesOf<typeof ClosedStreamMessageConfigContainer>["settings"] &
PropTypesOf<typeof ReactionConfigContainer>["settings"] &
PropTypesOf<typeof ClosingCommentStreamsConfigContainer>["settings"] &
PropTypesOf<typeof SitewideCommentingConfigContainer>["settings"];
PropTypesOf<typeof SitewideCommentingConfigContainer>["settings"] &
PropTypesOf<typeof LocaleConfigContainer>["settings"];
onInitValues: (values: any) => void;
}
@@ -29,6 +31,11 @@ const General: FunctionComponent<Props> = ({
onInitValues,
}) => (
<HorizontalGutter size="double" data-testid="configure-generalContainer">
<LocaleConfigContainer
disabled={disabled}
settings={settings}
onInitValues={onInitValues}
/>
<SitewideCommentingConfigContainer
disabled={disabled}
settings={settings}
@@ -45,6 +45,7 @@ class GeneralConfigContainer extends React.Component<Props> {
const enhanced = withFragmentContainer<Props>({
settings: graphql`
fragment GeneralConfigContainer_settings on Settings {
...LocaleConfigContainer_settings
...GuidelinesConfigContainer_settings
...CommentLengthConfigContainer_settings
...CommentEditingConfigContainer_settings
@@ -0,0 +1,64 @@
import { Localized } from "fluent-react/compat";
import React, { useMemo } from "react";
import { Field } from "react-final-form";
import { graphql } from "react-relay";
import { LocaleConfigContainer_settings } from "coral-admin/__generated__/LocaleConfigContainer_settings.graphql";
import { LocaleField } from "coral-framework/components";
import { withFragmentContainer } from "coral-framework/lib/relay";
import { required } from "coral-framework/lib/validation";
import { FormField, HorizontalGutter, Typography } from "coral-ui/components";
import Header from "../../Header";
import ValidationMessage from "../../ValidationMessage";
interface Props {
settings: LocaleConfigContainer_settings;
onInitValues: (values: LocaleConfigContainer_settings) => void;
disabled: boolean;
}
const LocaleConfigContainer: React.FunctionComponent<Props> = props => {
useMemo(() => props.onInitValues(props.settings), [props.onInitValues]);
return (
<FormField>
<HorizontalGutter size="full">
<Localized id="configure-general-locale-language">
<Header container={<label htmlFor="configure-locale-locale" />}>
Language
</Header>
</Localized>
<Localized
id="configure-general-locale-chooseLanguage"
strong={<strong />}
>
<Typography variant="detail">
Choose the language for your Coral community.
</Typography>
</Localized>
<Field name="locale" validate={required}>
{({ input, meta }) => (
<>
<LocaleField
id={`configure-locale-${input.name}`}
disabled={props.disabled}
{...input}
/>
<ValidationMessage meta={meta} fullWidth />
</>
)}
</Field>
</HorizontalGutter>
</FormField>
);
};
const enhanced = withFragmentContainer<Props>({
settings: graphql`
fragment LocaleConfigContainer_settings on Settings {
locale
}
`,
})(LocaleConfigContainer);
export default enhanced;
@@ -118,6 +118,81 @@ exports[`renders configure general 1`] = `
className="Box-root HorizontalGutter-root HorizontalGutter-double"
data-testid="configure-generalContainer"
>
<div
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-half"
>
<div
className="Box-root HorizontalGutter-root HorizontalGutter-full"
>
<label
className="Box-root Typography-root Typography-heading1 Typography-colorTextPrimary Header-root"
htmlFor="configure-locale-locale"
>
Language
</label>
<p
className="Box-root Typography-root Typography-detail Typography-colorTextPrimary"
>
Choose the language for your Coral community.
</p>
<span
className="SelectField-root"
>
<select
className="SelectField-select"
disabled={false}
id="configure-locale-locale"
name="locale"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
value="en-US"
>
<option
value="en-US"
>
English
</option>
<option
value="pt-BR"
>
Português brasileiro
</option>
<option
value="es"
>
Español
</option>
<option
value="de"
>
Deutsch
</option>
<option
value="nl-NL"
>
Nederlands
</option>
<option
value="da"
>
Dansk
</option>
</select>
<span
aria-hidden={true}
className="SelectField-afterWrapper"
>
<i
aria-hidden="true"
className="Icon-root Icon-sm"
>
expand_more
</i>
</span>
</span>
</div>
</div>
<fieldset
className="Box-root HorizontalGutter-root HorizontalGutter-oneAndAHalf"
>
@@ -1,3 +1,5 @@
import { SinonStub } from "sinon";
import { ERROR_CODES } from "coral-common/errors";
import { pureMerge } from "coral-common/utils";
import { InvalidRequestError } from "coral-framework/lib/errors";
@@ -63,6 +65,48 @@ it("renders configure general", async () => {
expect(within(configureContainer).toJSON()).toMatchSnapshot();
});
it("change language", async () => {
const resolvers = createResolversStub<GQLResolver>({
Mutation: {
updateSettings: ({ variables }) => {
expectAndFail(variables.settings.locale).toEqual("es");
return {
settings: pureMerge(settings, variables.settings),
};
},
},
});
const {
context: { changeLocale },
configureContainer,
generalContainer,
saveChangesButton,
} = await createTestRenderer({ resolvers });
const languageField = within(generalContainer).getByLabelText("Language");
// Let's change the language.
languageField.props.onChange("es");
// Send form
within(configureContainer)
.getByType("form")
.props.onSubmit();
// Submit button and text field should be disabled.
expect(saveChangesButton.props.disabled).toBe(true);
// Wait for submission to be finished
await wait(() => {
expect(resolvers.Mutation!.updateSettings!.called).toBe(true);
});
// Wait for client to change language.
await wait(() => {
expect((changeLocale as SinonStub).called).toBe(true);
});
});
it("change site wide commenting", async () => {
const resolvers = createResolversStub<GQLResolver>({
Mutation: {
+1
View File
@@ -24,6 +24,7 @@ export const settings = createFixture<GQLSettings>({
id: "settings",
moderation: GQLMODERATION_MODE.POST,
premodLinksEnable: false,
locale: "en-US",
live: {
enabled: true,
configurable: true,
-1
View File
@@ -33,7 +33,6 @@ async function main() {
const ManagedCoralContextProvider = await createManaged({
initLocalState,
localesData,
userLocales: navigator.languages,
});
const Index: FunctionComponent = () => (
@@ -0,0 +1,25 @@
import React, { FunctionComponent } from "react";
import { LanguageCode, LOCALES_MAP } from "coral-common/helpers/i18n";
import { PropTypesOf } from "coral-framework/types";
import { Option, SelectField } from "coral-ui/components";
interface Props extends PropTypesOf<typeof SelectField> {
value: LanguageCode;
}
const LocaleField: FunctionComponent<Props> = props => {
return (
<SelectField {...props}>
{Object.keys(LOCALES_MAP).map((lang: LanguageCode) => {
return (
<Option value={lang} key={lang}>
{LOCALES_MAP[lang]}
</Option>
);
})}
</SelectField>
);
};
export default LocaleField;
@@ -6,3 +6,4 @@ export { default as OIDCButton } from "./OIDCButton";
export { default as Markdown } from "./Markdown";
export { default as FadeInTransition } from "./FadeInTransition";
export { default as DurationField, DURATION_UNIT } from "./DurationField";
export { default as LocaleField } from "./LocaleField";
@@ -7,6 +7,7 @@ import { MediaQueryMatchers } from "react-responsive";
import { Formatter } from "react-timeago";
import { Environment } from "relay-runtime";
import { LanguageCode } from "coral-common/helpers/i18n";
import { BrowserInfo } from "coral-framework/lib/browserInfo";
import { PostMessageService } from "coral-framework/lib/postMessage";
import { RestClient } from "coral-framework/lib/rest";
@@ -64,6 +65,9 @@ export interface CoralContext {
/** Clear session data. */
clearSession: (nextAccessToken?: string | null) => Promise<void>;
/** Change locale and rerender */
changeLocale: (locale: LanguageCode) => Promise<void>;
/** Controls router transitions (for tests) */
transitionControl?: TransitionControlData;
}
@@ -7,12 +7,14 @@ import { Formatter } from "react-timeago";
import { Environment, RecordSource, Store } from "relay-runtime";
import uuid from "uuid/v1";
import { LanguageCode } from "coral-common/helpers/i18n";
import { getBrowserInfo } from "coral-framework/lib/browserInfo";
import {
commitLocalUpdatePromisified,
LOCAL_ID,
setAccessTokenInLocalState,
} from "coral-framework/lib/relay";
import { RestClient } from "coral-framework/lib/rest";
import {
createLocalStorage,
createPromisifiedStorage,
@@ -20,11 +22,9 @@ import {
createSessionStorage,
PromisifiedStorage,
} from "coral-framework/lib/storage";
import { RestClient } from "coral-framework/lib/rest";
import { ClickFarAwayRegister } from "coral-ui/components/ClickOutside";
import { generateBundles, LocalesData, negotiateLanguages } from "../i18n";
import { generateBundles, LocalesData } from "../i18n";
import {
createManagedSubscriptionClient,
createNetwork,
@@ -41,9 +41,6 @@ export type InitLocalState = (
) => void | Promise<void>;
interface CreateContextArguments {
/** Locales that the user accepts, usually `navigator.languages`. */
userLocales: ReadonlyArray<string>;
/** Locales data that is returned by our `locales-loader`. */
localesData: LocalesData;
@@ -128,11 +125,12 @@ function createRestClient(tokenGetter: () => string, clientID: string) {
* Returns a managed CoralContextProvider, that includes given context
* and handles context changes, e.g. when a user session changes.
*/
function createMangedCoralContextProvider(
function createManagedCoralContextProvider(
context: CoralContext,
subscriptionClient: ManagedSubscriptionClient,
clientID: string,
initLocalState: InitLocalState
initLocalState: InitLocalState,
localesData: LocalesData
) {
const ManagedCoralContextProvider = class extends Component<
{},
@@ -144,6 +142,7 @@ function createMangedCoralContextProvider(
context: {
...context,
clearSession: this.clearSession,
changeLocale: this.changeLocale,
},
};
}
@@ -196,6 +195,25 @@ function createMangedCoralContextProvider(
);
};
// This is called when the locale should change.
private changeLocale = async (locale: LanguageCode) => {
// Add fallback locale.
const locales = [localesData.fallbackLocale];
if (locale && locale !== localesData.fallbackLocale) {
locales.splice(0, 0, locale);
}
const localeBundles = await generateBundles(locales, localesData);
const newContext = {
...this.state.context,
locales,
localeBundles,
};
// Propagate new context.
this.setState({
context: newContext,
});
};
public render() {
return (
<CoralContextProvider value={this.state.context}>
@@ -240,7 +258,6 @@ function resolveSessionStorage(pym?: PymChild): PromisifiedStorage {
*/
export default async function createManaged({
initLocalState = noop,
userLocales,
localesData,
pym,
eventEmitter = new EventEmitter2({ wildcard: true, maxListeners: 20 }),
@@ -261,11 +278,24 @@ export default async function createManaged({
}
// Initialize i18n.
const locales = negotiateLanguages(userLocales, localesData);
const locales = [localesData.fallbackLocale];
if (
document.documentElement.lang &&
document.documentElement.lang !== localesData.fallbackLocale
) {
// Use locale specified by the server.
locales.splice(0, 0, document.documentElement.lang);
} else if (
localesData.defaultLocale &&
localesData.defaultLocale !== localesData.fallbackLocale
) {
// Use default locale.
locales.splice(0, 0, localesData.defaultLocale);
}
if (process.env.NODE_ENV !== "production") {
// tslint:disable:next-line: no-console
console.log(`Negotiated locales ${JSON.stringify(locales)}`);
console.log(`Using locales ${JSON.stringify(locales)}`);
}
const localeBundles = await generateBundles(locales, localesData);
@@ -304,6 +334,9 @@ export default async function createManaged({
// Noop, this is later replaced by the
// managed CoralContextProvider.
clearSession: (nextAccessToken?: string | null) => Promise.resolve(),
// Noop, this is later replaced by the
// managed CoralContextProvider.
changeLocale: (locale?: LanguageCode) => Promise.resolve(),
};
// Initialize local state.
@@ -317,10 +350,11 @@ export default async function createManaged({
// Returns a managed CoralContextProvider, that includes the above
// context and handles context changes, e.g. when a user session changes.
return createMangedCoralContextProvider(
return createManagedCoralContextProvider(
context,
subscriptionClient,
clientID,
initLocalState
initLocalState,
localesData
);
}
@@ -36,8 +36,6 @@ if (process.env.NODE_ENV !== "production") {
* Given a locales array and the `data` from the `locales-loader`,
* generateMessages returns an Array of MessageContext as a Promise.
* This array is meant to be consumed by `react-fluent`.
*
* Use it in conjunction with `negotiateLanguages`.
*/
export default async function generateBundles(
locales: ReadonlyArray<string>,
@@ -1,5 +1,4 @@
export { default as generateBundles } from "./generateBundles";
export { default as negotiateLanguages } from "./negotiateLanguages";
export { BundledLocales, LoadableLocales, LocalesData } from "./locales";
export { default as getMessage } from "./getMessage";
export { default as withGetMessage, GetMessage } from "./withGetMessage";
@@ -1,27 +0,0 @@
import { negotiateLanguages as negotiate } from "fluent-langneg/compat";
import { LocalesData } from "./locales";
/**
* negotiateLanguages accepts `userLocales` which usually comes from
* `navigator.languages` and the locales `data` as generated by
* the `locales-loader` and returns an array of matching languages.
*/
export default function negotiateLanguages(
userLocales: ReadonlyArray<string>,
data: LocalesData
) {
// Choose locale that is best for the user.
const languages = negotiate(userLocales, data.availableLocales, {
defaultLocale: data.defaultLocale,
strategy: "lookup",
});
if (data.fallbackLocale && languages[0] !== data.fallbackLocale) {
// Use default locale as fallback in case we have
// missing keys.
languages.push(data.fallbackLocale);
}
return languages;
}
@@ -1,3 +1,5 @@
import { LanguageCode } from "coral-common/helpers/i18n";
import { RestClient } from "../lib/rest";
export interface InstallInput {
@@ -8,6 +10,7 @@ export interface InstallInput {
url: string;
};
allowedDomains: string[];
locale: LanguageCode;
};
user: {
username: string;
@@ -10,7 +10,6 @@ import {
GQLCOMMENT_FLAG_REPORTED_REASON,
GQLCOMMENT_SORT,
GQLCOMMENT_STATUS,
GQLLOCALES,
GQLMODERATION_MODE,
GQLMODERATION_QUEUE,
GQLSTORY_STATUS,
@@ -35,7 +34,6 @@ export type GQLCOMMENT_FLAG_REPORTED_REASON_RL = RelayEnumLiteral<
>;
export type GQLCOMMENT_SORT_RL = RelayEnumLiteral<typeof GQLCOMMENT_SORT>;
export type GQLCOMMENT_STATUS_RL = RelayEnumLiteral<typeof GQLCOMMENT_STATUS>;
export type GQLLOCALES_RL = RelayEnumLiteral<typeof GQLLOCALES>;
export type GQLMODERATION_MODE_RL = RelayEnumLiteral<typeof GQLMODERATION_MODE>;
export type GQLSTORY_STATUS_RL = RelayEnumLiteral<typeof GQLSTORY_STATUS>;
export type GQLUSER_AUTH_CONDITIONS_RL = RelayEnumLiteral<
@@ -104,6 +104,7 @@ export default function createTestRenderer<
uuidGenerator: createUUIDGenerator(),
eventEmitter: new EventEmitter2({ wildcard: true, maxListeners: 20 }),
clearSession: sinon.stub(),
changeLocale: sinon.stub(),
transitionControl: {
allowTransition: true,
history: [],
@@ -1,5 +1,6 @@
import React, { Component } from "react";
import { LanguageCode } from "coral-common/helpers/i18n";
import { InstallInput } from "coral-framework/rest";
import { InstallMutation, withInstallMutation } from "./InstallMutation";
@@ -8,6 +9,7 @@ import CreateYourAccountStep from "./steps/CreateYourAccountStep";
import FinalStep from "./steps/FinalStep";
import InitialStep from "./steps/InitialStep";
import PermittedDomainsStep from "./steps/PermittedDomainsStep";
import SelectLanguageStep from "./steps/SelectLanguageStep";
import Wizard from "./Wizard";
interface FormData {
@@ -19,6 +21,7 @@ interface FormData {
password: string;
confirmPassword: string;
allowedDomains: string[];
locale: LanguageCode;
}
interface InstallWizardState {
@@ -35,6 +38,7 @@ function shapeFinalData(data: FormData): InstallInput {
username,
password,
email,
locale,
} = data;
return {
@@ -45,6 +49,7 @@ function shapeFinalData(data: FormData): InstallInput {
url: organizationURL,
},
allowedDomains,
locale,
},
user: {
username,
@@ -70,6 +75,7 @@ class InstallWizard extends Component<Props, InstallWizardState> {
password: "",
confirmPassword: "",
allowedDomains: [],
locale: "en-US" as LanguageCode,
},
};
@@ -99,6 +105,12 @@ class InstallWizard extends Component<Props, InstallWizardState> {
return (
<Wizard currentStep={this.state.step}>
<InitialStep onGoToNextStep={this.handleGoToNextStep} />
<SelectLanguageStep
data={this.state.data}
onSaveData={this.handleSaveData}
onGoToNextStep={this.handleGoToNextStep}
onGoToPreviousStep={this.handleGoToPreviousStep}
/>
<CreateYourAccountStep
data={this.state.data}
onSaveData={this.handleSaveData}
+5
View File
@@ -30,6 +30,11 @@ class Wizard extends Component<WizardProps> {
{currentStep !== 0 && currentStep !== wizardChildren.length - 1 && (
<StepBar currentStep={currentStep - 1} className={styles.stepBar}>
<Step hidden>Start</Step>
<Step>
<Localized id="install-selectLanguage-stepTitleSelect">
<span>Select Language</span>
</Localized>
</Step>
<Step>
<Localized id="install-createYourAccount-stepTitle">
<span>Create Admin Account</span>
@@ -26,6 +26,7 @@ import {
Typography,
} from "coral-ui/components";
import BackButton from "./BackButton";
import NextButton from "./NextButton";
interface FormProps {
@@ -188,8 +189,12 @@ class CreateYourAccountStep extends Component<Props> {
)}
</Field>
<Flex direction="row-reverse">
<Flex direction="row-reverse" itemGutter>
<NextButton submitting={submitting} />
<BackButton
submitting={submitting}
onGoToPreviousStep={this.props.onGoToPreviousStep}
/>
</Flex>
</HorizontalGutter>
</form>
@@ -0,0 +1,93 @@
import { Localized } from "fluent-react/compat";
import React, { FunctionComponent, useCallback } from "react";
import { Field, Form } from "react-final-form";
import { LanguageCode } from "coral-common/helpers/i18n";
import { LocaleField } from "coral-framework/components";
import { useCoralContext } from "coral-framework/lib/bootstrap";
import { OnSubmit, ValidationMessage } from "coral-framework/lib/form";
import { required } from "coral-framework/lib/validation";
import {
CallOut,
Flex,
FormField,
HorizontalGutter,
InputLabel,
Typography,
} from "coral-ui/components";
import NextButton from "./NextButton";
interface FormProps {
locale: string;
}
interface Props {
onGoToNextStep: () => void;
onGoToPreviousStep: () => void;
data: FormProps;
onSaveData: (newData: FormProps) => void;
}
const SelectLanguageStep: FunctionComponent<Props> = props => {
const { changeLocale } = useCoralContext();
const onSubmit = useCallback<OnSubmit<FormProps>>(
async (input, form) => {
props.onSaveData(input);
await changeLocale(input.locale as LanguageCode);
return props.onGoToNextStep();
},
[changeLocale, props.onSaveData, props.onGoToNextStep]
);
return (
<Form
onSubmit={onSubmit}
initialValues={{
locale: props.data.locale,
}}
>
{({ handleSubmit, submitting, submitError }) => (
<form autoComplete="off" onSubmit={handleSubmit}>
<HorizontalGutter size="double">
<Localized id="install-selectLanguage-selectLanguage">
<Typography variant="heading1" align="center">
Select language for Coral
</Typography>
</Localized>
<Localized id="install-selectLanguage-description">
<Typography variant="bodyCopy" align="center">
Choose the language to be used during the installation process.
This will also be the default language for your Coral community.
</Typography>
</Localized>
{submitError && (
<CallOut color="error" fullWidth>
{submitError}
</CallOut>
)}
<Field name="locale" validate={required}>
{({ input, meta }) => (
<FormField>
<Localized id="install-selectLanguage-language">
<InputLabel>Language</InputLabel>
</Localized>
<LocaleField disabled={submitting} fullWidth {...input} />
<ValidationMessage meta={meta} fullWidth />
</FormField>
)}
</Field>
<Flex direction="row-reverse">
<NextButton submitting={submitting} />
</Flex>
</HorizontalGutter>
</form>
)}
</Form>
);
};
export default SelectLanguageStep;
-1
View File
@@ -12,7 +12,6 @@ import "coral-ui/theme/variables.css";
async function main() {
const ManagedCoralContextProvider = await createManaged({
localesData,
userLocales: navigator.languages,
});
const Index: FunctionComponent = () => (
-1
View File
@@ -15,7 +15,6 @@ async function main() {
const ManagedCoralContextProvider = await createManaged({
initLocalState,
localesData,
userLocales: navigator.languages,
pym: new PymChild({
polling: 100,
}),
@@ -54,8 +54,11 @@ const SelectField: FunctionComponent<SelectFieldProps> = props => {
...rest
} = props;
const selectClassName = cn(classes.select, {
const rootClassName = cn(classes.root, className, {
[classes.fullWidth]: fullWidth,
});
const selectClassName = cn(classes.select, {
[classes.keyboardFocus]: keyboardFocus,
});
@@ -64,7 +67,7 @@ const SelectField: FunctionComponent<SelectFieldProps> = props => {
});
return (
<span className={cn(classes.root, className)}>
<span className={rootClassName}>
<select className={selectClassName} disabled={disabled} {...rest}>
{children}
</select>
@@ -2,11 +2,11 @@
exports[`renders correctly 1`] = `
<span
className="SelectField-root customClassName"
className="SelectField-root customClassName SelectField-fullWidth"
>
<select
autofocus={true}
className="SelectField-select SelectField-fullWidth"
className="SelectField-select"
disabled={true}
id="selectID"
name="selectName"
+1 -3
View File
@@ -6,9 +6,7 @@
url("material-design-icons/iconfont/MaterialIcons-Regular.woff2")
format("woff2"),
url("material-design-icons/iconfont/MaterialIcons-Regular.woff")
format("woff"),
url("material-design-icons/iconfont/MaterialIcons-Regular.ttf")
format("truetype");
format("woff");
}
.icon {