mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 04:48:53 +00:00
refactor(editor): improve implementation of lit adapter (#12101)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved mobile experience by disabling certain toolbars and slash menu features on mobile devices. - Introduced new modular extension classes for editor and view customization, enabling more flexible configuration of themes, AI features, and editor enhancements. - Added clipboard adapter configurations for a wide range of data types, improving clipboard compatibility. - Added a new theme extension specifically for preview scenarios. - Provided new hooks for block scope management in document modules. - **Refactor** - Streamlined editor extension setup, consolidating options and reducing complexity for better maintainability. - Reorganized mobile-specific extension exports for clearer usage. - Refined React-to-Lit rendering API by introducing a typed alias and updating related function signatures. - Simplified extension registration by splitting monolithic view extension into separate common and editor view extensions. - **Bug Fixes** - Corrected naming inconsistencies in internal effect tracking. - **Chores** - Updated type exports and documentation comments for improved clarity and consistency. - Removed unused or redundant exports and functions to clean up the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
export {
|
||||
type ElementOrFactory,
|
||||
type ReactToLit,
|
||||
useLitPortal,
|
||||
useLitPortalFactory,
|
||||
} from './lit-portal';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { html, LitElement } from 'lit';
|
||||
import { html, LitElement, type TemplateResult } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
@@ -82,59 +82,60 @@ type LitPortal = {
|
||||
litElement: LitReactPortal;
|
||||
};
|
||||
|
||||
export type ReactToLit = (
|
||||
elementOrFactory: ElementOrFactory,
|
||||
rerendering?: boolean
|
||||
) => TemplateResult;
|
||||
|
||||
// returns a factory function that renders a given element to a lit template
|
||||
export const useLitPortalFactory = () => {
|
||||
const [portals, setPortals] = useState<LitPortal[]>([]);
|
||||
|
||||
return [
|
||||
useCallback(
|
||||
(
|
||||
elementOrFactory: React.ReactElement | (() => React.ReactElement),
|
||||
rerendering = true
|
||||
) => {
|
||||
const element =
|
||||
typeof elementOrFactory === 'function'
|
||||
? elementOrFactory()
|
||||
: elementOrFactory;
|
||||
return createLitPortalAnchor(event => {
|
||||
setPortals(portals => {
|
||||
const { name, target } = event;
|
||||
const id = target.portalId;
|
||||
let newPortals = portals;
|
||||
const updatePortals = () => {
|
||||
let oldPortalIndex = portals.findIndex(
|
||||
p => p.litElement === target
|
||||
);
|
||||
oldPortalIndex =
|
||||
oldPortalIndex === -1 ? portals.length : oldPortalIndex;
|
||||
newPortals = portals.toSpliced(oldPortalIndex, 1, {
|
||||
id,
|
||||
portal: ReactDOM.createPortal(element, target),
|
||||
litElement: target,
|
||||
});
|
||||
};
|
||||
switch (name) {
|
||||
case 'connectedCallback':
|
||||
updatePortals();
|
||||
const reactToLit: ReactToLit = useCallback(
|
||||
(elementOrFactory, rerendering) => {
|
||||
const element =
|
||||
typeof elementOrFactory === 'function'
|
||||
? elementOrFactory()
|
||||
: elementOrFactory;
|
||||
return createLitPortalAnchor(event => {
|
||||
setPortals(portals => {
|
||||
const { name, target } = event;
|
||||
const id = target.portalId;
|
||||
let newPortals = portals;
|
||||
const updatePortals = () => {
|
||||
let oldPortalIndex = portals.findIndex(
|
||||
p => p.litElement === target
|
||||
);
|
||||
oldPortalIndex =
|
||||
oldPortalIndex === -1 ? portals.length : oldPortalIndex;
|
||||
newPortals = portals.toSpliced(oldPortalIndex, 1, {
|
||||
id,
|
||||
portal: ReactDOM.createPortal(element, target),
|
||||
litElement: target,
|
||||
});
|
||||
};
|
||||
switch (name) {
|
||||
case 'connectedCallback':
|
||||
updatePortals();
|
||||
break;
|
||||
case 'disconnectedCallback':
|
||||
newPortals = portals.filter(p => p.litElement.isConnected);
|
||||
break;
|
||||
case 'willUpdate':
|
||||
if (!target.isConnected || !rerendering) {
|
||||
break;
|
||||
case 'disconnectedCallback':
|
||||
newPortals = portals.filter(p => p.litElement.isConnected);
|
||||
break;
|
||||
case 'willUpdate':
|
||||
if (!target.isConnected || !rerendering) {
|
||||
break;
|
||||
}
|
||||
updatePortals();
|
||||
break;
|
||||
}
|
||||
return newPortals;
|
||||
});
|
||||
}
|
||||
updatePortals();
|
||||
break;
|
||||
}
|
||||
return newPortals;
|
||||
});
|
||||
},
|
||||
[setPortals]
|
||||
),
|
||||
portals,
|
||||
] as const;
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return [reactToLit, portals] as const;
|
||||
};
|
||||
|
||||
// render a react element to a lit template
|
||||
|
||||
Reference in New Issue
Block a user