@procore/text-editor 0.5.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.jest/ckeditorMock.js +47 -23
  2. package/CHANGELOG.md +30 -0
  3. package/README.md +96 -7
  4. package/dist/TextEditor/CKTextEditor.d.ts +3 -0
  5. package/dist/TextEditor/CKTextEditor.js +312 -0
  6. package/dist/TextEditor/CKTextEditor.js.map +1 -0
  7. package/dist/TextEditor/Providers/FeatureFlagProvider.d.ts +5 -0
  8. package/dist/TextEditor/Providers/FeatureFlagProvider.js +34 -0
  9. package/dist/TextEditor/Providers/FeatureFlagProvider.js.map +1 -0
  10. package/dist/TextEditor/TextEditor.d.ts +1 -1
  11. package/dist/TextEditor/TextEditor.js +16 -232
  12. package/dist/TextEditor/TextEditor.js.map +1 -1
  13. package/dist/TextEditor/TextEditor.styles.d.ts +14 -1
  14. package/dist/TextEditor/TextEditor.styles.js +18 -5
  15. package/dist/TextEditor/TextEditor.styles.js.map +1 -1
  16. package/dist/TextEditor/TextEditor.types.d.ts +82 -1
  17. package/dist/TextEditor/TextEditor.types.js.map +1 -1
  18. package/dist/TextEditor/TextEditorI18nProvider.d.ts +2 -0
  19. package/dist/TextEditor/TextEditorI18nProvider.js +27 -0
  20. package/dist/TextEditor/TextEditorI18nProvider.js.map +1 -0
  21. package/dist/TextEditor/TinyMCETextEditor.d.ts +3 -0
  22. package/dist/TextEditor/TinyMCETextEditor.js +63 -0
  23. package/dist/TextEditor/TinyMCETextEditor.js.map +1 -0
  24. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/NormalizeTableWidthPlugin.d.ts +15 -0
  25. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/NormalizeTableWidthPlugin.js +72 -0
  26. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/NormalizeTableWidthPlugin.js.map +1 -0
  27. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/index.d.ts +1 -0
  28. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/index.js +2 -0
  29. package/dist/TextEditor/plugins/NormalizeTableWidthPlugin/index.js.map +1 -0
  30. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/ProcoreImageUploadPlugin.d.ts +48 -0
  31. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/ProcoreImageUploadPlugin.js +441 -0
  32. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/ProcoreImageUploadPlugin.js.map +1 -0
  33. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/index.d.ts +1 -0
  34. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/index.js +2 -0
  35. package/dist/TextEditor/plugins/ProcoreImageUploadPlugin/index.js.map +1 -0
  36. package/dist/TextEditor/utils/config.d.ts +6 -1
  37. package/dist/TextEditor/utils/config.js +25 -10
  38. package/dist/TextEditor/utils/config.js.map +1 -1
  39. package/dist/TextEditor/utils/imageAttributes.d.ts +6 -0
  40. package/dist/TextEditor/utils/imageAttributes.js +17 -0
  41. package/dist/TextEditor/utils/imageAttributes.js.map +1 -0
  42. package/dist/TextEditor/utils/imageUrls.d.ts +2 -0
  43. package/dist/TextEditor/utils/imageUrls.js +36 -0
  44. package/dist/TextEditor/utils/imageUrls.js.map +1 -0
  45. package/dist/TextEditor/utils/richTextEditorHandlers.d.ts +9 -0
  46. package/dist/TextEditor/utils/richTextEditorHandlers.js +234 -0
  47. package/dist/TextEditor/utils/richTextEditorHandlers.js.map +1 -0
  48. package/dist/TextEditorOutput/TextEditorOutput.styles.js +2 -2
  49. package/dist/TextEditorOutput/TextEditorOutput.styles.js.map +1 -1
  50. package/dist/TextEditorOutput/TextEditorOutput.utils.d.ts +1 -1
  51. package/dist/TextEditorOutput/TextEditorOutput.utils.js +150 -6
  52. package/dist/TextEditorOutput/TextEditorOutput.utils.js.map +1 -1
  53. package/dist/_typedoc/TextEditor/TextEditor.types.json +215 -17
  54. package/dist/_typedoc/TextEditor/TextEditorProvider.types.json +2 -2
  55. package/dist/_typedoc/TextEditorOutput/TextEditorOutput.types.json +3 -3
  56. package/dist/ckeditor5-premium-features.d.js +2 -0
  57. package/dist/ckeditor5-premium-features.d.js.map +1 -0
  58. package/dist/locales/en.json +17 -0
  59. package/dist/locales/pseudo.json +17 -0
  60. package/dist/utils/debounce.js +4 -4
  61. package/dist/utils/debounce.js.map +1 -1
  62. package/package.json +8 -3
@@ -0,0 +1,34 @@
1
+ import { getProcoreZone, getProviderParams } from '@procore/web-sdk-env-utils';
2
+ import { FeatureToggleProvider } from '@procore/web-sdk-feature-toggle';
3
+ import React, { useId, useMemo, useRef } from 'react';
4
+ var LAUNCH_DARKLY_KEYS = {
5
+ development: '570f37b4eee8b907140070c5',
6
+ staging: '570f2f6e348a2806d7006b6f',
7
+ production: '570e9423348a2806d7004354'
8
+ };
9
+ var getEnvironment = function getEnvironment() {
10
+ var _getProcoreZone;
11
+ return (_getProcoreZone = getProcoreZone(globalThis.location.hostname)) === null || _getProcoreZone === void 0 ? void 0 : _getProcoreZone.environment;
12
+ };
13
+ export function FeatureFlagProvider(_ref) {
14
+ var children = _ref.children;
15
+ var _getProviderParams = getProviderParams(),
16
+ companyId = _getProviderParams.companyId,
17
+ projectId = _getProviderParams.projectId;
18
+ var environment = getEnvironment();
19
+ var idRef = useRef(useId());
20
+ var context = useMemo(function () {
21
+ return {
22
+ user: {
23
+ email: idRef.current,
24
+ projectId: projectId,
25
+ companyId: companyId
26
+ }
27
+ };
28
+ }, [projectId, companyId]);
29
+ return /*#__PURE__*/React.createElement(FeatureToggleProvider, {
30
+ apiKey: LAUNCH_DARKLY_KEYS[environment],
31
+ context: context
32
+ }, children);
33
+ }
34
+ //# sourceMappingURL=FeatureFlagProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagProvider.js","names":["getProcoreZone","getProviderParams","FeatureToggleProvider","React","useId","useMemo","useRef","LAUNCH_DARKLY_KEYS","development","staging","production","getEnvironment","_getProcoreZone","globalThis","location","hostname","environment","FeatureFlagProvider","_ref","children","_getProviderParams","companyId","projectId","idRef","context","user","email","current","createElement","apiKey"],"sources":["../../../src/TextEditor/Providers/FeatureFlagProvider.tsx"],"sourcesContent":["import { getProcoreZone, getProviderParams } from '@procore/web-sdk-env-utils'\nimport { FeatureToggleProvider } from '@procore/web-sdk-feature-toggle'\nimport type { ReactElement } from 'react'\nimport React, { useId, useMemo, useRef } from 'react'\n\nconst LAUNCH_DARKLY_KEYS: Record<string, string> = {\n development: '570f37b4eee8b907140070c5',\n staging: '570f2f6e348a2806d7006b6f',\n production: '570e9423348a2806d7004354',\n}\n\nconst getEnvironment = () =>\n getProcoreZone(globalThis.location.hostname)?.environment\n\nexport function FeatureFlagProvider({\n children,\n}: Readonly<{ children: ReactElement }>) {\n const { companyId, projectId } = getProviderParams()\n const environment = getEnvironment()\n const idRef = useRef(useId())\n\n const context = useMemo(\n () => ({ user: { email: idRef.current, projectId, companyId } }),\n [projectId, companyId]\n )\n\n return (\n <FeatureToggleProvider\n apiKey={LAUNCH_DARKLY_KEYS[environment]}\n context={context}\n >\n {children}\n </FeatureToggleProvider>\n )\n}\n"],"mappings":"AAAA,SAASA,cAAc,EAAEC,iBAAiB,QAAQ,4BAA4B;AAC9E,SAASC,qBAAqB,QAAQ,iCAAiC;AAEvE,OAAOC,KAAK,IAAIC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,OAAO;AAErD,IAAMC,kBAA0C,GAAG;EACjDC,WAAW,EAAE,0BAA0B;EACvCC,OAAO,EAAE,0BAA0B;EACnCC,UAAU,EAAE;AACd,CAAC;AAED,IAAMC,cAAc,GAAG,SAAjBA,cAAcA,CAAA;EAAA,IAAAC,eAAA;EAAA,QAAAA,eAAA,GAClBZ,cAAc,CAACa,UAAU,CAACC,QAAQ,CAACC,QAAQ,CAAC,cAAAH,eAAA,uBAA5CA,eAAA,CAA8CI,WAAW;AAAA;AAE3D,OAAO,SAASC,mBAAmBA,CAAAC,IAAA,EAEM;EAAA,IADvCC,QAAQ,GAAAD,IAAA,CAARC,QAAQ;EAER,IAAAC,kBAAA,GAAiCnB,iBAAiB,CAAC,CAAC;IAA5CoB,SAAS,GAAAD,kBAAA,CAATC,SAAS;IAAEC,SAAS,GAAAF,kBAAA,CAATE,SAAS;EAC5B,IAAMN,WAAW,GAAGL,cAAc,CAAC,CAAC;EACpC,IAAMY,KAAK,GAAGjB,MAAM,CAACF,KAAK,CAAC,CAAC,CAAC;EAE7B,IAAMoB,OAAO,GAAGnB,OAAO,CACrB;IAAA,OAAO;MAAEoB,IAAI,EAAE;QAAEC,KAAK,EAAEH,KAAK,CAACI,OAAO;QAAEL,SAAS,EAATA,SAAS;QAAED,SAAS,EAATA;MAAU;IAAE,CAAC;EAAA,CAAC,EAChE,CAACC,SAAS,EAAED,SAAS,CACvB,CAAC;EAED,oBACElB,KAAA,CAAAyB,aAAA,CAAC1B,qBAAqB;IACpB2B,MAAM,EAAEtB,kBAAkB,CAACS,WAAW,CAAE;IACxCQ,OAAO,EAAEA;EAAQ,GAEhBL,QACoB,CAAC;AAE5B"}
@@ -41,4 +41,4 @@ import type { TextEditorProps } from './TextEditor.types';
41
41
  * }),
