Material-ui: [RFC] Migrar a componentes con estilo

Creado en 11 feb. 2017  ·  164Comentarios  ·  Fuente: mui-org/material-ui

¿Podemos cambiar a componentes con estilo ?


Comparación obsoleta

Tiene muchas ventajas frente a JSS.
¡Aquí la tabla de comparación, y la próxima versión incluso evitará que los estilos SSR se vuelvan a renderizar!

Características | componentes de estilo | reaccionar-jss
------------ | ------------- | -------------
Sin requisitos de construcción | ✅| ✅
Pequeño y ligero | ✅ | ✅
Soporta CSS global | ✅ | ✅
Admite la totalidad de CSS | ✅ | ✅
Colocado | ✅ | ✅
aislado | ✅ | ✅
No rompe los estilos en línea | ✅ |✅
Fácil de anular | ✅ | ✅
Tematización | ✅ | ✅
Representación del lado del servidor | ✅ | ✅
Sin componentes de envoltura | ❌ | ✅
Soporte de ReactNative | ✅ | ❌

Leyenda: ✅ = Sí, ❌ = No, 😕 = Un poco, se refieren a notas o paréntesis

discussion enhancement

Comentario más útil

@oliviertassinari Según nuestras pruebas de rendimiento en curso, como se indica en https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897 Solo espero que el equipo de materiales no solo elija componentes con estilo porque son populares. Es lento. Siempre ha sido. Personalmente, es un punto de ser un desarrollador que necesita aprender cosas como la notación JS de CSS.

Es parte del trabajo.

Facilitar la vida de los desarrolladores es parte de nuestro trabajo como mantenedores de paquetes (para mis propios proyectos de los que estoy hablando), pero hay una línea entre hacerlo fácil y hacerlo eficiente.

Es por eso que solo uso makeStyles y siempre lo he hecho desde que se presentó.

El arquitecto de mi último equipo no escuchó y siguió adelante con componentes con estilo y ahora el sitio es lento. Cambié a makeStyles en una rama de prueba y ahorré un 50% (10 segundos) en TTI en dispositivos móviles, pero tal como dijiste en ese comentario, la notación JS no es conocida por todos, por lo que no fue aceptada.

Internamente, el material puede elegir lo que quiera, pero hágalo de manera predeterminada.

Todos 164 comentarios

@kybarg ¡ Gracias por abrir ese número! El CSS-in-JSS es un campo en movimiento, es posible que las elecciones que hicimos en el pasado ya no sean válidas a medida que cambian los problemas y las soluciones.

¿Por qué no componentes con estilo en el pasado?

Hemos estado comparando las diferentes soluciones de estilo disponibles antes de seleccionar JSS.

No elegimos componentes con estilo por las siguientes razones:

  • Costo de la abstracción. css-in-js-perf-tests es un buen recurso, los componentes con estilo usan glamour internamente.

    • 126 kb descomprimidos sobre 22 kb para JSS

    • El tiempo para pintar por primera vez es más lento. Compare el tiempo para pintar por primera vez en las demostraciones equivalentes de https://github.com/MicheleBertoli/css-in-js , JSS funciona un 40 % mejor.

  • Exponer el nombre de clase y el poder del selector profundo de CSS permite una implementación eficaz. Por ejemplo, con <Grid /> : #6010.
  • No es posible la concurrencia de representación del lado del servidor. Se basa en un singleton para recopilar los estilos, mientras que JSS crea una nueva instancia para recopilar estilos en cada solicitud. La cocción al vapor es realmente limitada.

En realidad, los componentes con estilo ni siquiera eran una cosa (existente) cuando @nathanmarks comenzó a trabajar para alejarse del estilo en línea.

la tabla de comparación

Admite CSS global

Con https://github.com/cssinjs/jss-global puedes escribir cosas como

const styles = {
  '<strong i="35">@global</strong> body': {
    color: 'green'
  }
}

Fácil de anular

¿Cómo es que esto no es fácil? Del lado de Material-UI, tenemos una tabla de orden de inyección predefinida. En la tierra del usuario, pueden usar afrodisíacos que implementan una gran API de anulación de afrodita.

Sin componentes de envoltura

No tenemos ningún componente contenedor en el lado Material-UI. Podríamos haber estado usando withStyles pero no lo hacemos por motivos de rendimiento. Exponemos ese componente de orden superior a los usuarios para abstraer la implementación del contexto.

Tematización

Usamos jss-theme-reactor internamente. JSS está exponiendo una API de bajo nivel que lo hace posible.

Soporte de ReactNative

Ese es un buen punto, la API de reacción con estilos es bastante interesante. ¡Eso es algo que podríamos estar mejorando!

El futuro

En el futuro, creo que el camino más prometedor es tener una API que permita cambiar la implementación del estilo. Eso nos traería dos beneficios:

  • Material-UI está menos acoplado a cualquier solución de diseño
  • Los usuarios que usan componentes con estilo / aphrodite/... por su parte pueden guardar la sobrecarga de JSS utilizada internamente.

react-toolbox está siguiendo ese camino . Mi única preocupación sería con los gastos generales que está agregando. Quiero decir, ¿vale la pena?

Estoy agregando @kof y @mxstbr al bucle.

@kybarg En realidad, no estoy seguro de entender completamente lo que sugiere.
No estamos usando react-jss como sugiere su pregunta.

Cuando dice nosotros, ¿está hablando de usuarios o Material-UI?

Mis puntos son:

  • styled-components es una biblioteca de nivel mucho más alto que el núcleo JSS, seguro que puede usarla en su capa de aplicación.
  • La tabla de comparación anterior es sobre react-jss, no sobre el núcleo JSS y es una opinión subjetiva de Max. En parte no es cierto y en parte solo es una mirada desde una perspectiva específica que no vemos desde la tabla.
  • Estamos trabajando en la representación de reglas dinámicas para un estilo dinámico más eficiente, jss-theme-reactor ya hace el trabajo en este momento, es solo una cuestión de optimización, que probablemente no sea muy relevante para MUI.
  • Lo que MUI usa internamente debería estar totalmente fuera de la preocupación del usuario final. Todo lo que un usuario necesita hacer debería ser posible sin siquiera saber qué MUI está usando internamente o al menos su sintaxis cssinjs más o menos regular para la creación de temas.
  • Necesitamos obtener casos de uso que MUI no admita en este momento y resolverlos. Siempre estoy feliz de ayudar en el proceso de integración y estoy disponible en gitter.
  • ¿Qué es el soporte nativo de reacción de todos modos? ¿No es solo un subconjunto de la plataforma web? Si es así, debería funcionar, de lo contrario, hágame saber qué JSS debe poder hacer para admitir react-native, aquí está el problema .

Esa tabla es de hecho muy subjetiva y se basa en mi propia experiencia. FWIW, styled-components funciona con cualquier biblioteca de componentes de terceros:

import { Button } from 'material-ui'

const MyButton = styled(Button)`
  // Only these styles will be overridden
  background: red;
`

Esto funciona siempre que los componentes adjunten el accesorio className internamente a algún nodo DOM:

const MaterialUIButton = (props) => {
  /* ... */
  // As long as props.className is attached, the above usage will work
  return <button className={`bla ${props.className}`} />
}

¿Qué es el soporte nativo de reacción de todos modos? ¿No es solo un subconjunto de la plataforma web?

No, no es tan fácil 😉 Sin embargo, agregar soporte a JSS no debería ser difícil, ya que todo lo que tienes que hacer es pasar el objeto de estilo a StyleSheet.create() . Esto requiere un poco más de esfuerzo por parte de styled-components para que las cadenas CSS funcionen.


He estado hablando con @javivelasco por un tiempo y me encanta a dónde va con react-toolbox . Su implementación es asombrosa y me encantaría ver que todas las bibliotecas de componentes de terceros la adopten. ¡Hazle un ping para que pueda participar con sus ideas aquí!


No es posible la concurrencia de representación del lado del servidor. Se basa en un singleton para recopilar los estilos, mientras que JSS crea una nueva instancia para recopilar estilos en cada solicitud. La cocción al vapor es realmente limitada.

Totalmente sin relación, ¿le importaría comentar en este número sus ideas para una API que permitiría que este fuera el caso? No hemos decidido lo que vamos a hacer, por lo que agradeceríamos mucho su opinión.

Hola, pregunté sobre esto en gitter. Solo para obtener las opiniones de otros, lo publicaré aquí también:

Sé que material-ui _next_ está fuertemente invertido en una solución jss personalizada.
¿Alguien descubrió alguna ventaja seria de usar jss sobre componentes con estilo?

Si bien jss es bueno ya que permite varios patrones como decoradores (estilos de inyección) y complementos, creo que el enfoque sencillo de componentes con estilo es mucho más limpio ya que no hay necesidad de decoradores, configuración personalizada y complementos porque no es necesario.

En styled-comp, todos los componentes ya tienen estilo, por lo que no es necesario pasar estilos. y pasa accesorios que pueden evaluarse para producir un estilo diferente
sin configuración (createJss)
sin complementos (prefijo)
sin JSON DSL

Alguien tiene que cerrar este hilo.

@rainice jss no tiene decoradores, un HOC es un detalle de implementación de react-jss y no se usa aquí.

¿Por qué debería estar bloqueado? Es una discusión sana en mi opinión

Porque el contenido basado en el usuario final aquí (no los mantenedores de lib) es muy superficial y esto es comprensible porque no leyeron una sola línea de código detrás de lo que usan.

Dado que la elección de la solución de estilo se ha discutido extensamente , se ha documentado la lógica detrás de la decisión y el trabajo de desarrollo hacia la próxima versión principal está en curso , este no es un problema útil, por lo que voy a cerrarlo.

Con suerte, las personas son lo suficientemente maduras como para no seguir publicando en un hilo cerrado, pero podemos bloquearlo si surge la necesidad.

¡Ojalá hubiéramos podido avanzar ese hilo con una solución de estilo menos acoplada!
Sin embargo, creo que nuestra prioridad, por ahora, debería ser terminar la migración/mejora general de los componentes.

@mxstbr gracias por los componentes con estilo

Esto funciona siempre que los componentes adjunten el accesorio className internamente a algún nodo DOM

Esto podría valer la pena resaltarlo en algún lugar de su guía de uso cuando se publique mui:next . Este comentario me acaba de salvar.

Los estilos flexibles para IE10 no funcionan con jss pero funcionan con componentes con estilo como un encanto

@yhaiovyi Material-UI no es compatible con IE10.

Prefijo de proveedor evtl. Se solucionará pronto para jss, no significa que solucionará todos los problemas si mui nunca se probó en IE10

De todos modos, no he encontrado ningún otro problema además de css flex con IE10 hasta ahora.

Parece que tenemos 3 formas (podría ser más fácil, pero no todo son flores) para anular los estilos de interfaz de usuario de material con componentes con estilo. Aquí está mi esencia .

También puede obtener una API de componentes con estilo con unas pocas líneas de código: https://material-ui-next.com/customization/css-in-js/#styled -components-api-15-lines-

También puede usar styled-jss , ejemplo: https://codesandbox.io/s/32mvjyjyxq

el único inconveniente con JSS en general es la falta de autocompletado en los editores de código, como se dijo aquí también , pero los beneficios están ahí, analizar css a js como en los componentes con estilo es un poco sobrecargado

editar: acabo de notar el problema al que se hace referencia justo arriba, interesante

Lo que es molesto es el contexto de Mui y withStyles HOC no parecen funcionar bien con el núcleo react-jss y styled-jss ThemeProvider https://codesandbox.io/s/32mvjyjyxq (Intenté poner un Typography pero eso no funciona, edite: nvm, sigo jugueteando con eso)

