chore(web): upgrade @base-ui/react to v1.4.0 (#35048)

This commit is contained in:
yyh 2026-04-13 22:48:29 +08:00 committed by GitHub
parent 28fce0a890
commit bd30784b1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 111 additions and 12 deletions

47
pnpm-lock.yaml generated
View File

@ -16,14 +16,17 @@ catalogs:
specifier: 8.1.1
version: 8.1.1
'@base-ui/react':
specifier: 1.3.0
version: 1.3.0
specifier: 1.4.0
version: 1.4.0
'@chromatic-com/storybook':
specifier: 5.1.1
version: 5.1.1
'@cucumber/cucumber':
specifier: 12.7.0
version: 12.7.0
'@date-fns/tz':
specifier: 1.2.0
version: 1.2.0
'@egoist/tailwindcss-icons':
specifier: 1.9.2
version: 1.9.2
@ -267,6 +270,9 @@ catalogs:
cron-parser:
specifier: 5.5.0
version: 5.5.0
date-fns:
specifier: 4.0.0
version: 4.0.0
dayjs:
specifier: 1.11.20
version: 1.11.20
@ -648,7 +654,10 @@ importers:
version: 1.27.6(@amplitude/rrweb@2.0.0-alpha.37)(rollup@4.59.0)
'@base-ui/react':
specifier: 'catalog:'
version: 1.3.0(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
version: 1.4.0(@date-fns/tz@1.2.0)(@types/react@19.2.14)(date-fns@4.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@date-fns/tz':
specifier: 'catalog:'
version: 1.2.0
'@emoji-mart/data':
specifier: 'catalog:'
version: 1.2.1
@ -751,6 +760,9 @@ importers:
cron-parser:
specifier: 'catalog:'
version: 5.5.0
date-fns:
specifier: 'catalog:'
version: 4.0.0
dayjs:
specifier: 'catalog:'
version: 1.11.20
@ -1391,19 +1403,21 @@ packages:
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'}
'@base-ui/react@1.3.0':
resolution: {integrity: sha512-FwpKqZbPz14AITp1CVgf4AjhKPe1OeeVKSBMdgD10zbFlj3QSWelmtCMLi2+/PFZZcIm3l87G7rwtCZJwHyXWA==}
'@base-ui/react@1.4.0':
resolution: {integrity: sha512-QcqdVbr/+ba2/RAKJIV1PV6S02Q5+r6a4Eym8ndBw+ZbBILkkmQAyRxXCg/pArrHnkrGeU8goe26aw0h6eE8pg==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@date-fns/tz': ^1.2.0
'@types/react': ^17 || ^18 || ^19
date-fns: ^4.0.0
react: ^17 || ^18 || ^19
react-dom: ^17 || ^18 || ^19
peerDependenciesMeta:
'@types/react':
optional: true
'@base-ui/utils@0.2.6':
resolution: {integrity: sha512-yQ+qeuqohwhsNpoYDqqXaLllYAkPCP4vYdDrVo8FQXaAPfHWm1pG/Vm+jmGTA5JFS0BAIjookyapuJFY8F9PIw==}
'@base-ui/utils@0.2.7':
resolution: {integrity: sha512-nXYKhiL/0JafyJE8PfcflipGftOftlIwKd72rU15iZ1M5yqgg5J9P8NHU71GReDuXco5MJA/eVQqUT5WRqX9sA==}
peerDependencies:
'@types/react': ^17 || ^18 || ^19
react: ^17 || ^18 || ^19
@ -1532,6 +1546,9 @@ packages:
'@cucumber/tag-expressions@9.1.0':
resolution: {integrity: sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==}
'@date-fns/tz@1.2.0':
resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==}
'@e18e/eslint-plugin@0.3.0':
resolution: {integrity: sha512-hHgfpxsrZ2UYHcicA+tGZnmk19uJTaye9VH79O+XS8R4ona2Hx3xjhXghclNW58uXMk3xXlbYEOMr8thsoBmWg==}
peerDependencies:
@ -5325,6 +5342,9 @@ packages:
dagre-d3-es@7.0.14:
resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==}
date-fns@4.0.0:
resolution: {integrity: sha512-6K33+I8fQ5otvHgLIvKK1xmMbLAh0pduyrx7dwMXKiGYeoWhmk6M3Zoak9n7bXHMJQlHq1yqmdGy1QxKddJjUA==}
dayjs@1.11.20:
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
@ -8896,20 +8916,21 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@base-ui/react@1.3.0(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
'@base-ui/react@1.4.0(@date-fns/tz@1.2.0)(@types/react@19.2.14)(date-fns@4.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies:
'@babel/runtime': 7.29.2
'@base-ui/utils': 0.2.6(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@base-ui/utils': 0.2.7(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@date-fns/tz': 1.2.0
'@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@floating-ui/utils': 0.2.11
date-fns: 4.0.0
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
tabbable: 6.4.0
use-sync-external-store: 1.6.0(react@19.2.5)
optionalDependencies:
'@types/react': 19.2.14
'@base-ui/utils@0.2.6(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
'@base-ui/utils@0.2.7(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies:
'@babel/runtime': 7.29.2
'@floating-ui/utils': 0.2.11
@ -9128,6 +9149,8 @@ snapshots:
'@cucumber/tag-expressions@9.1.0': {}
'@date-fns/tz@1.2.0': {}
'@e18e/eslint-plugin@0.3.0(eslint@10.2.0(jiti@2.6.1))(oxlint@1.58.0(oxlint-tsgolint@0.20.0))':
dependencies:
eslint-plugin-depend: 1.5.0(eslint@10.2.0(jiti@2.6.1))
@ -12793,6 +12816,8 @@ snapshots:
d3: 7.9.0
lodash-es: 4.18.0
date-fns@4.0.0: {}
dayjs@1.11.20: {}
debug@4.4.3(supports-color@8.1.1):

View File

@ -48,7 +48,8 @@ catalog:
"@amplitude/analytics-browser": 2.38.1
"@amplitude/plugin-session-replay-browser": 1.27.6
"@antfu/eslint-config": 8.1.1
"@base-ui/react": 1.3.0
"@base-ui/react": 1.4.0
"@date-fns/tz": 1.2.0
"@chromatic-com/storybook": 5.1.1
"@cucumber/cucumber": 12.7.0
"@egoist/tailwindcss-icons": 1.9.2
@ -135,6 +136,7 @@ catalog:
code-inspector-plugin: 1.5.1
copy-to-clipboard: 3.3.3
cron-parser: 5.5.0
date-fns: 4.0.0
dayjs: 1.11.20
decimal.js: 10.6.0
dompurify: 3.3.3

View File

@ -41,6 +41,33 @@ const renderOpenSelect = ({
}
describe('Select wrappers', () => {
describe('Select root integration', () => {
it('should associate the hidden input with an external form and preserve autocomplete hints', () => {
const formId = 'profile-form'
const { container } = render(
<>
<form id={formId} />
<Select defaultValue="seattle" name="city" form={formId} autoComplete="address-level2">
<SelectTrigger aria-label="city select">
<SelectValue />
</SelectTrigger>
<SelectContent listProps={{ 'role': 'listbox', 'aria-label': 'select list' }}>
<SelectItem value="seattle">Seattle</SelectItem>
<SelectItem value="new-york">New York</SelectItem>
</SelectContent>
</Select>
</>,
)
const hiddenInput = container.querySelector('input[name="city"]')
const form = container.querySelector(`#${formId}`) as HTMLFormElement
expect(hiddenInput).toHaveAttribute('form', formId)
expect(hiddenInput).toHaveAttribute('autocomplete', 'address-level2')
expect(new FormData(form).get('city')).toBe('seattle')
})
})
describe('SelectTrigger', () => {
it('should render clear button when clearable is true and loading is false', () => {
renderOpenSelect({

View File

@ -47,6 +47,23 @@ describe('Slider', () => {
expect(onValueChange).toHaveBeenLastCalledWith(21, expect.anything())
})
it('should round floating point keyboard updates to the configured step', async () => {
const user = userEvent.setup()
const onValueChange = vi.fn()
render(<Slider value={0.2} min={0} max={1} step={0.1} onValueChange={onValueChange} aria-label="Value" />)
const slider = getSliderInput()
await act(async () => {
slider.focus()
await user.keyboard('{ArrowRight}')
})
expect(onValueChange).toHaveBeenCalledTimes(1)
expect(onValueChange).toHaveBeenLastCalledWith(0.3, expect.anything())
})
it('should not trigger onValueChange when disabled', async () => {
const user = userEvent.setup()
const onValueChange = vi.fn()

View File

@ -251,6 +251,32 @@ describe('base/ui/toast', () => {
expect(screen.queryByText('Loading')).not.toBeInTheDocument()
})
// Re-adding the same toast id should upsert in place instead of stacking duplicates.
it('should upsert an existing toast when add is called with the same id', async () => {
render(<ToastHost />)
act(() => {
toast('Syncing', {
id: 'sync-job',
description: 'Uploading changes…',
})
})
expect(await screen.findByText('Syncing')).toBeInTheDocument()
act(() => {
toast.success('Synced', {
id: 'sync-job',
description: 'All changes are uploaded.',
})
})
expect(screen.queryByText('Syncing')).not.toBeInTheDocument()
expect(screen.getByText('Synced')).toBeInTheDocument()
expect(screen.getByText('All changes are uploaded.')).toBeInTheDocument()
expect(screen.getAllByRole('dialog')).toHaveLength(1)
})
// Action props should pass through to the Base UI action button.
it('should render and invoke toast action props', async () => {
const onAction = vi.fn()

View File

@ -56,6 +56,7 @@
"@amplitude/analytics-browser": "catalog:",
"@amplitude/plugin-session-replay-browser": "catalog:",
"@base-ui/react": "catalog:",
"@date-fns/tz": "catalog:",
"@emoji-mart/data": "catalog:",
"@floating-ui/react": "catalog:",
"@formatjs/intl-localematcher": "catalog:",
@ -90,6 +91,7 @@
"cmdk": "catalog:",
"copy-to-clipboard": "catalog:",
"cron-parser": "catalog:",
"date-fns": "catalog:",
"dayjs": "catalog:",
"decimal.js": "catalog:",
"dompurify": "catalog:",