Контейнер вложенных стилей JSS

Я работаю с компонентом React Material UI -> TextField, и я хочу сделать вокруг него некую оболочку с возможностью переопределения стилей. Согласно документации, для этого у нас есть 2 реквизита: 1) InputProps - здесь мы должны передать классы во внутренний Компонент ввода, который является ядром нашего TextField. 2) свойство direct classes, которое должно применяться непосредственно к TextField. И эти классы должны содержать правила для FormControl

(звучит сложно, на самом деле это когда вы работаете с Material UI =))

в любом случае, я хочу сделать что-то подобное

import { withStyles } from 'material-ui/styles';

export const TextInputCSSCreator = theme => ({
    "FormControlClasses" : {
        "root" : { "color" : "red }
       }
    "InputClasses" : {
       "underline" : {
           "&:after" : {
               backgroundColor : "red",
           },
       }
    }

});

<TextField
                classses={this.props.classes.FormControlClasses}
                id={this.props.id}
                InputProps={{
                    classes : this.props.classes.InputClasses
                }}
                label={this.props.label}
                value={this.state.value}
                onChange={this._onValueChange}
                margin={this.props.margin}
            />

export default withStyles(TextInputCSSCreator)(TextInput);

Здесь я хотел иметь возможность передать целый объект двум моим целям. Ввод и FormControl. Но вот основная проблема, и я не знаю, как ее решить. Похоже, JSS (то же самое со стилями из MaterialUi) не работает с объектом, который содержит вложенные контейнеры для правил.

Я выполнил эту задачу таким уродливым способом. Это похоже на АД, но я не нашел способа избежать этого. Кто-нибудь может мне помочь, пожалуйста? Неужели это только один способ выполнить это требование?

Потому что способ, который я хочу реализовать, обеспечивает нам гибкость, мы можем добавлять любые классы, которые мы хотим, в любое время, когда во втором способе (ниже) мы должны жестко закодировать все возможные классы в начале

Кстати. Я хочу предоставить механизм для изменения стилей моих компонентов из внешнего приложения, поэтому я не могу использовать CSS, потому что на выходе это должен быть действующий модуль commonJS.

export const TextInputCSSCreator = theme => ({
    "FormControlRoot" : {},
    "FormControlMarginNormal" : {},
    "FormControlMarginDense" : {},
    "FormControlFullWidth" : {},

    "InputRoot" : {},
    "InputFormControl" : {},
    "InputFocused" : {},
    "InputDisabled" : {},
    "InputUnderline" : {
        "&:after" : {
            backgroundColor : "red",
        },
    },
    "InputError" : {},
    "InputMultiline" : {},
    "InputFullWIdth" : {},
    "InputInput" : {},
    "InputInputMarginDense" : {},
    "InputInputDisabled" : {},
    "InputInputMultiline" : {},
    "InputInputType" : {},
    "InputInputTypeSearch" : {}
});

render() {
        const { classes } = this.props;
        return (

            <TextField
                classes={{
                    root : classes.FormControlRoot,
          marginNormal : classes.FormControlMarginNormal,
                    marginDense : classes.FormControlMarginDense,
                    fullWidth : classes.FormControlFullWidth,
                }}
                id={this.props.id}
                InputProps={{
                    classes : {
                        root : classes.InputRoot,
                        formControl : classes.InputFormControl,
                        focused : classes.InputFocused,
                        disabled : classes.InputDisabled,
                        underline : classes.InputUnderline,
                        error : classes.InputError,
                        multiline : classes.InputMultiline,
                        fullWidth : classes.InputFullWIdth,
                        input : classes.InputInput,
                        inputMarginDense : classes.InputInputMarginDense,
                        inputDisabled : classes.InputInputDisabled,
                        inputMultiline : classes.InputInputMultiline,
                        inputType : classes.InputInputType,
                        inputTypeSearch : classes.InputInputTypeSearch
                    }
                }}
                label={this.props.label}
                value={this.state.value}
                onChange={this._onValueChange}
                margin={this.props.margin}
            />


        );
    }

export default withStyles(TextInputCSSCreator)(TextInput);

person Velidan    schedule 03.04.2018    source источник


Ответы (1)


в этой ситуации я бы создал тему для этого компонента в отдельном файле с помощью createMuiTheme ({}) и применил ее к компоненту с компонентом поставщика MuiTheme. Опыт:

import { createMuiTheme } from 'material-ui/styles';
const customTheme = createMuiTheme({
    overrides: {
        MuiInput: {
            root:{
                color: 'red',
            },
            underline: {
                    '&:after': {
                      backgroundColor: '#000000',
                    }
              },
        },
    }

});
export default customTheme;

а затем используйте его на моем компоненте следующим образом:

<MuiThemeProvider theme = {customTheme}>
[Your component]
</MuiThemeProvider>

Надеюсь это поможет!

person Max    schedule 04.04.2018
comment
Привет.Спасибо за ответ. Но что, если я хочу иметь несколько компонентов, которые должны выглядеть иначе, чем другие, управляемые темой? - person Velidan; 04.04.2018
comment
Вы можете использовать разные темы для разных компонентов. Я тестировал это с помощью App.js, завернутого в ‹MuiThemeProvider theme = {globalTheme}›, и одного из дочерних компонентов, завернутых в собственную customTheme. В этом случае у дочернего компонента были только стили, предоставленные с customTheme, без наследования от globalTheme. - person Max; 04.04.2018
comment
Но похоже, что обернуть каждый компонент в свой собственный поставщик тем - это накладные расходы. Наверное, это снижает производительность приложения, не так ли? - person Velidan; 04.04.2018
comment
Я бы использовал этот подход, если бы у меня была одна глобальная тема, которая заботится о большинстве моих потребностей, и, возможно, если мне нужен специальный диалог, я бы создал его собственную тему и сохранил ее. Я бы не стал злоупотреблять этим до такой степени, что каждый компонент будет иметь свою собственную тему, некоторые вещи можно будет изменить с помощью классов и стилей и т.д. быть намного хуже, чем каждый раз переписывать стили с помощьюStyles (). - person Max; 04.04.2018