Material-ui: Suporte ao plug-in de extensão JSS por padrão

Criado em 30 nov. 2017  ·  57Comentários  ·  Fonte: mui-org/material-ui

Comportamento esperado

  • Cor do texto: #FF0000
.App-text-273 {
    color: #FF0000; // <--- Expected
    cursor: pointer;
    font-size: 50px;
    user-select: none;
}

Comportamento atual

.App-text-273 {
    extend: ext; // <--- Invalid
    cursor: pointer;
    font-size: 50px;
    user-select: none;
}

Etapas para reproduzir (para bugs)

import React, { Component } from 'react'
import ReactDOM, { render } from 'react-dom'
import PropTypes from 'prop-types'
import { withStyles } from 'material-ui/styles'

const styles = theme => ({
  ext: {
    color: '#FF0000',
  },
  text: {
    extend: 'ext',
    fontSize: '50px',
    cursor: 'pointer',
    userSelect: 'none'
  }
})

@withStyles(styles)
class App extends Component {
  static propTypes = {
    classes: PropTypes.object.isRequired
  }

  onClick(event) {
    const className = event.target.getAttribute('class')
    const style = getComputedStyle(event.target, null)
    const { fontSize, cursor, userSelect, color } = style

    console.log(`className: ${className}`)
    console.log({ fontSize, cursor, userSelect, color })
  }

  render() {
    const { classes } = this.props
    return (
      <p className={classes.text} onClick={this.onClick}>Foo Bar Baz</p>
    )
  }
}

render(<App />, document.getElementById('root'))

Edit 88ywmypq7l

Meio Ambiente

| Tecnologia | Versão |
|--------------|---------|
| Material-UI | 1.0.0-beta.22 |
| Reagir | 16.0.0 |
| navegador | Versão do Chrome 62.0.3202.94 (Build oficial) (64 bits) |

enhancement

Comentários muito úteis

:+1: ao adicionar novamente esses dois (estender e compor). Eles definitivamente valem a pena por um mero IMO de 2 KB.

Todos 57 comentários

@tdkn Você está carregando o plugin jss-extend? https://github.com/cssinjs/react-jss#custom -setup

@mbrookes
Obrigado👍
Eu consertei como abaixo.
Mas, isso documentado em detalhes ? :desapontado:

import React, { Component } from 'react'
import ReactDOM, { render } from 'react-dom'
import PropTypes from 'prop-types'
import { JssProvider, SheetsRegistry, jss } from 'react-jss'
import { withStyles } from 'material-ui/styles'

const withJSSProvider = Component => props => (
  <JssProvider registry={new SheetsRegistry()} jss={jss}>
    <Component {...props} />
  </JssProvider>
)

const styles = theme => ({
  ext: {
    color: '#FF0000',
  },
  text: {
    extend: 'ext',
    fontSize: '50px',
    cursor: 'pointer',
    userSelect: 'none'
  }
})

<strong i="10">@withJSSProvider</strong>
@withStyles(styles)
class App extends Component {
  static propTypes = {
    classes: PropTypes.object.isRequired
  }

  onClick(event) {
    const className = event.target.getAttribute('class')
    const style = getComputedStyle(event.target, null)
    const { fontSize, cursor, userSelect, color } = style

    console.log(`className: ${className}`)
    console.log({ fontSize, cursor, userSelect, color })
  }

  render() {
    const { classes } = this.props
    return (
      <p className={classes.text} onClick={this.onClick}>Foo Bar Baz</p>
    )
  }
}

render(<App />, document.getElementById('root'))

Edit 8n5lkpmm8l

@giapelle Bom ponto. @kof?

@tdkn Obrigado pelo feedback. Estou adicionando a alteração na parte de alteração de quebra do changelog.

Precisamos mencionar como o usuário pode personalizar uma instância JSS em vários lugares, porque através dessa otimização, fizemos com que muitos usuários se deparassem com esse e outros problemas semelhantes (ainda não convencidos de que valeu a pena)

@kof acho que você pode estar certo: #9335