Me pregunto si más tarde (post v1, supongo) no valdría la pena simplificar src/styles/withStyles y MuiThemeProvider + JSSProvider de doble capa, y tener algo un poco más simple como react-jss y styled-jss.

¡Totalmente por eso!

El 13 de marzo de 2018 a las 13:55, "Cyril Auburtin" [email protected] escribió:

Lo que es molesto es el contexto de Mui y withStyles HOC no parece funcionar.
bien con el core react-jss y styled-jss ThemeProvider
https://codesandbox.io/s/32mvjyjyxq

Me pregunto si más tarde (post v1, supongo) no valdría la pena simplificar
src/styles/withStyles y MuiThemeProvider + JSSProvider doble capa


Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/mui-org/material-ui/issues/6115#issuecomment-372655385 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AADOWAbwLOnRoypx9ANCZnKyalZyD0M9ks5td8HNgaJpZM4L-GwD
.

analizar css a js como en componentes con estilo es un poco sobrecargado

Al igual que analizar objetos a CSS es :wink: Analizar cadenas es aproximadamente a la misma velocidad, honestamente no importa. https://github.com/A-gambito/CSS-IN-JS-Benchmarks/blob/master/RESULT.md

Solución | Usar CSS | Usar estilos en línea | Tiempo de montaje (ms) | Tiempo de renderizado (ms)
:--- | :--- | :--- | :--- | :---
...
componentes de estilo | + | - | 182 | 146.84
estilo-componentes-desacoplamiento-celda | + | - | 213.53 | 152.39
...
reaccionar-jss | + | - | 198.97 | 297.74

@mxstbr , un analizador css completo escrito en js en tiempo de ejecución definitivamente tiene un precio. Ese punto de referencia no está midiendo su costo.

un analizador css completo escrito en js en tiempo de ejecución definitivamente tiene un precio.

Claro, pero no más que un analizador completo de CSS que maneja objetos en lugar de cadenas. Además de eso, los analizadores CSS que funcionan con cadenas CSS reales han sido optimizados y explorados durante mucho tiempo, mucho menos con los que manejan objetos. :sonrojo:

Tendría curiosidad acerca de comparar bootstraps CSS como un objeto con su analizador vs bootstraps CSS con stylis, nuestro analizador, pero estoy bastante seguro de que la diferencia será insignificante en el mejor de los casos.

Tendría curiosidad acerca de comparar bootstraps CSS como un objeto con su analizador vs bootstraps CSS con stylis, nuestro analizador, pero estoy bastante seguro de que la diferencia será insignificante en el mejor de los casos.

Sí, ese sería un punto de referencia apropiado, lo he probado un poco, trabajar con objetos es mucho más rápido, como 10-20 veces más rápido.

Pero, de nuevo, depende de qué complementos jss incluya, tenemos muchos complementos de azúcar sintáctico.

También tb. no importa si todos nos mudamos a la ISTF.

He probado un poco, trabajar con objetos es mucho más rápido, como 10-20 veces más rápido.

Claro, pero 10 ms (eso es lo que tarda stylis en analizar toda la hoja de estilos de arranque) frente a 1 ms de analizar todo el CSS de una aplicación no importará en el gran esquema de las cosas, ¿sabes? No hará ni romperá la aplicación de nadie.

De todos modos, dejemos de molestar a la gente con este problema con más notificaciones de las necesarias.

Por cierto. este punto de referencia parece ser más preciso: http://necolas.github.io/react-native-web/benchmarks/ No estoy seguro, aunque no depende de un caché después del primer análisis.

@mxstbr Si bien este problema ahora está bloqueado, un poco de competencia sana es buena para todos. Vuelva en cualquier momento: puede encontrarnos en el chat de gitter si un problema no es el lugar apropiado para la discusión.

Este problema tiene más de un año. Chicos, por favor dejen de comentarlo. Podemos mover la discusión a una nueva. Mucho ha cambiado desde que comenzó la discusión.

Pero tratemos de evitar problemas de bloqueo. Necesitamos seguir recopilando la mayor cantidad de comentarios posible para tomar mejores decisiones.

Creo que bloquear el problema como una herramienta para comunicar esto claramente está bien, nadie se ofendió por esto ni se tomó la libertad de expresión. En este caso está realmente bien.

Estoy reabriendo para recopilar más comentarios, tengo curiosidad por saber si esto es algo en lo que la gente todavía está interesada:

Capture d’écran 2019-03-10 à 10 38 56

Tenemos una encuesta de desarrolladores en curso y usaremos los resultados para actualizar nuestro MAPA DE RUTA.
Tenemos los siguientes requisitos con la solución de estilos:

  1. Tamaño del paquete . Queremos que las personas puedan usar un solo componente sin tener que pagar 20 KB comprimidos por él. Por clasificación:

    1. emoción es el mejor candidato en esta dirección: 10kB comprimido con gzip . Sin embargo, es utilizado por pocas personas. Si observa las estadísticas de descarga, ¿el 80% proviene del libro de cuentos ?

    2. Los componentes con estilo pesan alrededor de 16 KB comprimidos con gzip . Su ventaja proviene de la cantidad de personas que lo usan. ¿Quizás el 20% de los usuarios de React?

    3. JSS con un contenedor de reacción con un peso de aproximadamente 15 KB comprimido con gzip. Si observa las estadísticas de descarga, gran parte del uso proviene de Material-UI.

  2. rendimiento Queremos que la gente pueda personalizar nuestros componentes. Deben ser lo más rápido posible. El punto de referencia que pude hacer arroja la siguiente clasificación:

    1. emoción

    2. jss

    3. componentes con estilo

  3. API de personalización . Personalizar una variante debería ser fácil, personalizar un elemento anidado debería ser fácil, agregar una nueva variante debería ser fácil. En este momento, tenemos una API classes , una API de theme.overrides y la capacidad de tener nombres de clases deterministas globales.
  4. Interoperabilidad . Usar !important no es una solución.
  5. Soporte RTL

Solo he mencionado componentes de estilo, emoción y JSS, pero son alternativas diferentes: linaria, SASS, etc.

Creo que podría valer la pena agregar los siguientes dos problemas, ya que podrían ayudar a afectar la decisión cuando tendría tiempo para trabajar en la biblioteca CSS-in-JS que utiliza Material-UI:

@o-alexandrov ¿JSS sigue la misma estrategia que los componentes con estilo? No entiendo tu punto. ¿Podría aclarar? ¿Cual es la diferencia? ¿Cómo es mejor o vale la pena?

@oliviertassinari
En el mensaje anterior, no digo nada sobre styled-components , excepto que agradezco la idea de evaluar el uso de styled-components o cualquier otra biblioteca CSS-in-JS que tenga el equilibrio perfecto de:

  • experiencia del desarrollador (familiaridad y flexibilidad, contribuciones adicionales, uso real por parte de los desarrolladores, etc.)
  • rendimiento

Los enlaces a los dos problemas anteriores solo analizan el aspecto negativo actual de trabajar con JSS.
Olvidé dónde vi lo siguiente, pero recuerdo que hiciste un buen comentario de que para poder tomar decisiones, primero debemos agregar todo tipo de puntos de referencia para que las decisiones puedan evaluarse más fácilmente.

Personalmente, me gusta:

  • componentes con estilo sobre jss para una adopción comunitaria mucho más amplia.
    Creo que la adopción por parte de la comunidad es el aspecto clave que Material UI debe considerar.

@o-alexandrov Ok, en este caso, estoy marcando tu primer comentario como fuera de tema. En v5, queremos aislar los componentes principales de la solución de diseño. Ojalá podamos proporcionar versiones desnudas, JSS, emoción, linaria y componentes con estilo (por defecto) de los componentes. Esa es la visión. ¡Ahora la implementación va a ser un desafío!

Tamaño del paquete

Se demostró que styled-components estaba mejorando 12.3kB en @ 5.0.0-beta.8

API de personalización

Si introducen https://github.com/styled-components/styled-components/pull/2625 , ya sea en un paquete o en un paquete externo, creo que la API es paritaria con Mui, ya que carece de la API de componentes sin estilo que en algún momento podemos necesitar. , especialmente en sistemas heredados, pero no creo que necesite esa API en Mui con tanta frecuencia.

Fuera de eso,

No estoy seguro de qué información le gustaría recopilar ya que, según mi experiencia personal, styled-components ofrece las funciones que necesitamos.

Interoperabilidad.

¿Qué es esto para ti en este contexto? Puede anular las cosas en styled-components como cualquier otro marco que yo sepa.

Soporte RTL

¿No se basa esto en cómo codificamos los componentes? ¿Qué tiene para ofrecer exactamente styled-components o cualquier biblioteca CSS-in-JS para esto?

Mis pensamientos

Velocidad

Solía ​​​​ser más lento en comparación con otras soluciones, pero el soporte y el increíble esfuerzo de los colaboradores lo llevaron al punto en que se está volviendo aún más rápido que JSS.

Tamaño

v5 se está volviendo aún más delgado como dije 12.3kB de 16.2kB que representan su esfuerzo en este tema.

Familiaridad

La gente está familiarizada con la API ya que es la más popular, de hecho, la mayoría de la gente llama a styled-components refiriéndose a la API en lugar del paquete real cuando usamos la API styled(...) ... , en su mayor parte.

reaccionar nativo

Para Mui pesa mucho la web, pero la gente seguirá adoptando styled-components por eso.

Equipo central

Equipo central fuerte, a partir de hoy 81 números y 14 PR abiertos, estos son buenos números para la cantidad de personas que usan el paquete.

Además, personas como @mxstbr en realidad usan el paquete en spectrum , por lo que tiene experiencia en el mundo real al usar el paquete, eso es increíble, eso significa que realmente sabe cómo se siente usar el paquete.

Kit de herramientas

Bueno, no podría ser mejor https://www.styled-components.com/docs/tooling

Para autores de interfaz de usuario

A día de hoy, la adopción de styled-components para los componentes de Design System ha aumentado mucho; Atlassian, GitHub, Orbit y muchos otros.

Esto es bueno para Mui ya que no estarás solo, por lo que probablemente las personas ya lidian con situaciones potenciales que puedes encontrar y descubrieron cómo lidiar con ellas.

TL;RD

Apoyo styled-components .

Me gusta JSS porque la sintaxis de objetos para CSS se ha vuelto más fácil para mí, a veces soy perezoso e incluso paso esos estilos como style={{styles.dialogTitle}} estilo en línea, es fácil de refactorizar más adelante

Y se puede usar de diferentes maneras, con un contenedor de elementos como componentes con estilo https://material-ui.com/styles/basics/#styled -components-api

Realmente me gustan los componentes con estilo, pero recientemente descubrí que presenta una serie de problemas que dificultan que la sacudida de árboles funcione de manera consistente. Sé que el equipo de material-ui acaba de trabajar mucho para que el movimiento de árboles funcione completamente para esta biblioteca y, obviamente, se debe evitar cualquier regresión en eso.

