nextui icon indicating copy to clipboard operation
nextui copied to clipboard

[BUG] - Styling issue with Hero 2.8 / TW 4, when using prefix

Open AtmoFX opened this issue 6 months ago • 18 comments

HeroUI Version

@heroui/react 2.8.1

Though it was not originally the bug I was describing, the different answers to this thread have turned it into another, so I am changing it in an attempt to help the people who are not able to make prefix work. See a few answers down for how it turned that way :)

Describe the bug

Prefix, when defined, has no effect on variables and as a result, styles are not correctly applied.

Operating System Version

Windows

Browser

Firefox

AtmoFX avatar Jun 20 '25 02:06 AtmoFX

It looks fine on our beta docs (using the latest beta version). Could you please share a minimal reproducible sandbox for us to check?

https://beta.heroui.com/docs/components/input#usage

Image

wingkwong avatar Jun 20 '25 02:06 wingkwong

Sure, I have created this public repo: https://github.com/AtmoFX/HeroUI-Input.git

Taking the beta docs as reference helped; I see 2 CSS classes (possibly more may be missing, I have not analyzed every possible state for the input) are not being generated but I do not the reason why. I also realized the input with no placeholder does not behave correctly: when it has focus, the label font size slightly decreases but does not translate.

Capture and class below:

Image

@layer utilities {
  .group-data-\[filled-within\=true\]\:-translate-y-\[calc\(50\%_\+_var\(--heroui-font-size-small\)\/2_-_6px\)\]:is(:where(.group)[data-filled-within="true"] *) {
    --tw-translate-y: calc(calc(50% + var(--heroui-font-size-small)/2 - 6px)*-1);
    translate: var(--tw-translate-x)var(--tw-translate-y);
  }
}
@layer utilities {
  .transition-\[transform\,color\,left\,opacity\,translate\,scale\] {
    transition-property: transform,color,left,opacity,translate,scale;
    transition-timing-function: var(--tw-ease,var(--default-transition-timing-function));
    transition-duration: var(--tw-duration,var(--default-transition-duration));
  }
}

AtmoFX avatar Jun 21 '25 04:06 AtmoFX

I skimmed through your repo and saw you have installed system & theme packages. Could you please remove them, reinstall and retry? @heroui/react already includes them (but in beta version) and it could be caused by multiple versions.

wingkwong avatar Jun 21 '25 04:06 wingkwong

I removed them and ... I am not sure what is different now from what it was when I first tried to get it to work and no style whatsoever was being applied but well, it works now indeed.

Thanks for your help.

AtmoFX avatar Jun 21 '25 04:06 AtmoFX

@wingkwong This solution doesn't work, fresh install, @heroui/react": "^2.8.0-beta.11, the same issue.

FNDEVVE avatar Jul 05 '25 17:07 FNDEVVE

@FNDEVVE Still looking fine in our beta docs. I guess there is something wrong with your tw4 setup. Please provide a sandbox / repo for us to take a look.

wingkwong avatar Jul 05 '25 17:07 wingkwong

I updated the library and I confirm I have no styling issue anymore. Here is the result of pnpm list on my computer for that test project (Added dev for dev-only dependencies). I hope it helps:

dependencies:
@heroui/react 2.8.0-beta.11  pg-hstore 2.3.4
@types/pg 8.15.4             pnpm 10.12.1
add 2.0.6                    react 19.1.0
framer-motion 12.18.1        react-dom 19.1.0
next 15.3.3                  sequelize 6.37.7
pg 8.16.2                    tailwind-variants 1.0.0

devDependencies:
@eslint/eslintrc 3.3.1 (dev)
@tailwindcss/postcss 4.1.10 (dev)
@types/node 20.19.1
@types/react 19.1.8
@types/react-dom 19.1.6 (dev)
eslint 9.29.0 (dev)
eslint-config-next 15.3.3 (dev)
postcss 8.5.6 (dev)
tailwindcss 4.1.10
typescript 5.8.3 (dev)

AtmoFX avatar Jul 06 '25 00:07 AtmoFX

I also have this problem with labels and placeholders. None of the beta versions work. Tested today - from beta.9 to beta.13. Using @heroui/react only on fresh react project.

Marcin-Palubinski avatar Jul 09 '25 12:07 Marcin-Palubinski

OK found the problem. Custom prefix is not applying to some css variables in newer versions.

Marcin-Palubinski avatar Jul 09 '25 12:07 Marcin-Palubinski

OK found the problem. Custom prefix is not applying to some css variables in newer versions.

Any tips on how to fix it?

FNDEVVE avatar Jul 10 '25 18:07 FNDEVVE

hero.ts

import { heroui } from '@heroui/react';

export default heroui({
  addCommonColors: true,
  // prefix: 'customprefix', // removed this
});

I also noticed this is not only input problem, buttons and other components are also affected.

Marcin-Palubinski avatar Jul 10 '25 18:07 Marcin-Palubinski