@kof Acho que precisamos ver isso como um experimento. Minha estratégia era esperar para ver. Se as pessoas reclamarem, adicionamos os plugins que eles sentem falta.

para mim, é tudo sobre compõe

@kof Acho que precisamos ver isso como um experimento. Minha estratégia era esperar para ver. Se as pessoas reclamarem, adicionamos os plugins que eles sentem falta.

É basicamente como esperar o primeiro usuário que reclama da ausência de um plugin que ele está usando, você nunca vai terminar esse experimento haha

"Escreve" parece uma boa solução para resolver o problema da folha de estilo compartilhada"

Ah! @oallouch mesmo aqui: eu tinha certeza que mui estava usando jss-preset-default , mas então me deparei com isso.
Eu estava tentando usar compose ou extend .
@olegberman valeu a pena essa remoção se 2kb gzipado afinal? 🤔

@oliviertassinari te disse

Atualizamos a documentação para refletir essa alteração.

Eu me deparei com o mesmo problema, tentando usar o plugin extend.
Eu tentei seguir isso: https://material-ui-next.com/guides/right-to-left/#3 -jss-rtl
mas estou usando renderização do lado do servidor e não consegui fazer funcionar.

PS: Não tenho certeza se valeu a pena remover esses plugins por 2kb, pois são recursos realmente incríveis que todos deveriam usar 😁

Afirmo que estender e compor são ferramentas essenciais do IMHO em JSS e não valem os 2kb.

A sobrecarga do tempo de execução da renderização precisa ser quantificada. Não é apenas sobre o tamanho do pacote.

Ainda é opcional para o mui, portanto, se você achar que aumenta a sobrecarga, pode continuar usando a biblioteca classNames e o operador de propagação, acho que não fará muita diferença.

Eu estava tentando habilitar o plugin jss-extend da maneira exata como o plugin jss-rtl deveria ser habilitado de acordo com a documentação. O mesmo código, mas substituí todas as chamadas relacionadas a plugins para jss-extend one. Mas sem sucesso. As regras que deveriam ser estendidas, na verdade, não são afetadas. Alguém poderia ter feito isso eventualmente?

Porra, metade do último dia gasto em como usar jss-extend em material-ui, com este exemplo encontrado em algum lugar:
cssLabel: { "&$cssFocused": { color: grey[500] } }, cssFocused: { backgroundColor: blue[500] },
onde eu pensei que "&$cssFocused seria como extend: cssFocused. Mas isso não. Então, como fazê-lo ?

@nsaubi você está falando sobre a funcionalidade de aninhamento e é substituído pelo seletor de regras de contenção, da mesma forma que no sass.

Alguma informação sobre se jss-extend/compose se tornará padrão no futuro?

Espero que o extend volte, pois ajuda a tornar o código jss mais limpo imo.

++ (1)

2kb realmente não importa. Acho que estabelecer um bom padrão de codificação com "estender e compor" é mais importante para o futuro.
@oliviertassinari Você poderia avaliar para adicioná-los de volta e, na verdade, adicionar suporte total para eles?

@gitsupersmecher Você já pode ter suporte completo para "estender e compor" adicionando o plugin ao JSS com o componente JssProvider . A maioria das pessoas pode passar sem. O aumento do pacote de +2kb é um lado da questão, o custo do tempo de execução é o outro.

Acho que o custo de tempo de execução quase não é perceptível para esses 2. Também acho que vale a pena adicionar alguns kb para isso, já que tornamos o estilo parte da API pública e essas são coisas muito populares de se fazer.

No entanto, em vez de estender, pode-se usar o operador spread, que cobre a maioria dos casos e a composição pode ser feita dentro de um componente concatenando um className.

:+1: ao adicionar novamente esses dois (estender e compor). Eles definitivamente valem a pena por um mero IMO de 2 KB.

outra opção é realmente ocultar a instância interna do jss e deixar bem claro como usar a própria configuração do jss para estilizar.