Afortunadamente, la mayoría de sus problemas de sacudidas de árboles se resuelven usando babel-plugin-styled-components y configurando pure: true (ver https://www.styled-components.com/docs/tooling#dead-code-elimination ). Pero todavía quedan algunos problemas pendientes. Por ejemplo:
https://github.com/styled-components/babel-plugin-styled-components/issues/245

Otra es que el uso de una función de ayuda externa dentro de sus estilos puede romper el movimiento del árbol (a menos que configure terser/uglify para ignorar esa función específica), por ejemplo:

const Button = styled.button`
  font-size: ${externalHelperFunction()};
`

Creo que debería ser posible solucionar todos estos problemas para que el movimiento de árboles funcione correctamente, pero ciertamente puede ser complicado y no solo funciona de manera ideal tal como están las cosas actualmente. De hecho, sigo pensando que cambiar a componentes con estilo podría ser una buena idea, pero solo si estos problemas se pueden resolver.

@mbrowne No pude reproducir ningún problema con los componentes de estilo y sacudidas de árboles. El problema no incluye un ejemplo reproducible, así que traté de replicarlo con

// components.js
import React from "react";
import styled from "styled-components/macro";

const Wrapper = styled.div`
  color: blue;
`;

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

MyComponent.displayName = "FancyName";

export function OtherComponent() {
  return "only";
}

// App.js
import React from 'react';
import { OtherComponent } from "./components";

/* code */

con un create-react-app predeterminado. MyComponent no aparecerá en el paquete de producción.

¿Es algo con lo que solo rollup tiene problemas? Agradecería un ejemplo reproducible para entender el problema.

@eps1lon Creo que el problema aparece al configurar la propiedad estática en el componente con estilo, ¿puedes intentarlo?

const Wrapper = styled.div`
  color: blue;
`;

Wrapper.displayName = "FancyName";

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

@mxstbr Sí, aunque en ambos casos se incluyen componentes con estilo. Si bien la configuración de displayName en MyComponent no incluyó MyComponent en el paquete, aún incluye styled-components . Básicamente, elimina cualquier cosa que se haya hecho en MyComponent , por lo que originalmente pensé que se sacudía correctamente (solo busqué FancyName .

Pero aún incluye styled-components . Incluso si considera que una llamada de styled tiene efectos secundarios, consideraría

import React from "react";
import styled from "styled-components";

export function Wrapper() {
  // nonsense
  return styled.div``;
}

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

como libre de efectos secundarios al importar { OtherComponent } pero los componentes con estilo seguirán apareciendo en el paquete (incluso sin la macro). Entonces, o esto es un error o me estoy perdiendo algo grande. Incluso

// Wrapper.js
import React from "react";
import styled from "styled-components";

export default function Wrapper() {
  // side-effect free module even if styled has side-effects
  const Component = styled.div``;
  return <Component />;
}

// components.js
// commenting this out removes styled-components from the bundle
export { default as Wrapper } from "./Wrapper";

export function OtherComponent() {
  return "only";
}

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { OtherComponent } from "./components";
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<OtherComponent />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

incluirá styled-components (https://github.com/eps1lon/styled-components-shake).

Puede ser un error en los scripts de reacción, el paquete web o los componentes con estilo. En cualquier caso, depurar estos problemas es increíblemente difícil sin una reproducción.

Tiene sentido, gracias por investigar eso.

Para este caso de uso, no creo que importe si styled-components está incluido en el paquete (dado que todos los componentes deberían usarlo), sino si los componentes que no usa están incluidos, lo cual no es así. Suena como si fuera el caso, así que eso es bueno, ¿verdad?

@mxstbr Podría ser una preocupación importante, tenemos un par de componentes sin estilo y genéricos (Modal, Popper, TextareaAutosize, useMediaQueries, etc.), digamos que alguien usa

import { Modal } from '@material-ui/core';

con SASS. Esperaríamos un aumento de +5kB en gzip (a partir de hoy), no de +20kB en gzip.

Sin embargo, suponiendo que avancemos @material-ui/unstyled , en la práctica, podría no hacer ninguna diferencia ya que las personas podrían usar este paquete.

@eps1lon Lo siento, pensé que el problema con las propiedades estáticas sería más fácil de reproducir para otros, ya que parecía estar afectando a todos nuestros componentes... resulta que hay muchas cosas diferentes que desencadenan el problema, pero al menos en algunos casos simples funciona.

Creé una demostración reproducible aquí:
https://github.com/mbrowne/CRA-error-template/tree/styled-components-tree-shaking
git clone --single-branch --branch styled-components-tree-shaking [email protected]:mbrowne/CRA-error-template.git

Observe cómo solo el árbol Component1 se sacude correctamente.

La buena noticia es que creo que todos estos problemas tienen solución, y @mxstbr parece muy comprometido aquí. Pronto estaré trabajando en un PR que abordará al menos el problema de los accesorios estáticos (ya tengo un POC que funciona usando un complemento de Babel separado que escribí).

Abrí un PR en componentes de estilo babel-plugin para abordar los problemas de sacudir árboles. Si alguien aquí quiere ayudar a probarlo, me imagino que @mxstbr lo agradecería (y yo también, por supuesto):
https://github.com/styled-components/babel-plugin-styled-components/pull/248

Hola a todos, ¿dónde está este boleto actualmente? Estaría más que feliz de involucrarme y escribir algunos componentes con estilo para MUI si esa es la dirección en la que se dirige el proyecto en v5

Supongo que a menos que queramos hacer esto de una vez (dudo que queramos eso). Deberíamos comenzar haciendo que los componentes con estilo lean el tema desde jss o jss lea el tema desde los componentes con estilo. El objetivo debe ser que podamos migrar estilos por componente.

Esto probablemente debería suceder en otra rama. Si bien no queremos cambiar todo en el maestro de una sola vez, probablemente deberíamos lanzarlo con un cambio (en v5). De lo contrario, esto se vuelve aún más confuso.

Se solicitó la eliminación del comentario.

Hola chicos, yo también estoy listo para contribuir... una sucursal separada parece ser algo sensato para nosotros... ¡hagamos esto...!

@caprica-Six Gracias por la energía, pero no es necesaria una nueva sucursal. Deberíamos poder proporcionar una versión de componentes con estilo progresivamente (+ jss y emoción) (inestable durante v4), y hacer avanzar la historia sin estilo al mismo tiempo. Tengo un POC que necesito enviar. Los componentes con estilo (v5 beta) + accesorios dinámicos son un poco más lentos que los que tenemos con JSS y los estilos estáticos, pero esto aún debería ser aceptable.

@oliviertassinari , ¿hay algún lugar donde podamos involucrarnos? Estaba esperando a que un mantenedor me indicara la dirección correcta antes de saltar a cualquier cosa.

¿Por qué no prefieres la emoción a los componentes con estilo? Parece que la razón es que "[la emoción] es utilizada por pocas personas. Si observa las estadísticas de descarga, ¿el 80% proviene del libro de cuentos?", Pero esto es incorrecto. Se usa más que los componentes con estilo ( comparación ) y no veo por qué el 80% de las descargas provienen de un libro de cuentos. Claramente está creciendo mucho más rápido que el libro de cuentos.

Hago esta pregunta porque estaba harto de usar componentes con estilo (debido a múltiples problemas que estaba encontrando) y busqué una alternativa, y descubrí Emoción. Lo probé y solo encontré ventajas en comparación con los componentes con estilo.

Es más ligero, más rápido y tiene más funcionalidades: reenvío de propiedades, TypeScript listo para usar (y perfectamente compatible en comparación con los componentes con estilo), Next.js SSR listo para usar (sin tener que sobrescribir el archivo _app. js y archivos _document.js, lo que me llevó una hora manejar la primera vez)

Y además, se usa más que los componentes de estilo y claramente tiene un impulso.

@lcswillems Creo que también deberíamos apoyar la emoción para las personas que la prefieren. Pero no creo que deba ser el predeterminado.

  • "más ligero": no exacto: https://bundlephobia.com/[email protected] (12,2 kB) frente a https://bundlephobia.com/result?p=@emotion/ styled + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (13,1 kB sin tener en cuenta las dependencias compartidas)
  • "Next.js SSR listo para usar": creo que es un problema importante, en línea

Gracias por tu respuesta y corregirme.

  • "más ligero": tienes razón
  • "Next.js SSR listo para usar": ahora entiendo por qué pueden hacer SSR listo para usar y por qué su forma de hacerlo no es la buena.
  • "más usado que los componentes con estilo": no estoy seguro de si esto es confiable. Pero mi fuente puede no ser confiable también.
  • "más rápido": solo vi puntos de referencia obsoletos, así que no, no tengo ninguno.

El problema principal al que me enfrento es el reenvío/filtrado de accesorios: https://github.com/styled-components/styled-components/issues/439 . Me sucede muy a menudo y es un fastidio hacer el filtrado manualmente cada vez.

Pero con sus comentarios, la emoción parece ser una alternativa menos buena.

"más ligero": no exacto: https://bundlephobia.com/[email protected] (12,2 kB) frente a https://bundlephobia.com/result?p=@emotion/ con estilo + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (13.1 kB sin tomar

En el caso de Emoción, lo más probable es que no utilices el paquete @emotion/styled en favor de css accesorios + @jsx pragma. Además, es posible que no necesite el paquete emotion-theming , el ThemeContext ya está incluido en @emotion/core . Así que son 12,2 KB frente a 6,5 ​​KB.

en línea

Solo por curiosidad: ¿Qué significan estas actualizaciones para los usuarios de la biblioteca @material-ui/styles para componentes que no son MUI? En mi empresa lo usamos como base para una gran biblioteca de componentes internos, lo elegimos deliberadamente sobre styled-components y estamos muy contentos con él.

Solo pensé en verificar con anticipación si hay algún tipo de obsolescencia planificada para el paquete @material-ui/styles , para poder planificar en consecuencia.

De todos modos, ¡gracias por todas las cosas geniales que siguen proporcionando!

@nickjohnson-dev La migración a react-jss debería ser sencilla. ¿Funcionaría eso para su organización?

@oliviertassinari Creo que es probable que lo haga. Siempre que podamos mantener la API pública de los componentes casi igual ( classes anulaciones locales basadas en accesorios, anulaciones globales posibles en el tema), no creo que sea un problema cambiar los detalles de implementación.

¿Anticipa que habrá alguna documentación oficial para migrar de @material-ui/styles a las otras opciones de estilo después de que MUI esté más desacoplado? A primera vista, no veo ninguna característica que falte en react-jss que estamos aprovechando en @material-ui/styles , pero no estoy seguro si me falta algo especial que esté haciendo el paquete MUI entre bastidores.

@nickjohnson-dev Haremos nuestro mejor esfuerzo.

Si entiendo correctamente se producirá el siguiente problema.
Tenemos los ComponentA reutilizables. Hacemos el ComponentB que usa ComponentA .

const ComponentA = ({className}) => (
  <div className={className}>
    <div className='inner' />
  </div>
);

const ComponentB = ({ className, classNameInner }) => (
  <div className={className}>
    <div className='inner'>
      <ComponentA className={classNameInner} />
    </div>
  </div>
)

const StyledComponentB = styled(ComponentB)`
     ???
`;

Observe cómo tanto ComponentA como ComponentB tienen el elemento con el mismo className='inner' . ¿Cómo apuntaremos al elemento .inner solo en ComponentB ?

Hola @oliviertassinari , gracias por compartir todo el pensamiento detrás del diseño de la próxima versión de Material UI.

Y gracias también por Material UI. Ahora mismo estoy construyendo un sistema de diseño encima.

En cuanto a la adopción styled-components , parece que es una decisión tomada, y el trabajo hacia ese objetivo ya comenzó.

Sin embargo, comparto algunas de las observaciones realizadas por @croraf y @lcswillems

Algo grandioso del estilo actual de Material UI es la propiedad classes .

Es una idea simple que ayuda mucho con la personalización del estilo y la capacidad de mantenimiento porque escribir classes es parte de la interfaz pública. Por ejemplo, si necesito personalizar algo y uso un selector como & .Component-root nada garantiza que Component mantendrá esa clase css en todas las versiones. Al tener <Component classes={{root: ....}} /> al menos puedo obtener un error de verificación de tipo (si uso TypeScript) sobre el cambio de interfaz.

Como autor de componentes, puedo decidir documentar clases que son públicas (y admitidas) y dejar otras sin documentar.

Usé style-components durante aproximadamente 2 años. Es cierto que es popular y evolucionó mucho. Pero, en los ejemplos de documentación de MUI, veo el mismo problema que menciona @croad : usar un selector descendiente & .inner es muy frágil porque puede propagar los estilos a los subcomponentes (y desde mi propia experiencia puedo decir eso no es un caso de esquina... me pasó un par de veces). Dos posibles soluciones son:

  • Use &.inner y luego use ${props.className}.inner todas partes. Hice eso muchas veces, y es doloroso escribir.
  • Use > .inner pero luego depende de la estructura del componente. Agregue algunos div adicionales en el medio y se rompe.

Es cierto que JSS no es popular. Lo aprendo gracias a MUI. Pero después de trabajar durante tanto tiempo con styled-components , encontré el enfoque de los estilos MUI refrescante y más fácil de trabajar (después de un tiempo, tener el HOC con estilo en todas partes agrega mucho trabajo adicional y comencé a odiar esos HOCs... al menos esa es mi experiencia personal). Emoción coincide más o menos con el enfoque actual. Y después de leer sus comentarios y algunos de los problemas sobre el rendimiento de JSS en ciertos casos, estoy evaluando usar Emotion para el sistema de diseño.

Sin embargo, te veo tan convencido de styled-components que me encantará ver más ejemplos de cómo resolver la personalización de estilo usando accesorios classes . Los que están disponibles en los documentos MUI actuales comparten los problemas que mencioné anteriormente.

¿Hay otras formas de usar styled-components con el prop de clases? ¿Cuáles son tus pensamientos al respecto?

JSS es lo suficientemente bueno y es muy útil de usar. ¿Hay alguna razón fuerte para mudarse?

Personalmente, creo que el componente con estilo es una especie de paso atrás y, para ser honesto, JSS fue la razón principal por la que comencé a usar esta biblioteca.

@powerfulj ¿Por qué prefiere JSS a los componentes con estilo? Tuve que elegir entre los dos y los componentes con estilo me parecieron mejores.

@lcswillems
Me gusta porque creo que no introduce un nuevo componente y, en cambio, solo opera en las propiedades. Si realmente necesita un nuevo componente reutilizable con estilo, puede crearlo fácilmente con la solución JSS.

También es más rápido convertir de estilo en línea a estilo JSS, lo cual es conveniente para mí, ya que generalmente uso estilos en línea durante la implementación y luego lo convierto a JSS si se hace más grande y se reutiliza.

El lado negativo es que si tiene algo de CSS (como de las herramientas de desarrollo del navegador) y necesita convertirlo a JSS, debe dedicar más tiempo a ajustar la sintaxis. Con el componente con estilo, esto va más rápido.

Solo para compartir mi hallazgo con respecto a este problema.
Traté de migrar algunas demostraciones a componentes con estilo según lo requerido por #16947. El problema es con el tema por defecto. makeStyles acepta opciones donde se puede pasar el tema predeterminado. Hay un envoltorio makeStyles que proporcionará defaultTheme . Entonces useStyles hook comprobará si ThemeProvider proporciona el tema, y ​​si no, inyecta defaultTheme .

Parece que no existe tal funcionalidad en los componentes con estilo. En ausencia de ThemeProvider defaultTheme solo se puede inyectar con el método .attrs . Podemos crear algo similar al envoltorio makeStyles

import styledWithoutDefault from 'styled-components';
import defaultTheme from './defaultTheme';

const styled = Component => {
  return styledWithoutDefault(Component).attrs({ theme: defaultTheme });
};

export default styled;

Pero el método .attrs simplemente sobrescribirá el tema proporcionado por ThemeProvider si corresponde. Y actualmente no sé cómo resolver este problema.

Otro problema es que makeStyles usa jss-plugin-default-unit preset y parece que los componentes con estilo no lo son. Por lo tanto, los componentes con estilo no se agregan px para devolver el valor de la función spacing() .
La posible solución al último problema es usar Styled-JSS y no componentes con estilo.

Me complace escuchar sus ideas/sugerencias.

@fyodore82 .attrs funciona como una función (ver https://www.styled-components.com/docs/api#attrs), así que esto funcionará:

```js
.attrs(({ tema = tema predeterminado, ...accesorios }) => ({ ...accesorios, tema }))
````

@croraf

Me gusta porque creo que no introduce un nuevo componente y, en cambio, solo opera en las propiedades.

Creo que te has perdido algo muy bueno de los componentes con estilo: el accesorio css . Le permite agregar CSS a un componente sin tener que crear uno nuevo.

También es más rápido convertir de estilo en línea a estilo JSS, lo cual es conveniente para mí, ya que generalmente uso estilos en línea durante la implementación y luego lo convierto a JSS si se hace más grande y se reutiliza.

Con la propiedad CSS, tenga en cuenta que un componente con propiedad CSS no tiene un atributo style , ya se convirtió en un componente con estilo y, por lo tanto, tiene class . Si el CSS crece y se reutiliza, también puede crear un nuevo componente.

El lado negativo es que si tiene algo de CSS (como de las herramientas de desarrollo del navegador) y necesita convertirlo a JSS, debe dedicar más tiempo a ajustar la sintaxis. Con el componente con estilo, esto va más rápido.

Estoy de acuerdo. Esta es la razón principal por la que no lo usé. La mayor parte del CSS escrito en línea está escrito en CSS, no en JSS. Entonces, si desea usar algún código de StackOverflow, primero debe convertirlo a JSS, lo cual es muy doloroso.

Otros argumentos adicionales que me hicieron usar Styled-components:

  • Es más doloroso escribir JSS: debe agregar comillas, no tiene resaltado de sintaxis (o no pude encontrar uno).
  • Es más difícil de entender para los recién llegados. Todo el mundo conoce CSS, por lo que todo el mundo podría leer fácilmente el código con componentes Styled, lo que no es el caso con JSS (la sintaxis de JSS es generalmente un poco rara y en particular para pseudoselectores y consultas de medios).
  • El código es mucho menos legible. Para ilustrar este punto, reescribí este ejemplo de componente de tarjeta con componentes con estilo para mostrar cuánto más claro puede ser con ellos.

Versión JSS:

import React from 'react';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

const useStyles = makeStyles(theme => ({
  card: {
    display: 'flex',
  },
  details: {
    display: 'flex',
    flexDirection: 'column',
  },
  content: {
    flex: '1 0 auto',
  },
  cover: {
    width: 151,
  },
  controls: {
    display: 'flex',
    alignItems: 'center',
    paddingLeft: theme.spacing(1),
    paddingBottom: theme.spacing(1),
  },
  playIcon: {
    height: 38,
    width: 38,
  },
}));

export default function MediaControlCard() {
  const classes = useStyles();
  const theme = useTheme();

  return (
    <Card className={classes.card}>
      <div className={classes.details}>
        <CardContent className={classes.content}>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <div className={classes.controls}>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon className={classes.playIcon} />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </div>
      </div>
      <CardMedia
        className={classes.cover}
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

Versión de componentes con estilo:

import React from 'react';
import styled from 'styled-components';
import { useTheme } from '@material-ui/core';
import MuiCard from '@material-ui/core/Card';
import MuiCardContent from '@material-ui/core/CardContent';
import MuiCardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import MuiPlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

export default function MediaControlCard() {
  const theme = useTheme();

  return (
    <Card>
      <Details>
        <CardContent>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <Controls>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </Controls>
      </Details>
      <CardMedia
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

const Controls = styled.div`
  display: flex;
  align-items: center;
  padding-left: ${props => props.theme.spacing(1)}px;
  padding-bottom: ${props => props.theme.spacing(1)}px;
`

const PlayArrowIcon = styled(MuiPlayArrowIcon)`
  height: 38px;
  width: 38px;
`

Finalmente, no pude encontrar ninguna ventaja de usar JSS.

La propiedad css es muy buena y básicamente resuelve las desventajas que mencioné. (los imitadores forman componentes con estilo: D)

En cuanto a la comparación de los dos ejemplos, no me parece muy legible y duplica la cantidad de componentes.

@lcswillems

Sin argumentar a favor de una solución u otra, solo recogiendo un par de sus puntos:

si desea usar algún código de StackOverflow, primero debe convertirlo a JSS, lo cual es muy doloroso

Existe una extensión VSCode para convertir CSS a CSS-in-JS, aunque no siempre funciona a la perfección. De todos modos, no lo llamaría doloroso.

no tienes resaltado de sintaxis

No entiendo muy bien este argumento. Es solo un objeto JS, por lo que el resaltado de sintaxis de cualquier editor funciona:

image

(¿pero tal vez estás buscando algo más específico?)

En cuanto a la comparación de los dos ejemplos, no me parece mucho más legible. Si bien la falta de accesorios className es posiblemente más limpia, no es obvio en el bloque de código JSX principal si los componentes se refieren a componentes nativos de MUI o rediseñados sin tener que hacer una referencia cruzada de los componentes styled() . En un componente más grande, estos podrían estar muy alejados.

Las invocaciones styled() son (para mí) menos legibles que el objeto JSS (aunque imagino que te acostumbras a ellas).

@powerfulj ¿Por qué prefiere JSS a los componentes con estilo? Tuve que elegir entre los dos y los componentes con estilo me parecieron mejores.

Porque yo mismo soy un desarrollador de Typescript y prefiero construir todo en el objeto Typescript. Especialmente odio las cuerdas.

Aunque necesitamos transferir el código CSS al código JSS debido a la diferencia, sigo prefiriendo leer el código JSS porque la estructura se parece al CSS tradicional (orientado a la clase), dedicaría más tiempo a leer el código del componente con estilo porque es más largo y puede estar aquí y allá.

Creo que las personas reclamaron este cambio solo porque tenían experiencia en el componente Styled en el pasado. Me da la sensación de "¿por qué no elegimos una biblioteca con la que estamos familiarizados pero sin ningún beneficio obvio?".

Desde mi punto de vista, JSS es útil, podemos organizar objetos usando todas las formas de Javascript como

{
...compartidoJSS1,
...compartidoJSS2,
lo que
}

También tenemos temas dinámicos integrados con tipos y obtuvimos todas las sugerencias de tipo de los tipos className y css.

Para los nuevos desarrolladores, especialmente los desarrolladores de Typescript, simplemente amarían JSS.

FYI, es posible anidar algunos componentes con estilo si no siempre desea un componente separado para todo. En general, se desaconseja, ya que el uso de componentes separados con nombres significativos se considera más limpio y más legible de acuerdo con la filosofía de componentes con estilo, pero los documentos dicen que está bien si se "usa con moderación". Y, por supuesto, para cualquiera que no comparta esa filosofía, es libre de anidar más. Como ejemplo de lo que quiero decir con anidar:

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

Consulte https://www.styled-components.com/docs/faqs#can -i-nest-rules para obtener más detalles.

Las discusiones sobre las preferencias de estilo de codificación pueden continuar para siempre.

Después de usar styled-components por un tiempo, me gusta más el enfoque JSS porque:

  • Cuando los estilos se hacen más largos, generalmente los muevo a un archivo separado.
    También lo he hecho con styled-components , y encuentro que useStyles / makeStyles es más fácil de escribir, leer y mantener. P.ej. import useStyles from './MyComp.styles' vs import {XStyled, YStyled,...} from './MyComp.styles' ... mantener esas variaciones ...Styled con sus tipos en TS es molesto.
  • Tiendo a hacer las cosas de manera progresiva: primero empiezo con un borrador usando divs y clases, y luego los refactorizo ​​en componentes. Cuando uso styled-components lo hago usando clases internas (como en el ejemplo de @mbrowne), pero requiere más trabajo de refactorización. Encontré el enfoque useStyles mucho más cómodo para trabajar con ese flujo de trabajo.
  • Los literales de plantilla son buenos para pegar código CSS, pero son terribles cuando tienes que usar variables de tema/prop. El problema del código de pegado es fácil de resolver con un complemento, pero la edición con variables y funciones dentro del literal de la plantilla no tanto.

Pero estas son mis preferencias personales, las tuyas pueden ser diferentes.

Mi mayor pregunta abierta es sobre el cambio classes uso.

Los ejemplos de uso de className y clases internas tienen problemas (ver mi comentario anterior). El accesorio css en styled-components no es una opción para resolver esos problemas. A diferencia de la función css en Emotion, la propiedad css depende de estar adjunta a un componente (lo que significa que no puede usarla en un estilo de código useStyle/makeStyles/classes ).

La vinculación de estilos a un componente no es una decisión de diseño menor. Para mí, es lo bueno y lo malo de JSS. Los componentes con estilo y Emotion se basan en complementos de Babel e interactúan con React para manejar el almacenamiento en caché y la generación de nombres de clase para SSR. Lo bueno de JSS es que no necesita ningún complemento de Babel. La parte mala es que SSR en JSS requiere más trabajo, y he visto errores informados en esa área.

Volviendo a MUI, tengo la impresión de que adoptar componentes de estilo significa usar className y clases internas como la única forma de personalizar estilos. El estilo se vuelve más consistente en todos los marcos: puede usar styled o css prop, siempre que el componente use el className que está bien.

Pero para mí, quitar los classes es dar un paso atrás. Ese accesorio ayuda a documentar y escribir personalizaciones de estilo de verificación. Tal vez sea posible encontrar un término medio, como usar componentes con estilo pero manteniendo el soporte para classes (sin la necesidad del truco de la clase interna). No pude encontrar nada en la API de componentes con estilo que ayude en ese caso. Por eso puede ser bueno evaluar cuáles son los problemas técnicos de JSS. Porque si la popularidad es el problema principal, la emoción también se está volviendo popular (consulte https://2019.stateofcss.com/technologies/css-in-js/#tools-section-overview), y puede ser fácil como una forma de reescribe makeStyles .

@dfernandez-asapp hizo algunos puntos excelentes simplemente respondiendo a una pequeña parte de este fwiw @styled-components admite el uso de un objeto similar a jss en lugar de una cadena https://www.styled-components.com/docs/advanced# estilo -objetos

Aunque es bastante decepcionante, los componentes de estilo eliminaron el soporte de mecanografiado de primera clase y, en general, estoy de acuerdo con usted en que parece un paso atrás en las otras formas que describió.

FYI, es posible anidar algunos componentes con estilo si no siempre desea un componente separado para todo. En general, se desaconseja, ya que el uso de componentes separados con nombres significativos se considera más limpio y más legible de acuerdo con la filosofía de componentes con estilo, pero los documentos dicen que está bien si se "usa con moderación". Y, por supuesto, para cualquiera que no comparta esa filosofía, es libre de anidar más. Como ejemplo de lo que quiero decir con anidar:

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

Consulte https://www.styled-components.com/docs/faqs#can -i-nest-rules para obtener más detalles.

¿Algún tipo de soporte para esto? ¿O tenemos que poner hilo por todas partes?

No entiendo por qué hay tanto entusiasmo por los componentes con estilo. Se siente como un paso atrás para ser honesto. Las propiedades CSS escritas de JSS con TypeScript son mucho más convenientes y fáciles de mantener, además hay verificación de sintaxis como parte de JS: cualquier editor moderno/configurado le dirá si alguna vez comete un error tipográfico e incluso lo ayudará con la finalización automática si así lo desea.

editar: está escrito, vea la respuesta de South-Paw a continuación.

¿Parece que @martinjlowm tiene mecanografías?

image

Consulte: https://styled-components.com/docs/advanced#style -objects

Dices que no entiendes la exageración... pero tampoco entiendo todo el odio que recibe. 🤷‍♂

Los componentes de emoción y estilo son grandes mejoras sobre los objetos de estilo CSS IMO

¿Parece que @martinjlowm tiene mecanografías?

...

Consulte: https://styled-components.com/docs/advanced#style -objects

Dices que no entiendes la exageración... pero tampoco entiendo todo el odio que recibe. 🤷‍♂

Los componentes de emoción y estilo son grandes mejoras sobre los objetos de estilo CSS IMO

¡Veo! No sabía que admitía objetos como ese. Mi preocupación estaba relacionada con CSS en las cadenas de plantilla, pero si los objetos son una opción, ¡entonces no tengo nada en contra!

Obviamente, JSS tampoco es perfecto, lo sé, las hojas reutilizables generadas por el servidor serían una característica excelente, ¿los componentes con estilo lo admiten de alguna manera? ¿Alguien sabe?

En este momento, se siente estúpido tener que eliminar las hojas de estilo generadas por el servidor y obligar al cliente a volver a renderizar todos los estilos :(

¿Parece que @martinjlowm tiene mecanografías?
...
Consulte: https://styled-components.com/docs/advanced#style -objects
Dices que no entiendes la exageración... pero tampoco entiendo todo el odio que recibe. 🤷‍♂
Los componentes de emoción y estilo son grandes mejoras sobre los objetos de estilo CSS IMO

¡Veo! No sabía que admitía objetos como ese. Mi preocupación estaba relacionada con CSS en las cadenas de plantilla, pero si los objetos son una opción, ¡entonces no tengo nada en contra!

Obviamente, JSS tampoco es perfecto, lo sé, las hojas reutilizables generadas por el servidor serían una característica excelente, ¿los componentes con estilo lo admiten de alguna manera? ¿Alguien sabe?

En este momento, se siente estúpido tener que eliminar las hojas de estilo generadas por el servidor y obligar al cliente a volver a renderizar todos los estilos :(

También me gustaría aclarar que los literales de plantilla etiquetados también se pueden escribir. TypeScript los marcará correctamente como no válidos y el servicio de idioma proporcionará las sugerencias de autocompletado, etc.

image

@Zurdo

Los componentes de emoción y estilo son grandes mejoras sobre los objetos de estilo CSS IMO

Todavía estoy confundido por qué cualquier desarrollador de React estaría interesado en esto. Si desea poner su CSS en cadenas de plantilla, ¿por qué no usa Angular y también pone su HTML en cadenas de plantilla? La fuerza de React es que los elementos JSX son realmente solo objetos JS que tienes mucho poder para examinar y transformar, y lo mismo ocurre con JSS.

Todo lo que impulsa el movimiento CSS en JS es el hecho de que JS es muy superior a CSS para hacer cosas dinámicas, y el poder de los objetos JS no es una pequeña parte de eso.

El hecho de que styled-components admita objetos es una especie de pista falsa:

  • Los admite, pero por alguna razón dice "Esto es particularmente útil cuando tiene objetos de estilo existentes y desea pasar gradualmente a componentes con estilo". Aparentemente, no ven el valor de poder manipular objetos y parece que los objetos de estilo siempre serán tratados como ciudadanos de segunda clase en su API.
  • Los documentos no aclaran si admite selectores de CSS del mundo real como este con JSS:
{
  color: 'black',
  '&$error': {
    color: 'red'
  }
}

Incluso Emotion respeta debidamente el valor de los objetos de estilo y los trata como ciudadanos de primera clase:

Escribir estilos con objetos es un patrón poderoso construido directamente en el núcleo de la emoción.

@lcswillems , está subestimando lo complicado que es crear todos estos pequeños HOC todo el tiempo (y el hecho de que la mayoría de los sistemas de importación automática no son lo suficientemente inteligentes como para saber si desea importar @material-ui/core/Card como Card o MuiCard (y si todavía está escribiendo declaraciones de importación a mano, está perdiendo mucho el tiempo))

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

Este tipo de cosas provoca una horrible fatiga de decisión, ya que constantemente tiene que decidir cómo nombrar cada contenedor y componente envuelto.

De esto habla @dfernandez-asapp cuando dice:

(Después de un tiempo, tener el HOC con estilo en todas partes agrega mucho trabajo extra y comencé a odiar esos HOC ... al menos esa es mi experiencia personal)

Los HOC prácticamente necesitan morir. Es un patrón obsoleto. Por ejemplo, react-redux salió con el gancho useSelector que es 100 veces más conveniente que el HOC connect , Apollo pasó de los HOC a los ganchos, lo mismo ocurre con el useStyles hook en esta biblioteca es más conveniente que withStyles .

La molestia de convertir CSS copiado y pegado a JSS es un problema mucho más solucionable, si hay interés, incluso haré una extensión VSCode para automatizarlo o un sitio web.

si hay interés, incluso haré una extensión VSCode para automatizarlo

@ jedwards1211 Hay paulmolluzzo.convert-css-in-js , pero si puede mejorarlo para JSS, estoy seguro de que sería bienvenido.

Sí, parece que definitivamente puedo mejorarlo, solo convierte propiedades CSS, no reglas ni selectores.

@ jedwards1211 Leí lo que dijiste y retrocedí por un momento: solo me recuerda los comentarios de las personas que discuten sobre el uso de tabulaciones en lugar de espacios. La realidad es que realmente no importa lo que use, siempre y cuando produzca un producto útil al final.

Deje sus opiniones/tomas calientes en Twitter o Reddit y podemos discutirlas allí, pero no sigamos descarrilando este problema con guerras de llamas sin sentido en cadenas de plantilla frente a objetos para CSS... Creo que todos podemos estar de acuerdo en que somos mejores. que eso 😄

Gracias por señalar que no vale la pena cambiar el status quo en MUI. 😉

Mi principal preocupación es si mis paquetes de paquetes web se inflan con una combinación de código de componentes con estilo y código JSS, porque hay demasiado JSS existente en nuestra aplicación para sacarlo y reemplazarlo con algo más, y/o porque me gustaría quedarme con JSS para nuestros estilos de todos modos.

Sin embargo, para ser justos, no me importan las pestañas frente a los espacios, pero si tuviera que escribir media docena de HOC para cada componente que hago, no estaría disfrutando de mi trabajo. Todas las herramientas existentes han tenido la capacidad de producir un producto útil; si algo fuera perfectamente conveniente de usar en todos los casos, no habría un cambio constante en el ecosistema, y ​​no estaríamos teniendo estos debates. Así que realmente hace una diferencia cuando lo piensas.

@jedwards1211 incluso si se ve obligado a usar componentes con estilo, hay una sintaxis alternativa css prop introducida en v4 que puede emplear, al menos, de esta manera no tendrá que preocuparse dar prefijos a los componentes con estilo (MuiCard, StyledCard, etc.).

import { Avatar } from '@material-ui/core';

// CSS is separate from the markup 👍
const avatarStyle = css`
  width: 32px;
  height: 32px;
  border-radius: 50%
`;

// No wrappers, prefixes in the markup (such as <MuiAvatar>, <StyledAvatar> etc.) 👍
function SomeComponent(props) {
  return <div> ... <Avatar css={avatarStyle} /> ... </div>
}

@ jedwards1211 su ejemplo también se puede simplificar a lo siguiente si estuviera usando componentes con estilo

const Card = styled(MuiCard)`
  display: flex;

  ${MuiCardContent} {
    flex: 1 0 auto;
  }

  ${MuiCardMedia} {
    width: 151px;
  }
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

@koistya el accesorio css es genial, aunque una advertencia importante es que está implementado con un complemento de Babel, por lo que no es para todos, especialmente para las personas que usan tsc para compilar sus archivos tsx. También supongo que causaría que TypeScript o al menos Flow se quejen de que el componente no tiene css prop.

Creo que principalmente estoy descontento con la posible interrupción que esto causaría en mi aplicación. @oliviertassinari mencionó el otro día que está pensando en hacer que styled-components sea el predeterminado en MUI v5. Y que, con suerte, sería opcional y aún se podría usar JSS, pero veremos si pueden lograrlo, ya sabes. Fue un shock: ¿realmente ha habido un referéndum completo sobre las preferencias de toda la base de usuarios? Hubiera esperado Emoción en todo caso porque es mucho más popular ahora.

También supongo que causaría que TypeScript o al menos Flow se quejen de que el componente no tiene css prop.

Se puede configurar.

Sin embargo, ¿realmente ha habido un referéndum completo sobre las preferencias de toda la base de usuarios?

Esto es imposible. Solo podemos asumir realmente que las personas que interactúan en GitHub son "nuestros" usuarios. Este número es el más votado que hemos tenido .

Hubiera esperado Emoción en todo caso porque es mucho más popular ahora.

¿Cómo mediste la popularidad?

⚠️ La emoción es significativamente menos elegida por los desarrolladores que los componentes con estilo (/6 por lo que recuerdo). Si considera las descargas en npm, elimine el recuento de descargas de storybook y react-select (es enorme).

@eps1lon esto es lo que estaba viendo: https://2019.stateofcss.com/technologies/css-in-js/

Sin embargo, me equivoqué, desafortunadamente todo lo que recordé fue la aparente tendencia al alza, aunque este no es un gráfico de popularidad a lo largo del tiempo (diseño de gráfico muy cuestionable):
image

Se puede configurar

¿Hay alguna manera de hacer que TypeScript asuma que todos los elementos JSX admiten un accesorio css ? No conozco una forma de configurar Flow para hacer eso.

EDITAR : afortunadamente encontré una forma para TypeScript, no estoy seguro de si hay una forma para Flow.

Este problema es el más votado que hemos tenido.

Veo. Suspiro

FWIW, uno de los principales contribuyentes de styled-components parece tener una actitud hostil hacia los sistemas de tipos:

https://github.com/styled-components/styled-components/issues/3012#issuecomment -583878486

Me sentiría mucho más tranquilo con la idea de migrar a componentes con estilo si pareciera que les importa la experiencia de desarrollo de los usuarios de TS/Flow...

@jedwards1211 hay una macro de Babel por css si eso ayuda. Especialmente viniendo de css/scss/less, no creo que a todos les guste pasar a la forma "estilo".

Sin embargo, ¿cuáles son los objetivos? ¿Qué pasa con el rendimiento? Por ejemplo, algunos sistemas admiten atomic css. Viniendo de Tailwinds, hace las cosas mucho más limpias y quizás más rápidas.

@hc-codersatlas puede encontrar algunos puntos de referencia en packages/material-ui-benchmark .

@koistya si lo leí correctamente, la emoción se ve mucho más rápido que el resto.

@oliviertassinari , ¿realmente la mayoría de los desarrolladores "hacen" esta elección? Según su mención de react-select y storybook, es probable que la mayoría de los desarrolladores usen lo que esté incluido con los componentes de la interfaz de usuario y el material; más esfuerzo con un sistema diferente además de lo que ya está usando el marco de la interfaz de usuario.

La mayoría de estos marcos de interfaz de usuario son de grandes corporaciones, es decir, algunas personas realmente están haciendo esta "elección".

Por ejemplo, Grommet usa componentes con estilo, que muchas empresas usan o usaban en 1 punto.

Y en esa nota, ¿qué significan las descargas de npm? El uso corporativo probablemente signifique firewalls y almacenamiento en caché interno de npm, lo que sesga estas métricas.

Si va a haber un cambio, cámbielo al mejor 1 según el mérito técnico y no algo como la popularidad. Predigo que si material-ui usa cualquier biblioteca, será la popular 1, ya que mui es en sí misma 1 de los marcos de interfaz de usuario más populares.

image

@South-Paw su simplificación propuesta no funcionaría, no puede usar ${MuiCardContent} en su ejemplo porque MuiCardContent no es un componente con estilo.

https://styled-components.com/docs/advanced#referring-to-other-components

Esencialmente, no hay forma de evitar todos los envoltorios HoC individuales. Aunque después de pensarlo por un tiempo, me di cuenta de que es básicamente la misma cantidad de decisiones de escritura/nombre que uno tiene que hacer con JSS.

@mbrookes @oliviertassinari , ¿cómo se manejarían los estilos condicionales y los estilos de componentes internos?
Por ejemplo, ¿cuál sería un equivalente basado en styled-components de lo siguiente?

// conditional class name
<MenuItem classes={{selected: classes.selectedItem}}>...</MenuItem>

// inner component class name
<Dialog classes={{paper: classes.dialogPaper}}>...</Dialog>

Me tranquilicé con la idea del cambio a styled-components , pero quiero asegurarme de que haya un plan sólido para manejar este tipo de casos de uso, porque asumo que la API tendría que ser muy diferente o depender en los nombres de clase de estilo BEM.

@ jedwards1211 ah mi error. Tenía la impresión de que el ejemplo era si fueran componentes con estilo, pero de hecho eso no funcionará si no lo son 👍

@ jedwards1211 clsx es algo que he visto emparejado con componentes con estilo en el pasado para clases condicionales. ¿Es eso lo que quieres decir?

Los proyectos que estoy haciendo en este momento usan componentes con estilo que envuelven componentes MUI según sea necesario, por lo que no he usado ninguno de los estilos condicionales de MUI.

@South-Paw eso (o classnames ) podría ser un detalle interno de la solución, pero lo que quiero decir es que dado que los envoltorios styled-components solo inyectan un solo className AFAICT, habría Realmente no sería una forma conveniente de pasar varios nombres de clase de anulación a un componente. En su lugar, es posible que tengamos que hacer algo como <Dialog Paper={StyledPaper}>...</Dialog> , y ni siquiera estoy seguro de qué para el ejemplo de clase MenuItem seleccionado.

@ jedwards1211 , ¿tendría tiempo para hacer un ejemplo rápido para que pueda entender mejor cuál es el caso de uso que está describiendo y dónde cree que está el problema? Me gustaría poder intentar ayudar con una solución, pero todavía no entiendo a qué se aplica esto 😄

Sí, estoy fuera de tiempo esta noche, pero mañana lo haré.
También tengo trabajo en progreso en jss-codemorphs , en última instancia, planeo hacer una extensión VSCode para convertir CSS pegado en JSS.

nunca he sido fanático de la sintaxis de los componentes con estilo o la forma en que se mantiene el paquete, no soy fanático de esta propuesta. Una de las cosas que más me gustan del material ui es la solución de estilo actual.

Es interesante notar que leí que Facebook podría estar abriendo una solución CSS-in-JS también. También podría ser valioso echarle un vistazo a eso cuando salga.

Con respecto al tema real en cuestión. No me gustan los componentes con estilo debido a que la experiencia de Typescript no es excelente. Los tipos suelen hacer más daño que ayudar. Tiempos de compilación lentos, interfaces locas (tratar de entender cómo funcionan los componentes con estilo a través de la interfaz es una pesadilla debido a toda esa magia anidada Pick ). Siempre que los componentes con estilo tengan este tipo de DX, se sentiría como un paso atrás para que material-ui adopte esto.

Es interesante notar que leí que Facebook podría estar abriendo una solución CSS-in-JS también.

@venikx ¿Qué tan probable es que suceda? La última vez que escuché sobre algo que podría sugerirlo fue en https://reactpodcast.simplecast.fm/75 , parecía ser un objetivo de 5 años.

¿Wow en serio? No sabía que ya dieron una "línea de tiempo". Por alguna razón, asumí que vendría al mismo tiempo que el modo concurrente. Demasiado.

Dicho esto, mi punto sobre los componentes con estilo sigue en pie. Prefiero usar la forma de manejar estilos de pure material-ui en lugar de usar componentes con estilo. Los tipos de componentes con estilo parecen estar ahí para el compilador y no tanto para la documentación.

Otra cosa molesta (pero probablemente sea una preferencia personal) es cómo se maneja la aplicación dinámica de estilos a un componente. Prefiero mucho agregar o eliminar classNames en lugar de incrustar esa lógica en el componente con estilo.

Material-ui api está realmente limpio en este momento, en mi humilde opinión.

No me gustan los componentes con estilo debido a que la experiencia de Typescript no es excelente.

He usado componentes con estilo y Typescript juntos en al menos 4 proyectos grandes hasta ahora y no he tenido ningún problema con los tipos; pueden ser un poco complicados cuando se hacen cosas en una biblioteca de componentes, pero eso estaría en el final de MUI - no en el extremo de los consumidores.

Tiempos de compilación lentos

No he experimentado esto en ningún proyecto en el que haya trabajado que los use. ¿Tiene un ejemplo en alguna parte de lo que quiere decir?

interfaces locas (tratar de entender cómo funcionan los componentes con estilo a través de la interfaz es una pesadilla debido a toda esa magia de selección anidada)

También podría considerar contribuir al proyecto @types si cree que puede mejorarlos de alguna manera. ¡Estoy seguro de que todos apreciarían cualquier trabajo allí si es una mejora con respecto a lo que hay ahora!

Prefiero mucho agregar o eliminar classNames en lugar de incrustar esa lógica en el componente con estilo.

No hay nada que le impida usar clases con componentes con estilo:

const Box = styled.div`
  height: 160px
  width: 160px;
  background-color: black;

  .red {
    background-color: red;
  }
`;

// simple usage
<Box className="red" />

// get more complex with conditionals and using something like clsx (https://www.npmjs.com/package/clsx)
const isRed = true;
<Box className={clsx({ red: isRed })} />

Vale la pena señalar que, a pesar de que algunos de los comentarios afirman lo contrario, hay 150 👍 y 27 🎉 en el tema de los padres y solo 18 👎 y 9 😕. Parece que hay una minoría vocal a la que no le gusta esta discusión y una mayoría que piensa que es un paso positivo 🤷‍♂

@South-Paw, el problema con la votación es que la única opción es: JSS vs componentes con estilo. La parte vocal se trata de que no les gusten los componentes con estilo y no que les guste JSS. Tal vez si la votación

Al final del día, cualquier cosa es mejor que JSS. Es viejo. Es lento y voluminoso (tamaño de paquete) y debe moverse. Entonces, los votos no respaldan su conclusión en absoluto.

¿Podrían pasarse todos al chat de Spectrum o algo que no llene este problema con ruido sobre personas que pelean entre sí para ver quién gana la discusión?

Estoy siguiendo el hilo para discusiones sobre este tema del equipo central.

Creo que está subestimando el juicio del equipo central y, personalmente, creo que debe dejar de discutir sobre este tema y confiar más en el equipo central; al final del día, depende del equipo central decidir la dirección de Material UI.

Si realmente tiene una opinión muy fuerte al respecto, Material UI tiene una licencia asombrosa del MIT, bifurque y continúe con la visión que tiene, lo animo a que lo haga, tal vez aprendamos en el futuro del entorno diverso.

Pero, por favor, te lo ruego, deja que el equipo central haga su trabajo, confía en ellos, porque son personas realmente competentes con habilidades increíbles.

Aquí hay algo hermoso para ver.

image

Al final del día, cualquier cosa es mejor que JSS. Es viejo.

@hc-codersatlas old == maduro -- ¿podría explicar por qué eso es un problema?

Ok, parece un tema candente, pero alguien puede confirmar esta información simple: ¿es actualmente posible usar una sintaxis similar a styled-components , con literales de plantilla etiquetados que se parecen a CSS, en las versiones actuales de Mui (4 o 5)? ?
No pude encontrar ninguna respuesta clara de sí o no a esta pregunta. Realmente no me importa la tecnología subyacente, solo la conveniencia del desarrollador. Copiar y pegar CSS de InVision es básicamente bastante útil en algunos casos.

Este problema se trata de la solución de estilo utilizada en Material-UI, su pregunta parece ser sobre cómo diseña su aplicación/cambia el estilo de los componentes, para lo cual puede usar cualquier solución:

https://material-ui.com/guides/interoperabilidad/

JSS tiene soporte básico para literales de plantilla como complemento.

Acabo de terminar de implementar un convertidor de CSS a JSS muy completo:

Con suerte, se eliminará la molestia de copiar y pegar CSS en estilos JSS.

@jedwards1211 ve esto
https://css2js.dotenv.dev/

@nainardev He notado que esas y otras utilidades son muy limitadas, convierten atributos CSS, pero no convierten selectores, selectores anidados, fotogramas clave de animación, consultas de medios, etc. Por eso hice mi herramienta muy completa, puede convertir con suerte, cualquier CSS completo que le arrojes.

Es posible que se haya perdido esta respuesta en alguna parte, pero quiero plantearla de todos modos. Estamos en proceso de migrar a los componentes de Material UI y de evaluar nuestra solución de estilo ( less frente a makeStyles frente a styled-components ), la mayor parte de nuestro estilo se realiza a través de menos archivos y la mayor parte del nuevo código MUI usa makeStyles , lo que quiero aclarar es que, dado que esto será parte de v5, ¿qué podemos hacer para reducir la deuda técnica relacionada con el diseño?

  1. ¿Estará makeStyles en v5? ¿Cómo funcionará con styled-components y temas? Por ejemplo, cómo se verá esto con styled-components :
const useStyles = makeStyles((theme) => ({
  paper: {
    padding: theme.spacing(2),
    textAlign: 'center',
    color: theme.palette.text.secondary,
  },
}));
  1. (v4) ¿Hay una mejor manera de recuperar el objeto theme en una cadena de plantilla con estilo que esta, para que pueda usarlo varias veces?
const StyledContainer = styled.div`
  color: ${({ theme }) => theme.palette.primary.main};
  padding: ${({ theme }) => theme.spacing(1)};
  background-color: ${({ theme }) => theme.palette.background.paper};
`;
  1. Suponiendo que makeStyles esté presente en v5, ¿deberíamos esperar algún impacto en el rendimiento si usamos tanto el proveedor de temas styled-components como el proveedor de temas de UI Material para una gran base de código?

Me encanta usar Material UI, ¡gracias por todo el trabajo duro!

@egilsster

  1. Sí, ya sea desde @ material-ui/styles o react-jss, lo veremos.
  2. https://material-ui.com/guides/interoperability/#theme ,
const StyledContainer = styled.div`
  ${({ theme }) => `
  color: ${theme.palette.primary.main};
  padding: ${theme.spacing(1)};
  background-color: ${theme.palette.background.paper};
  `}
`;
  1. Los principales problemas son 1. sobrecarga de configuración, costo único, 2. cargar dos tiempos de ejecución CSS-in-JS, que tiene una sobrecarga de ~ 15 kB comprimida, un costo similar, por ejemplo, incluido Sentry: https://bundlephobia.com /resultado?p=@sentry/navegador.

Gracias por una respuesta rápida, muy apreciada.

  1. Sí material-ui.com/guides/interoperability/#theme

Esto está muy bien. Algunas soluciones de herramientas probablemente sigan esto, el proyecto que estoy migrando no usa TS pero VSCode/servidor de idioma no parece tener idea de qué es theme en este caso y pierdo styled-components resaltado de sintaxis también.

Gracias de nuevo, seguiré siguiendo este desarrollo.

@oliviertassinari si hay una migración a componentes con estilo, ¿significará eso que ya no podemos confiar en las API de CSS como <ListItem classes={{ selected: myCustomClassName}}> para estar presentes?

@ jedwards1211 La API classes permanecerá.

Bueno. Estoy un poco confundido sobre cómo MUI usaría los componentes con estilo internamente, ya que los componentes con estilo solo pueden aplicar una sola clase al elemento raíz.

const MyRoot = styled('div')`
  // some nice styles
`;

const MyAwesomeChild = styled('div')`
  // some nice styles
`;

export function AwesomeRoot(props) {
  return (
    <MyRoot className={props.classes?.root}>
      <MyAwesomeChild className={props.classes?.child}/>
      {props.children}
    </MyRoot>
  );
}

¿Tiene eso sentido @ jedwards1211 ?

@yordis Sé que parece tan simple, pero ¿cómo refactorizaría selectores compuestos como https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js #L75 ?

Realmente no puedo pensar en una forma de preservar este comportamiento existente con styled-components , por lo que podría causar más cambios importantes de lo que la gente espera.

  outlined: {
    '&$disabled': {
      border: `1px solid ${theme.palette.action.disabledBackground}`,
    },
  },

El código existente y las anulaciones personalizadas de las personas probablemente también dependan de la especificidad de CSS en algunos casos.

¿Tal vez esto? No estoy seguro de seguir ya que esto me parece básico, probablemente me falta algo de contexto y/o información.

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

@yordis posiblemente. Como dije, aunque la gente probablemente no esté pensando en cuántos cambios importantes causará esto para los usuarios, no creo que ese ejemplo prevenga cambios importantes.

¿Le importaría compartir ejemplos reales y cambios potenciales reales?

Es difícil seguirte cuando no compartes casos sólidos. Según sus mensajes, creo que no comprende completamente este tema, o puede que esté haciendo juicios equivocados. Por favor, ayúdame a entender, puedo ser el equivocado.

@oliviertassinari , ¿las anulaciones de temas seguirán funcionando sin modificaciones en v5? Para que funcione el siguiente ejemplo de anulación, parece que MUI aún tendría que aplicar nombres de clase generados por JSS además de un nombre de clase raíz generado por styled-components .

const theme = createMuiTheme({
  overrides: {
    MuiButton: {
      root: {
        '&$disabled': {
          color: myCustomColor,
        },
      },
    },
  },
});

@yordis después de pensarlo más, me di cuenta de que los selectores compuestos para estilos pasados ​​a través classes todavía funcionarían, afortunadamente. Sin embargo, no estoy seguro acerca de los estilos de anulación de tema.

He tenido el placer de usar ambos componentes con estilo sobre MUI junto con simplemente estilo MUI utilizando estilo = {objeto}.

Tome una página de lista de resultados, que contiene 50 tarjetas, cada una con carruseles de medios, información, controladores de clics, botones, etc.

El uso de componentes con estilo agregó casi medio segundo al tiempo de renderizado; en comparación con const useStyles = makeStyles o style={object}.

Tendré que aceptar el resultado de esta planificación de la hoja de ruta; pero definitivamente generará un problema en nuestros planes para la adopción de la interfaz de usuario si no se puede anular con otra cosa completamente de arriba hacia abajo.

@Icehunter , ¿podría publicar sus resultados y un proyecto de muestra en línea para que la gente lo vea?

@Icehunter , ¿podría publicar sus resultados y un proyecto de muestra en línea para que la gente lo vea?

El proyecto de muestra sería difícil ya que contendría código propietario. Publicaré una imagen renderizada y la sección de resultados de tiempos de la pestaña de rendimiento pronto.

Tome una página de lista de resultados, que contiene 50 tarjetas, cada una con carruseles de medios, información, controladores de clics, botones, etc.

@Icehunter , ¿estás enviando algún apoyo a esos estilos? ya sean 50 tarjetas o 500 tarjetas, el número de clases generadas debe ser el mismo. parece que su ejemplo específico contiene código propietario que no se puede compartir, pero ¿sería posible reproducir este problema con código que puede compartir?

Las API styled() / styled.div agregan una sobrecarga a la representación de _cada_ elemento, por lo que incluso con el almacenamiento en caché de los nombres de clase puede ser más lento. Con makeStyles puede adjuntar un grupo de estilos una vez y luego simplemente aplicar los nombres de clase manualmente, lo que suele ser mucho más rápido.

Reuní un ejemplo de CodeSandbox para ilustrar que las soluciones que se basan en componentes con estilo styled pueden ser de 3 a 4 veces más lentas que un MUI makeStyles :
image

styled Las API son buenas por conveniencia, pero me hago eco del sentimiento de @Icehunter de que puede ser un problema de rendimiento cuando se usa mucho en listas/tablas. Es bueno tener makeStyles como respaldo.

@schnerd Gracias por reunir estos ejemplos, ilustra muy bien la preocupación. Solo como una nota al margen, piense que el prefacio de la publicación con "No es difícil de ver ..." puede parecer un poco condescendiente y realmente no se sumó a un excelente conjunto de ejemplos.

@tuxracer disculpas - actualizado.

@Icehunter No entiendo lo que quiere decir con eso, ¿usó los estilos comunes con SC o JSS?

@Icehunter No entiendo lo que quiere decir con eso, ¿usó los estilos comunes con SC o JSS?

Ambos en realidad. Terminamos eligiendo makeStyles, pero eso o usar styled={object} nos dio los mismos resultados de rendimiento.

Estamos en un proceso de migración para obtener un mejor rendimiento en toda la biblioteca de componentes y el sitio principal.

En cuanto a la pila, está escrito en nextjs.

Para que quede claro (editar):

He usado SC según lo previsto, envolviendo componentes mui. Resultó muy lento.

Luego usé componentes mui usando makeStyles y/o style={object} desde una configuración de archivo compartido y local (cascada simulada). Mucho mucho más rápido.

No quiero bloquear esta idea en absoluto; pero si es por defecto; entonces debería haber una manera de anular globalmente de arriba hacia abajo la opción predeterminada e inyectar la suya propia.

¿Tal vez esto? No estoy seguro de seguir ya que esto me parece básico, probablemente me falta algo de contexto y/o información.

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

Tal vez llegue tarde a este juego. Pero creo que @ jedwards1211 está buscando una forma de expresar esto con SC: https://codesandbox.io/s/magical-snow-5bzd8

Yo mismo tengo esto en algunos lugares. Por lo tanto, sería bueno si fuera sencillo migrar a v5 cuando llegue ese día.

En realidad, no estoy seguro de cómo funcionará algo como esto usando componentes con estilo.

Por ejemplo, si Material UI admitirá la anulación de las variantes predeterminadas de Typography en el futuro, supongo que JSS es más fácil que los componentes con estilo.

@heb-mm hay un RFC detallado aquí que @oliviertassinari mencionó este hilo el 7 de marzo.

Me tomó menos de un minuto desplazarme hacia arriba y ver la mención.

Editar: para aquellos que se preguntan, heb-mm ha eliminado su comentario ahora.

Reuní un ejemplo de CodeSandbox para ilustrar que las soluciones que se basan en componentes con estilo styled pueden ser 3-4 veces más lentas que un MUI makeStyles :

@schnerd He actualizado su punto de referencia para incluir la API interna de Material-UI styled que debería imitar styled-components . Me sorprendió ver lo increíblemente lento que es en comparación con las otras opciones. Consulte https://codesandbox.io/s/css-in-js-comparison-ljtjz?file=/src/App.js

image

¿Alguien sabe si @emotion/styled (que tiene básicamente la misma API que los componentes con estilo) sería igualmente lento? Me pregunto si hay algo sobre su implementación que podría optimizarse mejor.

¿Alguien sabe si @emotion/styled (que tiene básicamente la misma API que los componentes con estilo) sería igualmente lento? Me pregunto si hay algo sobre su implementación que podría optimizarse mejor.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

Casi tan rápido como los componentes con estilo. Todavía no es tan rápido como makeStyles. El problema que veo en su mayor parte es la creación de objetos y las diferencias de almacenamiento en caché/memoización de objetos.

Hmm, esto podría complicar un poco nuestros planes de migración a MUI. Actualmente nos estamos alejando de styled-components a favor del sistema de diseño de estilos de la interfaz de usuario de Material después de tener muchos problemas para administrar nuestro CSS, la temática y el rendimiento. styled components estuvo bien al principio, construimos nuestra propia solución de temas encima, pero cuando la interfaz de usuario creció, también lo hizo el CSS. Usamos TypeScript, por lo que el hecho de que pudiéramos refactorizar fácilmente un objeto JS en lugar de una cadena CSS en línea fue un gran punto de venta. 😕

Así que soy bastante nuevo en Material UI y también acabo de ver el lanzamiento alfa de v5. @ldiego08 dijiste:

Actualmente nos estamos alejando de los componentes con estilo en favor del sistema de estilo Material UI

Usualmente uso componentes con estilo cuando trabajo con react. ¿Qué es el sistema de estilo de Material UI y cuál es la forma recomendada de usar estilos y CSS en Material UI en el futuro? Leí esta página y no me queda claro si está a favor de CSS-IN-JS o no: https://material-ui.com/system/basics/. Por lo general, prefiero escribir CSS no en sintaxis de objetos, y he disfrutado de los beneficios de usar CSS-IN-JS, ya que puede usar "sintaxis css normal", pero también tiene el poder de JS a mano.

Gracias por cualquier ayuda para ponerse en marcha!

No sé por qué la API de componentes con estilo es tan popular. Es más lento, debe envolver todo en el componente en lugar de solo generar el nombre de la clase. Y también, ¿qué pasa con los literales de plantilla etiquetados? No queríamos escribir css en archivos css, porque es mucho mejor escribirlo en una cadena javascript. :D La sintaxis de objetos es mucho más poderosa cuando se trata de composición y refactorización, etc. Para mí, las funciones css y cx de simple emoción que toman el objeto css y devuelven el nombre de la clase es la API más flexible y poderosa. Entonces, simplemente generar nombres de clase con emoción y usar la API de clases es súper flexible y poderoso. Así que no entiendo por qué cambiaría el rendimiento y la flexibilidad por una "API de desarrollador más conveniente" (para algunas personas, para mí, es una API terrible).

No sé por qué la API de componentes con estilo es tan popular. Es más lento, debe envolver todo en el componente en lugar de solo generar el nombre de la clase. Y también, ¿qué pasa con los literales de plantilla etiquetados? No queríamos escribir css en archivos css, porque es mucho mejor escribirlo en una cadena javascript. :D La sintaxis de objetos es mucho más poderosa cuando se trata de composición y refactorización, etc. Para mí, las funciones css y cx de simple emoción que toman el objeto css y devuelven el nombre de la clase es la API más flexible y poderosa. Entonces, simplemente generar nombres de clase con emoción y usar la API de clases es súper flexible y poderoso. Así que no entiendo por qué cambiaría el rendimiento y la flexibilidad por una "API de desarrollador más conveniente" (para algunas personas, para mí, es una API terrible).

Tenía la misma preocupación :) tal vez aclare un poco las cosas:
https://github.com/mui-org/material-ui/issues/6115#issuecomment-580449539

@martinjlowm Sí, estamos en la misma página :) Creo que la forma más inteligente de hacerlo para el equipo de material UI es implementar algún tipo de solución conectable y no combinar con ninguna solución css en js, dejando que las personas elijan qué usar y ahorre algo de tamaño de paquete de esa manera. Y también manteniendo las clases y la API createMuiTheme, porque esa es la parte más poderosa. Para mí, css en js se trata de estilo dinámico fácil basado en el estado del componente, confianza al refactorizar o eliminar css o componentes completos (ahí es donde el enfoque de objeto es superior), rendimiento (sin descargar un montón de estilos no utilizados de un montón de hojas de estilo externas) , etc. Y nuevamente, no entiendo por qué a la gente le gusta escribir cadenas con algún editor resaltado. Quiero decir, tienes que usar ${} para acceder a los accesorios desde el contexto. Para algo más complejo que configurar el fondo del elemento div, ese enfoque es desordenado y no legible en mi opinión. No lo estoy criticando, solo digo lo que pienso y trato de probar un punto de que no a todos los desarrolladores les gustan los componentes con estilo, e incluso si les gustara, no veo cómo es bueno cambiar el rendimiento y la flexibilidad por eso. :)

@vdjurdjevic De hecho, acoplar material-ui a una solución css en js es casi una receta garantizada para el conflicto cuando las prácticas de css-in-js inevitablemente crecen en diferentes direcciones.

¿Qué tal algún patrón de adaptador que aplique estilo con un proveedor css-in-js específico? Los estilos en sí deben definirse en un formato consistente dentro de los paquetes material-ui. Es la aplicación de esos estilos lo que se realiza de manera diferente por los adaptadores correspondientes.

Algo del estilo de:

import {EmotionAdapter, StyledComponentAdapter, ThemeProvider} from "@material-ui/core/styles";
...
return 
    (<ThemeProvider theme={theme} adapter={EmotionAdapter}>
        ...
    </ThemeProvider>)

@vdjurdjevic Estoy bastante de acuerdo con sus pensamientos sobre https://github.com/mui-org/material-ui/issues/6115#issuecomment -652762320. Puede que le guste este resumen de la dirección que estamos tomando que he compartido recientemente en https://github.com/mui-org/material-ui/issues/16947#issuecomment -653797178.

No entiendo por qué a la gente le gusta escribir cadenas con algún editor resaltado

Un par de razones desde mi perspectiva:

  • Cerca de por qué no escribimos React.createElement('div', {}) .
  • Las personas con experiencia limitada en el desarrollo web (son muchas) luchan por aprender la API de JavaScript, se siente más simple con la sintaxis de CSS. Tome a los diseñadores como ejemplo, pregúnteles a los de su equipo qué piensan al respecto :).
  • No puedo copiar y pegar entre las herramientas de desarrollo y la fuente (odio esta).

