Skip to content
Merged
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
12 changes: 6 additions & 6 deletions packages/markput/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export {MarkedInput} from './src/components/MarkedInput'
export {createMarkedInput} from './src/utils/functions/createMarkedInput'
export {useMark} from './src/utils/hooks/useMark'
export {useOverlay} from './src/utils/hooks/useOverlay'
export {useListener} from './src/utils/hooks/useListener'
export {createMarkedInput} from './src/lib/utils/createMarkedInput'
export {useMark} from './src/lib/hooks/useMark'
export {useOverlay} from './src/lib/hooks/useOverlay'
export {useListener} from './src/lib/hooks/useListener'

export type {MarkedInputProps, MarkedInputComponent} from './src/components/MarkedInput'
export type {MarkHandler} from './src/utils/hooks/useMark'
export type {OverlayHandler} from './src/utils/hooks/useOverlay'
export type {MarkHandler} from './src/lib/classes/MarkHandler'
export type {OverlayHandler} from './src/lib/hooks/useOverlay'
export type {MarkedInputHandler, Option, ConfiguredMarkedInput, MarkProps, OverlayProps} from './src/types'

// Re-export ParserV2 functions and types
Expand Down
14 changes: 4 additions & 10 deletions packages/markput/src/components/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {memo} from 'react'
import {resolveSlot, resolveSlotProps} from '../utils/functions/resolveSlot'
import {useListener} from '../utils/hooks/useListener'
import {useStore} from '../utils/hooks/useStore'
import {resolveSlot, resolveSlotProps} from '../lib/utils/resolveSlot'
import {useListener} from '../lib/hooks/useListener'
import {useStore} from '../lib/hooks/useStore'
import {Token} from './Token'
import {SystemEvent} from '@markput/core'