Oi, estou tentando adicionar jss-extend em um projeto nextjs, (usando o exemplo do plugin jss-rtl) sem sucesso. Alguém pode fazer funcionar?

^ também gostaria de saber

Aqui eu posto o que eu faço. eu não sei como implementar generateClassName porque no exemplo nextjs já é usado.

Tomando como base este exemplo:
https://github.com/mui-org/material-ui/tree/master/examples/nextjs

Primeiro instale o jss-extend
npm i --save jss-extend

/pages/_app.js

import React from 'react';
import App, { Container } from 'next/app';
import { MuiThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import JssProvider from 'react-jss/lib/JssProvider';
import getPageContext from '../src/getPageContext';

/* --------------------------------------------------------------------------------
* ADD THE IMPORTS
*-----------------------------------------------------------------------------------*/
import { createGenerateClassName, jssPreset } from '@material-ui/core/styles';
import { create } from 'jss';
import jssExtend from 'jss-extend';

const jss = create({ plugins: [...jssPreset().plugins, JssProvider ()] });


class MyApp extends App {
  constructor(props) {
    super(props);
    this.pageContext = getPageContext();
  }

  pageContext = null;

  componentDidMount() {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles && jssStyles.parentNode) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }

  render() {
    const { Component, pageProps } = this.props;
    return (
      <Container>
        {/* Wrap every page in Jss and Theme providers 
             HERE ALSO ADD JSS TO PROVIDER
          */}
        <JssProvider
          jss={this.jss}
          registry={this.pageContext.sheetsRegistry}
          generateClassName={this.pageContext.generateClassName}
        >
          {/* MuiThemeProvider makes the theme available down the React
              tree thanks to React context. */}
          <MuiThemeProvider
            theme={this.pageContext.theme}
            sheetsManager={this.pageContext.sheetsManager}
          >
            {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
            <CssBaseline />
            {/* Pass pageContext to the _document though the renderPage enhancer
                to render collected styles on server side. */}
            <Component pageContext={this.pageContext} {...pageProps} />
          </MuiThemeProvider>
        </JssProvider>
      </Container>
    );
  }
}

export default MyApp;

Existe algum plano para adicionar estender de volta?

Estou seguindo o guia em https://material-ui.com/guides/right-to-left/#3 -jss-rtl e alterei o rtl para estender, mas não funciona. Alguma visão do porquê?

Estou fazendo isso e o plugin não está carregando (v3.2.2)
Alguma ideia?

import React from 'react'
import ReactDOM from 'react-dom'
import {
  MuiThemeProvider,
  createMuiTheme,
  createGenerateClassName,
  jssPreset
} from '@material-ui/core/styles'
import JssProvider from 'react-jss/lib/JssProvider'
import { create } from 'jss'
import jssExtend from 'jss-extend'
import CssBaseline from '@material-ui/core/CssBaseline'
import { UserProvider } from './context/User'
import App from './components/App'

const jss = create({ plugins: [...jssPreset().plugins, jssExtend()] })
const generateClassName = createGenerateClassName()

const theme = createMuiTheme({ ... })

const Main = () => (
  <JssProvider jss={jss} generateClassName={generateClassName}>
    <MuiThemeProvider theme={theme}>
      <CssBaseline/>
        <App/>
    </MuiThemeProvider>
  </JssProvider>
)

Você precisa configurar os plugins na ordem correta, http://cssinjs.org/plugins?v=v9.8.7

Você está usando .a preset criado para mui e adicionando jssExtend na ordem errada. Em vez disso, você pode usar uma instância jss de react-jss que já tenha todas as predefinições aplicadas: import {jss} de "react-jss" ou importe a predefinição padrão do http://cssinjs.org/jss-preset-default?v =v4.5.0

Basta se deparar com esta questão. Também acredito que deveria estar no local por padrão.

Eu argumentaria que também deveria estar em vigor por padrão com base no fato de que o raciocínio de @oliviertassinari provavelmente não é forte o suficiente. Em parte, porque se estender/compor não for incentivado, há uma boa chance de que a base de código termine com inchaço adicional de CSS desnecessário — o que também pode levar a processamento desnecessário. Talvez não seja tão prejudicial quanto 2kb e talvez não tanto processamento quanto estender/compor, mas a manutenção do código também é um fator aqui. Concluindo, meu raciocínio também pode não ser tão forte, mas na presença de um raciocínio não tão forte para as opções à mão... eu digo para dar à multidão o que eles querem! :D

Concordo que estender e compor devem ser incluídos por padrão. São funções tão fundamentais e a razão de eu usar JSS. Eu adoraria vê-los re-adicionados, pois mesmo pequenos projetos provavelmente os usarão e a instalação personalizada é muito longa comparativamente.

@AdamWhitehurst Você poderia votar a favor do problema? Isso nos ajudaria a fazer uma troca melhor :).

