Browse Source

Maintenance: Improve TailwindCSS class name order.

Dusan Vuckovic 10 months ago
parent
commit
011b0b1d08

+ 3 - 0
.eslintrc.js

@@ -179,6 +179,9 @@ module.exports = {
     'sonarjs/prefer-immediate-return': 'off',
 
     'sonarjs/prefer-single-boolean-return': 'off',
+
+    // Consider prettier offenses as errors.
+    'prettier/prettier': ['error'],
   },
   overrides: [
     {

+ 2 - 1
.prettierrc.json

@@ -3,5 +3,6 @@
   "singleQuote": true,
   "tabWidth": 2,
   "trailingComma": "all",
-  "plugins": ["prettier-plugin-tailwindcss"]
+  "plugins": ["prettier-plugin-tailwindcss"],
+  "tailwindFunctions": ["extendClasses"]
 }

+ 15 - 15
app/frontend/apps/desktop/form/theme/global/getCoreDesktopClasses.ts

@@ -13,18 +13,18 @@ const textInputClasses = (classes: Classes = {}) => {
   const innerErrorsClasses = innerInvalidClasses.replace(/invalid/g, 'errors')
 
   return extendClasses(classes, {
-    wrapper: 'flex flex-col items-start justify-start mb-1.5 last:mb-0',
+    wrapper: 'mb-1.5 flex flex-col items-start justify-start last:mb-0',
     input:
-      'grow bg-transparent py-2 px-2.5 placeholder:text-stone-200 dark:placeholder:text-neutral-500',
-    label: 'block mb-1 text-sm text-gray-100 dark:text-neutral-400',
-    inner: `flex items-center w-full h-10 bg-blue-200 dark:bg-gray-700 text-black dark:text-white hover:outline hover:outline-1 hover:outline-offset-1 hover:outline-blue-600 dark:hover:outline-blue-900 focus-within:outline focus-within:outline-1 focus-within:outline-offset-1 focus-within:outline-blue-800 hover:focus-within:outline-blue-800 dark:hover:focus-within:outline-blue-800 ${innerInvalidClasses} ${innerErrorsClasses}`,
+      'grow bg-transparent px-2.5 py-2 placeholder:text-stone-200 dark:placeholder:text-neutral-500',
+    label: 'mb-1 block text-sm text-gray-100 dark:text-neutral-400',
+    inner: `flex h-10 w-full items-center bg-blue-200 text-black focus-within:outline focus-within:outline-1 focus-within:outline-offset-1 focus-within:outline-blue-800 hover:outline hover:outline-1 hover:outline-offset-1 hover:outline-blue-600 hover:focus-within:outline-blue-800 dark:bg-gray-700 dark:text-white dark:hover:outline-blue-900 dark:hover:focus-within:outline-blue-800 ${innerInvalidClasses} ${innerErrorsClasses}`,
   })
 }
 
 const selectInputClasses = (classes: Classes = {}) =>
   extendClasses(classes, {
     inner:
-      'w-full formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500',
+      'formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500 w-full',
   })
 
 export const getCoreDesktopClasses: FormThemeExtension = (
@@ -33,20 +33,20 @@ export const getCoreDesktopClasses: FormThemeExtension = (
   return {
     global: extendClasses(classes.global, {
       wrapper:
-        'flex-grow formkit-disabled:opacity-50 formkit-disabled:pointer-events-none',
+        'formkit-disabled:opacity-50 formkit-disabled:pointer-events-none flex-grow',
       block: 'flex items-end',
       label:
-        'block -:mb-1 text-sm text-gray-100 dark:text-neutral-400 formkit-required:required formkit-invalid:text-red-500 formkit-errors:text-red-500',
+        '-:mb-1 formkit-required:required formkit-invalid:text-red-500 formkit-errors:text-red-500 block text-sm text-gray-100 dark:text-neutral-400',
       inner: 'rounded-lg text-sm',
-      messages: 'mt-1 formkit-invalid:text-red-500 formkit-errors:text-red-500',
-      help: 'text-stone-200 dark:text-neutral-500 mt-1',
+      messages: 'formkit-invalid:text-red-500 formkit-errors:text-red-500 mt-1',
+      help: 'mt-1 text-stone-200 dark:text-neutral-500',
       prefixIcon:
-        'relative h-5 w-5 flex justify-center items-center fill-current text-stone-200 dark:text-neutral-500 ltr:ml-2.5 rtl:mr-2.5',
+        'relative flex h-5 w-5 items-center justify-center fill-current text-stone-200 ltr:ml-2.5 rtl:mr-2.5 dark:text-neutral-500',
       suffixIcon:
-        'relative h-5 w-5 flex justify-center items-center fill-current text-stone-200 dark:text-neutral-500 ltr:mr-2.5 rtl:ml-2.5',
+        'relative flex h-5 w-5 items-center justify-center fill-current text-stone-200 ltr:mr-2.5 rtl:ml-2.5 dark:text-neutral-500',
     }),
     form: extendClasses(classes.form, {
-      messages: 'mb-2.5 space-y-2 flex-wrap',
+      messages: 'mb-2.5 flex-wrap space-y-2',
     }),
     text: textInputClasses(classes.text),
     password: textInputClasses(classes.password),
@@ -75,20 +75,20 @@ export const getCoreDesktopClasses: FormThemeExtension = (
     }),
     imageUpload: extendClasses(classes.imageUpload, {
       inner:
-        'w-full bg-blue-200 dark:bg-gray-700 formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500',
+        'formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500 w-full bg-blue-200 dark:bg-gray-700',
     }),
     select: selectInputClasses(classes.select),
     treeselect: selectInputClasses(classes.treeselect),
     autocomplete: selectInputClasses(classes.autocomplete),
     agent: selectInputClasses(classes.agent),
     toggle: extendClasses(classes.toggle, {
-      wrapper: 'h-10 flex flex-row-reverse items-center gap-1.5',
+      wrapper: 'flex h-10 flex-row-reverse items-center gap-1.5',
       label: '!mb-0 grow',
       inner: 'leading-[0]',
     }),
     groupPermissions: extendClasses(classes.groupPermissions, {
       inner:
-        'w-full bg-blue-200 dark:bg-gray-700 formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500',
+        'formkit-invalid:outline formkit-invalid:outline-1 formkit-invalid:outline-offset-1 formkit-invalid:outline-red-500 formkit-errors:outline formkit-errors:outline-1 formkit-errors:outline-offset-1 formkit-errors:outline-red-500 w-full bg-blue-200 dark:bg-gray-700',
     }),
   }
 }

+ 11 - 11
app/frontend/apps/mobile/form/theme/global/addAbsoluteFloatingLabel.ts

@@ -11,30 +11,30 @@ export const addAbsoluteFloatingLabel = (classes: Classes = {}) => {
   return extendClasses(classes, {
     outer: clean(`
       absolute-floating-input
-      relative flex-col flex px-2
+      relative flex flex-col px-2
     `),
     wrapper: 'relative flex-1',
     inner: 'flex ltr:pr-2 rtl:pl-2',
     block: 'flex',
     // text-base ensures there is no zoom when you click on the input on iOS
     input: clean(`
-      w-full
+      formkit-populated:pt-8
+      formkit-label-hidden:pt-2
       h-14
-      text-base
-      bg-transparent
+      w-full
       border-none
-      focus:outline-none
+      bg-transparent
+      text-base
       placeholder:text-transparent
       focus-within:pt-8
-      formkit-populated:pt-8
-      formkit-label-hidden:pt-2
+      focus:outline-none
     `),
     label: clean(`
-      absolute top-0 ltr:left-0 rtl:right-0
-      py-4 px-2 h-14
+      pointer-events-none absolute top-0 h-14
+      origin-left px-2 py-4
       text-base
-      transition-all duration-100 ease-in-out origin-left
-      pointer-events-none
+      transition-all duration-100 ease-in-out ltr:left-0
+      rtl:right-0
     `),
   })
 }

+ 1 - 1
app/frontend/apps/mobile/form/theme/global/addBlockFloatingLabel.ts

@@ -9,11 +9,11 @@ export const addBlockFloatingLabel = (classes: Classes = {}): Classes => {
     extendClasses(classes, {
       outer: 'floating-input',
       label: clean(`
-        text-base
         formkit-populated:-translate-y-[0.4rem]
         formkit-populated:scale-80
         formkit-populated:opacity-75
         formkit-populated:text-xs
+        text-base
       `),
     }),
   )

+ 9 - 9
app/frontend/apps/mobile/form/theme/global/addFloatingTextareaLabel.ts

@@ -18,23 +18,23 @@ export const addFloatingTextareaLabel = (classes: Classes = {}) => {
     // text-base ensures there is no zoom when you click on the input on iOS
     input: clean(`
       w-full
-      text-base
-      bg-transparent
       border-none
-      focus:outline-none
+      bg-transparent
+      text-base
       placeholder:text-transparent
+      focus:outline-none
     `),
     label: clean(`
+      formkit-populated:translate-y-0
+      formkit-populated:text-xs
+      formkit-populated:opacity-75
       flex
-      items-end
-      px-2
-      pt-5
       h-2
+      origin-left
       translate-y-4
-      text-base
       cursor-text
-      transition-all duration-100 ease-in-out origin-left
-      formkit-populated:translate-y-0 formkit-populated:text-xs formkit-populated:opacity-75
+      items-end px-2 pt-5 text-base
+      transition-all duration-100 ease-in-out
     `),
   })
 }

