Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # React guidelines to support content theming in Open edX (Braden's proposal)
- 1. Build the UI out of small, modular React components as much as possible.
- 2. Build two types of components: "customizable" ones that only compose others
- using JSX and contain little-or-no HTML nor logic, as well as "internal"
- components that contain logic and detailed HTML and CSS, etc.
- 3. In customizable components, include placeholders like `{this.extraContent}`
- in the render() method so that subclasses don't have to override render().
- Bad example:
- ```typescript
- class Header extends React.PureComponent<Props, State> {
- public render() {
- return (
- <header>
- <div className="logoArea">
- <img src={this.props.brandedLogo} alt={this.props.siteName} />
- </div>
- <div className="mainNav">
- <ul>
- <li>
- <a href="/">Home</a>
- {this.props.isLoggedIn ? null : <a href="/login">Login</a>}
- </li>
- </ul>
- </div>
- <div class="currentUserAvatar">
- <!-- User avatar, account menu etc. -->
- </div>
- </header>
- );
- }
- }
- ```
- Good example:
- ```typescript
- // Customizable Header
- class _Header extends React.PureComponent<Props, State> {
- public render() {
- return (
- <header>
- <SiteLogo/>
- <MainNav/>
- <UserAvatar/>
- </header>
- );
- }
- }
- // Customizable Main Navigation Area
- class _MainNav extends React.PureComponent<Props> {
- public render() {
- return (
- <MainNavWrapper>
- <a href="/">Home</a>
- <LoginLink/>
- {this.extraNavLinks}
- </MainNavWrapper>
- );
- }
- get extraNavLinks(): JSX.Element[] { return []; }
- }
- // Internal MainNavWrapper - not meant to be modified in most cases)
- class _MainNavWrapper extends React.PureComponent<Props> {
- public render() {
- return <div className="mainNav">
- <ul>
- {React.Children.map(this.props.children, (child) => (child ? <li>{child}</li> : null))}
- </ul>
- </div>;
- }
- }
- // Default Theme:
- export const Header = _Header;
- export const MainNav = _MainNav;
- export const MainNavWrapper = _MainNavWrapper;
- ```
- And here's an example of a custom theme:
- ```typescript
- class MyThemedHeader extends _Header {
- public render() {
- return (
- <header>
- {/* Replace <SiteLogo/> with a fancy widget */}
- <MyCustomAnimatedLogoWidget/>
- <MainNav/>
- <UserAvatar/>
- </header>
- );
- }
- }
- // Customizable Main Navigation Area
- class MyThemedNav extends _MainNav {
- get extraNavLinks() {
- return [
- <a href="/about">About Us</a>,
- ];
- }
- }
- // My theme:
- export const Header = MyThemedHeader;
- export const MainNav = MyThemedNav
- export const MainNavWrapper = _MainNavWrapper;
- ```
- I've left out all the Redux glue code, etc., but you can get the idea.
Add Comment
Please, Sign In to add comment