Оператор if внутри стилизованного компонента

export enum SizeEnum {
    Small,
    Large
}

export interface ICheckbox {
    Size: SizeEnum;
}

const Box = styled.div`
    height: 20px;
    width: 20px;
`

В приведенном выше коде я хочу иметь возможность условно изменить значение высоты и ширины <Box> основанный на опоре. Как мне это сделать?

8 ответов

Другой способ сделать это, если вы хотите добавить несколько стилей css.

const Box = styled.div`
    height:100px;
    width:100px;
    ${props => props.Size === 'Small' && css`
         height:20px;
         width:20px;
`}
`

Увидеть Logical Operators а также Adapting based on props для получения дополнительной информации.

// Box.
const Box = styled.div`

  height: ${({Size}) => 
    Size == 'Small' && '25px' ||
    Size == 'Large' && '100px' || 
    '50px'
  };

  width: ${({Size}) => 
    Size == 'Small' && '25px' || 
    Size == 'Large' && '100px' || 
    '50px'
  };

`

// Render.
<Box/> // Normal.
<Box Size="Small"/> // Small.
<Box Size="Large"/> // Large.

Вы можете использовать троичный оператор

const Box = styled.div`
height: ${props => props.Size === 'Small' ? '20px' : '40px'}
width: ${props => props.Size === 'Small' ? '20px' : '40px'}
`

Ссылка: https://www.styled-components.com/docs/basics

Вы можете использовать оператор elvis примерно так:

       ${(props) => props.someValue ? css` width: 20px;` : css` width: 100px; `}

Надеюсь, это поможет кому-то изучить, как использовать логические операторы в компонентах в стиле React.

Мы можем добавить проверки if так же, как jsx

const Box = styled.div`
    height:100px;
    width:100px;
    ${props => props.Size === 'Small' && `
         height:20px;
         width:20px;
    `}
` 

Примечание: нет необходимости включать слово css

Вы можете добавить интерфейс в TypeScript и использовать логические значения для стандартных, маленьких и больших блоков. Этот пример для тех, у кого более двух вариантов. В случае выбора двух вариантов я бы использовал стрелочную функцию и ? : операторы.

      interface Sizes { 
  small?: boolean, 
  large?: boolean 
}

// Box.
const Box = styled.div<Sizes>`
  // p in this case means parameter which can have small and large booleans
  height: ${p => 
    (p.small && '25px') ||
    (large && '100px') || 
    '50px'
  };

  width: ${({Size}) => 
    (small && '25px') || 
    (large && '100px') || 
    '50px'
  };

`

// Render.
<Box/> // 50px - Normal.
<Box small/> // 25px - Small.
<Box large/> // 100px - Large.

Избавьтесь от всех IF

Я знаю, что этот вопрос довольно старый, но я хотел бы внести свой вклад одним предложением.

Недавно я придумал шаблон для вычисления значения с использованием объекта. Думаю, это оказалось довольно интересно!

      // types.ts
export type CheckboxSize: 'Small' | 'Large'

export interface ICheckbox {
    Size: CheckboxSize;
}


// styles.ts
import styled, { css } from 'styled-components'
import type { CheckboxSize } from './types.ts' 

interface GetBoxSizeProps { 
  size: CheckboxSize
}

function getBoxSize ({ size }: GetBoxSizeProps) => ({
  'Small': css`
    height: 16px;
    width: 16px;
  `,
  'Large': css`
    height: 20px;
    width: 20px;    
  `,
}[size])

interface BoxProps {
  size: CheckboxSize
}

/*
  Just by placing the function here, it will be automatically 
  called by styled components and computed
*/
const Box = styled.div<BoxProps>`
  ${getBoxSize}

  //other styles...
`

// usage

<Box size="Small" />
<Box size="Large" />

Моя проблема со старыми стилями «if» и «switch» заключалась в том, что после некоторых реквизитов логика стилей часто перерастала в нечто довольно многословное и трудно поддерживаемое.

Не называю эту схему своим изобретением, но похожего мне нигде не удалось найти!

Надеюсь, это кому-то поможет :)

Ps: если вы используете темы, можно передать свойство функции и сохранить его в чистоте!

Также можно использовать реальный синтаксис if/else , важно то, что возвращаемое значение должно быть строкой:

      const DrawerItemTitle = styled.div<{isExpanded: boolean}>(props => {
    const baseStyles = `
        white-space: nowrap;
    `;
    const expandedStyles = baseStyles + `
        opacity: 1;
        transition: opacity 0.4s;
        text-align: center;
        flex-grow: 1;`
    const notExpandedStyles = baseStyles + `
        opacity: 0;
        transition: opacity 0s;
        position: absolute;
        width: 100%;
    `;

    if(props.isExpanded) {
        return expandedStyles; 
    }
    else { 
        return notExpandedStyles;
    }
);
Другие вопросы по тегам