diff --git a/.changeset/fix-mcp-codex-compatibility.md b/.changeset/fix-mcp-codex-compatibility.md deleted file mode 100644 index 545ecda8a4d..00000000000 --- a/.changeset/fix-mcp-codex-compatibility.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@chakra-ui/react-mcp": patch ---- - -Fix OpenAI Codex compatibility by removing stdout logging, downgrading Zod to -v3.23.8, and upgrading MCP SDK to v1.20.2 diff --git a/.changeset/public-turkeys-appear.md b/.changeset/public-turkeys-appear.md index 04ef50643cf..21b46a6c0a7 100644 --- a/.changeset/public-turkeys-appear.md +++ b/.changeset/public-turkeys-appear.md @@ -2,5 +2,7 @@ "@chakra-ui/react": patch --- -**Combobox:** Refactor recipe for smarter padding management to prevent input -text from overflowing unto triggers +- **Combobox:** Refactor recipe for smarter padding management to prevent input + text from overflowing unto triggers + +- **CodeBlock:** Add missing `use client` directive diff --git a/apps/www/components/component-explorer.tsx b/apps/www/components/component-explorer.tsx index 351721b9ba1..f64f1c15fca 100644 --- a/apps/www/components/component-explorer.tsx +++ b/apps/www/components/component-explorer.tsx @@ -1,4 +1,4 @@ -import { Box, Flex } from "@chakra-ui/react" +import { Box } from "@chakra-ui/react" import { ComponentExplorerWrapper } from "./component-snapshot" import { ExamplePreview } from "./example" diff --git a/apps/www/components/component-snapshot.tsx b/apps/www/components/component-snapshot.tsx index 1a027520cf2..f07c5c73dfb 100644 --- a/apps/www/components/component-snapshot.tsx +++ b/apps/www/components/component-snapshot.tsx @@ -1,7 +1,7 @@ "use client" import { highlightCode } from "@/lib/highlight-code" -import { Box, Flex, Text } from "@chakra-ui/react" +import { Box, Flex, Span } from "@chakra-ui/react" import { useEffect, useState } from "react" import { SiTypescript } from "react-icons/si" import ts from "typescript" @@ -76,39 +76,15 @@ export const ${pascal}SlotRecipe = defineSlotRecipe({ colorScheme="dark" pos="relative" rounded="lg" - border="1px solid" - borderColor="border" + borderWidth="1px" bg="bg" > - - + + - + {kebab}.recipe.ts - + {activePart && ( { interface CodeWrapperProps extends BoxProps {} export const ExampleCodeWrapper = (props: CodeWrapperProps) => { - const { children, maxHeight, bg, px = "8", py = "6", ...rest } = props + const { children, maxHeight, bg, px = "6", py = "6", ...rest } = props return ( { mb="4em" size="sm" unmountOnExit + lazyMount > Preview diff --git a/apps/www/components/mdx/prop-table.tsx b/apps/www/components/mdx/prop-table.tsx index efdf2d84bdf..d232f922f7c 100644 --- a/apps/www/components/mdx/prop-table.tsx +++ b/apps/www/components/mdx/prop-table.tsx @@ -18,10 +18,24 @@ interface PropTableProps { omit?: string[] } -const stringify = (value: any) => { +const stringify = (property: any) => { + let value = property.defaultValue if (value === "true") return `true` if (value === "false") return `false` - return JSON.stringify(value) + + if (typeof value === "string") { + try { + const parsed = JSON.parse(value) + if (typeof parsed === "string" && property.type?.includes("string")) { + return parsed + } + return JSON.stringify(parsed).replaceAll('"', "'") + } catch { + return value + } + } + + return JSON.stringify(value).replaceAll('"', "'") } export const PropTable = async (props: PropTableProps) => { @@ -74,7 +88,7 @@ export const PropTable = async (props: PropTableProps) => { {property.defaultValue ? ( - {stringify(property.defaultValue).replaceAll('"', "'")} + {stringify(property)} ) : ( diff --git a/apps/www/content/docs/components/carousel.mdx b/apps/www/content/docs/components/carousel.mdx index 10d7396f540..ab4bcf3c862 100644 --- a/apps/www/content/docs/components/carousel.mdx +++ b/apps/www/content/docs/components/carousel.mdx @@ -1,6 +1,7 @@ --- title: Carousel -description: Used to display multiple items or images in a sliding view. +description: + Used to cycle through a series of visual content within a container. links: source: components/carousel storybook: components-carousel--basic @@ -21,15 +22,15 @@ import { Carousel } from "@chakra-ui/react" - + + + + + - - - - ``` @@ -37,12 +38,10 @@ import { Carousel } from "@chakra-ui/react" The `Carousel` component also provides convenient shortcuts for common patterns. -### CarouselIndicators +### Carousel.Indicators -The `CarouselIndicators` shortcut renders a full set of indicators automatically -based on the number of slides. - -This works: +The `Carousel.Indicators` shortcut renders a full set of indicators +automatically based on the number of slides. ```jsx @@ -58,30 +57,12 @@ This might be more concise if you don't need to customize each indicator: ``` -### CarouselAutoplayIndicator - -Renders a play or pause element based on the carousel’s autoplay state. Use it -to toggle visuals when autoplay starts or stops. - -```jsx -} pause={} /> -``` - -### CarouselProgressText - -Displays the current slide and total slide count (e.g. 2 / 5). Updates -automatically as the carousel moves. - -```jsx - -``` - ## Examples ### Controlled -Use the `page` and `onPageChange` props to manage the carousel's behavior -externally. +Use the `page` and `onPageChange` props to programatically control the active +carousel page. @@ -94,62 +75,68 @@ to the `Carousel.RootProvider` component for full programmatic control. ### Arrows -Enable intuitive navigation through your slides with previous and next arrows. +Use the `Carousel.PrevTrigger` and `Carousel.NextTrigger` components to create +arrows that navigate between slides. ### Indicators -Add visual indicators to help users track their position within the carousel and -jump to specific slides. +Use the `Carousel.Indicators` component to render visual indicators that help +users track the progress of the carousel and jump to specific slides. +### Thumbnail Indicators + +Here's an example that uses an image thumbnail as a custom indicator. + + + ### Spacing -Use the `spacing` prop to control the gap between slides. +Use the `spacing` prop to control the spacing between slides. ### Vertical -Transform your carousel into a vertical slider by setting the `orientation` -prop. +Use the `orientation` prop to `vertical` to transform your carousel into a +vertical slider. ### Mouse Drag -Toggle whether the carousel can be scrolled using mouse dragging via the -`allowMouseDrag` prop. +Use the `allowMouseDrag` prop to enable mouse dragging on the carousel. -### Lightbox - -Use carousel in a `Dialog` to create a first-run experience or modal gallery or -a lightbox. - - - -### Thumbnail +### Autoplay -Add custom indicators using thumbnails for navigation. +Pass the `autoplay` prop to the `Carousel.Root` component to make the carousel +automatically move between slides. - + -### Autoplay +### Lightbox -Automatically move between slides using the `autoplay` prop. Customize the -autoplay interval using the `autoplay={{ delay }}` prop. +Compose the `Carousel` component with the `Dialog` component to create a +lightbox. - + ### Image Carousel +Here's an example that shows how to create an image carousel for a product +showcase. + -### Composition +### Property Card + +Here's an example that shows how to compose the `Carousel` component with other +components to create a property card carousel. diff --git a/apps/www/content/docs/components/center.mdx b/apps/www/content/docs/components/center.mdx index 6013e8e1fc4..bfc4c37e22d 100644 --- a/apps/www/content/docs/components/center.mdx +++ b/apps/www/content/docs/components/center.mdx @@ -30,19 +30,27 @@ Center can be used to create frames around icons or numbers. ### Center with Inline -Use the `inline` to change the display to `inline-flex`. +Use the `inline` prop to make `Center` behave like an inline element +(`display: inline-flex`) instead of a block-level element (`display: flex`). +This makes `Center` only take up as much width as its content needs, allowing it +to fit inside links, buttons, or other inline contexts without breaking the +layout. ### Square -`Square` centers its child given the `size` (width and height). +`Square` centers its child within a fixed-size container of equal width and +height. It accepts a `size` prop that sets both width and height to the same +value. ### Circle -`Circle` centers its child given the `size` and creates a circle around it. +`Circle` extends `Square` by adding `borderRadius="9999px"` to create a perfect +circle. Like `Square`, it accepts a `size` prop that sets both width and height +to the same value. @@ -50,12 +58,15 @@ Use the `inline` to change the display to `inline-flex`. ### Center - + ### Square - + ### Circle - +`Circle` extends `Square` and accepts all the same props. The only difference is +that `Circle` applies `borderRadius="9999px"`. + + diff --git a/apps/www/lib/highlight-code.ts b/apps/www/lib/highlight-code.ts index 35d7203d5eb..0937351ac27 100644 --- a/apps/www/lib/highlight-code.ts +++ b/apps/www/lib/highlight-code.ts @@ -1,12 +1,12 @@ -import { codeToHtml } from "shiki" +import { getHighlighter } from "./highlighter" -export const highlightCode = ( +export const highlightCode = async ( code: string, - opts?: Partial[1]>, + opts?: { lang?: string; theme?: string }, ) => { - return codeToHtml(code, { - lang: "tsx", - theme: "dark-plus", - ...opts, + const highlighter = await getHighlighter() + return highlighter.codeToHtml(code, { + lang: opts?.lang || "tsx", + theme: opts?.theme || "dark-plus", }) } diff --git a/apps/www/lib/highlighter.ts b/apps/www/lib/highlighter.ts new file mode 100644 index 00000000000..76ee648fb46 --- /dev/null +++ b/apps/www/lib/highlighter.ts @@ -0,0 +1,28 @@ +import { type Highlighter, createHighlighter } from "shiki" + +const cache = new Map>() + +function cachePromise( + key: string, + setPromise: () => Promise, +): Promise { + const cached = cache.get(key) + if (cached) return cached as Promise + + const promise = setPromise() + cache.set(key, promise) + return promise +} + +export async function getHighlighter(): Promise { + return cachePromise("highlighter", () => + createHighlighter({ + themes: ["dark-plus"], + langs: ["tsx", "typescript", "javascript", "json", "bash", "shell"], + }), + ) +} + +export function disposeHighlighter() { + cache.clear() +} diff --git a/apps/www/public/r/types/carousel.json b/apps/www/public/r/types/carousel.json new file mode 100644 index 00000000000..9d0c924ffc7 --- /dev/null +++ b/apps/www/public/r/types/carousel.json @@ -0,0 +1,333 @@ +{ + "AutoplayTrigger": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLButtonElement" + }, + "Control": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLDivElement" + }, + "Indicator": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + }, + "index": { + "type": "number", + "isRequired": true, + "description": "The index of the indicator." + }, + "readOnly": { + "type": "boolean", + "isRequired": false, + "defaultValue": "false", + "description": "Whether the indicator is read only." + } + }, + "element": "HTMLButtonElement" + }, + "IndicatorGroup": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLDivElement" + }, + "Item": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + }, + "index": { + "type": "number", + "isRequired": true, + "description": "The index of the item." + }, + "snapAlign": { + "type": "'center' | 'end' | 'start'", + "isRequired": false, + "defaultValue": "\"start\"", + "description": "The snap alignment of the item." + } + }, + "element": "HTMLDivElement" + }, + "ItemGroup": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLDivElement" + }, + "NextTrigger": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLButtonElement" + }, + "PrevTrigger": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + }, + "element": "HTMLButtonElement" + }, + "Root": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + }, + "unstyled": { + "type": "boolean", + "isRequired": false, + "description": "Whether to remove the component's style." + }, + "slideCount": { + "type": "number", + "isRequired": true, + "description": "The total number of slides.\nUseful for SSR to render the initial ating the snap points." + }, + "allowMouseDrag": { + "type": "boolean", + "isRequired": false, + "defaultValue": "false", + "description": "Whether to allow scrolling via dragging with mouse" + }, + "autoplay": { + "type": "boolean | { delay: number }", + "isRequired": false, + "defaultValue": "false", + "description": "Whether to scroll automatically. The default delay is 4000ms." + }, + "defaultPage": { + "type": "number", + "isRequired": false, + "defaultValue": "0", + "description": "The initial page to scroll to when rendered.\nUse when you don't need to control the page of the carousel." + }, + "ids": { + "type": "Partial<{\n root: string\n item: (index: number) => string\n itemGroup: string\n nextTrigger: string\n prevTrigger: string\n indicatorGroup: string\n indicator: (index: number) => string\n}>", + "isRequired": false, + "description": "The ids of the elements in the carousel. Useful for composition." + }, + "inViewThreshold": { + "type": "number | number[]", + "isRequired": false, + "defaultValue": "0.6", + "description": "The threshold for determining if an item is in view." + }, + "loop": { + "type": "boolean", + "isRequired": false, + "defaultValue": "false", + "description": "Whether the carousel should loop around." + }, + "onAutoplayStatusChange": { + "type": "(details: AutoplayStatusDetails) => void", + "isRequired": false, + "description": "Function called when the autoplay status changes." + }, + "onDragStatusChange": { + "type": "(details: DragStatusDetails) => void", + "isRequired": false, + "description": "Function called when the drag status changes." + }, + "onPageChange": { + "type": "(details: PageChangeDetails) => void", + "isRequired": false, + "description": "Function called when the page changes." + }, + "orientation": { + "type": "'horizontal' | 'vertical'", + "isRequired": false, + "defaultValue": "\"horizontal\"", + "description": "The orientation of the element." + }, + "padding": { + "type": "string", + "isRequired": false, + "description": "Defines the extra space added around the scrollable area,\nenabling nearby items to remain partially in view." + }, + "page": { + "type": "number", + "isRequired": false, + "description": "The controlled page of the carousel." + }, + "slidesPerMove": { + "type": "number | 'auto'", + "isRequired": false, + "defaultValue": "\"auto\"", + "description": "The number of slides to scroll at a time.\n\nWhen set to `auto`, the number of slides to scroll is determined by the\n`slidesPerPage` property." + }, + "slidesPerPage": { + "type": "number", + "isRequired": false, + "defaultValue": "1", + "description": "The number of slides to show at a time." + }, + "snapType": { + "type": "'proximity' | 'mandatory'", + "isRequired": false, + "defaultValue": "\"mandatory\"", + "description": "The snap type of the item." + }, + "spacing": { + "type": "string", + "isRequired": false, + "defaultValue": "\"0px\"", + "description": "The amount of space between items." + }, + "translations": { + "type": "IntlTranslations", + "isRequired": false, + "description": "The localized messages to use." + } + }, + "element": "HTMLDivElement" + }, + "RootProvider": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + }, + "value": { + "type": "UseCarouselReturn", + "isRequired": true + } + }, + "element": "HTMLDivElement" + }, + "Indicators": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + } + }, + "AutoplayIndicator": { + "props": { + "play": { + "type": "React.ReactNode", + "isRequired": false + }, + "paused": { + "type": "React.ReactNode", + "isRequired": false + }, + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + } + }, + "ProgressText": { + "props": { + "as": { + "type": "React.ElementType", + "isRequired": false, + "description": "The underlying element to render." + }, + "asChild": { + "type": "boolean", + "isRequired": false, + "description": "Use the provided child element as the default rendered element, combining their props and behavior." + } + } + } +} \ No newline at end of file diff --git a/apps/www/public/r/types/index.json b/apps/www/public/r/types/index.json index ef06e5ff4fb..5e469a6e952 100644 --- a/apps/www/public/r/types/index.json +++ b/apps/www/public/r/types/index.json @@ -13,6 +13,7 @@ "breadcrumb", "button", "card", + "carousel", "center", "checkbox", "checkbox-card", diff --git a/packages/react/src/components/code-block/code-block-adapter-context.ts b/packages/react/src/components/code-block/code-block-adapter-context.ts index 4239b018b85..d72b694b04f 100644 --- a/packages/react/src/components/code-block/code-block-adapter-context.ts +++ b/packages/react/src/components/code-block/code-block-adapter-context.ts @@ -1,3 +1,5 @@ +"use client" + import { createContext } from "../../create-context" import { plainTextAdapter } from "./adapters" import type { UseCodeHighlightReturn } from "./use-code-highlight" diff --git a/packages/react/src/components/code-block/code-block-adapter-provider.tsx b/packages/react/src/components/code-block/code-block-adapter-provider.tsx index 38c5a3ee597..e124522906e 100644 --- a/packages/react/src/components/code-block/code-block-adapter-provider.tsx +++ b/packages/react/src/components/code-block/code-block-adapter-provider.tsx @@ -1,3 +1,5 @@ +"use client" + import { CodeBlockAdapterContextProvider } from "./code-block-adapter-context" import { type UseCodeHighlightProps, diff --git a/packages/react/src/components/code-block/use-code-highlight.ts b/packages/react/src/components/code-block/use-code-highlight.ts index 23f72640d4e..330519aa76d 100644 --- a/packages/react/src/components/code-block/use-code-highlight.ts +++ b/packages/react/src/components/code-block/use-code-highlight.ts @@ -1,3 +1,5 @@ +"use client" + import { useEffect, useMemo, useRef, useState } from "react" import type { CodeBlockAdapter, CodeBlockHighlighter } from "./types" diff --git a/packages/react/src/components/loader/loader-overlay.tsx b/packages/react/src/components/loader/loader-overlay.tsx index 740b0bb65b9..8d338b82d68 100644 --- a/packages/react/src/components/loader/loader-overlay.tsx +++ b/packages/react/src/components/loader/loader-overlay.tsx @@ -1,3 +1,5 @@ +"use client" + import { type HTMLChakraProps, chakra } from "../../styled-system" export interface LoaderOverlayProps extends HTMLChakraProps<"div"> {} diff --git a/packages/react/src/components/presence/index.tsx b/packages/react/src/components/presence/index.tsx index 5e4219169b7..42382e99ab0 100644 --- a/packages/react/src/components/presence/index.tsx +++ b/packages/react/src/components/presence/index.tsx @@ -1,3 +1,5 @@ +"use client" + import type { Assign } from "@ark-ui/react" import { Presence as ArkPresence,