42
42
  * })
43
43
  */
44
- export declare function TextEditor(props: Readonly<TextEditorProps>): React.JSX.Element | null;
44
+ export declare function TextEditor(props: Readonly<TextEditorProps>): React.JSX.Element;
@@ -1,28 +1,14 @@
1
- var _excluded = ["disabled", "error", "readonly", "value", "initialValue", "onChange", "onInit", "onBlur", "onKeyDown", "locale", "onDirty"];
2
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
4
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
1
+ var _excluded = ["enforceCKEditor"];
9
2
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
10
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
- import { CKEditor } from '@ckeditor/ckeditor5-react';
12
- import { ClassicEditor } from 'ckeditor5';
4
+ import { ToastAlertProvider } from '@procore/toast-alert';
5
+ import { useFeatureFlag } from '@procore/web-sdk-feature-toggle';
13
6
  import React from 'react';
14
- import { useI18nContext, useZIndexContext } from '@procore/core-react';
15
- import { TextEditorOutput } from '../TextEditorOutput';
16
- import { debounce } from '../utils/debounce';
17
- import { useStickyToolbar } from './StickyToolbar';
18
- import { GlobalEditorStyles, StyledTextEditor } from './TextEditor.styles';
19
- import { TextEditorContext } from './TextEditorProvider';
20
- import { TextEditorTheme } from './textEditorTheming';
21
- import { useCKEditorCss } from './useCKEditorCss';
22
- import { useCKEditorFocusScope } from './useCKEditorFocusScope';
23
- import { useTabAsNavigation } from './useTabAsNavigation';
24
- import { addButtonDataAttributes, getDefaultConfig } from './utils';
25
- var DEBOUNCE_MS = 300;
7
+ import { CKTextEditor } from './CKTextEditor';
8
+ import { FeatureFlagProvider } from './Providers/FeatureFlagProvider';
9
+ import { TextEditorI18nProvider } from './TextEditorI18nProvider';
10
+ import { TinyMCETextEditor } from './TinyMCETextEditor';
11
+ var FLAG_NAME = 'pmqs-ck-editor-enabled';
26
12
 
27
13
  /**
28
14
  * To ensure your Jest tests work with the CKEditor implementation, wrap your Jest configuration with `textEditorJestConfig`:
@@ -66,215 +52,13 @@ var DEBOUNCE_MS = 300;
66
52
  * })
67
53
  */
68
54
  export function TextEditor(props) {
69
- var disabled = props.disabled,
70
- error = props.error,
71
- readonly = props.readonly,
72
- value = props.value,
73
- initialValue = props.initialValue,
74
- onChange = props.onChange,
75
- onInit = props.onInit,
76
- onBlur = props.onBlur,
77
- onKeyDown = props.onKeyDown,
78
- propLocale = props.locale,
79
- onDirty = props.onDirty,
80
- restProps = _objectWithoutProperties(props, _excluded);
81
- var ariaLabel = props['aria-label'];
82
- var ariaDescription = props['aria-description'];
83
- var _useCKEditorCss = useCKEditorCss(),
84
- cssLoading = _useCKEditorCss.isLoading;
85
- useCKEditorFocusScope();
86
- var editorRef = React.useRef(null);
87
- var editorInstanceRef = React.useRef(null);
88
- var initialValueRef = React.useRef(value || initialValue || '');
89
- var lastExternalValueRef = React.useRef(value || initialValue || '');
90
- var keyDownListenerRef = React.useRef(null);
91
- var _React$useState = React.useState(false),
92
- _React$useState2 = _slicedToArray(_React$useState, 2),
93
- isDirtyState = _React$useState2[0],
94
- setIsDirtyState = _React$useState2[1];
95
- var _React$useState3 = React.useState(false),
96
- _React$useState4 = _slicedToArray(_React$useState3, 2),
97
- isEditorReady = _React$useState4[0],
98
- setIsEditorReady = _React$useState4[1];
99
- var _useI18nContext = useI18nContext(),
100
- contextLocale = _useI18nContext.locale;
101
- var locale = propLocale || contextLocale;
102
- React.useEffect(function () {
103
- if (value !== undefined) {
104
- lastExternalValueRef.current = value;
105
- }
106
- }, [value]);
107
- React.useEffect(function () {
108
- var editor = editorInstanceRef.current;
109
- if (!isEditorReady || !editor || value === undefined) return;
110
- if (editor.editing.view.document.isFocused) return;
111
- if (value === editor.getData()) return;
112
- editor.data.set(value);
113
- }, [value, isEditorReady]);
114
-
115
- // Cleanup keydown listener on unmount
116
- React.useEffect(function () {
117
- return function () {
118
- if (keyDownListenerRef.current && editorInstanceRef.current) {
119
- editorInstanceRef.current.editing.view.document.off('keydown', keyDownListenerRef.current);
120
- keyDownListenerRef.current = null;
121
- }
122
- };
123
- }, []);
124
-
125
- // Update aria-label when ariaLabel prop changes
126
- React.useEffect(function () {
127
- if (!isEditorReady || !editorInstanceRef.current) {
128
- return;
129
- }
130
- var editor = editorInstanceRef.current;
131
- editor.editing.view.change(function (writer) {
132
- var viewEditableRoot = editor.editing.view.document.getRoot();
133
- if (viewEditableRoot) {
134
- if (ariaLabel) {
135
- writer.setAttribute('aria-label', ariaLabel, viewEditableRoot);
136
- } else {
137
- writer.removeAttribute('aria-label', viewEditableRoot);
138
- }
139
- }
140
- });
141
- }, [ariaLabel, isEditorReady]);
142
-
143
- // Update aria-description when ariaDescription prop changes
144
- React.useEffect(function () {
145
- if (!isEditorReady || !editorInstanceRef.current) {
146
- return;
147
- }
148
- var editor = editorInstanceRef.current;
149
- editor.editing.view.change(function (writer) {
150
- var viewEditableRoot = editor.editing.view.document.getRoot();
151
- if (viewEditableRoot) {
152
- if (ariaDescription) {
153
- writer.setAttribute('aria-description', ariaDescription, viewEditableRoot);
154
- } else {
155
- writer.removeAttribute('aria-description', viewEditableRoot);
156
- }
157
- }
158
- });
159
- }, [ariaDescription, isEditorReady]);
160
- var _useZIndexContext = useZIndexContext(),
161
- zIndex = _useZIndexContext.value;
162
- var _React$useContext = React.useContext(TextEditorContext),
163
- features = _React$useContext.features;
164
- var enableStickyToolbar = !!(features !== null && features !== void 0 && features.stickyToolbar);
165
- var enableTabAsNavigation = !!(features !== null && features !== void 0 && features.tabAsNavigation);
166
- var mergedConfig = React.useMemo(function () {
167
- var defaultConfig = getDefaultConfig(locale);
168
-
169
- // Set accessible label for the editable area if provided
170
- // This is used by screen readers to announce the editor's purpose
171
- if (ariaLabel) {
172
- defaultConfig.label = ariaLabel;
173
- }
174
- return defaultConfig;
175
- }, [ariaLabel, locale]);
176
- var bindKeyDownHandler = React.useCallback(function (editor) {
177
- var editorElement = editor.editing.view.document.getRoot();
178
- if (!editorElement) {
179
- return;
180
- }
181
-
182
- // Remove existing keydown listener
183
- if (keyDownListenerRef.current) {
184
- editor.editing.view.document.off('keydown', keyDownListenerRef.current);
185
- }
186
-
187
- // Create and store the new listener
188
- var keyDownListener = function keyDownListener(_event, data) {
189
- var domEvent = data.domEvent;
190
- // Prevent Enter from propagating to parent forms so the
191
- // editor can handle newlines without accidentally submitting.
192
- if (domEvent.key === 'Enter') {
193
- domEvent.stopPropagation();
194
- }
195
- onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(domEvent, editor);
196
- };
197
- keyDownListenerRef.current = keyDownListener;
198
-
199
- // Add the keydown listener
200
- editor.editing.view.document.on('keydown', keyDownListener);
201
- }, [onKeyDown]);
202
- var debouncedChange = debounce(function (_event, editor) {
203
- var data = editor.getData();
204
- var isDirty = data !== lastExternalValueRef.current.trim();
205
- if (isDirty && !isDirtyState) {
206
- setIsDirtyState(true);
207
- onDirty === null || onDirty === void 0 ? void 0 : onDirty();
208
- }
209
- onChange === null || onChange === void 0 ? void 0 : onChange(data, isDirty);
210
- }, DEBOUNCE_MS);
211
- var handleChange = debouncedChange;
212
- var handleReady = function handleReady(editor) {
213
- addButtonDataAttributes(editor);
214
- editorInstanceRef.current = editor;
215
- setIsEditorReady(true);
216
-
217
- // Set aria-label and aria-description on the editable area if provided
218
- // These provide accessible context to screen reader users
219
- editor.editing.view.change(function (writer) {
220
- var viewEditableRoot = editor.editing.view.document.getRoot();
221
- if (viewEditableRoot) {
222
- if (ariaLabel) {
223
- writer.setAttribute('aria-label', ariaLabel, viewEditableRoot);
224
- }
225
- if (ariaDescription) {
226
- writer.setAttribute('aria-description', ariaDescription, viewEditableRoot);
227
- }
228
- }
229
- });
230
-
231
- // Bind keydown handler when editor is ready
232
- bindKeyDownHandler(editor);
233
- onInit === null || onInit === void 0 ? void 0 : onInit(editor);
234
- };
235
- var handleBlur = function handleBlur(event, editor) {
236
- debouncedChange.flush();
237
- onBlur === null || onBlur === void 0 ? void 0 : onBlur(event, editor);
238
- };
239
- useStickyToolbar({
240
- enabled: enableStickyToolbar,
241
- editor: isEditorReady ? editorInstanceRef.current : null,
242
- editorRef: editorRef,
243
- cssLoading: cssLoading
244
- });
245
- var _useTabAsNavigation = useTabAsNavigation({
246
- config: mergedConfig,
247
- enabled: enableTabAsNavigation,
248
- editor: isEditorReady ? editorInstanceRef.current : null
249
- }),
250
- config = _useTabAsNavigation.config;
251
- var editorKey = "".concat(locale, "-").concat(enableTabAsNavigation);
252
- if (cssLoading) {
253
- return null;
254
- }
255
- if (readonly) {
256
- return /*#__PURE__*/React.createElement(TextEditorOutput, {
257
- value: value,
258
- "aria-label": ariaLabel,
259
- "aria-description": ariaDescription
260
- });
261
- }
262
- return /*#__PURE__*/React.createElement(StyledTextEditor, {
263
- ref: editorRef,
264
- key: editorKey,
265
- error: error,
266
- ready: isEditorReady,
267
- "aria-invalid": error ? 'true' : 'false'
268
- }, /*#__PURE__*/React.createElement(GlobalEditorStyles, {
269
- zIndex: zIndex + 1
270
- }), /*#__PURE__*/React.createElement(TextEditorTheme, null), /*#__PURE__*/React.createElement(CKEditor, _extends({}, restProps, {
271
- editor: ClassicEditor,
272
- config: config,
273
- disabled: disabled,
274
- data: initialValueRef.current,
275
- onChange: handleChange,
276
- onReady: handleReady,
277
- onBlur: handleBlur
278
- })));
55
+ return /*#__PURE__*/React.createElement(TextEditorI18nProvider, null, /*#__PURE__*/React.createElement(ToastAlertProvider, null, /*#__PURE__*/React.createElement(FeatureFlagProvider, null, /*#__PURE__*/React.createElement(TextEditorInner, props))));
56
+ }
57
+ function TextEditorInner(props) {
58
+ var enforceCKEditor = props.enforceCKEditor,
59
+ editorProps = _objectWithoutProperties(props, _excluded);
60
+ var flagValue = useFeatureFlag(FLAG_NAME, false);
61
+ var isCKEditorEnabled = enforceCKEditor !== null && enforceCKEditor !== void 0 ? enforceCKEditor : flagValue;
62
+ return isCKEditorEnabled ? /*#__PURE__*/React.createElement(CKTextEditor, editorProps) : /*#__PURE__*/React.createElement(TinyMCETextEditor, editorProps);
279
63
  }
