Skip to content

Commit

Permalink
Bump raisins to support React 18 (#22)
Browse files Browse the repository at this point in the history
* bump react peer dependency version to 18

* bump jotai to version 2, some temp fixes on types / bugs from update

* cleanup console logs, remove bandaid fixes

* cleaning up types

* publish

* remove expect-error

* fix more types after jotai 2 update

* fix optic types

* bump package version

* add jotai 2 as a peer dependency

* Update package.json

* bum package lock

* Create mean-books-perform.md

* let changeset do the bump, update type

* another type fix for gh action

* gh action type fix

* more gh action types

* another batch of types

* types

* fix last couple of types, story

* fix other story

* update testing library to support react 18

* update types packages

* update dev react-dom for test

* Update package-lock.json

* update changeset to minor release
  • Loading branch information
00salmon authored Oct 2, 2024
1 parent 68b53a9 commit 73055b5
Show file tree
Hide file tree
Showing 23 changed files with 1,874 additions and 4,068 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-books-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@raisins/react": minor
---

Bump raisins to support React 18
5,738 changes: 1,762 additions & 3,976 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"storybook:build": "storybook build -c .storybook -o .out"
},
"peerDependencies": {
"react": "^16.13.0 || ^17.0.0"
"jotai": "^2.0.0",
"react": "^17.0.0 || ^18.0.0"
},
"prettier": {
"printWidth": 80,
Expand All @@ -61,7 +62,8 @@
"css-tree": "^1.1.3",
"fast-equals": "^5.0.1",
"hotkeys-js": "^3.8.7",
"jotai": "^1.6.0",
"jotai-optics": "^0.4.0",
"jotai-zustand": "^0.4.0",
"jsonpointer": "^5.0.0",
"optics-ts": "^2.2.0",
"penpal": "^6.2.2",
Expand All @@ -74,7 +76,7 @@
"style-to-object": "^0.3.0",
"throttle-debounce": "^5.0.0",
"valtio": "^1.5.2",
"zustand": "^4.0.0-rc.1"
"zustand": "^4.5.4"
},
"devDependencies": {
"@babel/core": "^7.15.5",
Expand All @@ -85,16 +87,16 @@
"@storybook/cli": "^7.0.21",
"@storybook/react": "^7.0.21",
"@storybook/react-vite": "^7.5.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/react": "^14.1.2",
"@types/css-tree": "^1.0.6",
"@types/jest": "^29.1.0",
"@types/prosemirror-commands": "^1.0.4",
"@types/prosemirror-keymap": "^1.0.4",
"@types/prosemirror-schema-basic": "^1.0.2",
"@types/prosemirror-state": "^1.2.7",
"@types/prosemirror-view": "^1.19.1",
"@types/react": "^17.0.24",
"@types/react-dom": "^17.0.9",
"@types/react": "18",
"@types/react-dom": "^18.3.0",
"@types/resize-observer-browser": "^0.1.7",
"@types/styled-components": "^5.1.14",
"@types/throttle-debounce": "^5.0.0",
Expand All @@ -108,7 +110,7 @@
"jest-environment-jsdom": "^29.1.0",
"local-cypress": "^1.2.5",
"react": "*",
"react-dom": "^16.14.0",
"react-dom": "^18.3.1",
"react-hooks-testing-library": "^0.6.0",
"react-is": "^17.0.2",
"size-limit": "^5.0.4",
Expand Down
7 changes: 5 additions & 2 deletions packages/react/src/attributes/AttributeMolecule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const AttributeMolecule = molecule(getMol => {
return get(attributesAtoms.valuesAtom)[name];
},
(_, set, next: SetStateAction<string | undefined>) => {
set(attributesAtoms.valuesAtom, prev => {
set(attributesAtoms.valuesAtom, (prev: { [key: string]: string }) => {
// @ts-expect-error Not all constituents of type are callable
const value = isFunction(next) ? next(prev[name]) : next;
const attrbsClone = { ...prev };
Expand Down Expand Up @@ -116,7 +116,10 @@ function toNumber(value: string | undefined): number | undefined {
/**
* Provides scope for a {@link AttributeScopeMolecule} and {@link AttributeMolecule}
*/
export const AttributeProvider: React.FC<{ attributeName: string }> = props => (
export const AttributeProvider: React.FC<{
attributeName: string;
children: React.PropsWithChildren['children'];
}> = props => (
<ScopeProvider scope={AttributeScope} value={props.attributeName}>
{props.children}
</ScopeProvider>
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/canvas/CanvasScopeMolecule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
SnabbdomRenderer,
} from './util/raisinToSnabdom';

type CanvasEventListener = WritableAtom<null, RichCanvasEvent>;
type CanvasEventListener = WritableAtom<null, RichCanvasEvent[], void>;

/**
* Used to "burn down" a snabbdom view for full replacement instead of incremental replacement.
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/canvas/ProxySet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { atomWithStore } from 'jotai/zustand';
import { atomWithStore } from 'jotai-zustand';
import { createStore } from 'zustand/vanilla';

type SetStore<T> = { values: T[]; add(item: T): void };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { act, renderHook } from '@testing-library/react-hooks/dom';
import expect from 'expect';
import { atom, useAtom } from 'jotai';
import { molecule, ScopeProvider, useMolecule } from 'bunshi/react';
Expand All @@ -10,9 +9,10 @@ import {
SnabbdomIframeProps,
SnabbdomIframeScope,
} from './SnabbdomSanboxedIframeAtom';
import { act, renderHook, waitFor } from '@testing-library/react';

describe('Thing', () => {
const useSnabbsom = () => {
const useSnabbdom = () => {
const atoms = useMolecule(SnabbdomIframeMolecule);
const [state, setState] = useAtom(atoms);
return { state, setState };
Expand All @@ -30,8 +30,9 @@ describe('Thing', () => {
};
});
it('Fails without a wrapper', () => {
const { result } = renderHook(() => useSnabbsom());
expect(result.error).toBeTruthy();
expect(() => {
const { result } = renderHook(() => useSnabbdom());
}).toThrowError();
});

// TODO: Move this testing functionality to playwright tests
Expand All @@ -41,7 +42,7 @@ describe('Thing', () => {
{children}
</ScopeProvider>
);
const { result, waitForNextUpdate } = renderHook(() => useSnabbsom(), {
const { result } = renderHook(() => useSnabbdom(), {
wrapper: Wrapper,
});

Expand All @@ -56,7 +57,7 @@ describe('Thing', () => {
expect((result.current.state as any).error).toBeUndefined();
expect(result.current.state.type).toBe('initializing');

await waitForNextUpdate();
await waitFor(() => result.current.state.type === 'loaded');
expect((result.current.state as any).error).toBeUndefined();
expect(result.current.state.type).toBe('loaded');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ export type SnabbdomIframeProps = {
* Set of types that will be listened to in the canvas
*/
eventTypes: Atom<Set<string>>;
onEvent: WritableAtom<null, RawCanvasEvent>;
onResize: WritableAtom<null, GeometryDetail>;
onEvent: WritableAtom<null, RawCanvasEvent[], void>;
onResize: WritableAtom<null, GeometryDetail[], void>;
};

export function createAtoms(props: SnabbdomIframeProps) {
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/canvas/iframe/throttledAtom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function throttledWriteAtom(delay: number) {
const throttledSetAtom = atom({ current: null as null | Setter });
const throttledOnEvent = atom(
null,
(get, set, e: { atom: WritableAtom<any, any>; value: any }) => {
(get, set, e: { atom: WritableAtom<any, any, void>; value: any }) => {
const throttledSetRef = get(throttledSetAtom);
let throttledSet = throttledSetRef.current;
if (!throttledSet) {
Expand All @@ -29,11 +29,11 @@ export function throttledWriteAtom(delay: number) {
*/
export function throttleAtom<R, W>(
ms: number,
atomToThrottle: WritableAtom<R, W>
): WritableAtom<R, W> {
atomToThrottle: WritableAtom<R, W[], void>
): WritableAtom<R, W[], void> {
const throttleSet = throttledWriteAtom(ms);
return atom(
(get) => get(atomToThrottle),
get => get(atomToThrottle),
(get, set, next: W) =>
set(throttleSet, { atom: atomToThrottle, value: next })
);
Expand Down
29 changes: 13 additions & 16 deletions packages/react/src/component-metamodel/ComponentModel.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { htmlParser, RaisinElementNode } from '@raisins/core';
import { Meta } from '@storybook/react';
import { useAtom } from 'jotai';
import { useMolecule } from 'bunshi/react';
import { useAtomValue, useUpdateAtom } from 'jotai/utils';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import React from 'react';
import {
AttributeProvider,
Expand Down Expand Up @@ -99,7 +98,7 @@ const BlocksController = () => {
}}
>
<h2>Blocks</h2>
{(blocks.length ? blocks : fakeBlocks).map((block) => {
{(blocks.length ? blocks : fakeBlocks).map(block => {
return (
<div
style={{
Expand All @@ -122,9 +121,7 @@ const BlocksController = () => {
);
};

export const CustomAttributesController: React.FC<AttributesControllerProps> = (
props
) => {
export const CustomAttributesController: React.FC<AttributesControllerProps> = props => {
const { keysAtom, groupedSchemaAtom } = useMolecule(AttributesMolecule);
const keys = useAtomValue(keysAtom);
const groupedSchema = useAtomValue(groupedSchemaAtom);
Expand All @@ -136,7 +133,7 @@ export const CustomAttributesController: React.FC<AttributesControllerProps> = (
{Object.keys(groupedSchema).map((key, idx) => {
return (
<>
{groupedSchema[key].map((attribute) => {
{groupedSchema[key].map(attribute => {
return (
<AttributeProvider
attributeName={attribute.name}
Expand Down Expand Up @@ -307,7 +304,7 @@ const CustomThemeTest = () => {
<>
<textarea
value={html}
onInput={(e) => setHtml((e.target as HTMLTextAreaElement).value)}
onInput={e => setHtml((e.target as HTMLTextAreaElement).value)}
rows={6}
style={{ width: '300px' }}
/>
Expand Down Expand Up @@ -354,9 +351,9 @@ function usePackageEditor(): ModuleManagement {
loadingModules: useAtomValue(ModulesLoadingAtom),
modules: useAtomValue(ModulesAtom),
moduleDetails: useAtomValue(ModuleDetailsAtom),
addModule: useUpdateAtom(AddModuleAtom),
removeModule: useUpdateAtom(RemoveModuleAtom),
removeModuleByName: useUpdateAtom(RemoveModuleByNameAtom),
addModule: useSetAtom(AddModuleAtom),
removeModule: useSetAtom(RemoveModuleAtom),
removeModuleByName: useSetAtom(RemoveModuleByNameAtom),
};
}

Expand All @@ -379,7 +376,7 @@ function PackageEditorView(props: ModuleManagement) {
<div>Loading: {props.loadingModules}</div>
Modules:
<ul>
{props.modules.map((m) => (
{props.modules.map(m => (
<li key={m.package + '@' + m.version + '/' + m.filePath}>
{m.package} @ {m.version} for {m.filePath}
</li>
Expand Down Expand Up @@ -411,7 +408,7 @@ function PackageEditorView(props: ModuleManagement) {
<h2>Add</h2>
<button
onClick={() => {
setOfThings.map((m) => props.addModule(m));
setOfThings.map(m => props.addModule(m));
}}
>
Shoelace + theme
Expand Down Expand Up @@ -441,11 +438,11 @@ function PackageEditorView(props: ModuleManagement) {
Mint (alpha)
</button>
<ul>
{PACKAGES.map((m) => {
{PACKAGES.map(m => {
return (
<li key={m}>
<button
onClick={(e) => {
onClick={e => {
props.addModule({
package: m,
});
Expand All @@ -459,7 +456,7 @@ function PackageEditorView(props: ModuleManagement) {
</ul>
<h2>Remove</h2>
<ul>
{PACKAGES.map((m) => {
{PACKAGES.map(m => {
return (
<li key={m}>
<button onClick={() => props.removeModuleByName(m)}>{m}</button>
Expand Down
21 changes: 13 additions & 8 deletions packages/react/src/component-metamodel/ComponentModel.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import {
DefaultTextMarks,
doesChildAllowParent,
doesParentAllowChild,
getSlots,
HTMLComponents,
isNodeAllowed,
NodeWithSlots,
RaisinDocumentNode,
RaisinElementNode,
RaisinNode,
DefaultTextMarks,
RaisinNodeWithChildren,
RaisinDocumentNode,
} from '@raisins/core';
import { CustomElement, Slot } from '@raisins/schema/schema';
import { Atom, atom, PrimitiveAtom, WritableAtom } from 'jotai';
import { molecule } from 'bunshi/react';
import { shallowEqual } from 'fast-equals';
import { Atom, atom, PrimitiveAtom, WritableAtom } from 'jotai';
import { loadable } from 'jotai/utils';
import { ConfigMolecule } from '../core';
import { CoreMolecule } from '../core/CoreAtoms';
Expand All @@ -22,7 +23,6 @@ import {
NPMRegistry,
NPMRegistryAtom as RegistryAtom,
} from '../util/NPMRegistry';
import { shallowEqual } from 'fast-equals';
import {
blockFromHtml,
moduleDetailsToBlocks,
Expand All @@ -39,9 +39,9 @@ export type ComponentModelMoleculeType = {
ComponentsAtom: Atom<CustomElement[]>;
LocalURLAtom: Atom<string | undefined>;
BlocksAtom: Atom<Block[]>;
AddModuleAtom: WritableAtom<null, Module>;
RemoveModuleAtom: WritableAtom<null, Module>;
RemoveModuleByNameAtom: WritableAtom<null, string>;
AddModuleAtom: WritableAtom<null, Module[], void>;
RemoveModuleAtom: WritableAtom<null, Module[], void>;
RemoveModuleByNameAtom: WritableAtom<null, string[], void>;
ComponentMetaAtom: Atom<ComponentMetaProvider>;
ValidChildrenAtom: Atom<
(node: RaisinNode, slot?: string | undefined) => Block[]
Expand Down Expand Up @@ -81,14 +81,19 @@ export const ComponentModelMolecule = molecule(
* `true` while module information is being loaded from NPM
*/
const ModulesLoadingAtom = atom(
get => get(ModuleDetailsStateAtom).state === 'loading'
get =>
get(ModuleDetailsStateAtom).state === 'loading' ||
// Only has status while details are being loaded
((get(ModuleDetailsAtom) as unknown) as ModuleDetails).status ===
'pending'
);

/**
* The array of {@link CustomElement} from ALL packages
*/
const ComponentsAtom = atom(get => {
const moduleDetails = get(ModuleDetailsAtom);

return [
...Object.values(HTMLComponents),
...moduleDetails.reduce(moduleDetailsToTags, [] as CustomElement[]),
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/component-metamodel/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type Module = {
export type ModuleDetails = {
'package.json': PackageJson;
raisins?: schema.Package;
status?: string;
} & Module;

export type ResolveType<T> = T extends Promise<infer V> ? V : T;
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/core/CoreAtoms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const CoreMolecule = molecule((getMol, getScope) => {
);

const StateListeners = new Set<
WritableAtom<unknown, { prev: RaisinNode; next: RaisinNode }>
WritableAtom<unknown, { prev: RaisinNode; next: RaisinNode }[], void>
>([]);

const InternalTransactionAtom = atom(
Expand Down
Loading

0 comments on commit 73055b5

Please sign in to comment.