Last Updated on : 2024-06-05 03:14:35download
The theme serves the following purposes:
You can override all theme configurations in the local theme configuration file (src/config/theme.js
). Alternatively, you can extend the theme configuration in the project. Custom theme examples are as follows:
Note: for all theme variables, see the Quick reference table of themes at the end of this topic.
export default {
// Override the local default theme variable global: {
brand: "#ff0000",
},
switchButton: {
margin: 2,
width: 40,
height: 24,
thumbSize: 20,
},
// Extend theme configuration myExtendTheme: {
customKey: "blue",
},
};
First, add Theme(ThemeProvider)
to the top level of the application, pass the theme to the React component tree, and then access the theme object in the following three ways.
import _ from "lodash";
import PropTypes from "prop-types";
import React, { Component } from "react";
import { View } from "react-native";
import { Provider, connect } from "react-redux";
import { TYSdk, Theme } from "tuya-panel-kit";
import {
devInfoChange,
deviceChange,
responseUpdateDp,
} from "./redux/modules/common";
import DebugView from "./components/DebugView";
const TYEvent = TYSdk.event;
const TYDevice = TYSdk.device;
const composeLayout = (store, component) => {
const NavigatorLayoutContainer = connect(_.identity)(component);
const ThemeContainer = connect(({ theme }) => ({ theme }))(Theme);
const { dispatch } = store;
TYEvent.on("deviceChanged", (data) => {
dispatch(deviceChange(data));
});
// eslint-disable-next-line
TYEvent.on("dpDataChange", (data) => {
dispatch(responseUpdateDp(data));
});
TYEvent.on("AppOnline", (data) => {
dispatch(deviceChange({ AppOnline: data.online }));
});
TYEvent.on("deviceOnline", (data) => {
dispatch(deviceChange({ deviceOnline: data.online }));
});
class PanelComponent extends Component {
static propTypes = {
// eslint-disable-next-line
devInfo: PropTypes.object.isRequired,
};
constructor(props) {
super(props);
if (props && props.devInfo && props.devInfo.devId) {
TYDevice.setDeviceInfo(props.devInfo);
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
// eslint-disable-next-line
} else if (props.preload) {
// do something
} else {
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
}
}
render() {
return (
<Provider store={store}>
<ThemeContainer>
<View style={{ flex: 1 }}>
<NavigatorLayoutContainer />
<DebugView />
</View>
</ThemeContainer>
</Provider>
);
}
}
return PanelComponent;
};
export default composeLayout;
styled
in styled-components
.import styled from "styled-components/native";
const defaultColor = "#333";
export const StyledTitle = styled(TYText).attrs({
type: "title",
size: "small",
})`
color: ${(props) => getTheme(props, "list.fontColor", "#333")};
color: ${(props) =>
props.fontColor ||
props.theme.list.fontColor ||
props.theme.list.light.fontColor ||
"#333"};
`;
withTheme
higher-order function.import React from "react";
import PropTypes from "prop-types";
import { View } from "react-native";
import { Utils } from "tuya-panel-kit";
const { withTheme } = Utils.ThemeUtils;
const ThemedView = (props) => {
const { theme } = props;
return <View style={{ backgroundColor: theme.global.brand }} />;
};
ThemedView.propTypes = {
theme: PropTypes.object.isRequired,
};
export default withTheme(ThemedView);
ThemeConsumer
component.import { Utils } from "tuya-panel-kit";
const { ThemeConsumer } = Utils.ThemeUtils;
export const StyledIconFont = (props) => {
return (
<ThemeConsumer>
{(theme) => {
const propsWithTheme = { ...props, theme };
return (
<IconFont
color={getTheme(
propsWithTheme,
"list.iconColor",
DEFAULT_THEME.iconColor
)}
{...props}
/>
);
}}
</ThemeConsumer>
);
};
import { Platform } from "react-native";
import { CoreUtils, RatioUtils } from "../../utils";
const { get } = CoreUtils;
const { convertX: cx } = RatioUtils;
/**
* General auxiliary function */
const getBrandColor = (props) => get(props, "theme.global.brand", global.brand);
const getDividerColor = (props) =>
get(props, "theme.global.dividerColor", global.dividerColor);
const getTypedFontColor = (props, reverse = false) => {
let type = get(props.theme, "type", "light");
if (reverse) type = type === "light" ? "dark" : "light";
const path = `global.text.${type}`;
return get(props.theme, path, global.text[type]);
};
// Adjust the font size according to the global font benchmark ratio
const normalizeFont = (props, fontSize, lineHeight) => {
const baseline = get(props, "theme.global.fontSizeBase", global.fontSizeBase);
return {
fontSize: fontSize * baseline,
lineHeight: Math.round(lineHeight * baseline), // Xiaomi will crash if it is not an integer };
};
export default {
type: "light",
/**
* Global basic variables */
global: {
brand: "#FF4800", // Brand color (theme color) bgColor: "#f8f8f8", // Background color
fontSizeBase: 1, // Font benchmark ratio
dividerColor: "#e5e5e5", // Divider color
success: "#00C800", // Success color
warning: "#FAAE17", // Warning color
error: "#F4182C", // Failure
// info, // Information color (not available now)
// disabled, // Disable the transparency (not available now)
mask: "rgba(0, 0, 0, 0.7)", // Mask color
text: {
light: "#333", // Font color under the `light`
dark: "#fff", // Font color under the `dark`
},
},
/**
* Font size variable
*/
text: {
heading: {
// Font size when type is heading, and size is small
small: (props) => normalizeFont(props, 28, 40),
normal: (props) => normalizeFont(props, 40, 56),
large: (props) => normalizeFont(props, 72, 100),
},
title: {
// Font size when type is title, and size is small
small: (props) => normalizeFont(props, 16, 22),
normal: (props) => normalizeFont(props, 17, 24),
large: (props) => normalizeFont(props, 20, 28),
},
// The main font color #333 applies to title and above
paragraph: {
// Font size when type is paragraph, and size is small
small: (props) => normalizeFont(props, 10, 14),
normal: (props) => normalizeFont(props, 12, 17),
large: (props) => normalizeFont(props, 14, 20),
},
},
/**
* Picker scroll selector variable */
picker: {
fontSize: 16, // Picker font size
fontColor: "#000", // Picker font color
dividerColor: getDividerColor, // Reserved, and not supported by iOS now
unitFontSize: 16, // Picker unit size
unitFontColor: "#000", // Picker unit color
},
/**
* Button variable
*/
button: {
margin: [0, 0, 0, 0], // Button container margin (top, right, bottom, and left) fontSize: 10, // Font size
fontColor: getTypedFontColor, // Font color
iconSize: 24, // Icon size
iconColor: (props) => getTypedFontColor(props, props.type === "primary"), // Icon color
bgWidth: null, // Button background width, which is adaptive inside the component by default
bgHeight: null, // Button background height, which is adaptive inside the component by default
bgRadius: null, // Button background border-radius, which is adaptive inside the component by default
bgColor: getBrandColor, // Button background color, which follows the theme color by default
},
/**
* TopBar variable
*/
topbar: {
background: "#fff", // Background color of the top bar
color: "#000", // Font color of the top bar (including icon color)
},
/**
* SwitchButton switch variable
*/
switchButton: {
width: 50, // Button width
height: Platform.select({
// Button width
web: 28,
ios: 28,
android: 14,
}),
thumbSize: 26, // Thumb width and height sizes
margin: Platform.select({
// Margins around the thumb
web: 1,
ios: 1,
android: 0,
}),
tintColor: "#e5e5e5", // Background color when disabled
onTintColor: "#4CD964", // Background color when enabled
thumbTintColor: "#fff", // Background color of the thumb when disabled
onThumbTintColor: "#fff", // Background color of the thumb when enabled
},
/**
* Slider variable
*/
slider: {
width: null, // Follow the parent container by default (slider width)
trackRadius: 2, // Border-radius
trackHeight: 4, // Slider height
minimumTrackTintColor: getBrandColor, // Color of the minimum value
maximumTrackTintColor: "#e5e5e5", // Color of the maximum value
thumbSize: 24, // Thumb size
thumbRadius: 14, // Thumb border-radius
thumbTintColor: "#fff", // Thumb color
},
/**
* Checkbox variable
*/
checkbox: {
size: 28, // Checkbox size
fontColor: "#333", // Checkbox font color
activeColor: "#3388FF", // The color when Checkbox is active
disabledColor: "#333", // The color when Checkbox is disabled
},
/**
* List variable
*/
list: {
boardBg: "#f8f8f8", // Container background color of the list
iconColor: "rgba(51, 51, 51, 0.5)", // Icon color
fontColor: "#333", // Title color
subFontColor: "rgba(51, 51, 51, 0.5)", // Subtitle color
descFontColor: "rgba(51, 51, 51, 0.5)", // Descriptive title color
cellLine: "rgba(51, 51, 51, 0.1)", // Cell line color
cellBg: "#fff", // Background color of the list item
cellRadius: 0, // Border-radius of the list item margin: [0, 0, 0, 0], // Outer margin of the list item (top, right, bottom, and left) padding: [12, cx(16), 12, cx(16)], // Inner margin of the list item (top, right, bottom, and left)
},
/**
* BrickButton variable
*/
brickButton: {
fontSize: 12, // Font size
fontColor: "#fff", // Font color
bgRadius: 24, // Background border-radius
bgColor: getBrandColor, // Follow the theme color
bgBorder: "transparent", // Background border
bgBorderWidth: 0, // Background border width
loadingColor: "#fff", // Loading color
loadingBackground: "rgba(0,0,0,.1)", // Loading background color
},
/**
* Dialog variable
*/
dialog: {
width: cx(315), // Container width of the pop-up window
bg: "#fff", // Background color of the pop-up window
radius: cx(8), // Container border-radius of the pop-up window
cellHeight: 56, // List height (header and footer)
lineColor: "#e5e5e5", // Color of the division line
titleFontSize: 18, // Title font size
titleFontColor: "#333", // Title color of the top bar
subTitleFontSize: 16, // Subtitle font size
subTitleFontColor: "#999", // Subtitle color of the top bar
cancelFontSize: 16, // Font size of cancellation at the bottom bar
cancelFontColor: "#666", // Font color of cancellation at the bottom bar
confirmFontSize: 16, // Font size of confirmation at the bottom bar
confirmFontColor: "#333", // Font color of confirmation at the bottom bar
prompt: {
bg: "#f8f8f8", // Background color of the input box
radius: cx(4), // Border-radius of the input box
padding: "12px 16px", // Padding of the input box
placeholder: "#d6d6de", // Font color of the placeholder
},
},
/**
* Popup variable
*/
popup: {
cellHeight: 48, // Height of the list item
cellBg: "#fff", // Background color of the list
titleRadius: cx(8), // Border-radius of the header
footerRadius: 0, // Border-radius of the footer
bottomBg: "#f5f5f5", // Background color of the bottom bar
lineColor: "#e5e5e5", // Color of the division line
titleFontSize: 14, // Title size of the top bar
titleFontColor: "#999", // Title color of the top bar
cancelFontSize: 16, // Font size of cancellation at the bottom bar
cancelFontColor: "#666", // Font color of cancellation at the bottom bar
confirmFontSize: 16, // Font size of confirmation at the bottom bar
confirmFontColor: "#333", // Font color of confirmation at the bottom bar
},
};
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback