rusackas opened a new issue #15264:
URL: https://github.com/apache/superset/issues/15264


   The following is a proposal to provide guidance on how best to use Emotion, 
some of the tips/tricks/patterns that exist in the repo, and the pros/cons of 
using `styled` vs `css` approaches, with example use cases. This proposal, 
after a little clean-up here and feedback from this thread, will be posted to 
the `dev@` email list for lazy consensus before being migrated to the Superset 
Wiki.
   
   ***********************
   
   # Emotion Tips and Strategies
   The first thing to consider when adding styles to an element is how much you 
think a style might be reusable in other areas of Superset. Always err on the 
side of reusability here. Nobody wants to chase styling inconsistencies, or try 
to debug little endless overrides scattered around the codebase. The more we 
can consolidate, the less will have to be figured out by those who follow. 
Reduce, reuse, recycle.
   
   ## When to use `css` or `Styled`
   In short, either works for just about any use case! And you’ll see them used 
somewhat interchangeably in the existing codebase. But we need a way to weigh 
it when we encounter the choice, so here’s one way to think about it:
   
   A good use of `styled` syntax if you want to re-use a styled component. In 
other words, if you wanted to export flavors of a component for use, like so:
   
   ```js
   const StatusThing = styled.div`
        padding: 10px;
        border-radius: 10px;
   `;
   
   export const InfoThing = styled(StatusThing)`
        background: blue;
        &::before {
                content: "ℹ️";
        }
   `;
   
   export const WarningThing = styled(StatusThing)`
        background: orange;
        &::before {
                content: "⚠️";
        }
   `;
   
   export const TerribleThing = styled(StatusThing)`
        background: red;
        &::before {
                content: "🔥";
        }
   `;
   ```
   
   You can also use `styled` when you’re building a bigger component, and just 
want to have some custom bits for internal use in your JSX. For example:
   
   ```js
   
   const SeparatorOnlyUsedInThisComponent = styled.hr`
        height: 12px;
     border: 0;
     box-shadow: inset 0 12px 12px -12px rgba(0, 0, 0, 0.5);
   `
   
   function SuperComplicatedComponent(props) {
     return (
                <>
                        Daily standup for {user.name}!
                        <SeparatorOnlyUsedInThisComponent />
                        <h2>Yesterday:</h2>
                        // spit out a list of accomplisments
                        <SeparatorOnlyUsedInThisComponent />
                        <h2>Today:</h2>
                        // spit out a list of plans
                        <SeparatorOnlyUsedInThisComponent />
                        <h2>Tomorrow:</h2>
                        // spit out a list of goals
                <>
        );
   }
   
   ```
   
   ### The `css` prop, in reality, shares all the same styling capabilities as 
`styled` but it does have some particular use cases that jump out as sensible. 
For example if you just want to style one element in your component, you could 
add the styles inline like so:
   
   ```js
   function SomeFanciness(props) {
     return (
                <>
                        Here's an awesome report card for {user.name}!
                        <div 
                                css={css`
                                        box-shadow: 5px 5px 10px #ccc;
                                        border-radius: 10px;
                                `
                        }>
                                <h2>Yesterday:</h2>
                                // ...some stuff
                                <h2>Today:</h2>
                                // ...some stuff
                                <h2>Tomorrow:</h2>
                                // ...some stuff
                        </div>
                <>
        );
   }
   ```
   
   You can also define the styles as a variable, external to your JSX. This is 