@oliviertassinari Ok, estos son algunos puntos sólidos, estoy de acuerdo :) Pero aún así, para mí (no soy diseñador, ni principiante, desarrollador senior), los componentes con estilo y los literales de plantilla etiquetados nunca serían una opción. Leí su resumen para la dirección de un mayor desarrollo, y me alegra saber que el motor css será opcional. No me importan los componentes con estilo como predeterminados (si eso es lo que le gusta a la mayoría de los usuarios), siempre que pueda cambiar eso. Y para ser honesto, creo que me apegaré a JSS con v4 para mi próximo proyecto, tiene algunas características interesantes (como expandir y componer complementos). Tuve que escribir el complemento stylis para que la emoción tuviera algo similar.

PD. Tampoco soy un gran fanático de JSX :) Rápidamente se vuelve desordenado, terminas con un código de flecha y para los componentes que deberían representar elementos dinámicos, no tienes más remedio que usar createElement. No digo que trabajar directamente con createElement sea mejor, solo digo que JSX no es ideal. En mi opinión, Flutter tiene el mejor DX, espero que algún día pueda manejar bien la plataforma web.

@oliviertassinari Según nuestras pruebas de rendimiento en curso, como se indica en https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897 Solo espero que el equipo de materiales no solo elija componentes con estilo porque son populares. Es lento. Siempre ha sido. Personalmente, es un punto de ser un desarrollador que necesita aprender cosas como la notación JS de CSS.

