@markput/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Ruslan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # [Marked Input](https://marked-input.vercel.app) · [![npm version](https://img.shields.io/npm/v/@markput/react.svg?style=flat)](https://www.npmjs.com/package/@markput/react) [![min zipped size](https://img.shields.io/bundlephobia/minzip/@markput/react)](https://bundlephobia.com/package/@markput/react) [![Storybook](https://gw.alipayobjects.com/mdn/ob_info/afts/img/A*CQXNTZfK1vwAAAAAAAAAAABjAQAAAQ/original)](https://marked-input.vercel.app)
2
+
3
+ <img width="521" alt="image" src="https://user-images.githubusercontent.com/37639183/182974441-49e4b247-449a-47ba-a090-2cb3aab7ce44.png">
4
+
5
+ A React component that lets you combine editable text with any component using annotated text.
6
+
7
+ **[Documentation](https://markput.vercel.app)** **[Storybook](https://marked-input.vercel.app)**
8
+
9
+ ## Feature
10
+
11
+ - Powerful annotations tool: add, edit, remove, visualize
12
+ - Nested marks support
13
+ - Support for custom syntax patterns (e.g., HTML, markdown)
14
+ - TypeScript
15
+ - Support for any components
16
+ - Flexible and customizable
17
+ - Two ways to configure
18
+ - Helpers for processing text
19
+ - Hooks for advanced components
20
+ - Button handling (Left, Right, Delete, Backspace, Esc)
21
+ - Overlay with the suggestions component by default
22
+ - Zero dependencies
23
+ - Cross selection
24
+
25
+ ## Installation
26
+
27
+ You can install the package via npm:
28
+
29
+ ```
30
+ npm install @markput/react
31
+ ```
32
+
33
+ ## Contributing
34
+
35
+ If you want to contribute, you are welcome! Create an issue or start a discussion.
package/index.css ADDED
@@ -0,0 +1 @@
1
+ ._Container_1lmfr_1{min-height:1.4em}._Container_1lmfr_1 span{outline:none;white-space:pre-wrap}._Suggestions_1lmfr_10{border:1px solid #ccc;max-height:186px;overflow-y:auto;padding-left:0;position:fixed;background:#fff;width:fit-content;min-width:100px;margin-top:0;margin-bottom:0;transition:1.1s ease-out;filter:blur(0);transform:scale(1);opacity:1;visibility:visible;color:#000;border-radius:4%;box-shadow:0 3px 6px -2px #0009}._Suggestions_1lmfr_10 li{padding:.5rem}._Suggestions_1lmfr_10 li:hover,._suggestionActive_1lmfr_38{background-color:#cce9ff;color:#2589f5;cursor:pointer}
package/index.d.ts ADDED
@@ -0,0 +1,261 @@
1
+ import { annotate } from '@markput/core';
2
+ import type { ComponentType } from 'react';
3
+ import type { CoreMarkputProps } from '@markput/core';
4
+ import type { CoreOption } from '@markput/core';
5
+ import type { CSSProperties } from 'react';
6
+ import { denote } from '@markput/core';
7
+ import type { DependencyList } from 'react';
8
+ import type { ElementType } from 'react';
9
+ import type { EventKey } from '@markput/core';
10
+ import type { ForwardedRef } from 'react';
11
+ import type { HTMLAttributes } from 'react';
12
+ import type { Listener } from '@markput/core';
13
+ import { MarkToken } from '@markput/core';
14
+ import { Markup } from '@markput/core';
15
+ import type { OverlayMatch } from '@markput/core';
16
+ import type { OverlayTrigger } from '@markput/core';
17
+ import type { ReactNode } from 'react';
18
+ import type { RefObject } from 'react';
19
+ import type { Store } from '@markput/core';
20
+ import { TextToken } from '@markput/core';
21
+ import { Token } from '@markput/core';
22
+
23
+ export { annotate }
24
+
25
+ /**
26
+ * Data attributes with automatic camelCase to kebab-case conversion
27
+ */
28
+ declare type DataAttributes = Record<`data${Capitalize<string>}`, string | number | boolean | undefined>;
29
+
30
+ export { denote }
31
+
32
+ /**
33
+ * @function
34
+ */
35
+ export declare const MarkedInput: MarkedInputComponent;
36
+
37
+ export declare interface MarkedInputComponent {
38
+ <TMarkProps = MarkProps, TOverlayProps = OverlayProps>(props: MarkedInputProps<TMarkProps, TOverlayProps>): JSX.Element | null;
39
+ displayName?: string;
40
+ }
41
+
42
+ export declare interface MarkedInputHandler {
43
+ /** Container element */
44
+ readonly container: HTMLDivElement | null;
45
+ /** Overlay element if exists */
46
+ readonly overlay: HTMLElement | null;
47
+ focus(): void;
48
+ }
49
+
50
+ /**
51
+ * Props for MarkedInput component.
52
+ *
53
+ * @template TMarkProps - Type of props for the global Mark component
54
+ * @template TOverlayProps - Type of props for the global Overlay component
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * <MarkedInput<ChipProps>
59
+ * Mark={Chip}
60
+ * options={[{
61
+ * markup: '@[__value__]',
62
+ * mark: { label: 'Click me' }
63
+ * }]}
64
+ * />
65
+ * ```
66
+ */
67
+ export declare interface MarkedInputProps<TMarkProps = MarkProps, TOverlayProps = OverlayProps> extends CoreMarkputProps {
68
+ /** Ref to handler */
69
+ ref?: ForwardedRef<MarkedInputHandler>;
70
+ /** Global component used for rendering markups (fallback for option.mark.slot) */
71
+ Mark?: ComponentType<TMarkProps>;
72
+ /** Global component used for rendering overlays (fallback for option.overlay.slot) */
73
+ Overlay?: ComponentType<TOverlayProps>;
74
+ /**
75
+ * Configuration options for markups and overlays.
76
+ * Each option can specify its own slot component via mark.slot or overlay.slot.
77
+ * Falls back to global Mark/Overlay components when not specified.
78
+ */
79
+ options?: Option_2<TMarkProps, TOverlayProps>[];
80
+ /** Additional classes */
81
+ className?: string;
82
+ /** Additional style */
83
+ style?: CSSProperties;
84
+ /**
85
+ * Override internal components using slots
86
+ * @example
87
+ * slots={{ container: 'div', span: 'span' }}
88
+ */
89
+ slots?: Slots;
90
+ /**
91
+ * Props to pass to slot components
92
+ * @example
93
+ * slotProps={{ container: { onKeyDown: handler }, span: { className: 'custom' } }}
94
+ */
95
+ slotProps?: SlotProps;
96
+ /**
97
+ * Events that trigger overlay display
98
+ * @default 'change'
99
+ */
100
+ showOverlayOn?: OverlayTrigger;
101
+ }
102
+
103
+ export declare class MarkHandler<T extends HTMLElement = HTMLElement> {
104
+ #private;
105
+ readonly ref: RefObject<T>;
106
+ readOnly?: boolean;
107
+ constructor(param: {
108
+ ref: RefObject<T>;
109
+ store: Store;
110
+ token: MarkToken;
111
+ });
112
+ /** Displayed text of the mark */
113
+ get content(): string;
114
+ set content(value: string);
115
+ /** Data value associated with the mark */
116
+ get value(): string | undefined;
117
+ set value(value: string | undefined);
118
+ /** Optional metadata for the mark */
119
+ get meta(): string | undefined;
120
+ set meta(value: string | undefined);
121
+ /** Nesting depth (0 for root-level marks) */
122
+ get depth(): number;
123
+ /** Whether this mark has nested children */
124
+ get hasChildren(): boolean;
125
+ /** Parent mark token (undefined for root-level marks) */
126
+ get parent(): MarkToken | undefined;
127
+ /** Child tokens of this mark */
128
+ get tokens(): Token[];
129
+ /** Update multiple properties in a single operation */
130
+ change: (props: {
131
+ content: string;
132
+ value?: string;
133
+ meta?: string;
134
+ }) => void;
135
+ /** Delete this mark from the editor */
136
+ remove: () => void;
137
+ }
138
+
139
+ declare interface MarkOptions {
140
+ /**
141
+ * @default false
142
+ */
143
+ controlled?: boolean;
144
+ }
145
+
146
+ /**
147
+ * Props passed to Mark components.
148
+ */
149
+ export declare interface MarkProps {
150
+ /** Custom component to render this mark */
151
+ slot?: ComponentType<MarkProps>;
152
+ /** Main content value of the mark */
153
+ value?: string;
154
+ /** Additional metadata for the mark */
155
+ meta?: string;
156
+ /** Nested content as string (raw, unparsed) */
157
+ nested?: string;
158
+ /** Rendered children content (ReactNode) for nested marks */
159
+ children?: ReactNode;
160
+ }
161
+
162
+ export { MarkToken }
163
+
164
+ export { Markup }
165
+
166
+ /**
167
+ * React-specific markup option for defining mark behavior and styling.
168
+ *
169
+ * @template TMarkProps - Type of props for the mark component
170
+ * @template TOverlayProps - Type of props for the overlay component
171
+ *
172
+ * @example
173
+ * const option: Option<ChipProps> = {
174
+ * markup: '@[__value__]',
175
+ * mark: { slot: Chip, label: 'Click' }
176
+ * }
177
+ */
178
+ declare interface Option_2<TMarkProps = MarkProps, TOverlayProps = OverlayProps> extends CoreOption {
179
+ /**
180
+ * Props for the mark component.
181
+ * Can be a static object or a function that transforms MarkProps.
182
+ */
183
+ mark?: TMarkProps | ((props: MarkProps) => TMarkProps);
184
+ /**
185
+ * Props for the overlay component.
186
+ */
187
+ overlay?: TOverlayProps;
188
+ }
189
+ export { Option_2 as Option }
190
+
191
+ export declare interface OverlayHandler {
192
+ /**
193
+ * Style with caret absolute position. Used for placing an overlay.
194
+ */
195
+ style: {
196
+ left: number;
197
+ top: number;
198
+ };
199
+ /**
200
+ * Used for close overlay.
201
+ */
202
+ close: () => void;
203
+ /**
204
+ * Used for insert an annotation instead a triggered value.
205
+ */
206
+ select: (value: {
207
+ value: string;
208
+ meta?: string;
209
+ }) => void;
210
+ /**
211
+ * Overlay match details
212
+ */
213
+ match: OverlayMatch<Option_2>;
214
+ ref: RefObject<HTMLElement>;
215
+ }
216
+
217
+ /**
218
+ * Props for Overlay components.
219
+ */
220
+ export declare interface OverlayProps {
221
+ /** Custom component to render this overlay */
222
+ slot?: ComponentType<OverlayProps>;
223
+ /** Trigger character(s) that activate the overlay */
224
+ trigger?: string;
225
+ /** Data array for suggestions/autocomplete */
226
+ data?: string[];
227
+ }
228
+
229
+ /**
230
+ * Props for each slot component
231
+ */
232
+ declare interface SlotProps {
233
+ /** Props to pass to the container slot */
234
+ container?: HTMLAttributes<HTMLDivElement> & DataAttributes;
235
+ /** Props to pass to the span slot */
236
+ span?: HTMLAttributes<HTMLSpanElement> & DataAttributes;
237
+ }
238
+
239
+ /**
240
+ * Available slots for customizing MarkedInput internal components
241
+ */
242
+ declare interface Slots {
243
+ /** Root container component */
244
+ container?: ElementType<HTMLAttributes<HTMLDivElement>>;
245
+ /** Text span component for rendering text tokens */
246
+ span?: ElementType<HTMLAttributes<HTMLSpanElement>>;
247
+ }
248
+
249
+ export { TextToken }
250
+
251
+ export { Token }
252
+
253
+ export declare function useListener<T>(key: EventKey<T>, listener: Listener<T>, deps?: DependencyList): void;
254
+
255
+ export declare function useListener<K extends keyof HTMLElementEventMap>(key: K, listener: Listener<HTMLElementEventMap[K]>, deps?: DependencyList): void;
256
+
257
+ export declare const useMark: <T extends HTMLElement = HTMLElement>(options?: MarkOptions) => MarkHandler<T>;
258
+
259
+ export declare function useOverlay(): OverlayHandler;
260
+
261
+ export { }