azat-io / eslint-plugin-perfectionist

🦄 ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.
https://eslint-plugin-perfectionist.azat.io
MIT License
1.62k stars 28 forks source link

Feature: Idiomatic Order #100

Open totomakers opened 4 months ago

totomakers commented 4 months ago

Describe the rule

I don't know if i can achive that already with the current config but i can't find anyting in the doc about it:

Propose a new rule or config for idiomatic css order:

https://github.com/necolas/idiomatic-css?tab=readme-ov-file#declaration-order

I whould like use it for a css-in-js library writing style in object. This kind of order can be applied also to JSX attribute (like Chakra-css)

Code example

const button = cva({
  base: {
    // Would be nice if this "mess" is properly sorted here
    alignItems: 'center',
    border: '2px solid transparent',
    borderRadius: '1',
    cursor: 'pointer',
    display: 'inline-flex',
    flexDirection: 'row',
    flexWrap: 'nowrap',
    fontWeight: 700,
    gap: 1,
    lineHeight: '24px',
    textAlign: 'center',
    transition:
      'background-color 150ms cubic-bezier(0.4, 0, 0.2, 1), border-color 150ms cubic-bezier(0.4, 0, 0.2, 1)',

    '&:disabled': {
      cursor: 'default',
      opacity: 0.5,
    },
    '&:focus, &[data-focused]': {
      outline: '3px solid var(--tintColor)',
      outlineOffset: '0px',
    },
    '&.fluid': {
      width: '100%',
    },
  },

  variants: {
    colorScheme: {
      error: {
        '--accentColor': 'colors.error.600',
        '--intenseAccentColor': 'colors.error.700',
        '--neutralColor': 'colors.error.500',
        '--tintColor': '#FEE4E2',
      },
      info: {
        '--accentColor': 'colors.info.600',
        '--intenseAccentColor': 'colors.info.700',
        '--neutralColor': 'colors.info.500',
        '--tintColor': '#E0F2FE',
      },
      neutral: {
        '--accentColor': 'colors.neutral.600',
        '--intenseAccentColor': 'colors.neutral.700',
        '--neutralColor': 'colors.neutral.500',
        '--tintColor': '#E9EEF1',
      },
      primary: {
        '--accentColor': 'colors.primary.600',
        '--intenseAccentColor': 'colors.primary.700',
        '--neutralColor': 'colors.primary.500',
        '--tintColor': '#D6F1F3',
      },
      success: {
        '--accentColor': 'colors.success.600',
        '--intenseAccentColor': 'colors.success.700',
        '--neutralColor': 'colors.success.500',
        '--tintColor': '#D1FADF',
      },
      warning: {
        '--accentColor': 'colors.warning.600',
        '--intenseAccentColor': 'colors.warning.700',
        '--neutralColor': 'colors.warning.500',
        '--tintColor': '#FEF0C7',
      },
    } satisfies Record<ButtonColorScheme, SystemStyleObject>,

    shape: {
      outline: {
        '&:not(:disabled)': {
          '&:active, &[data-pressed]': {
            backgroundColor: 'var(--intenseAccentColor)',
            borderColor: 'var(--intenseAccentColor)',
            color: 'neutral.0',
          },

          '&:hover, &[data-hovered]': {
            backgroundColor: 'var(--accentColor)',
            borderColor: 'var(--accentColor)',
            color: 'neutral.0',
          },
        },

        '&:focus, &[data-focused]': {
          backgroundColor: 'transparent',
          borderColor: 'var(--neutralColor)',
          color: 'var(--accentColor)',
        },

        backgroundColor: 'transparent',
        borderColor: 'var(--neutralColor)',
        color: 'var(--neutralColor)',
      },
      phantom: {
        '&:focus, &[data-focused]': {
          backgroundColor: 'var(--tintColor)',
          color: 'var(--accentColor)',
        },
        '&:not(:disabled)': {
          '&:active, &[data-pressed]': {
            backgroundColor: 'transparent',
            color: 'var(--intenseAccentColor)',
          },

          '&:hover, &[data-hovered]': {
            color: 'var(--accentColor)',
          },
        },
        backgroundColor: 'transparent',
        borderColor: 'transparent',
        color: 'var(--neutralColor)',
      },
      solid: {
        '&:focus, &[data-focused]': {
          backgroundColor: 'var(--neutralColor)',
        },
        '&:not(:disabled)': {
          '&:active, &[data-pressed]': {
            backgroundColor: 'var(--intenseAccentColor)',
            borderColor: 'var(--intenseAccentColor)',
          },

          '&:hover, &[data-hovered]': {
            backgroundColor: 'var(--accentColor)',
            borderColor: 'var(--accentColor)',
          },
        },
        backgroundColor: 'var(--neutralColor)',
        borderColor: 'var(--neutralColor)',
        color: 'neutral.0',
      },
    } satisfies Record<ButtonShape, SystemStyleObject>,

    size: {
      base: {
        padding: 1.5,
      },
      sm: {
        padding: 1,
      },
    } satisfies Record<ButtonSize, SystemStyleObject>,
  },
})

Additional comments

I don't know if we custom group we can target specific TS type (i don't think so) or specific file ?

<3 Thanks for the work and sorry for my english

Validations