diff --git a/packages/core/lib/index.ts b/packages/core/lib/index.ts index a94147084..44c86a9bf 100644 --- a/packages/core/lib/index.ts +++ b/packages/core/lib/index.ts @@ -57,9 +57,14 @@ export { formatThousand, } from './numbers'; +export { + mockState, +} from './state'; + export type { GenericObject, Grow, GrowToSize, FixedArray, + StateContent, } from './types'; diff --git a/packages/react/lib/utils.test.ts b/packages/core/lib/state/index.test.ts similarity index 86% rename from packages/react/lib/utils.test.ts rename to packages/core/lib/state/index.test.ts index b2659edc5..2fad1534d 100644 --- a/packages/react/lib/utils.test.ts +++ b/packages/core/lib/state/index.test.ts @@ -1,6 +1,6 @@ -import { mockState } from './utils'; +import { mockState } from './'; -describe('react/utils', () => { +describe('state', () => { describe('mockState(state, action)', () => { it('should merge state with action object to simulate setState', () => { expect(mockState({ foo: 'bar' }, { foo: 'test' })) diff --git a/packages/core/lib/state/index.ts b/packages/core/lib/state/index.ts new file mode 100644 index 000000000..712e8ebc3 --- /dev/null +++ b/packages/core/lib/state/index.ts @@ -0,0 +1,12 @@ +import type { StateContent } from '../types'; + +/** + * mockState should be inside react package, but some external packages + * (like @poool/react-access) only depend on @junipero/core, so it will be + * here forever). + */ +export const mockState = ( + state: T, + action : ((prev: T) => T) | Partial +) => typeof action === 'function' + ? action(state) : ({ ...state, ...action as T }); diff --git a/packages/core/lib/types.ts b/packages/core/lib/types.ts index 7995f8c00..29b27f79a 100644 --- a/packages/core/lib/types.ts +++ b/packages/core/lib/types.ts @@ -11,3 +11,11 @@ export type GrowToSize, N extends number> = { }[A['length'] extends N ? 0 : 1]; export type FixedArray = GrowToSize; + +/** +* Represents a state comming from useReducer. +* Volontarily abstracted to allow any kind of state. +*/ +export declare interface StateContent { + [key: string]: any; +} diff --git a/packages/react/lib/Calendar/index.tsx b/packages/react/lib/Calendar/index.tsx index b92ab6f0e..115796254 100644 --- a/packages/react/lib/Calendar/index.tsx +++ b/packages/react/lib/Calendar/index.tsx @@ -15,10 +15,10 @@ import { subMonths, addMonths, getDaysInMonth, + mockState, } from '@junipero/core'; import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; -import { mockState } from '../utils'; import { ArrowLeft, ArrowRight } from '../icons'; export declare interface CalendarRef extends JuniperoRef { diff --git a/packages/react/lib/CheckboxField/index.tsx b/packages/react/lib/CheckboxField/index.tsx index f06a73c8f..50fff4bb5 100644 --- a/packages/react/lib/CheckboxField/index.tsx +++ b/packages/react/lib/CheckboxField/index.tsx @@ -7,14 +7,13 @@ import { useReducer, useRef, } from 'react'; -import { classNames } from '@junipero/core'; +import { classNames, mockState } from '@junipero/core'; import type { FieldContent, JuniperoRef, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; import { Check } from '../icons'; diff --git a/packages/react/lib/CodeField/index.tsx b/packages/react/lib/CodeField/index.tsx index c93f91747..409d7aacd 100644 --- a/packages/react/lib/CodeField/index.tsx +++ b/packages/react/lib/CodeField/index.tsx @@ -9,14 +9,13 @@ import { useRef, useImperativeHandle, } from 'react'; -import { classNames } from '@junipero/core'; +import { classNames, mockState } from '@junipero/core'; import type { FieldContent, JuniperoRef, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; export declare interface CodeFieldRef extends JuniperoRef { diff --git a/packages/react/lib/ColorField/index.tsx b/packages/react/lib/ColorField/index.tsx index 3532810ed..367ffcc37 100644 --- a/packages/react/lib/ColorField/index.tsx +++ b/packages/react/lib/ColorField/index.tsx @@ -15,6 +15,7 @@ import { exists, stringifyColor, parseColor, + mockState, } from '@junipero/core'; import { useEventListener } from '@junipero/hooks'; @@ -24,7 +25,6 @@ import type { SpecialComponentPropsWithRef, } from '../types'; import type { TransitionProps } from '../Transition'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; import Dropdown, { type DropdownProps, type DropdownRef } from '../Dropdown'; import DropdownToggle from '../DropdownToggle'; diff --git a/packages/react/lib/DateField/index.tsx b/packages/react/lib/DateField/index.tsx index 5cc9177d0..ea2d06e04 100644 --- a/packages/react/lib/DateField/index.tsx +++ b/packages/react/lib/DateField/index.tsx @@ -9,7 +9,7 @@ import { useRef, useEffect, } from 'react'; -import { type FixedArray, classNames, exists } from '@junipero/core'; +import { type FixedArray, classNames, exists, mockState } from '@junipero/core'; import type { TransitionProps } from '../Transition'; import type { @@ -17,7 +17,6 @@ import type { FieldContent, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; import { Arrows, Remove, Time } from '../icons'; import Dropdown, { type DropdownRef } from '../Dropdown'; diff --git a/packages/react/lib/Dropdown/index.tsx b/packages/react/lib/Dropdown/index.tsx index 63c130457..62dc22d5d 100644 --- a/packages/react/lib/Dropdown/index.tsx +++ b/packages/react/lib/Dropdown/index.tsx @@ -7,7 +7,7 @@ import { useReducer, useEffect, } from 'react'; -import { classNames, omit } from '@junipero/core'; +import { classNames, omit, mockState } from '@junipero/core'; import { type UseClickProps, type UseDismissProps, @@ -30,7 +30,6 @@ import { import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; import { DropdownContext, type DropdownContextType } from '../contexts'; -import { mockState } from '../utils'; export declare interface DropdownRef extends JuniperoRef { opened: boolean; diff --git a/packages/react/lib/FieldControl/index.tsx b/packages/react/lib/FieldControl/index.tsx index 1e50abbf3..81de6ef0d 100644 --- a/packages/react/lib/FieldControl/index.tsx +++ b/packages/react/lib/FieldControl/index.tsx @@ -1,7 +1,7 @@ import { type ComponentPropsWithoutRef, useCallback, useReducer } from 'react'; +import { mockState } from '@junipero/core'; import { type FieldContextType, FieldControlContext } from '../contexts'; -import { mockState } from '../utils'; export declare interface FieldControlProps extends Omit< ComponentPropsWithoutRef, 'value' diff --git a/packages/react/lib/List/index.tsx b/packages/react/lib/List/index.tsx index 9def6508f..1080868d5 100644 --- a/packages/react/lib/List/index.tsx +++ b/packages/react/lib/List/index.tsx @@ -7,13 +7,12 @@ import { useMemo, useEffect, } from 'react'; -import { classNames } from '@junipero/core'; +import { classNames, mockState } from '@junipero/core'; import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; import type { ListColumnObject } from '../ListColumn'; import { ListContext, type ListContextType } from '../contexts'; import { ArrowDown, ArrowUp } from '../icons'; -import { mockState } from '../utils'; export declare interface ListRef extends JuniperoRef { orderable: boolean; diff --git a/packages/react/lib/Modal/index.tsx b/packages/react/lib/Modal/index.tsx index d9c3a7eb1..621c3b4b6 100644 --- a/packages/react/lib/Modal/index.tsx +++ b/packages/react/lib/Modal/index.tsx @@ -9,12 +9,11 @@ import { useRef, } from 'react'; import { createPortal } from 'react-dom'; -import { classNames, ensureNode } from '@junipero/core'; +import { classNames, ensureNode, mockState } from '@junipero/core'; import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; import type { TransitionProps } from '../Transition'; import { useModal } from '../hooks'; -import { mockState } from '../utils'; import { Remove } from '../icons'; export declare interface ModalRef extends JuniperoRef { diff --git a/packages/react/lib/RadioField/index.tsx b/packages/react/lib/RadioField/index.tsx index cafdf9fa8..81f2df2fa 100644 --- a/packages/react/lib/RadioField/index.tsx +++ b/packages/react/lib/RadioField/index.tsx @@ -6,14 +6,13 @@ import { useImperativeHandle, useEffect, } from 'react'; -import { classNames } from '@junipero/core'; +import { classNames, mockState } from '@junipero/core'; import type { FieldContent, JuniperoRef, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; export declare type RadioFieldValue = any; diff --git a/packages/react/lib/SelectField/index.test.tsx b/packages/react/lib/SelectField/index.test.tsx index fc74e5db8..a8dfb5ec7 100644 --- a/packages/react/lib/SelectField/index.test.tsx +++ b/packages/react/lib/SelectField/index.test.tsx @@ -1,12 +1,12 @@ import { createRef, useEffect, useReducer, useState } from 'react'; import { render, fireEvent, act } from '@testing-library/react'; import { configMocks, mockIntersectionObserver } from 'jsdom-testing-mocks'; +import { mockState } from '@junipero/core'; import userEvent from '@testing-library/user-event'; import { blur, focus, reset, sleep } from '~tests-utils'; import type { FieldContent } from '../types'; import { cloneDeep, set } from '../../../core/lib/core'; -import { mockState } from '../utils'; import FieldControl from '../FieldControl'; import Label from '../Label'; import Abstract from '../Abstract'; diff --git a/packages/react/lib/SelectField/index.tsx b/packages/react/lib/SelectField/index.tsx index 368761abd..acbb7952b 100644 --- a/packages/react/lib/SelectField/index.tsx +++ b/packages/react/lib/SelectField/index.tsx @@ -17,6 +17,7 @@ import { exists, filterDeep, findDeep, + mockState, } from '@junipero/core'; import { useTimeout } from '@junipero/hooks'; @@ -28,7 +29,6 @@ import type { import type { TransitionProps } from '../Transition'; import { useFieldControl } from '../hooks'; import { Arrows, Remove } from '../icons'; -import { mockState } from '../utils'; import Dropdown, { type DropdownRef } from '../Dropdown'; import DropdownToggle from '../DropdownToggle'; import DropdownMenu from '../DropdownMenu'; diff --git a/packages/react/lib/Slider/index.tsx b/packages/react/lib/Slider/index.tsx index b3b057fc4..7c378b33c 100644 --- a/packages/react/lib/Slider/index.tsx +++ b/packages/react/lib/Slider/index.tsx @@ -12,12 +12,12 @@ import { classNames, getFloatPrecision, ensureMinMax, + mockState, } from '@junipero/core'; import { useEventListener } from '@junipero/hooks'; import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; import type { TransitionProps } from '../Transition'; -import { mockState } from '../utils'; import Tooltip, { type TooltipRef } from '../Tooltip'; export declare interface SliderRef extends JuniperoRef { diff --git a/packages/react/lib/Tabs/index.tsx b/packages/react/lib/Tabs/index.tsx index f392b091e..e1469deee 100644 --- a/packages/react/lib/Tabs/index.tsx +++ b/packages/react/lib/Tabs/index.tsx @@ -3,6 +3,7 @@ import { type ReactNode, type MouseEvent, type ReactElement, + type ComponentPropsWithoutRef, Children, useEffect, useImperativeHandle, @@ -13,7 +14,7 @@ import { import { classNames } from '@junipero/core'; import type { JuniperoRef, SpecialComponentPropsWithRef } from '../types'; -import Tab, { TabProps, type TabObject } from '../Tab'; +import Tab, { type TabProps, type TabObject } from '../Tab'; export declare interface TabsRef extends JuniperoRef { activeTab: number; @@ -28,7 +29,7 @@ export declare interface TabsProps extends Omit< active?: number; disabled?: boolean; tabs?: Array; - filterTab?(child: ReactElement | ReactNode): boolean; + filterTab?(child: ReactElement>): boolean; onToggle?(index: number): void; } @@ -39,7 +40,7 @@ const Tabs = ({ active, tabs, disabled = false, - filterTab = (child: ReactElement) => + filterTab = (child: ReactElement>) => typeof child !== 'string' && child.type === Tab, onToggle, ...rest diff --git a/packages/react/lib/TextField/index.tsx b/packages/react/lib/TextField/index.tsx index 93fc422e3..9194a1217 100644 --- a/packages/react/lib/TextField/index.tsx +++ b/packages/react/lib/TextField/index.tsx @@ -8,14 +8,13 @@ import { useReducer, useRef, } from 'react'; -import { classNames, exists } from '@junipero/core'; +import { classNames, exists, mockState } from '@junipero/core'; import type { FieldContent, JuniperoRef, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; import { useFieldControl } from '../hooks'; export declare interface TextFieldRef extends JuniperoRef { diff --git a/packages/react/lib/Toggle/index.tsx b/packages/react/lib/Toggle/index.tsx index 711e0f7b1..0fdbc2227 100644 --- a/packages/react/lib/Toggle/index.tsx +++ b/packages/react/lib/Toggle/index.tsx @@ -6,14 +6,13 @@ import { useReducer, useRef, } from 'react'; -import { classNames } from '@junipero/core'; +import { classNames, mockState } from '@junipero/core'; import type { FieldContent, JuniperoRef, SpecialComponentPropsWithRef, } from '../types'; -import { mockState } from '../utils'; export declare type ToggleValue = any; diff --git a/packages/react/lib/Tooltip/index.tsx b/packages/react/lib/Tooltip/index.tsx index e3e5b23dc..e83694a7d 100644 --- a/packages/react/lib/Tooltip/index.tsx +++ b/packages/react/lib/Tooltip/index.tsx @@ -15,6 +15,7 @@ import { classNames, ensureNode, omit, + mockState, } from '@junipero/core'; import { type UseDismissProps, @@ -41,7 +42,6 @@ import type { SpecialComponentPropsWithRef, } from '../types'; import type { TransitionProps } from '../Transition'; -import { mockState } from '../utils'; export declare interface TooltipRef extends JuniperoRef { opened: boolean; diff --git a/packages/react/lib/Transition/index.stories.tsx b/packages/react/lib/Transition/index.stories.tsx index dc71f14fd..e474f51ec 100644 --- a/packages/react/lib/Transition/index.stories.tsx +++ b/packages/react/lib/Transition/index.stories.tsx @@ -1,7 +1,7 @@ import { useReducer } from 'react'; +import { mockState } from '@junipero/core'; import type { FieldContent } from '../types'; -import { mockState } from '../utils'; import Button from '../Button'; import Label from '../Label'; import TextField from '../TextField'; diff --git a/packages/react/lib/index.test.tsx b/packages/react/lib/index.test.tsx index e256ef031..a554f4081 100644 --- a/packages/react/lib/index.test.tsx +++ b/packages/react/lib/index.test.tsx @@ -1,9 +1,9 @@ import { useReducer } from 'react'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { mockState } from '@junipero/core'; import { useTimeout } from '@junipero/hooks'; import type { FieldContent } from './types'; -import { mockState } from './utils'; import TextField from './TextField'; type State = { diff --git a/packages/react/lib/index.ts b/packages/react/lib/index.ts index 80689918c..a85858125 100644 --- a/packages/react/lib/index.ts +++ b/packages/react/lib/index.ts @@ -2,6 +2,7 @@ export { type Grow, type GrowToSize, type FixedArray, + type StateContent, COLORS, ensureNode, classNames, @@ -46,6 +47,7 @@ export { ensureMinMax, getFloatPrecision, formatThousand, + mockState, } from '@junipero/core'; export { @@ -375,8 +377,4 @@ export { type ModalContextType, } from './contexts'; -export { - mockState, -} from './utils'; - export type * from './types'; diff --git a/packages/react/lib/utils.ts b/packages/react/lib/utils.ts deleted file mode 100644 index 27e34ad11..000000000 --- a/packages/react/lib/utils.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { StateContent } from './types'; - -export const mockState = ( - state: T, - action : ((prev: T) => T) | Partial -) => typeof action === 'function' - ? action(state) : ({ ...state, ...action as T });