handy if the styles get long and you just want it out of the way. This is also 
handy if you want to apply the same styles to disparate element types, kind of 
like you might use a CSS class on varied elements. Here’s a trumped up example:
   
   ```js
   function FakeGlobalNav(props) {
        const menuItemStyles = css`
                display: block;
                border-bottom: 1px solid cadetblue;
         font-family: "Comic Sans", cursive;
        `;
   
        return (
                <Nav>
                        <a css={menuItemStyles} href="#">One link</a>
                        <Link css={menuItemStyles} to={url} >Another link</Link>
                        <div css={menuItemStyles} onclick={alert('this is not a 
great example`)} >Another link</Link>
                </Nav>
        );
   }
   ```
   
   ## `css` tips and tricks
   Using the `theme` 
   
   ### `css` lets you write actual CSS
   By default the `css`prop uses the object syntax with JS style definitions, 
like so:
   ```js
   <div css={{
        borderRadius: 10;
        marginTop: 10;
        backgroundColor: `#00FF00`
   }}>Howdy</div>
   ```
   But you can use the `css` interpolator as well to get away from icky JS 
styling syntax. Doesn’t this look cleaner?
   ```js
   <div css={css`
        border-radius: 10px;
        margin-top: 10px;
        background-color: `#00FF00`;
   `}>Howdy</div>
   ```
   You might say “whatever… I can read and write JS syntax just fine.” Well, 
that’s great. But… let’s say you’re migrating in some of our legacy LESS 
styles… now it’s copy/paste! Or if you want to migrate to or from `styled` 
syntax… also copy/paste!
   
   ### You can combine `css` definitions with array syntax
   You can use multiple groupings of styles with the `css` interpolator, and 
combine/override them in array syntax, like so:
   ```js
   function AnotherSillyExampe(props) {
        const shadowedCard = css`
          box-shadow: 2px 2px 4px #999;
          padding: 4px;
        `;
        const infoCard = css`
          background-color: #33f;
          border-radius: 4px;
        `;
        const overrideInfoCard = css`
          background-color: #f33;
        `;
        return (
                <div className="App">
              Combining two classes:
              <div css={[shadowedCard, infoCard]}>Hello</div>
   
                  Combining again, but now with overrides:
              <div css={[shadowedCard, infoCard, overrideInfoCard]}>Hello</div>
       </div>
        );
   
   ```
   
   ### Style variations with props
   
   You can give any component a custom prop, and reference that prop in your 
component styles, effectively using the prop to turn on a “flavor” of that 
component
   
   For example, let’s make a styled component that acts as a card. Of course, 
this could be done with any AntD component, or any component at all. But we’ll 
do this with a humble `div` to illustrate the point
   
   ```js
   const SuperCard = styled.div`
        ${({ theme, cutout }) => `
                padding: ${theme.gridUnit * 2}px;
                border-radius: ${theme.borderRadius}px;
                box-shadow: 10px 5px 10px #ccc ${cutout && `inset`};
                border: 1px solid ${cutout ? transparent : 
theme.colors.secondary.light3 };
        `
   `
   ```
   
   Then just use the component as `<SuperCard>Some content</SuperCard>` or with 
the (potentially dynamic) prop:  `<SuperCard cutout>Some content</SuperCard>` 
   
   ## Styled component tips
   ### No need to use `theme` the hard way:
   It’s very tempting (and commonly done) to use the `theme`  prop inline in 
the template literal like so:
   ```js
        const SomeStyledThing=styled.div`
                padding: ${({ theme }) => theme.gridUnit * 2}px;        
                border-radius: ${({ theme }) => theme.borderRadius}px;
                border: 1px solid ${({ theme }) => 
theme.colors.secondary.light3};
     `
   ```
   Instead, you can make things a little easier to read/type by writing it like 
so:
   ```js
        const SomeStyledThing=styled.div`
                ${({ theme }) => `
                        padding: ${theme.gridUnit * 2}px;       
                        border-radius: ${theme.borderRadius}px;
                        border: 1px solid ${theme.colors.secondary.light3};
                `
     `
   ```
   
   ## Extend an AntD component with custom styling
   As mentioned, you want to keep your styling as close to the root of your 
component system as possible, to minimize repetitive styling/overrides, and err 
on the side of reusability. In some cases, that means you’ll want to globally 
tweak one of our core components to match our design system. In Superset, 
that’s Ant Design (AntD).
   
   AntD uses a cool trick called compound components.  For example, the `Menu` 
component also lets you use `Menu.Item`, `Menu.SubMenu`, `Menu.ItemGroup`, and 
`Menu.Divider`
   
   ### The `Obeject.assign` trick


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to