Es parte del trabajo.

Facilitar la vida de los desarrolladores es parte de nuestro trabajo como mantenedores de paquetes (para mis propios proyectos de los que estoy hablando), pero hay una línea entre hacerlo fácil y hacerlo eficiente.

Es por eso que solo uso makeStyles y siempre lo he hecho desde que se presentó.

El arquitecto de mi último equipo no escuchó y siguió adelante con componentes con estilo y ahora el sitio es lento. Cambié a makeStyles en una rama de prueba y ahorré un 50% (10 segundos) en TTI en dispositivos móviles, pero tal como dijiste en ese comentario, la notación JS no es conocida por todos, por lo que no fue aceptada.

Internamente, el material puede elegir lo que quiera, pero hágalo de manera predeterminada.

[Pregunta movida a StackOverflow.]

@haysclark Utilice StackOverflow para preguntas de soporte en lugar de incluirlas en un RFC.

@haysclark Utilice StackOverflow para preguntas de soporte en lugar de incluirlas en un RFC.

@mbrookes ¡ Gracias por el aviso!

¿Alguien sabe si @emotion/styled (que tiene básicamente la misma API que los componentes con estilo) sería igualmente lento? Me pregunto si hay algo sobre su implementación que podría optimizarse mejor.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

Casi tan rápido como los componentes con estilo. Todavía no es tan rápido como makeStyles. El problema que veo en su mayor parte es la creación de objetos y las diferencias de almacenamiento en caché/memoización de objetos.

