payload-intl 1.3.2 → 1.4.1
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/README.md +23 -3
- package/dist/components/MessagesField.d.ts +12 -0
- package/dist/components/MessagesField.d.ts.map +1 -0
- package/dist/components/MessagesField.js +36 -0
- package/dist/components/MessagesField.js.map +1 -0
- package/dist/components/MessagesImport.d.ts +2 -0
- package/dist/components/MessagesImport.d.ts.map +1 -0
- package/dist/components/MessagesImport.js +68 -0
- package/dist/components/MessagesImport.js.map +1 -0
- package/dist/components/MessagesImport.module.css +8 -0
- package/dist/components/input/LexicalInput.d.ts +8 -0
- package/dist/components/input/LexicalInput.d.ts.map +1 -0
- package/dist/components/input/LexicalInput.js +21 -0
- package/dist/components/input/LexicalInput.js.map +1 -0
- package/dist/components/input/MessageInput.d.ts +12 -0
- package/dist/components/input/MessageInput.d.ts.map +1 -0
- package/dist/components/{inputs → input}/MessageInput.js +31 -39
- package/dist/components/input/MessageInput.js.map +1 -0
- package/dist/components/{inputs → input}/MessageInput.module.css +14 -19
- package/dist/components/{inputs → input}/ReferencePopover.d.ts +1 -1
- package/dist/components/input/ReferencePopover.d.ts.map +1 -0
- package/dist/components/{inputs → input}/ReferencePopover.js +11 -5
- package/dist/components/input/ReferencePopover.js.map +1 -0
- package/dist/components/input/SingleLinePlugin.d.ts.map +1 -0
- package/dist/components/input/SingleLinePlugin.js.map +1 -0
- package/dist/components/{hooks → input}/useHtmlLexicalAdapter.d.ts.map +1 -1
- package/dist/components/{hooks → input}/useHtmlLexicalAdapter.js.map +1 -1
- package/dist/{utils/format.d.ts → components/input/utils.d.ts} +2 -2
- package/dist/components/input/utils.d.ts.map +1 -0
- package/dist/{utils/format.js → components/input/utils.js} +2 -2
- package/dist/components/input/utils.js.map +1 -0
- package/dist/components/input/variables/VariableChip.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/VariableChip.js +1 -2
- package/dist/components/input/variables/VariableChip.js.map +1 -0
- package/dist/components/input/variables/VariableIcon.d.ts.map +1 -0
- package/dist/components/input/variables/VariableIcon.js.map +1 -0
- package/dist/components/input/variables/VariableNode.d.ts.map +1 -0
- package/dist/components/input/variables/VariableNode.js.map +1 -0
- package/dist/components/input/variables/VariableSuggestion.d.ts.map +1 -0
- package/dist/components/input/variables/VariableSuggestion.js.map +1 -0
- package/dist/components/input/variables/editors/PluralVariableEditor.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/editors/PluralVariableEditor.js +1 -1
- package/dist/components/input/variables/editors/PluralVariableEditor.js.map +1 -0
- package/dist/components/input/variables/editors/SelectVariableEditor.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/editors/SelectVariableEditor.js +1 -2
- package/dist/components/input/variables/editors/SelectVariableEditor.js.map +1 -0
- package/dist/components/input/variables/editors/TagVariableEditor.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/editors/TagVariableEditor.js +1 -2
- package/dist/components/input/variables/editors/TagVariableEditor.js.map +1 -0
- package/dist/components/input/variables/editors/TemporalVariableEditor.d.ts.map +1 -0
- package/dist/components/input/variables/editors/TemporalVariableEditor.js.map +1 -0
- package/dist/components/input/variables/pickers/NumericVariableEditor.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/pickers/NumericVariableEditor.js +1 -2
- package/dist/components/input/variables/pickers/NumericVariableEditor.js.map +1 -0
- package/dist/components/input/variables/pickers/TemporalVariablePicker.d.ts.map +1 -0
- package/dist/components/{inputs → input}/variables/pickers/TemporalVariablePicker.js +1 -2
- package/dist/components/input/variables/pickers/TemporalVariablePicker.js.map +1 -0
- package/dist/components/layout/MessageField.d.ts +5 -4
- package/dist/components/layout/MessageField.d.ts.map +1 -1
- package/dist/components/layout/MessageField.js +44 -51
- package/dist/components/layout/MessageField.js.map +1 -1
- package/dist/components/layout/MessageField.module.css +17 -5
- package/dist/components/layout/MessagesTabs.d.ts.map +1 -1
- package/dist/components/layout/MessagesTabs.js +9 -19
- package/dist/components/layout/MessagesTabs.js.map +1 -1
- package/dist/components/layout/MessagesTree.d.ts +7 -5
- package/dist/components/layout/MessagesTree.d.ts.map +1 -1
- package/dist/components/layout/MessagesTree.js +12 -22
- package/dist/components/layout/MessagesTree.js.map +1 -1
- package/dist/components/layout/MessagesTree.module.css +7 -3
- package/dist/{utils/config.d.ts → config.d.ts} +1 -1
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js.map +1 -0
- package/dist/const.d.ts +3 -9
- package/dist/const.d.ts.map +1 -1
- package/dist/const.js +3 -12
- package/dist/const.js.map +1 -1
- package/dist/exports/client.d.ts +3 -1
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +3 -1
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/fetchMessages.d.ts +4 -0
- package/dist/exports/fetchMessages.d.ts.map +1 -0
- package/dist/exports/fetchMessages.js +18 -0
- package/dist/exports/fetchMessages.js.map +1 -0
- package/dist/exports/rsc.d.ts +0 -2
- package/dist/exports/rsc.d.ts.map +1 -1
- package/dist/exports/rsc.js +0 -2
- package/dist/exports/rsc.js.map +1 -1
- package/dist/file-storage-hooks.d.ts +17 -0
- package/dist/file-storage-hooks.d.ts.map +1 -0
- package/dist/file-storage-hooks.js +37 -0
- package/dist/file-storage-hooks.js.map +1 -0
- package/dist/hooks.d.ts +19 -3
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +41 -20
- package/dist/hooks.js.map +1 -1
- package/dist/icu/guards.d.ts.map +1 -0
- package/dist/icu/guards.js.map +1 -0
- package/dist/icu/index.d.ts +6 -0
- package/dist/icu/index.d.ts.map +1 -0
- package/dist/icu/index.js +7 -0
- package/dist/icu/index.js.map +1 -0
- package/dist/{utils/icu-tranform.d.ts → icu/lexical.d.ts} +1 -10
- package/dist/icu/lexical.d.ts.map +1 -0
- package/dist/{utils/icu-tranform.js → icu/lexical.js} +4 -44
- package/dist/icu/lexical.js.map +1 -0
- package/dist/icu/schema.d.ts +4 -0
- package/dist/icu/schema.d.ts.map +1 -0
- package/dist/icu/schema.js +43 -0
- package/dist/icu/schema.js.map +1 -0
- package/dist/icu/serialize.d.ts +11 -0
- package/dist/icu/serialize.d.ts.map +1 -0
- package/dist/icu/serialize.js +45 -0
- package/dist/icu/serialize.js.map +1 -0
- package/dist/icu/validate.d.ts.map +1 -0
- package/dist/icu/validate.js.map +1 -0
- package/dist/index.d.ts +23 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +181 -37
- package/dist/index.js.map +1 -1
- package/dist/payload-types.d.ts +43 -16
- package/dist/payload-types.d.ts.map +1 -1
- package/dist/types.d.ts +24 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/file-storage.d.ts +26 -0
- package/dist/utils/file-storage.d.ts.map +1 -0
- package/dist/utils/file-storage.js +61 -0
- package/dist/utils/file-storage.js.map +1 -0
- package/dist/utils/sanitize.d.ts +5 -3
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/utils/sanitize.js +4 -2
- package/dist/utils/sanitize.js.map +1 -1
- package/dist/utils/schema.d.ts +5 -7
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +11 -39
- package/dist/utils/schema.js.map +1 -1
- package/dist/utils/scopes.d.ts +3 -0
- package/dist/utils/scopes.d.ts.map +1 -0
- package/dist/utils/scopes.js +24 -0
- package/dist/utils/scopes.js.map +1 -0
- package/package.json +14 -12
- package/dist/components/MessageFormField.d.ts +0 -14
- package/dist/components/MessageFormField.d.ts.map +0 -1
- package/dist/components/MessageFormField.js +0 -28
- package/dist/components/MessageFormField.js.map +0 -1
- package/dist/components/MessagesForm.d.ts +0 -13
- package/dist/components/MessagesForm.d.ts.map +0 -1
- package/dist/components/MessagesForm.js +0 -120
- package/dist/components/MessagesForm.js.map +0 -1
- package/dist/components/MessagesForm.module.css +0 -41
- package/dist/components/MessagesFormProvider.d.ts +0 -33
- package/dist/components/MessagesFormProvider.d.ts.map +0 -1
- package/dist/components/MessagesFormProvider.js +0 -34
- package/dist/components/MessagesFormProvider.js.map +0 -1
- package/dist/components/MessagesLink.d.ts +0 -8
- package/dist/components/MessagesLink.d.ts.map +0 -1
- package/dist/components/MessagesLink.js +0 -22
- package/dist/components/MessagesLink.js.map +0 -1
- package/dist/components/MessagesView.d.ts +0 -10
- package/dist/components/MessagesView.d.ts.map +0 -1
- package/dist/components/MessagesView.js +0 -57
- package/dist/components/MessagesView.js.map +0 -1
- package/dist/components/actions/CopyMessages.d.ts +0 -2
- package/dist/components/actions/CopyMessages.d.ts.map +0 -1
- package/dist/components/actions/CopyMessages.js +0 -41
- package/dist/components/actions/CopyMessages.js.map +0 -1
- package/dist/components/actions/CopyMessages.module.css +0 -8
- package/dist/components/actions/JsonImport.d.ts +0 -5
- package/dist/components/actions/JsonImport.d.ts.map +0 -1
- package/dist/components/actions/JsonImport.js +0 -52
- package/dist/components/actions/JsonImport.js.map +0 -1
- package/dist/components/actions/JsonImport.module.css +0 -14
- package/dist/components/hooks/useMessagesFormSubmit.d.ts +0 -11
- package/dist/components/hooks/useMessagesFormSubmit.d.ts.map +0 -1
- package/dist/components/hooks/useMessagesFormSubmit.js +0 -44
- package/dist/components/hooks/useMessagesFormSubmit.js.map +0 -1
- package/dist/components/inputs/FieldWrapper.d.ts +0 -8
- package/dist/components/inputs/FieldWrapper.d.ts.map +0 -1
- package/dist/components/inputs/FieldWrapper.js +0 -24
- package/dist/components/inputs/FieldWrapper.js.map +0 -1
- package/dist/components/inputs/FieldWrapper.module.css +0 -24
- package/dist/components/inputs/LexicalInput.d.ts +0 -9
- package/dist/components/inputs/LexicalInput.d.ts.map +0 -1
- package/dist/components/inputs/LexicalInput.js +0 -26
- package/dist/components/inputs/LexicalInput.js.map +0 -1
- package/dist/components/inputs/MessageInput.d.ts +0 -14
- package/dist/components/inputs/MessageInput.d.ts.map +0 -1
- package/dist/components/inputs/MessageInput.js.map +0 -1
- package/dist/components/inputs/ReferencePopover.d.ts.map +0 -1
- package/dist/components/inputs/ReferencePopover.js.map +0 -1
- package/dist/components/inputs/SingleLinePlugin.d.ts.map +0 -1
- package/dist/components/inputs/SingleLinePlugin.js.map +0 -1
- package/dist/components/inputs/variables/VariableChip.d.ts.map +0 -1
- package/dist/components/inputs/variables/VariableChip.js.map +0 -1
- package/dist/components/inputs/variables/VariableIcon.d.ts.map +0 -1
- package/dist/components/inputs/variables/VariableIcon.js.map +0 -1
- package/dist/components/inputs/variables/VariableNode.d.ts.map +0 -1
- package/dist/components/inputs/variables/VariableNode.js.map +0 -1
- package/dist/components/inputs/variables/VariableSuggestion.d.ts.map +0 -1
- package/dist/components/inputs/variables/VariableSuggestion.js.map +0 -1
- package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts.map +0 -1
- package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +0 -1
- package/dist/components/inputs/variables/editors/SelectVariableEditor.d.ts.map +0 -1
- package/dist/components/inputs/variables/editors/SelectVariableEditor.js.map +0 -1
- package/dist/components/inputs/variables/editors/TagVariableEditor.d.ts.map +0 -1
- package/dist/components/inputs/variables/editors/TagVariableEditor.js.map +0 -1
- package/dist/components/inputs/variables/editors/TemporalVariableEditor.d.ts.map +0 -1
- package/dist/components/inputs/variables/editors/TemporalVariableEditor.js.map +0 -1
- package/dist/components/inputs/variables/pickers/NumericVariableEditor.d.ts.map +0 -1
- package/dist/components/inputs/variables/pickers/NumericVariableEditor.js.map +0 -1
- package/dist/components/inputs/variables/pickers/TemporalVariablePicker.d.ts.map +0 -1
- package/dist/components/inputs/variables/pickers/TemporalVariablePicker.js.map +0 -1
- package/dist/components/layout/GroupStatusDot.d.ts +0 -6
- package/dist/components/layout/GroupStatusDot.d.ts.map +0 -1
- package/dist/components/layout/GroupStatusDot.js +0 -24
- package/dist/components/layout/GroupStatusDot.js.map +0 -1
- package/dist/components/layout/StatusDot.d.ts +0 -7
- package/dist/components/layout/StatusDot.d.ts.map +0 -1
- package/dist/components/layout/StatusDot.js +0 -12
- package/dist/components/layout/StatusDot.js.map +0 -1
- package/dist/components/layout/StatusDot.module.css +0 -16
- package/dist/endpoints/set-messages.d.ts +0 -3
- package/dist/endpoints/set-messages.d.ts.map +0 -1
- package/dist/endpoints/set-messages.js +0 -105
- package/dist/endpoints/set-messages.js.map +0 -1
- package/dist/entities.d.ts +0 -5
- package/dist/entities.d.ts.map +0 -1
- package/dist/entities.js +0 -42
- package/dist/entities.js.map +0 -1
- package/dist/requests/fetchMessages.d.ts +0 -3
- package/dist/requests/fetchMessages.d.ts.map +0 -1
- package/dist/requests/fetchMessages.js +0 -40
- package/dist/requests/fetchMessages.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/guards.d.ts.map +0 -1
- package/dist/utils/guards.js.map +0 -1
- package/dist/utils/icu-tranform.d.ts.map +0 -1
- package/dist/utils/icu-tranform.js.map +0 -1
- package/dist/utils/validate.d.ts.map +0 -1
- package/dist/utils/validate.js.map +0 -1
- /package/dist/components/{inputs → input}/ReferencePopover.module.css +0 -0
- /package/dist/components/{inputs → input}/SingleLinePlugin.d.ts +0 -0
- /package/dist/components/{inputs → input}/SingleLinePlugin.js +0 -0
- /package/dist/components/{hooks → input}/useHtmlLexicalAdapter.d.ts +0 -0
- /package/dist/components/{hooks → input}/useHtmlLexicalAdapter.js +0 -0
- /package/dist/components/{inputs → input}/variables/VariableChip.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/VariableChip.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/VariableIcon.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/VariableIcon.js +0 -0
- /package/dist/components/{inputs → input}/variables/VariableNode.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/VariableNode.js +0 -0
- /package/dist/components/{inputs → input}/variables/VariableSuggestion.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/VariableSuggestion.js +0 -0
- /package/dist/components/{inputs → input}/variables/VariableSuggestion.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/editors/PluralVariableEditor.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/editors/PluralVariableEditor.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/editors/SelectVariableEditor.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/editors/SelectVariableEditor.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/editors/TagVariableEditor.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/editors/TagVariableEditor.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/editors/TemporalVariableEditor.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/editors/TemporalVariableEditor.js +0 -0
- /package/dist/components/{inputs → input}/variables/pickers/NumericVariableEditor.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/pickers/NumericVariableEditor.module.css +0 -0
- /package/dist/components/{inputs → input}/variables/pickers/TemporalVariablePicker.d.ts +0 -0
- /package/dist/components/{inputs → input}/variables/pickers/TemporalVariablePicker.module.css +0 -0
- /package/dist/{utils/config.js → config.js} +0 -0
- /package/dist/{utils → icu}/guards.d.ts +0 -0
- /package/dist/{utils → icu}/guards.js +0 -0
- /package/dist/{utils → icu}/validate.d.ts +0 -0
- /package/dist/{utils → icu}/validate.js +0 -0
package/README.md
CHANGED
|
@@ -54,6 +54,25 @@ export default buildConfig({
|
|
|
54
54
|
});
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
#### Scoped messages on globals
|
|
58
|
+
|
|
59
|
+
Colocate translations with the globals they belong to by adding `scopes`:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
intlPlugin({
|
|
63
|
+
schema: {
|
|
64
|
+
navigation: { home: "Home", about: "About" },
|
|
65
|
+
common: { greeting: "Hello {name}!" },
|
|
66
|
+
},
|
|
67
|
+
scopes: ["navigation"],
|
|
68
|
+
// or with position control:
|
|
69
|
+
// scopes: { navigation: 'sidebar' }
|
|
70
|
+
// scopes: { navigation: { position: 'tab', existingFieldsTabLabel: 'Nav Fields' } }
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `navigation` key will be edited on the `navigation` global (in a Messages tab by default), while `common` stays in the `/intl` view.
|
|
75
|
+
|
|
57
76
|
Fetch messages in your application:
|
|
58
77
|
|
|
59
78
|
```ts
|
|
@@ -67,13 +86,14 @@ const messages = await fetchMessages(payload, "en");
|
|
|
67
86
|
| Option | Type | Default | Description |
|
|
68
87
|
| ---------------- | ------------------------------------------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
88
|
| `schema` | `MessagesSchema` | — | Required. Nested object defining message keys and ICU templates. Leaf values are ICU MessageFormat strings, optionally prefixed with a `[description]`. |
|
|
70
|
-
| `
|
|
89
|
+
| `storage` | `'db' \| 'upload'` | `'db'` | `'db'` stores translations as JSON in the database. `'upload'` stores them as uploaded `.json` files for CDN/static hosting. |
|
|
90
|
+
| `scopes` | `MessagesScopesConfig` | — | Colocate translation editing with Payload globals. Maps top-level schema keys to globals, adding a Messages tab or sidebar. Accepts an array of slugs or a record with position config. |
|
|
91
|
+
| `tabs` | `boolean` | `false` | When enabled, top-level schema keys are rendered as tabs in the admin UI. |
|
|
92
|
+
| `collectionSlug` | `string` | `'messages'` | Slug of the collection used to store translation documents. |
|
|
71
93
|
| `editorAccess` | `(req: PayloadRequest) => boolean \| Promise<boolean>` | `(req) => req.user !== null` | Access control function that determines who can edit messages. |
|
|
72
94
|
| `hooks` | `MessagesHooks` | `{}` | Collection hooks. Extends Payload's collection hooks with an additional `afterUpdate` callback fired when translations are saved. |
|
|
73
|
-
| `storage` | `'db' \| 'upload'` | `'db'` | `'db'` stores translations as JSON in the database. `'upload'` stores them as uploaded `.json` files for CDN/static hosting. |
|
|
74
95
|
|
|
75
96
|
> **Note:** Switching between storage strategies on an existing deployment is not yet supported automatically. When the database schema changes (e.g. dropping upload columns), the migration data is lost before the app can read it. A safe migration path will be provided in a future release. For now, export your translations before switching strategies.
|
|
76
|
-
| `tabs` | `boolean` | `false` | When enabled, top-level keys in the schema are rendered as tabs in the admin UI. |
|
|
77
97
|
|
|
78
98
|
## Contributing
|
|
79
99
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { JSONFieldClientProps } from 'payload';
|
|
2
|
+
import type { MessagesSchema } from '../types';
|
|
3
|
+
export interface MessagesFieldProps {
|
|
4
|
+
readonly schema: MessagesSchema;
|
|
5
|
+
readonly hiddenGroups?: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Payload JSON field client component that bridges the virtual `_intlMessages`
|
|
9
|
+
* field with the existing MessagesFormProvider / MessagesTree component tree.
|
|
10
|
+
*/
|
|
11
|
+
export declare function MessagesField({ schema, hiddenGroups, path, }: JSONFieldClientProps & MessagesFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=MessagesField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessagesField.d.ts","sourceRoot":"","sources":["../../src/components/MessagesField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGpD,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,SAAS,CAAC;AAGxD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,YAAY,EACZ,IAAI,GACL,EAAE,oBAAoB,GAAG,kBAAkB,2CAwB3C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useField } from '@payloadcms/ui';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import { useForm } from 'react-hook-form';
|
|
6
|
+
import { MessagesTree } from './layout/MessagesTree';
|
|
7
|
+
/**
|
|
8
|
+
* Payload JSON field client component that bridges the virtual `_intlMessages`
|
|
9
|
+
* field with the existing MessagesFormProvider / MessagesTree component tree.
|
|
10
|
+
*/ export function MessagesField({ schema, hiddenGroups, path }) {
|
|
11
|
+
const { value, setValue } = useField({
|
|
12
|
+
path
|
|
13
|
+
});
|
|
14
|
+
const form = useForm({
|
|
15
|
+
values: value,
|
|
16
|
+
reValidateMode: 'onBlur'
|
|
17
|
+
});
|
|
18
|
+
// When form values change, push back to Payload's field
|
|
19
|
+
useEffect(()=>{
|
|
20
|
+
const subscription = form.watch((formValues)=>{
|
|
21
|
+
setValue(formValues);
|
|
22
|
+
});
|
|
23
|
+
return ()=>subscription.unsubscribe();
|
|
24
|
+
}, [
|
|
25
|
+
form,
|
|
26
|
+
setValue
|
|
27
|
+
]);
|
|
28
|
+
return /*#__PURE__*/ _jsx(MessagesTree, {
|
|
29
|
+
control: form.control,
|
|
30
|
+
hiddenGroups: hiddenGroups,
|
|
31
|
+
path: "",
|
|
32
|
+
schema: schema
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=MessagesField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/MessagesField.tsx"],"sourcesContent":["'use client';\n\nimport { useField } from '@payloadcms/ui';\nimport type { JSONFieldClientProps } from 'payload';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport type { Messages, MessagesSchema } from '@/types';\nimport { MessagesTree } from './layout/MessagesTree';\n\nexport interface MessagesFieldProps {\n readonly schema: MessagesSchema;\n readonly hiddenGroups?: string[];\n}\n\n/**\n * Payload JSON field client component that bridges the virtual `_intlMessages`\n * field with the existing MessagesFormProvider / MessagesTree component tree.\n */\nexport function MessagesField({\n schema,\n hiddenGroups,\n path,\n}: JSONFieldClientProps & MessagesFieldProps) {\n const { value, setValue } = useField<Messages>({ path });\n\n const form = useForm<Messages>({\n values: value,\n reValidateMode: 'onBlur',\n });\n\n // When form values change, push back to Payload's field\n useEffect(() => {\n const subscription = form.watch((formValues) => {\n setValue(formValues);\n });\n return () => subscription.unsubscribe();\n }, [form, setValue]);\n\n return (\n <MessagesTree\n control={form.control}\n hiddenGroups={hiddenGroups}\n path=\"\"\n schema={schema}\n />\n );\n}\n"],"names":["useField","useEffect","useForm","MessagesTree","MessagesField","schema","hiddenGroups","path","value","setValue","form","values","reValidateMode","subscription","watch","formValues","unsubscribe","control"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,QAAQ,iBAAiB;AAE1C,SAASC,SAAS,QAAQ,QAAQ;AAClC,SAASC,OAAO,QAAQ,kBAAkB;AAE1C,SAASC,YAAY,QAAQ,wBAAwB;AAOrD;;;CAGC,GACD,OAAO,SAASC,cAAc,EAC5BC,MAAM,EACNC,YAAY,EACZC,IAAI,EACsC;IAC1C,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGT,SAAmB;QAAEO;IAAK;IAEtD,MAAMG,OAAOR,QAAkB;QAC7BS,QAAQH;QACRI,gBAAgB;IAClB;IAEA,wDAAwD;IACxDX,UAAU;QACR,MAAMY,eAAeH,KAAKI,KAAK,CAAC,CAACC;YAC/BN,SAASM;QACX;QACA,OAAO,IAAMF,aAAaG,WAAW;IACvC,GAAG;QAACN;QAAMD;KAAS;IAEnB,qBACE,KAACN;QACCc,SAASP,KAAKO,OAAO;QACrBX,cAAcA;QACdC,MAAK;QACLF,QAAQA;;AAGd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessagesImport.d.ts","sourceRoot":"","sources":["../../src/components/MessagesImport.tsx"],"names":[],"mappings":"AAOA,wBAAgB,cAAc,4CAiE7B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Button, Popup, useField } from '@payloadcms/ui';
|
|
4
|
+
import { useRef } from 'react';
|
|
5
|
+
import styles from './MessagesImport.module.css';
|
|
6
|
+
export function MessagesImport() {
|
|
7
|
+
const { setValue } = useField({
|
|
8
|
+
path: 'data'
|
|
9
|
+
});
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const handleImportFromFile = (event)=>{
|
|
12
|
+
const file = event.target.files?.[0];
|
|
13
|
+
if (!file) {
|
|
14
|
+
event.target.value = '';
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const reader = new FileReader();
|
|
18
|
+
reader.onload = (readerEvent)=>{
|
|
19
|
+
const text = readerEvent.target?.result;
|
|
20
|
+
const data = JSON.parse(text);
|
|
21
|
+
setValue(data);
|
|
22
|
+
// Clear the input value to allow re-selection of the same or different file
|
|
23
|
+
event.target.value = '';
|
|
24
|
+
};
|
|
25
|
+
reader.readAsText(file);
|
|
26
|
+
};
|
|
27
|
+
const handleImportFromURL = ()=>{
|
|
28
|
+
const url = prompt('Enter the URL of the JSON file to import:');
|
|
29
|
+
if (!url) return;
|
|
30
|
+
// TODO Validate URL
|
|
31
|
+
fetch(url).then((response)=>response.json()).then(setValue).catch((error)=>console.error('Error importing JSON:', error));
|
|
32
|
+
};
|
|
33
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
34
|
+
children: [
|
|
35
|
+
/*#__PURE__*/ _jsx("input", {
|
|
36
|
+
accept: ".json",
|
|
37
|
+
hidden: true,
|
|
38
|
+
onChange: handleImportFromFile,
|
|
39
|
+
ref: inputRef,
|
|
40
|
+
type: "file"
|
|
41
|
+
}),
|
|
42
|
+
/*#__PURE__*/ _jsx(Popup, {
|
|
43
|
+
button: "Import",
|
|
44
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
45
|
+
className: styles.popup,
|
|
46
|
+
children: [
|
|
47
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
48
|
+
buttonStyle: "subtle",
|
|
49
|
+
className: styles.action,
|
|
50
|
+
iconPosition: "left",
|
|
51
|
+
onClick: ()=>inputRef.current?.click(),
|
|
52
|
+
children: "Import from File"
|
|
53
|
+
}),
|
|
54
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
55
|
+
buttonStyle: "subtle",
|
|
56
|
+
className: styles.action,
|
|
57
|
+
iconPosition: "left",
|
|
58
|
+
onClick: handleImportFromURL,
|
|
59
|
+
children: "Import from URL"
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=MessagesImport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/MessagesImport.tsx"],"sourcesContent":["'use client';\n\nimport { Button, Popup, useField } from '@payloadcms/ui';\nimport { useRef } from 'react';\n\nimport styles from './MessagesImport.module.css';\n\nexport function MessagesImport() {\n const { setValue } = useField({ path: 'data' });\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleImportFromFile = (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!file) {\n event.target.value = '';\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (readerEvent) => {\n const text = readerEvent.target?.result as string;\n const data = JSON.parse(text);\n setValue(data);\n // Clear the input value to allow re-selection of the same or different file\n event.target.value = '';\n };\n reader.readAsText(file);\n };\n\n const handleImportFromURL = () => {\n const url = prompt('Enter the URL of the JSON file to import:');\n if (!url) return;\n\n // TODO Validate URL\n\n fetch(url)\n .then((response) => response.json())\n .then(setValue)\n .catch((error) => console.error('Error importing JSON:', error));\n };\n\n return (\n <>\n <input\n accept=\".json\"\n hidden\n onChange={handleImportFromFile}\n ref={inputRef}\n type=\"file\"\n />\n <Popup button=\"Import\">\n <div className={styles.popup}>\n <Button\n buttonStyle=\"subtle\"\n className={styles.action}\n iconPosition=\"left\"\n onClick={() => inputRef.current?.click()}\n >\n Import from File\n </Button>\n <Button\n buttonStyle=\"subtle\"\n className={styles.action}\n iconPosition=\"left\"\n onClick={handleImportFromURL}\n >\n Import from URL\n </Button>\n </div>\n </Popup>\n </>\n );\n}\n"],"names":["Button","Popup","useField","useRef","styles","MessagesImport","setValue","path","inputRef","handleImportFromFile","event","file","target","files","value","reader","FileReader","onload","readerEvent","text","result","data","JSON","parse","readAsText","handleImportFromURL","url","prompt","fetch","then","response","json","catch","error","console","input","accept","hidden","onChange","ref","type","button","div","className","popup","buttonStyle","action","iconPosition","onClick","current","click"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,KAAK,EAAEC,QAAQ,QAAQ,iBAAiB;AACzD,SAASC,MAAM,QAAQ,QAAQ;AAE/B,OAAOC,YAAY,8BAA8B;AAEjD,OAAO,SAASC;IACd,MAAM,EAAEC,QAAQ,EAAE,GAAGJ,SAAS;QAAEK,MAAM;IAAO;IAC7C,MAAMC,WAAWL,OAAyB;IAE1C,MAAMM,uBAAuB,CAACC;QAC5B,MAAMC,OAAOD,MAAME,MAAM,CAACC,KAAK,EAAE,CAAC,EAAE;QACpC,IAAI,CAACF,MAAM;YACTD,MAAME,MAAM,CAACE,KAAK,GAAG;YACrB;QACF;QAEA,MAAMC,SAAS,IAAIC;QACnBD,OAAOE,MAAM,GAAG,CAACC;YACf,MAAMC,OAAOD,YAAYN,MAAM,EAAEQ;YACjC,MAAMC,OAAOC,KAAKC,KAAK,CAACJ;YACxBb,SAASe;YACT,4EAA4E;YAC5EX,MAAME,MAAM,CAACE,KAAK,GAAG;QACvB;QACAC,OAAOS,UAAU,CAACb;IACpB;IAEA,MAAMc,sBAAsB;QAC1B,MAAMC,MAAMC,OAAO;QACnB,IAAI,CAACD,KAAK;QAEV,oBAAoB;QAEpBE,MAAMF,KACHG,IAAI,CAAC,CAACC,WAAaA,SAASC,IAAI,IAChCF,IAAI,CAACvB,UACL0B,KAAK,CAAC,CAACC,QAAUC,QAAQD,KAAK,CAAC,yBAAyBA;IAC7D;IAEA,qBACE;;0BACE,KAACE;gBACCC,QAAO;gBACPC,MAAM;gBACNC,UAAU7B;gBACV8B,KAAK/B;gBACLgC,MAAK;;0BAEP,KAACvC;gBAAMwC,QAAO;0BACZ,cAAA,MAACC;oBAAIC,WAAWvC,OAAOwC,KAAK;;sCAC1B,KAAC5C;4BACC6C,aAAY;4BACZF,WAAWvC,OAAO0C,MAAM;4BACxBC,cAAa;4BACbC,SAAS,IAAMxC,SAASyC,OAAO,EAAEC;sCAClC;;sCAGD,KAAClD;4BACC6C,aAAY;4BACZF,WAAWvC,OAAO0C,MAAM;4BACxBC,cAAa;4BACbC,SAASvB;sCACV;;;;;;;AAOX"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface LexicalInputProps {
|
|
2
|
+
lang: string;
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
onBlur: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function LexicalInput({ value, onChange, }: LexicalInputProps): React.ReactNode;
|
|
8
|
+
//# sourceMappingURL=LexicalInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LexicalInput.d.ts","sourceRoot":"","sources":["../../../src/components/input/LexicalInput.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,GACT,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAkBrC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { RenderLexical } from '@payloadcms/richtext-lexical/client';
|
|
3
|
+
import { useHtmlLexicalAdapter } from './useHtmlLexicalAdapter';
|
|
4
|
+
export function LexicalInput({ value, onChange }) {
|
|
5
|
+
const editor = useHtmlLexicalAdapter({
|
|
6
|
+
html: value,
|
|
7
|
+
onChange
|
|
8
|
+
});
|
|
9
|
+
return /*#__PURE__*/ _jsx(RenderLexical, {
|
|
10
|
+
field: {
|
|
11
|
+
name: 'myCustomEditor',
|
|
12
|
+
label: false,
|
|
13
|
+
type: 'richText'
|
|
14
|
+
},
|
|
15
|
+
schemaPath: "global.intl-plugin.editorTemplate",
|
|
16
|
+
setValue: (val)=>editor.setValue(val),
|
|
17
|
+
value: editor.value
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=LexicalInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/LexicalInput.tsx"],"sourcesContent":["import { RenderLexical } from '@payloadcms/richtext-lexical/client';\nimport type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { useHtmlLexicalAdapter } from './useHtmlLexicalAdapter';\n\nexport interface LexicalInputProps {\n lang: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nexport function LexicalInput({\n value,\n onChange,\n}: LexicalInputProps): React.ReactNode {\n const editor = useHtmlLexicalAdapter({\n html: value,\n onChange,\n });\n\n return (\n <RenderLexical\n field={{\n name: 'myCustomEditor',\n label: false,\n type: 'richText',\n }}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n value={editor.value}\n />\n );\n}\n"],"names":["RenderLexical","useHtmlLexicalAdapter","LexicalInput","value","onChange","editor","html","field","name","label","type","schemaPath","setValue","val"],"mappings":";AAAA,SAASA,aAAa,QAAQ,sCAAsC;AAEpE,SAASC,qBAAqB,QAAQ,0BAA0B;AAShE,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,QAAQ,EACU;IAClB,MAAMC,SAASJ,sBAAsB;QACnCK,MAAMH;QACNC;IACF;IAEA,qBACE,KAACJ;QACCO,OAAO;YACLC,MAAM;YACNC,OAAO;YACPC,MAAM;QACR;QACAC,YAAW;QACXC,UAAU,CAACC,MAAQR,OAAOO,QAAQ,CAACC;QACnCV,OAAOE,OAAOF,KAAK;;AAGzB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TemplateVariable } from '../../types';
|
|
2
|
+
export interface MessageInputProps {
|
|
3
|
+
value: string;
|
|
4
|
+
variables: TemplateVariable[];
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
onBlur: () => void;
|
|
7
|
+
readOnly?: boolean;
|
|
8
|
+
multiline?: boolean;
|
|
9
|
+
error?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function MessageInput({ value, variables, onChange, onBlur, multiline, error, }: MessageInputProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=MessageInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/input/MessageInput.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA2BhD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,iBAAiB,2CA0EnB"}
|
|
@@ -8,13 +8,10 @@ import { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react
|
|
|
8
8
|
import { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';
|
|
9
9
|
import { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';
|
|
10
10
|
import { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';
|
|
11
|
-
import clsx from 'clsx';
|
|
12
11
|
import { BeautifulMentionNode, BeautifulMentionsPlugin } from 'lexical-beautiful-mentions';
|
|
13
12
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
14
|
-
import { formatVariableLabel } from '../../utils
|
|
15
|
-
import { isTagElement } from '../../
|
|
16
|
-
import { parseIcuToLexicalState, serializeICUMessage } from '../../utils/icu-tranform';
|
|
17
|
-
import { FieldWrapper } from './FieldWrapper';
|
|
13
|
+
import { formatVariableLabel } from '../../components/input/utils';
|
|
14
|
+
import { isTagElement, parseIcuToLexicalState, serializeICUMessage } from '../../icu';
|
|
18
15
|
import styles from './MessageInput.module.css';
|
|
19
16
|
import { SingleLinePlugin } from './SingleLinePlugin';
|
|
20
17
|
import { VariableMentionNode } from './variables/VariableNode';
|
|
@@ -35,7 +32,7 @@ function SyncValuePlugin({ value }) {
|
|
|
35
32
|
]);
|
|
36
33
|
return null;
|
|
37
34
|
}
|
|
38
|
-
export function MessageInput({ value,
|
|
35
|
+
export function MessageInput({ value, variables, onChange, onBlur, multiline, error }) {
|
|
39
36
|
const handleChange = useCallback((editorState)=>{
|
|
40
37
|
editorState.read(()=>{
|
|
41
38
|
onChange($getRoot().getTextContent());
|
|
@@ -59,7 +56,6 @@ export function MessageInput({ value, lang, error, variables, onChange, onBlur,
|
|
|
59
56
|
}, [
|
|
60
57
|
variables
|
|
61
58
|
]);
|
|
62
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: LexicalComposer only reads initialConfig on mount
|
|
63
59
|
const initialConfig = useMemo(()=>({
|
|
64
60
|
namespace: 'ICUMessageEditor',
|
|
65
61
|
nodes: [
|
|
@@ -74,39 +70,35 @@ export function MessageInput({ value, lang, error, variables, onChange, onBlur,
|
|
|
74
70
|
editable: true,
|
|
75
71
|
onError: console.error
|
|
76
72
|
}), []);
|
|
77
|
-
return /*#__PURE__*/ _jsx(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
contentEditable: /*#__PURE__*/ _jsx(ContentEditable, {
|
|
89
|
-
className: clsx(styles.contentEditable, error && styles.contentEditableError),
|
|
90
|
-
onBlur: onBlur
|
|
91
|
-
}),
|
|
92
|
-
ErrorBoundary: LexicalErrorBoundary
|
|
73
|
+
return /*#__PURE__*/ _jsx(LexicalComposer, {
|
|
74
|
+
initialConfig: initialConfig,
|
|
75
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
76
|
+
className: styles.editor,
|
|
77
|
+
"data-multiline": multiline,
|
|
78
|
+
children: [
|
|
79
|
+
/*#__PURE__*/ _jsx(PlainTextPlugin, {
|
|
80
|
+
contentEditable: /*#__PURE__*/ _jsx(ContentEditable, {
|
|
81
|
+
className: styles.contentEditable,
|
|
82
|
+
"data-error": error,
|
|
83
|
+
onBlur: onBlur
|
|
93
84
|
}),
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
85
|
+
ErrorBoundary: LexicalErrorBoundary
|
|
86
|
+
}),
|
|
87
|
+
multiline && /*#__PURE__*/ _jsx(SingleLinePlugin, {}),
|
|
88
|
+
/*#__PURE__*/ _jsx(SyncValuePlugin, {
|
|
89
|
+
value: value
|
|
90
|
+
}),
|
|
91
|
+
/*#__PURE__*/ _jsx(OnChangePlugin, {
|
|
92
|
+
onChange: handleChange
|
|
93
|
+
}),
|
|
94
|
+
/*#__PURE__*/ _jsx(HistoryPlugin, {}),
|
|
95
|
+
/*#__PURE__*/ _jsx(BeautifulMentionsPlugin, {
|
|
96
|
+
items: mentionItems,
|
|
97
|
+
menuAnchorClassName: styles.menuAnchor,
|
|
98
|
+
menuComponent: MentionMenu,
|
|
99
|
+
menuItemComponent: MentionMenuItem
|
|
100
|
+
})
|
|
101
|
+
]
|
|
110
102
|
})
|
|
111
103
|
});
|
|
112
104
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/MessageInput.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { $getRoot } from '@payloadcms/richtext-lexical/lexical';\nimport { LexicalComposer } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposer';\nimport { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';\nimport { ContentEditable } from '@payloadcms/richtext-lexical/lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react/LexicalErrorBoundary';\nimport { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';\nimport { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';\nimport { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';\nimport {\n BeautifulMentionNode,\n BeautifulMentionsPlugin,\n} from 'lexical-beautiful-mentions';\nimport { useCallback, useEffect, useMemo } from 'react';\nimport { formatVariableLabel } from '@/components/input/utils';\nimport {\n isTagElement,\n parseIcuToLexicalState,\n serializeICUMessage,\n} from '@/icu';\nimport type { TemplateVariable } from '@/types';\n\nimport styles from './MessageInput.module.css';\nimport { SingleLinePlugin } from './SingleLinePlugin';\nimport { VariableMentionNode } from './variables/VariableNode';\nimport { MentionMenu, MentionMenuItem } from './variables/VariableSuggestion';\n\nfunction SyncValuePlugin({ value }: { value: string }) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const currentText = editor\n .getEditorState()\n .read(() => $getRoot().getTextContent());\n if (value !== currentText) {\n queueMicrotask(() => {\n const newState = editor.parseEditorState(\n JSON.stringify(parseIcuToLexicalState(value)),\n );\n editor.setEditorState(newState);\n });\n }\n }, [value, editor]);\n\n return null;\n}\n\nexport interface MessageInputProps {\n value: string;\n variables: TemplateVariable[];\n onChange: (value: string) => void;\n onBlur: () => void;\n readOnly?: boolean;\n multiline?: boolean;\n error?: boolean;\n}\n\nexport function MessageInput({\n value,\n variables,\n onChange,\n onBlur,\n multiline,\n error,\n}: MessageInputProps) {\n const handleChange = useCallback(\n (editorState: EditorState) => {\n editorState.read(() => {\n onChange($getRoot().getTextContent());\n });\n },\n [onChange],\n );\n\n const mentionItems = useMemo(() => {\n const toItem = (v: TemplateVariable) => ({\n value: v.value,\n label: formatVariableLabel(v),\n icu: serializeICUMessage([v]),\n });\n\n return {\n '@': variables.map(toItem),\n '{': variables.filter((v) => !isTagElement(v)).map(toItem),\n '<': variables.filter((v) => isTagElement(v)).map(toItem),\n };\n }, [variables]);\n\n const initialConfig = useMemo(\n () => ({\n namespace: 'ICUMessageEditor',\n nodes: [\n VariableMentionNode,\n {\n replace: BeautifulMentionNode,\n with: (node: BeautifulMentionNode) =>\n new VariableMentionNode(\n node.getTrigger(),\n node.getValue(),\n node.getData(),\n ),\n withKlass: VariableMentionNode,\n },\n ],\n editorState: JSON.stringify(parseIcuToLexicalState(value)),\n editable: true,\n onError: console.error,\n }),\n [],\n );\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <div className={styles.editor} data-multiline={multiline}>\n <PlainTextPlugin\n contentEditable={\n <ContentEditable\n className={styles.contentEditable}\n data-error={error}\n onBlur={onBlur}\n />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n {multiline && <SingleLinePlugin />}\n <SyncValuePlugin value={value} />\n <OnChangePlugin onChange={handleChange} />\n <HistoryPlugin />\n\n <BeautifulMentionsPlugin\n items={mentionItems}\n menuAnchorClassName={styles.menuAnchor}\n menuComponent={MentionMenu}\n menuItemComponent={MentionMenuItem}\n />\n </div>\n </LexicalComposer>\n );\n}\n"],"names":["$getRoot","LexicalComposer","useLexicalComposerContext","ContentEditable","LexicalErrorBoundary","HistoryPlugin","OnChangePlugin","PlainTextPlugin","BeautifulMentionNode","BeautifulMentionsPlugin","useCallback","useEffect","useMemo","formatVariableLabel","isTagElement","parseIcuToLexicalState","serializeICUMessage","styles","SingleLinePlugin","VariableMentionNode","MentionMenu","MentionMenuItem","SyncValuePlugin","value","editor","currentText","getEditorState","read","getTextContent","queueMicrotask","newState","parseEditorState","JSON","stringify","setEditorState","MessageInput","variables","onChange","onBlur","multiline","error","handleChange","editorState","mentionItems","toItem","v","label","icu","map","filter","initialConfig","namespace","nodes","replace","with","node","getTrigger","getValue","getData","withKlass","editable","onError","console","div","className","data-multiline","contentEditable","data-error","ErrorBoundary","items","menuAnchorClassName","menuAnchor","menuComponent","menuItemComponent"],"mappings":"AAAA;;AAGA,SAASA,QAAQ,QAAQ,uCAAuC;AAChE,SAASC,eAAe,QAAQ,6DAA6D;AAC7F,SAASC,yBAAyB,QAAQ,oEAAoE;AAC9G,SAASC,eAAe,QAAQ,oEAAoE;AACpG,SAASC,oBAAoB,QAAQ,kEAAkE;AACvG,SAASC,aAAa,QAAQ,kEAAkE;AAChG,SAASC,cAAc,QAAQ,mEAAmE;AAClG,SAASC,eAAe,QAAQ,oEAAoE;AACpG,SACEC,oBAAoB,EACpBC,uBAAuB,QAClB,6BAA6B;AACpC,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,QAAQ,QAAQ;AACxD,SAASC,mBAAmB,QAAQ,2BAA2B;AAC/D,SACEC,YAAY,EACZC,sBAAsB,EACtBC,mBAAmB,QACd,QAAQ;AAGf,OAAOC,YAAY,4BAA4B;AAC/C,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,mBAAmB,QAAQ,2BAA2B;AAC/D,SAASC,WAAW,EAAEC,eAAe,QAAQ,iCAAiC;AAE9E,SAASC,gBAAgB,EAAEC,KAAK,EAAqB;IACnD,MAAM,CAACC,OAAO,GAAGtB;IAEjBS,UAAU;QACR,MAAMc,cAAcD,OACjBE,cAAc,GACdC,IAAI,CAAC,IAAM3B,WAAW4B,cAAc;QACvC,IAAIL,UAAUE,aAAa;YACzBI,eAAe;gBACb,MAAMC,WAAWN,OAAOO,gBAAgB,CACtCC,KAAKC,SAAS,CAAClB,uBAAuBQ;gBAExCC,OAAOU,cAAc,CAACJ;YACxB;QACF;IACF,GAAG;QAACP;QAAOC;KAAO;IAElB,OAAO;AACT;AAYA,OAAO,SAASW,aAAa,EAC3BZ,KAAK,EACLa,SAAS,EACTC,QAAQ,EACRC,MAAM,EACNC,SAAS,EACTC,KAAK,EACa;IAClB,MAAMC,eAAe/B,YACnB,CAACgC;QACCA,YAAYf,IAAI,CAAC;YACfU,SAASrC,WAAW4B,cAAc;QACpC;IACF,GACA;QAACS;KAAS;IAGZ,MAAMM,eAAe/B,QAAQ;QAC3B,MAAMgC,SAAS,CAACC,IAAyB,CAAA;gBACvCtB,OAAOsB,EAAEtB,KAAK;gBACduB,OAAOjC,oBAAoBgC;gBAC3BE,KAAK/B,oBAAoB;oBAAC6B;iBAAE;YAC9B,CAAA;QAEA,OAAO;YACL,KAAKT,UAAUY,GAAG,CAACJ;YACnB,KAAKR,UAAUa,MAAM,CAAC,CAACJ,IAAM,CAAC/B,aAAa+B,IAAIG,GAAG,CAACJ;YACnD,KAAKR,UAAUa,MAAM,CAAC,CAACJ,IAAM/B,aAAa+B,IAAIG,GAAG,CAACJ;QACpD;IACF,GAAG;QAACR;KAAU;IAEd,MAAMc,gBAAgBtC,QACpB,IAAO,CAAA;YACLuC,WAAW;YACXC,OAAO;gBACLjC;gBACA;oBACEkC,SAAS7C;oBACT8C,MAAM,CAACC,OACL,IAAIpC,oBACFoC,KAAKC,UAAU,IACfD,KAAKE,QAAQ,IACbF,KAAKG,OAAO;oBAEhBC,WAAWxC;gBACb;aACD;YACDuB,aAAaV,KAAKC,SAAS,CAAClB,uBAAuBQ;YACnDqC,UAAU;YACVC,SAASC,QAAQtB,KAAK;QACxB,CAAA,GACA,EAAE;IAGJ,qBACE,KAACvC;QAAgBiD,eAAeA;kBAC9B,cAAA,MAACa;YAAIC,WAAW/C,OAAOO,MAAM;YAAEyC,kBAAgB1B;;8BAC7C,KAAChC;oBACC2D,+BACE,KAAC/D;wBACC6D,WAAW/C,OAAOiD,eAAe;wBACjCC,cAAY3B;wBACZF,QAAQA;;oBAGZ8B,eAAehE;;gBAEhBmC,2BAAa,KAACrB;8BACf,KAACI;oBAAgBC,OAAOA;;8BACxB,KAACjB;oBAAe+B,UAAUI;;8BAC1B,KAACpC;8BAED,KAACI;oBACC4D,OAAO1B;oBACP2B,qBAAqBrD,OAAOsD,UAAU;oBACtCC,eAAepD;oBACfqD,mBAAmBpD;;;;;AAK7B"}
|
|
@@ -4,15 +4,10 @@
|
|
|
4
4
|
align-items: center;
|
|
5
5
|
min-height: 2rem;
|
|
6
6
|
font-size: var(--font-size-large);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.readOnly {
|
|
10
|
-
opacity: 0.7;
|
|
11
|
-
cursor: default;
|
|
12
|
-
}
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
&[data-multiline="true"] {
|
|
9
|
+
min-height: 4rem;
|
|
10
|
+
}
|
|
16
11
|
}
|
|
17
12
|
|
|
18
13
|
.menuAnchor {
|
|
@@ -27,18 +22,18 @@
|
|
|
27
22
|
padding-block: 0.25rem;
|
|
28
23
|
padding-inline: 0.75rem;
|
|
29
24
|
height: 100%;
|
|
30
|
-
}
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
26
|
+
&:focus {
|
|
27
|
+
outline: none;
|
|
28
|
+
border-color: var(--theme-elevation-600);
|
|
29
|
+
}
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
31
|
+
&[data-error="true"] {
|
|
32
|
+
border-color: var(--theme-error-400);
|
|
33
|
+
background-color: var(--theme-error-100);
|
|
34
|
+
}
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
p {
|
|
37
|
+
margin: 0;
|
|
38
|
+
}
|
|
44
39
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReferencePopover.d.ts","sourceRoot":"","sources":["../../../src/components/input/ReferencePopover.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,OAAO,CAAC;AAIlD,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,GACT,EAAE,qBAAqB,2CAQvB"}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Popover } from '@base-ui/react/popover';
|
|
3
3
|
import { IconX } from '@tabler/icons-react';
|
|
4
|
+
import { useRef } from 'react';
|
|
4
5
|
import styles from './ReferencePopover.module.css';
|
|
5
6
|
export function ReferencePopover({ reference, children }) {
|
|
6
7
|
if (!reference) return children;
|
|
8
|
+
return /*#__PURE__*/ _jsx(ControlledReferencePopover, {
|
|
9
|
+
reference: reference,
|
|
10
|
+
children: children
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function ControlledReferencePopover({ reference, children }) {
|
|
14
|
+
const anchorRef = useRef(null);
|
|
7
15
|
return /*#__PURE__*/ _jsxs(Popover.Root, {
|
|
8
16
|
children: [
|
|
9
|
-
/*#__PURE__*/ _jsx(Popover.Trigger, {
|
|
10
|
-
nativeButton: false,
|
|
11
|
-
render: children
|
|
12
|
-
}),
|
|
13
17
|
/*#__PURE__*/ _jsx(Popover.Portal, {
|
|
14
18
|
children: /*#__PURE__*/ _jsx(Popover.Positioner, {
|
|
15
19
|
align: "start",
|
|
20
|
+
anchor: anchorRef,
|
|
16
21
|
side: "top",
|
|
17
22
|
sideOffset: 4,
|
|
18
23
|
children: /*#__PURE__*/ _jsxs(Popover.Popup, {
|
|
@@ -34,7 +39,8 @@ export function ReferencePopover({ reference, children }) {
|
|
|
34
39
|
]
|
|
35
40
|
})
|
|
36
41
|
})
|
|
37
|
-
})
|
|
42
|
+
}),
|
|
43
|
+
children
|
|
38
44
|
]
|
|
39
45
|
});
|
|
40
46
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/ReferencePopover.tsx"],"sourcesContent":["import { Popover } from '@base-ui/react/popover';\n\nimport { IconX } from '@tabler/icons-react';\nimport { type ReactElement, useRef } from 'react';\n\nimport styles from './ReferencePopover.module.css';\n\nexport interface ReferencePopoverProps {\n reference?: string;\n children: ReactElement;\n}\n\nexport function ReferencePopover({\n reference,\n children,\n}: ReferencePopoverProps) {\n if (!reference) return children;\n\n return (\n <ControlledReferencePopover reference={reference}>\n {children}\n </ControlledReferencePopover>\n );\n}\n\nfunction ControlledReferencePopover({\n reference,\n children,\n}: {\n reference: string;\n children: ReactElement;\n}) {\n const anchorRef = useRef<HTMLElement>(null);\n\n return (\n <Popover.Root>\n <Popover.Portal>\n <Popover.Positioner\n align=\"start\"\n anchor={anchorRef}\n side=\"top\"\n sideOffset={4}\n >\n <Popover.Popup\n className={styles.popup}\n initialFocus={false}\n onMouseDown={(e) => e.preventDefault()}\n >\n <Popover.Close className={styles.dismiss} type=\"button\">\n <IconX size={14} />\n </Popover.Close>\n <p className={styles.text}>{reference}</p>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n {children}\n </Popover.Root>\n );\n}\n"],"names":["Popover","IconX","useRef","styles","ReferencePopover","reference","children","ControlledReferencePopover","anchorRef","Root","Portal","Positioner","align","anchor","side","sideOffset","Popup","className","popup","initialFocus","onMouseDown","e","preventDefault","Close","dismiss","type","size","p","text"],"mappings":";AAAA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,KAAK,QAAQ,sBAAsB;AAC5C,SAA4BC,MAAM,QAAQ,QAAQ;AAElD,OAAOC,YAAY,gCAAgC;AAOnD,OAAO,SAASC,iBAAiB,EAC/BC,SAAS,EACTC,QAAQ,EACc;IACtB,IAAI,CAACD,WAAW,OAAOC;IAEvB,qBACE,KAACC;QAA2BF,WAAWA;kBACpCC;;AAGP;AAEA,SAASC,2BAA2B,EAClCF,SAAS,EACTC,QAAQ,EAIT;IACC,MAAME,YAAYN,OAAoB;IAEtC,qBACE,MAACF,QAAQS,IAAI;;0BACX,KAACT,QAAQU,MAAM;0BACb,cAAA,KAACV,QAAQW,UAAU;oBACjBC,OAAM;oBACNC,QAAQL;oBACRM,MAAK;oBACLC,YAAY;8BAEZ,cAAA,MAACf,QAAQgB,KAAK;wBACZC,WAAWd,OAAOe,KAAK;wBACvBC,cAAc;wBACdC,aAAa,CAACC,IAAMA,EAAEC,cAAc;;0CAEpC,KAACtB,QAAQuB,KAAK;gCAACN,WAAWd,OAAOqB,OAAO;gCAAEC,MAAK;0CAC7C,cAAA,KAACxB;oCAAMyB,MAAM;;;0CAEf,KAACC;gCAAEV,WAAWd,OAAOyB,IAAI;0CAAGvB;;;;;;YAIjCC;;;AAGP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SingleLinePlugin.d.ts","sourceRoot":"","sources":["../../../src/components/input/SingleLinePlugin.tsx"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,SA2B/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/SingleLinePlugin.tsx"],"sourcesContent":["import {\n COMMAND_PRIORITY_HIGH,\n INSERT_LINE_BREAK_COMMAND,\n INSERT_PARAGRAPH_COMMAND,\n LineBreakNode,\n} from '@payloadcms/richtext-lexical/lexical';\nimport { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';\nimport { useEffect } from 'react';\n\nexport function SingleLinePlugin() {\n const [editor] = useLexicalComposerContext();\n useEffect(() => {\n const unregisterLineBreak = editor.registerCommand(\n INSERT_LINE_BREAK_COMMAND,\n () => true,\n COMMAND_PRIORITY_HIGH,\n );\n const unregisterParagraph = editor.registerCommand(\n INSERT_PARAGRAPH_COMMAND,\n () => true,\n COMMAND_PRIORITY_HIGH,\n );\n // Catch line breaks inserted via paste or other means\n const unregisterTransform = editor.registerNodeTransform(\n LineBreakNode,\n (node) => {\n node.remove();\n },\n );\n return () => {\n unregisterLineBreak();\n unregisterParagraph();\n unregisterTransform();\n };\n }, [editor]);\n return null;\n}\n"],"names":["COMMAND_PRIORITY_HIGH","INSERT_LINE_BREAK_COMMAND","INSERT_PARAGRAPH_COMMAND","LineBreakNode","useLexicalComposerContext","useEffect","SingleLinePlugin","editor","unregisterLineBreak","registerCommand","unregisterParagraph","unregisterTransform","registerNodeTransform","node","remove"],"mappings":"AAAA,SACEA,qBAAqB,EACrBC,yBAAyB,EACzBC,wBAAwB,EACxBC,aAAa,QACR,uCAAuC;AAC9C,SAASC,yBAAyB,QAAQ,oEAAoE;AAC9G,SAASC,SAAS,QAAQ,QAAQ;AAElC,OAAO,SAASC;IACd,MAAM,CAACC,OAAO,GAAGH;IACjBC,UAAU;QACR,MAAMG,sBAAsBD,OAAOE,eAAe,CAChDR,2BACA,IAAM,MACND;QAEF,MAAMU,sBAAsBH,OAAOE,eAAe,CAChDP,0BACA,IAAM,MACNF;QAEF,sDAAsD;QACtD,MAAMW,sBAAsBJ,OAAOK,qBAAqB,CACtDT,eACA,CAACU;YACCA,KAAKC,MAAM;QACb;QAEF,OAAO;YACLN;YACAE;YACAC;QACF;IACF,GAAG;QAACJ;KAAO;IACX,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHtmlLexicalAdapter.d.ts","sourceRoot":"","sources":["../../../src/components/
|
|
1
|
+
{"version":3,"file":"useHtmlLexicalAdapter.d.ts","sourceRoot":"","sources":["../../../src/components/input/useHtmlLexicalAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAUtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAWlF,UAAU,0BAA0B;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,QAAQ,GACT,EAAE,0BAA0B;WAiEF,gBAAgB,CAAC,gBAAgB,CAAC;gCAjBvC,qBAAqB;EAkB1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/useHtmlLexicalAdapter.ts"],"sourcesContent":["import type {\n DefaultNodeTypes,\n TypedEditorState,\n} from '@payloadcms/richtext-lexical';\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from '@payloadcms/richtext-lexical';\nimport {\n buildDefaultEditorState,\n getEnabledNodes,\n sanitizeClientEditorConfig,\n} from '@payloadcms/richtext-lexical/client';\nimport type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { $getRoot } from '@payloadcms/richtext-lexical/lexical';\nimport { createHeadlessEditor } from '@payloadcms/richtext-lexical/lexical/headless';\nimport {\n $generateHtmlFromNodes,\n $generateNodesFromDOM,\n} from '@payloadcms/richtext-lexical/lexical/html';\nimport { useCallback, useMemo, useRef } from 'react';\n\nconst EMPTY_STATE = buildDefaultEditorState({});\n\ninterface UseHtmlLexicalAdapterProps {\n html: string;\n onChange: (html: string) => void;\n}\n\nexport function useHtmlLexicalAdapter({\n html,\n onChange,\n}: UseHtmlLexicalAdapterProps) {\n // 1. Maintain a persistent headless editor for conversion\n const headlessEditor = useRef(\n createHeadlessEditor({\n nodes: getEnabledNodes({\n editorConfig: sanitizeClientEditorConfig(\n // @ts-expect-error - FIXME\n defaultEditorFeatures,\n defaultEditorConfig,\n ),\n }),\n }),\n );\n\n // 2. HTML -> SerializedState\n const getSerializedState = useCallback(\n (htmlString: string): SerializedEditorState => {\n const editor = headlessEditor.current;\n editor.update(\n () => {\n const parser = new DOMParser();\n const dom = parser.parseFromString(htmlString, 'text/html');\n const nodes = $generateNodesFromDOM(editor, dom);\n\n const root = $getRoot();\n root.clear().append(...nodes);\n },\n { discrete: true },\n );\n\n return editor.getEditorState().toJSON();\n },\n [],\n );\n\n // 3. Memoize the initial value to prevent unnecessary re-renders\n const value = useMemo(() => {\n const serializedState = getSerializedState(html);\n\n if (serializedState.root.children.length === 0) {\n return EMPTY_STATE;\n }\n\n return serializedState;\n }, [html, getSerializedState]);\n\n // 4. SerializedState -> HTML\n const setValue = useCallback(\n (serializedState: SerializedEditorState) => {\n const editor = headlessEditor.current;\n\n // Update headless editor to match the incoming state\n editor.setEditorState(editor.parseEditorState(serializedState));\n\n // Generate HTML and broadcast if it has changed\n editor.read(() => {\n const newHtml = $generateHtmlFromNodes(editor);\n if (newHtml !== html) {\n onChange(newHtml);\n }\n });\n },\n [html, onChange],\n );\n\n return { value: value as TypedEditorState<DefaultNodeTypes>, setValue };\n}\n"],"names":["defaultEditorConfig","defaultEditorFeatures","buildDefaultEditorState","getEnabledNodes","sanitizeClientEditorConfig","$getRoot","createHeadlessEditor","$generateHtmlFromNodes","$generateNodesFromDOM","useCallback","useMemo","useRef","EMPTY_STATE","useHtmlLexicalAdapter","html","onChange","headlessEditor","nodes","editorConfig","getSerializedState","htmlString","editor","current","update","parser","DOMParser","dom","parseFromString","root","clear","append","discrete","getEditorState","toJSON","value","serializedState","children","length","setValue","setEditorState","parseEditorState","read","newHtml"],"mappings":"AAIA,SACEA,mBAAmB,EACnBC,qBAAqB,QAChB,+BAA+B;AACtC,SACEC,uBAAuB,EACvBC,eAAe,EACfC,0BAA0B,QACrB,sCAAsC;AAE7C,SAASC,QAAQ,QAAQ,uCAAuC;AAChE,SAASC,oBAAoB,QAAQ,gDAAgD;AACrF,SACEC,sBAAsB,EACtBC,qBAAqB,QAChB,4CAA4C;AACnD,SAASC,WAAW,EAAEC,OAAO,EAAEC,MAAM,QAAQ,QAAQ;AAErD,MAAMC,cAAcV,wBAAwB,CAAC;AAO7C,OAAO,SAASW,sBAAsB,EACpCC,IAAI,EACJC,QAAQ,EACmB;IAC3B,0DAA0D;IAC1D,MAAMC,iBAAiBL,OACrBL,qBAAqB;QACnBW,OAAOd,gBAAgB;YACrBe,cAAcd,2BACZ,2BAA2B;YAC3BH,uBACAD;QAEJ;IACF;IAGF,6BAA6B;IAC7B,MAAMmB,qBAAqBV,YACzB,CAACW;QACC,MAAMC,SAASL,eAAeM,OAAO;QACrCD,OAAOE,MAAM,CACX;YACE,MAAMC,SAAS,IAAIC;YACnB,MAAMC,MAAMF,OAAOG,eAAe,CAACP,YAAY;YAC/C,MAAMH,QAAQT,sBAAsBa,QAAQK;YAE5C,MAAME,OAAOvB;YACbuB,KAAKC,KAAK,GAAGC,MAAM,IAAIb;QACzB,GACA;YAAEc,UAAU;QAAK;QAGnB,OAAOV,OAAOW,cAAc,GAAGC,MAAM;IACvC,GACA,EAAE;IAGJ,iEAAiE;IACjE,MAAMC,QAAQxB,QAAQ;QACpB,MAAMyB,kBAAkBhB,mBAAmBL;QAE3C,IAAIqB,gBAAgBP,IAAI,CAACQ,QAAQ,CAACC,MAAM,KAAK,GAAG;YAC9C,OAAOzB;QACT;QAEA,OAAOuB;IACT,GAAG;QAACrB;QAAMK;KAAmB;IAE7B,6BAA6B;IAC7B,MAAMmB,WAAW7B,YACf,CAAC0B;QACC,MAAMd,SAASL,eAAeM,OAAO;QAErC,qDAAqD;QACrDD,OAAOkB,cAAc,CAAClB,OAAOmB,gBAAgB,CAACL;QAE9C,gDAAgD;QAChDd,OAAOoB,IAAI,CAAC;YACV,MAAMC,UAAUnC,uBAAuBc;YACvC,IAAIqB,YAAY5B,MAAM;gBACpBC,SAAS2B;YACX;QACF;IACF,GACA;QAAC5B;QAAMC;KAAS;IAGlB,OAAO;QAAEmB,OAAOA;QAA6CI;IAAS;AACxE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TemplateVariable } from '
|
|
1
|
+
import type { TemplateVariable } from '../../types';
|
|
2
2
|
export declare const toWords: (inputString: string, joinWords?: boolean) => string;
|
|
3
3
|
export declare const formatVariableLabel: (variable: TemplateVariable) => string;
|
|
4
|
-
//# sourceMappingURL=
|
|
4
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/input/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,eAAO,MAAM,OAAO,gBAAiB,MAAM,0BAAsB,MAkBhE,CAAC;AAEF,eAAO,MAAM,mBAAmB,aAAc,gBAAgB,WAK7D,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isTagElement } from '
|
|
1
|
+
import { isTagElement } from '../../icu';
|
|
2
2
|
export const toWords = (inputString, joinWords = false)=>{
|
|
3
3
|
const capitalizeFirstLetter = (string)=>string.charAt(0).toUpperCase() + string.slice(1);
|
|
4
4
|
const notNullString = inputString || '';
|
|
@@ -20,4 +20,4 @@ export const formatVariableLabel = (variable)=>{
|
|
|
20
20
|
return variable.value;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
//# sourceMappingURL=
|
|
23
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/input/utils.ts"],"sourcesContent":["import { isTagElement } from '@/icu';\nimport type { TemplateVariable } from '@/types';\n\nexport const toWords = (inputString: string, joinWords = false): string => {\n const capitalizeFirstLetter = (string: string): string =>\n string.charAt(0).toUpperCase() + string.slice(1);\n const notNullString = inputString || '';\n const trimmedString = notNullString.trim();\n const arrayOfStrings = trimmedString.split(/[\\s-]/);\n\n const splitStringsArray: string[] = [];\n arrayOfStrings.forEach((tempString) => {\n if (tempString !== '') {\n const splitWords = tempString.split(/(?=[A-Z])/).join(' ');\n splitStringsArray.push(capitalizeFirstLetter(splitWords));\n }\n });\n\n return joinWords\n ? splitStringsArray.join('').replace(/\\s/g, '')\n : splitStringsArray.join(' ');\n};\n\nexport const formatVariableLabel = (variable: TemplateVariable) => {\n if (isTagElement(variable)) {\n return `<${variable.value}/>`;\n }\n return variable.value;\n};\n"],"names":["isTagElement","toWords","inputString","joinWords","capitalizeFirstLetter","string","charAt","toUpperCase","slice","notNullString","trimmedString","trim","arrayOfStrings","split","splitStringsArray","forEach","tempString","splitWords","join","push","replace","formatVariableLabel","variable","value"],"mappings":"AAAA,SAASA,YAAY,QAAQ,QAAQ;AAGrC,OAAO,MAAMC,UAAU,CAACC,aAAqBC,YAAY,KAAK;IAC5D,MAAMC,wBAAwB,CAACC,SAC7BA,OAAOC,MAAM,CAAC,GAAGC,WAAW,KAAKF,OAAOG,KAAK,CAAC;IAChD,MAAMC,gBAAgBP,eAAe;IACrC,MAAMQ,gBAAgBD,cAAcE,IAAI;IACxC,MAAMC,iBAAiBF,cAAcG,KAAK,CAAC;IAE3C,MAAMC,oBAA8B,EAAE;IACtCF,eAAeG,OAAO,CAAC,CAACC;QACtB,IAAIA,eAAe,IAAI;YACrB,MAAMC,aAAaD,WAAWH,KAAK,CAAC,aAAaK,IAAI,CAAC;YACtDJ,kBAAkBK,IAAI,CAACf,sBAAsBa;QAC/C;IACF;IAEA,OAAOd,YACHW,kBAAkBI,IAAI,CAAC,IAAIE,OAAO,CAAC,OAAO,MAC1CN,kBAAkBI,IAAI,CAAC;AAC7B,EAAE;AAEF,OAAO,MAAMG,sBAAsB,CAACC;IAClC,IAAItB,aAAasB,WAAW;QAC1B,OAAO,CAAC,CAAC,EAAEA,SAASC,KAAK,CAAC,EAAE,CAAC;IAC/B;IACA,OAAOD,SAASC,KAAK;AACvB,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariableChip.d.ts","sourceRoot":"","sources":["../../../../src/components/input/variables/VariableChip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAwBpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,iBAAiB,2CAqE5E"}
|
|
@@ -5,8 +5,7 @@ import { $getNodeByKey } from '@payloadcms/richtext-lexical/lexical';
|
|
|
5
5
|
import { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
|
-
import { isArgumentElement, isNumericElement, isSelectElement, isTagElement, isTemporalElement } from '../../../
|
|
9
|
-
import { parseICUMessage } from '../../../utils/icu-tranform';
|
|
8
|
+
import { isArgumentElement, isNumericElement, isSelectElement, isTagElement, isTemporalElement, parseICUMessage } from '../../../icu';
|
|
10
9
|
import { SelectVariableEditor } from './editors/SelectVariableEditor';
|
|
11
10
|
import { TagVariableEditor } from './editors/TagVariableEditor';
|
|
12
11
|
import { NumericVariableEditor } from './pickers/NumericVariableEditor';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/input/variables/VariableChip.tsx"],"sourcesContent":["'use client';\n\nimport { Popover } from '@base-ui/react/popover';\nimport type { NodeKey } from '@payloadcms/richtext-lexical/lexical';\nimport { $getNodeByKey } from '@payloadcms/richtext-lexical/lexical';\nimport { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';\nimport clsx from 'clsx';\nimport type { BeautifulMentionNode } from 'lexical-beautiful-mentions';\nimport { useMemo } from 'react';\n\nimport {\n isArgumentElement,\n isNumericElement,\n isSelectElement,\n isTagElement,\n isTemporalElement,\n parseICUMessage,\n} from '@/icu';\n\nimport { SelectVariableEditor } from './editors/SelectVariableEditor';\nimport { TagVariableEditor } from './editors/TagVariableEditor';\nimport { NumericVariableEditor } from './pickers/NumericVariableEditor';\nimport { TemporalVariablePicker } from './pickers/TemporalVariablePicker';\nimport styles from './VariableChip.module.css';\n\nconst TEMPORAL_ELEMENTS_FLAG = false;\n\nexport interface VariableChipProps {\n name: string;\n label: string;\n icu: string;\n nodeKey: NodeKey;\n}\n\n// TODO replace popover with portal below input field\n\nexport function VariableChip({ name, label, icu, nodeKey }: VariableChipProps) {\n const [editor] = useLexicalComposerContext();\n\n const handleUpdate = (value: string) => {\n editor.update(() => {\n const node = $getNodeByKey(nodeKey) as BeautifulMentionNode | null;\n if (node) {\n node.setData({ ...node.getData(), icu: value });\n }\n });\n };\n\n const element = useMemo(() => {\n try {\n const [part] = parseICUMessage(icu);\n if (!part) throw new Error('No part found');\n return part;\n } catch (error) {\n console.error(error);\n throw new Error(`Invalid ICU: ${icu}`, { cause: error });\n }\n }, [icu]);\n\n const isDisabled =\n isArgumentElement(element) ||\n (isTemporalElement(element) && !TEMPORAL_ELEMENTS_FLAG);\n\n return (\n <Popover.Root>\n <Popover.Trigger\n render={\n <button\n className={clsx(styles.chip, isDisabled && styles.chipDisabled)}\n data-icu={icu}\n data-variable={name}\n type=\"button\"\n />\n }\n >\n {/* <VariableIcon type={element.type} className=\"size-4\" /> */}\n {label}\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner align=\"start\" side=\"bottom\" sideOffset={5}>\n <Popover.Popup className={styles.popoverContent}>\n {isNumericElement(element) && (\n <NumericVariableEditor\n element={element}\n onUpdate={handleUpdate}\n />\n )}\n {isSelectElement(element) && (\n <SelectVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n {TEMPORAL_ELEMENTS_FLAG && isTemporalElement(element) && (\n <TemporalVariablePicker\n element={element}\n onUpdate={handleUpdate}\n />\n )}\n\n {isTagElement(element) && (\n <TagVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"names":["Popover","$getNodeByKey","useLexicalComposerContext","clsx","useMemo","isArgumentElement","isNumericElement","isSelectElement","isTagElement","isTemporalElement","parseICUMessage","SelectVariableEditor","TagVariableEditor","NumericVariableEditor","TemporalVariablePicker","styles","TEMPORAL_ELEMENTS_FLAG","VariableChip","name","label","icu","nodeKey","editor","handleUpdate","value","update","node","setData","getData","element","part","Error","error","console","cause","isDisabled","Root","Trigger","render","button","className","chip","chipDisabled","data-icu","data-variable","type","Portal","Positioner","align","side","sideOffset","Popup","popoverContent","onUpdate"],"mappings":"AAAA;;AAEA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,aAAa,QAAQ,uCAAuC;AACrE,SAASC,yBAAyB,QAAQ,oEAAoE;AAC9G,OAAOC,UAAU,OAAO;AAExB,SAASC,OAAO,QAAQ,QAAQ;AAEhC,SACEC,iBAAiB,EACjBC,gBAAgB,EAChBC,eAAe,EACfC,YAAY,EACZC,iBAAiB,EACjBC,eAAe,QACV,QAAQ;AAEf,SAASC,oBAAoB,QAAQ,iCAAiC;AACtE,SAASC,iBAAiB,QAAQ,8BAA8B;AAChE,SAASC,qBAAqB,QAAQ,kCAAkC;AACxE,SAASC,sBAAsB,QAAQ,mCAAmC;AAC1E,OAAOC,YAAY,4BAA4B;AAE/C,MAAMC,yBAAyB;AAS/B,qDAAqD;AAErD,OAAO,SAASC,aAAa,EAAEC,IAAI,EAAEC,KAAK,EAAEC,GAAG,EAAEC,OAAO,EAAqB;IAC3E,MAAM,CAACC,OAAO,GAAGpB;IAEjB,MAAMqB,eAAe,CAACC;QACpBF,OAAOG,MAAM,CAAC;YACZ,MAAMC,OAAOzB,cAAcoB;YAC3B,IAAIK,MAAM;gBACRA,KAAKC,OAAO,CAAC;oBAAE,GAAGD,KAAKE,OAAO,EAAE;oBAAER,KAAKI;gBAAM;YAC/C;QACF;IACF;IAEA,MAAMK,UAAUzB,QAAQ;QACtB,IAAI;YACF,MAAM,CAAC0B,KAAK,GAAGpB,gBAAgBU;YAC/B,IAAI,CAACU,MAAM,MAAM,IAAIC,MAAM;YAC3B,OAAOD;QACT,EAAE,OAAOE,OAAO;YACdC,QAAQD,KAAK,CAACA;YACd,MAAM,IAAID,MAAM,CAAC,aAAa,EAAEX,KAAK,EAAE;gBAAEc,OAAOF;YAAM;QACxD;IACF,GAAG;QAACZ;KAAI;IAER,MAAMe,aACJ9B,kBAAkBwB,YACjBpB,kBAAkBoB,YAAY,CAACb;IAElC,qBACE,MAAChB,QAAQoC,IAAI;;0BACX,KAACpC,QAAQqC,OAAO;gBACdC,sBACE,KAACC;oBACCC,WAAWrC,KAAKY,OAAO0B,IAAI,EAAEN,cAAcpB,OAAO2B,YAAY;oBAC9DC,YAAUvB;oBACVwB,iBAAe1B;oBACf2B,MAAK;;0BAKR1B;;0BAEH,KAACnB,QAAQ8C,MAAM;0BACb,cAAA,KAAC9C,QAAQ+C,UAAU;oBAACC,OAAM;oBAAQC,MAAK;oBAASC,YAAY;8BAC1D,cAAA,MAAClD,QAAQmD,KAAK;wBAACX,WAAWzB,OAAOqC,cAAc;;4BAC5C9C,iBAAiBuB,0BAChB,KAAChB;gCACCgB,SAASA;gCACTwB,UAAU9B;;4BAGbhB,gBAAgBsB,0BACf,KAAClB;gCAAqBkB,SAASA;gCAASwB,UAAU9B;;4BAEnDP,0BAA0BP,kBAAkBoB,0BAC3C,KAACf;gCACCe,SAASA;gCACTwB,UAAU9B;;4BAIbf,aAAaqB,0BACZ,KAACjB;gCAAkBiB,SAASA;gCAASwB,UAAU9B;;;;;;;;AAO7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariableIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/input/variables/VariableIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AASrD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC;IAChE,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,kDAmBjE"}
|