Expand All @@ -20,13 +20,7 @@ export const Container = memo(() => {
true
)

useListener(
'input',
() => {
bus.send(SystemEvent.Change)
},
[]
)
useListener('input', () => bus.send(SystemEvent.Change), [])

return (
<ContainerComponent ref={refs.setContainer} {...containerProps} className={className} style={style}>
Expand Down
6 changes: 3 additions & 3 deletions packages/markput/src/components/EditableSpan.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {ClipboardEvent} from 'react'
import {resolveSlot, resolveSlotProps} from '../utils/functions/resolveSlot'
import {useMark} from '../utils/hooks/useMark'
import {useStore} from '../utils/hooks/useStore'
import {resolveSlot, resolveSlotProps} from '../lib/utils/resolveSlot'
import {useMark} from '../lib/hooks/useMark'
import {useStore} from '../lib/hooks/useStore'

//Editable block - edit text here
export const EditableSpan = () => {
Expand Down
28 changes: 28 additions & 0 deletions packages/markput/src/components/MarkRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type {MarkToken} from '@markput/core'
import {useStore} from '../lib/hooks/useStore'
import {useSlot} from '../lib/hooks/useSlot'
import {useToken} from '../lib/providers/TokenProvider'
import type {MarkProps} from '../types'
// eslint-disable-next-line import/no-cycle
import {Token} from './Token'

/** Renders a MarkToken using the resolved Mark component from useSlot */
export function MarkRenderer() {
const node = useToken() as MarkToken
const {options, key} = useStore(store => ({options: store.props.options, key: store.key}), true)

const option = options?.[node.descriptor.index]

const children = node.children.map(child => <Token key={key.get(child)} mark={child} isNested />)

const markPropsData: MarkProps = {
value: node.value,
meta: node.meta,
nested: node.nested?.content,
children: node.children.length > 0 ? children : undefined,
}

const [Mark, props] = useSlot('mark', option, markPropsData)

return <Mark {...props} />
}
64 changes: 0 additions & 64 deletions packages/markput/src/components/Piece.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions packages/markput/src/components/StoreProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type {ReactNode} from 'react'
import {useEffect, useState} from 'react'
import {Store, DEFAULT_CLASS_NAME} from '@markput/core'
import type {MarkedInputProps} from './MarkedInput'
import {StoreContext} from '../utils/providers/StoreContext'
import {mergeClassNames, mergeStyles} from '../utils/functions/resolveSlot'
import {StoreContext} from '../lib/providers/StoreContext'
import {mergeClassNames, mergeStyles} from '../lib/utils/resolveSlot'
import {DEFAULT_OPTIONS} from '../constants'

interface StoreProviderProps {
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/components/Suggestions/Suggestions.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {RefObject} from 'react'
import {useMemo, useState} from 'react'
import {useDownOf} from '../../utils/hooks/useDownOf'
import {useOverlay} from '../../utils/hooks/useOverlay'
import {useDownOf} from '../../lib/hooks/useDownOf'
import {useOverlay} from '../../lib/hooks/useOverlay'
import {KEYBOARD} from '@markput/core'

export const Suggestions = () => {
Expand Down
6 changes: 3 additions & 3 deletions packages/markput/src/components/TextSpan.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {ClipboardEvent} from 'react'
import {useRef} from 'react'
import {resolveSlot, resolveSlotProps} from '../utils/functions/resolveSlot'
import {useStore} from '../utils/hooks/useStore'
import {useToken} from '../utils/providers/TokenProvider'
import {resolveSlot, resolveSlotProps} from '../lib/utils/resolveSlot'
import {useStore} from '../lib/hooks/useStore'
import {useToken} from '../lib/providers/TokenProvider'

/**
* TextSpan - renders text tokens (non-annotated text)
Expand Down
50 changes: 22 additions & 28 deletions packages/markput/src/components/Token.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import {memo} from 'react'
import type {Token as TokenType} from '@markput/core'
import {TokenProvider} from '../utils/providers/TokenProvider'
// eslint-disable-next-line import/no-cycle -- Legitimate recursive component relationship: Token renders Piece, Piece renders Token for children
import {Piece} from './Piece'
import {TokenProvider} from '../lib/providers/TokenProvider'
// eslint-disable-next-line import/no-cycle
import {MarkRenderer} from './MarkRenderer'
import {TextSpan} from './TextSpan'

/**
* Token component - renders a single token (text or mark) with recursive support for nested marks
*
* This component handles both TextToken and MarkToken types:
* - TextToken: renders as TextSpan (editable text) when isNested=false, or plain text when isNested=true
* - MarkToken: renders as Piece (custom Mark component with optional nested children)
*
* The isNested prop determines editing behavior:
* - isNested=false (default): TextTokens are editable contentEditable spans
* - isNested=true: TextTokens render as plain text within nested marks
*
* The component is memoized for performance and provides the token via context
* to child components through TokenProvider.
*/
export const Token = memo(({mark, isNested = false}: {mark: TokenType; isNested?: boolean}) => (
<TokenProvider value={mark}>
{mark.type === 'mark' ? (
<Piece />
) : isNested ? (
// For nested text tokens, render as plain text without contentEditable
mark.content
) : (
/** Renders a token - marks via MarkRenderer, text via TextSpan or plain text if nested */
export const Token = memo(({mark, isNested = false}: {mark: TokenType; isNested?: boolean}) => {
if (mark.type === 'mark') {
return (
<TokenProvider value={mark}>
<MarkRenderer />
</TokenProvider>
)
}

if (isNested) {
return <>{mark.content}</>
}

return (
<TokenProvider value={mark}>
<TextSpan />
)}
</TokenProvider>
))
</TokenProvider>
)
})

Token.displayName = 'Token'
4 changes: 2 additions & 2 deletions packages/markput/src/components/Whisper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {memo, useEffect} from 'react'
import {useStore} from '../utils/hooks/useStore'
import {useSlot} from '../utils/hooks/useSlot'
import {useStore} from '../lib/hooks/useStore'
import {useSlot} from '../lib/hooks/useSlot'
import {Suggestions} from './Suggestions'

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useEffect} from 'react'
import {useStore} from '../../utils/hooks/useStore'
import {useStore} from '../../lib/hooks/useStore'
import {KEYBOARD, SystemEvent} from '@markput/core'

export function useCloseOverlayByEsc() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useEffect} from 'react'
import {useStore} from '../../utils/hooks/useStore'
import {useStore} from '../../lib/hooks/useStore'
import {SystemEvent} from '@markput/core'

export function useCloseOverlayByOutsideClick() {
Expand Down
6 changes: 3 additions & 3 deletions packages/markput/src/features/events/useKeyDown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {deleteMark, KEYBOARD} from '@markput/core'
import {useDownOf} from '../../utils/hooks/useDownOf'
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useDownOf} from '../../lib/hooks/useDownOf'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'

//TODO Focus on mark and attribute for this
//TODO different rules for editable
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/events/useSystemListeners.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {SystemEvent, annotate, createNewSpan, toString} from '@markput/core'
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'

//TODO upgrade to full members of react events to external
export function useSystemListeners() {
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/focus/useFocusOnEmptyInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'

export const useFocusOnEmptyInput = () => {
const store = useStore()
Expand Down
2 changes: 1 addition & 1 deletion packages/markput/src/features/focus/useFocusRecovery.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useEffect} from 'react'
import {useStore} from '../../utils/hooks/useStore'
import {useStore} from '../../lib/hooks/useStore'

export const useFocusRecovery = () => {
const store = useStore()
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/focus/useFocusedNode.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'

export const useFocusedNode = () => {
const store = useStore()
Expand Down
2 changes: 1 addition & 1 deletion packages/markput/src/features/focus/useTextSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useEffect, useRef} from 'react'
import {useStore} from '../../utils/hooks/useStore'
import {useStore} from '../../lib/hooks/useStore'

export function useTextSelection() {
const store = useStore()
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/overlay/useCheckTrigger.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useCallback} from 'react'
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'
import type {OverlayTrigger} from '@markput/core'
import {SystemEvent} from '@markput/core'

Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/overlay/useTrigger.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {SystemEvent, TriggerFinder} from '@markput/core'
import type {Option} from '../../types'
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'

export const useTrigger = () => {
const store = useStore()
Expand Down
4 changes: 2 additions & 2 deletions packages/markput/src/features/parsing/useValueParser.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useEffect, useRef} from 'react'
import {useListener} from '../../utils/hooks/useListener'
import {useStore} from '../../utils/hooks/useStore'
import {useListener} from '../../lib/hooks/useListener'
import {useStore} from '../../lib/hooks/useStore'
import type {Store} from '@markput/core'
import {Parser, SystemEvent, findGap, getClosestIndexes} from '@markput/core'

Expand Down
2 changes: 1 addition & 1 deletion packages/markput/src/features/useMarkedInputHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {ForwardedRef} from 'react'
import {useImperativeHandle} from 'react'
import type {MarkedInputHandler} from '../types'
import type {Store} from '@markput/core'
import {useStore} from '../utils/hooks/useStore'
import {useStore} from '../lib/hooks/useStore'

const initHandler = (store: Store): MarkedInputHandler => ({
get container() {
Expand Down
Loading