@payload-enchants/translator 0.0.1-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -0
  3. package/dist/client/api/index.d.ts +8 -0
  4. package/dist/client/api/index.d.ts.map +1 -0
  5. package/dist/client/api/index.js +28 -0
  6. package/dist/client/api/index.js.map +1 -0
  7. package/dist/client/components/CustomSaveButton/CustomSaveButton.d.ts +4 -0
  8. package/dist/client/components/CustomSaveButton/CustomSaveButton.d.ts.map +1 -0
  9. package/dist/client/components/CustomSaveButton/CustomSaveButton.js +22 -0
  10. package/dist/client/components/CustomSaveButton/CustomSaveButton.js.map +1 -0
  11. package/dist/client/components/CustomSaveButton/index.d.ts +2 -0
  12. package/dist/client/components/CustomSaveButton/index.d.ts.map +1 -0
  13. package/dist/client/components/CustomSaveButton/index.js +3 -0
  14. package/dist/client/components/CustomSaveButton/index.js.map +1 -0
  15. package/dist/client/components/CustomSaveButton/styles.scss +5 -0
  16. package/dist/client/components/LocaleLabel/LocaleLabel.d.ts +6 -0
  17. package/dist/client/components/LocaleLabel/LocaleLabel.d.ts.map +1 -0
  18. package/dist/client/components/LocaleLabel/LocaleLabel.js +19 -0
  19. package/dist/client/components/LocaleLabel/LocaleLabel.js.map +1 -0
  20. package/dist/client/components/LocaleLabel/index.d.ts +2 -0
  21. package/dist/client/components/LocaleLabel/index.d.ts.map +1 -0
  22. package/dist/client/components/LocaleLabel/index.js +3 -0
  23. package/dist/client/components/LocaleLabel/index.js.map +1 -0
  24. package/dist/client/components/ResolverButton/ResolverButton.d.ts +6 -0
  25. package/dist/client/components/ResolverButton/ResolverButton.d.ts.map +1 -0
  26. package/dist/client/components/ResolverButton/ResolverButton.js +16 -0
  27. package/dist/client/components/ResolverButton/ResolverButton.js.map +1 -0
  28. package/dist/client/components/ResolverButton/index.d.ts +2 -0
  29. package/dist/client/components/ResolverButton/index.d.ts.map +1 -0
  30. package/dist/client/components/ResolverButton/index.js +3 -0
  31. package/dist/client/components/ResolverButton/index.js.map +1 -0
  32. package/dist/client/components/TranslatorModal/Content.d.ts +3 -0
  33. package/dist/client/components/TranslatorModal/Content.d.ts.map +1 -0
  34. package/dist/client/components/TranslatorModal/Content.js +42 -0
  35. package/dist/client/components/TranslatorModal/Content.js.map +1 -0
  36. package/dist/client/components/TranslatorModal/TranslatorModal.d.ts +4 -0
  37. package/dist/client/components/TranslatorModal/TranslatorModal.d.ts.map +1 -0
  38. package/dist/client/components/TranslatorModal/TranslatorModal.js +21 -0
  39. package/dist/client/components/TranslatorModal/TranslatorModal.js.map +1 -0
  40. package/dist/client/components/TranslatorModal/index.d.ts +2 -0
  41. package/dist/client/components/TranslatorModal/index.d.ts.map +1 -0
  42. package/dist/client/components/TranslatorModal/index.js +3 -0
  43. package/dist/client/components/TranslatorModal/index.js.map +1 -0
  44. package/dist/client/components/TranslatorModal/styles.scss +76 -0
  45. package/dist/client/providers/Translator/TranslatorProvider.d.ts +5 -0
  46. package/dist/client/providers/Translator/TranslatorProvider.d.ts.map +1 -0
  47. package/dist/client/providers/Translator/TranslatorProvider.js +100 -0
  48. package/dist/client/providers/Translator/TranslatorProvider.js.map +1 -0
  49. package/dist/client/providers/Translator/context.d.ts +22 -0
  50. package/dist/client/providers/Translator/context.d.ts.map +1 -0
  51. package/dist/client/providers/Translator/context.js +9 -0
  52. package/dist/client/providers/Translator/context.js.map +1 -0
  53. package/dist/i18n-translations.d.ts +25 -0
  54. package/dist/i18n-translations.d.ts.map +1 -0
  55. package/dist/i18n-translations.js +26 -0
  56. package/dist/i18n-translations.js.map +1 -0
  57. package/dist/index.d.ts +6 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +79 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/resolvers/copy.d.ts +3 -0
  62. package/dist/resolvers/copy.d.ts.map +1 -0
  63. package/dist/resolvers/copy.js +14 -0
  64. package/dist/resolvers/copy.js.map +1 -0
  65. package/dist/resolvers/google.d.ts +11 -0
  66. package/dist/resolvers/google.d.ts.map +1 -0
  67. package/dist/resolvers/google.js +47 -0
  68. package/dist/resolvers/google.js.map +1 -0
  69. package/dist/resolvers/openAI.d.ts +21 -0
  70. package/dist/resolvers/openAI.d.ts.map +1 -0
  71. package/dist/resolvers/openAI.js +97 -0
  72. package/dist/resolvers/openAI.js.map +1 -0
  73. package/dist/resolvers/types.d.ts +20 -0
  74. package/dist/resolvers/types.d.ts.map +1 -0
  75. package/dist/resolvers/types.js +3 -0
  76. package/dist/resolvers/types.js.map +1 -0
  77. package/dist/translate/endpoint.d.ts +3 -0
  78. package/dist/translate/endpoint.d.ts.map +1 -0
  79. package/dist/translate/endpoint.js +22 -0
  80. package/dist/translate/endpoint.js.map +1 -0
  81. package/dist/translate/findEntityWithConfig.d.ts +15 -0
  82. package/dist/translate/findEntityWithConfig.d.ts.map +1 -0
  83. package/dist/translate/findEntityWithConfig.js +32 -0
  84. package/dist/translate/findEntityWithConfig.js.map +1 -0
  85. package/dist/translate/operation.d.ts +9 -0
  86. package/dist/translate/operation.d.ts.map +1 -0
  87. package/dist/translate/operation.js +74 -0
  88. package/dist/translate/operation.js.map +1 -0
  89. package/dist/translate/traverseFields.d.ts +13 -0
  90. package/dist/translate/traverseFields.d.ts.map +1 -0
  91. package/dist/translate/traverseFields.js +160 -0
  92. package/dist/translate/traverseFields.js.map +1 -0
  93. package/dist/translate/traverseRichText.d.ts +6 -0
  94. package/dist/translate/traverseRichText.d.ts.map +1 -0
  95. package/dist/translate/traverseRichText.js +17 -0
  96. package/dist/translate/traverseRichText.js.map +1 -0
  97. package/dist/translate/types.d.ts +25 -0
  98. package/dist/translate/types.d.ts.map +1 -0
  99. package/dist/translate/types.js +3 -0
  100. package/dist/translate/types.js.map +1 -0
  101. package/dist/translate/updateEntity.d.ts +14 -0
  102. package/dist/translate/updateEntity.d.ts.map +1 -0
  103. package/dist/translate/updateEntity.js +26 -0
  104. package/dist/translate/updateEntity.js.map +1 -0
  105. package/dist/types.d.ts +21 -0
  106. package/dist/types.d.ts.map +1 -0
  107. package/dist/types.js +3 -0
  108. package/dist/types.js.map +1 -0
  109. package/dist/utils/chunkArray.d.ts +2 -0
  110. package/dist/utils/chunkArray.d.ts.map +1 -0
  111. package/dist/utils/chunkArray.js +7 -0
  112. package/dist/utils/chunkArray.js.map +1 -0
  113. package/dist/utils/isEmpty.d.ts +2 -0
  114. package/dist/utils/isEmpty.d.ts.map +1 -0
  115. package/dist/utils/isEmpty.js +8 -0
  116. package/dist/utils/isEmpty.js.map +1 -0
  117. package/package.json +75 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ritsu / Sasha Rakhmatulin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # Translator plugin for Payload 3.0 (beta)
