diff --git a/docs/package.json b/docs/package.json index f2a7e7892d0..50e0632f8b4 100644 --- a/docs/package.json +++ b/docs/package.json @@ -24,6 +24,7 @@ "@next/mdx": "^15.5.6", "@react-spring/web": "^10.0.3", "@stefanprobst/rehype-extract-toc": "^3.0.0", + "@tanstack/react-form": "^1.23.6", "@tanstack/react-virtual": "^3.13.12", "@types/mdx": "^2.0.13", "clipboard-copy": "^4.0.1", diff --git a/docs/src/app/(private)/experiments/forms/_components.tsx b/docs/src/app/(private)/experiments/forms/_components.tsx new file mode 100644 index 00000000000..fe06a5a7d56 --- /dev/null +++ b/docs/src/app/(private)/experiments/forms/_components.tsx @@ -0,0 +1,594 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { Field as BField } from '@base-ui-components/react/field'; +import { Fieldset as BFieldset } from '@base-ui-components/react/fieldset'; +import { Form as BForm } from '@base-ui-components/react/form'; +import { Combobox as BCombobox } from '@base-ui-components/react/combobox'; +import { Autocomplete as BAutocomplete } from '@base-ui-components/react/autocomplete'; +import { Select as BSelect } from '@base-ui-components/react/select'; +import { Slider as BSlider } from '@base-ui-components/react/slider'; +import { NumberField as BNumberField } from '@base-ui-components/react/number-field'; +import { Radio as BRadio } from '@base-ui-components/react/radio'; +import { RadioGroup as BRadioGroup } from '@base-ui-components/react/radio-group'; +import { Checkbox as BCheckbox } from '@base-ui-components/react/checkbox'; +import { CheckboxGroup as BCheckboxGroup } from '@base-ui-components/react/checkbox-group'; +import { Switch as BSwitch } from '@base-ui-components/react/switch'; +import { Toast as BToast } from '@base-ui-components/react/toast'; +import { X } from 'lucide-react'; + +export function SwitchRoot({ className, ...props }: BSwitch.Root.Props) { + return ( + + ); +} + +export function SwitchThumb({ className, ...props }: BSwitch.Thumb.Props) { + return ( + + ); +} + +export function CheckboxGroup({ className, ...props }: BCheckboxGroup.Props) { + return ( + + ); +} + +export function Checkbox({ className, ...props }: BCheckbox.Root.Props) { + return ( + + ); +} + +export function CheckboxIndicator({ className, ...props }: BCheckbox.Indicator.Props) { + return ( + + ); +} + +export function RadioGroup({ className, ...props }: BRadioGroup.Props) { + return ( + + ); +} + +export function Radio({ className, ...props }: BRadio.Root.Props) { + return ( + + ); +} + +export function RadioIndicator({ className, ...props }: BRadio.Indicator.Props) { + return ( + + ); +} + +export function NumberFieldRoot({ className, ...props }: BNumberField.Root.Props) { + return ( + + ); +} + +export function NumberFieldGroup({ className, ...props }: BNumberField.Group.Props) { + return ; +} + +export function NumberFieldDecrement({ className, ...props }: BNumberField.Decrement.Props) { + return ( + + ); +} + +export const NumberFieldInput = React.forwardRef( + function NumberFieldInput( + { className, ...props }: BNumberField.Input.Props, + forwardedRef: React.ForwardedRef, + ) { + return ( + + ); + }, +); + +export function NumberFieldIncrement({ className, ...props }: BNumberField.Increment.Props) { + return ( + + ); +} + +export function SliderRoot({ className, ...props }: BSlider.Root.Props) { + return ; +} + +export function SliderValue({ className, ...props }: BSlider.Value.Props) { + return ( + + ); +} + +export function SliderControl({ className, ...props }: BSlider.Control.Props) { + return ( + + ); +} + +export function SliderTrack({ className, ...props }: BSlider.Track.Props) { + return ( + + ); +} + +export function SliderIndicator({ className, ...props }: BSlider.Indicator.Props) { + return ( + + ); +} + +export function SliderThumb({ className, ...props }: BSlider.Thumb.Props) { + return ( + + ); +} + +export function SelectRoot(props: BSelect.Root.Props) { + return ; +} + +export function SelectTrigger({ className, ...props }: BSelect.Trigger.Props) { + return ( + + ); +} + +export function SelectValue({ className, ...props }: BSelect.Value.Props) { + return ; +} + +export function SelectIcon({ className, ...props }: BSelect.Icon.Props) { + return ; +} + +export function SelectPortal(props: BSelect.Portal.Props) { + return ; +} + +export function SelectPositioner({ className, ...props }: BSelect.Positioner.Props) { + return ( + + ); +} + +export function SelectPopup({ className, ...props }: BSelect.Popup.Props) { + return ( + + ); +} + +export function SelectScrollUpArrow({ className, ...props }: BSelect.ScrollUpArrow.Props) { + return ( + + ); +} + +export function SelectScrollDownArrow({ className, ...props }: BSelect.ScrollDownArrow.Props) { + return ( + + ); +} + +export function SelectList({ className, ...props }: BSelect.List.Props) { + return ( + + ); +} + +export function SelectItem({ className, ...props }: BSelect.Item.Props) { + return ( + + ); +} + +export function SelectItemIndicator({ className, ...props }: BSelect.ItemIndicator.Props) { + return ; +} + +export function SelectItemText({ className, ...props }: BSelect.ItemText.Props) { + return ; +} + +export function AutocompleteRoot(props: BAutocomplete.Root.Props) { + return ; +} + +export const AutocompleteInput = React.forwardRef( + function AutocompleteInput( + { className, ...props }: BAutocomplete.Input.Props, + forwardedRef: React.ForwardedRef, + ) { + return ( + + ); + }, +); + +export function AutocompletePortal(props: BAutocomplete.Portal.Props) { + return ; +} + +export function AutocompletePositioner({ className, ...props }: BAutocomplete.Positioner.Props) { + return ( + + ); +} + +export function AutocompletePopup({ className, ...props }: BAutocomplete.Popup.Props) { + return ( + + ); +} + +export function AutocompleteList(props: BAutocomplete.List.Props) { + return ; +} + +export function AutocompleteItem({ className, ...props }: BAutocomplete.Item.Props) { + return ( + + ); +} + +export function ComboboxRoot(props: BCombobox.Root.Props) { + return ; +} + +export const ComboboxInput = React.forwardRef( + function ComboboxInput( + { className, ...props }: BCombobox.Input.Props, + forwardedRef: React.ForwardedRef, + ) { + return ( + + ); + }, +); + +export function ComboboxClear({ className, ...props }: BCombobox.Clear.Props) { + return ( + + + + ); +} + +export function ComboboxTrigger({ className, ...props }: BCombobox.Trigger.Props) { + return ( + + ); +} + +export function ComboboxPortal(props: BCombobox.Portal.Props) { + return ; +} + +export function ComboboxPositioner({ className, ...props }: BCombobox.Positioner.Props) { + return ( + + ); +} + +export function ComboboxPopup({ className, ...props }: BCombobox.Popup.Props) { + return ( + + ); +} + +export function ComboboxEmpty({ className, ...props }: BCombobox.Empty.Props) { + return ( + + ); +} + +export function ComboboxList(props: BCombobox.List.Props) { + return ; +} + +export function ComboboxItem({ className, ...props }: BCombobox.Item.Props) { + return ( + + ); +} + +export function ComboboxItemIndicator({ className, ...props }: BCombobox.ItemIndicator.Props) { + return ; +} + +export function Form({ className, ...props }: BForm.Props) { + return ( + + ); +} + +export function FieldRoot({ className, ...props }: BField.Root.Props) { + return ; +} + +export function FieldLabel({ className, ...props }: BField.Label.Props) { + return ( + + ); +} + +export function FieldDescription({ className, ...props }: BField.Description.Props) { + return ; +} + +export const FieldControl = React.forwardRef( + function FieldControl( + { className, ...props }: BField.Control.Props, + forwardedRef: React.ForwardedRef, + ) { + return ( + + ); + }, +); + +export function FieldError({ className, ...props }: BField.Error.Props) { + return ; +} + +export function FieldsetRoot(props: BFieldset.Root.Props) { + return ; +} + +export function FieldsetLegend({ className, ...props }: BFieldset.Legend.Props) { + return ( + + ); +} + +export function Button({ className, ...props }: React.ComponentPropsWithoutRef<'button'>) { + return ( + + + ); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62910a11491..63132eec1d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,6 +195,9 @@ importers: '@stefanprobst/rehype-extract-toc': specifier: ^3.0.0 version: 3.0.0 + '@tanstack/react-form': + specifier: ^1.23.6 + version: 1.23.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-virtual': specifier: ^3.13.12 version: 3.13.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -4093,12 +4096,37 @@ packages: '@tailwindcss/postcss@4.1.15': resolution: {integrity: sha512-IZh8IT76KujRz6d15wZw4eoeViT4TqmzVWNNfpuNCTKiaZUwgr5vtPqO4HjuYDyx3MgGR5qgPt1HMzTeLJyA3g==} + '@tanstack/devtools-event-client@0.3.2': + resolution: {integrity: sha512-gkvph/YMCFUfAca75EsJBJnhbKitDGix7vdEcT/3lAV+eyGSv+uECYG43apVQN4yLJKnV6mzcNvGzOhDhb72gg==} + engines: {node: '>=18'} + + '@tanstack/form-core@1.24.2': + resolution: {integrity: sha512-qc2YFhM0PsxjLbZ7Fn5ErX9kz/Wr6gmd4m47Nf3OFfsFbI1O2B5AQLwt9OApMs19CDeNiqe/zTSK+ayeHaDJNQ==} + + '@tanstack/react-form@1.23.6': + resolution: {integrity: sha512-cz8Nskpe2zo24lJd0ky0hO7NOqV/U7drQ2XiK3bxt94v5hnMQtUOno6mtJ6Tvwy0p8xKwSN76SvnpU+tp8YMQA==} + peerDependencies: + '@tanstack/react-start': ^1.130.10 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@tanstack/react-start': + optional: true + + '@tanstack/react-store@0.7.7': + resolution: {integrity: sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/react-virtual@3.13.12': resolution: {integrity: sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/store@0.7.7': + resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} + '@tanstack/virtual-core@3.13.12': resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==} @@ -5375,6 +5403,9 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-formdata@0.9.0: + resolution: {integrity: sha512-q5uwOjR3Um5YD+ZWPOF/1sGHVW9A5rCrRwITQChRXlmPkxDFBqCm4jNTIVdGHNH9OnR+V9MoZVgRhsFb+ARbUw==} + decode-named-character-reference@1.2.0: resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} @@ -5446,6 +5477,9 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + devalue@5.3.2: + resolution: {integrity: sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -13965,12 +13999,38 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.15 + '@tanstack/devtools-event-client@0.3.2': {} + + '@tanstack/form-core@1.24.2': + dependencies: + '@tanstack/devtools-event-client': 0.3.2 + '@tanstack/store': 0.7.7 + + '@tanstack/react-form@1.23.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/form-core': 1.24.2 + '@tanstack/react-store': 0.7.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + decode-formdata: 0.9.0 + devalue: 5.3.2 + react: 19.2.0 + transitivePeerDependencies: + - react-dom + + '@tanstack/react-store@0.7.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/store': 0.7.7 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + use-sync-external-store: 1.6.0(react@19.2.0) + '@tanstack/react-virtual@3.13.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@tanstack/virtual-core': 3.13.12 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) + '@tanstack/store@0.7.7': {} + '@tanstack/virtual-core@3.13.12': {} '@testing-library/dom@10.4.1': @@ -15357,6 +15417,8 @@ snapshots: decimal.js@10.6.0: {} + decode-formdata@0.9.0: {} + decode-named-character-reference@1.2.0: dependencies: character-entities: 2.0.2 @@ -15410,6 +15472,8 @@ snapshots: detect-node-es@1.1.0: {} + devalue@5.3.2: {} + devlop@1.1.0: dependencies: dequal: 2.0.3