diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..dc8f99f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +pnpm-lock.yaml +node_modules +dist +build diff --git a/__tests__/__snapshots__/index.test.tsx.snap b/__tests__/__snapshots__/main.test.tsx.snap similarity index 100% rename from __tests__/__snapshots__/index.test.tsx.snap rename to __tests__/__snapshots__/main.test.tsx.snap diff --git a/__tests__/NavigationInsideEffect.tsx b/__tests__/components/NavigationInsideEffect.tsx similarity index 75% rename from __tests__/NavigationInsideEffect.tsx rename to __tests__/components/NavigationInsideEffect.tsx index 1e89277..26ff1a7 100644 --- a/__tests__/NavigationInsideEffect.tsx +++ b/__tests__/components/NavigationInsideEffect.tsx @@ -1,6 +1,6 @@ import { type FC, useEffect } from 'react'; -import { useNavigate } from '../src/index.js'; -import { LocationDisplay } from './index.test.js'; +import { useNavigate } from '../../src/index.js'; +import { LocationDisplay } from '../main.test.js'; export const NavigationInsideEffect: FC = () => { const { navigate } = useNavigate(); diff --git a/__tests__/helpers.ts b/__tests__/helpers.ts deleted file mode 100644 index 8bdb187..0000000 --- a/__tests__/helpers.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function urlRhs(url: URL): string { - return decodeURI(url.toString().slice(url.origin.length)); -} diff --git a/__tests__/index.test.tsx b/__tests__/main.test.tsx similarity index 94% rename from __tests__/index.test.tsx rename to __tests__/main.test.tsx index 48c4115..fe0a0e6 100644 --- a/__tests__/index.test.tsx +++ b/__tests__/main.test.tsx @@ -4,10 +4,6 @@ import { expect, test } from 'vitest'; import { Link, Route, Router, Routes, useLocation } from '../src/index.js'; import { namedRoute } from '../src/named-route.js'; -if (!window) { - throw new Error('window is not defined'); -} - export const LocationDisplay = () => { const [location] = useLocation(); @@ -20,7 +16,7 @@ test('basic', async () => { const userView = namedRoute('/user/:userId'); const { asFragment } = render( - + diff --git a/__tests__/navigate.test.tsx b/__tests__/navigate.test.tsx index 1c93751..6564f2a 100644 --- a/__tests__/navigate.test.tsx +++ b/__tests__/navigate.test.tsx @@ -3,8 +3,8 @@ import type { FC } from 'react'; import { expect, test } from 'vitest'; import { Route, Router, Routes, useNavigate } from '../src/index.js'; import { namedRoute } from '../src/named-route.js'; -import { NavigationInsideEffect } from './NavigationInsideEffect.js'; -import { LocationDisplay } from './index.test.js'; +import { NavigationInsideEffect } from './components/NavigationInsideEffect.js'; +import { LocationDisplay } from './main.test.js'; const usersView = namedRoute('/users/:userId'); @@ -35,7 +35,7 @@ const Buttons: FC = () => { test('nav with clicks', async () => { render( - + { test('programmatic navigation with hooks', async () => { render( - + , ); diff --git a/__tests__/nested.test.tsx b/__tests__/nested.test.tsx index b76648c..16a3b80 100644 --- a/__tests__/nested.test.tsx +++ b/__tests__/nested.test.tsx @@ -4,7 +4,7 @@ import type { FC } from 'react'; import { expect, test } from 'vitest'; import { namedRoute } from '../lib/named-route.js'; import { Route, Router, Routes } from '../src/index.js'; -import { LocationDisplay } from './index.test.js'; +import { LocationDisplay } from './main.test.js'; test('wildcard routes + nested', async () => { const userRoot = namedRoute('/users'); @@ -17,7 +17,7 @@ test('wildcard routes + nested', async () => { const ParamlessComponent: FC = () => <>I am a Paramless Component; const { asFragment } = render( - + diff --git a/__tests__/route.test.tsx b/__tests__/route.test.tsx index 23b8444..ab7b707 100644 --- a/__tests__/route.test.tsx +++ b/__tests__/route.test.tsx @@ -8,7 +8,7 @@ import { Route, Router, Routes, - type PartialNavigateEventListener, + type SyntheticNavigateEvent, } from '../src/index.js'; const login = namedRoute('/'); @@ -33,11 +33,11 @@ test('custom route', async () => { test('cancel nav', async () => { const Component: FC = () => { - const onNav = useCallback(async (e) => { + const onNav = useCallback(async (e: SyntheticNavigateEvent) => { e.preventDefault(); }, []); return ( - +

custom route

@@ -56,7 +56,7 @@ test('routes with components/children/paths/no paths', async () => { const HelloComponent = () =>

hello

; const { asFragment } = render( - + @@ -84,7 +84,7 @@ test('effects inside route components or children dont fire', async () => { }; render( - + diff --git a/bundlesize.config.cjs b/bundlesize.config.cjs index fbd93e7..e79e50c 100644 --- a/bundlesize.config.cjs +++ b/bundlesize.config.cjs @@ -2,12 +2,12 @@ module.exports = { files: [ { path: './build/*.js', - maxSize: '4 kB', + maxSize: '4.5 kB', compression: 'brotli', }, { path: './build/main.js', - maxSize: '3 kB', + maxSize: '3.5 kB', compression: 'brotli', }, ], diff --git a/index.html b/index.html index 81691d0..5d88bfc 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,8 @@ + + diff --git a/lib/DelayedEffect.tsx b/lib/DelayedEffect.tsx new file mode 100644 index 0000000..219fc1f --- /dev/null +++ b/lib/DelayedEffect.tsx @@ -0,0 +1,13 @@ +import { useEffect, type FC } from 'react'; + +/** + * Sometimes you want to run parent effects before those of the children. E.g. + when setting something up or binding document event listeners. By passing the + effect to the first child it will run before any effects by later children. + * @param {Function} effect + * @returns {null} + */ +export const DelayedEffect: FC<{ effect: () => void }> = ({ effect }) => { + useEffect(() => effect(), [effect]); + return null; +}; diff --git a/lib/Router.tsx b/lib/Router.tsx index 5a24131..2605eb1 100644 --- a/lib/Router.tsx +++ b/lib/Router.tsx @@ -1,91 +1,97 @@ import { createContext, useCallback, - useEffect, useReducer, - type Dispatch, + useRef, type FC, type PropsWithChildren, } from 'react'; +import { flushSync } from 'react-dom'; +import { DelayedEffect } from './DelayedEffect.js'; +import { + ActionType, + Direction, + currentEntryChangeEventName, + kCancelRecovery, + navigationEventName, + type Action, + type ContextInterface, + type State, + type SyntheticNavigateEventListener, +} from './State.js'; import { regexParamMatcher, type Matcher } from './matcher.js'; -import type { PartialWithUndefined, RestrictedURLProps } from './types.js'; import { - noop, nullOrigin, popStateEventName, urlObjectAssign, + withNavigation, withWindow, } from './util.js'; -export interface State { - url: URL; - matcher: Matcher; - hook?: PartialNavigateEventListener | undefined; - /** @private - discouraged, this is just an escape hatch */ - useNavigationApi: boolean; +function getDirection( + type: NavigationApiNavigationType | null, + from: NavigationHistoryEntry | null, + to: NavigationHistoryEntry, +) { + switch (type) { + case 'push': + return Direction.Forward; + case 'traverse': + if (!from || from.index === to.index) { + return Direction.Unknown; + } + return from.index < to.index ? Direction.Forward : Direction.Backward; + case 'reload': + case 'replace': + default: + return Direction.Unknown; + } } -export type ContextInterface = [State, Dispatch]; - -export type ActionInterface = Partial; - -export type PartialNavigateEvent = Pick< - NavigateEvent, - 'preventDefault' | 'signal' | 'type' | 'cancelable' ->; - -export type Destination = - | PartialWithUndefined - | URL - | string; - -export type NavigationMethodOptions = { history?: NavigationHistoryBehavior }; - -export type NavigationMethod = ( - href: Destination, - options?: NavigationMethodOptions, -) => void; - -type NavigateEventListener = (evt: NavigateEvent) => void; +function reducer(state: State, action: Action): State { + switch (action.type) { + case ActionType.Navigate: { + if ('dest' in action) { + // proper navigation update + const { dest, ...rest } = action; + const destUrl = new URL(dest); + return state.url.href !== destUrl.href + ? { + ...state, + direction: action.direction || state.direction, + url: destUrl, + ...rest, + } + : state; + } -// used so we can recognise the subsequent recovery navigation event that -// occurs after cancelling a navigation -const kCancelRecovery = Symbol('recover'); + // direction only + return { + ...state, + direction: action.direction, + }; + } + case ActionType.Hooks: { + const { type, ...hooks } = action; + return { ...state, ...hooks }; + } -function reducer(state: State, action: ActionInterface) { - return { ...state, ...action }; + default: + return state; + } } export const RouterContext = createContext(null); -export type PartialNavigateEventListener = ( - e: PartialNavigateEvent, -) => void | Promise; - -/** - * Sometimes you want to run parent effects before those of the children. E.g. - when setting something up or binding document event listeners. By passing the - effect to the first child it will run before any effects by later children. - * @param {Function} effect - * @returns null - */ -const DelayedEffect: FC<{ effect: () => void }> = ({ effect }) => { - useEffect(() => effect?.(), [effect]); - return null; -}; - export const Router: FC< PropsWithChildren<{ matcher?: Matcher; pathname?: string; search?: string; - hook?: PartialNavigateEventListener; - useNavigationApi?: boolean; + intercept?: SyntheticNavigateEventListener; + useNavApi?: false; // this can only ever be turned off }> -> = ({ children, pathname, search, useNavigationApi, ...props }) => { - const hasNav = - typeof navigation !== 'undefined' && useNavigationApi !== false; - +> = ({ children, pathname, search, useNavApi = true, ...props }) => { const [state, dispatch] = useReducer(reducer, { url: withWindow( ({ location }) => @@ -99,115 +105,195 @@ export const Router: FC< }), ), matcher: regexParamMatcher, - useNavigationApi: hasNav, + useNavApi, + direction: Direction.Unknown, ...props, }); - const setUrlOnlyIfChanged = useCallback( - (dest: string) => { - if (state.url.toString() !== dest) { - dispatch({ url: new URL(dest) }); + const navigationDirectionGuess = useRef(Direction.Unknown); + + const naviationApiChangeEventHandler = useCallback( + async (e: NavigationCurrentEntryChangeEvent) => { + if (navigation?.currentEntry) { + navigationDirectionGuess.current = getDirection( + e.navigationType || null, + e.from, + navigation.currentEntry, + ); } }, - [state.url], + [], ); - const { hook } = state; + const { intercept, change } = state; - const init = useCallback(() => { - // Navigation API - if (hasNav) { - const navigateEventHandler: NavigateEventListener = (e) => { - const currentUrl = navigation.currentEntry?.url; - - // Don't intercept fragment navigations or downloads. - if (e.hashChange || e.downloadRequest !== null) { - return; - } + const naviationApiNavigateEventHandler = useCallback( + (e: NavigateEvent) => { + if (typeof navigation === 'undefined') { + return; + } - // some urls for reference: - // Cancelling UI initiated navigations (back/forward) - https://github.com/WICG/navigation-api/issues/32 - // Cancelable traversals: avoiding a slowdown - https://github.com/WICG/navigation-api/issues/254 - const handler: NavigationInterceptHandler = async () => { - // we could also detect not user initiated, not cancellable etc - - if (hook && e.info !== kCancelRecovery) { - // WARN: `e` can be different after this is called - // especially if the user calls `preventDefault` - await hook({ - preventDefault: () => e.preventDefault(), - cancelable: e.cancelable, - signal: e.signal, - type: e.type, - }); - } + // Some navigations, e.g. cross-origin navigations, we cannot intercept. + // Let the browser handle those normally. + if (!e.canIntercept || e.defaultPrevented) { + return; + } - if (e.defaultPrevented && currentUrl) { - navigation.back({ - info: kCancelRecovery, - }); - } + // Don't intercept fragment navigations or downloads. + if (e.hashChange || e.downloadRequest !== null) { + return; + } - if (!e.defaultPrevented && !e.signal.aborted) { - setUrlOnlyIfChanged(e.destination.url); + // Some urls for reference: + // Cancelling UI initiated navigations (back/forward) - https://github.com/WICG/navigation-api/issues/32 + // Cancelable traversals: avoiding a slowdown - https://github.com/WICG/navigation-api/issues/254 + // TODO: we could also detect not user-initiated, not cancellable etc + e.intercept({ + // "manual" allows react to handle focus, without it, elements lose + // focus as the URL changes + focusReset: 'manual', + handler: async () => { + // hoisted destructure so we are all dealing with the same entry + const { currentEntry /* , activation */ } = navigation; + + // useless navigation + if (!currentEntry || !currentEntry.url) { + return; } - }; - - // Some navigations, e.g. cross-origin navigations, we cannot intercept. - // Let the browser handle those normally. - // as of Chrome 108, this works - if (e.canIntercept && !e.defaultPrevented) { - e.intercept?.({ - // "manual" allows react to handle focus, without it, elements lose - // focus as the URL changes - focusReset: 'manual', - handler, - }); - } - // as of Chrome 102, this seems to be the only thing that works - // as of Chrome 108, this no longer works - // else if (e.canTransition && e.transitionWhile) { - // e.transitionWhile(handler()); - // } - }; + const { url } = currentEntry; - const eventName = 'navigate'; + // a cancelled navigation + if (e.info === kCancelRecovery) { + dispatch({ + type: ActionType.Navigate, + dest: url, + }); + return; + } - navigation.addEventListener(eventName, navigateEventHandler); + const direction = navigationDirectionGuess.current; - // first trigger - // navigation.dispatchEvent(new Event(eventName)); + // direction state update which we will flush if we need to + // WARN: we cannot change the URL here as we flush the state update + // but we dont want the route to change yet. + dispatch({ + type: ActionType.Navigate, + direction, + }); - return () => { - navigation.removeEventListener( - eventName, - navigateEventHandler as EventListener, - ); - }; - } + const finish = async () => { + // if the event was cancelled, we need to go back to the previous + // this will trigger a navigate event again. + if (e.defaultPrevented) { + await navigation.back({ + info: kCancelRecovery, + }).finished; + return; + } + + // full state update which will trigger a re-render + dispatch({ + type: ActionType.Navigate, + dest: url, + direction, + }); + }; + + // this is the user intercept hook + if (intercept) { + // we need `intercept()` to have the absolute latest direction, so + // it gets flushed here. + + const promise = flushSync(async () => + // we always pass cleanup, but it may not get called. we check + // for that possibility below + Promise.resolve(intercept(e, finish)), + ); + + // intercepter is DEFINITELY NOT handling the `next` themselves, + // so we will await it + if (intercept.length === 1) { + await promise.then(finish); + } + } else { + finish(); + } + // eslint-disable-next-line no-useless-return + return; // WARN: `finish()` should be the last code running + }, + }); + }, + [intercept], + ); + + const popStateHandler = useCallback( + (e: PopStateEvent): void => { + if (typeof window !== 'undefined') { + if (!e.defaultPrevented) { + dispatch({ + type: ActionType.Navigate, + dest: window.location.href, + direction: Direction.Backward, // pop is always backwards + }); + } - return withWindow((w) => { - const navigateEventHandler = (e: PopStateEvent): void => { - if (hook) { - hook({ + // change hook + if (change) { + change({ preventDefault: e.preventDefault.bind(e), signal: new AbortController().signal, cancelable: e.cancelable, - type: 'push', + navigationType: 'traverse', // pop is always traverse }); } + } + }, + [change], + ); - setUrlOnlyIfChanged(w.location.href); - }; - - w.addEventListener(popStateEventName, navigateEventHandler); + const init = useCallback(() => { + if (useNavApi) { + withNavigation((n) => { + n.addEventListener( + currentEntryChangeEventName, + naviationApiChangeEventHandler, + ); + n.addEventListener( + navigationEventName, + naviationApiNavigateEventHandler, + ); + }); + } else { + withWindow((w) => { + w.addEventListener(popStateEventName, popStateHandler); + }); + } - return () => { - w.removeEventListener(popStateEventName, navigateEventHandler); - }; - }, noop); - }, [hasNav, hook, setUrlOnlyIfChanged]); + return () => { + if (useNavApi) { + withNavigation((n) => { + n.removeEventListener( + currentEntryChangeEventName, + naviationApiChangeEventHandler, + ); + n.removeEventListener( + navigationEventName, + naviationApiNavigateEventHandler, + ); + }); + } else { + withWindow((w) => { + w.removeEventListener(popStateEventName, popStateHandler); + }); + } + }; + }, [ + naviationApiChangeEventHandler, + naviationApiNavigateEventHandler, + popStateHandler, + useNavApi, + ]); return ( diff --git a/lib/State.tsx b/lib/State.tsx new file mode 100644 index 0000000..4247443 --- /dev/null +++ b/lib/State.tsx @@ -0,0 +1,79 @@ +import { type Dispatch } from 'react'; +import { type Matcher } from './matcher.js'; +import type { PartialWithUndefined, RestrictedURLProps } from './types.js'; + +export type EntryMeta = { + navigationType?: NavigationApiNavigationType | undefined; + navDirection?: Direction; +}; + +export type State = { + url: URL; + matcher: Matcher; + intercept?: SyntheticNavigateEventListener | undefined; + change?: SyntheticChangeEventListener | undefined; + direction: Direction; + + /** @deprecated this was just an escape hatch avoid the navigation API */ + useNavApi: boolean; +}; + +export type ContextInterface = [State, Dispatch]; + +export const enum ActionType { + Hooks, + Navigate, +} + +export const enum Direction { + Backward = -1, + Unknown, + Forward, +} + +export type Action = + | { + type: ActionType.Navigate; + direction: Direction; + } + | { + type: ActionType.Navigate; + dest: string; + direction?: Direction; + } + | ({ type: ActionType.Hooks } & Pick); + +export type SyntheticNavigateEvent = Pick< + NavigateEvent, + 'preventDefault' | 'signal' | 'navigationType' | 'cancelable' +>; + +export type Destination = + | PartialWithUndefined + | URL + | string; + +export type NavigationMethodOptions = { history?: NavigationHistoryBehavior }; + +export type NavigationMethod = ( + href: Destination, + options?: NavigationMethodOptions, +) => void; + +export type SyntheticNavigateEventListener = + | (( + e: SyntheticNavigateEvent, + next: () => Promise, + ) => void | Promise) + | ((e: SyntheticNavigateEvent) => void | Promise); + +export type SyntheticChangeEventListener = ( + e: SyntheticNavigateEvent, +) => void | Promise; + +// used so we can recognise the subsequent recovery navigation event that +// occurs after cancelling a navigation +export const kCancelRecovery = Symbol('kCancelRecovery'); + +export const navigationEventName = 'navigate'; +export const currentEntryChangeEventName = 'currententrychange'; diff --git a/lib/animate.ts b/lib/animate.ts index fa33179..2a90698 100644 --- a/lib/animate.ts +++ b/lib/animate.ts @@ -1,23 +1,18 @@ import { flushSync } from 'react-dom'; export function startViewTransition( - updateCallback: () => Promise | unknown, - withFlush = true, + updateCallback: () => Promise | unknown, // allowing any return type makes calling easier ): ViewTransition { if (document?.startViewTransition) { return document.startViewTransition(async () => { - if (withFlush) { - await flushSync(updateCallback); - } else { - await updateCallback(); - } + // https://developer.chrome.com/docs/web-platform/view-transitions/same-document#working_with_frameworks + await flushSync(updateCallback); }); } + // VTA not supported, run it immediately. updateCallback(); - const resolved = Promise.resolve(); - return { ready: resolved, finished: resolved, diff --git a/lib/components/Link.tsx b/lib/components/Link.tsx index 13c1d92..070521c 100644 --- a/lib/components/Link.tsx +++ b/lib/components/Link.tsx @@ -10,7 +10,7 @@ import { type MouseEvent, type PropsWithChildren, } from 'react'; -import { type Destination, type NavigationMethodOptions } from '../Router.js'; +import { type Destination, type NavigationMethodOptions } from '../State.js'; import { useLocation, useRouter } from '../use-router.js'; import { calculateUrl, nullOrigin, urlRhs } from '../util.js'; @@ -30,8 +30,8 @@ export const Link = forwardRef< // eslint-disable-next-line prefer-arrow-callback >(function Link({ children, href, onClick, history, ...props }, ref) { const [url, { navigate }] = useLocation(); - const [{ useNavigationApi }] = useRouter(); - const hasNav = useNavigationApi; + const [{ useNavApi }] = useRouter(); + const hasNav = useNavApi; const isStringDest = typeof href === 'string'; diff --git a/lib/components/Redirect.tsx b/lib/components/Redirect.tsx index b1e514b..ad013bb 100644 --- a/lib/components/Redirect.tsx +++ b/lib/components/Redirect.tsx @@ -1,5 +1,5 @@ import { type FC, type PropsWithChildren, useLayoutEffect } from 'react'; -import { type Destination, type NavigationMethodOptions } from '../Router.js'; +import { type Destination, type NavigationMethodOptions } from '../State.js'; import { useLocation } from '../use-router.js'; export const Redirect: FC< @@ -13,7 +13,7 @@ export const Redirect: FC< useLayoutEffect(() => { navigate(href, history && { history }); - }, [href, history, navigate]); + }, [history, href, navigate]); return <>{children}; }; diff --git a/lib/dom.d.ts b/lib/dom.d.ts index d93a6c3..191af60 100644 --- a/lib/dom.d.ts +++ b/lib/dom.d.ts @@ -33,6 +33,18 @@ declare global { value: string; } + interface Navigation { + // this is bleeding edge! + // https://github.com/whatwg/html/pull/9856 + // https://github.com/mdn/mdn/issues/491 + activation: { + // The current entry is the entry that is currently being navigated to. + from: NavigationHistoryEntry | null; + entry: NavigationHistoryEntry | null; + navigationType: NavigationApiNavigationType; + }; + } + interface Window { navigation: Navigation | undefined; location: Location; diff --git a/lib/hooks.ts b/lib/hooks.ts index 1b9b45e..9317c91 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -28,6 +28,10 @@ export function useHashParam(value: string) { return useHashAsParams().get(value); } +/** + * @deprecated + * @use navigation API and intercept hook + */ export function usePreventUnload( cb: boolean | ((e: BeforeUnloadEvent) => boolean), ) { diff --git a/lib/use-router.ts b/lib/use-router.ts index 7338da7..2c62116 100644 --- a/lib/use-router.ts +++ b/lib/use-router.ts @@ -1,8 +1,24 @@ import { useCallback, useContext } from 'react'; -import { RouterContext, type Destination } from './Router.js'; +import { RouterContext } from './Router.js'; +import { + ActionType, + type Destination, + type SyntheticNavigateEventListener, +} from './State.js'; import { type PartialWithUndefined, type RestrictedURLProps } from './types.js'; import { calculateUrl, popStateEventName, urlRhs, withWindow } from './util.js'; +type SyntheticNavigationResult = { + committed: Promise; + finished: Promise; +}; + +const resolved = Promise.resolve(); +const syntheticNavigationResult = { + committed: resolved, + finished: resolved, +}; + export function useRouter() { const state = useContext(RouterContext); if (!state) { @@ -11,40 +27,43 @@ export function useRouter() { return state; } -export function useHook() { +export function useRouterIntercept() { const [, dispatch] = useRouter(); - return dispatch; -} -type FakeNavigationResult = { - committed: Promise; - finished: Promise; -}; + return useCallback( + (listener: SyntheticNavigateEventListener) => { + dispatch({ + type: ActionType.Hooks, + intercept: listener, + }); -const resolved = Promise.resolve(); -const fakeNavigationResult = { - committed: resolved, - finished: resolved, -}; + return () => { + dispatch({ type: ActionType.Hooks, intercept: undefined }); + }; + }, + [dispatch], + ); +} export function useLocation() { - const [{ url, useNavigationApi }] = useRouter(); - const hasNav = - typeof navigation !== 'undefined' && useNavigationApi !== false; + const [{ url, useNavApi }] = useRouter(); + const hasNav = typeof navigation !== 'undefined' && useNavApi !== false; const navigate = useCallback( ( href: PartialWithUndefined | URL | string, options?: { history?: NavigationHistoryBehavior }, - ): NavigationResult | FakeNavigationResult => { + ): NavigationResult | SyntheticNavigationResult => { const nextUrl = calculateUrl(href, url); + // nav api if (hasNav) { return navigation.navigate(nextUrl.toString(), { ...(options?.history && { history: options.history }), }); } + // window return withWindow(({ history }) => { // we can only use push/replaceState for same origin if (nextUrl.origin === url.origin) { @@ -62,8 +81,8 @@ export function useLocation() { window?.location.assign(nextUrl); } - return fakeNavigationResult; - }, fakeNavigationResult); + return syntheticNavigationResult; + }, syntheticNavigationResult); }, [hasNav, url], ); @@ -71,7 +90,7 @@ export function useLocation() { const back = useCallback( async ( alternateHref?: Destination, - ): Promise => { + ): Promise => { if (hasNav) { if (navigation.entries()?.length > 0) { return navigation.back(); @@ -85,7 +104,7 @@ export function useLocation() { return navigation.back(); } window?.history.back(); - return fakeNavigationResult; + return syntheticNavigationResult; }, [hasNav, navigate], ); diff --git a/lib/util.ts b/lib/util.ts index ce9e1c8..1ccb87a 100644 --- a/lib/util.ts +++ b/lib/util.ts @@ -5,31 +5,13 @@ import { type ComponentProps, type ReactNode, } from 'react'; -import type { Destination } from './Router.js'; +import type { Destination } from './State.js'; import type { PartialWithUndefined, URLProps } from './types.js'; export const nullOrigin = new URL('https://0'); -export function noop() {} -export async function pnoop() { - // -} - export const popStateEventName = 'popstate'; -export class Deferred { - public promise: Promise; - - public resolve: (value: T | PromiseLike) => void; - - constructor() { - this.resolve = noop; - this.promise = new Promise((resolve) => { - this.resolve = resolve; - }); - } -} - export function withWindow(a: (window: Window) => A): A | undefined; export function withWindow(a: (window: Window) => A, b: B): A | B; export function withWindow( @@ -39,13 +21,18 @@ export function withWindow( return typeof window !== 'undefined' ? a(window) : b; } -export function withDocument(a: (document: Document) => A): A | undefined; -export function withDocument(a: (document: Document) => A, b: B): A | B; -export function withDocument( - a: (document: Document) => A, +export function withNavigation( + a: (navigation: Navigation) => A, +): A | undefined; +export function withNavigation( + a: (navigation: Navigation) => A, + b: B, +): A | B; +export function withNavigation( + a: (navigation: Navigation) => A, b?: B, ): A | B | undefined { - return typeof document !== 'undefined' ? a(document) : b; + return withWindow((w) => (w.navigation ? a(w.navigation) : b), b); } export function urlRhs(url: URL): string { diff --git a/package.json b/package.json index de8d9be..ee43d0d 100644 --- a/package.json +++ b/package.json @@ -39,24 +39,26 @@ "last 2 iOS major versions" ], "dependencies": { + "@types/dom-view-transitions": "^1.0.4", + "navigation-api-types": "^0.5.1", "regexparam": "^3.0.0" }, "devDependencies": { "@block65/bundlesize": "^1.0.1", "@block65/eslint-config": "^12.0.1", - "@block65/react-design-system": "0.32.0", + "@block65/react-design-system": "0.33.0", "@testing-library/dom": "^10.1.0", "@testing-library/jest-dom": "^6.4.5", - "@testing-library/react": "^15.0.7", + "@testing-library/react": "^16.0.0", "@tsconfig/strictest": "^2.0.5", "@tsconfig/vite-react": "^3.0.2", "@types/dom-view-transitions": "^1.0.4", "@types/jest": "^29.5.12", - "@types/node": "^20.14.0", + "@types/node": "^20.14.2", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.11.0", - "@typescript-eslint/parser": "^7.11.0", + "@typescript-eslint/eslint-plugin": "^7.12.0", + "@typescript-eslint/parser": "^7.12.0", "@vitejs/plugin-react": "^4.3.0", "eslint": "^8.57.0", "eslint-plugin-formatjs": "^4.13.3", @@ -69,13 +71,14 @@ "framer-motion": "^11.2.10", "jsdom": "^24.1.0", "navigation-api-types": "^0.5.1", - "prettier": "^3.3.0", + "prettier": "^3.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-intl": "^6.6.8", + "sass": "^1.77.4", "the-new-css-reset": "^1.11.2", "typescript": "^5.4.5", - "vite": "^5.2.12", + "vite": "^5.2.13", "vitest": "^1.6.0" }, "peerDependencies": { @@ -84,8 +87,8 @@ "react": "^18.3.1", "react-dom": "^18.3.1" }, + "packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0", "engines": { "node": ">=20.0.0" - }, - "packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5f0887..c474762 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@types/dom-view-transitions': + specifier: ^1.0.4 + version: 1.0.4 + navigation-api-types: + specifier: ^0.5.1 + version: 0.5.1 regexparam: specifier: ^3.0.0 version: 3.0.0 @@ -17,34 +23,31 @@ importers: version: 1.0.1(typescript@5.4.5) '@block65/eslint-config': specifier: ^12.0.1 - version: 12.0.1(@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-formatjs@4.13.3(eslint@8.57.0))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react-refresh@0.4.7(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.0)(typescript@5.4.5) + version: 12.0.1(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-formatjs@4.13.3(eslint@8.57.0))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react-refresh@0.4.7(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1)(typescript@5.4.5) '@block65/react-design-system': - specifier: 0.32.0 - version: 0.32.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.33.0 + version: 0.33.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react-intl@6.6.8(react@18.3.1)(typescript@5.4.5))(react@18.3.1) '@testing-library/dom': specifier: ^10.1.0 version: 10.1.0 '@testing-library/jest-dom': specifier: ^6.4.5 - version: 6.4.5(@types/jest@29.5.12)(vitest@1.6.0(@types/node@20.14.0)(jsdom@24.1.0)) + version: 6.4.5(@types/jest@29.5.12)(vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0)(sass@1.77.4)) '@testing-library/react': - specifier: ^15.0.7 - version: 15.0.7(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^16.0.0 + version: 16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tsconfig/strictest': specifier: ^2.0.5 version: 2.0.5 '@tsconfig/vite-react': specifier: ^3.0.2 version: 3.0.2 - '@types/dom-view-transitions': - specifier: ^1.0.4 - version: 1.0.4 '@types/jest': specifier: ^29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.0 - version: 20.14.0 + specifier: ^20.14.2 + version: 20.14.2 '@types/react': specifier: ^18.3.3 version: 18.3.3 @@ -52,14 +55,14 @@ importers: specifier: ^18.3.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': - specifier: ^7.11.0 - version: 7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.12.0 + version: 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': - specifier: ^7.11.0 - version: 7.11.0(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.12.0 + version: 7.12.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-react': specifier: ^4.3.0 - version: 4.3.0(vite@5.2.12(@types/node@20.14.0)) + version: 4.3.0(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -68,13 +71,13 @@ importers: version: 4.13.3(eslint@8.57.0) eslint-plugin-import: specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) eslint-plugin-jsx-a11y: specifier: ^6.8.0 version: 6.8.0(eslint@8.57.0) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.0) + version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1) eslint-plugin-react: specifier: ^7.34.2 version: 7.34.2(eslint@8.57.0) @@ -90,12 +93,9 @@ importers: jsdom: specifier: ^24.1.0 version: 24.1.0 - navigation-api-types: - specifier: ^0.5.1 - version: 0.5.1 prettier: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^3.3.1 + version: 3.3.1 react: specifier: ^18.3.1 version: 18.3.1 @@ -105,6 +105,9 @@ importers: react-intl: specifier: ^6.6.8 version: 6.6.8(react@18.3.1)(typescript@5.4.5) + sass: + specifier: ^1.77.4 + version: 1.77.4 the-new-css-reset: specifier: ^1.11.2 version: 1.11.2 @@ -112,126 +115,126 @@ importers: specifier: ^5.4.5 version: 5.4.5 vite: - specifier: ^5.2.12 - version: 5.2.12(@types/node@20.14.0) + specifier: ^5.2.13 + version: 5.2.13(@types/node@20.14.2)(sass@1.77.4) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@20.14.0)(jsdom@24.1.0) + version: 1.6.0(@types/node@20.14.2)(jsdom@24.1.0)(sass@1.77.4) packages: - '@adobe/css-tools@4.3.3': - resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} + '@adobe/css-tools@4.4.0': + resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/code-frame@7.24.6': - resolution: {integrity: sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.24.6': - resolution: {integrity: sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==} + '@babel/compat-data@7.24.7': + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} engines: {node: '>=6.9.0'} - '@babel/core@7.24.6': - resolution: {integrity: sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==} + '@babel/core@7.24.7': + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} engines: {node: '>=6.9.0'} - '@babel/generator@7.24.6': - resolution: {integrity: sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==} + '@babel/generator@7.24.7': + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.24.6': - resolution: {integrity: sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==} + '@babel/helper-compilation-targets@7.24.7': + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.24.6': - resolution: {integrity: sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==} + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.24.6': - resolution: {integrity: sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==} + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.24.6': - resolution: {integrity: sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==} + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.6': - resolution: {integrity: sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==} + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.24.6': - resolution: {integrity: sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==} + '@babel/helper-module-transforms@7.24.7': + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.24.6': - resolution: {integrity: sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==} + '@babel/helper-plugin-utils@7.24.7': + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} engines: {node: '>=6.9.0'} - '@babel/helper-simple-access@7.24.6': - resolution: {integrity: sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==} + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.24.6': - resolution: {integrity: sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.6': - resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.6': - resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.24.6': - resolution: {integrity: sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==} + '@babel/helper-validator-option@7.24.7': + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.24.6': - resolution: {integrity: sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==} + '@babel/helpers@7.24.7': + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.6': - resolution: {integrity: sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.24.6': - resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.24.6': - resolution: {integrity: sha512-FfZfHXtQ5jYPQsCRyLpOv2GeLIIJhs8aydpNh39vRDjhD411XcfWDni5i7OjP/Rs8GAtTn7sWFFELJSHqkIxYg==} + '@babel/plugin-transform-react-jsx-self@7.24.7': + resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.24.6': - resolution: {integrity: sha512-BQTBCXmFRreU3oTUXcGKuPOfXAGb1liNY4AvvFKsOBAJ89RKcTsIrSsnMYkj59fNa66OFKnSa4AJZfy5Y4B9WA==} + '@babel/plugin-transform-react-jsx-source@7.24.7': + resolution: {integrity: sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.24.6': - resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==} + '@babel/runtime@7.24.7': + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} engines: {node: '>=6.9.0'} - '@babel/template@7.24.6': - resolution: {integrity: sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==} + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.6': - resolution: {integrity: sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==} + '@babel/traverse@7.24.7': + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} engines: {node: '>=6.9.0'} - '@babel/types@7.24.6': - resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} engines: {node: '>=6.9.0'} '@block65/bundlesize@1.0.1': @@ -269,14 +272,17 @@ packages: eslint-plugin-unicorn: optional: true - '@block65/react-design-system@0.32.0': - resolution: {integrity: sha512-HikrhPRVYYCAkF5wLbY9HvecUxH0iPCo4/FHPFcLSZi9byeZCeFQBA/hxRGk9PGLiTC9lE+yoh3KOTuUNkk3WQ==} - engines: {node: '>=16.0.0'} + '@block65/react-design-system@0.33.0': + resolution: {integrity: sha512-WUPBLbOREqZQPxRcXYyOW4G+sfQ9YW1D7vMhpE9SwtSyc1AiCI29rja4ZWbrX4vGJlBtr+3EbqWHqYGMGjdHig==} peerDependencies: - '@types/react': ^18.2.36 - '@types/react-dom': ^18.2.14 + '@types/react': ^18.2.37 + '@types/react-dom': ^18.2.15 react: ^18.2.0 react-dom: ^18.2.0 + react-intl: ^6.5.5 + peerDependenciesMeta: + react-intl: + optional: true '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} @@ -422,8 +428,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': @@ -665,16 +671,20 @@ packages: vitest: optional: true - '@testing-library/react@15.0.7': - resolution: {integrity: sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==} + '@testing-library/react@16.0.0': + resolution: {integrity: sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==} engines: {node: '>=18'} peerDependencies: + '@testing-library/dom': ^10.0.0 '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 peerDependenciesMeta: '@types/react': optional: true + '@types/react-dom': + optional: true '@tsconfig/strictest@2.0.5': resolution: {integrity: sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==} @@ -733,8 +743,8 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@20.14.0': - resolution: {integrity: sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==} + '@types/node@20.14.2': + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} '@types/picomatch@2.3.3': resolution: {integrity: sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg==} @@ -760,8 +770,8 @@ packages: '@types/yargs@17.0.32': resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} - '@typescript-eslint/eslint-plugin@7.11.0': - resolution: {integrity: sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==} + '@typescript-eslint/eslint-plugin@7.12.0': + resolution: {integrity: sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -771,8 +781,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.11.0': - resolution: {integrity: sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==} + '@typescript-eslint/parser@7.12.0': + resolution: {integrity: sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -785,12 +795,12 @@ packages: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/scope-manager@7.11.0': - resolution: {integrity: sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==} + '@typescript-eslint/scope-manager@7.12.0': + resolution: {integrity: sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.11.0': - resolution: {integrity: sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==} + '@typescript-eslint/type-utils@7.12.0': + resolution: {integrity: sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -803,8 +813,8 @@ packages: resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/types@7.11.0': - resolution: {integrity: sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==} + '@typescript-eslint/types@7.12.0': + resolution: {integrity: sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==} engines: {node: ^18.18.0 || >=20.0.0} '@typescript-eslint/typescript-estree@6.21.0': @@ -816,8 +826,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@7.11.0': - resolution: {integrity: sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==} + '@typescript-eslint/typescript-estree@7.12.0': + resolution: {integrity: sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -831,8 +841,8 @@ packages: peerDependencies: eslint: ^7.0.0 || ^8.0.0 - '@typescript-eslint/utils@7.11.0': - resolution: {integrity: sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==} + '@typescript-eslint/utils@7.12.0': + resolution: {integrity: sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -841,8 +851,8 @@ packages: resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/visitor-keys@7.11.0': - resolution: {integrity: sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==} + '@typescript-eslint/visitor-keys@7.12.0': + resolution: {integrity: sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==} engines: {node: ^18.18.0 || >=20.0.0} '@ungap/structured-clone@1.2.0': @@ -890,8 +900,8 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.14.0: - resolution: {integrity: sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==} + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -917,6 +927,10 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -985,6 +999,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1012,8 +1030,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001627: - resolution: {integrity: sha512-4zgNiB8nTyV/tHhwZrFs88ryjls/lHiqFhrxCW4qSTeuRByBVnPYpDInchOIySWknznucaf31Z4KYqjfbrecVw==} + caniuse-lite@1.0.30001629: + resolution: {integrity: sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==} chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} @@ -1034,6 +1052,10 @@ packages: check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -1136,8 +1158,8 @@ packages: decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} deep-is@0.1.4: @@ -1184,8 +1206,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.4.788: - resolution: {integrity: sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA==} + electron-to-chromium@1.4.796: + resolution: {integrity: sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==} emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} @@ -1196,8 +1218,8 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enhanced-resolve@5.16.1: - resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==} + enhanced-resolve@5.17.0: + resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -1618,6 +1640,9 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} + immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -1658,6 +1683,10 @@ packages: is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} @@ -1767,8 +1796,8 @@ packages: iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} - jackspeak@3.1.2: - resolution: {integrity: sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==} + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} engines: {node: '>=14'} jest-diff@29.7.0: @@ -1951,8 +1980,8 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - mlly@1.7.0: - resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -1974,6 +2003,10 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2109,8 +2142,8 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@3.3.0: - resolution: {integrity: sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==} + prettier@3.3.1: + resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==} engines: {node: '>=14'} hasBin: true @@ -2173,6 +2206,10 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -2248,6 +2285,11 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sass@1.77.4: + resolution: {integrity: sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==} + engines: {node: '>=14.0.0'} + hasBin: true + saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -2430,6 +2472,9 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -2496,8 +2541,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.2.12: - resolution: {integrity: sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==} + vite@5.2.13: + resolution: {integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2641,32 +2686,32 @@ packages: snapshots: - '@adobe/css-tools@4.3.3': {} + '@adobe/css-tools@4.4.0': {} '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@babel/code-frame@7.24.6': + '@babel/code-frame@7.24.7': dependencies: - '@babel/highlight': 7.24.6 + '@babel/highlight': 7.24.7 picocolors: 1.0.1 - '@babel/compat-data@7.24.6': {} + '@babel/compat-data@7.24.7': {} - '@babel/core@7.24.6': + '@babel/core@7.24.7': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.6 - '@babel/generator': 7.24.6 - '@babel/helper-compilation-targets': 7.24.6 - '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.6) - '@babel/helpers': 7.24.6 - '@babel/parser': 7.24.6 - '@babel/template': 7.24.6 - '@babel/traverse': 7.24.6 - '@babel/types': 7.24.6 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 convert-source-map: 2.0.0 debug: 4.3.5 gensync: 1.0.0-beta.2 @@ -2675,121 +2720,131 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.24.6': + '@babel/generator@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/helper-compilation-targets@7.24.6': + '@babel/helper-compilation-targets@7.24.7': dependencies: - '@babel/compat-data': 7.24.6 - '@babel/helper-validator-option': 7.24.6 + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.24.6': {} + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.7 - '@babel/helper-function-name@7.24.6': + '@babel/helper-function-name@7.24.7': dependencies: - '@babel/template': 7.24.6 - '@babel/types': 7.24.6 + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 - '@babel/helper-hoist-variables@7.24.6': + '@babel/helper-hoist-variables@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 - '@babel/helper-module-imports@7.24.6': + '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-module-transforms@7.24.6(@babel/core@7.24.6)': + '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.6 - '@babel/helper-environment-visitor': 7.24.6 - '@babel/helper-module-imports': 7.24.6 - '@babel/helper-simple-access': 7.24.6 - '@babel/helper-split-export-declaration': 7.24.6 - '@babel/helper-validator-identifier': 7.24.6 + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-plugin-utils@7.24.6': {} + '@babel/helper-plugin-utils@7.24.7': {} - '@babel/helper-simple-access@7.24.6': + '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-split-export-declaration@7.24.6': + '@babel/helper-split-export-declaration@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 - '@babel/helper-string-parser@7.24.6': {} + '@babel/helper-string-parser@7.24.7': {} - '@babel/helper-validator-identifier@7.24.6': {} + '@babel/helper-validator-identifier@7.24.7': {} - '@babel/helper-validator-option@7.24.6': {} + '@babel/helper-validator-option@7.24.7': {} - '@babel/helpers@7.24.6': + '@babel/helpers@7.24.7': dependencies: - '@babel/template': 7.24.6 - '@babel/types': 7.24.6 + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 - '@babel/highlight@7.24.6': + '@babel/highlight@7.24.7': dependencies: - '@babel/helper-validator-identifier': 7.24.6 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/parser@7.24.6': + '@babel/parser@7.24.7': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 - '@babel/plugin-transform-react-jsx-self@7.24.6(@babel/core@7.24.6)': + '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.6 - '@babel/helper-plugin-utils': 7.24.6 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-react-jsx-source@7.24.6(@babel/core@7.24.6)': + '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.6 - '@babel/helper-plugin-utils': 7.24.6 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/runtime@7.24.6': + '@babel/runtime@7.24.7': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.24.6': + '@babel/template@7.24.7': dependencies: - '@babel/code-frame': 7.24.6 - '@babel/parser': 7.24.6 - '@babel/types': 7.24.6 + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 - '@babel/traverse@7.24.6': + '@babel/traverse@7.24.7': dependencies: - '@babel/code-frame': 7.24.6 - '@babel/generator': 7.24.6 - '@babel/helper-environment-visitor': 7.24.6 - '@babel/helper-function-name': 7.24.6 - '@babel/helper-hoist-variables': 7.24.6 - '@babel/helper-split-export-declaration': 7.24.6 - '@babel/parser': 7.24.6 - '@babel/types': 7.24.6 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 debug: 4.3.5 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.24.6': + '@babel/types@7.24.7': dependencies: - '@babel/helper-string-parser': 7.24.6 - '@babel/helper-validator-identifier': 7.24.6 + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 '@block65/bundlesize@1.0.1(typescript@5.4.5)': dependencies: - ajv: 8.14.0 + ajv: 8.16.0 colorette: 2.0.20 cosmiconfig: 8.3.6(typescript@5.4.5) glob: 10.4.1 @@ -2797,18 +2852,18 @@ snapshots: transitivePeerDependencies: - typescript - '@block65/eslint-config@12.0.1(@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-formatjs@4.13.3(eslint@8.57.0))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react-refresh@0.4.7(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.0)(typescript@5.4.5)': + '@block65/eslint-config@12.0.1(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-formatjs@4.13.3(eslint@8.57.0))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react-refresh@0.4.7(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1)(typescript@5.4.5)': dependencies: - '@typescript-eslint/eslint-plugin': 7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-config-airbnb-typescript: 18.0.0(@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-typescript: 18.0.0(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) - prettier: 3.3.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + prettier: 3.3.1 typescript: 5.4.5 optionalDependencies: eslint-plugin-formatjs: 4.13.3(eslint@8.57.0) @@ -2821,7 +2876,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - '@block65/react-design-system@0.32.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@block65/react-design-system@0.33.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react-intl@6.6.8(react@18.3.1)(typescript@5.4.5))(react@18.3.1)': dependencies: '@floating-ui/dom': 1.6.5 '@floating-ui/react': 0.26.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2832,6 +2887,8 @@ snapshots: js-cookie: 3.0.5 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + react-intl: 6.6.8(react@18.3.1)(typescript@5.4.5) '@esbuild/aix-ppc64@0.20.2': optional: true @@ -2907,7 +2964,7 @@ snapshots: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/regexpp@4.10.1': {} '@eslint/eslintrc@2.1.4': dependencies: @@ -2953,11 +3010,11 @@ snapshots: '@formatjs/ecma402-abstract@2.0.0': dependencies: '@formatjs/intl-localematcher': 0.5.4 - tslib: 2.6.2 + tslib: 2.6.3 '@formatjs/fast-memoize@2.2.0': dependencies: - tslib: 2.6.2 + tslib: 2.6.3 '@formatjs/icu-messageformat-parser@2.7.8': dependencies: @@ -2974,17 +3031,17 @@ snapshots: dependencies: '@formatjs/ecma402-abstract': 2.0.0 '@formatjs/intl-localematcher': 0.5.4 - tslib: 2.6.2 + tslib: 2.6.3 '@formatjs/intl-listformat@7.5.7': dependencies: '@formatjs/ecma402-abstract': 2.0.0 '@formatjs/intl-localematcher': 0.5.4 - tslib: 2.6.2 + tslib: 2.6.3 '@formatjs/intl-localematcher@0.5.4': dependencies: - tslib: 2.6.2 + tslib: 2.6.3 '@formatjs/intl@2.10.4(typescript@5.4.5)': dependencies: @@ -2994,7 +3051,7 @@ snapshots: '@formatjs/intl-displaynames': 6.6.8 '@formatjs/intl-listformat': 7.5.7 intl-messageformat: 10.5.14 - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: typescript: 5.4.5 @@ -3042,7 +3099,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.14.0 + '@types/node': 20.14.2 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -3132,8 +3189,8 @@ snapshots: '@testing-library/dom@10.1.0': dependencies: - '@babel/code-frame': 7.24.6 - '@babel/runtime': 7.24.6 + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.24.7 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -3141,10 +3198,10 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.5(@types/jest@29.5.12)(vitest@1.6.0(@types/node@20.14.0)(jsdom@24.1.0))': + '@testing-library/jest-dom@6.4.5(@types/jest@29.5.12)(vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0)(sass@1.77.4))': dependencies: - '@adobe/css-tools': 4.3.3 - '@babel/runtime': 7.24.6 + '@adobe/css-tools': 4.4.0 + '@babel/runtime': 7.24.7 aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 @@ -3153,17 +3210,17 @@ snapshots: redent: 3.0.0 optionalDependencies: '@types/jest': 29.5.12 - vitest: 1.6.0(@types/node@20.14.0)(jsdom@24.1.0) + vitest: 1.6.0(@types/node@20.14.2)(jsdom@24.1.0)(sass@1.77.4) - '@testing-library/react@15.0.7(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.24.7 '@testing-library/dom': 10.1.0 - '@types/react-dom': 18.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 '@tsconfig/strictest@2.0.5': {} @@ -3173,24 +3230,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.6 - '@babel/types': 7.24.6 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.6 - '@babel/types': 7.24.6 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.6 + '@babel/types': 7.24.7 '@types/dom-view-transitions@1.0.4': {} @@ -3229,7 +3286,7 @@ snapshots: '@types/node@17.0.45': {} - '@types/node@20.14.0': + '@types/node@20.14.2': dependencies: undici-types: 5.26.5 @@ -3256,14 +3313,14 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/type-utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.11.0 + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/type-utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.12.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -3274,12 +3331,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.11.0 + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.12.0 debug: 4.3.5 eslint: 8.57.0 optionalDependencies: @@ -3292,15 +3349,15 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/scope-manager@7.11.0': + '@typescript-eslint/scope-manager@7.12.0': dependencies: - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/visitor-keys': 7.11.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/visitor-keys': 7.12.0 - '@typescript-eslint/type-utils@7.11.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.12.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5) debug: 4.3.5 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) @@ -3311,7 +3368,7 @@ snapshots: '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/types@7.11.0': {} + '@typescript-eslint/types@7.12.0': {} '@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.5)': dependencies: @@ -3328,10 +3385,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.11.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.12.0(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/visitor-keys': 7.11.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/visitor-keys': 7.12.0 debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 @@ -3357,12 +3414,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.11.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.12.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -3373,21 +3430,21 @@ snapshots: '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@7.11.0': + '@typescript-eslint/visitor-keys@7.12.0': dependencies: - '@typescript-eslint/types': 7.11.0 + '@typescript-eslint/types': 7.12.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react@4.3.0(vite@5.2.12(@types/node@20.14.0))': + '@vitejs/plugin-react@4.3.0(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))': dependencies: - '@babel/core': 7.24.6 - '@babel/plugin-transform-react-jsx-self': 7.24.6(@babel/core@7.24.6) - '@babel/plugin-transform-react-jsx-source': 7.24.6(@babel/core@7.24.6) + '@babel/core': 7.24.7 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.2.12(@types/node@20.14.0) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) transitivePeerDependencies: - supports-color @@ -3441,7 +3498,7 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.14.0: + ajv@8.16.0: dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 @@ -3464,6 +3521,11 @@ snapshots: ansi-styles@6.2.1: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + argparse@2.0.1: {} aria-query@5.3.0: @@ -3562,6 +3624,8 @@ snapshots: balanced-match@1.0.2: {} + binary-extensions@2.3.0: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -3577,8 +3641,8 @@ snapshots: browserslist@4.23.0: dependencies: - caniuse-lite: 1.0.30001627 - electron-to-chromium: 1.4.788 + caniuse-lite: 1.0.30001629 + electron-to-chromium: 1.4.796 node-releases: 2.0.14 update-browserslist-db: 1.0.16(browserslist@4.23.0) @@ -3594,13 +3658,13 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001627: {} + caniuse-lite@1.0.30001629: {} chai@4.4.1: dependencies: assertion-error: 1.1.0 check-error: 1.0.3 - deep-eql: 4.1.3 + deep-eql: 4.1.4 get-func-name: 2.0.2 loupe: 2.3.7 pathval: 1.1.1 @@ -3626,6 +3690,18 @@ snapshots: dependencies: get-func-name: 2.0.2 + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + ci-info@3.9.0: {} clsx@2.1.1: {} @@ -3714,7 +3790,7 @@ snapshots: decimal.js@10.4.3: {} - deep-eql@4.1.3: + deep-eql@4.1.4: dependencies: type-detect: 4.0.8 @@ -3756,7 +3832,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.4.788: {} + electron-to-chromium@1.4.796: {} emoji-regex@10.3.0: {} @@ -3764,7 +3840,7 @@ snapshots: emoji-regex@9.2.2: {} - enhanced-resolve@5.16.1: + enhanced-resolve@5.17.0: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -3901,29 +3977,29 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/eslint-plugin': 7.11.0(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): dependencies: eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -3942,13 +4018,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 4.3.5 - enhanced-resolve: 5.16.1 + enhanced-resolve: 5.17.0 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -3959,23 +4035,23 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -3997,7 +4073,7 @@ snapshots: - supports-color - ts-jest - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -4007,7 +4083,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -4018,7 +4094,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -4026,7 +4102,7 @@ snapshots: eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.24.7 aria-query: 5.3.0 array-includes: 3.1.8 array.prototype.flatmap: 1.3.2 @@ -4044,10 +4120,10 @@ snapshots: object.entries: 1.1.8 object.fromentries: 2.0.8 - eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.0): + eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1): dependencies: eslint: 8.57.0 - prettier: 3.3.0 + prettier: 3.3.1 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 optionalDependencies: @@ -4094,7 +4170,7 @@ snapshots: eslint@8.57.0: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.0 + '@eslint-community/regexpp': 4.10.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 @@ -4234,7 +4310,7 @@ snapshots: framer-motion@11.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -4290,7 +4366,7 @@ snapshots: glob@10.4.1: dependencies: foreground-child: 3.1.1 - jackspeak: 3.1.2 + jackspeak: 3.4.0 minimatch: 9.0.4 minipass: 7.1.2 path-scurry: 1.11.1 @@ -4384,6 +4460,8 @@ snapshots: ignore@5.3.1: {} + immutable@4.3.6: {} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -4411,7 +4489,7 @@ snapshots: '@formatjs/ecma402-abstract': 2.0.0 '@formatjs/fast-memoize': 2.2.0 '@formatjs/icu-messageformat-parser': 2.7.8 - tslib: 2.6.2 + tslib: 2.6.3 is-array-buffer@3.0.4: dependencies: @@ -4428,6 +4506,10 @@ snapshots: dependencies: has-bigints: 1.0.2 + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-boolean-object@1.1.2: dependencies: call-bind: 1.0.7 @@ -4525,7 +4607,7 @@ snapshots: reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 - jackspeak@3.1.2: + jackspeak@3.4.0: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -4549,7 +4631,7 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.24.6 + '@babel/code-frame': 7.24.7 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -4562,7 +4644,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.0 + '@types/node': 20.14.2 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -4659,7 +4741,7 @@ snapshots: local-pkg@0.5.0: dependencies: - mlly: 1.7.0 + mlly: 1.7.1 pkg-types: 1.1.1 locate-path@6.0.0: @@ -4725,7 +4807,7 @@ snapshots: minipass@7.1.2: {} - mlly@1.7.0: + mlly@1.7.1: dependencies: acorn: 8.11.3 pathe: 1.1.2 @@ -4744,6 +4826,8 @@ snapshots: node-releases@2.0.14: {} + normalize-path@3.0.0: {} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -4829,7 +4913,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.6 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -4866,7 +4950,7 @@ snapshots: pkg-types@1.1.1: dependencies: confbox: 0.1.7 - mlly: 1.7.0 + mlly: 1.7.1 pathe: 1.1.2 possible-typed-array-names@1.0.0: {} @@ -4883,7 +4967,7 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@3.3.0: {} + prettier@3.3.1: {} pretty-bytes@6.1.1: {} @@ -4931,7 +5015,7 @@ snapshots: hoist-non-react-statics: 3.3.2 intl-messageformat: 10.5.14 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: typescript: 5.4.5 @@ -4947,6 +5031,10 @@ snapshots: dependencies: loose-envify: 1.4.0 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -5044,6 +5132,12 @@ snapshots: safer-buffer@2.1.2: {} + sass@1.77.4: + dependencies: + chokidar: 3.6.0 + immutable: 4.3.6 + source-map-js: 1.2.0 + saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -5184,7 +5278,7 @@ snapshots: synckit@0.8.8: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.6.2 + tslib: 2.6.3 tabbable@6.2.0: {} @@ -5230,6 +5324,8 @@ snapshots: tslib@2.6.2: {} + tslib@2.6.3: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -5304,13 +5400,13 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - vite-node@1.6.0(@types/node@20.14.0): + vite-node@1.6.0(@types/node@20.14.2)(sass@1.77.4): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 picocolors: 1.0.1 - vite: 5.2.12(@types/node@20.14.0) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) transitivePeerDependencies: - '@types/node' - less @@ -5321,16 +5417,17 @@ snapshots: - supports-color - terser - vite@5.2.12(@types/node@20.14.0): + vite@5.2.13(@types/node@20.14.2)(sass@1.77.4): dependencies: esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.18.0 optionalDependencies: - '@types/node': 20.14.0 + '@types/node': 20.14.2 fsevents: 2.3.3 + sass: 1.77.4 - vitest@1.6.0(@types/node@20.14.0)(jsdom@24.1.0): + vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0)(sass@1.77.4): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -5349,11 +5446,11 @@ snapshots: strip-literal: 2.1.0 tinybench: 2.8.0 tinypool: 0.8.4 - vite: 5.2.12(@types/node@20.14.0) - vite-node: 1.6.0(@types/node@20.14.0) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vite-node: 1.6.0(@types/node@20.14.2)(sass@1.77.4) why-is-node-running: 2.2.2 optionalDependencies: - '@types/node': 20.14.0 + '@types/node': 20.14.2 jsdom: 24.1.0 transitivePeerDependencies: - less diff --git a/src/examples/UnloadDialog.tsx b/src/examples/UnloadDialog.tsx index c9e25e8..a018d74 100644 --- a/src/examples/UnloadDialog.tsx +++ b/src/examples/UnloadDialog.tsx @@ -1,71 +1,59 @@ import { Block, Button, - Dialog, Form, FormInputCheckbox, Heading, Inline, Modal, - useDialog, useModal, } from '@block65/react-design-system'; import { useToggle } from '@block65/react-design-system/hooks'; import { useEffect, type FC } from 'react'; -import { useRouter } from '../index.js'; +import { useRouterIntercept } from '../index.js'; export const UnloadDialog: FC = () => { - const [dialog, dialogClose] = useDialog<'ok' | 'nah' | 'dismiss'>(); - const [modal] = useModal<'can' | 'cannot' | 'dismiss'>(); + // const [dialog, dialogClose] = useDialog<'ok' | 'nah' | 'dismiss'>(); + const modal = useModal< + 'can' | 'cannot' // dismiss comes from the RDS Modal component + >(); const [canLeave, setCanLeave] = useToggle(false); - const [, dispatch] = useRouter(); - useEffect(() => { - dispatch({ - hook: async (e) => { + const intercept = useRouterIntercept(); + useEffect( + () => + intercept(async (e, next) => { + // not allowed, show the modal if (!canLeave) { - dialog.show(); - } + // wait for the modal to be closed + const returnValue = await modal.show(); - const returnValue = await dialogClose(); - if (returnValue === 'nah') { - e.preventDefault(); - dialog.close(returnValue); + // if they cannot leave, prevent the navigation + if (returnValue !== 'can') { + e.preventDefault(); + } } - }, - }); - }, [canLeave, dialog, dialogClose, dispatch]); + + await next(); + }), + [canLeave, intercept, modal], + ); return ( {canLeave ? 'You are free!' : 'You are trapped!'} - - - - {modal.open && ( - + )} diff --git a/src/examples/UnloadWarn.tsx b/src/examples/UnloadWarn.tsx index 3b31266..b65e461 100644 --- a/src/examples/UnloadWarn.tsx +++ b/src/examples/UnloadWarn.tsx @@ -21,7 +21,6 @@ export const UnloadWarn: FC = () => { placeholder="delicious" autoFocus message={preventUnload ? 'preventNav' : 'allowNav'} - messageTone={preventUnload ? 'positive' : 'warn'} onChange={(e) => setValue(e.currentTarget.value)} /> diff --git a/src/examples/ViewTransitions.tsx b/src/examples/ViewTransitions.tsx deleted file mode 100644 index cfcba96..0000000 --- a/src/examples/ViewTransitions.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { Heading } from '@block65/react-design-system'; -import { type FC, type PropsWithChildren } from 'react'; -import { Routes } from '../../lib/Routes.js'; -import { Route, useLocation } from '../index.js'; -import { NavLink } from './animation/ViewTransitions.js'; -import { HSL, RGB } from './animation/components.js'; -import { hslRoute, rgbRoute } from './animation/routes.js'; - -const Page: FC = (props) => ( -
- Page - {props.children} -
-); - -export const ViewTransitionsExample = () => { - const [location] = useLocation(); - - return ( -
-
    - - HSL Red - - - - HSL Green - - - - RGB Blue - - - - RGB Pink - -
- -
- - - - - } - /> - - - - - } - /> - - - 404 - - -
-
- ); -}; diff --git a/src/examples/animation/ViewTransitions.module.scss b/src/examples/animation/ViewTransitions.module.scss new file mode 100644 index 0000000..81400c9 --- /dev/null +++ b/src/examples/animation/ViewTransitions.module.scss @@ -0,0 +1,77 @@ +@keyframes fade-in { + from { + opacity: 0; + } +} + +@keyframes fade-out { + 50% { + opacity: 0; + } + to { + opacity: 0; + } +} + +@keyframes slide-from-right { + from { + transform: translateX(100%); + } +} + +@keyframes slide-to-left { + to { + transform: translateX(-100%); + } +} + +@keyframes slide-from-left { + from { + transform: translateX(-100%); + } +} + +@keyframes slide-to-right { + to { + transform: translateX(100%); + } +} + +$duration: 150ms; + +$bezier: cubic-bezier(0.17, 0.67, 0.83, 0.67); + +:root { + --duration: #{$duration}; + + // reduced motion + @media (prefers-reduced-motion: reduce) { + --duration: 0ms; + } +} + +::view-transition-old(animation-example-bwd) { + animation: + var(--duration) #{$bezier} both slide-to-right, + var(--duration) linear both fade-out; +} +::view-transition-new(animation-example-bwd) { + animation: var(--duration) #{$bezier} both slide-from-left; +} + +::view-transition-old(animation-example-fwd) { + animation: + var(--duration) #{$bezier} both slide-to-left, + var(--duration) ease-out both fade-out; +} +::view-transition-new(animation-example-fwd) { + animation: var(--duration) #{$bezier} both slide-from-right; +} + +.fwd { + view-transition-name: animation-example-fwd; +} + +.bwd { + view-transition-name: animation-example-bwd; +} diff --git a/src/examples/animation/ViewTransitions.tsx b/src/examples/animation/ViewTransitions.tsx index 63af482..c7ea247 100644 --- a/src/examples/animation/ViewTransitions.tsx +++ b/src/examples/animation/ViewTransitions.tsx @@ -1,12 +1,23 @@ import { + Block, Heading, + Inline, + Paragraph, TextLink, type TextLinkProps, } from '@block65/react-design-system'; -import { type FC, type HTMLAttributes, type PropsWithChildren } from 'react'; -import { startViewTransition } from '../../../lib/animate.js'; +import { + useEffect, + useState, + type FC, + type HTMLAttributes, + type PropsWithChildren, +} from 'react'; +import styles from './ViewTransitions.module.scss'; import { Routes } from '../../../lib/Routes.js'; -import { Route, useLocation, useNavigate } from '../../index.js'; +import { ActionType, Direction } from '../../../lib/State.js'; +import { startViewTransition } from '../../../lib/animate.js'; +import { Route, useLocation, useNavigate, useRouter } from '../../index.js'; import { HSL, RGB } from './components.js'; import { hslRoute, rgbRoute } from './routes.js'; @@ -14,36 +25,74 @@ export const NavLink = ({ href, ...props }: TextLinkProps) => { const { navigate } = useNavigate(); return ( -
  • + { e.preventDefault(); - startViewTransition(() => navigate(`${href}`).committed); + // startViewTransition(() => navigate(`${href}`).committed); + navigate(`${href}`); }} /> -
  • +
    ); }; -const Page: FC>> = (props) => ( -
    - Page - {props.children} -
    -); +const TransitionPage: FC>> = ( + props, +) => { + const [sinceRender, setSinceRender] = useState(0); + useEffect(() => { + const interval = setInterval(() => { + setSinceRender((prev) => prev + 1); + }, 100); + return () => clearInterval(interval); + }, [sinceRender]); + + const [{ direction }, dispatch] = useRouter(); + + useEffect(() => { + dispatch({ + type: ActionType.Hooks, + intercept: async (_, update) => + startViewTransition(async () => { + await update(); + }).finished, + }); + + return () => { + dispatch({ type: ActionType.Hooks, intercept: undefined }); + }; + }, [dispatch]); + + return ( + + + navDirection= + {direction} + + {sinceRender} + {props.children} + + ); +}; export const ViewTransitionsExample = () => { const [location] = useLocation(); + return ( -
    -
      + + { > RGB Pink -
    + + - + } /> + - + } /> @@ -116,6 +165,6 @@ export const ViewTransitionsExample = () => { 404 -
    +
    ); }; diff --git a/src/index.ts b/src/index.ts index 2ef124c..8299e0f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,19 @@ export { Redirect } from '../lib/components/Redirect.js'; export { Link, type LinkProps } from '../lib/components/Link.js'; -export { Router, type PartialNavigateEventListener } from '../lib/Router.js'; +export type { + SyntheticNavigateEventListener, + SyntheticNavigateEvent, +} from '../lib/State.js'; + +export type { ExtractRouteParams } from '../lib/types.js'; + +export { Router } from '../lib/Router.js'; + export { useLocation, useRouter, - useHook as useRouterHook, + useRouterIntercept, } from '../lib/use-router.js'; export { Routes } from '../lib/Routes.js'; @@ -13,5 +21,3 @@ export { Route } from '../lib/Route.js'; export { useRouteParams } from '../lib/use-route-match.js'; export * from '../lib/hooks.js'; - -export type { ExtractRouteParams } from '../lib/types.js'; diff --git a/tsconfig.json b/tsconfig.json index e242052..d1dba41 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,11 +4,18 @@ "noEmit": false, "declaration": true, "outDir": "./dist", - "types": ["./node_modules/navigation-api-types", "dom-view-transitions"], + "types": [ + "./node_modules/navigation-api-types", + "dom-view-transitions", + "vite/client" + ], "allowJs": false, "checkJs": false, "removeComments": false, - "allowImportingTsExtensions": false + "allowImportingTsExtensions": false, + + // why does this even exist? + "noPropertyAccessFromIndexSignature": false }, "exclude": ["./dist", "./build", "node_modules"] }