+ 16 - 16
app/frontend/apps/mobile/form/theme/global/addStaticFloatingLabel.ts

@@ -11,29 +11,29 @@ import { clean, extendClasses } from '#shared/form/plugins/utils.ts'
 export const addStaticFloatingLabel = (classes: Classes = {}): Classes => {
   return extendClasses(classes, {
     outer: clean(`
-      relative flex flex-col px-2
-      focus-within:bg-blue-highlight
+      focus-within:bg-blue-highlight relative flex flex-col
+      px-2
     `),
-    wrapper: 'relative py-1 flex-1 flex self-start justify-center flex-col',
-    inner: 'flex ltr:pr-2 rtl:pl-2 pb-1 relative',
-    block: 'flex min-h-[3.5rem] cursor-pointer formkit-disabled:cursor-default',
+    wrapper: 'relative flex flex-1 flex-col justify-center self-start py-1',
+    inner: 'relative flex pb-1 ltr:pr-2 rtl:pl-2',
+    block: 'formkit-disabled:cursor-default flex min-h-[3.5rem] cursor-pointer',
     // text-base ensures there is no zoom when you click on the input on iOS
     input: clean(`
-      w-full
-      ltr:pl-2 rtl:pr-2
-      text-base
+      formkit-label-hidden:pt-4
+      w-full border-none
       bg-transparent
-      border-none
-      focus:outline-none
-      placeholder:text-transparent
       pt-6
-      formkit-label-hidden:pt-4
+      text-base
+      placeholder:text-transparent
+      focus:outline-none
+      ltr:pl-2
+      rtl:pr-2
     `),
     label: clean(`
-      absolute top-0 ltr:left-0 rtl:right-0
-      py-4 px-2 h-14
-      transition-all duration-100 ease-in-out origin-left
-      pointer-events-none
+      pointer-events-none absolute top-0 h-14
+      origin-left px-2 py-4
+      transition-all duration-100 ease-in-out ltr:left-0
+      rtl:right-0
     `),
   })
 }

