Crear componentes personalizados y darles estilo
Al igual que en la mayoría de las labores de desarrollo, existen muchas formas de realizar las personalizaciones en Flex. Estas directrices se basan en nuestra experiencia en la creación de Flex Plugins.
Componentes personalizados
Cuando se crea un nuevo componente, se recomienda seguir las convenciones demostradas en el generador de plugins. Crea un directorio dentro de /src/components
y, a continuación, un trío de archivos para representar el contenido y los estilos del componente.
src
├── components
│ └── MyComponent
│ │ └── MyComponent.jsx
│ │ └── MyComponent.Container.js
│ │ └── MyComponent.Styles.js
En este ejemplo:
MyComponent.jsx
devolverá un componente React que se podría agregar mediante una de las APIContent.add()
de Flex.MyComponent.Container.js
conecta el componente de presentación (MyComponent.jsx
) con el almacén de Redux.MyComponent.Styles.js
administra los estilos que aplicarás al componente y sus elementos secundarios.
Cómo usar Twilio Paste
Solo disponible en la versión 2.0.
No es necesario que crees desde cero todos los componentes. Puedes utilizar las bibliotecas de componentes de React existentes para acceder a componentes previamente creados teniendo en cuenta la compatibilidad con el navegador, la adaptación al tamaño de pantalla y la accesibilidad. Internamente, flex-ui
utiliza Paste para muchos de sus componentes. Igualmente, tú puedes utilizar Paste para crear componentes que comiencen con un estilo similar al diseño existente de Flex.
Aunque Paste ya es una dependencia de flex-ui
, recomendamos incluirlo como una dependencia explícita en el archivo package.json
de tu proyecto de plugin. Deberás agregar esto en tus dependencies
:
// package.json
"dependencies": {
...
"@twilio-paste/core": "^10.20.0",
},
Componentes de estilo
Hemos descubierto que es más fácil gestionar el desarrollo de plugins cuando los estilos y el código se agrupan como parte del plugin. Te recomendamos utilizar Emotion para gestionar los estilos de los componentes personalizados. Si eliges utilizar Emotion, cerciórate de incluir la biblioteca en las dependencias de tu package.json
.
Estructura
Te sugerimos definir un contenedor de estilo a nivel de componente para cada uno de tus componentes. Sin embargo, si se aplican los mismos estilos en el mismo tipo de elemento o si deseas crear estilos dinámicos, puedes crear componentes con estilos independientes para una mejor reutilización.
Si sigues la estructura de archivos anterior, te recomendamos mantener los estilos junto a los componentes en archivos como MyComponent.Styles.js
.
Usar Emotion
Hay muchas maneras en que puedes utilizar Emotion para dar estilo a tus componentes. Te sugerimos usar styled
para definir un contenedor de estilo a nivel de componente. Este componente styled
incluirá todos los estilos de tu componente principal y sus elementos secundarios.
// Panel.ts
import React from 'react';
import { PanelStyles } from './Panel.Styles';
const Panel = () => {
return (
<PanelStyles>
<ul>
<li className="first-item">A</li>
<li className="second-item">B</li>
<li className="third-item">C</li>
</ul>
</PanelStyles>
);
};
export default Panel;
// Panel.Styles.ts
import styled from 'react-emotion';
export const PanelStyles = styled('div')`
text-align: center;
background: #D8BFD8;
color: #fff;
height: 100%;
ul {
Padding-top: 10px;
}
.first-item {
font-size: 30px;
}
.second-item {
font-size: 40px;
}
.third-item {
font-size: 50px;
}
`;
Este enfoque también presenta ciertas convenciones útiles:
- El uso de nombres de clase sobre elementos con estilo individual favorece el uso de elementos HTML cuya semántica es más clara y familiar para los desarrolladores.
- Cuando un elemento tiene un nombre de clase, es fácil inferir que solo se aplica el estilo con CSS y que no hay funcionalidad personalizada.
Aplicar estilos dinámicos
styled
también se puede utilizar para implementar estilos dinámicos basados en propiedades. Se puede acceder automáticamente al tema de Flex dentro de los componentes styled
a través de props.theme
porque Flex UI (la interfaz de usuario de Flex) envuelve todos sus componentes en un ThemeProvider
. También puedes utilizar esta estrategia para pasar objetos personalizados, como el objeto bgColor
del siguiente ejemplo:
// MyView.Styles.ts
import styled from 'react-emotion'
export const SubHeader = styled('div')<{ bgColor: string }>`
color: ${props => props.theme.colors.base1};
background-color: ${props => props.bgColor};
font-weight: bold;
text-transform: uppercase;
`;
// MyView.tsx
render() {
return (
<div>
<SubHeader bgColor="red">This font color should be red.</SubHeader>
<SubHeader bgColor="blue">This font color should be blue.</SubHeader>
</div>
);
}
Estilos globales
Para agregar estilos globales a tu plugin, utiliza la función injectGlobal
de Emotion. Te sugerimos mantener un archivo independiente para los estilos globales e importarlo en tu plugin de nivel superior.
// GlobalStyles.ts
import { injectGlobal } from 'react-emotion';
injectGlobal`
.block {
display: block;
}
.inline-block {
display: inline-block;
}
`;
// MyPlugin.tsx
import '../common/GlobalStyles.ts
Cómo usar un archivo CSS con el plugin
También puedes declarar los estilos en un archivo CSS e importarlos a un archivo JS para configurarlos como los estilos globales.
// GlobalStyles.js
import { injectGlobal } from 'react-emotion';
import global from './global.css';
injectGlobal`
${global}
`;
/* global.css */
.Twilio-SidePanel-Custom-Container {
height: 100%;
border: 1px blue;
}
A continuación, puedes utilizar displayName
para cargar un componente de Flex estándar (como SidePanel) y establecer de forma dinámica su nombre de clase CSS en función de la cadena que establezcas.
<Container>
<StyledSidePanel
displayName="Custom"
themeOverride={theme && theme.OutboundDialerPanel}
handleCloseClick={handleClose}
title={title}
>
<ListContainer
itemList={itemList}
itemType={itemType}
/>
</StyledSidePanel>
</Container>
En este ejemplo, se aplicarán los estilos declarados dentro de .Twilio-SidePanel-Custom-Container
en el archivo CSS.
Estilos externos
Puede que no siempre sea práctico definir los estilos junto con cada componente. Tal vez estés utilizando hojas de estilo compartidas en un conjunto de aplicaciones. O tal vez estés desarrollando varios plugins que deberían compartir un activo CSS centralizado.
Los métodos loadCSS
y loadJS
de flex-plugin
se pueden utilizar en estas situaciones para cargar recursos externos al inicializar el plugin.
import { FlexPlugin, loadCSS, loadJS } from 'flex-plugin';
export default class AdminPlugin extends FlexPlugin {
constructor() {
super('AdminPlugin');
}
public init(flex, manager) {
loadCSS('https://dancing-owl-1234.twil.io/assets/test.css');
loadJS('https://dancing-owl-1234.twil.io/assets/test.js');
}
}
Una dificultad de esta estrategia es garantizar que las direcciones URL externas se puedan utilizar en cualquier entorno en el que estés implementando tu plugin. Por ejemplo, no deberías volver a compilar tu plugin si los estilos dependen de direcciones URL versionadas o si los activos son diferentes en tu entorno de desarrollo que en el de producción.
Una manera de hacerlo es utilizar la API de configuración de Flex para almacenar las URL como atributos y, a continuación, hacer referencia a dichos atributos dentro del plugin.
curl https://flex-api.twilio.com/v1/Configuration -X POST -u ACxxx:auth_token \
-H 'Content-Type: application/json' \
-d '{
"account_sid": "ACxxx",
"attributes": {
"stylesheet_url": "https://my-external-site.com/styles.css"
}
}'
public init(flex, manager) {
loadCSS(manager.serviceConfiguration.attributes.stylesheet_url);
}
¿Necesitas ayuda?
Todos la necesitamos a veces; la programación es difícil. Obtén ayuda ahora de nuestro equipo de soporte, o recurre a la sabiduría de la multitud visitando Stack Overflow Collective de Twilio o navegando por la etiqueta de Twilio en Stack Overflow.