Me preguntaba cuál sería el rendimiento del componente Box en comparación con su creación de perfiles, y agregué Box de Chakra-UI por si acaso, y los resultados fueron... sorprendentes: P
https://codesandbox.io/s/css-in-js-comparison-forked-mg3gx?file=/src/App.js

image

@Nvveen , ¿has probado Chakra-UI v1? Ha sido reescrito y espero que sea mejor. También está la emoción v11, aunque todavía en beta.

@Nvveen , ¿has probado Chakra-UI v1? Ha sido reescrito y espero que sea mejor. También está la emoción v11, aunque todavía en beta.

Acabo de probarlo con el último RC, pero no hay una diferencia notable; sigue siendo entre 1,5 y 2 veces más lento que el SC normal. La mayor pregunta para mí es por qué el MUI Box es tan lento.

@Nvveen , ¿has probado Chakra-UI v1? Ha sido reescrito y espero que sea mejor. También está la emoción v11, aunque todavía en beta.

Acabo de probarlo con el último RC, pero no hay una diferencia notable; sigue siendo entre 1,5 y 2 veces más lento que el SC normal. La mayor pregunta para mí es por qué el MUI Box es tan lento.

Utiliza Jss. SC es al menos algo mejor.

En mi máquina, el orden en que se ejecutan los casos de prueba afecta los resultados. Comparar

  1. Caja primero https://codesandbox.io/s/css-in-js-comparison-forked-tqlg1?file=/src/App.js
    Capture d’écran 2020-08-16 à 19 49 55

  2. Cuadro último https://codesandbox.io/s/css-in-js-comparison-forked-js6th?file=/src/App.js
    Capture d’écran 2020-08-16 à 19 49 45

La recolección de basura de @oliviertassinari y jit de v8 es lo que lo está causando. Es mejor tener ejecuciones de prueba aisladas/separadas realmente. Las pruebas posteriores tienen mejor jit, pero de vez en cuando activará la recolección de basura.

Parece que Emotion, SC y Chakra están todos cerca de un rendimiento máximo teórico para cuando cada pequeño componente tiene sus propios estilos para montar, con el estilo MUI aún no completamente optimizado. Parece que la única forma de obtener un mejor rendimiento es tener una hoja de estilo para todo el árbol de componentes como en makeStyles/pure CSS. Supongo que los 30 ms adicionales para emoción, SC, etc. son la sobrecarga inevitable de cada pequeño componente que tiene que asegurarse de que sus estilos estén montados.

@ jedwards1211 si se trata de mantener el dx, Atlassian hizo una librería que lo compila en css, llamado compilado

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

ghost picture ghost  ·  3Comentarios

reflog picture reflog  ·  3Comentarios

finaiized picture finaiized  ·  3Comentarios

sys13 picture sys13  ·  3Comentarios

FranBran picture FranBran  ·  3Comentarios