Skip to content

Commit 8111191

Browse files
committed
feat(ui-react/carousel): ✨ add placement support to Carousel.Caption with typed position variants and default bottom-left
refactor(docs/carousel): ♻️ migrate carousel demo caption positioning to the new `placement` prop API chore(lint/ui-react-docs): 🧹 align React ESLint suppression directives for refs, static-components, and hook-factory rules chore(deps/workspace): ⬆️ bump toolkit/internal packages, eslint/prettier tooling, app dependencies, catalog `react-hook-form`, and regenerate `pnpm-lock.yaml`
1 parent 808a9fd commit 8111191

15 files changed

Lines changed: 767 additions & 817 deletions

File tree

apps/dev/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,30 @@
1313
"dependencies": {
1414
"@hookform/resolvers": "5.2.2",
1515
"@iconify/react": "6.0.2",
16-
"@zayne-labs/callapi": "1.12.4",
17-
"@zayne-labs/toolkit-core": "0.12.49",
18-
"@zayne-labs/toolkit-react": "0.12.49",
19-
"@zayne-labs/toolkit-type-helpers": "0.12.49",
16+
"@zayne-labs/callapi": "1.12.6",
17+
"@zayne-labs/toolkit-core": "0.12.50",
18+
"@zayne-labs/toolkit-react": "0.12.50",
19+
"@zayne-labs/toolkit-type-helpers": "0.12.50",
2020
"@zayne-labs/ui-react": "workspace:*",
2121
"react": "catalog:react:peer",
2222
"react-dom": "catalog:react:peer",
2323
"react-hook-form": "catalog:react:peer",
2424
"tailwind-merge": "catalog:react:peer",
2525
"tailwind-variants": "3.2.2",
26-
"zod": "4.3.6"
26+
"zod": "4.4.3"
2727
},
2828
"devDependencies": {
2929
"@tailwindcss/vite": "4.2.4",
3030
"@types/node": "25.6.0",
3131
"@types/react": "19.2.14",
3232
"@types/react-dom": "19.2.3",
3333
"@vitejs/plugin-react": "6.0.1",
34-
"@zayne-labs/prettier-config": "0.13.5",
35-
"@zayne-labs/tsconfig": "0.13.5",
34+
"@zayne-labs/prettier-config": "0.13.11",
35+
"@zayne-labs/tsconfig": "0.13.11",
3636
"prettier": "3.8.3",
3737
"prettier-plugin-classnames": "0.10.1",
3838
"prettier-plugin-merge": "0.10.1",
39-
"prettier-plugin-tailwindcss": "0.7.3",
39+
"prettier-plugin-tailwindcss": "0.8.0",
4040
"tailwindcss": "catalog:react:peer",
4141
"tw-animate-css": "1.4.0",
4242
"typescript": "6.0.3",

apps/docs/components/preview/component-preview.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type ComponentPreviewProps = React.ComponentPropsWithoutRef<"div"> & {
1313
export function ComponentPreview(props: ComponentPreviewProps) {
1414
const { align = "center", className, fullPreview, name, preventPreviewFocus, scalePreview } = props;
1515

16+
// eslint-disable-next-line react/static-components
1617
const Component = getExampleComponent(name);
1718

1819
return (
@@ -37,7 +38,7 @@ export function ComponentPreview(props: ComponentPreviewProps) {
3738
)}
3839
>
3940
<Suspense fallback={<p className="text-fd-muted-foreground">Loading...</p>}>
40-
{/* eslint-disable-next-line react-hooks/static-components */}
41+
{/* eslint-disable-next-line react/static-components */}
4142
<Component />
4243
</Suspense>
4344
</div>

apps/docs/examples/carousel-demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ function CarouselDemo() {
5858

5959
<Carousel.Caption
6060
as="article"
61-
className="bottom-0 left-0 flex w-full flex-col gap-3 p-8 text-white md:py-13 md:pr-12
62-
md:pl-16"
61+
placement="bottom-left"
62+
className="flex w-full flex-col gap-3 p-8 text-white md:py-13 md:pr-12 md:pl-16"
6363
>
6464
<div className="flex items-center gap-2">
6565
<span

apps/docs/package.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,34 @@
1515
"start": "next start"
1616
},
1717
"dependencies": {
18-
"@ai-sdk/google": "^3.0.64",
19-
"@ai-sdk/react": "^3.0.170",
18+
"@ai-sdk/google": "^3.0.67",
19+
"@ai-sdk/react": "^3.0.177",
2020
"@base-ui/react": "^1.4.1",
2121
"@bprogress/next": "^3.2.12",
2222
"@hookform/resolvers": "5.2.2",
2323
"@iconify/react": "6.0.2",
2424
"@takumi-rs/image-response": "^1.1.2",
2525
"@types/hast": "^3.0.4",
26-
"@zayne-labs/callapi": "1.12.4",
27-
"@zayne-labs/toolkit-core": "0.12.49",
28-
"@zayne-labs/toolkit-react": "0.12.49",
29-
"@zayne-labs/toolkit-type-helpers": "0.12.49",
26+
"@zayne-labs/callapi": "1.12.6",
27+
"@zayne-labs/toolkit-core": "0.12.50",
28+
"@zayne-labs/toolkit-react": "0.12.50",
29+
"@zayne-labs/toolkit-type-helpers": "0.12.50",
3030
"@zayne-labs/ui-react": "workspace:*",
31-
"ai": "^6.0.168",
31+
"ai": "^6.0.175",
3232
"flexsearch": "^0.8.212",
33-
"fumadocs-core": "16.8.4",
34-
"fumadocs-mdx": "14.3.1",
33+
"fumadocs-core": "16.8.7",
34+
"fumadocs-mdx": "14.3.2",
3535
"fumadocs-typescript": "^5.2.6",
36-
"fumadocs-ui": "16.8.4",
36+
"fumadocs-ui": "16.8.7",
3737
"hast-util-to-jsx-runtime": "^2.3.6",
38-
"lru-cache": "^11.3.5",
39-
"lucide-react": "^1.11.0",
38+
"lru-cache": "^11.3.6",
39+
"lucide-react": "^1.14.0",
4040
"motion": "^12.36.0",
4141
"next": "16.2.4",
4242
"radix-ui": "^1.4.3",
4343
"react": "^19.2.5",
4444
"react-dom": "^19.2.5",
45-
"react-hook-form": "7.74.0",
45+
"react-hook-form": "7.75.0",
4646
"remark": "^15.0.1",
4747
"remark-gfm": "^4.0.1",
4848
"remark-mdx": "^3.1.1",
@@ -52,7 +52,7 @@
5252
"tailwind-merge": "^3.5.0",
5353
"tailwind-variants": "3.2.2",
5454
"unist-util-visit": "^5.1.0",
55-
"zod": "4.3.6"
55+
"zod": "4.4.3"
5656
},
5757
"devDependencies": {
5858
"@tailwindcss/postcss": "^4.2.4",
@@ -61,13 +61,13 @@
6161
"@types/node": "^25.6.0",
6262
"@types/react": "^19.2.14",
6363
"@types/react-dom": "^19.2.3",
64-
"@zayne-labs/prettier-config": "0.13.5",
65-
"@zayne-labs/tsconfig": "0.13.5",
66-
"postcss": "^8.5.12",
64+
"@zayne-labs/prettier-config": "0.13.11",
65+
"@zayne-labs/tsconfig": "0.13.11",
66+
"postcss": "^8.5.14",
6767
"prettier": "3.8.3",
6868
"prettier-plugin-classnames": "0.10.1",
6969
"prettier-plugin-merge": "0.10.1",
70-
"prettier-plugin-tailwindcss": "0.7.3",
70+
"prettier-plugin-tailwindcss": "0.8.0",
7171
"tailwindcss": "^4.2.4",
7272
"tsx": "4.21.0",
7373
"tw-animate-css": "^1.4.0",

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@
3030
},
3131
"devDependencies": {
3232
"@arethetypeswrong/cli": "0.18.2",
33-
"@eslint-react/eslint-plugin": "4.2.3",
33+
"@eslint-react/eslint-plugin": "5.7.2",
3434
"@next/eslint-plugin-next": "16.2.4",
3535
"@types/node": "25.6.0",
36-
"@zayne-labs/eslint-config": "0.13.5",
37-
"@zayne-labs/prettier-config": "0.13.5",
38-
"@zayne-labs/tsconfig": "0.13.5",
36+
"@zayne-labs/eslint-config": "0.13.11",
37+
"@zayne-labs/prettier-config": "0.13.11",
38+
"@zayne-labs/tsconfig": "0.13.11",
3939
"bumpp": "10.4.1",
40-
"eslint": "10.2.1",
41-
"eslint-plugin-better-tailwindcss": "4.4.1",
40+
"eslint": "10.3.0",
41+
"eslint-plugin-better-tailwindcss": "4.5.0",
4242
"eslint-plugin-react-hooks": "7.1.1",
4343
"eslint-plugin-react-refresh": "0.5.2",
44-
"eslint-plugin-react-you-might-not-need-an-effect": "0.9.3",
44+
"eslint-plugin-react-you-might-not-need-an-effect": "0.10.0",
4545
"husky": "9.1.7",
4646
"lint-staged": "16.4.0",
4747
"prettier": "3.8.3",
4848
"prettier-plugin-classnames": "0.10.1",
4949
"prettier-plugin-merge": "0.10.1",
50-
"prettier-plugin-tailwindcss": "0.7.3",
50+
"prettier-plugin-tailwindcss": "0.8.0",
5151
"tailwindcss": "4.2.4",
52-
"turbo": "2.9.6",
52+
"turbo": "2.9.9",
5353
"typescript": "6.0.3"
5454
},
5555
"publishConfig": {

packages/ui-react/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@
6161
}
6262
},
6363
"dependencies": {
64-
"@zayne-labs/toolkit-core": "0.12.49",
65-
"@zayne-labs/toolkit-react": "0.12.49",
66-
"@zayne-labs/toolkit-type-helpers": "0.12.49"
64+
"@zayne-labs/toolkit-core": "0.12.50",
65+
"@zayne-labs/toolkit-react": "0.12.50",
66+
"@zayne-labs/toolkit-type-helpers": "0.12.50"
6767
},
6868
"devDependencies": {
6969
"@arethetypeswrong/cli": "0.18.2",
@@ -73,14 +73,14 @@
7373
"@total-typescript/ts-reset": "0.6.1",
7474
"@types/react": "19.2.14",
7575
"@types/react-dom": "19.2.3",
76-
"@zayne-labs/prettier-config": "0.13.5",
77-
"@zayne-labs/tsconfig": "0.13.5",
76+
"@zayne-labs/prettier-config": "0.13.11",
77+
"@zayne-labs/tsconfig": "0.13.11",
7878
"concurrently": "9.2.1",
7979
"cross-env": "10.1.0",
8080
"prettier": "3.8.3",
8181
"prettier-plugin-classnames": "0.10.1",
8282
"prettier-plugin-merge": "0.10.1",
83-
"prettier-plugin-tailwindcss": "0.7.3",
83+
"prettier-plugin-tailwindcss": "0.8.0",
8484
"publint": "0.3.18",
8585
"react": "catalog:react:peer",
8686
"react-dom": "catalog:react:peer",

packages/ui-react/src/components/common/presence/use-presence.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ const usePresence = (options: UsePresenceOptions): UsePresenceResult => {
190190

191191
if (!prevNodeStateRef.current.prevPresent) {
192192
const currentFillMode = node.style.animationFillMode;
193+
// eslint-disable-next-line react/immutability -- Ignore
193194
node.style.animationFillMode = "forwards";
194195

195196
// Reset the style after the node had time to unmount (for cases
@@ -198,6 +199,7 @@ const usePresence = (options: UsePresenceOptions): UsePresenceResult => {
198199
// still causes a flash.
199200
timeoutId = ownerWindow.setTimeout(() => {
200201
if (node.style.animationFillMode === "forwards") {
202+
// eslint-disable-next-line react/immutability -- Ignore
201203
node.style.animationFillMode = currentFillMode;
202204
}
203205
}) as never;

packages/ui-react/src/components/common/slot/slot.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,10 @@ function SlotClone(props: SlotCloneProps) {
8686

8787
const childRef = resolvedChild.props.ref as React.Ref<HTMLElement>;
8888

89-
const ref = composeRefs(forwardedRef, childRef);
90-
9189
const clonedProps = {
9290
...mergeProps(restOfSlotProps, resolvedChild.props),
93-
...(resolvedChild.type !== ReactFragment && { ref }),
91+
// eslint-disable-next-line react/refs -- Ignore
92+
...(resolvedChild.type !== ReactFragment && { ref: composeRefs(forwardedRef, childRef) }),
9493
};
9594

9695
return cloneElement(resolvedChild, clonedProps);

packages/ui-react/src/components/ui/carousel/carousel-store-context.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ const useCarousel = <TImages extends ImagesType>(props: Omit<CarouselRootProps<T
7171
[images, savedOnSlideBtnClick]
7272
);
7373

74-
// eslint-disable-next-line react/component-hook-factories -- Ignore
7574
const useCarouselStore: typeof useCarouselStoreContext = (selector) => {
7675
// eslint-disable-next-line react-hooks/hooks -- Ignore
7776
return useStore(carouselStore, selector);

packages/ui-react/src/components/ui/carousel/carousel.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,33 @@ export function CarouselItem(props: CarouselItemProps) {
196196
}
197197

198198
export function CarouselCaption<TElement extends React.ElementType = "div">(
199-
props: PolymorphicPropsStrict<TElement, OtherCarouselProps>
199+
props: PolymorphicPropsStrict<
200+
TElement,
201+
OtherCarouselProps & {
202+
placement?:
203+
| "center"
204+
| Exclude<`${"bottom" | "center" | "top"}-${"center" | "left" | "right"}`, "center-center">;
205+
}
206+
>
200207
) {
201-
const { as: Element = "div", children, className } = props;
208+
const { as: Element = "div", children, className, placement = "bottom-left" } = props;
202209

203210
return (
204211
<Element
205212
data-slot="carousel-caption"
206213
data-scope="carousel"
207214
data-part="caption"
208-
className={cnMerge("absolute z-10", className)}
215+
className={cnMerge(
216+
"absolute z-10",
217+
placement === "bottom-center" && "bottom-0 left-1/2 -translate-x-1/2",
218+
placement === "bottom-left" && "bottom-0 left-0",
219+
placement === "bottom-right" && "right-0 bottom-0",
220+
placement === "center" && "top-1/2 left-1/2 -translate-1/2",
221+
placement === "top-center" && "top-0 left-1/2 -translate-x-1/2",
222+
placement === "top-left" && "top-0 left-0",
223+
placement === "top-right" && "top-0 right-0",
224+
className
225+
)}
209226
>
210227
{children}
211228
</Element>

0 commit comments

Comments
 (0)