+ 10 - 10
app/frontend/apps/mobile/form/theme/global/getCoreMobileClasses.ts

@@ -15,7 +15,7 @@ export const addButtonVariants = (classes: Classes = {}): Classes => {
   return extendClasses(classes, {
     wrapper: 'relative',
     input:
-      'bg-transparent text-white formkit-variant-primary:bg-blue formkit-variant-submit:text-black formkit-variant-submit:bg-yellow formkit-variant-submit:font-semibold formkit-variant-danger:bg-red-dark formkit-variant-danger:text-red-bright',
+      'formkit-variant-primary:bg-blue formkit-variant-submit:text-black formkit-variant-submit:bg-yellow formkit-variant-submit:font-semibold formkit-variant-danger:bg-red-dark formkit-variant-danger:text-red-bright bg-transparent text-white',
   })
 }
 
@@ -27,11 +27,11 @@ const getCoreClasses: FormThemeExtension = (classes: FormThemeClasses) => {
       messages: 'px-2',
       message: 'text-red-bright pb-1',
       help: 'mt-0.5 px-2 pb-2',
-      arrow: 'formkit-arrow flex items-center formkit-disabled:opacity-30',
+      arrow: 'formkit-arrow formkit-disabled:opacity-30 flex items-center',
       prefixIcon:
-        'absolute top-1/2 transform -translate-y-1/2 rtl:right-3 ltr:left-3',
+        'absolute top-1/2 -translate-y-1/2 transform ltr:left-3 rtl:right-3',
       suffixIcon:
-        'absolute top-1/2 transform -translate-y-1/2 rtl:left-3 ltr:right-3 text-white fill-current flex justify-center items-center',
+        'absolute top-1/2 flex -translate-y-1/2 transform items-center justify-center fill-current text-white ltr:right-3 rtl:left-3',
     }),
     text: addAbsoluteFloatingLabel(classes.text),
     email: addAbsoluteFloatingLabel(classes.email),
