payload-intl 0.0.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -27
- package/dist/components/MessageController.js +11 -11
- package/dist/components/MessageController.js.map +1 -1
- package/dist/components/MessagesForm.d.ts +2 -3
- package/dist/components/MessagesForm.js +75 -84
- package/dist/components/MessagesForm.js.map +1 -1
- package/dist/components/inputs/LexicalInput.d.ts +8 -0
- package/dist/components/inputs/LexicalInput.js +60 -0
- package/dist/components/inputs/LexicalInput.js.map +1 -0
- package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -1
- package/dist/components/inputs/variables/editors/SelectVariableEditor.js.map +1 -1
- package/dist/components/inputs/variables/editors/TagVariableEditor.js.map +1 -1
- package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +1 -1
- package/dist/components/layout/MessageField.js.map +1 -1
- package/dist/components/layout/MessagesTree.js.map +1 -1
- package/dist/context/messages-form.d.ts +2 -4
- package/dist/context/messages-form.js +10 -11
- package/dist/context/messages-form.js.map +1 -1
- package/dist/exports/view.d.ts +2 -3
- package/dist/exports/view.js +21 -23
- package/dist/exports/view.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -17
- package/dist/index.js.map +1 -1
- package/dist/requests/fetchMessages.js +7 -9
- package/dist/requests/fetchMessages.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +0 -8
- package/dist/utils/schema.js.map +1 -1
- package/dist/utils/validate.d.ts +1 -1
- package/dist/utils/validate.js.map +1 -1
- package/package.json +36 -34
- package/dist/components/inputs/RichTextInput.d.ts +0 -8
- package/dist/components/inputs/RichTextInput.js +0 -85
- package/dist/components/inputs/RichTextInput.js.map +0 -1
- package/dist/components/inputs/toolbar/AlignmentControls.d.ts +0 -5
- package/dist/components/inputs/toolbar/AlignmentControls.js +0 -62
- package/dist/components/inputs/toolbar/AlignmentControls.js.map +0 -1
- package/dist/components/inputs/toolbar/BlockElementSelect.d.ts +0 -5
- package/dist/components/inputs/toolbar/BlockElementSelect.js +0 -135
- package/dist/components/inputs/toolbar/BlockElementSelect.js.map +0 -1
- package/dist/components/inputs/toolbar/LinkEditor.d.ts +0 -58
- package/dist/components/inputs/toolbar/LinkEditor.js +0 -242
- package/dist/components/inputs/toolbar/LinkEditor.js.map +0 -1
- package/dist/components/inputs/toolbar/MarkControls.d.ts +0 -5
- package/dist/components/inputs/toolbar/MarkControls.js +0 -48
- package/dist/components/inputs/toolbar/MarkControls.js.map +0 -1
- package/dist/components/inputs/toolbar/RichTextToolbar.d.ts +0 -6
- package/dist/components/inputs/toolbar/RichTextToolbar.js +0 -35
- package/dist/components/inputs/toolbar/RichTextToolbar.js.map +0 -1
package/dist/utils/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sources":["../../src/utils/schema.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../src/utils/schema.ts"],"sourcesContent":["import type { MessageSchema, TemplateVariable } from \"@/types\";\nimport type { MessageFormatElement } from \"@formatjs/icu-messageformat-parser\";\nimport { parse, TYPE } from \"@formatjs/icu-messageformat-parser\";\n\nexport const parseMessageSchema = (schema: MessageSchema): MessageConfig => {\n const description = schema.match(/^\\[.+\\]/)?.[0];\n // TODO add support for variables description\n // const withoutDescription = schema.replace(description || \"\", \"\").trim();\n // const withoutOptional = withoutDescription.split(\" | \")[0]?.trim();\n\n return {\n description: description?.slice(1, -1),\n type: schema === \"$RICH$\" ? \"rich\" : \"icu\",\n variables: extractTemplateVariables(schema),\n };\n};\n\nexport const extractTemplateVariables = (\n schema: MessageSchema,\n): TemplateVariable[] => collectTemplateVariables(parse(schema));\n\nconst collectTemplateVariables = (\n parts: MessageFormatElement[],\n): TemplateVariable[] =>\n parts.flatMap<TemplateVariable>((part) => {\n switch (part.type) {\n case TYPE.literal:\n case TYPE.pound:\n return [];\n case TYPE.argument:\n case TYPE.number:\n case TYPE.date:\n case TYPE.time:\n return [part];\n case TYPE.plural:\n case TYPE.select:\n return [\n part,\n ...collectTemplateVariables(\n Object.values(part.options).flatMap(({ value }) => value),\n ),\n ];\n case TYPE.tag:\n return [part, ...collectTemplateVariables(part.children)];\n default:\n return [part];\n }\n });\n\n// MARK: Types\n\nexport type MessageType = \"rich\" | \"icu\";\nexport type MessageConfig = {\n description: string | undefined;\n type: MessageType;\n variables: TemplateVariable[];\n};\n"],"names":["parseMessageSchema","schema","extractTemplateVariables","collectTemplateVariables","parse","parts","part","TYPE","value"],"mappings":";AAIO,MAAMA,IAAqB,CAACC,OAM1B;AAAA,EACL,aANkBA,EAAO,MAAM,SAAS,IAAI,CAAC,GAMnB,MAAM,GAAG,EAAE;AAAA,EACrC,MAAMA,MAAW,WAAW,SAAS;AAAA,EACrC,WAAWC,EAAyBD,CAAM;AAAA,IAIjCC,IAA2B,CACtCD,MACuBE,EAAyBC,EAAMH,CAAM,CAAC,GAEzDE,IAA2B,CAC/BE,MAEAA,EAAM,QAA0B,CAACC,MAAS;AACxC,UAAQA,EAAK,MAAA;AAAA,IACX,KAAKC,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO,CAAA;AAAA,IACT,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO,CAACD,CAAI;AAAA,IACd,KAAKC,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO;AAAA,QACLD;AAAA,QACA,GAAGH;AAAA,UACD,OAAO,OAAOG,EAAK,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAAE,EAAA,MAAYA,CAAK;AAAA,QAAA;AAAA,MAC1D;AAAA,IAEJ,KAAKD,EAAK;AACR,aAAO,CAACD,GAAM,GAAGH,EAAyBG,EAAK,QAAQ,CAAC;AAAA,IAC1D;AACE,aAAO,CAACA,CAAI;AAAA,EAAA;AAElB,CAAC;"}
|
package/dist/utils/validate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ValidateResult } from 'react-hook-form';
|
|
2
1
|
import { TemplateVariable } from '../types.ts';
|
|
2
|
+
import { ValidateResult } from 'react-hook-form';
|
|
3
3
|
export declare const validateMessage: (value: unknown, variables: TemplateVariable[]) => ValidateResult;
|
|
4
4
|
export declare const createValidator: (variables: TemplateVariable[]) => MessageValidator;
|
|
5
5
|
export type MessageValidator = (value: unknown) => ValidateResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sources":["../../src/utils/validate.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"validate.js","sources":["../../src/utils/validate.ts"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\nimport type { ValidateResult } from \"react-hook-form\";\nimport { TYPE } from \"@formatjs/icu-messageformat-parser\";\n\nimport { isNumericElement, isTemporalElement } from \"./guards\";\nimport { extractTemplateVariables } from \"./schema\";\n\nexport const validateMessage = (\n value: unknown,\n variables: TemplateVariable[],\n): ValidateResult => {\n if (typeof value !== \"string\") return \"Invalid value\";\n\n try {\n const variableUsages = extractTemplateVariables(value);\n\n for (const allowedVariable of variables) {\n const variableUsage = variableUsages.find(\n (placeholder) => placeholder.value === allowedVariable.value,\n );\n\n if (!variableUsage) continue;\n\n if (isNumericElement(allowedVariable)) {\n if (isNumericElement(variableUsage)) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n\n if (isTemporalElement(allowedVariable)) {\n if (isTemporalElement(variableUsage)) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n\n switch (allowedVariable.type) {\n case TYPE.argument:\n if (variableUsage.type === TYPE.argument) continue;\n return `{${allowedVariable.value}} has invalid type`;\n case TYPE.select: {\n if (variableUsage.type !== TYPE.select)\n return `{${allowedVariable.value}} has invalid type`;\n\n const allowedOptions = Object.keys(allowedVariable.options);\n for (const option of allowedOptions) {\n if (variableUsage.options[option]) continue;\n return `{${allowedVariable.value}} has missing option: ${option}`;\n }\n const usedOptions = Object.keys(variableUsage.options);\n for (const option of usedOptions) {\n if (allowedOptions.includes(option)) continue;\n return `{${allowedVariable.value}} has unsupported option: ${option}`;\n }\n continue;\n }\n case TYPE.tag:\n if (variableUsage.type === TYPE.tag) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n }\n\n const supportedVariables = new Set(variables.map(({ value }) => value));\n\n for (const variableUsage of variableUsages) {\n if (supportedVariables.has(variableUsage.value)) continue;\n return `{${variableUsage.value}} is not supported`;\n }\n\n return true;\n } catch (error) {\n if (!(error instanceof Error)) return false;\n return `Invalid syntax: ${error.message}`;\n }\n};\n\nexport const createValidator =\n (variables: TemplateVariable[]): MessageValidator =>\n (value: unknown) =>\n validateMessage(value, variables);\n\nexport type MessageValidator = (value: unknown) => ValidateResult;\n"],"names":["validateMessage","value","variables","variableUsages","extractTemplateVariables","allowedVariable","variableUsage","placeholder","isNumericElement","isTemporalElement","TYPE","allowedOptions","option","usedOptions","supportedVariables","error","createValidator"],"mappings":";;;AAOO,MAAMA,IAAkB,CAC7BC,GACAC,MACmB;AACnB,MAAI,OAAOD,KAAU,SAAU,QAAO;AAEtC,MAAI;AACF,UAAME,IAAiBC,EAAyBH,CAAK;AAErD,eAAWI,KAAmBH,GAAW;AACvC,YAAMI,IAAgBH,EAAe;AAAA,QACnC,CAACI,MAAgBA,EAAY,UAAUF,EAAgB;AAAA,MAAA;AAGzD,UAAKC,GAEL;AAAA,YAAIE,EAAiBH,CAAe,GAAG;AACrC,cAAIG,EAAiBF,CAAa,EAAG;AACrC,iBAAO,IAAID,EAAgB,KAAK;AAAA,QAClC;AAEA,YAAII,EAAkBJ,CAAe,GAAG;AACtC,cAAII,EAAkBH,CAAa,EAAG;AACtC,iBAAO,IAAID,EAAgB,KAAK;AAAA,QAClC;AAEA,gBAAQA,EAAgB,MAAA;AAAA,UACtB,KAAKK,EAAK;AACR,gBAAIJ,EAAc,SAASI,EAAK,SAAU;AAC1C,mBAAO,IAAIL,EAAgB,KAAK;AAAA,UAClC,KAAKK,EAAK,QAAQ;AAChB,gBAAIJ,EAAc,SAASI,EAAK;AAC9B,qBAAO,IAAIL,EAAgB,KAAK;AAElC,kBAAMM,IAAiB,OAAO,KAAKN,EAAgB,OAAO;AAC1D,uBAAWO,KAAUD;AACnB,kBAAI,CAAAL,EAAc,QAAQM,CAAM;AAChC,uBAAO,IAAIP,EAAgB,KAAK,yBAAyBO,CAAM;AAEjE,kBAAMC,IAAc,OAAO,KAAKP,EAAc,OAAO;AACrD,uBAAWM,KAAUC;AACnB,kBAAI,CAAAF,EAAe,SAASC,CAAM;AAClC,uBAAO,IAAIP,EAAgB,KAAK,6BAA6BO,CAAM;AAErE;AAAA,UACF;AAAA,UACA,KAAKF,EAAK;AACR,gBAAIJ,EAAc,SAASI,EAAK,IAAK;AACrC,mBAAO,IAAIL,EAAgB,KAAK;AAAA,QAAA;AAAA;AAAA,IAEtC;AAEA,UAAMS,IAAqB,IAAI,IAAIZ,EAAU,IAAI,CAAC,EAAE,OAAAD,QAAYA,CAAK,CAAC;AAEtE,eAAWK,KAAiBH;AAC1B,UAAI,CAAAW,EAAmB,IAAIR,EAAc,KAAK;AAC9C,eAAO,IAAIA,EAAc,KAAK;AAGhC,WAAO;AAAA,EACT,SAASS,GAAO;AACd,WAAMA,aAAiB,QAChB,mBAAmBA,EAAM,OAAO,KADD;AAAA,EAExC;AACF,GAEaC,IACX,CAACd,MACD,CAACD,MACCD,EAAgBC,GAAOC,CAAS;"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload-intl",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Payload Plugin for I18N using ICU Messages",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"author": "Michael Zeltner",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"payload",
|
|
9
|
+
"intl",
|
|
10
|
+
"i18n",
|
|
11
|
+
"internationalization",
|
|
12
|
+
"localization",
|
|
13
|
+
"react",
|
|
14
|
+
"next.js",
|
|
15
|
+
"translation",
|
|
16
|
+
"translations",
|
|
17
|
+
"icu"
|
|
18
|
+
],
|
|
6
19
|
"type": "module",
|
|
7
20
|
"exports": {
|
|
8
21
|
".": {
|
|
@@ -25,16 +38,17 @@
|
|
|
25
38
|
"devDependencies": {
|
|
26
39
|
"@eslint/eslintrc": "^3.2.0",
|
|
27
40
|
"@ianvs/prettier-plugin-sort-imports": "^4.5.1",
|
|
28
|
-
"@
|
|
29
|
-
"@payloadcms/
|
|
30
|
-
"@payloadcms/
|
|
31
|
-
"@payloadcms/
|
|
32
|
-
"@payloadcms/
|
|
33
|
-
"@payloadcms/
|
|
41
|
+
"@lexical/html": "*",
|
|
42
|
+
"@payloadcms/db-postgres": "3.72.0",
|
|
43
|
+
"@payloadcms/eslint-config": "3.28.0",
|
|
44
|
+
"@payloadcms/next": "3.72.0",
|
|
45
|
+
"@payloadcms/richtext-lexical": "3.72.0",
|
|
46
|
+
"@payloadcms/storage-uploadthing": "3.72.0",
|
|
47
|
+
"@payloadcms/ui": "3.72.0",
|
|
34
48
|
"@playwright/test": "^1.52.0",
|
|
35
49
|
"@tailwindcss/typography": "^0.5.16",
|
|
36
50
|
"@tailwindcss/vite": "^4.1.11",
|
|
37
|
-
"@tiptap/suggestion": "^3.0
|
|
51
|
+
"@tiptap/suggestion": "^3.16.0",
|
|
38
52
|
"@types/lodash-es": "^4.17.12",
|
|
39
53
|
"@types/node": "^22.5.4",
|
|
40
54
|
"@types/react": "19.1.0",
|
|
@@ -44,10 +58,10 @@
|
|
|
44
58
|
"eslint": "^9.23.0",
|
|
45
59
|
"eslint-config-next": "15.3.0",
|
|
46
60
|
"graphql": "^16.8.1",
|
|
47
|
-
"next": "15.
|
|
61
|
+
"next": "15.5.9",
|
|
48
62
|
"next-intl": "^4.3.4",
|
|
49
63
|
"open": "^10.1.0",
|
|
50
|
-
"payload": "3.
|
|
64
|
+
"payload": "3.72.0",
|
|
51
65
|
"prettier": "^3.4.2",
|
|
52
66
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
|
53
67
|
"react": "19.1.0",
|
|
@@ -64,10 +78,11 @@
|
|
|
64
78
|
"vitest": "^3.1.2"
|
|
65
79
|
},
|
|
66
80
|
"peerDependencies": {
|
|
67
|
-
"@
|
|
68
|
-
"@payloadcms/
|
|
81
|
+
"@lexical/html": "*",
|
|
82
|
+
"@payloadcms/next": ">=3.72.0",
|
|
83
|
+
"@payloadcms/ui": ">=3.72.0",
|
|
69
84
|
"next": ">=15.2.3",
|
|
70
|
-
"payload": ">=3.
|
|
85
|
+
"payload": ">=3.72.0"
|
|
71
86
|
},
|
|
72
87
|
"engines": {
|
|
73
88
|
"node": "^18.20.2 || >=20.9.0",
|
|
@@ -83,27 +98,14 @@
|
|
|
83
98
|
"@radix-ui/react-select": "^2.2.5",
|
|
84
99
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
|
85
100
|
"@radix-ui/react-toolbar": "^1.1.10",
|
|
86
|
-
"@tabler/icons-react": "^3.
|
|
87
|
-
"@tiptap/
|
|
88
|
-
"@tiptap/extension-
|
|
89
|
-
"@tiptap/extension-
|
|
90
|
-
"@tiptap/extension-
|
|
91
|
-
"@tiptap/extension-
|
|
92
|
-
"@tiptap/
|
|
93
|
-
"@tiptap/
|
|
94
|
-
"@tiptap/extension-horizontal-rule": "^3.0.9",
|
|
95
|
-
"@tiptap/extension-italic": "^3.0.9",
|
|
96
|
-
"@tiptap/extension-link": "^3.0.9",
|
|
97
|
-
"@tiptap/extension-list": "^3.0.9",
|
|
98
|
-
"@tiptap/extension-mention": "^3.0.9",
|
|
99
|
-
"@tiptap/extension-paragraph": "^3.0.9",
|
|
100
|
-
"@tiptap/extension-strike": "^3.0.9",
|
|
101
|
-
"@tiptap/extension-text": "^3.0.9",
|
|
102
|
-
"@tiptap/extension-text-align": "^3.0.9",
|
|
103
|
-
"@tiptap/extension-typography": "^3.0.9",
|
|
104
|
-
"@tiptap/extension-underline": "^3.0.9",
|
|
105
|
-
"@tiptap/extensions": "^3.0.9",
|
|
106
|
-
"@tiptap/react": "^3.0.9",
|
|
101
|
+
"@tabler/icons-react": "^3.36.1",
|
|
102
|
+
"@tiptap/core": "^3.16.0",
|
|
103
|
+
"@tiptap/extension-document": "^3.16.0",
|
|
104
|
+
"@tiptap/extension-mention": "^3.16.0",
|
|
105
|
+
"@tiptap/extension-paragraph": "^3.16.0",
|
|
106
|
+
"@tiptap/extension-text": "^3.16.0",
|
|
107
|
+
"@tiptap/pm": "^3.16.0",
|
|
108
|
+
"@tiptap/react": "^3.16.0",
|
|
107
109
|
"clsx": "^2.1.1",
|
|
108
110
|
"lodash-es": "^4.17.21",
|
|
109
111
|
"radix-ui": "^1.4.2",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { InputWrapperProps } from './InputWrapper';
|
|
2
|
-
export interface RichTextInputProps extends InputWrapperProps {
|
|
3
|
-
value: string;
|
|
4
|
-
lang: string;
|
|
5
|
-
onChange: (value: string) => void;
|
|
6
|
-
onBlur: () => void;
|
|
7
|
-
}
|
|
8
|
-
export declare function RichTextInput({ error, label, lang, onBlur, onChange, value, className, }: RichTextInputProps): React.ReactNode;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { jsxs as s, jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import d from "@tiptap/extension-blockquote";
|
|
3
|
-
import c from "@tiptap/extension-bold";
|
|
4
|
-
import g from "@tiptap/extension-code-block";
|
|
5
|
-
import u from "@tiptap/extension-document";
|
|
6
|
-
import h from "@tiptap/extension-hard-break";
|
|
7
|
-
import x from "@tiptap/extension-heading";
|
|
8
|
-
import T from "@tiptap/extension-highlight";
|
|
9
|
-
import k from "@tiptap/extension-horizontal-rule";
|
|
10
|
-
import L from "@tiptap/extension-italic";
|
|
11
|
-
import y from "@tiptap/extension-link";
|
|
12
|
-
import { BulletList as B, OrderedList as H, ListItem as R, ListKeymap as b } from "@tiptap/extension-list";
|
|
13
|
-
import C from "@tiptap/extension-paragraph";
|
|
14
|
-
import I from "@tiptap/extension-strike";
|
|
15
|
-
import E from "@tiptap/extension-text";
|
|
16
|
-
import N from "@tiptap/extension-text-align";
|
|
17
|
-
import O from "@tiptap/extension-typography";
|
|
18
|
-
import U from "@tiptap/extension-underline";
|
|
19
|
-
import { UndoRedo as j, TrailingNode as q } from "@tiptap/extensions";
|
|
20
|
-
import { useEditor as w, EditorContent as M } from "@tiptap/react";
|
|
21
|
-
import { useMessagesForm as S } from "../../context/messages-form.js";
|
|
22
|
-
import { InputWrapper as z } from "./InputWrapper.js";
|
|
23
|
-
import { RichTextToolbar as A } from "./toolbar/RichTextToolbar.js";
|
|
24
|
-
function ao({
|
|
25
|
-
error: i,
|
|
26
|
-
label: e,
|
|
27
|
-
lang: m,
|
|
28
|
-
onBlur: p,
|
|
29
|
-
onChange: n,
|
|
30
|
-
value: a,
|
|
31
|
-
className: f
|
|
32
|
-
}) {
|
|
33
|
-
const { richTextEditorOptions: o } = S();
|
|
34
|
-
console.log(o);
|
|
35
|
-
const r = w({
|
|
36
|
-
content: a,
|
|
37
|
-
extensions: [
|
|
38
|
-
u,
|
|
39
|
-
...o?.heading !== !1 ? [x.configure(o?.heading)] : [],
|
|
40
|
-
C,
|
|
41
|
-
E,
|
|
42
|
-
h,
|
|
43
|
-
k,
|
|
44
|
-
d,
|
|
45
|
-
g,
|
|
46
|
-
B,
|
|
47
|
-
H,
|
|
48
|
-
R,
|
|
49
|
-
y.configure({
|
|
50
|
-
openOnClick: !1,
|
|
51
|
-
enableClickSelection: !0
|
|
52
|
-
}),
|
|
53
|
-
c,
|
|
54
|
-
L,
|
|
55
|
-
I,
|
|
56
|
-
U,
|
|
57
|
-
O,
|
|
58
|
-
T,
|
|
59
|
-
N.configure({
|
|
60
|
-
types: ["heading", "paragraph", "blockquote"]
|
|
61
|
-
}),
|
|
62
|
-
j,
|
|
63
|
-
q,
|
|
64
|
-
b
|
|
65
|
-
],
|
|
66
|
-
immediatelyRender: !1,
|
|
67
|
-
onUpdate: ({ editor: l }) => n?.(l.getHTML())
|
|
68
|
-
});
|
|
69
|
-
return /* @__PURE__ */ s(z, { label: e, error: i, className: f, children: [
|
|
70
|
-
/* @__PURE__ */ t(A, { className: "mb-3 w-full min-w-max", editor: r }),
|
|
71
|
-
/* @__PURE__ */ t(
|
|
72
|
-
M,
|
|
73
|
-
{
|
|
74
|
-
className: "tiptap-editor min-h-8",
|
|
75
|
-
editor: r,
|
|
76
|
-
lang: m,
|
|
77
|
-
onBlur: p
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
] });
|
|
81
|
-
}
|
|
82
|
-
export {
|
|
83
|
-
ao as RichTextInput
|
|
84
|
-
};
|
|
85
|
-
//# sourceMappingURL=RichTextInput.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RichTextInput.js","sources":["../../../src/components/inputs/RichTextInput.tsx"],"sourcesContent":["import Blockquote from \"@tiptap/extension-blockquote\";\nimport Bold from \"@tiptap/extension-bold\";\nimport CodeBlock from \"@tiptap/extension-code-block\";\nimport Document from \"@tiptap/extension-document\";\nimport HardBreak from \"@tiptap/extension-hard-break\";\nimport Heading from \"@tiptap/extension-heading\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport HorizontalRule from \"@tiptap/extension-horizontal-rule\";\nimport Italic from \"@tiptap/extension-italic\";\nimport Link from \"@tiptap/extension-link\";\nimport {\n BulletList,\n ListItem,\n ListKeymap,\n OrderedList,\n} from \"@tiptap/extension-list\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Strike from \"@tiptap/extension-strike\";\nimport Text from \"@tiptap/extension-text\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport Typography from \"@tiptap/extension-typography\";\nimport Underline from \"@tiptap/extension-underline\";\nimport { TrailingNode, UndoRedo } from \"@tiptap/extensions\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\n\nimport { useMessagesForm } from \"@/context/messages-form\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\nimport { RichTextToolbar } from \"./toolbar/RichTextToolbar\";\n\nexport interface RichTextInputProps extends InputWrapperProps {\n value: string;\n lang: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nexport function RichTextInput({\n error,\n label,\n lang,\n onBlur,\n onChange,\n value,\n className,\n}: RichTextInputProps): React.ReactNode {\n const { richTextEditorOptions } = useMessagesForm();\n console.log(richTextEditorOptions);\n const editor = useEditor({\n content: value,\n extensions: [\n Document,\n ...(richTextEditorOptions?.heading !== false\n ? [Heading.configure(richTextEditorOptions?.heading)]\n : []),\n Paragraph,\n Text,\n HardBreak,\n HorizontalRule,\n Blockquote,\n CodeBlock,\n BulletList,\n OrderedList,\n ListItem,\n Link.configure({\n openOnClick: false,\n enableClickSelection: true,\n }),\n Bold,\n Italic,\n Strike,\n Underline,\n Typography,\n Highlight,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\", \"blockquote\"],\n }),\n UndoRedo,\n TrailingNode,\n ListKeymap,\n ],\n immediatelyRender: false,\n onUpdate: ({ editor }) => onChange?.(editor.getHTML()),\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <RichTextToolbar className=\"mb-3 w-full min-w-max\" editor={editor} />\n <EditorContent\n className=\"tiptap-editor min-h-8\"\n editor={editor}\n lang={lang}\n onBlur={onBlur}\n />\n </InputWrapper>\n );\n}\n"],"names":["RichTextInput","error","label","lang","onBlur","onChange","value","className","richTextEditorOptions","useMessagesForm","editor","useEditor","Document","Heading","Paragraph","Text","HardBreak","HorizontalRule","Blockquote","CodeBlock","BulletList","OrderedList","ListItem","Link","Bold","Italic","Strike","Underline","Typography","Highlight","TextAlign","UndoRedo","TrailingNode","ListKeymap","jsxs","InputWrapper","jsx","RichTextToolbar","EditorContent"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsCO,SAASA,GAAc;AAAA,EAC5B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AACF,GAAwC;AACtC,QAAM,EAAE,uBAAAC,EAAA,IAA0BC,EAAA;AAClC,UAAQ,IAAID,CAAqB;AACjC,QAAME,IAASC,EAAU;AAAA,IACvB,SAASL;AAAA,IACT,YAAY;AAAA,MACVM;AAAA,MACA,GAAIJ,GAAuB,YAAY,KACnC,CAACK,EAAQ,UAAUL,GAAuB,OAAO,CAAC,IAClD,CAAA;AAAA,MACJM;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC,EAAK,UAAU;AAAA,QACb,aAAa;AAAA,QACb,sBAAsB;AAAA,MAAA,CACvB;AAAA,MACDC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC,EAAU,UAAU;AAAA,QAClB,OAAO,CAAC,WAAW,aAAa,YAAY;AAAA,MAAA,CAC7C;AAAA,MACDC;AAAA,MACAC;AAAA,MACAC;AAAA,IAAA;AAAA,IAEF,mBAAmB;AAAA,IACnB,UAAU,CAAC,EAAE,QAAAvB,QAAaL,IAAWK,EAAO,QAAA,CAAS;AAAA,EAAA,CACtD;AAED,SACE,gBAAAwB,EAACC,GAAA,EAAa,OAAAjC,GAAc,OAAAD,GAAc,WAAAM,GACxC,UAAA;AAAA,IAAA,gBAAA6B,EAACC,GAAA,EAAgB,WAAU,yBAAwB,QAAA3B,EAAA,CAAgB;AAAA,IACnE,gBAAA0B;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,QAAA5B;AAAA,QACA,MAAAP;AAAA,QACA,QAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { jsxs as u, jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { IconAlignLeft as c, IconAlignCenter as d, IconAlignRight as f } from "@tabler/icons-react";
|
|
3
|
-
import { useEditorState as b } from "@tiptap/react";
|
|
4
|
-
import { Toolbar as n } from "radix-ui";
|
|
5
|
-
function p({ editor: i }) {
|
|
6
|
-
const { value: o, disabled: r } = b({
|
|
7
|
-
editor: i,
|
|
8
|
-
selector: (e) => {
|
|
9
|
-
const l = e.editor?.getAttributes("paragraph"), s = e.editor?.getAttributes("heading"), g = e.editor?.getAttributes("blockquote");
|
|
10
|
-
return {
|
|
11
|
-
disabled: e.editor?.isActive("bulletList") || e.editor?.isActive("orderedList"),
|
|
12
|
-
value: l?.textAlign || s?.textAlign || g?.textAlign
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
}) ?? { value: "left" }, a = (e) => {
|
|
16
|
-
i && i.chain().focus().setTextAlign(e).run();
|
|
17
|
-
};
|
|
18
|
-
return /* @__PURE__ */ u(
|
|
19
|
-
n.ToggleGroup,
|
|
20
|
-
{
|
|
21
|
-
type: "single",
|
|
22
|
-
className: "flex items-center",
|
|
23
|
-
"aria-label": "Text alignment",
|
|
24
|
-
value: o,
|
|
25
|
-
onValueChange: a,
|
|
26
|
-
disabled: r,
|
|
27
|
-
children: [
|
|
28
|
-
/* @__PURE__ */ t(
|
|
29
|
-
n.ToggleItem,
|
|
30
|
-
{
|
|
31
|
-
className: "inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0",
|
|
32
|
-
value: "left",
|
|
33
|
-
"aria-label": "Left aligned",
|
|
34
|
-
children: /* @__PURE__ */ t(c, { size: 16 })
|
|
35
|
-
}
|
|
36
|
-
),
|
|
37
|
-
/* @__PURE__ */ t(
|
|
38
|
-
n.ToggleItem,
|
|
39
|
-
{
|
|
40
|
-
className: "inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0",
|
|
41
|
-
value: "center",
|
|
42
|
-
"aria-label": "Center aligned",
|
|
43
|
-
children: /* @__PURE__ */ t(d, { size: 16 })
|
|
44
|
-
}
|
|
45
|
-
),
|
|
46
|
-
/* @__PURE__ */ t(
|
|
47
|
-
n.ToggleItem,
|
|
48
|
-
{
|
|
49
|
-
className: "inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0",
|
|
50
|
-
value: "right",
|
|
51
|
-
"aria-label": "Right aligned",
|
|
52
|
-
children: /* @__PURE__ */ t(f, { size: 16 })
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
]
|
|
56
|
-
}
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
export {
|
|
60
|
-
p as AlignmentControls
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=AlignmentControls.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AlignmentControls.js","sources":["../../../../src/components/inputs/toolbar/AlignmentControls.tsx"],"sourcesContent":["import type { Editor } from \"@tiptap/react\";\nimport {\n IconAlignCenter,\n IconAlignLeft,\n IconAlignRight,\n} from \"@tabler/icons-react\";\nimport { useEditorState } from \"@tiptap/react\";\nimport { Toolbar } from \"radix-ui\";\n\nexport interface AlignmentControlsProps {\n editor: Editor | null;\n}\n\nexport function AlignmentControls({ editor }: AlignmentControlsProps) {\n const { value, disabled } = useEditorState<{\n value: string;\n disabled?: boolean;\n }>({\n editor,\n selector: (state) => {\n const attrs = state.editor?.getAttributes(\"paragraph\");\n const headingAttrs = state.editor?.getAttributes(\"heading\");\n const blockquoteAttrs = state.editor?.getAttributes(\"blockquote\");\n\n return {\n disabled:\n state.editor?.isActive(\"bulletList\") ||\n state.editor?.isActive(\"orderedList\"),\n value:\n attrs?.textAlign ||\n headingAttrs?.textAlign ||\n blockquoteAttrs?.textAlign,\n };\n },\n }) ?? { value: \"left\" };\n\n const handleChange = (value: string) => {\n if (!editor) return;\n editor.chain().focus().setTextAlign(value).run();\n };\n\n return (\n <Toolbar.ToggleGroup\n type=\"single\"\n className=\"flex items-center\"\n aria-label=\"Text alignment\"\n value={value}\n onValueChange={handleChange}\n disabled={disabled}\n >\n <Toolbar.ToggleItem\n className=\"inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0\"\n value=\"left\"\n aria-label=\"Left aligned\"\n >\n <IconAlignLeft size={16} />\n </Toolbar.ToggleItem>\n <Toolbar.ToggleItem\n className=\"inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0\"\n value=\"center\"\n aria-label=\"Center aligned\"\n >\n <IconAlignCenter size={16} />\n </Toolbar.ToggleItem>\n <Toolbar.ToggleItem\n className=\"inline-flex h-7 flex-shrink-0 flex-grow-0 basis-auto cursor-pointer items-center justify-center rounded border-none bg-transparent px-2 leading-none hover:bg-elevation-250 focus:relative focus:outline data-[state=on]:bg-elevation-600 data-[state=on]:text-elevation-0\"\n value=\"right\"\n aria-label=\"Right aligned\"\n >\n <IconAlignRight size={16} />\n </Toolbar.ToggleItem>\n </Toolbar.ToggleGroup>\n );\n}\n"],"names":["AlignmentControls","editor","value","disabled","useEditorState","state","attrs","headingAttrs","blockquoteAttrs","handleChange","jsxs","Toolbar","jsx","IconAlignLeft","IconAlignCenter","IconAlignRight"],"mappings":";;;;AAaO,SAASA,EAAkB,EAAE,QAAAC,KAAkC;AACpE,QAAM,EAAE,OAAAC,GAAO,UAAAC,EAAA,IAAaC,EAGzB;AAAA,IACD,QAAAH;AAAA,IACA,UAAU,CAACI,MAAU;AACnB,YAAMC,IAAQD,EAAM,QAAQ,cAAc,WAAW,GAC/CE,IAAeF,EAAM,QAAQ,cAAc,SAAS,GACpDG,IAAkBH,EAAM,QAAQ,cAAc,YAAY;AAEhE,aAAO;AAAA,QACL,UACEA,EAAM,QAAQ,SAAS,YAAY,KACnCA,EAAM,QAAQ,SAAS,aAAa;AAAA,QACtC,OACEC,GAAO,aACPC,GAAc,aACdC,GAAiB;AAAA,MAAA;AAAA,IAEvB;AAAA,EAAA,CACD,KAAK,EAAE,OAAO,OAAA,GAETC,IAAe,CAACP,MAAkB;AACtC,IAAKD,KACLA,EAAO,QAAQ,MAAA,EAAQ,aAAaC,CAAK,EAAE,IAAA;AAAA,EAC7C;AAEA,SACE,gBAAAQ;AAAA,IAACC,EAAQ;AAAA,IAAR;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,cAAW;AAAA,MACX,OAAAT;AAAA,MACA,eAAeO;AAAA,MACf,UAAAN;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAAS;AAAA,UAACD,EAAQ;AAAA,UAAR;AAAA,YACC,WAAU;AAAA,YACV,OAAM;AAAA,YACN,cAAW;AAAA,YAEX,UAAA,gBAAAC,EAACC,GAAA,EAAc,MAAM,GAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,QAE3B,gBAAAD;AAAA,UAACD,EAAQ;AAAA,UAAR;AAAA,YACC,WAAU;AAAA,YACV,OAAM;AAAA,YACN,cAAW;AAAA,YAEX,UAAA,gBAAAC,EAACE,GAAA,EAAgB,MAAM,GAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,QAE7B,gBAAAF;AAAA,UAACD,EAAQ;AAAA,UAAR;AAAA,YACC,WAAU;AAAA,YACV,OAAM;AAAA,YACN,cAAW;AAAA,YAEX,UAAA,gBAAAC,EAACG,GAAA,EAAe,MAAM,GAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5B;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { jsxs as c, jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { IconH6 as d, IconH5 as h, IconH4 as b, IconH3 as v, IconH2 as f, IconH1 as m, IconLetterT as g, IconList as k, IconListNumbers as p, IconSeparatorHorizontal as H, IconBlockquote as I, IconCode as L } from "@tabler/icons-react";
|
|
3
|
-
import { useEditorState as T } from "@tiptap/react";
|
|
4
|
-
import { Select as n, Toolbar as x } from "radix-ui";
|
|
5
|
-
import { useMemo as A } from "react";
|
|
6
|
-
import { cn as r } from "../../../utils/cn.js";
|
|
7
|
-
function q({ editor: a }) {
|
|
8
|
-
const i = A(() => {
|
|
9
|
-
const e = a?.extensionManager.extensions.find((l) => l.name === "heading")?.options.levels.map(
|
|
10
|
-
(l) => o.HEADINGS[l]
|
|
11
|
-
) ?? [];
|
|
12
|
-
return [
|
|
13
|
-
o.TEXT,
|
|
14
|
-
...e.length > 0 ? ["-", ...e] : [],
|
|
15
|
-
"-",
|
|
16
|
-
...o.LIST,
|
|
17
|
-
"-",
|
|
18
|
-
o.SEPARATOR,
|
|
19
|
-
o.BLOCKQUOTE,
|
|
20
|
-
o.CODE_BLOCK
|
|
21
|
-
];
|
|
22
|
-
}, [a]), s = T({
|
|
23
|
-
editor: a,
|
|
24
|
-
selector: (e) => e.editor?.isActive("heading", { level: 1 }) ? "h1" : e.editor?.isActive("heading", { level: 2 }) ? "h2" : e.editor?.isActive("heading", { level: 3 }) ? "h3" : e.editor?.isActive("heading", { level: 4 }) ? "h4" : e.editor?.isActive("heading", { level: 5 }) ? "h5" : e.editor?.isActive("heading", { level: 6 }) ? "h6" : e.editor?.isActive("bulletList") ? "bullet-list" : e.editor?.isActive("orderedList") ? "ordered-list" : e.editor?.isActive("blockquote") ? "blockquote" : e.editor?.isActive("codeBlock") ? "code-block" : "text"
|
|
25
|
-
}), u = (e) => {
|
|
26
|
-
if (a) {
|
|
27
|
-
switch (e !== "blockquote" && a.chain().focus().unsetBlockquote().run(), e) {
|
|
28
|
-
case "h1":
|
|
29
|
-
a.chain().focus().setHeading({ level: 1 }).run();
|
|
30
|
-
break;
|
|
31
|
-
case "h2":
|
|
32
|
-
a.chain().focus().setHeading({ level: 2 }).run();
|
|
33
|
-
break;
|
|
34
|
-
case "h3":
|
|
35
|
-
a.chain().focus().setHeading({ level: 3 }).run();
|
|
36
|
-
break;
|
|
37
|
-
case "h4":
|
|
38
|
-
a.chain().focus().setHeading({ level: 4 }).run();
|
|
39
|
-
break;
|
|
40
|
-
case "h5":
|
|
41
|
-
a.chain().focus().setHeading({ level: 5 }).run();
|
|
42
|
-
break;
|
|
43
|
-
case "h6":
|
|
44
|
-
a.chain().focus().setHeading({ level: 6 }).run();
|
|
45
|
-
break;
|
|
46
|
-
case "bullet-list":
|
|
47
|
-
a.chain().focus().toggleBulletList().run();
|
|
48
|
-
break;
|
|
49
|
-
case "ordered-list":
|
|
50
|
-
a.chain().focus().toggleOrderedList().run();
|
|
51
|
-
break;
|
|
52
|
-
case "task-list":
|
|
53
|
-
a.chain().focus().toggleTaskList().run();
|
|
54
|
-
break;
|
|
55
|
-
case "separator":
|
|
56
|
-
a.chain().focus().setHorizontalRule().run();
|
|
57
|
-
break;
|
|
58
|
-
case "blockquote":
|
|
59
|
-
a.chain().focus().setParagraph().run(), a.chain().focus().setBlockquote().run();
|
|
60
|
-
break;
|
|
61
|
-
case "code-block":
|
|
62
|
-
a.chain().focus().setCodeBlock().run();
|
|
63
|
-
break;
|
|
64
|
-
case "text":
|
|
65
|
-
a.chain().focus().setParagraph().run();
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
setTimeout(() => {
|
|
69
|
-
a.commands.focus();
|
|
70
|
-
}, 100);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
return /* @__PURE__ */ c(n.Root, { value: s ?? "text", onValueChange: u, children: [
|
|
74
|
-
/* @__PURE__ */ t(n.Trigger, { asChild: !0, children: /* @__PURE__ */ t(x.Button, { className: "flex w-34 cursor-pointer items-center justify-center gap-2 rounded-sm border-none bg-transparent hover:bg-elevation-250 focus:outline", children: /* @__PURE__ */ t(n.Value, {}) }) }),
|
|
75
|
-
/* @__PURE__ */ t(n.Portal, { children: /* @__PURE__ */ t(
|
|
76
|
-
n.Content,
|
|
77
|
-
{
|
|
78
|
-
"data-slot": "select-content",
|
|
79
|
-
side: "bottom",
|
|
80
|
-
className: "relative z-50 w-40 translate-y-2 rounded-md border border-border bg-elevation-100 shadow-md slide-in-from-top-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
81
|
-
children: /* @__PURE__ */ t(n.Viewport, { className: r("p-1"), children: i.map((e, l) => e === "-" ? /* @__PURE__ */ t(
|
|
82
|
-
n.Separator,
|
|
83
|
-
{
|
|
84
|
-
className: "my-1 h-px bg-border"
|
|
85
|
-
},
|
|
86
|
-
l
|
|
87
|
-
) : /* @__PURE__ */ c(
|
|
88
|
-
n.Item,
|
|
89
|
-
{
|
|
90
|
-
"data-slot": "select-item",
|
|
91
|
-
className: r(
|
|
92
|
-
"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1 hover:bg-elevation-250 hover:outline-none data-[state=checked]:pointer-events-none data-[state=checked]:bg-elevation-800 data-[state=checked]:text-elevation-0"
|
|
93
|
-
),
|
|
94
|
-
value: e.value,
|
|
95
|
-
children: [
|
|
96
|
-
/* @__PURE__ */ t(n.Icon, { asChild: !0, children: /* @__PURE__ */ t(e.icon, { className: "size-4" }) }),
|
|
97
|
-
/* @__PURE__ */ t(n.ItemText, { children: e.label })
|
|
98
|
-
]
|
|
99
|
-
},
|
|
100
|
-
e.value
|
|
101
|
-
)) })
|
|
102
|
-
}
|
|
103
|
-
) })
|
|
104
|
-
] });
|
|
105
|
-
}
|
|
106
|
-
const o = {
|
|
107
|
-
TEXT: { value: "text", label: "Text", icon: g },
|
|
108
|
-
HEADINGS: {
|
|
109
|
-
1: { value: "h1", label: "Heading 1", icon: m },
|
|
110
|
-
2: { value: "h2", label: "Heading 2", icon: f },
|
|
111
|
-
3: { value: "h3", label: "Heading 3", icon: v },
|
|
112
|
-
4: { value: "h4", label: "Heading 4", icon: b },
|
|
113
|
-
5: { value: "h5", label: "Heading 5", icon: h },
|
|
114
|
-
6: { value: "h6", label: "Heading 6", icon: d }
|
|
115
|
-
},
|
|
116
|
-
LIST: [
|
|
117
|
-
{ value: "bullet-list", label: "Bullet List", icon: k },
|
|
118
|
-
{ value: "ordered-list", label: "Ordered List", icon: p }
|
|
119
|
-
],
|
|
120
|
-
SEPARATOR: {
|
|
121
|
-
value: "separator",
|
|
122
|
-
label: "Separator",
|
|
123
|
-
icon: H
|
|
124
|
-
},
|
|
125
|
-
BLOCKQUOTE: {
|
|
126
|
-
value: "blockquote",
|
|
127
|
-
label: "Blockquote",
|
|
128
|
-
icon: I
|
|
129
|
-
},
|
|
130
|
-
CODE_BLOCK: { value: "code-block", label: "Code Block", icon: L }
|
|
131
|
-
};
|
|
132
|
-
export {
|
|
133
|
-
q as BlockElementSelect
|
|
134
|
-
};
|
|
135
|
-
//# sourceMappingURL=BlockElementSelect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BlockElementSelect.js","sources":["../../../../src/components/inputs/toolbar/BlockElementSelect.tsx"],"sourcesContent":["import type { IconProps } from \"@tabler/icons-react\";\nimport type { Editor } from \"@tiptap/react\";\nimport {\n IconBlockquote,\n IconCode,\n IconH1,\n IconH2,\n IconH3,\n IconH4,\n IconH5,\n IconH6,\n IconLetterT,\n IconList,\n IconListNumbers,\n IconSeparatorHorizontal,\n} from \"@tabler/icons-react\";\nimport { useEditorState } from \"@tiptap/react\";\nimport { Select, Toolbar } from \"radix-ui\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport interface BlockElementSelectProps {\n // TODO add config\n editor: Editor | null;\n}\nexport function BlockElementSelect({ editor }: BlockElementSelectProps) {\n const items = useMemo(() => {\n const headings =\n editor?.extensionManager.extensions\n .find((extension) => extension.name === \"heading\")\n ?.options.levels.map(\n (level: 1 | 2 | 3 | 4 | 5 | 6) => BLOCK_ELEMENTS.HEADINGS[level],\n ) ?? [];\n\n return [\n BLOCK_ELEMENTS.TEXT,\n ...(headings.length > 0 ? [\"-\", ...headings] : []),\n \"-\",\n ...BLOCK_ELEMENTS.LIST,\n \"-\",\n BLOCK_ELEMENTS.SEPARATOR,\n BLOCK_ELEMENTS.BLOCKQUOTE,\n BLOCK_ELEMENTS.CODE_BLOCK,\n ];\n }, [editor]);\n\n const value = useEditorState<BlockElementType>({\n editor,\n selector: (state) => {\n if (state.editor?.isActive(\"heading\", { level: 1 })) return \"h1\";\n if (state.editor?.isActive(\"heading\", { level: 2 })) return \"h2\";\n if (state.editor?.isActive(\"heading\", { level: 3 })) return \"h3\";\n if (state.editor?.isActive(\"heading\", { level: 4 })) return \"h4\";\n if (state.editor?.isActive(\"heading\", { level: 5 })) return \"h5\";\n if (state.editor?.isActive(\"heading\", { level: 6 })) return \"h6\";\n if (state.editor?.isActive(\"bulletList\")) return \"bullet-list\";\n if (state.editor?.isActive(\"orderedList\")) return \"ordered-list\";\n if (state.editor?.isActive(\"blockquote\")) return \"blockquote\";\n if (state.editor?.isActive(\"codeBlock\")) return \"code-block\";\n return \"text\";\n },\n });\n const handleChange = (value: string) => {\n if (!editor) return;\n\n if (value !== \"blockquote\") {\n editor.chain().focus().unsetBlockquote().run();\n }\n\n switch (value as BlockElementType) {\n case \"h1\":\n editor.chain().focus().setHeading({ level: 1 }).run();\n break;\n case \"h2\":\n editor.chain().focus().setHeading({ level: 2 }).run();\n break;\n case \"h3\":\n editor.chain().focus().setHeading({ level: 3 }).run();\n break;\n case \"h4\":\n editor.chain().focus().setHeading({ level: 4 }).run();\n break;\n case \"h5\":\n editor.chain().focus().setHeading({ level: 5 }).run();\n break;\n case \"h6\":\n editor.chain().focus().setHeading({ level: 6 }).run();\n break;\n case \"bullet-list\":\n editor.chain().focus().toggleBulletList().run();\n break;\n case \"ordered-list\":\n editor.chain().focus().toggleOrderedList().run();\n break;\n case \"task-list\":\n editor.chain().focus().toggleTaskList().run();\n break;\n case \"separator\":\n editor.chain().focus().setHorizontalRule().run();\n break;\n case \"blockquote\":\n editor.chain().focus().setParagraph().run();\n editor.chain().focus().setBlockquote().run();\n break;\n case \"code-block\":\n editor.chain().focus().setCodeBlock().run();\n break;\n case \"text\":\n editor.chain().focus().setParagraph().run();\n break;\n }\n // TODO bring back the focus to the active text\n setTimeout(() => {\n editor.commands.focus();\n }, 100);\n };\n\n return (\n <Select.Root value={value ?? \"text\"} onValueChange={handleChange}>\n <Select.Trigger asChild>\n <Toolbar.Button className=\"flex w-34 cursor-pointer items-center justify-center gap-2 rounded-sm border-none bg-transparent hover:bg-elevation-250 focus:outline\">\n <Select.Value />\n </Toolbar.Button>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n data-slot=\"select-content\"\n side=\"bottom\"\n className=\"relative z-50 w-40 translate-y-2 rounded-md border border-border bg-elevation-100 shadow-md slide-in-from-top-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\"\n >\n <Select.Viewport className={cn(\"p-1\")}>\n {items.map((option, index) => {\n if (option === \"-\")\n return (\n <Select.Separator\n key={index}\n className=\"my-1 h-px bg-border\"\n />\n );\n\n return (\n <Select.Item\n key={option.value}\n data-slot=\"select-item\"\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1 hover:bg-elevation-250 hover:outline-none data-[state=checked]:pointer-events-none data-[state=checked]:bg-elevation-800 data-[state=checked]:text-elevation-0\",\n )}\n value={option.value}\n >\n <Select.Icon asChild>\n <option.icon className=\"size-4\" />\n </Select.Icon>\n <Select.ItemText>{option.label}</Select.ItemText>\n </Select.Item>\n );\n })}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\n// MARK: Options\n\ntype BlockElementType =\n | \"text\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"bullet-list\"\n | \"ordered-list\"\n | \"task-list\"\n | \"blockquote\"\n | \"separator\"\n | \"code-block\";\n\ninterface BlockElementOption {\n value: BlockElementType;\n label: string;\n icon: React.FunctionComponent<IconProps>;\n}\n\nconst BLOCK_ELEMENTS = {\n TEXT: { value: \"text\", label: \"Text\", icon: IconLetterT },\n HEADINGS: {\n 1: { value: \"h1\", label: \"Heading 1\", icon: IconH1 },\n 2: { value: \"h2\", label: \"Heading 2\", icon: IconH2 },\n 3: { value: \"h3\", label: \"Heading 3\", icon: IconH3 },\n 4: { value: \"h4\", label: \"Heading 4\", icon: IconH4 },\n 5: { value: \"h5\", label: \"Heading 5\", icon: IconH5 },\n 6: { value: \"h6\", label: \"Heading 6\", icon: IconH6 },\n },\n LIST: [\n { value: \"bullet-list\", label: \"Bullet List\", icon: IconList },\n { value: \"ordered-list\", label: \"Ordered List\", icon: IconListNumbers },\n ],\n SEPARATOR: {\n value: \"separator\",\n label: \"Separator\",\n icon: IconSeparatorHorizontal,\n },\n BLOCKQUOTE: {\n value: \"blockquote\",\n label: \"Blockquote\",\n icon: IconBlockquote,\n },\n CODE_BLOCK: { value: \"code-block\", label: \"Code Block\", icon: IconCode },\n} satisfies Record<\n string,\n | BlockElementOption\n | BlockElementOption[]\n | Record<string | number, BlockElementOption>\n>;\n"],"names":["BlockElementSelect","editor","items","useMemo","headings","extension","level","BLOCK_ELEMENTS","value","useEditorState","state","handleChange","jsxs","Select","jsx","Toolbar","cn","option","index","IconLetterT","IconH1","IconH2","IconH3","IconH4","IconH5","IconH6","IconList","IconListNumbers","IconSeparatorHorizontal","IconBlockquote","IconCode"],"mappings":"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"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/react';
|
|
2
|
-
export interface LinkEditorProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, "type" | "children">, UseLinkPopoverConfig {
|
|
3
|
-
/**
|
|
4
|
-
* Callback for when the popover opens or closes.
|
|
5
|
-
*/
|
|
6
|
-
onOpenChange?: (isOpen: boolean) => void;
|
|
7
|
-
/**
|
|
8
|
-
* Whether to automatically open the popover when a link is active.
|
|
9
|
-
* @default true
|
|
10
|
-
*/
|
|
11
|
-
autoOpenOnLinkActive?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export declare function LinkEditor({ editor, hideWhenUnavailable, onSetLink, onOpenChange, autoOpenOnLinkActive, onClick, className, ...buttonProps }: LinkEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
/**
|
|
15
|
-
* Configuration for the link popover functionality
|
|
16
|
-
*/
|
|
17
|
-
export interface UseLinkPopoverConfig {
|
|
18
|
-
/**
|
|
19
|
-
* The Tiptap editor instance.
|
|
20
|
-
*/
|
|
21
|
-
editor?: Editor | null;
|
|
22
|
-
/**
|
|
23
|
-
* Whether to hide the link popover when not available.
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
hideWhenUnavailable?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Callback function called when the link is set.
|
|
29
|
-
*/
|
|
30
|
-
onSetLink?: () => void;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Checks if a mark exists in the editor schema
|
|
34
|
-
*/
|
|
35
|
-
export declare const isMarkInSchema: (markName: string, editor: Editor | null) => boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Configuration for the link handler functionality
|
|
38
|
-
*/
|
|
39
|
-
export interface LinkHandlerProps {
|
|
40
|
-
/**
|
|
41
|
-
* The Tiptap editor instance.
|
|
42
|
-
*/
|
|
43
|
-
editor: Editor | null;
|
|
44
|
-
/**
|
|
45
|
-
* Callback function called when the link is set.
|
|
46
|
-
*/
|
|
47
|
-
onSetLink?: () => void;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Custom hook for handling link operations in a Tiptap editor
|
|
51
|
-
*/
|
|
52
|
-
export declare function useLinkHandler({ editor, onSetLink }: LinkHandlerProps): {
|
|
53
|
-
url: string;
|
|
54
|
-
setUrl: import('react').Dispatch<import('react').SetStateAction<string | null>>;
|
|
55
|
-
setLink: () => void;
|
|
56
|
-
removeLink: () => void;
|
|
57
|
-
openLink: (target?: string, features?: string) => void;
|
|
58
|
-
};
|