diff --git a/ROADMAP.md b/ROADMAP.md index 0ba9b0a..d586e78 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -127,15 +127,15 @@ twice. Reference sources: `https://ui.shadcn.com/r/styles/base-nova/.json` ### 4b. Site foundation (nova) - [x] Re-vendor the docs site's `components/ui/` from the `base-nova` preset; - nova theme adopted. Remaining straggler: `ui/form.tsx` still imports - `@radix-ui/react-label`/`react-slot` — replace with Base UI - `Field`/`Form` when demo form plumbing is reworked (see 4c). -- [ ] Remove Radix dependencies from `apps/v4` — **all of them** (re-decided + nova theme adopted. The `ui/form.tsx` straggler (Radix label/slot) was + replaced with base-nova `field.tsx` in PR #63 (2026-07-16). +- [x] Remove Radix dependencies from `apps/v4` — **all of them** (re-decided 2026-07-15 with the clean-cut policy: the earlier "no maintained component imports Radix" carve-out for frozen superseded components no - longer applies since those are removed rather than frozen). Zero - `@radix-ui/*` packages remain after the 4c ports, the superseded- - component removal, and the `ui/form.tsx` replacement. + longer applies since those are removed rather than frozen). Shipped + 2026-07-16 (PR #63): zero `@radix-ui/*` packages remain after the 4c + ports, the superseded-component removal, and the `ui/form.tsx` → + base-nova `field.tsx` replacement. - [x] Fix site-header vertical separators — shipped 2026-07-15 (PR #61, `fix/header-separator`). @@ -176,9 +176,10 @@ demos. (PR #62): combobox, date-picker, date/time fields, native-select, password-input and all examples migrated; phone-input 4px height mismatch fixed; every page browser-verified. -- [ ] Port each kept component: swap Radix building blocks for Base UI - equivalents and apply classes from the `base-nova` sources. Concrete - Radix → Base UI swaps (surveyed 2026-07-15): +- [x] Port each kept component: swap Radix building blocks for Base UI + equivalents and apply classes from the `base-nova` sources — shipped + 2026-07-16 (PR #63). Concrete Radix → Base UI swaps (surveyed + 2026-07-15): - Full primitives: `date-picker-primitive` popover → Base UI Popover; `badge-group` + `emoji-picker` toggle-group → Base UI Toggle Group; `sortable` portal → React DOM `createPortal`. @@ -195,14 +196,19 @@ demos. registry.json 34 → 26 items; entangled keeper examples rewritten against vendored shadcn `kbd`/`button-group`/`attachment`/`combobox` (Base UI) in `apps/v4/src/components/ui/`. -- [ ] Rewrite demos/examples against the nova metrics (adopt Base UI +- [x] Rewrite demos/examples against the nova metrics (adopt Base UI `Field`/`Form` for form plumbing, replacing `ui/form.tsx`); verify - every page. + every page — shipped 2026-07-16 (PR #63); form demos stay controlled + from first render (`field.value ?? null`). - [ ] Styling polish during the ports: date/time field segments render taller than desired (noted 2026-07-16) — revisit segment height when applying nova classes to the field components. -- [ ] Update registry.json (single style) and install docs after the - removals + ports. +- [x] Update registry.json (single style) and install docs after the + removals + ports — done 2026-07-16: internal `registryDependencies` + switched from dead self-hosted `https://ui-x.junwen-k.dev/r/*.json` + URLs to GitHub-registry addresses (`junwen-k/ui-x/`), registry + validated (`shadcn registry validate`, 26 items); `installation.mdx` + already documents the `junwen-k/ui-x/` install form. ### 4d. Docs content — API Reference & Accessibility sections (after ports) diff --git a/apps/v4/registry.json b/apps/v4/registry.json index 839af18..875675f 100644 --- a/apps/v4/registry.json +++ b/apps/v4/registry.json @@ -8,9 +8,7 @@ "type": "registry:component", "title": "BProgress Provider Next App", "description": "A smooth progress bar for page transitions in Next.js apps, using the App Router.", - "dependencies": [ - "@bprogress/next" - ], + "dependencies": ["@bprogress/next"], "files": [ { "path": "src/registry/new-york/components/bprogress-provider-next-app.tsx", @@ -24,9 +22,7 @@ "type": "registry:component", "title": "BProgress Provider Next Pages", "description": "A smooth progress bar for page transitions in Next.js pages, using the Pages Router.", - "dependencies": [ - "@bprogress/next" - ], + "dependencies": ["@bprogress/next"], "files": [ { "path": "src/registry/new-york/components/bprogress-provider-next-pages.tsx", @@ -40,13 +36,8 @@ "type": "registry:ui", "title": "Date Time Field Primitive", "description": "Date Time Field Primitive allows user to enter date and time value.", - "dependencies": [ - "@base-ui/react", - "timescape" - ], - "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/use-timescape.json" - ], + "dependencies": ["@base-ui/react", "timescape"], + "registryDependencies": ["junwen-k/ui-x/use-timescape"], "files": [ { "path": "src/registry/new-york/ui/date-time-field-primitive.tsx", @@ -59,14 +50,8 @@ "type": "registry:ui", "title": "Emoji Picker", "description": "A emoji picker is a component that allows users to select an emoji from a list of emojis.", - "dependencies": [ - "@base-ui/react", - "frimousse" - ], - "registryDependencies": [ - "button", - "popover" - ], + "dependencies": ["@base-ui/react", "frimousse"], + "registryDependencies": ["button", "popover"], "files": [ { "path": "src/registry/new-york/ui/emoji-picker.tsx", @@ -79,11 +64,7 @@ "type": "registry:hook", "title": "Use Timescape", "description": "A reactive wrapper around Timescape that provides controlled and uncontrolled state management for date/time input.", - "dependencies": [ - "@base-ui/utils", - "react-day-picker", - "timescape" - ], + "dependencies": ["@base-ui/utils", "react-day-picker", "timescape"], "files": [ { "path": "src/registry/new-york/hooks/use-timescape.ts", @@ -96,13 +77,8 @@ "type": "registry:ui", "title": "Date Time Range Field Primitive", "description": "Date Time Range Field Primitive allows user to enter date and time value for a range of dates.", - "dependencies": [ - "@base-ui/react", - "timescape" - ], - "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/use-timescape.json" - ], + "dependencies": ["@base-ui/react", "timescape"], + "registryDependencies": ["junwen-k/ui-x/use-timescape"], "files": [ { "path": "src/registry/new-york/ui/date-time-range-field-primitive.tsx", @@ -122,8 +98,8 @@ "react-day-picker" ], "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/date-time-field-primitive.json", - "https://ui-x.junwen-k.dev/r/date-time-range-field-primitive.json" + "junwen-k/ui-x/date-time-field-primitive", + "junwen-k/ui-x/date-time-range-field-primitive" ], "files": [ { @@ -137,10 +113,7 @@ "type": "registry:ui", "title": "Dropzone Primitive", "description": "A dropzone is an area into which one or multiple objects can be dragged and dropped.", - "dependencies": [ - "@base-ui/react", - "react-dropzone" - ], + "dependencies": ["@base-ui/react", "react-dropzone"], "files": [ { "path": "src/registry/new-york/ui/dropzone-primitive.tsx", @@ -153,10 +126,7 @@ "type": "registry:ui", "title": "Password Input Primitive", "description": "Password Input provides a way for the user to securely enter a password, with the ability to toggle the visibility of the password.", - "dependencies": [ - "@base-ui/react", - "@base-ui/utils" - ], + "dependencies": ["@base-ui/react", "@base-ui/utils"], "files": [ { "path": "src/registry/new-york/ui/password-input-primitive.tsx", @@ -204,10 +174,7 @@ "type": "registry:ui", "title": "Virtualized", "description": "A virtualized component that allows you to efficiently render large lists and tabular data.", - "dependencies": [ - "@base-ui/react", - "virtua" - ], + "dependencies": ["@base-ui/react", "virtua"], "files": [ { "path": "src/registry/new-york/ui/virtualized.tsx", @@ -220,13 +187,8 @@ "type": "registry:ui", "title": "Badge Group", "description": "A badge group is a focusable list of labels, categories, keywords, filters, or other items, with support for keyboard navigation, selection, and removal.", - "dependencies": [ - "@base-ui/react", - "@base-ui/utils" - ], - "registryDependencies": [ - "badge" - ], + "dependencies": ["@base-ui/react", "@base-ui/utils"], + "registryDependencies": ["badge"], "files": [ { "path": "src/registry/new-york/ui/badge-group.tsx", @@ -239,13 +201,8 @@ "type": "registry:ui", "title": "Confirmer", "description": "Imperative confirm dialog implementation.", - "dependencies": [ - "react-call" - ], - "registryDependencies": [ - "alert-dialog", - "button" - ], + "dependencies": ["react-call"], + "registryDependencies": ["alert-dialog", "button"], "files": [ { "path": "src/registry/new-york/ui/confirmer.tsx", @@ -258,9 +215,7 @@ "type": "registry:ui", "title": "Date Field", "description": "Date Field allows user to enter date value.", - "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/date-time-field.json" - ], + "registryDependencies": ["junwen-k/ui-x/date-time-field"], "files": [ { "path": "src/registry/new-york/ui/date-field.tsx", @@ -275,7 +230,7 @@ "description": "Date Time Field allows user to enter date and time value.", "registryDependencies": [ "input-group", - "https://ui-x.junwen-k.dev/r/date-time-field-primitive.json" + "junwen-k/ui-x/date-time-field-primitive" ], "files": [ { @@ -291,8 +246,8 @@ "description": "Date Time Range Field allows user to enter date and time value for a range of dates.", "registryDependencies": [ "input-group", - "https://ui-x.junwen-k.dev/r/date-time-field.json", - "https://ui-x.junwen-k.dev/r/date-time-range-field-primitive.json" + "junwen-k/ui-x/date-time-field", + "junwen-k/ui-x/date-time-range-field-primitive" ], "files": [ { @@ -310,8 +265,8 @@ "button", "input-group", "calendar", - "https://ui-x.junwen-k.dev/r/date-field.json", - "https://ui-x.junwen-k.dev/r/date-picker-primitive.json" + "junwen-k/ui-x/date-field", + "junwen-k/ui-x/date-picker-primitive" ], "files": [ { @@ -337,12 +292,8 @@ "type": "registry:ui", "title": "Dropzone", "description": "A dropzone is an area into which one or multiple objects can be dragged and dropped.", - "dependencies": [ - "@base-ui/react" - ], - "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/dropzone-primitive.json" - ], + "dependencies": ["@base-ui/react"], + "registryDependencies": ["junwen-k/ui-x/dropzone-primitive"], "files": [ { "path": "src/registry/new-york/ui/dropzone.tsx", @@ -357,7 +308,7 @@ "description": "Password Input provides a way for the user to securely enter a password, with the ability to toggle the visibility of the password.", "registryDependencies": [ "input-group", - "https://ui-x.junwen-k.dev/r/password-input-primitive.json" + "junwen-k/ui-x/password-input-primitive" ], "files": [ { @@ -372,7 +323,7 @@ "title": "Phone Input", "description": "Phone Input allows user to enter phone number in E.164 format.", "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/phone-input-primitive.json", + "junwen-k/ui-x/phone-input-primitive", "input", "select" ], @@ -388,9 +339,7 @@ "type": "registry:ui", "title": "Time Field", "description": "Time Field allows user to enter time value.", - "registryDependencies": [ - "https://ui-x.junwen-k.dev/r/date-time-field.json" - ], + "registryDependencies": ["junwen-k/ui-x/date-time-field"], "files": [ { "path": "src/registry/new-york/ui/time-field.tsx", @@ -403,9 +352,7 @@ "type": "registry:ui", "title": "Time", "description": "Displays a specific time (or datetime).", - "dependencies": [ - "date-fns" - ], + "dependencies": ["date-fns"], "files": [ { "path": "src/registry/new-york/ui/time.tsx", @@ -418,9 +365,7 @@ "type": "registry:ui", "title": "Timeline", "description": "Timeline displays a list of events in chronological order.", - "dependencies": [ - "@base-ui/react" - ], + "dependencies": ["@base-ui/react"], "files": [ { "path": "src/registry/new-york/ui/timeline.tsx", @@ -433,9 +378,7 @@ "type": "registry:ui", "title": "Wheel Picker", "description": "iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.", - "dependencies": [ - "@ncdai/react-wheel-picker" - ], + "dependencies": ["@ncdai/react-wheel-picker"], "files": [ { "path": "src/registry/new-york/ui/wheel-picker.tsx", diff --git a/apps/v4/src/components/examples/password-input-checkbox.tsx b/apps/v4/src/components/examples/password-input-checkbox.tsx index 58d466e..56a5b8e 100644 --- a/apps/v4/src/components/examples/password-input-checkbox.tsx +++ b/apps/v4/src/components/examples/password-input-checkbox.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { Checkbox } from "@/components/ui/checkbox"; +import { Label } from "@/components/ui/label"; import { PasswordInput, PasswordInputInput, @@ -22,12 +23,7 @@ export default function PasswordInputCheckbox() { checked={visible} onCheckedChange={(checked) => setVisible(Boolean(checked))} /> - + ); diff --git a/apps/v4/src/components/examples/phone-input-combobox.tsx b/apps/v4/src/components/examples/phone-input-combobox.tsx index b775729..6bfe676 100644 --- a/apps/v4/src/components/examples/phone-input-combobox.tsx +++ b/apps/v4/src/components/examples/phone-input-combobox.tsx @@ -2,6 +2,7 @@ import * as React from "react"; import { getCountryCallingCode } from "react-phone-number-input"; +import en from "react-phone-number-input/locale/en"; import { Button } from "@/components/ui/button"; import { ButtonGroup } from "@/components/ui/button-group"; @@ -23,10 +24,6 @@ import { } from "@/registry/new-york/ui/phone-input"; import * as PhoneInputPrimitive from "@/registry/new-york/ui/phone-input-primitive"; -const regionNames = new Intl.DisplayNames(["en"], { - type: "region", -}); - const countries = PhoneInputPrimitive.getCountryOptions().map( (option) => option.countryCode, ); @@ -41,14 +38,17 @@ export default function PhoneInputCombobox() { items={countries} value={country} onValueChange={(value) => setCountry(value as Country)} - itemToStringLabel={(value) => regionNames.of(value as Country) ?? ""} + itemToStringLabel={(value) => en[value as Country] ?? ""} > } aria-label="Select country" > - + } /> @@ -61,9 +61,7 @@ export default function PhoneInputCombobox() { {(countryCode: Country) => ( - - {regionNames.of(countryCode)} - + {en[countryCode]} {`+${getCountryCallingCode(countryCode)}`} diff --git a/apps/v4/src/components/examples/phone-input-primitive-demo.tsx b/apps/v4/src/components/examples/phone-input-primitive-demo.tsx index 1205663..c0f17c9 100644 --- a/apps/v4/src/components/examples/phone-input-primitive-demo.tsx +++ b/apps/v4/src/components/examples/phone-input-primitive-demo.tsx @@ -1,10 +1,8 @@ "use client"; -import * as PhoneInputPrimitive from "@/registry/new-york/ui/phone-input-primitive"; +import en from "react-phone-number-input/locale/en"; -const regionNames = new Intl.DisplayNames(["en"], { - type: "region", -}); +import * as PhoneInputPrimitive from "@/registry/new-york/ui/phone-input-primitive"; export default function PhoneInputPrimitiveDemo() { return ( @@ -18,7 +16,7 @@ export default function PhoneInputPrimitiveDemo() { key={option.countryCode} value={option.countryCode} > - {`${regionNames.of(option.countryCode)} +${option.countryCallingCode}`} + {`${en[option.countryCode]} +${option.countryCallingCode}`} ))} diff --git a/apps/v4/src/components/examples/phone-input-primitive-disabled.tsx b/apps/v4/src/components/examples/phone-input-primitive-disabled.tsx index 3d5ec09..5d6ad86 100644 --- a/apps/v4/src/components/examples/phone-input-primitive-disabled.tsx +++ b/apps/v4/src/components/examples/phone-input-primitive-disabled.tsx @@ -1,10 +1,8 @@ "use client"; -import * as PhoneInputPrimitive from "@/registry/new-york/ui/phone-input-primitive"; +import en from "react-phone-number-input/locale/en"; -const regionNames = new Intl.DisplayNames(["en"], { - type: "region", -}); +import * as PhoneInputPrimitive from "@/registry/new-york/ui/phone-input-primitive"; export default function PhoneInputPrimitiveDisabled() { return ( @@ -18,7 +16,7 @@ export default function PhoneInputPrimitiveDisabled() { key={option.countryCode} value={option.countryCode} > - {`${regionNames.of(option.countryCode)} +${option.countryCallingCode}`} + {`${en[option.countryCode]} +${option.countryCallingCode}`} ))} diff --git a/apps/v4/src/components/examples/phone-input-primitive-preferred-country.tsx b/apps/v4/src/components/examples/phone-input-primitive-preferred-country.tsx index 9db266f..db9e624 100644 --- a/apps/v4/src/components/examples/phone-input-primitive-preferred-country.tsx +++ b/apps/v4/src/components/examples/phone-input-primitive-preferred-country.tsx @@ -22,9 +22,7 @@ export default function PhoneInputPrimitivePreferredCountry() { preferredCountry="MY" defaultInternationalForPreferredCountry > - , [])} - /> + } />