hero.ts

import { heroui } from '@heroui/react';

export default heroui({ addCommonColors: true, // prefix: 'customprefix', // removed this });

I also noticed this is not only input problem, buttons and other components are also affected.

I confirm, CheckBox and Input are both broken simply by using a custom prefix

saoudi-h avatar Jul 20 '25 06:07 saoudi-h

It seems the issue needs to be reopened to address the now multiple comments that something is wrong (when a custom prefix is defined, if I understand correctly).

AtmoFX avatar Jul 21 '25 16:07 AtmoFX

I confirm this is a big issue after upgrading (to HeroUI 2.8 and TW 4): prefix in a theme breaks label positioning with the latest version (input v2.4.24). Glad I found this issue.

dmythro avatar Jul 24 '25 00:07 dmythro

same problem. after adding the prefix, some CSS variables were not affected

Image Image

aurora-lch avatar Jul 25 '25 07:07 aurora-lch

Some additional information. I've set a prefix then migrated to tailwind v4.

The generated css bundle seems to have 124 instances where --heroui prefix is applied anyway, whereas my --custom appeared 1500+ times.

Here are where --heroui is still being found (I only list one variant). That being said, the e.g. --custom-font-size-tiny: xxxrem declaration is still being generated.

  .group-data-\[has-helper\=true\]\:-translate-y-\[calc\(100\%\+var\(--heroui-font-size-small\)\/2\+26px\)\] {
    &:is(:where(.group)[data-has-helper="true"] *) {
      --tw-translate-y: calc(calc(100% + var(--heroui-font-size-small) / 2 + 26px) * -1);
      translate: var(--tw-translate-x) var(--tw-translate-y);
    }
  }
  .rounded-\[calc\(var\(--heroui-radius-large\)\/1\.5\)\] {
    border-radius: calc(var(--heroui-radius-large) / 1.5);
  }
  .before\:rounded-\[calc\(var\(--heroui-radius-medium\)\*0\.5\)\] {
    &::before {
      content: var(--tw-content);
      border-radius: calc(var(--heroui-radius-medium) * 0.5);
    }
  }
  .data-\[has-helper\=true\]\:pb-\[calc\(var\(--heroui-font-size-tiny\)\+8px\)\] {
    &[data-has-helper="true"] {
      padding-bottom: calc(var(--heroui-font-size-tiny) + 8px);
    }
  }
  .\[\&\+\.border-medium\.border-danger\]\:ms-\[calc\(var\(--heroui-border-width-medium\)\*-1\)\] {
    &+.border-medium.border-danger {
      margin-inline-start: calc(var(--heroui-border-width-medium) * -1);
    }
  }
  .text-large {
    font-size: var(--heroui-font-size-large);
    line-height: var(--heroui-line-height-large);
  }

danvim avatar Aug 05 '25 18:08 danvim

Workaround with custom prefix:

:root {
  --heroui-background: var(--custom-background);
  --heroui-foreground-50: var(--custom-foreground-50);
  --heroui-foreground-100: var(--custom-foreground-100);
  --heroui-foreground-200: var(--custom-foreground-200);
  --heroui-foreground-300: var(--custom-foreground-300);
  --heroui-foreground-400: var(--custom-foreground-400);
  --heroui-foreground-500: var(--custom-foreground-500);
  --heroui-foreground-600: var(--custom-foreground-600);
  --heroui-foreground-700: var(--custom-foreground-700);
  --heroui-foreground-800: var(--custom-foreground-800);
  --heroui-foreground-900: var(--custom-foreground-900);
  --heroui-foreground: var(--custom-foreground);
  --heroui-focus: var(--custom-focus);
  --heroui-overlay: var(--custom-overlay);
  --heroui-divider: var(--custom-divider);
  --heroui-content1: var(--custom-content1);
  --heroui-content1-foreground: var(--custom-content1-foreground);
  --heroui-content2: var(--custom-content2);
  --heroui-content2-foreground: var(--custom-content2-foreground);
  --heroui-content3: var(--custom-content3);
  --heroui-content3-foreground: var(--custom-content3-foreground);
  --heroui-content4: var(--custom-content4);
  --heroui-content4-foreground: var(--custom-content4-foreground);
  --heroui-default-50: var(--custom-default-50);
  --heroui-default-100: var(--custom-default-100);
  --heroui-default-200: var(--custom-default-200);
  --heroui-default-300: var(--custom-default-300);
  --heroui-default-400: var(--custom-default-400);
  --heroui-default-500: var(--custom-default-500);
  --heroui-default-600: var(--custom-default-600);
  --heroui-default-700: var(--custom-default-700);
  --heroui-default-800: var(--custom-default-800);
  --heroui-default-900: var(--custom-default-900);
  --heroui-default-foreground: var(--custom-default-foreground);
  --heroui-default: var(--custom-default);
  --heroui-primary-50: var(--custom-primary-50);
  --heroui-primary-100: var(--custom-primary-100);
  --heroui-primary-200: var(--custom-primary-200);
  --heroui-primary-300: var(--custom-primary-300);
  --heroui-primary-400: var(--custom-primary-400);
  --heroui-primary-500: var(--custom-primary-500);
  --heroui-primary-600: var(--custom-primary-600);
  --heroui-primary-700: var(--custom-primary-700);
  --heroui-primary-800: var(--custom-primary-800);
  --heroui-primary-900: var(--custom-primary-900);
  --heroui-primary-foreground: var(--custom-primary-foreground);
  --heroui-primary: var(--custom-primary);
  --heroui-secondary-50: var(--custom-secondary-50);
  --heroui-secondary-100: var(--custom-secondary-100);
  --heroui-secondary-200: var(--custom-secondary-200);
  --heroui-secondary-300: var(--custom-secondary-300);
  --heroui-secondary-400: var(--custom-secondary-400);
  --heroui-secondary-500: var(--custom-secondary-500);
  --heroui-secondary-600: var(--custom-secondary-600);
  --heroui-secondary-700: var(--custom-secondary-700);
  --heroui-secondary-800: var(--custom-secondary-800);
  --heroui-secondary-900: var(--custom-secondary-900);
  --heroui-secondary-foreground: var(--custom-secondary-foreground);
  --heroui-secondary: var(--custom-secondary);
  --heroui-success-50: var(--custom-success-50);
  --heroui-success-100: var(--custom-success-100);
  --heroui-success-200: var(--custom-success-200);
  --heroui-success-300: var(--custom-success-300);
  --heroui-success-400: var(--custom-success-400);
  --heroui-success-500: var(--custom-success-500);
  --heroui-success-600: var(--custom-success-600);
  --heroui-success-700: var(--custom-success-700);
  --heroui-success-800: var(--custom-success-800);
  --heroui-success-900: var(--custom-success-900);
  --heroui-success-foreground: var(--custom-success-foreground);
  --heroui-success: var(--custom-success);
  --heroui-warning-50: var(--custom-warning-50);
  --heroui-warning-100: var(--custom-warning-100);
  --heroui-warning-200: var(--custom-warning-200);
  --heroui-warning-300: var(--custom-warning-300);
  --heroui-warning-400: var(--custom-warning-400);
  --heroui-warning-500: var(--custom-warning-500);
  --heroui-warning-600: var(--custom-warning-600);
  --heroui-warning-700: var(--custom-warning-700);
  --heroui-warning-800: var(--custom-warning-800);
  --heroui-warning-900: var(--custom-warning-900);
  --heroui-warning-foreground: var(--custom-warning-foreground);
  --heroui-warning: var(--custom-warning);
  --heroui-danger-50: var(--custom-danger-50);
  --heroui-danger-100: var(--custom-danger-100);
  --heroui-danger-200: var(--custom-danger-200);
  --heroui-danger-300: var(--custom-danger-300);
  --heroui-danger-400: var(--custom-danger-400);
  --heroui-danger-500: var(--custom-danger-500);
  --heroui-danger-600: var(--custom-danger-600);
  --heroui-danger-700: var(--custom-danger-700);
  --heroui-danger-800: var(--custom-danger-800);
  --heroui-danger-900: var(--custom-danger-900);
  --heroui-danger-foreground: var(--custom-danger-foreground);
  --heroui-danger: var(--custom-danger);
  --heroui-divider-weight: var(--custom-divider-weight);
  --heroui-disabled-opacity: var(--custom-disabled-opacity);
  --heroui-font-size-tiny: var(--custom-font-size-tiny);
  --heroui-font-size-small: var(--custom-font-size-small);
  --heroui-font-size-medium: var(--custom-font-size-medium);
  --heroui-font-size-large: var(--custom-font-size-large);
  --heroui-line-height-tiny: var(--custom-line-height-tiny);
  --heroui-line-height-small: var(--custom-line-height-small);
  --heroui-line-height-medium: var(--custom-line-height-medium);
  --heroui-line-height-large: var(--custom-line-height-large);
  --heroui-radius-small: var(--custom-radius-small);
  --heroui-radius-medium: var(--custom-radius-medium);
  --heroui-radius-large: var(--custom-radius-large);
  --heroui-border-width-small: var(--custom-border-width-small);
  --heroui-border-width-medium: var(--custom-border-width-medium);
  --heroui-border-width-large: var(--custom-border-width-large);
  --heroui-box-shadow-small: var(--custom-box-shadow-small);
  --heroui-box-shadow-medium: var(--custom-box-shadow-medium);
  --heroui-box-shadow-large: var(--custom-box-shadow-large);
  --heroui-hover-opacity: var(--custom-hover-opacity);
}

Marcin-Palubinski avatar Nov 03 '25 12:11 Marcin-Palubinski