@particle-academy/react-fancy 5.31.0 → 5.32.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/CHANGELOG.md +62 -0
- package/dist/accordion-panel.cjs +8 -8
- package/dist/accordion-panel.js +2 -2
- package/dist/autocomplete.cjs +3 -3
- package/dist/autocomplete.js +2 -2
- package/dist/carousel.cjs +8 -8
- package/dist/carousel.js +2 -2
- package/dist/checkbox-group.cjs +3 -3
- package/dist/checkbox-group.js +2 -2
- package/dist/checkbox.cjs +3 -3
- package/dist/checkbox.js +2 -2
- package/dist/{chunk-TQFQUNV3.js → chunk-2KAJ4L7C.js} +3 -3
- package/dist/{chunk-TQFQUNV3.js.map → chunk-2KAJ4L7C.js.map} +1 -1
- package/dist/{chunk-L5KKMJ2Q.js → chunk-2VIDYJUG.js} +3 -3
- package/dist/{chunk-L5KKMJ2Q.js.map → chunk-2VIDYJUG.js.map} +1 -1
- package/dist/{chunk-3EIB7RPD.cjs → chunk-3Q4NSAEA.cjs} +4 -4
- package/dist/{chunk-3EIB7RPD.cjs.map → chunk-3Q4NSAEA.cjs.map} +1 -1
- package/dist/{chunk-H6F6ZWAG.js → chunk-4HRD4S25.js} +3 -3
- package/dist/{chunk-H6F6ZWAG.js.map → chunk-4HRD4S25.js.map} +1 -1
- package/dist/{chunk-LY7PZEF4.cjs → chunk-6IBBAOQC.cjs} +4 -4
- package/dist/{chunk-LY7PZEF4.cjs.map → chunk-6IBBAOQC.cjs.map} +1 -1
- package/dist/{chunk-RFLPFQFF.js → chunk-BMTTSBHF.js} +3 -3
- package/dist/{chunk-RFLPFQFF.js.map → chunk-BMTTSBHF.js.map} +1 -1
- package/dist/{chunk-ASCATIDJ.js → chunk-BQ77ZWFM.js} +6 -6
- package/dist/{chunk-ASCATIDJ.js.map → chunk-BQ77ZWFM.js.map} +1 -1
- package/dist/{chunk-JM2H642B.cjs → chunk-BVRPDMB7.cjs} +4 -4
- package/dist/{chunk-JM2H642B.cjs.map → chunk-BVRPDMB7.cjs.map} +1 -1
- package/dist/{chunk-JDRKYYXP.cjs → chunk-BZDXX6E3.cjs} +4 -4
- package/dist/{chunk-JDRKYYXP.cjs.map → chunk-BZDXX6E3.cjs.map} +1 -1
- package/dist/{chunk-VUKIFFWK.cjs → chunk-BZZDHDMK.cjs} +5 -5
- package/dist/{chunk-VUKIFFWK.cjs.map → chunk-BZZDHDMK.cjs.map} +1 -1
- package/dist/{chunk-6SO2ZX3J.cjs → chunk-DHIUMQLP.cjs} +4 -4
- package/dist/{chunk-6SO2ZX3J.cjs.map → chunk-DHIUMQLP.cjs.map} +1 -1
- package/dist/chunk-EDYAXGUM.js +27 -0
- package/dist/chunk-EDYAXGUM.js.map +1 -0
- package/dist/{chunk-MRRKDRZU.js → chunk-EIUS2K72.js} +3 -3
- package/dist/{chunk-MRRKDRZU.js.map → chunk-EIUS2K72.js.map} +1 -1
- package/dist/{chunk-6PF5ENWM.js → chunk-F2GAZZVS.js} +3 -3
- package/dist/{chunk-6PF5ENWM.js.map → chunk-F2GAZZVS.js.map} +1 -1
- package/dist/{chunk-VME5743O.js → chunk-FNEPZ33A.js} +3 -3
- package/dist/{chunk-VME5743O.js.map → chunk-FNEPZ33A.js.map} +1 -1
- package/dist/{chunk-JP4C3ROX.js → chunk-FNJDMGJ3.js} +3 -3
- package/dist/{chunk-JP4C3ROX.js.map → chunk-FNJDMGJ3.js.map} +1 -1
- package/dist/{chunk-UA2C2U3M.cjs → chunk-FPZYPD3N.cjs} +4 -4
- package/dist/{chunk-UA2C2U3M.cjs.map → chunk-FPZYPD3N.cjs.map} +1 -1
- package/dist/{chunk-SX4CSO6C.js → chunk-FSRPZYZZ.js} +3 -3
- package/dist/{chunk-SX4CSO6C.js.map → chunk-FSRPZYZZ.js.map} +1 -1
- package/dist/{chunk-IRD6UXDK.cjs → chunk-FVTCPERB.cjs} +5 -5
- package/dist/{chunk-IRD6UXDK.cjs.map → chunk-FVTCPERB.cjs.map} +1 -1
- package/dist/{chunk-FUG3OCGP.js → chunk-G73TVXDQ.js} +3 -3
- package/dist/{chunk-FUG3OCGP.js.map → chunk-G73TVXDQ.js.map} +1 -1
- package/dist/{chunk-LHNC42J3.cjs → chunk-IPNJMHJ3.cjs} +4 -4
- package/dist/{chunk-LHNC42J3.cjs.map → chunk-IPNJMHJ3.cjs.map} +1 -1
- package/dist/{chunk-PIFJECFU.js → chunk-LBU3T2LF.js} +3 -3
- package/dist/{chunk-PIFJECFU.js.map → chunk-LBU3T2LF.js.map} +1 -1
- package/dist/{chunk-YAJYIRQL.cjs → chunk-LLA33GKC.cjs} +4 -4
- package/dist/{chunk-YAJYIRQL.cjs.map → chunk-LLA33GKC.cjs.map} +1 -1
- package/dist/{chunk-HIOMHITU.cjs → chunk-LQFQ2UKU.cjs} +5 -5
- package/dist/{chunk-HIOMHITU.cjs.map → chunk-LQFQ2UKU.cjs.map} +1 -1
- package/dist/{chunk-6ZDXG5VC.js → chunk-NBAHXZHJ.js} +3 -3
- package/dist/{chunk-6ZDXG5VC.js.map → chunk-NBAHXZHJ.js.map} +1 -1
- package/dist/{chunk-IUT3Q2EC.js → chunk-NE3Z4AWP.js} +3 -3
- package/dist/{chunk-IUT3Q2EC.js.map → chunk-NE3Z4AWP.js.map} +1 -1
- package/dist/{chunk-MIUSTEIV.js → chunk-O2ZHORSC.js} +3 -3
- package/dist/{chunk-MIUSTEIV.js.map → chunk-O2ZHORSC.js.map} +1 -1
- package/dist/{chunk-L2FPIFMN.js → chunk-OC75GWX5.js} +3 -3
- package/dist/{chunk-L2FPIFMN.js.map → chunk-OC75GWX5.js.map} +1 -1
- package/dist/{chunk-GKEWT3DW.js → chunk-OTCLBINT.js} +3 -3
- package/dist/{chunk-GKEWT3DW.js.map → chunk-OTCLBINT.js.map} +1 -1
- package/dist/{chunk-XXBW4EUO.js → chunk-P7Q2YIIS.js} +3 -3
- package/dist/{chunk-XXBW4EUO.js.map → chunk-P7Q2YIIS.js.map} +1 -1
- package/dist/{chunk-YTXBU6QC.cjs → chunk-QBNR5IVM.cjs} +4 -4
- package/dist/{chunk-YTXBU6QC.cjs.map → chunk-QBNR5IVM.cjs.map} +1 -1
- package/dist/{chunk-I3RPL3GE.js → chunk-RUSRAKKA.js} +3 -3
- package/dist/{chunk-I3RPL3GE.js.map → chunk-RUSRAKKA.js.map} +1 -1
- package/dist/{chunk-ZTC3EQFZ.cjs → chunk-S5KUYX3Z.cjs} +4 -4
- package/dist/{chunk-ZTC3EQFZ.cjs.map → chunk-S5KUYX3Z.cjs.map} +1 -1
- package/dist/chunk-SNHU2AI4.cjs +29 -0
- package/dist/chunk-SNHU2AI4.cjs.map +1 -0
- package/dist/{chunk-JV6RDIA6.cjs → chunk-T45XK5GN.cjs} +7 -7
- package/dist/{chunk-JV6RDIA6.cjs.map → chunk-T45XK5GN.cjs.map} +1 -1
- package/dist/{chunk-RKG2Q2HT.cjs → chunk-U7PFHQBN.cjs} +4 -4
- package/dist/{chunk-RKG2Q2HT.cjs.map → chunk-U7PFHQBN.cjs.map} +1 -1
- package/dist/{chunk-3FG5K7A7.js → chunk-VYHZEQIG.js} +3 -3
- package/dist/{chunk-3FG5K7A7.js.map → chunk-VYHZEQIG.js.map} +1 -1
- package/dist/{chunk-NH5XJ6VD.js → chunk-WHOVPDC5.js} +58 -27
- package/dist/chunk-WHOVPDC5.js.map +1 -0
- package/dist/{chunk-N6K2CTSU.cjs → chunk-WIS4QRGK.cjs} +4 -4
- package/dist/{chunk-N6K2CTSU.cjs.map → chunk-WIS4QRGK.cjs.map} +1 -1
- package/dist/{chunk-7MSIREUY.cjs → chunk-WRQBV7GU.cjs} +59 -27
- package/dist/chunk-WRQBV7GU.cjs.map +1 -0
- package/dist/{chunk-2LBRS6Z4.js → chunk-XDJSFGXW.js} +3 -3
- package/dist/{chunk-2LBRS6Z4.js.map → chunk-XDJSFGXW.js.map} +1 -1
- package/dist/{chunk-6LOV75CN.cjs → chunk-XK5WHQ3O.cjs} +4 -4
- package/dist/{chunk-6LOV75CN.cjs.map → chunk-XK5WHQ3O.cjs.map} +1 -1
- package/dist/{chunk-B5KK7NYP.cjs → chunk-Y52NXM73.cjs} +4 -4
- package/dist/{chunk-B5KK7NYP.cjs.map → chunk-Y52NXM73.cjs.map} +1 -1
- package/dist/{chunk-YLDYGT5O.js → chunk-YD4SXA6K.js} +3 -3
- package/dist/{chunk-YLDYGT5O.js.map → chunk-YD4SXA6K.js.map} +1 -1
- package/dist/{chunk-NR346SKH.cjs → chunk-YMDYDUBH.cjs} +4 -4
- package/dist/{chunk-NR346SKH.cjs.map → chunk-YMDYDUBH.cjs.map} +1 -1
- package/dist/{chunk-SCGE6DCE.cjs → chunk-YMU3SS6D.cjs} +14 -14
- package/dist/{chunk-SCGE6DCE.cjs.map → chunk-YMU3SS6D.cjs.map} +1 -1
- package/dist/{chunk-PWLBHNOA.cjs → chunk-Z3NSPDTW.cjs} +4 -4
- package/dist/{chunk-PWLBHNOA.cjs.map → chunk-Z3NSPDTW.cjs.map} +1 -1
- package/dist/{chunk-BJYTI2ID.cjs → chunk-ZUQUL53P.cjs} +4 -4
- package/dist/{chunk-BJYTI2ID.cjs.map → chunk-ZUQUL53P.cjs.map} +1 -1
- package/dist/color-picker.cjs +3 -3
- package/dist/color-picker.js +2 -2
- package/dist/composer.cjs +3 -3
- package/dist/composer.d.cts +2 -50
- package/dist/composer.d.ts +2 -50
- package/dist/composer.js +2 -2
- package/dist/date-picker.cjs +3 -3
- package/dist/date-picker.js +2 -2
- package/dist/editor.cjs +4 -4
- package/dist/editor.js +2 -2
- package/dist/emoji-select.cjs +3 -3
- package/dist/emoji-select.js +2 -2
- package/dist/file-browser.cjs +6 -6
- package/dist/file-browser.js +2 -2
- package/dist/index-CDo7LyIB.d.cts +132 -0
- package/dist/index-CDo7LyIB.d.ts +132 -0
- package/dist/index.cjs +75 -71
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +24 -24
- package/dist/input.cjs +3 -3
- package/dist/input.js +2 -2
- package/dist/inputs.cjs +17 -17
- package/dist/inputs.js +9 -9
- package/dist/json-editor.cjs +17 -17
- package/dist/json-editor.js +6 -6
- package/dist/mobile-menu.cjs +1 -1
- package/dist/mobile-menu.js +1 -1
- package/dist/multi-switch.cjs +3 -3
- package/dist/multi-switch.js +2 -2
- package/dist/otp-input.cjs +3 -3
- package/dist/otp-input.js +2 -2
- package/dist/pillbox.cjs +3 -3
- package/dist/pillbox.js +2 -2
- package/dist/radio-group.cjs +3 -3
- package/dist/radio-group.js +2 -2
- package/dist/sidebar.cjs +4 -4
- package/dist/sidebar.js +2 -2
- package/dist/slider.cjs +3 -3
- package/dist/slider.js +2 -2
- package/dist/switch.cjs +3 -3
- package/dist/switch.js +2 -2
- package/dist/table.cjs +12 -12
- package/dist/table.js +2 -2
- package/dist/tabs.cjs +4 -4
- package/dist/tabs.js +2 -2
- package/dist/time-picker.cjs +3 -3
- package/dist/time-picker.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-6FQGMVF2.js +0 -25
- package/dist/chunk-6FQGMVF2.js.map +0 -1
- package/dist/chunk-7MSIREUY.cjs.map +0 -1
- package/dist/chunk-NH5XJ6VD.js.map +0 -1
- package/dist/chunk-OUOEQZHY.cjs +0 -27
- package/dist/chunk-OUOEQZHY.cjs.map +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A paste held beside a composer rather than inserted into it.
|
|
6
|
+
*
|
|
7
|
+
* There is deliberately **no `length` field.** It would be `text.length` and
|
|
8
|
+
* nothing else, and a derived value stored beside its source is a value that can
|
|
9
|
+
* disagree with it — the two drift the moment anything edits one. Read
|
|
10
|
+
* `paste.text.length`.
|
|
11
|
+
*/
|
|
12
|
+
interface HeldPaste {
|
|
13
|
+
id: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The minimum of a clipboard event this hook touches.
|
|
18
|
+
*
|
|
19
|
+
* Structural rather than `React.ClipboardEvent` so a host can call it from a
|
|
20
|
+
* native listener, a synthetic one, or a test double. React's own event satisfies
|
|
21
|
+
* it.
|
|
22
|
+
*/
|
|
23
|
+
interface PasteEventLike {
|
|
24
|
+
clipboardData?: {
|
|
25
|
+
getData(type: string): string;
|
|
26
|
+
} | null;
|
|
27
|
+
preventDefault(): void;
|
|
28
|
+
}
|
|
29
|
+
interface UsePastePillsOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Hold a paste of at least this many characters. Try 500 — about a long
|
|
32
|
+
* paragraph.
|
|
33
|
+
*
|
|
34
|
+
* **No default, on purpose.** Paste is a fundamental interaction, so holding one
|
|
35
|
+
* is something a host asks for rather than something it discovers. Omit this and
|
|
36
|
+
* `handlePaste` always returns `false` and touches nothing.
|
|
37
|
+
*/
|
|
38
|
+
threshold?: number;
|
|
39
|
+
/** Own the list yourself. Omit to let the hook keep it. */
|
|
40
|
+
heldPastes?: HeldPaste[];
|
|
41
|
+
onHeldPastesChange?: (pastes: HeldPaste[]) => void;
|
|
42
|
+
}
|
|
43
|
+
interface UsePastePillsResult {
|
|
44
|
+
heldPastes: HeldPaste[];
|
|
45
|
+
/**
|
|
46
|
+
* Call this from your OWN paste handler. Returns `true` if it took the paste —
|
|
47
|
+
* in which case it has already called `preventDefault()` — and `false` if it
|
|
48
|
+
* declined, having touched nothing.
|
|
49
|
+
*
|
|
50
|
+
* Composable on purpose: a host whose handler already intercepts paste for its
|
|
51
|
+
* own reasons needs to ask "did you want this?" rather than hand over the event.
|
|
52
|
+
*
|
|
53
|
+
* function onPaste(e) {
|
|
54
|
+
* if (pills.handlePaste(e)) return;
|
|
55
|
+
* // ...your own handling
|
|
56
|
+
* }
|
|
57
|
+
*/
|
|
58
|
+
handlePaste: (event: PasteEventLike) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Removes the paste and returns its text, for the host to insert into its own
|
|
61
|
+
* surface. `undefined` if there is no such id.
|
|
62
|
+
*
|
|
63
|
+
* The hook cannot insert it — it owns no DOM and does not know what a host's
|
|
64
|
+
* surface is. That is the point.
|
|
65
|
+
*/
|
|
66
|
+
expand: (id: string) => string | undefined;
|
|
67
|
+
/** Discard one without returning it. */
|
|
68
|
+
remove: (id: string) => void;
|
|
69
|
+
/** Empty the list, e.g. after a send. */
|
|
70
|
+
clear: () => void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Hold a large paste as state, so a composer can show it as a pill instead of
|
|
74
|
+
* turning itself into a scrolling wall.
|
|
75
|
+
*
|
|
76
|
+
* ---------------------------------------------------------------------------
|
|
77
|
+
* Why this is a hook and not just a feature of `Composer`
|
|
78
|
+
* ---------------------------------------------------------------------------
|
|
79
|
+
*
|
|
80
|
+
* `Composer` shipped the behaviour in 5.31.0 and the MOIC estate, who specified it,
|
|
81
|
+
* then established something I had missed: their chat input is a contenteditable
|
|
82
|
+
* rendering inline `[deal:42|Acme]` badges, so they **cannot** adopt `Composer` (a
|
|
83
|
+
* plain textarea) however much they want its behaviour. Their plan to delete their
|
|
84
|
+
* own composer when ours landed could never have worked.
|
|
85
|
+
*
|
|
86
|
+
* So the logic lives here and **`Composer` is its first caller.** One
|
|
87
|
+
* implementation rather than two, which matters more than the convenience: two
|
|
88
|
+
* copies of a rule drift, and the copy nobody reads is the one that rots. The rule
|
|
89
|
+
* that must not drift is the one in `Composer`'s own tests — a send with pills
|
|
90
|
+
* still closed carries the text.
|
|
91
|
+
*
|
|
92
|
+
* It owns no DOM. The host renders the pills.
|
|
93
|
+
*/
|
|
94
|
+
declare function usePastePills({ threshold, heldPastes: controlledHeldPastes, onHeldPastesChange, }?: UsePastePillsOptions): UsePastePillsResult;
|
|
95
|
+
|
|
96
|
+
interface ComposerProps {
|
|
97
|
+
value?: string;
|
|
98
|
+
defaultValue?: string;
|
|
99
|
+
onChange?: (value: string) => void;
|
|
100
|
+
onSubmit?: (value: string) => void;
|
|
101
|
+
placeholder?: string;
|
|
102
|
+
actions?: ReactNode;
|
|
103
|
+
disabled?: boolean;
|
|
104
|
+
className?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Hold a paste of at least this many characters beside the composer as a pill,
|
|
107
|
+
* instead of inserting it. Try 500 — about a long paragraph.
|
|
108
|
+
*
|
|
109
|
+
* **Omit it and paste behaves exactly as it always has.** Opt-in on purpose:
|
|
110
|
+
* paste is a fundamental interaction and this library is past 1.0, so a minor
|
|
111
|
+
* release must not quietly change what pasting does for every consumer. There is
|
|
112
|
+
* no default threshold for the same reason.
|
|
113
|
+
*
|
|
114
|
+
* Below the threshold nothing changes at all — no prevented event, no pill, no
|
|
115
|
+
* ceremony for an address or a name.
|
|
116
|
+
*/
|
|
117
|
+
pasteThreshold?: number;
|
|
118
|
+
/**
|
|
119
|
+
* The held pastes, if you want to own them.
|
|
120
|
+
*
|
|
121
|
+
* Controllable rather than internal because the component contract forbids
|
|
122
|
+
* internal-only state for anything an agent might need to read or write — an
|
|
123
|
+
* agent driving this surface has to be able to see that a paste is attached, and
|
|
124
|
+
* to attach one itself.
|
|
125
|
+
*/
|
|
126
|
+
heldPastes?: HeldPaste[];
|
|
127
|
+
onHeldPastesChange?: (pastes: HeldPaste[]) => void;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
|
|
131
|
+
|
|
132
|
+
export { Composer as C, type HeldPaste as H, type PasteEventLike as P, type UsePastePillsOptions as U, type ComposerProps as a, type UsePastePillsResult as b, usePastePills as u };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A paste held beside a composer rather than inserted into it.
|
|
6
|
+
*
|
|
7
|
+
* There is deliberately **no `length` field.** It would be `text.length` and
|
|
8
|
+
* nothing else, and a derived value stored beside its source is a value that can
|
|
9
|
+
* disagree with it — the two drift the moment anything edits one. Read
|
|
10
|
+
* `paste.text.length`.
|
|
11
|
+
*/
|
|
12
|
+
interface HeldPaste {
|
|
13
|
+
id: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The minimum of a clipboard event this hook touches.
|
|
18
|
+
*
|
|
19
|
+
* Structural rather than `React.ClipboardEvent` so a host can call it from a
|
|
20
|
+
* native listener, a synthetic one, or a test double. React's own event satisfies
|
|
21
|
+
* it.
|
|
22
|
+
*/
|
|
23
|
+
interface PasteEventLike {
|
|
24
|
+
clipboardData?: {
|
|
25
|
+
getData(type: string): string;
|
|
26
|
+
} | null;
|
|
27
|
+
preventDefault(): void;
|
|
28
|
+
}
|
|
29
|
+
interface UsePastePillsOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Hold a paste of at least this many characters. Try 500 — about a long
|
|
32
|
+
* paragraph.
|
|
33
|
+
*
|
|
34
|
+
* **No default, on purpose.** Paste is a fundamental interaction, so holding one
|
|
35
|
+
* is something a host asks for rather than something it discovers. Omit this and
|
|
36
|
+
* `handlePaste` always returns `false` and touches nothing.
|
|
37
|
+
*/
|
|
38
|
+
threshold?: number;
|
|
39
|
+
/** Own the list yourself. Omit to let the hook keep it. */
|
|
40
|
+
heldPastes?: HeldPaste[];
|
|
41
|
+
onHeldPastesChange?: (pastes: HeldPaste[]) => void;
|
|
42
|
+
}
|
|
43
|
+
interface UsePastePillsResult {
|
|
44
|
+
heldPastes: HeldPaste[];
|
|
45
|
+
/**
|
|
46
|
+
* Call this from your OWN paste handler. Returns `true` if it took the paste —
|
|
47
|
+
* in which case it has already called `preventDefault()` — and `false` if it
|
|
48
|
+
* declined, having touched nothing.
|
|
49
|
+
*
|
|
50
|
+
* Composable on purpose: a host whose handler already intercepts paste for its
|
|
51
|
+
* own reasons needs to ask "did you want this?" rather than hand over the event.
|
|
52
|
+
*
|
|
53
|
+
* function onPaste(e) {
|
|
54
|
+
* if (pills.handlePaste(e)) return;
|
|
55
|
+
* // ...your own handling
|
|
56
|
+
* }
|
|
57
|
+
*/
|
|
58
|
+
handlePaste: (event: PasteEventLike) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Removes the paste and returns its text, for the host to insert into its own
|
|
61
|
+
* surface. `undefined` if there is no such id.
|
|
62
|
+
*
|
|
63
|
+
* The hook cannot insert it — it owns no DOM and does not know what a host's
|
|
64
|
+
* surface is. That is the point.
|
|
65
|
+
*/
|
|
66
|
+
expand: (id: string) => string | undefined;
|
|
67
|
+
/** Discard one without returning it. */
|
|
68
|
+
remove: (id: string) => void;
|
|
69
|
+
/** Empty the list, e.g. after a send. */
|
|
70
|
+
clear: () => void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Hold a large paste as state, so a composer can show it as a pill instead of
|
|
74
|
+
* turning itself into a scrolling wall.
|
|
75
|
+
*
|
|
76
|
+
* ---------------------------------------------------------------------------
|
|
77
|
+
* Why this is a hook and not just a feature of `Composer`
|
|
78
|
+
* ---------------------------------------------------------------------------
|
|
79
|
+
*
|
|
80
|
+
* `Composer` shipped the behaviour in 5.31.0 and the MOIC estate, who specified it,
|
|
81
|
+
* then established something I had missed: their chat input is a contenteditable
|
|
82
|
+
* rendering inline `[deal:42|Acme]` badges, so they **cannot** adopt `Composer` (a
|
|
83
|
+
* plain textarea) however much they want its behaviour. Their plan to delete their
|
|
84
|
+
* own composer when ours landed could never have worked.
|
|
85
|
+
*
|
|
86
|
+
* So the logic lives here and **`Composer` is its first caller.** One
|
|
87
|
+
* implementation rather than two, which matters more than the convenience: two
|
|
88
|
+
* copies of a rule drift, and the copy nobody reads is the one that rots. The rule
|
|
89
|
+
* that must not drift is the one in `Composer`'s own tests — a send with pills
|
|
90
|
+
* still closed carries the text.
|
|
91
|
+
*
|
|
92
|
+
* It owns no DOM. The host renders the pills.
|
|
93
|
+
*/
|
|
94
|
+
declare function usePastePills({ threshold, heldPastes: controlledHeldPastes, onHeldPastesChange, }?: UsePastePillsOptions): UsePastePillsResult;
|
|
95
|
+
|
|
96
|
+
interface ComposerProps {
|
|
97
|
+
value?: string;
|
|
98
|
+
defaultValue?: string;
|
|
99
|
+
onChange?: (value: string) => void;
|
|
100
|
+
onSubmit?: (value: string) => void;
|
|
101
|
+
placeholder?: string;
|
|
102
|
+
actions?: ReactNode;
|
|
103
|
+
disabled?: boolean;
|
|
104
|
+
className?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Hold a paste of at least this many characters beside the composer as a pill,
|
|
107
|
+
* instead of inserting it. Try 500 — about a long paragraph.
|
|
108
|
+
*
|
|
109
|
+
* **Omit it and paste behaves exactly as it always has.** Opt-in on purpose:
|
|
110
|
+
* paste is a fundamental interaction and this library is past 1.0, so a minor
|
|
111
|
+
* release must not quietly change what pasting does for every consumer. There is
|
|
112
|
+
* no default threshold for the same reason.
|
|
113
|
+
*
|
|
114
|
+
* Below the threshold nothing changes at all — no prevented event, no pill, no
|
|
115
|
+
* ceremony for an address or a name.
|
|
116
|
+
*/
|
|
117
|
+
pasteThreshold?: number;
|
|
118
|
+
/**
|
|
119
|
+
* The held pastes, if you want to own them.
|
|
120
|
+
*
|
|
121
|
+
* Controllable rather than internal because the component contract forbids
|
|
122
|
+
* internal-only state for anything an agent might need to read or write — an
|
|
123
|
+
* agent driving this surface has to be able to see that a paste is attached, and
|
|
124
|
+
* to attach one itself.
|
|
125
|
+
*/
|
|
126
|
+
heldPastes?: HeldPaste[];
|
|
127
|
+
onHeldPastesChange?: (pastes: HeldPaste[]) => void;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
|
|
131
|
+
|
|
132
|
+
export { Composer as C, type HeldPaste as H, type PasteEventLike as P, type UsePastePillsOptions as U, type ComposerProps as a, type UsePastePillsResult as b, usePastePills as u };
|