Preferred country has been set to{" "} diff --git a/apps/v4/src/components/ui/attachment.tsx b/apps/v4/src/components/ui/attachment.tsx index 56bea8f..c476b41 100644 --- a/apps/v4/src/components/ui/attachment.tsx +++ b/apps/v4/src/components/ui/attachment.tsx @@ -103,7 +103,7 @@ function AttachmentTitle({ ) {

) { +}: React.ComponentProps & { + buttonVariant?: React.ComponentProps["variant"]; +}) { + const defaultClassNames = getDefaultClassNames(); + return ( svg]:rotate-180`, + String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, + className, + )} + captionLayout={captionLayout} + locale={locale} + formatters={{ + formatMonthDropdown: (date) => + date.toLocaleString(locale?.code, { month: "short" }), + ...formatters, + }} classNames={{ - months: "flex flex-col gap-2 sm:flex-row", - month: "flex flex-col gap-4", - caption: "relative flex w-full items-center justify-center pt-1", - caption_label: "text-sm font-medium", - nav: "flex items-center gap-1", - nav_button: cn( - buttonVariants({ variant: "outline" }), - "size-7 bg-transparent p-0 opacity-50 hover:opacity-100", - ), - nav_button_previous: "absolute left-1", - nav_button_next: "absolute right-1", - table: "w-full border-collapse space-x-1", - head_row: "flex", - head_cell: - "text-muted-foreground w-8 rounded-md text-[0.8rem] font-normal", - row: "mt-2 flex w-full", - cell: cn( - "[&:has([aria-selected])]:bg-accent relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected].day-range-end)]:rounded-r-md", - props.mode === "range" - ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" - : "[&:has([aria-selected])]:rounded-md", + root: cn("w-fit", defaultClassNames.root), + months: cn( + "relative flex flex-col gap-4 md:flex-row", + defaultClassNames.months, + ), + month: cn("flex w-full flex-col gap-4", defaultClassNames.month), + nav: cn( + "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", + defaultClassNames.nav, + ), + button_previous: cn( + buttonVariants({ variant: buttonVariant }), + "size-(--cell-size) p-0 select-none aria-disabled:opacity-50", + defaultClassNames.button_previous, + ), + button_next: cn( + buttonVariants({ variant: buttonVariant }), + "size-(--cell-size) p-0 select-none aria-disabled:opacity-50", + defaultClassNames.button_next, + ), + month_caption: cn( + "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)", + defaultClassNames.month_caption, + ), + dropdowns: cn( + "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium", + defaultClassNames.dropdowns, + ), + dropdown_root: cn( + "border-input has-focus:border-ring has-focus:ring-ring/50 relative rounded-(--cell-radius) border shadow-xs has-focus:ring-[3px]", + defaultClassNames.dropdown_root, + ), + dropdown: cn( + "bg-popover absolute inset-0 opacity-0", + defaultClassNames.dropdown, + ), + caption_label: cn( + "font-medium select-none", + captionLayout === "label" + ? "text-sm" + : "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-(--cell-radius) pr-1 pl-2 text-sm [&>svg]:size-3.5", + defaultClassNames.caption_label, + ), + month_grid: cn("w-full border-collapse", defaultClassNames.month_grid), + weekdays: cn("flex", defaultClassNames.weekdays), + weekday: cn( + "text-muted-foreground flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal select-none", + defaultClassNames.weekday, + ), + week: cn("mt-2 flex w-full", defaultClassNames.week), + week_number_header: cn( + "w-(--cell-size) select-none", + defaultClassNames.week_number_header, + ), + week_number: cn( + "text-muted-foreground text-[0.8rem] select-none", + defaultClassNames.week_number, ), day: cn( - buttonVariants({ variant: "ghost" }), - "size-8 p-0 font-normal aria-selected:opacity-100", - ), - day_range_start: - "day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground", - day_range_end: - "day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground", - day_selected: - "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", - day_today: "bg-accent text-accent-foreground", - day_outside: - "day-outside text-muted-foreground aria-selected:text-muted-foreground", - day_disabled: "text-muted-foreground opacity-50", - day_range_middle: - "aria-selected:bg-accent aria-selected:text-accent-foreground", - day_hidden: "invisible", + "group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)", + props.showWeekNumber + ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)" + : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)", + defaultClassNames.day, + ), + range_start: cn( + "bg-muted after:bg-muted relative isolate z-0 rounded-l-(--cell-radius) after:absolute after:inset-y-0 after:right-0 after:w-4", + defaultClassNames.range_start, + ), + range_middle: cn("rounded-none", defaultClassNames.range_middle), + range_end: cn( + "bg-muted after:bg-muted relative isolate z-0 rounded-r-(--cell-radius) after:absolute after:inset-y-0 after:left-0 after:w-4", + defaultClassNames.range_end, + ), + today: cn( + "bg-muted text-foreground rounded-(--cell-radius) data-[selected=true]:rounded-none", + defaultClassNames.today, + ), + outside: cn( + "text-muted-foreground aria-selected:text-muted-foreground", + defaultClassNames.outside, + ), + disabled: cn( + "text-muted-foreground opacity-50", + defaultClassNames.disabled, + ), + hidden: cn("invisible", defaultClassNames.hidden), ...classNames, }} components={{ + Root: ({ className, rootRef, ...props }) => { + return ( +
+ ); + }, Chevron: ({ className, orientation, ...props }) => { - switch (orientation) { - case "up": - return ( - - ); - case "down": - return ( - - ); - case "left": - return ( - - ); - case "right": - default: - return ( - - ); + if (orientation === "left") { + return ( + + ); + } + + if (orientation === "right") { + return ( + + ); } + + return ( + + ); + }, + DayButton: ({ ...props }) => ( + + ), + WeekNumber: ({ children, ...props }) => { + return ( + +
+ {children} +
+ + ); }, + ...components, }} {...props} /> ); } -export { Calendar }; +function CalendarDayButton({ + className, + day, + modifiers, + locale, + ...props +}: React.ComponentProps & { locale?: Partial }) { + const defaultClassNames = getDefaultClassNames(); + + const ref = React.useRef(null); + React.useEffect(() => { + if (modifiers.focused) ref.current?.focus(); + }, [modifiers.focused]); + + return ( + + @@ -61,6 +66,8 @@ const CallableConfirm = createCallable( UNMOUNTING_DELAY, ); -export const Confirmer = CallableConfirm.Root; +const Confirmer = CallableConfirm.Root; -export const confirm = CallableConfirm.call; +const confirm = CallableConfirm.call; + +export { Confirmer, confirm }; diff --git a/apps/v4/src/registry/new-york/ui/description-list.tsx b/apps/v4/src/registry/new-york/ui/description-list.tsx index 835c10a..c812241 100644 --- a/apps/v4/src/registry/new-york/ui/description-list.tsx +++ b/apps/v4/src/registry/new-york/ui/description-list.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import * as React from "react"; import { cn } from "@/lib/utils"; diff --git a/apps/v4/src/registry/new-york/ui/phone-input.tsx b/apps/v4/src/registry/new-york/ui/phone-input.tsx index 3d58ba8..4331fae 100644 --- a/apps/v4/src/registry/new-york/ui/phone-input.tsx +++ b/apps/v4/src/registry/new-york/ui/phone-input.tsx @@ -5,6 +5,7 @@ import { CheckIcon, GlobeIcon } from "lucide-react"; import * as React from "react"; import { getCountryCallingCode } from "react-phone-number-input"; import flags from "react-phone-number-input/flags"; +import en from "react-phone-number-input/locale/en"; import { Input } from "@/components/ui/input"; import { @@ -170,10 +171,6 @@ interface PhoneInputCountrySelectItemProps value: PhoneInputPrimitive.Country; } -const regionNames = new Intl.DisplayNames(["en"], { - type: "region", -}); - function PhoneInputCountrySelectItem({ className, value, @@ -193,9 +190,7 @@ function PhoneInputCountrySelectItem({
- - {regionNames.of(value)} - + {en[value]}
{`+${getCountryCallingCode(value)}`} diff --git a/apps/v4/src/registry/new-york/ui/time.tsx b/apps/v4/src/registry/new-york/ui/time.tsx index 3797f90..08a2489 100644 --- a/apps/v4/src/registry/new-york/ui/time.tsx +++ b/apps/v4/src/registry/new-york/ui/time.tsx @@ -4,7 +4,7 @@ import * as React from "react"; import { cn } from "@/lib/utils"; export interface TimeProps - extends Omit, "children"> { + extends Omit, "children"> { children: Parameters[0]; dateTimeFormatStr?: Parameters[1]; formatStr?: Parameters[1];