Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(richtext-lexical): add noImplicitAny to the richtext-lexical package #8763

Open
wants to merge 5 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ type Props = {
// Inside of fields.data however, that sub-blocks blockName property does not exist at all.
function removeUndefinedAndNullAndEmptyArraysRecursively(obj: object) {
for (const key in obj) {
const value = obj[key]
const value = obj[key as keyof object] as unknown
if (Array.isArray(value) && !value?.length) {
delete obj[key]
delete obj[key as keyof object]
} else if (value && typeof value === 'object') {
removeUndefinedAndNullAndEmptyArraysRecursively(value)
} else if (value === undefined || value === null) {
delete obj[key]
delete obj[key as keyof object]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const BlockComponent: React.FC<Props> = (props) => {
}, [config.routes.api, config.serverURL, schemaFieldsPath, id]) // DO NOT ADD FORMDATA HERE! Adding formData will kick you out of sub block editors while writing.

const onChange = useCallback(
async ({ formState: prevFormState }) => {
async ({ formState: prevFormState }: { formState: FormState }) => {
const { state: formState } = await getFormState({
apiRoute: config.routes.api,
body: {
Expand Down
25 changes: 15 additions & 10 deletions packages/richtext-lexical/src/features/blocks/client/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'

import type { I18nClient } from '@payloadcms/translations'
import type { BlocksFieldClient } from 'payload'

import { getTranslation } from '@payloadcms/translations'
Expand Down Expand Up @@ -44,8 +45,8 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>
}

const componentMapRenderedBlockPath = `lexical_internal_feature.blocks.fields.lexical_blocks`
const blocksField: BlocksFieldClient = richTextComponentMap.get(
componentMapRenderedBlockPath,
const blocksField = (
richTextComponentMap.get(componentMapRenderedBlockPath) as BlocksFieldClient[]
)?.[0]

const clientBlock = blocksField.blocks.find((_block) => _block.slug === blockSlug)
Expand All @@ -65,7 +66,7 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>
} as SlashMenuItem
}),
key: 'blocks',
label: ({ i18n }) => {
label: ({ i18n }: { i18n: I18nClient<object, 'lexical:blocks:label'> }) => {
return i18n.t('lexical:blocks:label')
},
}
Expand All @@ -84,8 +85,8 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>

const componentMapRenderedBlockPath = `lexical_internal_feature.blocks.fields.lexical_inline_blocks`

const blocksField: BlocksFieldClient = richTextComponentMap.get(
componentMapRenderedBlockPath,
const blocksField = (
richTextComponentMap.get(componentMapRenderedBlockPath) as BlocksFieldClient[]
)?.[0]

const clientBlock = blocksField.blocks.find(
Expand All @@ -109,7 +110,11 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>
} as SlashMenuItem
}),
key: 'inlineBlocks',
label: ({ i18n }) => {
label: ({
i18n,
}: {
i18n: I18nClient<object, 'lexical:blocks:inlineBlocks:label'>
}) => {
return i18n.t('lexical:blocks:inlineBlocks:label')
},
}
Expand All @@ -132,8 +137,8 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>
return blockSlug
}
const componentMapRenderedBlockPath = `lexical_internal_feature.blocks.fields.lexical_blocks`
const blocksField: BlocksFieldClient = richTextComponentMap.get(
componentMapRenderedBlockPath,
const blocksField = (
richTextComponentMap.get(componentMapRenderedBlockPath) as BlocksFieldClient[]
)?.[0]

const clientBlock = blocksField.blocks.find((_block) => _block.slug === blockSlug)
Expand Down Expand Up @@ -172,8 +177,8 @@ export const BlocksFeatureClient = createClientFeature<BlocksFeatureClientProps>
}

const componentMapRenderedBlockPath = `lexical_internal_feature.blocks.fields.lexical_inline_blocks`
const blocksField: BlocksFieldClient = richTextComponentMap.get(
componentMapRenderedBlockPath,
const blocksField = (
richTextComponentMap.get(componentMapRenderedBlockPath) as BlocksFieldClient[]
)?.[0]

const clientBlock = blocksField.blocks.find(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck - not worth it migrate jsdoc to tsdoc
'use client'
// Copied & modified from https://github.com/lodash/lodash/blob/main/src/debounce.ts
/*
Expand Down Expand Up @@ -242,4 +244,5 @@ function debounce(func, wait, options) {
return debounced
}

// eslint-disable-next-line no-restricted-exports
export default debounce
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,15 @@ const Component: React.FC<Props> = (props) => {
})
}, [editor, nodeKey])

const updateRelationship = React.useCallback(
({ doc }) => {
setParams({
...initialParams,
cacheBust, // do this to get the usePayloadAPI to re-fetch the data even though the URL string hasn't changed
})

closeDrawer()
dispatchCacheBust()
},
[cacheBust, setParams, closeDrawer],
)
const updateRelationship = React.useCallback(() => {
setParams({
...initialParams,
cacheBust, // do this to get the usePayloadAPI to re-fetch the data even though the URL string hasn't changed
})

closeDrawer()
dispatchCacheBust()
}, [cacheBust, setParams, closeDrawer])

const $onDelete = useCallback(
(payload: KeyboardEvent) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const RelationshipDrawerComponent: React.FC<Props> = ({ enabledCollectionSlugs }
}, [editor, openDrawer])

const onSelect = useCallback(
({ collectionSlug, docID }) => {
({ collectionSlug, docID }: { collectionSlug: string; docID: number | string }) => {
insertRelationship({
editor,
relationTo: collectionSlug,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ function InlineToolbar({
const isLinkEditorVisible =
possibleLinkEditor !== null &&
'style' in possibleLinkEditor &&
possibleLinkEditor?.style?.['opacity'] === '1'
possibleLinkEditor?.style?.['opacity' as keyof typeof possibleLinkEditor.style] === '1'

const rootElement = editor.getRootElement()
if (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client'
import type { ClientCollectionConfig, Data } from 'payload'
import type { ClientCollectionConfig, Data, FormState, JsonObject } from 'payload'

import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection.js'
Expand Down Expand Up @@ -179,7 +179,7 @@ const Component: React.FC<ElementProps> = (props) => {
).collections?.[relatedCollection.slug]?.hasExtraFields

const onExtraFieldsDrawerSubmit = useCallback(
(_, data) => {
(_: FormState, data: JsonObject) => {
// Update lexical node (with key nodeKey) with new data
editor.update(() => {
const uploadNode: null | UploadNode = $getNodeByKey(nodeKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const UploadDrawerComponent: React.FC<Props> = ({ enabledCollectionSlugs }) => {

const [replaceNodeKey, setReplaceNodeKey] = useState<null | string>(null)

const [ListDrawer, ListDrawerToggler, { closeDrawer, openDrawer }] = useListDrawer({
const [ListDrawer, _ListDrawerToggler, { closeDrawer, openDrawer }] = useListDrawer({
collectionSlugs: enabledCollectionSlugs,
uploads: true,
})
Expand All @@ -77,7 +77,7 @@ const UploadDrawerComponent: React.FC<Props> = ({ enabledCollectionSlugs }) => {
}, [editor, openDrawer])

const onSelect = useCallback(
({ collectionSlug, docID }) => {
({ collectionSlug, docID }: { collectionSlug: string; docID: number | string }) => {
insertUpload({
editor,
relationTo: collectionSlug,
Expand Down
10 changes: 6 additions & 4 deletions packages/richtext-lexical/src/field/Field.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'
import type { SerializedEditorState } from 'lexical'
import type { Validate } from 'payload'

import {
FieldDescription,
Expand All @@ -17,9 +18,9 @@ import type { SanitizedClientEditorConfig } from '../lexical/config/types.js'
import type { LexicalRichTextFieldProps } from '../types.js'

import { LexicalProvider } from '../lexical/LexicalProvider.js'
import '../lexical/theme/EditorTheme.scss'
import './bundled.css'
import './index.scss'
import '../lexical/theme/EditorTheme.scss'

const baseClass = 'rich-text-lexical'

Expand Down Expand Up @@ -50,11 +51,13 @@ const RichTextComponent: React.FC<

const editDepth = useEditDepth()

const memoizedValidate = useCallback(
const memoizedValidate = useCallback<Validate>(
(value, validationOptions) => {
if (typeof validate === 'function') {
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
return validate(value, { ...validationOptions, props, required })
}
return true
},
// Important: do not add props to the dependencies array.
// This would cause an infinite loop and endless re-rendering.
Expand All @@ -65,7 +68,6 @@ const RichTextComponent: React.FC<

const fieldType = useField<SerializedEditorState>({
path: pathFromContext ?? pathFromProps ?? name,
// @ts-expect-error: TODO: Fix this
validate: memoizedValidate,
})

Expand Down Expand Up @@ -133,7 +135,7 @@ const RichTextComponent: React.FC<
)
}

function fallbackRender({ error }): React.ReactElement {
function fallbackRender({ error }: { error: Error }) {
// Call resetErrorBoundary() to reset the error boundary and retry the render.

return (
Expand Down
12 changes: 8 additions & 4 deletions packages/richtext-lexical/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte
})
}

let features: FeatureProviderServer<any, any, any>[] = []
let features: FeatureProviderServer<unknown, unknown, unknown>[] = []
let resolvedFeatureMap: ResolvedServerFeatureMap

let finalSanitizedEditorConfig: SanitizedServerEditorConfig // For server only
Expand Down Expand Up @@ -123,12 +123,12 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte

const featureI18n = finalSanitizedEditorConfig.features.i18n
for (const lang in i18n) {
if (!featureI18n[lang]) {
featureI18n[lang] = {
if (!featureI18n[lang as keyof typeof featureI18n]) {
featureI18n[lang as keyof typeof featureI18n] = {
lexical: {},
}
}

// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
featureI18n[lang].lexical.general = i18n[lang]
}

Expand Down Expand Up @@ -212,6 +212,8 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte
) {
return value
}
// TO-DO: We should not use context, as it is intended for external use only
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const context: any = _context
const nodeIDMap: {
[key: string]: SerializedLexicalNode
Expand Down Expand Up @@ -441,6 +443,8 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte
return value
}

// TO-DO: We should not use context, as it is intended for external use only
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const context: any = _context
const nodeIDMap: {
[key: string]: SerializedLexicalNode
Expand Down
9 changes: 8 additions & 1 deletion packages/richtext-lexical/src/lexical/LexicalProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ export type LexicalProviderProps = {
value: SerializedEditorState
}

const NestProviders = ({ children, providers }) => {
const NestProviders = ({
children,
providers,
}: {
children: React.ReactNode
// eslint-disable-next-line @typescript-eslint/no-explicit-any
providers: any[]
}) => {
if (!providers?.length) {
return children
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ export const sanitizeServerFeatures = (

if (feature?.i18n) {
for (const lang in feature.i18n) {
if (!sanitized.i18n[lang]) {
sanitized.i18n[lang] = {
if (!sanitized.i18n[lang as keyof typeof sanitized.i18n]) {
sanitized.i18n[lang as keyof typeof sanitized.i18n] = {
lexical: {},
}
}
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
sanitized.i18n[lang].lexical[feature.key] = feature.i18n[lang]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function useAddBlockHandle(
}, [anchorElem, hoveredElement, blockHandleHorizontalOffset])

const handleAddClick = useCallback(
(event) => {
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
let hoveredElementToUse = hoveredElement
if (!hoveredElementToUse?.node) {
return
Expand Down Expand Up @@ -189,6 +189,7 @@ function useAddBlockHandle(
return createPortal(
<React.Fragment>
<button
aria-label="Add block"
className="icon add-block-menu"
onClick={(event) => {
handleAddClick(event)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use client'
export function debounce(func: (...args: any[]) => void, wait: number) {
let timeout
return function (...args: any[]) {
export function debounce(func: (...args: undefined[]) => void, wait: number) {
let timeout: number | string | undefined
return function (...args: undefined[]) {
const later = () => {
clearTimeout(timeout)
timeout = null
timeout = undefined
func(...args)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const DrawerContent: React.FC<Omit<FieldsDrawerProps, 'drawerSlug' | 'dra
}, [config.routes.api, config.serverURL, schemaFieldsPath, id, data])

const onChange = useCallback(
async ({ formState: prevFormState }) => {
async ({ formState: prevFormState }: { formState: FormState }) => {
const { state } = await getFormState({
apiRoute: config.routes.api,
body: {
Expand Down
2 changes: 2 additions & 0 deletions packages/richtext-lexical/src/utilities/generateImportMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { ResolvedServerFeatureMap } from '../features/typesServer.js'

export const getGenerateImportMap =
(args: { resolvedFeatureMap: ResolvedServerFeatureMap }): RichTextAdapter['generateImportMap'] =>
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
({ addToImportMap, baseDir, config, importMap, imports }) => {
addToImportMap('@payloadcms/richtext-lexical/client#RichTextCell')
addToImportMap('@payloadcms/richtext-lexical/client#RichTextField')
Expand All @@ -23,6 +24,7 @@ export const getGenerateImportMap =
imports,
})
} else if (resolvedFeature.componentImports?.length) {
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
resolvedFeature.componentImports.forEach((component) => {
addToImportMap(component)
})
Expand Down
Loading