diff --git a/.changeset/calm-trees-serve.md b/.changeset/calm-trees-serve.md new file mode 100644 index 0000000000..c5dd228d82 --- /dev/null +++ b/.changeset/calm-trees-serve.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/theme": patch +--- + +fix label placement in input and select diff --git a/.changeset/dull-bags-divide.md b/.changeset/dull-bags-divide.md new file mode 100644 index 0000000000..25e4ee0d56 --- /dev/null +++ b/.changeset/dull-bags-divide.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/select": patch +--- + +update label placement in Select to use `shouldLabelBeOutside` instead of `isOutsideLeft`, resolving multiline label placement issues (#3841). diff --git a/.changeset/fast-horses-explode.md b/.changeset/fast-horses-explode.md new file mode 100644 index 0000000000..bf5c56177b --- /dev/null +++ b/.changeset/fast-horses-explode.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/theme": patch +--- + +fix the fullWidth variant in input and select component. (#3745) diff --git a/.changeset/giant-worms-hammer.md b/.changeset/giant-worms-hammer.md new file mode 100644 index 0000000000..f11a1ec96e --- /dev/null +++ b/.changeset/giant-worms-hammer.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/theme": patch +--- + +replace the use of RTL-specific styles with logical properties. diff --git a/.changeset/mighty-birds-deny.md b/.changeset/mighty-birds-deny.md new file mode 100644 index 0000000000..b991ace2ff --- /dev/null +++ b/.changeset/mighty-birds-deny.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/autocomplete": patch +--- + +Return null if there are items for exit animation on popover close to work diff --git a/apps/docs/config/site.ts b/apps/docs/config/site.ts index d982df3b07..b2bf8f37bf 100644 --- a/apps/docs/config/site.ts +++ b/apps/docs/config/site.ts @@ -33,7 +33,7 @@ export const siteConfig = { links: { github: "https://github.com/nextui-org/nextui", twitter: "https://x.com/getnextui", - docs: "https://nextui-docs-v2.vercel.app", + docs: "https://nextui.org", discord: "https://discord.gg/9b6yyZKmH4", sponsor: "https://patreon.com/jrgarciadev", portfolio: "https://jrgarciadev.com", diff --git a/apps/docs/content/components/image/blurred.ts b/apps/docs/content/components/image/blurred.ts index 7a958a8e3c..379e433c7a 100644 --- a/apps/docs/content/components/image/blurred.ts +++ b/apps/docs/content/components/image/blurred.ts @@ -5,7 +5,7 @@ export default function App() { NextUI Album Cover diff --git a/apps/docs/content/components/image/fallback.ts b/apps/docs/content/components/image/fallback.ts index 3d66825416..165089d80a 100644 --- a/apps/docs/content/components/image/fallback.ts +++ b/apps/docs/content/components/image/fallback.ts @@ -5,7 +5,7 @@ export default function App() { NextUI Image with fallback diff --git a/apps/docs/content/components/image/loading.ts b/apps/docs/content/components/image/loading.ts index 6ba0fa34e0..e2d70af02f 100644 --- a/apps/docs/content/components/image/loading.ts +++ b/apps/docs/content/components/image/loading.ts @@ -6,7 +6,7 @@ export default function App() { width={300} height={200} alt="NextUI hero Image with delay" - src="https://app.requestly.io/delay/5000/https://nextui-docs-v2.vercel.app/images/hero-card-complete.jpeg" + src="https://app.requestly.io/delay/5000/https://nextui.org/images/hero-card-complete.jpeg" /> ); }`; diff --git a/apps/docs/content/components/image/nextjs.ts b/apps/docs/content/components/image/nextjs.ts index 8721fa27c5..ff6a18e14e 100644 --- a/apps/docs/content/components/image/nextjs.ts +++ b/apps/docs/content/components/image/nextjs.ts @@ -7,7 +7,7 @@ export default function App() { as={NextImage} width={300} height={200} - src="https://nextui-docs-v2.vercel.app/images/hero-card-complete.jpeg" + src="https://nextui.org/images/hero-card-complete.jpeg" alt="NextUI hero Image" /> ); diff --git a/apps/docs/content/components/image/usage.ts b/apps/docs/content/components/image/usage.ts index 8c793f4d9c..7041554fed 100644 --- a/apps/docs/content/components/image/usage.ts +++ b/apps/docs/content/components/image/usage.ts @@ -5,7 +5,7 @@ export default function App() { NextUI hero Image ); }`; diff --git a/apps/docs/content/components/image/zoomed.ts b/apps/docs/content/components/image/zoomed.ts index 6094e5d565..2aaa13b28f 100644 --- a/apps/docs/content/components/image/zoomed.ts +++ b/apps/docs/content/components/image/zoomed.ts @@ -6,7 +6,7 @@ export default function App() { isZoomed width={240} alt="NextUI Fruit Image with Zoom" - src="https://nextui-docs-v2.vercel.app/images/fruit-1.jpeg" + src="https://nextui.org/images/fruit-1.jpeg" /> ); }`; diff --git a/apps/docs/content/docs/components/date-picker.mdx b/apps/docs/content/docs/components/date-picker.mdx index 6aa0270917..7e11ee64cf 100644 --- a/apps/docs/content/docs/components/date-picker.mdx +++ b/apps/docs/content/docs/components/date-picker.mdx @@ -277,7 +277,7 @@ import {I18nProvider} from "@react-aria/i18n"; `DatePicker` has the following attributes on the `base` element: - **data-slot**: - All slots have this prop. which slot the element represents(e.g. `canlendar`). + All slots have this prop. which slot the element represents(e.g. `calendar`). - **data-open**: Indicates if the calendar popover is open. - **data-invalid**: diff --git a/apps/docs/content/docs/components/select.mdx b/apps/docs/content/docs/components/select.mdx index 1edb25ae6a..e95072ffd7 100644 --- a/apps/docs/content/docs/components/select.mdx +++ b/apps/docs/content/docs/components/select.mdx @@ -54,7 +54,7 @@ Select follows the [Collection Components API](https://react-spectrum.adobe.com/ - **Static**: The usage example above shows the static implementation, which can be used when the full list of options is known ahead of time. - **Dynamic**: The example below can be used when the options come from an external data source such as an API call, or update over time. - + ### Multiple Selection diff --git a/apps/docs/content/docs/customization/dark-mode.mdx b/apps/docs/content/docs/customization/dark-mode.mdx index d0539d70bf..1feeac9806 100644 --- a/apps/docs/content/docs/customization/dark-mode.mdx +++ b/apps/docs/content/docs/customization/dark-mode.mdx @@ -118,7 +118,7 @@ export function ThemeSwitcher() { }; ``` -> **Note**: You can use any theme name you want, but make sure it exits in your +> **Note**: You can use any theme name you want, but make sure it exists in your `tailwind.config.js` file. See [Create Theme](/docs/customization/create-theme) for more details. @@ -185,7 +185,7 @@ export const ThemeSwitcher = () => { }; ``` -> **Note**: You can use any theme name you want, but make sure it exits in your +> **Note**: You can use any theme name you want, but make sure it exists in your `tailwind.config.js` file. See [Create Theme](/docs/customization/create-theme) for more details. @@ -258,4 +258,4 @@ export const ThemeSwitcher = () => { `tailwind.config.js` file. See [Create Theme](/docs/customization/create-theme) for more details. - \ No newline at end of file + diff --git a/packages/components/autocomplete/src/autocomplete.tsx b/packages/components/autocomplete/src/autocomplete.tsx index 2eadca4ebd..ba434fe292 100644 --- a/packages/components/autocomplete/src/autocomplete.tsx +++ b/packages/components/autocomplete/src/autocomplete.tsx @@ -31,15 +31,17 @@ function Autocomplete(props: Props, ref: ForwardedRef({...props, ref}); + const listboxProps = getListBoxProps(); + const popoverContent = isOpen ? ( - + - ) : ( + ) : listboxProps.state?.collection.size === 0 ? (
- ); + ) : null; return ( diff --git a/packages/components/dropdown/__tests__/dropdown.test.tsx b/packages/components/dropdown/__tests__/dropdown.test.tsx index 359e337116..51be87d10d 100644 --- a/packages/components/dropdown/__tests__/dropdown.test.tsx +++ b/packages/components/dropdown/__tests__/dropdown.test.tsx @@ -526,7 +526,7 @@ describe("Dropdown", () => { NextUI hero Image diff --git a/packages/components/select/__tests__/select.test.tsx b/packages/components/select/__tests__/select.test.tsx index ec751bec8c..85258d1aaa 100644 --- a/packages/components/select/__tests__/select.test.tsx +++ b/packages/components/select/__tests__/select.test.tsx @@ -720,6 +720,63 @@ describe("Select", () => { expect(onChange).toBeCalledTimes(1); }); }); + + it("should place the label outside when labelPlacement is outside", () => { + const labelContent = "Favorite Animal Label"; + + render( + , + ); + + const base = document.querySelector("[data-slot=base]"); + const trigger = document.querySelector("[data-slot=trigger]"); + + expect(base).toHaveTextContent(labelContent); + expect(trigger).not.toHaveTextContent(labelContent); + }); + + it("should place the label inside when labelPlacement prop is not passed", () => { + const labelContent = "Favorite Animal Label"; + + render( + , + ); + + const trigger = document.querySelector("[data-slot=trigger]"); + + expect(trigger).toHaveTextContent(labelContent); + }); }); describe("Select with React Hook Form", () => { diff --git a/packages/components/select/src/select.tsx b/packages/components/select/src/select.tsx index e116d78a8f..da6c46ad0e 100644 --- a/packages/components/select/src/select.tsx +++ b/packages/components/select/src/select.tsx @@ -31,6 +31,7 @@ function Select(props: Props, ref: ForwardedRef(props: Props, ref: ForwardedRef - {isOutsideLeft ? labelContent : null} + {shouldLabelBeOutside ? labelContent : null}
- {!isOutsideLeft ? labelContent : null} + {!shouldLabelBeOutside ? labelContent : null}
{startContent} {renderSelectedItem} diff --git a/packages/core/theme/src/components/checkbox.ts b/packages/core/theme/src/components/checkbox.ts index 7ebf311c7d..3a9de2c9a0 100644 --- a/packages/core/theme/src/components/checkbox.ts +++ b/packages/core/theme/src/components/checkbox.ts @@ -78,7 +78,7 @@ const checkbox = tv({ size: { sm: { wrapper: [ - "w-4 h-4 mr-2 rtl:ml-2 rtl:mr-[unset]", + "w-4 h-4 me-2", "rounded-[calc(theme(borderRadius.medium)*0.5)]", "before:rounded-[calc(theme(borderRadius.medium)*0.5)]", "after:rounded-[calc(theme(borderRadius.medium)*0.5)]", @@ -88,7 +88,7 @@ const checkbox = tv({ }, md: { wrapper: [ - "w-5 h-5 mr-2 rtl:ml-2 rtl:mr-[unset]", + "w-5 h-5 me-2", "rounded-[calc(theme(borderRadius.medium)*0.6)]", "before:rounded-[calc(theme(borderRadius.medium)*0.6)]", "after:rounded-[calc(theme(borderRadius.medium)*0.6)]", @@ -98,7 +98,7 @@ const checkbox = tv({ }, lg: { wrapper: [ - "w-6 h-6 mr-2 rtl:ml-2 rtl:mr-[unset]", + "w-6 h-6 me-2", "rounded-[calc(theme(borderRadius.medium)*0.7)]", "before:rounded-[calc(theme(borderRadius.medium)*0.7)]", "after:rounded-[calc(theme(borderRadius.medium)*0.7)]", diff --git a/packages/core/theme/src/components/date-input.ts b/packages/core/theme/src/components/date-input.ts index 1036491eec..62977f947f 100644 --- a/packages/core/theme/src/components/date-input.ts +++ b/packages/core/theme/src/components/date-input.ts @@ -166,13 +166,13 @@ const dateInput = tv({ outside: { base: "flex flex-col data-[has-helper=true]:pb-[calc(theme(fontSize.tiny)_+8px)] gap-y-1.5", label: "w-full text-foreground", - helperWrapper: "absolute top-[calc(100%_+_2px)] left-0 rtl:right-0", + helperWrapper: "absolute top-[calc(100%_+_2px)] start-0", }, "outside-left": { base: "flex-row items-center data-[has-helper=true]:pb-[calc(theme(fontSize.tiny)_+_8px)] gap-x-2 flex-nowrap", label: "relative text-foreground", inputWrapper: "relative flex-1", - helperWrapper: "absolute top-[calc(100%_+_2px)] left-0 rtl:right-0", + helperWrapper: "absolute top-[calc(100%_+_2px)] start-0", }, inside: { label: "w-full text-tiny cursor-text", diff --git a/packages/core/theme/src/components/input.ts b/packages/core/theme/src/components/input.ts index 43c0741982..cf89a5f1a2 100644 --- a/packages/core/theme/src/components/input.ts +++ b/packages/core/theme/src/components/input.ts @@ -29,6 +29,7 @@ const input = tv({ "z-10", "pointer-events-none", "origin-top-left", + // Using RTL here as Tailwind CSS doesn't support `start` and `end` logical properties for transforms yet. "rtl:origin-top-right", "subpixel-antialiased", "block", @@ -185,10 +186,11 @@ const input = tv({ true: { base: "w-full", }, + false: {}, }, isClearable: { true: { - input: "peer pr-6 rtl:pr-0 rtl:pl-6", + input: "peer pe-6", clearButton: "peer-data-[filled=true]:opacity-70 peer-data-[filled=true]:block", }, }, @@ -207,8 +209,7 @@ const input = tv({ }, isRequired: { true: { - label: - "after:content-['*'] after:text-danger after:ml-0.5 rtl:after:ml-[unset] rtl:after:mr-0.5", + label: "after:content-['*'] after:text-danger after:ms-0.5", }, }, isMultiline: { diff --git a/packages/core/theme/src/components/modal.ts b/packages/core/theme/src/components/modal.ts index b98f3d24f0..4aeeb471f1 100644 --- a/packages/core/theme/src/components/modal.ts +++ b/packages/core/theme/src/components/modal.ts @@ -59,9 +59,7 @@ const modal = tv({ "outline-none", "select-none", "top-1", - "right-1", - "rtl:left-1", - "rtl:right-[unset]", + "end-1", "p-2", "text-foreground-500", "rounded-full", diff --git a/packages/core/theme/src/components/radio.ts b/packages/core/theme/src/components/radio.ts index 30f0feeacb..a5161981fd 100644 --- a/packages/core/theme/src/components/radio.ts +++ b/packages/core/theme/src/components/radio.ts @@ -97,14 +97,14 @@ const radio = tv({ md: { wrapper: "w-5 h-5", control: "w-2 h-2", - labelWrapper: "ml-2 rtl:mr-2 rtl:ml-[unset]", + labelWrapper: "ms-2", label: "text-medium", description: "text-small", }, lg: { wrapper: "w-6 h-6", control: "w-2.5 h-2.5", - labelWrapper: "ml-2 rtl:mr-2 rtl:ml-[unset]", + labelWrapper: "ms-2", label: "text-large", description: "text-medium", }, diff --git a/packages/core/theme/src/components/select.ts b/packages/core/theme/src/components/select.ts index eff6392b2e..2d73f7fd4e 100644 --- a/packages/core/theme/src/components/select.ts +++ b/packages/core/theme/src/components/select.ts @@ -5,12 +5,13 @@ import {tv} from "../utils/tv"; const select = tv({ slots: { - base: ["group inline-flex flex-col relative w-full"], + base: ["group inline-flex flex-col relative"], label: [ "block", "absolute", "z-10", "origin-top-left", + // Using RTL here as Tailwind CSS doesn't support `start` and `end` logical properties for transforms yet. "rtl:origin-top-right", "subpixel-antialiased", "text-small", @@ -24,7 +25,7 @@ const select = tv({ "inline-flex h-full w-[calc(100%_-_theme(spacing.6))] min-h-4 items-center gap-1.5 box-border", selectorIcon: "absolute end-3 w-4 h-4", spinner: "absolute end-3", - value: ["text-foreground-500", "font-normal", "w-full", "text-left", "rtl:text-right"], + value: ["text-foreground-500", "font-normal", "w-full", "text-start"], listboxWrapper: "scroll-py-6 max-h-64 w-full", listbox: "", popoverContent: "w-full p-1 overflow-hidden", @@ -166,6 +167,9 @@ const select = tv({ true: { base: "w-full", }, + false: { + base: "min-w-40", + }, }, isClearable: { true: { @@ -211,6 +215,7 @@ const select = tv({ label: [ "will-change-auto", "origin-top-left", + // Using RTL here as Tailwind CSS doesn't support `start` and `end` logical properties for transforms yet. "rtl:origin-top-right", "!duration-200", "!ease-out", diff --git a/packages/core/theme/src/components/toggle.ts b/packages/core/theme/src/components/toggle.ts index 8b70dcf2be..f8d32f7032 100644 --- a/packages/core/theme/src/components/toggle.ts +++ b/packages/core/theme/src/components/toggle.ts @@ -54,8 +54,8 @@ const toggle = tv({ "rounded-full", "origin-right", ], - startContent: "z-0 absolute left-1.5 rtl:right-1.5 rtl:left-[unset] text-current", - endContent: "z-0 absolute right-1.5 rtl:left-1.5 rtl:right-[unset] text-default-600", + startContent: "z-0 absolute start-1.5 text-current", + endContent: "z-0 absolute end-1.5 text-default-600", thumbIcon: "text-black", label: "relative text-foreground select-none", }, @@ -100,33 +100,33 @@ const toggle = tv({ }, size: { sm: { - wrapper: "w-10 h-6 mr-2 rtl:ml-2 rtl:mr-[unset]", + wrapper: "w-10 h-6 me-2", thumb: [ "w-4 h-4 text-tiny", //selected - "group-data-[selected=true]:ml-4 rtl:group-data-[selected=true]:ml-0 rtl:group-data-[selected=true]:mr-4", + "group-data-[selected=true]:ms-4", ], endContent: "text-tiny", startContent: "text-tiny", label: "text-small", }, md: { - wrapper: "w-12 h-7 mr-2 rtl:ml-2 rtl:mr-[unset]", + wrapper: "w-12 h-7 me-2", thumb: [ "w-5 h-5 text-small", //selected - "group-data-[selected=true]:ml-5 rtl:group-data-[selected=true]:ml-0 rtl:group-data-[selected=true]:mr-5", + "group-data-[selected=true]:ms-5", ], endContent: "text-small", startContent: "text-small", label: "text-medium", }, lg: { - wrapper: "w-14 h-8 mr-2 rtl:ml-2 rtl:mr-[unset]", + wrapper: "w-14 h-8 me-2", thumb: [ "w-6 h-6 text-medium", //selected - "group-data-[selected=true]:ml-6 rtl:group-data-[selected=true]:ml-0 rtl:group-data-[selected=true]:mr-6", + "group-data-[selected=true]:ms-6", ], endContent: "text-medium", startContent: "text-medium",