diff --git a/packages/date/package.json b/packages/date/package.json
index 828407f0a2..5fda42f4ae 100644
--- a/packages/date/package.json
+++ b/packages/date/package.json
@@ -48,10 +48,12 @@
"dependencies": {
"@vtex/shoreline-icons": "workspace",
"@vtex/shoreline-utils": "workspace",
+ "@vtex/shoreline-store": "workspace",
"@internationalized/date": "3.5.0",
"@react-aria/calendar": "3.5.3",
"@react-aria/datepicker": "3.9.0",
"@react-stately/datepicker": "3.9.0",
- "@react-stately/calendar": "3.4.2"
+ "@react-stately/calendar": "3.4.2",
+ "@react-aria/i18n": "3.9.0"
}
}
diff --git a/packages/date/src/calendar/calendar-cell.css b/packages/date/src/calendar/calendar-cell.css
index 7526a5eaa4..4bfe10b2ff 100644
--- a/packages/date/src/calendar/calendar-cell.css
+++ b/packages/date/src/calendar/calendar-cell.css
@@ -2,7 +2,9 @@
[data-sl-calendar-cell] {
/* height: 32px; */
}
+}
+@layer sl-expended-components {
[data-sl-calendar-cell-button] {
width: 100%;
height: 100%;
diff --git a/packages/date/src/calendar/calendar-cell.tsx b/packages/date/src/calendar/calendar-cell.tsx
index 001e947bec..d64432c229 100644
--- a/packages/date/src/calendar/calendar-cell.tsx
+++ b/packages/date/src/calendar/calendar-cell.tsx
@@ -3,9 +3,12 @@ import { useCalendarCell } from '@react-aria/calendar'
import { IconButton } from '@vtex/shoreline-components'
import './calendar-cell.css'
+import { useCalendarContext } from './calendar-provider'
-export function CalendarCell({ state, date }: any) {
+export function CalendarCell({ date }: any) {
const ref = useRef(null)
+ const store = useCalendarContext()
+
const {
cellProps,
buttonProps,
@@ -15,7 +18,7 @@ export function CalendarCell({ state, date }: any) {
isUnavailable,
formattedDate,
isFocused,
- } = useCalendarCell({ date }, state, ref)
+ } = useCalendarCell({ date }, store.state, ref)
return (
diff --git a/packages/date/src/calendar/calendar-grid.tsx b/packages/date/src/calendar/calendar-grid.tsx
index d6e978bde1..bec9a61496 100644
--- a/packages/date/src/calendar/calendar-grid.tsx
+++ b/packages/date/src/calendar/calendar-grid.tsx
@@ -1,16 +1,23 @@
import React from 'react'
import { useCalendarGrid } from '@react-aria/calendar'
import { useLocale } from '@vtex/shoreline-components'
-import { getWeeksInMonth } from '../utils'
+import { getWeeksInMonth } from '../utils'
import { CalendarCell } from './calendar-cell'
+import { useCalendarContext } from './calendar-provider'
import './calendar-grid.css'
-export function CalendarGrid({ state, ...props }: any) {
+export function CalendarGrid(props: any) {
const locale = useLocale()
- const { gridProps, headerProps, weekDays } = useCalendarGrid(props, state)
- const weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale)
+ const store = useCalendarContext()
+
+ const { gridProps, headerProps, weekDays } = useCalendarGrid(
+ props,
+ store.state
+ )
+
+ const weeksInMonth = getWeeksInMonth(store.state.visibleRange.start, locale)
return (
@@ -24,11 +31,11 @@ export function CalendarGrid({ state, ...props }: any) {
{[...new Array(weeksInMonth).keys()].map((weekIndex) => (
- {state
+ {store.state
.getDatesInWeek(weekIndex)
.map((date: any, i: number) =>
date ? (
-
+
) : (
|
)
diff --git a/packages/date/src/calendar/calendar-provider.tsx b/packages/date/src/calendar/calendar-provider.tsx
new file mode 100644
index 0000000000..d47fce3096
--- /dev/null
+++ b/packages/date/src/calendar/calendar-provider.tsx
@@ -0,0 +1,23 @@
+import type { CalendarState } from '@react-stately/calendar'
+import React, { createContext, useContext } from 'react'
+import type { Store } from '@vtex/shoreline-store'
+
+export const CalendarContext = createContext | null>(null)
+
+export function CalendarProvider({ store, children }: any) {
+ return (
+
+ {children}
+
+ )
+}
+
+export function useCalendarContext() {
+ const context = useContext(CalendarContext)
+
+ if (!context) {
+ throw new Error('Calendar components must be wrapped by CalendarProvider')
+ }
+
+ return context
+}
diff --git a/packages/date/src/calendar/calendar-store.ts b/packages/date/src/calendar/calendar-store.ts
new file mode 100644
index 0000000000..461722876a
--- /dev/null
+++ b/packages/date/src/calendar/calendar-store.ts
@@ -0,0 +1,15 @@
+import { createCalendar } from '@internationalized/date'
+import { useCalendarState } from '@react-stately/calendar'
+import { Store } from '@vtex/shoreline-store'
+import { useMemo } from 'react'
+
+export function useCalendarStore(props: any) {
+ const state = useCalendarState({
+ ...props,
+ createCalendar,
+ })
+
+ const store = useMemo(() => new Store(state), [state])
+
+ return store
+}
diff --git a/packages/date/src/calendar/calendar.tsx b/packages/date/src/calendar/calendar.tsx
index 285f9e5136..461f7fdffc 100644
--- a/packages/date/src/calendar/calendar.tsx
+++ b/packages/date/src/calendar/calendar.tsx
@@ -1,52 +1,57 @@
import React from 'react'
import { useCalendar } from '@react-aria/calendar'
-import { useCalendarState } from '@react-stately/calendar'
import { createCalendar } from '@internationalized/date'
import { useLocale, IconButton } from '@vtex/shoreline-components'
import { IconCaretLeft, IconCaretRight } from '@vtex/shoreline-icons'
+import { I18nProvider } from '@react-aria/i18n'
+
import { CalendarGrid } from './calendar-grid'
+import { CalendarProvider } from './calendar-provider'
+import { useCalendarStore } from './calendar-store'
import './calendar.css'
export function Calendar(props: any) {
const locale = useLocale()
- const state = useCalendarState({
+ const store = useCalendarStore({
...props,
locale,
createCalendar,
})
const { calendarProps, prevButtonProps, nextButtonProps, title } =
- useCalendar(props, state)
-
- console.log(prevButtonProps)
+ useCalendar(props, store.state)
return (
-
-
-
-
-
- {title}
-
-
-
-
-
-
+
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
)
}
diff --git a/packages/date/src/calendar/stories/calendar.stories.tsx b/packages/date/src/calendar/stories/calendar.stories.tsx
index 7011539afd..ebc3f40e88 100644
--- a/packages/date/src/calendar/stories/calendar.stories.tsx
+++ b/packages/date/src/calendar/stories/calendar.stories.tsx
@@ -2,6 +2,8 @@ import React, { useState } from 'react'
// import { Stack } from '@vtex/shoreline-components'
import { Calendar } from '../index'
+import { LocaleProvider } from '@vtex/shoreline-components'
+
// import { parseDate } from '../../utils'
export default {
@@ -18,9 +20,13 @@ export function Default() {
// return
// }
-// export function Locale() {
-// return
-// }
+export function Locale() {
+ return (
+
+
+
+ )
+}
// export function Granularity() {
// return (
diff --git a/packages/store/CHANGELOG.md b/packages/store/CHANGELOG.md
new file mode 100644
index 0000000000..e4d87c4d45
--- /dev/null
+++ b/packages/store/CHANGELOG.md
@@ -0,0 +1,4 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
diff --git a/packages/store/package.json b/packages/store/package.json
new file mode 100644
index 0000000000..f5eea192a5
--- /dev/null
+++ b/packages/store/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "@vtex/shoreline-store",
+ "version": "0.0.0",
+ "main": "./dist/index.js",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.ts",
+ "publishConfig": {
+ "access": "public",
+ "registry": "https://registry.npmjs.org"
+ },
+ "files": [
+ "dist"
+ ],
+ "exports": {
+ ".": {
+ "require": "./dist/index.js",
+ "import": "./dist/index.mjs",
+ "types": "./dist/index.d.ts"
+ },
+ "./styles": "./dist/index.css"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "scripts": {
+ "prebuild": "rm -rf dist",
+ "dev": "tsup --watch",
+ "build": "tsup"
+ },
+ "repository": {
+ "directory": "packages/shoreline",
+ "type": "git",
+ "url": "git+https://github.com/vtex/shoreline.git"
+ },
+ "bugs": {
+ "url": "https://github.com/vtex/shoreline/issues"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "devDependencies": {
+ "@types/use-sync-external-store": "0.0.6"
+ },
+ "dependencies": {
+ "use-sync-external-store": "1.2.0"
+ }
+}
diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts
new file mode 100644
index 0000000000..505c32cbbf
--- /dev/null
+++ b/packages/store/src/index.ts
@@ -0,0 +1,2 @@
+export * from './store'
+export * from './use-store'
diff --git a/packages/store/src/shallow.ts b/packages/store/src/shallow.ts
new file mode 100644
index 0000000000..52b95f5e46
--- /dev/null
+++ b/packages/store/src/shallow.ts
@@ -0,0 +1,31 @@
+export function shallow(objA: T, objB: T) {
+ if (Object.is(objA, objB)) {
+ return true
+ }
+
+ if (
+ typeof objA !== 'object' ||
+ objA === null ||
+ typeof objB !== 'object' ||
+ objB === null
+ ) {
+ return false
+ }
+
+ const keysA = Object.keys(objA)
+
+ if (keysA.length !== Object.keys(objB).length) {
+ return false
+ }
+
+ for (let i = 0; i < keysA.length; i++) {
+ if (
+ !Object.prototype.hasOwnProperty.call(objB, keysA[i] as string) ||
+ !Object.is(objA[keysA[i] as keyof T], objB[keysA[i] as keyof T])
+ ) {
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/packages/store/src/store.ts b/packages/store/src/store.ts
new file mode 100644
index 0000000000..ebf6192018
--- /dev/null
+++ b/packages/store/src/store.ts
@@ -0,0 +1,77 @@
+export type AnyUpdater = (...args: any[]) => any
+
+export type Listener = () => void
+
+interface StoreOptions<
+ TState,
+ TUpdater extends AnyUpdater = (cb: TState) => TState
+> {
+ updateFn?: (previous: TState) => (updater: TUpdater) => TState
+ onSubscribe?: (
+ listener: Listener,
+ store: Store
+ ) => () => void
+ onUpdate?: () => void
+}
+
+export class Store<
+ TState,
+ TUpdater extends AnyUpdater = (cb: TState) => TState
+> {
+ private listeners = new Set()
+ private _state: TState
+ private _options?: StoreOptions
+ private _batching = false
+ private _flushing = 0
+
+ constructor(initialState: TState, options?: StoreOptions) {
+ this._state = initialState
+ this._options = options
+ }
+
+ public get state() {
+ return this._state
+ }
+
+ public subscribe = (listener: Listener) => {
+ this.listeners.add(listener)
+ const unsub = this._options?.onSubscribe?.(listener, this)
+
+ return () => {
+ this.listeners.delete(listener)
+ unsub?.()
+ }
+ }
+
+ public setState = (updater: TUpdater) => {
+ const previous = this._state
+
+ this._state = this._options?.updateFn
+ ? this._options.updateFn(previous)(updater)
+ : (updater as any)(previous)
+
+ // Always run onUpdate, regardless of batching
+ this._options?.onUpdate?.()
+
+ // Attempt to flush
+ this._flush()
+ }
+
+ public _flush = () => {
+ if (this._batching) return
+ const flushId = ++this._flushing
+
+ this.listeners.forEach((listener) => {
+ if (this._flushing !== flushId) return
+ listener()
+ })
+ }
+
+ public batch = (cb: () => void) => {
+ if (this._batching) return cb()
+ this._batching = true
+ cb()
+ this._batching = false
+ this._flush()
+ }
+}
diff --git a/packages/store/src/tests/shallow.test.ts b/packages/store/src/tests/shallow.test.ts
new file mode 100644
index 0000000000..20a2165b37
--- /dev/null
+++ b/packages/store/src/tests/shallow.test.ts
@@ -0,0 +1,60 @@
+import { describe, it, expect } from '@vtex/shoreline-test-utils'
+import { shallow } from '../shallow'
+
+describe('shallow', () => {
+ it('should return true for shallowly equal objects', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = { a: 1, b: 'hello' }
+
+ expect(shallow(objA, objB)).toBe(true)
+ })
+
+ it('should return false for objects with different values', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = { a: 2, b: 'world' }
+
+ expect(shallow(objA, objB)).toBe(false)
+ })
+
+ it('should return false for objects with different keys', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = { a: 1, c: 'world' }
+
+ expect(shallow(objA, objB as any)).toBe(false)
+ })
+
+ it('should return false for objects with different structures', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = [1, 'hello']
+
+ expect(shallow(objA, objB as any)).toBe(false)
+ })
+
+ it('should return false for one object being null', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = null
+
+ expect(shallow(objA, objB)).toBe(false)
+ })
+
+ it('should return false for one object being undefined', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = undefined
+
+ expect(shallow(objA, objB)).toBe(false)
+ })
+
+ it('should return true for two null objects', () => {
+ const objA = null
+ const objB = null
+
+ expect(shallow(objA, objB)).toBe(true)
+ })
+
+ it('should return false for objects with different types', () => {
+ const objA = { a: 1, b: 'hello' }
+ const objB = { a: '1', b: 'hello' }
+
+ expect(shallow(objA, objB as any)).toBe(false)
+ })
+})
diff --git a/packages/store/src/tests/store.test.ts b/packages/store/src/tests/store.test.ts
new file mode 100644
index 0000000000..d894eb5706
--- /dev/null
+++ b/packages/store/src/tests/store.test.ts
@@ -0,0 +1,83 @@
+import { describe, test, expect, vi } from '@vtex/shoreline-test-utils'
+import { Store } from '../store'
+
+describe('store', () => {
+ test(`should set the initial value`, () => {
+ const store = new Store(0)
+
+ expect(store.state).toEqual(0)
+ })
+
+ test(`basic subscriptions should work`, () => {
+ const store = new Store(0)
+
+ const subscription = vi.fn()
+
+ const unsub = store.subscribe(subscription)
+
+ store.setState(() => 1)
+
+ expect(store.state).toEqual(1)
+ expect(subscription).toHaveBeenCalled()
+
+ unsub()
+
+ store.setState(() => 2)
+
+ expect(store.state).toEqual(2)
+
+ expect(subscription).toHaveBeenCalledTimes(1)
+ })
+
+ test(`setState passes previous state`, () => {
+ const store = new Store(3)
+
+ store.setState((v) => v + 1)
+
+ expect(store.state).toEqual(4)
+ })
+
+ test(`updateFn acts as state transformer`, () => {
+ const store = new Store(1, {
+ updateFn: (v) => (updater) => Number(updater(v)),
+ })
+
+ store.setState((v) => `${v + 1}` as never)
+
+ expect(store.state).toEqual(2)
+
+ store.setState((v) => `${v + 2}` as never)
+
+ expect(store.state).toEqual(4)
+
+ expect(typeof store.state).toEqual('number')
+ })
+
+ test('Batch prevents listeners from being called during repeated setStates', () => {
+ const store = new Store(0)
+
+ const listener = vi.fn()
+
+ store.subscribe(listener)
+
+ store.batch(() => {
+ store.setState(() => 1)
+ store.setState(() => 2)
+ store.setState(() => 3)
+ store.setState(() => 4)
+ })
+
+ expect(store.state).toEqual(4)
+ // Listener is only called once because of batching
+ expect(listener).toHaveBeenCalledTimes(1)
+
+ store.setState(() => 1)
+ store.setState(() => 2)
+ store.setState(() => 3)
+ store.setState(() => 4)
+
+ expect(store.state).toEqual(4)
+ // Listener is called 4 times because of a lack of batching
+ expect(listener).toHaveBeenCalledTimes(5)
+ })
+})
diff --git a/packages/store/src/tests/use-store.test.tsx b/packages/store/src/tests/use-store.test.tsx
new file mode 100644
index 0000000000..41de8a5649
--- /dev/null
+++ b/packages/store/src/tests/use-store.test.tsx
@@ -0,0 +1,88 @@
+import {
+ render,
+ waitFor,
+ expect,
+ describe,
+ it,
+ userEvent,
+ vi,
+} from '@vtex/shoreline-test-utils'
+import * as React from 'react'
+import { Store } from '../store'
+import { useStore } from '../use-store'
+import { useState } from 'react'
+
+const user = userEvent.setup()
+
+describe('useStore', () => {
+ it('allows us to select state using a selector', async () => {
+ const store = new Store({
+ select: 0,
+ ignored: 1,
+ })
+
+ function Comp() {
+ const storeVal = useStore(store, (state) => state.select)
+
+ return Store: {storeVal}
+ }
+
+ const { getByText } = render()
+
+ expect(getByText('Store: 0')).toBeInTheDocument()
+ })
+
+ it('only triggers a re-render when selector state is updated', async () => {
+ const store = new Store({
+ select: 0,
+ ignored: 1,
+ })
+
+ function Comp() {
+ const storeVal = useStore(store, (state) => state.select)
+ const [fn] = useState(vi.fn)
+
+ fn()
+
+ return (
+
+ Number rendered: {fn.mock.calls.length}
+ Store: {storeVal}
+
+
+
+ )
+ }
+
+ const { getByText } = render()
+
+ expect(getByText('Store: 0')).toBeInTheDocument()
+ expect(getByText('Number rendered: 1')).toBeInTheDocument()
+
+ await user.click(getByText('Update select'))
+
+ await waitFor(() => expect(getByText('Store: 10')).toBeInTheDocument())
+ expect(getByText('Number rendered: 2')).toBeInTheDocument()
+
+ await user.click(getByText('Update ignored'))
+ expect(getByText('Number rendered: 2')).toBeInTheDocument()
+ })
+})
diff --git a/packages/store/src/use-store.ts b/packages/store/src/use-store.ts
new file mode 100644
index 0000000000..1e9ec969ee
--- /dev/null
+++ b/packages/store/src/use-store.ts
@@ -0,0 +1,24 @@
+import type { AnyUpdater, Store } from './store'
+import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js'
+import { shallow } from './shallow'
+
+export type NoInfer = [T][T extends any ? 0 : never]
+
+export function useStore<
+ TState,
+ TSelected = NoInfer,
+ TUpdater extends AnyUpdater = AnyUpdater
+>(
+ store: Store,
+ selector: (state: NoInfer) => TSelected = (d) => d as any
+) {
+ const slice = useSyncExternalStoreWithSelector(
+ store.subscribe,
+ () => store.state,
+ () => store.state,
+ selector,
+ shallow
+ )
+
+ return slice
+}
diff --git a/packages/store/tsconfig.json b/packages/store/tsconfig.json
new file mode 100644
index 0000000000..9907687682
--- /dev/null
+++ b/packages/store/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "declarationDir": "declarations"
+ },
+ "include": ["./src"],
+ "exclude": [
+ "node_modules",
+ "dist",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/*test-utils*"
+ ]
+}
diff --git a/packages/store/tsup.config.ts b/packages/store/tsup.config.ts
new file mode 100644
index 0000000000..752fe81784
--- /dev/null
+++ b/packages/store/tsup.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig } from 'tsup'
+
+export default defineConfig({
+ entry: ['src/index.ts'],
+ format: ['cjs', 'esm'],
+ external: ['react'],
+ splitting: false,
+ sourcemap: true,
+ clean: true,
+ dts: true,
+})
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index 4c7be86c31..39bec48f2b 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -40,6 +40,7 @@
"dependencies": {
"@testing-library/dom": "9.3.3",
"@testing-library/jest-dom": "6.1.4",
- "@testing-library/react": "14.1.2"
+ "@testing-library/react": "14.1.2",
+ "@testing-library/user-event": "14.5.1"
}
}
diff --git a/packages/test-utils/src/react.ts b/packages/test-utils/src/react.ts
index 4c421ecc23..57ae296037 100644
--- a/packages/test-utils/src/react.ts
+++ b/packages/test-utils/src/react.ts
@@ -4,6 +4,8 @@ import {
act,
screen,
fireEvent,
+ waitFor,
} from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
-export { render, renderHook, act, screen, fireEvent }
+export { render, renderHook, act, screen, fireEvent, waitFor, userEvent }
diff --git a/packages/theme/src/get-preflight.ts b/packages/theme/src/get-preflight.ts
index 6943bdfb3b..17c85b0514 100644
--- a/packages/theme/src/get-preflight.ts
+++ b/packages/theme/src/get-preflight.ts
@@ -1,7 +1,7 @@
import { constants } from '@vtex/shoreline-utils'
export const getPreflight = (prefix = constants.dsPrefix) => `
-@layer sl-reset, sl-base, sl-tokens, sl-components;
+@layer sl-reset, sl-base, sl-tokens, sl-components, sl-expended-components;
@layer sl-reset {
*,
*::before,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 46984aa61a..bc9967f71f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -339,6 +339,9 @@ importers:
'@react-aria/datepicker':
specifier: 3.9.0
version: 3.9.0(react-dom@18.2.0)(react@18.2.0)
+ '@react-aria/i18n':
+ specifier: 3.9.0
+ version: 3.9.0(react@18.2.0)
'@react-stately/calendar':
specifier: 3.4.2
version: 3.4.2(react@18.2.0)
@@ -348,6 +351,9 @@ importers:
'@vtex/shoreline-icons':
specifier: workspace
version: link:../icons
+ '@vtex/shoreline-store':
+ specifier: workspace
+ version: link:../store
'@vtex/shoreline-utils':
specifier: workspace
version: link:../utils
@@ -435,6 +441,22 @@ importers:
specifier: 20.10.0
version: 20.10.0
+ packages/store:
+ dependencies:
+ react:
+ specifier: '>=18'
+ version: 18.2.0
+ react-dom:
+ specifier: '>=18'
+ version: 18.2.0(react@18.2.0)
+ use-sync-external-store:
+ specifier: 1.2.0
+ version: 1.2.0(react@18.2.0)
+ devDependencies:
+ '@types/use-sync-external-store':
+ specifier: 0.0.6
+ version: 0.0.6
+
packages/stylelint:
dependencies:
stylelint:
@@ -452,6 +474,9 @@ importers:
'@testing-library/react':
specifier: 14.1.2
version: 14.1.2(react-dom@18.2.0)(react@18.2.0)
+ '@testing-library/user-event':
+ specifier: 14.5.1
+ version: 14.5.1(@testing-library/dom@9.3.3)
devDependencies:
vitest:
specifier: 0.34.6
@@ -5950,7 +5975,7 @@ packages:
dependencies:
'@babel/runtime': 7.22.6
'@react-aria/focus': 3.14.3(react@18.2.0)
- '@react-aria/i18n': 3.5.1(react@18.2.0)
+ '@react-aria/i18n': 3.9.0(react@18.2.0)
'@react-aria/interactions': 3.19.1(react@18.2.0)
'@react-aria/utils': 3.21.1(react@18.2.0)
'@react-stately/collections': 3.4.2(react@18.2.0)
@@ -5966,7 +5991,7 @@ packages:
react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0
dependencies:
'@babel/runtime': 7.22.6
- '@react-aria/i18n': 3.5.1(react@18.2.0)
+ '@react-aria/i18n': 3.9.0(react@18.2.0)
'@react-aria/live-announcer': 3.1.1
'@react-aria/utils': 3.21.1(react@18.2.0)
'@react-types/button': 3.6.0(react@18.2.0)
@@ -7776,6 +7801,15 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@testing-library/user-event@14.5.1(@testing-library/dom@9.3.3):
+ resolution: {integrity: sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==}
+ engines: {node: '>=12', npm: '>=6'}
+ peerDependencies:
+ '@testing-library/dom': '>=7.21.4'
+ dependencies:
+ '@testing-library/dom': 9.3.3
+ dev: false
+
/@theguild/remark-mermaid@0.0.4(react@18.2.0):
resolution: {integrity: sha512-C1gssw07eURtCwzXqZZdvyV/eawQ/cXfARaXIgBU9orffox+/YQ+exxmNu9v16NSGzAVsGF4qEVHvCOcCR/FpQ==}
peerDependencies:
@@ -8217,6 +8251,10 @@ packages:
/@types/unist@3.0.0:
resolution: {integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==}
+ /@types/use-sync-external-store@0.0.6:
+ resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+ dev: true
+
/@types/websocket@1.0.2:
resolution: {integrity: sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ==}
dependencies:
@@ -8757,7 +8795,7 @@ packages:
react-dom: ^16.9 || ^17.0
dependencies:
'@babel/core': 7.23.5
- '@react-aria/i18n': 3.5.1(react@18.2.0)
+ '@react-aria/i18n': 3.9.0(react@18.2.0)
'@react-aria/listbox': 3.6.0(react@18.2.0)
'@react-aria/spinbutton': 3.1.2(react-dom@18.2.0)(react@18.2.0)
'@react-aria/utils': 3.21.1(react@18.2.0)
|