2
+
3
+ ## Install
4
+
5
+ `pnpm add @payload-enchants/translator`
6
+
7
+ ## Video
8
+
9
+ https://github.com/r1tsuu/payload-plugin-translator/assets/64744993/d39aeba4-bafc-4c3b-838e-9abc5cf1d64a
10
+
11
+ ## Features:
12
+
13
+ 1. A flexible structure with [resolvers](https://github.com/r1tsuu/payload-plugin-translator/tree/6d0c8098467f9b5e757bf9fd8cfe63ff5da68d5b/plugin/src/resolvers) that allows you to apply any kind of transformation to your localizated data.
14
+ 2. Can be used not only from the admin panel, but within Local API as well. [Example of the hook](#example-of-the-hook-that-uses-local-operation-to-copy-the-doc-data-to-other-locales) that automatically fills the other locales data on create
15
+ 3. Out of the box supports 3 resolvers - Copy, Google Translate, OpenAI and your own can be written easily.
16
+ 4. Works with any nested document structure and 2 Rich Text editor adapters - Lexical and Slate.
17
+
18
+ ## Usage:
19
+
20
+ ```ts
21
+ import { buildConfig } from 'payload/config';
22
+ import { translator } from '@payload-enchants/translator';
23
+ import { copyResolver } from '@payload-enchants/translator/resolvers/copy';
24
+ import { googleResolver } from '@payload-enchants/translator/resolvers/google';
25
+ import { openAIResolver } from '@payload-enchants/translator/resolvers/openAI';
26
+
27
+ export default buildConfig({
28
+ plugins: [
29
+ translator({
30
+ // collections with the enabled translator in the admin UI
31
+ collections: ['posts', 'small-posts'],
32
+ // globals with the enabled translator in the admin UI
33
+ globals: [],
34
+ // add resolvers that you want to include, examples on how to write your own in ./plugin/src/resolvers
35
+ resolvers: [
36
+ copyResolver(),
37
+ googleResolver({
38
+ apiKey: process.env.GOOGLE_API_KEY!,
39
+ }),
40
+ openAIResolver({
41
+ apiKey: process.env.OPENAI_KEY!,
42
+ }),
43
+ ],
44
+ }),
45
+ ],
46
+ });
47
+ ```
48
+
49
+ ## Resolvers
50
+
51
+ ### OpenAI
52
+
53
+ #### Config:
54
+
55
+ ```ts
56
+ export type OpenAIResolverConfig = {
57
+ apiKey: string; // API key
58
+ chunkLength?: number; // How many texts to include into 1 request, default: 100
59
+ model?: string; // model, default: 'gpt-3.5-turbo'
60
+ promt?: OpenAIPrompt; // custom prompt
61
+ };
62
+ ```
63
+
64
+ ### Custom prompt:
65
+
66
+ ```ts
67
+ export type OpenAIPrompt = (args: {
68
+ localeFrom: string;
69
+ localeTo: string;
70
+ texts: string[];
71
+ }) => string;
72
+
73
+ // Default
74
+ const defaultPromt: OpenAIPrompt = ({ localeFrom, localeTo, texts }) => {
75
+ return `Translate me the following array: ${JSON.stringify(texts)} in locale=${localeFrom} to locale ${localeTo}, respond me with the same array structure`;
76
+ };
77
+ ```
78
+
79
+ ### Google
80
+
81
+ #### Config:
82
+
83
+ ```ts
84
+ export type GoogleResolverConfig = {
85
+ apiKey: string; // API key
86
+ chunkLength?: number; / /How many texts to include into 1 request, default: 100
87
+ };
88
+ ```
89
+
90
+ ### Writing your own
91
+
92
+ ```ts
93
+ import type { TranslateResolver } from '@payload-enchants/translator/resolvers/types';
94
+
95
+ const myResolver: TranslateResolver = {
96
+ key: 'my',
97
+ resolve: async (args) => {
98
+ const { localeFrom, localeTo, req, texts } = args;
99
+ // here you can apply any kind of transformation to incoming texts, could be as well API call to a service.
100
+ const transformed = texts.map((each) => `${each} translated to ${localeTo}`);
101
+
102
+ return {
103
+ success: true,
104
+ translatedTexts: transformed,
105
+ };
106
+ },
107
+ };
108
+
109
+ export default buildConfig({
110
+ plugins: [
111
+ payloadPluginTranslator({
112
+ collections: ['posts', 'small-posts'],
113
+ globals: [],
114
+ resolvers: [myResolver],
115
+ }),
116
+ ],
117
+ // apply translations that will be used for your resolver in the admin UI
118
+ i18n: {
119
+ supportedLanguages: { en },
120
+ translations: {
121
+ en: {
122
+ 'plugin-translator': {
123
+ resolver_my_buttonLabel: 'Google Translate',
124
+ resolver_my_errorMessage: 'An error occurred when trying to translate the data',
125
+ resolver_my_modalTitle: 'Choose the locale to translate from',
126
+ resolver_my_submitButtonLabelEmpty: 'Translate only empty fields',
127
+ resolver_my_submitButtonLabelFull: 'Translate all',
128
+ resolver_my_successMessage: 'Successfully translated. Press "Save" to apply the changes.',
129
+ },
130
+ },
131
+ },
132
+ },
133
+ });
134
+ ```
135
+
136
+ ## Using the Local API
137
+
138
+ ```ts
139
+ import { translateOperation } from '@payload-enchants/translator';
140
+
141
+ const translateResult = await translateOperation({
142
+ collectionSlug: 'posts', // or globalSlug if globals,
143
+ emptyOnly: false, // optional, should translate all the fields values or only fields that are empty, by default false.
144
+ id: postDefaultLocale.id, // pass the doc id if it's a collection
145
+ locale: 'de', // locale to translate to
146
+ localeFrom: 'en', // locale to translate from
147
+ payload, // payload instance, you can get it with getPayload or req.payload in hooks
148
+ req, // PayloadRequest, can be used instead of payload, more appreciable than payload if you have it
149
+ overrideAccess: false, //
150
+ resolver: 'copy', // pass resolver key
151
+ update: true, // optional, should update immediately or just return the translated result, default false
152
+ data: {}, // Optional, if you want to translate from your data passed here instead of the current doc, should be in "localeFrom" locale, for example { title: "Hello" }
153
+ });
154
+ ```
155
+
156
+ ### Example of the hook that uses local operation to copy the doc data to other locales
157
+
158
+ ```ts
159
+ import type { CollectionAfterChangeHook } from 'payload/types';
160
+ import { translateOperation } from '@payload-enchants/translator';
161
+
162
+ export const copyOtherLocales: CollectionAfterChangeHook = async ({
163
+ collection,
164
+ doc,
165
+ operation,
166
+ req,
167
+ }) => {
168
+ if (operation !== 'create') return;
169
+
170
+ const locale = req.locale;
171
+
172
+ if (!locale || !req.payload.config.localization) return;
173
+
174
+ const otherLocales = req.payload.config.localization.locales.filter(
175
+ (each) => each.code !== locale,
176
+ );
177
+
178
+ const { id } = doc;
179
+
180
+ for (const { code } of otherLocales) {
181
+ await translateOperation({
182
+ collectionSlug: collection.slug,
183
+ data: doc,
184
+ id,
185
+ locale: code,
186
+ localeFrom: locale,
187
+ req,
188
+ resolver: 'copy',
189
+ update: true,
190
+ });
191
+ }
192
+ };
193
+ ```
@@ -0,0 +1,8 @@
1
+ import type { TranslateEndpointArgs, TranslateResult } from '../../translate/types';
2
+ export declare const createClient: ({ api, serverURL }: {
3
+ api: string;
4
+ serverURL: string;
5
+ }) => {
6
+ translate: (args: TranslateEndpointArgs) => Promise<TranslateResult>;
7
+ };
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEpF,eAAO,MAAM,YAAY,uBAAwB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;sBAClD,qBAAqB,KAAG,QAAQ,eAAe,CAAC;CAwBhF,CAAC"}
@@ -0,0 +1,28 @@
1
+ export const createClient = ({ api, serverURL })=>{
2
+ const translate = async (args)=>{
3
+ try {
4
+ const response = await fetch(`${serverURL}${api}/translator/translate`, {
5
+ body: JSON.stringify(args),
6
+ credentials: 'include',
7
+ headers: {
8
+ 'Content-Type': 'application/json'
9
+ },
10
+ method: 'POST'
11
+ });
12
+ if (!response.ok) return {
13
+ success: false
14
+ };
15
+ return response.json();
16
+ } catch (e) {
17
+ if (e instanceof Error) console.error(e.message);
18
+ return {
19
+ success: false
20
+ };
21
+ }
22
+ };
23
+ return {
24
+ translate
25
+ };
26
+ };
27
+
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/client/api/index.ts"],"sourcesContent":["import type { TranslateEndpointArgs, TranslateResult } from '../../translate/types';\r\n\r\nexport const createClient = ({ api, serverURL }: { api: string; serverURL: string }) => {\r\n const translate = async (args: TranslateEndpointArgs): Promise<TranslateResult> => {\r\n try {\r\n const response = await fetch(`${serverURL}${api}/translator/translate`, {\r\n body: JSON.stringify(args),\r\n credentials: 'include',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n method: 'POST',\r\n });\r\n\r\n if (!response.ok) return { success: false };\r\n\r\n return response.json();\r\n } catch (e) {\r\n if (e instanceof Error) console.error(e.message);\r\n\r\n return { success: false };\r\n }\r\n };\r\n\r\n return {\r\n translate,\r\n };\r\n};\r\n"],"names":["createClient","api","serverURL","translate","args","response","fetch","body","JSON","stringify","credentials","headers","method","ok","success","json","e","Error","console","error","message"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,OAAO,MAAMA,eAAe,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAsC;IACjF,MAAMC,YAAY,OAAOC;QACvB,IAAI;YACF,MAAMC,WAAW,MAAMC,MAAM,CAAC,EAAEJ,UAAU,EAAED,IAAI,qBAAqB,CAAC,EAAE;gBACtEM,MAAMC,KAAKC,SAAS,CAACL;gBACrBM,aAAa;gBACbC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,QAAQ;YACV;YAEA,IAAI,CAACP,SAASQ,EAAE,EAAE,OAAO;gBAAEC,SAAS;YAAM;YAE1C,OAAOT,SAASU,IAAI;QACtB,EAAE,OAAOC,GAAG;YACV,IAAIA,aAAaC,OAAOC,QAAQC,KAAK,CAACH,EAAEI,OAAO;YAE/C,OAAO;gBAAEN,SAAS;YAAM;QAC1B;IACF;IAEA,OAAO;QACLX;IACF;AACF,EAAE"}
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import './styles.scss';
3
+ export declare const CustomSaveButton: () => import("react").JSX.Element;
4
+ //# sourceMappingURL=CustomSaveButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomSaveButton.d.ts","sourceRoot":"","sources":["../../../../src/client/components/CustomSaveButton/CustomSaveButton.tsx"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC;AAWvB,eAAO,MAAM,gBAAgB,mCAoB5B,CAAC"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import './styles.scss';
3
+ import { DefaultSaveButton } from '@payloadcms/ui/elements/Save';
4
+ import { useConfig } from '@payloadcms/ui/providers/Config';
5
+ import { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo';
6
+ import { TranslatorProvider } from '../../providers/Translator/TranslatorProvider';
7
+ import { ResolverButton } from '../ResolverButton';
8
+ import { TranslatorModal } from '../TranslatorModal';
9
+ export const CustomSaveButton = ()=>{
10
+ const config = useConfig();
11
+ const { globalSlug, id } = useDocumentInfo();
12
+ const resolvers = config.admin?.custom?.translator?.resolvers ?? [];
13
+ if (!id && !globalSlug) return /*#__PURE__*/ React.createElement(DefaultSaveButton, null);
14
+ return /*#__PURE__*/ React.createElement(TranslatorProvider, null, /*#__PURE__*/ React.createElement("div", {
15
+ className: 'translator__custom-save-button'
16
+ }, /*#__PURE__*/ React.createElement(TranslatorModal, null), resolvers.map((resolver)=>/*#__PURE__*/ React.createElement(ResolverButton, {
17
+ key: resolver.key,
18
+ resolver: resolver
19
+ })), /*#__PURE__*/ React.createElement(DefaultSaveButton, null)));
20
+ };
21
+
22
+ //# sourceMappingURL=CustomSaveButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/CustomSaveButton/CustomSaveButton.tsx"],"sourcesContent":["'use client';\r\n\r\nimport './styles.scss';\r\n\r\nimport { DefaultSaveButton } from '@payloadcms/ui/elements/Save';\r\nimport { useConfig } from '@payloadcms/ui/providers/Config';\r\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo';\r\n\r\nimport type { TranslateResolver } from '../../../resolvers/types';\r\nimport { TranslatorProvider } from '../../providers/Translator/TranslatorProvider';\r\nimport { ResolverButton } from '../ResolverButton';\r\nimport { TranslatorModal } from '../TranslatorModal';\r\n\r\nexport const CustomSaveButton = () => {\r\n const config = useConfig();\r\n\r\n const { globalSlug, id } = useDocumentInfo();\r\n\r\n const resolvers = (config.admin?.custom?.translator?.resolvers as TranslateResolver[]) ?? [];\r\n\r\n if (!id && !globalSlug) return <DefaultSaveButton />;\r\n\r\n return (\r\n <TranslatorProvider>\r\n <div className={'translator__custom-save-button'}>\r\n <TranslatorModal />\r\n {resolvers.map((resolver) => (\r\n <ResolverButton key={resolver.key} resolver={resolver} />\r\n ))}\r\n <DefaultSaveButton />\r\n </div>\r\n </TranslatorProvider>\r\n );\r\n};\r\n"],"names":["DefaultSaveButton","useConfig","useDocumentInfo","TranslatorProvider","ResolverButton","TranslatorModal","CustomSaveButton","config","globalSlug","id","resolvers","admin","custom","translator","div","className","map","resolver","key"],"rangeMappings":";;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAEA,OAAO,gBAAgB;AAEvB,SAASA,iBAAiB,QAAQ,+BAA+B;AACjE,SAASC,SAAS,QAAQ,kCAAkC;AAC5D,SAASC,eAAe,QAAQ,wCAAwC;AAGxE,SAASC,kBAAkB,QAAQ,gDAAgD;AACnF,SAASC,cAAc,QAAQ,oBAAoB;AACnD,SAASC,eAAe,QAAQ,qBAAqB;AAErD,OAAO,MAAMC,mBAAmB;IAC9B,MAAMC,SAASN;IAEf,MAAM,EAAEO,UAAU,EAAEC,EAAE,EAAE,GAAGP;IAE3B,MAAMQ,YAAY,AAACH,OAAOI,KAAK,EAAEC,QAAQC,YAAYH,aAAqC,EAAE;IAE5F,IAAI,CAACD,MAAM,CAACD,YAAY,qBAAO,oBAACR;IAEhC,qBACE,oBAACG,wCACC,oBAACW;QAAIC,WAAW;qBACd,oBAACV,wBACAK,UAAUM,GAAG,CAAC,CAACC,yBACd,oBAACb;YAAec,KAAKD,SAASC,GAAG;YAAED,UAAUA;2BAE/C,oBAACjB;AAIT,EAAE"}
@@ -0,0 +1,2 @@
1
+ export * from './CustomSaveButton';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/CustomSaveButton/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './CustomSaveButton';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/CustomSaveButton/index.ts"],"sourcesContent":["export * from './CustomSaveButton';\r\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,qBAAqB"}
@@ -0,0 +1,5 @@
1
+ .translator__custom-save-button {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 10px;
5
+ }
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { Locale } from 'payload/config';
3
+ export declare const LocaleLabel: ({ locale }: {
4
+ locale: Locale;
5
+ }) => import("react").JSX.Element;
6
+ //# sourceMappingURL=LocaleLabel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocaleLabel.d.ts","sourceRoot":"","sources":["../../../../src/client/components/LocaleLabel/LocaleLabel.tsx"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,eAAO,MAAM,WAAW,eAAgB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,gCAczD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { getTranslation } from '@payloadcms/translations';
2
+ import { Chevron } from '@payloadcms/ui/icons/Chevron';
3
+ import { useTranslation } from '@payloadcms/ui/providers/Translation';
4
+ const baseClass = 'localizer-button';
5
+ export const LocaleLabel = ({ locale })=>{
6
+ const { i18n, t } = useTranslation();
7
+ return /*#__PURE__*/ React.createElement("div", {
8
+ "aria-label": t('general:locale'),
9
+ className: baseClass
10
+ }, /*#__PURE__*/ React.createElement("div", {
11
+ className: `${baseClass}__label`
12
+ }, `${t('general:locale')}:`), "  ", /*#__PURE__*/ React.createElement("span", {
13
+ className: `${baseClass}__current-label`
14
+ }, `${getTranslation(locale.label, i18n)}`), " ", /*#__PURE__*/ React.createElement(Chevron, {
15
+ className: `${baseClass}__chevron`
16
+ }));
17
+ };
18
+
19
+ //# sourceMappingURL=LocaleLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/LocaleLabel/LocaleLabel.tsx"],"sourcesContent":["import { getTranslation } from '@payloadcms/translations';\r\nimport { Chevron } from '@payloadcms/ui/icons/Chevron';\r\nimport { useTranslation } from '@payloadcms/ui/providers/Translation';\r\nimport type { Locale } from 'payload/config';\r\n\r\nconst baseClass = 'localizer-button';\r\n\r\nexport const LocaleLabel = ({ locale }: { locale: Locale }) => {\r\n const { i18n, t } = useTranslation();\r\n\r\n return (\r\n <div aria-label={t('general:locale')} className={baseClass}>\r\n <div className={`${baseClass}__label`}>{`${t('general:locale')}:`}</div>\r\n &nbsp;&nbsp;\r\n <span className={`${baseClass}__current-label`}>\r\n {`${getTranslation(locale.label, i18n)}`}\r\n </span>\r\n &nbsp;\r\n <Chevron className={`${baseClass}__chevron`} />\r\n </div>\r\n );\r\n};\r\n"],"names":["getTranslation","Chevron","useTranslation","baseClass","LocaleLabel","locale","i18n","t","div","aria-label","className","span","label"],"rangeMappings":";;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,OAAO,QAAQ,+BAA+B;AACvD,SAASC,cAAc,QAAQ,uCAAuC;AAGtE,MAAMC,YAAY;AAElB,OAAO,MAAMC,cAAc,CAAC,EAAEC,MAAM,EAAsB;IACxD,MAAM,EAAEC,IAAI,EAAEC,CAAC,EAAE,GAAGL;IAEpB,qBACE,oBAACM;QAAIC,cAAYF,EAAE;QAAmBG,WAAWP;qBAC/C,oBAACK;QAAIE,WAAW,CAAC,EAAEP,UAAU,OAAO,CAAC;OAAG,CAAC,EAAEI,EAAE,kBAAkB,CAAC,CAAC,GAAO,oBAExE,oBAACI;QAAKD,WAAW,CAAC,EAAEP,UAAU,eAAe,CAAC;OAC3C,CAAC,EAAEH,eAAeK,OAAOO,KAAK,EAAEN,MAAM,CAAC,GACnC,mBAEP,oBAACL;QAAQS,WAAW,CAAC,EAAEP,UAAU,SAAS,CAAC;;AAGjD,EAAE"}
@@ -0,0 +1,2 @@
1
+ export * from './LocaleLabel';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/LocaleLabel/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './LocaleLabel';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/LocaleLabel/index.ts"],"sourcesContent":["export * from './LocaleLabel';\r\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,gBAAgB"}
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { TranslateResolver } from '../../../resolvers/types';
3
+ export declare const ResolverButton: ({ resolver: { key: resolverKey }, }: {
4
+ resolver: TranslateResolver;
5
+ }) => import("react").JSX.Element;
6
+ //# sourceMappingURL=ResolverButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResolverButton.d.ts","sourceRoot":"","sources":["../../../../src/client/components/ResolverButton/ResolverButton.tsx"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,eAAO,MAAM,cAAc,wCAExB;IACD,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,gCAYA,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Button } from '@payloadcms/ui/elements';
2
+ import { useTranslation } from '@payloadcms/ui/providers/Translation';
3
+ import { useTranslator } from '../../providers/Translator/context';
4
+ export const ResolverButton = ({ resolver: { key: resolverKey } })=>{
5
+ const { openTranslator } = useTranslator();
6
+ const { t } = useTranslation();
7
+ const handleClick = ()=>openTranslator({
8
+ resolverKey
9
+ });
10
+ return /*#__PURE__*/ React.createElement(Button, {
11
+ onClick: handleClick,
12
+ size: "small"
13
+ }, t(`plugin-translator:resolver_${resolverKey}_buttonLabel`));
14
+ };
15
+
16
+ //# sourceMappingURL=ResolverButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/ResolverButton/ResolverButton.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui/elements';\r\nimport { useTranslation } from '@payloadcms/ui/providers/Translation';\r\n\r\nimport type { TranslateResolver } from '../../../resolvers/types';\r\nimport { useTranslator } from '../../providers/Translator/context';\r\n\r\nexport const ResolverButton = ({\r\n resolver: { key: resolverKey },\r\n}: {\r\n resolver: TranslateResolver;\r\n}) => {\r\n const { openTranslator } = useTranslator();\r\n\r\n const { t } = useTranslation();\r\n\r\n const handleClick = () => openTranslator({ resolverKey });\r\n\r\n return (\r\n <Button onClick={handleClick} size='small'>\r\n {t(`plugin-translator:resolver_${resolverKey}_buttonLabel`)}\r\n </Button>\r\n );\r\n};\r\n"],"names":["Button","useTranslation","useTranslator","ResolverButton","resolver","key","resolverKey","openTranslator","t","handleClick","onClick","size"],"rangeMappings":";;;;;;;;;;;;;","mappings":"AAAA,SAASA,MAAM,QAAQ,0BAA0B;AACjD,SAASC,cAAc,QAAQ,uCAAuC;AAGtE,SAASC,aAAa,QAAQ,qCAAqC;AAEnE,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,UAAU,EAAEC,KAAKC,WAAW,EAAE,EAG/B;IACC,MAAM,EAAEC,cAAc,EAAE,GAAGL;IAE3B,MAAM,EAAEM,CAAC,EAAE,GAAGP;IAEd,MAAMQ,cAAc,IAAMF,eAAe;YAAED;QAAY;IAEvD,qBACE,oBAACN;QAAOU,SAASD;QAAaE,MAAK;OAChCH,EAAE,CAAC,2BAA2B,EAAEF,YAAY,YAAY,CAAC;AAGhE,EAAE"}
@@ -0,0 +1,2 @@
1
+ export * from './ResolverButton';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/ResolverButton/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './ResolverButton';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/ResolverButton/index.ts"],"sourcesContent":["export * from './ResolverButton';\r\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,mBAAmB"}
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ export declare const Content: () => import("react").JSX.Element;
3
+ //# sourceMappingURL=Content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../../../../src/client/components/TranslatorModal/Content.tsx"],"names":[],"mappings":";AAOA,eAAO,MAAM,OAAO,mCAwDnB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { getTranslation } from '@payloadcms/translations';
2
+ import { Button, Popup, PopupList } from '@payloadcms/ui/elements';
3
+ import { useTranslation } from '@payloadcms/ui/providers/Translation';
4
+ import { useTranslator } from '../../providers/Translator/context';
5
+ import { LocaleLabel } from '../LocaleLabel';
6
+ export const Content = ()=>{
7
+ const { localeToTranslateFrom: localeCodeToTranslateFrom, localesOptions, resolverT, setLocaleToTranslateFrom, submit } = useTranslator();
8
+ const { i18n } = useTranslation();
9
+ const localeToTranslateFrom = localesOptions.find((each)=>each.code === localeCodeToTranslateFrom);
10
+ return /*#__PURE__*/ React.createElement("div", {
11
+ className: 'translator__content'
12
+ }, /*#__PURE__*/ React.createElement("h2", null, resolverT('modalTitle')), localeToTranslateFrom && /*#__PURE__*/ React.createElement(Popup, {
13
+ button: /*#__PURE__*/ React.createElement(LocaleLabel, {
14
+ locale: localeToTranslateFrom
15
+ }),
16
+ horizontalAlign: "center",
17
+ render: ({ close })=>/*#__PURE__*/ React.createElement(PopupList.ButtonGroup, null, localesOptions.map((option)=>{
18
+ const label = getTranslation(option.label, i18n);
19
+ return /*#__PURE__*/ React.createElement(PopupList.Button, {
20
+ active: option.code === localeCodeToTranslateFrom,
21
+ key: option.code,
22
+ onClick: ()=>{
23
+ setLocaleToTranslateFrom(option.code);
24
+ close();
25
+ }
26
+ }, label, label !== option.code && ` (${option.code})`);
27
+ })),
28
+ verticalAlign: "bottom"
29
+ }), /*#__PURE__*/ React.createElement("div", {
30
+ className: 'translator__buttons'
31
+ }, /*#__PURE__*/ React.createElement(Button, {
32
+ onClick: ()=>submit({
33
+ emptyOnly: false
34
+ })
35
+ }, resolverT('submitButtonLabelFull')), /*#__PURE__*/ React.createElement(Button, {
36
+ onClick: ()=>submit({
37
+ emptyOnly: true
38
+ })
39
+ }, resolverT('submitButtonLabelEmpty'))));
40
+ };
41
+
42
+ //# sourceMappingURL=Content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/TranslatorModal/Content.tsx"],"sourcesContent":["import { getTranslation } from '@payloadcms/translations';\r\nimport { Button, Popup, PopupList } from '@payloadcms/ui/elements';\r\nimport { useTranslation } from '@payloadcms/ui/providers/Translation';\r\n\r\nimport { useTranslator } from '../../providers/Translator/context';\r\nimport { LocaleLabel } from '../LocaleLabel';\r\n\r\nexport const Content = () => {\r\n const {\r\n localeToTranslateFrom: localeCodeToTranslateFrom,\r\n localesOptions,\r\n resolverT,\r\n setLocaleToTranslateFrom,\r\n submit,\r\n } = useTranslator();\r\n\r\n const { i18n } = useTranslation();\r\n\r\n const localeToTranslateFrom = localesOptions.find(\r\n (each) => each.code === localeCodeToTranslateFrom,\r\n );\r\n\r\n return (\r\n <div className={'translator__content'}>\r\n <h2>{resolverT('modalTitle')}</h2>\r\n {localeToTranslateFrom && (\r\n <Popup\r\n button={<LocaleLabel locale={localeToTranslateFrom} />}\r\n horizontalAlign='center'\r\n render={({ close }) => (\r\n <PopupList.ButtonGroup>\r\n {localesOptions.map((option) => {\r\n const label = getTranslation(option.label, i18n);\r\n\r\n return (\r\n <PopupList.Button\r\n active={option.code === localeCodeToTranslateFrom}\r\n key={option.code}\r\n onClick={() => {\r\n setLocaleToTranslateFrom(option.code);\r\n close();\r\n }}\r\n >\r\n {label}\r\n {label !== option.code && ` (${option.code})`}\r\n </PopupList.Button>\r\n );\r\n })}\r\n </PopupList.ButtonGroup>\r\n )}\r\n verticalAlign='bottom'\r\n />\r\n )}\r\n <div className={'translator__buttons'}>\r\n <Button onClick={() => submit({ emptyOnly: false })}>\r\n {resolverT('submitButtonLabelFull')}\r\n </Button>\r\n <Button onClick={() => submit({ emptyOnly: true })}>\r\n {resolverT('submitButtonLabelEmpty')}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["getTranslation","Button","Popup","PopupList","useTranslation","useTranslator","LocaleLabel","Content","localeToTranslateFrom","localeCodeToTranslateFrom","localesOptions","resolverT","setLocaleToTranslateFrom","submit","i18n","find","each","code","div","className","h2","button","locale","horizontalAlign","render","close","ButtonGroup","map","option","label","active","key","onClick","verticalAlign","emptyOnly"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,MAAM,EAAEC,KAAK,EAAEC,SAAS,QAAQ,0BAA0B;AACnE,SAASC,cAAc,QAAQ,uCAAuC;AAEtE,SAASC,aAAa,QAAQ,qCAAqC;AACnE,SAASC,WAAW,QAAQ,iBAAiB;AAE7C,OAAO,MAAMC,UAAU;IACrB,MAAM,EACJC,uBAAuBC,yBAAyB,EAChDC,cAAc,EACdC,SAAS,EACTC,wBAAwB,EACxBC,MAAM,EACP,GAAGR;IAEJ,MAAM,EAAES,IAAI,EAAE,GAAGV;IAEjB,MAAMI,wBAAwBE,eAAeK,IAAI,CAC/C,CAACC,OAASA,KAAKC,IAAI,KAAKR;IAG1B,qBACE,oBAACS;QAAIC,WAAW;qBACd,oBAACC,YAAIT,UAAU,gBACdH,uCACC,oBAACN;QACCmB,sBAAQ,oBAACf;YAAYgB,QAAQd;;QAC7Be,iBAAgB;QAChBC,QAAQ,CAAC,EAAEC,KAAK,EAAE,iBAChB,oBAACtB,UAAUuB,WAAW,QACnBhB,eAAeiB,GAAG,CAAC,CAACC;gBACnB,MAAMC,QAAQ7B,eAAe4B,OAAOC,KAAK,EAAEf;gBAE3C,qBACE,oBAACX,UAAUF,MAAM;oBACf6B,QAAQF,OAAOX,IAAI,KAAKR;oBACxBsB,KAAKH,OAAOX,IAAI;oBAChBe,SAAS;wBACPpB,yBAAyBgB,OAAOX,IAAI;wBACpCQ;oBACF;mBAECI,OACAA,UAAUD,OAAOX,IAAI,IAAI,CAAC,EAAE,EAAEW,OAAOX,IAAI,CAAC,CAAC,CAAC;YAGnD;QAGJgB,eAAc;sBAGlB,oBAACf;QAAIC,WAAW;qBACd,oBAAClB;QAAO+B,SAAS,IAAMnB,OAAO;gBAAEqB,WAAW;YAAM;OAC9CvB,UAAU,yCAEb,oBAACV;QAAO+B,SAAS,IAAMnB,OAAO;gBAAEqB,WAAW;YAAK;OAC7CvB,UAAU;AAKrB,EAAE"}
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import './styles.scss';
3
+ export declare const TranslatorModal: () => import("react").JSX.Element | undefined;
4
+ //# sourceMappingURL=TranslatorModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslatorModal.d.ts","sourceRoot":"","sources":["../../../../src/client/components/TranslatorModal/TranslatorModal.tsx"],"names":[],"mappings":";AAAA,OAAO,eAAe,CAAC;AAOvB,eAAO,MAAM,eAAe,+CAkB3B,CAAC"}
@@ -0,0 +1,21 @@
1
+ import './styles.scss';
2
+ import { Modal } from '@payloadcms/ui/elements';
3
+ import { useTranslator } from '../../providers/Translator/context';
4
+ import { Content } from './Content';
5
+ export const TranslatorModal = ()=>{
6
+ const { closeTranslator, modalSlug, resolver } = useTranslator();
7
+ if (!resolver) return;
8
+ return /*#__PURE__*/ React.createElement(Modal, {
9
+ className: 'translator__modal',
10
+ slug: modalSlug
11
+ }, /*#__PURE__*/ React.createElement("div", {
12
+ className: 'translator__wrapper'
13
+ }, /*#__PURE__*/ React.createElement("span", {
14
+ "aria-label": "Close",
15
+ className: 'translator__close',
16
+ onClick: closeTranslator,
17
+ role: "button"
18
+ }), /*#__PURE__*/ React.createElement(Content, null)));
19
+ };
20
+
21
+ //# sourceMappingURL=TranslatorModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/TranslatorModal/TranslatorModal.tsx"],"sourcesContent":["import './styles.scss';\r\n\r\nimport { Modal } from '@payloadcms/ui/elements';\r\n\r\nimport { useTranslator } from '../../providers/Translator/context';\r\nimport { Content } from './Content';\r\n\r\nexport const TranslatorModal = () => {\r\n const { closeTranslator, modalSlug, resolver } = useTranslator();\r\n\r\n if (!resolver) return;\r\n\r\n return (\r\n <Modal className={'translator__modal'} slug={modalSlug}>\r\n <div className={'translator__wrapper'}>\r\n <span\r\n aria-label='Close'\r\n className={'translator__close'}\r\n onClick={closeTranslator}\r\n role='button'\r\n />\r\n <Content />\r\n </div>\r\n </Modal>\r\n );\r\n};\r\n"],"names":["Modal","useTranslator","Content","TranslatorModal","closeTranslator","modalSlug","resolver","className","slug","div","span","aria-label","onClick","role"],"rangeMappings":";;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAO,gBAAgB;AAEvB,SAASA,KAAK,QAAQ,0BAA0B;AAEhD,SAASC,aAAa,QAAQ,qCAAqC;AACnE,SAASC,OAAO,QAAQ,YAAY;AAEpC,OAAO,MAAMC,kBAAkB;IAC7B,MAAM,EAAEC,eAAe,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGL;IAEjD,IAAI,CAACK,UAAU;IAEf,qBACE,oBAACN;QAAMO,WAAW;QAAqBC,MAAMH;qBAC3C,oBAACI;QAAIF,WAAW;qBACd,oBAACG;QACCC,cAAW;QACXJ,WAAW;QACXK,SAASR;QACTS,MAAK;sBAEP,oBAACX;AAIT,EAAE"}
@@ -0,0 +1,2 @@
1
+ export * from './TranslatorModal';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/TranslatorModal/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './TranslatorModal';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/client/components/TranslatorModal/index.ts"],"sourcesContent":["export * from './TranslatorModal';\r\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,oBAAoB"}
@@ -0,0 +1,76 @@
1
+ .translator {
2
+ &__modal {
3
+ display: flex;
4
+ position: relative;
5
+ justify-content: center;
6
+ align-items: center;
7
+ width: fit-content;
8
+ height: fit-content;
9
+ }
10
+
11
+ &__wrapper {
12
+ display: flex;
13
+ position: relative;
14
+ flex-direction: column;
15
+ gap: var(--base);
16
+ z-index: 1;
17
+ background: var(--theme-elevation-50);
18
+ padding: 50px;
19
+ }
20
+
21
+ &__content {
22
+ display: flex;
23
+ flex-direction: column;
24
+ align-items: center;
25
+ gap: var(--base);
26
+ max-width: 400px;
27
+
28
+ h2 {
29
+ margin: 0;
30
+ text-align: center;
31
+ }
32
+ }
33
+
34
+ &__buttons {
35
+ display: flex;
36
+ justify-content: center;
37
+ gap: 10px;
38
+ width: 100%;
39
+
40
+ button {
41
+ margin: 0;
42
+ }
43
+ }
44
+
45
+ &__close {
46
+ position: absolute;
47
+ top: 10px;
48
+ right: 10px;
49
+ transition: 0.25s;
50
+ cursor: pointer;
51
+ width: 32px;
52
+ height: 32px;
53
+
54
+ &:hover {
55
+ opacity: 0.6;
56
+ }
57
+
58
+ &:before,
59
+ &:after {
60
+ position: absolute;
61
+ left: 15px;
62
+ background-color: var(--theme-elevation-800);
63
+ width: 2px;
64
+ height: 33px;
65
+ content: ' ';
66
+ }
67
+
68
+ &:before {
69
+ transform: rotate(45deg);
70
+ }
71
+
72
+ &:after {
73
+ transform: rotate(-45deg);
74
+ }
75
+ }
76
+ }