280
64
  //# sourceMappingURL=TextEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextEditor.js","names":["CKEditor","ClassicEditor","React","useI18nContext","useZIndexContext","TextEditorOutput","debounce","useStickyToolbar","GlobalEditorStyles","StyledTextEditor","TextEditorContext","TextEditorTheme","useCKEditorCss","useCKEditorFocusScope","useTabAsNavigation","addButtonDataAttributes","getDefaultConfig","DEBOUNCE_MS","TextEditor","props","disabled","error","readonly","value","initialValue","onChange","onInit","onBlur","onKeyDown","propLocale","locale","onDirty","restProps","_objectWithoutProperties","_excluded","ariaLabel","ariaDescription","_useCKEditorCss","cssLoading","isLoading","editorRef","useRef","editorInstanceRef","initialValueRef","lastExternalValueRef","keyDownListenerRef","_React$useState","useState","_React$useState2","_slicedToArray","isDirtyState","setIsDirtyState","_React$useState3","_React$useState4","isEditorReady","setIsEditorReady","_useI18nContext","contextLocale","useEffect","undefined","current","editor","editing","view","document","isFocused","getData","data","set","off","change","writer","viewEditableRoot","getRoot","setAttribute","removeAttribute","_useZIndexContext","zIndex","_React$useContext","useContext","features","enableStickyToolbar","stickyToolbar","enableTabAsNavigation","tabAsNavigation","mergedConfig","useMemo","defaultConfig","label","bindKeyDownHandler","useCallback","editorElement","keyDownListener","_event","domEvent","key","stopPropagation","on","debouncedChange","isDirty","trim","handleChange","handleReady","handleBlur","event","flush","enabled","_useTabAsNavigation","config","editorKey","concat","createElement","ref","ready","_extends","onReady"],"sources":["../../src/TextEditor/TextEditor.tsx"],"sourcesContent":["import { CKEditor } from '@ckeditor/ckeditor5-react'\nimport { ClassicEditor, type EventInfo } from 'ckeditor5'\nimport React from 'react'\n\nimport { useI18nContext, useZIndexContext } from '@procore/core-react'\nimport { TextEditorOutput } from '../TextEditorOutput'\nimport { debounce } from '../utils/debounce'\nimport { useStickyToolbar } from './StickyToolbar'\nimport { GlobalEditorStyles, StyledTextEditor } from './TextEditor.styles'\nimport type { KeyDownListener, TextEditorProps } from './TextEditor.types'\nimport { TextEditorContext } from './TextEditorProvider'\nimport { TextEditorTheme } from './textEditorTheming'\nimport { useCKEditorCss } from './useCKEditorCss'\nimport { useCKEditorFocusScope } from './useCKEditorFocusScope'\nimport { useTabAsNavigation } from './useTabAsNavigation'\nimport { addButtonDataAttributes, getDefaultConfig } from './utils'\n\nconst DEBOUNCE_MS = 300\n\n/**\n * To ensure your Jest tests work with the CKEditor implementation, wrap your Jest configuration with `textEditorJestConfig`:\n *\n * @example\n *\n * // Using Jest config file\n *\n * const { textEditorJestConfig } = require('@procore/text-editor/jestConfig')\n *\n * module.exports = textEditorJestConfig({\n * // Your existing Jest config\n * })\n *\n * @example\n *\n * // Using Hammer\n *\n * import { textEditorJestConfig } from '@procore/text-editor/jestConfig'\n *\n * export default {\n * testJest: (defaultConfig) =>\n * textEditorJestConfig({\n * ...defaultConfig,\n * // Your existing Jest config\n * }),\n * }\n *\n * @example\n *\n * // Using Core Scripts\n *\n * const { textEditorJestConfig } = require('@procore/text-editor/jestConfig')\n *\n * module.exports = () => ({\n * jestOverride: (defaultConfig) =>\n * textEditorJestConfig({\n * ...defaultConfig,\n * // Your existing Jest config\n * }),\n * })\n */\nexport function TextEditor(props: Readonly<TextEditorProps>) {\n const {\n disabled,\n error,\n readonly,\n value,\n initialValue,\n onChange,\n onInit,\n onBlur,\n onKeyDown,\n locale: propLocale,\n onDirty,\n ...restProps\n } = props\n const ariaLabel = props['aria-label']\n const ariaDescription = props['aria-description']\n const { isLoading: cssLoading } = useCKEditorCss()\n useCKEditorFocusScope()\n\n const editorRef = React.useRef<HTMLDivElement>(null)\n const editorInstanceRef = React.useRef<ClassicEditor | null>(null)\n const initialValueRef = React.useRef<string>(value || initialValue || '')\n const lastExternalValueRef = React.useRef<string>(value || initialValue || '')\n const keyDownListenerRef = React.useRef<KeyDownListener | null>(null)\n const [isDirtyState, setIsDirtyState] = React.useState(false)\n const [isEditorReady, setIsEditorReady] = React.useState(false)\n const { locale: contextLocale } = useI18nContext()\n const locale = propLocale || contextLocale\n\n React.useEffect(() => {\n if (value !== undefined) {\n lastExternalValueRef.current = value\n }\n }, [value])\n\n React.useEffect(() => {\n const editor = editorInstanceRef.current\n if (!isEditorReady || !editor || value === undefined) return\n if (editor.editing.view.document.isFocused) return\n if (value === editor.getData()) return\n\n editor.data.set(value)\n }, [value, isEditorReady])\n\n // Cleanup keydown listener on unmount\n React.useEffect(() => {\n return () => {\n if (keyDownListenerRef.current && editorInstanceRef.current) {\n editorInstanceRef.current.editing.view.document.off(\n 'keydown',\n keyDownListenerRef.current\n )\n keyDownListenerRef.current = null\n }\n }\n }, [])\n\n // Update aria-label when ariaLabel prop changes\n React.useEffect(() => {\n if (!isEditorReady || !editorInstanceRef.current) {\n return\n }\n\n const editor = editorInstanceRef.current\n editor.editing.view.change((writer) => {\n const viewEditableRoot = editor.editing.view.document.getRoot()\n if (viewEditableRoot) {\n if (ariaLabel) {\n writer.setAttribute('aria-label', ariaLabel, viewEditableRoot)\n } else {\n writer.removeAttribute('aria-label', viewEditableRoot)\n }\n }\n })\n }, [ariaLabel, isEditorReady])\n\n // Update aria-description when ariaDescription prop changes\n React.useEffect(() => {\n if (!isEditorReady || !editorInstanceRef.current) {\n return\n }\n\n const editor = editorInstanceRef.current\n editor.editing.view.change((writer) => {\n const viewEditableRoot = editor.editing.view.document.getRoot()\n if (viewEditableRoot) {\n if (ariaDescription) {\n writer.setAttribute(\n 'aria-description',\n ariaDescription,\n viewEditableRoot\n )\n } else {\n writer.removeAttribute('aria-description', viewEditableRoot)\n }\n }\n })\n }, [ariaDescription, isEditorReady])\n\n const { value: zIndex } = useZIndexContext()\n\n const { features } = React.useContext(TextEditorContext)\n const enableStickyToolbar = !!features?.stickyToolbar\n const enableTabAsNavigation = !!features?.tabAsNavigation\n\n const mergedConfig = React.useMemo(() => {\n const defaultConfig = getDefaultConfig(locale)\n\n // Set accessible label for the editable area if provided\n // This is used by screen readers to announce the editor's purpose\n if (ariaLabel) {\n defaultConfig.label = ariaLabel\n }\n\n return defaultConfig\n }, [ariaLabel, locale])\n\n const bindKeyDownHandler = React.useCallback(\n (editor: ClassicEditor) => {\n const editorElement = editor.editing.view.document.getRoot()\n if (!editorElement) {\n return\n }\n\n // Remove existing keydown listener\n if (keyDownListenerRef.current) {\n editor.editing.view.document.off('keydown', keyDownListenerRef.current)\n }\n\n // Create and store the new listener\n const keyDownListener = (\n _event: EventInfo,\n data: { domEvent: Event }\n ) => {\n const domEvent = data.domEvent as KeyboardEvent\n // Prevent Enter from propagating to parent forms so the\n // editor can handle newlines without accidentally submitting.\n if (domEvent.key === 'Enter') {\n domEvent.stopPropagation()\n }\n\n onKeyDown?.(domEvent, editor)\n }\n\n keyDownListenerRef.current = keyDownListener\n\n // Add the keydown listener\n editor.editing.view.document.on('keydown', keyDownListener)\n },\n [onKeyDown]\n )\n\n const debouncedChange = debounce(\n (_event: EventInfo<string, unknown>, editor: ClassicEditor) => {\n const data = editor.getData()\n const isDirty = data !== lastExternalValueRef.current.trim()\n\n if (isDirty && !isDirtyState) {\n setIsDirtyState(true)\n onDirty?.()\n }\n\n onChange?.(data, isDirty)\n },\n DEBOUNCE_MS\n )\n\n const handleChange = debouncedChange\n\n const handleReady = (editor: ClassicEditor) => {\n addButtonDataAttributes(editor)\n editorInstanceRef.current = editor\n setIsEditorReady(true)\n\n // Set aria-label and aria-description on the editable area if provided\n // These provide accessible context to screen reader users\n editor.editing.view.change((writer) => {\n const viewEditableRoot = editor.editing.view.document.getRoot()\n if (viewEditableRoot) {\n if (ariaLabel) {\n writer.setAttribute('aria-label', ariaLabel, viewEditableRoot)\n }\n if (ariaDescription) {\n writer.setAttribute(\n 'aria-description',\n ariaDescription,\n viewEditableRoot\n )\n }\n }\n })\n\n // Bind keydown handler when editor is ready\n bindKeyDownHandler(editor)\n\n onInit?.(editor)\n }\n\n const handleBlur = (\n event: EventInfo<string, unknown>,\n editor: ClassicEditor\n ) => {\n debouncedChange.flush()\n onBlur?.(event, editor)\n }\n\n useStickyToolbar({\n enabled: enableStickyToolbar,\n editor: isEditorReady ? editorInstanceRef.current : null,\n editorRef,\n cssLoading,\n })\n\n const { config } = useTabAsNavigation({\n config: mergedConfig,\n enabled: enableTabAsNavigation,\n editor: isEditorReady ? editorInstanceRef.current : null,\n })\n\n const editorKey = `${locale}-${enableTabAsNavigation}`\n\n if (cssLoading) {\n return null\n }\n\n if (readonly) {\n return (\n <TextEditorOutput\n value={value}\n aria-label={ariaLabel}\n aria-description={ariaDescription}\n />\n )\n }\n\n return (\n <StyledTextEditor\n ref={editorRef}\n key={editorKey}\n error={error}\n ready={isEditorReady}\n aria-invalid={error ? 'true' : 'false'}\n >\n <GlobalEditorStyles zIndex={zIndex + 1} />\n <TextEditorTheme />\n <CKEditor\n {...restProps}\n editor={ClassicEditor}\n config={config}\n disabled={disabled}\n data={initialValueRef.current}\n onChange={handleChange}\n onReady={handleReady}\n onBlur={handleBlur}\n />\n </StyledTextEditor>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TextEditor.js","names":["ToastAlertProvider","useFeatureFlag","React","CKTextEditor","FeatureFlagProvider","TextEditorI18nProvider","TinyMCETextEditor","FLAG_NAME","TextEditor","props","createElement","TextEditorInner","enforceCKEditor","editorProps","_objectWithoutProperties","_excluded","flagValue","isCKEditorEnabled"],"sources":["../../src/TextEditor/TextEditor.tsx"],"sourcesContent":["import { ToastAlertProvider } from '@procore/toast-alert'\nimport { useFeatureFlag } from '@procore/web-sdk-feature-toggle'\nimport React from 'react'\n\nimport { CKTextEditor } from './CKTextEditor'\nimport { FeatureFlagProvider } from './Providers/FeatureFlagProvider'\nimport type { TextEditorProps } from './TextEditor.types'\nimport { TextEditorI18nProvider } from './TextEditorI18nProvider'\nimport { TinyMCETextEditor } from './TinyMCETextEditor'\n\nconst FLAG_NAME = 'pmqs-ck-editor-enabled'\n\n/**\n * To ensure your Jest tests work with the CKEditor implementation, wrap your Jest configuration with `textEditorJestConfig`:\n *\n * @example\n *\n * // Using Jest config file\n *\n * const { textEditorJestConfig } = require('@procore/text-editor/jestConfig')\n *\n * module.exports = textEditorJestConfig({\n * // Your existing Jest config\n * })\n *\n * @example\n *\n * // Using Hammer\n *\n * import { textEditorJestConfig } from '@procore/text-editor/jestConfig'\n *\n * export default {\n * testJest: (defaultConfig) =>\n * textEditorJestConfig({\n * ...defaultConfig,\n * // Your existing Jest config\n * }),\n * }\n *\n * @example\n *\n * // Using Core Scripts\n *\n * const { textEditorJestConfig } = require('@procore/text-editor/jestConfig')\n *\n * module.exports = () => ({\n * jestOverride: (defaultConfig) =>\n * textEditorJestConfig({\n * ...defaultConfig,\n * // Your existing Jest config\n * }),\n * })\n */\nexport function TextEditor(props: Readonly<TextEditorProps>) {\n return (\n <TextEditorI18nProvider>\n <ToastAlertProvider>\n <FeatureFlagProvider>\n <TextEditorInner {...props} />\n </FeatureFlagProvider>\n </ToastAlertProvider>\n </TextEditorI18nProvider>\n )\n}\n\nfunction TextEditorInner(props: Readonly<TextEditorProps>) {\n const { enforceCKEditor, ...editorProps } = props\n const flagValue = useFeatureFlag<boolean>(FLAG_NAME, false)\n const isCKEditorEnabled = enforceCKEditor ?? flagValue\n\n return isCKEditorEnabled ? (\n <CKTextEditor {...editorProps} />\n ) : (\n <TinyMCETextEditor {...editorProps} />\n )\n}\n"],"mappings":";;;AAAA,SAASA,kBAAkB,QAAQ,sBAAsB;AACzD,SAASC,cAAc,QAAQ,iCAAiC;AAChE,OAAOC,KAAK,MAAM,OAAO;AAEzB,SAASC,YAAY,QAAQ,gBAAgB;AAC7C,SAASC,mBAAmB,QAAQ,iCAAiC;AAErE,SAASC,sBAAsB,QAAQ,0BAA0B;AACjE,SAASC,iBAAiB,QAAQ,qBAAqB;AAEvD,IAAMC,SAAS,GAAG,wBAAwB;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAACC,KAAgC,EAAE;EAC3D,oBACEP,KAAA,CAAAQ,aAAA,CAACL,sBAAsB,qBACrBH,KAAA,CAAAQ,aAAA,CAACV,kBAAkB,qBACjBE,KAAA,CAAAQ,aAAA,CAACN,mBAAmB,qBAClBF,KAAA,CAAAQ,aAAA,CAACC,eAAe,EAAKF,KAAQ,CACV,CACH,CACE,CAAC;AAE7B;AAEA,SAASE,eAAeA,CAACF,KAAgC,EAAE;EACzD,IAAQG,eAAe,GAAqBH,KAAK,CAAzCG,eAAe;IAAKC,WAAW,GAAAC,wBAAA,CAAKL,KAAK,EAAAM,SAAA;EACjD,IAAMC,SAAS,GAAGf,cAAc,CAAUM,SAAS,EAAE,KAAK,CAAC;EAC3D,IAAMU,iBAAiB,GAAGL,eAAe,aAAfA,eAAe,cAAfA,eAAe,GAAII,SAAS;EAEtD,OAAOC,iBAAiB,gBACtBf,KAAA,CAAAQ,aAAA,CAACP,YAAY,EAAKU,WAAc,CAAC,gBAEjCX,KAAA,CAAAQ,aAAA,CAACJ,iBAAiB,EAAKO,WAAc,CACtC;AACH"}
