You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Defines how custom theming can be achieved in the Porto Dialog, over three areas:
The API provided to define a custom theme (see Custom Theming).
The Porto theme format.
The way custom themes are passed from the app to the Porto Dialog.
Themes can be defined partially, allowing app authors to extend the default theme. They can define a single color scheme (light or dark), in which case the dialog will only use this color scheme. Or they can define a dual color scheme (light and dark), allowing to provide two theme variants depending on the user preferred scheme.
Themes are applied as a Tailwind CSS theme override in the Porto Dialog app, but the format is not specific to Tailwind or even CSS and is meant to be applied to other contexts.
Motivation
Porto currently provides the equivalent of two color themes, light and dark, without any option to customize them. It has the benefit of always looking the same for users, but in certain cases, there might be a need for consumers to define their own color themes. One example could be for branding consistency, requiring Porto to appear visually similar to the app using it. Supporting custom themes lets app authors achieve this without having to fork the project.
Specification & Design
Terms
Entity
Description
Porto Theme
A Porto theme is a JSON structure defining colors and other styling elements. It can be passed to the Porto Dialog.
Theme Fragment
A partial Porto theme that extends the default Porto theme. It can be used to define only a subset of the theme properties.
Custom Theming
This flow shows how a custom theme is defined and passed to the Porto Dialog:
Colors are defined as layers with colors (text & icons) on top of them, e.g. base is the main background, while baseText is the text (or icon) color used on top of it. Here is the naming convention used for most of the color properties:
Object / surface (e.g. base, primary, field)
(optional) Variant (e.g. fieldError)
(optional) Interaction state (e.g. baseHovered, fieldFocused)
Surface part (e.g. fieldBackground, fieldBorder, fieldRadius)
(optional) Surface part variant (e.g. baseContentDimmed)
Examples:
baseBackground: base object => background color
baseContent: base object => text color
primaryBackground: primary object => background color
primaryBorder: primary object => border color
primaryHoveredBackground: primary object => when hovered => background color
primaryHoveredBorder: primary object => when hovered => border color
Theme Definition
// Colors can only be defined as hex strings.typeColor= `#${string}` |"transparent";// A pair of two colors for light and dark modes.typeLightDarkColor=[Color,Color];// Px refers to CSS pixels (px unit) or equivalent// for non-web platforms, i.e. virtual pixel unit// that depend on screen resolution.typePx=number;// Themes using the "light dark" color scheme must define// both light and dark colors for each color property.typeThemeLightDark={colorScheme: "light dark";// miscaccent: LightDarkColor;focus: LightDarkColor;link: LightDarkColor;separator: LightDarkColor;// basebaseBackground: LightDarkColor;baseBorder: LightDarkColor;baseContent: LightDarkColor;baseContentDimmed: LightDarkColor;baseHoveredBackground: LightDarkColor;// frameframeBackground: LightDarkColor;frameContent: LightDarkColor;frameBorder: LightDarkColor;frameRadius: Px;// icon infoiconInfoBackground: LightDarkColor;iconInfoContent: LightDarkColor;// primaryprimaryBackground: LightDarkColor;primaryBorder: LightDarkColor;primaryContent: LightDarkColor;primaryHoveredBackground: LightDarkColor;primaryHoveredBorder: LightDarkColor;// positive / negativenegativeBackground: LightDarkColor;negativeContent: LightDarkColor;positiveBackground: LightDarkColor;positiveContent: LightDarkColor;// fieldfieldBackground: LightDarkColor;fieldBorder: LightDarkColor;fieldContent: LightDarkColor;fieldErrorBorder: LightDarkColor;fieldFocusedBackground: LightDarkColor;fieldFocusedContent: LightDarkColor;// … (more are being added)};// A single color theme can also be defined.typeThemeSingleColorScheme={colorScheme: "light"|"dark";accent: Color;// Single color, no pair.// …};exporttypeTheme=ThemeLightDark|ThemeSingleColorScheme;
Here is a preview to illustrate how the theme properties get applied to the Porto Dialog. It shows how theme colors might only make sense for certain themes, e.g. frameBackground is the same as the baseBackground layer in the two first themes, but not in the third one.
API Changes
A new theme property is added to the PortoDialogOptions interface:
No backward incompatibility, as the default theme is still provided.
Security Considerations
The theme values passed to the dialog must be parsed strictly to avoid any malicious code injection. For this reason, a static mapping of theme names to tailwind variable names is used to convert the theme into CSS.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Porto Dialog Theming
Abstract
Defines how custom theming can be achieved in the Porto Dialog, over three areas:
Themes can be defined partially, allowing app authors to extend the default theme. They can define a single color scheme (light or dark), in which case the dialog will only use this color scheme. Or they can define a dual color scheme (light and dark), allowing to provide two theme variants depending on the user preferred scheme.
Themes are applied as a Tailwind CSS theme override in the Porto Dialog app, but the format is not specific to Tailwind or even CSS and is meant to be applied to other contexts.
Motivation
Porto currently provides the equivalent of two color themes, light and dark, without any option to customize them. It has the benefit of always looking the same for users, but in certain cases, there might be a need for consumers to define their own color themes. One example could be for branding consistency, requiring Porto to appear visually similar to the app using it. Supporting custom themes lets app authors achieve this without having to fork the project.
Specification & Design
Terms
Custom Theming
This flow shows how a custom theme is defined and passed to the Porto Dialog:
sequenceDiagram participant App as App participant SDK as SDK participant Dialog as Dialog App ->> App: mode = Mode.dialog({ theme: … }) App ->> SDK: Porto.create({ mode }) SDK ->> SDK: url = getDialogUrl(host, theme) SDK ->> Dialog: Open dialog Dialog ->> Dialog: store.setState({ theme: urlSearchParams.theme }) Dialog ->> Dialog: css = Theme.formatTailwindTheme(theme) Dialog ->> Dialog: Inject theme: <style>{css}</style>Porto Theme Format
Colors are defined as layers with colors (text & icons) on top of them, e.g.
baseis the main background, whilebaseTextis the text (or icon) color used on top of it. Here is the naming convention used for most of the color properties:base,primary,field)fieldError)baseHovered,fieldFocused)fieldBackground,fieldBorder,fieldRadius)baseContentDimmed)Examples:
baseBackground: base object => background colorbaseContent: base object => text colorprimaryBackground: primary object => background colorprimaryBorder: primary object => border colorprimaryHoveredBackground: primary object => when hovered => background colorprimaryHoveredBorder: primary object => when hovered => border colorTheme Definition
Example of a complete theme:
{ "colorScheme": "light dark", "accent": ["#0588f0", "#3b9eff"], "focus": ["#F0F", "#eee"], "link": ["#0588f0", "#3b9eff"], "separator": ["#e0e0e0", "#2a2a2a"], "baseBackground": ["#fcfcfc", "#191919"], "baseBorder": ["#e0e0e0", "#2a2a2a"], "baseContent": ["#202020", "#eeeeee"], "baseContentDimmed": ["#8d8d8d", "#6e6e6e"], "baseHoveredBackground": ["#f0f0f0", "#222222"], "frameBackground": ["#f9f9f9", "#222222"], "frameContent": ["#838383", "#7b7b7b"], "frameBorder": ["#e0e0e0", "#2a2a2a"], "frameRadius": 14, "iconInfoBackground": ["#008ff519", "#0077ff3a"], "iconInfoContent": ["#0588f0", "#3b9eff"], "primaryBackground": ["#0090ff", "#0090ff"], "primaryBorder": ["#e0e0e0", "#2a2a2a"], "primaryContent": ["#FFF", "#FFF"], "primaryHoveredBackground": ["#058bf0", "#3b9eff"], "primaryHoveredBorder": ["#058bf0", "#3b9eff"], "negativeBackground": ["#F0F", "#F0F"], "negativeContent": ["#F0F", "#F0F"], "positiveBackground": ["#F0F", "#F0F"], "positiveContent": ["#F0F", "#F0F"], "fieldBackground": ["#F0F", "#F0F"], "fieldBorder": ["#F0F", "#F0F"], "fieldContent": ["#F0F", "#F0F"], "fieldErrorBorder": ["#F0F", "#F0F"], "fieldFocusedBackground": ["#F0F", "#F0F"], "fieldFocusedContent": ["#F0F", "#F0F"] }Example of a partial theme (
ThemeFragment):{ "colorScheme": "light dark", "accent": ["#0588f0", "#3b9eff"] }Theme Preview
Here is a preview to illustrate how the theme properties get applied to the Porto Dialog. It shows how theme colors might only make sense for certain themes, e.g.
frameBackgroundis the same as thebaseBackgroundlayer in the two first themes, but not in the third one.API Changes
A new
themeproperty is added to thePortoDialogOptionsinterface:Backwards Compatibility
No backward incompatibility, as the default theme is still provided.
Security Considerations
The theme values passed to the dialog must be parsed strictly to avoid any malicious code injection. For this reason, a static mapping of theme names to tailwind variable names is used to convert the theme into CSS.
Beta Was this translation helpful? Give feedback.
All reactions