@bikdotai/bik-component-library 0.0.811-beta.2 → 0.0.811
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/dist/cjs/components/feature-announcements/hooks/useFeatureAnnouncements.js +1 -1
- package/dist/cjs/components/feature-announcements/hooks/useFeatureAnnouncements.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.styles.js +12 -22
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/cjs/editor/BikEditor.utils.js +1 -1
- package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/PasteNormalizationExtension.js +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/PasteNormalizationExtension.js.map +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js.map +1 -1
- package/dist/cjs/src/components/QueryBuilder/Triggers/EVENTS/components/EventsTrigger.d.ts +1 -1
- package/dist/cjs/src/components/QueryBuilder/Triggers/EVENTS/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
- package/dist/cjs/src/components/QueryBuilder/Triggers/IG/components/IGTrigger.d.ts +1 -1
- package/dist/cjs/src/components/QueryBuilder/Triggers/IG/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
- package/dist/cjs/src/components/QueryBuilder/Triggers/components/BaseTriggerQueryBuilderNode.d.ts +2 -2
- package/dist/cjs/src/components/bik-layout/MockMenus.d.ts +0 -1
- package/dist/cjs/src/editor/BikEditor.styles.d.ts +1 -1
- package/dist/cjs/src/editor/BikEditor.types.d.ts +2 -0
- package/dist/cjs/src/editor/BikEditor.utils.d.ts +8 -14
- package/dist/cjs/src/editor/extensions/buildExtensions.d.ts +2 -1
- package/dist/cjs/src/editor/extensions/plainClipboard/PasteNormalizationExtension.d.ts +4 -22
- package/dist/cjs/src/editor/extensions/plainClipboard/pasteUtils.d.ts +5 -28
- package/dist/esm/components/feature-announcements/hooks/useFeatureAnnouncements.js +1 -1
- package/dist/esm/components/feature-announcements/hooks/useFeatureAnnouncements.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +1 -1
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.js +12 -22
- package/dist/esm/editor/BikEditor.styles.js.map +1 -1
- package/dist/esm/editor/BikEditor.types.js.map +1 -1
- package/dist/esm/editor/BikEditor.utils.js +1 -1
- package/dist/esm/editor/BikEditor.utils.js.map +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/esm/editor/extensions/plainClipboard/PasteNormalizationExtension.js +1 -1
- package/dist/esm/editor/extensions/plainClipboard/PasteNormalizationExtension.js.map +1 -1
- package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js +1 -1
- package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js.map +1 -1
- package/dist/esm/src/components/QueryBuilder/Triggers/EVENTS/components/EventsTrigger.d.ts +1 -1
- package/dist/esm/src/components/QueryBuilder/Triggers/EVENTS/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
- package/dist/esm/src/components/QueryBuilder/Triggers/IG/components/IGTrigger.d.ts +1 -1
- package/dist/esm/src/components/QueryBuilder/Triggers/IG/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
- package/dist/esm/src/components/QueryBuilder/Triggers/components/BaseTriggerQueryBuilderNode.d.ts +2 -2
- package/dist/esm/src/components/bik-layout/MockMenus.d.ts +0 -1
- package/dist/esm/src/editor/BikEditor.styles.d.ts +1 -1
- package/dist/esm/src/editor/BikEditor.types.d.ts +2 -0
- package/dist/esm/src/editor/BikEditor.utils.d.ts +8 -14
- package/dist/esm/src/editor/extensions/buildExtensions.d.ts +2 -1
- package/dist/esm/src/editor/extensions/plainClipboard/PasteNormalizationExtension.d.ts +4 -22
- package/dist/esm/src/editor/extensions/plainClipboard/pasteUtils.d.ts +5 -28
- package/package.json +1 -2
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Fragment, Schema, Slice } from '@tiptap/pm/model';
|
|
2
2
|
export declare const TEXTBLOCK_TAGS: Set<string>;
|
|
3
3
|
export declare const BLOCK_SELECTOR = "p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre";
|
|
4
|
-
/** Normalise clipboard newlines: Windows CRLF and lone CR → LF. */
|
|
5
|
-
export declare function normalizeNewlines(text: string): string;
|
|
6
4
|
/**
|
|
7
5
|
* When pasted HTML is entirely inline (no block elements), split at
|
|
8
6
|
* `<br><br>` boundaries into `<p>` elements. Single `<br>` stays as a
|
|
@@ -23,31 +21,14 @@ export declare function cleanBlockBrs(container: HTMLElement): void;
|
|
|
23
21
|
*/
|
|
24
22
|
export declare function stripTrailingBrs(container: HTMLElement): void;
|
|
25
23
|
/**
|
|
26
|
-
* Convert
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* (childCount 0) gives a single-height blank line.
|
|
24
|
+
* Convert paragraphs containing only a hardBreak into truly empty paragraphs.
|
|
25
|
+
* Google Docs represents blank lines as `<p><br></p>` — ProseMirror parses
|
|
26
|
+
* the `<br>` as a hardBreak node, which renders double-height. Converting to
|
|
27
|
+
* an empty paragraph (childCount 0) gives a single-height blank line.
|
|
30
28
|
*
|
|
31
|
-
* Does NOT
|
|
32
|
-
* collapse consecutive empties — those `<br>`s/blank lines are intentional
|
|
33
|
-
* (e.g. shift+enter / enter runs from Google Docs) and Gmail preserves them.
|
|
29
|
+
* Does NOT collapse consecutive empties — that would destroy user intent.
|
|
34
30
|
*/
|
|
35
31
|
export declare function normalizeHardBreaks(fragment: Fragment): Fragment;
|
|
36
|
-
/**
|
|
37
|
-
* Mirror the source paragraph-margin convention across a pasted block.
|
|
38
|
-
*
|
|
39
|
-
* Gmail decides spacing from the SOURCE: it keeps default margins for content
|
|
40
|
-
* pasted from ChatGPT/plain `<p>`, and `margin:0` for Google-Docs-style content
|
|
41
|
-
* (whose paragraphs carry `margin:0`). We do the same. A paragraph's margin is
|
|
42
|
-
* already preserved from the source (the Paragraph node's `margin` attribute),
|
|
43
|
-
* so the only gap is the synthesized blank-line paragraphs (created from a
|
|
44
|
-
* Google-Docs block-level `<br>`), which have no source margin. If the pasted
|
|
45
|
-
* block is margin:0-style (any paragraph carries margin:0), apply margin:0 to
|
|
46
|
-
* every paragraph of THIS paste — so the blank lines match. Pastes with no
|
|
47
|
-
* margin:0 paragraph (ChatGPT, plain text) are left untouched → default margins.
|
|
48
|
-
* Scoped to the pasted slice, so it never tightens existing/typed content.
|
|
49
|
-
*/
|
|
50
|
-
export declare function mirrorParagraphMargins(fragment: Fragment): Fragment;
|
|
51
32
|
/**
|
|
52
33
|
* Strip "rich" marks (link, textStyle, highlight, etc.) while keeping
|
|
53
34
|
* basic marks (bold, italic, strike, underline, code) that messaging
|
|
@@ -68,9 +49,5 @@ export declare function parseClipboardText(text: string, schema: Schema): Slice;
|
|
|
68
49
|
* every `\n`. Produces the same structure as Gmail's Cmd+Shift+V output:
|
|
69
50
|
* one block element with `<br>` for line breaks and `<br><br>` for blank
|
|
70
51
|
* lines. This gives identical html and text output to Gmail.
|
|
71
|
-
*
|
|
72
|
-
* The paragraph is tight (`margin: '0'`) — plain/paste-without-formatting is
|
|
73
|
-
* Gmail's `<div>` (no margin), and typed Enter inherits this margin, so
|
|
74
|
-
* splitting plain-pasted text stays tight like Gmail (not default-margin gaps).
|
|
75
52
|
*/
|
|
76
53
|
export declare function parseClipboardTextAsBreaks(text: string, schema: Schema): Slice;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__awaiter as e}from"../../../_virtual/_tslib.js";import{useState as t,useCallback as r,useEffect as o}from"react";import{ANIMATION_TIMING as i}from"../constants/animations.js";import{QUERY_PARAMS as a,LOCAL_STORAGE_KEYS as n}from"../constants/localStorageKeys.js";const l=l=>{let{fetchVisibleFeatures:d,getStoreFeatureProgress:u,fetchFeatureById:s,markFeatureAsViewedForStore:c,isFeatureApplicableToCurrentPage:f,module:p,router:g}=l;var v;const y=(()=>{const[e,r]=t(null);return o((()=>{if("undefined"!=typeof window){let e=null;try{if(e=localStorage.getItem(n.STORE_ID)||localStorage.getItem(n.BIK_STORE_ID)||localStorage.getItem(n.CURRENT_STORE)||localStorage.getItem(n.STORE),!e){const t=localStorage.getItem(n.CURRENT_USER);t&&(e=JSON.parse(t).storeId)}e||(e=new URLSearchParams(window.location.search).get(n.QUERY_PARAM))}catch(e){}r(e)}}),[]),e})(),[m,D]=t([]),[U,
|
|
1
|
+
import{__awaiter as e}from"../../../_virtual/_tslib.js";import{useState as t,useCallback as r,useEffect as o}from"react";import{ANIMATION_TIMING as i}from"../constants/animations.js";import{QUERY_PARAMS as a,LOCAL_STORAGE_KEYS as n}from"../constants/localStorageKeys.js";const l=l=>{let{fetchVisibleFeatures:d,getStoreFeatureProgress:u,fetchFeatureById:s,markFeatureAsViewedForStore:c,isFeatureApplicableToCurrentPage:f,module:p,router:g}=l;var v;const y=(()=>{const[e,r]=t(null);return o((()=>{if("undefined"!=typeof window){let e=null;try{if(e=localStorage.getItem(n.STORE_ID)||localStorage.getItem(n.BIK_STORE_ID)||localStorage.getItem(n.CURRENT_STORE)||localStorage.getItem(n.STORE),!e){const t=localStorage.getItem(n.CURRENT_USER);t&&(e=JSON.parse(t).storeId)}e||(e=new URLSearchParams(window.location.search).get(n.QUERY_PARAM))}catch(e){}r(e)}}),[]),e})(),[m,D]=t([]),[U,h]=t([]),[w,R]=t([]),[I,S]=t(!1),[T,x]=t(null),E=r((()=>e(void 0,void 0,void 0,(function*(){if(y){S(!0),x(null);try{const[e,t]=yield d(p);if(e||!t)return void x("Failed to fetch features");const[r,o]=yield u(y),a=new Date,n="undefined"!=typeof window?window.location.pathname:"",l=e=>{if(!e.expirationDate)return!0;let t;return"object"==typeof e.expirationDate&&null!==e.expirationDate&&("seconds"in e.expirationDate||"nanoseconds"in e.expirationDate)?t=new Date(1e3*e.expirationDate.seconds):"string"==typeof e.expirationDate?t=new Date(e.expirationDate):e.expirationDate instanceof Date&&(t=e.expirationDate),!(!t||isNaN(t.getTime()))&&a<t},s=e=>{if("Major"===e.featureUpdateType){let t=[];return Array.isArray(e.pageUrls)?t=e.pageUrls:"object"==typeof e.pageUrls&&null!==e.pageUrls&&"length"in e.pageUrls&&(t=Array.from(e.pageUrls)),0===t.length||t.some((e=>{if(e===n)return!0;const t=e.replace(/\[([^\]]+)\]/g,"[^/]+").replace(/\//g,"\\/");return new RegExp(`^${t}$`).test(n)}))}return!0},c=t.filter((e=>{var t;const r=(null===(t=null==o?void 0:o.viewedFeatures)||void 0===t?void 0:t[e.id])||!1,i=e.archived||!1,a=f(e),n=l(e),d=s(e);return!r&&!i&&a&&n&&d})),g=c.filter((e=>"Major"===e.featureUpdateType)),v=c.filter((e=>"Minor"===e.featureUpdateType));D(c),h(g),setTimeout((()=>{R(v)}),i.MINOR_POPUP_DELAY)}catch(e){x("An unexpected error occurred")}finally{S(!1)}}}))),[y,d,u,f,p]),F=r((t=>e(void 0,void 0,void 0,(function*(){S(!0),x(null);try{const[e,r]=yield s(t);if(e||!r)return void x("Failed to fetch feature by ID");"Major"===r.featureUpdateType?h([r]):R([r]),D([r])}catch(e){x("An unexpected error occurred while fetching by ID")}finally{S(!1)}}))),[s]),A=r((t=>e(void 0,void 0,void 0,(function*(){if(!y)return;const[e]=yield c(y,t);D((e=>e.filter((e=>e.id!==t)))),h((e=>e.filter((e=>e.id!==t)))),R((e=>e.filter((e=>e.id!==t))))}))),[y,c]);return o((()=>{var e;const t=null===(e=null==g?void 0:g.query)||void 0===e?void 0:e[a.FEATURE_ID];t&&g?F(t):E()}),[null==g?void 0:g.pathname,null===(v=null==g?void 0:g.query)||void 0===v?void 0:v[a.FEATURE_ID],y,E,F,g]),{features:m,majorUpdateFeatures:U,minorUpdateFeatures:w,isLoading:I,error:T,markFeatureAsViewed:A,refetch:E}};export{l as useFeatureAnnouncements};
|
|
2
2
|
//# sourceMappingURL=useFeatureAnnouncements.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFeatureAnnouncements.js","sources":["../../../../../src/components/feature-announcements/hooks/useFeatureAnnouncements.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport {\n\tANIMATION_TIMING,\n\tLOCAL_STORAGE_KEYS,\n\tQUERY_PARAMS,\n} from '../constants';\nimport {\n\tFeatureAnnouncement,\n\tFeatureAnnouncementRepository,\n\tRouterProps,\n} from '../types';\n\nconst useStoreId = () => {\n\tconst [storeId, setStoreId] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tlet storedStoreId: string | null = null;\n\n\t\t\ttry {\n\t\t\t\tstoredStoreId =\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.STORE_ID) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.BIK_STORE_ID) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.CURRENT_STORE) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.STORE);\n\n\t\t\t\tif (!storedStoreId) {\n\t\t\t\t\tconst currentUser = localStorage.getItem(\n\t\t\t\t\t\tLOCAL_STORAGE_KEYS.CURRENT_USER,\n\t\t\t\t\t);\n\t\t\t\t\tif (currentUser) {\n\t\t\t\t\t\tconst parsed = JSON.parse(currentUser);\n\t\t\t\t\t\tstoredStoreId = parsed.storeId;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!storedStoreId) {\n\t\t\t\t\tstoredStoreId = new URLSearchParams(window.location.search).get(\n\t\t\t\t\t\tLOCAL_STORAGE_KEYS.QUERY_PARAM,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Failed to get store ID\n\t\t\t}\n\t\t\tsetStoreId(storedStoreId);\n\t\t}\n\t}, []);\n\n\treturn storeId;\n};\n\nexport const useFeatureAnnouncements = ({\n\tfetchVisibleFeatures,\n\tgetStoreFeatureProgress,\n\tfetchFeatureById,\n\tmarkFeatureAsViewedForStore,\n\tisFeatureApplicableToCurrentPage,\n\tmodule,\n\trouter,\n}: FeatureAnnouncementRepository & {\n\tmodule?: string;\n\trouter?: RouterProps;\n}) => {\n\tconst storeId = useStoreId();\n\tconst [features, setFeatures] = useState<FeatureAnnouncement[]>([]);\n\tconst [majorUpdateFeatures, setMajorUpdateFeatures] = useState<\n\t\tFeatureAnnouncement[]\n\t>([]);\n\tconst [minorUpdateFeatures, setMinorUpdateFeatures] = useState<\n\t\tFeatureAnnouncement[]\n\t>([]);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst fetchFeatures = useCallback(async () => {\n\t\tif (!storeId) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst [featuresError, allFeatures] = await fetchVisibleFeatures(module);\n\n\t\t\tif (featuresError || !allFeatures) {\n\t\t\t\tsetError('Failed to fetch features');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst [progressError, userProgress] = await getStoreFeatureProgress(\n\t\t\t\tstoreId,\n\t\t\t);\n\n\t\t\tif (progressError) {\n\t\t\t\t// Progress fetch failed, treating all features as new\n\t\t\t}\n\n\t\t\tconst now = new Date();\n\t\t\tconst currentRoute =\n\t\t\t\ttypeof window !== 'undefined' ? window.location.pathname : '';\n\n\t\t\tconst isNotExpired = (feature: FeatureAnnouncement) => {\n\t\t\t\tif (!feature.expirationDate) return true;\n\t\t\t\tlet expiry: Date | undefined;\n\t\t\t\t// Firestore timestamp object\n\t\t\t\tif (\n\t\t\t\t\ttypeof feature.expirationDate === 'object' &&\n\t\t\t\t\tfeature.expirationDate !== null &&\n\t\t\t\t\t('seconds' in feature.expirationDate ||\n\t\t\t\t\t\t'nanoseconds' in feature.expirationDate)\n\t\t\t\t) {\n\t\t\t\t\t// Firestore timestamp: { seconds: number, nanoseconds?: number }\n\t\t\t\t\texpiry = new Date((feature.expirationDate as any).seconds * 1000);\n\t\t\t\t} else if (typeof feature.expirationDate === 'string') {\n\t\t\t\t\t// String date\n\t\t\t\t\texpiry = new Date(feature.expirationDate);\n\t\t\t\t} else if (feature.expirationDate instanceof Date) {\n\t\t\t\t\texpiry = feature.expirationDate;\n\t\t\t\t}\n\t\t\t\tif (!expiry || isNaN(expiry.getTime())) return false;\n\t\t\t\treturn now < expiry;\n\t\t\t};\n\n\t\t\tconst isOnCorrectPage = (feature: FeatureAnnouncement) => {\n\t\t\t\tif (feature.featureUpdateType === 'Major') {\n\t\t\t\t\t// Accept both array and object (Firestore array)\n\t\t\t\t\tlet urls: string[] = [];\n\t\t\t\t\tif (Array.isArray(feature.pageUrls)) {\n\t\t\t\t\t\turls = feature.pageUrls;\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof feature.pageUrls === 'object' &&\n\t\t\t\t\t\tfeature.pageUrls !== null &&\n\t\t\t\t\t\t'length' in feature.pageUrls\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Firestore array\n\t\t\t\t\t\turls = Array.from(feature.pageUrls as any);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check for exact match or dynamic route pattern match\n\t\t\t\t\treturn urls.some((url) => {\n\t\t\t\t\t\t// Exact match\n\t\t\t\t\t\tif (url === currentRoute) return true;\n\n\t\t\t\t\t\t// Dynamic route matching (e.g., /campaign/details/[broadcastId])\n\t\t\t\t\t\t// Convert Next.js route pattern to regex\n\t\t\t\t\t\tconst pattern = url\n\t\t\t\t\t\t\t.replace(/\\[([^\\]]+)\\]/g, '[^/]+') // Replace [param] with [^/]+\n\t\t\t\t\t\t\t.replace(/\\//g, '\\\\/'); // Escape forward slashes\n\n\t\t\t\t\t\tconst regex = new RegExp(`^${pattern}$`);\n\t\t\t\t\t\treturn regex.test(currentRoute);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t};\n\n\t\t\tconst unviewedFeatures = allFeatures.filter((feature) => {\n\t\t\t\tconst isViewed = userProgress?.viewedFeatures?.[feature.id] || false;\n\t\t\t\tconst isArchived = feature.archived || false;\n\t\t\t\tconst isApplicable = isFeatureApplicableToCurrentPage(feature);\n\t\t\t\tconst notExpired = isNotExpired(feature);\n\t\t\t\tconst onCorrectPage = isOnCorrectPage(feature);\n\n\t\t\t\tconst shouldShow =\n\t\t\t\t\t!isViewed &&\n\t\t\t\t\t!isArchived &&\n\t\t\t\t\tisApplicable &&\n\t\t\t\t\tnotExpired &&\n\t\t\t\t\tonCorrectPage;\n\n\t\t\t\treturn shouldShow;\n\t\t\t});\n\n\t\t\t// Separate major and minor updates\n\t\t\tconst majorFeatures = unviewedFeatures.filter(\n\t\t\t\t(f) => f.featureUpdateType === 'Major',\n\t\t\t);\n\t\t\tconst minorFeatures = unviewedFeatures.filter(\n\t\t\t\t(f) => f.featureUpdateType === 'Minor',\n\t\t\t);\n\n\t\t\tsetFeatures(unviewedFeatures);\n\t\t\tsetMajorUpdateFeatures(majorFeatures);\n\t\t\t// Delay minor popups by 2 seconds\n\t\t\tsetTimeout(() => {\n\t\t\t\tsetMinorUpdateFeatures(minorFeatures);\n\t\t\t}, ANIMATION_TIMING.MINOR_POPUP_DELAY);\n\t\t} catch (err) {\n\t\t\tsetError('An unexpected error occurred');\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [\n\t\tstoreId,\n\t\tfetchVisibleFeatures,\n\t\tgetStoreFeatureProgress,\n\t\tisFeatureApplicableToCurrentPage,\n\t\tmodule,\n\t]);\n\n\tconst fetchFeatureByIdCallback = useCallback(\n\t\tasync (featureId: string) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst [error, feature] = await fetchFeatureById(featureId);\n\t\t\t\tif (error || !feature) {\n\t\t\t\t\tsetError('Failed to fetch feature by ID');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (feature.featureUpdateType === 'Major') {\n\t\t\t\t\tsetMajorUpdateFeatures([feature]);\n\t\t\t\t} else {\n\t\t\t\t\tsetMinorUpdateFeatures([feature]);\n\t\t\t\t}\n\t\t\t\tsetFeatures([feature]);\n\t\t\t} catch (err) {\n\t\t\t\tsetError('An unexpected error occurred while fetching by ID');\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[fetchFeatureById],\n\t);\n\n\tconst markFeatureAsViewedCallback = useCallback(\n\t\tasync (featureId: string) => {\n\t\t\tif (!storeId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst [error] = await markFeatureAsViewedForStore(storeId, featureId);\n\n\t\t\tif (!error) {\n\t\t\t\tsetFeatures((prev) => prev.filter((f) => f.id !== featureId));\n\t\t\t\tsetMajorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t\tsetMinorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Failed to mark feature as viewed, removing from local state anyway\n\t\t\t\tsetFeatures((prev) => prev.filter((f) => f.id !== featureId));\n\t\t\t\tsetMajorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t\tsetMinorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[storeId, markFeatureAsViewedForStore],\n\t);\n\n\tuseEffect(() => {\n\t\tconst featureIdFromQuery = router?.query?.[\n\t\t\tQUERY_PARAMS.FEATURE_ID\n\t\t] as string;\n\n\t\t// In test mode with featureId, ONLY fetch that specific feature\n\t\tif (featureIdFromQuery && router) {\n\t\t\tfetchFeatureByIdCallback(featureIdFromQuery);\n\t\t\treturn; // Don't run fetchFeatures\n\t\t}\n\n\t\t// Normal mode: fetch all features\n\t\tfetchFeatures();\n\t}, [\n\t\trouter?.pathname,\n\t\trouter?.query?.[QUERY_PARAMS.FEATURE_ID],\n\t\tstoreId,\n\t\tfetchFeatures,\n\t\tfetchFeatureByIdCallback,\n\t\trouter,\n\t]);\n\n\treturn {\n\t\tfeatures,\n\t\tmajorUpdateFeatures,\n\t\tminorUpdateFeatures,\n\t\tisLoading,\n\t\terror,\n\t\tmarkFeatureAsViewed: markFeatureAsViewedCallback,\n\t\trefetch: fetchFeatures,\n\t};\n};\n"],"names":["useFeatureAnnouncements","_ref","fetchVisibleFeatures","getStoreFeatureProgress","fetchFeatureById","markFeatureAsViewedForStore","isFeatureApplicableToCurrentPage","module","router","storeId","useStoreId","setStoreId","useState","useEffect","window","storedStoreId","localStorage","getItem","LOCAL_STORAGE_KEYS","STORE_ID","BIK_STORE_ID","CURRENT_STORE","STORE","currentUser","CURRENT_USER","JSON","parse","URLSearchParams","location","search","get","QUERY_PARAM","e","features","setFeatures","majorUpdateFeatures","setMajorUpdateFeatures","minorUpdateFeatures","setMinorUpdateFeatures","isLoading","setIsLoading","error","setError","fetchFeatures","useCallback","__awaiter","featuresError","allFeatures","progressError","userProgress","now","Date","currentRoute","pathname","isNotExpired","feature","expirationDate","expiry","seconds","isNaN","getTime","isOnCorrectPage","featureUpdateType","urls","Array","isArray","pageUrls","from","some","url","pattern","replace","RegExp","test","unviewedFeatures","filter","isViewed","viewedFeatures","id","isArchived","archived","isApplicable","notExpired","onCorrectPage","majorFeatures","f","minorFeatures","setTimeout","ANIMATION_TIMING","MINOR_POPUP_DELAY","err","fetchFeatureByIdCallback","featureId","markFeatureAsViewedCallback","prev","featureIdFromQuery","_a","query","QUERY_PARAMS","FEATURE_ID","markFeatureAsViewed","refetch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFeatureAnnouncements.js","sources":["../../../../../src/components/feature-announcements/hooks/useFeatureAnnouncements.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport {\n\tANIMATION_TIMING,\n\tLOCAL_STORAGE_KEYS,\n\tQUERY_PARAMS,\n} from '../constants';\nimport {\n\tFeatureAnnouncement,\n\tFeatureAnnouncementRepository,\n\tRouterProps,\n} from '../types';\n\nconst useStoreId = () => {\n\tconst [storeId, setStoreId] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tlet storedStoreId: string | null = null;\n\n\t\t\ttry {\n\t\t\t\tstoredStoreId =\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.STORE_ID) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.BIK_STORE_ID) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.CURRENT_STORE) ||\n\t\t\t\t\tlocalStorage.getItem(LOCAL_STORAGE_KEYS.STORE);\n\n\t\t\t\tif (!storedStoreId) {\n\t\t\t\t\tconst currentUser = localStorage.getItem(\n\t\t\t\t\t\tLOCAL_STORAGE_KEYS.CURRENT_USER,\n\t\t\t\t\t);\n\t\t\t\t\tif (currentUser) {\n\t\t\t\t\t\tconst parsed = JSON.parse(currentUser);\n\t\t\t\t\t\tstoredStoreId = parsed.storeId;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!storedStoreId) {\n\t\t\t\t\tstoredStoreId = new URLSearchParams(window.location.search).get(\n\t\t\t\t\t\tLOCAL_STORAGE_KEYS.QUERY_PARAM,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Failed to get store ID\n\t\t\t}\n\t\t\tsetStoreId(storedStoreId);\n\t\t}\n\t}, []);\n\n\treturn storeId;\n};\n\nexport const useFeatureAnnouncements = ({\n\tfetchVisibleFeatures,\n\tgetStoreFeatureProgress,\n\tfetchFeatureById,\n\tmarkFeatureAsViewedForStore,\n\tisFeatureApplicableToCurrentPage,\n\tmodule,\n\trouter,\n}: FeatureAnnouncementRepository & {\n\tmodule?: string;\n\trouter?: RouterProps;\n}) => {\n\tconst storeId = useStoreId();\n\tconst [features, setFeatures] = useState<FeatureAnnouncement[]>([]);\n\tconst [majorUpdateFeatures, setMajorUpdateFeatures] = useState<\n\t\tFeatureAnnouncement[]\n\t>([]);\n\tconst [minorUpdateFeatures, setMinorUpdateFeatures] = useState<\n\t\tFeatureAnnouncement[]\n\t>([]);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst fetchFeatures = useCallback(async () => {\n\t\tif (!storeId) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst [featuresError, allFeatures] = await fetchVisibleFeatures(module);\n\n\t\t\tif (featuresError || !allFeatures) {\n\t\t\t\tsetError('Failed to fetch features');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst [progressError, userProgress] = await getStoreFeatureProgress(\n\t\t\t\tstoreId,\n\t\t\t);\n\n\t\t\tif (progressError) {\n\t\t\t\t// Progress fetch failed, treating all features as new\n\t\t\t}\n\n\t\t\tconst now = new Date();\n\t\t\tconst currentRoute =\n\t\t\t\ttypeof window !== 'undefined' ? window.location.pathname : '';\n\n\t\t\tconst isNotExpired = (feature: FeatureAnnouncement) => {\n\t\t\t\tif (!feature.expirationDate) return true;\n\t\t\t\tlet expiry: Date | undefined;\n\t\t\t\t// Firestore timestamp object\n\t\t\t\tif (\n\t\t\t\t\ttypeof feature.expirationDate === 'object' &&\n\t\t\t\t\tfeature.expirationDate !== null &&\n\t\t\t\t\t('seconds' in feature.expirationDate ||\n\t\t\t\t\t\t'nanoseconds' in feature.expirationDate)\n\t\t\t\t) {\n\t\t\t\t\t// Firestore timestamp: { seconds: number, nanoseconds?: number }\n\t\t\t\t\texpiry = new Date((feature.expirationDate as any).seconds * 1000);\n\t\t\t\t} else if (typeof feature.expirationDate === 'string') {\n\t\t\t\t\t// String date\n\t\t\t\t\texpiry = new Date(feature.expirationDate);\n\t\t\t\t} else if (feature.expirationDate instanceof Date) {\n\t\t\t\t\texpiry = feature.expirationDate;\n\t\t\t\t}\n\t\t\t\tif (!expiry || isNaN(expiry.getTime())) return false;\n\t\t\t\treturn now < expiry;\n\t\t\t};\n\n\t\t\tconst isOnCorrectPage = (feature: FeatureAnnouncement) => {\n\t\t\t\tif (feature.featureUpdateType === 'Major') {\n\t\t\t\t\t// Accept both array and object (Firestore array)\n\t\t\t\t\tlet urls: string[] = [];\n\t\t\t\t\tif (Array.isArray(feature.pageUrls)) {\n\t\t\t\t\t\turls = feature.pageUrls;\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof feature.pageUrls === 'object' &&\n\t\t\t\t\t\tfeature.pageUrls !== null &&\n\t\t\t\t\t\t'length' in feature.pageUrls\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Firestore array\n\t\t\t\t\t\turls = Array.from(feature.pageUrls as any);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Empty pageUrls means no restriction — show on all pages\n\t\t\t\t\tif (urls.length === 0) return true;\n\n\t\t\t\t\t// Check for exact match or dynamic route pattern match\n\t\t\t\t\treturn urls.some((url) => {\n\t\t\t\t\t\t// Exact match\n\t\t\t\t\t\tif (url === currentRoute) return true;\n\n\t\t\t\t\t\t// Dynamic route matching (e.g., /campaign/details/[broadcastId])\n\t\t\t\t\t\t// Convert Next.js route pattern to regex\n\t\t\t\t\t\tconst pattern = url\n\t\t\t\t\t\t\t.replace(/\\[([^\\]]+)\\]/g, '[^/]+') // Replace [param] with [^/]+\n\t\t\t\t\t\t\t.replace(/\\//g, '\\\\/'); // Escape forward slashes\n\n\t\t\t\t\t\tconst regex = new RegExp(`^${pattern}$`);\n\t\t\t\t\t\treturn regex.test(currentRoute);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t};\n\n\t\t\tconst unviewedFeatures = allFeatures.filter((feature) => {\n\t\t\t\tconst isViewed = userProgress?.viewedFeatures?.[feature.id] || false;\n\t\t\t\tconst isArchived = feature.archived || false;\n\t\t\t\tconst isApplicable = isFeatureApplicableToCurrentPage(feature);\n\t\t\t\tconst notExpired = isNotExpired(feature);\n\t\t\t\tconst onCorrectPage = isOnCorrectPage(feature);\n\n\t\t\t\tconst shouldShow =\n\t\t\t\t\t!isViewed &&\n\t\t\t\t\t!isArchived &&\n\t\t\t\t\tisApplicable &&\n\t\t\t\t\tnotExpired &&\n\t\t\t\t\tonCorrectPage;\n\n\t\t\t\treturn shouldShow;\n\t\t\t});\n\n\t\t\t// Separate major and minor updates\n\t\t\tconst majorFeatures = unviewedFeatures.filter(\n\t\t\t\t(f) => f.featureUpdateType === 'Major',\n\t\t\t);\n\t\t\tconst minorFeatures = unviewedFeatures.filter(\n\t\t\t\t(f) => f.featureUpdateType === 'Minor',\n\t\t\t);\n\n\t\t\tsetFeatures(unviewedFeatures);\n\t\t\tsetMajorUpdateFeatures(majorFeatures);\n\t\t\t// Delay minor popups by 2 seconds\n\t\t\tsetTimeout(() => {\n\t\t\t\tsetMinorUpdateFeatures(minorFeatures);\n\t\t\t}, ANIMATION_TIMING.MINOR_POPUP_DELAY);\n\t\t} catch (err) {\n\t\t\tsetError('An unexpected error occurred');\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [\n\t\tstoreId,\n\t\tfetchVisibleFeatures,\n\t\tgetStoreFeatureProgress,\n\t\tisFeatureApplicableToCurrentPage,\n\t\tmodule,\n\t]);\n\n\tconst fetchFeatureByIdCallback = useCallback(\n\t\tasync (featureId: string) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst [error, feature] = await fetchFeatureById(featureId);\n\t\t\t\tif (error || !feature) {\n\t\t\t\t\tsetError('Failed to fetch feature by ID');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (feature.featureUpdateType === 'Major') {\n\t\t\t\t\tsetMajorUpdateFeatures([feature]);\n\t\t\t\t} else {\n\t\t\t\t\tsetMinorUpdateFeatures([feature]);\n\t\t\t\t}\n\t\t\t\tsetFeatures([feature]);\n\t\t\t} catch (err) {\n\t\t\t\tsetError('An unexpected error occurred while fetching by ID');\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[fetchFeatureById],\n\t);\n\n\tconst markFeatureAsViewedCallback = useCallback(\n\t\tasync (featureId: string) => {\n\t\t\tif (!storeId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst [error] = await markFeatureAsViewedForStore(storeId, featureId);\n\n\t\t\tif (!error) {\n\t\t\t\tsetFeatures((prev) => prev.filter((f) => f.id !== featureId));\n\t\t\t\tsetMajorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t\tsetMinorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Failed to mark feature as viewed, removing from local state anyway\n\t\t\t\tsetFeatures((prev) => prev.filter((f) => f.id !== featureId));\n\t\t\t\tsetMajorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t\tsetMinorUpdateFeatures((prev) =>\n\t\t\t\t\tprev.filter((f) => f.id !== featureId),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[storeId, markFeatureAsViewedForStore],\n\t);\n\n\tuseEffect(() => {\n\t\tconst featureIdFromQuery = router?.query?.[\n\t\t\tQUERY_PARAMS.FEATURE_ID\n\t\t] as string;\n\n\t\t// In test mode with featureId, ONLY fetch that specific feature\n\t\tif (featureIdFromQuery && router) {\n\t\t\tfetchFeatureByIdCallback(featureIdFromQuery);\n\t\t\treturn; // Don't run fetchFeatures\n\t\t}\n\n\t\t// Normal mode: fetch all features\n\t\tfetchFeatures();\n\t}, [\n\t\trouter?.pathname,\n\t\trouter?.query?.[QUERY_PARAMS.FEATURE_ID],\n\t\tstoreId,\n\t\tfetchFeatures,\n\t\tfetchFeatureByIdCallback,\n\t\trouter,\n\t]);\n\n\treturn {\n\t\tfeatures,\n\t\tmajorUpdateFeatures,\n\t\tminorUpdateFeatures,\n\t\tisLoading,\n\t\terror,\n\t\tmarkFeatureAsViewed: markFeatureAsViewedCallback,\n\t\trefetch: fetchFeatures,\n\t};\n};\n"],"names":["useFeatureAnnouncements","_ref","fetchVisibleFeatures","getStoreFeatureProgress","fetchFeatureById","markFeatureAsViewedForStore","isFeatureApplicableToCurrentPage","module","router","storeId","useStoreId","setStoreId","useState","useEffect","window","storedStoreId","localStorage","getItem","LOCAL_STORAGE_KEYS","STORE_ID","BIK_STORE_ID","CURRENT_STORE","STORE","currentUser","CURRENT_USER","JSON","parse","URLSearchParams","location","search","get","QUERY_PARAM","e","features","setFeatures","majorUpdateFeatures","setMajorUpdateFeatures","minorUpdateFeatures","setMinorUpdateFeatures","isLoading","setIsLoading","error","setError","fetchFeatures","useCallback","__awaiter","featuresError","allFeatures","progressError","userProgress","now","Date","currentRoute","pathname","isNotExpired","feature","expirationDate","expiry","seconds","isNaN","getTime","isOnCorrectPage","featureUpdateType","urls","Array","isArray","pageUrls","from","length","some","url","pattern","replace","RegExp","test","unviewedFeatures","filter","isViewed","viewedFeatures","id","isArchived","archived","isApplicable","notExpired","onCorrectPage","majorFeatures","f","minorFeatures","setTimeout","ANIMATION_TIMING","MINOR_POPUP_DELAY","err","fetchFeatureByIdCallback","featureId","markFeatureAsViewedCallback","prev","featureIdFromQuery","_a","query","QUERY_PARAMS","FEATURE_ID","markFeatureAsViewed","refetch"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as t,jsx as n}from"react/jsx-runtime";import{getMarkRange as e}from"../node_modules/@tiptap/core/dist/index.js";import{useEditor as o,EditorContent as
|
|
1
|
+
import{jsxs as t,jsx as n}from"react/jsx-runtime";import{getMarkRange as e}from"../node_modules/@tiptap/core/dist/index.js";import{useEditor as o,EditorContent as r}from"@tiptap/react";import{forwardRef as i,useRef as l,useEffect as s,useImperativeHandle as c}from"react";import{BikEditorShell as a}from"./BikEditor.styles.js";import{DEFAULT_FORMAT_STATE as u}from"./BikEditor.types.js";import{buildSectionedContent as d,normalizeHtml as m,extractContent as g,extractActiveFormats as v,extractSectionContent as h,extractBodyContent as f,insertInlineHtml as p,setSectionContentInEditor as C,findSectionEndPos as S,findSectionStartPos as k}from"./BikEditor.utils.js";import{buildExtensions as y}from"./extensions/buildExtensions.js";import{LinkBubbleMenu as x}from"./floating/LinkBubbleMenu.js";function B(t){return Object.entries(t).map((t=>{let[n,e]=t;return`${n.replace(/([A-Z])/g,(t=>`-${t.toLowerCase()}`))}:${e}`})).join(";")}const b=i(((i,b)=>{var A,I,j,L,E,O,T;const{initialContent:w,sections:F,features:H,disabled:M,maxCharacters:z,shortcuts:R,sendShortcut:D,mentions:N,slashCommands:U,link:P,onPaste:$,onReady:q,onChange:G,onSend:J,onFocus:V,onBlur:W,onSelectionChange:Z,minHeight:_,maxHeight:K,paragraphGap:Q,style:X,className:Y,editorClassName:tt,editorStyle:nt}=i,et=(null==F?void 0:F.length)?d(m(null!=w?w:""),F.map((t=>Object.assign(Object.assign({},t),{content:m(t.content)})))):m(null!=w?w:""),ot=l([]),rt=l(!1),it=l(q);it.current=q;const lt=l(G);lt.current=G;const st=l(Z);st.current=Z;const ct=l(V);ct.current=V;const at=l(W);at.current=W;const ut=l(J);ut.current=J;const dt=l(null!==(A=null==N?void 0:N.agents)&&void 0!==A?A:[]);dt.current=null!==(I=null==N?void 0:N.agents)&&void 0!==I?I:[];const mt=l(null!==(j=null==N?void 0:N.teams)&&void 0!==j?j:[]);mt.current=null!==(L=null==N?void 0:N.teams)&&void 0!==L?L:[];const gt=l(null!==(E=null==U?void 0:U.items)&&void 0!==E?E:[]);gt.current=null!==(O=null==U?void 0:U.items)&&void 0!==O?O:[];const vt=o({extensions:y({features:H,placeholder:i.placeholder,maxCharacters:z,hasSections:(null!==(T=null==F?void 0:F.length)&&void 0!==T?T:0)>0,mentions:{agents:N?dt:void 0,teams:N?mt:void 0},slashCommands:U?gt:void 0,onPaste:$,onSend:J?t=>{var n;return null===(n=ut.current)||void 0===n?void 0:n.call(ut,t)}:void 0,sendShortcut:D,shortcuts:R,onMentionSelected:null==N?void 0:N.onSelect,onSlashCommandSelected:null==U?void 0:U.onSelect,renderMentionItem:null==N?void 0:N.renderItem,renderMentionDropdown:null==N?void 0:N.renderDropdown,renderSlashCommandItem:null==U?void 0:U.renderItem,renderSlashCommandDropdown:null==U?void 0:U.renderDropdown}),content:et,editable:!M,immediatelyRender:!1,editorProps:{attributes:Object.assign(Object.assign({},tt?{class:tt}:{}),nt?{style:B(nt)}:{})},onUpdate:t=>{let{editor:n}=t;var e;null===(e=lt.current)||void 0===e||e.call(lt,g(n))},onTransaction:t=>{let{editor:n}=t;var e;null===(e=st.current)||void 0===e||e.call(st,v(n))},onFocus:()=>{var t;return null===(t=ct.current)||void 0===t?void 0:t.call(ct)},onBlur:()=>{var t;return null===(t=at.current)||void 0===t?void 0:t.call(at)}});function ht(t){vt?t(vt):ot.current.push(t)}return s((()=>{var t;if(vt){if(ot.current.length>0){ot.current.splice(0).forEach((t=>t(vt)))}rt.current||(rt.current=!0,null===(t=it.current)||void 0===t||t.call(it))}}),[vt]),c(b,(()=>({focus:t=>ht((n=>n.commands.focus(t))),blur:()=>ht((t=>t.commands.blur())),clearContent:()=>ht((t=>t.commands.clearContent(!0))),setContent:t=>{const n=m(t);ht((t=>t.commands.setContent(n,{emitUpdate:!0})))},insertContent:t=>{const n=m(t);ht((t=>t.commands.insertContent(n)))},insertInlineContent:t=>{ht((n=>p(n,t)))},insertAtStart:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(1,n)))},insertBlock:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(t.state.doc.content.size,n)))},appendInline:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(t.state.doc.content.size-1,n)))},insertAtEnd(t){this.insertBlock(t)},appendContent(t){this.appendInline(t)},getContent:()=>vt?g(vt):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>{var t;return null!==(t=null==vt?void 0:vt.getJSON())&&void 0!==t?t:null},getMentions:()=>{const t=new Set,n=new Set;return vt?(vt.state.doc.descendants((e=>{"mentionAgent"===e.type.name&&null!=e.attrs.id?t.add(String(e.attrs.id)):"mentionTeam"===e.type.name&&null!=e.attrs.id&&n.add(String(e.attrs.id))})),{agentIds:Array.from(t),teamIds:Array.from(n)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!vt)return{from:0,to:0};const{from:t,to:n}=vt.state.selection;return{from:t,to:n}},insertAtPosition:(t,n)=>{const e=m(n);ht((n=>n.commands.insertContentAt(t,e)))},getSelectedText:()=>{if(!vt)return"";const{state:t}=vt,{from:n,to:o,empty:r}=t.selection;if(!r)return t.doc.textBetween(n,o," ");const i=t.schema.marks.link;if(i){const o=e(t.doc.resolve(n),i);if(o)return t.doc.textBetween(o.from,o.to," ")}return""},getCharacterCount:()=>{var t,n,e,o;return{count:null!==(o=null!==(e=null===(n=null===(t=null==vt?void 0:vt.storage.characterCount)||void 0===t?void 0:t.characters)||void 0===n?void 0:n.call(t))&&void 0!==e?e:null==vt?void 0:vt.getText().length)&&void 0!==o?o:0,limit:null!=z?z:null}},getSectionContent:t=>vt?h(vt,t):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(t,n)=>{const e=m(n);ht((n=>C(n,t,e)))},focusSection:t=>{ht((n=>{if("body"===t){let t=n.state.doc.content.size-1;return n.state.doc.descendants(((e,o)=>("sectionDivider"===e.type.name&&t===n.state.doc.content.size-1&&(t=o-1),t===n.state.doc.content.size-1))),t<1&&(t=1),void n.chain().focus().setTextSelection(t).run()}let e=-1;n.state.doc.descendants(((n,o)=>{if(-1!==e)return!1;"sectionDivider"===n.type.name&&n.attrs.sectionId===t&&(e=o+n.nodeSize+1)})),-1!==e&&n.chain().focus().setTextSelection(e).run()}))},clearSection:t=>{ht((n=>C(n,t,"<p></p>")))},getBodyContent:()=>vt?f(vt):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:t=>{const n=m(t);ht((t=>C(t,"body",n)))},setBodyAndSections:(t,n)=>{const e=d(m(t),n.map((t=>({id:t.id,content:m(t.content)}))));ht((t=>t.commands.setContent(e,{emitUpdate:!0})))},appendBodyContent:t=>{const n=m(t);ht((t=>{const e=S(t,"body");t.commands.insertContentAt(e-1,n)}))},insertAtSectionStart:(t,n)=>{const e=m(n);ht((n=>{const o=k(n,t);-1!==o&&n.commands.insertContentAt(o,e)}))},insertAtSectionEnd:(t,n)=>{const e=m(n);ht((n=>{const o=S(n,t);n.commands.insertContentAt(o,e)}))},getActiveFormats:()=>vt?v(vt):u,actions:{toggleBold:()=>null==vt?void 0:vt.chain().focus().toggleBold().run(),toggleItalic:()=>null==vt?void 0:vt.chain().focus().toggleItalic().run(),toggleUnderline:()=>null==vt?void 0:vt.chain().focus().toggleUnderline().run(),toggleStrike:()=>null==vt?void 0:vt.chain().focus().toggleStrike().run(),toggleBulletList:()=>null==vt?void 0:vt.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>null==vt?void 0:vt.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>null==vt?void 0:vt.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>null==vt?void 0:vt.chain().focus().toggleCodeBlock().run(),setTextAlign:t=>null==vt?void 0:vt.chain().focus().setTextAlign(t).run(),setFontFamily:t=>null==vt?void 0:vt.chain().focus().setFontFamily(t).run(),setFontSize:t=>null==vt?void 0:vt.chain().focus().setFontSize(t).run(),setColor:t=>null==vt?void 0:vt.chain().focus().setColor(t).run(),setHighlight:t=>null==vt?void 0:vt.chain().focus().toggleHighlight({color:t}).run(),unsetColor:()=>null==vt?void 0:vt.chain().focus().unsetColor().run(),unsetHighlight:()=>null==vt?void 0:vt.chain().focus().unsetHighlight().run(),setLink:(t,n)=>{vt&&(void 0!==n?vt.chain().focus().extendMarkRange("link").command((e=>{let{tr:o,state:r}=e;const{from:i,to:l}=o.selection,s=r.schema.marks.link;if(!s)return!1;const c=r.schema.text(n,[s.create({href:t})]),a=r.schema.text(" ");return o.replaceWith(i,l,[c,a]),!0})).run():vt.chain().focus().extendMarkRange("link").setLink({href:t}).insertContent(" ").run())},updateLink:t=>null==vt?void 0:vt.chain().focus().extendMarkRange("link").setLink({href:t}).run(),removeLink:()=>null==vt?void 0:vt.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:t=>null==vt?void 0:vt.chain().focus().insertContent(t).run(),insertVariable:t=>null==vt?void 0:vt.chain().focus().insertContent(`{{${t}}}`).run(),insertHtml:t=>null==vt?void 0:vt.commands.insertContent(m(t)),undo:()=>null==vt?void 0:vt.chain().focus().undo().run(),redo:()=>null==vt?void 0:vt.chain().focus().redo().run(),canUndo:()=>{var t;return null!==(t=null==vt?void 0:vt.can().undo())&&void 0!==t&&t},canRedo:()=>{var t;return null!==(t=null==vt?void 0:vt.can().redo())&&void 0!==t&&t},toggleSuperscript:()=>null==vt?void 0:vt.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>null==vt?void 0:vt.chain().focus().toggleSubscript().run(),insertImage:t=>null==vt?void 0:vt.chain().focus().setImage({src:t}).run()}})),[vt]),vt?t(a,Object.assign({minHeight:_,maxHeight:K,paragraphGap:Q,style:X,className:Y},{children:[n(r,{editor:vt}),n(x,{editor:vt,renderLinkTooltip:null==P?void 0:P.renderTooltip})]})):null}));b.displayName="BikEditor";export{b as BikEditor};
|
|
2
2
|
//# sourceMappingURL=BikEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditor","forwardRef","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","next","extractActiveFormats","prev","bold","italic","underline","strike","bulletList","orderedList","blockquote","codeBlock","superscript","subscript","textAlign","fontFamily","fontSize","color","highlight","href","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","tightParagraphs","richPaste","children","_jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","displayName"],"mappings":"yxBAsCA,SAASA,EAAYC,GACpB,OAAOC,OAAOC,QAAQF,GACpBG,KACAC,IAAA,IAAEC,EAAGC,GAAEF,EAAA,MAAK,GAAGC,EAAEE,QAAQ,YAAaC,OAAUA,EAAEC,qBAAoBH,GAAG,IAEzEI,KAAK,IACR,CAEA,MAscaC,EAAYC,GAtcFC,CACtBC,EACAC,uBAEA,MAAMC,eACLA,EAAcC,SACdA,EAAQC,SACRA,EAAQC,SACRA,EAAQC,cACRA,EAAaC,UACbA,EAASC,aACTA,EAAYC,SACZA,EAAQC,cACRA,EAAaC,KACbA,EAAIC,QACJA,EAAOC,QACPA,EAAOC,SACPA,EAAQC,OACRA,EAAMC,QACNA,EAAOC,OACPA,EAAMC,kBACNA,EAAiBC,UACjBA,EAASC,UACTA,EAASlC,MACTA,EAAKmC,UACLA,EAASC,gBACTA,EAAeC,YACfA,IACGvB,EAEEwB,IAAuBrB,aAAQ,EAARA,EAAUsB,QACpCC,EACAC,EAAczB,QAAAA,EAAkB,IAChCC,EAASd,KAAKuC,GAAYzC,OAAA0C,OAAA1C,OAAA0C,OAAA,CAAA,EAAAD,IAAGE,QAASH,EAAcC,EAAEE,cAEtDH,EAAczB,QAAAA,EAAkB,IAO7B6B,GAAeC,EAAmC,IAClDC,GAAmBD,GAAO,GAI1BE,GAAaF,EAAOnB,GAC1BqB,GAAWC,QAAUtB,EACrB,MAAMuB,GAAcJ,EAAOlB,GAC3BsB,GAAYD,QAAUrB,EACtB,MAAMuB,GAAuBL,EAAOd,GACpCmB,GAAqBF,QAAUjB,EAC/B,MAAMoB,GAAiBN,EAAoBO,GACrCC,GAAaR,EAAOhB,GAC1BwB,GAAWL,QAAUnB,EACrB,MAAMyB,GAAYT,EAAOf,GACzBwB,GAAUN,QAAUlB,EACpB,MAAMyB,GAAYV,EAAOjB,GACzB2B,GAAUP,QAAUpB,EACpB,MAAM4B,GAAmBX,EAA2B,UAApBvB,aAAQ,EAARA,EAAUmC,cAAU,IAAAC,EAAAA,EAAA,IACpDF,GAAiBR,QAA0B,QAAhBW,EAAArC,aAAQ,EAARA,EAAUmC,cAAM,IAAAE,EAAAA,EAAI,GAC/C,MAAMC,GAAkBf,EAA0B,UAAnBvB,aAAQ,EAARA,EAAUuC,aAAS,IAAAC,EAAAA,EAAA,IAClDF,GAAgBZ,QAAyB,QAAfe,EAAAzC,aAAQ,EAARA,EAAUuC,aAAK,IAAAE,EAAAA,EAAI,GAC7C,MAAMC,GAAmBnB,EAA+B,UAAxBtB,aAAa,EAAbA,EAAe0C,aAAS,IAAAC,EAAAA,EAAA,IACxDF,GAAiBhB,QAA8B,QAApBmB,EAAA5C,aAAa,EAAbA,EAAe0C,aAAK,IAAAE,EAAAA,EAAI,GAEnD,MAAMC,GAASC,EAAU,CACxBC,WAAYC,EAAgB,CAC3BtD,WACAuD,YAAa3D,EAAM2D,YACnBrD,gBACAsD,aAA8B,QAAhBC,EAAA1D,aAAQ,EAARA,EAAUsB,cAAM,IAAAoC,EAAAA,EAAI,GAAK,EACvCpD,SAAU,CACTmC,OAAQnC,EAAWkC,QAAmBmB,EACtCd,MAAOvC,EAAWsC,QAAkBe,GAErCpD,cAAeA,EAAgByC,QAAmBW,EAClDlD,UACAG,OAAQA,EAAUgD,IAAa,IAAAlB,EAAA,OAAiB,UAAjBH,GAAUP,eAAO,IAAAU,OAAA,EAAAA,EAAAmB,KAAAtB,GAAGqB,EAAS,OAAGD,EAC/DtD,eACAD,YACA0D,kBAAmBxD,aAAA,EAAAA,EAAUyD,SAC7BC,uBAAwBzD,aAAA,EAAAA,EAAewD,SACvCE,kBAAmB3D,aAAA,EAAAA,EAAU4D,WAC7BC,sBAAuB7D,aAAA,EAAAA,EAAU8D,eACjCC,uBAAwB9D,aAAA,EAAAA,EAAe2D,WACvCI,2BAA4B/D,aAAA,EAAAA,EAAe6D,iBAE5CzC,QAASN,GACTkD,UAAWrE,EACXsE,mBAAmB,EACnBC,YAAa,CACZC,WACI1F,OAAA0C,OAAA1C,OAAA0C,OAAA,CAAA,EAACP,EAAkB,CAAEwD,MAAOxD,GAAoB,CAAA,GAC/CC,GAAc,CAAErC,MAAOD,EAAYsC,KAAiB,KAG1DwD,SAAUC,IAAkB,IAAfzB,OAAQ0B,GAAGD,QACJ,QAAnBnC,EAAAT,GAAYD,eAAO,IAAAU,GAAAA,EAAAmB,KAAA5B,GAAG8C,EAAeD,GAAG,EAEzCE,cAAeC,IAAkB,IAAf7B,OAAQ0B,GAAGG,YAC5B,MAAMC,EAAOC,EAAqBL,GAC5BM,EAAOjD,GAAeH,SAE3BoD,EAAKC,OAASH,EAAKG,MACnBD,EAAKE,SAAWJ,EAAKI,QACrBF,EAAKG,YAAcL,EAAKK,WACxBH,EAAKI,SAAWN,EAAKM,QACrBJ,EAAKK,aAAeP,EAAKO,YACzBL,EAAKM,cAAgBR,EAAKQ,aAC1BN,EAAKO,aAAeT,EAAKS,YACzBP,EAAKQ,YAAcV,EAAKU,WACxBR,EAAKS,cAAgBX,EAAKW,aAC1BT,EAAKU,YAAcZ,EAAKY,WACxBV,EAAKW,YAAcb,EAAKa,WACxBX,EAAKY,aAAed,EAAKc,YACzBZ,EAAKa,WAAaf,EAAKe,UACvBb,EAAKc,QAAUhB,EAAKgB,OACpBd,EAAKe,YAAcjB,EAAKiB,oBACxBzD,EAAA0C,EAAK5E,2BAAM4F,SAAoB,QAAXzD,EAAAuC,EAAK1E,YAAM,IAAAmC,OAAA,EAAAA,EAAAyD,SAE/BjE,GAAeH,QAAUkD,EACM,QAA/BpC,EAAAZ,GAAqBF,eAAU,IAAAc,GAAAA,EAAAe,KAAA3B,GAAAgD,GAC/B,EAEFrE,QAASA,KAAM,IAAA6B,EAAA,OAAsB,QAAtBA,EAAAL,GAAWL,eAAW,IAAAU,OAAA,EAAAA,EAAAmB,KAAAxB,GAAA,EACrCvB,OAAQA,KAAM,IAAA4B,EAAA,OAAqB,QAArBA,EAAAJ,GAAUN,eAAW,IAAAU,OAAA,EAAAA,EAAAmB,KAAAvB,GAAA,IAOpC,SAAS+D,GAAQC,GACZlD,GACHkD,EAAGlD,IAEHxB,GAAaI,QAAQuE,KAAKD,EAE5B,CA0SA,OAvSAE,GAAU,WACT,GAAKpD,GAAL,CACA,GAAIxB,GAAaI,QAAQV,OAAS,EAAG,CACtBM,GAAaI,QAAQyE,OAAO,GACpCC,SAASJ,GAAOA,EAAGlD,KACzB,CACItB,GAAiBE,UACrBF,GAAiBE,SAAU,EACT,QAAlBU,EAAAX,GAAWC,eAAO,IAAAU,GAAAA,EAAAmB,KAAA9B,IAPN,CAQZ,GACC,CAACqB,KAEJuD,EACC7G,GACA,KAAO,CAEN8G,MAAQC,GAAaR,IAASvB,GAAMA,EAAEgC,SAASF,MAAMC,KACrDE,KAAMA,IAAMV,IAASvB,GAAMA,EAAEgC,SAASC,SAGtCC,aAAcA,IAAMX,IAASvB,GAAMA,EAAEgC,SAASE,cAAa,KAC3DC,WAAaC,IACZ,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAMA,EAAEgC,SAASG,WAAWE,EAAY,CAAEC,YAAY,KAAQ,EAExEC,cAAgBH,IACf,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAMA,EAAEgC,SAASO,cAAcF,IAAY,EAErDG,oBAAsBJ,IACrBb,IAASvB,GAAMyC,EAAiBzC,EAAGoC,IAAM,EAE1CM,cAAgBN,IACf,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAMA,EAAEgC,SAASW,gBAAgB,EAAGN,IAAY,EAE1DO,YAAcR,IACb,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GACRA,EAAEgC,SAASW,gBAAgB3C,EAAE6C,MAAMC,IAAIjG,QAAQkG,KAAMV,IACrD,EAEFW,aAAeZ,IACd,MAAMC,EAAa3F,EAAc0F,GAIjCb,IAASvB,GACRA,EAAEgC,SAASW,gBAAgB3C,EAAE6C,MAAMC,IAAIjG,QAAQkG,KAAO,EAAGV,IACzD,EAGFY,YAAYb,GACXc,KAAKN,YAAYR,EACjB,EACDe,cAAcf,GACbc,KAAKF,aAAaZ,EAClB,EACDgB,WAAYA,IACX9E,GACG2B,EAAe3B,IACf,CAAE8D,KAAM,GAAIiB,KAAM,GAAIC,SAAS,EAAMC,eAAgB,GACzDC,QAASA,KAAM,IAAA5F,EAAA,OAAqB,UAArBU,cAAM,EAANA,GAAQkF,iBAAa,IAAA5F,EAAAA,EAAA,IAAI,EACxC6F,YAAaA,KACZ,MAAMC,EAAW,IAAIC,IACfC,EAAU,IAAID,IACpB,OAAKrF,IACLA,GAAOuE,MAAMC,IAAIe,aAAaC,IACN,iBAAnBA,EAAKC,KAAKC,MAA+C,MAApBF,EAAKG,MAAU,GACvDP,EAASQ,IAAIC,OAAOL,EAAKG,MAAU,KAEhB,gBAAnBH,EAAKC,KAAKC,MACU,MAApBF,EAAKG,MAAU,IAEfL,EAAQM,IAAIC,OAAOL,EAAKG,MAAU,IAClC,IAEK,CAAEP,SAAUU,MAAMC,KAAKX,GAAWE,QAASQ,MAAMC,KAAKT,KAXzC,CAAEF,SAAU,GAAIE,QAAS,GAW0B,EAIxEU,kBAAmBA,KAClB,IAAKhG,GAAQ,MAAO,CAAE+F,KAAM,EAAGE,GAAI,GACnC,MAAMF,KAAEA,EAAIE,GAAEA,GAAOjG,GAAOuE,MAAM2B,UAClC,MAAO,CAAEH,OAAME,KAAI,EAEpBE,iBAAkBA,CAACC,EAAKtC,KACvB,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAMA,EAAEgC,SAASW,gBAAgB+B,EAAKrC,IAAY,EAE5DsC,gBAAiBA,KAChB,IAAKrG,GAAQ,MAAO,GACpB,MAAMuE,MAAEA,GAAUvE,IACZ+F,KAAEA,EAAIE,GAAEA,EAAEK,MAAEA,GAAU/B,EAAM2B,UAClC,IAAKI,EACJ,OAAO/B,EAAMC,IAAI+B,YAAYR,EAAME,EAAI,KAIxC,MAAMO,EAAejC,EAAMkC,OAAOC,MAAY,KAC9C,GAAIF,EAAc,CACjB,MAAMG,EAAQC,EAAarC,EAAMC,IAAIqC,QAAQd,GAAOS,GACpD,GAAIG,EACH,OAAOpC,EAAMC,IAAI+B,YAAYI,EAAMZ,KAAMY,EAAMV,GAAI,IAEpD,CACD,MAAO,EAAE,EAIVa,kBAAmBA,iBAAM,MAAC,CACzBC,MAEyB,QADxBpH,EAA8C,QAA9CD,EAA8C,QAA9CH,EAAgC,QAAhCD,EAAAU,cAAA,EAAAA,GAAQgH,QAAQ/B,sBAAgB,IAAA3F,OAAA,EAAAA,EAAA2H,kBAAc,IAAA1H,OAAA,EAAAA,EAAAkB,KAAAnB,UAAA,IAAAI,EAAAA,EAC9CM,cAAM,EAANA,GAAQkH,UAAUhJ,cAAM,IAAAyB,EAAAA,EACxB,EACDwH,MAAOpK,QAAAA,EAAiB,KACxB,EAGDqK,kBAAoBC,GACnBrH,GACGsH,EAAsBtH,GAAQqH,GAC9B,CAAEvD,KAAM,GAAIiB,KAAM,GAAIC,SAAS,EAAMC,eAAgB,GAEzDsC,kBAAmBA,CAACF,EAAWvD,KAC9B,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAM8F,EAA0B9F,EAAG2F,EAAWtD,IAAY,EAGpE0D,aAAeJ,IACdpE,IAASvB,IACR,GAAkB,SAAd2F,EAAsB,CACzB,IAAIK,EAAYhG,EAAE6C,MAAMC,IAAIjG,QAAQkG,KAAO,EAY3C,OAXA/C,EAAE6C,MAAMC,IAAIe,aAAY,CAACC,EAAMY,KAEV,mBAAnBZ,EAAKC,KAAKC,MACVgC,IAAchG,EAAE6C,MAAMC,IAAIjG,QAAQkG,KAAO,IAEzCiD,EAAYtB,EAAM,GAEZsB,IAAchG,EAAE6C,MAAMC,IAAIjG,QAAQkG,KAAO,KAE7CiD,EAAY,IAAGA,EAAY,QAC/BhG,EAAEiG,QAAQnE,QAAQoE,iBAAiBF,GAAWG,KAE9C,CACD,IAAIC,GAAa,EACjBpG,EAAE6C,MAAMC,IAAIe,aAAY,CAACC,EAAMY,KAC9B,IAAmB,IAAf0B,EAAkB,OAAO,EAET,mBAAnBtC,EAAKC,KAAKC,MACVF,EAAKG,MAAiB,YAAM0B,IAI5BS,EAAY1B,EAAMZ,EAAKuC,SAAW,EAClC,KAEiB,IAAfD,GACHpG,EAAEiG,QAAQnE,QAAQoE,iBAAiBE,GAAWD,KAC9C,GACA,EAGHG,aAAeX,IACdpE,IAASvB,GAAM8F,EAA0B9F,EAAG2F,EAAW,YAAW,EAInEY,eAAgBA,IACfjI,GACGkI,EAAmBlI,IACnB,CAAE8D,KAAM,GAAIiB,KAAM,GAAIC,SAAS,EAAMC,eAAgB,GACzDkD,eAAiBrE,IAChB,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,GAAM8F,EAA0B9F,EAAG,OAAQqC,IAAY,EAEjEqE,mBAAoBA,CAACC,EAAMzL,KAC1B,MAAMkH,EAAO3F,EACZC,EAAciK,GACdzL,EAASd,KAAKuC,IAAO,CACpBiK,GAAIjK,EAAEiK,GACN/J,QAASH,EAAcC,EAAEE,cAG3B0E,IAASvB,GAAMA,EAAEgC,SAASG,WAAWC,EAAM,CAAEE,YAAY,KAAQ,EAElEuE,kBAAoBzE,IACnB,MAAMC,EAAa3F,EAAc0F,GAKjCb,IAASvB,IACR,MAAM8G,EAAcC,EAAkB/G,EAAG,QACzCA,EAAEgC,SAASW,gBAAgBmE,EAAc,EAAGzE,EAAW,GACtD,EAEH2E,qBAAsBA,CAACrB,EAAWvD,KACjC,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,IACR,MAAM0E,EAAMuC,EAAoBjH,EAAG2F,IACtB,IAATjB,GAAY1E,EAAEgC,SAASW,gBAAgB+B,EAAKrC,EAAW,GAC1D,EAEH6E,mBAAoBA,CAACvB,EAAWvD,KAC/B,MAAMC,EAAa3F,EAAc0F,GACjCb,IAASvB,IACR,MAAM0E,EAAMqC,EAAkB/G,EAAG2F,GACjC3F,EAAEgC,SAASW,gBAAgB+B,EAAKrC,EAAW,GAC1C,EAGH8E,iBAAkBA,IACjB7I,GAAS+B,EAAqB/B,IAAUhB,EACzC8J,QAAS,CACRC,WAAYA,IAAM/I,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQuF,aAAalB,MACvDmB,aAAcA,IAAMhJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQwF,eAAenB,MAC3DoB,gBAAiBA,IAAMjJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQyF,kBAAkBpB,MACjEqB,aAAcA,IAAMlJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ0F,eAAerB,MAC3DsB,iBAAkBA,IACjBnJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ2F,mBAAmBtB,MAC5CuB,kBAAmBA,IAClBpJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ4F,oBAAoBvB,MAC7CwB,iBAAkBA,IACjBrJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ6F,mBAAmBxB,MAC5CyB,gBAAiBA,IAAMtJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ8F,kBAAkBzB,MACjE0B,aAAeC,GACdxJ,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ+F,aAAaC,GAAO3B,MAC7C4B,cAAgBC,GACf1J,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQiG,cAAcC,GAAM7B,MAC7C8B,YAAclF,GAASzE,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQmG,YAAYlF,GAAMoD,MACjE+B,SAAW9G,GAAU9C,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQoG,SAAS9G,GAAO+E,MAC7DgC,aAAe/G,GACd9C,cAAA,EAAAA,GAAQ2H,QAAQnE,QAAQsG,gBAAgB,CAAEhH,UAAS+E,MACpDkC,WAAYA,IAAM/J,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQuG,aAAalC,MACvDmC,eAAgBA,IAAMhK,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQwG,iBAAiBnC,MAC/DoC,QAASA,CAACjH,EAAM+B,KACV/E,UACQO,IAATwE,EACH/E,GACE2H,QACAnE,QACA0G,gBAAgB,QAChBC,SAAQC,IAAkB,IAAjBC,GAAEA,EAAE9F,MAAEA,GAAO6F,EACtB,MAAMrE,KAAEA,EAAIE,GAAEA,GAAOoE,EAAGnE,UAClBM,EAAejC,EAAMkC,OAAOC,MAAY,KAC9C,IAAKF,EAAc,OAAO,EAC1B,MAAM8D,EAAW/F,EAAMkC,OAAO1B,KAAKA,EAAM,CACxCyB,EAAa+D,OAAO,CAAEvH,WAEjBwH,EAAQjG,EAAMkC,OAAO1B,KAAK,KAEhC,OADAsF,EAAGI,YAAY1E,EAAME,EAAI,CAACqE,EAAUE,KAC7B,CAAI,IAEX3C,MAEF7H,GACE2H,QACAnE,QACA0G,gBAAgB,QAChBD,QAAQ,CAAEjH,SACViB,cAAc,KACd4D,MACF,EAEF6C,WAAa1H,GACZhD,cAAA,EAAAA,GACG2H,QACDnE,QACA0G,gBAAgB,QAChBD,QAAQ,CAAEjH,SACV6E,MACH8C,WAAYA,IACX3K,gBAAAA,GAAQ2H,QAAQnE,QAAQ0G,gBAAgB,QAAQU,YAAY/C,MAC7DgD,YAAcC,GACb9K,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQS,cAAc6G,GAAOjD,MAC9CkD,eAAiBC,GAChBhL,cAAA,EAAAA,GAAQ2H,QAAQnE,QAAQS,mBAAmB+G,OAAkBnD,MAC9DoD,WAAanH,GACZ9D,cAAM,EAANA,GAAQ0D,SAASO,cAAc7F,EAAc0F,IAC9CoH,KAAMA,IAAMlL,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ0H,OAAOrD,MAC3CsD,KAAMA,IAAMnL,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ2H,OAAOtD,MAC3CuD,QAASA,WAAM,OAAwB,QAAxB9L,EAAAU,gBAAAA,GAAQqL,MAAMH,cAAU,IAAA5L,GAAAA,CAAK,EAC5CgM,QAASA,WAAM,OAAwB,QAAxBhM,EAAAU,gBAAAA,GAAQqL,MAAMF,cAAU,IAAA7L,GAAAA,CAAK,EAC5CiM,kBAAmBA,IAClBvL,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQ+H,oBAAoB1D,MAC7C2D,gBAAiBA,IAAMxL,cAAM,EAANA,GAAQ2H,QAAQnE,QAAQgI,kBAAkB3D,MACjE4D,YAAcC,GAAQ1L,cAAA,EAAAA,GAAQ2H,QAAQnE,QAAQmI,SAAS,CAAED,QAAO7D,UAIlE,CAAC7H,KAGGA,GAGJ4L,EAACC,EAAcjQ,OAAA0C,OAAA,CACdV,UAAWA,EACXC,UAAWA,EACXiO,kBAAkBjP,aAAQ,EAARA,EAAUkP,WAC5BpQ,MAAOA,EACPmC,UAAWA,GAEX,CAAAkO,SAAA,CAAAC,EAACC,EAAa,CAAClM,OAAQA,KACvBiM,EAACE,EAAc,CAACnM,OAAQA,GAAQoM,kBAAmBhP,aAAI,EAAJA,EAAMiP,oBAXvC,IAYF,IAOnB/P,EAAUgQ,YAAc"}
|
|
1
|
+
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tparagraphGap,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tonSelectionChangeRef.current?.(extractActiveFormats(e));\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\tparagraphGap={paragraphGap}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditor","forwardRef","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","paragraphGap","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","extractActiveFormats","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","DEFAULT_FORMAT_STATE","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","color","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","href","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","children","_jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","displayName"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";const
|
|
1
|
+
import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";const o=e.div`
|
|
2
2
|
position: relative;
|
|
3
3
|
width: 100%;
|
|
4
4
|
|
|
@@ -12,30 +12,20 @@ import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";
|
|
|
12
12
|
line-height: 1.5;
|
|
13
13
|
word-break: break-word;
|
|
14
14
|
|
|
15
|
-
/* Paragraph spacing.
|
|
16
|
-
Email/signature (rich): paragraphs carry the browser-default 1em block
|
|
17
|
-
margin — the SAME spacing the sent HTML gets (we emit plain <p>, which
|
|
18
|
-
renders against the default <p> margin in Gmail and our email viewer),
|
|
19
|
-
so editor view == emitted HTML == Gmail. A single Enter = a new
|
|
20
|
-
paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.
|
|
21
|
-
Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with
|
|
22
|
-
no paragraph-gap concept — paragraphs are tight (margin:0) regardless of
|
|
23
|
-
typed vs pasted. (A margin:0 attr still overrides to tight either way.) */
|
|
24
15
|
p {
|
|
25
|
-
margin:
|
|
16
|
+
margin: 0;
|
|
26
17
|
padding: 0;
|
|
27
18
|
}
|
|
28
19
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
display: none;
|
|
20
|
+
p + p {
|
|
21
|
+
margin-top: ${e=>{let{paragraphGap:t}=e;return null!=t?t:"4px"}};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
p.is-blank {
|
|
25
|
+
margin-top: 0;
|
|
26
|
+
}
|
|
27
|
+
p.is-blank + p {
|
|
28
|
+
margin-top: 0;
|
|
39
29
|
}
|
|
40
30
|
|
|
41
31
|
ul,
|
|
@@ -79,5 +69,5 @@ import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";
|
|
|
79
69
|
text-decoration-color: #6366f1;
|
|
80
70
|
}
|
|
81
71
|
}
|
|
82
|
-
`;export{
|
|
72
|
+
`;export{o as BikEditorShell};
|
|
83
73
|
//# sourceMappingURL=BikEditor.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\
|
|
1
|
+
{"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\tparagraphGap?: string;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\tp {\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tp + p {\n\t\t\tmargin-top: ${({ paragraphGap }) => paragraphGap ?? '4px'};\n\t\t}\n\n\t\tp.is-blank {\n\t\t\tmargin-top: 0;\n\t\t}\n\t\tp.is-blank + p {\n\t\t\tmargin-top: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","styled","div","_ref","minHeight","_ref2","maxHeight","_ref3","paragraphGap","COLORS","content","brand"],"mappings":"gFAGaA,MAAAA,EAAiBC,EAAOC,GAInC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;iBAcrCC,IAAA,IAACC,aAAEA,GAAcD,EAAA,OAAKC,QAAAA,EAAgB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BjDC,EAAOC,QAAQC;;;;WAIfF,EAAOC,QAAQC;;;;;;;;;;;;;;;;;"}
|