@@ -4,5 +4,18 @@ export declare const GlobalEditorStyles: import("react").NamedExoticComponent<im
4
4
  }>;
5
5
  export declare const StyledTextEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
6
6
  error?: boolean | undefined;
7
- ready?: boolean | undefined;
7
+ $ready?: boolean | undefined;
8
8
  }>> & string;
9
+ export declare const StyledImageUploadWarningToast: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("react").HTMLAttributes<HTMLDivElement> & import("@procore/core-react").FlexProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
10
+ ref?: ((instance: HTMLDivElement | null) => void) | import("react").RefObject<HTMLDivElement> | null | undefined;
11
+ }, never>> & string & Omit<import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("@procore/core-react").FlexProps & import("react").RefAttributes<HTMLDivElement>>, keyof import("react").Component<any, {}, any>>;
12
+ export declare const StyledImageUploadWarningToastIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<{
13
+ size?: import("@procore/core-icons/dist/Icon").IconSize | undefined;
14
+ } & import("react").SVGAttributes<SVGElement> & import("react").RefAttributes<SVGSVGElement>, "ref"> & {
15
+ ref?: ((instance: SVGSVGElement | null) => void) | import("react").RefObject<SVGSVGElement> | null | undefined;
16
+ }, never>> & string & Omit<import("react").ForwardRefExoticComponent<{
17
+ size?: import("@procore/core-icons/dist/Icon").IconSize | undefined;
18
+ } & import("react").SVGAttributes<SVGElement> & import("react").RefAttributes<SVGSVGElement>>, keyof import("react").Component<any, {}, any>>;
19
+ export declare const StyledReadOnlyValue: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("react").HTMLAttributes<HTMLSpanElement> & import("@procore/core-react").TypographyProps & import("react").RefAttributes<HTMLSpanElement>, "ref"> & {
20
+ ref?: ((instance: HTMLSpanElement | null) => void) | import("react").RefObject<HTMLSpanElement> | null | undefined;
21
+ }, never>> & string & Omit<import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLSpanElement> & import("@procore/core-react").TypographyProps & import("react").RefAttributes<HTMLSpanElement>>, keyof import("react").Component<any, {}, any>>;
@@ -1,6 +1,7 @@
1
- import { colors } from '@procore/core-react';
1
+ import { Info } from '@procore/core-icons';
2
+ import { borderRadius, colors, Flex, Typography } from '@procore/core-react';
2
3
  import styled, { createGlobalStyle } from 'styled-components';
