mirror of
https://github.com/mathuo/dockview
synced 2025-02-02 14:35:46 +00:00
Merge pull request #825 from mathuo/818-container-with-theme-class-is-created-twice-1
bug: duplicate container HTML Element
This commit is contained in:
commit
6678ae24e0
@ -105,6 +105,21 @@ class ClassUnderTest extends BaseGrid<TestPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('baseComponentGridview', () => {
|
describe('baseComponentGridview', () => {
|
||||||
|
test('that the container is not removed when grid is disposed', () => {
|
||||||
|
const root = document.createElement('div');
|
||||||
|
const container = document.createElement('div');
|
||||||
|
root.appendChild(container);
|
||||||
|
|
||||||
|
const cut = new ClassUnderTest(container, {
|
||||||
|
orientation: Orientation.HORIZONTAL,
|
||||||
|
proportionalLayout: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
cut.dispose();
|
||||||
|
|
||||||
|
expect(container.parentElement).toBe(root);
|
||||||
|
});
|
||||||
|
|
||||||
test('that .layout(...) force flag works', () => {
|
test('that .layout(...) force flag works', () => {
|
||||||
const cut = new ClassUnderTest(document.createElement('div'), {
|
const cut = new ClassUnderTest(document.createElement('div'), {
|
||||||
orientation: Orientation.HORIZONTAL,
|
orientation: Orientation.HORIZONTAL,
|
||||||
|
@ -67,6 +67,27 @@ describe('componentPaneview', () => {
|
|||||||
container.className = 'container';
|
container.className = 'container';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('that the container is not removed when grid is disposed', () => {
|
||||||
|
const root = document.createElement('div');
|
||||||
|
const container = document.createElement('div');
|
||||||
|
root.appendChild(container);
|
||||||
|
|
||||||
|
const paneview = new PaneviewComponent(container, {
|
||||||
|
createComponent: (options) => {
|
||||||
|
switch (options.name) {
|
||||||
|
case 'default':
|
||||||
|
return new TestPanel(options.id, options.name);
|
||||||
|
default:
|
||||||
|
throw new Error('unsupported');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
paneview.dispose();
|
||||||
|
|
||||||
|
expect(container.parentElement).toBe(root);
|
||||||
|
});
|
||||||
|
|
||||||
test('vertical panels', () => {
|
test('vertical panels', () => {
|
||||||
const disposables = new CompositeDisposable();
|
const disposables = new CompositeDisposable();
|
||||||
|
|
||||||
@ -293,40 +314,6 @@ describe('componentPaneview', () => {
|
|||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose of paneviewComponent', () => {
|
|
||||||
expect(container.childNodes.length).toBe(0);
|
|
||||||
|
|
||||||
const paneview = new PaneviewComponent(container, {
|
|
||||||
createComponent: (options) => {
|
|
||||||
switch (options.name) {
|
|
||||||
case 'default':
|
|
||||||
return new TestPanel(options.id, options.name);
|
|
||||||
default:
|
|
||||||
throw new Error('unsupported');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
paneview.layout(1000, 1000);
|
|
||||||
|
|
||||||
paneview.addPanel({
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 1',
|
|
||||||
});
|
|
||||||
paneview.addPanel({
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 2',
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(container.childNodes.length).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
paneview.dispose();
|
|
||||||
|
|
||||||
expect(container.childNodes.length).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('panel is disposed of when component is disposed', () => {
|
test('panel is disposed of when component is disposed', () => {
|
||||||
const paneview = new PaneviewComponent(container, {
|
const paneview = new PaneviewComponent(container, {
|
||||||
createComponent: (options) => {
|
createComponent: (options) => {
|
||||||
@ -606,10 +593,10 @@ describe('componentPaneview', () => {
|
|||||||
className: 'test-a test-b',
|
className: 'test-a test-b',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(paneview.element.className).toBe('container test-a test-b');
|
expect(paneview.element.className).toBe('test-a test-b');
|
||||||
|
|
||||||
paneview.updateOptions({ className: 'test-b test-c' });
|
paneview.updateOptions({ className: 'test-b test-c' });
|
||||||
|
|
||||||
expect(paneview.element.className).toBe('container test-b test-c');
|
expect(paneview.element.className).toBe('test-b test-c');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -26,6 +26,28 @@ describe('componentSplitview', () => {
|
|||||||
container.className = 'container';
|
container.className = 'container';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('that the container is not removed when grid is disposed', () => {
|
||||||
|
const root = document.createElement('div');
|
||||||
|
const container = document.createElement('div');
|
||||||
|
root.appendChild(container);
|
||||||
|
|
||||||
|
const splitview = new SplitviewComponent(container, {
|
||||||
|
orientation: Orientation.VERTICAL,
|
||||||
|
createComponent: (options) => {
|
||||||
|
switch (options.name) {
|
||||||
|
case 'default':
|
||||||
|
return new TestPanel(options.id, options.name);
|
||||||
|
default:
|
||||||
|
throw new Error('unsupported');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
splitview.dispose();
|
||||||
|
|
||||||
|
expect(container.parentElement).toBe(root);
|
||||||
|
});
|
||||||
|
|
||||||
test('event leakage', () => {
|
test('event leakage', () => {
|
||||||
Emitter.setLeakageMonitorEnabled(true);
|
Emitter.setLeakageMonitorEnabled(true);
|
||||||
|
|
||||||
@ -451,39 +473,6 @@ describe('componentSplitview', () => {
|
|||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose of splitviewComponent', () => {
|
|
||||||
expect(container.childNodes.length).toBe(0);
|
|
||||||
|
|
||||||
const splitview = new SplitviewComponent(container, {
|
|
||||||
orientation: Orientation.HORIZONTAL,
|
|
||||||
createComponent: (options) => {
|
|
||||||
switch (options.name) {
|
|
||||||
case 'default':
|
|
||||||
return new TestPanel(options.id, options.name);
|
|
||||||
default:
|
|
||||||
throw new Error('unsupported');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
splitview.layout(1000, 1000);
|
|
||||||
|
|
||||||
splitview.addPanel({
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
splitview.addPanel({
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(container.childNodes.length).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
splitview.dispose();
|
|
||||||
|
|
||||||
expect(container.childNodes.length).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('panel is disposed of when component is disposed', () => {
|
test('panel is disposed of when component is disposed', () => {
|
||||||
const splitview = new SplitviewComponent(container, {
|
const splitview = new SplitviewComponent(container, {
|
||||||
orientation: Orientation.HORIZONTAL,
|
orientation: Orientation.HORIZONTAL,
|
||||||
@ -736,10 +725,10 @@ describe('componentSplitview', () => {
|
|||||||
className: 'test-a test-b',
|
className: 'test-a test-b',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(splitview.element.className).toBe('container test-a test-b');
|
expect(splitview.element.className).toBe('test-a test-b');
|
||||||
|
|
||||||
splitview.updateOptions({ className: 'test-b test-c' });
|
splitview.updateOptions({ className: 'test-b test-c' });
|
||||||
|
|
||||||
expect(splitview.element.className).toBe('container test-b test-c');
|
expect(splitview.element.className).toBe('test-b test-c');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -368,8 +368,8 @@ export class DockviewComponent
|
|||||||
return this._floatingGroups;
|
return this._floatingGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(parentElement: HTMLElement, options: DockviewComponentOptions) {
|
constructor(container: HTMLElement, options: DockviewComponentOptions) {
|
||||||
super(parentElement, {
|
super(container, {
|
||||||
proportionalLayout: true,
|
proportionalLayout: true,
|
||||||
orientation: Orientation.HORIZONTAL,
|
orientation: Orientation.HORIZONTAL,
|
||||||
styles: options.hideBorders
|
styles: options.hideBorders
|
||||||
|
@ -155,14 +155,17 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
|||||||
this.gridview.locked = value;
|
this.gridview.locked = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(parentElement: HTMLElement, options: BaseGridOptions) {
|
constructor(container: HTMLElement, options: BaseGridOptions) {
|
||||||
super(parentElement, options.disableAutoResizing);
|
super(document.createElement('div'), options.disableAutoResizing);
|
||||||
this.element.style.height = '100%';
|
this.element.style.height = '100%';
|
||||||
this.element.style.width = '100%';
|
this.element.style.width = '100%';
|
||||||
|
|
||||||
this._classNames = new Classnames(this.element);
|
this._classNames = new Classnames(this.element);
|
||||||
this._classNames.setClassNames(options.className ?? '');
|
this._classNames.setClassNames(options.className ?? '');
|
||||||
|
|
||||||
|
// the container is owned by the third-party, do not modify/delete it
|
||||||
|
container.appendChild(this.element);
|
||||||
|
|
||||||
this.gridview = new Gridview(
|
this.gridview = new Gridview(
|
||||||
!!options.proportionalLayout,
|
!!options.proportionalLayout,
|
||||||
options.styles,
|
options.styles,
|
||||||
|
@ -113,8 +113,8 @@ export class GridviewComponent
|
|||||||
this._deserializer = value;
|
this._deserializer = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(parentElement: HTMLElement, options: GridviewComponentOptions) {
|
constructor(container: HTMLElement, options: GridviewComponentOptions) {
|
||||||
super(parentElement, {
|
super(container, {
|
||||||
proportionalLayout: options.proportionalLayout ?? true,
|
proportionalLayout: options.proportionalLayout ?? true,
|
||||||
orientation: options.orientation,
|
orientation: options.orientation,
|
||||||
styles: options.hideBorders
|
styles: options.hideBorders
|
||||||
|
@ -195,8 +195,10 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
|||||||
return this._options;
|
return this._options;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(parentElement: HTMLElement, options: PaneviewComponentOptions) {
|
constructor(container: HTMLElement, options: PaneviewComponentOptions) {
|
||||||
super(parentElement, options.disableAutoResizing);
|
super(document.createElement('div'), options.disableAutoResizing);
|
||||||
|
this.element.style.height = '100%';
|
||||||
|
this.element.style.width = '100%';
|
||||||
|
|
||||||
this.addDisposables(
|
this.addDisposables(
|
||||||
this._onDidLayoutChange,
|
this._onDidLayoutChange,
|
||||||
@ -210,6 +212,9 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
|||||||
this._classNames = new Classnames(this.element);
|
this._classNames = new Classnames(this.element);
|
||||||
this._classNames.setClassNames(options.className ?? '');
|
this._classNames.setClassNames(options.className ?? '');
|
||||||
|
|
||||||
|
// the container is owned by the third-party, do not modify/delete it
|
||||||
|
container.appendChild(this.element);
|
||||||
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
|
||||||
this.paneview = new Paneview(this.element, {
|
this.paneview = new Paneview(this.element, {
|
||||||
|
@ -32,7 +32,7 @@ export interface ISplitviewStyles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SplitViewOptions {
|
export interface SplitViewOptions {
|
||||||
orientation: Orientation;
|
orientation?: Orientation;
|
||||||
descriptor?: ISplitViewDescriptor;
|
descriptor?: ISplitViewDescriptor;
|
||||||
proportionalLayout?: boolean;
|
proportionalLayout?: boolean;
|
||||||
styles?: ISplitviewStyles;
|
styles?: ISplitviewStyles;
|
||||||
@ -225,7 +225,7 @@ export class Splitview {
|
|||||||
private readonly container: HTMLElement,
|
private readonly container: HTMLElement,
|
||||||
options: SplitViewOptions
|
options: SplitViewOptions
|
||||||
) {
|
) {
|
||||||
this._orientation = options.orientation;
|
this._orientation = options.orientation ?? Orientation.VERTICAL;
|
||||||
this.element = this.createContainer();
|
this.element = this.createContainer();
|
||||||
|
|
||||||
this.margin = options.margin ?? 0;
|
this.margin = options.margin ?? 0;
|
||||||
|
@ -155,15 +155,17 @@ export class SplitviewComponent
|
|||||||
: this.splitview.orthogonalSize;
|
: this.splitview.orthogonalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(container: HTMLElement, options: SplitviewComponentOptions) {
|
||||||
parentElement: HTMLElement,
|
super(document.createElement('div'), options.disableAutoResizing);
|
||||||
options: SplitviewComponentOptions
|
this.element.style.height = '100%';
|
||||||
) {
|
this.element.style.width = '100%';
|
||||||
super(parentElement, options.disableAutoResizing);
|
|
||||||
|
|
||||||
this._classNames = new Classnames(this.element);
|
this._classNames = new Classnames(this.element);
|
||||||
this._classNames.setClassNames(options.className ?? '');
|
this._classNames.setClassNames(options.className ?? '');
|
||||||
|
|
||||||
|
// the container is owned by the third-party, do not modify/delete it
|
||||||
|
container.appendChild(this.element);
|
||||||
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
|
||||||
this.splitview = new Splitview(this.element, options);
|
this.splitview = new Splitview(this.element, options);
|
||||||
|
@ -318,11 +318,7 @@ export const DockviewReact = React.forwardRef(
|
|||||||
}, [props.prefixHeaderActionsComponent]);
|
}, [props.prefixHeaderActionsComponent]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div style={{ height: '100%', width: '100%' }} ref={domRef}>
|
||||||
className={props.className}
|
|
||||||
style={{ height: '100%', width: '100%' }}
|
|
||||||
ref={domRef}
|
|
||||||
>
|
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -126,11 +126,7 @@ export const GridviewReact = React.forwardRef(
|
|||||||
}, [props.components]);
|
}, [props.components]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div style={{ height: '100%', width: '100%' }} ref={domRef}>
|
||||||
className={props.className}
|
|
||||||
style={{ height: '100%', width: '100%' }}
|
|
||||||
ref={domRef}
|
|
||||||
>
|
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -176,11 +176,7 @@ export const PaneviewReact = React.forwardRef(
|
|||||||
}, [props.onDidDrop]);
|
}, [props.onDidDrop]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div style={{ height: '100%', width: '100%' }} ref={domRef}>
|
||||||
className={props.className}
|
|
||||||
style={{ height: '100%', width: '100%' }}
|
|
||||||
ref={domRef}
|
|
||||||
>
|
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -126,11 +126,7 @@ export const SplitviewReact = React.forwardRef(
|
|||||||
}, [props.components]);
|
}, [props.components]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div style={{ height: '100%', width: '100%' }} ref={domRef}>
|
||||||
className={props.className}
|
|
||||||
style={{ height: '100%', width: '100%' }}
|
|
||||||
ref={domRef}
|
|
||||||
>
|
|
||||||
{portals}
|
{portals}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -176,23 +176,21 @@ const DockviewDemo = (props: { theme?: string }) => {
|
|||||||
setPending([]);
|
setPending([]);
|
||||||
}, [pending]);
|
}, [pending]);
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
React.useEffect(() => {
|
||||||
setApi(event.api);
|
if (!api) {
|
||||||
setPanels([]);
|
return;
|
||||||
setGroups([]);
|
}
|
||||||
setActivePanel(undefined);
|
|
||||||
setActiveGroup(undefined);
|
|
||||||
addLogLine(`Dockview Is Ready`);
|
|
||||||
|
|
||||||
event.api.onDidAddPanel((event) => {
|
const disposables = [
|
||||||
|
api.onDidAddPanel((event) => {
|
||||||
setPanels((_) => [..._, event.id]);
|
setPanels((_) => [..._, event.id]);
|
||||||
addLogLine(`Panel Added ${event.id}`);
|
addLogLine(`Panel Added ${event.id}`);
|
||||||
});
|
}),
|
||||||
event.api.onDidActivePanelChange((event) => {
|
api.onDidActivePanelChange((event) => {
|
||||||
setActivePanel(event?.id);
|
setActivePanel(event?.id);
|
||||||
addLogLine(`Panel Activated ${event?.id}`);
|
addLogLine(`Panel Activated ${event?.id}`);
|
||||||
});
|
}),
|
||||||
event.api.onDidRemovePanel((event) => {
|
api.onDidRemovePanel((event) => {
|
||||||
setPanels((_) => {
|
setPanels((_) => {
|
||||||
const next = [..._];
|
const next = [..._];
|
||||||
next.splice(
|
next.splice(
|
||||||
@ -203,24 +201,24 @@ const DockviewDemo = (props: { theme?: string }) => {
|
|||||||
return next;
|
return next;
|
||||||
});
|
});
|
||||||
addLogLine(`Panel Removed ${event.id}`);
|
addLogLine(`Panel Removed ${event.id}`);
|
||||||
});
|
}),
|
||||||
|
|
||||||
event.api.onDidAddGroup((event) => {
|
api.onDidAddGroup((event) => {
|
||||||
setGroups((_) => [..._, event.id]);
|
setGroups((_) => [..._, event.id]);
|
||||||
addLogLine(`Group Added ${event.id}`);
|
addLogLine(`Group Added ${event.id}`);
|
||||||
});
|
}),
|
||||||
|
|
||||||
event.api.onDidMovePanel((event) => {
|
api.onDidMovePanel((event) => {
|
||||||
addLogLine(`Panel Moved ${event.panel.id}`);
|
addLogLine(`Panel Moved ${event.panel.id}`);
|
||||||
});
|
}),
|
||||||
|
|
||||||
event.api.onDidMaximizedGroupChange((event) => {
|
api.onDidMaximizedGroupChange((event) => {
|
||||||
addLogLine(
|
addLogLine(
|
||||||
`Group Maximized Changed ${event.group.api.id} [${event.isMaximized}]`
|
`Group Maximized Changed ${event.group.api.id} [${event.isMaximized}]`
|
||||||
);
|
);
|
||||||
});
|
}),
|
||||||
|
|
||||||
event.api.onDidRemoveGroup((event) => {
|
api.onDidRemoveGroup((event) => {
|
||||||
setGroups((_) => {
|
setGroups((_) => {
|
||||||
const next = [..._];
|
const next = [..._];
|
||||||
next.splice(
|
next.splice(
|
||||||
@ -231,17 +229,20 @@ const DockviewDemo = (props: { theme?: string }) => {
|
|||||||
return next;
|
return next;
|
||||||
});
|
});
|
||||||
addLogLine(`Group Removed ${event.id}`);
|
addLogLine(`Group Removed ${event.id}`);
|
||||||
});
|
}),
|
||||||
|
|
||||||
event.api.onDidActiveGroupChange((event) => {
|
api.onDidActiveGroupChange((event) => {
|
||||||
setActiveGroup(event?.id);
|
setActiveGroup(event?.id);
|
||||||
addLogLine(`Group Activated ${event?.id}`);
|
addLogLine(`Group Activated ${event?.id}`);
|
||||||
});
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const loadLayout = () => {
|
||||||
const state = localStorage.getItem('dv-demo-state');
|
const state = localStorage.getItem('dv-demo-state');
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
try {
|
try {
|
||||||
event.api.fromJSON(JSON.parse(state));
|
api.fromJSON(JSON.parse(state));
|
||||||
return;
|
return;
|
||||||
} catch {
|
} catch {
|
||||||
localStorage.removeItem('dv-demo-state');
|
localStorage.removeItem('dv-demo-state');
|
||||||
@ -249,7 +250,18 @@ const DockviewDemo = (props: { theme?: string }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig(event.api);
|
defaultConfig(api);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadLayout();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposables.forEach((disposable) => disposable.dispose());
|
||||||
|
};
|
||||||
|
}, [api]);
|
||||||
|
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
setApi(event.api);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [watermark, setWatermark] = React.useState<boolean>(false);
|
const [watermark, setWatermark] = React.useState<boolean>(false);
|
||||||
|
@ -88,7 +88,6 @@ const GroupAction = (props: {
|
|||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (group) {
|
if (group) {
|
||||||
|
|
||||||
props.api.addFloatingGroup(group, {
|
props.api.addFloatingGroup(group, {
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 300,
|
height: 300,
|
||||||
@ -99,7 +98,6 @@ const GroupAction = (props: {
|
|||||||
right: 50,
|
right: 50,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -3,5 +3,9 @@ import { RecoilRoot } from 'recoil';
|
|||||||
|
|
||||||
// Default implementation, that you can customize
|
// Default implementation, that you can customize
|
||||||
export default function Root({ children }) {
|
export default function Root({ children }) {
|
||||||
return <RecoilRoot>{children}</RecoilRoot>;
|
return (
|
||||||
|
<React.StrictMode>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user