Acho que temos que considerar as seguintes dimensões ponderadas:

  • o número de votos positivos/participantes da conversa.
  • o custo de tempo de execução: ? (alguém pode executar nosso conjunto de benchmarks com ele?)
  • o custo do tamanho do pacote: 613 B . O problema com essa dimensão está no custo para X usar apenas um de nossos componentes, como o Modal.

Eventualmente, poderíamos fazer uma enquete no Twitter para isso 🤔.

o custo de tempo de execução se você tiver plugins de extensão/composição instalados é quase 0, é uma verificação se a propriedade extend ou composes está definida, se não - não faz nada

Totalmente, eu votei no primeiro post, é isso que você quer dizer? Eu sou meio novo para tudo isso, então tenha paciência comigo, haha.

Aceite meu upvote também

Outra consideração pode ser o desempenho das soluções alternativas. Exemplo do meu código:

<Typography variant='h5' className={`${classes.sideLink} ${classes.leftSideLink}`} >About</Typography>

Qual seria o custo de fazer essa solução alternativa?

Alguma notícia sobre este assunto para estender e compor? Como outros, também não consegui seguir os documentos para instalar plugins separados. Eu até copiei o exemplo, mas tive problemas com StylesProvider.

@gabrielliwerant Deve ser fácil adicionar novos plugins. Se o Material-UI falhar na execução disso, devemos nos concentrar nesse problema.

Estou fechando porque já adicionamos o rótulo wait for upvotes .

@gabrielliwerant

O mais recente está atualmente em: https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-extend

npm i jss-plugin-extend
import {jssPreset, StylesProvider, ThemeProvider} from '@material-ui/styles';
import {create} from "jss";
import jssPluginSyntaxExtend from "jss-plugin-extend";

const jss = create({
    plugins: [...jssPreset().plugins, jssPluginSyntaxExtend()],
});

Então, algo assim parece funcionar bem o suficiente ...

    render() {
        const {Component, pageProps} = this.props;

        return (
            <Container>
                <Head>
                    <title></title>
                </Head>
                <StylesProvider jss={jss}>
                    <ThemeProvider theme={theme}>
                            <CssBaseline/>
                            <Component {...pageProps} />
                    </ThemeProvider>
                </StylesProvider>
            </Container>
        );
    }

@gabrielliwerant

O mais recente está atualmente em: https://github.com/cssinjs/jss/tree/master/packages/jss-plugin-extend

npm i jss-plugin-extend
import {jssPreset, StylesProvider, ThemeProvider} from '@material-ui/styles';
import {create} from "jss";
import jssPluginSyntaxExtend from "jss-plugin-extend";

const jss = create({
  plugins: [...jssPreset().plugins, jssPluginSyntaxExtend()],
});

Então, algo assim parece funcionar bem o suficiente ...

  render() {
      const {Component, pageProps} = this.props;

      return (
          <Container>
              <Head>
                  <title></title>
              </Head>
              <StylesProvider jss={jss}>
                  <ThemeProvider theme={theme}>
                          <CssBaseline/>
                          <Component {...pageProps} />
                  </ThemeProvider>
              </StylesProvider>
          </Container>
      );
  }