@@ -57,19 +57,19 @@ const getCoreClasses: FormThemeExtension = (classes: FormThemeClasses) => {
       }),
     ),
     checkbox: extendClasses(classes.checkbox, {
-      wrapper: 'ltr:pl-2 rtl:pr-2 w-full select-none',
+      wrapper: 'w-full select-none ltr:pl-2 rtl:pr-2',
       inner: 'ltr:mr-2 rtl:ml-2',
       input:
-        'h-4 w-4 border-[1.5px] border-white rounded-sm bg-transparent focus:border-blue focus:bg-blue-highlight checked:focus:color-blue checked:bg-blue checked:border-blue checked:focus:bg-blue checked:hover:bg-blue',
+        'focus:border-blue focus:bg-blue-highlight checked:focus:color-blue checked:bg-blue checked:border-blue checked:focus:bg-blue checked:hover:bg-blue h-4 w-4 rounded-sm border-[1.5px] border-white bg-transparent',
     }),
     radio: extendClasses(classes.radio, {
       inner: 'ltr:mr-2 rtl:ml-2',
     }),
     toggle: extendClasses(classes.toggle, {
       outer: 'relative px-2',
-      wrapper: 'inline-flex w-full h-14 px-2',
-      label: 'flex items-center w-full h-full text-base cursor-pointer',
-      inner: 'flex items-center h-full',
+      wrapper: 'inline-flex h-14 w-full px-2',
+      label: 'flex h-full w-full cursor-pointer items-center text-base',
+      inner: 'flex h-full items-center',
     }),
     tags: addBlockFloatingLabel(classes.tags),
     select: addBlockFloatingLabel(classes.select),
@@ -84,8 +84,8 @@ const getCoreClasses: FormThemeExtension = (classes: FormThemeClasses) => {
     security: addStaticFloatingLabel(
       extendClasses(classes.security, {
         label: clean(`
-          -translate-y-[0.4rem]
           scale-80
+          -translate-y-[0.4rem]
           text-xs
         `),
       }),

+ 1 - 1
package.json

@@ -7,7 +7,7 @@
     "dev:https": "VITE_RUBY_HOST=0.0.0.0 VITE_RUBY_HTTPS=true RAILS_ENV=development forego start -f Procfile.dev-https",
     "i18n": "rails generate zammad:translation_catalog",
     "lint": "vue-tsc --noEmit && eslint --cache --cache-location ./tmp/eslintcache.js  --cache-strategy content -c .eslintrc.js --ext .js,.ts,.vue app/frontend/ .eslint-plugin-zammad/",
-    "lint:fix": "yarn lint -- --fix",
+    "lint:fix": "yarn lint --fix",
     "lint:css": "stylelint **/*.{css,vue,scss}",
     "lint:css:fix": "stylelint **/*.{css,vue,scss} --fix",
     "test": "VTL_SKIP_AUTO_CLEANUP=true TZ=utc vitest",