@particle-academy/react-fancy 5.70.0 → 5.71.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 +49 -0
- package/README.md +1 -0
- package/dist/autocomplete.cjs +3 -3
- package/dist/autocomplete.js +2 -2
- package/dist/chat-thread.cjs +27 -0
- package/dist/chat-thread.cjs.map +1 -0
- package/dist/chat-thread.d.cts +260 -0
- package/dist/chat-thread.d.ts +260 -0
- package/dist/chat-thread.js +14 -0
- package/dist/chat-thread.js.map +1 -0
- package/dist/chunk-5IE65DIH.cjs +623 -0
- package/dist/chunk-5IE65DIH.cjs.map +1 -0
- package/dist/{chunk-6QAF35AJ.cjs → chunk-7JLKOVHX.cjs} +3 -3
- package/dist/{chunk-6QAF35AJ.cjs.map → chunk-7JLKOVHX.cjs.map} +1 -1
- package/dist/{chunk-TCMOD3WW.js → chunk-A6NYZ3F5.js} +3 -3
- package/dist/{chunk-TCMOD3WW.js.map → chunk-A6NYZ3F5.js.map} +1 -1
- package/dist/{chunk-6EA3DSPT.cjs → chunk-FGOFG2UZ.cjs} +5 -5
- package/dist/{chunk-6EA3DSPT.cjs.map → chunk-FGOFG2UZ.cjs.map} +1 -1
- package/dist/{chunk-J7S42MJP.js → chunk-FYUEDPST.js} +39 -20
- package/dist/chunk-FYUEDPST.js.map +1 -0
- package/dist/{chunk-HN5J7TK6.js → chunk-GDH43QH6.js} +21 -8
- package/dist/chunk-GDH43QH6.js.map +1 -0
- package/dist/{chunk-AC3W3TIV.js → chunk-J6IQHJET.js} +14 -5
- package/dist/chunk-J6IQHJET.js.map +1 -0
- package/dist/{chunk-XNHAJQRF.cjs → chunk-JKD6CFIP.cjs} +14 -5
- package/dist/chunk-JKD6CFIP.cjs.map +1 -0
- package/dist/{chunk-FHRVSYJU.cjs → chunk-MP55W37V.cjs} +3 -3
- package/dist/{chunk-FHRVSYJU.cjs.map → chunk-MP55W37V.cjs.map} +1 -1
- package/dist/{chunk-LBSAWRFT.cjs → chunk-NPSKZ7ZB.cjs} +22 -9
- package/dist/chunk-NPSKZ7ZB.cjs.map +1 -0
- package/dist/{chunk-EZL5DILH.js → chunk-OPDHSOUN.js} +3 -3
- package/dist/{chunk-EZL5DILH.js.map → chunk-OPDHSOUN.js.map} +1 -1
- package/dist/{chunk-XAKZ6VBP.cjs → chunk-PS7C6GKI.cjs} +40 -21
- package/dist/chunk-PS7C6GKI.cjs.map +1 -0
- package/dist/chunk-UWYSJARZ.js +620 -0
- package/dist/chunk-UWYSJARZ.js.map +1 -0
- package/dist/{chunk-M6UAVA2I.js → chunk-XIA2UAVO.js} +3 -3
- package/dist/{chunk-M6UAVA2I.js.map → chunk-XIA2UAVO.js.map} +1 -1
- package/dist/composer.cjs +3 -3
- package/dist/composer.d.cts +3 -2
- package/dist/composer.d.ts +3 -2
- package/dist/composer.js +2 -2
- package/dist/editor.cjs +3 -3
- package/dist/editor.js +3 -3
- package/dist/{index-BAtF94lw.d.ts → index-B8OkuYSt.d.ts} +3 -2
- package/dist/{index-xwL2MACB.d.cts → index-BMVQnKTH.d.cts} +3 -2
- package/dist/index.cjs +170 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +26 -25
- package/dist/index.js.map +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/inputs.cjs +7 -7
- package/dist/inputs.js +3 -3
- package/dist/json-editor.cjs +16 -16
- package/dist/json-editor.js +5 -5
- package/dist/prompt-input.cjs +6 -6
- package/dist/prompt-input.d.cts +1 -1
- package/dist/prompt-input.d.ts +1 -1
- package/dist/prompt-input.js +3 -3
- package/dist/select.cjs +3 -3
- package/dist/select.js +2 -2
- package/docs/ChatThread.md +318 -0
- package/docs/Composer.md +5 -2
- package/docs/PromptInput.md +8 -2
- package/package.json +11 -1
- package/dist/chunk-AC3W3TIV.js.map +0 -1
- package/dist/chunk-HN5J7TK6.js.map +0 -1
- package/dist/chunk-J7S42MJP.js.map +0 -1
- package/dist/chunk-LBSAWRFT.cjs.map +0 -1
- package/dist/chunk-XAKZ6VBP.cjs.map +0 -1
- package/dist/chunk-XNHAJQRF.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Autocomplete/Autocomplete.tsx"],"names":["forwardRef","Autocomplete","useControllableState","useFieldMode","useInlineEdit","useState","useRef","useFloatingPosition","useCallback","useOutsideClick","useEscapeKey","useEffect","isImeComposing","jsx","cn","jsxs","Portal","Fragment"],"mappings":"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","file":"chunk-FHRVSYJU.cjs","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { isImeComposing } from \"../../utils/ime\";\nimport { Portal } from \"../Portal\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport { useFloatingPosition } from \"../../hooks/use-floating-position\";\nimport { useOutsideClick } from \"../../hooks/use-outside-click\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useFieldMode } from \"../inputs/mode/FieldMode.context\";\nimport { useInlineEdit } from \"../inputs/mode/useInlineEdit\";\nimport type { AutocompleteProps } from \"./Autocomplete.types\";\n\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n function Autocomplete(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSearch,\n options,\n placeholder,\n loading = false,\n emptyMessage = \"No results found.\",\n disabled = false,\n className,\n mode,\n },\n ref,\n ) {\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [query, setQuery] = useState(value);\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n\n const anchorRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n const position = useFloatingPosition(anchorRef, listRef, {\n placement: \"bottom-start\",\n offset: 4,\n enabled: open,\n });\n\n const close = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n }, []);\n\n useOutsideClick(wrapperRef, close, open);\n useEscapeKey(close, open);\n\n const filtered = options.filter((o) =>\n o.label.toLowerCase().includes(query.toLowerCase()),\n );\n\n const select = useCallback(\n (val: string) => {\n setValue(val);\n const opt = options.find((o) => o.value === val);\n setQuery(opt?.label ?? val);\n close();\n },\n [setValue, options, close],\n );\n\n useEffect(() => {\n onSearch?.(query);\n }, [query, onSearch]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!open) {\n if (e.key === \"ArrowDown\") {\n setOpen(true);\n return;\n }\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\" && activeIndex >= 0 && !isImeComposing(e)) {\n e.preventDefault();\n const item = filtered[activeIndex];\n if (item && !item.disabled) select(item.value);\n }\n };\n\n if (!showControl) {\n const matched = options.find((o) => o.value === value);\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n data-mode=\"view\"\n ref={wrapperRef}\n role={interactive ? \"button\" : undefined}\n tabIndex={interactive ? 0 : undefined}\n title={interactive ? \"Click to edit\" : undefined}\n onClick={interactive ? enterEdit : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n enterEdit();\n }\n }\n : undefined\n }\n className={cn(\n \"text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n !value && \"text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\",\n interactive &&\n \"cursor-pointer rounded-md outline-none transition-colors hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n >\n {matched?.label ?? value ?? \"—\"}\n </div>\n );\n }\n\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n ref={wrapperRef}\n className={cn(\"relative\", className)}\n onBlur={(e) => {\n // Options live in a Portal; only exit when closed and focus left.\n if (interactive && !open && !e.currentTarget.contains(e.relatedTarget as Node)) {\n exitEdit();\n }\n }}\n >\n <input\n ref={(node) => {\n (anchorRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }}\n type=\"text\"\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n setActiveIndex(-1);\n }}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={interactive}\n role=\"combobox\"\n aria-expanded={open}\n aria-autocomplete=\"list\"\n className=\"w-full rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-input,var(--color-white))] px-3 py-2 text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] placeholder:text-[color:var(--fancy-text-faint,var(--color-zinc-400))] outline-none transition-[border-color,box-shadow] duration-150 focus:border-[color:var(--fancy-focus,var(--color-blue-500))] focus:ring-2 focus:ring-[color:var(--fancy-focus,var(--color-blue-500))]/40 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-input-dark,#1e1e24)] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))] dark:placeholder:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:focus:border-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]/20\"\n />\n {open && (\n <Portal>\n <div\n ref={listRef}\n role=\"listbox\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-1 shadow-lg dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:shadow-zinc-950/50 fancy-scale-in\"\n style={{\n left: position.x,\n top: position.y,\n width: anchorRef.current?.offsetWidth,\n }}\n >\n {loading ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">Loading...</div>\n ) : filtered.length === 0 ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">\n {emptyMessage}\n </div>\n ) : (\n filtered.map((option, i) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n disabled={option.disabled}\n onClick={() => select(option.value)}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200\",\n i === activeIndex\n ? \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n : \"hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))]\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <HighlightMatch text={option.label} query={query} />\n </button>\n ))\n )}\n </div>\n </Portal>\n )}\n </div>\n );\n },\n);\n\nfunction HighlightMatch({ text, query }: { text: string; query: string }) {\n if (!query) return <>{text}</>;\n\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return <>{text}</>;\n\n return (\n <>\n {text.slice(0, idx)}\n <span className=\"font-semibold text-zinc-900 dark:text-white\">\n {text.slice(idx, idx + query.length)}\n </span>\n {text.slice(idx + query.length)}\n </>\n );\n}\n\nAutocomplete.displayName = \"Autocomplete\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Autocomplete/Autocomplete.tsx"],"names":["forwardRef","Autocomplete","useControllableState","useFieldMode","useInlineEdit","useState","useRef","useFloatingPosition","useCallback","useOutsideClick","useEscapeKey","useEffect","isImeComposing","jsx","cn","jsxs","Portal","Fragment"],"mappings":"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","file":"chunk-MP55W37V.cjs","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { isImeComposing } from \"../../utils/ime\";\nimport { Portal } from \"../Portal\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport { useFloatingPosition } from \"../../hooks/use-floating-position\";\nimport { useOutsideClick } from \"../../hooks/use-outside-click\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useFieldMode } from \"../inputs/mode/FieldMode.context\";\nimport { useInlineEdit } from \"../inputs/mode/useInlineEdit\";\nimport type { AutocompleteProps } from \"./Autocomplete.types\";\n\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n function Autocomplete(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSearch,\n options,\n placeholder,\n loading = false,\n emptyMessage = \"No results found.\",\n disabled = false,\n className,\n mode,\n },\n ref,\n ) {\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [query, setQuery] = useState(value);\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n\n const anchorRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n const position = useFloatingPosition(anchorRef, listRef, {\n placement: \"bottom-start\",\n offset: 4,\n enabled: open,\n });\n\n const close = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n }, []);\n\n useOutsideClick(wrapperRef, close, open);\n useEscapeKey(close, open);\n\n const filtered = options.filter((o) =>\n o.label.toLowerCase().includes(query.toLowerCase()),\n );\n\n const select = useCallback(\n (val: string) => {\n setValue(val);\n const opt = options.find((o) => o.value === val);\n setQuery(opt?.label ?? val);\n close();\n },\n [setValue, options, close],\n );\n\n useEffect(() => {\n onSearch?.(query);\n }, [query, onSearch]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!open) {\n if (e.key === \"ArrowDown\") {\n setOpen(true);\n return;\n }\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\" && activeIndex >= 0 && !isImeComposing(e)) {\n e.preventDefault();\n const item = filtered[activeIndex];\n if (item && !item.disabled) select(item.value);\n }\n };\n\n if (!showControl) {\n const matched = options.find((o) => o.value === value);\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n data-mode=\"view\"\n ref={wrapperRef}\n role={interactive ? \"button\" : undefined}\n tabIndex={interactive ? 0 : undefined}\n title={interactive ? \"Click to edit\" : undefined}\n onClick={interactive ? enterEdit : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n enterEdit();\n }\n }\n : undefined\n }\n className={cn(\n \"text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n !value && \"text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\",\n interactive &&\n \"cursor-pointer rounded-md outline-none transition-colors hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n >\n {matched?.label ?? value ?? \"—\"}\n </div>\n );\n }\n\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n ref={wrapperRef}\n className={cn(\"relative\", className)}\n onBlur={(e) => {\n // Options live in a Portal; only exit when closed and focus left.\n if (interactive && !open && !e.currentTarget.contains(e.relatedTarget as Node)) {\n exitEdit();\n }\n }}\n >\n <input\n ref={(node) => {\n (anchorRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }}\n type=\"text\"\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n setActiveIndex(-1);\n }}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={interactive}\n role=\"combobox\"\n aria-expanded={open}\n aria-autocomplete=\"list\"\n className=\"w-full rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-input,var(--color-white))] px-3 py-2 text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] placeholder:text-[color:var(--fancy-text-faint,var(--color-zinc-400))] outline-none transition-[border-color,box-shadow] duration-150 focus:border-[color:var(--fancy-focus,var(--color-blue-500))] focus:ring-2 focus:ring-[color:var(--fancy-focus,var(--color-blue-500))]/40 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-input-dark,#1e1e24)] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))] dark:placeholder:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:focus:border-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]/20\"\n />\n {open && (\n <Portal>\n <div\n ref={listRef}\n role=\"listbox\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-1 shadow-lg dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:shadow-zinc-950/50 fancy-scale-in\"\n style={{\n left: position.x,\n top: position.y,\n width: anchorRef.current?.offsetWidth,\n }}\n >\n {loading ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">Loading...</div>\n ) : filtered.length === 0 ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">\n {emptyMessage}\n </div>\n ) : (\n filtered.map((option, i) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n disabled={option.disabled}\n onClick={() => select(option.value)}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200\",\n i === activeIndex\n ? \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n : \"hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))]\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <HighlightMatch text={option.label} query={query} />\n </button>\n ))\n )}\n </div>\n </Portal>\n )}\n </div>\n );\n },\n);\n\nfunction HighlightMatch({ text, query }: { text: string; query: string }) {\n if (!query) return <>{text}</>;\n\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return <>{text}</>;\n\n return (\n <>\n {text.slice(0, idx)}\n <span className=\"font-semibold text-zinc-900 dark:text-white\">\n {text.slice(idx, idx + query.length)}\n </span>\n {text.slice(idx + query.length)}\n </>\n );\n}\n\nAutocomplete.displayName = \"Autocomplete\";\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkJKD6CFIP_cjs = require('./chunk-JKD6CFIP.cjs');
|
|
4
4
|
var chunkKKYILQTG_cjs = require('./chunk-KKYILQTG.cjs');
|
|
5
5
|
var chunk2C64OVOZ_cjs = require('./chunk-2C64OVOZ.cjs');
|
|
6
6
|
var chunk6V44RRSB_cjs = require('./chunk-6V44RRSB.cjs');
|
|
@@ -85,18 +85,25 @@ var Composer = react.forwardRef(
|
|
|
85
85
|
if (inline) editorRef.current?.focus();
|
|
86
86
|
else textareaRef.current?.focus();
|
|
87
87
|
}, [inline]);
|
|
88
|
-
const ack =
|
|
88
|
+
const ack = chunkJKD6CFIP_cjs.useAcknowledgedSubmit(onSubmitError);
|
|
89
89
|
const submitting = ack.status === "submitting";
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
90
|
+
const heldImages = paste.heldImages;
|
|
91
|
+
const revisionRef = react.useRef(0);
|
|
92
|
+
const seenRef = react.useRef({ value, heldPastes, heldImages });
|
|
93
|
+
const seen = seenRef.current;
|
|
94
|
+
if (seen.value !== value || seen.heldPastes !== heldPastes || seen.heldImages !== heldImages) {
|
|
95
|
+
if (seen.value !== value || !samePastes(seen.heldPastes, heldPastes) || !sameImages(seen.heldImages, heldImages)) {
|
|
96
|
+
revisionRef.current += 1;
|
|
97
|
+
}
|
|
98
|
+
seenRef.current = { value, heldPastes, heldImages };
|
|
99
|
+
}
|
|
93
100
|
const handleSubmit = react.useCallback(() => {
|
|
94
101
|
if (!hasContent || disabled || sendDisabled || ack.busy()) return;
|
|
95
102
|
const images = inline ? paste.imagesIn(value) : [];
|
|
96
103
|
const result = onSubmit?.(composeOutgoing(), { images });
|
|
97
|
-
const sent =
|
|
104
|
+
const sent = revisionRef.current;
|
|
98
105
|
ack.track(result, () => {
|
|
99
|
-
if (
|
|
106
|
+
if (revisionRef.current !== sent) return;
|
|
100
107
|
setValue("");
|
|
101
108
|
paste.clear();
|
|
102
109
|
});
|
|
@@ -266,7 +273,13 @@ ${text}` : text);
|
|
|
266
273
|
}
|
|
267
274
|
);
|
|
268
275
|
Composer.displayName = "Composer";
|
|
276
|
+
function samePastes(a, b) {
|
|
277
|
+
return a.length === b.length && a.every((p, i) => p.id === b[i].id && p.text === b[i].text && p.label === b[i].label);
|
|
278
|
+
}
|
|
279
|
+
function sameImages(a, b) {
|
|
280
|
+
return a.length === b.length && a.every((img, i) => img.id === b[i].id && img.label === b[i].label && img.file === b[i].file);
|
|
281
|
+
}
|
|
269
282
|
|
|
270
283
|
exports.Composer = Composer;
|
|
271
|
-
//# sourceMappingURL=chunk-
|
|
272
|
-
//# sourceMappingURL=chunk-
|
|
284
|
+
//# sourceMappingURL=chunk-NPSKZ7ZB.cjs.map
|
|
285
|
+
//# sourceMappingURL=chunk-NPSKZ7ZB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Composer/Composer.tsx"],"names":["forwardRef","Composer","useControllableState","useRef","useInlinePaste","useMemo","useCallback","useAcknowledgedSubmit","isImeComposing","jsxs","cn","jsx","paste","withSeparators","endsOf","Fragment","InlinePasteEditor","PastedFilesInput","visuallyHidden"],"mappings":"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","file":"chunk-NPSKZ7ZB.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { isImeComposing } from \"../../utils/ime\";\nimport { visuallyHidden } from \"../../utils/visually-hidden\";\nimport { useAcknowledgedSubmit } from \"../../hooks/use-acknowledged-submit\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport {\n endsOf,\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n withSeparators,\n type HeldImage,\n type HeldPaste,\n type InlinePasteEditorHandle,\n} from \"../PastePills\";\nimport type { ComposerProps } from \"./Composer.types\";\n\n/** Characters of a held paste shown at each end of the hover preview, unless `previewChars` says otherwise. */\nconst PREVIEW_CHARS = 20;\n\nexport const Composer = forwardRef<HTMLDivElement, ComposerProps>(\n function Composer(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSubmit,\n onSubmitError,\n placeholder = \"Type a message...\",\n actions,\n disabled = false,\n sendDisabled = false,\n name,\n inputId,\n className,\n pasteThreshold,\n pastePlacement = \"above\",\n pasteImages = false,\n previewChars = PREVIEW_CHARS,\n renderPastePreview,\n classNames,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n pasteFilesName,\n },\n ref,\n ) {\n const inline = pastePlacement === \"inline\";\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n /*\n * The holding logic lives in `usePastePills`, wrapped by `useInlinePaste` for\n * the inline placement — which `PromptInput` shares, so the two components\n * cannot disagree about what a pill means. The rule that must not drift is\n * the one below: a send with pills still closed carries the text.\n */\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames,\n disabled,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n editorRef,\n });\n const pills = paste.pills;\n const heldPastes = paste.heldPastes;\n const pastedFiles = useMemo(\n () => (inline && pasteImages ? paste.imagesIn(value).map((i) => i.file) : []),\n [inline, pasteImages, paste, value],\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n // Composable by design, so this reads as a question rather than a handover.\n // Nothing else here wants the paste, so the answer is simply ignored.\n pills.handlePaste(e);\n },\n [pills],\n );\n\n const handleInlineChange = useCallback(\n (next: string) => {\n setValue(next);\n paste.prune(next);\n },\n [setValue, paste],\n );\n\n /** Everything the person believes they are sending, in the order they built it. */\n const composeOutgoing = useCallback(() => {\n if (inline) return paste.expand(value);\n\n return [value, ...heldPastes.map((p) => p.text)].filter(Boolean).join(\"\\n\\n\");\n }, [inline, value, heldPastes, paste]);\n\n const hasContent = value.trim().length > 0 || (!inline && heldPastes.length > 0);\n\n const focusInput = useCallback(() => {\n if (inline) editorRef.current?.focus();\n else textareaRef.current?.focus();\n }, [inline]);\n\n const ack = useAcknowledgedSubmit(onSubmitError);\n const submitting = ack.status === \"submitting\";\n\n /*\n * The draft's REVISION: bumped by every render in which the text, a held\n * paste or a held image differs from the last one seen — the person typing\n * or pasting, or a host moving a controlled `value` / `heldPastes` /\n * `heldImages`. An acknowledged send clears only if the revision is still\n * the one it sent. Comparing content instead (5.70.0) threw away newer\n * drafts that happened to compare equal: an edit typed and undone, a pill\n * whose text the host changed under the same id.\n */\n const heldImages = paste.heldImages;\n const revisionRef = useRef(0);\n const seenRef = useRef({ value, heldPastes, heldImages });\n const seen = seenRef.current;\n if (seen.value !== value || seen.heldPastes !== heldPastes || seen.heldImages !== heldImages) {\n if (\n seen.value !== value ||\n !samePastes(seen.heldPastes, heldPastes) ||\n !sameImages(seen.heldImages, heldImages)\n ) {\n revisionRef.current += 1;\n }\n seenRef.current = { value, heldPastes, heldImages };\n }\n\n const handleSubmit = useCallback(() => {\n if (!hasContent || disabled || sendDisabled || ack.busy()) return;\n\n /*\n * THE DANGEROUS STATE, and the reason this feature needed a spec rather than\n * a guess. A pill reads as \"your paste is attached\" — so a send that drops it\n * means asking a question about a document without the document, and nobody\n * can tell: the sender believes it went, the receiver sees a question about\n * nothing.\n *\n * Above the input, held pastes go out in arrival order after what was typed,\n * because people type the question BEFORE pasting the thing it is about.\n * Inline, every pill goes out exactly where it sits.\n */\n const images = inline ? paste.imagesIn(value) : [];\n\n const result = onSubmit?.(composeOutgoing(), { images });\n const sent = revisionRef.current;\n ack.track(result, () => {\n /*\n * A void `onSubmit` reaches here synchronously, so `sent` is still the\n * current revision and this clears exactly as it always has. An async one\n * reaches here when it resolves: if anything changed the message while it\n * was in flight, that message is newer than the send, even if it reads the\n * same, and throwing it away is the one outcome nobody can undo. So only\n * the revision that was sent is cleared.\n */\n if (revisionRef.current !== sent) return;\n setValue(\"\");\n paste.clear();\n });\n // Focus goes back to the text at once, as before: it stays editable while\n // a send is in flight, and the send button the person may have clicked is\n // about to be disabled.\n focusInput();\n }, [hasContent, disabled, sendDisabled, ack, value, inline, paste, onSubmit, composeOutgoing, setValue, focusInput]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n // Enter that confirms an IME composition finishes a word; it is not a send.\n if (e.key === \"Enter\" && !e.shiftKey && !isImeComposing(e)) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n /** Above the input: click a pill to dump it in, APPENDED to what is already typed. */\n const insertPaste = useCallback(\n (held: HeldPaste) => {\n // `expand` removes it and hands back the text; inserting is this\n // component's job because the hook owns no DOM.\n const text = pills.expand(held.id);\n\n if (text === undefined) return;\n\n setValue((current) => (current ? `${current}\\n\\n${text}` : text));\n textareaRef.current?.focus();\n },\n [pills, setValue],\n );\n\n return (\n <div\n data-react-fancy-composer=\"\"\n // Absent while idle; \"submitting\" while an onSubmit Promise is pending;\n // \"error\" after one was refused, until the next send.\n data-submit-state={ack.status === \"idle\" ? undefined : ack.status}\n ref={ref}\n className={cn(\n \"rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n disabled && \"opacity-50\",\n className,\n )}\n >\n {!inline && heldPastes.length > 0 && (\n <div\n data-react-fancy-composer-paste-pills=\"\"\n className=\"flex flex-wrap gap-1.5 px-3 pt-3\"\n >\n {heldPastes.map((paste) => (\n // `group` + `group-hover` rather than hover state: the preview is\n // presentation, and a useState for it would be one more thing an\n // agent could desynchronise.\n <span key={paste.id} className=\"group relative inline-flex\">\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill={paste.id}\n onClick={() => insertPaste(paste)}\n disabled={disabled}\n // No `title`. A native tooltip plus the hover preview below\n // renders TWO tooltips on the same hover, at different delays.\n // The label says what clicking does; the preview says what the\n // text is, and it is linked rather than merely adjacent so a\n // screen reader reaches it too.\n aria-label={`Insert this pasted text, ${withSeparators(paste.text.length)} characters`}\n aria-describedby={`${paste.id}-preview`}\n // `pr-7` leaves room for the absolutely-positioned × that sits\n // over this button's right edge. With a smaller right padding the\n // × lands on top of the label.\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700\",\n classNames?.pill,\n classNames?.textPill,\n )}\n >\n <span>\n Pasted text · {withSeparators(paste.text.length)} characters\n </span>\n </button>\n\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill-remove={paste.id}\n onClick={() => pills.remove(paste.id)}\n disabled={disabled}\n aria-label=\"Discard this pasted text\"\n className={cn(\n \"absolute right-1 top-1/2 -translate-y-1/2 rounded-full px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-700 dark:hover:text-zinc-100\",\n classNames?.remove,\n )}\n >\n ×\n </button>\n\n <span\n id={`${paste.id}-preview`}\n data-react-fancy-composer-paste-pill-preview={paste.id}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900\",\n classNames?.preview,\n )}\n >\n {renderPastePreview?.({ kind: \"text\", paste }) ??\n endsOf(paste.text, previewChars)}\n </span>\n </span>\n ))}\n </div>\n )}\n\n {inline ? (\n <>\n <InlinePasteEditor\n ref={editorRef}\n value={value}\n known={paste.known}\n onChange={handleInlineChange}\n onSubmit={handleSubmit}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={placeholder}\n disabled={disabled}\n id={inputId}\n className={classNames?.input}\n />\n {paste.portals}\n {/* A contenteditable is no form field, so `name` rides on a hidden\n one carrying what a send would carry: the expanded text. */}\n {name && <input type=\"hidden\" name={name} value={composeOutgoing()} />}\n {pasteImages && pasteFilesName && (\n <PastedFilesInput name={pasteFilesName} files={pastedFiles} />\n )}\n </>\n ) : (\n <textarea\n ref={textareaRef}\n // Its own handle, NOT the inline editor's `data-react-fancy-composer-input`:\n // that one already means \"the contenteditable is on\", and a host that\n // tests for it to pick a write path must not be handed a textarea.\n data-react-fancy-composer-textarea=\"\"\n id={inputId}\n name={name}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none bg-transparent px-4 pt-3 text-sm outline-none placeholder:text-zinc-400\",\n classNames?.input,\n )}\n />\n )}\n <div className=\"relative flex items-center justify-between border-t border-zinc-100 px-3 py-2 dark:border-zinc-800\">\n <div className=\"flex items-center gap-1\">{actions}</div>\n {ack.status === \"error\" && (\n // Mounted with its text, as `role=\"alert\"` is announced on insertion.\n <div\n role=\"alert\"\n data-react-fancy-composer-error=\"\"\n className=\"sr-only\"\n style={visuallyHidden}\n >\n {ack.message}\n </div>\n )}\n <button\n type=\"button\"\n data-react-fancy-composer-send=\"\"\n onClick={handleSubmit}\n disabled={disabled || sendDisabled || submitting || !hasContent}\n aria-busy={submitting || undefined}\n className=\"rounded-lg bg-zinc-900 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 disabled:opacity-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100\"\n >\n Send\n </button>\n </div>\n </div>\n );\n },\n);\n\nComposer.displayName = \"Composer\";\n\n/** Same pills, same content: a host echoing a copy of what it was told is not a new revision. */\nfunction samePastes(a: HeldPaste[], b: HeldPaste[]): boolean {\n return (\n a.length === b.length &&\n a.every((p, i) => p.id === b[i]!.id && p.text === b[i]!.text && p.label === b[i]!.label)\n );\n}\n\nfunction sameImages(a: HeldImage[], b: HeldImage[]): boolean {\n return (\n a.length === b.length &&\n a.every((img, i) => img.id === b[i]!.id && img.label === b[i]!.label && img.file === b[i]!.file)\n );\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Select } from './chunk-XIA2UAVO.js';
|
|
1
2
|
import { Switch } from './chunk-DXZCKDYS.js';
|
|
2
3
|
import { DatePicker } from './chunk-2UTN3EFK.js';
|
|
3
4
|
import { Input } from './chunk-PJNUGSKI.js';
|
|
4
|
-
import { Select } from './chunk-M6UAVA2I.js';
|
|
5
5
|
import { Textarea } from './chunk-UVUBV4VZ.js';
|
|
6
6
|
import { DisplayValue } from './chunk-WX5XYDVN.js';
|
|
7
7
|
import { resolveOption } from './chunk-USWQAMI3.js';
|
|
@@ -1338,5 +1338,5 @@ function buildItems({
|
|
|
1338
1338
|
}
|
|
1339
1339
|
|
|
1340
1340
|
export { JSON_FIELD_TYPES, JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches };
|
|
1341
|
-
//# sourceMappingURL=chunk-
|
|
1342
|
-
//# sourceMappingURL=chunk-
|
|
1341
|
+
//# sourceMappingURL=chunk-OPDHSOUN.js.map
|
|
1342
|
+
//# sourceMappingURL=chunk-OPDHSOUN.js.map
|