3
- export var GlobalEditorStyles = /*#__PURE__*/createGlobalStyle([":root{--ck-z-default:", ";--ck-z-modal:", ";--ck-z-dialog:", ";}.ck-body-wrapper{--ck-z-default:", ";--ck-z-modal:", ";--ck-z-dialog:", ";}.ck-balloon-panel{z-index:", " !important;}.ck-dropdown__panel{z-index:", " !important;}.ck.ck-toolbar_grouping{container-type:inline-size;}.ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel{max-width:100cqw !important;z-index:", " !important;}.ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel .ck-toolbar__items{flex-wrap:wrap !important;}.ck-content{padding:16px 28px !important;--ck-content-font-family:Inter,'Noto Sans JP','Noto Sans KR','Noto Sans SC','Noto Sans TC',sans-serif;--ck-content-font-size:14px;--ck-content-word-break:break-word;--ck-content-overflow-wrap:break-word;--ck-content-line-height:1.4;p{margin-top:0 !important;margin-bottom:0 !important;}}[data-id=\"modal\"] .ck-sticky-panel__content_sticky{top:var(--modal-header-height,84px) !important;}"], function (_ref) {
4
+ export var GlobalEditorStyles = /*#__PURE__*/createGlobalStyle([":root{--ck-z-default:", ";--ck-z-modal:", ";--ck-z-dialog:", ";}.ck-body-wrapper{--ck-z-default:", ";--ck-z-modal:", ";--ck-z-dialog:", ";}.ck-balloon-panel{z-index:", " !important;}.ck-dropdown__panel{z-index:", " !important;}.ck.ck-toolbar_grouping{container-type:inline-size;}.ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel{max-width:100cqw !important;z-index:", " !important;}.ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel .ck-toolbar__items{flex-wrap:wrap !important;}.ck-content{padding:16px 28px !important;--ck-content-font-family:Inter,'Noto Sans JP','Noto Sans KR','Noto Sans SC','Noto Sans TC',sans-serif;--ck-content-font-size:14px;--ck-content-word-break:break-word;--ck-content-overflow-wrap:break-word;--ck-content-line-height:1.4;p{margin-top:0 !important;margin-bottom:0 !important;}img{max-width:100%;height:auto;}}[data-id=\"modal\"] .ck-sticky-panel__content_sticky{top:var(--modal-header-height,84px) !important;}"], function (_ref) {
4
5
  var zIndex = _ref.zIndex;
5
6
  return zIndex;
6
7
  }, function (_ref2) {
@@ -30,12 +31,24 @@ export var GlobalEditorStyles = /*#__PURE__*/createGlobalStyle([":root{--ck-z-de
30
31
  });
31
32
  export var StyledTextEditor = /*#__PURE__*/styled.div.withConfig({
32
33
  displayName: "StyledTextEditor",
33
- componentId: "text-editor-0_5_0__sc-iim79x-0"
34
+ componentId: "text-editor-1_0_0__sc-iim79x-0"
34
35
  })([".ck.ck-editor{opacity:", ";}", ""], function (_ref0) {
35
- var ready = _ref0.ready;
36
- return ready ? 1 : 0;
36
+ var $ready = _ref0.$ready;
37
+ return $ready ? 1 : 0;
37
38
  }, function (_ref1) {
38
39
  var error = _ref1.error;
39
40
  return error && "\n .ck-sticky-panel__content {\n border-top-color: ".concat(colors.red50, " !important;\n border-left-color: ").concat(colors.red50, " !important;\n border-right-color: ").concat(colors.red50, " !important;\n }\n\n .ck-editor__editable {\n border-left-color: ").concat(colors.red50, " !important;\n border-right-color: ").concat(colors.red50, " !important;\n border-bottom-color: ").concat(colors.red50, " !important;\n }\n ");
40
41
  });
42
+ export var StyledImageUploadWarningToast = /*#__PURE__*/styled(Flex).withConfig({
43
+ displayName: "StyledImageUploadWarningToast",
44
+ componentId: "text-editor-1_0_0__sc-iim79x-1"
45
+ })(["background-color:", ";border-radius:", "px;box-shadow:0px 8px 32px -4px hsla(200,10%,15%,0.64);color:", ";min-height:48px;width:550px;"], colors.blue40, borderRadius.md, colors.white);
46
+ export var StyledImageUploadWarningToastIcon = /*#__PURE__*/styled(Info).withConfig({
47
+ displayName: "StyledImageUploadWarningToastIcon",
48
+ componentId: "text-editor-1_0_0__sc-iim79x-2"
49
+ })(["color:", ";"], colors.white);
50
+ export var StyledReadOnlyValue = /*#__PURE__*/styled(Typography).withConfig({
51
+ displayName: "StyledReadOnlyValue",
52
+ componentId: "text-editor-1_0_0__sc-iim79x-3"
53
+ })(["overflow-wrap:anywhere;margin-block-start:0 !important;user-select:text;table{border-width:revert-layer;border-style:solid;border-color:", ";overflow-wrap:break-word;}td,tr,th,tbody{border-width:revert-layer;border-style:inherit;border-color:inherit;}p{line-height:normal;}"], colors.gray60);
41
54
  //# sourceMappingURL=TextEditor.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextEditor.styles.js","names":["colors","styled","createGlobalStyle","GlobalEditorStyles","_ref","zIndex","_ref2","_ref3","_ref4","_ref5","_ref6","_ref7","_ref8","_ref9","StyledTextEditor","div","withConfig","displayName","componentId","_ref0","ready","_ref1","error","concat","red50"],"sources":["../../src/TextEditor/TextEditor.styles.ts"],"sourcesContent":["import { colors } from '@procore/core-react'\nimport styled, { createGlobalStyle } from 'styled-components'\n\nexport const GlobalEditorStyles = createGlobalStyle<{\n zIndex: number\n}>`\n :root {\n --ck-z-default: ${({ zIndex }) => zIndex};\n --ck-z-modal: ${({ zIndex }) => zIndex + 999};\n --ck-z-dialog: ${({ zIndex }) => zIndex + 1000};\n }\n \n .ck-body-wrapper {\n --ck-z-default: ${({ zIndex }) => zIndex};\n --ck-z-modal: ${({ zIndex }) => zIndex + 999};\n --ck-z-dialog: ${({ zIndex }) => zIndex + 1000};\n }\n \n .ck-balloon-panel {\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck-dropdown__panel {\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck.ck-toolbar_grouping {\n container-type: inline-size;\n }\n\n .ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel {\n max-width: 100cqw !important;\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel .ck-toolbar__items {\n flex-wrap: wrap !important;\n }\n\n .ck-content {\n padding: 16px 28px !important;\n --ck-content-font-family: Inter, 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', sans-serif;\n --ck-content-font-size: 14px;\n --ck-content-word-break: break-word;\n --ck-content-overflow-wrap: break-word;\n --ck-content-line-height: 1.4;\n\n p {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n }\n\n [data-id=\"modal\"] .ck-sticky-panel__content_sticky {\n top: var(--modal-header-height, 84px) !important;\n }\n`\n\nexport const StyledTextEditor = styled.div<{\n error?: boolean\n ready?: boolean\n}>`\n .ck.ck-editor {\n opacity: ${({ ready }) => (ready ? 1 : 0)};\n }\n\n ${({ error }) =>\n error &&\n `\n .ck-sticky-panel__content {\n border-top-color: ${colors.red50} !important;\n border-left-color: ${colors.red50} !important;\n border-right-color: ${colors.red50} !important;\n }\n\n .ck-editor__editable {\n border-left-color: ${colors.red50} !important;\n border-right-color: ${colors.red50} !important;\n border-bottom-color: ${colors.red50} !important;\n }\n `}\n`\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,qBAAqB;AAC5C,OAAOC,MAAM,IAAIC,iBAAiB,QAAQ,mBAAmB;AAE7D,OAAO,IAAMC,kBAAkB,gBAAGD,iBAAiB,45BAI7B,UAAAE,IAAA;EAAA,IAAGC,MAAM,GAAAD,IAAA,CAANC,MAAM;EAAA,OAAOA,MAAM;AAAA,GACxB,UAAAC,KAAA;EAAA,IAAGD,MAAM,GAAAC,KAAA,CAAND,MAAM;EAAA,OAAOA,MAAM,GAAG,GAAG;AAAA,GAC3B,UAAAE,KAAA;EAAA,IAAGF,MAAM,GAAAE,KAAA,CAANF,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAI5B,UAAAG,KAAA;EAAA,IAAGH,MAAM,GAAAG,KAAA,CAANH,MAAM;EAAA,OAAOA,MAAM;AAAA,GACxB,UAAAI,KAAA;EAAA,IAAGJ,MAAM,GAAAI,KAAA,CAANJ,MAAM;EAAA,OAAOA,MAAM,GAAG,GAAG;AAAA,GAC3B,UAAAK,KAAA;EAAA,IAAGL,MAAM,GAAAK,KAAA,CAANL,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAInC,UAAAM,KAAA;EAAA,IAAGN,MAAM,GAAAM,KAAA,CAANN,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAI7B,UAAAO,KAAA;EAAA,IAAGP,MAAM,GAAAO,KAAA,CAANP,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAS7B,UAAAQ,KAAA;EAAA,IAAGR,MAAM,GAAAQ,KAAA,CAANR,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,EAwB3C;AAED,OAAO,IAAMS,gBAAgB,gBAAGb,MAAM,CAACc,GAAG,CAAAC,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,yCAK3B,UAAAC,KAAA;EAAA,IAAGC,KAAK,GAAAD,KAAA,CAALC,KAAK;EAAA,OAAQA,KAAK,GAAG,CAAC,GAAG,CAAC;AAAA,CAAC,EAGzC,UAAAC,KAAA;EAAA,IAAGC,KAAK,GAAAD,KAAA,CAALC,KAAK;EAAA,OACRA,KAAK,sEAAAC,MAAA,CAGmBvB,MAAM,CAACwB,KAAK,+CAAAD,MAAA,CACXvB,MAAM,CAACwB,KAAK,gDAAAD,MAAA,CACXvB,MAAM,CAACwB,KAAK,wFAAAD,MAAA,CAIbvB,MAAM,CAACwB,KAAK,gDAAAD,MAAA,CACXvB,MAAM,CAACwB,KAAK,iDAAAD,MAAA,CACXvB,MAAM,CAACwB,KAAK,gCAEtC;AAAA,EACJ"}
1
+ {"version":3,"file":"TextEditor.styles.js","names":["Info","borderRadius","colors","Flex","Typography","styled","createGlobalStyle","GlobalEditorStyles","_ref","zIndex","_ref2","_ref3","_ref4","_ref5","_ref6","_ref7","_ref8","_ref9","StyledTextEditor","div","withConfig","displayName","componentId","_ref0","$ready","_ref1","error","concat","red50","StyledImageUploadWarningToast","blue40","md","white","StyledImageUploadWarningToastIcon","StyledReadOnlyValue","gray60"],"sources":["../../src/TextEditor/TextEditor.styles.ts"],"sourcesContent":["import { Info } from '@procore/core-icons'\nimport { borderRadius, colors, Flex, Typography } from '@procore/core-react'\nimport styled, { createGlobalStyle } from 'styled-components'\n\nexport const GlobalEditorStyles = createGlobalStyle<{\n zIndex: number\n}>`\n :root {\n --ck-z-default: ${({ zIndex }) => zIndex};\n --ck-z-modal: ${({ zIndex }) => zIndex + 999};\n --ck-z-dialog: ${({ zIndex }) => zIndex + 1000};\n }\n \n .ck-body-wrapper {\n --ck-z-default: ${({ zIndex }) => zIndex};\n --ck-z-modal: ${({ zIndex }) => zIndex + 999};\n --ck-z-dialog: ${({ zIndex }) => zIndex + 1000};\n }\n \n .ck-balloon-panel {\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck-dropdown__panel {\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck.ck-toolbar_grouping {\n container-type: inline-size;\n }\n\n .ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel {\n max-width: 100cqw !important;\n z-index: ${({ zIndex }) => zIndex + 1000} !important;\n }\n\n .ck.ck-toolbar__grouped-dropdown > .ck-dropdown__panel .ck-toolbar__items {\n flex-wrap: wrap !important;\n }\n\n .ck-content {\n padding: 16px 28px !important;\n --ck-content-font-family: Inter, 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', sans-serif;\n --ck-content-font-size: 14px;\n --ck-content-word-break: break-word;\n --ck-content-overflow-wrap: break-word;\n --ck-content-line-height: 1.4;\n\n p {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n\n img {\n max-width: 100%;\n height: auto;\n }\n }\n\n [data-id=\"modal\"] .ck-sticky-panel__content_sticky {\n top: var(--modal-header-height, 84px) !important;\n }\n`\n\nexport const StyledTextEditor = styled.div<{\n error?: boolean\n $ready?: boolean\n}>`\n .ck.ck-editor {\n opacity: ${({ $ready }) => ($ready ? 1 : 0)};\n }\n\n ${({ error }) =>\n error &&\n `\n .ck-sticky-panel__content {\n border-top-color: ${colors.red50} !important;\n border-left-color: ${colors.red50} !important;\n border-right-color: ${colors.red50} !important;\n }\n\n .ck-editor__editable {\n border-left-color: ${colors.red50} !important;\n border-right-color: ${colors.red50} !important;\n border-bottom-color: ${colors.red50} !important;\n }\n `}\n`\n\nexport const StyledImageUploadWarningToast = styled(Flex)`\n background-color: ${colors.blue40};\n border-radius: ${borderRadius.md}px;\n box-shadow: 0px 8px 32px -4px hsla(200, 10%, 15%, 0.64);\n color: ${colors.white};\n min-height: 48px;\n width: 550px;\n`\n\nexport const StyledImageUploadWarningToastIcon = styled(Info)`\n color: ${colors.white};\n`\n\nexport const StyledReadOnlyValue = styled(Typography)`\n overflow-wrap: anywhere;\n margin-block-start: 0 !important;\n user-select: text;\n\n table {\n border-width: revert-layer;\n border-style: solid;\n border-color: ${colors.gray60};\n overflow-wrap: break-word;\n }\n\n td,\n tr,\n th,\n tbody {\n border-width: revert-layer;\n border-style: inherit;\n border-color: inherit;\n }\n\n p {\n line-height: normal;\n }\n`\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,qBAAqB;AAC1C,SAASC,YAAY,EAAEC,MAAM,EAAEC,IAAI,EAAEC,UAAU,QAAQ,qBAAqB;AAC5E,OAAOC,MAAM,IAAIC,iBAAiB,QAAQ,mBAAmB;AAE7D,OAAO,IAAMC,kBAAkB,gBAAGD,iBAAiB,47BAI7B,UAAAE,IAAA;EAAA,IAAGC,MAAM,GAAAD,IAAA,CAANC,MAAM;EAAA,OAAOA,MAAM;AAAA,GACxB,UAAAC,KAAA;EAAA,IAAGD,MAAM,GAAAC,KAAA,CAAND,MAAM;EAAA,OAAOA,MAAM,GAAG,GAAG;AAAA,GAC3B,UAAAE,KAAA;EAAA,IAAGF,MAAM,GAAAE,KAAA,CAANF,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAI5B,UAAAG,KAAA;EAAA,IAAGH,MAAM,GAAAG,KAAA,CAANH,MAAM;EAAA,OAAOA,MAAM;AAAA,GACxB,UAAAI,KAAA;EAAA,IAAGJ,MAAM,GAAAI,KAAA,CAANJ,MAAM;EAAA,OAAOA,MAAM,GAAG,GAAG;AAAA,GAC3B,UAAAK,KAAA;EAAA,IAAGL,MAAM,GAAAK,KAAA,CAANL,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAInC,UAAAM,KAAA;EAAA,IAAGN,MAAM,GAAAM,KAAA,CAANN,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAI7B,UAAAO,KAAA;EAAA,IAAGP,MAAM,GAAAO,KAAA,CAANP,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,GAS7B,UAAAQ,KAAA;EAAA,IAAGR,MAAM,GAAAQ,KAAA,CAANR,MAAM;EAAA,OAAOA,MAAM,GAAG,IAAI;AAAA,EA6B3C;AAED,OAAO,IAAMS,gBAAgB,gBAAGb,MAAM,CAACc,GAAG,CAAAC,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,yCAK3B,UAAAC,KAAA;EAAA,IAAGC,MAAM,GAAAD,KAAA,CAANC,MAAM;EAAA,OAAQA,MAAM,GAAG,CAAC,GAAG,CAAC;AAAA,CAAC,EAG3C,UAAAC,KAAA;EAAA,IAAGC,KAAK,GAAAD,KAAA,CAALC,KAAK;EAAA,OACRA,KAAK,sEAAAC,MAAA,CAGmBzB,MAAM,CAAC0B,KAAK,+CAAAD,MAAA,CACXzB,MAAM,CAAC0B,KAAK,gDAAAD,MAAA,CACXzB,MAAM,CAAC0B,KAAK,wFAAAD,MAAA,CAIbzB,MAAM,CAAC0B,KAAK,gDAAAD,MAAA,CACXzB,MAAM,CAAC0B,KAAK,iDAAAD,MAAA,CACXzB,MAAM,CAAC0B,KAAK,gCAEtC;AAAA,EACJ;AAED,OAAO,IAAMC,6BAA6B,gBAAGxB,MAAM,CAACF,IAAI,CAAC,CAAAiB,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,+IACnCpB,MAAM,CAAC4B,MAAM,EAChB7B,YAAY,CAAC8B,EAAE,EAEvB7B,MAAM,CAAC8B,KAAK,CAGtB;AAED,OAAO,IAAMC,iCAAiC,gBAAG5B,MAAM,CAACL,IAAI,CAAC,CAAAoB,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,oBAClDpB,MAAM,CAAC8B,KAAK,CACtB;AAED,OAAO,IAAME,mBAAmB,gBAAG7B,MAAM,CAACD,UAAU,CAAC,CAAAgB,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,0RAQjCpB,MAAM,CAACiC,MAAM,CAgBhC"}
@@ -1,6 +1,58 @@
1
+ import type { I18njs } from '@procore/core-i18n-js';
2
+ import type { TextEditorProps as CoreTextEditorProps } from '@procore/core-react';
1
3
  import type { Locale } from '@procore/globalization-toolkit';
2
4
  import type { ClassicEditor, EventInfo } from 'ckeditor5';
3
- export interface TextEditorProps {
5
+ export interface TextEditorImageUploadResult {
6
+ urls: {
7
+ default: string;
8
+ };
9
+ /**
10
+ * Durable ProstoreFile id. The text editor embeds this ID in saved markup to
11
+ * mark the image as a first-party upload (backend email/PDF sanitizers rely on
12
+ * it). The persisted URL is a permanent, publicly fetchable Prostore URL, so
13
+ * it renders as-is in the app, emails, and exports.
14
+ *
15
+ * @since 0.6.0
16
+ */
17
+ prostoreFileId: number | string;
18
+ width?: number;
19
+ height?: number;
20
+ }
21
+ export interface TextEditorImageUploadHandlers {
22
+ /**
23
+ * Uploads the selected image and returns durable backend-approved image URLs.
24
+ *
25
+ * @since 0.4.2
26
+ */
27
+ upload: (file: File, context: {
28
+ signal: AbortSignal;
29
+ }, callbacks: {
30
+ onProgress?: (uploaded: number, total?: number) => void;
31
+ }) => Promise<TextEditorImageUploadResult>;
32
+ i18n: Pick<I18njs, 't'>;
33
+ onError?: (message: string) => void;
34
+ onWarning?: (message: string) => void;
35
+ }
36
+ export interface TextEditorImageUploadOptions {
37
+ /**
38
+ * Required to enable image uploads. When omitted, the editor renders without
39
+ * the Procore image-upload plugin.
40
+ *
41
+ * @since 0.5.0
42
+ */
43
+ companyId?: number | string;
44
+ projectId?: number | string;
45
+ /**
46
+ * Identifier of the tool hosting the editor (e.g. `rfis`, `submittal_log`).
47
+ * Required to enable image uploads: it is sent with each upload for
48
+ * attribution/audit and is validated by the backend against known tools.
49
+ * When omitted, the editor renders without the Procore image-upload plugin.
50
+ *
51
+ * @since 0.7.0
52
+ */
53
+ toolName?: string;
54
+ }
55
+ export interface TextEditorProps extends TextEditorImageUploadOptions {
4
56
  /**
5
57
  * Unique identifier for the editor
6
58
  *
@@ -119,6 +171,35 @@ export interface TextEditorProps {
119
171
  * @since 0.0.1
120
172
  */
121
173
  onKeyDown?: (event: KeyboardEvent, editor: ClassicEditor) => void;
174
+ /**
175
+ * Placeholder text shown when the editor is empty
176
+ *
177
+ * @since 1.0.0
178
+ */
179
+ placeholder?: string;
180
+ /**
181
+ * TinyMCE init configuration. Merged with internal defaults; use this to
182
+ * pass custom content_style, paste hooks, or other TinyMCE-specific options.
183
+ * Has no effect when CKEditor is active.
184
+ *
185
+ * @since 1.0.0
186
+ */
187
+ init?: CoreTextEditorProps['init'];
188
+ /**
189
+ * Number of rows to control the editor height. When set, the editor height
190
+ * is fixed. When omitted, the editor grows with content.
191
+ *
192
+ * @since 1.0.0
193
+ */
194
+ rows?: number;
195
+ /**
196
+ * Opt in to CKEditor immediately, bypassing the gradual feature flag rollout.
197
+ * Use this only when you explicitly want to ignore the rollout schedule.
198
+ * When enabled, the LaunchDarkly flag is bypassed and CKEditor is rendered directly.
199
+ *
200
+ * @since 1.0.0
201
+ */
202
+ enforceCKEditor?: true;
122
203
  }
123
204
  export declare type KeyDownListener = (event: EventInfo, data: {
124
205
  domEvent: Event;
@@ -1 +1 @@
1
- {"version":3,"file":"TextEditor.types.js","names":[],"sources":["../../src/TextEditor/TextEditor.types.ts"],"sourcesContent":["import type { Locale } from '@procore/globalization-toolkit'\nimport type { ClassicEditor, EventInfo } from 'ckeditor5'\n\nexport interface TextEditorProps {\n /**\n * Unique identifier for the editor\n *\n * @since 0.0.1\n */\n id?: string\n\n /**\n * Initial value of the editor\n *\n * @deprecated `initialValue` has been deprecated and will be removed in a future version.\n * Please use the `value` prop instead\n * @deprecatedSince 0.0.1\n * @since 0.0.1\n */\n initialValue?: string\n\n /**\n * The current value of the editor\n *\n * @since 0.0.1\n */\n value?: string\n\n /**\n * Indicates if the editor is disabled\n *\n * @since 0.0.1\n */\n disabled?: boolean\n\n /**\n * Indicates if the editor is in an error state\n *\n * @since 0.0.1\n */\n error?: boolean\n\n /**\n * Indicates if the editor is in readonly mode.\n * When true, renders the content using TextEditorOutput instead of the editable editor.\n *\n * @since 0.2.0\n */\n readonly?: boolean\n\n /**\n * Accessible label for the editor's editable area. This text will be\n * announced by screen readers when the user focuses the editor. It should\n * match or include the visible label associated with this editor field.\n * If not provided, screen readers will announce a generic \"Rich Text Editor\" message.\n *\n * @since 0.1.0\n */\n 'aria-label'?: string\n\n /**\n * Accessible description for the editor's editable area.\n * This text provides additional context to screen reader users. It will be\n * announced after the label when the user focuses the editor.\n *\n * @since 0.1.0\n */\n 'aria-description'?: string\n\n /**\n * Locale which will be used for localization. Can be passed directly or\n * set by wrapping components in I18n provider.\n * @since 0.0.1\n */\n locale?: Locale\n\n /**\n * Callback fired when the editor content changes\n *\n * @param value - The current content of the editor\n * @param isDirty - Whether the content differs from the initial value\n * @since 0.0.1\n */\n onChange?: (value: string, isDirty?: boolean) => void\n\n /**\n * Callback fired when the editor gains focus\n *\n * @since 0.0.1\n */\n onFocus?: (event: EventInfo, editor: ClassicEditor) => void\n\n /**\n * Callback fired when the editor loses focus\n *\n * @since 0.0.1\n */\n onBlur?: (event: EventInfo, editor: ClassicEditor) => void\n\n /**\n * Callback fired when an error occurs in the editor\n *\n * @since 0.0.1\n */\n onError?: (\n error: Error,\n details: {\n phase: 'initialization' | 'runtime'\n willEditorRestart?: boolean\n }\n ) => void\n\n /**\n * Callback fired when the editor is ready\n *\n * @since 0.0.1\n */\n onInit?: (editor: ClassicEditor) => void\n\n /**\n * Callback fired after the editor instance is destroyed\n *\n * @since 0.0.1\n */\n onAfterDestroy?: () => void\n\n /**\n * Callback fired when the editor becomes dirty (content differs from initial value)\n *\n * @since 0.0.1\n */\n onDirty?: () => void\n\n /**\n * Callback fired when a key is pressed in the editor\n *\n * @param event - The keyboard event\n * @param editor - The CKEditor instance\n * @since 0.0.1\n */\n onKeyDown?: (event: KeyboardEvent, editor: ClassicEditor) => void\n}\n\nexport type KeyDownListener = (\n event: EventInfo,\n data: { domEvent: Event }\n) => void\n"],"mappings":""}
1
+ {"version":3,"file":"TextEditor.types.js","names":[],"sources":["../../src/TextEditor/TextEditor.types.ts"],"sourcesContent":["import type { I18njs } from '@procore/core-i18n-js'\nimport type { TextEditorProps as CoreTextEditorProps } from '@procore/core-react'\nimport type { Locale } from '@procore/globalization-toolkit'\nimport type { ClassicEditor, EventInfo } from 'ckeditor5'\n\nexport interface TextEditorImageUploadResult {\n urls: {\n default: string\n }\n /**\n * Durable ProstoreFile id. The text editor embeds this ID in saved markup to\n * mark the image as a first-party upload (backend email/PDF sanitizers rely on\n * it). The persisted URL is a permanent, publicly fetchable Prostore URL, so\n * it renders as-is in the app, emails, and exports.\n *\n * @since 0.6.0\n */\n prostoreFileId: number | string\n width?: number\n height?: number\n}\n\nexport interface TextEditorImageUploadHandlers {\n /**\n * Uploads the selected image and returns durable backend-approved image URLs.\n *\n * @since 0.4.2\n */\n upload: (\n file: File,\n context: { signal: AbortSignal },\n callbacks: { onProgress?: (uploaded: number, total?: number) => void }\n ) => Promise<TextEditorImageUploadResult>\n i18n: Pick<I18njs, 't'>\n onError?: (message: string) => void\n onWarning?: (message: string) => void\n}\n\nexport interface TextEditorImageUploadOptions {\n /**\n * Required to enable image uploads. When omitted, the editor renders without\n * the Procore image-upload plugin.\n *\n * @since 0.5.0\n */\n companyId?: number | string\n projectId?: number | string\n /**\n * Identifier of the tool hosting the editor (e.g. `rfis`, `submittal_log`).\n * Required to enable image uploads: it is sent with each upload for\n * attribution/audit and is validated by the backend against known tools.\n * When omitted, the editor renders without the Procore image-upload plugin.\n *\n * @since 0.7.0\n */\n toolName?: string\n}\n\nexport interface TextEditorProps extends TextEditorImageUploadOptions {\n /**\n * Unique identifier for the editor\n *\n * @since 0.0.1\n */\n id?: string\n\n /**\n * Initial value of the editor\n *\n * @deprecated `initialValue` has been deprecated and will be removed in a future version.\n * Please use the `value` prop instead\n * @deprecatedSince 0.0.1\n * @since 0.0.1\n */\n initialValue?: string\n\n /**\n * The current value of the editor\n *\n * @since 0.0.1\n */\n value?: string\n\n /**\n * Indicates if the editor is disabled\n *\n * @since 0.0.1\n */\n disabled?: boolean\n\n /**\n * Indicates if the editor is in an error state\n *\n * @since 0.0.1\n */\n error?: boolean\n\n /**\n * Indicates if the editor is in readonly mode.\n * When true, renders the content using TextEditorOutput instead of the editable editor.\n *\n * @since 0.2.0\n */\n readonly?: boolean\n\n /**\n * Accessible label for the editor's editable area. This text will be\n * announced by screen readers when the user focuses the editor. It should\n * match or include the visible label associated with this editor field.\n * If not provided, screen readers will announce a generic \"Rich Text Editor\" message.\n *\n * @since 0.1.0\n */\n 'aria-label'?: string\n\n /**\n * Accessible description for the editor's editable area.\n * This text provides additional context to screen reader users. It will be\n * announced after the label when the user focuses the editor.\n *\n * @since 0.1.0\n */\n 'aria-description'?: string\n\n /**\n * Locale which will be used for localization. Can be passed directly or\n * set by wrapping components in I18n provider.\n * @since 0.0.1\n */\n locale?: Locale\n\n /**\n * Callback fired when the editor content changes\n *\n * @param value - The current content of the editor\n * @param isDirty - Whether the content differs from the initial value\n * @since 0.0.1\n */\n onChange?: (value: string, isDirty?: boolean) => void\n\n /**\n * Callback fired when the editor gains focus\n *\n * @since 0.0.1\n */\n onFocus?: (event: EventInfo, editor: ClassicEditor) => void\n\n /**\n * Callback fired when the editor loses focus\n *\n * @since 0.0.1\n */\n onBlur?: (event: EventInfo, editor: ClassicEditor) => void\n\n /**\n * Callback fired when an error occurs in the editor\n *\n * @since 0.0.1\n */\n onError?: (\n error: Error,\n details: {\n phase: 'initialization' | 'runtime'\n willEditorRestart?: boolean\n }\n ) => void\n\n /**\n * Callback fired when the editor is ready\n *\n * @since 0.0.1\n */\n onInit?: (editor: ClassicEditor) => void\n\n /**\n * Callback fired after the editor instance is destroyed\n *\n * @since 0.0.1\n */\n onAfterDestroy?: () => void\n\n /**\n * Callback fired when the editor becomes dirty (content differs from initial value)\n *\n * @since 0.0.1\n */\n onDirty?: () => void\n\n /**\n * Callback fired when a key is pressed in the editor\n *\n * @param event - The keyboard event\n * @param editor - The CKEditor instance\n * @since 0.0.1\n */\n onKeyDown?: (event: KeyboardEvent, editor: ClassicEditor) => void\n\n /**\n * Placeholder text shown when the editor is empty\n *\n * @since 1.0.0\n */\n placeholder?: string\n\n /**\n * TinyMCE init configuration. Merged with internal defaults; use this to\n * pass custom content_style, paste hooks, or other TinyMCE-specific options.\n * Has no effect when CKEditor is active.\n *\n * @since 1.0.0\n */\n init?: CoreTextEditorProps['init']\n\n /**\n * Number of rows to control the editor height. When set, the editor height\n * is fixed. When omitted, the editor grows with content.\n *\n * @since 1.0.0\n */\n rows?: number\n\n /**\n * Opt in to CKEditor immediately, bypassing the gradual feature flag rollout.\n * Use this only when you explicitly want to ignore the rollout schedule.\n * When enabled, the LaunchDarkly flag is bypassed and CKEditor is rendered directly.\n *\n * @since 1.0.0\n */\n enforceCKEditor?: true\n}\n\nexport type KeyDownListener = (\n event: EventInfo,\n data: { domEvent: Event }\n) => void\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function TextEditorI18nProvider({ children, }: Readonly<React.PropsWithChildren>): React.JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { useRequestTranslations } from '@procore/cdn-translations';
2
+ import { I18nProvider, useI18nContext } from '@procore/core-react';
3
+ import React from 'react';
4
+ import en from '../locales/en.json';
5
+ import pseudo from '../locales/pseudo.json';
6
+ export function TextEditorI18nProvider(_ref) {
7
+ var children = _ref.children;
8
+ var clientI18n = useI18nContext();
9
+ var cdnTranslations = useRequestTranslations({
10
+ locale: clientI18n.locale,
11
+ type: 'file',
12
+ absolute_file_path: function absolute_file_path(locale) {
13
+ return "core/packages/text-editor/src/locales/".concat(locale, ".json");
14
+ }
15
+ }, {
16
+ en: en,
17
+ pseudo: pseudo
18
+ }, {
19
+ oldTranslations: {},
20
+ enableCDN: true
21
+ });
22
+ return /*#__PURE__*/React.createElement(I18nProvider, {
23
+ locale: clientI18n.locale,
24
+ translations: cdnTranslations.translations
25
+ }, children);
26
+ }
27
+ //# sourceMappingURL=TextEditorI18nProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextEditorI18nProvider.js","names":["useRequestTranslations","I18nProvider","useI18nContext","React","en","pseudo","TextEditorI18nProvider","_ref","children","clientI18n","cdnTranslations","locale","type","absolute_file_path","concat","oldTranslations","enableCDN","createElement","translations"],"sources":["../../src/TextEditor/TextEditorI18nProvider.tsx"],"sourcesContent":["import { useRequestTranslations } from '@procore/cdn-translations'\nimport { I18nProvider, useI18nContext } from '@procore/core-react'\nimport React from 'react'\n\nimport en from '../locales/en.json'\nimport pseudo from '../locales/pseudo.json'\n\nexport function TextEditorI18nProvider({\n children,\n}: Readonly<React.PropsWithChildren>) {\n const clientI18n = useI18nContext()\n\n const cdnTranslations = useRequestTranslations(\n {\n locale: clientI18n.locale,\n type: 'file',\n absolute_file_path: (locale) =>\n `core/packages/text-editor/src/locales/${locale}.json`,\n },\n {\n en,\n pseudo,\n },\n {\n oldTranslations: {},\n enableCDN: true,\n }\n )\n\n return (\n <I18nProvider\n locale={clientI18n.locale}\n translations={cdnTranslations.translations}\n >\n {children}\n </I18nProvider>\n )\n}\n"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,2BAA2B;AAClE,SAASC,YAAY,EAAEC,cAAc,QAAQ,qBAAqB;AAClE,OAAOC,KAAK,MAAM,OAAO;AAEzB,OAAOC,EAAE,MAAM,oBAAoB;AACnC,OAAOC,MAAM,MAAM,wBAAwB;AAE3C,OAAO,SAASC,sBAAsBA,CAAAC,IAAA,EAEA;EAAA,IADpCC,QAAQ,GAAAD,IAAA,CAARC,QAAQ;EAER,IAAMC,UAAU,GAAGP,cAAc,CAAC,CAAC;EAEnC,IAAMQ,eAAe,GAAGV,sBAAsB,CAC5C;IACEW,MAAM,EAAEF,UAAU,CAACE,MAAM;IACzBC,IAAI,EAAE,MAAM;IACZC,kBAAkB,EAAE,SAApBA,kBAAkBA,CAAGF,MAAM;MAAA,gDAAAG,MAAA,CACgBH,MAAM;IAAA;EACnD,CAAC,EACD;IACEP,EAAE,EAAFA,EAAE;IACFC,MAAM,EAANA;EACF,CAAC,EACD;IACEU,eAAe,EAAE,CAAC,CAAC;IACnBC,SAAS,EAAE;EACb,CACF,CAAC;EAED,oBACEb,KAAA,CAAAc,aAAA,CAAChB,YAAY;IACXU,MAAM,EAAEF,UAAU,CAACE,MAAO;IAC1BO,YAAY,EAAER,eAAe,CAACQ;EAAa,GAE1CV,QACW,CAAC;AAEnB"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { TextEditorProps } from './TextEditor.types';
3
+ export declare const TinyMCETextEditor: (props: TextEditorProps) => React.JSX.Element;