Eu tentei esta solução, mas nesta versão apenas jss-plugin-extend funciona, todos os plugins internos ( ... jssPreset ().plugins ) não funcionam, como se não estivessem lá. material-ui v4.5, jss v10

Esta é a solução que funciona para mim:

import jss from 'jss';
import preset from 'jss-preset-default';
import { StylesProvider } from '@material-ui/styles';

jss.setup(preset());
<StylesProvider jss={jss}>
  ...
</StylesProvider>
"@material-ui/styles": "^4.5.0",
"jss": "^10.0.0",
"jss-preset-default": "^10.0.0-alpha.27"

Oi pessoal, é possível usar o MuiThemeProvider e usar plugins jss também? A documentação parece ser um pouco antiga, e tenho uma solução que para de funcionar com extend e compose.
Suponho que seja por causa de alguma mudança de contexto. É assim que meu código se parece:

import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { StylesProvider, jssPreset, createGenerateClassName } from '@material-ui/styles';
import { create } from 'jss';
import jssCompose from 'jss-plugin-compose';
import jssExtend from 'jss-plugin-extend';

const ThemeProvider = ({ children }) => (
  <StylesProvider jss={jss} generateClassName={generateClassName}>
    <MuiThemeProvider theme={theme}>
      <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
    </MuiThemeProvider>
  </StylesProvider>
);

Sim, é possível, é um requisito do suporte da direita para a esquerda para a biblioteca.

@oliviertassinari existe algum exemplo de como adicionar plugins JSS personalizados como jss-extend com nextJS?

@guiihlopes Eu encorajaria a seguir o guia RTL, deve ser semelhante: https://material-ui.com/guides/right-to-left/#3 -jss-rtl.

@guiihlopes Eu encorajaria a seguir o guia RTL, deve ser semelhante: https://material-ui.com/guides/right-to-left/#3 -jss-rtl.

Legal... Tentei seguir o mesmo guia e estou preso em:

async getInitialProps(ctx) {
    // imported jssExtend from 'jss-plugin-extend';
    const plugins = [...jssPreset().plugins, jssExtend()];
    const jss = create({ plugins });
    // Render app and page and get the context of the page with collected side effects.
    const sheets = new ServerStyleSheets({
      jss,
    });
    const originalRenderPage = ctx.renderPage;

    ctx.renderPage = () =>
      originalRenderPage({
        enhanceApp: App => props => sheets.collect(<App {...props} />),
      });

    const initialProps = await Document.getInitialProps(ctx);

    return {
      ...initialProps,
      // Styles fragment is rendered after the app and page rendering finish.
      styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
    };
  }

Eu também usei o seguinte guia: https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js

Idk porque não está funcionando, ServerStyleSheets passa opções para StylesProvider e deve funcionar, certo?
https://github.com/mui-org/material-ui/blob/master/packages/material-ui-styles/src/ServerStyleSheets/ServerStyleSheets.js#L24

Você @oliviertassinari poderia me dar uma ideia de por que não está funcionando corretamente?

@guiihlopes altere a ordem dos seus plugins e coloque jssExtend antes dos presets. ;)

@guiihlopes altere a ordem dos seus plugins e coloque jssExtend antes dos presets. ;)

Já tentei, ainda não funcionou... :/

Embora seja possível adicionar o plug-in de extensão ao StyleProvider , as definições de tipo TS para estilo JSS no MUI não permitem a sintaxe de extensão.

Embora seja possível adicionar o plug-in de extensão ao StyleProvider , as definições de tipo TS para estilo JSS no MUI não permitem a sintaxe de extensão.

Acho que @mifrej está certo. Eu tentei quase todas as maneiras mencionadas aqui, mas nenhuma delas funciona mais. Talvez eles costumavam trabalhar antes!

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

chris-hinds picture chris-hinds  ·  3Comentários

ryanflorence picture ryanflorence  ·  3Comentários

sys13 picture sys13  ·  3Comentários

ericraffin picture ericraffin  ·  3Comentários

ghost picture ghost  ·  3Comentários